This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tcb] [RFC] partial rewrite of PHI-OPT
- From: Andrew Pinski <pinskia at physics dot uc dot edu>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Diego Novillo <dnovillo at redhat dot com>
- Date: Wed, 29 Sep 2004 13:04:56 -0400
- Subject: [tcb] [RFC] partial rewrite of PHI-OPT
Since PHI-OPT only takes into account if find a PHI with two nodes
we miss some opportunities for optimization on the tree level which
we pick up on the RTL level via the if-cvt pass. This patch
implements so that look at all COND_EXPR and see if we can do the
transformations.
Testcases which we now optimize on the tree level:
For C and C++:
int f(int a, int b)
{
if (a == 0)
return 0;
if (a != b)
return a;
return a;
}
int f1(int a, int b, int c)
{
if (c == 0) goto temp;
if (a == 0)
return 0;
temp:
if (a == b)
return a;
return a;
}
One which we now optimize, only in C++ because C++ does not produce
"if(bool!=0) for "if(bool)":
bool t();
bool t1();
bool f2()
{
bool t3 = 0;
if (t())
if (t1()) //<-- this is now sib-called, at least on PPC-darwin
t3 = 1;
return t3;
}
OK for tcb? Bootstrapped and tested on powerpc-apple-darwin.
Thanks,
Andrew Pinski
ChangeLog:
* tree-ssa-phiopt.c (tree_ssa_phiopt): Rewrite so we base the
bbs on the COND_EXPR instead of the PHI_NODEs.
(candidate_bb_for_phi_optimization): Remove.
(replace_phi_with_stmt): Rename to ...
(replace_phi_edge_with_variable): this and change so that we
replace the phi argument instead of removing the PHI.
(conditional_replacement): Change so we deal with PHI with more
than two arguments.
(value_replacement): Likewise.
(abs_replacement): Likewise.
Index: tree-ssa-phiopt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-phiopt.c,v
retrieving revision 2.13.2.1
diff -p -c -3 -r2.13.2.1 tree-ssa-phiopt.c
*** tree-ssa-phiopt.c 22 Sep 2004 23:43:56 -0000 2.13.2.1
--- tree-ssa-phiopt.c 29 Sep 2004 16:33:14 -0000
*************** Software Foundation, 59 Temple Place - S
*** 37,50 ****
#include "langhooks.h"
static void tree_ssa_phiopt (void);
! static bool conditional_replacement (basic_block, tree, tree, tree);
! static bool value_replacement (basic_block, tree, tree, tree);
! static bool abs_replacement (basic_block, tree, tree, tree);
! static void replace_phi_with_stmt (block_stmt_iterator, basic_block,
! basic_block, tree, tree);
static bool candidate_bb_for_phi_optimization (basic_block,
basic_block *,
basic_block *);
/* This pass eliminates PHI nodes which can be trivially implemented
as
an assignment from a conditional expression. i.e. if we have
something
--- 37,55 ----
#include "langhooks.h"
static void tree_ssa_phiopt (void);
! static bool conditional_replacement (basic_block, basic_block,
basic_block,
! edge, edge, tree, tree, tree);
! static bool value_replacement (basic_block, basic_block, basic_block,
! edge, edge, tree, tree, tree);
! static bool abs_replacement (basic_block, basic_block, basic_block,
! edge, edge, tree, tree, tree);
! static void replace_phi_edge_with_variable (basic_block, basic_block,
edge,
! tree, tree);
! #if 0
static bool candidate_bb_for_phi_optimization (basic_block,
basic_block *,
basic_block *);
+ #endif
/* This pass eliminates PHI nodes which can be trivially implemented
as
an assignment from a conditional expression. i.e. if we have
something
*************** tree_ssa_phiopt (void)
*** 112,135 ****
basic_block bb;
bool removed_phis = false;
! /* Search every basic block for PHI nodes we may be able to
optimize. */
! FOR_EACH_BB (bb)
! {
! tree arg0, arg1, phi;
!
! /* We're searching for blocks with one PHI node which has two
! arguments. */
! phi = phi_nodes (bb);
! if (phi && PHI_CHAIN (phi) == NULL
! && PHI_NUM_ARGS (phi) == 2)
{
! arg0 = PHI_ARG_DEF (phi, 0);
! arg1 = PHI_ARG_DEF (phi, 1);
/* Do the replacement of conditional if it can be done. */
! if (conditional_replacement (bb, phi, arg0, arg1)
! || value_replacement (bb, phi, arg0, arg1)
! || abs_replacement (bb, phi, arg0, arg1))
{
/* We have done the replacement so we need to rebuild the
cfg when this pass is complete. */
--- 117,205 ----
basic_block bb;
bool removed_phis = false;
! /* Search every basic block for COND_EXPR we may be able to
optimize in reverse
! order so we can find more. */
! FOR_EACH_BB_REVERSE (bb)
! {
! tree cond_expr;
! tree phi;
! basic_block bb1, bb2;
! edge e1, e2;
!
! cond_expr = last_stmt (bb);
! /* Check to see if the last statement is a COND_EXPR */
! if (!cond_expr
! || TREE_CODE (cond_expr) != COND_EXPR)
! continue;
!
! e1 = bb->succ;
! bb1 = e1->dest;
! e2 = bb->succ->succ_next;
! bb2 = e2->dest;
!
! /* We cannot do the optimization on abnormal edges. */
! if ((e1->flags & EDGE_ABNORMAL) != 0
! || (e2->flags & EDGE_ABNORMAL) != 0)
! continue;
!
! /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
! if (bb1->succ == NULL
! || bb2 == NULL
! || bb2->succ == NULL)
! continue;
!
! /* Find the bb which is the fall through to the other. */
! if (bb1->succ->dest == bb2)
! ;
! else if (bb2->succ->dest == bb1)
! {
! basic_block bb_tmp = bb1;
! edge e_tmp = e1;
! bb1 = bb2;
! bb2 = bb_tmp;
! e1 = e2;
! e2 = e_tmp;
! }
! else
! continue;
!
! /* Make sure that bb1 is just a fall through. */
! if (bb1->succ->succ_next != NULL
! || (bb1->succ->flags & EDGE_FALLTHRU) == 0)
! continue;
!
! /* Also make that bb1 only have one pred and it is bb. */
! if (bb1->pred->src != bb
! || bb1->pred->pred_next != NULL)
! continue;
!
! e1 = bb1->succ;
!
! phi = phi_nodes (bb2);
!
! /* Check to make sure that there is only one PHI node.
! TODO: we could do it with more than one iff the other PHI
nodes
! have the same elements for these two edges. */
! if (phi && PHI_CHAIN (phi) == NULL)
{
! tree arg0 = NULL, arg1 = NULL;
! int i;
! for (i = 0;i < PHI_NUM_ARGS (phi); i++)
! {
! if (PHI_ARG_EDGE (phi, i) == e1)
! arg0 = PHI_ARG_DEF_TREE (phi, i);
! else if (PHI_ARG_EDGE (phi, i) == e2)
! arg1 = PHI_ARG_DEF_TREE (phi, i);
! }
!
! /* We know something is wrong if we cannot find the edges in the
PHI
! node. */
! gcc_assert (arg0 != NULL && arg1 != NULL);
/* Do the replacement of conditional if it can be done. */
! if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0,
arg1)
! || value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
! || abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
{
/* We have done the replacement so we need to rebuild the
cfg when this pass is complete. */
*************** empty_block_p (basic_block bb)
*** 164,256 ****
return true;
}
! /* BB is a basic block which has only one PHI node with precisely two
! arguments.
!
! Examine both of BB's predecessors to see if one ends with a
! COND_EXPR and the other is a successor of the COND_EXPR. If so,
then
! we may be able to optimize PHI nodes at the start of BB.
!
! If so, mark store the block with the COND_EXPR into COND_BLOCK_P
! and the other block into OTHER_BLOCK_P and return true, otherwise
! return false. */
!
! static bool
! candidate_bb_for_phi_optimization (basic_block bb,
! basic_block *cond_block_p,
! basic_block *other_block_p)
! {
! tree last0, last1;
! basic_block cond_block, other_block;
!
! /* One of the alternatives must come from a block ending with
! a COND_EXPR. */
! last0 = last_stmt (bb->pred->src);
! last1 = last_stmt (bb->pred->pred_next->src);
! if (last0 && TREE_CODE (last0) == COND_EXPR)
! {
! cond_block = bb->pred->src;
! other_block = bb->pred->pred_next->src;
! }
! else if (last1 && TREE_CODE (last1) == COND_EXPR)
! {
! other_block = bb->pred->src;
! cond_block = bb->pred->pred_next->src;
! }
! else
! return false;
!
! /* COND_BLOCK must have precisely two successors. We indirectly
! verify that those successors are BB and OTHER_BLOCK. */
! if (!cond_block->succ
! || !cond_block->succ->succ_next
! || cond_block->succ->succ_next->succ_next
! || (cond_block->succ->flags & EDGE_ABNORMAL) != 0
! || (cond_block->succ->succ_next->flags & EDGE_ABNORMAL) != 0)
! return false;
!
! /* OTHER_BLOCK must have a single predecessor which is COND_BLOCK,
! OTHER_BLOCK must have a single successor which is BB and
! OTHER_BLOCK must have no PHI nodes. */
! if (!other_block->pred
! || other_block->pred->src != cond_block
! || other_block->pred->pred_next
! || !other_block->succ
! || other_block->succ->dest != bb
! || other_block->succ->succ_next
! || phi_nodes (other_block))
! return false;
!
! *cond_block_p = cond_block;
! *other_block_p = other_block;
! /* Everything looks OK. */
! return true;
! }
!
! /* Replace PHI in block BB with statement NEW. NEW is inserted after
! BSI. Remove the edge from COND_BLOCK which does not lead to BB
(COND_BLOCK
is known to have two edges, one of which must reach BB). */
static void
! replace_phi_with_stmt (block_stmt_iterator bsi, basic_block bb,
! basic_block cond_block, tree phi, tree new)
{
basic_block block_to_remove;
- /* Insert our new statement at the head of our block. */
- bsi_insert_after (&bsi, new, BSI_NEW_STMT);
-
- /* Register our new statement as the defining statement for
- the result. */
- SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new;
-
- /* Remove the now useless PHI node.
-
- We do not want to use remove_phi_node since that releases the
- SSA_NAME as well and the SSA_NAME is still being used. */
- release_phi_node (phi);
- bb_ann (bb)->phi_nodes = NULL;
-
/* Remove the empty basic block. */
if (cond_block->succ->dest == bb)
{
--- 234,261 ----
return true;
}
! /* Replace PHI node element whoes edge is E in block BB with variable
NEW.
! Remove the edge from COND_BLOCK which does not lead to BB
(COND_BLOCK
is known to have two edges, one of which must reach BB). */
static void
! replace_phi_edge_with_variable (basic_block cond_block, basic_block
bb,
! edge e, tree phi, tree new)
{
basic_block block_to_remove;
+ int i;
+ block_stmt_iterator bsi;
+
+ /* Change the PHI argument to new. */
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ if (PHI_ARG_EDGE (phi, i) == e)
+ {
+ PHI_ARG_DEF_TREE (phi, i) = new;
+ break;
+ }
+ }
/* Remove the empty basic block. */
if (cond_block->succ->dest == bb)
{
*************** replace_phi_with_stmt (block_stmt_iterat
*** 287,302 ****
is argument 0 from PHI. Likewise for ARG1. */
static bool
! conditional_replacement (basic_block bb, tree phi, tree arg0, tree
arg1)
{
tree result;
tree old_result = NULL;
- basic_block other_block = NULL;
- basic_block cond_block = NULL;
tree new, cond;
block_stmt_iterator bsi;
edge true_edge, false_edge;
tree new_var = NULL;
/* The PHI arguments have the constants 0 and 1, then convert
it to the conditional. */
--- 292,308 ----
is argument 0 from PHI. Likewise for ARG1. */
static bool
! conditional_replacement (basic_block cond_bb, basic_block middle_bb,
! basic_block phi_bb, edge e0, edge e1, tree phi,
! tree arg0, tree arg1)
{
tree result;
tree old_result = NULL;
tree new, cond;
block_stmt_iterator bsi;
edge true_edge, false_edge;
tree new_var = NULL;
+ tree new_var1;
/* The PHI arguments have the constants 0 and 1, then convert
it to the conditional. */
*************** conditional_replacement (basic_block bb,
*** 306,313 ****
else
return false;
! if (!candidate_bb_for_phi_optimization (bb, &cond_block,
&other_block)
! || !empty_block_p (other_block))
return false;
/* If the condition is not a naked SSA_NAME and its type does not
--- 312,318 ----
else
return false;
! if (!empty_block_p (middle_bb))
return false;
/* If the condition is not a naked SSA_NAME and its type does not
*************** conditional_replacement (basic_block bb,
*** 315,321 ****
variable to optimize this case as it would likely create
non-gimple code when the condition was converted to the
result's type. */
! cond = COND_EXPR_COND (last_stmt (cond_block));
result = PHI_RESULT (phi);
if (TREE_CODE (cond) != SSA_NAME
&& !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE
(result)))
--- 320,326 ----
variable to optimize this case as it would likely create
non-gimple code when the condition was converted to the
result's type. */
! cond = COND_EXPR_COND (last_stmt (cond_bb));
result = PHI_RESULT (phi);
if (TREE_CODE (cond) != SSA_NAME
&& !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE
(result)))
*************** conditional_replacement (basic_block bb,
*** 333,342 ****
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
! extract_true_false_edges_from_block (cond_block, &true_edge,
&false_edge);
! /* Insert our new statement at the head of our block. */
! bsi = bsi_start (bb);
if (old_result)
{
--- 338,350 ----
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
! extract_true_false_edges_from_block (cond_bb, &true_edge,
&false_edge);
! /* Insert our new statement at the end of condtional block before
the
! COND_EXPR. */
! bsi = bsi_last (cond_bb);
! bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
!
if (old_result)
{
*************** conditional_replacement (basic_block bb,
*** 344,356 ****
if (!COMPARISON_CLASS_P (old_result))
return false;
! new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
TREE_OPERAND (old_result, 0),
TREE_OPERAND (old_result, 1));
! new1 = build (MODIFY_EXPR, TREE_TYPE (result), new_var, new1);
bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
}
/* At this point we know we have a COND_EXPR with two successors.
One successor is BB, the other successor is an empty block which
--- 352,367 ----
if (!COMPARISON_CLASS_P (old_result))
return false;
! new1 = build (TREE_CODE (old_result), TREE_TYPE (old_result),
TREE_OPERAND (old_result, 0),
TREE_OPERAND (old_result, 1));
! new1 = build (MODIFY_EXPR, TREE_TYPE (old_result), new_var,
new1);
bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
}
+
+ new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
+
/* At this point we know we have a COND_EXPR with two successors.
One successor is BB, the other successor is an empty block which
*************** conditional_replacement (basic_block bb,
*** 369,381 ****
false edge as the value zero. Note that those conditions are not
the same since only one of the outgoing edges from the COND_EXPR
will directly reach BB and thus be associated with an argument.
*/
! if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
! || (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
! || (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
! || (PHI_ARG_EDGE (phi, 1) == false_edge && integer_zerop
(arg1)))
{
! new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
! PHI_RESULT (phi), cond);
}
else
{
--- 380,391 ----
false edge as the value zero. Note that those conditions are not
the same since only one of the outgoing edges from the COND_EXPR
will directly reach BB and thus be associated with an argument.
*/
! if ((e0 == true_edge && integer_onep (arg0))
! || (e0 == false_edge && integer_zerop (arg0))
! || (e1 == true_edge && integer_onep (arg1))
! || (e1 == false_edge && integer_zerop (arg1)))
{
! new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
}
else
{
*************** conditional_replacement (basic_block bb,
*** 403,413 ****
&& !is_gimple_val (TREE_OPERAND (cond, 0)))
return false;
! new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
! PHI_RESULT (phi), cond);
}
! replace_phi_with_stmt (bsi, bb, cond_block, phi, new);
/* Note that we optimized this PHI. */
return true;
--- 413,426 ----
&& !is_gimple_val (TREE_OPERAND (cond, 0)))
return false;
! new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
}
! bsi_insert_after (&bsi, new, BSI_NEW_STMT);
!
! SSA_NAME_DEF_STMT (new_var1) = new;
!
! replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
/* Note that we optimized this PHI. */
return true;
*************** conditional_replacement (basic_block bb,
*** 420,431 ****
is argument 0 from the PHI. Likewise for ARG1. */
static bool
! value_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
{
tree result;
! basic_block other_block = NULL;
! basic_block cond_block = NULL;
! tree new, cond;
edge true_edge, false_edge;
/* If the type says honor signed zeros we cannot do this
--- 433,444 ----
is argument 0 from the PHI. Likewise for ARG1. */
static bool
! value_replacement (basic_block cond_bb, basic_block middle_bb,
! basic_block phi_bb, edge e0, edge e1, tree phi,
! tree arg0, tree arg1)
{
tree result;
! tree cond;
edge true_edge, false_edge;
/* If the type says honor signed zeros we cannot do this
*************** value_replacement (basic_block bb, tree
*** 433,443 ****
if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
return false;
! if (!candidate_bb_for_phi_optimization (bb, &cond_block,
&other_block)
! || !empty_block_p (other_block))
return false;
! cond = COND_EXPR_COND (last_stmt (cond_block));
result = PHI_RESULT (phi);
/* This transformation is only valid for equality comparisons. */
--- 446,455 ----
if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
return false;
! if (!empty_block_p (middle_bb))
return false;
! cond = COND_EXPR_COND (last_stmt (cond_bb));
result = PHI_RESULT (phi);
/* This transformation is only valid for equality comparisons. */
*************** value_replacement (basic_block bb, tree
*** 446,452 ****
/* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */
! extract_true_false_edges_from_block (cond_block, &true_edge,
&false_edge);
/* At this point we know we have a COND_EXPR with two successors.
One successor is BB, the other successor is an empty block which
--- 458,464 ----
/* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */
! extract_true_false_edges_from_block (cond_bb, &true_edge,
&false_edge);
/* At this point we know we have a COND_EXPR with two successors.
One successor is BB, the other successor is an empty block which
*************** value_replacement (basic_block bb, tree
*** 476,495 ****
OTHER_BLOCK). If that is the case, then we want the single outgoing
edge from OTHER_BLOCK which reaches BB and represents the desired
path from COND_BLOCK. */
! if (e->dest == other_block)
e = e->dest->succ;
/* Now we know the incoming edge to BB that has the argument
for the
RHS of our new assignment statement. */
! if (PHI_ARG_EDGE (phi, 0) == e)
arg = arg0;
else
arg = arg1;
! /* Build the new assignment. */
! new = build (MODIFY_EXPR, TREE_TYPE (result), result, arg);
!
! replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi,
new);
/* Note that we optimized this PHI. */
return true;
--- 488,504 ----
OTHER_BLOCK). If that is the case, then we want the single outgoing
edge from OTHER_BLOCK which reaches BB and represents the desired
path from COND_BLOCK. */
! if (e->dest == middle_bb)
e = e->dest->succ;
/* Now we know the incoming edge to BB that has the argument
for the
RHS of our new assignment statement. */
! if (e0 == e)
arg = arg0;
else
arg = arg1;
! replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
/* Note that we optimized this PHI. */
return true;
*************** value_replacement (basic_block bb, tree
*** 502,513 ****
false.
bb is the basic block where the replacement is going to be done
on. arg0
is argument 0 from the phi. Likewise for arg1. */
static bool
! abs_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
{
tree result;
- basic_block other_block = NULL;
- basic_block cond_block = NULL;
tree new, cond;
block_stmt_iterator bsi;
edge true_edge, false_edge;
--- 511,523 ----
false.
bb is the basic block where the replacement is going to be done
on. arg0
is argument 0 from the phi. Likewise for arg1. */
+
static bool
! abs_replacement (basic_block cond_bb, basic_block middle_bb,
! basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1, tree phi,
! tree arg0, tree arg1)
{
tree result;
tree new, cond;
block_stmt_iterator bsi;
edge true_edge, false_edge;
*************** abs_replacement (basic_block bb, tree ph
*** 522,533 ****
if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
return false;
- if (!candidate_bb_for_phi_optimization (bb, &cond_block,
&other_block))
- return false;
-
/* OTHER_BLOCK must have only one executable statement which must
have the
form arg0 = -arg1 or arg1 = -arg0. */
! bsi = bsi_start (other_block);
while (!bsi_end_p (bsi))
{
tree stmt = bsi_stmt (bsi);
--- 532,540 ----
if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
return false;
/* OTHER_BLOCK must have only one executable statement which must
have the
form arg0 = -arg1 or arg1 = -arg0. */
! bsi = bsi_start (middle_bb);
while (!bsi_end_p (bsi))
{
tree stmt = bsi_stmt (bsi);
*************** abs_replacement (basic_block bb, tree ph
*** 579,585 ****
if (assign == NULL)
return false;
! cond = COND_EXPR_COND (last_stmt (cond_block));
result = PHI_RESULT (phi);
/* Only relationals comparing arg[01] against zero are interesting.
*/
--- 586,592 ----
if (assign == NULL)
return false;
! cond = COND_EXPR_COND (last_stmt (cond_bb));
result = PHI_RESULT (phi);
/* Only relationals comparing arg[01] against zero are interesting.
*/
*************** abs_replacement (basic_block bb, tree ph
*** 601,607 ****
/* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */
! extract_true_false_edges_from_block (cond_block, &true_edge,
&false_edge);
/* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then
we
will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
--- 608,614 ----
/* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */
! extract_true_false_edges_from_block (cond_bb, &true_edge,
&false_edge);
/* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then
we
will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
*************** abs_replacement (basic_block bb, tree ph
*** 611,620 ****
else
e = false_edge;
! if (e->dest == other_block)
negate = true;
else
negate = false;
if (negate)
lhs = make_rename_temp (TREE_TYPE (result), NULL);
--- 618,629 ----
else
e = false_edge;
! if (e->dest == middle_bb)
negate = true;
else
negate = false;
+
+ result = duplicate_ssa_name (result, NULL);
if (negate)
lhs = make_rename_temp (TREE_TYPE (result), NULL);
*************** abs_replacement (basic_block bb, tree ph
*** 625,631 ****
new = build (MODIFY_EXPR, TREE_TYPE (lhs),
lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
! replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
if (negate)
{
--- 634,641 ----
new = build (MODIFY_EXPR, TREE_TYPE (lhs),
lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
! bsi = bsi_last (cond_bb);
! bsi_insert_before (&bsi, new, BSI_NEW_STMT);
if (negate)
{
*************** abs_replacement (basic_block bb, tree ph
*** 633,650 ****
/* Get the right BSI. We want to insert after the recently
added ABS_EXPR statement (which we know is the first statement
in the block. */
- bsi = bsi_start (bb);
- bsi_next (&bsi);
new = build (MODIFY_EXPR, TREE_TYPE (result),
result, build1 (NEGATE_EXPR, TREE_TYPE (lhs),
lhs));
bsi_insert_after (&bsi, new, BSI_NEW_STMT);
!
! /* Register the new statement as defining the temporary -- this
is
! normally done by replace_phi_with_stmt, but the link will be wrong
! if we had to negate the resulting value. */
! SSA_NAME_DEF_STMT (result) = new;
}
/* Note that we optimized this PHI. */
return true;
--- 643,657 ----
/* Get the right BSI. We want to insert after the recently
added ABS_EXPR statement (which we know is the first statement
in the block. */
new = build (MODIFY_EXPR, TREE_TYPE (result),
result, build1 (NEGATE_EXPR, TREE_TYPE (lhs),
lhs));
bsi_insert_after (&bsi, new, BSI_NEW_STMT);
!
}
+
+ SSA_NAME_DEF_STMT (result) = new;
+ replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
/* Note that we optimized this PHI. */
return true;
*************** struct tree_opt_pass pass_phiopt =
*** 674,680 ****
0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
| TODO_verify_ssa | TODO_rename_vars
! | TODO_verify_flow,
0 /* letter */
};
--- 681,687 ----
0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
| TODO_verify_ssa | TODO_rename_vars
! | TODO_verify_flow | TODO_verify_stmts,
0 /* letter */
};