OSDN Git Service

New out of ssa Coalescer.
[pf3gnuchains/gcc-fork.git] / gcc / ipa-pure-const.c
index 1402607..bd1d72b 100644 (file)
@@ -16,8 +16,8 @@ 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.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* This file mark functions as being either const (TREE_READONLY) or
    pure (DECL_IS_PURE).
@@ -51,6 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "timevar.h"
 #include "diagnostic.h"
 #include "langhooks.h"
+#include "target.h"
 
 static struct pointer_set_t *visited_nodes;
 
@@ -165,6 +166,14 @@ check_tree (funct_state local, tree t, bool checking_write)
   if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
     return;
 
+  /* Any tree which is volatile disqualifies thie function from being
+     const or pure. */
+  if (TREE_THIS_VOLATILE (t))
+    {
+      local->pure_const_state = IPA_NEITHER;
+      return;
+    }
+
   while (TREE_CODE (t) == REALPART_EXPR 
         || TREE_CODE (t) == IMAGPART_EXPR
         || handled_component_p (t))
@@ -182,13 +191,15 @@ check_tree (funct_state local, tree t, bool checking_write)
       
       /* Any indirect reference that occurs on the lhs
         disqualifies the function from being pure or const. Any
-        indirect reference that occurs on the rhs disqualifies
-        the function from being const.  */
+        indirect reference that occurs on the rhs disqualifies the
+        function from being const.  */
       if (checking_write) 
-       local->pure_const_state = IPA_NEITHER;
-      else 
-       if (local->pure_const_state == IPA_CONST)
-         local->pure_const_state = IPA_PURE;
+       {
+         local->pure_const_state = IPA_NEITHER;
+         return;
+       }
+      else if (local->pure_const_state == IPA_CONST)
+       local->pure_const_state = IPA_PURE;
     }
 
   if (SSA_VAR_P (t))
@@ -401,11 +412,11 @@ scan_function (tree *tp,
       *walk_subtrees = 0;
       break;
 
-    case MODIFY_EXPR:
+    case GIMPLE_MODIFY_STMT:
       {
        /* First look on the lhs and see what variable is stored to */
-       tree lhs = TREE_OPERAND (t, 0);
-       tree rhs = TREE_OPERAND (t, 1);
+       tree lhs = GIMPLE_STMT_OPERAND (t, 0);
+       tree rhs = GIMPLE_STMT_OPERAND (t, 1);
        check_lhs_var (local, lhs);
 
        /* For the purposes of figuring out what the cast affects */
@@ -489,7 +500,7 @@ scan_function (tree *tp,
 static void
 analyze_function (struct cgraph_node *fn)
 {
-  funct_state l = xcalloc (1, sizeof (struct funct_state_d));
+  funct_state l = XCNEW (struct funct_state_d);
   tree decl = fn->decl;
   struct ipa_dfs_info * w_info = fn->aux;
 
@@ -498,9 +509,11 @@ analyze_function (struct cgraph_node *fn)
   l->pure_const_state = IPA_CONST;
   l->state_set_in_source = false;
 
-  /* If this is a volatile function, do not touch this unless it has
-     been marked as const or pure by the front end.  */
-  if (TREE_THIS_VOLATILE (decl))
+  /* If this function does not return normally or does not bind local,
+     do not touch this unless it has been marked as const or pure by the
+     front end.  */
+  if (TREE_THIS_VOLATILE (decl)
+      || !targetm.binds_local_p (decl))
     {
       l->pure_const_state = IPA_NEITHER;
       return;
@@ -537,7 +550,7 @@ analyze_function (struct cgraph_node *fn)
              walk_tree (bsi_stmt_ptr (bsi), scan_function, 
                         fn, visited_nodes);
              if (l->pure_const_state == IPA_NEITHER) 
-               return;
+               goto end;
            }
        }
 
@@ -564,6 +577,14 @@ analyze_function (struct cgraph_node *fn)
          pop_cfun ();
        }
     }
+
+end:
+  if (dump_file)
+    {
+      fprintf (dump_file, "after local analysis of %s with initial value = %d\n ", 
+              cgraph_node_name (fn),
+              l->pure_const_state);
+    }
 }
 
 \f
@@ -571,13 +592,13 @@ analyze_function (struct cgraph_node *fn)
    on the local information that was produced by ipa_analyze_function
    and ipa_analyze_variable.  */
 
-static void
+static unsigned int
 static_execute (void)
 {
   struct cgraph_node *node;
   struct cgraph_node *w;
   struct cgraph_node **order =
-    xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+    XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
   int order_pos = order_pos = ipa_utils_reduced_inorder (order, true, false);
   int i;
   struct ipa_dfs_info * w_info;
@@ -694,11 +715,15 @@ static_execute (void)
     /* Get rid of the aux information.  */
     if (node->aux)
       {
+       w_info = node->aux;
+       if (w_info->aux)
+         free (w_info->aux);
        free (node->aux);
        node->aux = NULL;
       }
 
   free (order);
+  return 0;
 }
 
 static bool
@@ -711,7 +736,7 @@ gate_pure_const (void)
 
 struct tree_opt_pass pass_ipa_pure_const =
 {
-  "ipa-pure-const",                    /* name */
+  "pure-const",                                /* name */
   gate_pure_const,                     /* gate */
   static_execute,                      /* execute */
   NULL,                                        /* sub */