summaryrefslogtreecommitdiffstats
path: root/polly/lib/Analysis/ScopInfo.cpp
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2019-06-12 22:51:56 +0000
committerMichael Kruse <llvm@meinersbur.de>2019-06-12 22:51:56 +0000
commit189abad128672e55c4317f7fc88c3dd0987703af (patch)
tree02dcda73a1ab8659e677d6544895f5538590e8b4 /polly/lib/Analysis/ScopInfo.cpp
parent41e0b9f2803089155536bdec7cbea6b82680a727 (diff)
downloadbcm5719-llvm-189abad128672e55c4317f7fc88c3dd0987703af.tar.gz
bcm5719-llvm-189abad128672e55c4317f7fc88c3dd0987703af.zip
[ScopBuilder] Move addInvariantLoads to ScopBuilder. NFC.
Moved addInvariantLoads and functions listed below to ScopBuilder: isAParameter canAlwaysBeHoisted These functions were referenced only by getNonHoistableCtx. Moved CLI parameter PollyAllowDereferenceOfAllFunctionParams to ScopBuilder. Added iterator range through InvariantEquivClasses. Patch by Dominik Adamski <adamski.dominik@gmail.com> Differential Revision: https://reviews.llvm.org/D63172 llvm-svn: 363216
Diffstat (limited to 'polly/lib/Analysis/ScopInfo.cpp')
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp171
1 files changed, 0 insertions, 171 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index b5f80bfc14a..0e5c3c39435 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -171,16 +171,6 @@ static cl::opt<bool> PollyIgnoreParamBounds(
"Do not add parameter bounds and do no gist simplify sets accordingly"),
cl::Hidden, cl::init(false), cl::cat(PollyCategory));
-static cl::opt<bool> PollyAllowDereferenceOfAllFunctionParams(
- "polly-allow-dereference-of-all-function-parameters",
- cl::desc(
- "Treat all parameters to functions that are pointers as dereferencible."
- " This is useful for invariant load hoisting, since we can generate"
- " less runtime checks. This is only valid if all pointers to functions"
- " are always initialized, so that Polly can choose to hoist"
- " their loads. "),
- cl::Hidden, cl::init(false), cl::cat(PollyCategory));
-
static cl::opt<bool> PollyPreciseFoldAccesses(
"polly-precise-fold-accesses",
cl::desc("Fold memory accesses to model more possible delinearizations "
@@ -3500,167 +3490,6 @@ InvariantEquivClassTy *Scop::lookupInvariantEquivClass(Value *Val) {
return nullptr;
}
-bool isAParameter(llvm::Value *maybeParam, const Function &F) {
- for (const llvm::Argument &Arg : F.args())
- if (&Arg == maybeParam)
- return true;
-
- return false;
-}
-
-bool Scop::canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty,
- bool MAInvalidCtxIsEmpty,
- bool NonHoistableCtxIsEmpty) {
- LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
- const DataLayout &DL = LInst->getParent()->getModule()->getDataLayout();
- if (PollyAllowDereferenceOfAllFunctionParams &&
- isAParameter(LInst->getPointerOperand(), getFunction()))
- return true;
-
- // TODO: We can provide more information for better but more expensive
- // results.
- if (!isDereferenceableAndAlignedPointer(LInst->getPointerOperand(),
- LInst->getAlignment(), DL))
- return false;
-
- // If the location might be overwritten we do not hoist it unconditionally.
- //
- // TODO: This is probably too conservative.
- if (!NonHoistableCtxIsEmpty)
- return false;
-
- // If a dereferenceable load is in a statement that is modeled precisely we
- // can hoist it.
- if (StmtInvalidCtxIsEmpty && MAInvalidCtxIsEmpty)
- return true;
-
- // Even if the statement is not modeled precisely we can hoist the load if it
- // does not involve any parameters that might have been specialized by the
- // statement domain.
- for (unsigned u = 0, e = MA->getNumSubscripts(); u < e; u++)
- if (!isa<SCEVConstant>(MA->getSubscript(u)))
- return false;
- return true;
-}
-
-void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
- if (InvMAs.empty())
- return;
-
- isl::set StmtInvalidCtx = Stmt.getInvalidContext();
- bool StmtInvalidCtxIsEmpty = StmtInvalidCtx.is_empty();
-
- // Get the context under which the statement is executed but remove the error
- // context under which this statement is reached.
- isl::set DomainCtx = Stmt.getDomain().params();
- DomainCtx = DomainCtx.subtract(StmtInvalidCtx);
-
- if (DomainCtx.n_basic_set() >= MaxDisjunctsInDomain) {
- auto *AccInst = InvMAs.front().MA->getAccessInstruction();
- invalidate(COMPLEXITY, AccInst->getDebugLoc(), AccInst->getParent());
- return;
- }
-
- // Project out all parameters that relate to loads in the statement. Otherwise
- // we could have cyclic dependences on the constraints under which the
- // hoisted loads are executed and we could not determine an order in which to
- // pre-load them. This happens because not only lower bounds are part of the
- // domain but also upper bounds.
- for (auto &InvMA : InvMAs) {
- auto *MA = InvMA.MA;
- Instruction *AccInst = MA->getAccessInstruction();
- if (SE->isSCEVable(AccInst->getType())) {
- SetVector<Value *> Values;
- for (const SCEV *Parameter : Parameters) {
- Values.clear();
- findValues(Parameter, *SE, Values);
- if (!Values.count(AccInst))
- continue;
-
- if (isl::id ParamId = getIdForParam(Parameter)) {
- int Dim = DomainCtx.find_dim_by_id(isl::dim::param, ParamId);
- if (Dim >= 0)
- DomainCtx = DomainCtx.eliminate(isl::dim::param, Dim, 1);
- }
- }
- }
- }
-
- for (auto &InvMA : InvMAs) {
- auto *MA = InvMA.MA;
- isl::set NHCtx = InvMA.NonHoistableCtx;
-
- // Check for another invariant access that accesses the same location as
- // MA and if found consolidate them. Otherwise create a new equivalence
- // class at the end of InvariantEquivClasses.
- LoadInst *LInst = cast<LoadInst>(MA->getAccessInstruction());
- Type *Ty = LInst->getType();
- const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand());
-
- isl::set MAInvalidCtx = MA->getInvalidContext();
- bool NonHoistableCtxIsEmpty = NHCtx.is_empty();
- bool MAInvalidCtxIsEmpty = MAInvalidCtx.is_empty();
-
- isl::set MACtx;
- // Check if we know that this pointer can be speculatively accessed.
- if (canAlwaysBeHoisted(MA, StmtInvalidCtxIsEmpty, MAInvalidCtxIsEmpty,
- NonHoistableCtxIsEmpty)) {
- MACtx = isl::set::universe(DomainCtx.get_space());
- } else {
- MACtx = DomainCtx;
- MACtx = MACtx.subtract(MAInvalidCtx.unite(NHCtx));
- MACtx = MACtx.gist_params(getContext());
- }
-
- bool Consolidated = false;
- for (auto &IAClass : InvariantEquivClasses) {
- if (PointerSCEV != IAClass.IdentifyingPointer || Ty != IAClass.AccessType)
- continue;
-
- // If the pointer and the type is equal check if the access function wrt.
- // to the domain is equal too. It can happen that the domain fixes
- // parameter values and these can be different for distinct part of the
- // SCoP. If this happens we cannot consolidate the loads but need to
- // create a new invariant load equivalence class.
- auto &MAs = IAClass.InvariantAccesses;
- if (!MAs.empty()) {
- auto *LastMA = MAs.front();
-
- isl::set AR = MA->getAccessRelation().range();
- isl::set LastAR = LastMA->getAccessRelation().range();
- bool SameAR = AR.is_equal(LastAR);
-
- if (!SameAR)
- continue;
- }
-
- // Add MA to the list of accesses that are in this class.
- MAs.push_front(MA);
-
- Consolidated = true;
-
- // Unify the execution context of the class and this statement.
- isl::set IAClassDomainCtx = IAClass.ExecutionContext;
- if (IAClassDomainCtx)
- IAClassDomainCtx = IAClassDomainCtx.unite(MACtx).coalesce();
- else
- IAClassDomainCtx = MACtx;
- IAClass.ExecutionContext = IAClassDomainCtx;
- break;
- }
-
- if (Consolidated)
- continue;
-
- MACtx = MACtx.coalesce();
-
- // If we did not consolidate MA, thus did not find an equivalence class
- // for it, we create a new one.
- addInvariantEquivClass(
- InvariantEquivClassTy{PointerSCEV, MemoryAccessList{MA}, MACtx, Ty});
- }
-}
-
ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
ArrayRef<const SCEV *> Sizes,
MemoryKind Kind,
OpenPOWER on IntegriCloud