diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-18 10:50:47 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-18 10:50:47 +0000 |
commit | 11833cca5c63a5d9e65af0f84fc62bfdef20d610 (patch) | |
tree | aa9c6427dcc97a3b76b02ae4b8e5bfd7aa409495 | |
parent | 95997886c2a0df89ad5409cfc55aea3991137d25 (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 26 | ||||
-rw-r--r-- | gcc/rtlhooks-def.h | 5 | ||||
-rw-r--r-- | gcc/rtlhooks.c | 15 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 65 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr55717.C | 107 |
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); + } +} |