1 //===- ScopDetectionDiagnostic.cpp - Error diagnostics --------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Small set of diagnostic helper classes to encapsulate any errors occurred
10 // during the detection of Scops.
12 // The ScopDetection defines a set of error classes (via Statistic variables)
13 // that groups a number of individual errors into a group, e.g. non-affinity
15 // On error we generate an object that carries enough additional information
16 // to diagnose the error and generate a helpful error message.
18 //===----------------------------------------------------------------------===//
20 #include "polly/ScopDetectionDiagnostic.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Statistic.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/Analysis/AliasSetTracker.h"
27 #include "llvm/Analysis/LoopInfo.h"
28 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
29 #include "llvm/Analysis/RegionInfo.h"
30 #include "llvm/Analysis/ScalarEvolution.h"
31 #include "llvm/IR/BasicBlock.h"
32 #include "llvm/IR/CFG.h"
33 #include "llvm/IR/DebugLoc.h"
34 #include "llvm/IR/DiagnosticInfo.h"
35 #include "llvm/IR/Instruction.h"
36 #include "llvm/IR/Value.h"
37 #include "llvm/Support/raw_ostream.h"
45 #define DEBUG_TYPE "polly-detect"
47 #define SCOP_STAT(NAME, DESC) \
48 { "polly-detect", "NAME", "Number of rejected regions: " DESC }
50 Statistic RejectStatistics
[] = {
52 SCOP_STAT(InvalidTerminator
, "Unsupported terminator instruction"),
53 SCOP_STAT(UnreachableInExit
, "Unreachable in exit block"),
54 SCOP_STAT(IrreducibleRegion
, "Irreducible loops"),
55 SCOP_STAT(LastCFG
, ""),
56 SCOP_STAT(AffFunc
, ""),
57 SCOP_STAT(UndefCond
, "Undefined branch condition"),
58 SCOP_STAT(InvalidCond
, "Non-integer branch condition"),
59 SCOP_STAT(UndefOperand
, "Undefined operands in comparison"),
60 SCOP_STAT(NonAffBranch
, "Non-affine branch condition"),
61 SCOP_STAT(NoBasePtr
, "No base pointer"),
62 SCOP_STAT(UndefBasePtr
, "Undefined base pointer"),
63 SCOP_STAT(VariantBasePtr
, "Variant base pointer"),
64 SCOP_STAT(NonAffineAccess
, "Non-affine memory accesses"),
65 SCOP_STAT(DifferentElementSize
, "Accesses with differing sizes"),
66 SCOP_STAT(LastAffFunc
, ""),
67 SCOP_STAT(LoopBound
, "Uncomputable loop bounds"),
68 SCOP_STAT(LoopHasNoExit
, "Loop without exit"),
69 SCOP_STAT(LoopHasMultipleExits
, "Loop with multiple exits"),
70 SCOP_STAT(LoopOnlySomeLatches
, "Not all loop latches in scop"),
71 SCOP_STAT(FuncCall
, "Function call with side effects"),
72 SCOP_STAT(NonSimpleMemoryAccess
,
73 "Compilated access semantics (volatile or atomic)"),
74 SCOP_STAT(Alias
, "Base address aliasing"),
76 SCOP_STAT(IntToPtr
, "Integer to pointer conversions"),
77 SCOP_STAT(Alloca
, "Stack allocations"),
78 SCOP_STAT(UnknownInst
, "Unknown Instructions"),
79 SCOP_STAT(Entry
, "Contains entry block"),
80 SCOP_STAT(Unprofitable
, "Assumed to be unprofitable"),
81 SCOP_STAT(LastOther
, ""),
86 /// Small string conversion via raw_string_stream.
87 template <typename T
> std::string
operator+(Twine LHS
, const T
&RHS
) {
89 raw_string_ostream
fmt(Buf
);
93 return LHS
.concat(Buf
).str();
99 // Lexicographic order on (line, col) of our debug locations.
100 static bool operator<(const DebugLoc
&LHS
, const DebugLoc
&RHS
) {
101 return LHS
.getLine() < RHS
.getLine() ||
102 (LHS
.getLine() == RHS
.getLine() && LHS
.getCol() < RHS
.getCol());
108 BBPair
getBBPairForRegion(const Region
*R
) {
109 return std::make_pair(R
->getEntry(), R
->getExit());
112 void getDebugLocations(const BBPair
&P
, DebugLoc
&Begin
, DebugLoc
&End
) {
113 SmallPtrSet
<BasicBlock
*, 32> Seen
;
114 SmallVector
<BasicBlock
*, 32> Todo
;
115 Todo
.push_back(P
.first
);
116 while (!Todo
.empty()) {
117 auto *BB
= Todo
.pop_back_val();
120 if (!Seen
.insert(BB
).second
)
122 Todo
.append(succ_begin(BB
), succ_end(BB
));
123 for (const Instruction
&Inst
: *BB
) {
124 DebugLoc DL
= Inst
.getDebugLoc();
128 Begin
= Begin
? std::min(Begin
, DL
) : DL
;
129 End
= End
? std::max(End
, DL
) : DL
;
134 void emitRejectionRemarks(const BBPair
&P
, const RejectLog
&Log
,
135 OptimizationRemarkEmitter
&ORE
) {
137 getDebugLocations(P
, Begin
, End
);
140 OptimizationRemarkMissed(DEBUG_TYPE
, "RejectionErrors", Begin
, P
.first
)
141 << "The following errors keep this region from being a Scop.");
143 for (RejectReasonPtr RR
: Log
) {
145 if (const DebugLoc
&Loc
= RR
->getDebugLoc())
146 ORE
.emit(OptimizationRemarkMissed(DEBUG_TYPE
, RR
->getRemarkName(), Loc
,
148 << RR
->getEndUserMessage());
150 ORE
.emit(OptimizationRemarkMissed(DEBUG_TYPE
, RR
->getRemarkName(), Begin
,
152 << RR
->getEndUserMessage());
155 /* Check to see if Region is a top level region, getExit = NULL*/
158 OptimizationRemarkMissed(DEBUG_TYPE
, "InvalidScopEnd", End
, P
.second
)
159 << "Invalid Scop candidate ends here.");
162 OptimizationRemarkMissed(DEBUG_TYPE
, "InvalidScopEnd", End
, P
.first
)
163 << "Invalid Scop candidate ends here.");
166 //===----------------------------------------------------------------------===//
169 RejectReason::RejectReason(RejectReasonKind K
) : Kind(K
) {
170 RejectStatistics
[static_cast<int>(K
)]++;
173 const DebugLoc
RejectReason::Unknown
= DebugLoc();
175 const DebugLoc
&RejectReason::getDebugLoc() const {
176 // Allocate an empty DebugLoc and return it a reference to it.
181 void RejectLog::print(raw_ostream
&OS
, int level
) const {
183 for (auto Reason
: ErrorReports
)
184 OS
.indent(level
) << "[" << j
++ << "] " << Reason
->getMessage() << "\n";
187 //===----------------------------------------------------------------------===//
190 ReportCFG::ReportCFG(const RejectReasonKind K
) : RejectReason(K
) {}
192 bool ReportCFG::classof(const RejectReason
*RR
) {
193 return RR
->getKind() >= RejectReasonKind::CFG
&&
194 RR
->getKind() <= RejectReasonKind::LastCFG
;
197 //===----------------------------------------------------------------------===//
198 // ReportInvalidTerminator.
200 std::string
ReportInvalidTerminator::getRemarkName() const {
201 return "InvalidTerminator";
204 const Value
*ReportInvalidTerminator::getRemarkBB() const { return BB
; }
206 std::string
ReportInvalidTerminator::getMessage() const {
207 return ("Invalid instruction terminates BB: " + BB
->getName()).str();
210 const DebugLoc
&ReportInvalidTerminator::getDebugLoc() const {
211 return BB
->getTerminator()->getDebugLoc();
214 bool ReportInvalidTerminator::classof(const RejectReason
*RR
) {
215 return RR
->getKind() == RejectReasonKind::InvalidTerminator
;
218 //===----------------------------------------------------------------------===//
219 // UnreachableInExit.
221 std::string
ReportUnreachableInExit::getRemarkName() const {
222 return "UnreachableInExit";
225 const Value
*ReportUnreachableInExit::getRemarkBB() const { return BB
; }
227 std::string
ReportUnreachableInExit::getMessage() const {
228 std::string BBName
= BB
->getName();
229 return "Unreachable in exit block" + BBName
;
232 const DebugLoc
&ReportUnreachableInExit::getDebugLoc() const { return DbgLoc
; }
234 std::string
ReportUnreachableInExit::getEndUserMessage() const {
235 return "Unreachable in exit block.";
238 bool ReportUnreachableInExit::classof(const RejectReason
*RR
) {
239 return RR
->getKind() == RejectReasonKind::UnreachableInExit
;
242 //===----------------------------------------------------------------------===//
243 // ReportIrreducibleRegion.
245 std::string
ReportIrreducibleRegion::getRemarkName() const {
246 return "IrreducibleRegion";
249 const Value
*ReportIrreducibleRegion::getRemarkBB() const {
250 return R
->getEntry();
253 std::string
ReportIrreducibleRegion::getMessage() const {
254 return "Irreducible region encountered: " + R
->getNameStr();
257 const DebugLoc
&ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc
; }
259 std::string
ReportIrreducibleRegion::getEndUserMessage() const {
260 return "Irreducible region encountered in control flow.";
263 bool ReportIrreducibleRegion::classof(const RejectReason
*RR
) {
264 return RR
->getKind() == RejectReasonKind::IrreducibleRegion
;
267 //===----------------------------------------------------------------------===//
270 ReportAffFunc::ReportAffFunc(const RejectReasonKind K
, const Instruction
*Inst
)
271 : RejectReason(K
), Inst(Inst
) {}
273 bool ReportAffFunc::classof(const RejectReason
*RR
) {
274 return RR
->getKind() >= RejectReasonKind::AffFunc
&&
275 RR
->getKind() <= RejectReasonKind::LastAffFunc
;
278 //===----------------------------------------------------------------------===//
281 std::string
ReportUndefCond::getRemarkName() const { return "UndefCond"; }
283 const Value
*ReportUndefCond::getRemarkBB() const { return BB
; }
285 std::string
ReportUndefCond::getMessage() const {
286 return ("Condition based on 'undef' value in BB: " + BB
->getName()).str();
289 bool ReportUndefCond::classof(const RejectReason
*RR
) {
290 return RR
->getKind() == RejectReasonKind::UndefCond
;
293 //===----------------------------------------------------------------------===//
294 // ReportInvalidCond.
296 std::string
ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
298 const Value
*ReportInvalidCond::getRemarkBB() const { return BB
; }
300 std::string
ReportInvalidCond::getMessage() const {
301 return ("Condition in BB '" + BB
->getName()).str() +
302 "' neither constant nor an icmp instruction";
305 bool ReportInvalidCond::classof(const RejectReason
*RR
) {
306 return RR
->getKind() == RejectReasonKind::InvalidCond
;
309 //===----------------------------------------------------------------------===//
310 // ReportUndefOperand.
312 std::string
ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
314 const Value
*ReportUndefOperand::getRemarkBB() const { return BB
; }
316 std::string
ReportUndefOperand::getMessage() const {
317 return ("undef operand in branch at BB: " + BB
->getName()).str();
320 bool ReportUndefOperand::classof(const RejectReason
*RR
) {
321 return RR
->getKind() == RejectReasonKind::UndefOperand
;
324 //===----------------------------------------------------------------------===//
325 // ReportNonAffBranch.
327 std::string
ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
329 const Value
*ReportNonAffBranch::getRemarkBB() const { return BB
; }
331 std::string
ReportNonAffBranch::getMessage() const {
332 return ("Non affine branch in BB '" + BB
->getName()).str() +
333 "' with LHS: " + *LHS
+ " and RHS: " + *RHS
;
336 bool ReportNonAffBranch::classof(const RejectReason
*RR
) {
337 return RR
->getKind() == RejectReasonKind::NonAffBranch
;
340 //===----------------------------------------------------------------------===//
343 std::string
ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
345 const Value
*ReportNoBasePtr::getRemarkBB() const { return Inst
->getParent(); }
347 std::string
ReportNoBasePtr::getMessage() const { return "No base pointer"; }
349 bool ReportNoBasePtr::classof(const RejectReason
*RR
) {
350 return RR
->getKind() == RejectReasonKind::NoBasePtr
;
353 //===----------------------------------------------------------------------===//
354 // ReportUndefBasePtr.
356 std::string
ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
358 const Value
*ReportUndefBasePtr::getRemarkBB() const {
359 return Inst
->getParent();
362 std::string
ReportUndefBasePtr::getMessage() const {
363 return "Undefined base pointer";
366 bool ReportUndefBasePtr::classof(const RejectReason
*RR
) {
367 return RR
->getKind() == RejectReasonKind::UndefBasePtr
;
370 //===----------------------------------------------------------------------===//
371 // ReportVariantBasePtr.
373 std::string
ReportVariantBasePtr::getRemarkName() const {
374 return "VariantBasePtr";
377 const Value
*ReportVariantBasePtr::getRemarkBB() const {
378 return Inst
->getParent();
381 std::string
ReportVariantBasePtr::getMessage() const {
382 return "Base address not invariant in current region:" + *BaseValue
;
385 std::string
ReportVariantBasePtr::getEndUserMessage() const {
386 return "The base address of this array is not invariant inside the loop";
389 bool ReportVariantBasePtr::classof(const RejectReason
*RR
) {
390 return RR
->getKind() == RejectReasonKind::VariantBasePtr
;
393 //===----------------------------------------------------------------------===//
394 // ReportDifferentArrayElementSize
396 std::string
ReportDifferentArrayElementSize::getRemarkName() const {
397 return "DifferentArrayElementSize";
400 const Value
*ReportDifferentArrayElementSize::getRemarkBB() const {
401 return Inst
->getParent();
404 std::string
ReportDifferentArrayElementSize::getMessage() const {
405 return "Access to one array through data types of different size";
408 bool ReportDifferentArrayElementSize::classof(const RejectReason
*RR
) {
409 return RR
->getKind() == RejectReasonKind::DifferentElementSize
;
412 std::string
ReportDifferentArrayElementSize::getEndUserMessage() const {
413 StringRef BaseName
= BaseValue
->getName();
414 std::string Name
= BaseName
.empty() ? "UNKNOWN" : BaseName
;
415 return "The array \"" + Name
+
416 "\" is accessed through elements that differ "
420 //===----------------------------------------------------------------------===//
421 // ReportNonAffineAccess.
423 std::string
ReportNonAffineAccess::getRemarkName() const {
424 return "NonAffineAccess";
427 const Value
*ReportNonAffineAccess::getRemarkBB() const {
428 return Inst
->getParent();
431 std::string
ReportNonAffineAccess::getMessage() const {
432 return "Non affine access function: " + *AccessFunction
;
435 bool ReportNonAffineAccess::classof(const RejectReason
*RR
) {
436 return RR
->getKind() == RejectReasonKind::NonAffineAccess
;
439 std::string
ReportNonAffineAccess::getEndUserMessage() const {
440 StringRef BaseName
= BaseValue
->getName();
441 std::string Name
= BaseName
.empty() ? "UNKNOWN" : BaseName
;
442 return "The array subscript of \"" + Name
+ "\" is not affine";
445 //===----------------------------------------------------------------------===//
448 ReportLoopBound::ReportLoopBound(Loop
*L
, const SCEV
*LoopCount
)
449 : RejectReason(RejectReasonKind::LoopBound
), L(L
), LoopCount(LoopCount
),
450 Loc(L
->getStartLoc()) {}
452 std::string
ReportLoopBound::getRemarkName() const { return "LoopBound"; }
454 const Value
*ReportLoopBound::getRemarkBB() const { return L
->getHeader(); }
456 std::string
ReportLoopBound::getMessage() const {
457 return "Non affine loop bound '" + *LoopCount
+
458 "' in loop: " + L
->getHeader()->getName();
461 const DebugLoc
&ReportLoopBound::getDebugLoc() const { return Loc
; }
463 bool ReportLoopBound::classof(const RejectReason
*RR
) {
464 return RR
->getKind() == RejectReasonKind::LoopBound
;
467 std::string
ReportLoopBound::getEndUserMessage() const {
468 return "Failed to derive an affine function from the loop bounds.";
471 //===----------------------------------------------------------------------===//
472 // ReportLoopHasNoExit.
474 std::string
ReportLoopHasNoExit::getRemarkName() const {
475 return "LoopHasNoExit";
478 const Value
*ReportLoopHasNoExit::getRemarkBB() const { return L
->getHeader(); }
480 std::string
ReportLoopHasNoExit::getMessage() const {
481 return "Loop " + L
->getHeader()->getName() + " has no exit.";
484 bool ReportLoopHasNoExit::classof(const RejectReason
*RR
) {
485 return RR
->getKind() == RejectReasonKind::LoopHasNoExit
;
488 const DebugLoc
&ReportLoopHasNoExit::getDebugLoc() const { return Loc
; }
490 std::string
ReportLoopHasNoExit::getEndUserMessage() const {
491 return "Loop cannot be handled because it has no exit.";
494 //===----------------------------------------------------------------------===//
495 // ReportLoopHasMultipleExits.
497 std::string
ReportLoopHasMultipleExits::getRemarkName() const {
498 return "ReportLoopHasMultipleExits";
501 const Value
*ReportLoopHasMultipleExits::getRemarkBB() const {
502 return L
->getHeader();
505 std::string
ReportLoopHasMultipleExits::getMessage() const {
506 return "Loop " + L
->getHeader()->getName() + " has multiple exits.";
509 bool ReportLoopHasMultipleExits::classof(const RejectReason
*RR
) {
510 return RR
->getKind() == RejectReasonKind::LoopHasMultipleExits
;
513 const DebugLoc
&ReportLoopHasMultipleExits::getDebugLoc() const { return Loc
; }
515 std::string
ReportLoopHasMultipleExits::getEndUserMessage() const {
516 return "Loop cannot be handled because it has multiple exits.";
519 //===----------------------------------------------------------------------===//
520 // ReportLoopOnlySomeLatches
522 std::string
ReportLoopOnlySomeLatches::getRemarkName() const {
523 return "LoopHasNoExit";
526 const Value
*ReportLoopOnlySomeLatches::getRemarkBB() const {
527 return L
->getHeader();
530 std::string
ReportLoopOnlySomeLatches::getMessage() const {
531 return "Not all latches of loop " + L
->getHeader()->getName() +
535 bool ReportLoopOnlySomeLatches::classof(const RejectReason
*RR
) {
536 return RR
->getKind() == RejectReasonKind::LoopHasNoExit
;
539 const DebugLoc
&ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc
; }
541 std::string
ReportLoopOnlySomeLatches::getEndUserMessage() const {
542 return "Loop cannot be handled because not all latches are part of loop "
546 //===----------------------------------------------------------------------===//
549 ReportFuncCall::ReportFuncCall(Instruction
*Inst
)
550 : RejectReason(RejectReasonKind::FuncCall
), Inst(Inst
) {}
552 std::string
ReportFuncCall::getRemarkName() const { return "FuncCall"; }
554 const Value
*ReportFuncCall::getRemarkBB() const { return Inst
->getParent(); }
556 std::string
ReportFuncCall::getMessage() const {
557 return "Call instruction: " + *Inst
;
560 const DebugLoc
&ReportFuncCall::getDebugLoc() const {
561 return Inst
->getDebugLoc();
564 std::string
ReportFuncCall::getEndUserMessage() const {
565 return "This function call cannot be handled. "
569 bool ReportFuncCall::classof(const RejectReason
*RR
) {
570 return RR
->getKind() == RejectReasonKind::FuncCall
;
573 //===----------------------------------------------------------------------===//
574 // ReportNonSimpleMemoryAccess
576 ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction
*Inst
)
577 : ReportOther(RejectReasonKind::NonSimpleMemoryAccess
), Inst(Inst
) {}
579 std::string
ReportNonSimpleMemoryAccess::getRemarkName() const {
580 return "NonSimpleMemoryAccess";
583 const Value
*ReportNonSimpleMemoryAccess::getRemarkBB() const {
584 return Inst
->getParent();
587 std::string
ReportNonSimpleMemoryAccess::getMessage() const {
588 return "Non-simple memory access: " + *Inst
;
591 const DebugLoc
&ReportNonSimpleMemoryAccess::getDebugLoc() const {
592 return Inst
->getDebugLoc();
595 std::string
ReportNonSimpleMemoryAccess::getEndUserMessage() const {
596 return "Volatile memory accesses or memory accesses for atomic types "
597 "are not supported.";
600 bool ReportNonSimpleMemoryAccess::classof(const RejectReason
*RR
) {
601 return RR
->getKind() == RejectReasonKind::NonSimpleMemoryAccess
;
604 //===----------------------------------------------------------------------===//
607 ReportAlias::ReportAlias(Instruction
*Inst
, AliasSet
&AS
)
608 : RejectReason(RejectReasonKind::Alias
), Inst(Inst
) {
609 for (const auto &I
: AS
)
610 Pointers
.push_back(I
.getValue());
613 std::string
ReportAlias::formatInvalidAlias(std::string Prefix
,
614 std::string Suffix
) const {
616 raw_string_ostream
OS(Message
);
620 for (PointerSnapshotTy::const_iterator PI
= Pointers
.begin(),
623 const Value
*V
= *PI
;
624 assert(V
&& "Diagnostic info does not match found LLVM-IR anymore.");
626 if (V
->getName().empty())
627 OS
<< "\" <unknown> \"";
629 OS
<< "\"" << V
->getName() << "\"";
644 std::string
ReportAlias::getRemarkName() const { return "Alias"; }
646 const Value
*ReportAlias::getRemarkBB() const { return Inst
->getParent(); }
648 std::string
ReportAlias::getMessage() const {
649 return formatInvalidAlias("Possible aliasing: ");
652 std::string
ReportAlias::getEndUserMessage() const {
653 return formatInvalidAlias("Accesses to the arrays ",
654 " may access the same memory.");
657 const DebugLoc
&ReportAlias::getDebugLoc() const { return Inst
->getDebugLoc(); }
659 bool ReportAlias::classof(const RejectReason
*RR
) {
660 return RR
->getKind() == RejectReasonKind::Alias
;
663 //===----------------------------------------------------------------------===//
666 std::string
ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
668 std::string
ReportOther::getMessage() const { return "Unknown reject reason"; }
670 ReportOther::ReportOther(const RejectReasonKind K
) : RejectReason(K
) {}
672 bool ReportOther::classof(const RejectReason
*RR
) {
673 return RR
->getKind() >= RejectReasonKind::Other
&&
674 RR
->getKind() <= RejectReasonKind::LastOther
;
677 //===----------------------------------------------------------------------===//
679 ReportIntToPtr::ReportIntToPtr(Instruction
*BaseValue
)
680 : ReportOther(RejectReasonKind::IntToPtr
), BaseValue(BaseValue
) {}
682 std::string
ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
684 const Value
*ReportIntToPtr::getRemarkBB() const {
685 return BaseValue
->getParent();
688 std::string
ReportIntToPtr::getMessage() const {
689 return "Find bad intToptr prt: " + *BaseValue
;
692 const DebugLoc
&ReportIntToPtr::getDebugLoc() const {
693 return BaseValue
->getDebugLoc();
696 bool ReportIntToPtr::classof(const RejectReason
*RR
) {
697 return RR
->getKind() == RejectReasonKind::IntToPtr
;
700 //===----------------------------------------------------------------------===//
703 ReportAlloca::ReportAlloca(Instruction
*Inst
)
704 : ReportOther(RejectReasonKind::Alloca
), Inst(Inst
) {}
706 std::string
ReportAlloca::getRemarkName() const { return "Alloca"; }
708 const Value
*ReportAlloca::getRemarkBB() const { return Inst
->getParent(); }
710 std::string
ReportAlloca::getMessage() const {
711 return "Alloca instruction: " + *Inst
;
714 const DebugLoc
&ReportAlloca::getDebugLoc() const {
715 return Inst
->getDebugLoc();
718 bool ReportAlloca::classof(const RejectReason
*RR
) {
719 return RR
->getKind() == RejectReasonKind::Alloca
;
722 //===----------------------------------------------------------------------===//
723 // ReportUnknownInst.
725 ReportUnknownInst::ReportUnknownInst(Instruction
*Inst
)
726 : ReportOther(RejectReasonKind::UnknownInst
), Inst(Inst
) {}
728 std::string
ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
730 const Value
*ReportUnknownInst::getRemarkBB() const {
731 return Inst
->getParent();
734 std::string
ReportUnknownInst::getMessage() const {
735 return "Unknown instruction: " + *Inst
;
738 const DebugLoc
&ReportUnknownInst::getDebugLoc() const {
739 return Inst
->getDebugLoc();
742 bool ReportUnknownInst::classof(const RejectReason
*RR
) {
743 return RR
->getKind() == RejectReasonKind::UnknownInst
;
746 //===----------------------------------------------------------------------===//
749 ReportEntry::ReportEntry(BasicBlock
*BB
)
750 : ReportOther(RejectReasonKind::Entry
), BB(BB
) {}
752 std::string
ReportEntry::getRemarkName() const { return "Entry"; }
754 const Value
*ReportEntry::getRemarkBB() const { return BB
; }
756 std::string
ReportEntry::getMessage() const {
757 return "Region containing entry block of function is invalid!";
760 std::string
ReportEntry::getEndUserMessage() const {
761 return "Scop contains function entry (not yet supported).";
764 const DebugLoc
&ReportEntry::getDebugLoc() const {
765 return BB
->getTerminator()->getDebugLoc();
768 bool ReportEntry::classof(const RejectReason
*RR
) {
769 return RR
->getKind() == RejectReasonKind::Entry
;
772 //===----------------------------------------------------------------------===//
773 // ReportUnprofitable.
775 ReportUnprofitable::ReportUnprofitable(Region
*R
)
776 : ReportOther(RejectReasonKind::Unprofitable
), R(R
) {}
778 std::string
ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
780 const Value
*ReportUnprofitable::getRemarkBB() const { return R
->getEntry(); }
782 std::string
ReportUnprofitable::getMessage() const {
783 return "Region can not profitably be optimized!";
786 std::string
ReportUnprofitable::getEndUserMessage() const {
787 return "No profitable polyhedral optimization found";
790 const DebugLoc
&ReportUnprofitable::getDebugLoc() const {
791 for (const BasicBlock
*BB
: R
->blocks())
792 for (const Instruction
&Inst
: *BB
)
793 if (const DebugLoc
&DL
= Inst
.getDebugLoc())
796 return R
->getEntry()->getTerminator()->getDebugLoc();
799 bool ReportUnprofitable::classof(const RejectReason
*RR
) {
800 return RR
->getKind() == RejectReasonKind::Unprofitable
;