]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR debug/55717
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Dec 2012 10:50:47 +0000 (10:50 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Dec 2012 10:50:47 +0000 (10:50 +0000)
* 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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/rtlhooks-def.h
gcc/rtlhooks.c
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr55717.C [new file with mode: 0644]

index 14ee6d92e3e6ec66ae23cfa3dd99465cddfe530a..104fc9e6d76dfcb854a363cd23e5b82c5115ca31 100644 (file)
@@ -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;
index c92fa4bd4b58e393b157ee28aae04c6bafbffeb6..a284eed6977fabb225ee2c12ae6413888666af81 100644 (file)
@@ -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.  */
index 07d8fcfce38690ae8ae4c733d2e0cae856115ae2..ab442e690b2f195049426ee67ccae3209af666db 100644 (file)
@@ -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,
index 60e4d52890e5294c55c6db7481fe35b23d77b885..ef6552dfd5609d83adc9c98fa2a8cddbad4d381d 100644 (file)
@@ -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,
index f26f0083cf6db2d9dd974f35da7e7e68c204839e..ea99c64bff848f493891ace69eb8ef424925f6a9 100644 (file)
@@ -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;
index 0d8b3e7de2485d416a89b2b5b9354b12a9f64b67..2360147fba7d4d290e57419c0d31c58e29c66659 100644 (file)
@@ -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 (file)
index 0000000..7b3af58
--- /dev/null
@@ -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);
+    }
+}