Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-ssa-phiprop.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 58ad6c70ea60 |
children | b7f97abdc517 |
line wrap: on
line diff
--- a/gcc/tree-ssa-phiprop.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/tree-ssa-phiprop.c Fri Feb 12 23:39:51 2010 +0900 @@ -90,12 +90,12 @@ /* Structure to keep track of the value of a dereferenced PHI result - and the set of virtual operands used for that dereference. */ + and the virtual operand used for that dereference. */ struct phiprop_d { tree value; - gimple vop_stmt; + tree vuse; }; /* Verify if the value recorded for NAME in PHIVN is still valid at @@ -104,34 +104,27 @@ static bool phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb) { - gimple vop_stmt = phivn[SSA_NAME_VERSION (name)].vop_stmt; - ssa_op_iter ui; - tree vuse; + tree vuse = phivn[SSA_NAME_VERSION (name)].vuse; + gimple use_stmt; + imm_use_iterator ui2; + bool ok = true; - /* The def stmts of all virtual uses need to be post-dominated - by bb. */ - FOR_EACH_SSA_TREE_OPERAND (vuse, vop_stmt, ui, SSA_OP_VUSE) - { - gimple use_stmt; - imm_use_iterator ui2; - bool ok = true; + /* The def stmts of the virtual uses need to be dominated by bb. */ + gcc_assert (vuse != NULL_TREE); - FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse) + FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse) + { + /* If BB does not dominate a VDEF, the value is invalid. */ + if ((gimple_vdef (use_stmt) != NULL_TREE + || gimple_code (use_stmt) == GIMPLE_PHI) + && !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb)) { - /* If BB does not dominate a VDEF, the value is invalid. */ - if ((!ZERO_SSA_OPERANDS (use_stmt, SSA_OP_VDEF) - || gimple_code (use_stmt) == GIMPLE_PHI) - && !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb)) - { - ok = false; - BREAK_FROM_IMM_USE_STMT (ui2); - } + ok = false; + BREAK_FROM_IMM_USE_STMT (ui2); } - if (!ok) - return false; } - return true; + return ok; } /* Insert a new phi node for the dereference of PHI at basic_block @@ -154,25 +147,45 @@ res = gimple_assign_lhs (use_stmt); SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Inserting PHI for result of load "); + print_gimple_stmt (dump_file, use_stmt, 0, 0); + } + /* Add PHI arguments for each edge inserting loads of the addressable operands. */ FOR_EACH_EDGE (e, ei, bb->preds) { tree old_arg, new_var; gimple tmp; + source_location locus; old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e); + locus = gimple_phi_arg_location_from_edge (phi, e); while (TREE_CODE (old_arg) == SSA_NAME && (SSA_NAME_VERSION (old_arg) >= n || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE)) { gimple def_stmt = SSA_NAME_DEF_STMT (old_arg); old_arg = gimple_assign_rhs1 (def_stmt); + locus = gimple_location (def_stmt); } if (TREE_CODE (old_arg) == SSA_NAME) - /* Reuse a formerly created dereference. */ - new_var = phivn[SSA_NAME_VERSION (old_arg)].value; + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " for edge defining "); + print_generic_expr (dump_file, PHI_ARG_DEF_FROM_EDGE (phi, e), 0); + fprintf (dump_file, " reusing PHI result "); + print_generic_expr (dump_file, + phivn[SSA_NAME_VERSION (old_arg)].value, 0); + fprintf (dump_file, "\n"); + } + /* Reuse a formerly created dereference. */ + new_var = phivn[SSA_NAME_VERSION (old_arg)].value; + } else { gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR); @@ -186,18 +199,28 @@ add_referenced_var (new_var); new_var = make_ssa_name (new_var, tmp); gimple_assign_set_lhs (tmp, new_var); + gimple_set_location (tmp, locus); gsi_insert_on_edge (e, tmp); + update_stmt (tmp); - update_stmt (tmp); - mark_symbols_for_renaming (tmp); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " for edge defining "); + print_generic_expr (dump_file, PHI_ARG_DEF_FROM_EDGE (phi, e), 0); + fprintf (dump_file, " inserting load "); + print_gimple_stmt (dump_file, tmp, 0, 0); + } } - add_phi_arg (new_phi, new_var, e); + add_phi_arg (new_phi, new_var, e, locus); } update_stmt (new_phi); + if (dump_file && (dump_flags & TDF_DETAILS)) + print_gimple_stmt (dump_file, new_phi, 0, 0); + return res; } @@ -228,8 +251,7 @@ ssa_op_iter i; bool phi_inserted; - if (MTAG_P (SSA_NAME_VAR (ptr)) - || !POINTER_TYPE_P (TREE_TYPE (ptr)) + if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr)))) return false; @@ -254,6 +276,7 @@ /* Avoid to have to decay *&a to a[0] later. */ || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0)))) && !(TREE_CODE (arg) == SSA_NAME + && SSA_NAME_VERSION (arg) < n && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE && phivn_valid_p (phivn, arg, bb))) return false; @@ -270,29 +293,27 @@ phi_inserted = false; FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) { - ssa_op_iter ui2; + gimple def_stmt; tree vuse; /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) - && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME + && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr /* We cannot replace a load that may throw or is volatile. */ && !stmt_can_throw_internal (use_stmt))) continue; - /* Check if we can move the loads. The def stmts of all virtual uses - need to be post-dominated by bb. */ - FOR_EACH_SSA_TREE_OPERAND (vuse, use_stmt, ui2, SSA_OP_VUSE) - { - gimple def_stmt = SSA_NAME_DEF_STMT (vuse); - if (!SSA_NAME_IS_DEFAULT_DEF (vuse) - && (gimple_bb (def_stmt) == bb - || !dominated_by_p (CDI_DOMINATORS, - bb, gimple_bb (def_stmt)))) - goto next; - } + /* Check if we can move the loads. The def stmt of the virtual use + needs to be in a different basic block dominating bb. */ + vuse = gimple_vuse (use_stmt); + def_stmt = SSA_NAME_DEF_STMT (vuse); + if (!SSA_NAME_IS_DEFAULT_DEF (vuse) + && (gimple_bb (def_stmt) == bb + || !dominated_by_p (CDI_DOMINATORS, + bb, gimple_bb (def_stmt)))) + goto next; /* Found a proper dereference. Insert a phi node if this is the first load transformation. */ @@ -302,7 +323,7 @@ /* Remember the value we created for *ptr. */ phivn[SSA_NAME_VERSION (ptr)].value = res; - phivn[SSA_NAME_VERSION (ptr)].vop_stmt = use_stmt; + phivn[SSA_NAME_VERSION (ptr)].vuse = vuse; /* Remove old stmt. The phi is taken care of by DCE, if we want to delete it here we also have to delete all intermediate @@ -327,41 +348,35 @@ return phi_inserted; } -/* Helper walking the dominator tree starting from BB and processing - phi nodes with global data PHIVN and N. */ - -static bool -tree_ssa_phiprop_1 (basic_block bb, struct phiprop_d *phivn, size_t n) -{ - bool did_something = false; - basic_block son; - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n); - - for (son = first_dom_son (CDI_DOMINATORS, bb); - son; - son = next_dom_son (CDI_DOMINATORS, son)) - did_something |= tree_ssa_phiprop_1 (son, phivn, n); - - return did_something; -} - /* Main entry for phiprop pass. */ static unsigned int tree_ssa_phiprop (void) { + VEC(basic_block, heap) *bbs; struct phiprop_d *phivn; + bool did_something = false; + basic_block bb; + gimple_stmt_iterator gsi; + unsigned i; + size_t n; calculate_dominance_info (CDI_DOMINATORS); - phivn = XCNEWVEC (struct phiprop_d, num_ssa_names); + n = num_ssa_names; + phivn = XCNEWVEC (struct phiprop_d, n); - if (tree_ssa_phiprop_1 (ENTRY_BLOCK_PTR, phivn, num_ssa_names)) + /* 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 (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n); + + if (did_something) gsi_commit_edge_inserts (); + VEC_free (basic_block, heap, bbs); free (phivn); return 0; @@ -370,10 +385,10 @@ static bool gate_phiprop (void) { - return 1; + return flag_tree_phiprop; } -struct gimple_opt_pass pass_phiprop = +struct gimple_opt_pass pass_phiprop = { { GIMPLE_PASS,