[ScopInfo] Add missing ISL annotations NFC.
[polly-mirror.git] / include / polly / ScopDetectionDiagnostic.h
blob350522f24aa851f0c09400c63bf34bc1a87e091d
1 //=== ScopDetectionDiagnostic.h -- Diagnostic for ScopDetection -*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
20 #ifndef POLLY_SCOP_DETECTION_DIAGNOSTIC_H
21 #define POLLY_SCOP_DETECTION_DIAGNOSTIC_H
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/Analysis/AliasSetTracker.h"
27 #include "llvm/Analysis/LoopInfo.h"
28 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
29 #include "llvm/IR/BasicBlock.h"
30 #include "llvm/IR/Value.h"
31 #include "llvm/Support/Casting.h"
32 #include <memory>
33 #include <string>
35 using namespace llvm;
37 namespace llvm {
38 class SCEV;
39 class BasicBlock;
40 class Value;
41 class Region;
42 } // namespace llvm
44 namespace polly {
46 /// @brief Type to hold region delimiters (entry & exit block).
47 using BBPair = std::pair<BasicBlock *, BasicBlock *>;
49 /// @brief Return the region delimiters (entry & exit block) of @p R.
50 BBPair getBBPairForRegion(const Region *R);
52 /// @brief Set the begin and end source location for the region limited by @p P.
53 void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End);
55 class RejectLog;
56 /// @brief Emit optimization remarks about the rejected regions to the user.
57 ///
58 /// This emits the content of the reject log as optimization remarks.
59 /// Remember to at least track failures (-polly-detect-track-failures).
60 /// @param P The region delimiters (entry & exit) we emit remarks for.
61 /// @param Log The error log containing all messages being emitted as remark.
62 void emitRejectionRemarks(const BBPair &P, const RejectLog &Log);
64 // Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
65 enum RejectReasonKind {
66 // CFG Category
67 rrkCFG,
68 rrkInvalidTerminator,
69 rrkCondition,
70 rrkLastCFG,
71 rrkIrreducibleRegion,
73 // Non-Affinity
74 rrkAffFunc,
75 rrkUndefCond,
76 rrkInvalidCond,
77 rrkUndefOperand,
78 rrkNonAffBranch,
79 rrkNoBasePtr,
80 rrkUndefBasePtr,
81 rrkVariantBasePtr,
82 rrkNonAffineAccess,
83 rrkDifferentElementSize,
84 rrkLastAffFunc,
86 rrkLoopBound,
87 rrkLoopOverlapWithNonAffineSubRegion,
89 rrkFuncCall,
90 rrkNonSimpleMemoryAccess,
92 rrkAlias,
94 // Other
95 rrkOther,
96 rrkIntToPtr,
97 rrkAlloca,
98 rrkUnknownInst,
99 rrkEntry,
100 rrkUnprofitable,
101 rrkLastOther
104 //===----------------------------------------------------------------------===//
105 /// @brief Base class of all reject reasons found during Scop detection.
107 /// Subclasses of RejectReason should provide means to capture enough
108 /// diagnostic information to help clients figure out what and where something
109 /// went wrong in the Scop detection.
110 class RejectReason {
111 //===--------------------------------------------------------------------===//
112 private:
113 const RejectReasonKind Kind;
115 protected:
116 static const DebugLoc Unknown;
118 public:
119 RejectReasonKind getKind() const { return Kind; }
121 RejectReason(RejectReasonKind K) : Kind(K) {}
123 virtual ~RejectReason() {}
125 /// @brief Generate a reasonable diagnostic message describing this error.
127 /// @return A debug message representing this error.
128 virtual std::string getMessage() const = 0;
130 /// @brief Generate a message for the end-user describing this error.
132 /// The message provided has to be suitable for the end-user. So it should
133 /// not reference any LLVM internal data structures or terminology.
134 /// Ideally, the message helps the end-user to increase the size of the
135 /// regions amenable to Polly.
137 /// @return A short message representing this error.
138 virtual std::string getEndUserMessage() const { return "Unspecified error."; }
140 /// @brief Get the source location of this error.
142 /// @return The debug location for this error.
143 virtual const llvm::DebugLoc &getDebugLoc() const;
146 typedef std::shared_ptr<RejectReason> RejectReasonPtr;
148 /// @brief Stores all errors that ocurred during the detection.
149 class RejectLog {
150 Region *R;
151 llvm::SmallVector<RejectReasonPtr, 1> ErrorReports;
153 public:
154 explicit RejectLog(Region *R) : R(R) {}
156 typedef llvm::SmallVector<RejectReasonPtr, 1>::const_iterator iterator;
158 iterator begin() const { return ErrorReports.begin(); }
159 iterator end() const { return ErrorReports.end(); }
160 size_t size() const { return ErrorReports.size(); }
162 /// @brief Returns true, if we store at least one error.
164 /// @return true, if we store at least one error.
165 bool hasErrors() const { return size() > 0; }
167 void print(raw_ostream &OS, int level = 0) const;
169 const Region *region() const { return R; }
170 void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); }
173 //===----------------------------------------------------------------------===//
174 /// @brief Base class for CFG related reject reasons.
176 /// Scop candidates that violate structural restrictions can be grouped under
177 /// this reject reason class.
178 class ReportCFG : public RejectReason {
179 //===--------------------------------------------------------------------===//
180 public:
181 ReportCFG(const RejectReasonKind K);
183 /// @name LLVM-RTTI interface
184 //@{
185 static bool classof(const RejectReason *RR);
186 //@}
189 //===----------------------------------------------------------------------===//
190 /// @brief Captures bad terminator within a Scop candidate.
191 class ReportInvalidTerminator : public ReportCFG {
192 BasicBlock *BB;
194 public:
195 ReportInvalidTerminator(BasicBlock *BB)
196 : ReportCFG(rrkInvalidTerminator), BB(BB) {}
198 /// @name LLVM-RTTI interface
199 //@{
200 static bool classof(const RejectReason *RR);
201 //@}
203 /// @name RejectReason interface
204 //@{
205 virtual std::string getMessage() const override;
206 virtual const DebugLoc &getDebugLoc() const override;
207 //@}
210 //===----------------------------------------------------------------------===//
211 /// @brief Captures irreducible regions in CFG.
212 class ReportIrreducibleRegion : public ReportCFG {
213 Region *R;
214 DebugLoc DbgLoc;
216 public:
217 ReportIrreducibleRegion(Region *R, DebugLoc DbgLoc)
218 : ReportCFG(rrkIrreducibleRegion), R(R), DbgLoc(DbgLoc) {}
220 /// @name LLVM-RTTI interface
221 //@{
222 static bool classof(const RejectReason *RR);
223 //@}
225 /// @name RejectReason interface
226 //@{
227 virtual std::string getMessage() const override;
228 virtual std::string getEndUserMessage() const override;
229 virtual const DebugLoc &getDebugLoc() const override;
230 //@}
233 //===----------------------------------------------------------------------===//
234 /// @brief Base class for non-affine reject reasons.
236 /// Scop candidates that violate restrictions to affinity are reported under
237 /// this class.
238 class ReportAffFunc : public RejectReason {
239 //===--------------------------------------------------------------------===//
241 // The instruction that caused non-affinity to occur.
242 const Instruction *Inst;
244 public:
245 ReportAffFunc(const RejectReasonKind K, const Instruction *Inst);
247 /// @name LLVM-RTTI interface
248 //@{
249 static bool classof(const RejectReason *RR);
250 //@}
252 /// @name RejectReason interface
253 //@{
254 virtual const DebugLoc &getDebugLoc() const override {
255 return Inst->getDebugLoc();
257 //@}
260 //===----------------------------------------------------------------------===//
261 /// @brief Captures a condition that is based on an 'undef' value.
262 class ReportUndefCond : public ReportAffFunc {
263 //===--------------------------------------------------------------------===//
265 // The BasicBlock we found the broken condition in.
266 BasicBlock *BB;
268 public:
269 ReportUndefCond(const Instruction *Inst, BasicBlock *BB)
270 : ReportAffFunc(rrkUndefCond, Inst), BB(BB) {}
272 /// @name LLVM-RTTI interface
273 //@{
274 static bool classof(const RejectReason *RR);
275 //@}
277 /// @name RejectReason interface
278 //@{
279 virtual std::string getMessage() const override;
280 //@}
283 //===----------------------------------------------------------------------===//
284 /// @brief Captures an invalid condition
286 /// Conditions have to be either constants or icmp instructions.
287 class ReportInvalidCond : public ReportAffFunc {
288 //===--------------------------------------------------------------------===//
290 // The BasicBlock we found the broken condition in.
291 BasicBlock *BB;
293 public:
294 ReportInvalidCond(const Instruction *Inst, BasicBlock *BB)
295 : ReportAffFunc(rrkInvalidCond, Inst), BB(BB) {}
297 /// @name LLVM-RTTI interface
298 //@{
299 static bool classof(const RejectReason *RR);
300 //@}
302 /// @name RejectReason interface
303 //@{
304 virtual std::string getMessage() const override;
305 //@}
308 //===----------------------------------------------------------------------===//
309 /// @brief Captures an undefined operand.
310 class ReportUndefOperand : public ReportAffFunc {
311 //===--------------------------------------------------------------------===//
313 // The BasicBlock we found the undefined operand in.
314 BasicBlock *BB;
316 public:
317 ReportUndefOperand(BasicBlock *BB, const Instruction *Inst)
318 : ReportAffFunc(rrkUndefOperand, Inst), BB(BB) {}
320 /// @name LLVM-RTTI interface
321 //@{
322 static bool classof(const RejectReason *RR);
323 //@}
325 /// @name RejectReason interface
326 //@{
327 virtual std::string getMessage() const override;
328 //@}
331 //===----------------------------------------------------------------------===//
332 /// @brief Captures a non-affine branch.
333 class ReportNonAffBranch : public ReportAffFunc {
334 //===--------------------------------------------------------------------===//
336 // The BasicBlock we found the non-affine branch in.
337 BasicBlock *BB;
339 /// @brief LHS & RHS of the failed condition.
340 //@{
341 const SCEV *LHS;
342 const SCEV *RHS;
343 //@}
345 public:
346 ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS,
347 const Instruction *Inst)
348 : ReportAffFunc(rrkNonAffBranch, Inst), BB(BB), LHS(LHS), RHS(RHS) {}
350 const SCEV *lhs() { return LHS; }
351 const SCEV *rhs() { return RHS; }
353 /// @name LLVM-RTTI interface
354 //@{
355 static bool classof(const RejectReason *RR);
356 //@}
358 /// @name RejectReason interface
359 //@{
360 virtual std::string getMessage() const override;
361 //@}
364 //===----------------------------------------------------------------------===//
365 /// @brief Captures a missing base pointer.
366 class ReportNoBasePtr : public ReportAffFunc {
367 //===--------------------------------------------------------------------===//
368 public:
369 ReportNoBasePtr(const Instruction *Inst)
370 : ReportAffFunc(rrkNoBasePtr, Inst) {}
372 /// @name LLVM-RTTI interface
373 //@{
374 static bool classof(const RejectReason *RR);
375 //@}
377 /// @name RejectReason interface
378 //@{
379 virtual std::string getMessage() const override;
380 //@}
383 //===----------------------------------------------------------------------===//
384 /// @brief Captures an undefined base pointer.
385 class ReportUndefBasePtr : public ReportAffFunc {
386 //===--------------------------------------------------------------------===//
387 public:
388 ReportUndefBasePtr(const Instruction *Inst)
389 : ReportAffFunc(rrkUndefBasePtr, Inst) {}
391 /// @name LLVM-RTTI interface
392 //@{
393 static bool classof(const RejectReason *RR);
394 //@}
396 /// @name RejectReason interface
397 //@{
398 virtual std::string getMessage() const override;
399 //@}
402 //===----------------------------------------------------------------------===//
403 /// @brief Captures a base pointer that is not invariant in the region.
404 class ReportVariantBasePtr : public ReportAffFunc {
405 //===--------------------------------------------------------------------===//
407 // The variant base pointer.
408 Value *BaseValue;
410 public:
411 ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst)
412 : ReportAffFunc(rrkVariantBasePtr, Inst), BaseValue(BaseValue) {}
414 /// @name LLVM-RTTI interface
415 //@{
416 static bool classof(const RejectReason *RR);
417 //@}
419 /// @name RejectReason interface
420 //@{
421 virtual std::string getMessage() const override;
422 virtual std::string getEndUserMessage() const override;
423 //@}
426 //===----------------------------------------------------------------------===//
427 /// @brief Captures a non-affine access function.
428 class ReportNonAffineAccess : public ReportAffFunc {
429 //===--------------------------------------------------------------------===//
431 // The non-affine access function.
432 const SCEV *AccessFunction;
434 // The base pointer of the memory access.
435 const Value *BaseValue;
437 public:
438 ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst,
439 const Value *V)
440 : ReportAffFunc(rrkNonAffineAccess, Inst), AccessFunction(AccessFunction),
441 BaseValue(V) {}
443 const SCEV *get() { return AccessFunction; }
445 /// @name LLVM-RTTI interface
446 //@{
447 static bool classof(const RejectReason *RR);
448 //@}
450 /// @name RejectReason interface
451 //@{
452 virtual std::string getMessage() const override;
453 virtual std::string getEndUserMessage() const override;
454 //@}
457 //===----------------------------------------------------------------------===//
458 /// @brief Report array accesses with differing element size.
459 class ReportDifferentArrayElementSize : public ReportAffFunc {
460 //===--------------------------------------------------------------------===//
462 // The base pointer of the memory access.
463 const Value *BaseValue;
465 public:
466 ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V)
467 : ReportAffFunc(rrkDifferentElementSize, Inst), BaseValue(V) {}
469 /// @name LLVM-RTTI interface
470 //@{
471 static bool classof(const RejectReason *RR);
472 //@}
474 /// @name RejectReason interface
475 //@{
476 virtual std::string getMessage() const override;
477 virtual std::string getEndUserMessage() const override;
478 //@}
481 //===----------------------------------------------------------------------===//
482 /// @brief Captures errors with non affine loop bounds.
483 class ReportLoopBound : public RejectReason {
484 //===--------------------------------------------------------------------===//
486 // The offending loop.
487 Loop *L;
489 // The non-affine loop bound.
490 const SCEV *LoopCount;
492 // A copy of the offending loop's debug location.
493 const DebugLoc Loc;
495 public:
496 ReportLoopBound(Loop *L, const SCEV *LoopCount);
498 const SCEV *loopCount() { return LoopCount; }
500 /// @name LLVM-RTTI interface
501 //@{
502 static bool classof(const RejectReason *RR);
503 //@}
505 /// @name RejectReason interface
506 //@{
507 virtual std::string getMessage() const override;
508 virtual const DebugLoc &getDebugLoc() const override;
509 virtual std::string getEndUserMessage() const override;
510 //@}
513 //===----------------------------------------------------------------------===//
514 /// @brief Captures errors when loop overlap with nonaffine subregion.
515 class ReportLoopOverlapWithNonAffineSubRegion : public RejectReason {
516 //===--------------------------------------------------------------------===//
518 /// @brief If L and R are set then L and R overlap.
520 /// The loop contains stmt overlapping nonaffine subregion.
521 Loop *L;
523 /// The nonaffine subregion that contains infinite loop.
524 Region *R;
526 const DebugLoc Loc;
528 public:
529 ReportLoopOverlapWithNonAffineSubRegion(Loop *L, Region *R);
531 /// @name LLVM-RTTI interface
532 //@{
533 static bool classof(const RejectReason *RR);
534 //@}
536 /// @name RejectReason interface
537 //@{
538 virtual std::string getMessage() const override;
539 virtual const DebugLoc &getDebugLoc() const override;
540 virtual std::string getEndUserMessage() const override;
541 //@}
544 //===----------------------------------------------------------------------===//
545 /// @brief Captures errors with non-side-effect-known function calls.
546 class ReportFuncCall : public RejectReason {
547 //===--------------------------------------------------------------------===//
549 // The offending call instruction.
550 Instruction *Inst;
552 public:
553 ReportFuncCall(Instruction *Inst);
555 /// @name LLVM-RTTI interface
556 //@{
557 static bool classof(const RejectReason *RR);
558 //@}
560 /// @name RejectReason interface
561 //@{
562 virtual std::string getMessage() const override;
563 virtual const DebugLoc &getDebugLoc() const override;
564 virtual std::string getEndUserMessage() const override;
565 //@}
568 //===----------------------------------------------------------------------===//
569 /// @brief Captures errors with aliasing.
570 class ReportAlias : public RejectReason {
571 //===--------------------------------------------------------------------===//
572 public:
573 typedef std::vector<const llvm::Value *> PointerSnapshotTy;
575 private:
576 /// @brief Format an invalid alias set.
578 // @param Prefix A prefix string to put before the list of aliasing pointers.
579 // @param Suffix A suffix string to put after the list of aliasing pointers.
580 std::string formatInvalidAlias(std::string Prefix = "",
581 std::string Suffix = "") const;
583 Instruction *Inst;
585 // A snapshot of the llvm values that took part in the aliasing error.
586 mutable PointerSnapshotTy Pointers;
588 public:
589 ReportAlias(Instruction *Inst, AliasSet &AS);
591 const PointerSnapshotTy &getPointers() const { return Pointers; }
593 /// @name LLVM-RTTI interface
594 //@{
595 static bool classof(const RejectReason *RR);
596 //@}
598 /// @name RejectReason interface
599 //@{
600 virtual std::string getMessage() const override;
601 virtual const DebugLoc &getDebugLoc() const override;
602 virtual std::string getEndUserMessage() const override;
603 //@}
606 //===----------------------------------------------------------------------===//
607 /// @brief Base class for otherwise ungrouped reject reasons.
608 class ReportOther : public RejectReason {
609 //===--------------------------------------------------------------------===//
610 public:
611 ReportOther(const RejectReasonKind K);
613 /// @name LLVM-RTTI interface
614 //@{
615 static bool classof(const RejectReason *RR);
616 //@}
618 /// @name RejectReason interface
619 //@{
620 virtual std::string getMessage() const override;
621 //@}
624 //===----------------------------------------------------------------------===//
625 /// @brief Captures errors with bad IntToPtr instructions.
626 class ReportIntToPtr : public ReportOther {
627 //===--------------------------------------------------------------------===//
629 // The offending base value.
630 Instruction *BaseValue;
632 public:
633 ReportIntToPtr(Instruction *BaseValue);
635 /// @name LLVM-RTTI interface
636 //@{
637 static bool classof(const RejectReason *RR);
638 //@}
640 /// @name RejectReason interface
641 //@{
642 virtual std::string getMessage() const override;
643 virtual const DebugLoc &getDebugLoc() const override;
644 //@}
647 //===----------------------------------------------------------------------===//
648 /// @brief Captures errors with alloca instructions.
649 class ReportAlloca : public ReportOther {
650 //===--------------------------------------------------------------------===//
651 Instruction *Inst;
653 public:
654 ReportAlloca(Instruction *Inst);
656 /// @name LLVM-RTTI interface
657 //@{
658 static bool classof(const RejectReason *RR);
659 //@}
661 /// @name RejectReason interface
662 //@{
663 virtual std::string getMessage() const override;
664 virtual const DebugLoc &getDebugLoc() const override;
665 //@}
668 //===----------------------------------------------------------------------===//
669 /// @brief Captures errors with unknown instructions.
670 class ReportUnknownInst : public ReportOther {
671 //===--------------------------------------------------------------------===//
672 Instruction *Inst;
674 public:
675 ReportUnknownInst(Instruction *Inst);
677 /// @name LLVM-RTTI interface
678 //@{
679 static bool classof(const RejectReason *RR);
680 //@}
682 /// @name RejectReason interface
683 //@{
684 virtual std::string getMessage() const override;
685 virtual const DebugLoc &getDebugLoc() const override;
686 //@}
689 //===----------------------------------------------------------------------===//
690 /// @brief Captures errors with regions containing the function entry block.
691 class ReportEntry : public ReportOther {
692 //===--------------------------------------------------------------------===//
693 BasicBlock *BB;
695 public:
696 ReportEntry(BasicBlock *BB);
698 /// @name LLVM-RTTI interface
699 //@{
700 static bool classof(const RejectReason *RR);
701 //@}
703 /// @name RejectReason interface
704 //@{
705 virtual std::string getMessage() const override;
706 virtual const DebugLoc &getDebugLoc() const override;
707 //@}
710 //===----------------------------------------------------------------------===//
711 /// @brief Report regions that seem not profitable to be optimized.
712 class ReportUnprofitable : public ReportOther {
713 //===--------------------------------------------------------------------===//
714 Region *R;
716 public:
717 ReportUnprofitable(Region *R);
719 /// @name LLVM-RTTI interface
720 //@{
721 static bool classof(const RejectReason *RR);
722 //@}
724 /// @name RejectReason interface
725 //@{
726 virtual std::string getMessage() const override;
727 virtual std::string getEndUserMessage() const override;
728 virtual const DebugLoc &getDebugLoc() const override;
729 //@}
732 //===----------------------------------------------------------------------===//
733 /// @brief Captures errors with non-simple memory accesses.
734 class ReportNonSimpleMemoryAccess : public ReportOther {
735 //===--------------------------------------------------------------------===//
737 // The offending call instruction.
738 Instruction *Inst;
740 public:
741 ReportNonSimpleMemoryAccess(Instruction *Inst);
743 /// @name LLVM-RTTI interface
744 //@{
745 static bool classof(const RejectReason *RR);
746 //@}
748 /// @name RejectReason interface
749 //@{
750 virtual std::string getMessage() const override;
751 virtual const DebugLoc &getDebugLoc() const override;
752 virtual std::string getEndUserMessage() const override;
753 //@}
756 } // namespace polly
758 #endif // POLLY_SCOP_DETECTION_DIAGNOSTIC_H