1//===- ScopDetectionDiagnostic.h - Diagnostic for ScopDetection -*- C++ -*-===//
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.
11//
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.
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef POLLY_SCOPDETECTIONDIAGNOSTIC_H
21#define POLLY_SCOPDETECTIONDIAGNOSTIC_H
22
23#include "llvm/Analysis/LoopInfo.h"
24#include "llvm/IR/DebugLoc.h"
25#include "llvm/IR/Instruction.h"
26#include <cstddef>
27
28namespace llvm {
29class AliasSet;
30class BasicBlock;
31class OptimizationRemarkEmitter;
32class Region;
33class SCEV;
34} // namespace llvm
35
36namespace polly {
37using llvm::AliasSet;
38using llvm::BasicBlock;
39using llvm::DebugLoc;
40using llvm::Instruction;
41using llvm::Loop;
42using llvm::OptimizationRemarkEmitter;
43using llvm::raw_ostream;
44using llvm::Region;
45using llvm::SCEV;
46using llvm::SmallVector;
47using llvm::Value;
48
49/// Type to hold region delimiters (entry & exit block).
50using BBPair = std::pair<BasicBlock *, BasicBlock *>;
51
52/// Return the region delimiters (entry & exit block) of @p R.
53BBPair getBBPairForRegion(const Region *R);
54
55/// Set the begin and end source location for the region limited by @p P.
56void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End);
57
58class RejectLog;
59
60/// Emit optimization remarks about the rejected regions to the user.
61///
62/// This emits the content of the reject log as optimization remarks.
63/// Remember to at least track failures (-polly-detect-track-failures).
64/// @param P The region delimiters (entry & exit) we emit remarks for.
65/// @param Log The error log containing all messages being emitted as remark.
66void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
67 OptimizationRemarkEmitter &ORE);
68
69// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
70enum class RejectReasonKind {
71 // CFG Category
72 CFG,
73 InvalidTerminator,
74 IrreducibleRegion,
75 UnreachableInExit,
76 IndirectPredecessor,
77 LastCFG,
78
79 // Non-Affinity
80 AffFunc,
81 UndefCond,
82 InvalidCond,
83 UndefOperand,
84 NonAffBranch,
85 NoBasePtr,
86 UndefBasePtr,
87 VariantBasePtr,
88 NonAffineAccess,
89 DifferentElementSize,
90 LastAffFunc,
91
92 LoopBound,
93 LoopHasNoExit,
94 LoopHasMultipleExits,
95 LoopOnlySomeLatches,
96
97 FuncCall,
98 NonSimpleMemoryAccess,
99
100 Alias,
101
102 // Other
103 Other,
104 IntToPtr,
105 Alloca,
106 UnknownInst,
107 Entry,
108 Unprofitable,
109 LastOther
110};
111
112//===----------------------------------------------------------------------===//
113/// Base class of all reject reasons found during Scop detection.
114///
115/// Subclasses of RejectReason should provide means to capture enough
116/// diagnostic information to help clients figure out what and where something
117/// went wrong in the Scop detection.
118class RejectReason {
119private:
120 const RejectReasonKind Kind;
121
122protected:
123 static const DebugLoc Unknown;
124
125public:
126 RejectReason(RejectReasonKind K);
127
128 virtual ~RejectReason() = default;
129
130 RejectReasonKind getKind() const { return Kind; }
131
132 /// Generate the remark name to identify this remark.
133 ///
134 /// @return A short string that identifies the error.
135 virtual std::string getRemarkName() const = 0;
136
137 /// Get the Basic Block containing this remark.
138 ///
139 /// @return The Basic Block containing this remark.
140 virtual const Value *getRemarkBB() const = 0;
141
142 /// Generate a reasonable diagnostic message describing this error.
143 ///
144 /// @return A debug message representing this error.
145 virtual std::string getMessage() const = 0;
146
147 /// Generate a message for the end-user describing this error.
148 ///
149 /// The message provided has to be suitable for the end-user. So it should
150 /// not reference any LLVM internal data structures or terminology.
151 /// Ideally, the message helps the end-user to increase the size of the
152 /// regions amenable to Polly.
153 ///
154 /// @return A short message representing this error.
155 virtual std::string getEndUserMessage() const { return "Unspecified error."; }
156
157 /// Get the source location of this error.
158 ///
159 /// @return The debug location for this error.
160 virtual const DebugLoc &getDebugLoc() const;
161};
162
163using RejectReasonPtr = std::shared_ptr<RejectReason>;
164
165/// Stores all errors that occurred during the detection.
166class RejectLog final {
167 Region *R;
168 SmallVector<RejectReasonPtr, 1> ErrorReports;
169
170public:
171 explicit RejectLog(Region *R) : R(R) {}
172
173 using iterator = SmallVector<RejectReasonPtr, 1>::const_iterator;
174
175 iterator begin() const { return ErrorReports.begin(); }
176 iterator end() const { return ErrorReports.end(); }
177 size_t size() const { return ErrorReports.size(); }
178
179 /// Returns true, if we store at least one error.
180 ///
181 /// @return true, if we store at least one error.
182 bool hasErrors() const { return size() > 0; }
183
184 void print(raw_ostream &OS, int level = 0) const;
185
186 const Region *region() const { return R; }
187 void report(RejectReasonPtr Reject) { ErrorReports.push_back(Elt: Reject); }
188};
189
190//===----------------------------------------------------------------------===//
191/// Base class for CFG related reject reasons.
192///
193/// Scop candidates that violate structural restrictions can be grouped under
194/// this reject reason class.
195class ReportCFG : public RejectReason {
196public:
197 ReportCFG(const RejectReasonKind K);
198
199 /// @name LLVM-RTTI interface
200 //@{
201 static bool classof(const RejectReason *RR);
202 //@}
203};
204
205//===----------------------------------------------------------------------===//
206/// Captures bad terminator within a Scop candidate.
207class ReportInvalidTerminator final : public ReportCFG {
208 BasicBlock *BB;
209
210public:
211 ReportInvalidTerminator(BasicBlock *BB)
212 : ReportCFG(RejectReasonKind::InvalidTerminator), BB(BB) {}
213
214 /// @name LLVM-RTTI interface
215 //@{
216 static bool classof(const RejectReason *RR);
217 //@}
218
219 /// @name RejectReason interface
220 //@{
221 std::string getRemarkName() const override;
222 const Value *getRemarkBB() const override;
223 std::string getMessage() const override;
224 const DebugLoc &getDebugLoc() const override;
225 //@}
226};
227
228//===----------------------------------------------------------------------===//
229/// Captures irreducible regions in CFG.
230class ReportIrreducibleRegion final : public ReportCFG {
231 Region *R;
232 DebugLoc DbgLoc;
233
234public:
235 ReportIrreducibleRegion(Region *R, DebugLoc DbgLoc)
236 : ReportCFG(RejectReasonKind::IrreducibleRegion), R(R), DbgLoc(DbgLoc) {}
237
238 /// @name LLVM-RTTI interface
239 //@{
240 static bool classof(const RejectReason *RR);
241 //@}
242
243 /// @name RejectReason interface
244 //@{
245 std::string getRemarkName() const override;
246 const Value *getRemarkBB() const override;
247 std::string getMessage() const override;
248 std::string getEndUserMessage() const override;
249 const DebugLoc &getDebugLoc() const override;
250 //@}
251};
252
253//===----------------------------------------------------------------------===//
254/// Captures regions with an unreachable in the exit block.
255class ReportUnreachableInExit final : public ReportCFG {
256 BasicBlock *BB;
257 DebugLoc DbgLoc;
258
259public:
260 ReportUnreachableInExit(BasicBlock *BB, DebugLoc DbgLoc)
261 : ReportCFG(RejectReasonKind::UnreachableInExit), BB(BB), DbgLoc(DbgLoc) {
262 }
263
264 /// @name LLVM-RTTI interface
265 //@{
266 static bool classof(const RejectReason *RR);
267 //@}
268
269 /// @name RejectReason interface
270 //@{
271 std::string getRemarkName() const override;
272 const Value *getRemarkBB() const override;
273 std::string getMessage() const override;
274 std::string getEndUserMessage() const override;
275 const DebugLoc &getDebugLoc() const override;
276 //@}
277};
278
279//===----------------------------------------------------------------------===//
280/// Captures regions with an IndirectBr predecessor.
281class ReportIndirectPredecessor final : public ReportCFG {
282 Instruction *Inst;
283 DebugLoc DbgLoc;
284
285public:
286 ReportIndirectPredecessor(Instruction *Inst, DebugLoc DbgLoc)
287 : ReportCFG(RejectReasonKind::IndirectPredecessor), Inst(Inst),
288 DbgLoc(DbgLoc) {}
289
290 /// @name LLVM-RTTI interface
291 //@{
292 static bool classof(const RejectReason *RR);
293 //@}
294
295 /// @name RejectReason interface
296 //@{
297 std::string getRemarkName() const override;
298 const Value *getRemarkBB() const override;
299 std::string getMessage() const override;
300 std::string getEndUserMessage() const override;
301 const DebugLoc &getDebugLoc() const override;
302 //@}
303};
304
305//===----------------------------------------------------------------------===//
306/// Base class for non-affine reject reasons.
307///
308/// Scop candidates that violate restrictions to affinity are reported under
309/// this class.
310class ReportAffFunc : public RejectReason {
311protected:
312 // The instruction that caused non-affinity to occur.
313 const Instruction *Inst;
314
315public:
316 ReportAffFunc(const RejectReasonKind K, const Instruction *Inst);
317
318 /// @name LLVM-RTTI interface
319 //@{
320 static bool classof(const RejectReason *RR);
321 //@}
322
323 /// @name RejectReason interface
324 //@{
325 const DebugLoc &getDebugLoc() const override { return Inst->getDebugLoc(); }
326 //@}
327};
328
329//===----------------------------------------------------------------------===//
330/// Captures a condition that is based on an 'undef' value.
331class ReportUndefCond final : public ReportAffFunc {
332 // The BasicBlock we found the broken condition in.
333 BasicBlock *BB;
334
335public:
336 ReportUndefCond(const Instruction *Inst, BasicBlock *BB)
337 : ReportAffFunc(RejectReasonKind::UndefCond, Inst), BB(BB) {}
338
339 /// @name LLVM-RTTI interface
340 //@{
341 static bool classof(const RejectReason *RR);
342 //@}
343
344 /// @name RejectReason interface
345 //@{
346 std::string getRemarkName() const override;
347 const Value *getRemarkBB() const override;
348 std::string getMessage() const override;
349 //@}
350};
351
352//===----------------------------------------------------------------------===//
353/// Captures an invalid condition
354///
355/// Conditions have to be either constants or icmp instructions.
356class ReportInvalidCond final : public ReportAffFunc {
357 // The BasicBlock we found the broken condition in.
358 BasicBlock *BB;
359
360public:
361 ReportInvalidCond(const Instruction *Inst, BasicBlock *BB)
362 : ReportAffFunc(RejectReasonKind::InvalidCond, Inst), BB(BB) {}
363
364 /// @name LLVM-RTTI interface
365 //@{
366 static bool classof(const RejectReason *RR);
367 //@}
368
369 /// @name RejectReason interface
370 //@{
371 std::string getRemarkName() const override;
372 const Value *getRemarkBB() const override;
373 std::string getMessage() const override;
374 //@}
375};
376
377//===----------------------------------------------------------------------===//
378/// Captures an undefined operand.
379class ReportUndefOperand final : public ReportAffFunc {
380 // The BasicBlock we found the undefined operand in.
381 BasicBlock *BB;
382
383public:
384 ReportUndefOperand(BasicBlock *BB, const Instruction *Inst)
385 : ReportAffFunc(RejectReasonKind::UndefOperand, Inst), BB(BB) {}
386
387 /// @name LLVM-RTTI interface
388 //@{
389 static bool classof(const RejectReason *RR);
390 //@}
391
392 /// @name RejectReason interface
393 //@{
394 std::string getRemarkName() const override;
395 const Value *getRemarkBB() const override;
396 std::string getMessage() const override;
397 //@}
398};
399
400//===----------------------------------------------------------------------===//
401/// Captures a non-affine branch.
402class ReportNonAffBranch final : public ReportAffFunc {
403 // The BasicBlock we found the non-affine branch in.
404 BasicBlock *BB;
405
406 /// LHS & RHS of the failed condition.
407 //@{
408 const SCEV *LHS;
409 const SCEV *RHS;
410 //@}
411
412public:
413 ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS,
414 const Instruction *Inst)
415 : ReportAffFunc(RejectReasonKind::NonAffBranch, Inst), BB(BB), LHS(LHS),
416 RHS(RHS) {}
417
418 const SCEV *lhs() { return LHS; }
419 const SCEV *rhs() { return RHS; }
420
421 /// @name LLVM-RTTI interface
422 //@{
423 static bool classof(const RejectReason *RR);
424 //@}
425
426 /// @name RejectReason interface
427 //@{
428 std::string getRemarkName() const override;
429 const Value *getRemarkBB() const override;
430 std::string getMessage() const override;
431 //@}
432};
433
434//===----------------------------------------------------------------------===//
435/// Captures a missing base pointer.
436class ReportNoBasePtr final : public ReportAffFunc {
437public:
438 ReportNoBasePtr(const Instruction *Inst)
439 : ReportAffFunc(RejectReasonKind::NoBasePtr, Inst) {}
440
441 /// @name LLVM-RTTI interface
442 //@{
443 static bool classof(const RejectReason *RR);
444 //@}
445
446 /// @name RejectReason interface
447 //@{
448 std::string getRemarkName() const override;
449 const Value *getRemarkBB() const override;
450 std::string getMessage() const override;
451 //@}
452};
453
454//===----------------------------------------------------------------------===//
455/// Captures an undefined base pointer.
456class ReportUndefBasePtr final : public ReportAffFunc {
457public:
458 ReportUndefBasePtr(const Instruction *Inst)
459 : ReportAffFunc(RejectReasonKind::UndefBasePtr, Inst) {}
460
461 /// @name LLVM-RTTI interface
462 //@{
463 static bool classof(const RejectReason *RR);
464 //@}
465
466 /// @name RejectReason interface
467 //@{
468 std::string getRemarkName() const override;
469 const Value *getRemarkBB() const override;
470 std::string getMessage() const override;
471 //@}
472};
473
474//===----------------------------------------------------------------------===//
475/// Captures a base pointer that is not invariant in the region.
476class ReportVariantBasePtr final : public ReportAffFunc {
477 // The variant base pointer.
478 Value *BaseValue;
479
480public:
481 ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst)
482 : ReportAffFunc(RejectReasonKind::VariantBasePtr, Inst),
483 BaseValue(BaseValue) {}
484
485 /// @name LLVM-RTTI interface
486 //@{
487 static bool classof(const RejectReason *RR);
488 //@}
489
490 /// @name RejectReason interface
491 //@{
492 std::string getRemarkName() const override;
493 const Value *getRemarkBB() const override;
494 std::string getMessage() const override;
495 std::string getEndUserMessage() const override;
496 //@}
497};
498
499//===----------------------------------------------------------------------===//
500/// Captures a non-affine access function.
501class ReportNonAffineAccess final : public ReportAffFunc {
502 // The non-affine access function.
503 const SCEV *AccessFunction;
504
505 // The base pointer of the memory access.
506 const Value *BaseValue;
507
508public:
509 ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst,
510 const Value *V)
511 : ReportAffFunc(RejectReasonKind::NonAffineAccess, Inst),
512 AccessFunction(AccessFunction), BaseValue(V) {}
513
514 const SCEV *get() { return AccessFunction; }
515
516 /// @name LLVM-RTTI interface
517 //@{
518 static bool classof(const RejectReason *RR);
519 //@}
520
521 /// @name RejectReason interface
522 //@{
523 std::string getRemarkName() const override;
524 const Value *getRemarkBB() const override;
525 std::string getMessage() const override;
526 std::string getEndUserMessage() const override;
527 //@}
528};
529
530//===----------------------------------------------------------------------===//
531/// Report array accesses with differing element size.
532class ReportDifferentArrayElementSize final : public ReportAffFunc {
533 // The base pointer of the memory access.
534 const Value *BaseValue;
535
536public:
537 ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V)
538 : ReportAffFunc(RejectReasonKind::DifferentElementSize, Inst),
539 BaseValue(V) {}
540
541 /// @name LLVM-RTTI interface
542 //@{
543 static bool classof(const RejectReason *RR);
544 //@}
545
546 /// @name RejectReason interface
547 //@{
548 std::string getRemarkName() const override;
549 const Value *getRemarkBB() const override;
550 std::string getMessage() const override;
551 std::string getEndUserMessage() const override;
552 //@}
553};
554
555//===----------------------------------------------------------------------===//
556/// Captures errors with non affine loop bounds.
557class ReportLoopBound final : public RejectReason {
558 // The offending loop.
559 Loop *L;
560
561 // The non-affine loop bound.
562 const SCEV *LoopCount;
563
564 // A copy of the offending loop's debug location.
565 const DebugLoc Loc;
566
567public:
568 ReportLoopBound(Loop *L, const SCEV *LoopCount);
569
570 const SCEV *loopCount() { return LoopCount; }
571
572 /// @name LLVM-RTTI interface
573 //@{
574 static bool classof(const RejectReason *RR);
575 //@}
576
577 /// @name RejectReason interface
578 //@{
579 std::string getRemarkName() const override;
580 const Value *getRemarkBB() const override;
581 std::string getMessage() const override;
582 const DebugLoc &getDebugLoc() const override;
583 std::string getEndUserMessage() const override;
584 //@}
585};
586
587//===----------------------------------------------------------------------===//
588/// Captures errors when loop has no exit.
589class ReportLoopHasNoExit final : public RejectReason {
590 /// The loop that has no exit.
591 Loop *L;
592
593 const DebugLoc Loc;
594
595public:
596 ReportLoopHasNoExit(Loop *L)
597 : RejectReason(RejectReasonKind::LoopHasNoExit), L(L),
598 Loc(L->getStartLoc()) {}
599
600 /// @name LLVM-RTTI interface
601 //@{
602 static bool classof(const RejectReason *RR);
603 //@}
604
605 /// @name RejectReason interface
606 //@{
607 std::string getRemarkName() const override;
608 const Value *getRemarkBB() const override;
609 std::string getMessage() const override;
610 const DebugLoc &getDebugLoc() const override;
611 std::string getEndUserMessage() const override;
612 //@}
613};
614
615//===----------------------------------------------------------------------===//
616/// Captures errors when a loop has multiple exists.
617class ReportLoopHasMultipleExits final : public RejectReason {
618 /// The loop that has multiple exits.
619 Loop *L;
620
621 const DebugLoc Loc;
622
623public:
624 ReportLoopHasMultipleExits(Loop *L)
625 : RejectReason(RejectReasonKind::LoopHasMultipleExits), L(L),
626 Loc(L->getStartLoc()) {}
627
628 /// @name LLVM-RTTI interface
629 //@{
630 static bool classof(const RejectReason *RR);
631 //@}
632
633 /// @name RejectReason interface
634 //@{
635 std::string getRemarkName() const override;
636 const Value *getRemarkBB() const override;
637 std::string getMessage() const override;
638 const DebugLoc &getDebugLoc() const override;
639 std::string getEndUserMessage() const override;
640 //@}
641};
642
643//===----------------------------------------------------------------------===//
644/// Captures errors when not all loop latches are part of the scop.
645class ReportLoopOnlySomeLatches final : public RejectReason {
646 /// The loop for which not all loop latches are part of the scop.
647 Loop *L;
648
649 const DebugLoc Loc;
650
651public:
652 ReportLoopOnlySomeLatches(Loop *L)
653 : RejectReason(RejectReasonKind::LoopOnlySomeLatches), L(L),
654 Loc(L->getStartLoc()) {}
655
656 /// @name LLVM-RTTI interface
657 //@{
658 static bool classof(const RejectReason *RR);
659 //@}
660
661 /// @name RejectReason interface
662 //@{
663 std::string getRemarkName() const override;
664 const Value *getRemarkBB() const override;
665 std::string getMessage() const override;
666 const DebugLoc &getDebugLoc() const override;
667 std::string getEndUserMessage() const override;
668 //@}
669};
670
671//===----------------------------------------------------------------------===//
672/// Captures errors with non-side-effect-known function calls.
673class ReportFuncCall final : public RejectReason {
674 // The offending call instruction.
675 Instruction *Inst;
676
677public:
678 ReportFuncCall(Instruction *Inst);
679
680 /// @name LLVM-RTTI interface
681 //@{
682 static bool classof(const RejectReason *RR);
683 //@}
684
685 /// @name RejectReason interface
686 //@{
687 std::string getRemarkName() const override;
688 const Value *getRemarkBB() const override;
689 std::string getMessage() const override;
690 const DebugLoc &getDebugLoc() const override;
691 std::string getEndUserMessage() const override;
692 //@}
693};
694
695//===----------------------------------------------------------------------===//
696/// Captures errors with aliasing.
697class ReportAlias final : public RejectReason {
698public:
699 using PointerSnapshotTy = std::vector<const Value *>;
700
701private:
702 /// Format an invalid alias set.
703 ///
704 // @param Prefix A prefix string to put before the list of aliasing pointers.
705 // @param Suffix A suffix string to put after the list of aliasing pointers.
706 std::string formatInvalidAlias(std::string Prefix = "",
707 std::string Suffix = "") const;
708
709 Instruction *Inst;
710
711 // A snapshot of the llvm values that took part in the aliasing error.
712 mutable PointerSnapshotTy Pointers;
713
714public:
715 ReportAlias(Instruction *Inst, AliasSet &AS);
716
717 const PointerSnapshotTy &getPointers() const { return Pointers; }
718
719 /// @name LLVM-RTTI interface
720 //@{
721 static bool classof(const RejectReason *RR);
722 //@}
723
724 /// @name RejectReason interface
725 //@{
726 std::string getRemarkName() const override;
727 const Value *getRemarkBB() const override;
728 std::string getMessage() const override;
729 const DebugLoc &getDebugLoc() const override;
730 std::string getEndUserMessage() const override;
731 //@}
732};
733
734//===----------------------------------------------------------------------===//
735/// Base class for otherwise ungrouped reject reasons.
736class ReportOther : public RejectReason {
737public:
738 ReportOther(const RejectReasonKind K);
739
740 /// @name LLVM-RTTI interface
741 //@{
742 static bool classof(const RejectReason *RR);
743 //@}
744
745 /// @name RejectReason interface
746 //@{
747 std::string getRemarkName() const override;
748 std::string getMessage() const override;
749 //@}
750};
751
752//===----------------------------------------------------------------------===//
753/// Captures errors with bad IntToPtr instructions.
754class ReportIntToPtr final : public ReportOther {
755 // The offending base value.
756 Instruction *BaseValue;
757
758public:
759 ReportIntToPtr(Instruction *BaseValue);
760
761 /// @name LLVM-RTTI interface
762 //@{
763 static bool classof(const RejectReason *RR);
764 //@}
765
766 /// @name RejectReason interface
767 //@{
768 std::string getRemarkName() const override;
769 const Value *getRemarkBB() const override;
770 std::string getMessage() const override;
771 const DebugLoc &getDebugLoc() const override;
772 //@}
773};
774
775//===----------------------------------------------------------------------===//
776/// Captures errors with alloca instructions.
777class ReportAlloca final : public ReportOther {
778 Instruction *Inst;
779
780public:
781 ReportAlloca(Instruction *Inst);
782
783 /// @name LLVM-RTTI interface
784 //@{
785 static bool classof(const RejectReason *RR);
786 //@}
787
788 /// @name RejectReason interface
789 //@{
790 std::string getRemarkName() const override;
791 const Value *getRemarkBB() const override;
792 std::string getMessage() const override;
793 const DebugLoc &getDebugLoc() const override;
794 //@}
795};
796
797//===----------------------------------------------------------------------===//
798/// Captures errors with unknown instructions.
799class ReportUnknownInst final : public ReportOther {
800 Instruction *Inst;
801
802public:
803 ReportUnknownInst(Instruction *Inst);
804
805 /// @name LLVM-RTTI interface
806 //@{
807 static bool classof(const RejectReason *RR);
808 //@}
809
810 /// @name RejectReason interface
811 //@{
812 std::string getRemarkName() const override;
813 const Value *getRemarkBB() const override;
814 std::string getMessage() const override;
815 const DebugLoc &getDebugLoc() const override;
816 //@}
817};
818
819//===----------------------------------------------------------------------===//
820/// Captures errors with regions containing the function entry block.
821class ReportEntry final : public ReportOther {
822 BasicBlock *BB;
823
824public:
825 ReportEntry(BasicBlock *BB);
826
827 /// @name LLVM-RTTI interface
828 //@{
829 static bool classof(const RejectReason *RR);
830 //@}
831
832 /// @name RejectReason interface
833 //@{
834 std::string getRemarkName() const override;
835 const Value *getRemarkBB() const override;
836 std::string getMessage() const override;
837 std::string getEndUserMessage() const override;
838 const DebugLoc &getDebugLoc() const override;
839 //@}
840};
841
842//===----------------------------------------------------------------------===//
843/// Report regions that seem not profitable to be optimized.
844class ReportUnprofitable final : public ReportOther {
845 Region *R;
846
847public:
848 ReportUnprofitable(Region *R);
849
850 /// @name LLVM-RTTI interface
851 //@{
852 static bool classof(const RejectReason *RR);
853 //@}
854
855 /// @name RejectReason interface
856 //@{
857 std::string getRemarkName() const override;
858 const Value *getRemarkBB() const override;
859 std::string getMessage() const override;
860 std::string getEndUserMessage() const override;
861 const DebugLoc &getDebugLoc() const override;
862 //@}
863};
864
865//===----------------------------------------------------------------------===//
866/// Captures errors with non-simple memory accesses.
867class ReportNonSimpleMemoryAccess final : public ReportOther {
868 // The offending call instruction.
869 Instruction *Inst;
870
871public:
872 ReportNonSimpleMemoryAccess(Instruction *Inst);
873
874 /// @name LLVM-RTTI interface
875 //@{
876 static bool classof(const RejectReason *RR);
877 //@}
878
879 /// @name RejectReason interface
880 //@{
881 std::string getRemarkName() const override;
882 const Value *getRemarkBB() const override;
883 std::string getMessage() const override;
884 const DebugLoc &getDebugLoc() const override;
885 std::string getEndUserMessage() const override;
886 //@}
887};
888} // namespace polly
889
890#endif // POLLY_SCOPDETECTIONDIAGNOSTIC_H
891

source code of polly/include/polly/ScopDetectionDiagnostic.h