1 //=== ScopDetectionDiagnostic.h -- Diagnostic for ScopDetection -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
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"
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
);
56 /// @brief Emit optimization remarks about the rejected regions to the user.
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
{
83 rrkDifferentElementSize
,
87 rrkLoopOverlapWithNonAffineSubRegion
,
90 rrkNonSimpleMemoryAccess
,
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.
111 //===--------------------------------------------------------------------===//
113 const RejectReasonKind Kind
;
116 static const DebugLoc Unknown
;
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.
151 llvm::SmallVector
<RejectReasonPtr
, 1> ErrorReports
;
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 //===--------------------------------------------------------------------===//
181 ReportCFG(const RejectReasonKind K
);
183 /// @name LLVM-RTTI interface
185 static bool classof(const RejectReason
*RR
);
189 //===----------------------------------------------------------------------===//
190 /// @brief Captures bad terminator within a Scop candidate.
191 class ReportInvalidTerminator
: public ReportCFG
{
195 ReportInvalidTerminator(BasicBlock
*BB
)
196 : ReportCFG(rrkInvalidTerminator
), BB(BB
) {}
198 /// @name LLVM-RTTI interface
200 static bool classof(const RejectReason
*RR
);
203 /// @name RejectReason interface
205 virtual std::string
getMessage() const override
;
206 virtual const DebugLoc
&getDebugLoc() const override
;
210 //===----------------------------------------------------------------------===//
211 /// @brief Captures irreducible regions in CFG.
212 class ReportIrreducibleRegion
: public ReportCFG
{
217 ReportIrreducibleRegion(Region
*R
, DebugLoc DbgLoc
)
218 : ReportCFG(rrkIrreducibleRegion
), R(R
), DbgLoc(DbgLoc
) {}
220 /// @name LLVM-RTTI interface
222 static bool classof(const RejectReason
*RR
);
225 /// @name RejectReason interface
227 virtual std::string
getMessage() const override
;
228 virtual std::string
getEndUserMessage() const override
;
229 virtual const DebugLoc
&getDebugLoc() const override
;
233 //===----------------------------------------------------------------------===//
234 /// @brief Base class for non-affine reject reasons.
236 /// Scop candidates that violate restrictions to affinity are reported under
238 class ReportAffFunc
: public RejectReason
{
239 //===--------------------------------------------------------------------===//
241 // The instruction that caused non-affinity to occur.
242 const Instruction
*Inst
;
245 ReportAffFunc(const RejectReasonKind K
, const Instruction
*Inst
);
247 /// @name LLVM-RTTI interface
249 static bool classof(const RejectReason
*RR
);
252 /// @name RejectReason interface
254 virtual const DebugLoc
&getDebugLoc() const override
{
255 return Inst
->getDebugLoc();
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.
269 ReportUndefCond(const Instruction
*Inst
, BasicBlock
*BB
)
270 : ReportAffFunc(rrkUndefCond
, Inst
), BB(BB
) {}
272 /// @name LLVM-RTTI interface
274 static bool classof(const RejectReason
*RR
);
277 /// @name RejectReason interface
279 virtual std::string
getMessage() const override
;
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.
294 ReportInvalidCond(const Instruction
*Inst
, BasicBlock
*BB
)
295 : ReportAffFunc(rrkInvalidCond
, Inst
), BB(BB
) {}
297 /// @name LLVM-RTTI interface
299 static bool classof(const RejectReason
*RR
);
302 /// @name RejectReason interface
304 virtual std::string
getMessage() const override
;
308 //===----------------------------------------------------------------------===//
309 /// @brief Captures an undefined operand.
310 class ReportUndefOperand
: public ReportAffFunc
{
311 //===--------------------------------------------------------------------===//
313 // The BasicBlock we found the undefined operand in.
317 ReportUndefOperand(BasicBlock
*BB
, const Instruction
*Inst
)
318 : ReportAffFunc(rrkUndefOperand
, Inst
), BB(BB
) {}
320 /// @name LLVM-RTTI interface
322 static bool classof(const RejectReason
*RR
);
325 /// @name RejectReason interface
327 virtual std::string
getMessage() const override
;
331 //===----------------------------------------------------------------------===//
332 /// @brief Captures a non-affine branch.
333 class ReportNonAffBranch
: public ReportAffFunc
{
334 //===--------------------------------------------------------------------===//
336 // The BasicBlock we found the non-affine branch in.
339 /// @brief LHS & RHS of the failed condition.
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
355 static bool classof(const RejectReason
*RR
);
358 /// @name RejectReason interface
360 virtual std::string
getMessage() const override
;
364 //===----------------------------------------------------------------------===//
365 /// @brief Captures a missing base pointer.
366 class ReportNoBasePtr
: public ReportAffFunc
{
367 //===--------------------------------------------------------------------===//
369 ReportNoBasePtr(const Instruction
*Inst
)
370 : ReportAffFunc(rrkNoBasePtr
, Inst
) {}
372 /// @name LLVM-RTTI interface
374 static bool classof(const RejectReason
*RR
);
377 /// @name RejectReason interface
379 virtual std::string
getMessage() const override
;
383 //===----------------------------------------------------------------------===//
384 /// @brief Captures an undefined base pointer.
385 class ReportUndefBasePtr
: public ReportAffFunc
{
386 //===--------------------------------------------------------------------===//
388 ReportUndefBasePtr(const Instruction
*Inst
)
389 : ReportAffFunc(rrkUndefBasePtr
, Inst
) {}
391 /// @name LLVM-RTTI interface
393 static bool classof(const RejectReason
*RR
);
396 /// @name RejectReason interface
398 virtual std::string
getMessage() const override
;
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.
411 ReportVariantBasePtr(Value
*BaseValue
, const Instruction
*Inst
)
412 : ReportAffFunc(rrkVariantBasePtr
, Inst
), BaseValue(BaseValue
) {}
414 /// @name LLVM-RTTI interface
416 static bool classof(const RejectReason
*RR
);
419 /// @name RejectReason interface
421 virtual std::string
getMessage() const override
;
422 virtual std::string
getEndUserMessage() const override
;
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
;
438 ReportNonAffineAccess(const SCEV
*AccessFunction
, const Instruction
*Inst
,
440 : ReportAffFunc(rrkNonAffineAccess
, Inst
), AccessFunction(AccessFunction
),
443 const SCEV
*get() { return AccessFunction
; }
445 /// @name LLVM-RTTI interface
447 static bool classof(const RejectReason
*RR
);
450 /// @name RejectReason interface
452 virtual std::string
getMessage() const override
;
453 virtual std::string
getEndUserMessage() const override
;
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
;
466 ReportDifferentArrayElementSize(const Instruction
*Inst
, const Value
*V
)
467 : ReportAffFunc(rrkDifferentElementSize
, Inst
), BaseValue(V
) {}
469 /// @name LLVM-RTTI interface
471 static bool classof(const RejectReason
*RR
);
474 /// @name RejectReason interface
476 virtual std::string
getMessage() const override
;
477 virtual std::string
getEndUserMessage() const override
;
481 //===----------------------------------------------------------------------===//
482 /// @brief Captures errors with non affine loop bounds.
483 class ReportLoopBound
: public RejectReason
{
484 //===--------------------------------------------------------------------===//
486 // The offending loop.
489 // The non-affine loop bound.
490 const SCEV
*LoopCount
;
492 // A copy of the offending loop's debug location.
496 ReportLoopBound(Loop
*L
, const SCEV
*LoopCount
);
498 const SCEV
*loopCount() { return LoopCount
; }
500 /// @name LLVM-RTTI interface
502 static bool classof(const RejectReason
*RR
);
505 /// @name RejectReason interface
507 virtual std::string
getMessage() const override
;
508 virtual const DebugLoc
&getDebugLoc() const override
;
509 virtual std::string
getEndUserMessage() const override
;
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.
523 /// The nonaffine subregion that contains infinite loop.
529 ReportLoopOverlapWithNonAffineSubRegion(Loop
*L
, Region
*R
);
531 /// @name LLVM-RTTI interface
533 static bool classof(const RejectReason
*RR
);
536 /// @name RejectReason interface
538 virtual std::string
getMessage() const override
;
539 virtual const DebugLoc
&getDebugLoc() const override
;
540 virtual std::string
getEndUserMessage() const override
;
544 //===----------------------------------------------------------------------===//
545 /// @brief Captures errors with non-side-effect-known function calls.
546 class ReportFuncCall
: public RejectReason
{
547 //===--------------------------------------------------------------------===//
549 // The offending call instruction.
553 ReportFuncCall(Instruction
*Inst
);
555 /// @name LLVM-RTTI interface
557 static bool classof(const RejectReason
*RR
);
560 /// @name RejectReason interface
562 virtual std::string
getMessage() const override
;
563 virtual const DebugLoc
&getDebugLoc() const override
;
564 virtual std::string
getEndUserMessage() const override
;
568 //===----------------------------------------------------------------------===//
569 /// @brief Captures errors with aliasing.
570 class ReportAlias
: public RejectReason
{
571 //===--------------------------------------------------------------------===//
573 typedef std::vector
<const llvm::Value
*> PointerSnapshotTy
;
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;
585 // A snapshot of the llvm values that took part in the aliasing error.
586 mutable PointerSnapshotTy Pointers
;
589 ReportAlias(Instruction
*Inst
, AliasSet
&AS
);
591 const PointerSnapshotTy
&getPointers() const { return Pointers
; }
593 /// @name LLVM-RTTI interface
595 static bool classof(const RejectReason
*RR
);
598 /// @name RejectReason interface
600 virtual std::string
getMessage() const override
;
601 virtual const DebugLoc
&getDebugLoc() const override
;
602 virtual std::string
getEndUserMessage() const override
;
606 //===----------------------------------------------------------------------===//
607 /// @brief Base class for otherwise ungrouped reject reasons.
608 class ReportOther
: public RejectReason
{
609 //===--------------------------------------------------------------------===//
611 ReportOther(const RejectReasonKind K
);
613 /// @name LLVM-RTTI interface
615 static bool classof(const RejectReason
*RR
);
618 /// @name RejectReason interface
620 virtual std::string
getMessage() const override
;
624 //===----------------------------------------------------------------------===//
625 /// @brief Captures errors with bad IntToPtr instructions.
626 class ReportIntToPtr
: public ReportOther
{
627 //===--------------------------------------------------------------------===//
629 // The offending base value.
630 Instruction
*BaseValue
;
633 ReportIntToPtr(Instruction
*BaseValue
);
635 /// @name LLVM-RTTI interface
637 static bool classof(const RejectReason
*RR
);
640 /// @name RejectReason interface
642 virtual std::string
getMessage() const override
;
643 virtual const DebugLoc
&getDebugLoc() const override
;
647 //===----------------------------------------------------------------------===//
648 /// @brief Captures errors with alloca instructions.
649 class ReportAlloca
: public ReportOther
{
650 //===--------------------------------------------------------------------===//
654 ReportAlloca(Instruction
*Inst
);
656 /// @name LLVM-RTTI interface
658 static bool classof(const RejectReason
*RR
);
661 /// @name RejectReason interface
663 virtual std::string
getMessage() const override
;
664 virtual const DebugLoc
&getDebugLoc() const override
;
668 //===----------------------------------------------------------------------===//
669 /// @brief Captures errors with unknown instructions.
670 class ReportUnknownInst
: public ReportOther
{
671 //===--------------------------------------------------------------------===//
675 ReportUnknownInst(Instruction
*Inst
);
677 /// @name LLVM-RTTI interface
679 static bool classof(const RejectReason
*RR
);
682 /// @name RejectReason interface
684 virtual std::string
getMessage() const override
;
685 virtual const DebugLoc
&getDebugLoc() const override
;
689 //===----------------------------------------------------------------------===//
690 /// @brief Captures errors with regions containing the function entry block.
691 class ReportEntry
: public ReportOther
{
692 //===--------------------------------------------------------------------===//
696 ReportEntry(BasicBlock
*BB
);
698 /// @name LLVM-RTTI interface
700 static bool classof(const RejectReason
*RR
);
703 /// @name RejectReason interface
705 virtual std::string
getMessage() const override
;
706 virtual const DebugLoc
&getDebugLoc() const override
;
710 //===----------------------------------------------------------------------===//
711 /// @brief Report regions that seem not profitable to be optimized.
712 class ReportUnprofitable
: public ReportOther
{
713 //===--------------------------------------------------------------------===//
717 ReportUnprofitable(Region
*R
);
719 /// @name LLVM-RTTI interface
721 static bool classof(const RejectReason
*RR
);
724 /// @name RejectReason interface
726 virtual std::string
getMessage() const override
;
727 virtual std::string
getEndUserMessage() const override
;
728 virtual const DebugLoc
&getDebugLoc() const override
;
732 //===----------------------------------------------------------------------===//
733 /// @brief Captures errors with non-simple memory accesses.
734 class ReportNonSimpleMemoryAccess
: public ReportOther
{
735 //===--------------------------------------------------------------------===//
737 // The offending call instruction.
741 ReportNonSimpleMemoryAccess(Instruction
*Inst
);
743 /// @name LLVM-RTTI interface
745 static bool classof(const RejectReason
*RR
);
748 /// @name RejectReason interface
750 virtual std::string
getMessage() const override
;
751 virtual const DebugLoc
&getDebugLoc() const override
;
752 virtual std::string
getEndUserMessage() const override
;
758 #endif // POLLY_SCOP_DETECTION_DIAGNOSTIC_H