X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-pre.c;h=425d2204a3c2442dd00e39f9d0371fc67fba977f;hb=92264cad834c0a11f72bee1702460d1500871471;hp=67bc6d4dd5813ca19d106040be39ed8fb09309dd;hpb=73e4e0cc9a578f9e55baf3d86552582170b95b3c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 67bc6d4dd58..425d2204a3c 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -2136,6 +2136,77 @@ can_value_number_call (tree stmt) 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 + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs)) + || 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 @@ -2226,6 +2297,12 @@ compute_avail (void) 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) @@ -2247,7 +2324,8 @@ compute_avail (void) continue; } } - else if (TREE_CODE (rhs) == SSA_NAME + else if ((TREE_CODE (rhs) == SSA_NAME + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs)) || is_gimple_min_invariant (rhs) || TREE_CODE (rhs) == ADDR_EXPR || TREE_INVARIANT (rhs) @@ -2807,6 +2885,7 @@ do_eustores (void) if (NUM_SSA_OPERANDS (found, SSA_OP_VUSE) != 1 || VUSE_OP (VUSE_OPS (found)) != kill + || !DECL_P (TREE_OPERAND (stmt, 0)) || !operand_equal_p (TREE_OPERAND (found, 1), TREE_OPERAND (stmt, 0), 0)) {