diff options
-rw-r--r-- | polly/include/polly/ScopInfo.h | 30 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 57 | ||||
-rw-r--r-- | polly/test/ScopInfo/remarks.ll | 5 |
3 files changed, 81 insertions, 11 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 0946cbf2691..b0686a83c0d 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -66,6 +66,17 @@ class ScopInfo; //===---------------------------------------------------------------------===// +/// @brief Enumeration of assumptions Polly can take. +enum AssumptionKind { + ALIASING, + INBOUNDS, + WRAPPING, + ERRORBLOCK, + INFINITELOOP, + INVARIANTLOAD, + DELINEARIZATION, +}; + /// Maps from a loop to the affine function expressing its backedge taken count. /// The backedge taken count already enough to express iteration domain as we /// only allow loops with canonical induction variable. @@ -1453,6 +1464,17 @@ public: /// @returns True if the optimized SCoP can be executed. bool hasFeasibleRuntimeContext() const; + /// @brief Track and report an assumption. + /// + /// Use 'clang -Rpass-analysis=polly-scops' or 'opt -pass-remarks=polly-scops' + /// to output the assumptions. + /// + /// @param Kind The assumption kind describing the underlying cause. + /// @param Set The relations between parameters that are assumed to hold. + /// @param Loc The location in the source that caused this assumption. + void trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set, + DebugLoc Loc); + /// @brief Add assumptions to assumed context. /// /// The assumptions added will be assumed to hold during the execution of the @@ -1464,9 +1486,11 @@ public: /// that assumptions do not change the set of statement instances /// executed. /// - /// @param Set A set describing relations between parameters that are assumed - /// to hold. - void addAssumption(__isl_take isl_set *Set); + /// @param Kind The assumption kind describing the underlying cause. + /// @param Set The relations between parameters that are assumed to hold. + /// @param Loc The location in the source that caused this assumption. + void addAssumption(AssumptionKind Kind, __isl_take isl_set *Set, + DebugLoc Loc); /// @brief Get the boundary context for this Scop. /// diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 5b6cd49c259..bb2dd56f8d6 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -512,7 +512,8 @@ void MemoryAccess::assumeNoOutOfBound() { // bail out more often than strictly necessary. Outside = isl_set_remove_divs(Outside); Outside = isl_set_complement(Outside); - Statement->getParent()->addAssumption(Outside); + Statement->getParent()->addAssumption(INBOUNDS, Outside, + getAccessInstruction()->getDebugLoc()); isl_space_free(Space); } @@ -1175,7 +1176,7 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP) { isl_set *InBoundIfExecuted = isl_set_union(isl_set_complement(Executed), InBound); - Parent.addAssumption(InBoundIfExecuted); + Parent.addAssumption(INBOUNDS, InBoundIfExecuted, GEP->getDebugLoc()); } isl_local_space_free(LSpace); @@ -1607,6 +1608,7 @@ void Scop::buildBoundaryContext() { isl_ctx_reset_operations(getIslCtx()); isl_ctx_set_max_operations(getIslCtx(), MaxOpsOld); BoundaryContext = isl_set_gist_params(BoundaryContext, getContext()); + trackAssumption(WRAPPING, BoundaryContext, DebugLoc()); } void Scop::addUserContext() { @@ -2181,7 +2183,8 @@ void Scop::propagateDomainConstraints(Region *R) { if (containsErrorBlock(RN, getRegion(), LI, DT)) { IsOptimized = true; isl_set *DomPar = isl_set_params(isl_set_copy(Domain)); - addAssumption(isl_set_complement(DomPar)); + addAssumption(ERRORBLOCK, isl_set_complement(DomPar), + BB->getTerminator()->getDebugLoc()); } } } @@ -2282,7 +2285,8 @@ void Scop::addLoopBoundsToHeaderDomain(Loop *L) { isl_set *UnboundedCtx = isl_set_params(Parts.first); isl_set *BoundedCtx = isl_set_complement(UnboundedCtx); - addAssumption(BoundedCtx); + addAssumption(INFINITELOOP, BoundedCtx, + HeaderBB->getTerminator()->getDebugLoc()); } void Scop::buildAliasChecks(AliasAnalysis &AA) { @@ -2295,7 +2299,7 @@ void Scop::buildAliasChecks(AliasAnalysis &AA) { // If a problem occurs while building the alias groups we need to delete // this SCoP and pretend it wasn't valid in the first place. To this end // we make the assumed context infeasible. - addAssumption(isl_set_empty(getParamSpace())); + addAssumption(ALIASING, isl_set_empty(getParamSpace()), DebugLoc()); DEBUG(dbgs() << "\n\nNOTE: Run time checks for " << getNameStr() << " could not be created as the number of parameters involved " @@ -2802,7 +2806,8 @@ void Scop::hoistInvariantLoads() { << ") is required to be invariant but was not marked as " "such. SCoP for " << getRegion() << " will be dropped\n\n"); - addAssumption(isl_set_empty(getParamSpace())); + addAssumption(INVARIANTLOAD, isl_set_empty(getParamSpace()), + LI->getDebugLoc()); return; } } @@ -2820,7 +2825,8 @@ Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *AccessType, // In case of mismatching array sizes, we bail out by setting the run-time // context to false. if (!SAI->updateSizes(Sizes)) - addAssumption(isl_set_empty(getParamSpace())); + addAssumption(DELINEARIZATION, isl_set_empty(getParamSpace()), + DebugLoc()); } return SAI.get(); } @@ -2882,7 +2888,42 @@ bool Scop::hasFeasibleRuntimeContext() const { return IsFeasible; } -void Scop::addAssumption(__isl_take isl_set *Set) { +static std::string toString(AssumptionKind Kind) { + switch (Kind) { + case ALIASING: + return "No-aliasing"; + case INBOUNDS: + return "Inbounds"; + case WRAPPING: + return "No-overflows"; + case ERRORBLOCK: + return "No-error"; + case INFINITELOOP: + return "Finite loop"; + case INVARIANTLOAD: + return "Invariant load"; + case DELINEARIZATION: + return "Delinearization"; + } + llvm_unreachable("Unknown AssumptionKind!"); +} + +void Scop::trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set, + DebugLoc Loc) { + if (isl_set_is_subset(Context, Set)) + return; + + if (isl_set_is_subset(AssumedContext, Set)) + return; + + auto &F = *getRegion().getEntry()->getParent(); + std::string Msg = toString(Kind) + " assumption:\t" + stringFromIslObj(Set); + emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F, Loc, Msg); +} + +void Scop::addAssumption(AssumptionKind Kind, __isl_take isl_set *Set, + DebugLoc Loc) { + trackAssumption(Kind, Set, Loc); AssumedContext = isl_set_intersect(AssumedContext, Set); int NSets = isl_set_n_basic_set(AssumedContext); diff --git a/polly/test/ScopInfo/remarks.ll b/polly/test/ScopInfo/remarks.ll index c27c973f76b..feb08d6f253 100644 --- a/polly/test/ScopInfo/remarks.ll +++ b/polly/test/ScopInfo/remarks.ll @@ -1,11 +1,16 @@ ; RUN: opt %loadPolly -pass-remarks-analysis="polly-scops" -polly-scops < %s 2>&1| FileCheck %s ; ; CHECK: remark: test/ScopInfo/remarks.c:4:7: SCoP begins here. +; CHECK: remark: test/ScopInfo/remarks.c:8:5: Finite loop assumption: [M, N, Debug] -> { : M >= 0 or (M <= -2 and N <= 0) or (M = -1 and N <= 0) } +; CHECK: remark: test/ScopInfo/remarks.c:13:7: No-error assumption: [M, N, Debug] -> { : M <= -1 or (M >= 0 and N <= 0) or (Debug = 0 and M >= 0 and N >= 1) } +; CHECK: remark: test/ScopInfo/remarks.c:9:15: Inbounds assumption: [M, N, Debug] -> { : M <= 100 or (M >= 101 and N <= 0) } +; CHECK: remark: <unknown>:0:0: No-overflows assumption: [N, M, Debug] -> { : M <= 2147483647 - N and M >= -2147483648 - N } ; CHECK: remark: test/ScopInfo/remarks.c:9:18: Possibly aliasing pointer, use restrict keyword. ; CHECK: remark: test/ScopInfo/remarks.c:9:33: Possibly aliasing pointer, use restrict keyword. ; CHECK: remark: test/ScopInfo/remarks.c:9:15: Possibly aliasing pointer, use restrict keyword. ; CHECK: remark: test/ScopInfo/remarks.c:14:3: SCoP ends here. ; CHECK: remark: test/ScopInfo/remarks.c:19:3: SCoP begins here. +; CHECK: remark: test/ScopInfo/remarks.c:21:11: Invariant load assumption: [tmp] -> { : 1 = 0 } ; CHECK: remark: test/ScopInfo/remarks.c:22:16: SCoP ends here but was dismissed. ; ; #include <stdio.h> |