[ScopInfo] Move splitAliasGroupsByDomain and getAccessDomain to isl++ [NFCI]
[polly-mirror.git] / lib / Analysis / ScopDetectionDiagnostic.cpp
bloba0c371237c42568d1476d1b26a7e352763f2a95d
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 { \
50 "polly-detect", "NAME", "Number of rejected regions: " DESC, {0}, { \
51 false \
52 } \
55 Statistic RejectStatistics[] = {
56 SCOP_STAT(CFG, ""),
57 SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
58 SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
59 SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
60 SCOP_STAT(LastCFG, ""),
61 SCOP_STAT(AffFunc, ""),
62 SCOP_STAT(UndefCond, "Undefined branch condition"),
63 SCOP_STAT(InvalidCond, "Non-integer branch condition"),
64 SCOP_STAT(UndefOperand, "Undefined operands in comparison"),
65 SCOP_STAT(NonAffBranch, "Non-affine branch condition"),
66 SCOP_STAT(NoBasePtr, "No base pointer"),
67 SCOP_STAT(UndefBasePtr, "Undefined base pointer"),
68 SCOP_STAT(VariantBasePtr, "Variant base pointer"),
69 SCOP_STAT(NonAffineAccess, "Non-affine memory accesses"),
70 SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"),
71 SCOP_STAT(LastAffFunc, ""),
72 SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
73 SCOP_STAT(LoopHasNoExit, "Loop without exit"),
74 SCOP_STAT(LoopHasMultipleExits, "Loop with multiple exits"),
75 SCOP_STAT(LoopOnlySomeLatches, "Not all loop latches in scop"),
76 SCOP_STAT(FuncCall, "Function call with side effects"),
77 SCOP_STAT(NonSimpleMemoryAccess,
78 "Compilated access semantics (volatile or atomic)"),
79 SCOP_STAT(Alias, "Base address aliasing"),
80 SCOP_STAT(Other, ""),
81 SCOP_STAT(IntToPtr, "Integer to pointer conversions"),
82 SCOP_STAT(Alloca, "Stack allocations"),
83 SCOP_STAT(UnknownInst, "Unknown Instructions"),
84 SCOP_STAT(Entry, "Contains entry block"),
85 SCOP_STAT(Unprofitable, "Assumed to be unprofitable"),
86 SCOP_STAT(LastOther, ""),
89 namespace polly {
91 /// Small string conversion via raw_string_stream.
92 template <typename T> std::string operator+(Twine LHS, const T &RHS) {
93 std::string Buf;
94 raw_string_ostream fmt(Buf);
95 fmt << RHS;
96 fmt.flush();
98 return LHS.concat(Buf).str();
100 } // namespace polly
102 namespace llvm {
104 // Lexicographic order on (line, col) of our debug locations.
105 static bool operator<(const DebugLoc &LHS, const DebugLoc &RHS) {
106 return LHS.getLine() < RHS.getLine() ||
107 (LHS.getLine() == RHS.getLine() && LHS.getCol() < RHS.getCol());
109 } // namespace llvm
111 namespace polly {
113 BBPair getBBPairForRegion(const Region *R) {
114 return std::make_pair(R->getEntry(), R->getExit());
117 void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
118 SmallPtrSet<BasicBlock *, 32> Seen;
119 SmallVector<BasicBlock *, 32> Todo;
120 Todo.push_back(P.first);
121 while (!Todo.empty()) {
122 auto *BB = Todo.pop_back_val();
123 if (BB == P.second)
124 continue;
125 if (!Seen.insert(BB).second)
126 continue;
127 Todo.append(succ_begin(BB), succ_end(BB));
128 for (const Instruction &Inst : *BB) {
129 DebugLoc DL = Inst.getDebugLoc();
130 if (!DL)
131 continue;
133 Begin = Begin ? std::min(Begin, DL) : DL;
134 End = End ? std::max(End, DL) : DL;
139 void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
140 OptimizationRemarkEmitter &ORE) {
141 DebugLoc Begin, End;
142 getDebugLocations(P, Begin, End);
144 ORE.emit(
145 OptimizationRemarkMissed(DEBUG_TYPE, "RejectionErrors", Begin, P.first)
146 << "The following errors keep this region from being a Scop.");
148 for (RejectReasonPtr RR : Log) {
150 if (const DebugLoc &Loc = RR->getDebugLoc())
151 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Loc,
152 RR->getRemarkBB())
153 << RR->getEndUserMessage());
154 else
155 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
156 RR->getRemarkBB())
157 << RR->getEndUserMessage());
160 /* Check to see if Region is a top level region, getExit = NULL*/
161 if (P.second)
162 ORE.emit(
163 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
164 << "Invalid Scop candidate ends here.");
165 else
166 ORE.emit(
167 OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
168 << "Invalid Scop candidate ends here.");
171 //===----------------------------------------------------------------------===//
172 // RejectReason.
174 RejectReason::RejectReason(RejectReasonKind K) : Kind(K) {
175 RejectStatistics[static_cast<int>(K)]++;
178 const DebugLoc RejectReason::Unknown = DebugLoc();
180 const DebugLoc &RejectReason::getDebugLoc() const {
181 // Allocate an empty DebugLoc and return it a reference to it.
182 return Unknown;
185 // RejectLog.
186 void RejectLog::print(raw_ostream &OS, int level) const {
187 int j = 0;
188 for (auto Reason : ErrorReports)
189 OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
192 //===----------------------------------------------------------------------===//
193 // ReportCFG.
195 ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {}
197 bool ReportCFG::classof(const RejectReason *RR) {
198 return RR->getKind() >= RejectReasonKind::CFG &&
199 RR->getKind() <= RejectReasonKind::LastCFG;
202 //===----------------------------------------------------------------------===//
203 // ReportInvalidTerminator.
205 std::string ReportInvalidTerminator::getRemarkName() const {
206 return "InvalidTerminator";
209 const Value *ReportInvalidTerminator::getRemarkBB() const { return BB; }
211 std::string ReportInvalidTerminator::getMessage() const {
212 return ("Invalid instruction terminates BB: " + BB->getName()).str();
215 const DebugLoc &ReportInvalidTerminator::getDebugLoc() const {
216 return BB->getTerminator()->getDebugLoc();
219 bool ReportInvalidTerminator::classof(const RejectReason *RR) {
220 return RR->getKind() == RejectReasonKind::InvalidTerminator;
223 //===----------------------------------------------------------------------===//
224 // UnreachableInExit.
226 std::string ReportUnreachableInExit::getRemarkName() const {
227 return "UnreachableInExit";
230 const Value *ReportUnreachableInExit::getRemarkBB() const { return BB; }
232 std::string ReportUnreachableInExit::getMessage() const {
233 std::string BBName = BB->getName();
234 return "Unreachable in exit block" + BBName;
237 const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; }
239 std::string ReportUnreachableInExit::getEndUserMessage() const {
240 return "Unreachable in exit block.";
243 bool ReportUnreachableInExit::classof(const RejectReason *RR) {
244 return RR->getKind() == RejectReasonKind::UnreachableInExit;
247 //===----------------------------------------------------------------------===//
248 // ReportIrreducibleRegion.
250 std::string ReportIrreducibleRegion::getRemarkName() const {
251 return "IrreducibleRegion";
254 const Value *ReportIrreducibleRegion::getRemarkBB() const {
255 return R->getEntry();
258 std::string ReportIrreducibleRegion::getMessage() const {
259 return "Irreducible region encountered: " + R->getNameStr();
262 const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
264 std::string ReportIrreducibleRegion::getEndUserMessage() const {
265 return "Irreducible region encountered in control flow.";
268 bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
269 return RR->getKind() == RejectReasonKind::IrreducibleRegion;
272 //===----------------------------------------------------------------------===//
273 // ReportAffFunc.
275 ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
276 : RejectReason(K), Inst(Inst) {}
278 bool ReportAffFunc::classof(const RejectReason *RR) {
279 return RR->getKind() >= RejectReasonKind::AffFunc &&
280 RR->getKind() <= RejectReasonKind::LastAffFunc;
283 //===----------------------------------------------------------------------===//
284 // ReportUndefCond.
286 std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
288 const Value *ReportUndefCond::getRemarkBB() const { return BB; }
290 std::string ReportUndefCond::getMessage() const {
291 return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
294 bool ReportUndefCond::classof(const RejectReason *RR) {
295 return RR->getKind() == RejectReasonKind::UndefCond;
298 //===----------------------------------------------------------------------===//
299 // ReportInvalidCond.
301 std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
303 const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
305 std::string ReportInvalidCond::getMessage() const {
306 return ("Condition in BB '" + BB->getName()).str() +
307 "' neither constant nor an icmp instruction";
310 bool ReportInvalidCond::classof(const RejectReason *RR) {
311 return RR->getKind() == RejectReasonKind::InvalidCond;
314 //===----------------------------------------------------------------------===//
315 // ReportUndefOperand.
317 std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
319 const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
321 std::string ReportUndefOperand::getMessage() const {
322 return ("undef operand in branch at BB: " + BB->getName()).str();
325 bool ReportUndefOperand::classof(const RejectReason *RR) {
326 return RR->getKind() == RejectReasonKind::UndefOperand;
329 //===----------------------------------------------------------------------===//
330 // ReportNonAffBranch.
332 std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
334 const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
336 std::string ReportNonAffBranch::getMessage() const {
337 return ("Non affine branch in BB '" + BB->getName()).str() +
338 "' with LHS: " + *LHS + " and RHS: " + *RHS;
341 bool ReportNonAffBranch::classof(const RejectReason *RR) {
342 return RR->getKind() == RejectReasonKind::NonAffBranch;
345 //===----------------------------------------------------------------------===//
346 // ReportNoBasePtr.
348 std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
350 const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
352 std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
354 bool ReportNoBasePtr::classof(const RejectReason *RR) {
355 return RR->getKind() == RejectReasonKind::NoBasePtr;
358 //===----------------------------------------------------------------------===//
359 // ReportUndefBasePtr.
361 std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
363 const Value *ReportUndefBasePtr::getRemarkBB() const {
364 return Inst->getParent();
367 std::string ReportUndefBasePtr::getMessage() const {
368 return "Undefined base pointer";
371 bool ReportUndefBasePtr::classof(const RejectReason *RR) {
372 return RR->getKind() == RejectReasonKind::UndefBasePtr;
375 //===----------------------------------------------------------------------===//
376 // ReportVariantBasePtr.
378 std::string ReportVariantBasePtr::getRemarkName() const {
379 return "VariantBasePtr";
382 const Value *ReportVariantBasePtr::getRemarkBB() const {
383 return Inst->getParent();
386 std::string ReportVariantBasePtr::getMessage() const {
387 return "Base address not invariant in current region:" + *BaseValue;
390 std::string ReportVariantBasePtr::getEndUserMessage() const {
391 return "The base address of this array is not invariant inside the loop";
394 bool ReportVariantBasePtr::classof(const RejectReason *RR) {
395 return RR->getKind() == RejectReasonKind::VariantBasePtr;
398 //===----------------------------------------------------------------------===//
399 // ReportDifferentArrayElementSize
401 std::string ReportDifferentArrayElementSize::getRemarkName() const {
402 return "DifferentArrayElementSize";
405 const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
406 return Inst->getParent();
409 std::string ReportDifferentArrayElementSize::getMessage() const {
410 return "Access to one array through data types of different size";
413 bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
414 return RR->getKind() == RejectReasonKind::DifferentElementSize;
417 std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
418 StringRef BaseName = BaseValue->getName();
419 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName;
420 return "The array \"" + Name +
421 "\" is accessed through elements that differ "
422 "in size";
425 //===----------------------------------------------------------------------===//
426 // ReportNonAffineAccess.
428 std::string ReportNonAffineAccess::getRemarkName() const {
429 return "NonAffineAccess";
432 const Value *ReportNonAffineAccess::getRemarkBB() const {
433 return Inst->getParent();
436 std::string ReportNonAffineAccess::getMessage() const {
437 return "Non affine access function: " + *AccessFunction;
440 bool ReportNonAffineAccess::classof(const RejectReason *RR) {
441 return RR->getKind() == RejectReasonKind::NonAffineAccess;
444 std::string ReportNonAffineAccess::getEndUserMessage() const {
445 StringRef BaseName = BaseValue->getName();
446 std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName;
447 return "The array subscript of \"" + Name + "\" is not affine";
450 //===----------------------------------------------------------------------===//
451 // ReportLoopBound.
453 ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
454 : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
455 Loc(L->getStartLoc()) {}
457 std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
459 const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
461 std::string ReportLoopBound::getMessage() const {
462 return "Non affine loop bound '" + *LoopCount +
463 "' in loop: " + L->getHeader()->getName();
466 const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
468 bool ReportLoopBound::classof(const RejectReason *RR) {
469 return RR->getKind() == RejectReasonKind::LoopBound;
472 std::string ReportLoopBound::getEndUserMessage() const {
473 return "Failed to derive an affine function from the loop bounds.";
476 //===----------------------------------------------------------------------===//
477 // ReportLoopHasNoExit.
479 std::string ReportLoopHasNoExit::getRemarkName() const {
480 return "LoopHasNoExit";
483 const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
485 std::string ReportLoopHasNoExit::getMessage() const {
486 return "Loop " + L->getHeader()->getName() + " has no exit.";
489 bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
490 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
493 const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
495 std::string ReportLoopHasNoExit::getEndUserMessage() const {
496 return "Loop cannot be handled because it has no exit.";
499 //===----------------------------------------------------------------------===//
500 // ReportLoopHasMultipleExits.
502 std::string ReportLoopHasMultipleExits::getRemarkName() const {
503 return "ReportLoopHasMultipleExits";
506 const Value *ReportLoopHasMultipleExits::getRemarkBB() const {
507 return L->getHeader();
510 std::string ReportLoopHasMultipleExits::getMessage() const {
511 return "Loop " + L->getHeader()->getName() + " has multiple exits.";
514 bool ReportLoopHasMultipleExits::classof(const RejectReason *RR) {
515 return RR->getKind() == RejectReasonKind::LoopHasMultipleExits;
518 const DebugLoc &ReportLoopHasMultipleExits::getDebugLoc() const { return Loc; }
520 std::string ReportLoopHasMultipleExits::getEndUserMessage() const {
521 return "Loop cannot be handled because it has multiple exits.";
524 //===----------------------------------------------------------------------===//
525 // ReportLoopOnlySomeLatches
527 std::string ReportLoopOnlySomeLatches::getRemarkName() const {
528 return "LoopHasNoExit";
531 const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
532 return L->getHeader();
535 std::string ReportLoopOnlySomeLatches::getMessage() const {
536 return "Not all latches of loop " + L->getHeader()->getName() +
537 " part of scop.";
540 bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
541 return RR->getKind() == RejectReasonKind::LoopHasNoExit;
544 const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
546 std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
547 return "Loop cannot be handled because not all latches are part of loop "
548 "region.";
551 //===----------------------------------------------------------------------===//
552 // ReportFuncCall.
554 ReportFuncCall::ReportFuncCall(Instruction *Inst)
555 : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
557 std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
559 const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
561 std::string ReportFuncCall::getMessage() const {
562 return "Call instruction: " + *Inst;
565 const DebugLoc &ReportFuncCall::getDebugLoc() const {
566 return Inst->getDebugLoc();
569 std::string ReportFuncCall::getEndUserMessage() const {
570 return "This function call cannot be handled. "
571 "Try to inline it.";
574 bool ReportFuncCall::classof(const RejectReason *RR) {
575 return RR->getKind() == RejectReasonKind::FuncCall;
578 //===----------------------------------------------------------------------===//
579 // ReportNonSimpleMemoryAccess
581 ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
582 : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
584 std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
585 return "NonSimpleMemoryAccess";
588 const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
589 return Inst->getParent();
592 std::string ReportNonSimpleMemoryAccess::getMessage() const {
593 return "Non-simple memory access: " + *Inst;
596 const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
597 return Inst->getDebugLoc();
600 std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
601 return "Volatile memory accesses or memory accesses for atomic types "
602 "are not supported.";
605 bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
606 return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
609 //===----------------------------------------------------------------------===//
610 // ReportAlias.
612 ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
613 : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
614 for (const auto &I : AS)
615 Pointers.push_back(I.getValue());
618 std::string ReportAlias::formatInvalidAlias(std::string Prefix,
619 std::string Suffix) const {
620 std::string Message;
621 raw_string_ostream OS(Message);
623 OS << Prefix;
625 for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
626 PE = Pointers.end();
627 ;) {
628 const Value *V = *PI;
629 assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
631 if (V->getName().empty())
632 OS << "\" <unknown> \"";
633 else
634 OS << "\"" << V->getName() << "\"";
636 ++PI;
638 if (PI != PE)
639 OS << ", ";
640 else
641 break;
644 OS << Suffix;
646 return OS.str();
649 std::string ReportAlias::getRemarkName() const { return "Alias"; }
651 const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
653 std::string ReportAlias::getMessage() const {
654 return formatInvalidAlias("Possible aliasing: ");
657 std::string ReportAlias::getEndUserMessage() const {
658 return formatInvalidAlias("Accesses to the arrays ",
659 " may access the same memory.");
662 const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
664 bool ReportAlias::classof(const RejectReason *RR) {
665 return RR->getKind() == RejectReasonKind::Alias;
668 //===----------------------------------------------------------------------===//
669 // ReportOther.
671 std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
673 std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
675 ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
677 bool ReportOther::classof(const RejectReason *RR) {
678 return RR->getKind() >= RejectReasonKind::Other &&
679 RR->getKind() <= RejectReasonKind::LastOther;
682 //===----------------------------------------------------------------------===//
683 // ReportIntToPtr.
684 ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
685 : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
687 std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
689 const Value *ReportIntToPtr::getRemarkBB() const {
690 return BaseValue->getParent();
693 std::string ReportIntToPtr::getMessage() const {
694 return "Find bad intToptr prt: " + *BaseValue;
697 const DebugLoc &ReportIntToPtr::getDebugLoc() const {
698 return BaseValue->getDebugLoc();
701 bool ReportIntToPtr::classof(const RejectReason *RR) {
702 return RR->getKind() == RejectReasonKind::IntToPtr;
705 //===----------------------------------------------------------------------===//
706 // ReportAlloca.
708 ReportAlloca::ReportAlloca(Instruction *Inst)
709 : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
711 std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
713 const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
715 std::string ReportAlloca::getMessage() const {
716 return "Alloca instruction: " + *Inst;
719 const DebugLoc &ReportAlloca::getDebugLoc() const {
720 return Inst->getDebugLoc();
723 bool ReportAlloca::classof(const RejectReason *RR) {
724 return RR->getKind() == RejectReasonKind::Alloca;
727 //===----------------------------------------------------------------------===//
728 // ReportUnknownInst.
730 ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
731 : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
733 std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
735 const Value *ReportUnknownInst::getRemarkBB() const {
736 return Inst->getParent();
739 std::string ReportUnknownInst::getMessage() const {
740 return "Unknown instruction: " + *Inst;
743 const DebugLoc &ReportUnknownInst::getDebugLoc() const {
744 return Inst->getDebugLoc();
747 bool ReportUnknownInst::classof(const RejectReason *RR) {
748 return RR->getKind() == RejectReasonKind::UnknownInst;
751 //===----------------------------------------------------------------------===//
752 // ReportEntry.
754 ReportEntry::ReportEntry(BasicBlock *BB)
755 : ReportOther(RejectReasonKind::Entry), BB(BB) {}
757 std::string ReportEntry::getRemarkName() const { return "Entry"; }
759 const Value *ReportEntry::getRemarkBB() const { return BB; }
761 std::string ReportEntry::getMessage() const {
762 return "Region containing entry block of function is invalid!";
765 std::string ReportEntry::getEndUserMessage() const {
766 return "Scop contains function entry (not yet supported).";
769 const DebugLoc &ReportEntry::getDebugLoc() const {
770 return BB->getTerminator()->getDebugLoc();
773 bool ReportEntry::classof(const RejectReason *RR) {
774 return RR->getKind() == RejectReasonKind::Entry;
777 //===----------------------------------------------------------------------===//
778 // ReportUnprofitable.
780 ReportUnprofitable::ReportUnprofitable(Region *R)
781 : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
783 std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
785 const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
787 std::string ReportUnprofitable::getMessage() const {
788 return "Region can not profitably be optimized!";
791 std::string ReportUnprofitable::getEndUserMessage() const {
792 return "No profitable polyhedral optimization found";
795 const DebugLoc &ReportUnprofitable::getDebugLoc() const {
796 for (const BasicBlock *BB : R->blocks())
797 for (const Instruction &Inst : *BB)
798 if (const DebugLoc &DL = Inst.getDebugLoc())
799 return DL;
801 return R->getEntry()->getTerminator()->getDebugLoc();
804 bool ReportUnprofitable::classof(const RejectReason *RR) {
805 return RR->getKind() == RejectReasonKind::Unprofitable;
807 } // namespace polly