mirror of git://gcc.gnu.org/git/gcc.git
tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Rewrite to propagate the VN result into all uses where possible and to remove...
2014-06-13 Richard Biener <rguenther@suse.de> * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Rewrite to propagate the VN result into all uses where possible and to remove stmts becoming dead because of that. (eliminate): Generalize stmt removal handling, remove in reverse dominator order to support proper debug stmt generation. Update stmts before removing stmts. * tree-ssa-propagate.c (propagate_tree_value): Remove bogus assert. * c-c++-common/pr46562-2.c: Adjust. * g++.dg/tree-ssa/pr8781.C: Likewise. * gcc.dg/tree-ssa/ssa-fre-24.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-25.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-32.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-39.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-16.c: Likewise. From-SVN: r211625
This commit is contained in:
parent
80298c3b46
commit
6aa4c5b68d
|
|
@ -1,3 +1,14 @@
|
||||||
|
2014-06-13 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
|
||||||
|
Rewrite to propagate the VN result into all uses where
|
||||||
|
possible and to remove stmts becoming dead because of that.
|
||||||
|
(eliminate): Generalize stmt removal handling, remove in
|
||||||
|
reverse dominator order to support proper debug stmt
|
||||||
|
generation. Update stmts before removing stmts.
|
||||||
|
* tree-ssa-propagate.c (propagate_tree_value): Remove
|
||||||
|
bogus assert.
|
||||||
|
|
||||||
2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||||
|
|
||||||
PR tree-optimization/61375
|
PR tree-optimization/61375
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
2014-06-13 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* c-c++-common/pr46562-2.c: Adjust.
|
||||||
|
* g++.dg/tree-ssa/pr8781.C: Likewise.
|
||||||
|
* gcc.dg/tree-ssa/ssa-fre-24.c: Likewise.
|
||||||
|
* gcc.dg/tree-ssa/ssa-fre-25.c: Likewise.
|
||||||
|
* gcc.dg/tree-ssa/ssa-fre-32.c: Likewise.
|
||||||
|
* gcc.dg/tree-ssa/ssa-fre-39.c: Likewise.
|
||||||
|
* gcc.dg/tree-ssa/ssa-pre-16.c: Likewise.
|
||||||
|
|
||||||
2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||||
|
|
||||||
PR tree-optimization/61375
|
PR tree-optimization/61375
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@ int foo(void)
|
||||||
return *p;
|
return *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump "= 0;" "fre1" } } */
|
/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1-details" } */
|
/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1" } */
|
||||||
|
|
||||||
int f();
|
int f();
|
||||||
|
|
||||||
|
|
@ -24,5 +24,5 @@ int x()
|
||||||
|
|
||||||
/* We should optimize this to a direct call. */
|
/* We should optimize this to a direct call. */
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump "converting indirect call to function int f()" "fre1" } } */
|
/* { dg-final { scan-tree-dump-times "= f \\(\\);" 1 "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -30,5 +30,5 @@ int bazzoo (void)
|
||||||
return b.i;
|
return b.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump-times "= 0;" 5 "fre1" } } */
|
/* { dg-final { scan-tree-dump-times "return 0;" 4 "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,5 @@ int foo (struct X *p)
|
||||||
|
|
||||||
/* We should optimize this to return 0. */
|
/* We should optimize this to return 0. */
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump "= 0;" "fre1" } } */
|
/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,6 @@ bar (_Complex float x)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We should CSE all the way to replace the final assignment to z with x. */
|
/* We should CSE all the way to replace the return value with x. */
|
||||||
/* { dg-final { scan-tree-dump-times "with x_1\\\(D\\\) in z" 3 "fre1" } } */
|
/* { dg-final { scan-tree-dump-times "return x_\\d\+\\(D\\);" 2 "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,5 @@ int foo (int i)
|
||||||
|
|
||||||
/* We should be able to value-number the final assignment to k to 1. */
|
/* We should be able to value-number the final assignment to k to 1. */
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump "k_. = 1;" "fre1" } } */
|
/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */
|
||||||
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
/* { dg-final { cleanup-tree-dump "fre1" } } */
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,5 @@ int foo(int k, int *x)
|
||||||
} while (++j<k);
|
} while (++j<k);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */
|
/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
|
||||||
/* { dg-final { cleanup-tree-dump "pre" } } */
|
/* { dg-final { cleanup-tree-dump "pre" } } */
|
||||||
|
|
|
||||||
|
|
@ -4012,120 +4012,93 @@ eliminate_dom_walker::before_dom_children (basic_block b)
|
||||||
/* Mark new bb. */
|
/* Mark new bb. */
|
||||||
el_avail_stack.safe_push (NULL_TREE);
|
el_avail_stack.safe_push (NULL_TREE);
|
||||||
|
|
||||||
/* If this block is not reachable do nothing. */
|
/* ??? If we do nothing for unreachable blocks then this will confuse
|
||||||
edge_iterator ei;
|
tailmerging. Eventually we can reduce its reliance on SCCVN now
|
||||||
edge e;
|
that we fully copy/constant-propagate (most) things. */
|
||||||
FOR_EACH_EDGE (e, ei, b->preds)
|
|
||||||
if (e->flags & EDGE_EXECUTABLE)
|
|
||||||
break;
|
|
||||||
if (!e)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
|
for (gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
|
||||||
{
|
{
|
||||||
gimple stmt, phi = gsi_stmt (gsi);
|
gimple phi = gsi_stmt (gsi);
|
||||||
tree sprime = NULL_TREE, res = PHI_RESULT (phi);
|
tree res = PHI_RESULT (phi);
|
||||||
gimple_stmt_iterator gsi2;
|
|
||||||
|
|
||||||
/* We want to perform redundant PHI elimination. Do so by
|
if (virtual_operand_p (res))
|
||||||
replacing the PHI with a single copy if possible.
|
|
||||||
Do not touch inserted, single-argument or virtual PHIs. */
|
|
||||||
if (gimple_phi_num_args (phi) == 1
|
|
||||||
|| virtual_operand_p (res))
|
|
||||||
{
|
{
|
||||||
gsi_next (&gsi);
|
gsi_next (&gsi);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprime = eliminate_avail (res);
|
tree sprime = eliminate_avail (res);
|
||||||
if (!sprime
|
if (sprime
|
||||||
|| sprime == res)
|
&& sprime != res)
|
||||||
{
|
{
|
||||||
eliminate_push_avail (res);
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
gsi_next (&gsi);
|
{
|
||||||
continue;
|
fprintf (dump_file, "Replaced redundant PHI node defining ");
|
||||||
}
|
print_generic_expr (dump_file, res, 0);
|
||||||
else if (is_gimple_min_invariant (sprime))
|
fprintf (dump_file, " with ");
|
||||||
{
|
print_generic_expr (dump_file, sprime, 0);
|
||||||
if (!useless_type_conversion_p (TREE_TYPE (res),
|
fprintf (dump_file, "\n");
|
||||||
TREE_TYPE (sprime)))
|
}
|
||||||
|
|
||||||
|
/* If we inserted this PHI node ourself, it's not an elimination. */
|
||||||
|
if (inserted_exprs
|
||||||
|
&& bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
|
||||||
|
pre_stats.phis--;
|
||||||
|
else
|
||||||
|
pre_stats.eliminations++;
|
||||||
|
|
||||||
|
/* If we will propagate into all uses don't bother to do
|
||||||
|
anything. */
|
||||||
|
if (may_propagate_copy (res, sprime))
|
||||||
|
{
|
||||||
|
/* Mark the PHI for removal. */
|
||||||
|
el_to_remove.safe_push (phi);
|
||||||
|
gsi_next (&gsi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
eliminate_push_avail (res);
|
||||||
{
|
gsi_next (&gsi);
|
||||||
fprintf (dump_file, "Replaced redundant PHI node defining ");
|
|
||||||
print_generic_expr (dump_file, res, 0);
|
|
||||||
fprintf (dump_file, " with ");
|
|
||||||
print_generic_expr (dump_file, sprime, 0);
|
|
||||||
fprintf (dump_file, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
stmt = gimple_build_assign (res, sprime);
|
|
||||||
gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY));
|
|
||||||
|
|
||||||
gsi2 = gsi_after_labels (b);
|
|
||||||
gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
|
|
||||||
/* Queue the copy for eventual removal. */
|
|
||||||
el_to_remove.safe_push (stmt);
|
|
||||||
/* If we inserted this PHI node ourself, it's not an elimination. */
|
|
||||||
if (inserted_exprs
|
|
||||||
&& bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
|
|
||||||
pre_stats.phis--;
|
|
||||||
else
|
|
||||||
pre_stats.eliminations++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
|
for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||||
{
|
{
|
||||||
tree lhs = NULL_TREE;
|
tree sprime = NULL_TREE;
|
||||||
tree rhs = NULL_TREE;
|
|
||||||
|
|
||||||
stmt = gsi_stmt (gsi);
|
stmt = gsi_stmt (gsi);
|
||||||
|
tree lhs = gimple_get_lhs (stmt);
|
||||||
if (gimple_has_lhs (stmt))
|
if (lhs && TREE_CODE (lhs) == SSA_NAME
|
||||||
lhs = gimple_get_lhs (stmt);
|
&& !gimple_has_volatile_ops (stmt)
|
||||||
|
|
||||||
if (gimple_assign_single_p (stmt))
|
|
||||||
rhs = gimple_assign_rhs1 (stmt);
|
|
||||||
|
|
||||||
/* Lookup the RHS of the expression, see if we have an
|
|
||||||
available computation for it. If so, replace the RHS with
|
|
||||||
the available computation. */
|
|
||||||
if (gimple_has_lhs (stmt)
|
|
||||||
&& TREE_CODE (lhs) == SSA_NAME
|
|
||||||
&& !gimple_has_volatile_ops (stmt))
|
|
||||||
{
|
|
||||||
tree sprime;
|
|
||||||
gimple orig_stmt = stmt;
|
|
||||||
|
|
||||||
sprime = eliminate_avail (lhs);
|
|
||||||
/* If there is no usable leader mark lhs as leader for its value. */
|
|
||||||
if (!sprime)
|
|
||||||
eliminate_push_avail (lhs);
|
|
||||||
|
|
||||||
/* See PR43491. Do not replace a global register variable when
|
/* See PR43491. Do not replace a global register variable when
|
||||||
it is a the RHS of an assignment. Do replace local register
|
it is a the RHS of an assignment. Do replace local register
|
||||||
variables since gcc does not guarantee a local variable will
|
variables since gcc does not guarantee a local variable will
|
||||||
be allocated in register.
|
be allocated in register.
|
||||||
Do not perform copy propagation or undo constant propagation. */
|
??? The fix isn't effective here. This should instead
|
||||||
if (gimple_assign_single_p (stmt)
|
be ensured by not value-numbering them the same but treating
|
||||||
&& (TREE_CODE (rhs) == SSA_NAME
|
them like volatiles? */
|
||||||
|| is_gimple_min_invariant (rhs)
|
&& !(gimple_assign_single_p (stmt)
|
||||||
|| (TREE_CODE (rhs) == VAR_DECL
|
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
|
||||||
&& is_global_var (rhs)
|
&& DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
|
||||||
&& DECL_HARD_REGISTER (rhs))))
|
&& is_global_var (gimple_assign_rhs1 (stmt)))))
|
||||||
continue;
|
{
|
||||||
|
sprime = eliminate_avail (lhs);
|
||||||
if (!sprime)
|
if (!sprime)
|
||||||
{
|
{
|
||||||
/* If there is no existing usable leader but SCCVN thinks
|
/* If there is no existing usable leader but SCCVN thinks
|
||||||
|
|
@ -4139,108 +4112,129 @@ eliminate_dom_walker::before_dom_children (basic_block b)
|
||||||
&& (sprime = eliminate_insert (&gsi, val)) != NULL_TREE)
|
&& (sprime = eliminate_insert (&gsi, val)) != NULL_TREE)
|
||||||
eliminate_push_avail (sprime);
|
eliminate_push_avail (sprime);
|
||||||
}
|
}
|
||||||
else if (is_gimple_min_invariant (sprime))
|
|
||||||
|
/* If this now constitutes a copy duplicate points-to
|
||||||
|
and range info appropriately. This is especially
|
||||||
|
important for inserted code. See tree-ssa-copy.c
|
||||||
|
for similar code. */
|
||||||
|
if (sprime
|
||||||
|
&& TREE_CODE (sprime) == SSA_NAME)
|
||||||
{
|
{
|
||||||
/* If there is no existing leader but SCCVN knows this
|
basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime));
|
||||||
value is constant, use that constant. */
|
if (POINTER_TYPE_P (TREE_TYPE (lhs))
|
||||||
if (!useless_type_conversion_p (TREE_TYPE (lhs),
|
&& SSA_NAME_PTR_INFO (lhs)
|
||||||
TREE_TYPE (sprime)))
|
&& !SSA_NAME_PTR_INFO (sprime))
|
||||||
sprime = fold_convert (TREE_TYPE (lhs), sprime);
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
{
|
{
|
||||||
fprintf (dump_file, "Replaced ");
|
duplicate_ssa_name_ptr_info (sprime,
|
||||||
print_gimple_expr (dump_file, stmt, 0, 0);
|
SSA_NAME_PTR_INFO (lhs));
|
||||||
fprintf (dump_file, " with ");
|
if (b != sprime_b)
|
||||||
print_generic_expr (dump_file, sprime, 0);
|
mark_ptr_info_alignment_unknown
|
||||||
fprintf (dump_file, " in ");
|
(SSA_NAME_PTR_INFO (sprime));
|
||||||
print_gimple_stmt (dump_file, stmt, 0, 0);
|
|
||||||
}
|
}
|
||||||
pre_stats.eliminations++;
|
else if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|
||||||
|
&& SSA_NAME_RANGE_INFO (lhs)
|
||||||
tree vdef = gimple_vdef (stmt);
|
&& !SSA_NAME_RANGE_INFO (sprime)
|
||||||
tree vuse = gimple_vuse (stmt);
|
&& b == sprime_b)
|
||||||
propagate_tree_value_into_stmt (&gsi, sprime);
|
duplicate_ssa_name_range_info (sprime,
|
||||||
stmt = gsi_stmt (gsi);
|
SSA_NAME_RANGE_TYPE (lhs),
|
||||||
update_stmt (stmt);
|
SSA_NAME_RANGE_INFO (lhs));
|
||||||
if (vdef != gimple_vdef (stmt))
|
|
||||||
VN_INFO (vdef)->valnum = vuse;
|
|
||||||
|
|
||||||
/* If we removed EH side-effects from the statement, clean
|
|
||||||
its EH information. */
|
|
||||||
if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
|
|
||||||
{
|
|
||||||
bitmap_set_bit (need_eh_cleanup,
|
|
||||||
gimple_bb (stmt)->index);
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
fprintf (dump_file, " Removed EH side-effects.\n");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inhibit the use of an inserted PHI on a loop header when
|
||||||
|
the address of the memory reference is a simple induction
|
||||||
|
variable. In other cases the vectorizer won't do anything
|
||||||
|
anyway (either it's loop invariant or a complicated
|
||||||
|
expression). */
|
||||||
if (sprime
|
if (sprime
|
||||||
&& sprime != lhs
|
&& TREE_CODE (sprime) == SSA_NAME
|
||||||
&& (rhs == NULL_TREE
|
&& do_pre
|
||||||
|| TREE_CODE (rhs) != SSA_NAME
|
&& flag_tree_loop_vectorize
|
||||||
|| may_propagate_copy (rhs, sprime)))
|
&& loop_outer (b->loop_father)
|
||||||
|
&& has_zero_uses (sprime)
|
||||||
|
&& bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
|
||||||
|
&& gimple_assign_load_p (stmt))
|
||||||
{
|
{
|
||||||
|
gimple def_stmt = SSA_NAME_DEF_STMT (sprime);
|
||||||
|
basic_block def_bb = gimple_bb (def_stmt);
|
||||||
|
if (gimple_code (def_stmt) == GIMPLE_PHI
|
||||||
|
&& b->loop_father->header == def_bb)
|
||||||
|
{
|
||||||
|
ssa_op_iter iter;
|
||||||
|
tree op;
|
||||||
|
bool found = false;
|
||||||
|
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
|
||||||
|
{
|
||||||
|
affine_iv iv;
|
||||||
|
def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
|
||||||
|
if (def_bb
|
||||||
|
&& flow_bb_inside_loop_p (b->loop_father, def_bb)
|
||||||
|
&& simple_iv (b->loop_father,
|
||||||
|
b->loop_father, op, &iv, true))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "Not replacing ");
|
||||||
|
print_gimple_expr (dump_file, stmt, 0, 0);
|
||||||
|
fprintf (dump_file, " with ");
|
||||||
|
print_generic_expr (dump_file, sprime, 0);
|
||||||
|
fprintf (dump_file, " which would add a loop"
|
||||||
|
" carried dependence to loop %d\n",
|
||||||
|
b->loop_father->num);
|
||||||
|
}
|
||||||
|
/* Don't keep sprime available. */
|
||||||
|
eliminate_push_avail (lhs);
|
||||||
|
sprime = NULL_TREE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprime)
|
||||||
|
{
|
||||||
|
/* If we can propagate the value computed for LHS into
|
||||||
|
all uses don't bother doing anything with this stmt. */
|
||||||
|
if (may_propagate_copy (lhs, sprime))
|
||||||
|
{
|
||||||
|
/* Mark it for removal. */
|
||||||
|
el_to_remove.safe_push (stmt);
|
||||||
|
|
||||||
|
/* ??? Don't count copy/constant propagations. */
|
||||||
|
if (gimple_assign_single_p (stmt)
|
||||||
|
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|
||||||
|
|| gimple_assign_rhs1 (stmt) == sprime))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "Replaced ");
|
||||||
|
print_gimple_expr (dump_file, stmt, 0, 0);
|
||||||
|
fprintf (dump_file, " with ");
|
||||||
|
print_generic_expr (dump_file, sprime, 0);
|
||||||
|
fprintf (dump_file, " in all uses of ");
|
||||||
|
print_gimple_stmt (dump_file, stmt, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_stats.eliminations++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is an assignment from our leader (which
|
||||||
|
happens in the case the value-number is a constant)
|
||||||
|
then there is nothing to do. */
|
||||||
|
if (gimple_assign_single_p (stmt)
|
||||||
|
&& sprime == gimple_assign_rhs1 (stmt))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Else replace its RHS. */
|
||||||
bool can_make_abnormal_goto
|
bool can_make_abnormal_goto
|
||||||
= is_gimple_call (stmt)
|
= is_gimple_call (stmt)
|
||||||
&& stmt_can_make_abnormal_goto (stmt);
|
&& stmt_can_make_abnormal_goto (stmt);
|
||||||
|
|
||||||
gcc_assert (sprime != rhs);
|
|
||||||
|
|
||||||
/* Inhibit the use of an inserted PHI on a loop header when
|
|
||||||
the address of the memory reference is a simple induction
|
|
||||||
variable. In other cases the vectorizer won't do anything
|
|
||||||
anyway (either it's loop invariant or a complicated
|
|
||||||
expression). */
|
|
||||||
if (do_pre
|
|
||||||
&& flag_tree_loop_vectorize
|
|
||||||
&& gimple_assign_single_p (stmt)
|
|
||||||
&& TREE_CODE (sprime) == SSA_NAME
|
|
||||||
&& loop_outer (b->loop_father))
|
|
||||||
{
|
|
||||||
gimple def_stmt = SSA_NAME_DEF_STMT (sprime);
|
|
||||||
basic_block def_bb = gimple_bb (def_stmt);
|
|
||||||
if (gimple_code (def_stmt) == GIMPLE_PHI
|
|
||||||
&& b->loop_father->header == def_bb
|
|
||||||
&& has_zero_uses (sprime))
|
|
||||||
{
|
|
||||||
ssa_op_iter iter;
|
|
||||||
tree op;
|
|
||||||
bool found = false;
|
|
||||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
|
|
||||||
{
|
|
||||||
affine_iv iv;
|
|
||||||
def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
|
|
||||||
if (def_bb
|
|
||||||
&& flow_bb_inside_loop_p (b->loop_father,
|
|
||||||
def_bb)
|
|
||||||
&& simple_iv (b->loop_father,
|
|
||||||
b->loop_father, op, &iv, true))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
{
|
|
||||||
fprintf (dump_file, "Not replacing ");
|
|
||||||
print_gimple_expr (dump_file, stmt, 0, 0);
|
|
||||||
fprintf (dump_file, " with ");
|
|
||||||
print_generic_expr (dump_file, sprime, 0);
|
|
||||||
fprintf (dump_file, " which would add a loop"
|
|
||||||
" carried dependence to loop %d\n",
|
|
||||||
b->loop_father->num);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
{
|
{
|
||||||
fprintf (dump_file, "Replaced ");
|
fprintf (dump_file, "Replaced ");
|
||||||
|
|
@ -4254,16 +4248,12 @@ eliminate_dom_walker::before_dom_children (basic_block b)
|
||||||
if (TREE_CODE (sprime) == SSA_NAME)
|
if (TREE_CODE (sprime) == SSA_NAME)
|
||||||
gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
|
gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
|
||||||
NECESSARY, true);
|
NECESSARY, true);
|
||||||
/* We need to make sure the new and old types actually match,
|
|
||||||
which may require adding a simple cast, which fold_convert
|
|
||||||
will do for us. */
|
|
||||||
if ((!rhs || TREE_CODE (rhs) != SSA_NAME)
|
|
||||||
&& !useless_type_conversion_p (gimple_expr_type (stmt),
|
|
||||||
TREE_TYPE (sprime)))
|
|
||||||
sprime = fold_convert (gimple_expr_type (stmt), sprime);
|
|
||||||
|
|
||||||
pre_stats.eliminations++;
|
pre_stats.eliminations++;
|
||||||
|
gimple orig_stmt = stmt;
|
||||||
|
if (!useless_type_conversion_p (TREE_TYPE (lhs),
|
||||||
|
TREE_TYPE (sprime)))
|
||||||
|
sprime = fold_convert (TREE_TYPE (lhs), sprime);
|
||||||
tree vdef = gimple_vdef (stmt);
|
tree vdef = gimple_vdef (stmt);
|
||||||
tree vuse = gimple_vuse (stmt);
|
tree vuse = gimple_vuse (stmt);
|
||||||
propagate_tree_value_into_stmt (&gsi, sprime);
|
propagate_tree_value_into_stmt (&gsi, sprime);
|
||||||
|
|
@ -4291,135 +4281,183 @@ eliminate_dom_walker::before_dom_children (basic_block b)
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
fprintf (dump_file, " Removed AB side-effects.\n");
|
fprintf (dump_file, " Removed AB side-effects.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the statement is a scalar store, see if the expression
|
/* If the statement is a scalar store, see if the expression
|
||||||
has the same value number as its rhs. If so, the store is
|
has the same value number as its rhs. If so, the store is
|
||||||
dead. */
|
dead. */
|
||||||
else if (gimple_assign_single_p (stmt)
|
if (gimple_assign_single_p (stmt)
|
||||||
&& !gimple_has_volatile_ops (stmt)
|
&& !gimple_has_volatile_ops (stmt)
|
||||||
&& !is_gimple_reg (gimple_assign_lhs (stmt))
|
&& !is_gimple_reg (gimple_assign_lhs (stmt))
|
||||||
&& (TREE_CODE (rhs) == SSA_NAME
|
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|
||||||
|| is_gimple_min_invariant (rhs)))
|
|| is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
|
||||||
{
|
{
|
||||||
tree val;
|
tree val;
|
||||||
val = vn_reference_lookup (gimple_assign_lhs (stmt),
|
tree rhs = gimple_assign_rhs1 (stmt);
|
||||||
gimple_vuse (stmt), VN_WALK, NULL);
|
val = vn_reference_lookup (gimple_assign_lhs (stmt),
|
||||||
if (TREE_CODE (rhs) == SSA_NAME)
|
gimple_vuse (stmt), VN_WALK, NULL);
|
||||||
rhs = VN_INFO (rhs)->valnum;
|
if (TREE_CODE (rhs) == SSA_NAME)
|
||||||
if (val
|
rhs = VN_INFO (rhs)->valnum;
|
||||||
&& operand_equal_p (val, rhs, 0))
|
if (val
|
||||||
{
|
&& operand_equal_p (val, rhs, 0))
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
{
|
||||||
{
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
fprintf (dump_file, "Deleted redundant store ");
|
{
|
||||||
print_gimple_stmt (dump_file, stmt, 0, 0);
|
fprintf (dump_file, "Deleted redundant store ");
|
||||||
}
|
print_gimple_stmt (dump_file, stmt, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Queue stmt for removal. */
|
/* Queue stmt for removal. */
|
||||||
el_to_remove.safe_push (stmt);
|
el_to_remove.safe_push (stmt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
|
||||||
|
bool was_noreturn = (is_gimple_call (stmt)
|
||||||
|
&& gimple_call_noreturn_p (stmt));
|
||||||
|
tree vdef = gimple_vdef (stmt);
|
||||||
|
tree vuse = gimple_vuse (stmt);
|
||||||
|
|
||||||
|
/* If we didn't replace the whole stmt (or propagate the result
|
||||||
|
into all uses), replace all uses on this stmt with their
|
||||||
|
leaders. */
|
||||||
|
use_operand_p use_p;
|
||||||
|
ssa_op_iter iter;
|
||||||
|
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||||
|
{
|
||||||
|
tree use = USE_FROM_PTR (use_p);
|
||||||
|
/* ??? The call code above leaves stmt operands un-updated. */
|
||||||
|
if (TREE_CODE (use) != SSA_NAME)
|
||||||
|
continue;
|
||||||
|
tree sprime = eliminate_avail (use);
|
||||||
|
if (sprime && sprime != use
|
||||||
|
&& may_propagate_copy (use, sprime)
|
||||||
|
/* We substitute into debug stmts to avoid excessive
|
||||||
|
debug temporaries created by removed stmts, but we need
|
||||||
|
to avoid doing so for inserted sprimes as we never want
|
||||||
|
to create debug temporaries for them. */
|
||||||
|
&& (!inserted_exprs
|
||||||
|
|| TREE_CODE (sprime) != SSA_NAME
|
||||||
|
|| !is_gimple_debug (stmt)
|
||||||
|
|| !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
|
||||||
|
{
|
||||||
|
propagate_value (use_p, sprime);
|
||||||
|
gimple_set_modified (stmt, true);
|
||||||
|
if (TREE_CODE (sprime) == SSA_NAME
|
||||||
|
&& !is_gimple_debug (stmt))
|
||||||
|
gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
|
||||||
|
NECESSARY, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Visit COND_EXPRs and fold the comparison with the
|
|
||||||
available value-numbers. */
|
|
||||||
else if (gimple_code (stmt) == GIMPLE_COND)
|
|
||||||
{
|
|
||||||
tree op0 = gimple_cond_lhs (stmt);
|
|
||||||
tree op1 = gimple_cond_rhs (stmt);
|
|
||||||
tree result;
|
|
||||||
|
|
||||||
if (TREE_CODE (op0) == SSA_NAME)
|
|
||||||
op0 = VN_INFO (op0)->valnum;
|
|
||||||
if (TREE_CODE (op1) == SSA_NAME)
|
|
||||||
op1 = VN_INFO (op1)->valnum;
|
|
||||||
result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
|
|
||||||
op0, op1);
|
|
||||||
if (result && TREE_CODE (result) == INTEGER_CST)
|
|
||||||
{
|
|
||||||
if (integer_zerop (result))
|
|
||||||
gimple_cond_make_false (stmt);
|
|
||||||
else
|
|
||||||
gimple_cond_make_true (stmt);
|
|
||||||
update_stmt (stmt);
|
|
||||||
el_todo = TODO_cleanup_cfg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Visit indirect calls and turn them into direct calls if
|
/* Visit indirect calls and turn them into direct calls if
|
||||||
possible. */
|
possible using the devirtualization machinery. */
|
||||||
if (is_gimple_call (stmt))
|
if (is_gimple_call (stmt))
|
||||||
{
|
{
|
||||||
tree orig_fn = gimple_call_fn (stmt);
|
tree fn = gimple_call_fn (stmt);
|
||||||
tree fn;
|
if (fn
|
||||||
if (!orig_fn)
|
&& TREE_CODE (fn) == OBJ_TYPE_REF
|
||||||
continue;
|
&& TREE_CODE (OBJ_TYPE_REF_EXPR (fn)) == SSA_NAME)
|
||||||
if (TREE_CODE (orig_fn) == SSA_NAME)
|
|
||||||
fn = VN_INFO (orig_fn)->valnum;
|
|
||||||
else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF
|
|
||||||
&& TREE_CODE (OBJ_TYPE_REF_EXPR (orig_fn)) == SSA_NAME)
|
|
||||||
{
|
{
|
||||||
fn = VN_INFO (OBJ_TYPE_REF_EXPR (orig_fn))->valnum;
|
fn = ipa_intraprocedural_devirtualization (stmt);
|
||||||
if (!gimple_call_addr_fndecl (fn))
|
if (fn && dbg_cnt (devirt))
|
||||||
{
|
{
|
||||||
fn = ipa_intraprocedural_devirtualization (stmt);
|
if (dump_enabled_p ())
|
||||||
if (fn)
|
{
|
||||||
fn = build_fold_addr_expr (fn);
|
location_t loc = gimple_location (stmt);
|
||||||
|
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
|
||||||
|
"converting indirect call to "
|
||||||
|
"function %s\n",
|
||||||
|
cgraph_get_node (fn)->name ());
|
||||||
|
}
|
||||||
|
gimple_call_set_fndecl (stmt, fn);
|
||||||
|
gimple_set_modified (stmt, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
continue;
|
|
||||||
if (gimple_call_addr_fndecl (fn) != NULL_TREE
|
if (gimple_modified_p (stmt))
|
||||||
&& useless_type_conversion_p (TREE_TYPE (orig_fn),
|
{
|
||||||
TREE_TYPE (fn))
|
/* If a formerly non-invariant ADDR_EXPR is turned into an
|
||||||
&& dbg_cnt (devirt))
|
invariant one it was on a separate stmt. */
|
||||||
|
if (gimple_assign_single_p (stmt)
|
||||||
|
&& TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
|
||||||
|
recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
|
||||||
|
gimple old_stmt = stmt;
|
||||||
|
if (is_gimple_call (stmt))
|
||||||
{
|
{
|
||||||
bool can_make_abnormal_goto
|
/* ??? Only fold calls inplace for now, this may create new
|
||||||
= stmt_can_make_abnormal_goto (stmt);
|
SSA names which in turn will confuse free_scc_vn SSA name
|
||||||
bool was_noreturn = gimple_call_noreturn_p (stmt);
|
release code. */
|
||||||
|
fold_stmt_inplace (&gsi);
|
||||||
if (dump_enabled_p ())
|
|
||||||
{
|
|
||||||
location_t loc = gimple_location (stmt);
|
|
||||||
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
|
|
||||||
"converting indirect call to function %s\n",
|
|
||||||
cgraph_get_node (gimple_call_addr_fndecl (fn))->name ());
|
|
||||||
}
|
|
||||||
|
|
||||||
gimple_call_set_fn (stmt, fn);
|
|
||||||
tree vdef = gimple_vdef (stmt);
|
|
||||||
tree vuse = gimple_vuse (stmt);
|
|
||||||
update_stmt (stmt);
|
|
||||||
if (vdef != gimple_vdef (stmt))
|
|
||||||
VN_INFO (vdef)->valnum = vuse;
|
|
||||||
|
|
||||||
/* When changing a call into a noreturn call, cfg cleanup
|
/* When changing a call into a noreturn call, cfg cleanup
|
||||||
is needed to fix up the noreturn call. */
|
is needed to fix up the noreturn call. */
|
||||||
if (!was_noreturn && gimple_call_noreturn_p (stmt))
|
if (!was_noreturn && gimple_call_noreturn_p (stmt))
|
||||||
el_todo |= TODO_cleanup_cfg;
|
el_todo |= TODO_cleanup_cfg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fold_stmt (&gsi);
|
||||||
|
stmt = gsi_stmt (gsi);
|
||||||
|
if ((gimple_code (stmt) == GIMPLE_COND
|
||||||
|
&& (gimple_cond_true_p (stmt)
|
||||||
|
|| gimple_cond_false_p (stmt)))
|
||||||
|
|| (gimple_code (stmt) == GIMPLE_SWITCH
|
||||||
|
&& TREE_CODE (gimple_switch_index (stmt)) == INTEGER_CST))
|
||||||
|
el_todo |= TODO_cleanup_cfg;
|
||||||
|
}
|
||||||
|
/* If we removed EH side-effects from the statement, clean
|
||||||
|
its EH information. */
|
||||||
|
if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
|
||||||
|
{
|
||||||
|
bitmap_set_bit (need_eh_cleanup,
|
||||||
|
gimple_bb (stmt)->index);
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, " Removed EH side-effects.\n");
|
||||||
|
}
|
||||||
|
/* Likewise for AB side-effects. */
|
||||||
|
if (can_make_abnormal_goto
|
||||||
|
&& !stmt_can_make_abnormal_goto (stmt))
|
||||||
|
{
|
||||||
|
bitmap_set_bit (need_ab_cleanup,
|
||||||
|
gimple_bb (stmt)->index);
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, " Removed AB side-effects.\n");
|
||||||
|
}
|
||||||
|
update_stmt (stmt);
|
||||||
|
if (vdef != gimple_vdef (stmt))
|
||||||
|
VN_INFO (vdef)->valnum = vuse;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we removed EH side-effects from the statement, clean
|
/* Make the new value available - for fully redundant LHS we
|
||||||
its EH information. */
|
continue with the next stmt above. */
|
||||||
if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
|
if (lhs && TREE_CODE (lhs) == SSA_NAME)
|
||||||
{
|
eliminate_push_avail (lhs);
|
||||||
bitmap_set_bit (need_eh_cleanup,
|
}
|
||||||
gimple_bb (stmt)->index);
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
fprintf (dump_file, " Removed EH side-effects.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Likewise for AB side-effects. */
|
/* Replace destination PHI arguments. */
|
||||||
if (can_make_abnormal_goto
|
edge_iterator ei;
|
||||||
&& !stmt_can_make_abnormal_goto (stmt))
|
edge e;
|
||||||
{
|
FOR_EACH_EDGE (e, ei, b->succs)
|
||||||
bitmap_set_bit (need_ab_cleanup,
|
{
|
||||||
gimple_bb (stmt)->index);
|
for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
{
|
||||||
fprintf (dump_file, " Removed AB side-effects.\n");
|
gimple phi = gsi_stmt (gsi);
|
||||||
}
|
use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
|
||||||
|
tree arg = USE_FROM_PTR (use_p);
|
||||||
/* Changing an indirect call to a direct call may
|
if (TREE_CODE (arg) != SSA_NAME
|
||||||
have exposed different semantics. This may
|
|| virtual_operand_p (arg))
|
||||||
require an SSA update. */
|
continue;
|
||||||
el_todo |= TODO_update_ssa_only_virtuals;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4442,7 +4480,6 @@ eliminate (bool do_pre)
|
||||||
{
|
{
|
||||||
gimple_stmt_iterator gsi;
|
gimple_stmt_iterator gsi;
|
||||||
gimple stmt;
|
gimple stmt;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||||
need_ab_cleanup = BITMAP_ALLOC (NULL);
|
need_ab_cleanup = BITMAP_ALLOC (NULL);
|
||||||
|
|
@ -4460,41 +4497,37 @@ eliminate (bool do_pre)
|
||||||
|
|
||||||
/* We cannot remove stmts during BB walk, especially not release SSA
|
/* We cannot remove stmts during BB walk, especially not release SSA
|
||||||
names there as this confuses the VN machinery. The stmts ending
|
names there as this confuses the VN machinery. The stmts ending
|
||||||
up in el_to_remove are either stores or simple copies. */
|
up in el_to_remove are either stores or simple copies.
|
||||||
FOR_EACH_VEC_ELT (el_to_remove, i, stmt)
|
Remove stmts in reverse order to make debug stmt creation possible. */
|
||||||
|
while (!el_to_remove.is_empty ())
|
||||||
{
|
{
|
||||||
tree lhs = gimple_assign_lhs (stmt);
|
stmt = el_to_remove.pop ();
|
||||||
tree rhs = gimple_assign_rhs1 (stmt);
|
|
||||||
use_operand_p use_p;
|
|
||||||
gimple use_stmt;
|
|
||||||
|
|
||||||
/* If there is a single use only, propagate the equivalency
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
instead of keeping the copy. */
|
|
||||||
if (TREE_CODE (lhs) == SSA_NAME
|
|
||||||
&& TREE_CODE (rhs) == SSA_NAME
|
|
||||||
&& single_imm_use (lhs, &use_p, &use_stmt)
|
|
||||||
&& may_propagate_copy (USE_FROM_PTR (use_p), rhs))
|
|
||||||
{
|
{
|
||||||
SET_USE (use_p, rhs);
|
fprintf (dump_file, "Removing dead stmt ");
|
||||||
update_stmt (use_stmt);
|
print_gimple_stmt (dump_file, stmt, 0, 0);
|
||||||
if (inserted_exprs
|
|
||||||
&& bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs))
|
|
||||||
&& TREE_CODE (rhs) == SSA_NAME)
|
|
||||||
gimple_set_plf (SSA_NAME_DEF_STMT (rhs), NECESSARY, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a store or a now unused copy, remove it. */
|
tree lhs;
|
||||||
if (TREE_CODE (lhs) != SSA_NAME
|
if (gimple_code (stmt) == GIMPLE_PHI)
|
||||||
|| has_zero_uses (lhs))
|
lhs = gimple_phi_result (stmt);
|
||||||
|
else
|
||||||
|
lhs = gimple_get_lhs (stmt);
|
||||||
|
|
||||||
|
if (inserted_exprs
|
||||||
|
&& TREE_CODE (lhs) == SSA_NAME)
|
||||||
|
bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
|
||||||
|
|
||||||
|
gsi = gsi_for_stmt (stmt);
|
||||||
|
if (gimple_code (stmt) == GIMPLE_PHI)
|
||||||
|
remove_phi_node (&gsi, true);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
basic_block bb = gimple_bb (stmt);
|
basic_block bb = gimple_bb (stmt);
|
||||||
gsi = gsi_for_stmt (stmt);
|
|
||||||
unlink_stmt_vdef (stmt);
|
unlink_stmt_vdef (stmt);
|
||||||
if (gsi_remove (&gsi, true))
|
if (gsi_remove (&gsi, true))
|
||||||
bitmap_set_bit (need_eh_cleanup, bb->index);
|
bitmap_set_bit (need_eh_cleanup, bb->index);
|
||||||
if (inserted_exprs
|
|
||||||
&& TREE_CODE (lhs) == SSA_NAME)
|
|
||||||
bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
|
|
||||||
release_defs (stmt);
|
release_defs (stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1410,11 +1410,6 @@ replace_exp (use_operand_p op_p, tree val)
|
||||||
void
|
void
|
||||||
propagate_tree_value (tree *op_p, tree val)
|
propagate_tree_value (tree *op_p, tree val)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (!(TREE_CODE (val) == SSA_NAME
|
|
||||||
&& *op_p
|
|
||||||
&& TREE_CODE (*op_p) == SSA_NAME
|
|
||||||
&& !may_propagate_copy (*op_p, val)));
|
|
||||||
|
|
||||||
if (TREE_CODE (val) == SSA_NAME)
|
if (TREE_CODE (val) == SSA_NAME)
|
||||||
*op_p = val;
|
*op_p = val;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue