Mercurial > hg > CbC > CbC_gcc
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;