Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(866)

Unified Diff: gcc/gcc/tree-ssa-phiprop.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gcc/tree-ssa-math-opts.c ('k') | gcc/gcc/tree-ssa-pre.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gcc/tree-ssa-phiprop.c
diff --git a/gcc/gcc/tree-ssa-phiprop.c b/gcc/gcc/tree-ssa-phiprop.c
index 1b9c6fa85b5abf8b2ddcd25db8c91baeea46d07c..fcd1d23bac8f08e5436c25a72b19047be21edd4b 100644
--- a/gcc/gcc/tree-ssa-phiprop.c
+++ b/gcc/gcc/tree-ssa-phiprop.c
@@ -90,12 +90,12 @@ along with GCC; see the file COPYING3. If not see
/* 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 @@ struct phiprop_d
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 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
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 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
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);
- 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 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
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 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
/* 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 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
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 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
/* 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 @@ next:;
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);
+
+ /* 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 (tree_ssa_phiprop_1 (ENTRY_BLOCK_PTR, phivn, num_ssa_names))
+ if (did_something)
gsi_commit_edge_inserts ();
+ VEC_free (basic_block, heap, bbs);
free (phivn);
return 0;
@@ -370,10 +385,10 @@ tree_ssa_phiprop (void)
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,
« no previous file with comments | « gcc/gcc/tree-ssa-math-opts.c ('k') | gcc/gcc/tree-ssa-pre.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698