[clangd] Fix erroneous qualification of template type parameters (#116821)
[llvm-project.git] / polly / lib / Analysis / ScopDetectionDiagnostic.cpp
blob14a6f074454f767b32a7ffa26a8cd150942a7483
1 //===- ScopDetectionDiagnostic.cpp - Error diagnostics --------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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
14 // related errors.
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"
38 #include <algorithm>
39 #include <cassert>
40 #include <string>
41 #include <utility>
43 using namespace llvm;
45 #define DEBUG_TYPE "polly-detect"
47 #define SCOP_STAT(NAME, DESC) \
48 {"polly-detect", "NAME", "Number of rejected regions: " DESC}
50 static Statistic RejectStatistics[] = {
51 SCOP_STAT(CFG, ""),
52 SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
53 SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
54 SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
55 SCOP_STAT(IndirectPredecessor, "Branch from indirect terminator"),
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(LoopHasMultipleExits, "Loop with multiple exits"),
71 SCOP_STAT(LoopOnlySomeLatches, "Not all loop latches in scop"),
72 SCOP_STAT(FuncCall, "Function call with side effects"),
73 SCOP_STAT(NonSimpleMemoryAccess,
74 "Compilated access semantics (volatile or atomic)"),
75 SCOP_STAT(Alias, "Base address aliasing"),
76 SCOP_STAT(Other, ""),
77 SCOP_STAT(IntToPtr, "Integer to pointer conversions"),
78 SCOP_STAT(Alloca, "Stack allocations"),
79 SCOP_STAT(UnknownInst, "Unknown Instructions"),
80 SCOP_STAT(Entry, "Contains entry block"),
81 SCOP_STAT(Unprofitable, "Assumed to be unprofitable"),
82 SCOP_STAT(LastOther, ""),
85 namespace polly {
87 /// Small string conversion via raw_string_stream.
88 template <typename T> std::string operator+(Twine LHS, const T &RHS) {
89 std::string Buf;
90 raw_string_ostream fmt(Buf);
91 fmt << RHS;
93 return LHS.concat(Buf).str();
95 } // namespace polly
97 namespace llvm {
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());
104 } // namespace llvm
106 namespace polly {
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();
118 if (BB == P.second)
119 continue;
120 if (!Seen.insert(BB).second)
121 continue;
122 Todo.append(succ_begin(BB), succ_end(BB));
123 for (const Instruction &Inst : *BB) {
124 DebugLoc DL = Inst.getStableDebugLoc();
125 if (!DL)
126 continue;
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) {
136 DebugLoc Begin, End;
137 getDebugLocations(P, Begin, End);
139 ORE.emit(
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,
147 RR->getRemarkBB())
148 << RR->getEndUserMessage());
149 else
150 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
151 RR->getRemarkBB())
152 << RR->getEndUserMessage());
155 /* Check to see if Region is a top level region, getExit = NULL*/
156 if (P.second)
157 ORE.emit(
158 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
159 << "Invalid Scop candidate ends here.");
160 else
161 ORE.emit(
162 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
163 << "Invalid Scop candidate ends here.");
166 //===----------------------------------------------------------------------===//
167 // RejectReason.
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.
177 return Unknown;
180 // RejectLog.
181 void RejectLog::print(raw_ostream &OS, int level) const {
182 int j = 0;
183 for (auto Reason : ErrorReports)
184 OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
187 //===----------------------------------------------------------------------===//
188 // ReportCFG.
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().str();
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 // IndirectPredecessor.
245 std::string ReportIndirectPredecessor::getRemarkName() const {
246 return "IndirectPredecessor";
249 const Value *ReportIndirectPredecessor::getRemarkBB() const {
250 if (Inst)
251 return Inst->getParent();
252 return nullptr;
255 std::string ReportIndirectPredecessor::getMessage() const {
256 if (Inst)
257 return "Branch from indirect terminator: " + *Inst;
258 return getEndUserMessage();
261 const DebugLoc &ReportIndirectPredecessor::getDebugLoc() const {
262 return DbgLoc;
265 std::string ReportIndirectPredecessor::getEndUserMessage() const {
266 return "Branch from indirect terminator.";
269 bool ReportIndirectPredecessor::classof(const RejectReason *RR) {
270 return RR->getKind() == RejectReasonKind::IndirectPredecessor;
273 //===----------------------------------------------------------------------===//
274 // ReportIrreducibleRegion.
276 std::string ReportIrreducibleRegion::getRemarkName() const {
277 return "IrreducibleRegion";
280 const Value *ReportIrreducibleRegion::getRemarkBB() const {
281 return R->getEntry();
284 std::string ReportIrreducibleRegion::getMessage() const {
285 return "Irreducible region encountered: " + R->getNameStr();
288 const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
290 std::string ReportIrreducibleRegion::getEndUserMessage() const {
291 return "Irreducible region encountered in control flow.";
294 bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
295 return RR->getKind() == RejectReasonKind::IrreducibleRegion;
298 //===----------------------------------------------------------------------===//
299 // ReportAffFunc.
301 ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
302 : RejectReason(K), Inst(Inst) {}
304 bool ReportAffFunc::classof(const RejectReason *RR) {
305 return RR->getKind() >= RejectReasonKind::AffFunc &&
306 RR->getKind() <= RejectReasonKind::LastAffFunc;
309 //===----------------------------------------------------------------------===//
310 // ReportUndefCond.
312 std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
314 const Value *ReportUndefCond::getRemarkBB() const { return BB; }
316 std::string ReportUndefCond::getMessage() const {
317 return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
320 bool ReportUndefCond::classof(const RejectReason *RR) {
321 return RR->getKind() == RejectReasonKind::UndefCond;
324 //===----------------------------------------------------------------------===//
325 // ReportInvalidCond.
327 std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
329 const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
331 std::string ReportInvalidCond::getMessage() const {
332 return ("Condition in BB '" + BB->getName()).str() +
333 "' neither constant nor an icmp instruction";
336 bool ReportInvalidCond::classof(const RejectReason *RR) {
337 return RR->getKind() == RejectReasonKind::InvalidCond;
340 //===----------------------------------------------------------------------===//
341 // ReportUndefOperand.
343 std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
345 const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
347 std::string ReportUndefOperand::getMessage() const {
348 return ("undef operand in branch at BB: " + BB->getName()).str();
351 bool ReportUndefOperand::classof(const RejectReason *RR) {
352 return RR->getKind() == RejectReasonKind::UndefOperand;
355 //===----------------------------------------------------------------------===//
356 // ReportNonAffBranch.
358 std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
360 const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
362 std::string ReportNonAffBranch::getMessage() const {
363 return ("Non affine branch in BB '" + BB->getName()).str() +
364 "' with LHS: " + *LHS + " and RHS: " + *RHS;
367 bool ReportNonAffBranch::classof(const RejectReason *RR) {
368 return RR->getKind() == RejectReasonKind::NonAffBranch;
371 //===----------------------------------------------------------------------===//
372 // ReportNoBasePtr.
374 std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
376 const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
378 std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
380 bool ReportNoBasePtr::classof(const RejectReason *RR) {
381 return RR->getKind() == RejectReasonKind::NoBasePtr;
384 //===----------------------------------------------------------------------===//
385 // ReportUndefBasePtr.
387 std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
389 const Value *ReportUndefBasePtr::getRemarkBB() const {
390 return Inst->getParent();
393 std::string ReportUndefBasePtr::getMessage() const {
394 return "Undefined base pointer";
397 bool ReportUndefBasePtr::classof(const RejectReason *RR) {
398 return RR->getKind() == RejectReasonKind::UndefBasePtr;
401 //===----------------------------------------------------------------------===//
402 // ReportVariantBasePtr.
404 std::string ReportVariantBasePtr::getRemarkName() const {
405 return "VariantBasePtr";
408 const Value *ReportVariantBasePtr::getRemarkBB() const {
409 return Inst->getParent();
412 std::string ReportVariantBasePtr::getMessage() const {
413 return "Base address not invariant in current region:" + *BaseValue;
416 std::string ReportVariantBasePtr::getEndUserMessage() const {
417 return "The base address of this array is not invariant inside the loop";
420 bool ReportVariantBasePtr::classof(const RejectReason *RR) {
421 return RR->getKind() == RejectReasonKind::VariantBasePtr;
424 //===----------------------------------------------------------------------===//
425 // ReportDifferentArrayElementSize
427 std::string ReportDifferentArrayElementSize::getRemarkName() const {
428 return "DifferentArrayElementSize";
431 const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
432 return Inst->getParent();
435 std::string ReportDifferentArrayElementSize::getMessage() const {
436 return "Access to one array through data types of different size";
439 bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
440 return RR->getKind() == RejectReasonKind::DifferentElementSize;
443 std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
444 StringRef BaseName = BaseValue->getName();
445 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName.str();
446 return "The array \"" + Name +
447 "\" is accessed through elements that differ "
448 "in size";
451 //===----------------------------------------------------------------------===//
452 // ReportNonAffineAccess.
454 std::string ReportNonAffineAccess::getRemarkName() const {
455 return "NonAffineAccess";
458 const Value *ReportNonAffineAccess::getRemarkBB() const {
459 return Inst->getParent();
462 std::string ReportNonAffineAccess::getMessage() const {
463 return "Non affine access function: " + *AccessFunction;
466 bool ReportNonAffineAccess::classof(const RejectReason *RR) {
467 return RR->getKind() == RejectReasonKind::NonAffineAccess;
470 std::string ReportNonAffineAccess::getEndUserMessage() const {
471 StringRef BaseName = BaseValue->getName();
472 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName.str();
473 return "The array subscript of \"" + Name + "\" is not affine";
476 //===----------------------------------------------------------------------===//
477 // ReportLoopBound.
479 ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
480 : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
481 Loc(L->getStartLoc()) {}
483 std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
485 const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
487 std::string ReportLoopBound::getMessage() const {
488 return "Non affine loop bound '" + *LoopCount +
489 "' in loop: " + L->getHeader()->getName();
492 const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
494 bool ReportLoopBound::classof(const RejectReason *RR) {
495 return RR->getKind() == RejectReasonKind::LoopBound;
498 std::string ReportLoopBound::getEndUserMessage() const {
499 return "Failed to derive an affine function from the loop bounds.";
502 //===----------------------------------------------------------------------===//
503 // ReportLoopHasNoExit.
505 std::string ReportLoopHasNoExit::getRemarkName() const {
506 return "LoopHasNoExit";
509 const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
511 std::string ReportLoopHasNoExit::getMessage() const {
512 return "Loop " + L->getHeader()->getName() + " has no exit.";
515 bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
516 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
519 const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
521 std::string ReportLoopHasNoExit::getEndUserMessage() const {
522 return "Loop cannot be handled because it has no exit.";
525 //===----------------------------------------------------------------------===//
526 // ReportLoopHasMultipleExits.
528 std::string ReportLoopHasMultipleExits::getRemarkName() const {
529 return "ReportLoopHasMultipleExits";
532 const Value *ReportLoopHasMultipleExits::getRemarkBB() const {
533 return L->getHeader();
536 std::string ReportLoopHasMultipleExits::getMessage() const {
537 return "Loop " + L->getHeader()->getName() + " has multiple exits.";
540 bool ReportLoopHasMultipleExits::classof(const RejectReason *RR) {
541 return RR->getKind() == RejectReasonKind::LoopHasMultipleExits;
544 const DebugLoc &ReportLoopHasMultipleExits::getDebugLoc() const { return Loc; }
546 std::string ReportLoopHasMultipleExits::getEndUserMessage() const {
547 return "Loop cannot be handled because it has multiple exits.";
550 //===----------------------------------------------------------------------===//
551 // ReportLoopOnlySomeLatches
553 std::string ReportLoopOnlySomeLatches::getRemarkName() const {
554 return "LoopHasNoExit";
557 const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
558 return L->getHeader();
561 std::string ReportLoopOnlySomeLatches::getMessage() const {
562 return "Not all latches of loop " + L->getHeader()->getName() +
563 " part of scop.";
566 bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
567 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
570 const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
572 std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
573 return "Loop cannot be handled because not all latches are part of loop "
574 "region.";
577 //===----------------------------------------------------------------------===//
578 // ReportFuncCall.
580 ReportFuncCall::ReportFuncCall(Instruction *Inst)
581 : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
583 std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
585 const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
587 std::string ReportFuncCall::getMessage() const {
588 return "Call instruction: " + *Inst;
591 const DebugLoc &ReportFuncCall::getDebugLoc() const {
592 return Inst->getDebugLoc();
595 std::string ReportFuncCall::getEndUserMessage() const {
596 return "This function call cannot be handled. "
597 "Try to inline it.";
600 bool ReportFuncCall::classof(const RejectReason *RR) {
601 return RR->getKind() == RejectReasonKind::FuncCall;
604 //===----------------------------------------------------------------------===//
605 // ReportNonSimpleMemoryAccess
607 ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
608 : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
610 std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
611 return "NonSimpleMemoryAccess";
614 const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
615 return Inst->getParent();
618 std::string ReportNonSimpleMemoryAccess::getMessage() const {
619 return "Non-simple memory access: " + *Inst;
622 const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
623 return Inst->getDebugLoc();
626 std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
627 return "Volatile memory accesses or memory accesses for atomic types "
628 "are not supported.";
631 bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
632 return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
635 //===----------------------------------------------------------------------===//
636 // ReportAlias.
638 ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
639 : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
640 append_range(Pointers, AS.getPointers());
643 std::string ReportAlias::formatInvalidAlias(std::string Prefix,
644 std::string Suffix) const {
645 std::string Message;
646 raw_string_ostream OS(Message);
648 OS << Prefix;
650 for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
651 PE = Pointers.end();
652 ;) {
653 const Value *V = *PI;
654 assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
656 if (V->getName().empty())
657 OS << "\" <unknown> \"";
658 else
659 OS << "\"" << V->getName() << "\"";
661 ++PI;
663 if (PI != PE)
664 OS << ", ";
665 else
666 break;
669 OS << Suffix;
671 return Message;
674 std::string ReportAlias::getRemarkName() const { return "Alias"; }
676 const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
678 std::string ReportAlias::getMessage() const {
679 return formatInvalidAlias("Possible aliasing: ");
682 std::string ReportAlias::getEndUserMessage() const {
683 return formatInvalidAlias("Accesses to the arrays ",
684 " may access the same memory.");
687 const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
689 bool ReportAlias::classof(const RejectReason *RR) {
690 return RR->getKind() == RejectReasonKind::Alias;
693 //===----------------------------------------------------------------------===//
694 // ReportOther.
696 std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
698 std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
700 ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
702 bool ReportOther::classof(const RejectReason *RR) {
703 return RR->getKind() >= RejectReasonKind::Other &&
704 RR->getKind() <= RejectReasonKind::LastOther;
707 //===----------------------------------------------------------------------===//
708 // ReportIntToPtr.
709 ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
710 : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
712 std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
714 const Value *ReportIntToPtr::getRemarkBB() const {
715 return BaseValue->getParent();
718 std::string ReportIntToPtr::getMessage() const {
719 return "Find bad intToptr prt: " + *BaseValue;
722 const DebugLoc &ReportIntToPtr::getDebugLoc() const {
723 return BaseValue->getDebugLoc();
726 bool ReportIntToPtr::classof(const RejectReason *RR) {
727 return RR->getKind() == RejectReasonKind::IntToPtr;
730 //===----------------------------------------------------------------------===//
731 // ReportAlloca.
733 ReportAlloca::ReportAlloca(Instruction *Inst)
734 : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
736 std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
738 const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
740 std::string ReportAlloca::getMessage() const {
741 return "Alloca instruction: " + *Inst;
744 const DebugLoc &ReportAlloca::getDebugLoc() const {
745 return Inst->getDebugLoc();
748 bool ReportAlloca::classof(const RejectReason *RR) {
749 return RR->getKind() == RejectReasonKind::Alloca;
752 //===----------------------------------------------------------------------===//
753 // ReportUnknownInst.
755 ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
756 : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
758 std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
760 const Value *ReportUnknownInst::getRemarkBB() const {
761 return Inst->getParent();
764 std::string ReportUnknownInst::getMessage() const {
765 return "Unknown instruction: " + *Inst;
768 const DebugLoc &ReportUnknownInst::getDebugLoc() const {
769 return Inst->getDebugLoc();
772 bool ReportUnknownInst::classof(const RejectReason *RR) {
773 return RR->getKind() == RejectReasonKind::UnknownInst;
776 //===----------------------------------------------------------------------===//
777 // ReportEntry.
779 ReportEntry::ReportEntry(BasicBlock *BB)
780 : ReportOther(RejectReasonKind::Entry), BB(BB) {}
782 std::string ReportEntry::getRemarkName() const { return "Entry"; }
784 const Value *ReportEntry::getRemarkBB() const { return BB; }
786 std::string ReportEntry::getMessage() const {
787 return "Region containing entry block of function is invalid!";
790 std::string ReportEntry::getEndUserMessage() const {
791 return "Scop contains function entry (not yet supported).";
794 const DebugLoc &ReportEntry::getDebugLoc() const {
795 return BB->getTerminator()->getDebugLoc();
798 bool ReportEntry::classof(const RejectReason *RR) {
799 return RR->getKind() == RejectReasonKind::Entry;
802 //===----------------------------------------------------------------------===//
803 // ReportUnprofitable.
805 ReportUnprofitable::ReportUnprofitable(Region *R)
806 : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
808 std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
810 const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
812 std::string ReportUnprofitable::getMessage() const {
813 return "Region can not profitably be optimized!";
816 std::string ReportUnprofitable::getEndUserMessage() const {
817 return "No profitable polyhedral optimization found";
820 const DebugLoc &ReportUnprofitable::getDebugLoc() const {
821 for (const BasicBlock *BB : R->blocks())
822 for (const Instruction &Inst : *BB)
823 if (const DebugLoc &DL = Inst.getStableDebugLoc())
824 return DL;
826 return R->getEntry()->getTerminator()->getDebugLoc();
829 bool ReportUnprofitable::classof(const RejectReason *RR) {
830 return RR->getKind() == RejectReasonKind::Unprofitable;
832 } // namespace polly