summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-18 10:50:47 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-18 10:50:47 +0000
commit11833cca5c63a5d9e65af0f84fc62bfdef20d610 (patch)
treeaa9c6427dcc97a3b76b02ae4b8e5bfd7aa409495
parent95997886c2a0df89ad5409cfc55aea3991137d25 (diff)
downloadgcc-11833cca5c63a5d9e65af0f84fc62bfdef20d610.tar.gz
PR debug/55717
* rtlhooks-def.h (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Define to gen_lowpart_if_possible. (gen_lowpart_no_emit_general): Remove prototype. * rtlhooks.c (gen_lowpart_no_emit_general): Removed. * simplify-rtx.c (simplify_unary_operation_1, simplify_binary_operation_1): Continue simplifying if rtl_hooks.gen_lowpart_no_emit returns NULL_RTX. * dwarf2out.c (mem_loc_descriptor) <case TRUNCATE>: Handle truncation like lowpart SUBREG. * testsuite/g++.dg/opt/pr55717.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194575 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/dwarf2out.c26
-rw-r--r--gcc/rtlhooks-def.h5
-rw-r--r--gcc/rtlhooks.c15
-rw-r--r--gcc/simplify-rtx.c65
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/pr55717.C107
7 files changed, 195 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14ee6d92e3e..104fc9e6d76 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2012-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/55717
+ * rtlhooks-def.h (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Define to
+ gen_lowpart_if_possible.
+ (gen_lowpart_no_emit_general): Remove prototype.
+ * rtlhooks.c (gen_lowpart_no_emit_general): Removed.
+ * simplify-rtx.c (simplify_unary_operation_1,
+ simplify_binary_operation_1): Continue simplifying if
+ rtl_hooks.gen_lowpart_no_emit returns NULL_RTX.
+ * dwarf2out.c (mem_loc_descriptor) <case TRUNCATE>: Handle
+ truncation like lowpart SUBREG.
+
2012-12-17 Gerald Pfeifer <gerald@pfeifer.com>
* doc/contrib.texi (Contributors): Update Kaveh Ghazi's entry;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c92fa4bd4b5..a284eed6977 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -11840,6 +11840,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
dw_loc_descr_ref mem_loc_result = NULL;
enum dwarf_location_atom op;
dw_loc_descr_ref op0, op1;
+ rtx inner = NULL_RTX;
if (mode == VOIDmode)
mode = GET_MODE (rtl);
@@ -11869,35 +11870,39 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
contains the given subreg. */
if (!subreg_lowpart_p (rtl))
break;
+ inner = SUBREG_REG (rtl);
+ case TRUNCATE:
+ if (inner == NULL_RTX)
+ inner = XEXP (rtl, 0);
if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_CLASS (GET_MODE (SUBREG_REG (rtl))) == MODE_INT
+ && GET_MODE_CLASS (GET_MODE (inner)) == MODE_INT
&& (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE
#ifdef POINTERS_EXTEND_UNSIGNED
|| (mode == Pmode && mem_mode != VOIDmode)
#endif
)
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))) <= DWARF2_ADDR_SIZE)
+ && GET_MODE_SIZE (GET_MODE (inner)) <= DWARF2_ADDR_SIZE)
{
- mem_loc_result = mem_loc_descriptor (SUBREG_REG (rtl),
- GET_MODE (SUBREG_REG (rtl)),
+ mem_loc_result = mem_loc_descriptor (inner,
+ GET_MODE (inner),
mem_mode, initialized);
break;
}
if (dwarf_strict)
break;
- if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))))
+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (inner)))
break;
- if (GET_MODE_SIZE (mode) != GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl)))
+ if (GET_MODE_SIZE (mode) != GET_MODE_SIZE (GET_MODE (inner))
&& (GET_MODE_CLASS (mode) != MODE_INT
- || GET_MODE_CLASS (GET_MODE (SUBREG_REG (rtl))) != MODE_INT))
+ || GET_MODE_CLASS (GET_MODE (inner)) != MODE_INT))
break;
else
{
dw_die_ref type_die;
dw_loc_descr_ref cvt;
- mem_loc_result = mem_loc_descriptor (SUBREG_REG (rtl),
- GET_MODE (SUBREG_REG (rtl)),
+ mem_loc_result = mem_loc_descriptor (inner,
+ GET_MODE (inner),
mem_mode, initialized);
if (mem_loc_result == NULL)
break;
@@ -11909,7 +11914,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
break;
}
if (GET_MODE_SIZE (mode)
- != GET_MODE_SIZE (GET_MODE (SUBREG_REG (rtl))))
+ != GET_MODE_SIZE (GET_MODE (inner)))
cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
else
cvt = new_loc_descr (DW_OP_GNU_reinterpret, 0, 0);
@@ -12666,7 +12671,6 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
break;
case COMPARE:
- case TRUNCATE:
/* In theory, we could implement the above. */
/* DWARF cannot represent the unsigned compare operations
natively. */
diff --git a/gcc/rtlhooks-def.h b/gcc/rtlhooks-def.h
index 07d8fcfce38..ab442e690b2 100644
--- a/gcc/rtlhooks-def.h
+++ b/gcc/rtlhooks-def.h
@@ -1,5 +1,5 @@
/* Default macros to initialize an rtl_hooks data structure.
- Copyright 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright 2004, 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtl.h"
#define RTL_HOOKS_GEN_LOWPART gen_lowpart_general
-#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_no_emit_general
+#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_if_possible
#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general
@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. If not see
}
extern rtx gen_lowpart_general (enum machine_mode, rtx);
-extern rtx gen_lowpart_no_emit_general (enum machine_mode, rtx);
extern rtx reg_nonzero_bits_general (const_rtx, enum machine_mode, const_rtx,
enum machine_mode,
unsigned HOST_WIDE_INT,
diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c
index 60e4d52890e..ef6552dfd56 100644
--- a/gcc/rtlhooks.c
+++ b/gcc/rtlhooks.c
@@ -1,5 +1,6 @@
/* Generic hooks for the RTL middle-end.
- Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008, 2009, 2011, 2012
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -79,18 +80,6 @@ gen_lowpart_general (enum machine_mode mode, rtx x)
}
}
-/* Similar to gen_lowpart, but cannot emit any instruction via
- copy_to_reg or force_reg. Mainly used in simplify-rtx.c. */
-rtx
-gen_lowpart_no_emit_general (enum machine_mode mode, rtx x)
-{
- rtx result = gen_lowpart_if_possible (mode, x);
- if (result)
- return result;
- else
- return x;
-}
-
rtx
reg_num_sign_bit_copies_general (const_rtx x ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index f26f0083cf6..ea99c64bff8 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -873,7 +873,9 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
simplify_gen_unary (NOT, inner_mode, const1_rtx,
inner_mode),
XEXP (SUBREG_REG (op), 1));
- return rtl_hooks.gen_lowpart_no_emit (mode, x);
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
+ if (temp)
+ return temp;
}
/* Apply De Morgan's laws to reduce number of patterns for machines
@@ -1029,7 +1031,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
{
if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
/* We can't handle truncation to a partial integer mode here
because we don't know the real bitsize of the partial
integer mode. */
@@ -1048,7 +1054,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
if (GET_MODE_NUNITS (mode) == 1
&& (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
|| truncated_to_mode (mode, op)))
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
/* A truncate of a comparison can be replaced with a subreg if
STORE_FLAG_VALUE permits. This is like the previous test,
@@ -1057,7 +1067,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
if (HWI_COMPUTABLE_MODE_P (mode)
&& COMPARISON_P (op)
&& (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
/* A truncate of a memory is just loading the low part of the memory
if we are not changing the meaning of the address. */
@@ -1065,7 +1079,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
&& !VECTOR_MODE_P (mode)
&& !MEM_VOLATILE_P (op)
&& !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
break;
@@ -1298,7 +1316,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
&& SUBREG_PROMOTED_VAR_P (op)
&& ! SUBREG_PROMOTED_UNSIGNED_P (op)
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
(sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
@@ -1330,9 +1352,10 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
{
rtx inner =
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
- return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
- ? SIGN_EXTEND : ZERO_EXTEND,
- mode, inner, tmode);
+ if (inner)
+ return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
+ ? SIGN_EXTEND : ZERO_EXTEND,
+ mode, inner, tmode);
}
}
@@ -1360,7 +1383,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
&& SUBREG_PROMOTED_VAR_P (op)
&& SUBREG_PROMOTED_UNSIGNED_P (op) > 0
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
- return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+ if (temp)
+ return temp;
+ }
/* Extending a widening multiplication should be canonicalized to
a wider widening multiplication. */
@@ -1425,7 +1452,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
{
rtx inner =
rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
- return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode);
+ if (inner)
+ return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode);
}
}
@@ -3095,7 +3123,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
}
/* x/1 is x. */
if (trueop1 == CONST1_RTX (mode))
- return rtl_hooks.gen_lowpart_no_emit (mode, op0);
+ {
+ tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
+ if (tem)
+ return tem;
+ }
/* Convert divide by power of two into shift. */
if (CONST_INT_P (trueop1)
&& (val = exact_log2 (UINTVAL (trueop1))) > 0)
@@ -3154,12 +3186,17 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
}
/* x/1 is x. */
if (trueop1 == CONST1_RTX (mode))
- return rtl_hooks.gen_lowpart_no_emit (mode, op0);
+ {
+ tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
+ if (tem)
+ return tem;
+ }
/* x/-1 is -x. */
if (trueop1 == constm1_rtx)
{
rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
- return simplify_gen_unary (NEG, mode, x, mode);
+ if (x)
+ return simplify_gen_unary (NEG, mode, x, mode);
}
}
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0d8b3e7de24..2360147fba7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/55717
+ * testsuite/g++.dg/opt/pr55717.C: New test.
+
2012-12-17 Andrew Stubbs <ams@codesourcery.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
diff --git a/gcc/testsuite/g++.dg/opt/pr55717.C b/gcc/testsuite/g++.dg/opt/pr55717.C
new file mode 100644
index 00000000000..7b3af589ee6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr55717.C
@@ -0,0 +1,107 @@
+// PR debug/55717
+// { dg-do compile }
+// { dg-options "-O -g" }
+
+struct DebugOnly {};
+template <class T>
+struct StripConst { typedef T result; };
+class TempAllocPolicy {};
+template <class T>
+class HashTableEntry
+{
+ unsigned keyHash;
+ template <class, class, class>
+ friend class HashTable;
+ T t;
+ void setLive (unsigned hn) { keyHash = hn; }
+};
+template <class T, class HashPolicy, class>
+struct HashTable
+{
+ typedef typename HashPolicy::KeyType Key;
+ typedef typename HashPolicy::Lookup Lookup;
+ typedef HashTableEntry <T> Entry;
+ struct Range
+ {
+ Range () {}
+ Entry *cur, end;
+ bool empty () { return false; }
+ T front () { return T (); }
+ };
+ struct Enum : public Range
+ {
+ HashTable table;
+ bool removed;
+ template <class Map>
+ Enum (Map map) : Range (map.all ()), table (map.impl), removed () {}
+ void rekeyFront (Lookup l, Key)
+ {
+ T t = this->cur->t;
+ table.putNewInfallible (l, t);
+ }
+ void rekeyFront (Key k)
+ {
+ rekeyFront (k, k);
+ }
+ };
+ unsigned entryCount;
+ unsigned sCollisionBit;
+ unsigned prepareHash (Lookup l)
+ {
+ unsigned keyHash (HashPolicy::hash (l));
+ return keyHash & sCollisionBit;
+ }
+ static Entry *entryp;
+ Entry *findFreeEntry (unsigned) { return entryp; }
+ void putNewInfallible (Lookup l, T)
+ {
+ unsigned keyHash = prepareHash (l);
+ Entry *entry = findFreeEntry (keyHash);
+ entry->setLive (keyHash);
+ entryCount++;
+ }
+};
+template <class Key>
+struct HashMapEntry { Key key; };
+template <class Key, class Value, class HashPolicy = DebugOnly, class AllocPolicy = TempAllocPolicy>
+struct HashMap
+{
+ typedef HashMapEntry <Key> Entry;
+ struct MapHashPolicy : HashPolicy
+ {
+ typedef Key KeyType;
+ };
+ typedef HashTable <Entry, MapHashPolicy, AllocPolicy> Impl;
+ Impl impl;
+ typedef typename Impl::Range Range;
+ Range all () { return Range (); }
+ typedef typename Impl::Enum Enum;
+};
+class FreeOp;
+struct AllocationSiteKey;
+typedef HashMap <AllocationSiteKey, DebugOnly, AllocationSiteKey, TempAllocPolicy> AllocationSiteTable;
+struct TypeCompartment
+{
+ AllocationSiteTable *allocationSiteTable;
+ void sweep (FreeOp *);
+};
+struct JSScript { unsigned *code; };
+bool IsScriptMarked (JSScript **);
+struct AllocationSiteKey
+{
+ JSScript *script;
+ unsigned offset : 24;
+ int kind;
+ typedef AllocationSiteKey Lookup;
+ static unsigned hash (AllocationSiteKey key) { return (long (key.script->code + key.offset)) ^ key.kind; }
+};
+void
+TypeCompartment::sweep (FreeOp *)
+{
+ for (AllocationSiteTable::Enum e (*allocationSiteTable); !e.empty ();)
+ {
+ AllocationSiteKey key = e.front ().key;
+ IsScriptMarked (&key.script);
+ e.rekeyFront (key);
+ }
+}