Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-ssa-phiprop.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/tree-ssa-phiprop.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/tree-ssa-phiprop.c Tue Mar 22 17:18:12 2011 +0900 @@ -26,7 +26,6 @@ #include "tm_p.h" #include "basic-block.h" #include "timevar.h" -#include "diagnostic.h" #include "tree-pretty-print.h" #include "gimple-pretty-print.h" #include "tree-flow.h" @@ -140,7 +139,7 @@ edge e; gcc_assert (is_gimple_assign (use_stmt) - && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF); + && gimple_assign_rhs_code (use_stmt) == MEM_REF); /* Build a new PHI node to replace the definition of the indirect reference lhs. */ @@ -188,10 +187,17 @@ } else { + tree rhs = gimple_assign_rhs1 (use_stmt); gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR); - old_arg = TREE_OPERAND (old_arg, 0); - new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL); - tmp = gimple_build_assign (new_var, unshare_expr (old_arg)); + new_var = create_tmp_reg (TREE_TYPE (rhs), NULL); + if (!is_gimple_min_invariant (old_arg)) + old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e); + else + old_arg = unshare_expr (old_arg); + tmp = gimple_build_assign (new_var, + fold_build2 (MEM_REF, TREE_TYPE (rhs), + old_arg, + TREE_OPERAND (rhs, 1))); gcc_assert (is_gimple_reg (new_var)); add_referenced_var (new_var); new_var = make_ssa_name (new_var, tmp); @@ -247,6 +253,8 @@ use_operand_p arg_p, use; ssa_op_iter i; bool phi_inserted; + tree type = NULL_TREE; + bool one_invariant = false; if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr)))) @@ -269,16 +277,29 @@ return false; arg = gimple_assign_rhs1 (def_stmt); } - if ((TREE_CODE (arg) != ADDR_EXPR - /* Avoid to have to decay *&a to a[0] later. */ - || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0)))) + if (TREE_CODE (arg) != ADDR_EXPR && !(TREE_CODE (arg) == SSA_NAME && SSA_NAME_VERSION (arg) < n && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE + && (!type + || types_compatible_p + (type, TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value))) && phivn_valid_p (phivn, arg, bb))) return false; + if (!type + && TREE_CODE (arg) == SSA_NAME) + type = TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value); + if (TREE_CODE (arg) == ADDR_EXPR + && is_gimple_min_invariant (arg)) + one_invariant = true; } + /* If we neither have an address of a decl nor can reuse a previously + inserted load, do not hoist anything. */ + if (!one_invariant + && !type) + return false; + /* Find a dereferencing use. First follow (single use) ssa copy chains for ptr. */ while (single_imm_use (ptr, &use, &use_stmt) @@ -296,8 +317,12 @@ /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME - && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF + && gimple_assign_rhs_code (use_stmt) == MEM_REF && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr + && integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1)) + && (!type + || types_compatible_p + (TREE_TYPE (gimple_assign_lhs (use_stmt)), type)) /* We cannot replace a load that may throw or is volatile. */ && !stmt_can_throw_internal (use_stmt))) continue; @@ -317,6 +342,7 @@ if (!phi_inserted) { res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n); + type = TREE_TYPE (res); /* Remember the value we created for *ptr. */ phivn[SSA_NAME_VERSION (ptr)].value = res; @@ -326,7 +352,7 @@ want to delete it here we also have to delete all intermediate copies. */ gsi = gsi_for_stmt (use_stmt); - gsi_remove (&gsi, false); + gsi_remove (&gsi, true); phi_inserted = true; } @@ -366,7 +392,7 @@ /* Walk the dominator tree in preorder. */ bbs = get_all_dominated_blocks (CDI_DOMINATORS, single_succ (ENTRY_BLOCK_PTR)); - for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i) + FOR_EACH_VEC_ELT (basic_block, bbs, i, bb) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n);