Lots of bug fixes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37467 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2007-06-06 10:16:17 +00:00
parent c1d7384cb0
commit 7a655479ae

View File

@@ -41,7 +41,7 @@ namespace {
ICTriangle, // BB is entry of a triangle sub-CFG. ICTriangle, // BB is entry of a triangle sub-CFG.
ICDiamond, // BB is entry of a diamond sub-CFG. ICDiamond, // BB is entry of a diamond sub-CFG.
ICChild, // BB is part of the sub-CFG that'll be predicated. 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 /// BBInfo - One per MachineBasicBlock, this is used to cache the result
@@ -54,8 +54,8 @@ namespace {
/// Kind - Type of block. See BBICKind. /// Kind - Type of block. See BBICKind.
/// NonPredSize - Number of non-predicated instructions. /// NonPredSize - Number of non-predicated instructions.
/// IsAnalyzable - True if AnalyzeBranch() returns false. /// IsAnalyzable - True if AnalyzeBranch() returns false.
/// ModifyPredicate - FIXME: Not used right now. True if BB would modify /// ModifyPredicate - True if BB would modify the predicate (e.g. has
/// the predicate (e.g. has cmp, call, etc.) /// cmp, call, etc.)
/// BB - Corresponding MachineBasicBlock. /// BB - Corresponding MachineBasicBlock.
/// TrueBB / FalseBB- See AnalyzeBranch(). /// TrueBB / FalseBB- See AnalyzeBranch().
/// BrCond - Conditions for end of block conditional branches. /// BrCond - Conditions for end of block conditional branches.
@@ -96,6 +96,7 @@ namespace {
private: private:
bool ReverseBranchCondition(BBInfo &BBI); bool ReverseBranchCondition(BBInfo &BBI);
bool BlockModifyPredicate(MachineBasicBlock *BB) const;
void StructuralAnalysis(MachineBasicBlock *BB); void StructuralAnalysis(MachineBasicBlock *BB);
bool FeasibilityAnalysis(BBInfo &BBI, bool FeasibilityAnalysis(BBInfo &BBI,
std::vector<MachineOperand> &Cond, std::vector<MachineOperand> &Cond,
@@ -112,6 +113,11 @@ namespace {
bool IgnoreTerm = false); bool IgnoreTerm = false);
void MergeBlocks(BBInfo &TrueBBI, BBInfo &FalseBBI); 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. // IfcvtCandidateCmp - Used to sort if-conversion candidates.
static bool IfcvtCandidateCmp(BBInfo* C1, BBInfo* C2){ static bool IfcvtCandidateCmp(BBInfo* C1, BBInfo* C2){
// Favor diamond over triangle, etc. // Favor diamond over triangle, etc.
@@ -161,7 +167,9 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
case ICSimpleFalse: { case ICSimpleFalse: {
bool isRev = BBI.Kind == ICSimpleFalse; bool isRev = BBI.Kind == ICSimpleFalse;
DOUT << "Ifcvt (Simple" << (BBI.Kind == ICSimpleFalse ? " false" : "") 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); RetVal = IfConvertSimple(BBI);
DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
if (RetVal) if (RetVal)
@@ -170,13 +178,19 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
break; break;
} }
case ICTriangle: 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); RetVal = IfConvertTriangle(BBI);
DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
if (RetVal) NumTriangle++; if (RetVal) NumTriangle++;
break; break;
case ICDiamond: 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); RetVal = IfConvertDiamond(BBI);
DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; DOUT << (RetVal ? "succeeded!" : "failed!") << "\n";
if (RetVal) NumDiamonds++; if (RetVal) NumDiamonds++;
@@ -217,6 +231,17 @@ bool IfConverter::ReverseBranchCondition(BBInfo &BBI) {
return false; 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 /// StructuralAnalysis - Analyze the structure of the sub-CFG starting from
/// the specified block. Record its successors and whether it looks like an /// the specified block. Record its successors and whether it looks like an
/// if-conversion candidate. /// if-conversion candidate.
@@ -231,6 +256,7 @@ void IfConverter::StructuralAnalysis(MachineBasicBlock *BB) {
return; // Already analyzed. return; // Already analyzed.
BBI.BB = BB; BBI.BB = BB;
BBI.NonPredSize = std::distance(BB->begin(), BB->end()); BBI.NonPredSize = std::distance(BB->begin(), BB->end());
BBI.ModifyPredicate = BlockModifyPredicate(BB);
} }
// Look for 'root' of a simple (non-nested) triangle or diamond. // Look for 'root' of a simple (non-nested) triangle or diamond.
@@ -254,7 +280,13 @@ void IfConverter::StructuralAnalysis(MachineBasicBlock *BB) {
StructuralAnalysis(BBI.FalseBB); StructuralAnalysis(BBI.FalseBB);
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; 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 // Look for more opportunities to if-convert a triangle. Try to restructure
// the CFG to form a triangle with the 'false' path. // the CFG to form a triangle with the 'false' path.
std::vector<MachineOperand> RevCond(BBI.BrCond); std::vector<MachineOperand> RevCond(BBI.BrCond);
@@ -337,11 +369,12 @@ void IfConverter::StructuralAnalysis(MachineBasicBlock *BB) {
} }
} else if (FalseBBI.BrCond.size() == 0 && FalseBBI.BB->pred_size() == 1) { } else if (FalseBBI.BrCond.size() == 0 && FalseBBI.BB->pred_size() == 1) {
// Try the other path... // Try the other path...
bool TryTriangle = FalseBBI.TrueBB && FalseBBI.TrueBB == BBI.TrueBB &&
FalseBBI.BB->pred_size() == 1;
std::vector<MachineOperand> RevCond(BBI.BrCond); std::vector<MachineOperand> RevCond(BBI.BrCond);
if (!TII->ReverseBranchCondition(RevCond) && if (!TII->ReverseBranchCondition(RevCond) &&
FeasibilityAnalysis(FalseBBI, RevCond)) { FeasibilityAnalysis(FalseBBI, RevCond)) {
if (FalseBBI.TrueBB && FalseBBI.TrueBB == BBI.TrueBB && if (TryTriangle) {
FalseBBI.BB->pred_size() == 1) {
// Reverse 'true' and 'false' paths. // Reverse 'true' and 'false' paths.
ReverseBranchCondition(BBI); ReverseBranchCondition(BBI);
BBI.Kind = ICTriangle; BBI.Kind = ICTriangle;
@@ -486,17 +519,13 @@ static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB,
/// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG. /// IfConvertSimple - If convert a simple (split, no rejoin) sub-CFG.
/// ///
bool IfConverter::IfConvertSimple(BBInfo &BBI) { bool IfConverter::IfConvertSimple(BBInfo &BBI) {
bool ReverseCond = BBI.Kind == ICSimpleFalse;
BBI.Kind = ICNotClassfied;
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
BBInfo *CvtBBI = &TrueBBI; BBInfo *CvtBBI = &TrueBBI;
BBInfo *NextBBI = &FalseBBI; BBInfo *NextBBI = &FalseBBI;
std::vector<MachineOperand> Cond(BBI.BrCond); std::vector<MachineOperand> Cond(BBI.BrCond);
if (ReverseCond) { if (BBI.Kind == ICSimpleFalse) {
std::swap(CvtBBI, NextBBI); std::swap(CvtBBI, NextBBI);
TII->ReverseBranchCondition(Cond); TII->ReverseBranchCondition(Cond);
} }
@@ -517,23 +546,27 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI) {
MergeBlocks(BBI, *CvtBBI); MergeBlocks(BBI, *CvtBBI);
bool IterIfcvt = true; bool IterIfcvt = true;
if (!isNextBlock(BBI.BB, NextBBI->BB)) { 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); 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)); std::copy(Cond.begin(), Cond.end(), std::back_inserter(BBI.Predicate));
// Update block info. BB can be iteratively if-converted. // Update block info. BB can be iteratively if-converted.
if (IterIfcvt) if (IterIfcvt)
BBI.Kind = ICReAnalyze; BBI.Kind = ICReAnalyze;
else
BBI.Kind = ICDead;
ReTryPreds(BBI.BB); ReTryPreds(BBI.BB);
CvtBBI->Kind = ICDead; CvtBBI->Kind = ICDead;
@@ -544,8 +577,6 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI) {
/// IfConvertTriangle - If convert a triangle sub-CFG. /// IfConvertTriangle - If convert a triangle sub-CFG.
/// ///
bool IfConverter::IfConvertTriangle(BBInfo &BBI) { bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
BBI.Kind = ICNotClassfied;
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
// Predicate the 'true' block after removing its branch. // Predicate the 'true' block after removing its branch.
@@ -571,17 +602,18 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
FalseBBDead = true; FalseBBDead = true;
} else if (!isNextBlock(TrueBBI.BB, FalseBBI.BB)) { } else if (!isNextBlock(TrueBBI.BB, FalseBBI.BB)) {
InsertUncondBranch(TrueBBI.BB, FalseBBI.BB, TII); InsertUncondBranch(TrueBBI.BB, FalseBBI.BB, TII);
// Now ifcvt'd block will look like this: if (BBI.ModifyPredicate || TrueBBI.ModifyPredicate)
// BB: // Now ifcvt'd block will look like this:
// ... // BB:
// t, f = cmp // ...
// if t op // t, f = cmp
// b BBf // 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 // We cannot further ifcvt this block because the unconditional branch will
// if cmp executes. // have to be predicated on the new condition, that will not be available
IterIfcvt = false; // if cmp executes.
IterIfcvt = false;
} }
// Now merge the entry of the triangle with the true block. // Now merge the entry of the triangle with the true block.
@@ -593,6 +625,8 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
// Update block info. BB can be iteratively if-converted. // Update block info. BB can be iteratively if-converted.
if (IterIfcvt) if (IterIfcvt)
BBI.Kind = ICReAnalyze; BBI.Kind = ICReAnalyze;
else
BBI.Kind = ICDead;
ReTryPreds(BBI.BB); ReTryPreds(BBI.BB);
TrueBBI.Kind = ICDead; TrueBBI.Kind = ICDead;
if (FalseBBDead) if (FalseBBDead)
@@ -605,8 +639,6 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
/// IfConvertDiamond - If convert a diamond sub-CFG. /// IfConvertDiamond - If convert a diamond sub-CFG.
/// ///
bool IfConverter::IfConvertDiamond(BBInfo &BBI) { bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
BBI.Kind = ICNotClassfied;
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
@@ -714,6 +746,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
} }
// Update block info. // Update block info.
BBI.Kind = ICDead;
TrueBBI.Kind = ICDead; TrueBBI.Kind = ICDead;
FalseBBI.Kind = ICDead; FalseBBI.Kind = ICDead;
@@ -785,7 +818,10 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI) {
// Transfer preds / succs and update size. // Transfer preds / succs and update size.
TransferPreds(ToBBI.BB, FromBBI.BB); TransferPreds(ToBBI.BB, FromBBI.BB);
TransferSuccs(ToBBI.BB, FromBBI.BB); if (!blockFallsThrough(FromBBI.BB))
TransferSuccs(ToBBI.BB, FromBBI.BB);
ToBBI.NonPredSize += FromBBI.NonPredSize; ToBBI.NonPredSize += FromBBI.NonPredSize;
FromBBI.NonPredSize = 0; FromBBI.NonPredSize = 0;
ToBBI.ModifyPredicate |= FromBBI.ModifyPredicate;
} }