mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 22:23:10 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user