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

Evan Cheng evan.cheng at apple.com
Wed Jun 6 19:12:37 PDT 2007



Changes in directory llvm/lib/CodeGen:

IfConversion.cpp updated: 1.34 -> 1.35
---
Log message:

Lots of bug fixes. Now finally in a reasonable state.

---
Diffs of the changes:  (+104 -78)

 IfConversion.cpp |  182 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 104 insertions(+), 78 deletions(-)


Index: llvm/lib/CodeGen/IfConversion.cpp
diff -u llvm/lib/CodeGen/IfConversion.cpp:1.34 llvm/lib/CodeGen/IfConversion.cpp:1.35
--- llvm/lib/CodeGen/IfConversion.cpp:1.34	Wed Jun  6 11:22:00 2007
+++ llvm/lib/CodeGen/IfConversion.cpp	Wed Jun  6 21:12:15 2007
@@ -64,6 +64,7 @@
       BBICKind Kind;
       unsigned NonPredSize;
       bool IsAnalyzable;
+      bool hasFallThrough;
       bool ModifyPredicate;
       MachineBasicBlock *BB;
       MachineBasicBlock *TrueBB;
@@ -72,7 +73,8 @@
       std::vector<MachineOperand> BrCond;
       std::vector<MachineOperand> Predicate;
       BBInfo() : Kind(ICNotAnalyzed), NonPredSize(0),
-                 IsAnalyzable(false), ModifyPredicate(false),
+                 IsAnalyzable(false), hasFallThrough(false),
+                 ModifyPredicate(false),
                  BB(0), TrueBB(0), FalseBB(0), TailBB(0) {}
     };
 
@@ -97,6 +99,8 @@
   private:
     bool ReverseBranchCondition(BBInfo &BBI);
     bool BlockModifyPredicate(MachineBasicBlock *BB) const;
+    bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI) const;
+    bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI) const;
     void StructuralAnalysis(MachineBasicBlock *BB);
     bool FeasibilityAnalysis(BBInfo &BBI,
                              std::vector<MachineOperand> &Cond,
@@ -113,8 +117,8 @@
                         bool IgnoreTerm = false);
     void MergeBlocks(BBInfo &TrueBBI, BBInfo &FalseBBI);
 
-    // blockFallsThrough - Block ends without a terminator.
-    bool blockFallsThrough(BBInfo &BBI) const {
+    // blockAlwaysFallThrough - Block ends without a terminator.
+    bool blockAlwaysFallThrough(BBInfo &BBI) const {
       return BBI.IsAnalyzable && BBI.TrueBB == NULL;
     }
 
@@ -242,6 +246,32 @@
   return false;
 }
 
+/// ValidTriangle - Returns true if the 'true' and 'false' blocks paths (along
+/// with their common predecessor) forms a valid triangle shape for ifcvt.
+bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI) const {
+  if (TrueBBI.BB->pred_size() != 1)
+    return false;
+
+  MachineBasicBlock *TTBB = TrueBBI.TrueBB;
+  if (!TTBB && blockAlwaysFallThrough(TrueBBI)) {
+    MachineFunction::iterator I = TrueBBI.BB;
+    if (++I == TrueBBI.BB->getParent()->end())
+      return false;
+    TTBB = I;
+  }
+  return TTBB && TTBB == FalseBBI.BB;
+}
+
+/// ValidDiamond - Returns true if the 'true' and 'false' blocks paths (along
+/// with their common predecessor) forms a valid diamond shape for ifcvt.
+bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI) const {
+  return (TrueBBI.TrueBB == FalseBBI.TrueBB &&
+          TrueBBI.BB->pred_size() == 1 &&
+          FalseBBI.BB->pred_size() == 1 &&
+          !(TrueBBI.ModifyPredicate && FalseBBI.ModifyPredicate) &&
+          !TrueBBI.FalseBB && !FalseBBI.FalseBB);
+}
+
 /// StructuralAnalysis - Analyze the structure of the sub-CFG starting from
 /// the specified block. Record its successors and whether it looks like an
 /// if-conversion candidate.
@@ -263,6 +293,8 @@
   BBI.Kind = ICNotClassfied;
   BBI.IsAnalyzable =
     !TII->AnalyzeBranch(*BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond);
+  BBI.hasFallThrough = BBI.IsAnalyzable && BBI.FalseBB == NULL;
+  // Unanalyable or ends with fallthrough or unconditional branch.
   if (!BBI.IsAnalyzable || BBI.BrCond.size() == 0)
     return;
   // Do not ifcvt if either path is a back edge to the entry block.
@@ -316,16 +348,7 @@
         FalseBBI.Kind = ICChild;
       }
     }
-  } else if (TrueBBI.TrueBB == FalseBBI.TrueBB && CanRevCond &&
-             TrueBBI.BB->pred_size() == 1 &&
-             FalseBBI.BB->pred_size() == 1 &&
-             // Check the 'true' and 'false' blocks if either isn't ended with
-             // a branch. If the block does not fallthrough to another block
-             // then we need to add a branch to its successor.
-             !(TrueBBI.ModifyPredicate &&
-               !TrueBBI.TrueBB && TrueBBI.BB->succ_size()) &&
-             !(FalseBBI.ModifyPredicate &&
-               !FalseBBI.TrueBB && FalseBBI.BB->succ_size()) &&
+  } else if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI) &&
              FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
              FeasibilityAnalysis(FalseBBI, RevCond)) {
     // Diamond:
@@ -341,9 +364,9 @@
     BBI.TailBB = TrueBBI.TrueBB;
   } else {
     // FIXME: Consider duplicating if BB is small.
-    bool TryTriangle = TrueBBI.TrueBB && TrueBBI.TrueBB == BBI.FalseBB &&
-                       TrueBBI.BB->pred_size() == 1;
-    bool TrySimple = TrueBBI.BrCond.size() == 0 && TrueBBI.BB->pred_size() == 1;
+    bool TryTriangle = ValidTriangle(TrueBBI, FalseBBI);
+    bool TrySimple = !blockAlwaysFallThrough(TrueBBI) &&
+                     TrueBBI.BrCond.size() == 0 && TrueBBI.BB->pred_size() == 1;
     if ((TryTriangle || TrySimple) &&
         FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
       if (TryTriangle) {
@@ -369,19 +392,21 @@
       }
     } else if (FalseBBI.BrCond.size() == 0 && FalseBBI.BB->pred_size() == 1) {
       // Try the other path...
-      bool TryTriangle = FalseBBI.TrueBB && FalseBBI.TrueBB == BBI.TrueBB &&
-                         FalseBBI.BB->pred_size() == 1;
-      std::vector<MachineOperand> RevCond(BBI.BrCond);
-      if (!TII->ReverseBranchCondition(RevCond) &&
-          FeasibilityAnalysis(FalseBBI, RevCond)) {
-        if (TryTriangle) {
-          // Reverse 'true' and 'false' paths.
-          ReverseBranchCondition(BBI);
-          BBI.Kind = ICTriangle;
-          FalseBBI.Kind = ICChild;
-        } else {
-          BBI.Kind = ICSimpleFalse;
-          FalseBBI.Kind = ICChild;
+      bool TryTriangle = ValidTriangle(FalseBBI, TrueBBI);
+      bool TrySimple = !blockAlwaysFallThrough(FalseBBI);
+      if (TryTriangle || TrySimple) {
+        std::vector<MachineOperand> RevCond(BBI.BrCond);
+        if (!TII->ReverseBranchCondition(RevCond) &&
+            FeasibilityAnalysis(FalseBBI, RevCond)) {
+          if (TryTriangle) {
+            // Reverse 'true' and 'false' paths.
+            ReverseBranchCondition(BBI);
+            BBI.Kind = ICTriangle;
+            FalseBBI.Kind = ICChild;
+          } else {
+            BBI.Kind = ICSimpleFalse;
+            FalseBBI.Kind = ICChild;
+          }
         }
       }
     }
@@ -418,7 +443,6 @@
        I != E; ++I) {
     if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
       continue;
-    // TODO: check if instruction clobbers predicate.
     if (!I->isPredicable())
       return false;
   }
@@ -531,22 +555,16 @@
   }
 
   PredicateBlock(*CvtBBI, Cond);
-  // If the 'true' block ends without a branch, add a conditional branch
-  // to its successor unless that happens to be the 'false' block.
-  if (CvtBBI->IsAnalyzable && CvtBBI->TrueBB == NULL) {
-    assert(CvtBBI->BB->succ_size() == 1 && "Unexpected!");
-    MachineBasicBlock *SuccBB = *CvtBBI->BB->succ_begin();
-    if (SuccBB != NextBBI->BB)
-      TII->InsertBranch(*CvtBBI->BB, SuccBB, NULL, Cond);
-  }
 
   // Merge converted block into entry block. Also add an unconditional branch
   // to the 'false' branch.
   BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
   MergeBlocks(BBI, *CvtBBI);
+
   bool IterIfcvt = true;
   if (!isNextBlock(BBI.BB, NextBBI->BB)) {
     InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
+    BBI.hasFallThrough = false;
     if (BBI.ModifyPredicate)
       // Now ifcvt'd block will look like this:
       // BB:
@@ -555,9 +573,9 @@
       // if t op
       // b BBf
       //
-      // We cannot further ifcvt this block because the unconditional branch will
-      // have to be predicated on the new condition, that will not be available
-      // if cmp executes.
+      // We cannot further ifcvt this block because the unconditional branch
+      // will have to be predicated on the new condition, that will not be
+      // available if cmp executes.
       IterIfcvt = false;
   }
   std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
@@ -602,6 +620,7 @@
     FalseBBDead = true;
   } else if (!isNextBlock(TrueBBI.BB, FalseBBI.BB)) {
     InsertUncondBranch(TrueBBI.BB, FalseBBI.BB, TII);
+    TrueBBI.hasFallThrough = false;
     if (BBI.ModifyPredicate || TrueBBI.ModifyPredicate)
       // Now ifcvt'd block will look like this:
       // BB:
@@ -715,8 +734,14 @@
 
   // Add an unconditional branch from 'false' to to 'false' successor if it
   // will not be the fallthrough block.
-  if (NeedBr2 && !isNextBlock(BBI2->BB, *BBI2->BB->succ_begin()))
-    InsertUncondBranch(BBI2->BB, *BBI2->BB->succ_begin(), TII);
+  if (NeedBr2 && !NeedBr1) {
+    // If BBI2 isn't going to be merged in, then the existing fallthrough
+    // or branch is fine.
+    if (!isNextBlock(BBI.BB, *BBI2->BB->succ_begin())) {
+      InsertUncondBranch(BBI2->BB, *BBI2->BB->succ_begin(), TII);
+      BBI2->hasFallThrough = false;
+    }
+  }
 
   // Keep them as two separate blocks if there is an early exit.
   if (!NeedBr1)
@@ -727,11 +752,18 @@
 
   // Merge the combined block into the entry of the diamond.
   MergeBlocks(BBI, *BBI1);
+  std::copy(Cond1->begin(), Cond1->end(),
+            std::back_inserter(BBI.Predicate));
+  if (!NeedBr1)
+    std::copy(Cond2->begin(), Cond2->end(),
+              std::back_inserter(BBI.Predicate));
 
   // 'True' and 'false' aren't combined, see if we need to add a unconditional
   // branch to the 'false' block.
-  if (NeedBr1 && !isNextBlock(BBI.BB, BBI2->BB))
-    InsertUncondBranch(BBI1->BB, BBI2->BB, TII);
+  if (NeedBr1 && !isNextBlock(BBI.BB, BBI2->BB)) {
+    InsertUncondBranch(BBI.BB, BBI2->BB, TII);
+    BBI1->hasFallThrough = false;
+  }
 
   // If the if-converted block fallthrough or unconditionally branch into the
   // tail block, and the tail block does not have other predecessors, then
@@ -775,28 +807,12 @@
   NumIfConvBBs++;
 }
 
-/// TransferPreds - Transfer all the predecessors of FromBB to ToBB.
-///
-static void TransferPreds(MachineBasicBlock *ToBB, MachineBasicBlock *FromBB) {
-  for (MachineBasicBlock::pred_iterator I = FromBB->pred_begin(),
-         E = FromBB->pred_end(); I != E; ++I) {
-    MachineBasicBlock *Pred = *I;
-    Pred->removeSuccessor(FromBB);
-    if (!Pred->isSuccessor(ToBB))
-      Pred->addSuccessor(ToBB);
-  }
-}
-
-/// TransferSuccs - Transfer all the successors of FromBB to ToBB.
-///
-static void TransferSuccs(MachineBasicBlock *ToBB, MachineBasicBlock *FromBB) {
-  for (MachineBasicBlock::succ_iterator I = FromBB->succ_begin(),
-         E = FromBB->succ_end(); I != E; ++I) {
-    MachineBasicBlock *Succ = *I;
-    FromBB->removeSuccessor(Succ);
-    if (!ToBB->isSuccessor(Succ))
-      ToBB->addSuccessor(Succ);
-  }
+static MachineBasicBlock *getNextBlock(MachineBasicBlock *BB) {
+  MachineFunction::iterator I = BB;
+  MachineFunction::iterator E = BB->getParent()->end();
+  if (++I == E)
+    return NULL;
+  return I;
 }
 
 /// MergeBlocks - Move all instructions from FromBB to the end of ToBB.
@@ -805,23 +821,33 @@
   ToBBI.BB->splice(ToBBI.BB->end(),
                    FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
 
-  // If FromBBI is previously a successor, remove it from ToBBI's successor
-  // list and update its TrueBB / FalseBB field if needed.
-  if (ToBBI.BB->isSuccessor(FromBBI.BB))
-    ToBBI.BB->removeSuccessor(FromBBI.BB);
-
   // Redirect all branches to FromBB to ToBB.
   std::vector<MachineBasicBlock *> Preds(FromBBI.BB->pred_begin(),
                                          FromBBI.BB->pred_end());
-  for (unsigned i = 0, e = Preds.size(); i != e; ++i)
-    Preds[i]->ReplaceUsesOfBlockWith(FromBBI.BB, ToBBI.BB);
+  for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
+    MachineBasicBlock *Pred = Preds[i];
+    if (Pred == ToBBI.BB)
+      continue;
+    Pred->ReplaceUsesOfBlockWith(FromBBI.BB, ToBBI.BB);
+  }
+ 
+  std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
+                                         FromBBI.BB->succ_end());
+  MachineBasicBlock *FallThrough = FromBBI.hasFallThrough
+    ? getNextBlock(FromBBI.BB) : NULL;
+
+  for (unsigned i = 0, e = Succs.size(); i != e; ++i) {
+    MachineBasicBlock *Succ = Succs[i];
+    if (Succ == FallThrough)
+      continue;
+    FromBBI.BB->removeSuccessor(Succ);
+    if (!ToBBI.BB->isSuccessor(Succ))
+      ToBBI.BB->addSuccessor(Succ);
+  }
 
-  // Transfer preds / succs and update size.
-  TransferPreds(ToBBI.BB, FromBBI.BB);
-  if (!blockFallsThrough(FromBBI))
-    TransferSuccs(ToBBI.BB, FromBBI.BB);
   ToBBI.NonPredSize += FromBBI.NonPredSize;
   FromBBI.NonPredSize = 0;
 
   ToBBI.ModifyPredicate |= FromBBI.ModifyPredicate;
+  ToBBI.hasFallThrough = FromBBI.hasFallThrough;
 }






More information about the llvm-commits mailing list