Makefile.in: Add ipcp.c, ipa-prop.h, ipa-prop.c.
authorRazya Ladelsky <razya@il.ibm.com>
Mon, 1 Aug 2005 07:42:09 +0000 (07:42 +0000)
committerRazya Ladelsky <razya@gcc.gnu.org>
Mon, 1 Aug 2005 07:42:09 +0000 (07:42 +0000)
* Makefile.in: Add ipcp.c, ipa-prop.h, ipa-prop.c. Remove integrate.h
dependency from tree-inline.o.
Add ipa-prop.h dependency to tree-inline.o and cgraphunit.o.
        * common.opt: Add ipa-cp flag.
        * timevar.def: Add IPCP optimization.
        * tree-optimize.c (init_tree_optimization_passes): Schedule
pass_ipa_cp.
* tree-pass.h (pass_ipa_cp): Declare.
        * cgraph.h (update_call_expr, cgraph_copy_node_for_versioning,
        cgraph_function_versioning): New declarations.
* cgraphunit.c: Add include to ipa-prop.h.
        (update_call_expr, cgraph_copy_node_for_versioning,
cgraph_function_versioning): New functions.
        * integrate.c (copy_decl_for_inlining): Remove.
        * tree-inline.c: Remove include to integrate.h, Add include ipa-prop.h.
        (struct inline_data): Add versioning_p, ipa_info, new fields.
        (remap_decl, mark_local_for_remap_r, setup_one_parameter,
declare_return_variable): Replace calls to copy_decl_for_inlining with
        copy_decl_for_dup.
        (copy_body_r, copy_bb, copy_cfg_body, copy_tree_r, inlining_p): Add
versioning support.
        (copy_decl_for_dup): Rename from copy_decl_for_inlining.
Add argument VERSIONING.
        (copy_arguments_for_versioning, copy_static_chain,
function_versionable_p, tree_versionable_function_p,
tree_function_versioning, replace_ref_tree): New functions.
* tree-inline.h: Include varray.h.
        (tree_versionable_function_p,  tree_function_versioning,
tree copy_decl_for_dup): New declarations.

From-SVN: r102625

gcc/ChangeLog
gcc/Makefile.in
gcc/cgraph.h
gcc/cgraphunit.c
gcc/common.opt
gcc/integrate.c
gcc/passes.c

index bc0f2930bc2709e109ca4f9b259e49ed1d90c84a..1f090f441e57e679a3057829f4acdb871378e626 100644 (file)
@@ -1,3 +1,58 @@
+2005-08-01  Razya Ladelsky  <razya@il.ibm.com>
+
+        * cgraph.h (update_call_expr, cgraph_copy_node_for_versioning,
+        cgraph_function_versioning): New declarations.
+        * cgraphunit.c: Add include to ipa-prop.h.
+        (update_call_expr, cgraph_copy_node_for_versioning,
+        cgraph_function_versioning): New functions.
+        * integrate.c (copy_decl_for_inlining): Remove.
+        * ipa-prop.h (ipa_replace_map): New struct.
+        (struct ipa_node): Add ipcp_orig_node, count_scale, new fields.
+        * ipa-cp.c (ipcp_method_orig_node, ipcp_method_is_cloned,
+        ipcp_method_set_orig_node, ipcp_cloned_create, ipcp_method_get_scale,
+        ipcp_method_set_scale, ipcp_method_compute_scale, ipcp_after_propagate,
+        ipcp_iterate_stage, ipcp_method_scale_print,
+        ipcp_profile_mt_count_print, ipcp_profile_cs_count_print,
+        ipcp_profile_edge_print, ipcp_profile_bb_print , ipcp_profile_print,
+        ipcp_replace_map_create, ipcp_redirect, ipcp_update_callgraph,
+        ipcp_update_bb_counts, ipcp_update_profiling,
+        ipcp_update_edges_counts): New functions.
+        (ipcp_method_cval_init): Remove restriction regarding local methods.
+        (ipcp_init_stage): Add ipcp_method_compute_scale.
+        (ipcp_insert_stage): Add versioning.
+        (ipcp_structures_print): Add ipcp_method_scale_print.
+        (ipcp_driver): Dump profiling info.
+        * Makefile.in: Remove integrate.h dependency from tree-inline.o.
+        Add ipa-prop.h dependency to tree-inline.o and cgraphunit.o.
+        * tree-inline.c: Remove include to integrate.h, Add include ipa-prop.h.
+        (struct inline_data): Add versioning_p, ipa_info, new fields.
+        (remap_decl, mark_local_for_remap_r, setup_one_parameter,
+        declare_return_variable): Replace calls to copy_decl_for_inlining with
+        copy_decl_for_dup.
+        (copy_body_r, copy_bb, copy_cfg_body, copy_tree_r, inlining_p): Add
+        versioning support.
+        (copy_decl_for_dup): Rename from copy_decl_for_inlining.
+        Add argument VERSIONING.
+        (copy_arguments_for_versioning, copy_static_chain,
+        function_versionable_p, tree_versionable_function_p,
+        tree_function_versioning, replace_ref_tree): New functions.
+        * tree-inline.h: Include varray.h.
+        (tree_versionable_function_p,  tree_function_versioning,
+        tree copy_decl_for_dup): New declarations.
+
+2005-08-01  Razya Ladelsky  <razya@il.ibm.com>
+
+        * ipa-cp.c: New file. Contains IPCP specific functionality.
+        * ipa-prop.h: New file. Contains structures/definitions that can be
+        used by several interprocedural data flow optimizations (and also IPCP).
+        * ipa-prop.c: New file.
+        * Makefile.in: Add ipa-cp.c, ipa-prop.h, ipa-prop.c.
+        * common.opt: Add ipa-cp flag.
+        * timevar.def: Add IPCP optimization.
+        * tree-optimize.c (init_tree_optimization_passes): Schedule
+        pass_ipa_cp.
+        * tree-pass.h (pass_ipa_cp): Declare.
+
 2005-08-01  Kazu Hirata  <kazu@codesourcery.com>
 
        * dwarf2out.c, fold-const.c, ipa-type-escape.c,
index e465e00550e64b0133fba127087fa3f186eabb76..c8023300cb3f1da13dae974cd0cb3191a1c878e7 100644 (file)
@@ -975,7 +975,8 @@ OBJS-common = \
 OBJS-md = $(out_object_file)
 OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) tree-inline.o               \
   cgraph.o cgraphunit.o tree-nomudflap.o ipa.o ipa-inline.o                \
-  ipa-utils.o ipa-reference.o ipa-pure-const.o ipa-type-escape.o
+  ipa-utils.o ipa-reference.o ipa-pure-const.o ipa-type-escape.o           \
+  ipa-prop.o ipa-cp.o
 
 OBJS = $(OBJS-common) $(out_object_file) $(OBJS-archive)
 
@@ -1715,9 +1716,10 @@ tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    tree-iterator.h tree-pass.h $(DIAGNOSTIC_H)
 tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
-   $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
+   $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
    langhooks.h tree-inline.h $(CGRAPH_H) intl.h function.h $(TREE_GIMPLE_H) \
-   debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h
+   debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
+   ipa-prop.h
 print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(GGC_H) langhooks.h real.h tree-iterator.h
 stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2151,8 +2153,15 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h tree-inline.h toplev.h $(FLAGS_H) $(GGC_H) \
    $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h function.h $(TREE_GIMPLE_H) \
    $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
-   $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H)
+   $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h
 ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) 
+ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h  \
+   langhooks.h $(GGC_H) target.h $(CGRAPH_H) ipa-prop.h \
+   tree-flow.h $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H)
+ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h  \
+   langhooks.h target.h $(CGRAPH_H) ipa-prop.h  \
+   tree-flow.h $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) \
+   diagnostic.h
 ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h tree-inline.h $(FLAGS_H) $(CGRAPH_H) intl.h \
    $(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TIMEVAR_H) tree-pass.h \
@@ -2712,6 +2721,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
   $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/cgraph.h \
   $(srcdir)/c-common.h $(srcdir)/c-tree.h $(srcdir)/reload.h \
   $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
+  $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c\
   $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
   $(srcdir)/dojump.c $(srcdir)/tree-profile.c \
   $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
index 81eb10b5f3c1852396480b60569ea76e84fd81b2..ccb2cdd3b644bb90d942fbfd0bceaf1e0b518a4b 100644 (file)
@@ -281,6 +281,8 @@ void cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate);
 void cgraph_build_static_cdtor (char which, tree body, int priority);
 void cgraph_reset_static_var_maps (void);
 void init_cgraph (void);
+struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
+                                                varray_type, varray_type);
 
 /* In ipa.c  */
 bool cgraph_remove_unreachable_nodes (bool, FILE *);
index f8f864c11f811352326964df50b4eb2c36f4b41b..a10859dd0bc31c667e5cbe1e1c8b78a33d22dcba 100644 (file)
@@ -162,6 +162,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "c-common.h"
 #include "intl.h"
 #include "function.h"
+#include "ipa-prop.h"
 #include "tree-gimple.h"
 #include "tree-pass.h"
 #include "output.h"
@@ -1368,3 +1369,134 @@ init_cgraph (void)
 {
   cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
 }
+
+/* The edges representing the callers of the NEW_VERSION node were 
+   fixed by cgraph_function_versioning (), now the call_expr in their
+   respective tree code should be updated to call the NEW_VERSION.  */
+
+static void
+update_call_expr (struct cgraph_node *new_version)
+{
+  struct cgraph_edge *e;
+
+  gcc_assert (new_version);
+  for (e = new_version->callers; e; e = e->next_caller)
+    /* Update the call expr on the edges
+       to call the new version.  */
+    TREE_OPERAND (TREE_OPERAND (get_call_expr_in (e->call_stmt), 0), 0) = new_version->decl;
+}
+
+
+/* Create a new cgraph node which is the new version of
+   OLD_VERSION node.  REDIRECT_CALLERS holds the callers
+   edges which should be redirected to point to
+   NEW_VERSION.  ALL the callees edges of OLD_VERSION
+   are cloned to the new version node.  Return the new
+   version node.  */
+
+static struct cgraph_node *
+cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
+                                tree new_decl, varray_type redirect_callers)
+ {
+   struct cgraph_node *new_version;
+   struct cgraph_edge *e, *new_e;
+   struct cgraph_edge *next_callee;
+   unsigned i;
+
+   gcc_assert (old_version);
+   
+   new_version = cgraph_node (new_decl);
+
+   new_version->analyzed = true;
+   new_version->local = old_version->local;
+   new_version->global = old_version->global;
+   new_version->rtl = new_version->rtl;
+   new_version->reachable = true;
+   new_version->count = old_version->count;
+
+   /* Clone the old node callees.  Recursive calls are
+      also cloned.  */
+   for (e = old_version->callees;e; e=e->next_callee)
+     {
+       new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->loop_nest, true);
+       new_e->count = e->count;
+     }
+   /* Fix recursive calls.
+      If OLD_VERSION has a recursive call after the
+      previous edge cloning, the new version will have an edge
+      pointing to the old version, which is wrong;
+      Redirect it to point to the new version. */
+   for (e = new_version->callees ; e; e = next_callee)
+     {
+       next_callee = e->next_callee;
+       if (e->callee == old_version)
+        cgraph_redirect_edge_callee (e, new_version);
+         
+       if (!next_callee)
+        break;
+     }
+   if (redirect_callers)
+     for (i = 0; i < VARRAY_ACTIVE_SIZE (redirect_callers); i++)
+       {
+         e = VARRAY_GENERIC_PTR (redirect_callers, i);
+        /* Redirect calls to the old version node
+           to point to it's new version.  */
+         cgraph_redirect_edge_callee (e, new_version);
+       }
+
+   return new_version;
+ }
+
+ /* Perform function versioning.
+    Function versioning includes copying of the tree and 
+    a callgraph update (creating a new cgraph node and updating
+    its callees and callers).
+
+    REDIRECT_CALLERS varray includes the edges to be redirected
+    to the new version.
+
+    TREE_MAP is a mapping of tree nodes we want to replace with
+    new ones (according to results of prior analysis).
+    OLD_VERSION_NODE is the node that is versioned.
+    It returns the new version's cgraph node.  */
+
+struct cgraph_node *
+cgraph_function_versioning (struct cgraph_node *old_version_node,
+                           varray_type redirect_callers,
+                           varray_type tree_map)
+{
+  tree old_decl = old_version_node->decl;
+  struct cgraph_node *new_version_node = NULL;
+  tree new_decl;
+
+  if (!tree_versionable_function_p (old_decl))
+    return NULL;
+
+  /* Make a new FUNCTION_DECL tree node for the
+     new version. */
+  new_decl = copy_node (old_decl);
+
+  /* Create the new version's call-graph node.
+     and update the edges of the new node. */
+  new_version_node =
+    cgraph_copy_node_for_versioning (old_version_node, new_decl,
+                                    redirect_callers);
+
+  /* Copy the OLD_VERSION_NODE function tree to the new version.  */
+  tree_function_versioning (old_decl, new_decl, tree_map);
+  /* Update the call_expr on the edges to call the new version node. */
+  update_call_expr (new_version_node);
+
+  /* Update the new version's properties.  
+     Make The new version visible only within this translation unit.
+     ??? We cannot use COMDAT linkage because there is no 
+     ABI support for this.  */
+  DECL_EXTERNAL (new_version_node->decl) = 0;
+  DECL_ONE_ONLY (new_version_node->decl) = 0;
+  TREE_PUBLIC (new_version_node->decl) = 0;
+  DECL_COMDAT (new_version_node->decl) = 0;
+  new_version_node->local.externally_visible = 0;
+  new_version_node->local.local = 1;
+  new_version_node->lowered = true;
+  return new_version_node;
+}
index 28d9a0633291079ac74a97bec041f04fbfce472d..a993ff915c7ea534e48939523e591f8b135bf169 100644 (file)
@@ -507,6 +507,10 @@ fipa-type-escape
 Common Report Var(flag_ipa_type_escape) Init(0)
 Type based escape and alias analysis
 
+fipa-cp
+Common Report Var(flag_ipa_cp)
+Perform Interprocedural constant propagation
+
 fivopts
 Common Report Var(flag_ivopts) Init(1)
 Optimize induction variables on trees
index eadf6606830205aa1ef454d9c5c95755b7a57900..ee9c1849855d1e97df2ef14016d8ce977fb553be 100644 (file)
@@ -88,82 +88,6 @@ function_attribute_inlinable_p (tree fndecl)
 
   return true;
 }
-\f
-/* Copy NODE (which must be a DECL).  The DECL originally was in the FROM_FN,
-   but now it will be in the TO_FN.  */
-
-tree
-copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
-{
-  tree copy;
-
-  /* Copy the declaration.  */
-  if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
-    {
-      tree type = TREE_TYPE (decl);
-
-      /* For a parameter or result, we must make an equivalent VAR_DECL, not a
-        new PARM_DECL.  */
-      copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
-      TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
-      TREE_READONLY (copy) = TREE_READONLY (decl);
-      TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
-      DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl);
-    }
-  else
-    {
-      copy = copy_node (decl);
-      /* The COPY is not abstract; it will be generated in TO_FN.  */
-      DECL_ABSTRACT (copy) = 0;
-      lang_hooks.dup_lang_specific_decl (copy);
-
-      /* TREE_ADDRESSABLE isn't used to indicate that a label's
-        address has been taken; it's for internal bookkeeping in
-        expand_goto_internal.  */
-      if (TREE_CODE (copy) == LABEL_DECL)
-       {
-         TREE_ADDRESSABLE (copy) = 0;
-          LABEL_DECL_UID (copy) = -1;
-       }
-    }
-
-  /* Don't generate debug information for the copy if we wouldn't have
-     generated it for the copy either.  */
-  DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
-  DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
-
-  /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what
-     declaration inspired this copy.  */
-  DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
-
-  /* The new variable/label has no RTL, yet.  */
-  if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL) 
-      && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
-    SET_DECL_RTL (copy, NULL_RTX);
-
-  /* These args would always appear unused, if not for this.  */
-  TREE_USED (copy) = 1;
-
-  /* Set the context for the new declaration.  */
-  if (!DECL_CONTEXT (decl))
-    /* Globals stay global.  */
-    ;
-  else if (DECL_CONTEXT (decl) != from_fn)
-    /* Things that weren't in the scope of the function we're inlining
-       from aren't in the scope we're inlining to, either.  */
-    ;
-  else if (TREE_STATIC (decl))
-    /* Function-scoped static variables should stay in the original
-       function.  */
-    ;
-  else
-    /* Ordinary automatic local variables are now in the scope of the
-       new function.  */
-    DECL_CONTEXT (copy) = to_fn;
-
-  return copy;
-}
-
 \f
 /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
    given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
index 16f816c7c1662839ebea0732ba60987e5ab75034..76f5da3988bf3c3a510f4ef1ffc478378ab2fa74 100644 (file)
@@ -433,6 +433,7 @@ init_optimization_passes (void)
   p = &all_ipa_passes;
   NEXT_PASS (pass_early_ipa_inline);
   NEXT_PASS (pass_early_local_passes);
+  NEXT_PASS (pass_ipa_cp);
   NEXT_PASS (pass_ipa_inline);
   NEXT_PASS (pass_ipa_reference);
   NEXT_PASS (pass_ipa_pure_const);