//===- 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
