Commit db04bcf2 by Richard Biener Committed by Richard Biener

tree-ssa-pre.c (NECESSARY): Remove.

2017-09-06  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (NECESSARY): Remove.
	(create_expression_by_pieces): Do not touch pass-local flags.
	(insert_into_preds_of_block): Likewise.
	(do_pre_regular_insertion): Likewise.
	(eliminate_insert): Likewise.
	(eliminate_dom_walker::before_dom_children): Likewise.
	(fini_eliminate): Do not look at inserted_exprs.
	(mark_operand_necessary): Remove.
	(remove_dead_inserted_code): Replace with simple work-list
	algorithm based on inserted_exprs and SSA uses.
	(pass_pre::execute): Re-order fini_eliminate and
	remove_dead_inserted_code.

From-SVN: r251798
parent c48e0f27
2017-09-06 Richard Biener <rguenther@suse.de>
* tree-ssa-pre.c (NECESSARY): Remove.
(create_expression_by_pieces): Do not touch pass-local flags.
(insert_into_preds_of_block): Likewise.
(do_pre_regular_insertion): Likewise.
(eliminate_insert): Likewise.
(eliminate_dom_walker::before_dom_children): Likewise.
(fini_eliminate): Do not look at inserted_exprs.
(mark_operand_necessary): Remove.
(remove_dead_inserted_code): Replace with simple work-list
algorithm based on inserted_exprs and SSA uses.
(pass_pre::execute): Re-order fini_eliminate and
remove_dead_inserted_code.
2017-09-06 Olivier Hainque <hainque@adacore.com>
* config/powerpcspe/vxworks.h (VXCPU_FOR_8548): Correct definition
......
......@@ -2753,8 +2753,6 @@ find_or_generate_expression (basic_block block, tree op, gimple_seq *stmts)
return NULL_TREE;
}
#define NECESSARY GF_PLF_1
/* Create an expression in pieces, so that we can handle very complex
expressions that may be ANTIC, but not necessary GIMPLE.
BLOCK is the basic block the expression will be inserted into,
......@@ -2972,7 +2970,6 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
}
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
gimple_set_plf (stmt, NECESSARY, false);
}
gimple_seq_add_seq (stmts, forced_stmts);
}
......@@ -3095,7 +3092,6 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
temp = make_temp_ssa_name (type, NULL, "prephitmp");
phi = create_phi_node (temp, block);
gimple_set_plf (phi, NECESSARY, false);
VN_INFO_GET (temp)->value_id = val;
VN_INFO (temp)->valnum = sccvn_valnum_from_value_id (val);
if (VN_INFO (temp)->valnum == NULL_TREE)
......@@ -3342,7 +3338,6 @@ do_pre_regular_insertion (basic_block block, basic_block dom)
gimple_stmt_iterator gsi = gsi_after_labels (block);
gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
gimple_set_plf (assign, NECESSARY, false);
VN_INFO_GET (temp)->value_id = val;
VN_INFO (temp)->valnum = sccvn_valnum_from_value_id (val);
if (VN_INFO (temp)->valnum == NULL_TREE)
......@@ -4204,9 +4199,6 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
{
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
VN_INFO_GET (res)->valnum = val;
if (TREE_CODE (leader) == SSA_NAME)
gimple_set_plf (SSA_NAME_DEF_STMT (leader), NECESSARY, true);
}
pre_stats.insertions++;
......@@ -4291,17 +4283,9 @@ eliminate_dom_walker::before_dom_children (basic_block b)
remove_phi_node (&gsi, false);
if (inserted_exprs
&& !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res))
&& TREE_CODE (sprime) == SSA_NAME)
gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
sprime = fold_convert (TREE_TYPE (res), sprime);
gimple *stmt = gimple_build_assign (res, sprime);
/* ??? It cannot yet be necessary (DOM walk). */
gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY));
gimple_stmt_iterator gsi2 = gsi_after_labels (b);
gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
continue;
......@@ -4478,10 +4462,6 @@ eliminate_dom_walker::before_dom_children (basic_block b)
print_gimple_stmt (dump_file, stmt, 0);
}
if (TREE_CODE (sprime) == SSA_NAME)
gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
NECESSARY, true);
pre_stats.eliminations++;
gimple *orig_stmt = stmt;
if (!useless_type_conversion_p (TREE_TYPE (lhs),
......@@ -4615,10 +4595,6 @@ eliminate_dom_walker::before_dom_children (basic_block b)
{
propagate_value (use_p, sprime);
modified = true;
if (TREE_CODE (sprime) == SSA_NAME
&& !is_gimple_debug (stmt))
gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
NECESSARY, true);
}
}
......@@ -4787,11 +4763,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
continue;
tree sprime = eliminate_avail (arg);
if (sprime && may_propagate_copy (arg, sprime))
{
propagate_value (use_p, sprime);
if (TREE_CODE (sprime) == SSA_NAME)
gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
}
propagate_value (use_p, sprime);
}
return NULL;
}
......@@ -4853,18 +4825,6 @@ fini_eliminate (void)
{
stmt = el_to_remove.pop ();
tree lhs;
if (gimple_code (stmt) == GIMPLE_PHI)
lhs = gimple_phi_result (stmt);
else
lhs = gimple_get_lhs (stmt);
if (inserted_exprs
&& lhs
&& TREE_CODE (lhs) == SSA_NAME
&& bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs)))
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing dead stmt ");
......@@ -4926,36 +4886,9 @@ fini_eliminate (void)
return todo;
}
/* Borrow a bit of tree-ssa-dce.c for the moment.
XXX: In 4.1, we should be able to just run a DCE pass after PRE, though
this may be a bit faster, and we may want critical edges kept split. */
/* If OP's defining statement has not already been determined to be necessary,
mark that statement necessary. Return the stmt, if it is newly
necessary. */
static inline gimple *
mark_operand_necessary (tree op)
{
gimple *stmt;
gcc_assert (op);
if (TREE_CODE (op) != SSA_NAME)
return NULL;
/* Cheap DCE of a known set of possibly dead stmts.
stmt = SSA_NAME_DEF_STMT (op);
gcc_assert (stmt);
if (gimple_plf (stmt, NECESSARY)
|| gimple_nop_p (stmt))
return NULL;
gimple_set_plf (stmt, NECESSARY, true);
return stmt;
}
/* Because we don't follow exactly the standard PRE algorithm, and decide not
Because we don't follow exactly the standard PRE algorithm, and decide not
to insert PHI nodes sometimes, and because value numbering of casts isn't
perfect, we sometimes end up inserting dead code. This simple DCE-like
pass removes any insertions we made that weren't actually used. */
......@@ -4963,99 +4896,50 @@ mark_operand_necessary (tree op)
static void
remove_dead_inserted_code (void)
{
unsigned i;
bitmap_iterator bi;
gimple *t;
auto_bitmap worklist;
EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
/* ??? Re-use inserted_exprs as worklist not only as initial set.
This may end up removing non-inserted code as well. If we
keep inserted_exprs unchanged we could restrict new worklist
elements to members of inserted_exprs. */
bitmap worklist = inserted_exprs;
while (! bitmap_empty_p (worklist))
{
t = SSA_NAME_DEF_STMT (ssa_name (i));
if (gimple_plf (t, NECESSARY))
bitmap_set_bit (worklist, i);
}
while (!bitmap_empty_p (worklist))
{
i = bitmap_first_set_bit (worklist);
/* Pop item. */
unsigned i = bitmap_first_set_bit (worklist);
bitmap_clear_bit (worklist, i);
t = SSA_NAME_DEF_STMT (ssa_name (i));
/* PHI nodes are somewhat special in that each PHI alternative has
data and control dependencies. All the statements feeding the
PHI node's arguments are always necessary. */
if (gimple_code (t) == GIMPLE_PHI)
{
unsigned k;
for (k = 0; k < gimple_phi_num_args (t); k++)
{
tree arg = PHI_ARG_DEF (t, k);
if (TREE_CODE (arg) == SSA_NAME)
{
gimple *n = mark_operand_necessary (arg);
if (n)
bitmap_set_bit (worklist, SSA_NAME_VERSION (arg));
}
}
}
else
{
/* Propagate through the operands. Examine all the USE, VUSE and
VDEF operands in this statement. Mark all the statements
which feed this statement's uses as necessary. */
ssa_op_iter iter;
tree use;
tree def = ssa_name (i);
/* Removed by somebody else or still in use. */
if (! def || ! has_zero_uses (def))
continue;
/* The operands of VDEF expressions are also needed as they
represent potential definitions that may reach this
statement (VDEF operands allow us to follow def-def
links). */
gimple *t = SSA_NAME_DEF_STMT (def);
FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
{
gimple *n = mark_operand_necessary (use);
if (n)
bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
}
/* Add uses to the worklist. */
ssa_op_iter iter;
use_operand_p use_p;
FOR_EACH_PHI_OR_STMT_USE (use_p, t, iter, SSA_OP_USE)
{
tree use = USE_FROM_PTR (use_p);
if (TREE_CODE (use) == SSA_NAME
&& ! SSA_NAME_IS_DEFAULT_DEF (use))
bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
}
}
unsigned int to_clear = -1U;
EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
{
if (to_clear != -1U)
/* Remove stmt. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
bitmap_clear_bit (inserted_exprs, to_clear);
to_clear = -1U;
fprintf (dump_file, "Removing unnecessary insertion:");
print_gimple_stmt (dump_file, t, 0);
}
t = SSA_NAME_DEF_STMT (ssa_name (i));
if (!gimple_plf (t, NECESSARY))
gimple_stmt_iterator gsi = gsi_for_stmt (t);
if (gimple_code (t) == GIMPLE_PHI)
remove_phi_node (&gsi, true);
else
{
gimple_stmt_iterator gsi;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing unnecessary insertion:");
print_gimple_stmt (dump_file, t, 0);
}
gsi = gsi_for_stmt (t);
if (gimple_code (t) == GIMPLE_PHI)
remove_phi_node (&gsi, true);
else
{
gsi_remove (&gsi, true);
release_defs (t);
}
gsi_remove (&gsi, true);
release_defs (t);
}
else
/* eliminate_fini will skip stmts marked for removal if we
already removed it and uses inserted_exprs for this, so
clear those we didn't end up removing. */
to_clear = i;
}
if (to_clear != -1U)
bitmap_clear_bit (inserted_exprs, to_clear);
}
......@@ -5196,10 +5080,10 @@ pass_pre::execute (function *fun)
statistics_counter_event (fun, "Eliminated", pre_stats.eliminations);
clear_expression_ids ();
remove_dead_inserted_code ();
scev_finalize ();
todo |= fini_eliminate ();
remove_dead_inserted_code ();
fini_pre ();
loop_optimizer_finalize ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment