OSDN Git Service

2008-03-04 Uros Bizjak <ubizjak@gmail.com>
[pf3gnuchains/gcc-fork.git] / gcc / ipa-prop.c
index cdbf94b..76e2d3b 100644 (file)
@@ -1,11 +1,11 @@
 /* Interprocedural analyses.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -14,9 +14,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -167,7 +166,7 @@ static inline void
 ipa_method_tree_map_create (struct cgraph_node *mt)
 {
   IPA_NODE_REF (mt)->ipa_param_tree =
-    xcalloc (ipa_method_formal_count (mt), sizeof (tree));
+    XCNEWVEC (tree, ipa_method_formal_count (mt));
 }
 
 /* Create modify structure for MT.  */
@@ -175,7 +174,7 @@ static inline void
 ipa_method_modify_create (struct cgraph_node *mt)
 {
   ((struct ipa_node *) mt->aux)->ipa_mod =
-    xcalloc (ipa_method_formal_count (mt), sizeof (bool));
+    XCNEWVEC (bool, ipa_method_formal_count (mt));
 }
 
 /* Set modify of I-th formal of MT to VAL.  */
@@ -244,15 +243,17 @@ static void
 ipa_method_modify_stmt (struct cgraph_node *mt, tree stmt)
 {
   int i, j;
+  tree parm_decl;
 
   switch (TREE_CODE (stmt))
     {
-    case MODIFY_EXPR:
-      if (TREE_CODE (TREE_OPERAND (stmt, 0)) == PARM_DECL)
+    case GIMPLE_MODIFY_STMT:
+         if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
        {
-         i = ipa_method_tree_map (mt, TREE_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 +293,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 +312,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 +384,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;
 }
@@ -388,7 +395,7 @@ static inline void
 ipa_callsite_param_map_create (struct cgraph_edge *cs)
 {
   IPA_EDGE_REF (cs)->ipa_param_map =
-    xcalloc (ipa_callsite_param_count (cs), sizeof (struct ipa_jump_func));
+    XCNEWVEC (struct ipa_jump_func, ipa_callsite_param_count (cs));
 }
 
 /* Return the call expr tree related to callsite CS.  */
@@ -411,15 +418,11 @@ void
 ipa_callsite_compute_count (struct cgraph_edge *cs)
 {
   tree call_tree;
-  tree arg;
   int arg_num;
 
   call_tree = get_call_expr_in (ipa_callsite_tree (cs));
   gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
-  arg = TREE_OPERAND (call_tree, 1);
-  arg_num = 0;
-  for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
-    arg_num++;
+  arg_num = call_expr_nargs (call_tree);
   ipa_callsite_param_count_set (cs, arg_num);
 }
 
@@ -431,93 +434,75 @@ void
 ipa_callsite_compute_param (struct cgraph_edge *cs)
 {
   tree call_tree;
-  tree arg, cst_decl, arg_type, formal_type;
+  tree arg, cst_decl;
   int arg_num;
   int i;
   struct cgraph_node *mt;
+  tree parm_decl;
+  struct function *curr_cfun;
+  call_expr_arg_iterator iter;
 
   if (ipa_callsite_param_count (cs) == 0)
     return;
   ipa_callsite_param_map_create (cs);
   call_tree = get_call_expr_in (ipa_callsite_tree (cs));
   gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
-  arg = TREE_OPERAND (call_tree, 1);
   arg_num = 0;
 
-  for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
     {
       /* 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 (arg) == SSA_NAME
+          && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
+         || TREE_CODE (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 (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
+          
+         i = ipa_method_tree_map (mt, parm_decl);
+         if (TREE_CODE (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) != 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
            {
-               arg_type = TREE_TYPE (TREE_VALUE (arg));
-               formal_type = TREE_TYPE (ipa_method_get_tree (cs->callee, arg_num));
-               if (TYPE_NAME (arg_type) == TYPE_NAME (formal_type)
-                   && TYPE_CONTEXT (arg_type) == TYPE_CONTEXT (formal_type)
-                   && attribute_list_equal (TYPE_ATTRIBUTES (arg_type),
-                                            TYPE_ATTRIBUTES (formal_type)))
-                 {
-                   ipa_callsite_param_set_type (cs, arg_num, FORMAL_IPATYPE);
-                   ipa_callsite_param_set_info_type_formal (cs, arg_num, i);
-                 }
-               else
-                 ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
+             ipa_callsite_param_set_type (cs, arg_num, FORMAL_IPATYPE);
+             ipa_callsite_param_set_info_type_formal (cs, arg_num, i);
            }
        }
       /* If a constant value was passed as argument, 
          we store CONST_IPATYPE and its value as the jump function 
          of this argument.  */
-      else if (TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
-              || TREE_CODE (TREE_VALUE (arg)) == REAL_CST)
+      else if (TREE_CODE (arg) == INTEGER_CST
+              || TREE_CODE (arg) == REAL_CST
+              || TREE_CODE (arg) == FIXED_CST)
        {
-         arg_type = TREE_TYPE (TREE_VALUE (arg));
-         formal_type = TREE_TYPE (ipa_method_get_tree (cs->callee, arg_num));
-         if (TYPE_NAME (arg_type) == TYPE_NAME (formal_type)
-             && TYPE_CONTEXT (arg_type) == TYPE_CONTEXT (formal_type)
-             && attribute_list_equal (TYPE_ATTRIBUTES (arg_type),
-                                      TYPE_ATTRIBUTES (formal_type)))
-           {
-             ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
-             ipa_callsite_param_set_info_type (cs, arg_num, TREE_VALUE (arg));
-           }
-         else
-           ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
+         ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
+         ipa_callsite_param_set_info_type (cs, arg_num, arg);
        }
       /* This is for the case of Fortran. If the address of a const_decl 
          was passed as argument then we store 
-         CONST_IPATYPE_REF/CONST_IPATYPE_REF and the costant 
+         CONST_IPATYPE_REF/CONST_IPATYPE_REF and the constant 
          value as the jump function corresponding to this argument.  */
-      else if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR
-              && TREE_CODE (TREE_OPERAND (TREE_VALUE (arg), 0)) ==
-              CONST_DECL)
+      else if (TREE_CODE (arg) == ADDR_EXPR
+              && TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
        {
-         cst_decl = TREE_OPERAND (TREE_VALUE (arg), 0);
-         arg_type = TREE_TYPE (DECL_INITIAL (cst_decl));
-         formal_type =
-           TREE_TYPE (TREE_TYPE (ipa_method_get_tree (cs->callee, arg_num)));
+         cst_decl = TREE_OPERAND (arg, 0);
          if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
-             || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST)
+             || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
+             || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
            {
-             if (TYPE_NAME (arg_type) == TYPE_NAME (formal_type)
-                 && TYPE_CONTEXT (arg_type) == TYPE_CONTEXT (formal_type)
-                 && attribute_list_equal (TYPE_ATTRIBUTES (arg_type),
-                                          TYPE_ATTRIBUTES (formal_type)))
-
-               {
-                 ipa_callsite_param_set_type (cs, arg_num,
-                                              CONST_IPATYPE_REF);
-                 ipa_callsite_param_set_info_type (cs, arg_num, DECL_INITIAL (cst_decl));
-
-               }
-             else
-               ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
+             ipa_callsite_param_set_type (cs, arg_num,
+                                          CONST_IPATYPE_REF);
+             ipa_callsite_param_set_info_type (cs, arg_num,
+                                               DECL_INITIAL (cst_decl));
            }
        }
       else