1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

Try to appease MSVC, NFCI.

This time by lifting the lambda's in `createNodeFromSelectLikePHI` to
the file scope.  Looks like there are differences in capture rules
between clang and MSVC?

llvm-svn: 249222
This commit is contained in:
Sanjoy Das 2015-10-03 00:34:19 +00:00
parent d683063aaa
commit 4572919871

View File

@ -3742,116 +3742,116 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
return nullptr; return nullptr;
} }
const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) { // Checks if the SCEV S is available at BB. S is considered available at BB
const Loop *L = LI.getLoopFor(PN->getParent()); // if S can be materialized at BB without introducing a fault.
static bool IsAvailableOnEntry(const Loop *L, DominatorTree &DT, const SCEV *S,
BasicBlock *BB) {
struct CheckAvailable {
bool TraversalDone = false;
bool Available = true;
// Try to match a control flow sequence that branches out at BI and merges const Loop *L = nullptr; // The loop BB is in (can be nullptr)
// back at Merge into a "C ? LHS : RHS" select pattern. Return true on a BasicBlock *BB = nullptr;
// successful match. DominatorTree &DT;
auto BrPHIToSelect = [&](BranchInst *BI, PHINode *Merge, Value *&C,
Value *&LHS, Value *&RHS) {
C = BI->getCondition();
BasicBlockEdge LeftEdge(BI->getParent(), BI->getSuccessor(0)); CheckAvailable(const Loop *L, BasicBlock *BB, DominatorTree &DT)
BasicBlockEdge RightEdge(BI->getParent(), BI->getSuccessor(1)); : L(L), BB(BB), DT(DT) {}
if (!LeftEdge.isSingleEdge()) bool setUnavailable() {
TraversalDone = true;
Available = false;
return false; return false;
assert(RightEdge.isSingleEdge() && "Follows from LeftEdge.isSingleEdge()");
Use &LeftUse = Merge->getOperandUse(0);
Use &RightUse = Merge->getOperandUse(1);
if (DT.dominates(LeftEdge, LeftUse) && DT.dominates(RightEdge, RightUse)) {
LHS = LeftUse;
RHS = RightUse;
return true;
} }
if (DT.dominates(LeftEdge, RightUse) && DT.dominates(RightEdge, LeftUse)) { bool follow(const SCEV *S) {
LHS = RightUse; switch (S->getSCEVType()) {
RHS = LeftUse; case scConstant: case scTruncate: case scZeroExtend: case scSignExtend:
case scAddExpr: case scMulExpr: case scUMaxExpr: case scSMaxExpr:
// These expressions are available if their operand(s) is/are.
return true; return true;
}
return false; case scAddRecExpr: {
}; // We allow add recurrences that are on the loop BB is in, or some
// outer loop. This guarantees availability because the value of the
// Checks if the SCEV S is available at BB. S is considered available at BB // add recurrence at BB is simply the "current" value of the induction
// if S can be materialized at BB without introducing a fault. // variable. We can relax this in the future; for instance an add
auto IsAvailableOnEntry = [&](const SCEV *S, BasicBlock *BB) { // recurrence on a sibling dominating loop is also available at BB.
struct CheckAvailable { const auto *ARLoop = cast<SCEVAddRecExpr>(S)->getLoop();
bool TraversalDone = false; if (L && (ARLoop == L || ARLoop->contains(L)))
bool Available = true;
const Loop *L = nullptr; // The loop BB is in (can be nullptr)
BasicBlock *BB = nullptr;
DominatorTree &DT;
CheckAvailable(const Loop *L, BasicBlock *BB, DominatorTree &DT)
: L(L), BB(BB), DT(DT) {}
bool setUnavailable() {
TraversalDone = true;
Available = false;
return false;
}
bool follow(const SCEV *S) {
switch (S->getSCEVType()) {
case scConstant: case scTruncate: case scZeroExtend: case scSignExtend:
case scAddExpr: case scMulExpr: case scUMaxExpr: case scSMaxExpr:
// These expressions are available if their operand(s) is/are.
return true; return true;
case scAddRecExpr: { return setUnavailable();
// We allow add recurrences that are on the loop BB is in, or some
// outer loop. This guarantees availability because the value of the
// add recurrence at BB is simply the "current" value of the induction
// variable. We can relax this in the future; for instance an add
// recurrence on a sibling dominating loop is also available at BB.
const auto *ARLoop = cast<SCEVAddRecExpr>(S)->getLoop();
if (L && (ARLoop == L || ARLoop->contains(L)))
return true;
return setUnavailable();
}
case scUnknown: {
// For SCEVUnknown, we check for simple dominance.
const auto *SU = cast<SCEVUnknown>(S);
Value *V = SU->getValue();
if (isa<Argument>(V))
return false;
if (isa<Instruction>(V) &&
this->DT.dominates(cast<Instruction>(V), BB))
return false;
return setUnavailable();
}
case scUDivExpr:
case scCouldNotCompute:
// We do not try to smart about these at all.
return setUnavailable();
}
llvm_unreachable("switch should be fully covered!");
} }
bool isDone() { return TraversalDone; } case scUnknown: {
}; // For SCEVUnknown, we check for simple dominance.
const auto *SU = cast<SCEVUnknown>(S);
Value *V = SU->getValue();
CheckAvailable CA(L, BB, this->DT); if (isa<Argument>(V))
SCEVTraversal<CheckAvailable> ST(CA); return false;
ST.visitAll(S); if (isa<Instruction>(V) && DT.dominates(cast<Instruction>(V), BB))
return CA.Available; return false;
return setUnavailable();
}
case scUDivExpr:
case scCouldNotCompute:
// We do not try to smart about these at all.
return setUnavailable();
}
llvm_unreachable("switch should be fully covered!");
}
bool isDone() { return TraversalDone; }
}; };
CheckAvailable CA(L, BB, DT);
SCEVTraversal<CheckAvailable> ST(CA);
ST.visitAll(S);
return CA.Available;
}
// Try to match a control flow sequence that branches out at BI and merges back
// at Merge into a "C ? LHS : RHS" select pattern. Return true on a successful
// match.
static bool BrPHIToSelect(DominatorTree &DT, BranchInst *BI, PHINode *Merge,
Value *&C, Value *&LHS, Value *&RHS) {
C = BI->getCondition();
BasicBlockEdge LeftEdge(BI->getParent(), BI->getSuccessor(0));
BasicBlockEdge RightEdge(BI->getParent(), BI->getSuccessor(1));
if (!LeftEdge.isSingleEdge())
return false;
assert(RightEdge.isSingleEdge() && "Follows from LeftEdge.isSingleEdge()");
Use &LeftUse = Merge->getOperandUse(0);
Use &RightUse = Merge->getOperandUse(1);
if (DT.dominates(LeftEdge, LeftUse) && DT.dominates(RightEdge, RightUse)) {
LHS = LeftUse;
RHS = RightUse;
return true;
}
if (DT.dominates(LeftEdge, RightUse) && DT.dominates(RightEdge, LeftUse)) {
LHS = RightUse;
RHS = LeftUse;
return true;
}
return false;
}
const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
if (PN->getNumIncomingValues() == 2) { if (PN->getNumIncomingValues() == 2) {
const Loop *L = LI.getLoopFor(PN->getParent());
// Try to match // Try to match
// //
// br %cond, label %left, label %right // br %cond, label %left, label %right
@ -3870,9 +3870,10 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
auto *BI = dyn_cast<BranchInst>(IDom->getTerminator()); auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr; Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
if (BI && BI->isConditional() && BrPHIToSelect(BI, PN, Cond, LHS, RHS) && if (BI && BI->isConditional() &&
IsAvailableOnEntry(getSCEV(LHS), PN->getParent()) && BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS) &&
IsAvailableOnEntry(getSCEV(RHS), PN->getParent())) IsAvailableOnEntry(L, DT, getSCEV(LHS), PN->getParent()) &&
IsAvailableOnEntry(L, DT, getSCEV(RHS), PN->getParent()))
return createNodeForSelectOrPHI(PN, Cond, LHS, RHS); return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
} }