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]

Factor some code in tree-ssa-phiopt.c


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;
  }



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