[llvm-commits] CVS: llvm/lib/CodeGen/BranchFolding.cpp

Chris Lattner sabre at nondot.org
Mon Oct 23 18:12:47 PDT 2006



Changes in directory llvm/lib/CodeGen:

BranchFolding.cpp updated: 1.21 -> 1.22
---
Log message:

move single basic blocks that are neither fallen into nor fall out of into 
a place more useful.  In particular, if we can put them in a place where code
will be able to fall into it, do so.  Otherwise, put it in a place it can fall
through into a successor.  Otherwise, if preventing a fallthrough, move to the
end of the function, out of the way.

This deletes several hundred unconditional branches from spass.


---
Diffs of the changes:  (+96 -13)

 BranchFolding.cpp |  109 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 96 insertions(+), 13 deletions(-)


Index: llvm/lib/CodeGen/BranchFolding.cpp
diff -u llvm/lib/CodeGen/BranchFolding.cpp:1.21 llvm/lib/CodeGen/BranchFolding.cpp:1.22
--- llvm/lib/CodeGen/BranchFolding.cpp:1.21	Mon Oct 23 17:10:12 2006
+++ llvm/lib/CodeGen/BranchFolding.cpp	Mon Oct 23 20:12:32 2006
@@ -46,7 +46,7 @@
 
     // Branch optzn.
     bool OptimizeBranches(MachineFunction &MF);
-    void OptimizeBlock(MachineFunction::iterator MBB);
+    void OptimizeBlock(MachineBasicBlock *MBB);
     void RemoveDeadBlock(MachineBasicBlock *MBB);
   };
 }
@@ -394,17 +394,42 @@
     }
 }
 
+/// CanFallThrough - Return true of the specified branch condition can transfer
+/// control to FallthroughBlock, the block immediately after the branch.
+static bool CanFallThrough(MachineBasicBlock *TBB,
+                           MachineBasicBlock *FBB,
+                           const std::vector<MachineOperand> &Cond,
+                           MachineFunction::iterator FallthroughBlock) {
+  // If there is no branch, control always falls through.
+  if (TBB == 0) return true;
+
+  // If there is some explicit branch to the fallthrough block, it can obviously
+  // reach, even though the branch should get folded to fall through implicitly.
+  if (MachineFunction::iterator(TBB) == FallthroughBlock ||
+      MachineFunction::iterator(FBB) == FallthroughBlock)
+    return true;
+  
+  // If it's an unconditional branch to some block not the fall through, it 
+  // doesn't fall through.
+  if (Cond.empty()) return false;
+  
+  // Otherwise, if it is conditional and has no explicit false block, it falls
+  // through.
+  return !Cond.empty() && FBB == 0;
+}
+
 /// OptimizeBlock - Analyze and optimize control flow related to the specified
 /// block.  This is never called on the entry block.
-void BranchFolder::OptimizeBlock(MachineFunction::iterator MBB) {
+void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
+  MachineFunction::iterator FallThrough = MBB;
+  ++FallThrough;
+  
   // If this block is empty, make everyone use its fall-through, not the block
   // explicitly.
   if (MBB->empty()) {
     // Dead block?  Leave for cleanup later.
     if (MBB->pred_empty()) return;
     
-    MachineFunction::iterator FallThrough = next(MBB);
-    
     if (FallThrough == MBB->getParent()->end()) {
       // TODO: Simplify preds to not branch here if possible!
     } else {
@@ -426,7 +451,7 @@
 
   // Check to see if we can simplify the terminator of the block before this
   // one.
-  MachineBasicBlock &PrevBB = *prior(MBB);
+  MachineBasicBlock &PrevBB = *prior(MachineFunction::iterator(MBB));
 
   MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0;
   std::vector<MachineOperand> PriorCond;
@@ -443,7 +468,7 @@
     if (PriorTBB && PriorTBB == PriorFBB) {
       TII->RemoveBranch(PrevBB);
       PriorCond.clear(); 
-      if (PriorTBB != &*MBB)
+      if (PriorTBB != MBB)
         TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond);
       MadeChange = true;
       ++NumBranchOpts;
@@ -452,7 +477,7 @@
     
     // If the previous branch *only* branches to *this* block (conditional or
     // not) remove the branch.
-    if (PriorTBB == &*MBB && PriorFBB == 0) {
+    if (PriorTBB == MBB && PriorFBB == 0) {
       TII->RemoveBranch(PrevBB);
       MadeChange = true;
       ++NumBranchOpts;
@@ -461,7 +486,7 @@
     
     // If the prior block branches somewhere else on the condition and here if
     // the condition is false, remove the uncond second branch.
-    if (PriorFBB == &*MBB) {
+    if (PriorFBB == MBB) {
       TII->RemoveBranch(PrevBB);
       TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond);
       MadeChange = true;
@@ -472,7 +497,7 @@
     // If the prior block branches here on true and somewhere else on false, and
     // if the branch condition is reversible, reverse the branch to create a
     // fall-through.
-    if (PriorTBB == &*MBB) {
+    if (PriorTBB == MBB) {
       std::vector<MachineOperand> NewPriorCond(PriorCond);
       if (!TII->ReverseBranchCondition(NewPriorCond)) {
         TII->RemoveBranch(PrevBB);
@@ -490,12 +515,13 @@
   if (!TII->AnalyzeBranch(*MBB, CurTBB, CurFBB, CurCond)) {
     // If the CFG for the prior block has extra edges, remove them.
     MadeChange |= CorrectExtraCFGEdges(*MBB, CurTBB, CurFBB,
-                                       !CurCond.empty(), next(MBB));
+                                       !CurCond.empty(),
+                                       ++MachineFunction::iterator(MBB));
 
     // If this branch is the only thing in its block, see if we can forward
     // other blocks across it.
     if (CurTBB && CurCond.empty() && CurFBB == 0 && 
-        TII->isBranch(MBB->begin()->getOpcode()) && CurTBB != &*MBB) {
+        TII->isBranch(MBB->begin()->getOpcode()) && CurTBB != MBB) {
       // This block may contain just an unconditional branch.  Because there can
       // be 'non-branch terminators' in the block, try removing the branch and
       // then seeing if the block is empty.
@@ -509,7 +535,7 @@
       if (MBB->empty() && (!PriorUnAnalyzable || !PrevBB.isSuccessor(MBB))) {
         // If the prior block falls through into us, turn it into an
         // explicit branch to us to make updates simpler.
-        if (PrevBB.isSuccessor(MBB) && PriorTBB != &*MBB && PriorFBB != &*MBB) {
+        if (PrevBB.isSuccessor(MBB) && PriorTBB != MBB && PriorFBB != MBB) {
           if (PriorTBB == 0) {
             assert(PriorCond.empty() && PriorFBB == 0 && "Bad branch analysis");
             PriorTBB = MBB;
@@ -526,7 +552,7 @@
         bool DidChange = false;
         bool HasBranchToSelf = false;
         while (PI != MBB->pred_end()) {
-          if (*PI == &*MBB) {
+          if (*PI == MBB) {
             // If this block has an uncond branch to itself, leave it.
             ++PI;
             HasBranchToSelf = true;
@@ -549,5 +575,62 @@
       // Add the branch back if the block is more than just an uncond branch.
       TII->InsertBranch(*MBB, CurTBB, 0, CurCond);
     }
+    
+    // If the prior block doesn't fall through into this block, and if this
+    // block doesn't fall through into some other block, see if we can find a
+    // place to move this block where a fall-through will happen.
+    if (!PriorUnAnalyzable && !CanFallThrough(PriorTBB, PriorFBB,
+                                              PriorCond, MBB)) {
+      // Now we know that there was no fall-through into this block, check to
+      // see if it has fall-throughs.
+      if (!CanFallThrough(CurTBB, CurFBB, CurCond, FallThrough)) {
+        
+        // Check all the predecessors of this block.  If one of them has no fall
+        // throughs, move this block right after it.
+        for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+             E = MBB->pred_end(); PI != E; ++PI) {
+          // Analyze the branch at the end of the pred.
+          MachineBasicBlock *PredBB = *PI;
+          MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough;
+          MachineBasicBlock *PredTBB = 0, *PredFBB = 0;
+          std::vector<MachineOperand> PredCond;
+          if (PredBB != MBB &&
+              !TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond) &&
+              !CanFallThrough(PredTBB, PredFBB, PredCond, PredFallthrough)) {
+            MBB->moveAfter(PredBB);
+            MadeChange = true;
+            return OptimizeBlock(MBB);
+          }
+        }
+        
+        // Check all successors to see if we can move this block before it.
+        for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
+             E = MBB->succ_end(); SI != E; ++SI) {
+          // Analyze the branch at the end of the block before the succ.
+          MachineBasicBlock *SuccBB = *SI;
+          MachineFunction::iterator SuccPrev = SuccBB; --SuccPrev;
+          MachineBasicBlock *SuccPrevTBB = 0, *SuccPrevFBB = 0;
+          std::vector<MachineOperand> SuccPrevCond;
+          if (SuccBB != MBB &&
+              !TII->AnalyzeBranch(*SuccPrev, SuccPrevTBB, SuccPrevFBB,
+                                  SuccPrevCond) &&
+              !CanFallThrough(SuccPrevTBB, SuccPrevFBB, SuccPrevCond, SuccBB)) {
+            MBB->moveBefore(SuccBB);
+            MadeChange = true;
+            return OptimizeBlock(MBB);
+          }
+        }
+        
+        // Okay, there is no really great place to put this block.  If, however,
+        // the block before this one would be a fall-through if this block were
+        // removed, move this block to the end of the function.
+        if (FallThrough != MBB->getParent()->end() &&
+            CanFallThrough(PriorTBB, PriorFBB, PriorCond, FallThrough)) {
+          MBB->moveAfter(--MBB->getParent()->end());
+          MadeChange = true;
+          return;
+        }
+      }
+    }
   }
 }






More information about the llvm-commits mailing list