On Thu, 23 Apr 2020, Richard Biener wrote:

> On Wed, 22 Apr 2020, Richard Sandiford wrote:
> 
> > Richard Biener <rguent...@suse.de> writes:
> > > On Wed, 22 Apr 2020, Richard Biener wrote:
> > >
> > >> 
> > >> This extends DECL_GIMPLE_REG_P to all types so we can clear
> > >> TREE_ADDRESSABLE even for integers with partial defs, not just
> > >> complex and vector variables.  To make that transition easier
> > >> the patch inverts DECL_GIMPLE_REG_P to DECL_NOT_GIMPLE_REG_P
> > >> since that makes the default the current state for all other
> > >> types besides complex and vectors.  That also nicely simplifies
> > >> code throughout the compiler.
> > >> 
> > >> TREE_ADDRESSABLE and DECL_NOT_GIMPLE_REG_P are now truly
> > >> independent, either set prevents a decl from being rewritten
> > >> into SSA form.
> > >> 
> > >> For the testcase in PR94703 we're able to expand the partial
> > >> def'ed local integer to a register then, producing a single
> > >> movl rather than going through the stack.
> > >> 
> > >> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> > >> 
> > >> If there are no objections I'm going to install this once
> > >> stage1 opens.
> > >
> > > Of course there was some fallout.  On 32bit x86 gcc.dg/torture/pr71522.c
> > > fails execution because while the GIMPLE is unchanged at RTL expansion
> > > time:
> > >
> > > main ()
> > > {
> > >   char s[12];
> > >   long double d;
> > >
> > >   MEM <unsigned char[12]> [(char * {ref-all})&d] = MEM <unsigned 
> > > char[12]> 
> > > [(char * {ref-all})"AAAAAAAAAAA"];
> > >   MEM <unsigned char[12]> [(char * {ref-all})&s] = MEM <unsigned 
> > > char[12]> 
> > > [(char * {ref-all})&d];
> > >   _1 = __builtin_strcmp (&s, "AAAAAAAAAAA");
> > >   if (_1 != 0)
> > > ...
> > >
> > > we now assign 'd' an XFmode register (TREE_ADDRESSABLE is cleared
> > > now since we can set DECL_NOT_GIMPLE_REG_P).  The case is lost
> > > then, impossible to fix up AFAICS.  On x86 all moves to/from
> > > XFmode are normalizing, specifically we end up with
> > >
> > >         fldt    .LC0
> > >         fstpt   (%esp)
> > >
> > > now the most appealing solution - and totally in the opposite
> > > direction of this patch - is to simply stop expanding non-SSA names
> > > as pseudos.  I do not remember the history as why we do this
> > > but it's likely remanents we preserved from either pre-SSA, times
> > > we did not go into SSA for -O0 or times we really gone out-of-SSA.
> > >
> > > There is _some_ good reason to expand a non-SSA "register" into
> > > a pseudo though - namely that RTL is not SSA and thus can accept
> > > partial defs.  And of course that RTL cannot get rid of a stack
> > > slot assigned to a variable.  Today we have somewhat robust
> > > infrastructure to deal with partial defs on GIMPLE, namely
> > > BIT_INSERT_EXPR, but it's not fully exercised.
> > 
> > Yeah, not being able to get rid of the stack slot seems
> > worrying here.
> > 
> > > It's of course possible to fixup the above problematical
> > > cases (there's precenent with discover_nonconstant_array_refs,
> > > which could be "easily" extended to handle "weird" accesses
> > > of non-integral-mode variables) but with the recent discussion
> > > on making RTL expansion more straight-forward I'd bring up
> > > the above idea ... it would get rid of quite some special
> > > code dealing with tcc_reference trees (and MEM_REFs) ending
> > > up operating on registers.
> > 
> > It might be nice to do it eventually, but I think at least
> > is_gimple_reg_type would need to be "return true" first,
> > otherwise we'll lose too much on aggregates.
> > 
> > There's also the problem that things passed in registers do need
> > to be RTL registers at function boundaries, so I'm not sure all
> > the expand code would necessarily go away.
> > 
> > Wouldn't want to see all targets suffer for XFmode oddities :-)
> 
> OK, so here's the patch amemded with some heuristics to catch
> this.  The heuristic triggers exactly on the previously
> failing testcase and nothing else on a x86_64 bootstrap and regtest.
> Citing the code:
> 
> /* If there's a chance to get a pseudo for t then if it would be of float 
> mode
>    and the actual access is via an integer mode (lowered memcpy or similar
>    access) then avoid the register expansion if the mode likely is not 
> storage
>    suitable for raw bits processing (like XFmode on i?86).  */
> 
> static void
> avoid_type_punning_on_regs (tree t)
> {
>   machine_mode access_mode = TYPE_MODE (TREE_TYPE (t));
>   if (access_mode != BLKmode
>       && !SCALAR_INT_MODE_P (access_mode))
>     return;
>   tree base = get_base_address (t);
>   if (DECL_P (base)
>       && !TREE_ADDRESSABLE (base)
>       && FLOAT_MODE_P (DECL_MODE (base))
>       && maybe_lt (GET_MODE_PRECISION (DECL_MODE (base)),
>                    GET_MODE_BITSIZE (GET_MODE_INNER (DECL_MODE (base))))
>       /* Double check in the expensive way we really would get a pseudo.  
> */
>       && use_register_for_decl (base))
>     TREE_ADDRESSABLE (base) = 1;
> }
> 
> invoked on stores like
> 
>             if (gimple_vdef (stmt))
>               {
>                 tree t = gimple_get_lhs (stmt);
>                 if (t && REFERENCE_CLASS_P (t))
>                   avoid_type_punning_on_regs (t);
>               }
> 
> loads are not an issue on their own.  So the basic idea is to rule
> out float-mode pseudos which have less precision than their mode
> but where we store to with integer-like modes.  A but hand-wavy
> since similar issues might exist with partial integer modes as storage(?),
> but we shouldn't really need this at all in an ideal world.
> 
> You could check whether this triggers on arm with the respective
> long double testcase.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1.

I have now pushed this.

Richard.

> Richard.
> 
> Subject: [PATCH] extend DECL_GIMPLE_REG_P to all types
> 
> This extends DECL_GIMPLE_REG_P to all types so we can clear
> TREE_ADDRESSABLE even for integers with partial defs, not just
> complex and vector variables.  To make that transition easier
> the patch inverts DECL_GIMPLE_REG_P to DECL_NOT_GIMPLE_REG_P
> since that makes the default the current state for all other
> types besides complex and vectors.
> 
> For the testcase in PR94703 we're able to expand the partial
> def'ed local integer to a register then, producing a single
> movl rather than going through the stack.
> 
> On i?86 this execute FAILs gcc.dg/torture/pr71522.c because
> we now expand a round-trip through a long double automatic var
> to a register fld/fst which normalizes the value.  For that
> during RTL expansion we're looking for problematic punnings
> of decls and avoid pseudos for those - I chose integer or
> BLKmode accesses on decls with modes where precision doesn't
> match bitsize which covers the XFmode case.
> 
> 2020-04-22  Richard Biener  <rguent...@suse.de>
> 
>       PR middle-end/94703
>       * tree-core.h (tree_decl_common::gimple_reg_flag): Rename ...
>       (tree_decl_common::not_gimple_reg_flag): ... to this.
>       * tree.h (DECL_GIMPLE_REG_P): Rename ...
>       (DECL_NOT_GIMPLE_REG_P): ... to this.
>       * gimple-expr.c (copy_var_decl): Copy DECL_NOT_GIMPLE_REG_P.
>       (create_tmp_reg): Simplify.
>       (create_tmp_reg_fn): Likewise.
>       (is_gimple_reg): Check DECL_NOT_GIMPLE_REG_P for all regs.
>       * gimplify.c (create_tmp_from_val): Simplify.
>       (gimplify_bind_expr): Likewise.
>       (gimplify_compound_literal_expr): Likewise.
>       (gimplify_function_tree): Likewise.
>       (prepare_gimple_addressable): Set DECL_NOT_GIMPLE_REG_P.
>       * asan.c (create_odr_indicator): Do not clear DECL_GIMPLE_REG_P.
>       (asan_add_global): Copy it.
>       * cgraphunit.c (cgraph_node::expand_thunk): Force args
>       to be GIMPLE regs.
>       * function.c (gimplify_parameters): Copy
>       DECL_NOT_GIMPLE_REG_P.
>       * ipa-param-manipulation.c
>       (ipa_param_body_adjustments::common_initialization): Simplify.
>       (ipa_param_body_adjustments::reset_debug_stmts): Copy
>       DECL_NOT_GIMPLE_REG_P.
>       * omp-low.c (lower_omp_for_scan): Do not set DECL_GIMPLE_REG_P.
>       * sanopt.c (sanitize_rewrite_addressable_params): Likewise.
>       * tree-cfg.c (make_blocks_1): Simplify.
>       (verify_address): Do not verify DECL_GIMPLE_REG_P setting.
>       * tree-eh.c (lower_eh_constructs_2): Simplify.
>       * tree-inline.c (declare_return_variable): Adjust and
>       generalize.
>       (copy_decl_to_var): Copy DECL_NOT_GIMPLE_REG_P.
>       (copy_result_decl_to_var): Likewise.
>       * tree-into-ssa.c (pass_build_ssa::execute): Adjust comment.
>       * tree-nested.c (create_tmp_var_for): Simplify.
>       * tree-parloops.c (separate_decls_in_region_name): Copy
>       DECL_NOT_GIMPLE_REG_P.
>       * tree-sra.c (create_access_replacement): Adjust and
>       generalize partial def support.
>       * tree-ssa-forwprop.c (pass_forwprop::execute): Set
>       DECL_NOT_GIMPLE_REG_P on decls we introduce partial defs on.
>       * tree-ssa.c (maybe_optimize_var): Handle clearing of
>       TREE_ADDRESSABLE and setting/clearing DECL_NOT_GIMPLE_REG_P
>       independently.
>       * lto-streamer-out.c (hash_tree): Hash DECL_NOT_GIMPLE_REG_P.
>       * tree-streamer-out.c (pack_ts_decl_common_value_fields): Stream
>       DECL_NOT_GIMPLE_REG_P.
>       * tree-streamer-in.c (unpack_ts_decl_common_value_fields): Likewise.
>       * cfgexpand.c (avoid_type_punning_on_regs): New.
>       (discover_nonconstant_array_refs): Call
>       avoid_type_punning_on_regs to avoid unsupported mode punning.
> 
>       lto/
>       * lto-common.c (compare_tree_sccs_1): Compare
>       DECL_NOT_GIMPLE_REG_P.
> 
>       c/
>       * gimple-parser.c (c_parser_parse_ssa_name): Do not set
>       DECL_GIMPLE_REG_P.
> 
>       cp/
>       * optimize.c (update_cloned_parm): Copy DECL_NOT_GIMPLE_REG_P.
> 
>       * gcc.dg/tree-ssa/pr94703.c: New testcase.
> ---
>  gcc/asan.c                              |  3 +-
>  gcc/c/gimple-parser.c                   |  3 --
>  gcc/cfgexpand.c                         | 29 +++++++++++++++
>  gcc/cgraphunit.c                        |  5 +--
>  gcc/cp/optimize.c                       |  2 +-
>  gcc/function.c                          |  5 +--
>  gcc/gimple-expr.c                       | 24 +++---------
>  gcc/gimplify.c                          | 46 +----------------------
>  gcc/ipa-param-manipulation.c            |  6 +--
>  gcc/lto-streamer-out.c                  |  2 +-
>  gcc/lto/lto-common.c                    |  2 +-
>  gcc/omp-low.c                           |  1 -
>  gcc/sanopt.c                            |  1 -
>  gcc/testsuite/gcc.dg/tree-ssa/pr94703.c | 11 ++++++
>  gcc/tree-cfg.c                          |  9 -----
>  gcc/tree-core.h                         |  2 +-
>  gcc/tree-eh.c                           |  3 --
>  gcc/tree-inline.c                       | 28 +++++++-------
>  gcc/tree-into-ssa.c                     |  3 +-
>  gcc/tree-nested.c                       |  3 --
>  gcc/tree-parloops.c                     |  2 +-
>  gcc/tree-sra.c                          | 12 ++----
>  gcc/tree-ssa-forwprop.c                 |  6 ++-
>  gcc/tree-ssa.c                          | 66 
> +++++++++++++++++----------------
>  gcc/tree-streamer-in.c                  |  2 +-
>  gcc/tree-streamer-out.c                 |  2 +-
>  gcc/tree.h                              |  4 +-
>  27 files changed, 118 insertions(+), 164 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr94703.c
> 
> diff --git a/gcc/asan.c b/gcc/asan.c
> index ae14f7e543c..c9872f1b007 100644
> --- a/gcc/asan.c
> +++ b/gcc/asan.c
> @@ -2696,7 +2696,6 @@ create_odr_indicator (tree decl, tree type)
>    TREE_ADDRESSABLE (var) = 1;
>    TREE_READONLY (var) = 0;
>    TREE_THIS_VOLATILE (var) = 1;
> -  DECL_GIMPLE_REG_P (var) = 0;
>    DECL_ARTIFICIAL (var) = 1;
>    DECL_IGNORED_P (var) = 1;
>    TREE_STATIC (var) = 1;
> @@ -2766,7 +2765,7 @@ asan_add_global (tree decl, tree type, 
> vec<constructor_elt, va_gc> *v)
>        TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
>        TREE_READONLY (refdecl) = TREE_READONLY (decl);
>        TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
> -      DECL_GIMPLE_REG_P (refdecl) = DECL_GIMPLE_REG_P (decl);
> +      DECL_NOT_GIMPLE_REG_P (refdecl) = DECL_NOT_GIMPLE_REG_P (decl);
>        DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
>        DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
>        TREE_STATIC (refdecl) = 1;
> diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
> index 4e8ff5b1c4f..577d8b58c7d 100644
> --- a/gcc/c/gimple-parser.c
> +++ b/gcc/c/gimple-parser.c
> @@ -1272,9 +1272,6 @@ c_parser_parse_ssa_name (gimple_parser &parser,
>             error ("invalid base %qE for SSA name", parent);
>             return error_mark_node;
>           }
> -       if (VECTOR_TYPE_P (TREE_TYPE (parent))
> -           || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
> -         DECL_GIMPLE_REG_P (parent) = 1;
>         name = make_ssa_name_fn (cfun, parent,
>                                  gimple_build_nop (), version);
>       }
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index a7ec77d5c85..2d39c5e43c5 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -6126,6 +6126,29 @@ discover_nonconstant_array_refs_r (tree * tp, int 
> *walk_subtrees,
>    return NULL_TREE;
>  }
>  
> +/* If there's a chance to get a pseudo for t then if it would be of float 
> mode
> +   and the actual access is via an integer mode (lowered memcpy or similar
> +   access) then avoid the register expansion if the mode likely is not 
> storage
> +   suitable for raw bits processing (like XFmode on i?86).  */
> +
> +static void
> +avoid_type_punning_on_regs (tree t)
> +{
> +  machine_mode access_mode = TYPE_MODE (TREE_TYPE (t));
> +  if (access_mode != BLKmode
> +      && !SCALAR_INT_MODE_P (access_mode))
> +    return;
> +  tree base = get_base_address (t);
> +  if (DECL_P (base)
> +      && !TREE_ADDRESSABLE (base)
> +      && FLOAT_MODE_P (DECL_MODE (base))
> +      && maybe_lt (GET_MODE_PRECISION (DECL_MODE (base)),
> +                GET_MODE_BITSIZE (GET_MODE_INNER (DECL_MODE (base))))
> +      /* Double check in the expensive way we really would get a pseudo.  */
> +      && use_register_for_decl (base))
> +    TREE_ADDRESSABLE (base) = 1;
> +}
> +
>  /* RTL expansion is not able to compile array references with variable
>     offsets for arrays stored in single register.  Discover such
>     expressions and mark variables as addressable to avoid this
> @@ -6159,6 +6182,12 @@ discover_nonconstant_array_refs (void)
>               default:
>                 break;
>               }
> +         if (gimple_vdef (stmt))
> +           {
> +             tree t = gimple_get_lhs (stmt);
> +             if (t && REFERENCE_CLASS_P (t))
> +               avoid_type_punning_on_regs (t);
> +           }
>         }
>        }
>  }
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index a1ace95879a..0563932a709 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -2058,10 +2058,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, 
> bool force_gimple_thunk)
>       for (; i < nargs; i++, arg = DECL_CHAIN (arg))
>         {
>           tree tmp = arg;
> -         if (VECTOR_TYPE_P (TREE_TYPE (arg))
> -             || TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
> -           DECL_GIMPLE_REG_P (arg) = 1;
> -
> +         DECL_NOT_GIMPLE_REG_P (arg) = 0;
>           if (!is_gimple_val (arg))
>             {
>               tmp = create_tmp_reg (TYPE_MAIN_VARIANT
> diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
> index d4f12dbb84d..abdcd7fa19f 100644
> --- a/gcc/cp/optimize.c
> +++ b/gcc/cp/optimize.c
> @@ -58,7 +58,7 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
>    DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
>    TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
>  
> -  DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
> +  DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
>  }
>  
>  /* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
> diff --git a/gcc/function.c b/gcc/function.c
> index d616f5f64f4..9eee9b59bfd 100644
> --- a/gcc/function.c
> +++ b/gcc/function.c
> @@ -3913,9 +3913,8 @@ gimplify_parameters (gimple_seq *cleanup)
>                    as we'll query that flag during gimplification.  */
>                 if (TREE_ADDRESSABLE (parm))
>                   TREE_ADDRESSABLE (local) = 1;
> -               else if (TREE_CODE (type) == COMPLEX_TYPE
> -                        || TREE_CODE (type) == VECTOR_TYPE)
> -                 DECL_GIMPLE_REG_P (local) = 1;
> +               if (DECL_NOT_GIMPLE_REG_P (parm))
> +                 DECL_NOT_GIMPLE_REG_P (local) = 1;
>  
>                 if (!is_gimple_reg (local)
>                     && flag_stack_reuse != SR_NONE)
> diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
> index 44a0b8790f5..45871ac2c27 100644
> --- a/gcc/gimple-expr.c
> +++ b/gcc/gimple-expr.c
> @@ -373,7 +373,7 @@ copy_var_decl (tree var, tree name, tree type)
>  
>    TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
>    TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
> -  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
> +  DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (var);
>    DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
>    DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
>    DECL_CONTEXT (copy) = DECL_CONTEXT (var);
> @@ -493,14 +493,7 @@ create_tmp_var (tree type, const char *prefix)
>  tree
>  create_tmp_reg (tree type, const char *prefix)
>  {
> -  tree tmp;
> -
> -  tmp = create_tmp_var (type, prefix);
> -  if (TREE_CODE (type) == COMPLEX_TYPE
> -      || TREE_CODE (type) == VECTOR_TYPE)
> -    DECL_GIMPLE_REG_P (tmp) = 1;
> -
> -  return tmp;
> +  return create_tmp_var (type, prefix);
>  }
>  
>  /* Create a new temporary variable declaration of type TYPE by calling
> @@ -514,9 +507,6 @@ create_tmp_reg_fn (struct function *fn, tree type, const 
> char *prefix)
>  
>    tmp = create_tmp_var_raw (type, prefix);
>    gimple_add_tmp_var_fn (fn, tmp);
> -  if (TREE_CODE (type) == COMPLEX_TYPE
> -      || TREE_CODE (type) == VECTOR_TYPE)
> -    DECL_GIMPLE_REG_P (tmp) = 1;
>  
>    return tmp;
>  }
> @@ -792,13 +782,9 @@ is_gimple_reg (tree t)
>    if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
>      return false;
>  
> -  /* Complex and vector values must have been put into SSA-like form.
> -     That is, no assignments to the individual components.  */
> -  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> -      || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> -    return DECL_GIMPLE_REG_P (t);
> -
> -  return true;
> +  /* Variables can be marked as having partial definitions, avoid
> +     putting them into SSA form.  */
> +  return !DECL_NOT_GIMPLE_REG_P (t);
>  }
>  
>  
> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> index 2f2c51b2d89..ef7679d4c2b 100644
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -559,9 +559,6 @@ create_tmp_from_val (tree val)
>    /* Drop all qualifiers and address-space information from the value type.  
> */
>    tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
>    tree var = create_tmp_var (type, get_name (val));
> -  if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
> -      || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
> -    DECL_GIMPLE_REG_P (var) = 1;
>    return var;
>  }
>  
> @@ -1400,16 +1397,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
>         if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
>           cfun->has_local_explicit_reg_vars = true;
>       }
> -
> -      /* Preliminarily mark non-addressed complex variables as eligible
> -      for promotion to gimple registers.  We'll transform their uses
> -      as we find them.  */
> -      if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
> -        || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
> -       && !TREE_THIS_VOLATILE (t)
> -       && (VAR_P (t) && !DECL_HARD_REGISTER (t))
> -       && !needs_to_live_in_memory (t))
> -     DECL_GIMPLE_REG_P (t) = 1;
>      }
>  
>    bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
> @@ -4308,7 +4295,7 @@ prepare_gimple_addressable (tree *expr_p, gimple_seq 
> *seq_p)
>      {
>        /* Do not allow an SSA name as the temporary.  */
>        tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
> -      DECL_GIMPLE_REG_P (var) = 0;
> +      DECL_NOT_GIMPLE_REG_P (var) = 1;
>        *expr_p = var;
>      }
>  }
> @@ -4774,15 +4761,6 @@ gimplify_compound_literal_expr (tree *expr_p, 
> gimple_seq *pre_p,
>        return GS_OK;
>      }
>  
> -  /* Preliminarily mark non-addressed complex variables as eligible
> -     for promotion to gimple registers.  We'll transform their uses
> -     as we find them.  */
> -  if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
> -       || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
> -      && !TREE_THIS_VOLATILE (decl)
> -      && !needs_to_live_in_memory (decl))
> -    DECL_GIMPLE_REG_P (decl) = 1;
> -
>    /* If the decl is not addressable, then it is being used in some
>       expression or on the right hand side of a statement, and it can
>       be put into a readonly data section.  */
> @@ -5617,8 +5595,7 @@ is_gimple_stmt (tree t)
>  
>  
>  /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
> -   a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
> -   DECL_GIMPLE_REG_P set.
> +   a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
>  
>     IMPORTANT NOTE: This promotion is performed by introducing a load of the
>     other, unmodified part of the complex object just before the total store.
> @@ -14992,7 +14969,6 @@ flag_instrument_functions_exclude_p (tree fndecl)
>  void
>  gimplify_function_tree (tree fndecl)
>  {
> -  tree parm, ret;
>    gimple_seq seq;
>    gbind *bind;
>  
> @@ -15007,24 +14983,6 @@ gimplify_function_tree (tree fndecl)
>       if necessary.  */
>    cfun->curr_properties |= PROP_gimple_lva;
>  
> -  for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
> -    {
> -      /* Preliminarily mark non-addressed complex variables as eligible
> -         for promotion to gimple registers.  We'll transform their uses
> -         as we find them.  */
> -      if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
> -        || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
> -          && !TREE_THIS_VOLATILE (parm)
> -          && !needs_to_live_in_memory (parm))
> -        DECL_GIMPLE_REG_P (parm) = 1;
> -    }
> -
> -  ret = DECL_RESULT (fndecl);
> -  if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
> -       || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
> -      && !needs_to_live_in_memory (ret))
> -    DECL_GIMPLE_REG_P (ret) = 1;
> -
>    if (asan_sanitize_use_after_scope () && sanitize_flags_p 
> (SANITIZE_ADDRESS))
>      asan_poisoned_variables = new hash_set<tree> ();
>    bind = gimplify_body (fndecl, true);
> diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
> index 839bd2ef870..978916057f0 100644
> --- a/gcc/ipa-param-manipulation.c
> +++ b/gcc/ipa-param-manipulation.c
> @@ -1028,10 +1028,6 @@ ipa_param_body_adjustments::common_initialization 
> (tree old_fndecl,
>         DECL_CONTEXT (new_parm) = m_fndecl;
>         TREE_USED (new_parm) = 1;
>         DECL_IGNORED_P (new_parm) = 1;
> -       /* We assume all newly created arguments are not addressable.  */
> -       if (TREE_CODE (new_type) == COMPLEX_TYPE
> -           || TREE_CODE (new_type) == VECTOR_TYPE)
> -         DECL_GIMPLE_REG_P (new_parm) = 1;
>         layout_decl (new_parm, 0);
>         m_new_decls.quick_push (new_parm);
>  
> @@ -1888,7 +1884,7 @@ ipa_param_body_adjustments::reset_debug_stmts ()
>         TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
>         TREE_READONLY (copy) = TREE_READONLY (decl);
>         TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
> -       DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
> +       DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
>         DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
>         DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
>         DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
> diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
> index 52ef94718db..c5edb6b00fd 100644
> --- a/gcc/lto-streamer-out.c
> +++ b/gcc/lto-streamer-out.c
> @@ -1067,7 +1067,7 @@ hash_tree (struct streamer_tree_cache_d *cache, 
> hash_map<tree, hashval_t> *map,
>        hstate.add_flag (DECL_USER_ALIGN (t));
>        hstate.add_flag (DECL_PRESERVE_P (t));
>        hstate.add_flag (DECL_EXTERNAL (t));
> -      hstate.add_flag (DECL_GIMPLE_REG_P (t));
> +      hstate.add_flag (DECL_NOT_GIMPLE_REG_P (t));
>        hstate.commit_flag ();
>        hstate.add_int (DECL_ALIGN (t));
>        if (code == LABEL_DECL)
> diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
> index cee5f0e9935..afd2375c516 100644
> --- a/gcc/lto/lto-common.c
> +++ b/gcc/lto/lto-common.c
> @@ -1167,7 +1167,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
>        compare_values (DECL_USER_ALIGN);
>        compare_values (DECL_PRESERVE_P);
>        compare_values (DECL_EXTERNAL);
> -      compare_values (DECL_GIMPLE_REG_P);
> +      compare_values (DECL_NOT_GIMPLE_REG_P);
>        compare_values (DECL_ALIGN);
>        if (code == LABEL_DECL)
>       {
> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> index 88f23e60d34..c8c9db43afb 100644
> --- a/gcc/omp-low.c
> +++ b/gcc/omp-low.c
> @@ -10322,7 +10322,6 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq 
> *dlist, gomp_for *stmt,
>    gimple_seq_add_stmt (body_p, g);
>  
>    tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, 
> false));
> -  DECL_GIMPLE_REG_P (cplx) = 1;
>    g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
>    gimple_call_set_lhs (g, cplx);
>    gimple_seq_add_stmt (body_p, g);
> diff --git a/gcc/sanopt.c b/gcc/sanopt.c
> index 0788eef597e..86180e32c7e 100644
> --- a/gcc/sanopt.c
> +++ b/gcc/sanopt.c
> @@ -1189,7 +1189,6 @@ sanitize_rewrite_addressable_params (function *fun)
>           {
>             /* We need to create a SSA name that will be used for the
>                assignment.  */
> -           DECL_GIMPLE_REG_P (arg) = 1;
>             tree tmp = get_or_create_ssa_default_def (cfun, arg);
>             g = gimple_build_assign (var, tmp);
>             gimple_set_location (g, DECL_SOURCE_LOCATION (arg));
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94703.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr94703.c
> new file mode 100644
> index 00000000000..7209fa0a4d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94703.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-ssa" } */
> +
> +unsigned int set_lowpart (unsigned int const *X)
> +{
> +  unsigned int r = 0;
> +  __builtin_memcpy(&r,X,sizeof (unsigned int) / 2);
> +  return r;
> +}
> +
> +/* { dg-final { scan-tree-dump "No longer having address taken: r" "ssa" } } 
> */
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index e99fb9ff5d1..8b6548f3001 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -577,9 +577,6 @@ make_blocks_1 (gimple_seq seq, basic_block bb)
>             gimple_set_location (s, gimple_location (stmt));
>             gimple_set_block (s, gimple_block (stmt));
>             gimple_set_lhs (stmt, tmp);
> -           if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
> -               || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
> -             DECL_GIMPLE_REG_P (tmp) = 1;
>             gsi_insert_after (&i, s, GSI_SAME_STMT);
>           }
>         start_new_block = true;
> @@ -2983,12 +2980,6 @@ verify_address (tree t, bool verify_addressable)
>       || TREE_CODE (base) == RESULT_DECL))
>      return false;
>  
> -  if (DECL_GIMPLE_REG_P (base))
> -    {
> -      error ("%<DECL_GIMPLE_REG_P%> set on a variable with address taken");
> -      return true;
> -    }
> -
>    if (verify_addressable && !TREE_ADDRESSABLE (base))
>      {
>        error ("address taken but %<TREE_ADDRESSABLE%> bit not set");
> diff --git a/gcc/tree-core.h b/gcc/tree-core.h
> index d84fe959acc..9439f1ffc88 100644
> --- a/gcc/tree-core.h
> +++ b/gcc/tree-core.h
> @@ -1723,7 +1723,7 @@ struct GTY(()) tree_decl_common {
>    unsigned decl_flag_3 : 1;
>    /* Logically, these two would go in a theoretical base shared by var and
>       parm decl. */
> -  unsigned gimple_reg_flag : 1;
> +  unsigned not_gimple_reg_flag : 1;
>    /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE.  */
>    unsigned decl_by_reference_flag : 1;
>    /* In a VAR_DECL and PARM_DECL, this is DECL_READ_P.  */
> diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> index 2a409dcaffe..10ef2e3157c 100644
> --- a/gcc/tree-eh.c
> +++ b/gcc/tree-eh.c
> @@ -2072,9 +2072,6 @@ lower_eh_constructs_2 (struct leh_state *state, 
> gimple_stmt_iterator *gsi)
>         gimple_set_location (s, gimple_location (stmt));
>         gimple_set_block (s, gimple_block (stmt));
>         gimple_set_lhs (stmt, tmp);
> -       if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
> -           || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
> -         DECL_GIMPLE_REG_P (tmp) = 1;
>         gsi_insert_after (gsi, s, GSI_SAME_STMT);
>       }
>        /* Look for things that can throw exceptions, and record them.  */
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 69ca8e99109..80f35ef9350 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -3670,11 +3670,9 @@ declare_return_variable (copy_body_data *id, tree 
> return_slot, tree modify_dest,
>         if (TREE_ADDRESSABLE (result))
>           mark_addressable (var);
>       }
> -      if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
> -           || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
> -       && !DECL_GIMPLE_REG_P (result)
> +      if (DECL_NOT_GIMPLE_REG_P (result)
>         && DECL_P (var))
> -     DECL_GIMPLE_REG_P (var) = 0;
> +     DECL_NOT_GIMPLE_REG_P (var) = 1;
>  
>        if (!useless_type_conversion_p (callee_type, caller_type))
>       var = build1 (VIEW_CONVERT_EXPR, callee_type, var);
> @@ -3717,10 +3715,8 @@ declare_return_variable (copy_body_data *id, tree 
> return_slot, tree modify_dest,
>           use_it = false;
>         else if (is_global_var (base_m))
>           use_it = false;
> -       else if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
> -                 || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
> -                && !DECL_GIMPLE_REG_P (result)
> -                && DECL_GIMPLE_REG_P (base_m))
> +       else if (DECL_NOT_GIMPLE_REG_P (result)
> +                && !DECL_NOT_GIMPLE_REG_P (base_m))
>           use_it = false;
>         else if (!TREE_ADDRESSABLE (base_m))
>           use_it = true;
> @@ -3760,11 +3756,8 @@ declare_return_variable (copy_body_data *id, tree 
> return_slot, tree modify_dest,
>            to using a MEM_REF to not leak invalid GIMPLE to the following
>            passes.  */
>         /* Prevent var from being written into SSA form.  */
> -       if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
> -           || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
> -         DECL_GIMPLE_REG_P (var) = false;
> -       else if (is_gimple_reg_type (TREE_TYPE (var)))
> -         TREE_ADDRESSABLE (var) = true;
> +       if (is_gimple_reg_type (TREE_TYPE (var)))
> +         DECL_NOT_GIMPLE_REG_P (var) = true;
>         use = fold_build2 (MEM_REF, caller_type,
>                            build_fold_addr_expr (var),
>                            build_int_cst (ptr_type_node, 0));
> @@ -5930,7 +5923,7 @@ copy_decl_to_var (tree decl, copy_body_data *id)
>    TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
>    TREE_READONLY (copy) = TREE_READONLY (decl);
>    TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
> -  DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
> +  DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
>    DECL_BY_REFERENCE (copy) = DECL_BY_REFERENCE (decl);
>  
>    return copy_decl_for_dup_finish (id, decl, copy);
> @@ -5960,7 +5953,12 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
>    if (!DECL_BY_REFERENCE (decl))
>      {
>        TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
> -      DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
> +      DECL_NOT_GIMPLE_REG_P (copy)
> +     = (DECL_NOT_GIMPLE_REG_P (decl)
> +        /* RESULT_DECLs are treated special by needs_to_live_in_memory,
> +           mirror that to the created VAR_DECL.  */
> +        || (TREE_CODE (decl) == RESULT_DECL
> +            && aggregate_value_p (decl, id->src_fn)));
>      }
>  
>    return copy_decl_for_dup_finish (id, decl, copy);
> diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
> index 6528acac31a..c24931effac 100644
> --- a/gcc/tree-into-ssa.c
> +++ b/gcc/tree-into-ssa.c
> @@ -2430,8 +2430,7 @@ pass_build_ssa::execute (function *fun)
>    basic_block bb;
>  
>    /* Increase the set of variables we can rewrite into SSA form
> -     by clearing TREE_ADDRESSABLE and setting DECL_GIMPLE_REG_P
> -     and transform the IL to support this.  */
> +     by clearing TREE_ADDRESSABLE and transform the IL to support this.  */
>    if (optimize)
>      execute_update_addresses_taken ();
>  
> diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
> index 6f696da5332..de168df70a1 100644
> --- a/gcc/tree-nested.c
> +++ b/gcc/tree-nested.c
> @@ -160,9 +160,6 @@ create_tmp_var_for (struct nesting_info *info, tree type, 
> const char *prefix)
>    DECL_CONTEXT (tmp_var) = info->context;
>    DECL_CHAIN (tmp_var) = info->new_local_var_chain;
>    DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
> -  if (TREE_CODE (type) == COMPLEX_TYPE
> -      || TREE_CODE (type) == VECTOR_TYPE)
> -    DECL_GIMPLE_REG_P (tmp_var) = 1;
>  
>    info->new_local_var_chain = tmp_var;
>  
> diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
> index d9250d36c72..8cd50234a1c 100644
> --- a/gcc/tree-parloops.c
> +++ b/gcc/tree-parloops.c
> @@ -1574,7 +1574,7 @@ separate_decls_in_region_name (tree name, 
> name_to_copy_table_type *name_copies,
>    if (!dslot->to)
>      {
>        var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
> -      DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
> +      DECL_NOT_GIMPLE_REG_P (var_copy) = DECL_NOT_GIMPLE_REG_P (var);
>        dslot->uid = uid;
>        dslot->to = var_copy;
>  
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index 227bde06257..4793b48f32c 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -2168,15 +2168,9 @@ create_access_replacement (struct access *access, tree 
> reg_type = NULL_TREE)
>         variant.  This avoids issues with weirdo ABIs like AAPCS.  */
>      repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
>                                                TYPE_QUALS (type)), "SR");
> -  if (TREE_CODE (type) == COMPLEX_TYPE
> -      || TREE_CODE (type) == VECTOR_TYPE)
> -    {
> -      if (!access->grp_partial_lhs)
> -     DECL_GIMPLE_REG_P (repl) = 1;
> -    }
> -  else if (access->grp_partial_lhs
> -        && is_gimple_reg_type (type))
> -    TREE_ADDRESSABLE (repl) = 1;
> +  if (access->grp_partial_lhs
> +      && is_gimple_reg_type (type))
> +    DECL_NOT_GIMPLE_REG_P (repl) = 1;
>  
>    DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
>    DECL_ARTIFICIAL (repl) = 1;
> diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
> index 1a50045b367..b68da91723b 100644
> --- a/gcc/tree-ssa-forwprop.c
> +++ b/gcc/tree-ssa-forwprop.c
> @@ -2945,6 +2945,8 @@ pass_forwprop::execute (function *fun)
>                     != TARGET_MEM_REF))
>               {
>                 tree use_lhs = gimple_assign_lhs (use_stmt);
> +               if (auto_var_p (use_lhs))
> +                 DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
>                 tree new_lhs = build1 (REALPART_EXPR,
>                                        TREE_TYPE (TREE_TYPE (use_lhs)),
>                                        unshare_expr (use_lhs));
> @@ -2996,6 +2998,9 @@ pass_forwprop::execute (function *fun)
>                   = tree_to_uhwi (TYPE_SIZE (elt_t));
>                 unsigned HOST_WIDE_INT n
>                   = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (rhs)));
> +               tree use_lhs = gimple_assign_lhs (use_stmt);
> +               if (auto_var_p (use_lhs))
> +                 DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
>                 for (unsigned HOST_WIDE_INT bi = 0; bi < n; bi += elt_w)
>                   {
>                     unsigned HOST_WIDE_INT ci = bi / elt_w;
> @@ -3004,7 +3009,6 @@ pass_forwprop::execute (function *fun)
>                       new_rhs = CONSTRUCTOR_ELT (rhs, ci)->value;
>                     else
>                       new_rhs = build_zero_cst (elt_t);
> -                   tree use_lhs = gimple_assign_lhs (use_stmt);
>                     tree new_lhs = build3 (BIT_FIELD_REF,
>                                            elt_t,
>                                            unshare_expr (use_lhs),
> diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
> index 4f4ab2b8992..c47b963bbb2 100644
> --- a/gcc/tree-ssa.c
> +++ b/gcc/tree-ssa.c
> @@ -1583,8 +1583,8 @@ non_rewritable_lvalue_p (tree lhs)
>    return true;
>  }
>  
> -/* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
> -   mark the variable VAR for conversion into SSA.  Return true when updating
> +/* When possible, clear TREE_ADDRESSABLE bit, set or clear 
> DECL_NOT_GIMPLE_REG_P
> +   and mark the variable VAR for conversion into SSA.  Return true when 
> updating
>     stmts is required.  */
>  
>  static void
> @@ -1597,24 +1597,11 @@ maybe_optimize_var (tree var, bitmap addresses_taken, 
> bitmap not_reg_needs,
>        || bitmap_bit_p (addresses_taken, DECL_UID (var)))
>      return;
>  
> -  if (TREE_ADDRESSABLE (var)
> -      /* Do not change TREE_ADDRESSABLE if we need to preserve var as
> -      a non-register.  Otherwise we are confused and forget to
> -      add virtual operands for it.  */
> -      && (!is_gimple_reg_type (TREE_TYPE (var))
> -       || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
> -       || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
> -       || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
> +  bool maybe_reg = false;
> +  if (TREE_ADDRESSABLE (var))
>      {
>        TREE_ADDRESSABLE (var) = 0;
> -      /* If we cleared TREE_ADDRESSABLE make sure DECL_GIMPLE_REG_P
> -         is unset if we cannot rewrite the var into SSA.  */
> -      if ((TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
> -        || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
> -       && bitmap_bit_p (not_reg_needs, DECL_UID (var)))
> -     DECL_GIMPLE_REG_P (var) = 0;
> -      if (is_gimple_reg (var))
> -     bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
> +      maybe_reg = true;
>        if (dump_file)
>       {
>         fprintf (dump_file, "No longer having address taken: ");
> @@ -1623,20 +1610,36 @@ maybe_optimize_var (tree var, bitmap addresses_taken, 
> bitmap not_reg_needs,
>       }
>      }
>  
> -  if (!DECL_GIMPLE_REG_P (var)
> -      && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
> -      && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
> -       || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
> -      && !TREE_THIS_VOLATILE (var)
> -      && (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
> +  /* For register type decls if we do not have any partial defs
> +     we cannot express in SSA form mark them as DECL_NOT_GIMPLE_REG_P
> +     as to avoid SSA rewrite.  For the others go ahead and mark
> +     them for renaming.  */
> +  if (is_gimple_reg_type (TREE_TYPE (var)))
>      {
> -      DECL_GIMPLE_REG_P (var) = 1;
> -      bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
> -      if (dump_file)
> +      if (bitmap_bit_p (not_reg_needs, DECL_UID (var)))
>       {
> -       fprintf (dump_file, "Now a gimple register: ");
> -       print_generic_expr (dump_file, var);
> -       fprintf (dump_file, "\n");
> +       DECL_NOT_GIMPLE_REG_P (var) = 1;
> +       if (dump_file)
> +         {
> +           fprintf (dump_file, "Has partial defs: ");
> +           print_generic_expr (dump_file, var);
> +           fprintf (dump_file, "\n");
> +         }
> +     }
> +      else if (DECL_NOT_GIMPLE_REG_P (var))
> +     {
> +       maybe_reg = true;
> +       DECL_NOT_GIMPLE_REG_P (var) = 0;
> +     }
> +      if (maybe_reg && is_gimple_reg (var))
> +     {
> +       if (dump_file)
> +         {
> +           fprintf (dump_file, "Now a gimple register: ");
> +           print_generic_expr (dump_file, var);
> +           fprintf (dump_file, "\n");
> +         }
> +       bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
>       }
>      }
>  }
> @@ -1669,7 +1672,8 @@ is_asan_mark_p (gimple *stmt)
>    return false;
>  }
>  
> -/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables.  */
> +/* Compute TREE_ADDRESSABLE and whether we have unhandled partial defs
> +   for local variables.  */
>  
>  void
>  execute_update_addresses_taken (void)
> diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
> index 0bfc272d076..79b97ffa9a3 100644
> --- a/gcc/tree-streamer-in.c
> +++ b/gcc/tree-streamer-in.c
> @@ -236,7 +236,7 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, 
> tree expr)
>    DECL_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
>    DECL_PRESERVE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
>    DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  DECL_NOT_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
>    SET_DECL_ALIGN (expr, (unsigned) bp_unpack_var_len_unsigned (bp));
>  #ifdef ACCEL_COMPILER
>    if (DECL_ALIGN (expr) > targetm.absolute_biggest_alignment)
> diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
> index 5bbcebba87e..3ab8c889a23 100644
> --- a/gcc/tree-streamer-out.c
> +++ b/gcc/tree-streamer-out.c
> @@ -201,7 +201,7 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, 
> tree expr)
>    bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
>    bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
>    bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
> -  bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
> +  bp_pack_value (bp, DECL_NOT_GIMPLE_REG_P (expr), 1);
>    bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));
>  
>    if (TREE_CODE (expr) == LABEL_DECL)
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 1c28785d411..66042c14290 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -2646,8 +2646,8 @@ extern machine_mode vector_type_mode (const_tree);
>     they are killing assignments.  Thus the variable may now
>     be treated as a GIMPLE register, and use real instead of
>     virtual ops in SSA form.  */
> -#define DECL_GIMPLE_REG_P(DECL) \
> -  DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
> +#define DECL_NOT_GIMPLE_REG_P(DECL) \
> +  DECL_COMMON_CHECK (DECL)->decl_common.not_gimple_reg_flag
>  
>  extern tree decl_value_expr_lookup (tree);
>  extern void decl_value_expr_insert (tree, tree);
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to