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

Evan Cheng evan.cheng at apple.com
Wed Jun 6 03:16:39 PDT 2007



Changes in directory llvm/lib/CodeGen:

IfConversion.cpp updated: 1.32 -> 1.33
---
Log message:

Lots of bug fixes.

---
Diffs of the changes:  (+76 -40)

 IfConversion.cpp |  116 ++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 76 insertions(+), 40 deletions(-)


Index: llvm/lib/CodeGen/IfConversion.cpp
diff -u llvm/lib/CodeGen/IfConversion.cpp:1.32 llvm/lib/CodeGen/IfConversion.cpp:1.33
--- llvm/lib/CodeGen/IfConversion.cpp:1.32	Tue Jun  5 21:08:52 2007
+++ llvm/lib/CodeGen/IfConversion.cpp	Wed Jun  6 05:16:17 2007
@@ -41,7 +41,7 @@
       ICTriangle,      // BB is entry of a triangle sub-CFG.
       ICDiamond,       // BB is entry of a diamond sub-CFG.
       ICChild,         // BB is part of the sub-CFG that'll be predicated.
-      ICDead           // BB has been converted and merged, it's now dead.
+      ICDead           // BB cannot be if-converted again.
     };
 
     /// BBInfo - One per MachineBasicBlock, this is used to cache the result
@@ -54,8 +54,8 @@
     /// Kind            - Type of block. See BBICKind.
     /// NonPredSize     - Number of non-predicated instructions.
     /// IsAnalyzable    - True if AnalyzeBranch() returns false.
-    /// ModifyPredicate - FIXME: Not used right now. True if BB would modify
-    ///                   the predicate (e.g. has cmp, call, etc.)
+    /// ModifyPredicate - True if BB would modify the predicate (e.g. has
+    ///                   cmp, call, etc.)
     /// BB              - Corresponding MachineBasicBlock.
     /// TrueBB / FalseBB- See AnalyzeBranch().
     /// BrCond          - Conditions for end of block conditional branches.
@@ -96,6 +96,7 @@
 
   private:
     bool ReverseBranchCondition(BBInfo &BBI);
+    bool BlockModifyPredicate(MachineBasicBlock *BB) const;
     void StructuralAnalysis(MachineBasicBlock *BB);
     bool FeasibilityAnalysis(BBInfo &BBI,
                              std::vector<MachineOperand> &Cond,
@@ -112,6 +113,11 @@
                         bool IgnoreTerm = false);
     void MergeBlocks(BBInfo &TrueBBI, BBInfo &FalseBBI);
 
+    // blockFallsThrough - Block ends without a terminator.
+    bool blockFallsThrough(BBInfo &BBI) const {
+      return BBI.IsAnalyzable && BBI.TrueBB == NULL;
+    }
+
     // IfcvtCandidateCmp - Used to sort if-conversion candidates.
     static bool IfcvtCandidateCmp(BBInfo* C1, BBInfo* C2){
       // Favor diamond over triangle, etc.
@@ -161,7 +167,9 @@
       case ICSimpleFalse: {
         bool isRev = BBI.Kind == ICSimpleFalse;
         DOUT << "Ifcvt (Simple" << (BBI.Kind == ICSimpleFalse ? " false" : "")
-             << "): BB#" << BBI.BB->getNumber() << " ";
+             << "): BB#" << BBI.BB->getNumber() << " ("
+             << ((BBI.Kind == ICSimpleFalse)
+                 ? BBI.FalseBB->getNumber() : BBI.TrueBB->getNumber()) << ") ";
         RetVal = IfConvertSimple(BBI);
         DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
         if (RetVal)
@@ -170,13 +178,19 @@
        break;
       }
       case ICTriangle:
-        DOUT << "Ifcvt (Triangle): BB#" << BBI.BB->getNumber() << " ";
+        DOUT << "Ifcvt (Triangle): BB#" << BBI.BB->getNumber() << " (T:"
+             << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber()
+             << ") ";
         RetVal = IfConvertTriangle(BBI);
         DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
         if (RetVal) NumTriangle++;
         break;
       case ICDiamond:
-        DOUT << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " ";
+        DOUT << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
+             << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber();
+        if (BBI.TailBB)
+          DOUT << "," << BBI.TailBB->getNumber() ;
+        DOUT << ") ";
         RetVal = IfConvertDiamond(BBI);
         DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
         if (RetVal) NumDiamonds++;
@@ -217,6 +231,17 @@
   return false;
 }
 
+/// BlockModifyPredicate - Returns true if any instruction in the block may
+/// clobber the condition code or register(s) used to predicate instructions,
+/// e.g. call, cmp.
+bool IfConverter::BlockModifyPredicate(MachineBasicBlock *BB) const {
+  for (MachineBasicBlock::const_reverse_iterator I = BB->rbegin(),
+         E = BB->rend(); I != E; ++I)
+    if (I->getInstrDescriptor()->Flags & M_CLOBBERS_PRED)
+      return true;
+  return false;
+}
+
 /// 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.
@@ -231,6 +256,7 @@
       return;  // Already analyzed.
     BBI.BB = BB;
     BBI.NonPredSize = std::distance(BB->begin(), BB->end());
+    BBI.ModifyPredicate = BlockModifyPredicate(BB);
   }
 
   // Look for 'root' of a simple (non-nested) triangle or diamond.
@@ -254,7 +280,13 @@
 
   StructuralAnalysis(BBI.FalseBB);
   BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
-  
+
+  // If both paths are dead, then forget about it.
+  if (TrueBBI.Kind == ICDead && FalseBBI.Kind == ICDead) {
+    BBI.Kind = ICDead;
+    return;
+  }
+
   // Look for more opportunities to if-convert a triangle. Try to restructure
   // the CFG to form a triangle with the 'false' path.
   std::vector<MachineOperand> RevCond(BBI.BrCond);
@@ -337,11 +369,12 @@
       }
     } 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 (FalseBBI.TrueBB && FalseBBI.TrueBB == BBI.TrueBB &&
-            FalseBBI.BB->pred_size() == 1) {
+        if (TryTriangle) {
           // Reverse 'true' and 'false' paths.
           ReverseBranchCondition(BBI);
           BBI.Kind = ICTriangle;
@@ -486,17 +519,13 @@
 /// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
 ///
 bool IfConverter::IfConvertSimple(BBInfo &BBI) {
-  bool ReverseCond = BBI.Kind == ICSimpleFalse;
-
-  BBI.Kind = ICNotClassfied;
-
   BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumber()];
   BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
   BBInfo *CvtBBI = &TrueBBI;
   BBInfo *NextBBI = &FalseBBI;
 
   std::vector<MachineOperand> Cond(BBI.BrCond);
-  if (ReverseCond) {
+  if (BBI.Kind == ICSimpleFalse) {
     std::swap(CvtBBI, NextBBI);
     TII->ReverseBranchCondition(Cond);
   }
@@ -517,23 +546,27 @@
   MergeBlocks(BBI, *CvtBBI);
   bool IterIfcvt = true;
   if (!isNextBlock(BBI.BB, NextBBI->BB)) {
-    // Now ifcvt'd block will look like this:
-    // BB:
-    // ...
-    // t, f = cmp
-    // 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.
     InsertUncondBranch(BBI.BB, NextBBI->BB, TII);
+    if (BBI.ModifyPredicate)
+      // Now ifcvt'd block will look like this:
+      // BB:
+      // ...
+      // t, f = cmp
+      // 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.
+      IterIfcvt = false;
   }
   std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
 
   // Update block info. BB can be iteratively if-converted.
   if (IterIfcvt)
     BBI.Kind = ICReAnalyze;
+  else
+    BBI.Kind = ICDead;
   ReTryPreds(BBI.BB);
   CvtBBI->Kind = ICDead;
 
@@ -544,8 +577,6 @@
 /// IfConvertTriangle - If convert a triangle sub-CFG.
 ///
 bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
-  BBI.Kind = ICNotClassfied;
-
   BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
 
   // Predicate the 'true' block after removing its branch.
@@ -571,17 +602,18 @@
     FalseBBDead = true;
   } else if (!isNextBlock(TrueBBI.BB, FalseBBI.BB)) {
     InsertUncondBranch(TrueBBI.BB, FalseBBI.BB, TII);
-    // Now ifcvt'd block will look like this:
-    // BB:
-    // ...
-    // t, f = cmp
-    // 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.
-    IterIfcvt = false;
+    if (BBI.ModifyPredicate || TrueBBI.ModifyPredicate)
+      // Now ifcvt'd block will look like this:
+      // BB:
+      // ...
+      // t, f = cmp
+      // 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.
+      IterIfcvt = false;
   }
 
   // Now merge the entry of the triangle with the true block.
@@ -593,6 +625,8 @@
   // Update block info. BB can be iteratively if-converted.
   if (IterIfcvt) 
     BBI.Kind = ICReAnalyze;
+  else
+    BBI.Kind = ICDead;
   ReTryPreds(BBI.BB);
   TrueBBI.Kind = ICDead;
   if (FalseBBDead)
@@ -605,8 +639,6 @@
 /// IfConvertDiamond - If convert a diamond sub-CFG.
 ///
 bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
-  BBI.Kind = ICNotClassfied;
-
   BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumber()];
   BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
 
@@ -714,6 +746,7 @@
   }
 
   // Update block info.
+  BBI.Kind = ICDead;
   TrueBBI.Kind = ICDead;
   FalseBBI.Kind = ICDead;
 
@@ -785,7 +818,10 @@
 
   // Transfer preds / succs and update size.
   TransferPreds(ToBBI.BB, FromBBI.BB);
-  TransferSuccs(ToBBI.BB, FromBBI.BB);
+  if (!blockFallsThrough(FromBBI.BB))
+    TransferSuccs(ToBBI.BB, FromBBI.BB);
   ToBBI.NonPredSize += FromBBI.NonPredSize;
   FromBBI.NonPredSize = 0;
+
+  ToBBI.ModifyPredicate |= FromBBI.ModifyPredicate;
 }






More information about the llvm-commits mailing list