This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 */
  };
  												


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]