]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-cp.c (constant_val_insert): Remove.
authorJan Hubicka <jh@suse.cz>
Sat, 23 Aug 2008 22:25:20 +0000 (00:25 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 23 Aug 2008 22:25:20 +0000 (22:25 +0000)
* ipa-cp.c (constant_val_insert): Remove.
(ipcp_propagate_one_const): Remove.
(ipcp_create_replace_map): Always insert replacements to the map.
(ipcp_insert_stage): Do not try to insert statements by hand.
* tree-inline.c (insert_init_stmt): Break out from ...
(setup_one_parameter): ... here; allow NULL BB pointer.
(tree_function_versioning): Use setup_one_parameter to process
replacement map.

From-SVN: r139525

gcc/ChangeLog
gcc/ipa-cp.c
gcc/opts.c
gcc/tree-inline.c

index 33605b99b5ba47dc40d86b56a639d154fd9c7840..6068239dde444c685d6cfe40385b5f6b908c5d23 100644 (file)
@@ -1,3 +1,14 @@
+2008-08-23  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-cp.c (constant_val_insert): Remove.
+       (ipcp_propagate_one_const): Remove.
+       (ipcp_create_replace_map): Always insert replacements to the map.
+       (ipcp_insert_stage): Do not try to insert statements by hand.
+       * tree-inline.c (insert_init_stmt): Break out from ...
+       (setup_one_parameter): ... here; allow NULL BB pointer.
+       (tree_function_versioning): Use setup_one_parameter to process
+       replacement map.
+
 2008-08-23  Jan Hubicka  <jh@suse.cz>
 
        * tree.c (decl_address_ip_invariant_p): New function.
index 868a57caec34768419e621a4a6575eab3d3d1bf1..78a24bcb71750e9789357186f7f170ebdc9e4061 100644 (file)
@@ -369,20 +369,6 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
     ipcp_get_ith_lattice (info, i)->type = IPA_TOP;
 }
 
-/* Create a new assignment statement and make it the first statement in the
-   function.  PARM1 is the lhs of the assignment and VAL is the rhs. */
-static void
-constant_val_insert (tree parm1 ATTRIBUTE_UNUSED, tree val ATTRIBUTE_UNUSED)
-{
-  gimple init_stmt = NULL;
-  edge e_step;
-
-  init_stmt = gimple_build_assign (parm1, val);
-  gcc_assert (init_stmt);
-  e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
-  gsi_insert_on_edge_immediate (e_step, init_stmt);
-}
-
 /* build INTEGER_CST tree with type TREE_TYPE and value according to LAT.
    Return the tree.  */
 static tree
@@ -403,21 +389,6 @@ build_const_val (struct ipcp_lattice *lat, tree tree_type)
   return val;
 }
 
-/* Build the tree representing the constant and call constant_val_insert().  */
-static void
-ipcp_propagate_one_const (struct cgraph_node *node, int param,
-                         struct ipcp_lattice *lat)
-{
-  tree const_val;
-  tree parm_tree;
-
-  if (dump_file)
-    fprintf (dump_file, "propagating const to %s\n", cgraph_node_name (node));
-  parm_tree = ipa_get_ith_param (IPA_NODE_REF (node), param);
-  const_val = build_const_val (lat, TREE_TYPE (parm_tree));
-  constant_val_insert (parm_tree, const_val);
-}
-
 /* Compute the proper scale for NODE.  It is the ratio between the number of
    direct calls (represented on the incoming cgraph_edges) and sum of all
    invocations of NODE (represented as count in cgraph_node).  */
@@ -755,33 +726,19 @@ ipcp_print_profile_data (FILE * f)
    PARM_TREE is the formal parameter found to be constant.  LAT represents the
    constant.  */
 static struct ipa_replace_map *
-ipcp_create_replace_map (struct function *func, tree parm_tree,
-                        struct ipcp_lattice *lat)
+ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat)
 {
   struct ipa_replace_map *replace_map;
   tree const_val;
 
   replace_map = XCNEW (struct ipa_replace_map);
-  if (is_gimple_reg (parm_tree)
-      && gimple_default_def (func, parm_tree)
-      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func,
-                                                                parm_tree)))
-    {
-      if (dump_file)
-       fprintf (dump_file, "replacing param with const\n");
-      const_val = build_const_val (lat, TREE_TYPE (parm_tree));
-      replace_map->old_tree =gimple_default_def (func, parm_tree);
-      replace_map->new_tree = const_val;
-      replace_map->replace_p = true;
-      replace_map->ref_p = false;
-    }
-  else
-    {
-      replace_map->old_tree = NULL;
-      replace_map->new_tree = NULL;
-      replace_map->replace_p = false;
-      replace_map->ref_p = false;
-    }
+  if (dump_file)
+    fprintf (dump_file, "replacing param with const\n");
+  const_val = build_const_val (lat, TREE_TYPE (parm_tree));
+  replace_map->old_tree = parm_tree;
+  replace_map->new_tree = const_val;
+  replace_map->replace_p = true;
+  replace_map->ref_p = false;
 
   return replace_map;
 }
@@ -939,8 +896,7 @@ ipcp_insert_stage (void)
            {
              parm_tree = ipa_get_ith_param (info, i);
              replace_param =
-               ipcp_create_replace_map (DECL_STRUCT_FUNCTION (node->decl),
-                                        parm_tree, lat);
+               ipcp_create_replace_map (parm_tree, lat);
              VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
            }
        }
@@ -963,36 +919,8 @@ ipcp_insert_stage (void)
        fprintf (dump_file, "versioned function %s\n",
                 cgraph_node_name (node));
       ipcp_init_cloned_node (node, node1);
-      if (const_param > 0)
-       {
-         push_cfun (DECL_STRUCT_FUNCTION (node1->decl));
-         gimple_register_cfg_hooks ();
-         current_function_decl = node1->decl;
-
-         for (i = 0; i < count; i++)
-           {
-             struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
-             if (ipcp_lat_is_insertable (lat))
-               {
-                 parm_tree = ipa_get_ith_param (info, i);
-                 if (!is_gimple_reg (parm_tree))
-                   ipcp_propagate_one_const (node1, i, lat);
-               }
-           }
-         if (gimple_in_ssa_p (cfun))
-           {
-             update_ssa (TODO_update_ssa);
-#ifdef   ENABLE_CHECKING
-             verify_ssa (true);
-#endif
-           }
-         free_dominance_info (CDI_DOMINATORS);
-         free_dominance_info (CDI_POST_DOMINATORS);
-         pop_cfun ();
-         current_function_decl = NULL;
-         /* We've possibly introduced direct calls.  */
-         ipcp_update_cloned_node (node1);
-       }
+      /* We've possibly introduced direct calls.  */
+      ipcp_update_cloned_node (node1);
 
       if (dump_file)
        dump_function_to_file (node1->decl, dump_file, dump_flags);
index 1de217eb3af726216fcee6238b06bbe4820b9e0f..2f5994181b1a91e244b6c6830bd42a52142b50d0 100644 (file)
@@ -951,6 +951,7 @@ decode_options (unsigned int argc, const char **argv)
   flag_tree_builtin_call_dce = opt2;
   flag_tree_pre = opt2;
       flag_tree_switch_conversion = 1;
+      flag_ipa_cp = opt2;
 
       /* Allow more virtual operators to increase alias precision.  */
 
index ab994379f1e5a72495d026ee98b5e9b999fa108f..7be46cfe7c1e1bb25a958fa966a7c837c8861ea1 100644 (file)
@@ -1856,10 +1856,52 @@ self_inlining_addr_expr (tree value, tree fn)
 }
 
 static void
+insert_init_stmt (basic_block bb, gimple init_stmt)
+{
+  gimple_stmt_iterator si = gsi_last_bb (bb);
+  gimple_stmt_iterator i;
+  gimple_seq seq = gimple_seq_alloc ();
+  struct gimplify_ctx gctx;
+
+  push_gimplify_context (&gctx);
+
+  i = gsi_start (seq);
+  gimple_regimplify_operands (init_stmt, &i);
+
+  if (gimple_in_ssa_p (cfun)
+      && init_stmt
+      && !gimple_seq_empty_p (seq))
+    {
+      /* The replacement can expose previously unreferenced
+        variables.  */
+      for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+       find_new_referenced_vars (gsi_stmt (i));
+
+      /* Insert the gimplified sequence needed for INIT_STMT
+        after SI.  INIT_STMT will be inserted after SEQ.  */
+      gsi_insert_seq_after (&si, seq, GSI_NEW_STMT);
+     }
+
+  pop_gimplify_context (NULL);
+
+  /* If VAR represents a zero-sized variable, it's possible that the
+     assignment statement may result in no gimple statements.  */
+  if (init_stmt)
+    gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
+
+  if (gimple_in_ssa_p (cfun))
+    for (;!gsi_end_p (si); gsi_next (&si))
+      mark_symbols_for_renaming (gsi_stmt (si));
+}
+
+/* Initialize parameter P with VALUE.  If needed, produce init statement
+   at the end of BB.  When BB is NULL, we return init statement to be
+   output later.  */
+static gimple
 setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
                     basic_block bb, tree *vars)
 {
-  gimple init_stmt;
+  gimple init_stmt = NULL;
   tree var;
   tree rhs = value;
   tree def = (gimple_in_ssa_p (cfun)
@@ -1902,7 +1944,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
          && ! self_inlining_addr_expr (value, fn))
        {
          insert_decl_map (id, p, value);
-         return;
+         return NULL;
        }
     }
 
@@ -1960,7 +2002,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def))
     {
       insert_decl_map (id, def, rhs);
-      return;
+      return NULL;
     }
 
   /* If the value of argument is never used, don't care about initializing
@@ -1968,19 +2010,17 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
   if (gimple_in_ssa_p (cfun) && !def && is_gimple_reg (p))
     {
       gcc_assert (!value || !TREE_SIDE_EFFECTS (value));
-      return;
+      return NULL;
     }
 
   /* Initialize this VAR_DECL from the equivalent argument.  Convert
      the argument to the proper type in case it was promoted.  */
   if (value)
     {
-      gimple_stmt_iterator si = gsi_last_bb (bb);
-
       if (rhs == error_mark_node)
        {
          insert_decl_map (id, p, var);
-         return;
+         return NULL;
        }
 
       STRIP_USELESS_TYPE_CONVERSION (rhs);
@@ -1997,51 +2037,10 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
       else
         init_stmt = gimple_build_assign (var, rhs);
 
-      /* If we did not create a gimple value and we did not create a gimple
-        cast of a gimple value, then we will need to gimplify INIT_STMT
-        at the end.  Note that is_gimple_cast only checks the outer
-        tree code, not its operand.  Thus the explicit check that its
-        operand is a gimple value.  */
-      if ((!is_gimple_val (rhs)
-         && (!is_gimple_cast (rhs)
-             || !is_gimple_val (TREE_OPERAND (rhs, 0))))
-         || !is_gimple_reg (var))
-       {
-         gimple_stmt_iterator i;
-         gimple_seq seq = gimple_seq_alloc ();
-          struct gimplify_ctx gctx;
-
-         push_gimplify_context (&gctx);
-
-         i = gsi_start (seq);
-         gimple_regimplify_operands (init_stmt, &i);
-
-         if (gimple_in_ssa_p (cfun)
-              && init_stmt
-             && !gimple_seq_empty_p (seq))
-           {
-             /* The replacement can expose previously unreferenced
-                variables.  */
-             for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
-               find_new_referenced_vars (gsi_stmt (i));
-
-             /* Insert the gimplified sequence needed for INIT_STMT
-                after SI.  INIT_STMT will be inserted after SEQ.  */
-             gsi_insert_seq_after (&si, seq, GSI_NEW_STMT);
-            }
-
-         pop_gimplify_context (NULL);
-       }
-
-      /* If VAR represents a zero-sized variable, it's possible that the
-        assignment statement may result in no gimple statements.  */
-      if (init_stmt)
-        gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
-
-      if (gimple_in_ssa_p (cfun))
-       for (;!gsi_end_p (si); gsi_next (&si))
-         mark_symbols_for_renaming (gsi_stmt (si));
+      if (bb && init_stmt)
+        insert_init_stmt (bb, init_stmt);
     }
+  return init_stmt;
 }
 
 /* Generate code to initialize the parameters of the function at the
@@ -4149,8 +4148,11 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
   unsigned i;
   struct ipa_replace_map *replace_info;
   basic_block old_entry_block;
+  VEC (gimple, heap) *init_stmts = VEC_alloc (gimple, heap, 10);
+
   tree t_step;
   tree old_current_function_decl = current_function_decl;
+  tree vars = NULL_TREE;
 
   gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL
              && TREE_CODE (new_decl) == FUNCTION_DECL);
@@ -4207,10 +4209,16 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
     DECL_ARGUMENTS (new_decl) =
       copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id);
   
+  DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
+  
+  /* Renumber the lexical scoping (non-code) blocks consecutively.  */
+  number_blocks (id.dst_fn);
+  
   /* If there's a tree_map, prepare for substitution.  */
   if (tree_map)
     for (i = 0; i < VARRAY_ACTIVE_SIZE (tree_map); i++)
       {
+       gimple init;
        replace_info
          = (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i);
        if (replace_info->replace_p)
@@ -4223,16 +4231,17 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
                if (TREE_CODE (op) == VAR_DECL)
                  add_referenced_var (op);
              }
-           insert_decl_map (&id, replace_info->old_tree,
-                            replace_info->new_tree);
+           gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL);
+           init = setup_one_parameter (&id, replace_info->old_tree,
+                                       replace_info->new_tree, id.src_fn,
+                                       NULL,
+                                       &vars);
+           if (init)
+             VEC_safe_push (gimple, heap, init_stmts, init);
          }
       }
   
-  DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
-  
-  /* Renumber the lexical scoping (non-code) blocks consecutively.  */
-  number_blocks (id.dst_fn);
-  
+  declare_inline_vars (DECL_INITIAL (new_decl), vars);
   if (DECL_STRUCT_FUNCTION (old_decl)->local_decls != NULL_TREE)
     /* Add local vars.  */
     for (t_step = DECL_STRUCT_FUNCTION (old_decl)->local_decls;
@@ -4260,6 +4269,13 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
   number_blocks (new_decl);
 
+  if (VEC_length (gimple, init_stmts))
+    {
+      basic_block bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
+      while (VEC_length (gimple, init_stmts))
+       insert_init_stmt (bb, VEC_pop (gimple, init_stmts));
+    }
+
   /* Clean up.  */
   pointer_map_destroy (id.decl_map);
   if (!update_clones)
@@ -4284,6 +4300,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
     }
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
+  VEC_free (gimple, heap, init_stmts);
   pop_cfun ();
   current_function_decl = old_current_function_decl;
   gcc_assert (!current_function_decl