Hi,
this patch removes flag_strict_aliasing kludge in expanding debug locations and
instead it introduces explicit parameter DEBUG that makes
set_mem_attributes_minus_bitpos to not affect alias sets.  This is sanity
checked by comparing number of alias sets before and after at a time we
originally overwritten flag_strict_aliasing.

I also added code to prevent memory attributes creation for !optimize and to
avoid get_alias_set computation for !flag_strict_aliasing. This slightly
optimizes -O0 builds but the results seems to be down in the noise (I would not
object to leave it out).

The patch should fix at least one (latent?) bug that call_stmt expansion
invoke expand_debug_expr without clearing flag_strict_aliasing.

Bootstrapped/regtested x86_64-linux, also tested with compare-debug, OK?

Honza

        * cfgexpand.c: Include alias.h
        (expand_debug_expr): Pass debug=true to set_mem_attributes.
        (expand_debug_locations): Do not fiddle with flag_strict_aliasing;
        sanity check that no new alias set was introduced.
        * varasm.c: Include alias.h
        (make_decl_rtl): New parameter DEBUG; pass it to set_mem_attributes.
        (make_decl_rtl_for_debug): Do ont fiddle with flag_strict_aliasing;
        assert that no new alias set was introduced.
        * varasm.h (make_decl_rtl): New parameter debug.
        * alias.h (num_alias_sets): New function.
        * emit-rtl.c (set_mem_attributes_minus_bitpos): New parameter DEBUG;
        exit early when not optimizing; do not introduce new alias set when
        producing debug only attributes.
        (set_mem_attributes): New parameter DEBUG.
        * emit-rtl.h (set_mem_attributes, set_mem_attributes_minus_bitpos):
        New parameters DEBUG.
        (num_alias_sets): New function.

Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 231122)
+++ cfgexpand.c (working copy)
@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3.
 #include "builtins.h"
 #include "tree-chkp.h"
 #include "rtl-chkp.h"
+#include "alias.h"
 
 /* Some systems use __main in a way incompatible with its use in gcc, in these
    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
@@ -4178,7 +4179,7 @@ expand_debug_expr (tree exp)
            return NULL_RTX;
          op0 = gen_rtx_CONST_STRING (Pmode, TREE_STRING_POINTER (exp));
          op0 = gen_rtx_MEM (BLKmode, op0);
-         set_mem_attributes (op0, exp, 0);
+         set_mem_attributes (op0, exp, 0, true);
          return op0;
        }
       /* Fall through...  */
@@ -4346,7 +4347,7 @@ expand_debug_expr (tree exp)
        return NULL;
 
       op0 = gen_rtx_MEM (mode, op0);
-      set_mem_attributes (op0, exp, 0);
+      set_mem_attributes (op0, exp, 0, true);
       if (TREE_CODE (exp) == MEM_REF
          && !is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0)))
        set_mem_expr (op0, NULL_TREE);
@@ -4372,7 +4373,7 @@ expand_debug_expr (tree exp)
 
       op0 = gen_rtx_MEM (mode, op0);
 
-      set_mem_attributes (op0, exp, 0);
+      set_mem_attributes (op0, exp, 0, true);
       set_mem_addr_space (op0, as);
 
       return op0;
@@ -4458,7 +4459,7 @@ expand_debug_expr (tree exp)
              op0 = copy_rtx (op0);
            if (op0 == orig_op0)
              op0 = shallow_copy_rtx (op0);
-           set_mem_attributes (op0, exp, 0);
+           set_mem_attributes (op0, exp, 0, true);
          }
 
        if (bitpos == 0 && mode == GET_MODE (op0))
@@ -5219,12 +5220,11 @@ expand_debug_locations (void)
 {
   rtx_insn *insn;
   rtx_insn *last = get_last_insn ();
-  int save_strict_alias = flag_strict_aliasing;
 
   /* New alias sets while setting up memory attributes cause
      -fcompare-debug failures, even though it doesn't bring about any
      codegen changes.  */
-  flag_strict_aliasing = 0;
+  int num = num_alias_sets ();
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     if (DEBUG_INSN_P (insn))
@@ -5284,7 +5284,7 @@ expand_debug_locations (void)
          avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0);
       }
 
-  flag_strict_aliasing = save_strict_alias;
+  gcc_checking_assert (num == num_alias_sets ());
 }
 
 /* Performs swapping operands of commutative operations to expand
Index: varasm.c
===================================================================
--- varasm.c    (revision 231122)
+++ varasm.c    (working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
 #include "common/common-target.h"
 #include "asan.h"
 #include "rtl-iter.h"
+#include "alias.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"          /* Needed for external data declarations.  */
@@ -1280,7 +1281,7 @@ ultimate_transparent_alias_target (tree
    This is never called for PARM_DECL nodes.  */
 
 void
-make_decl_rtl (tree decl)
+make_decl_rtl (tree decl, bool debug)
 {
   const char *name = 0;
   int reg_number;
@@ -1470,7 +1471,7 @@ make_decl_rtl (tree decl)
 
   x = gen_rtx_MEM (DECL_MODE (decl), x);
   if (TREE_CODE (decl) != FUNCTION_DECL)
-    set_mem_attributes (x, decl, 1);
+    set_mem_attributes (x, decl, 1, debug);
   SET_DECL_RTL (decl, x);
 
   /* Optionally set flags or add text to the name to record information
@@ -1487,27 +1488,25 @@ make_decl_rtl (tree decl)
 rtx
 make_decl_rtl_for_debug (tree decl)
 {
-  unsigned int save_aliasing_flag;
   rtx rtl;
 
   if (DECL_RTL_SET_P (decl))
     return DECL_RTL (decl);
 
-  /* Kludge alert!  Somewhere down the call chain, make_decl_rtl will
-     call new_alias_set.  If running with -fcompare-debug, sometimes
-     we do not want to create alias sets that will throw the alias
-     numbers off in the comparison dumps.  So... clearing
-     flag_strict_aliasing will keep new_alias_set() from creating a
-     new set.  */
-  save_aliasing_flag = flag_strict_aliasing;
-  flag_strict_aliasing = 0;
+  int num = num_alias_sets ();
 
+  make_decl_rtl (decl, true);
   rtl = DECL_RTL (decl);
   /* Reset DECL_RTL back, as various parts of the compiler expects
      DECL_RTL set meaning it is actually going to be output.  */
   SET_DECL_RTL (decl, NULL);
+  
+  /* Be sure that make_decl_rtl will not cal lnew_alias set.
+     If running with -fcompare-debug, sometimes
+     we do not want to create alias sets that will throw the alias
+     numbers off in the comparison dumps.  */
+  gcc_checking_assert (num == num_alias_sets ());
 
-  flag_strict_aliasing = save_aliasing_flag;
   return rtl;
 }
 
Index: varasm.h
===================================================================
--- varasm.h    (revision 231122)
+++ varasm.h    (working copy)
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.
 extern tree cold_function_name;
 
 extern tree tree_output_constant_def (tree);
-extern void make_decl_rtl (tree);
+extern void make_decl_rtl (tree, bool debug = false);
 extern rtx make_decl_rtl_for_debug (tree);
 extern void make_decl_one_only (tree, tree);
 extern int supports_one_only (void);
Index: alias.h
===================================================================
--- alias.h     (revision 231122)
+++ alias.h     (working copy)
@@ -25,6 +25,7 @@ extern alias_set_type get_alias_set (tre
 extern alias_set_type get_deref_alias_set (tree);
 extern alias_set_type get_varargs_alias_set (void);
 extern alias_set_type get_frame_alias_set (void);
+extern int num_alias_sets (void);
 extern tree component_uses_parent_alias_set_from (const_tree);
 extern bool alias_set_subset_of (alias_set_type, alias_set_type);
 extern void record_alias_subset (alias_set_type, alias_set_type);
Index: emit-rtl.c
===================================================================
--- emit-rtl.c  (revision 231122)
+++ emit-rtl.c  (working copy)
@@ -1738,16 +1738,20 @@ get_mem_align_offset (rtx mem, unsigned
 /* Given REF (a MEM) and T, either the type of X or the expression
    corresponding to REF, set the memory attributes.  OBJECTP is nonzero
    if we are making a new object of this type.  BITPOS is nonzero if
-   there is an offset outstanding on T that will be applied later.  */
+   there is an offset outstanding on T that will be applied later.
+   if DEBUG is true, assume that the MEM will be used only for debug
+   insns.  */
 
 void
 set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
-                                HOST_WIDE_INT bitpos)
+                                HOST_WIDE_INT bitpos, bool debug)
 {
   HOST_WIDE_INT apply_bitpos = 0;
   tree type;
   struct mem_attrs attrs, *defattrs, *refattrs;
   addr_space_t as;
+  bool global_var = false;
+  tree orig_t = t;
 
   /* It can happen that type_for_mode was given a mode for which there
      is no language-level type.  In which case it returns NULL, which
@@ -1759,18 +1763,8 @@ set_mem_attributes_minus_bitpos (rtx ref
   if (type == error_mark_node)
     return;
 
-  /* If we have already set DECL_RTL = ref, get_alias_set will get the
-     wrong answer, as it assumes that DECL_RTL already has the right alias
-     info.  Callers should not set DECL_RTL until after the call to
-     set_mem_attributes.  */
-  gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t));
-
   memset (&attrs, 0, sizeof (attrs));
 
-  /* Get the alias set from the expression or type (perhaps using a
-     front-end routine) and use it.  */
-  attrs.alias = get_alias_set (t);
-
   MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
   MEM_POINTER (ref) = POINTER_TYPE_P (type);
 
@@ -1829,6 +1823,12 @@ set_mem_attributes_minus_bitpos (rtx ref
     {
       tree base;
 
+      if (TREE_CODE (t) == CONST_DECL
+         || (TREE_CODE (t) == VAR_DECL
+             && auto_var_in_fn_p (t, current_function_decl))
+         || (TREE_CODE (t) == LABEL_DECL && DECL_NONLOCAL (t)))
+       global_var = true;
+
       if (TREE_THIS_VOLATILE (t))
        MEM_VOLATILE_P (ref) = 1;
 
@@ -1866,13 +1866,20 @@ set_mem_attributes_minus_bitpos (rtx ref
            as = TYPE_ADDR_SPACE (TREE_TYPE (base));
        }
 
+      /* When not optimizing, there is no need to attach memory attributes
+        unless we produce DECL_RTL of declaration that may later be used in a
+        function that is optimized.  */
+      if (!optimize && !global_var)
+       return;
+
       /* If this expression uses it's parent's alias set, mark it such
         that we won't change it.  */
-      if (component_uses_parent_alias_set_from (t) != NULL_TREE)
+      if (!debug && (flag_strict_aliasing || global_var)
+         && component_uses_parent_alias_set_from (t) != NULL_TREE)
        MEM_KEEP_ALIAS_SET_P (ref) = 1;
 
       /* If this is a decl, set the attributes of the MEM from it.  */
-      if (DECL_P (t))
+      else if (DECL_P (t))
        {
          attrs.expr = t;
          attrs.offset_known_p = true;
@@ -1962,6 +1969,11 @@ set_mem_attributes_minus_bitpos (rtx ref
        obj_align = (obj_bitpos & -obj_bitpos);
       attrs.align = MAX (attrs.align, obj_align);
     }
+  /* When not optimizing, there is no need to attach memory attributes
+     unless we produce DECL_RTL of declaration that may later be used in a
+     function that is optimized.  */
+  else if (!global_var && !optimize)
+    return;
 
   if (tree_fits_uhwi_p (new_size))
     {
@@ -1980,15 +1992,29 @@ set_mem_attributes_minus_bitpos (rtx ref
        attrs.size += apply_bitpos / BITS_PER_UNIT;
     }
 
+  /* Get the alias set from the expression or type (perhaps using a
+     front-end routine) and use it.  Never produce new alias sets when
+     the memory reference is used only for debug (so the alias numbers
+     are stable) and with !flag_strict_aliasing for all function local RTLs.  
*/
+  if (!debug && (flag_strict_aliasing || global_var))
+    {
+      /* If we have already set DECL_RTL = ref, get_alias_set will get the
+        wrong answer, as it assumes that DECL_RTL already has the right alias
+        info.  Callers should not set DECL_RTL until after the call to
+        set_mem_attributes.  */
+      gcc_assert (!DECL_P (orig_t) || ref != DECL_RTL_IF_SET (orig_t));
+      attrs.alias = get_alias_set (orig_t);
+    }
+
   /* Now set the attributes we computed above.  */
   attrs.addrspace = as;
   set_mem_attrs (ref, &attrs);
 }
 
 void
-set_mem_attributes (rtx ref, tree t, int objectp)
+set_mem_attributes (rtx ref, tree t, int objectp, bool debug)
 {
-  set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
+  set_mem_attributes_minus_bitpos (ref, t, objectp, 0, debug);
 }
 
 /* Set the alias set of MEM to SET.  */
Index: emit-rtl.h
===================================================================
--- emit-rtl.h  (revision 231122)
+++ emit-rtl.h  (working copy)
@@ -484,13 +484,16 @@ extern rtx offset_address (rtx, rtx, uns
 
 /* Given REF, a MEM, and T, either the type of X or the expression
    corresponding to REF, set the memory attributes.  OBJECTP is nonzero
-   if we are making a new object of this type.  */
-extern void set_mem_attributes (rtx, tree, int);
+   if we are making a new object of this type.
+   If DEBUG is true, the memory expression will be used only for debug
+   statements and in that case avoid creation of new alias set.  */
+extern void set_mem_attributes (rtx, tree, int, bool debug = false);
 
 /* Similar, except that BITPOS has not yet been applied to REF, so if
    we alter MEM_OFFSET according to T then we should subtract BITPOS
    expecting that it'll be added back in later.  */
-extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT);
+extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT,
+                                            bool debug = false);
 
 /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
    bits aligned for 0 <= OFFSET < ALIGN / BITS_PER_UNIT, or
Index: alias.c
===================================================================
--- alias.c     (revision 231146)
+++ alias.c     (working copy)
@@ -1096,6 +1096,17 @@ new_alias_set (void)
     return 0;
 }
 
+/* Return number of alias sets;  used for sanity checking that we did not
+   introduced new ones for debug statements.  */
+
+int
+num_alias_sets (void)
+{
+  if (!alias_sets)
+    return 0;
+  return alias_sets->length ();
+}
+
 /* Indicate that things in SUBSET can alias things in SUPERSET, but that
    not everything that aliases SUPERSET also aliases SUBSET.  For example,
    in C, a store to an `int' can alias a load of a structure containing an

Reply via email to