Hi,

this patch is new, it addresses a problem I outlined in
https://gcc.gnu.org/ml/gcc-patches/2016-01/msg00424.html and it is an
implementation of Jakub's suggestion in
https://gcc.gnu.org/ml/gcc-patches/2016-01/msg00614.html

I have refrained from bigger changes in struct copy_body_data in
tree-inline.h as I think that such a cleanup should be done
separately, but the structure could probably use some field-re
ordering to remove padding.

I hope I have grasped it correctly and that the patch is OK for trunk.

Thanks,

Martin


2016-01-13  Martin Jambor  <mjam...@suse.cz>

        * tree-inline.c (remap_decl): Use existing dclarations if
        remapping a type and prevent_decl_creation_for_types.
        (replace_locals_stmt): Do an initial remapping of non-VLA typed
        decls first.  Do real remapping with
        prevent_decl_creation_for_types set.
        * tree-inline.h (copy_body_data): New field
        prevent_decl_creation_for_types, moved remap_var_for_cilk to avoid
        padding.

diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6bf2467..7b34288 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -340,8 +340,22 @@ remap_decl (tree decl, copy_body_data *id)
       return decl;
     }
 
-  /* If we didn't already have an equivalent for this declaration,
-     create one now.  */
+  /* When remapping a type within copy_gimple_seq_and_replace_locals, all
+     necessary DECLs have already been remapped and we do not want to duplicate
+     a decl coming from outside of the sequence we are copying.  */
+  if (!n
+      && id->prevent_decl_creation_for_types
+      && id->remapping_type_depth > 0
+      && (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL))
+    {
+      if (id->do_not_unshare)
+       return decl;
+      else
+       return unshare_expr (decl);
+    }
+
+  /* If we didn't already have an equivalent for this declaration, create one
+     now.  */
   if (!n)
     {
       /* Make a copy of the variable or label.  */
@@ -5225,8 +5239,19 @@ replace_locals_stmt (gimple_stmt_iterator *gsip,
       /* This will remap a lot of the same decls again, but this should be
         harmless.  */
       if (gimple_bind_vars (stmt))
-       gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt),
-                                                NULL, id));
+       {
+         tree old_var, decls = gimple_bind_vars (stmt);
+
+         for (old_var = decls; old_var; old_var = DECL_CHAIN (old_var))
+           if (!can_be_nonlocal (old_var, id)
+               && ! variably_modified_type_p (TREE_TYPE (old_var), id->src_fn))
+             remap_decl (old_var, id);
+
+         gcc_checking_assert (!id->prevent_decl_creation_for_types);
+         id->prevent_decl_creation_for_types = true;
+         gimple_bind_set_vars (stmt, remap_decls (decls, NULL, id));
+         id->prevent_decl_creation_for_types = false;
+       }
     }
 
   /* Keep iterating.  */
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index d3e5229..4cc1f19 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -140,14 +140,17 @@ struct copy_body_data
      the originals have been mapped to a value rather than to a
      variable.  */
   hash_map<tree, tree> *debug_map;
- 
-  /* Cilk keywords currently need to replace some variables that
-     ordinary nested functions do not.  */ 
-  bool remap_var_for_cilk;
 
   /* A map from the inlined functions dependence info cliques to
      equivalents in the function into which it is being inlined.  */
   hash_map<dependence_hash, unsigned short> *dependence_map;
+
+  /* Cilk keywords currently need to replace some variables that
+     ordinary nested functions do not.  */
+  bool remap_var_for_cilk;
+
+  /* Do not create new declarations when within type remapping.  */
+  bool prevent_decl_creation_for_types;
 };
 
 /* Weights of constructions for estimate_num_insns.  */

Reply via email to