forked from OSchip/llvm-project
[If Converter] Convert recursion to iteration.
This commit makes changes to IfConverter::AnalyzeBlock to use iteration instead of recursion. Previously, this function would get called recursively a large number of times and eventually segfault when a function with the following CFG was compiled: BB0: if (condition0) goto BB1 goto BB2 BB1: goto BB2 BB2: if (condition1) goto BB3 goto BB4 BB3: ... (repeat until BB7488) rdar://problem/21386145 Differential Revision: http://reviews.llvm.org/D10587 llvm-svn: 240589
This commit is contained in:
parent
75403d7753
commit
14348aa2c5
|
@ -197,8 +197,7 @@ namespace {
|
||||||
bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
|
||||||
unsigned &Dups1, unsigned &Dups2) const;
|
unsigned &Dups1, unsigned &Dups2) const;
|
||||||
void ScanInstructions(BBInfo &BBI);
|
void ScanInstructions(BBInfo &BBI);
|
||||||
BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
|
void AnalyzeBlock(MachineBasicBlock *MBB, std::vector<IfcvtToken*> &Tokens);
|
||||||
std::vector<IfcvtToken*> &Tokens);
|
|
||||||
bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
|
bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
|
||||||
bool isTriangle = false, bool RevBranch = false);
|
bool isTriangle = false, bool RevBranch = false);
|
||||||
void AnalyzeBlocks(MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
|
void AnalyzeBlocks(MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
|
||||||
|
@ -764,50 +763,79 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
|
||||||
/// AnalyzeBlock - Analyze the structure of the sub-CFG starting from
|
/// AnalyzeBlock - 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.
|
||||||
IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
|
void IfConverter::AnalyzeBlock(MachineBasicBlock *MBB,
|
||||||
std::vector<IfcvtToken*> &Tokens) {
|
std::vector<IfcvtToken*> &Tokens) {
|
||||||
|
struct BBState {
|
||||||
|
BBState(MachineBasicBlock *BB) : MBB(BB), SuccsAnalyzed(false) {}
|
||||||
|
MachineBasicBlock *MBB;
|
||||||
|
|
||||||
|
/// This flag is true if MBB's successors have been analyzed.
|
||||||
|
bool SuccsAnalyzed;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Push MBB to the stack.
|
||||||
|
SmallVector<BBState, 16> BBStack(1, MBB);
|
||||||
|
|
||||||
|
while (!BBStack.empty()) {
|
||||||
|
BBState &State = BBStack.back();
|
||||||
|
MachineBasicBlock *BB = State.MBB;
|
||||||
BBInfo &BBI = BBAnalysis[BB->getNumber()];
|
BBInfo &BBI = BBAnalysis[BB->getNumber()];
|
||||||
|
|
||||||
if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
|
if (!State.SuccsAnalyzed) {
|
||||||
return BBI;
|
if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
|
||||||
|
BBStack.pop_back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BBI.BB = BB;
|
BBI.BB = BB;
|
||||||
BBI.IsBeingAnalyzed = true;
|
BBI.IsBeingAnalyzed = true;
|
||||||
|
|
||||||
ScanInstructions(BBI);
|
ScanInstructions(BBI);
|
||||||
|
|
||||||
// Unanalyzable or ends with fallthrough or unconditional branch, or if is not
|
// Unanalyzable or ends with fallthrough or unconditional branch, or if is
|
||||||
// considered for ifcvt anymore.
|
// not considered for ifcvt anymore.
|
||||||
if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
|
if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
|
||||||
BBI.IsBeingAnalyzed = false;
|
BBI.IsBeingAnalyzed = false;
|
||||||
BBI.IsAnalyzed = true;
|
BBI.IsAnalyzed = true;
|
||||||
return BBI;
|
BBStack.pop_back();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not ifcvt if either path is a back edge to the entry block.
|
// Do not ifcvt if either path is a back edge to the entry block.
|
||||||
if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
|
if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
|
||||||
BBI.IsBeingAnalyzed = false;
|
BBI.IsBeingAnalyzed = false;
|
||||||
BBI.IsAnalyzed = true;
|
BBI.IsAnalyzed = true;
|
||||||
return BBI;
|
BBStack.pop_back();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not ifcvt if true and false fallthrough blocks are the same.
|
// Do not ifcvt if true and false fallthrough blocks are the same.
|
||||||
if (!BBI.FalseBB) {
|
if (!BBI.FalseBB) {
|
||||||
BBI.IsBeingAnalyzed = false;
|
BBI.IsBeingAnalyzed = false;
|
||||||
BBI.IsAnalyzed = true;
|
BBI.IsAnalyzed = true;
|
||||||
return BBI;
|
BBStack.pop_back();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens);
|
// Push the False and True blocks to the stack.
|
||||||
BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
|
State.SuccsAnalyzed = true;
|
||||||
|
BBStack.push_back(BBI.FalseBB);
|
||||||
|
BBStack.push_back(BBI.TrueBB);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
|
||||||
|
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
|
||||||
|
|
||||||
if (TrueBBI.IsDone && FalseBBI.IsDone) {
|
if (TrueBBI.IsDone && FalseBBI.IsDone) {
|
||||||
BBI.IsBeingAnalyzed = false;
|
BBI.IsBeingAnalyzed = false;
|
||||||
BBI.IsAnalyzed = true;
|
BBI.IsAnalyzed = true;
|
||||||
return BBI;
|
BBStack.pop_back();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
|
SmallVector<MachineOperand, 4>
|
||||||
|
RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
|
||||||
bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
|
bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
|
||||||
|
|
||||||
unsigned Dups = 0;
|
unsigned Dups = 0;
|
||||||
|
@ -912,7 +940,8 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
|
||||||
BBI.IsEnqueued = Enqueued;
|
BBI.IsEnqueued = Enqueued;
|
||||||
BBI.IsBeingAnalyzed = false;
|
BBI.IsBeingAnalyzed = false;
|
||||||
BBI.IsAnalyzed = true;
|
BBI.IsAnalyzed = true;
|
||||||
return BBI;
|
BBStack.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
|
/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
|
||||||
|
|
Loading…
Reference in New Issue