OSDN Git Service

* tree-ssa-pre.c (try_look_through_load): New function.
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 18:51:26 +0000 (18:51 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 18:51:26 +0000 (18:51 +0000)
(compute_avail): Use it to try to look through loads for some
more useful expressions.

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

gcc/ChangeLog
gcc/tree-ssa-pre.c

index a26af5a..3d6de0f 100644 (file)
@@ -1,3 +1,9 @@
+2005-09-06  Steven Bosscher  <stevenb@suse.de>
+
+       * tree-ssa-pre.c (try_look_through_load): New function.
+       (compute_avail): Use it to try to look through loads for some
+       more useful expressions.
+
 2005-09-06  Saurabh Verma  <saurabh.verma@codito.com>
 
        * simplify-rtx.c (simplify_binary_operation_1): Correct the 
 2005-09-06  Saurabh Verma  <saurabh.verma@codito.com>
 
        * simplify-rtx.c (simplify_binary_operation_1): Correct the 
index d83b5e4..b0e7953 100644 (file)
@@ -2136,6 +2136,75 @@ can_value_number_call (tree stmt)
   return false;
 }
 
   return false;
 }
 
+/* Given a statement STMT and its right hand side which is a load, try
+   to look for the expression stored in the location for the load, and
+   return true if a useful equivalence was recorded for LHS.  */
+
+static bool
+try_look_through_load (tree lhs, tree mem_ref, tree stmt, basic_block block)
+{
+  tree store_stmt = NULL;
+  tree rhs;
+  ssa_op_iter i;
+  tree vuse;
+
+  FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, i, SSA_OP_VIRTUAL_USES)
+    {
+      tree def_stmt;
+
+      gcc_assert (TREE_CODE (vuse) == SSA_NAME);
+      def_stmt = SSA_NAME_DEF_STMT (vuse);
+
+      /* If there is no useful statement for this VUSE, we'll not find a
+        useful expression to return either.  Likewise, if there is a
+        statement but it is not a simple assignment or it has virtual
+        uses, we can stop right here.  Note that this means we do
+        not look through PHI nodes, which is intentional.  */
+      if (!def_stmt
+         || TREE_CODE (def_stmt) != MODIFY_EXPR
+         || !ZERO_SSA_OPERANDS (def_stmt, SSA_OP_VIRTUAL_USES))
+       return false;
+
+      /* If this is not the same statement as one we have looked at for
+        another VUSE of STMT already, we have two statements producing
+        something that reaches our STMT.  */
+      if (store_stmt && store_stmt != def_stmt)
+       return false;
+      else
+       {
+         /* Is this a store to the exact same location as the one we are
+            loading from in STMT?  */
+         if (!operand_equal_p (TREE_OPERAND (def_stmt, 0), mem_ref, 0))
+           return false;
+
+         /* Otherwise remember this statement and see if all other VUSEs
+            come from the same statement.  */
+         store_stmt = def_stmt;
+       }
+    }
+
+  /* Alright then, we have visited all VUSEs of STMT and we've determined
+     that all of them come from the same statement STORE_STMT.  See if there
+     is a useful expression we can deduce from STORE_STMT.  */
+  rhs = TREE_OPERAND (store_stmt, 1);
+  if (TREE_CODE (rhs) == SSA_NAME
+      || is_gimple_min_invariant (rhs)
+      || TREE_CODE (rhs) == ADDR_EXPR
+      || TREE_INVARIANT (rhs))
+    {
+      /* Yay!  Compute a value number for the RHS of the statement and
+        add its value to the AVAIL_OUT set for the block.  Add the LHS
+        to TMP_GEN.  */
+      add_to_sets (lhs, rhs, store_stmt, TMP_GEN (block), AVAIL_OUT (block));
+      if (TREE_CODE (rhs) == SSA_NAME
+         && !is_undefined_value (rhs))
+       value_insert_into_set (EXP_GEN (block), rhs);
+      return true;
+    }
+
+  return false;
+}
+
 /* Compute the AVAIL set for all basic blocks.
 
    This function performs value numbering of the statements in each basic
 /* Compute the AVAIL set for all basic blocks.
 
    This function performs value numbering of the statements in each basic
@@ -2226,6 +2295,12 @@ compute_avail (void)
              tree lhs = TREE_OPERAND (stmt, 0);
              tree rhs = TREE_OPERAND (stmt, 1);
 
              tree lhs = TREE_OPERAND (stmt, 0);
              tree rhs = TREE_OPERAND (stmt, 1);
 
+             /* Try to look through loads.  */
+             if (TREE_CODE (lhs) == SSA_NAME
+                 && !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES)
+                 && try_look_through_load (lhs, rhs, stmt, block))
+               continue;
+
              STRIP_USELESS_TYPE_CONVERSION (rhs);
              if (UNARY_CLASS_P (rhs)
                  || BINARY_CLASS_P (rhs)
              STRIP_USELESS_TYPE_CONVERSION (rhs);
              if (UNARY_CLASS_P (rhs)
                  || BINARY_CLASS_P (rhs)