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.

Thanks,
Richard.

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.

        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/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                       | 23 ++++--------
 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 +-
 26 files changed, 84 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/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..b4a69c1ad48 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,7 @@ 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);
     }
 
   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);
-- 
2.13.7

Reply via email to