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 namespace llvm {
29 class AliasSet;
30 class BasicBlock;
31 class OptimizationRemarkEmitter;
32 class Region;
33 class SCEV;
34 } // namespace llvm
35 
36 namespace polly {
37 using llvm::AliasSet;
38 using llvm::BasicBlock;
39 using llvm::DebugLoc;
40 using llvm::Instruction;
41 using llvm::Loop;
42 using llvm::OptimizationRemarkEmitter;
43 using llvm::raw_ostream;
44 using llvm::Region;
45 using llvm::SCEV;
46 using llvm::SmallVector;
47 using llvm::Value;
48 
49 /// Type to hold region delimiters (entry & exit block).
50 using BBPair = std::pair<BasicBlock *, BasicBlock *>;
51 
52 /// Return the region delimiters (entry & exit block) of @p R.
53 BBPair getBBPairForRegion(const Region *R);
54 
55 /// Set the begin and end source location for the region limited by @p P.
56 void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End);
57 
58 class 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.
66 void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
67                           OptimizationRemarkEmitter &ORE);
68 
69 // Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
70 enum 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.
118 class RejectReason {
119 private:
120   const RejectReasonKind Kind;
121 
122 protected:
123   static const DebugLoc Unknown;
124 
125 public:
126   RejectReason(RejectReasonKind K);
127 
128   virtual ~RejectReason() = default;
129 
getKind()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.
getEndUserMessage()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 
163 using RejectReasonPtr = std::shared_ptr<RejectReason>;
164 
165 /// Stores all errors that occurred during the detection.
166 class RejectLog {
167   Region *R;
168   SmallVector<RejectReasonPtr, 1> ErrorReports;
169 
170 public:
RejectLog(Region * R)171   explicit RejectLog(Region *R) : R(R) {}
172 
173   using iterator = SmallVector<RejectReasonPtr, 1>::const_iterator;
174 
begin()175   iterator begin() const { return ErrorReports.begin(); }
end()176   iterator end() const { return ErrorReports.end(); }
size()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.
hasErrors()182   bool hasErrors() const { return size() > 0; }
183 
184   void print(raw_ostream &OS, int level = 0) const;
185 
region()186   const Region *region() const { return R; }
report(RejectReasonPtr Reject)187   void report(RejectReasonPtr Reject) { ErrorReports.push_back(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.
195 class ReportCFG : public RejectReason {
196 public:
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.
207 class ReportInvalidTerminator : public ReportCFG {
208   BasicBlock *BB;
209 
210 public:
ReportInvalidTerminator(BasicBlock * BB)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.
230 class ReportIrreducibleRegion : public ReportCFG {
231   Region *R;
232   DebugLoc DbgLoc;
233 
234 public:
ReportIrreducibleRegion(Region * R,DebugLoc DbgLoc)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.
255 class ReportUnreachableInExit : public ReportCFG {
256   BasicBlock *BB;
257   DebugLoc DbgLoc;
258 
259 public:
ReportUnreachableInExit(BasicBlock * BB,DebugLoc DbgLoc)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.
281 class ReportIndirectPredecessor : public ReportCFG {
282   Instruction *Inst;
283   DebugLoc DbgLoc;
284 
285 public:
ReportIndirectPredecessor(Instruction * Inst,DebugLoc DbgLoc)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.
310 class ReportAffFunc : public RejectReason {
311 protected:
312   // The instruction that caused non-affinity to occur.
313   const Instruction *Inst;
314 
315 public:
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   //@{
getDebugLoc()325   const DebugLoc &getDebugLoc() const override { return Inst->getDebugLoc(); }
326   //@}
327 };
328 
329 //===----------------------------------------------------------------------===//
330 /// Captures a condition that is based on an 'undef' value.
331 class ReportUndefCond : public ReportAffFunc {
332   // The BasicBlock we found the broken condition in.
333   BasicBlock *BB;
334 
335 public:
ReportUndefCond(const Instruction * Inst,BasicBlock * BB)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.
356 class ReportInvalidCond : public ReportAffFunc {
357   // The BasicBlock we found the broken condition in.
358   BasicBlock *BB;
359 
360 public:
ReportInvalidCond(const Instruction * Inst,BasicBlock * BB)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.
379 class ReportUndefOperand : public ReportAffFunc {
380   // The BasicBlock we found the undefined operand in.
381   BasicBlock *BB;
382 
383 public:
ReportUndefOperand(BasicBlock * BB,const Instruction * Inst)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.
402 class ReportNonAffBranch : 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 
412 public:
ReportNonAffBranch(BasicBlock * BB,const SCEV * LHS,const SCEV * RHS,const Instruction * Inst)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 
lhs()418   const SCEV *lhs() { return LHS; }
rhs()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.
436 class ReportNoBasePtr : public ReportAffFunc {
437 public:
ReportNoBasePtr(const Instruction * Inst)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.
456 class ReportUndefBasePtr : public ReportAffFunc {
457 public:
ReportUndefBasePtr(const Instruction * Inst)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.
476 class ReportVariantBasePtr : public ReportAffFunc {
477   // The variant base pointer.
478   Value *BaseValue;
479 
480 public:
ReportVariantBasePtr(Value * BaseValue,const Instruction * Inst)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.
501 class ReportNonAffineAccess : 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 
508 public:
ReportNonAffineAccess(const SCEV * AccessFunction,const Instruction * Inst,const Value * V)509   ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst,
510                         const Value *V)
511       : ReportAffFunc(RejectReasonKind::NonAffineAccess, Inst),
512         AccessFunction(AccessFunction), BaseValue(V) {}
513 
get()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.
532 class ReportDifferentArrayElementSize : public ReportAffFunc {
533   // The base pointer of the memory access.
534   const Value *BaseValue;
535 
536 public:
ReportDifferentArrayElementSize(const Instruction * Inst,const Value * V)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.
557 class ReportLoopBound : 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 
567 public:
568   ReportLoopBound(Loop *L, const SCEV *LoopCount);
569 
loopCount()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.
589 class ReportLoopHasNoExit : public RejectReason {
590   /// The loop that has no exit.
591   Loop *L;
592 
593   const DebugLoc Loc;
594 
595 public:
ReportLoopHasNoExit(Loop * L)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.
617 class ReportLoopHasMultipleExits : public RejectReason {
618   /// The loop that has multiple exits.
619   Loop *L;
620 
621   const DebugLoc Loc;
622 
623 public:
ReportLoopHasMultipleExits(Loop * L)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.
645 class ReportLoopOnlySomeLatches : 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 
651 public:
ReportLoopOnlySomeLatches(Loop * L)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.
673 class ReportFuncCall : public RejectReason {
674   // The offending call instruction.
675   Instruction *Inst;
676 
677 public:
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.
697 class ReportAlias : public RejectReason {
698 public:
699   using PointerSnapshotTy = std::vector<const Value *>;
700 
701 private:
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 
714 public:
715   ReportAlias(Instruction *Inst, AliasSet &AS);
716 
getPointers()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.
736 class ReportOther : public RejectReason {
737 public:
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.
754 class ReportIntToPtr : public ReportOther {
755   // The offending base value.
756   Instruction *BaseValue;
757 
758 public:
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.
777 class ReportAlloca : public ReportOther {
778   Instruction *Inst;
779 
780 public:
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.
799 class ReportUnknownInst : public ReportOther {
800   Instruction *Inst;
801 
802 public:
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.
821 class ReportEntry : public ReportOther {
822   BasicBlock *BB;
823 
824 public:
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.
844 class ReportUnprofitable : public ReportOther {
845   Region *R;
846 
847 public:
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.
867 class ReportNonSimpleMemoryAccess : public ReportOther {
868   // The offending call instruction.
869   Instruction *Inst;
870 
871 public:
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