OSDN Git Service

2007-01-25 Razya Ladelsky <razya@il.ibm.com>
authorrazya <razya@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Jan 2007 13:01:53 +0000 (13:01 +0000)
committerrazya <razya@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Jan 2007 13:01:53 +0000 (13:01 +0000)
        * ipa-cp.c (ipcp_insert_stage, ipcp_driver): Support for SSA.
        (ipcp_driver): Change to static definition.
        Add dumping of the ifunctions.
        (constant_val_insert): Remove unused parameter. Support for SSA.
        (ipcp_propagate_const): Support for SSA.
        (ipcp_profile_bb_print): Print only analyzed nodes.
        (ipcp_replace_map_create): Remove support for Fortran constant
        for now.
        * ipa-prop.c (ipa_method_modify_stmt,
        ipa_callsite_compute_param): Support for SSA.
        * ipa-prop.h (ipcp_driver): Remove declaration.
        (IS_VALID_TREE_MAP_INDEX): Add define.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121256 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/Makefile.in
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/ipa-prop.h

index 0fd30cd..1bde783 100644 (file)
@@ -2434,7 +2434,7 @@ 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  \
+   langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h tree-inline.h tree-dump.h \
    $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(DIAGNOSTIC_H)
 ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
index 0451667..f2e9773 100644 (file)
@@ -143,6 +143,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "flags.h"
 #include "timevar.h"
 #include "diagnostic.h"
+#include "tree-dump.h"
+#include "tree-inline.h"
 
 /* Get orig node field of ipa_node associated with method MT.  */
 static inline struct cgraph_node *
@@ -219,7 +221,7 @@ ipcp_cval_set_cvalue (struct ipcp_formal *cval, union parameter_info *value,
                      enum cvalue_type type)
 {
   if (type == CONST_VALUE || type == CONST_VALUE_REF)
-    cval->cvalue.value =  value->value;
+    cval->cvalue.value = value->value;
 }
 
 /* Return whether TYPE is a constant type.  */
@@ -336,7 +338,7 @@ ipcp_cval_changed (struct ipcp_formal *cval1, struct ipcp_formal *cval2)
   if (ipcp_cval_get_cvalue_type (cval1) == ipcp_cval_get_cvalue_type (cval2))
     {
       if (ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE &&
-         ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE_REF)  
+         ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE_REF)
        return false;
       if (ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
                                   ipcp_cval_get_cvalue (cval2),
@@ -379,7 +381,7 @@ ipcp_method_cval_print (FILE * f)
   struct cgraph_node *node;
   int i, count;
   tree cvalue;
+
   fprintf (f, "\nCVAL PRINT\n");
   for (node = cgraph_nodes; node; node = node->next)
     {
@@ -395,10 +397,9 @@ ipcp_method_cval_print (FILE * f)
              fprintf (f, " param [%d]: ", i);
              fprintf (f, "type is CONST ");
              cvalue =
-               ipcp_cval_get_cvalue (ipcp_method_cval (node, i))->
-                 value;
-              print_generic_expr (f, cvalue, 0);
-              fprintf (f, "\n");
+               ipcp_cval_get_cvalue (ipcp_method_cval (node, i))->value;
+             print_generic_expr (f, cvalue, 0);
+             fprintf (f, "\n");
            }
          else if (ipcp_method_cval (node, i)->cval_type == TOP)
            fprintf (f, "param [%d]: type is TOP  \n", i);
@@ -424,8 +425,8 @@ ipcp_method_cval_init (struct cgraph_node *mt)
   for (i = 0; i < ipa_method_formal_count (mt); i++)
     {
       parm_tree = ipa_method_get_tree (mt, i);
-      if (INTEGRAL_TYPE_P (TREE_TYPE (parm_tree)) 
-         || SCALAR_FLOAT_TYPE_P (TREE_TYPE (parm_tree)) 
+      if (INTEGRAL_TYPE_P (TREE_TYPE (parm_tree))
+         || SCALAR_FLOAT_TYPE_P (TREE_TYPE (parm_tree))
          || POINTER_TYPE_P (TREE_TYPE (parm_tree)))
        ipcp_method_cval_set_cvalue_type (mt, i, TOP);
       else
@@ -439,22 +440,18 @@ ipcp_method_cval_init (struct cgraph_node *mt)
    PARM1 is the lhs of the assignment and
    VAL is the rhs. */
 static void
-constant_val_insert (tree fn, tree parm1, tree val)
+constant_val_insert (tree parm1, tree val)
 {
-  struct function *func;
-  tree init_stmt;
+  tree init_stmt = NULL;
   edge e_step;
-  edge_iterator ei;
 
   init_stmt = build2 (GIMPLE_MODIFY_STMT, void_type_node, parm1, val);
-  func = DECL_STRUCT_FUNCTION (fn);
-  cfun = func;
-  current_function_decl = fn;
-  if (ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
-    FOR_EACH_EDGE (e_step, ei, ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
+
+  if (init_stmt)
+    {
+      e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
       bsi_insert_on_edge_immediate (e_step, init_stmt);
-  current_function_decl = NULL;
-  cfun = NULL;
+    }
 }
 
 /* build INTEGER_CST tree with type TREE_TYPE and 
@@ -474,18 +471,16 @@ build_const_val (union parameter_info *cvalue, enum cvalue_type type,
    constant_val_insert().  */
 static void
 ipcp_propagate_const (struct cgraph_node *mt, int param,
-                     union parameter_info *cvalue ,enum cvalue_type type)
+                     union parameter_info *cvalueenum cvalue_type type)
 {
-  tree fndecl;
   tree const_val;
   tree parm_tree;
 
   if (dump_file)
     fprintf (dump_file, "propagating const to %s\n", cgraph_node_name (mt));
-  fndecl = mt->decl;
   parm_tree = ipa_method_get_tree (mt, param);
   const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
-  constant_val_insert (fndecl, parm_tree, const_val);
+  constant_val_insert (parm_tree, const_val);
 }
 
 /* Compute the proper scale for NODE.  It is the ratio between 
@@ -644,7 +639,7 @@ ipcp_callsite_param_print (FILE * f)
   struct ipa_jump_func *jump_func;
   enum jump_func_type type;
   tree info_type;
+
   fprintf (f, "\nCALLSITE PARAM PRINT\n");
   for (node = cgraph_nodes; node; node = node->next)
     {
@@ -663,11 +658,10 @@ ipcp_callsite_param_print (FILE * f)
                fprintf (f, "UNKNOWN\n");
              else if (type == CONST_IPATYPE || type == CONST_IPATYPE_REF)
                {
-                 info_type =
-                   ipa_jf_get_info_type (jump_func)->value;
-                  fprintf (f, "CONST : ");
-                  print_generic_expr (f, info_type, 0);
-                  fprintf (f, "\n");
+                 info_type = ipa_jf_get_info_type (jump_func)->value;
+                 fprintf (f, "CONST : ");
+                 print_generic_expr (f, info_type, 0);
+                 fprintf (f, "\n");
                }
              else if (type == FORMAL_IPATYPE)
                {
@@ -792,7 +786,7 @@ ipcp_profile_bb_print (FILE * f)
   for (node = cgraph_nodes; node; node = node->next)
     {
       fprintf (f, "method %s: \n", cgraph_node_name (node));
-      if (DECL_SAVED_TREE (node->decl))
+      if (node->analyzed)
        {
          bb =
            ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
@@ -849,27 +843,22 @@ ipcp_profile_print (FILE * f)
    operates according to the flags sent.  PARM_TREE is the 
    formal's tree found to be constant.  CVALUE represents the constant.  */
 static struct ipa_replace_map *
-ipcp_replace_map_create (enum cvalue_type type, tree parm_tree,
-                        union parameter_info *cvalue)
+ipcp_replace_map_create (struct function *func, enum cvalue_type type,
+                        tree parm_tree, union parameter_info *cvalue)
 {
   struct ipa_replace_map *replace_map;
   tree const_val;
 
   replace_map = XCNEW (struct ipa_replace_map);
   gcc_assert (ipcp_type_is_const (type));
-  if (type == CONST_VALUE_REF )
-    {
-      const_val =
-       build_const_val (cvalue, type, TREE_TYPE (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 = true;
-    }
-  else if (TREE_READONLY (parm_tree) && !TREE_ADDRESSABLE (parm_tree))
+  if (type != CONST_VALUE_REF
+      && 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 (cvalue, type, TREE_TYPE (parm_tree));
-      replace_map->old_tree = 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;
@@ -908,8 +897,7 @@ ipcp_redirect (struct cgraph_edge *cs)
        {
          jump_func = ipa_callsite_param (cs, i);
          type = get_type (jump_func);
-         if (type != CONST_IPATYPE 
-             && type != CONST_IPATYPE_REF)
+         if (type != CONST_IPATYPE && type != CONST_IPATYPE_REF)
            return true;
        }
     }
@@ -1007,7 +995,7 @@ ipcp_insert_stage (void)
   struct cgraph_node *node, *node1 = NULL;
   int i, const_param;
   union parameter_info *cvalue;
-  VEC(cgraph_edge_p,heap) *redirect_callers;
+  VEC (cgraph_edge_p, heap) * redirect_callers;
   varray_type replace_trees;
   struct cgraph_edge *cs;
   int node_callers, count;
@@ -1019,7 +1007,7 @@ ipcp_insert_stage (void)
     {
       /* Propagation of the constant is forbidden in 
          certain conditions.  */
-      if (ipcp_method_dont_insert_const (node))
+      if (!node->analyzed || ipcp_method_dont_insert_const (node))
        continue;
       const_param = 0;
       count = ipa_method_formal_count (node);
@@ -1040,7 +1028,8 @@ ipcp_insert_stage (void)
              cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
              parm_tree = ipa_method_get_tree (node, i);
              replace_param =
-               ipcp_replace_map_create (type, parm_tree, cvalue);
+               ipcp_replace_map_create (DECL_STRUCT_FUNCTION (node->decl),
+                                        type, parm_tree, cvalue);
              VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
            }
        }
@@ -1063,25 +1052,44 @@ ipcp_insert_stage (void)
        fprintf (dump_file, "versioned function %s\n",
                 cgraph_node_name (node));
       ipcp_cloned_create (node, node1);
-      for (i = 0; i < count; i++)
+      if (const_param > 0)
        {
-         type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
-         if (ipcp_type_is_const (type))
+         push_cfun (DECL_STRUCT_FUNCTION (node1->decl));
+         tree_register_cfg_hooks ();
+         current_function_decl = node1->decl;
+
+         for (i = 0; i < count; i++)
            {
-             cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
-             parm_tree = ipa_method_get_tree (node, i);
-             if (type != CONST_VALUE_REF 
-                 && !TREE_READONLY (parm_tree))
-               ipcp_propagate_const (node1, i, cvalue, type);
+             type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
+             if (ipcp_type_is_const (type))
+               {
+                 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
+                 parm_tree = ipa_method_get_tree (node, i);
+                 if (type != CONST_VALUE_REF && !is_gimple_reg (parm_tree))
+                   ipcp_propagate_const (node1, i, cvalue, type);
+               }
            }
+         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;
        }
+      if (dump_file)
+       dump_function_to_file (node1->decl, dump_file, dump_flags);
     }
   ipcp_update_callgraph ();
   ipcp_update_profiling ();
 }
 
 /* The IPCP driver.  */
-unsigned int
+static unsigned int
 ipcp_driver (void)
 {
   if (dump_file)
index 91eff19..55ff37c 100644 (file)
@@ -244,15 +244,17 @@ static void
 ipa_method_modify_stmt (struct cgraph_node *mt, tree stmt)
 {
   int i, j;
+  tree parm_decl;
 
   switch (TREE_CODE (stmt))
     {
     case GIMPLE_MODIFY_STMT:
-      if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
+         if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
        {
-         i = ipa_method_tree_map (mt, GIMPLE_STMT_OPERAND (stmt, 0));
+         parm_decl = GIMPLE_STMT_OPERAND (stmt, 0);
+         i = ipa_method_tree_map (mt, parm_decl);
          if (i >= 0)
-            ipa_method_modify_set (mt, i, true);
+           ipa_method_modify_set (mt, i, true);
        }
       break;
     case ASM_EXPR:
@@ -292,11 +294,15 @@ ipa_method_compute_modify (struct cgraph_node *mt)
   block_stmt_iterator bsi;
   tree stmt, parm_tree;
 
+  if (ipa_method_formal_count (mt) == 0)
+    return;
+
   ipa_method_modify_init (mt);
   decl = mt->decl;
   count = ipa_method_formal_count (mt);
   /* ??? Handle pending sizes case. Set all parameters 
      of the method to be modified.  */
+
   if (DECL_UNINLINABLE (decl))
     {
       for (j = 0; j < count; j++)
@@ -307,7 +313,8 @@ ipa_method_compute_modify (struct cgraph_node *mt)
   for (j = 0; j < count; j++)
     {
       parm_tree = ipa_method_get_tree (mt, j);
-      if (TREE_ADDRESSABLE (parm_tree))
+      if (!is_gimple_reg (parm_tree) 
+         && TREE_ADDRESSABLE (parm_tree))
        ipa_method_modify_set (mt, j, true);
     }
   body = DECL_SAVED_TREE (decl);
@@ -378,7 +385,8 @@ ipa_callsite_param_set_info_type_formal (struct cgraph_edge *cs, int i,
 /* Set int-valued INFO_TYPE1 as 'info_type' field of 
    jump function (ipa_jump_func struct) of argument I of callsite CS.  */
 static inline void
-ipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i, tree info_type1)
+ipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i,
+                                 tree info_type1)
 {
   ipa_callsite_param (cs, i)->info_type.value = info_type1;
 }
@@ -435,6 +443,8 @@ ipa_callsite_compute_param (struct cgraph_edge *cs)
   int arg_num;
   int i;
   struct cgraph_node *mt;
+  tree parm_decl;
+  struct function *curr_cfun;
 
   if (ipa_callsite_param_count (cs) == 0)
     return;
@@ -449,11 +459,25 @@ ipa_callsite_compute_param (struct cgraph_edge *cs)
       /* If the formal parameter was passed as argument, we store 
          FORMAL_IPATYPE and its index in the caller as the jump function 
          of this argument.  */
-      if (TREE_CODE (TREE_VALUE (arg)) == PARM_DECL)
+      if ((TREE_CODE (TREE_VALUE (arg)) == SSA_NAME
+          && TREE_CODE (SSA_NAME_VAR (TREE_VALUE (arg))) == PARM_DECL)
+         || TREE_CODE (TREE_VALUE (arg)) == PARM_DECL)
        {
          mt = ipa_callsite_caller (cs);
-         i = ipa_method_tree_map (mt, TREE_VALUE (arg));
-         if (i < 0 || ipa_method_is_modified (mt, i))
+         parm_decl =
+           TREE_CODE (TREE_VALUE (arg)) ==
+           PARM_DECL ? TREE_VALUE (arg) : SSA_NAME_VAR (TREE_VALUE (arg));
+          
+         i = ipa_method_tree_map (mt, parm_decl);
+         if (TREE_CODE (TREE_VALUE (arg)) == SSA_NAME 
+             && IS_VALID_TREE_MAP_INDEX (i)) 
+           {
+              curr_cfun = DECL_STRUCT_FUNCTION (mt->decl);
+             if (!gimple_default_def (curr_cfun, parm_decl) 
+                 || gimple_default_def (curr_cfun, parm_decl) != TREE_VALUE (arg))
+                   ipa_method_modify_set (mt, i, true); 
+            }
+         if (!IS_VALID_TREE_MAP_INDEX (i) || ipa_method_is_modified (mt, i))
            ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
          else
            {
index b5c5f2d..8450ce4 100644 (file)
@@ -106,6 +106,9 @@ struct ipa_replace_map
    to ipa_node/ipa_edge struct.  */
 #define IPA_NODE_REF(MT) ((struct ipa_node *)(MT)->aux)
 #define IPA_EDGE_REF(EDGE) ((struct ipa_edge *)(EDGE)->aux)
+/* This macro checks validity of index returned by
+   ipa_method_tree_map function.  */
+#define IS_VALID_TREE_MAP_INDEX(I) ((I) != -1)
 
 /* ipa_node stores information related to a method and
    its formal parameters. It is pointed to by a field in the
@@ -199,6 +202,4 @@ void ipa_nodes_free (void);
 void ipa_method_tree_print (FILE *);
 void ipa_method_modify_print (FILE *);
 
-unsigned int ipcp_driver (void);
-
 #endif /* IPA_PROP_H */