summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopDetection.h6
-rw-r--r--polly/include/polly/ScopInfo.h2
-rw-r--r--polly/include/polly/Support/SCEVAffinator.h3
-rw-r--r--polly/include/polly/Support/SCEVValidator.h11
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp23
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp25
-rw-r--r--polly/lib/Support/SCEVAffinator.cpp7
-rw-r--r--polly/lib/Support/SCEVValidator.cpp38
8 files changed, 67 insertions, 48 deletions
diff --git a/polly/include/polly/ScopDetection.h b/polly/include/polly/ScopDetection.h
index b91a4e0a023..d033a98f01e 100644
--- a/polly/include/polly/ScopDetection.h
+++ b/polly/include/polly/ScopDetection.h
@@ -438,9 +438,10 @@ private:
/// non-affine.
///
/// @param S The expression to be checked.
+ /// @param Scope The loop nest in which @p S is used.
/// @param Context The context of scop detection.
/// @param BaseAddress The base address of the expression @p S (if any).
- bool isAffine(const SCEV *S, DetectionContext &Context,
+ bool isAffine(const SCEV *S, Loop *Scope, DetectionContext &Context,
Value *BaseAddress = nullptr) const;
/// @brief Check if the control flow in a basic block is valid.
@@ -516,6 +517,9 @@ public:
/// This was added to give the DOT printer easy access to this information.
RegionInfo *getRI() const { return RI; }
+ /// @brief Get the LoopInfo stored in this pass.
+ LoopInfo *getLI() const { return LI; }
+
/// @brief Is the region is the maximum region of a Scop?
///
/// @param R The Region to test if it is maximum.
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 5c189712902..ffb79c385dd 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -1411,7 +1411,7 @@ private:
InvariantEquivClassesTy InvariantEquivClasses;
/// @brief Scop constructor; invoked from ScopInfo::buildScop.
- Scop(Region &R, ScalarEvolution &SE, unsigned MaxLoopDepth);
+ Scop(Region &R, ScalarEvolution &SE, LoopInfo &LI, unsigned MaxLoopDepth);
/// @brief Get or create the access function set in a BasicBlock
AccFuncSetType &getOrCreateAccessFunctions(const BasicBlock *BB) {
diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h
index c982349a1fa..e462c951071 100644
--- a/polly/include/polly/Support/SCEVAffinator.h
+++ b/polly/include/polly/Support/SCEVAffinator.h
@@ -46,7 +46,7 @@ class ScopStmt;
/// Translate a SCEV to an isl_pw_aff.
struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
public:
- SCEVAffinator(Scop *S);
+ SCEVAffinator(Scop *S, llvm::LoopInfo &LI);
~SCEVAffinator();
/// @brief Translate a SCEV to an isl_pw_aff.
@@ -81,6 +81,7 @@ private:
unsigned NumIterators;
const llvm::Region &R;
llvm::ScalarEvolution &SE;
+ llvm::LoopInfo &LI;
llvm::BasicBlock *BB;
/// @brief Target data for element size computing.
diff --git a/polly/include/polly/Support/SCEVValidator.h b/polly/include/polly/Support/SCEVValidator.h
index 99bb972c32c..4e1351ce419 100644
--- a/polly/include/polly/Support/SCEVValidator.h
+++ b/polly/include/polly/Support/SCEVValidator.h
@@ -51,19 +51,20 @@ void findValues(const llvm::SCEV *Expr, llvm::SetVector<llvm::Value *> &Values);
/// region count as dependence.
bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R,
llvm::Loop *Scope, bool AllowLoops);
-bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
- llvm::ScalarEvolution &SE, const llvm::Value *BaseAddress = 0,
+bool isAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
+ const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
+ const llvm::Value *BaseAddress = 0,
InvariantLoadsSetTy *ILS = nullptr);
/// @brief Check if @p V describes an affine parameter constraint in @p R.
bool isAffineParamConstraint(llvm::Value *V, const llvm::Region *R,
- llvm::ScalarEvolution &SE,
+ llvm::Loop *Scope, llvm::ScalarEvolution &SE,
std::vector<const llvm::SCEV *> &Params,
bool OrExpr = false);
std::vector<const llvm::SCEV *>
-getParamsInAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
- llvm::ScalarEvolution &SE,
+getParamsInAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
+ const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
const llvm::Value *BaseAddress = 0);
/// @brief Extract the constant factors from the multiplication @p M.
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 47bf54786fb..548b8747c20 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -322,11 +322,12 @@ bool ScopDetection::onlyValidRequiredInvariantLoads(
return true;
}
-bool ScopDetection::isAffine(const SCEV *S, DetectionContext &Context,
+bool ScopDetection::isAffine(const SCEV *S, Loop *Scope,
+ DetectionContext &Context,
Value *BaseAddress) const {
InvariantLoadsSetTy AccessILS;
- if (!isAffineExpr(&Context.CurRegion, S, *SE, BaseAddress, &AccessILS))
+ if (!isAffineExpr(&Context.CurRegion, Scope, S, *SE, BaseAddress, &AccessILS))
return false;
if (!onlyValidRequiredInvariantLoads(AccessILS, Context))
@@ -341,7 +342,7 @@ bool ScopDetection::isValidSwitch(BasicBlock &BB, SwitchInst *SI,
Loop *L = LI->getLoopFor(&BB);
const SCEV *ConditionSCEV = SE->getSCEVAtScope(Condition, L);
- if (isAffine(ConditionSCEV, Context))
+ if (isAffine(ConditionSCEV, L, Context))
return true;
if (!IsLoopBranch && AllowNonAffineSubRegions &&
@@ -401,7 +402,7 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI,
const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
- if (isAffine(LHS, Context) && isAffine(RHS, Context))
+ if (isAffine(LHS, L, Context) && isAffine(RHS, L, Context))
return true;
if (!IsLoopBranch && AllowNonAffineSubRegions &&
@@ -537,7 +538,7 @@ bool ScopDetection::isValidIntrinsicInst(IntrinsicInst &II,
return false;
// Bail if the length is not affine.
- if (!isAffine(SE->getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L),
+ if (!isAffine(SE->getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L), L,
Context))
return false;
@@ -721,7 +722,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
Value *BaseValue = BasePointer->getValue();
Region &CurRegion = Context.CurRegion;
for (const SCEV *DelinearizedSize : Sizes) {
- if (!isAffine(DelinearizedSize, Context, nullptr)) {
+ if (!isAffine(DelinearizedSize, Scope, Context, nullptr)) {
Sizes.clear();
break;
}
@@ -749,7 +750,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
const Instruction *Insn = Pair.first;
const SCEV *AF = Pair.second;
- if (!isAffine(AF, Context, BaseValue)) {
+ if (!isAffine(AF, Scope, Context, BaseValue)) {
invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
BaseValue);
if (!KeepGoing)
@@ -780,9 +781,10 @@ bool ScopDetection::computeAccessFunctions(
bool IsNonAffine = false;
TempMemoryAccesses.insert(std::make_pair(Insn, MemAcc(Insn, Shape)));
MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
+ auto *Scope = LI->getLoopFor(Insn->getParent());
if (!AF) {
- if (isAffine(Pair.second, Context, BaseValue))
+ if (isAffine(Pair.second, Scope, Context, BaseValue))
Acc->DelinearizedSubscripts.push_back(Pair.second);
else
IsNonAffine = true;
@@ -792,7 +794,7 @@ bool ScopDetection::computeAccessFunctions(
if (Acc->DelinearizedSubscripts.size() == 0)
IsNonAffine = true;
for (const SCEV *S : Acc->DelinearizedSubscripts)
- if (!isAffine(S, Context, BaseValue))
+ if (!isAffine(S, Scope, Context, BaseValue))
IsNonAffine = true;
}
@@ -898,7 +900,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
if (Context.BoxedLoopsSet.count(L))
IsVariantInNonAffineLoop = true;
- bool IsAffine = !IsVariantInNonAffineLoop && isAffine(AF, Context, BV);
+ auto *Scope = LI->getLoopFor(Inst->getParent());
+ bool IsAffine = !IsVariantInNonAffineLoop && isAffine(AF, Scope, Context, BV);
// Do not try to delinearize memory intrinsics and force them to be affine.
if (isa<MemIntrinsic>(Inst) && !IsAffine) {
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 4e940350f24..a6c14c6224f 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1318,8 +1318,10 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP,
auto *Expr = Subscripts[i + IndexOffset];
auto Size = Sizes[i];
+ auto *Scope = SD.getLI()->getLoopFor(getEntryBlock());
InvariantLoadsSetTy AccessILS;
- if (!isAffineExpr(&Parent.getRegion(), Expr, SE, nullptr, &AccessILS))
+ if (!isAffineExpr(&Parent.getRegion(), Scope, Expr, SE, nullptr,
+ &AccessILS))
continue;
bool NonAffine = false;
@@ -1783,9 +1785,10 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
if (!DT.dominates(CI->getParent(), R->getEntry()))
continue;
+ auto *L = LI.getLoopFor(CI->getParent());
auto *Val = CI->getArgOperand(0);
std::vector<const SCEV *> Params;
- if (!isAffineParamConstraint(Val, R, *SE, Params)) {
+ if (!isAffineParamConstraint(Val, R, L, *SE, Params)) {
emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
CI->getDebugLoc(),
"Non-affine user assumption ignored.");
@@ -1794,7 +1797,6 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
addParams(Params);
- auto *L = LI.getLoopFor(CI->getParent());
SmallVector<isl_set *, 2> ConditionSets;
buildConditionSets(*this, Val, nullptr, L, Context, ConditionSets);
assert(ConditionSets.size() == 2);
@@ -2765,11 +2767,12 @@ static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
return MaxLD - MinLD + 1;
}
-Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, unsigned MaxLoopDepth)
+Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
+ unsigned MaxLoopDepth)
: SE(&ScalarEvolution), R(R), IsOptimized(false),
HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
MaxLoopDepth(MaxLoopDepth), IslCtx(isl_ctx_alloc(), isl_ctx_free),
- Context(nullptr), Affinator(this), AssumedContext(nullptr),
+ Context(nullptr), Affinator(this, LI), AssumedContext(nullptr),
InvalidContext(nullptr), Schedule(nullptr) {
isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
buildContext();
@@ -3855,7 +3858,7 @@ bool ScopInfo::buildAccessMultiDimFixed(
for (auto *Subscript : Subscripts) {
InvariantLoadsSetTy AccessILS;
- if (!isAffineExpr(R, Subscript, *SE, nullptr, &AccessILS))
+ if (!isAffineExpr(R, L, Subscript, *SE, nullptr, &AccessILS))
return false;
for (LoadInst *LInst : AccessILS)
@@ -3934,7 +3937,7 @@ bool ScopInfo::buildAccessMemIntrinsic(
// Check if the length val is actually affine or if we overapproximate it
InvariantLoadsSetTy AccessILS;
- bool LengthIsAffine = isAffineExpr(R, LengthVal, *SE, nullptr, &AccessILS);
+ bool LengthIsAffine = isAffineExpr(R, L, LengthVal, *SE, nullptr, &AccessILS);
for (LoadInst *LInst : AccessILS)
if (!ScopRIL.count(LInst))
LengthIsAffine = false;
@@ -4044,9 +4047,9 @@ void ScopInfo::buildAccessSingleDim(
}
InvariantLoadsSetTy AccessILS;
- bool IsAffine =
- !isVariantInNonAffineLoop &&
- isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue(), &AccessILS);
+ bool IsAffine = !isVariantInNonAffineLoop &&
+ isAffineExpr(R, L, AccessFunction, *SE,
+ BasePointer->getValue(), &AccessILS);
for (LoadInst *LInst : AccessILS)
if (!ScopRIL.count(LInst))
@@ -4317,7 +4320,7 @@ void ScopInfo::addPHIReadAccess(PHINode *PHI) {
void ScopInfo::buildScop(Region &R, AssumptionCache &AC) {
unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
- scop.reset(new Scop(R, *SE, MaxLoopDepth));
+ scop.reset(new Scop(R, *SE, *LI, MaxLoopDepth));
buildStmts(R, R);
buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R));
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp
index e94df79d19d..084fcf0de00 100644
--- a/polly/lib/Support/SCEVAffinator.cpp
+++ b/polly/lib/Support/SCEVAffinator.cpp
@@ -24,8 +24,8 @@
using namespace llvm;
using namespace polly;
-SCEVAffinator::SCEVAffinator(Scop *S)
- : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()),
+SCEVAffinator::SCEVAffinator(Scop *S, LoopInfo &LI)
+ : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()), LI(LI),
TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {}
SCEVAffinator::~SCEVAffinator() {
@@ -44,7 +44,8 @@ __isl_give isl_pw_aff *SCEVAffinator::getPwAff(const SCEV *Expr,
} else
NumIterators = 0;
- S->addParams(getParamsInAffineExpr(&R, Expr, SE));
+ auto *Scope = LI.getLoopFor(BB);
+ S->addParams(getParamsInAffineExpr(&R, Scope, Expr, SE));
return visit(Expr);
}
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index 492264bcb57..24139908c5d 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -124,14 +124,15 @@ struct SCEVValidator
: public SCEVVisitor<SCEVValidator, class ValidatorResult> {
private:
const Region *R;
+ Loop *Scope;
ScalarEvolution &SE;
const Value *BaseAddress;
InvariantLoadsSetTy *ILS;
public:
- SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress,
- InvariantLoadsSetTy *ILS)
- : R(R), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
+ SCEVValidator(const Region *R, Loop *Scope, ScalarEvolution &SE,
+ const Value *BaseAddress, InvariantLoadsSetTy *ILS)
+ : R(R), Scope(Scope), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
class ValidatorResult visitConstant(const SCEVConstant *Constant) {
return ValidatorResult(SCEVType::INT);
@@ -576,12 +577,13 @@ bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R,
return SCEVInRegionDependences::hasDependences(Expr, R, Scope, AllowLoops);
}
-bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
- const Value *BaseAddress, InvariantLoadsSetTy *ILS) {
+bool isAffineExpr(const Region *R, llvm::Loop *Scope, const SCEV *Expr,
+ ScalarEvolution &SE, const Value *BaseAddress,
+ InvariantLoadsSetTy *ILS) {
if (isa<SCEVCouldNotCompute>(Expr))
return false;
- SCEVValidator Validator(R, SE, BaseAddress, ILS);
+ SCEVValidator Validator(R, Scope, SE, BaseAddress, ILS);
DEBUG({
dbgs() << "\n";
dbgs() << "Expr: " << *Expr << "\n";
@@ -600,13 +602,14 @@ bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
return Result.isValid();
}
-static bool isAffineParamExpr(Value *V, const Region *R, ScalarEvolution &SE,
+static bool isAffineParamExpr(Value *V, const Region *R, Loop *Scope,
+ ScalarEvolution &SE,
std::vector<const SCEV *> &Params) {
auto *E = SE.getSCEV(V);
if (isa<SCEVCouldNotCompute>(E))
return false;
- SCEVValidator Validator(R, SE, nullptr, nullptr);
+ SCEVValidator Validator(R, Scope, SE, nullptr, nullptr);
ValidatorResult Result = Validator.visit(E);
if (!Result.isConstant())
return false;
@@ -617,17 +620,20 @@ static bool isAffineParamExpr(Value *V, const Region *R, ScalarEvolution &SE,
return true;
}
-bool isAffineParamConstraint(Value *V, const Region *R, ScalarEvolution &SE,
+bool isAffineParamConstraint(Value *V, const Region *R, llvm::Loop *Scope,
+ ScalarEvolution &SE,
std::vector<const SCEV *> &Params, bool OrExpr) {
if (auto *ICmp = dyn_cast<ICmpInst>(V)) {
- return isAffineParamConstraint(ICmp->getOperand(0), R, SE, Params, true) &&
- isAffineParamConstraint(ICmp->getOperand(1), R, SE, Params, true);
+ return isAffineParamConstraint(ICmp->getOperand(0), R, Scope, SE, Params,
+ true) &&
+ isAffineParamConstraint(ICmp->getOperand(1), R, Scope, SE, Params,
+ true);
} else if (auto *BinOp = dyn_cast<BinaryOperator>(V)) {
auto Opcode = BinOp->getOpcode();
if (Opcode == Instruction::And || Opcode == Instruction::Or)
- return isAffineParamConstraint(BinOp->getOperand(0), R, SE, Params,
+ return isAffineParamConstraint(BinOp->getOperand(0), R, Scope, SE, Params,
false) &&
- isAffineParamConstraint(BinOp->getOperand(1), R, SE, Params,
+ isAffineParamConstraint(BinOp->getOperand(1), R, Scope, SE, Params,
false);
/* Fall through */
}
@@ -635,10 +641,10 @@ bool isAffineParamConstraint(Value *V, const Region *R, ScalarEvolution &SE,
if (!OrExpr)
return false;
- return isAffineParamExpr(V, R, SE, Params);
+ return isAffineParamExpr(V, R, Scope, SE, Params);
}
-std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
+std::vector<const SCEV *> getParamsInAffineExpr(const Region *R, Loop *Scope,
const SCEV *Expr,
ScalarEvolution &SE,
const Value *BaseAddress) {
@@ -646,7 +652,7 @@ std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
return std::vector<const SCEV *>();
InvariantLoadsSetTy ILS;
- SCEVValidator Validator(R, SE, BaseAddress, &ILS);
+ SCEVValidator Validator(R, Scope, SE, BaseAddress, &ILS);
ValidatorResult Result = Validator.visit(Expr);
assert(Result.isValid() && "Requested parameters for an invalid SCEV!");
OpenPOWER on IntegriCloud