re PR tree-optimization/31081 (Inliner messes up SSA for abnormals)
authorJan Hubicka <jh@suse.cz>
Thu, 3 Jan 2008 21:23:26 +0000 (22:23 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 3 Jan 2008 21:23:26 +0000 (21:23 +0000)
PR tree-optimization/31081
* tree-inline.c (remap_ssa_name): Initialize uninitialized SSA vars to
0 when inlining and not inlining to first basic block.
(remap_decl): When var is initialized to 0, don't set default_def.
(expand_call_inline): Set entry_bb.
* tree-inline.h (copy_body_data): Add entry_bb.

From-SVN: r131306

gcc/ChangeLog
gcc/tree-inline.c
gcc/tree-inline.h

index 952d851121da217878156ecbf7251507a080aa79..08cc05c39c6c6b3cea36459dd050dc969fe5c1e6 100644 (file)
@@ -1,3 +1,12 @@
+2008-01-03  Jan Hubicka  <jh@suse.cz>
+
+       PR tree-optimization/31081
+       * tree-inline.c (remap_ssa_name): Initialize uninitialized SSA vars to
+       0 when inlining and not inlining to first basic block.
+       (remap_decl): When var is initialized to 0, don't set default_def.
+       (expand_call_inline): Set entry_bb.
+       * tree-inline.h (copy_body_data): Add entry_bb.
+
 2008-01-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/34619
index ebb413ae9bc760fd497d3f0592bf9b22e89c409e..65ffd91cb2a309bacbdfe7bb67d85a6e6927af27 100644 (file)
@@ -186,15 +186,42 @@ remap_ssa_name (tree name, copy_body_data *id)
     {
       new = make_ssa_name (new, NULL);
       insert_decl_map (id, name, new);
-      if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (name)))
-       {
-         SSA_NAME_DEF_STMT (new) = build_empty_stmt ();
-         if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name)) == name)
-           set_default_def (SSA_NAME_VAR (new), new);
-       }
       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new)
        = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name);
       TREE_TYPE (new) = TREE_TYPE (SSA_NAME_VAR (new));
+      if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (name)))
+       {
+         /* By inlining function having uninitialized variable, we might
+            extend the lifetime (variable might get reused).  This cause
+            ICE in the case we end up extending lifetime of SSA name across
+            abnormal edge, but also increase register presure.
+
+            We simply initialize all uninitialized vars by 0 except for case
+            we are inlining to very first BB.  We can avoid this for all
+            BBs that are not withing strongly connected regions of the CFG,
+            but this is bit expensive to test.
+          */
+         if (id->entry_bb && is_gimple_reg (SSA_NAME_VAR (name))
+             && TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL
+             && (id->entry_bb != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)
+                 || EDGE_COUNT (id->entry_bb->preds) != 1))
+           {
+             block_stmt_iterator bsi = bsi_last (id->entry_bb);
+             tree init_stmt
+                 = build_gimple_modify_stmt (new,
+                                             fold_convert (TREE_TYPE (new),
+                                                           integer_zero_node));
+             bsi_insert_after (&bsi, init_stmt, BSI_NEW_STMT);
+             SSA_NAME_DEF_STMT (new) = init_stmt;
+             SSA_NAME_IS_DEFAULT_DEF (new) = 0;
+           }
+         else
+           {
+             SSA_NAME_DEF_STMT (new) = build_empty_stmt ();
+             if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name)) == name)
+               set_default_def (SSA_NAME_VAR (new), new);
+           }
+       }
     }
   else
     insert_decl_map (id, name, new);
@@ -259,7 +286,8 @@ remap_decl (tree decl, copy_body_data *id)
              tree map = remap_ssa_name (def, id);
              /* Watch out RESULT_DECLs whose SSA names map directly
                 to them.  */
-             if (TREE_CODE (map) == SSA_NAME)
+             if (TREE_CODE (map) == SSA_NAME
+                 && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (map)))
                set_default_def (t, map);
            }
          add_referenced_var (t);
@@ -2698,6 +2726,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
 
   gcc_assert (!id->src_cfun->after_inlining);
 
+  id->entry_bb = bb;
   initialize_inlined_parameters (id, t, fn, bb);
 
   if (DECL_INITIAL (fn))
index 33eb908b7cde9b410bc61be683e08fe46af7674b..dbb78d0b4ccb52c8ecea1b5d0ec9984a92514b34 100644 (file)
@@ -97,6 +97,9 @@ typedef struct copy_body_data
 
   /* Statements that might be possibly folded.  */
   struct pointer_set_t *statements_to_fold;
+
+  /* Entry basic block to currently copied body.  */
+  struct basic_block_def *entry_bb;
 } copy_body_data;
 
 /* Weights of constructions for estimate_num_insns.  */