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,
|
||||
unsigned &Dups1, unsigned &Dups2) const;
|
||||
void ScanInstructions(BBInfo &BBI);
|
||||
BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
|
||||
std::vector<IfcvtToken*> &Tokens);
|
||||
void AnalyzeBlock(MachineBasicBlock *MBB, std::vector<IfcvtToken*> &Tokens);
|
||||
bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool isTriangle = false, bool RevBranch = false);
|
||||
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
|
||||
/// the specified block. Record its successors and whether it looks like an
|
||||
/// if-conversion candidate.
|
||||
IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
|
||||
void IfConverter::AnalyzeBlock(MachineBasicBlock *MBB,
|
||||
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()];
|
||||
|
||||
if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
|
||||
return BBI;
|
||||
if (!State.SuccsAnalyzed) {
|
||||
if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
|
||||
BBStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
BBI.BB = BB;
|
||||
BBI.IsBeingAnalyzed = true;
|
||||
|
||||
ScanInstructions(BBI);
|
||||
|
||||
// Unanalyzable or ends with fallthrough or unconditional branch, or if is not
|
||||
// considered for ifcvt anymore.
|
||||
// Unanalyzable or ends with fallthrough or unconditional branch, or if is
|
||||
// not considered for ifcvt anymore.
|
||||
if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
|
||||
BBI.IsBeingAnalyzed = false;
|
||||
BBI.IsAnalyzed = true;
|
||||
return BBI;
|
||||
BBStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do not ifcvt if either path is a back edge to the entry block.
|
||||
if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
|
||||
BBI.IsBeingAnalyzed = false;
|
||||
BBI.IsAnalyzed = true;
|
||||
return BBI;
|
||||
BBStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do not ifcvt if true and false fallthrough blocks are the same.
|
||||
if (!BBI.FalseBB) {
|
||||
BBI.IsBeingAnalyzed = false;
|
||||
BBI.IsAnalyzed = true;
|
||||
return BBI;
|
||||
BBStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens);
|
||||
BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
|
||||
// Push the False and True blocks to the stack.
|
||||
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) {
|
||||
BBI.IsBeingAnalyzed = false;
|
||||
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);
|
||||
|
||||
unsigned Dups = 0;
|
||||
|
@ -912,7 +940,8 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
|
|||
BBI.IsEnqueued = Enqueued;
|
||||
BBI.IsBeingAnalyzed = false;
|
||||
BBI.IsAnalyzed = true;
|
||||
return BBI;
|
||||
BBStack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
|
||||
|
|
Loading…
Reference in New Issue