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