| //===- ScopDetectionDiagnostic.h - Diagnostic for ScopDetection -*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Small set of diagnostic helper classes to encapsulate any errors occurred |
| // during the detection of Scops. |
| // |
| // The ScopDetection defines a set of error classes (via Statistic variables) |
| // that groups a number of individual errors into a group, e.g. non-affinity |
| // related errors. |
| // On error we generate an object that carries enough additional information |
| // to diagnose the error and generate a helpful error message. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef POLLY_SCOPDETECTIONDIAGNOSTIC_H |
| #define POLLY_SCOPDETECTIONDIAGNOSTIC_H |
| |
| #include "llvm/Analysis/LoopInfo.h" |
| #include "llvm/IR/DebugLoc.h" |
| #include "llvm/IR/Instruction.h" |
| #include <cstddef> |
| |
| namespace llvm { |
| class AliasSet; |
| class BasicBlock; |
| class OptimizationRemarkEmitter; |
| class Region; |
| class SCEV; |
| } // namespace llvm |
| |
| namespace polly { |
| using llvm::AliasSet; |
| using llvm::BasicBlock; |
| using llvm::DebugLoc; |
| using llvm::Instruction; |
| using llvm::Loop; |
| using llvm::OptimizationRemarkEmitter; |
| using llvm::raw_ostream; |
| using llvm::Region; |
| using llvm::SCEV; |
| using llvm::SmallVector; |
| using llvm::Value; |
| |
| /// Type to hold region delimiters (entry & exit block). |
| using BBPair = std::pair<BasicBlock *, BasicBlock *>; |
| |
| /// Return the region delimiters (entry & exit block) of @p R. |
| BBPair getBBPairForRegion(const Region *R); |
| |
| /// Set the begin and end source location for the region limited by @p P. |
| void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End); |
| |
| class RejectLog; |
| |
| /// Emit optimization remarks about the rejected regions to the user. |
| /// |
| /// This emits the content of the reject log as optimization remarks. |
| /// Remember to at least track failures (-polly-detect-track-failures). |
| /// @param P The region delimiters (entry & exit) we emit remarks for. |
| /// @param Log The error log containing all messages being emitted as remark. |
| void emitRejectionRemarks(const BBPair &P, const RejectLog &Log, |
| OptimizationRemarkEmitter &ORE); |
| |
| // Discriminator for LLVM-style RTTI (dyn_cast<> et al.) |
| enum class RejectReasonKind { |
| // CFG Category |
| CFG, |
| InvalidTerminator, |
| IrreducibleRegion, |
| UnreachableInExit, |
| IndirectPredecessor, |
| LastCFG, |
| |
| // Non-Affinity |
| AffFunc, |
| UndefCond, |
| InvalidCond, |
| UndefOperand, |
| NonAffBranch, |
| NoBasePtr, |
| UndefBasePtr, |
| VariantBasePtr, |
| NonAffineAccess, |
| DifferentElementSize, |
| LastAffFunc, |
| |
| LoopBound, |
| LoopHasNoExit, |
| LoopHasMultipleExits, |
| LoopOnlySomeLatches, |
| |
| FuncCall, |
| NonSimpleMemoryAccess, |
| |
| Alias, |
| |
| // Other |
| Other, |
| IntToPtr, |
| Alloca, |
| UnknownInst, |
| Entry, |
| Unprofitable, |
| LastOther |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Base class of all reject reasons found during Scop detection. |
| /// |
| /// Subclasses of RejectReason should provide means to capture enough |
| /// diagnostic information to help clients figure out what and where something |
| /// went wrong in the Scop detection. |
| class RejectReason { |
| private: |
| const RejectReasonKind Kind; |
| |
| protected: |
| static const DebugLoc Unknown; |
| |
| public: |
| RejectReason(RejectReasonKind K); |
| |
| virtual ~RejectReason() = default; |
| |
| RejectReasonKind getKind() const { return Kind; } |
| |
| /// Generate the remark name to identify this remark. |
| /// |
| /// @return A short string that identifies the error. |
| virtual std::string getRemarkName() const = 0; |
| |
| /// Get the Basic Block containing this remark. |
| /// |
| /// @return The Basic Block containing this remark. |
| virtual const Value *getRemarkBB() const = 0; |
| |
| /// Generate a reasonable diagnostic message describing this error. |
| /// |
| /// @return A debug message representing this error. |
| virtual std::string getMessage() const = 0; |
| |
| /// Generate a message for the end-user describing this error. |
| /// |
| /// The message provided has to be suitable for the end-user. So it should |
| /// not reference any LLVM internal data structures or terminology. |
| /// Ideally, the message helps the end-user to increase the size of the |
| /// regions amenable to Polly. |
| /// |
| /// @return A short message representing this error. |
| virtual std::string getEndUserMessage() const { return "Unspecified error."; } |
| |
| /// Get the source location of this error. |
| /// |
| /// @return The debug location for this error. |
| virtual const DebugLoc &getDebugLoc() const; |
| }; |
| |
| using RejectReasonPtr = std::shared_ptr<RejectReason>; |
| |
| /// Stores all errors that occurred during the detection. |
| class RejectLog { |
| Region *R; |
| SmallVector<RejectReasonPtr, 1> ErrorReports; |
| |
| public: |
| explicit RejectLog(Region *R) : R(R) {} |
| |
| using iterator = SmallVector<RejectReasonPtr, 1>::const_iterator; |
| |
| iterator begin() const { return ErrorReports.begin(); } |
| iterator end() const { return ErrorReports.end(); } |
| size_t size() const { return ErrorReports.size(); } |
| |
| /// Returns true, if we store at least one error. |
| /// |
| /// @return true, if we store at least one error. |
| bool hasErrors() const { return size() > 0; } |
| |
| void print(raw_ostream &OS, int level = 0) const; |
| |
| const Region *region() const { return R; } |
| void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); } |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Base class for CFG related reject reasons. |
| /// |
| /// Scop candidates that violate structural restrictions can be grouped under |
| /// this reject reason class. |
| class ReportCFG : public RejectReason { |
| public: |
| ReportCFG(const RejectReasonKind K); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures bad terminator within a Scop candidate. |
| class ReportInvalidTerminator : public ReportCFG { |
| BasicBlock *BB; |
| |
| public: |
| ReportInvalidTerminator(BasicBlock *BB) |
| : ReportCFG(RejectReasonKind::InvalidTerminator), BB(BB) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures irreducible regions in CFG. |
| class ReportIrreducibleRegion : public ReportCFG { |
| Region *R; |
| DebugLoc DbgLoc; |
| |
| public: |
| ReportIrreducibleRegion(Region *R, DebugLoc DbgLoc) |
| : ReportCFG(RejectReasonKind::IrreducibleRegion), R(R), DbgLoc(DbgLoc) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures regions with an unreachable in the exit block. |
| class ReportUnreachableInExit : public ReportCFG { |
| BasicBlock *BB; |
| DebugLoc DbgLoc; |
| |
| public: |
| ReportUnreachableInExit(BasicBlock *BB, DebugLoc DbgLoc) |
| : ReportCFG(RejectReasonKind::UnreachableInExit), BB(BB), DbgLoc(DbgLoc) { |
| } |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures regions with an IndirectBr predecessor. |
| class ReportIndirectPredecessor : public ReportCFG { |
| Instruction *Inst; |
| DebugLoc DbgLoc; |
| |
| public: |
| ReportIndirectPredecessor(Instruction *Inst, DebugLoc DbgLoc) |
| : ReportCFG(RejectReasonKind::IndirectPredecessor), Inst(Inst), |
| DbgLoc(DbgLoc) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Base class for non-affine reject reasons. |
| /// |
| /// Scop candidates that violate restrictions to affinity are reported under |
| /// this class. |
| class ReportAffFunc : public RejectReason { |
| protected: |
| // The instruction that caused non-affinity to occur. |
| const Instruction *Inst; |
| |
| public: |
| ReportAffFunc(const RejectReasonKind K, const Instruction *Inst); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| const DebugLoc &getDebugLoc() const override { return Inst->getDebugLoc(); } |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures a condition that is based on an 'undef' value. |
| class ReportUndefCond : public ReportAffFunc { |
| // The BasicBlock we found the broken condition in. |
| BasicBlock *BB; |
| |
| public: |
| ReportUndefCond(const Instruction *Inst, BasicBlock *BB) |
| : ReportAffFunc(RejectReasonKind::UndefCond, Inst), BB(BB) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures an invalid condition |
| /// |
| /// Conditions have to be either constants or icmp instructions. |
| class ReportInvalidCond : public ReportAffFunc { |
| // The BasicBlock we found the broken condition in. |
| BasicBlock *BB; |
| |
| public: |
| ReportInvalidCond(const Instruction *Inst, BasicBlock *BB) |
| : ReportAffFunc(RejectReasonKind::InvalidCond, Inst), BB(BB) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures an undefined operand. |
| class ReportUndefOperand : public ReportAffFunc { |
| // The BasicBlock we found the undefined operand in. |
| BasicBlock *BB; |
| |
| public: |
| ReportUndefOperand(BasicBlock *BB, const Instruction *Inst) |
| : ReportAffFunc(RejectReasonKind::UndefOperand, Inst), BB(BB) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures a non-affine branch. |
| class ReportNonAffBranch : public ReportAffFunc { |
| // The BasicBlock we found the non-affine branch in. |
| BasicBlock *BB; |
| |
| /// LHS & RHS of the failed condition. |
| //@{ |
| const SCEV *LHS; |
| const SCEV *RHS; |
| //@} |
| |
| public: |
| ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS, |
| const Instruction *Inst) |
| : ReportAffFunc(RejectReasonKind::NonAffBranch, Inst), BB(BB), LHS(LHS), |
| RHS(RHS) {} |
| |
| const SCEV *lhs() { return LHS; } |
| const SCEV *rhs() { return RHS; } |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures a missing base pointer. |
| class ReportNoBasePtr : public ReportAffFunc { |
| public: |
| ReportNoBasePtr(const Instruction *Inst) |
| : ReportAffFunc(RejectReasonKind::NoBasePtr, Inst) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures an undefined base pointer. |
| class ReportUndefBasePtr : public ReportAffFunc { |
| public: |
| ReportUndefBasePtr(const Instruction *Inst) |
| : ReportAffFunc(RejectReasonKind::UndefBasePtr, Inst) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures a base pointer that is not invariant in the region. |
| class ReportVariantBasePtr : public ReportAffFunc { |
| // The variant base pointer. |
| Value *BaseValue; |
| |
| public: |
| ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst) |
| : ReportAffFunc(RejectReasonKind::VariantBasePtr, Inst), |
| BaseValue(BaseValue) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures a non-affine access function. |
| class ReportNonAffineAccess : public ReportAffFunc { |
| // The non-affine access function. |
| const SCEV *AccessFunction; |
| |
| // The base pointer of the memory access. |
| const Value *BaseValue; |
| |
| public: |
| ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst, |
| const Value *V) |
| : ReportAffFunc(RejectReasonKind::NonAffineAccess, Inst), |
| AccessFunction(AccessFunction), BaseValue(V) {} |
| |
| const SCEV *get() { return AccessFunction; } |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Report array accesses with differing element size. |
| class ReportDifferentArrayElementSize : public ReportAffFunc { |
| // The base pointer of the memory access. |
| const Value *BaseValue; |
| |
| public: |
| ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V) |
| : ReportAffFunc(RejectReasonKind::DifferentElementSize, Inst), |
| BaseValue(V) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with non affine loop bounds. |
| class ReportLoopBound : public RejectReason { |
| // The offending loop. |
| Loop *L; |
| |
| // The non-affine loop bound. |
| const SCEV *LoopCount; |
| |
| // A copy of the offending loop's debug location. |
| const DebugLoc Loc; |
| |
| public: |
| ReportLoopBound(Loop *L, const SCEV *LoopCount); |
| |
| const SCEV *loopCount() { return LoopCount; } |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors when loop has no exit. |
| class ReportLoopHasNoExit : public RejectReason { |
| /// The loop that has no exit. |
| Loop *L; |
| |
| const DebugLoc Loc; |
| |
| public: |
| ReportLoopHasNoExit(Loop *L) |
| : RejectReason(RejectReasonKind::LoopHasNoExit), L(L), |
| Loc(L->getStartLoc()) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors when a loop has multiple exists. |
| class ReportLoopHasMultipleExits : public RejectReason { |
| /// The loop that has multiple exits. |
| Loop *L; |
| |
| const DebugLoc Loc; |
| |
| public: |
| ReportLoopHasMultipleExits(Loop *L) |
| : RejectReason(RejectReasonKind::LoopHasMultipleExits), L(L), |
| Loc(L->getStartLoc()) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors when not all loop latches are part of the scop. |
| class ReportLoopOnlySomeLatches : public RejectReason { |
| /// The loop for which not all loop latches are part of the scop. |
| Loop *L; |
| |
| const DebugLoc Loc; |
| |
| public: |
| ReportLoopOnlySomeLatches(Loop *L) |
| : RejectReason(RejectReasonKind::LoopOnlySomeLatches), L(L), |
| Loc(L->getStartLoc()) {} |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with non-side-effect-known function calls. |
| class ReportFuncCall : public RejectReason { |
| // The offending call instruction. |
| Instruction *Inst; |
| |
| public: |
| ReportFuncCall(Instruction *Inst); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with aliasing. |
| class ReportAlias : public RejectReason { |
| public: |
| using PointerSnapshotTy = std::vector<const Value *>; |
| |
| private: |
| /// Format an invalid alias set. |
| /// |
| // @param Prefix A prefix string to put before the list of aliasing pointers. |
| // @param Suffix A suffix string to put after the list of aliasing pointers. |
| std::string formatInvalidAlias(std::string Prefix = "", |
| std::string Suffix = "") const; |
| |
| Instruction *Inst; |
| |
| // A snapshot of the llvm values that took part in the aliasing error. |
| mutable PointerSnapshotTy Pointers; |
| |
| public: |
| ReportAlias(Instruction *Inst, AliasSet &AS); |
| |
| const PointerSnapshotTy &getPointers() const { return Pointers; } |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Base class for otherwise ungrouped reject reasons. |
| class ReportOther : public RejectReason { |
| public: |
| ReportOther(const RejectReasonKind K); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| std::string getMessage() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with bad IntToPtr instructions. |
| class ReportIntToPtr : public ReportOther { |
| // The offending base value. |
| Instruction *BaseValue; |
| |
| public: |
| ReportIntToPtr(Instruction *BaseValue); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with alloca instructions. |
| class ReportAlloca : public ReportOther { |
| Instruction *Inst; |
| |
| public: |
| ReportAlloca(Instruction *Inst); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with unknown instructions. |
| class ReportUnknownInst : public ReportOther { |
| Instruction *Inst; |
| |
| public: |
| ReportUnknownInst(Instruction *Inst); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with regions containing the function entry block. |
| class ReportEntry : public ReportOther { |
| BasicBlock *BB; |
| |
| public: |
| ReportEntry(BasicBlock *BB); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Report regions that seem not profitable to be optimized. |
| class ReportUnprofitable : public ReportOther { |
| Region *R; |
| |
| public: |
| ReportUnprofitable(Region *R); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| std::string getEndUserMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| //@} |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| /// Captures errors with non-simple memory accesses. |
| class ReportNonSimpleMemoryAccess : public ReportOther { |
| // The offending call instruction. |
| Instruction *Inst; |
| |
| public: |
| ReportNonSimpleMemoryAccess(Instruction *Inst); |
| |
| /// @name LLVM-RTTI interface |
| //@{ |
| static bool classof(const RejectReason *RR); |
| //@} |
| |
| /// @name RejectReason interface |
| //@{ |
| std::string getRemarkName() const override; |
| const Value *getRemarkBB() const override; |
| std::string getMessage() const override; |
| const DebugLoc &getDebugLoc() const override; |
| std::string getEndUserMessage() const override; |
| //@} |
| }; |
| } // namespace polly |
| |
| #endif // POLLY_SCOPDETECTIONDIAGNOSTIC_H |