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

Evan Cheng evan.cheng at apple.com
Fri May 18 11:14:57 PDT 2007



Changes in directory llvm/lib/CodeGen:

IfConversion.cpp updated: 1.7 -> 1.8
---
Log message:

Some restructuring in preparation for most aggressive if-conversion.

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

 IfConversion.cpp |  111 +++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 71 insertions(+), 40 deletions(-)


Index: llvm/lib/CodeGen/IfConversion.cpp
diff -u llvm/lib/CodeGen/IfConversion.cpp:1.7 llvm/lib/CodeGen/IfConversion.cpp:1.8
--- llvm/lib/CodeGen/IfConversion.cpp:1.7	Fri May 18 12:06:53 2007
+++ llvm/lib/CodeGen/IfConversion.cpp	Fri May 18 13:14:37 2007
@@ -39,16 +39,20 @@
     /// if-conversion feasibility analysis. This includes results from
     /// TargetInstrInfo::AnalyzeBranch() (i.e. TBB, FBB, and Cond), and its
     /// classification, and common tail block of its successors (if it's a
-    /// diamond shape).
+    /// diamond shape), its size, whether it's predicable, and whether any
+    /// instruction can clobber the 'would-be' predicate.
     struct BBInfo {
       BBICKind Kind;
+      unsigned Size;
+      bool isPredicable;
+      bool ClobbersPred;
       MachineBasicBlock *BB;
       MachineBasicBlock *TrueBB;
       MachineBasicBlock *FalseBB;
       MachineBasicBlock *TailBB;
       std::vector<MachineOperand> Cond;
-      unsigned Size;
-      BBInfo() : Kind(ICInvalid), BB(0), TrueBB(0), FalseBB(0), TailBB(0), Size(0) {}
+      BBInfo() : Kind(ICInvalid), Size(0), isPredicable(false),
+                 ClobbersPred(false), BB(0), TrueBB(0), FalseBB(0), TailBB(0) {}
     };
 
     /// BBAnalysis - Results of if-conversion feasibility analysis indexed by
@@ -66,12 +70,12 @@
     virtual const char *getPassName() const { return "If converter"; }
 
   private:
-    void AnalyzeBlock(MachineBasicBlock *BB);
+    void StructuralAnalysis(MachineBasicBlock *BB);
+    void FeasibilityAnalysis(BBInfo &BBI);
     void InitialFunctionAnalysis(MachineFunction &MF,
                                  std::vector<int> &Candidates);
-    bool IfConvertDiamond(BBInfo &BBI);
     bool IfConvertTriangle(BBInfo &BBI);
-    bool isBlockPredicable(MachineBasicBlock *BB) const;
+    bool IfConvertDiamond(BBInfo &BBI);
     void PredicateBlock(MachineBasicBlock *BB,
                         std::vector<MachineOperand> &Cond,
                         bool IgnoreTerm = false);
@@ -127,7 +131,10 @@
   return NULL;
 }
 
-void IfConverter::AnalyzeBlock(MachineBasicBlock *BB) {
+/// 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.
+void IfConverter::StructuralAnalysis(MachineBasicBlock *BB) {
   BBInfo &BBI = BBAnalysis[BB->getNumber()];
 
   if (BBI.Kind != ICInvalid)
@@ -147,7 +154,7 @@
     return;
 
   // Not a candidate if 'true' block is going to be if-converted.
-  AnalyzeBlock(BBI.TrueBB);
+  StructuralAnalysis(BBI.TrueBB);
   BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
   if (TrueBBI.Kind != ICNotClassfied)
     return;
@@ -168,7 +175,7 @@
     return;
 
   // Not a candidate if 'false' block is going to be if-converted.
-  AnalyzeBlock(BBI.FalseBB);
+  StructuralAnalysis(BBI.FalseBB);
   BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
   if (FalseBBI.Kind != ICNotClassfied)
     return;
@@ -203,13 +210,36 @@
   return;
 }
 
+/// FeasibilityAnalysis - Determine if the block is predicable. In most
+/// cases, that means all the instructions in the block has M_PREDICABLE flag.
+/// Also checks if the block contains any instruction which can clobber a
+/// predicate (e.g. condition code register). If so, the block is not
+/// predicable unless it's the last instruction. Note, this function assumes
+/// all the terminator instructions can be converted or deleted so it ignore
+/// them.
+void IfConverter::FeasibilityAnalysis(BBInfo &BBI) {
+  if (BBI.Size == 0 || BBI.Size > TLI->getIfCvtBlockSizeLimit())
+    return;
+
+  for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end();
+       I != E; ++I) {
+    // TODO: check if instruction clobbers predicate.
+    if (TII->isTerminatorInstr(I->getOpcode()))
+      break;
+    if (!I->isPredicable())
+      return;
+  }
+
+  BBI.isPredicable = true;
+}
+
 /// InitialFunctionAnalysis - Analyze all blocks and find entries for all
 /// if-conversion candidates.
 void IfConverter::InitialFunctionAnalysis(MachineFunction &MF,
                                           std::vector<int> &Candidates) {
   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
     MachineBasicBlock *BB = I;
-    AnalyzeBlock(BB);
+    StructuralAnalysis(BB);
     BBInfo &BBI = BBAnalysis[BB->getNumber()];
     if (BBI.Kind == ICTriangleEntry || BBI.Kind == ICDiamondEntry)
       Candidates.push_back(BB->getNumber());
@@ -245,8 +275,10 @@
 /// IfConvertTriangle - If convert a triangle sub-CFG.
 ///
 bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
-  if (isBlockPredicable(BBI.TrueBB)) {
-    BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
+  BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
+  FeasibilityAnalysis(TrueBBI);
+
+  if (TrueBBI.isPredicable) {
     BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
 
     // Predicate the 'true' block after removing its branch.
@@ -276,7 +308,29 @@
 /// IfConvertDiamond - If convert a diamond sub-CFG.
 ///
 bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
-  if (isBlockPredicable(BBI.TrueBB) && isBlockPredicable(BBI.FalseBB)) {
+  BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
+  BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
+  FeasibilityAnalysis(TrueBBI);
+  FeasibilityAnalysis(FalseBBI);
+
+  if (TrueBBI.isPredicable && FalseBBI.isPredicable) {
+    // Check the 'true' and 'false' blocks if either isn't ended with a branch.
+    // Either the block fallthrough to another block or it ends with a
+    // return. If it's the former, add a conditional branch to its successor.
+    bool Proceed = true;
+    bool TrueNeedCBr  = !TrueBBI.TrueBB && BBI.TrueBB->succ_size();
+    bool FalseNeedCBr = !FalseBBI.TrueBB && BBI.FalseBB->succ_size();
+    if (TrueNeedCBr && TrueBBI.ClobbersPred) {
+      TrueBBI.isPredicable = false;
+      Proceed = false;
+    }
+    if (FalseNeedCBr && FalseBBI.ClobbersPred) {
+      FalseBBI.isPredicable = false;
+      Proceed = false;
+    }
+    if (!Proceed)
+      return false;
+
     std::vector<MachineInstr*> Dups;
     if (!BBI.TailBB) {
       // No common merge block. Check if the terminators (e.g. return) are
@@ -301,9 +355,6 @@
           return false; // Can't if-convert. Abort!
     }
 
-    BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
-    BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
-
     // Remove the duplicated instructions from the 'true' block.
     for (unsigned i = 0, e = Dups.size(); i != e; ++i) {
       Dups[i]->eraseFromParent();
@@ -314,9 +365,8 @@
     TrueBBI.Size -= TII->RemoveBranch(*BBI.TrueBB);
     PredicateBlock(BBI.TrueBB, BBI.Cond);
 
-    // Either the 'true' block fallthrough to another block or it ends with a
-    // return. If it's the former, add a conditional branch to its successor.
-    if (!TrueBBI.TrueBB && BBI.TrueBB->succ_size())
+    // Add a conditional branch to 'true' successor if needed.
+    if (TrueNeedCBr)
       TII->InsertBranch(*BBI.TrueBB, *BBI.TrueBB->succ_begin(), NULL, BBI.Cond);
 
     // Predicate the 'false' block.
@@ -324,9 +374,8 @@
     TII->ReverseBranchCondition(NewCond);
     PredicateBlock(BBI.FalseBB, NewCond, true);
 
-    // Either the 'false' block fallthrough to another block or it ends with a
-    // return. If it's the former, add a conditional branch to its successor.
-    if (!FalseBBI.TrueBB && BBI.FalseBB->succ_size())
+    // Add a conditional branch to 'false' successor if needed.
+    if (FalseNeedCBr)
       TII->InsertBranch(*BBI.FalseBB, *BBI.FalseBB->succ_begin(), NULL,NewCond);
 
     // Merge the 'true' and 'false' blocks by copying the instructions
@@ -370,24 +419,6 @@
   return false;
 }
 
-/// isBlockPredicable - Returns true if the block is predicable. In most
-/// cases, that means all the instructions in the block has M_PREDICABLE flag.
-/// It assume all the terminator instructions can be converted or deleted.
-bool IfConverter::isBlockPredicable(MachineBasicBlock *BB) const {
-  const BBInfo &BBI = BBAnalysis[BB->getNumber()];
-  if (BBI.Size == 0 || BBI.Size > TLI->getIfCvtBlockSizeLimit())
-    return false;
-
-  for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
-       I != E; ++I) {
-    if (TII->isTerminatorInstr(I->getOpcode()))
-      continue;
-    if (!I->isPredicable())
-      return false;
-  }
-  return true;
-}
-
 /// PredicateBlock - Predicate every instruction in the block with the specified
 /// condition. If IgnoreTerm is true, skip over all terminator instructions.
 void IfConverter::PredicateBlock(MachineBasicBlock *BB,






More information about the llvm-commits mailing list