[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