diff gcc/tree-ssa-forwprop.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
line wrap: on
line diff
--- a/gcc/tree-ssa-forwprop.c	Fri Feb 12 23:41:23 2010 +0900
+++ b/gcc/tree-ssa-forwprop.c	Mon May 24 12:47:05 2010 +0900
@@ -1,5 +1,6 @@
 /* Forward propagation of expressions for single use variables.
-   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -21,13 +22,12 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "ggc.h"
 #include "tree.h"
-#include "rtl.h"
 #include "tm_p.h"
 #include "basic-block.h"
 #include "timevar.h"
 #include "diagnostic.h"
+#include "tree-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-dump.h"
@@ -398,25 +398,27 @@
 
   do {
     tree tmp = NULL_TREE;
-    tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
+    tree name = NULL_TREE, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
     gimple def_stmt;
     bool single_use0_p = false, single_use1_p = false;
     enum tree_code code = gimple_cond_code (stmt);
 
     /* We can do tree combining on SSA_NAME and comparison expressions.  */
-    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison
-        && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
+    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison)
       {
 	/* For comparisons use the first operand, that is likely to
 	   simplify comparisons against constants.  */
-	name = gimple_cond_lhs (stmt);
-	def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
-	if (def_stmt && can_propagate_from (def_stmt))
+	if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
 	  {
-	    tree op1 = gimple_cond_rhs (stmt);
-	    rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
-	    tmp = combine_cond_expr_cond (loc, code, boolean_type_node, rhs0,
-					  op1, !single_use0_p);
+	    name = gimple_cond_lhs (stmt);
+	    def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
+	    if (def_stmt && can_propagate_from (def_stmt))
+	      {
+		tree op1 = gimple_cond_rhs (stmt);
+		rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
+		tmp = combine_cond_expr_cond (loc, code, boolean_type_node,
+					      rhs0, op1, !single_use0_p);
+	      }
 	  }
 	/* If that wasn't successful, try the second operand.  */
 	if (tmp == NULL_TREE
@@ -728,6 +730,7 @@
   gimple use_stmt = gsi_stmt (*use_stmt_gsi);
   enum tree_code rhs_code;
   bool res = true;
+  bool addr_p = false;
 
   gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
 
@@ -800,8 +803,12 @@
   /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
      nodes from the RHS.  */
   rhsp = gimple_assign_rhs1_ptr (use_stmt);
-  while (handled_component_p (*rhsp)
-	 || TREE_CODE (*rhsp) == ADDR_EXPR)
+  if (TREE_CODE (*rhsp) == ADDR_EXPR)
+    {
+      rhsp = &TREE_OPERAND (*rhsp, 0);
+      addr_p = true;
+    }
+  while (handled_component_p (*rhsp))
     rhsp = &TREE_OPERAND (*rhsp, 0);
   rhs = *rhsp;
 
@@ -850,11 +857,14 @@
 	 return res;
        }
      /* If the defining rhs comes from an indirect reference, then do not
-        convert into a VIEW_CONVERT_EXPR.  */
+        convert into a VIEW_CONVERT_EXPR.  Likewise if we'll end up taking
+	the address of a V_C_E of a constant.  */
      def_rhs_base = TREE_OPERAND (def_rhs, 0);
      while (handled_component_p (def_rhs_base))
        def_rhs_base = TREE_OPERAND (def_rhs_base, 0);
-     if (!INDIRECT_REF_P (def_rhs_base))
+     if (!INDIRECT_REF_P (def_rhs_base)
+	 && (!addr_p
+	     || !is_gimple_min_invariant (def_rhs)))
        {
 	 /* We may have arbitrary VIEW_CONVERT_EXPRs in a nested component
 	    reference.  Place it there and fold the thing.  */
@@ -955,9 +965,10 @@
 	}
 
       /* If the use is in a deeper loop nest, then we do not want
-	 to propagate the ADDR_EXPR into the loop as that is likely
-	 adding expression evaluations into the loop.  */
-      if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth)
+	 to propagate non-invariant ADDR_EXPRs into the loop as that
+	 is likely adding expression evaluations into the loop.  */
+      if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth
+	  && !is_gimple_min_invariant (rhs))
 	{
 	  all = false;
 	  continue;