This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Factor some code in tree-ssa-phiopt.c
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 18 May 2004 10:22:04 -0600
- Subject: Factor some code in tree-ssa-phiopt.c
- Reply-to: law at redhat dot com
This breaks out some code from conditional_replacement so that it can be
re-used by some new code.
* tree-ssa-phiopt.c (replace_phi_with_stmt): New function extracted
from conditional_replacement.
(candidate_bb_for_phi_optimization): Similarly.
(conditional_replacement): Use replace_phi_with_stmt and
candidate_bb_for_phi_optimization.
Index: tree-ssa-phiopt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-phiopt.c,v
retrieving revision 2.3
diff -c -p -r2.3 tree-ssa-phiopt.c
*** tree-ssa-phiopt.c 18 May 2004 16:13:44 -0000 2.3
--- tree-ssa-phiopt.c 18 May 2004 16:19:28 -0000
*************** Software Foundation, 59 Temple Place - S
*** 38,43 ****
--- 38,49 ----
static void tree_ssa_phiopt (void);
static bool conditional_replacement (basic_block bb, tree phi, tree arg0,
tree arg1);
+ 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. ie if we have something
*************** tree_ssa_phiopt (void)
*** 97,128 ****
cleanup_tree_cfg ();
}
! /* The function conditional_replacement does the main work of doing the
! conditional replacement. Return true if the replacement is done.
! Otherwise return false.
! BB is the basic block where the replacement is going to be done on. ARG0
! 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 last0, last1, 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. */
- if ((integer_zerop (arg0) && integer_onep (arg1))
- || (integer_zerop (arg1) && integer_onep (arg0)))
- ;
- else
- return false;
-
/* One of the alternatives must come from a block ending with
a COND_EXPR. The other block must be entirely empty, except
for labels. */
--- 103,128 ----
cleanup_tree_cfg ();
}
! /* 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 an empty block. 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;
block_stmt_iterator bsi;
! basic_block cond_block, other_block;
/* One of the alternatives must come from a block ending with
a COND_EXPR. The other block must be entirely empty, except
for labels. */
*************** conditional_replacement (basic_block bb,
*** 171,177 ****
--- 171,261 ----
if (!bsi_end_p (bsi))
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)
+ {
+ /* 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;
+
+ /* Disconnect the edge leading into the empty block. That will
+ make the empty block unreachable and it will be removed later. */
+ if (cond_block->succ->dest == bb)
+ {
+ cond_block->succ->flags |= EDGE_FALLTHRU;
+ cond_block->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+ ssa_remove_edge (cond_block->succ->succ_next);
+ }
+ else
+ {
+ cond_block->succ->succ_next->flags |= EDGE_FALLTHRU;
+ cond_block->succ->succ_next->flags
+ &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+ ssa_remove_edge (cond_block->succ);
+ }
+
+ /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
+ bsi = bsi_last (cond_block);
+ bsi_remove (&bsi);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "COND_EXPR in block %d and PHI in block %d converted to straightline
code.\n",
+ cond_block->index,
+ bb->index);
+ }
+
+ /* The function conditional_replacement does the main work of doing the
+ conditional replacement. Return true if the replacement is done.
+ Otherwise return false.
+ BB is the basic block where the replacement is going to be done on. ARG0
+ 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. */
+ if ((integer_zerop (arg0) && integer_onep (arg1))
+ || (integer_zerop (arg1) && integer_onep (arg0)))
+ ;
+ else
+ return false;
+ if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block))
+ return false;
+
/* If the condition is not a naked SSA_NAME and its type does not
match the type of the result, then we have to create a new
variable to optimize this case as it would likely create
*************** conditional_replacement (basic_block bb,
*** 270,314 ****
PHI_RESULT (phi), cond);
}
! 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;
!
! /* Disconnect the edge leading into the empty block. That will
! make the empty block unreachable and it will be removed later. */
! if (cond_block->succ->dest == bb)
! {
! cond_block->succ->flags |= EDGE_FALLTHRU;
! cond_block->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
! ssa_remove_edge (cond_block->succ->succ_next);
! }
! else
! {
! cond_block->succ->succ_next->flags |= EDGE_FALLTHRU;
! cond_block->succ->succ_next->flags
! &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
! ssa_remove_edge (cond_block->succ);
! }
!
! /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
! bsi = bsi_last (cond_block);
! bsi_remove (&bsi);
!
! if (dump_file && (dump_flags & TDF_DETAILS))
! fprintf (dump_file,
! "COND_EXPR in block %d and PHI in block %d converted to straightline
code.\n",
! cond_block->index,
! bb->index);
!
/* Note that we optimized this PHI. */
return true;
}
--- 354,361 ----
PHI_RESULT (phi), cond);
}
! replace_phi_with_stmt (bsi, bb, cond_block, phi, new);
!
/* Note that we optimized this PHI. */
return true;
}