forked from OSchip/llvm-project
Pass scope and LoopInfo to SCEVValidator. NFC.
The scope will be required in the following fix. This commit separates the large changes that do not change behaviour from the small, but functional change. llvm-svn: 262664
This commit is contained in:
parent
6ad7b5aff2
commit
09eb4451d2
|
|
@ -438,9 +438,10 @@ private:
|
||||||
/// non-affine.
|
/// non-affine.
|
||||||
///
|
///
|
||||||
/// @param S The expression to be checked.
|
/// @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 Context The context of scop detection.
|
||||||
/// @param BaseAddress The base address of the expression @p S (if any).
|
/// @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;
|
Value *BaseAddress = nullptr) const;
|
||||||
|
|
||||||
/// @brief Check if the control flow in a basic block is valid.
|
/// @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.
|
/// This was added to give the DOT printer easy access to this information.
|
||||||
RegionInfo *getRI() const { return RI; }
|
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?
|
/// @brief Is the region is the maximum region of a Scop?
|
||||||
///
|
///
|
||||||
/// @param R The Region to test if it is maximum.
|
/// @param R The Region to test if it is maximum.
|
||||||
|
|
|
||||||
|
|
@ -1411,7 +1411,7 @@ private:
|
||||||
InvariantEquivClassesTy InvariantEquivClasses;
|
InvariantEquivClassesTy InvariantEquivClasses;
|
||||||
|
|
||||||
/// @brief Scop constructor; invoked from ScopInfo::buildScop.
|
/// @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
|
/// @brief Get or create the access function set in a BasicBlock
|
||||||
AccFuncSetType &getOrCreateAccessFunctions(const BasicBlock *BB) {
|
AccFuncSetType &getOrCreateAccessFunctions(const BasicBlock *BB) {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class ScopStmt;
|
||||||
/// Translate a SCEV to an isl_pw_aff.
|
/// Translate a SCEV to an isl_pw_aff.
|
||||||
struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
|
struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
|
||||||
public:
|
public:
|
||||||
SCEVAffinator(Scop *S);
|
SCEVAffinator(Scop *S, llvm::LoopInfo &LI);
|
||||||
~SCEVAffinator();
|
~SCEVAffinator();
|
||||||
|
|
||||||
/// @brief Translate a SCEV to an isl_pw_aff.
|
/// @brief Translate a SCEV to an isl_pw_aff.
|
||||||
|
|
@ -81,6 +81,7 @@ private:
|
||||||
unsigned NumIterators;
|
unsigned NumIterators;
|
||||||
const llvm::Region &R;
|
const llvm::Region &R;
|
||||||
llvm::ScalarEvolution &SE;
|
llvm::ScalarEvolution &SE;
|
||||||
|
llvm::LoopInfo &LI;
|
||||||
llvm::BasicBlock *BB;
|
llvm::BasicBlock *BB;
|
||||||
|
|
||||||
/// @brief Target data for element size computing.
|
/// @brief Target data for element size computing.
|
||||||
|
|
|
||||||
|
|
@ -51,19 +51,20 @@ void findValues(const llvm::SCEV *Expr, llvm::SetVector<llvm::Value *> &Values);
|
||||||
/// region count as dependence.
|
/// region count as dependence.
|
||||||
bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R,
|
bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R,
|
||||||
llvm::Loop *Scope, bool AllowLoops);
|
llvm::Loop *Scope, bool AllowLoops);
|
||||||
bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
|
bool isAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
|
||||||
llvm::ScalarEvolution &SE, const llvm::Value *BaseAddress = 0,
|
const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
|
||||||
|
const llvm::Value *BaseAddress = 0,
|
||||||
InvariantLoadsSetTy *ILS = nullptr);
|
InvariantLoadsSetTy *ILS = nullptr);
|
||||||
|
|
||||||
/// @brief Check if @p V describes an affine parameter constraint in @p R.
|
/// @brief Check if @p V describes an affine parameter constraint in @p R.
|
||||||
bool isAffineParamConstraint(llvm::Value *V, const llvm::Region *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,
|
std::vector<const llvm::SCEV *> &Params,
|
||||||
bool OrExpr = false);
|
bool OrExpr = false);
|
||||||
|
|
||||||
std::vector<const llvm::SCEV *>
|
std::vector<const llvm::SCEV *>
|
||||||
getParamsInAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
|
getParamsInAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
|
||||||
llvm::ScalarEvolution &SE,
|
const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
|
||||||
const llvm::Value *BaseAddress = 0);
|
const llvm::Value *BaseAddress = 0);
|
||||||
|
|
||||||
/// @brief Extract the constant factors from the multiplication @p M.
|
/// @brief Extract the constant factors from the multiplication @p M.
|
||||||
|
|
|
||||||
|
|
@ -322,11 +322,12 @@ bool ScopDetection::onlyValidRequiredInvariantLoads(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScopDetection::isAffine(const SCEV *S, DetectionContext &Context,
|
bool ScopDetection::isAffine(const SCEV *S, Loop *Scope,
|
||||||
|
DetectionContext &Context,
|
||||||
Value *BaseAddress) const {
|
Value *BaseAddress) const {
|
||||||
|
|
||||||
InvariantLoadsSetTy AccessILS;
|
InvariantLoadsSetTy AccessILS;
|
||||||
if (!isAffineExpr(&Context.CurRegion, S, *SE, BaseAddress, &AccessILS))
|
if (!isAffineExpr(&Context.CurRegion, Scope, S, *SE, BaseAddress, &AccessILS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!onlyValidRequiredInvariantLoads(AccessILS, Context))
|
if (!onlyValidRequiredInvariantLoads(AccessILS, Context))
|
||||||
|
|
@ -341,7 +342,7 @@ bool ScopDetection::isValidSwitch(BasicBlock &BB, SwitchInst *SI,
|
||||||
Loop *L = LI->getLoopFor(&BB);
|
Loop *L = LI->getLoopFor(&BB);
|
||||||
const SCEV *ConditionSCEV = SE->getSCEVAtScope(Condition, L);
|
const SCEV *ConditionSCEV = SE->getSCEVAtScope(Condition, L);
|
||||||
|
|
||||||
if (isAffine(ConditionSCEV, Context))
|
if (isAffine(ConditionSCEV, L, Context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!IsLoopBranch && AllowNonAffineSubRegions &&
|
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 *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
|
||||||
const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), 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;
|
return true;
|
||||||
|
|
||||||
if (!IsLoopBranch && AllowNonAffineSubRegions &&
|
if (!IsLoopBranch && AllowNonAffineSubRegions &&
|
||||||
|
|
@ -537,7 +538,7 @@ bool ScopDetection::isValidIntrinsicInst(IntrinsicInst &II,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Bail if the length is not affine.
|
// 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))
|
Context))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -721,7 +722,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
|
||||||
Value *BaseValue = BasePointer->getValue();
|
Value *BaseValue = BasePointer->getValue();
|
||||||
Region &CurRegion = Context.CurRegion;
|
Region &CurRegion = Context.CurRegion;
|
||||||
for (const SCEV *DelinearizedSize : Sizes) {
|
for (const SCEV *DelinearizedSize : Sizes) {
|
||||||
if (!isAffine(DelinearizedSize, Context, nullptr)) {
|
if (!isAffine(DelinearizedSize, Scope, Context, nullptr)) {
|
||||||
Sizes.clear();
|
Sizes.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -749,7 +750,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
|
||||||
const Instruction *Insn = Pair.first;
|
const Instruction *Insn = Pair.first;
|
||||||
const SCEV *AF = Pair.second;
|
const SCEV *AF = Pair.second;
|
||||||
|
|
||||||
if (!isAffine(AF, Context, BaseValue)) {
|
if (!isAffine(AF, Scope, Context, BaseValue)) {
|
||||||
invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
|
invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
|
||||||
BaseValue);
|
BaseValue);
|
||||||
if (!KeepGoing)
|
if (!KeepGoing)
|
||||||
|
|
@ -780,9 +781,10 @@ bool ScopDetection::computeAccessFunctions(
|
||||||
bool IsNonAffine = false;
|
bool IsNonAffine = false;
|
||||||
TempMemoryAccesses.insert(std::make_pair(Insn, MemAcc(Insn, Shape)));
|
TempMemoryAccesses.insert(std::make_pair(Insn, MemAcc(Insn, Shape)));
|
||||||
MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
|
MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
|
||||||
|
auto *Scope = LI->getLoopFor(Insn->getParent());
|
||||||
|
|
||||||
if (!AF) {
|
if (!AF) {
|
||||||
if (isAffine(Pair.second, Context, BaseValue))
|
if (isAffine(Pair.second, Scope, Context, BaseValue))
|
||||||
Acc->DelinearizedSubscripts.push_back(Pair.second);
|
Acc->DelinearizedSubscripts.push_back(Pair.second);
|
||||||
else
|
else
|
||||||
IsNonAffine = true;
|
IsNonAffine = true;
|
||||||
|
|
@ -792,7 +794,7 @@ bool ScopDetection::computeAccessFunctions(
|
||||||
if (Acc->DelinearizedSubscripts.size() == 0)
|
if (Acc->DelinearizedSubscripts.size() == 0)
|
||||||
IsNonAffine = true;
|
IsNonAffine = true;
|
||||||
for (const SCEV *S : Acc->DelinearizedSubscripts)
|
for (const SCEV *S : Acc->DelinearizedSubscripts)
|
||||||
if (!isAffine(S, Context, BaseValue))
|
if (!isAffine(S, Scope, Context, BaseValue))
|
||||||
IsNonAffine = true;
|
IsNonAffine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -898,7 +900,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
|
||||||
if (Context.BoxedLoopsSet.count(L))
|
if (Context.BoxedLoopsSet.count(L))
|
||||||
IsVariantInNonAffineLoop = true;
|
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.
|
// Do not try to delinearize memory intrinsics and force them to be affine.
|
||||||
if (isa<MemIntrinsic>(Inst) && !IsAffine) {
|
if (isa<MemIntrinsic>(Inst) && !IsAffine) {
|
||||||
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
|
return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
|
||||||
|
|
|
||||||
|
|
@ -1318,8 +1318,10 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP,
|
||||||
auto *Expr = Subscripts[i + IndexOffset];
|
auto *Expr = Subscripts[i + IndexOffset];
|
||||||
auto Size = Sizes[i];
|
auto Size = Sizes[i];
|
||||||
|
|
||||||
|
auto *Scope = SD.getLI()->getLoopFor(getEntryBlock());
|
||||||
InvariantLoadsSetTy AccessILS;
|
InvariantLoadsSetTy AccessILS;
|
||||||
if (!isAffineExpr(&Parent.getRegion(), Expr, SE, nullptr, &AccessILS))
|
if (!isAffineExpr(&Parent.getRegion(), Scope, Expr, SE, nullptr,
|
||||||
|
&AccessILS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool NonAffine = false;
|
bool NonAffine = false;
|
||||||
|
|
@ -1783,9 +1785,10 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
|
||||||
if (!DT.dominates(CI->getParent(), R->getEntry()))
|
if (!DT.dominates(CI->getParent(), R->getEntry()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto *L = LI.getLoopFor(CI->getParent());
|
||||||
auto *Val = CI->getArgOperand(0);
|
auto *Val = CI->getArgOperand(0);
|
||||||
std::vector<const SCEV *> Params;
|
std::vector<const SCEV *> Params;
|
||||||
if (!isAffineParamConstraint(Val, R, *SE, Params)) {
|
if (!isAffineParamConstraint(Val, R, L, *SE, Params)) {
|
||||||
emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
|
emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
|
||||||
CI->getDebugLoc(),
|
CI->getDebugLoc(),
|
||||||
"Non-affine user assumption ignored.");
|
"Non-affine user assumption ignored.");
|
||||||
|
|
@ -1794,7 +1797,6 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
|
||||||
|
|
||||||
addParams(Params);
|
addParams(Params);
|
||||||
|
|
||||||
auto *L = LI.getLoopFor(CI->getParent());
|
|
||||||
SmallVector<isl_set *, 2> ConditionSets;
|
SmallVector<isl_set *, 2> ConditionSets;
|
||||||
buildConditionSets(*this, Val, nullptr, L, Context, ConditionSets);
|
buildConditionSets(*this, Val, nullptr, L, Context, ConditionSets);
|
||||||
assert(ConditionSets.size() == 2);
|
assert(ConditionSets.size() == 2);
|
||||||
|
|
@ -2765,11 +2767,12 @@ static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
|
||||||
return MaxLD - MinLD + 1;
|
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),
|
: SE(&ScalarEvolution), R(R), IsOptimized(false),
|
||||||
HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
|
HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
|
||||||
MaxLoopDepth(MaxLoopDepth), IslCtx(isl_ctx_alloc(), isl_ctx_free),
|
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) {
|
InvalidContext(nullptr), Schedule(nullptr) {
|
||||||
isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
|
isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
|
||||||
buildContext();
|
buildContext();
|
||||||
|
|
@ -3855,7 +3858,7 @@ bool ScopInfo::buildAccessMultiDimFixed(
|
||||||
|
|
||||||
for (auto *Subscript : Subscripts) {
|
for (auto *Subscript : Subscripts) {
|
||||||
InvariantLoadsSetTy AccessILS;
|
InvariantLoadsSetTy AccessILS;
|
||||||
if (!isAffineExpr(R, Subscript, *SE, nullptr, &AccessILS))
|
if (!isAffineExpr(R, L, Subscript, *SE, nullptr, &AccessILS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (LoadInst *LInst : AccessILS)
|
for (LoadInst *LInst : AccessILS)
|
||||||
|
|
@ -3934,7 +3937,7 @@ bool ScopInfo::buildAccessMemIntrinsic(
|
||||||
|
|
||||||
// Check if the length val is actually affine or if we overapproximate it
|
// Check if the length val is actually affine or if we overapproximate it
|
||||||
InvariantLoadsSetTy AccessILS;
|
InvariantLoadsSetTy AccessILS;
|
||||||
bool LengthIsAffine = isAffineExpr(R, LengthVal, *SE, nullptr, &AccessILS);
|
bool LengthIsAffine = isAffineExpr(R, L, LengthVal, *SE, nullptr, &AccessILS);
|
||||||
for (LoadInst *LInst : AccessILS)
|
for (LoadInst *LInst : AccessILS)
|
||||||
if (!ScopRIL.count(LInst))
|
if (!ScopRIL.count(LInst))
|
||||||
LengthIsAffine = false;
|
LengthIsAffine = false;
|
||||||
|
|
@ -4044,9 +4047,9 @@ void ScopInfo::buildAccessSingleDim(
|
||||||
}
|
}
|
||||||
|
|
||||||
InvariantLoadsSetTy AccessILS;
|
InvariantLoadsSetTy AccessILS;
|
||||||
bool IsAffine =
|
bool IsAffine = !isVariantInNonAffineLoop &&
|
||||||
!isVariantInNonAffineLoop &&
|
isAffineExpr(R, L, AccessFunction, *SE,
|
||||||
isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue(), &AccessILS);
|
BasePointer->getValue(), &AccessILS);
|
||||||
|
|
||||||
for (LoadInst *LInst : AccessILS)
|
for (LoadInst *LInst : AccessILS)
|
||||||
if (!ScopRIL.count(LInst))
|
if (!ScopRIL.count(LInst))
|
||||||
|
|
@ -4317,7 +4320,7 @@ void ScopInfo::addPHIReadAccess(PHINode *PHI) {
|
||||||
|
|
||||||
void ScopInfo::buildScop(Region &R, AssumptionCache &AC) {
|
void ScopInfo::buildScop(Region &R, AssumptionCache &AC) {
|
||||||
unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
|
unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
|
||||||
scop.reset(new Scop(R, *SE, MaxLoopDepth));
|
scop.reset(new Scop(R, *SE, *LI, MaxLoopDepth));
|
||||||
|
|
||||||
buildStmts(R, R);
|
buildStmts(R, R);
|
||||||
buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R));
|
buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R));
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace polly;
|
using namespace polly;
|
||||||
|
|
||||||
SCEVAffinator::SCEVAffinator(Scop *S)
|
SCEVAffinator::SCEVAffinator(Scop *S, LoopInfo &LI)
|
||||||
: S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()),
|
: S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()), LI(LI),
|
||||||
TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {}
|
TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {}
|
||||||
|
|
||||||
SCEVAffinator::~SCEVAffinator() {
|
SCEVAffinator::~SCEVAffinator() {
|
||||||
|
|
@ -44,7 +44,8 @@ __isl_give isl_pw_aff *SCEVAffinator::getPwAff(const SCEV *Expr,
|
||||||
} else
|
} else
|
||||||
NumIterators = 0;
|
NumIterators = 0;
|
||||||
|
|
||||||
S->addParams(getParamsInAffineExpr(&R, Expr, SE));
|
auto *Scope = LI.getLoopFor(BB);
|
||||||
|
S->addParams(getParamsInAffineExpr(&R, Scope, Expr, SE));
|
||||||
|
|
||||||
return visit(Expr);
|
return visit(Expr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,14 +124,15 @@ struct SCEVValidator
|
||||||
: public SCEVVisitor<SCEVValidator, class ValidatorResult> {
|
: public SCEVVisitor<SCEVValidator, class ValidatorResult> {
|
||||||
private:
|
private:
|
||||||
const Region *R;
|
const Region *R;
|
||||||
|
Loop *Scope;
|
||||||
ScalarEvolution &SE;
|
ScalarEvolution &SE;
|
||||||
const Value *BaseAddress;
|
const Value *BaseAddress;
|
||||||
InvariantLoadsSetTy *ILS;
|
InvariantLoadsSetTy *ILS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress,
|
SCEVValidator(const Region *R, Loop *Scope, ScalarEvolution &SE,
|
||||||
InvariantLoadsSetTy *ILS)
|
const Value *BaseAddress, InvariantLoadsSetTy *ILS)
|
||||||
: R(R), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
|
: R(R), Scope(Scope), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
|
||||||
|
|
||||||
class ValidatorResult visitConstant(const SCEVConstant *Constant) {
|
class ValidatorResult visitConstant(const SCEVConstant *Constant) {
|
||||||
return ValidatorResult(SCEVType::INT);
|
return ValidatorResult(SCEVType::INT);
|
||||||
|
|
@ -576,12 +577,13 @@ bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R,
|
||||||
return SCEVInRegionDependences::hasDependences(Expr, R, Scope, AllowLoops);
|
return SCEVInRegionDependences::hasDependences(Expr, R, Scope, AllowLoops);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
|
bool isAffineExpr(const Region *R, llvm::Loop *Scope, const SCEV *Expr,
|
||||||
const Value *BaseAddress, InvariantLoadsSetTy *ILS) {
|
ScalarEvolution &SE, const Value *BaseAddress,
|
||||||
|
InvariantLoadsSetTy *ILS) {
|
||||||
if (isa<SCEVCouldNotCompute>(Expr))
|
if (isa<SCEVCouldNotCompute>(Expr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SCEVValidator Validator(R, SE, BaseAddress, ILS);
|
SCEVValidator Validator(R, Scope, SE, BaseAddress, ILS);
|
||||||
DEBUG({
|
DEBUG({
|
||||||
dbgs() << "\n";
|
dbgs() << "\n";
|
||||||
dbgs() << "Expr: " << *Expr << "\n";
|
dbgs() << "Expr: " << *Expr << "\n";
|
||||||
|
|
@ -600,13 +602,14 @@ bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
|
||||||
return Result.isValid();
|
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) {
|
std::vector<const SCEV *> &Params) {
|
||||||
auto *E = SE.getSCEV(V);
|
auto *E = SE.getSCEV(V);
|
||||||
if (isa<SCEVCouldNotCompute>(E))
|
if (isa<SCEVCouldNotCompute>(E))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SCEVValidator Validator(R, SE, nullptr, nullptr);
|
SCEVValidator Validator(R, Scope, SE, nullptr, nullptr);
|
||||||
ValidatorResult Result = Validator.visit(E);
|
ValidatorResult Result = Validator.visit(E);
|
||||||
if (!Result.isConstant())
|
if (!Result.isConstant())
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -617,17 +620,20 @@ static bool isAffineParamExpr(Value *V, const Region *R, ScalarEvolution &SE,
|
||||||
return true;
|
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) {
|
std::vector<const SCEV *> &Params, bool OrExpr) {
|
||||||
if (auto *ICmp = dyn_cast<ICmpInst>(V)) {
|
if (auto *ICmp = dyn_cast<ICmpInst>(V)) {
|
||||||
return isAffineParamConstraint(ICmp->getOperand(0), R, SE, Params, true) &&
|
return isAffineParamConstraint(ICmp->getOperand(0), R, Scope, SE, Params,
|
||||||
isAffineParamConstraint(ICmp->getOperand(1), R, SE, Params, true);
|
true) &&
|
||||||
|
isAffineParamConstraint(ICmp->getOperand(1), R, Scope, SE, Params,
|
||||||
|
true);
|
||||||
} else if (auto *BinOp = dyn_cast<BinaryOperator>(V)) {
|
} else if (auto *BinOp = dyn_cast<BinaryOperator>(V)) {
|
||||||
auto Opcode = BinOp->getOpcode();
|
auto Opcode = BinOp->getOpcode();
|
||||||
if (Opcode == Instruction::And || Opcode == Instruction::Or)
|
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) &&
|
false) &&
|
||||||
isAffineParamConstraint(BinOp->getOperand(1), R, SE, Params,
|
isAffineParamConstraint(BinOp->getOperand(1), R, Scope, SE, Params,
|
||||||
false);
|
false);
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
}
|
}
|
||||||
|
|
@ -635,10 +641,10 @@ bool isAffineParamConstraint(Value *V, const Region *R, ScalarEvolution &SE,
|
||||||
if (!OrExpr)
|
if (!OrExpr)
|
||||||
return false;
|
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,
|
const SCEV *Expr,
|
||||||
ScalarEvolution &SE,
|
ScalarEvolution &SE,
|
||||||
const Value *BaseAddress) {
|
const Value *BaseAddress) {
|
||||||
|
|
@ -646,7 +652,7 @@ std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
|
||||||
return std::vector<const SCEV *>();
|
return std::vector<const SCEV *>();
|
||||||
|
|
||||||
InvariantLoadsSetTy ILS;
|
InvariantLoadsSetTy ILS;
|
||||||
SCEVValidator Validator(R, SE, BaseAddress, &ILS);
|
SCEVValidator Validator(R, Scope, SE, BaseAddress, &ILS);
|
||||||
ValidatorResult Result = Validator.visit(Expr);
|
ValidatorResult Result = Validator.visit(Expr);
|
||||||
assert(Result.isValid() && "Requested parameters for an invalid SCEV!");
|
assert(Result.isValid() && "Requested parameters for an invalid SCEV!");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue