aboutsummaryrefslogtreecommitdiff
path: root/polly
diff options
context:
space:
mode:
authorEli Friedman <efriedma@codeaurora.org>2017-07-17 23:58:33 +0000
committerEli Friedman <efriedma@codeaurora.org>2017-07-17 23:58:33 +0000
commite737fc120e96fbdabab24060ec33567ea6c265db (patch)
tree3b044878dbc48ff5ea9928b04d0435d8100120b5 /polly
parent7828c88525b4c306d165383b772dd91473a6f03c (diff)
downloadllvm-e737fc120e96fbdabab24060ec33567ea6c265db.zip
llvm-e737fc120e96fbdabab24060ec33567ea6c265db.tar.gz
llvm-e737fc120e96fbdabab24060ec33567ea6c265db.tar.bz2
[Polly] [OptDiag] Updating Polly Diagnostics Remarks
Utilizing newer LLVM diagnostic remark API in order to enable use of opt-viewer tool. Polly Diagnostic Remarks also now appear in YAML remark file. In this patch, I've added the OptimizationRemarkEmitter into certain classes where remarks are being emitted and update the remark emit calls itself. I also provide each remark a BasicBlock or Instruction from where it is being called, in order to compute the hotness of the remark. Patch by Tarun Rajendran! Differential Revision: https://reviews.llvm.org/D35399 llvm-svn: 308233
Diffstat (limited to 'polly')
-rw-r--r--polly/include/polly/ScopDetection.h7
-rw-r--r--polly/include/polly/ScopDetectionDiagnostic.h62
-rw-r--r--polly/include/polly/ScopInfo.h16
-rw-r--r--polly/lib/Analysis/ScopBuilder.cpp20
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp14
-rw-r--r--polly/lib/Analysis/ScopDetectionDiagnostic.cpp165
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp66
-rw-r--r--polly/test/ScopDetectionDiagnostics/ReportUnprofitable.ll55
-rw-r--r--polly/test/ScopInfo/user_provided_non_dominating_assumptions.ll35
9 files changed, 375 insertions, 65 deletions
diff --git a/polly/include/polly/ScopDetection.h b/polly/include/polly/ScopDetection.h
index 0a6fc6a..c674d15 100644
--- a/polly/include/polly/ScopDetection.h
+++ b/polly/include/polly/ScopDetection.h
@@ -52,6 +52,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Pass.h"
#include <map>
@@ -526,7 +527,8 @@ private:
public:
ScopDetection(Function &F, const DominatorTree &DT, ScalarEvolution &SE,
- LoopInfo &LI, RegionInfo &RI, AliasAnalysis &AA);
+ LoopInfo &LI, RegionInfo &RI, AliasAnalysis &AA,
+ OptimizationRemarkEmitter &ORE);
/// Get the RegionInfo stored in this pass.
///
@@ -607,6 +609,9 @@ public:
static ScopDetection::LoopStats
countBeneficialLoops(Region *R, ScalarEvolution &SE, LoopInfo &LI,
unsigned MinProfitableTrips);
+
+ /// OptimizationRemarkEmitter object used to emit diagnostic remarks
+ OptimizationRemarkEmitter &ORE;
};
struct ScopAnalysis : public AnalysisInfoMixin<ScopAnalysis> {
diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h
index f9b28f5..f0cb61e 100644
--- a/polly/include/polly/ScopDetectionDiagnostic.h
+++ b/polly/include/polly/ScopDetectionDiagnostic.h
@@ -25,6 +25,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Value.h"
@@ -59,7 +60,8 @@ class RejectLog;
/// Remember to at least track failures (-polly-detect-track-failures).
/// @param P The region delimiters (entry & exit) we emit remarks for.
/// @param Log The error log containing all messages being emitted as remark.
-void emitRejectionRemarks(const BBPair &P, const RejectLog &Log);
+void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
+ OptimizationRemarkEmitter &ORE);
// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
enum class RejectReasonKind {
@@ -123,6 +125,16 @@ public:
virtual ~RejectReason() {}
+ /// Generate the remark name to identify this remark.
+ ///
+ /// @return A short string that identifies the error.
+ virtual std::string getRemarkName() const = 0;
+
+ /// Get the Basic Block containing this remark.
+ ///
+ /// @return The Basic Block containing this remark.
+ virtual const Value *getRemarkBB() const = 0;
+
/// Generate a reasonable diagnostic message describing this error.
///
/// @return A debug message representing this error.
@@ -203,6 +215,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
//@}
@@ -225,6 +239,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
@@ -249,6 +265,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
@@ -263,6 +281,7 @@ public:
class ReportAffFunc : public RejectReason {
//===--------------------------------------------------------------------===//
+protected:
// The instruction that caused non-affinity to occur.
const Instruction *Inst;
@@ -301,6 +320,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -326,6 +347,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -349,6 +372,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -383,6 +408,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -402,6 +429,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -421,6 +450,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -445,6 +476,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
//@}
@@ -476,6 +509,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
//@}
@@ -501,6 +536,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
//@}
@@ -532,6 +569,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
@@ -560,6 +599,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
@@ -588,6 +629,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
@@ -612,6 +655,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
@@ -650,6 +695,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
@@ -670,6 +717,7 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
virtual std::string getMessage() const override;
//@}
};
@@ -692,6 +740,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
//@}
@@ -713,6 +763,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
//@}
@@ -734,6 +786,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
//@}
@@ -755,6 +809,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
@@ -777,6 +833,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual std::string getEndUserMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
@@ -801,6 +859,8 @@ public:
/// @name RejectReason interface
//@{
+ virtual std::string getRemarkName() const override;
+ virtual const Value *getRemarkBB() const override;
virtual std::string getMessage() const override;
virtual const DebugLoc &getDebugLoc() const override;
virtual std::string getEndUserMessage() const override;
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index bc77bbf..edf40d6b 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -1658,6 +1658,9 @@ private:
/// The context of the SCoP created during SCoP detection.
ScopDetection::DetectionContext &DC;
+ /// OptimizationRemarkEmitter object for displaying diagnostic remarks
+ OptimizationRemarkEmitter &ORE;
+
/// Isl context.
///
/// We need a shared_ptr with reference counter to delete the context when all
@@ -1822,7 +1825,7 @@ private:
/// Scop constructor; invoked from ScopBuilder::buildScop.
Scop(Region &R, ScalarEvolution &SE, LoopInfo &LI,
- ScopDetection::DetectionContext &DC);
+ ScopDetection::DetectionContext &DC, OptimizationRemarkEmitter &ORE);
//@}
@@ -2453,10 +2456,12 @@ public:
/// @param Loc The location in the source that caused this assumption.
/// @param Sign Enum to indicate if the assumptions in @p Set are positive
/// (needed/assumptions) or negative (invalid/restrictions).
+ /// @param BB The block in which this assumption was taken. Used to
+ /// calculate hotness when emitting remark.
///
/// @returns True if the assumption is not trivial.
bool trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set,
- DebugLoc Loc, AssumptionSign Sign);
+ DebugLoc Loc, AssumptionSign Sign, BasicBlock *BB);
/// Add assumptions to assumed context.
///
@@ -2474,8 +2479,10 @@ public:
/// @param Loc The location in the source that caused this assumption.
/// @param Sign Enum to indicate if the assumptions in @p Set are positive
/// (needed/assumptions) or negative (invalid/restrictions).
+ /// @param BB The block in which this assumption was taken. Used to
+ /// calculate hotness when emitting remark.
void addAssumption(AssumptionKind Kind, __isl_take isl_set *Set, DebugLoc Loc,
- AssumptionSign Sign);
+ AssumptionSign Sign, BasicBlock *BB);
/// Record an assumption for later addition to the assumed context.
///
@@ -2508,7 +2515,8 @@ public:
///
/// @param Kind The assumption kind describing the underlying cause.
/// @param Loc The location in the source that triggered .
- void invalidate(AssumptionKind Kind, DebugLoc Loc);
+ /// @param BB The BasicBlock where it was triggered.
+ void invalidate(AssumptionKind Kind, DebugLoc Loc, BasicBlock *BB = nullptr);
/// Get the invalid context for this Scop.
///
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index f33a28b..4ec4c98 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -427,7 +427,7 @@ bool ScopBuilder::buildAccessMultiDimParam(MemAccInst Inst, ScopStmt *Stmt) {
cast<SCEVConstant>(Sizes.back())->getAPInt().getSExtValue();
Sizes.pop_back();
if (ElementSize != DelinearizedSize)
- scop->invalidate(DELINEARIZATION, Inst->getDebugLoc());
+ scop->invalidate(DELINEARIZATION, Inst->getDebugLoc(), Inst->getParent());
addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType,
true, AccItr->second.DelinearizedSubscripts, Sizes, Val);
@@ -935,7 +935,7 @@ static inline BasicBlock *getRegionNodeBasicBlock(RegionNode *RN) {
}
void ScopBuilder::buildScop(Region &R, AssumptionCache &AC) {
- scop.reset(new Scop(R, SE, LI, *SD.getDetectionContext(&R)));
+ scop.reset(new Scop(R, SE, LI, *SD.getDetectionContext(&R), SD.ORE));
buildStmts(R);
buildAccessFunctions();
@@ -1038,12 +1038,13 @@ ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
ScopDetection &SD, ScalarEvolution &SE)
: AA(AA), DL(DL), DT(DT), LI(LI), SD(SD), SE(SE) {
- Function *F = R->getEntry()->getParent();
-
DebugLoc Beg, End;
- getDebugLocations(getBBPairForRegion(R), Beg, End);
+ auto P = getBBPairForRegion(R);
+ getDebugLocations(P, Beg, End);
+
std::string Msg = "SCoP begins here.";
- emitOptimizationRemarkAnalysis(F->getContext(), DEBUG_TYPE, *F, Beg, Msg);
+ SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEntry", Beg, P.first)
+ << Msg);
buildScop(*R, AC);
@@ -1060,5 +1061,10 @@ ScopBuilder::ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
++RichScopFound;
}
- emitOptimizationRemarkAnalysis(F->getContext(), DEBUG_TYPE, *F, End, Msg);
+ if (R->isTopLevelRegion())
+ SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.first)
+ << Msg);
+ else
+ SD.ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "ScopEnd", End, P.second)
+ << Msg);
}
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 27dfc93..199306a 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -284,8 +284,8 @@ static bool IsFnNameListedInOnlyFunctions(StringRef FnName) {
ScopDetection::ScopDetection(Function &F, const DominatorTree &DT,
ScalarEvolution &SE, LoopInfo &LI, RegionInfo &RI,
- AliasAnalysis &AA)
- : DT(DT), SE(SE), LI(LI), RI(RI), AA(AA) {
+ AliasAnalysis &AA, OptimizationRemarkEmitter &ORE)
+ : DT(DT), SE(SE), LI(LI), RI(RI), AA(AA), ORE(ORE) {
if (!PollyProcessUnprofitable && LI.empty())
return;
@@ -1579,7 +1579,7 @@ void ScopDetection::emitMissedRemarks(const Function &F) {
for (auto &DIt : DetectionContextMap) {
auto &DC = DIt.getSecond();
if (DC.Log.hasErrors())
- emitRejectionRemarks(DIt.getFirst(), DC.Log);
+ emitRejectionRemarks(DIt.getFirst(), DC.Log, ORE);
}
}
@@ -1728,7 +1728,8 @@ bool ScopDetectionWrapperPass::runOnFunction(llvm::Function &F) {
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- Result.reset(new ScopDetection(F, DT, SE, LI, RI, AA));
+ auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
+ Result.reset(new ScopDetection(F, DT, SE, LI, RI, AA, ORE));
return false;
}
@@ -1736,6 +1737,7 @@ void ScopDetectionWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
// We also need AA and RegionInfo when we are verifying analysis.
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<RegionInfoPass>();
@@ -1767,7 +1769,8 @@ ScopDetection ScopAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
auto &AA = FAM.getResult<AAManager>(F);
auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
- return {F, DT, SE, LI, RI, AA};
+ auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+ return {F, DT, SE, LI, RI, AA, ORE};
}
PreservedAnalyses ScopAnalysisPrinterPass::run(Function &F,
@@ -1792,5 +1795,6 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass);
INITIALIZE_PASS_END(ScopDetectionWrapperPass, "polly-detect",
"Polly - Detect static control parts (SCoPs)", false, false)
diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
index ffc259f..4277ae3 100644
--- a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
+++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DebugInfo.h"
@@ -121,28 +122,36 @@ void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
}
}
-void emitRejectionRemarks(const BBPair &P, const RejectLog &Log) {
- Function &F = *P.first->getParent();
- LLVMContext &Ctx = F.getContext();
-
+void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
+ OptimizationRemarkEmitter &ORE) {
DebugLoc Begin, End;
getDebugLocations(P, Begin, End);
- emitOptimizationRemarkMissed(
- Ctx, DEBUG_TYPE, F, Begin,
- "The following errors keep this region from being a Scop.");
+ ORE.emit(
+ OptimizationRemarkMissed(DEBUG_TYPE, "RejectionErrors", Begin, P.first)
+ << "The following errors keep this region from being a Scop.");
for (RejectReasonPtr RR : Log) {
+
if (const DebugLoc &Loc = RR->getDebugLoc())
- emitOptimizationRemarkMissed(Ctx, DEBUG_TYPE, F, Loc,
- RR->getEndUserMessage());
+ ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Loc,
+ RR->getRemarkBB())
+ << RR->getEndUserMessage());
else
- emitOptimizationRemarkMissed(Ctx, DEBUG_TYPE, F, Begin,
- RR->getEndUserMessage());
+ ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
+ RR->getRemarkBB())
+ << RR->getEndUserMessage());
}
- emitOptimizationRemarkMissed(Ctx, DEBUG_TYPE, F, End,
- "Invalid Scop candidate ends here.");
+ /* Check to see if Region is a top level region, getExit = NULL*/
+ if (P.second)
+ ORE.emit(
+ OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
+ << "Invalid Scop candidate ends here.");
+ else
+ ORE.emit(
+ OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
+ << "Invalid Scop candidate ends here.");
}
//===----------------------------------------------------------------------===//
@@ -179,6 +188,12 @@ bool ReportCFG::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportInvalidTerminator.
+std::string ReportInvalidTerminator::getRemarkName() const {
+ return "InvalidTerminator";
+}
+
+const Value *ReportInvalidTerminator::getRemarkBB() const { return BB; }
+
std::string ReportInvalidTerminator::getMessage() const {
return ("Invalid instruction terminates BB: " + BB->getName()).str();
}
@@ -194,6 +209,12 @@ bool ReportInvalidTerminator::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// UnreachableInExit.
+std::string ReportUnreachableInExit::getRemarkName() const {
+ return "UnreachableInExit";
+}
+
+const Value *ReportUnreachableInExit::getRemarkBB() const { return BB; }
+
std::string ReportUnreachableInExit::getMessage() const {
std::string BBName = BB->getName();
return "Unreachable in exit block" + BBName;
@@ -212,6 +233,14 @@ bool ReportUnreachableInExit::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportIrreducibleRegion.
+std::string ReportIrreducibleRegion::getRemarkName() const {
+ return "IrreducibleRegion";
+}
+
+const Value *ReportIrreducibleRegion::getRemarkBB() const {
+ return R->getEntry();
+}
+
std::string ReportIrreducibleRegion::getMessage() const {
return "Irreducible region encountered: " + R->getNameStr();
}
@@ -240,6 +269,10 @@ bool ReportAffFunc::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportUndefCond.
+std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
+
+const Value *ReportUndefCond::getRemarkBB() const { return BB; }
+
std::string ReportUndefCond::getMessage() const {
return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
}
@@ -251,6 +284,10 @@ bool ReportUndefCond::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportInvalidCond.
+std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
+
+const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
+
std::string ReportInvalidCond::getMessage() const {
return ("Condition in BB '" + BB->getName()).str() +
"' neither constant nor an icmp instruction";
@@ -263,6 +300,10 @@ bool ReportInvalidCond::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportUndefOperand.
+std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
+
+const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
+
std::string ReportUndefOperand::getMessage() const {
return ("undef operand in branch at BB: " + BB->getName()).str();
}
@@ -274,6 +315,10 @@ bool ReportUndefOperand::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportNonAffBranch.
+std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
+
+const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
+
std::string ReportNonAffBranch::getMessage() const {
return ("Non affine branch in BB '" + BB->getName()).str() +
"' with LHS: " + *LHS + " and RHS: " + *RHS;
@@ -286,6 +331,10 @@ bool ReportNonAffBranch::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportNoBasePtr.
+std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
+
+const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
+
std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
bool ReportNoBasePtr::classof(const RejectReason *RR) {
@@ -295,6 +344,12 @@ bool ReportNoBasePtr::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportUndefBasePtr.
+std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
+
+const Value *ReportUndefBasePtr::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportUndefBasePtr::getMessage() const {
return "Undefined base pointer";
}
@@ -306,6 +361,14 @@ bool ReportUndefBasePtr::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportVariantBasePtr.
+std::string ReportVariantBasePtr::getRemarkName() const {
+ return "VariantBasePtr";
+}
+
+const Value *ReportVariantBasePtr::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportVariantBasePtr::getMessage() const {
return "Base address not invariant in current region:" + *BaseValue;
}
@@ -321,6 +384,14 @@ bool ReportVariantBasePtr::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportDifferentArrayElementSize
+std::string ReportDifferentArrayElementSize::getRemarkName() const {
+ return "DifferentArrayElementSize";
+}
+
+const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportDifferentArrayElementSize::getMessage() const {
return "Access to one array through data types of different size";
}
@@ -340,6 +411,14 @@ std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
//===----------------------------------------------------------------------===//
// ReportNonAffineAccess.
+std::string ReportNonAffineAccess::getRemarkName() const {
+ return "NonAffineAccess";
+}
+
+const Value *ReportNonAffineAccess::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportNonAffineAccess::getMessage() const {
return "Non affine access function: " + *AccessFunction;
}
@@ -361,6 +440,10 @@ ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
: RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
Loc(L->getStartLoc()) {}
+std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
+
+const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
+
std::string ReportLoopBound::getMessage() const {
return "Non affine loop bound '" + *LoopCount +
"' in loop: " + L->getHeader()->getName();
@@ -379,6 +462,12 @@ std::string ReportLoopBound::getEndUserMessage() const {
//===----------------------------------------------------------------------===//
// ReportLoopHasNoExit.
+std::string ReportLoopHasNoExit::getRemarkName() const {
+ return "LoopHasNoExit";
+}
+
+const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
+
std::string ReportLoopHasNoExit::getMessage() const {
return "Loop " + L->getHeader()->getName() + " has no exit.";
}
@@ -396,6 +485,14 @@ std::string ReportLoopHasNoExit::getEndUserMessage() const {
//===----------------------------------------------------------------------===//
// ReportLoopOnlySomeLatches
+std::string ReportLoopOnlySomeLatches::getRemarkName() const {
+ return "LoopHasNoExit";
+}
+
+const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
+ return L->getHeader();
+}
+
std::string ReportLoopOnlySomeLatches::getMessage() const {
return "Not all latches of loop " + L->getHeader()->getName() +
" part of scop.";
@@ -418,6 +515,10 @@ std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
ReportFuncCall::ReportFuncCall(Instruction *Inst)
: RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
+std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
+
+const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
+
std::string ReportFuncCall::getMessage() const {
return "Call instruction: " + *Inst;
}
@@ -441,6 +542,14 @@ bool ReportFuncCall::classof(const RejectReason *RR) {
ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
: ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
+std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
+ return "NonSimpleMemoryAccess";
+}
+
+const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportNonSimpleMemoryAccess::getMessage() const {
return "Non-simple memory access: " + *Inst;
}
@@ -499,6 +608,10 @@ std::string ReportAlias::formatInvalidAlias(std::string Prefix,
return OS.str();
}
+std::string ReportAlias::getRemarkName() const { return "Alias"; }
+
+const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
+
std::string ReportAlias::getMessage() const {
return formatInvalidAlias("Possible aliasing: ");
}
@@ -517,6 +630,8 @@ bool ReportAlias::classof(const RejectReason *RR) {
//===----------------------------------------------------------------------===//
// ReportOther.
+std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
+
std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
@@ -531,6 +646,12 @@ bool ReportOther::classof(const RejectReason *RR) {
ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
: ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
+std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
+
+const Value *ReportIntToPtr::getRemarkBB() const {
+ return BaseValue->getParent();
+}
+
std::string ReportIntToPtr::getMessage() const {
return "Find bad intToptr prt: " + *BaseValue;
}
@@ -549,6 +670,10 @@ bool ReportIntToPtr::classof(const RejectReason *RR) {
ReportAlloca::ReportAlloca(Instruction *Inst)
: ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
+std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
+
+const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
+
std::string ReportAlloca::getMessage() const {
return "Alloca instruction: " + *Inst;
}
@@ -567,6 +692,12 @@ bool ReportAlloca::classof(const RejectReason *RR) {
ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
: ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
+std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
+
+const Value *ReportUnknownInst::getRemarkBB() const {
+ return Inst->getParent();
+}
+
std::string ReportUnknownInst::getMessage() const {
return "Unknown instruction: " + *Inst;
}
@@ -584,6 +715,10 @@ bool ReportUnknownInst::classof(const RejectReason *RR) {
ReportEntry::ReportEntry(BasicBlock *BB)
: ReportOther(RejectReasonKind::Entry), BB(BB) {}
+std::string ReportEntry::getRemarkName() const { return "Entry"; }
+
+const Value *ReportEntry::getRemarkBB() const { return BB; }
+
std::string ReportEntry::getMessage() const {
return "Region containing entry block of function is invalid!";
}
@@ -605,6 +740,10 @@ bool ReportEntry::classof(const RejectReason *RR) {
ReportUnprofitable::ReportUnprofitable(Region *R)
: ReportOther(RejectReasonKind::Unprofitable), R(R) {}
+std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
+
+const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
+
std::string ReportUnprofitable::getMessage() const {
return "Region can not profitably be optimized!";
}
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index b5d4100..0f23526 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1617,7 +1617,8 @@ buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition,
}
if (TooComplex) {
- S.invalidate(COMPLEXITY, TI ? TI->getDebugLoc() : DebugLoc());
+ S.invalidate(COMPLEXITY, TI ? TI->getDebugLoc() : DebugLoc(),
+ TI ? TI->getParent() : nullptr /* BasicBlock */);
isl_set_free(AlternativeCondSet);
isl_set_free(ConsequenceCondSet);
return false;
@@ -2163,7 +2164,6 @@ bool Scop::isDominatedBy(const DominatorTree &DT, BasicBlock *BB) const {
void Scop::addUserAssumptions(
AssumptionCache &AC, DominatorTree &DT, LoopInfo &LI,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
- auto &F = getFunction();
for (auto &Assumption : AC.assumptions()) {
auto *CI = dyn_cast_or_null<CallInst>(Assumption);
if (!CI || CI->getNumArgOperands() != 1)
@@ -2177,9 +2177,9 @@ void Scop::addUserAssumptions(
auto *Val = CI->getArgOperand(0);
ParameterSetTy DetectedParams;
if (!isAffineConstraint(Val, &R, L, *SE, DetectedParams)) {
- emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
- CI->getDebugLoc(),
- "Non-affine user assumption ignored.");
+ ORE.emit(
+ OptimizationRemarkAnalysis(DEBUG_TYPE, "IgnoreUserAssumption", CI)
+ << "Non-affine user assumption ignored.");
continue;
}
@@ -2227,10 +2227,8 @@ void Scop::addUserAssumptions(
isl_set_project_out(AssumptionCtx, isl_dim_param, u--, 1);
}
}
-
- emitOptimizationRemarkAnalysis(
- F.getContext(), DEBUG_TYPE, F, CI->getDebugLoc(),
- "Use user assumption: " + stringFromIslObj(AssumptionCtx));
+ ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "UserAssumption", CI)
+ << "Use user assumption: " << stringFromIslObj(AssumptionCtx));
Context = isl_set_intersect(Context, AssumptionCtx);
}
}
@@ -2827,7 +2825,7 @@ bool Scop::propagateInvalidStmtDomains(
continue;
InvalidDomainMap.erase(BB);
- invalidate(COMPLEXITY, TI->getDebugLoc());
+ invalidate(COMPLEXITY, TI->getDebugLoc(), TI->getParent());
return false;
}
@@ -3383,17 +3381,13 @@ bool Scop::buildAliasGroup(Scop::AliasGroupTy &AliasGroup,
SmallPtrSet<const ScopArrayInfo *, 4> ReadWriteArrays;
SmallPtrSet<const ScopArrayInfo *, 4> ReadOnlyArrays;
- auto &F = getFunction();
-
if (AliasGroup.size() < 2)
return true;
for (MemoryAccess *Access : AliasGroup) {
- emitOptimizationRemarkAnalysis(
- F.getContext(), DEBUG_TYPE, F,
- Access->getAccessInstruction()->getDebugLoc(),
- "Possibly aliasing pointer, use restrict keyword.");
-
+ ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "PossibleAlias",
+ Access->getAccessInstruction())
+ << "Possibly aliasing pointer, use restrict keyword.");
const ScopArrayInfo *Array = Access->getScopArrayInfo();
if (HasWriteAccess.count(Array)) {
ReadWriteArrays.insert(Array);
@@ -3417,7 +3411,8 @@ bool Scop::buildAliasGroup(Scop::AliasGroupTy &AliasGroup,
// compute a sufficiently tight lower and upper bound: bail out.
for (MemoryAccess *MA : AliasGroup) {
if (!MA->isAffine()) {
- invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc());
+ invalidate(ALIASING, MA->getAccessInstruction()->getDebugLoc(),
+ MA->getAccessInstruction()->getParent());
return false;
}
}
@@ -3492,10 +3487,10 @@ int Scop::getNextID(std::string ParentFunc) {
}
Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
- ScopDetection::DetectionContext &DC)
+ ScopDetection::DetectionContext &DC, OptimizationRemarkEmitter &ORE)
: SE(&ScalarEvolution), R(R), name(R.getNameStr()), IsOptimized(false),
HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
- MaxLoopDepth(0), CopyStmtsNum(0), SkipScop(false), DC(DC),
+ MaxLoopDepth(0), CopyStmtsNum(0), SkipScop(false), DC(DC), ORE(ORE),
IslCtx(isl_ctx_alloc(), isl_ctx_free), Context(nullptr),
Affinator(this, LI), AssumedContext(nullptr), InvalidContext(nullptr),
Schedule(nullptr),
@@ -3850,7 +3845,7 @@ void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) {
if (isl_set_n_basic_set(DomainCtx) >= MaxDisjunctsInDomain) {
auto *AccInst = InvMAs.front().MA->getAccessInstruction();
- invalidate(COMPLEXITY, AccInst->getDebugLoc());
+ invalidate(COMPLEXITY, AccInst->getDebugLoc(), AccInst->getParent());
isl_set_free(DomainCtx);
for (auto &InvMA : InvMAs)
isl_set_free(InvMA.NonHoistableCtx);
@@ -4024,7 +4019,7 @@ isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) {
return nullptr;
addAssumption(INVARIANTLOAD, WrittenCtx.copy(), LI->getDebugLoc(),
- AS_RESTRICTION);
+ AS_RESTRICTION, LI->getParent());
return WrittenCtx;
}
@@ -4034,7 +4029,7 @@ void Scop::verifyInvariantLoads() {
assert(LI && contains(LI));
ScopStmt *Stmt = getStmtFor(LI);
if (Stmt && Stmt->getArrayAccessOrNULLFor(LI)) {
- invalidate(INVARIANTLOAD, LI->getDebugLoc());
+ invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent());
return;
}
}
@@ -4319,7 +4314,7 @@ bool Scop::isEffectiveAssumption(__isl_keep isl_set *Set, AssumptionSign Sign) {
}
bool Scop::trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set,
- DebugLoc Loc, AssumptionSign Sign) {
+ DebugLoc Loc, AssumptionSign Sign, BasicBlock *BB) {
if (PollyRemarksMinimal && !isEffectiveAssumption(Set, Sign))
return false;
@@ -4370,19 +4365,24 @@ bool Scop::trackAssumption(AssumptionKind Kind, __isl_keep isl_set *Set,
break;
}
- auto &F = getFunction();
auto Suffix = Sign == AS_ASSUMPTION ? " assumption:\t" : " restriction:\t";
std::string Msg = toString(Kind) + Suffix + stringFromIslObj(Set);
- emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F, Loc, Msg);
+ if (BB)
+ ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc, BB)
+ << Msg);
+ else
+ ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AssumpRestrict", Loc,
+ R.getEntry())
+ << Msg);
return true;
}
void Scop::addAssumption(AssumptionKind Kind, __isl_take isl_set *Set,
- DebugLoc Loc, AssumptionSign Sign) {
+ DebugLoc Loc, AssumptionSign Sign, BasicBlock *BB) {
// Simplify the assumptions/restrictions first.
Set = isl_set_gist_params(Set, getContext());
- if (!trackAssumption(Kind, Set, Loc, Sign)) {
+ if (!trackAssumption(Kind, Set, Loc, Sign, BB)) {
isl_set_free(Set);
return;
}
@@ -4408,7 +4408,7 @@ void Scop::addRecordedAssumptions() {
const Assumption &AS = RecordedAssumptions.pop_back_val();
if (!AS.BB) {
- addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign);
+ addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign, nullptr /* BasicBlock */);
continue;
}
@@ -4434,12 +4434,12 @@ void Scop::addRecordedAssumptions() {
else /* (AS.Sign == AS_ASSUMPTION) */
S = isl_set_params(isl_set_subtract(Dom, S));
- addAssumption(AS.Kind, S, AS.Loc, AS_RESTRICTION);
+ addAssumption(AS.Kind, S, AS.Loc, AS_RESTRICTION, AS.BB);
}
}
-void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc) {
- addAssumption(Kind, isl_set_empty(getParamSpace()), Loc, AS_ASSUMPTION);
+void Scop::invalidate(AssumptionKind Kind, DebugLoc Loc, BasicBlock *BB) {
+ addAssumption(Kind, isl_set_empty(getParamSpace()), Loc, AS_ASSUMPTION, BB);
}
__isl_give isl_set *Scop::getInvalidContext() const {
@@ -4571,7 +4571,7 @@ __isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
}
auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
- invalidate(COMPLEXITY, DL);
+ invalidate(COMPLEXITY, DL, BB);
return Affinator.getPwAff(SE->getZero(E->getType()), BB);
}
diff --git a/polly/test/ScopDetectionDiagnostics/ReportUnprofitable.ll b/polly/test/ScopDetectionDiagnostics/ReportUnprofitable.ll
index 07d6ffb..4ea1aee 100644
--- a/polly/test/ScopDetectionDiagnostics/ReportUnprofitable.ll
+++ b/polly/test/ScopDetectionDiagnostics/ReportUnprofitable.ll
@@ -1,13 +1,18 @@
; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" \
; RUN: -polly-detect-track-failures -polly-detect -analyze \
; RUN: -polly-process-unprofitable=false < %s 2>&1| FileCheck %s
+
+; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" \
+; RUN: -polly-detect-track-failures -polly-detect -analyze \
+; RUN: -polly-process-unprofitable=false < %s 2>&1 -pass-remarks-output=%t.yaml
+; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; void onlyWrite(float *A) {
; for (long i = 0; i < 100; i++)
; A[i] = 0;
; }
-;
+;
; void onlyRead(float *A) {
; for (long i = 0; i < 100; i++)
; A[i];
@@ -21,6 +26,54 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK: remark: /tmp/test.c:7:3: No profitable polyhedral optimization found
; CHECK: remark: /tmp/test.c:8:10: Invalid Scop candidate ends here.
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: RejectionErrors
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 2, Column: 3 }
+; YAML: Function: onlyWrite
+; YAML: Args:
+; YAML: - String: The following errors keep this region from being a Scop.
+; YAML: ...
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: Unprofitable
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 2, Column: 3 }
+; YAML: Function: onlyWrite
+; YAML: Args:
+; YAML: - String: No profitable polyhedral optimization found
+; YAML: ...
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: InvalidScopEnd
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 3, Column: 10 }
+; YAML: Function: onlyWrite
+; YAML: Args:
+; YAML: - String: Invalid Scop candidate ends here.
+; YAML: ...
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: RejectionErrors
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 7, Column: 3 }
+; YAML: Function: onlyRead
+; YAML: Args:
+; YAML: - String: The following errors keep this region from being a Scop.
+; YAML: ...
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: Unprofitable
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 7, Column: 3 }
+; YAML: Function: onlyRead
+; YAML: Args:
+; YAML: - String: No profitable polyhedral optimization found
+; YAML: ...
+; YAML: --- !Missed
+; YAML: Pass: polly-detect
+; YAML: Name: InvalidScopEnd
+; YAML: DebugLoc: { File: /tmp/test.c, Line: 8, Column: 10 }
+; YAML: Function: onlyRead
+; YAML: Args:
+; YAML: - String: Invalid Scop candidate ends here.
+
; Function Attrs: nounwind uwtable
define void @onlyWrite(float* %A) #0 !dbg !4 {
diff --git a/polly/test/ScopInfo/user_provided_non_dominating_assumptions.ll b/polly/test/ScopInfo/user_provided_non_dominating_assumptions.ll
index 1a91aab..4ca96ff 100644
--- a/polly/test/ScopInfo/user_provided_non_dominating_assumptions.ll
+++ b/polly/test/ScopInfo/user_provided_non_dominating_assumptions.ll
@@ -16,6 +16,41 @@
; }
; }
;
+
+
+; RUN: opt %loadPolly -pass-remarks-analysis="polly-scops" -polly-scops \
+; RUN: -polly-precise-inbounds -disable-output < %s 2>&1 -pass-remarks-output=%t.yaml
+; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
+; YAML: --- !Analysis
+; YAML: Pass: polly-scops
+; YAML: Name: ScopEntry
+; YAML: Function: f
+; YAML: Args:
+; YAML: - String: SCoP begins here.
+; YAML: ...
+; YAML: --- !Analysis
+; YAML: Pass: polly-scops
+; YAML: Name: UserAssumption
+; YAML: Function: f
+; YAML: Args:
+; YAML: - String: 'Use user assumption: '
+; YAML: - String: '[i, N, M] -> { : N <= i or (N > i and N >= 0) }'
+; YAML: ...
+; YAML: --- !Analysis
+; YAML: Pass: polly-scops
+; YAML: Name: AssumpRestrict
+; YAML: Function: f
+; YAML: Args:
+; YAML: - String: 'Inbounds assumption: [i, N, M] -> { : N <= i or (N > i and M <= 100) }'
+; YAML: ...
+; YAML: --- !Analysis
+; YAML: Pass: polly-scops
+; YAML: Name: ScopEnd
+; YAML: Function: f
+; YAML: Args:
+; YAML: - String: SCoP ends here.
+; YAML: ...
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* noalias %A, i32* noalias %B, i32 %i, i32 %N, i32 %M, [100 x i32]* %C) {