Rename OptimizationDiagnosticInfo.h to OptimizationRemarkEmitter.h
[polly-mirror.git] / lib / Analysis / ScopDetectionDiagnostic.cpp
blob7135262fd8def8353925278bdb93c27fcad81be5
1 //===- ScopDetectionDiagnostic.cpp - Error diagnostics --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Small set of diagnostic helper classes to encapsulate any errors occurred
11 // during the detection of Scops.
13 // The ScopDetection defines a set of error classes (via Statistic variables)
14 // that groups a number of individual errors into a group, e.g. non-affinity
15 // related errors.
16 // On error we generate an object that carries enough additional information
17 // to diagnose the error and generate a helpful error message.
19 //===----------------------------------------------------------------------===//
21 #include "polly/ScopDetectionDiagnostic.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/Twine.h"
27 #include "llvm/Analysis/AliasSetTracker.h"
28 #include "llvm/Analysis/LoopInfo.h"
29 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
30 #include "llvm/Analysis/RegionInfo.h"
31 #include "llvm/Analysis/ScalarEvolution.h"
32 #include "llvm/IR/BasicBlock.h"
33 #include "llvm/IR/CFG.h"
34 #include "llvm/IR/DebugLoc.h"
35 #include "llvm/IR/DiagnosticInfo.h"
36 #include "llvm/IR/Instruction.h"
37 #include "llvm/IR/Value.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <algorithm>
40 #include <cassert>
41 #include <string>
42 #include <utility>
44 using namespace llvm;
46 #define DEBUG_TYPE "polly-detect"
48 #define SCOP_STAT(NAME, DESC) \
49 { "polly-detect", "NAME", "Number of rejected regions: " DESC, {0}, false }
51 Statistic RejectStatistics[] = {
52 SCOP_STAT(CFG, ""),
53 SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
54 SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
55 SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
56 SCOP_STAT(LastCFG, ""),
57 SCOP_STAT(AffFunc, ""),
58 SCOP_STAT(UndefCond, "Undefined branch condition"),
59 SCOP_STAT(InvalidCond, "Non-integer branch condition"),
60 SCOP_STAT(UndefOperand, "Undefined operands in comparison"),
61 SCOP_STAT(NonAffBranch, "Non-affine branch condition"),
62 SCOP_STAT(NoBasePtr, "No base pointer"),
63 SCOP_STAT(UndefBasePtr, "Undefined base pointer"),
64 SCOP_STAT(VariantBasePtr, "Variant base pointer"),
65 SCOP_STAT(NonAffineAccess, "Non-affine memory accesses"),
66 SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"),
67 SCOP_STAT(LastAffFunc, ""),
68 SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
69 SCOP_STAT(LoopHasNoExit, "Loop without exit"),
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"),
75 SCOP_STAT(Other, ""),
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, ""),
84 namespace polly {
86 /// Small string conversion via raw_string_stream.
87 template <typename T> std::string operator+(Twine LHS, const T &RHS) {
88 std::string Buf;
89 raw_string_ostream fmt(Buf);
90 fmt << RHS;
91 fmt.flush();
93 return LHS.concat(Buf).str();
96 } // namespace polly
98 namespace llvm {
100 // Lexicographic order on (line, col) of our debug locations.
101 static bool operator<(const DebugLoc &LHS, const DebugLoc &RHS) {
102 return LHS.getLine() < RHS.getLine() ||
103 (LHS.getLine() == RHS.getLine() && LHS.getCol() < RHS.getCol());
106 } // namespace llvm
108 namespace polly {
110 BBPair getBBPairForRegion(const Region *R) {
111 return std::make_pair(R->getEntry(), R->getExit());
114 void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
115 SmallPtrSet<BasicBlock *, 32> Seen;
116 SmallVector<BasicBlock *, 32> Todo;
117 Todo.push_back(P.first);
118 while (!Todo.empty()) {
119 auto *BB = Todo.pop_back_val();
120 if (BB == P.second)
121 continue;
122 if (!Seen.insert(BB).second)
123 continue;
124 Todo.append(succ_begin(BB), succ_end(BB));
125 for (const Instruction &Inst : *BB) {
126 DebugLoc DL = Inst.getDebugLoc();
127 if (!DL)
128 continue;
130 Begin = Begin ? std::min(Begin, DL) : DL;
131 End = End ? std::max(End, DL) : DL;
136 void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
137 OptimizationRemarkEmitter &ORE) {
138 DebugLoc Begin, End;
139 getDebugLocations(P, Begin, End);
141 ORE.emit(
142 OptimizationRemarkMissed(DEBUG_TYPE, "RejectionErrors", Begin, P.first)
143 << "The following errors keep this region from being a Scop.");
145 for (RejectReasonPtr RR : Log) {
147 if (const DebugLoc &Loc = RR->getDebugLoc())
148 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Loc,
149 RR->getRemarkBB())
150 << RR->getEndUserMessage());
151 else
152 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
153 RR->getRemarkBB())
154 << RR->getEndUserMessage());
157 /* Check to see if Region is a top level region, getExit = NULL*/
158 if (P.second)
159 ORE.emit(
160 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
161 << "Invalid Scop candidate ends here.");
162 else
163 ORE.emit(
164 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
165 << "Invalid Scop candidate ends here.");
168 //===----------------------------------------------------------------------===//
169 // RejectReason.
171 RejectReason::RejectReason(RejectReasonKind K) : Kind(K) {
172 RejectStatistics[static_cast<int>(K)]++;
175 const DebugLoc RejectReason::Unknown = DebugLoc();
177 const DebugLoc &RejectReason::getDebugLoc() const {
178 // Allocate an empty DebugLoc and return it a reference to it.
179 return Unknown;
182 // RejectLog.
183 void RejectLog::print(raw_ostream &OS, int level) const {
184 int j = 0;
185 for (auto Reason : ErrorReports)
186 OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
189 //===----------------------------------------------------------------------===//
190 // ReportCFG.
192 ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {}
194 bool ReportCFG::classof(const RejectReason *RR) {
195 return RR->getKind() >= RejectReasonKind::CFG &&
196 RR->getKind() <= RejectReasonKind::LastCFG;
199 //===----------------------------------------------------------------------===//
200 // ReportInvalidTerminator.
202 std::string ReportInvalidTerminator::getRemarkName() const {
203 return "InvalidTerminator";
206 const Value *ReportInvalidTerminator::getRemarkBB() const { return BB; }
208 std::string ReportInvalidTerminator::getMessage() const {
209 return ("Invalid instruction terminates BB: " + BB->getName()).str();
212 const DebugLoc &ReportInvalidTerminator::getDebugLoc() const {
213 return BB->getTerminator()->getDebugLoc();
216 bool ReportInvalidTerminator::classof(const RejectReason *RR) {
217 return RR->getKind() == RejectReasonKind::InvalidTerminator;
220 //===----------------------------------------------------------------------===//
221 // UnreachableInExit.
223 std::string ReportUnreachableInExit::getRemarkName() const {
224 return "UnreachableInExit";
227 const Value *ReportUnreachableInExit::getRemarkBB() const { return BB; }
229 std::string ReportUnreachableInExit::getMessage() const {
230 std::string BBName = BB->getName();
231 return "Unreachable in exit block" + BBName;
234 const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; }
236 std::string ReportUnreachableInExit::getEndUserMessage() const {
237 return "Unreachable in exit block.";
240 bool ReportUnreachableInExit::classof(const RejectReason *RR) {
241 return RR->getKind() == RejectReasonKind::UnreachableInExit;
244 //===----------------------------------------------------------------------===//
245 // ReportIrreducibleRegion.
247 std::string ReportIrreducibleRegion::getRemarkName() const {
248 return "IrreducibleRegion";
251 const Value *ReportIrreducibleRegion::getRemarkBB() const {
252 return R->getEntry();
255 std::string ReportIrreducibleRegion::getMessage() const {
256 return "Irreducible region encountered: " + R->getNameStr();
259 const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
261 std::string ReportIrreducibleRegion::getEndUserMessage() const {
262 return "Irreducible region encountered in control flow.";
265 bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
266 return RR->getKind() == RejectReasonKind::IrreducibleRegion;
269 //===----------------------------------------------------------------------===//
270 // ReportAffFunc.
272 ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
273 : RejectReason(K), Inst(Inst) {}
275 bool ReportAffFunc::classof(const RejectReason *RR) {
276 return RR->getKind() >= RejectReasonKind::AffFunc &&
277 RR->getKind() <= RejectReasonKind::LastAffFunc;
280 //===----------------------------------------------------------------------===//
281 // ReportUndefCond.
283 std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
285 const Value *ReportUndefCond::getRemarkBB() const { return BB; }
287 std::string ReportUndefCond::getMessage() const {
288 return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
291 bool ReportUndefCond::classof(const RejectReason *RR) {
292 return RR->getKind() == RejectReasonKind::UndefCond;
295 //===----------------------------------------------------------------------===//
296 // ReportInvalidCond.
298 std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
300 const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
302 std::string ReportInvalidCond::getMessage() const {
303 return ("Condition in BB '" + BB->getName()).str() +
304 "' neither constant nor an icmp instruction";
307 bool ReportInvalidCond::classof(const RejectReason *RR) {
308 return RR->getKind() == RejectReasonKind::InvalidCond;
311 //===----------------------------------------------------------------------===//
312 // ReportUndefOperand.
314 std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
316 const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
318 std::string ReportUndefOperand::getMessage() const {
319 return ("undef operand in branch at BB: " + BB->getName()).str();
322 bool ReportUndefOperand::classof(const RejectReason *RR) {
323 return RR->getKind() == RejectReasonKind::UndefOperand;
326 //===----------------------------------------------------------------------===//
327 // ReportNonAffBranch.
329 std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
331 const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
333 std::string ReportNonAffBranch::getMessage() const {
334 return ("Non affine branch in BB '" + BB->getName()).str() +
335 "' with LHS: " + *LHS + " and RHS: " + *RHS;
338 bool ReportNonAffBranch::classof(const RejectReason *RR) {
339 return RR->getKind() == RejectReasonKind::NonAffBranch;
342 //===----------------------------------------------------------------------===//
343 // ReportNoBasePtr.
345 std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
347 const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
349 std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
351 bool ReportNoBasePtr::classof(const RejectReason *RR) {
352 return RR->getKind() == RejectReasonKind::NoBasePtr;
355 //===----------------------------------------------------------------------===//
356 // ReportUndefBasePtr.
358 std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
360 const Value *ReportUndefBasePtr::getRemarkBB() const {
361 return Inst->getParent();
364 std::string ReportUndefBasePtr::getMessage() const {
365 return "Undefined base pointer";
368 bool ReportUndefBasePtr::classof(const RejectReason *RR) {
369 return RR->getKind() == RejectReasonKind::UndefBasePtr;
372 //===----------------------------------------------------------------------===//
373 // ReportVariantBasePtr.
375 std::string ReportVariantBasePtr::getRemarkName() const {
376 return "VariantBasePtr";
379 const Value *ReportVariantBasePtr::getRemarkBB() const {
380 return Inst->getParent();
383 std::string ReportVariantBasePtr::getMessage() const {
384 return "Base address not invariant in current region:" + *BaseValue;
387 std::string ReportVariantBasePtr::getEndUserMessage() const {
388 return "The base address of this array is not invariant inside the loop";
391 bool ReportVariantBasePtr::classof(const RejectReason *RR) {
392 return RR->getKind() == RejectReasonKind::VariantBasePtr;
395 //===----------------------------------------------------------------------===//
396 // ReportDifferentArrayElementSize
398 std::string ReportDifferentArrayElementSize::getRemarkName() const {
399 return "DifferentArrayElementSize";
402 const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
403 return Inst->getParent();
406 std::string ReportDifferentArrayElementSize::getMessage() const {
407 return "Access to one array through data types of different size";
410 bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
411 return RR->getKind() == RejectReasonKind::DifferentElementSize;
414 std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
415 StringRef BaseName = BaseValue->getName();
416 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName;
417 return "The array \"" + Name +
418 "\" is accessed through elements that differ "
419 "in size";
422 //===----------------------------------------------------------------------===//
423 // ReportNonAffineAccess.
425 std::string ReportNonAffineAccess::getRemarkName() const {
426 return "NonAffineAccess";
429 const Value *ReportNonAffineAccess::getRemarkBB() const {
430 return Inst->getParent();
433 std::string ReportNonAffineAccess::getMessage() const {
434 return "Non affine access function: " + *AccessFunction;
437 bool ReportNonAffineAccess::classof(const RejectReason *RR) {
438 return RR->getKind() == RejectReasonKind::NonAffineAccess;
441 std::string ReportNonAffineAccess::getEndUserMessage() const {
442 StringRef BaseName = BaseValue->getName();
443 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName;
444 return "The array subscript of \"" + Name + "\" is not affine";
447 //===----------------------------------------------------------------------===//
448 // ReportLoopBound.
450 ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
451 : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
452 Loc(L->getStartLoc()) {}
454 std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
456 const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
458 std::string ReportLoopBound::getMessage() const {
459 return "Non affine loop bound '" + *LoopCount +
460 "' in loop: " + L->getHeader()->getName();
463 const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
465 bool ReportLoopBound::classof(const RejectReason *RR) {
466 return RR->getKind() == RejectReasonKind::LoopBound;
469 std::string ReportLoopBound::getEndUserMessage() const {
470 return "Failed to derive an affine function from the loop bounds.";
473 //===----------------------------------------------------------------------===//
474 // ReportLoopHasNoExit.
476 std::string ReportLoopHasNoExit::getRemarkName() const {
477 return "LoopHasNoExit";
480 const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
482 std::string ReportLoopHasNoExit::getMessage() const {
483 return "Loop " + L->getHeader()->getName() + " has no exit.";
486 bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
487 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
490 const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
492 std::string ReportLoopHasNoExit::getEndUserMessage() const {
493 return "Loop cannot be handled because it has no exit.";
496 //===----------------------------------------------------------------------===//
497 // ReportLoopOnlySomeLatches
499 std::string ReportLoopOnlySomeLatches::getRemarkName() const {
500 return "LoopHasNoExit";
503 const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
504 return L->getHeader();
507 std::string ReportLoopOnlySomeLatches::getMessage() const {
508 return "Not all latches of loop " + L->getHeader()->getName() +
509 " part of scop.";
512 bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
513 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
516 const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
518 std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
519 return "Loop cannot be handled because not all latches are part of loop "
520 "region.";
523 //===----------------------------------------------------------------------===//
524 // ReportFuncCall.
526 ReportFuncCall::ReportFuncCall(Instruction *Inst)
527 : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
529 std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
531 const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
533 std::string ReportFuncCall::getMessage() const {
534 return "Call instruction: " + *Inst;
537 const DebugLoc &ReportFuncCall::getDebugLoc() const {
538 return Inst->getDebugLoc();
541 std::string ReportFuncCall::getEndUserMessage() const {
542 return "This function call cannot be handled. "
543 "Try to inline it.";
546 bool ReportFuncCall::classof(const RejectReason *RR) {
547 return RR->getKind() == RejectReasonKind::FuncCall;
550 //===----------------------------------------------------------------------===//
551 // ReportNonSimpleMemoryAccess
553 ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
554 : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
556 std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
557 return "NonSimpleMemoryAccess";
560 const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
561 return Inst->getParent();
564 std::string ReportNonSimpleMemoryAccess::getMessage() const {
565 return "Non-simple memory access: " + *Inst;
568 const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
569 return Inst->getDebugLoc();
572 std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
573 return "Volatile memory accesses or memory accesses for atomic types "
574 "are not supported.";
577 bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
578 return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
581 //===----------------------------------------------------------------------===//
582 // ReportAlias.
584 ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
585 : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
586 for (const auto &I : AS)
587 Pointers.push_back(I.getValue());
590 std::string ReportAlias::formatInvalidAlias(std::string Prefix,
591 std::string Suffix) const {
592 std::string Message;
593 raw_string_ostream OS(Message);
595 OS << Prefix;
597 for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
598 PE = Pointers.end();
599 ;) {
600 const Value *V = *PI;
601 assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
603 if (V->getName().empty())
604 OS << "\" <unknown> \"";
605 else
606 OS << "\"" << V->getName() << "\"";
608 ++PI;
610 if (PI != PE)
611 OS << ", ";
612 else
613 break;
616 OS << Suffix;
618 return OS.str();
621 std::string ReportAlias::getRemarkName() const { return "Alias"; }
623 const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
625 std::string ReportAlias::getMessage() const {
626 return formatInvalidAlias("Possible aliasing: ");
629 std::string ReportAlias::getEndUserMessage() const {
630 return formatInvalidAlias("Accesses to the arrays ",
631 " may access the same memory.");
634 const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
636 bool ReportAlias::classof(const RejectReason *RR) {
637 return RR->getKind() == RejectReasonKind::Alias;
640 //===----------------------------------------------------------------------===//
641 // ReportOther.
643 std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
645 std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
647 ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
649 bool ReportOther::classof(const RejectReason *RR) {
650 return RR->getKind() >= RejectReasonKind::Other &&
651 RR->getKind() <= RejectReasonKind::LastOther;
654 //===----------------------------------------------------------------------===//
655 // ReportIntToPtr.
656 ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
657 : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
659 std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
661 const Value *ReportIntToPtr::getRemarkBB() const {
662 return BaseValue->getParent();
665 std::string ReportIntToPtr::getMessage() const {
666 return "Find bad intToptr prt: " + *BaseValue;
669 const DebugLoc &ReportIntToPtr::getDebugLoc() const {
670 return BaseValue->getDebugLoc();
673 bool ReportIntToPtr::classof(const RejectReason *RR) {
674 return RR->getKind() == RejectReasonKind::IntToPtr;
677 //===----------------------------------------------------------------------===//
678 // ReportAlloca.
680 ReportAlloca::ReportAlloca(Instruction *Inst)
681 : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
683 std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
685 const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
687 std::string ReportAlloca::getMessage() const {
688 return "Alloca instruction: " + *Inst;
691 const DebugLoc &ReportAlloca::getDebugLoc() const {
692 return Inst->getDebugLoc();
695 bool ReportAlloca::classof(const RejectReason *RR) {
696 return RR->getKind() == RejectReasonKind::Alloca;
699 //===----------------------------------------------------------------------===//
700 // ReportUnknownInst.
702 ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
703 : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
705 std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
707 const Value *ReportUnknownInst::getRemarkBB() const {
708 return Inst->getParent();
711 std::string ReportUnknownInst::getMessage() const {
712 return "Unknown instruction: " + *Inst;
715 const DebugLoc &ReportUnknownInst::getDebugLoc() const {
716 return Inst->getDebugLoc();
719 bool ReportUnknownInst::classof(const RejectReason *RR) {
720 return RR->getKind() == RejectReasonKind::UnknownInst;
723 //===----------------------------------------------------------------------===//
724 // ReportEntry.
726 ReportEntry::ReportEntry(BasicBlock *BB)
727 : ReportOther(RejectReasonKind::Entry), BB(BB) {}
729 std::string ReportEntry::getRemarkName() const { return "Entry"; }
731 const Value *ReportEntry::getRemarkBB() const { return BB; }
733 std::string ReportEntry::getMessage() const {
734 return "Region containing entry block of function is invalid!";
737 std::string ReportEntry::getEndUserMessage() const {
738 return "Scop contains function entry (not yet supported).";
741 const DebugLoc &ReportEntry::getDebugLoc() const {
742 return BB->getTerminator()->getDebugLoc();
745 bool ReportEntry::classof(const RejectReason *RR) {
746 return RR->getKind() == RejectReasonKind::Entry;
749 //===----------------------------------------------------------------------===//
750 // ReportUnprofitable.
752 ReportUnprofitable::ReportUnprofitable(Region *R)
753 : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
755 std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
757 const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
759 std::string ReportUnprofitable::getMessage() const {
760 return "Region can not profitably be optimized!";
763 std::string ReportUnprofitable::getEndUserMessage() const {
764 return "No profitable polyhedral optimization found";
767 const DebugLoc &ReportUnprofitable::getDebugLoc() const {
768 for (const BasicBlock *BB : R->blocks())
769 for (const Instruction &Inst : *BB)
770 if (const DebugLoc &DL = Inst.getDebugLoc())
771 return DL;
773 return R->getEntry()->getTerminator()->getDebugLoc();
776 bool ReportUnprofitable::classof(const RejectReason *RR) {
777 return RR->getKind() == RejectReasonKind::Unprofitable;
780 } // namespace polly