123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834 |
- //===- ScopDetectionDiagnostic.cpp - Error diagnostics --------------------===//
- //
- // 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.
- //
- //===----------------------------------------------------------------------===//
- #include "polly/ScopDetectionDiagnostic.h"
- #include "llvm/ADT/SmallPtrSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/Statistic.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/Twine.h"
- #include "llvm/Analysis/AliasSetTracker.h"
- #include "llvm/Analysis/LoopInfo.h"
- #include "llvm/Analysis/OptimizationRemarkEmitter.h"
- #include "llvm/Analysis/RegionInfo.h"
- #include "llvm/Analysis/ScalarEvolution.h"
- #include "llvm/IR/BasicBlock.h"
- #include "llvm/IR/CFG.h"
- #include "llvm/IR/DebugLoc.h"
- #include "llvm/IR/DiagnosticInfo.h"
- #include "llvm/IR/Instruction.h"
- #include "llvm/IR/Value.h"
- #include "llvm/Support/raw_ostream.h"
- #include <algorithm>
- #include <cassert>
- #include <string>
- #include <utility>
- using namespace llvm;
- #define DEBUG_TYPE "polly-detect"
- #define SCOP_STAT(NAME, DESC) \
- { "polly-detect", "NAME", "Number of rejected regions: " DESC }
- static Statistic RejectStatistics[] = {
- SCOP_STAT(CFG, ""),
- SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
- SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
- SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
- SCOP_STAT(IndirectPredecessor, "Branch from indirect terminator"),
- SCOP_STAT(LastCFG, ""),
- SCOP_STAT(AffFunc, ""),
- SCOP_STAT(UndefCond, "Undefined branch condition"),
- SCOP_STAT(InvalidCond, "Non-integer branch condition"),
- SCOP_STAT(UndefOperand, "Undefined operands in comparison"),
- SCOP_STAT(NonAffBranch, "Non-affine branch condition"),
- SCOP_STAT(NoBasePtr, "No base pointer"),
- SCOP_STAT(UndefBasePtr, "Undefined base pointer"),
- SCOP_STAT(VariantBasePtr, "Variant base pointer"),
- SCOP_STAT(NonAffineAccess, "Non-affine memory accesses"),
- SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"),
- SCOP_STAT(LastAffFunc, ""),
- SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
- SCOP_STAT(LoopHasNoExit, "Loop without exit"),
- SCOP_STAT(LoopHasMultipleExits, "Loop with multiple exits"),
- SCOP_STAT(LoopOnlySomeLatches, "Not all loop latches in scop"),
- SCOP_STAT(FuncCall, "Function call with side effects"),
- SCOP_STAT(NonSimpleMemoryAccess,
- "Compilated access semantics (volatile or atomic)"),
- SCOP_STAT(Alias, "Base address aliasing"),
- SCOP_STAT(Other, ""),
- SCOP_STAT(IntToPtr, "Integer to pointer conversions"),
- SCOP_STAT(Alloca, "Stack allocations"),
- SCOP_STAT(UnknownInst, "Unknown Instructions"),
- SCOP_STAT(Entry, "Contains entry block"),
- SCOP_STAT(Unprofitable, "Assumed to be unprofitable"),
- SCOP_STAT(LastOther, ""),
- };
- namespace polly {
- /// Small string conversion via raw_string_stream.
- template <typename T> std::string operator+(Twine LHS, const T &RHS) {
- std::string Buf;
- raw_string_ostream fmt(Buf);
- fmt << RHS;
- fmt.flush();
- return LHS.concat(Buf).str();
- }
- } // namespace polly
- namespace llvm {
- // Lexicographic order on (line, col) of our debug locations.
- static bool operator<(const DebugLoc &LHS, const DebugLoc &RHS) {
- return LHS.getLine() < RHS.getLine() ||
- (LHS.getLine() == RHS.getLine() && LHS.getCol() < RHS.getCol());
- }
- } // namespace llvm
- namespace polly {
- BBPair getBBPairForRegion(const Region *R) {
- return std::make_pair(R->getEntry(), R->getExit());
- }
- void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
- SmallPtrSet<BasicBlock *, 32> Seen;
- SmallVector<BasicBlock *, 32> Todo;
- Todo.push_back(P.first);
- while (!Todo.empty()) {
- auto *BB = Todo.pop_back_val();
- if (BB == P.second)
- continue;
- if (!Seen.insert(BB).second)
- continue;
- Todo.append(succ_begin(BB), succ_end(BB));
- for (const Instruction &Inst : *BB) {
- DebugLoc DL = Inst.getDebugLoc();
- if (!DL)
- continue;
- Begin = Begin ? std::min(Begin, DL) : DL;
- End = End ? std::max(End, DL) : DL;
- }
- }
- }
- void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
- OptimizationRemarkEmitter &ORE) {
- DebugLoc Begin, End;
- getDebugLocations(P, Begin, End);
- ORE.emit(
- OptimizationRemarkMissed(DEBUG_TYPE, "RejectionErrors", Begin, P.first)
- << "The following errors keep this region from being a Scop.");
- for (RejectReasonPtr RR : Log) {
- if (const DebugLoc &Loc = RR->getDebugLoc())
- ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Loc,
- RR->getRemarkBB())
- << RR->getEndUserMessage());
- else
- ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
- RR->getRemarkBB())
- << RR->getEndUserMessage());
- }
- /* Check to see if Region is a top level region, getExit = NULL*/
- if (P.second)
- ORE.emit(
- OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
- << "Invalid Scop candidate ends here.");
- else
- ORE.emit(
- OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
- << "Invalid Scop candidate ends here.");
- }
- //===----------------------------------------------------------------------===//
- // RejectReason.
- RejectReason::RejectReason(RejectReasonKind K) : Kind(K) {
- RejectStatistics[static_cast<int>(K)]++;
- }
- const DebugLoc RejectReason::Unknown = DebugLoc();
- const DebugLoc &RejectReason::getDebugLoc() const {
- // Allocate an empty DebugLoc and return it a reference to it.
- return Unknown;
- }
- // RejectLog.
- void RejectLog::print(raw_ostream &OS, int level) const {
- int j = 0;
- for (auto Reason : ErrorReports)
- OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
- }
- //===----------------------------------------------------------------------===//
- // ReportCFG.
- ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {}
- bool ReportCFG::classof(const RejectReason *RR) {
- return RR->getKind() >= RejectReasonKind::CFG &&
- RR->getKind() <= RejectReasonKind::LastCFG;
- }
- //===----------------------------------------------------------------------===//
- // ReportInvalidTerminator.
- std::string ReportInvalidTerminator::getRemarkName() const {
- return "InvalidTerminator";
- }
- const Value *ReportInvalidTerminator::getRemarkBB() const { return BB; }
- std::string ReportInvalidTerminator::getMessage() const {
- return ("Invalid instruction terminates BB: " + BB->getName()).str();
- }
- const DebugLoc &ReportInvalidTerminator::getDebugLoc() const {
- return BB->getTerminator()->getDebugLoc();
- }
- bool ReportInvalidTerminator::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::InvalidTerminator;
- }
- //===----------------------------------------------------------------------===//
- // UnreachableInExit.
- std::string ReportUnreachableInExit::getRemarkName() const {
- return "UnreachableInExit";
- }
- const Value *ReportUnreachableInExit::getRemarkBB() const { return BB; }
- std::string ReportUnreachableInExit::getMessage() const {
- std::string BBName = BB->getName().str();
- return "Unreachable in exit block" + BBName;
- }
- const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; }
- std::string ReportUnreachableInExit::getEndUserMessage() const {
- return "Unreachable in exit block.";
- }
- bool ReportUnreachableInExit::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::UnreachableInExit;
- }
- //===----------------------------------------------------------------------===//
- // IndirectPredecessor.
- std::string ReportIndirectPredecessor::getRemarkName() const {
- return "IndirectPredecessor";
- }
- const Value *ReportIndirectPredecessor::getRemarkBB() const {
- if (Inst)
- return Inst->getParent();
- return nullptr;
- }
- std::string ReportIndirectPredecessor::getMessage() const {
- if (Inst)
- return "Branch from indirect terminator: " + *Inst;
- return getEndUserMessage();
- }
- const DebugLoc &ReportIndirectPredecessor::getDebugLoc() const {
- return DbgLoc;
- }
- std::string ReportIndirectPredecessor::getEndUserMessage() const {
- return "Branch from indirect terminator.";
- }
- bool ReportIndirectPredecessor::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::IndirectPredecessor;
- }
- //===----------------------------------------------------------------------===//
- // ReportIrreducibleRegion.
- std::string ReportIrreducibleRegion::getRemarkName() const {
- return "IrreducibleRegion";
- }
- const Value *ReportIrreducibleRegion::getRemarkBB() const {
- return R->getEntry();
- }
- std::string ReportIrreducibleRegion::getMessage() const {
- return "Irreducible region encountered: " + R->getNameStr();
- }
- const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
- std::string ReportIrreducibleRegion::getEndUserMessage() const {
- return "Irreducible region encountered in control flow.";
- }
- bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::IrreducibleRegion;
- }
- //===----------------------------------------------------------------------===//
- // ReportAffFunc.
- ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
- : RejectReason(K), Inst(Inst) {}
- bool ReportAffFunc::classof(const RejectReason *RR) {
- return RR->getKind() >= RejectReasonKind::AffFunc &&
- RR->getKind() <= RejectReasonKind::LastAffFunc;
- }
- //===----------------------------------------------------------------------===//
- // ReportUndefCond.
- std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
- const Value *ReportUndefCond::getRemarkBB() const { return BB; }
- std::string ReportUndefCond::getMessage() const {
- return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
- }
- bool ReportUndefCond::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::UndefCond;
- }
- //===----------------------------------------------------------------------===//
- // ReportInvalidCond.
- std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
- const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
- std::string ReportInvalidCond::getMessage() const {
- return ("Condition in BB '" + BB->getName()).str() +
- "' neither constant nor an icmp instruction";
- }
- bool ReportInvalidCond::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::InvalidCond;
- }
- //===----------------------------------------------------------------------===//
- // ReportUndefOperand.
- std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
- const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
- std::string ReportUndefOperand::getMessage() const {
- return ("undef operand in branch at BB: " + BB->getName()).str();
- }
- bool ReportUndefOperand::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::UndefOperand;
- }
- //===----------------------------------------------------------------------===//
- // ReportNonAffBranch.
- std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
- const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
- std::string ReportNonAffBranch::getMessage() const {
- return ("Non affine branch in BB '" + BB->getName()).str() +
- "' with LHS: " + *LHS + " and RHS: " + *RHS;
- }
- bool ReportNonAffBranch::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::NonAffBranch;
- }
- //===----------------------------------------------------------------------===//
- // ReportNoBasePtr.
- std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
- const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
- std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
- bool ReportNoBasePtr::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::NoBasePtr;
- }
- //===----------------------------------------------------------------------===//
- // ReportUndefBasePtr.
- std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
- const Value *ReportUndefBasePtr::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportUndefBasePtr::getMessage() const {
- return "Undefined base pointer";
- }
- bool ReportUndefBasePtr::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::UndefBasePtr;
- }
- //===----------------------------------------------------------------------===//
- // ReportVariantBasePtr.
- std::string ReportVariantBasePtr::getRemarkName() const {
- return "VariantBasePtr";
- }
- const Value *ReportVariantBasePtr::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportVariantBasePtr::getMessage() const {
- return "Base address not invariant in current region:" + *BaseValue;
- }
- std::string ReportVariantBasePtr::getEndUserMessage() const {
- return "The base address of this array is not invariant inside the loop";
- }
- bool ReportVariantBasePtr::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::VariantBasePtr;
- }
- //===----------------------------------------------------------------------===//
- // ReportDifferentArrayElementSize
- std::string ReportDifferentArrayElementSize::getRemarkName() const {
- return "DifferentArrayElementSize";
- }
- const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportDifferentArrayElementSize::getMessage() const {
- return "Access to one array through data types of different size";
- }
- bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::DifferentElementSize;
- }
- std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
- StringRef BaseName = BaseValue->getName();
- std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName.str();
- return "The array \"" + Name +
- "\" is accessed through elements that differ "
- "in size";
- }
- //===----------------------------------------------------------------------===//
- // ReportNonAffineAccess.
- std::string ReportNonAffineAccess::getRemarkName() const {
- return "NonAffineAccess";
- }
- const Value *ReportNonAffineAccess::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportNonAffineAccess::getMessage() const {
- return "Non affine access function: " + *AccessFunction;
- }
- bool ReportNonAffineAccess::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::NonAffineAccess;
- }
- std::string ReportNonAffineAccess::getEndUserMessage() const {
- StringRef BaseName = BaseValue->getName();
- std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName.str();
- return "The array subscript of \"" + Name + "\" is not affine";
- }
- //===----------------------------------------------------------------------===//
- // ReportLoopBound.
- ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
- : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
- Loc(L->getStartLoc()) {}
- std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
- const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
- std::string ReportLoopBound::getMessage() const {
- return "Non affine loop bound '" + *LoopCount +
- "' in loop: " + L->getHeader()->getName();
- }
- const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
- bool ReportLoopBound::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::LoopBound;
- }
- std::string ReportLoopBound::getEndUserMessage() const {
- return "Failed to derive an affine function from the loop bounds.";
- }
- //===----------------------------------------------------------------------===//
- // ReportLoopHasNoExit.
- std::string ReportLoopHasNoExit::getRemarkName() const {
- return "LoopHasNoExit";
- }
- const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
- std::string ReportLoopHasNoExit::getMessage() const {
- return "Loop " + L->getHeader()->getName() + " has no exit.";
- }
- bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::LoopHasNoExit;
- }
- const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
- std::string ReportLoopHasNoExit::getEndUserMessage() const {
- return "Loop cannot be handled because it has no exit.";
- }
- //===----------------------------------------------------------------------===//
- // ReportLoopHasMultipleExits.
- std::string ReportLoopHasMultipleExits::getRemarkName() const {
- return "ReportLoopHasMultipleExits";
- }
- const Value *ReportLoopHasMultipleExits::getRemarkBB() const {
- return L->getHeader();
- }
- std::string ReportLoopHasMultipleExits::getMessage() const {
- return "Loop " + L->getHeader()->getName() + " has multiple exits.";
- }
- bool ReportLoopHasMultipleExits::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::LoopHasMultipleExits;
- }
- const DebugLoc &ReportLoopHasMultipleExits::getDebugLoc() const { return Loc; }
- std::string ReportLoopHasMultipleExits::getEndUserMessage() const {
- return "Loop cannot be handled because it has multiple exits.";
- }
- //===----------------------------------------------------------------------===//
- // ReportLoopOnlySomeLatches
- std::string ReportLoopOnlySomeLatches::getRemarkName() const {
- return "LoopHasNoExit";
- }
- const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
- return L->getHeader();
- }
- std::string ReportLoopOnlySomeLatches::getMessage() const {
- return "Not all latches of loop " + L->getHeader()->getName() +
- " part of scop.";
- }
- bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::LoopHasNoExit;
- }
- const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
- std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
- return "Loop cannot be handled because not all latches are part of loop "
- "region.";
- }
- //===----------------------------------------------------------------------===//
- // ReportFuncCall.
- ReportFuncCall::ReportFuncCall(Instruction *Inst)
- : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
- std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
- const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
- std::string ReportFuncCall::getMessage() const {
- return "Call instruction: " + *Inst;
- }
- const DebugLoc &ReportFuncCall::getDebugLoc() const {
- return Inst->getDebugLoc();
- }
- std::string ReportFuncCall::getEndUserMessage() const {
- return "This function call cannot be handled. "
- "Try to inline it.";
- }
- bool ReportFuncCall::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::FuncCall;
- }
- //===----------------------------------------------------------------------===//
- // ReportNonSimpleMemoryAccess
- ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
- : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
- std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
- return "NonSimpleMemoryAccess";
- }
- const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportNonSimpleMemoryAccess::getMessage() const {
- return "Non-simple memory access: " + *Inst;
- }
- const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
- return Inst->getDebugLoc();
- }
- std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
- return "Volatile memory accesses or memory accesses for atomic types "
- "are not supported.";
- }
- bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
- }
- //===----------------------------------------------------------------------===//
- // ReportAlias.
- ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
- : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
- for (const auto &I : AS)
- Pointers.push_back(I.getValue());
- }
- std::string ReportAlias::formatInvalidAlias(std::string Prefix,
- std::string Suffix) const {
- std::string Message;
- raw_string_ostream OS(Message);
- OS << Prefix;
- for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
- PE = Pointers.end();
- ;) {
- const Value *V = *PI;
- assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
- if (V->getName().empty())
- OS << "\" <unknown> \"";
- else
- OS << "\"" << V->getName() << "\"";
- ++PI;
- if (PI != PE)
- OS << ", ";
- else
- break;
- }
- OS << Suffix;
- return OS.str();
- }
- std::string ReportAlias::getRemarkName() const { return "Alias"; }
- const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
- std::string ReportAlias::getMessage() const {
- return formatInvalidAlias("Possible aliasing: ");
- }
- std::string ReportAlias::getEndUserMessage() const {
- return formatInvalidAlias("Accesses to the arrays ",
- " may access the same memory.");
- }
- const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
- bool ReportAlias::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::Alias;
- }
- //===----------------------------------------------------------------------===//
- // ReportOther.
- std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
- std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
- ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
- bool ReportOther::classof(const RejectReason *RR) {
- return RR->getKind() >= RejectReasonKind::Other &&
- RR->getKind() <= RejectReasonKind::LastOther;
- }
- //===----------------------------------------------------------------------===//
- // ReportIntToPtr.
- ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
- : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
- std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
- const Value *ReportIntToPtr::getRemarkBB() const {
- return BaseValue->getParent();
- }
- std::string ReportIntToPtr::getMessage() const {
- return "Find bad intToptr prt: " + *BaseValue;
- }
- const DebugLoc &ReportIntToPtr::getDebugLoc() const {
- return BaseValue->getDebugLoc();
- }
- bool ReportIntToPtr::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::IntToPtr;
- }
- //===----------------------------------------------------------------------===//
- // ReportAlloca.
- ReportAlloca::ReportAlloca(Instruction *Inst)
- : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
- std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
- const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
- std::string ReportAlloca::getMessage() const {
- return "Alloca instruction: " + *Inst;
- }
- const DebugLoc &ReportAlloca::getDebugLoc() const {
- return Inst->getDebugLoc();
- }
- bool ReportAlloca::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::Alloca;
- }
- //===----------------------------------------------------------------------===//
- // ReportUnknownInst.
- ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
- : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
- std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
- const Value *ReportUnknownInst::getRemarkBB() const {
- return Inst->getParent();
- }
- std::string ReportUnknownInst::getMessage() const {
- return "Unknown instruction: " + *Inst;
- }
- const DebugLoc &ReportUnknownInst::getDebugLoc() const {
- return Inst->getDebugLoc();
- }
- bool ReportUnknownInst::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::UnknownInst;
- }
- //===----------------------------------------------------------------------===//
- // ReportEntry.
- ReportEntry::ReportEntry(BasicBlock *BB)
- : ReportOther(RejectReasonKind::Entry), BB(BB) {}
- std::string ReportEntry::getRemarkName() const { return "Entry"; }
- const Value *ReportEntry::getRemarkBB() const { return BB; }
- std::string ReportEntry::getMessage() const {
- return "Region containing entry block of function is invalid!";
- }
- std::string ReportEntry::getEndUserMessage() const {
- return "Scop contains function entry (not yet supported).";
- }
- const DebugLoc &ReportEntry::getDebugLoc() const {
- return BB->getTerminator()->getDebugLoc();
- }
- bool ReportEntry::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::Entry;
- }
- //===----------------------------------------------------------------------===//
- // ReportUnprofitable.
- ReportUnprofitable::ReportUnprofitable(Region *R)
- : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
- std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
- const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
- std::string ReportUnprofitable::getMessage() const {
- return "Region can not profitably be optimized!";
- }
- std::string ReportUnprofitable::getEndUserMessage() const {
- return "No profitable polyhedral optimization found";
- }
- const DebugLoc &ReportUnprofitable::getDebugLoc() const {
- for (const BasicBlock *BB : R->blocks())
- for (const Instruction &Inst : *BB)
- if (const DebugLoc &DL = Inst.getDebugLoc())
- return DL;
- return R->getEntry()->getTerminator()->getDebugLoc();
- }
- bool ReportUnprofitable::classof(const RejectReason *RR) {
- return RR->getKind() == RejectReasonKind::Unprofitable;
- }
- } // namespace polly
|