OSDN Git Service

PR rtl-optimization/28940
[pf3gnuchains/gcc-fork.git] / gcc / ipa-pure-const.c
index bd1d72b..d3b880a 100644 (file)
@@ -1,12 +1,12 @@
 /* Callgraph based analysis of static variables.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 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
@@ -15,9 +15,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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This file mark functions as being either const (TREE_READONLY) or
    pure (DECL_IS_PURE).
@@ -80,8 +79,8 @@ typedef struct funct_state_d * funct_state;
 static inline funct_state
 get_function_state (struct cgraph_node *node)
 {
-  struct ipa_dfs_info * info = node->aux;
-  return info->aux;
+  struct ipa_dfs_info * info = (struct ipa_dfs_info *) node->aux;
+  return (funct_state) info->aux;
 }
 
 /* Check to see if the use (or definition when CHECHING_WRITE is true) 
@@ -115,7 +114,10 @@ check_decl (funct_state local,
      are CHECKING_WRITE, this cannot be a pure or constant
      function.  */
   if (checking_write) 
-    local->pure_const_state = IPA_NEITHER;
+    {
+      local->pure_const_state = IPA_NEITHER;
+      return;
+    }
 
   if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
     {
@@ -163,7 +165,8 @@ check_operand (funct_state local,
 static void
 check_tree (funct_state local, tree t, bool checking_write)
 {
-  if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
+  if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR)
+      || TREE_CODE (t) == SSA_NAME)
     return;
 
   /* Any tree which is volatile disqualifies thie function from being
@@ -315,20 +318,15 @@ get_asm_expr_operands (funct_state local, tree stmt)
 static void
 check_call (funct_state local, tree call_expr) 
 {
-  int flags = call_expr_flags(call_expr);
-  tree operand_list = TREE_OPERAND (call_expr, 1);
+  int flags = call_expr_flags (call_expr);
   tree operand;
+  call_expr_arg_iterator iter;
   tree callee_t = get_callee_fndecl (call_expr);
   struct cgraph_node* callee;
   enum availability avail = AVAIL_NOT_AVAILABLE;
 
-  for (operand = operand_list;
-       operand != NULL_TREE;
-       operand = TREE_CHAIN (operand))
-    {
-      tree argument = TREE_VALUE (operand);
-      check_rhs_var (local, argument);
-    }
+  FOR_EACH_CALL_EXPR_ARG (operand, iter, call_expr)
+    check_rhs_var (local, operand);
   
   /* The const and pure flags are set by a variety of places in the
      compiler (including here).  If someone has already set the flags
@@ -400,7 +398,7 @@ scan_function (tree *tp,
                      int *walk_subtrees, 
                      void *data)
 {
-  struct cgraph_node *fn = data;
+  struct cgraph_node *fn = (struct cgraph_node *) data;
   tree t = *tp;
   funct_state local = get_function_state (fn);
 
@@ -451,7 +449,14 @@ scan_function (tree *tp,
              case ADDR_EXPR:
                check_rhs_var (local, rhs);
                break;
-             case CALL_EXPR: 
+             default:
+               break;
+             }
+           break;
+         case tcc_vl_exp:
+           switch (TREE_CODE (rhs)) 
+             {
+             case CALL_EXPR:
                check_call (local, rhs);
                break;
              default:
@@ -502,7 +507,7 @@ analyze_function (struct cgraph_node *fn)
 {
   funct_state l = XCNEW (struct funct_state_d);
   tree decl = fn->decl;
-  struct ipa_dfs_info * w_info = fn->aux;
+  struct ipa_dfs_info * w_info = (struct ipa_dfs_info *) fn->aux;
 
   w_info->aux = l;
 
@@ -599,7 +604,7 @@ static_execute (void)
   struct cgraph_node *w;
   struct cgraph_node **order =
     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
-  int order_pos = order_pos = ipa_utils_reduced_inorder (order, true, false);
+  int order_pos = ipa_utils_reduced_inorder (order, true, false);
   int i;
   struct ipa_dfs_info * w_info;
 
@@ -670,7 +675,7 @@ static_execute (void)
                    }
                }
            }
-         w_info = w->aux;
+         w_info = (struct ipa_dfs_info *) w->aux;
          w = w_info->next_cycle;
        }
 
@@ -705,7 +710,7 @@ static_execute (void)
                  break;
                }
            }
-         w_info = w->aux;
+         w_info = (struct ipa_dfs_info *) w->aux;
          w = w_info->next_cycle;
        }
     }
@@ -715,7 +720,7 @@ static_execute (void)
     /* Get rid of the aux information.  */
     if (node->aux)
       {
-       w_info = node->aux;
+       w_info = (struct ipa_dfs_info *) node->aux;
        if (w_info->aux)
          free (w_info->aux);
        free (node->aux);