mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Move SCEV::isLoopInvariant and hasComputableLoopEvolution to be member
functions of ScalarEvolution, in preparation for memoization and other optimizations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119562 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f8dabac604
commit
17ead4ff4b
@ -78,16 +78,6 @@ namespace llvm {
|
||||
|
||||
unsigned getSCEVType() const { return SCEVType; }
|
||||
|
||||
/// isLoopInvariant - Return true if the value of this SCEV is unchanging in
|
||||
/// the specified loop.
|
||||
virtual bool isLoopInvariant(const Loop *L) const = 0;
|
||||
|
||||
/// hasComputableLoopEvolution - Return true if this SCEV changes value in a
|
||||
/// known way in the specified loop. This property being true implies that
|
||||
/// the value is variant in the loop AND that we can emit an expression to
|
||||
/// compute the value of the expression at any particular loop iteration.
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const = 0;
|
||||
|
||||
/// getType - Return the LLVM type of this SCEV expression.
|
||||
///
|
||||
virtual const Type *getType() const = 0;
|
||||
@ -156,9 +146,7 @@ namespace llvm {
|
||||
SCEVCouldNotCompute();
|
||||
|
||||
// None of these methods are valid for this object.
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
virtual const Type *getType() const;
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const;
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
virtual bool hasOperand(const SCEV *Op) const;
|
||||
|
||||
@ -701,6 +689,16 @@ namespace llvm {
|
||||
const SCEV *&LHS,
|
||||
const SCEV *&RHS);
|
||||
|
||||
/// isLoopInvariant - Return true if the value of the given SCEV is
|
||||
/// unchanging in the specified loop.
|
||||
bool isLoopInvariant(const SCEV *S, const Loop *L);
|
||||
|
||||
/// hasComputableLoopEvolution - Return true if the given SCEV changes value
|
||||
/// in a known way in the specified loop. This property being true implies
|
||||
/// that the value is variant in the loop AND that we can emit an expression
|
||||
/// to compute the value of the expression at any particular loop iteration.
|
||||
bool hasComputableLoopEvolution(const SCEV *S, const Loop *L);
|
||||
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual void releaseMemory();
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
@ -42,14 +42,6 @@ namespace llvm {
|
||||
public:
|
||||
ConstantInt *getValue() const { return V; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const {
|
||||
return false; // Not loop variant
|
||||
}
|
||||
|
||||
virtual const Type *getType() const;
|
||||
|
||||
virtual bool hasOperand(const SCEV *) const {
|
||||
@ -88,14 +80,6 @@ namespace llvm {
|
||||
const SCEV *getOperand() const { return Op; }
|
||||
virtual const Type *getType() const { return Ty; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const {
|
||||
return Op->isLoopInvariant(L);
|
||||
}
|
||||
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const {
|
||||
return Op->hasComputableLoopEvolution(L);
|
||||
}
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const {
|
||||
return Op == O || Op->hasOperand(O);
|
||||
}
|
||||
@ -202,13 +186,6 @@ namespace llvm {
|
||||
op_iterator op_begin() const { return Operands; }
|
||||
op_iterator op_end() const { return Operands + NumOperands; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
|
||||
// hasComputableLoopEvolution - N-ary expressions have computable loop
|
||||
// evolutions iff they have at least one operand that varies with the loop,
|
||||
// but that all varying operands are computable.
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const;
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const;
|
||||
|
||||
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
|
||||
@ -328,15 +305,6 @@ namespace llvm {
|
||||
const SCEV *getLHS() const { return LHS; }
|
||||
const SCEV *getRHS() const { return RHS; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const {
|
||||
return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
|
||||
}
|
||||
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const {
|
||||
return LHS->hasComputableLoopEvolution(L) &&
|
||||
RHS->hasComputableLoopEvolution(L);
|
||||
}
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const {
|
||||
return O == LHS || O == RHS || LHS->hasOperand(O) || RHS->hasOperand(O);
|
||||
}
|
||||
@ -389,12 +357,6 @@ namespace llvm {
|
||||
getLoop());
|
||||
}
|
||||
|
||||
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
|
||||
return L == QL;
|
||||
}
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *QueryLoop) const;
|
||||
|
||||
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
|
||||
|
||||
bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
|
||||
@ -530,11 +492,6 @@ namespace llvm {
|
||||
bool isAlignOf(const Type *&AllocTy) const;
|
||||
bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
|
||||
return false; // not computable
|
||||
}
|
||||
|
||||
virtual bool hasOperand(const SCEV *) const {
|
||||
return false;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ void LoopDependenceAnalysis::getLoops(const SCEV *S,
|
||||
DenseSet<const Loop*>* Loops) const {
|
||||
// Refactor this into an SCEVVisitor, if efficiency becomes a concern.
|
||||
for (const Loop *L = this->L; L != 0; L = L->getParentLoop())
|
||||
if (!S->isLoopInvariant(L))
|
||||
if (!SE->isLoopInvariant(S, L))
|
||||
Loops->insert(L);
|
||||
}
|
||||
|
||||
|
@ -148,21 +148,11 @@ bool SCEV::isAllOnesValue() const {
|
||||
SCEVCouldNotCompute::SCEVCouldNotCompute() :
|
||||
SCEV(FoldingSetNodeIDRef(), scCouldNotCompute) {}
|
||||
|
||||
bool SCEVCouldNotCompute::isLoopInvariant(const Loop *L) const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const Type *SCEVCouldNotCompute::getType() const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SCEVCouldNotCompute::hasComputableLoopEvolution(const Loop *L) const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SCEVCouldNotCompute::hasOperand(const SCEV *) const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
@ -276,30 +266,6 @@ bool SCEVNAryExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SCEVNAryExpr::isLoopInvariant(const Loop *L) const {
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
|
||||
if (!(*I)->isLoopInvariant(L))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// hasComputableLoopEvolution - N-ary expressions have computable loop
|
||||
// evolutions iff they have at least one operand that varies with the loop,
|
||||
// but that all varying operands are computable.
|
||||
bool SCEVNAryExpr::hasComputableLoopEvolution(const Loop *L) const {
|
||||
bool HasVarying = false;
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) {
|
||||
const SCEV *S = *I;
|
||||
if (!S->isLoopInvariant(L)) {
|
||||
if (S->hasComputableLoopEvolution(L))
|
||||
HasVarying = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return HasVarying;
|
||||
}
|
||||
|
||||
bool SCEVNAryExpr::hasOperand(const SCEV *O) const {
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) {
|
||||
const SCEV *S = *I;
|
||||
@ -330,29 +296,6 @@ const Type *SCEVUDivExpr::getType() const {
|
||||
return RHS->getType();
|
||||
}
|
||||
|
||||
bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
|
||||
// Add recurrences are never invariant in the function-body (null loop).
|
||||
if (!QueryLoop)
|
||||
return false;
|
||||
|
||||
// This recurrence is variant w.r.t. QueryLoop if QueryLoop contains L.
|
||||
if (QueryLoop->contains(L))
|
||||
return false;
|
||||
|
||||
// This recurrence is invariant w.r.t. QueryLoop if L contains QueryLoop.
|
||||
if (L->contains(QueryLoop))
|
||||
return true;
|
||||
|
||||
// This recurrence is variant w.r.t. QueryLoop if any of its operands
|
||||
// are variant.
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
|
||||
if (!(*I)->isLoopInvariant(QueryLoop))
|
||||
return false;
|
||||
|
||||
// Otherwise it's loop-invariant.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
return DT->dominates(L->getHeader(), BB) &&
|
||||
@ -405,16 +348,6 @@ void SCEVUnknown::allUsesReplacedWith(Value *New) {
|
||||
setValPtr(New);
|
||||
}
|
||||
|
||||
bool SCEVUnknown::isLoopInvariant(const Loop *L) const {
|
||||
// All non-instruction values are loop invariant. All instructions are loop
|
||||
// invariant if they are not contained in the specified loop.
|
||||
// Instructions are never considered invariant in the function body
|
||||
// (null loop) because they are defined within the "loop".
|
||||
if (Instruction *I = dyn_cast<Instruction>(getValue()))
|
||||
return L && !L->contains(I);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SCEVUnknown::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
if (Instruction *I = dyn_cast<Instruction>(getValue()))
|
||||
return DT->dominates(I->getParent(), BB);
|
||||
@ -1648,7 +1581,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
|
||||
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
|
||||
const Loop *AddRecLoop = AddRec->getLoop();
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
if (Ops[i]->isLoopInvariant(AddRecLoop)) {
|
||||
if (isLoopInvariant(Ops[i], AddRecLoop)) {
|
||||
LIOps.push_back(Ops[i]);
|
||||
Ops.erase(Ops.begin()+i);
|
||||
--i; --e;
|
||||
@ -1854,7 +1787,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
|
||||
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
|
||||
const Loop *AddRecLoop = AddRec->getLoop();
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
if (Ops[i]->isLoopInvariant(AddRecLoop)) {
|
||||
if (isLoopInvariant(Ops[i], AddRecLoop)) {
|
||||
LIOps.push_back(Ops[i]);
|
||||
Ops.erase(Ops.begin()+i);
|
||||
--i; --e;
|
||||
@ -2074,7 +2007,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
|
||||
assert(getEffectiveSCEVType(Operands[i]->getType()) == ETy &&
|
||||
"SCEVAddRecExpr operand types don't match!");
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
|
||||
assert(Operands[i]->isLoopInvariant(L) &&
|
||||
assert(isLoopInvariant(Operands[i], L) &&
|
||||
"SCEVAddRecExpr operand is not loop-invariant!");
|
||||
#endif
|
||||
|
||||
@ -2116,7 +2049,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
|
||||
// requirement.
|
||||
bool AllInvariant = true;
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
|
||||
if (!Operands[i]->isLoopInvariant(L)) {
|
||||
if (!isLoopInvariant(Operands[i], L)) {
|
||||
AllInvariant = false;
|
||||
break;
|
||||
}
|
||||
@ -2124,7 +2057,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
|
||||
NestedOperands[0] = getAddRecExpr(Operands, L);
|
||||
AllInvariant = true;
|
||||
for (unsigned i = 0, e = NestedOperands.size(); i != e; ++i)
|
||||
if (!NestedOperands[i]->isLoopInvariant(NestedLoop)) {
|
||||
if (!isLoopInvariant(NestedOperands[i], NestedLoop)) {
|
||||
AllInvariant = false;
|
||||
break;
|
||||
}
|
||||
@ -2812,7 +2745,7 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
|
||||
|
||||
// This is not a valid addrec if the step amount is varying each
|
||||
// loop iteration, but is not itself an addrec in this loop.
|
||||
if (Accum->isLoopInvariant(L) ||
|
||||
if (isLoopInvariant(Accum, L) ||
|
||||
(isa<SCEVAddRecExpr>(Accum) &&
|
||||
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
|
||||
bool HasNUW = false;
|
||||
@ -2833,7 +2766,7 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
|
||||
|
||||
// Since the no-wrap flags are on the increment, they apply to the
|
||||
// post-incremented value as well.
|
||||
if (Accum->isLoopInvariant(L))
|
||||
if (isLoopInvariant(Accum, L))
|
||||
(void)getAddRecExpr(getAddExpr(StartVal, Accum),
|
||||
Accum, L, HasNUW, HasNSW);
|
||||
|
||||
@ -3736,8 +3669,8 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
if (Pair.second) {
|
||||
BackedgeTakenInfo BECount = ComputeBackedgeTakenCount(L);
|
||||
if (BECount.Exact != getCouldNotCompute()) {
|
||||
assert(BECount.Exact->isLoopInvariant(L) &&
|
||||
BECount.Max->isLoopInvariant(L) &&
|
||||
assert(isLoopInvariant(BECount.Exact, L) &&
|
||||
isLoopInvariant(BECount.Max, L) &&
|
||||
"Computed backedge-taken count isn't loop invariant for loop!");
|
||||
++NumTripCountsComputed;
|
||||
|
||||
@ -4099,7 +4032,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
|
||||
|
||||
// At this point, we would like to compute how many iterations of the
|
||||
// loop the predicate will return true for these inputs.
|
||||
if (LHS->isLoopInvariant(L) && !RHS->isLoopInvariant(L)) {
|
||||
if (isLoopInvariant(LHS, L) && !isLoopInvariant(RHS, L)) {
|
||||
// If there is a loop-invariant, force it into the RHS.
|
||||
std::swap(LHS, RHS);
|
||||
Cond = ICmpInst::getSwappedPredicate(Cond);
|
||||
@ -4261,7 +4194,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
// We can only recognize very limited forms of loop index expressions, in
|
||||
// particular, only affine AddRec's like {C1,+,C2}.
|
||||
const SCEVAddRecExpr *IdxExpr = dyn_cast<SCEVAddRecExpr>(Idx);
|
||||
if (!IdxExpr || !IdxExpr->isAffine() || IdxExpr->isLoopInvariant(L) ||
|
||||
if (!IdxExpr || !IdxExpr->isAffine() || isLoopInvariant(IdxExpr, L) ||
|
||||
!isa<SCEVConstant>(IdxExpr->getOperand(0)) ||
|
||||
!isa<SCEVConstant>(IdxExpr->getOperand(1)))
|
||||
return getCouldNotCompute();
|
||||
@ -4988,7 +4921,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
// as both operands could be addrecs loop-invariant in each other's loop.
|
||||
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(RHS)) {
|
||||
const Loop *L = AR->getLoop();
|
||||
if (LHS->isLoopInvariant(L) && LHS->properlyDominates(L->getHeader(), DT)) {
|
||||
if (isLoopInvariant(LHS, L) && LHS->properlyDominates(L->getHeader(), DT)) {
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Changed = true;
|
||||
@ -5605,7 +5538,7 @@ ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
const Loop *L, bool isSigned) {
|
||||
// Only handle: "ADDREC < LoopInvariant".
|
||||
if (!RHS->isLoopInvariant(L)) return getCouldNotCompute();
|
||||
if (!isLoopInvariant(RHS, L)) return getCouldNotCompute();
|
||||
|
||||
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS);
|
||||
if (!AddRec || AddRec->getLoop() != L)
|
||||
@ -5988,7 +5921,7 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const {
|
||||
if (L) {
|
||||
OS << "\t\t" "Exits: ";
|
||||
const SCEV *ExitValue = SE.getSCEVAtScope(SV, L->getParentLoop());
|
||||
if (!ExitValue->isLoopInvariant(L)) {
|
||||
if (!SE.isLoopInvariant(ExitValue, L)) {
|
||||
OS << "<<Unknown>>";
|
||||
} else {
|
||||
OS << *ExitValue;
|
||||
@ -6005,3 +5938,124 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const {
|
||||
PrintLoopInfo(OS, &SE, *I);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isLoopInvariant(const SCEV *S, const Loop *L) {
|
||||
switch (S->getSCEVType()) {
|
||||
case scConstant:
|
||||
return true;
|
||||
case scTruncate:
|
||||
case scZeroExtend:
|
||||
case scSignExtend:
|
||||
return isLoopInvariant(cast<SCEVCastExpr>(S)->getOperand(), L);
|
||||
case scAddRecExpr: {
|
||||
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(S);
|
||||
|
||||
// Add recurrences are never invariant in the function-body (null loop).
|
||||
if (!L)
|
||||
return false;
|
||||
|
||||
// This recurrence is variant w.r.t. L if L contains AR's loop.
|
||||
if (L->contains(AR->getLoop()))
|
||||
return false;
|
||||
|
||||
// This recurrence is invariant w.r.t. L if AR's loop contains L.
|
||||
if (AR->getLoop()->contains(L))
|
||||
return true;
|
||||
|
||||
// This recurrence is variant w.r.t. L if any of its operands
|
||||
// are variant.
|
||||
for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end();
|
||||
I != E; ++I)
|
||||
if (!isLoopInvariant(*I, L))
|
||||
return false;
|
||||
|
||||
// Otherwise it's loop-invariant.
|
||||
return true;
|
||||
}
|
||||
case scAddExpr:
|
||||
case scMulExpr:
|
||||
case scUMaxExpr:
|
||||
case scSMaxExpr: {
|
||||
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
|
||||
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
|
||||
I != E; ++I)
|
||||
if (!isLoopInvariant(*I, L))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
case scUDivExpr: {
|
||||
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
|
||||
return isLoopInvariant(UDiv->getLHS(), L) &&
|
||||
isLoopInvariant(UDiv->getRHS(), L);
|
||||
}
|
||||
case scUnknown:
|
||||
// All non-instruction values are loop invariant. All instructions are loop
|
||||
// invariant if they are not contained in the specified loop.
|
||||
// Instructions are never considered invariant in the function body
|
||||
// (null loop) because they are defined within the "loop".
|
||||
if (Instruction *I = dyn_cast<Instruction>(cast<SCEVUnknown>(S)->getValue()))
|
||||
return L && !L->contains(I);
|
||||
return true;
|
||||
case scCouldNotCompute:
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
default: break;
|
||||
}
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::hasComputableLoopEvolution(const SCEV *S, const Loop *L) {
|
||||
switch (S->getSCEVType()) {
|
||||
case scConstant:
|
||||
return false;
|
||||
case scTruncate:
|
||||
case scZeroExtend:
|
||||
case scSignExtend:
|
||||
return hasComputableLoopEvolution(cast<SCEVCastExpr>(S)->getOperand(), L);
|
||||
case scAddRecExpr:
|
||||
return cast<SCEVAddRecExpr>(S)->getLoop() == L;
|
||||
case scAddExpr:
|
||||
case scMulExpr:
|
||||
case scUMaxExpr:
|
||||
case scSMaxExpr: {
|
||||
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
|
||||
bool HasVarying = false;
|
||||
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
|
||||
I != E; ++I) {
|
||||
const SCEV *Op = *I;
|
||||
if (!isLoopInvariant(Op, L)) {
|
||||
if (hasComputableLoopEvolution(Op, L))
|
||||
HasVarying = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return HasVarying;
|
||||
}
|
||||
case scUDivExpr: {
|
||||
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
|
||||
bool HasVarying = false;
|
||||
if (!isLoopInvariant(UDiv->getLHS(), L)) {
|
||||
if (hasComputableLoopEvolution(UDiv->getLHS(), L))
|
||||
HasVarying = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (!isLoopInvariant(UDiv->getRHS(), L)) {
|
||||
if (hasComputableLoopEvolution(UDiv->getRHS(), L))
|
||||
HasVarying = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return HasVarying;
|
||||
}
|
||||
case scUnknown:
|
||||
return false;
|
||||
case scCouldNotCompute:
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
default: break;
|
||||
}
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
return false;
|
||||
}
|
||||
|
@ -1278,7 +1278,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
Instruction *InsertPt = Builder.GetInsertPoint();
|
||||
for (Loop *L = SE.LI->getLoopFor(Builder.GetInsertBlock()); ;
|
||||
L = L->getParentLoop())
|
||||
if (S->isLoopInvariant(L)) {
|
||||
if (SE.isLoopInvariant(S, L)) {
|
||||
if (!L) break;
|
||||
if (BasicBlock *Preheader = L->getLoopPreheader())
|
||||
InsertPt = Preheader->getTerminator();
|
||||
@ -1286,7 +1286,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
// If the SCEV is computable at this level, insert it into the header
|
||||
// after the PHIs (and after any other instructions that we've inserted
|
||||
// there) so that it is guaranteed to dominate any user inside the loop.
|
||||
if (L && S->hasComputableLoopEvolution(L) && !PostIncLoops.count(L))
|
||||
if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L))
|
||||
InsertPt = L->getHeader()->getFirstNonPHI();
|
||||
while (isInsertedInstruction(InsertPt) || isa<DbgInfoIntrinsic>(InsertPt))
|
||||
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
|
||||
|
@ -200,7 +200,7 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
||||
}
|
||||
|
||||
// Expand the code for the iteration count.
|
||||
assert(RHS->isLoopInvariant(L) &&
|
||||
assert(SE->isLoopInvariant(RHS, L) &&
|
||||
"Computed iteration count is not loop invariant!");
|
||||
Value *ExitCnt = Rewriter.expandCodeFor(RHS, IndVar->getType(), BI);
|
||||
|
||||
@ -302,7 +302,7 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L,
|
||||
// and varies predictably *inside* the loop. Evaluate the value it
|
||||
// contains when the loop exits, if possible.
|
||||
const SCEV *ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
|
||||
if (!ExitValue->isLoopInvariant(L))
|
||||
if (!SE->isLoopInvariant(ExitValue, L))
|
||||
continue;
|
||||
|
||||
Changed = true;
|
||||
@ -617,9 +617,9 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
// currently can only reduce affine polynomials. For now just disable
|
||||
// indvar subst on anything more complex than an affine addrec, unless
|
||||
// it can be expanded to a trivial value.
|
||||
static bool isSafe(const SCEV *S, const Loop *L) {
|
||||
static bool isSafe(const SCEV *S, const Loop *L, ScalarEvolution *SE) {
|
||||
// Loop-invariant values are safe.
|
||||
if (S->isLoopInvariant(L)) return true;
|
||||
if (SE->isLoopInvariant(S, L)) return true;
|
||||
|
||||
// Affine addrecs are safe. Non-affine are not, because LSR doesn't know how
|
||||
// to transform them into efficient code.
|
||||
@ -630,18 +630,18 @@ static bool isSafe(const SCEV *S, const Loop *L) {
|
||||
if (const SCEVCommutativeExpr *Commutative = dyn_cast<SCEVCommutativeExpr>(S)) {
|
||||
for (SCEVCommutativeExpr::op_iterator I = Commutative->op_begin(),
|
||||
E = Commutative->op_end(); I != E; ++I)
|
||||
if (!isSafe(*I, L)) return false;
|
||||
if (!isSafe(*I, L, SE)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// A cast is safe if its operand is.
|
||||
if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
|
||||
return isSafe(C->getOperand(), L);
|
||||
return isSafe(C->getOperand(), L, SE);
|
||||
|
||||
// A udiv is safe if its operands are.
|
||||
if (const SCEVUDivExpr *UD = dyn_cast<SCEVUDivExpr>(S))
|
||||
return isSafe(UD->getLHS(), L) &&
|
||||
isSafe(UD->getRHS(), L);
|
||||
return isSafe(UD->getLHS(), L, SE) &&
|
||||
isSafe(UD->getRHS(), L, SE);
|
||||
|
||||
// SCEVUnknown is always safe.
|
||||
if (isa<SCEVUnknown>(S))
|
||||
@ -672,7 +672,7 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) {
|
||||
// Evaluate the expression out of the loop, if possible.
|
||||
if (!L->contains(UI->getUser())) {
|
||||
const SCEV *ExitVal = SE->getSCEVAtScope(AR, L->getParentLoop());
|
||||
if (ExitVal->isLoopInvariant(L))
|
||||
if (SE->isLoopInvariant(ExitVal, L))
|
||||
AR = ExitVal;
|
||||
}
|
||||
|
||||
@ -682,7 +682,7 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) {
|
||||
// currently can only reduce affine polynomials. For now just disable
|
||||
// indvar subst on anything more complex than an affine addrec, unless
|
||||
// it can be expanded to a trivial value.
|
||||
if (!isSafe(AR, L))
|
||||
if (!isSafe(AR, L, SE))
|
||||
continue;
|
||||
|
||||
// Determine the insertion point for this user. By default, insert
|
||||
|
@ -730,7 +730,7 @@ void Cost::RateRegister(const SCEV *Reg,
|
||||
++SetupCost;
|
||||
|
||||
NumIVMuls += isa<SCEVMulExpr>(Reg) &&
|
||||
Reg->hasComputableLoopEvolution(L);
|
||||
SE.hasComputableLoopEvolution(Reg, L);
|
||||
}
|
||||
|
||||
/// RatePrimaryRegister - Record this register in the set. If we haven't seen it
|
||||
@ -2056,7 +2056,7 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
|
||||
|
||||
// x == y --> x - y == 0
|
||||
const SCEV *N = SE.getSCEV(NV);
|
||||
if (N->isLoopInvariant(L)) {
|
||||
if (SE.isLoopInvariant(N, L)) {
|
||||
Kind = LSRUse::ICmpZero;
|
||||
S = SE.getMinusSCEV(N, S);
|
||||
}
|
||||
@ -2196,7 +2196,7 @@ LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
|
||||
if (const ICmpInst *ICI = dyn_cast<ICmpInst>(UserInst)) {
|
||||
unsigned OtherIdx = !UI.getOperandNo();
|
||||
Value *OtherOp = const_cast<Value *>(ICI->getOperand(OtherIdx));
|
||||
if (SE.getSCEV(OtherOp)->hasComputableLoopEvolution(L))
|
||||
if (SE.hasComputableLoopEvolution(SE.getSCEV(OtherOp), L))
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2279,7 +2279,7 @@ void LSRInstance::GenerateReassociations(LSRUse &LU, unsigned LUIdx,
|
||||
|
||||
// Loop-variant "unknown" values are uninteresting; we won't be able to
|
||||
// do anything meaningful with them.
|
||||
if (isa<SCEVUnknown>(*J) && !(*J)->isLoopInvariant(L))
|
||||
if (isa<SCEVUnknown>(*J) && !SE.isLoopInvariant(*J, L))
|
||||
continue;
|
||||
|
||||
// Don't pull a constant into a register if the constant could be folded
|
||||
@ -2331,7 +2331,7 @@ void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx,
|
||||
I = Base.BaseRegs.begin(), E = Base.BaseRegs.end(); I != E; ++I) {
|
||||
const SCEV *BaseReg = *I;
|
||||
if (BaseReg->properlyDominates(L->getHeader(), &DT) &&
|
||||
!BaseReg->hasComputableLoopEvolution(L))
|
||||
!SE.hasComputableLoopEvolution(BaseReg, L))
|
||||
Ops.push_back(BaseReg);
|
||||
else
|
||||
F.BaseRegs.push_back(BaseReg);
|
||||
|
Loading…
Reference in New Issue
Block a user