On Wed, 2 Dec 2015, Jan Hubicka wrote:

> 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?

First of all, why do debug MEMs need mem-attrs?  Second, I'd rather
refactor make_decl_rtl into a _raw part that can be used from
both make_decl_rtl and make_decl_rtl_for_debug avoiding the debug
parameter.

I don't think any of this is suitable for stage3.

Thanks,
Richard.

> 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
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to