brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.5 KiB · 8e6d654 Raw
506 lines · cpp
1//===- llvm/IR/DiagnosticInfo.cpp - Diagnostic Definitions ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the different classes involved in low level diagnostics.10//11// Diagnostics reporting is still done as part of the LLVMContext.12//===----------------------------------------------------------------------===//13 14#include "llvm/IR/DiagnosticInfo.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/ADT/Twine.h"17#include "llvm/ADT/iterator_range.h"18#include "llvm/Demangle/Demangle.h"19#include "llvm/IR/BasicBlock.h"20#include "llvm/IR/Constants.h"21#include "llvm/IR/DebugInfoMetadata.h"22#include "llvm/IR/DerivedTypes.h"23#include "llvm/IR/DiagnosticPrinter.h"24#include "llvm/IR/Function.h"25#include "llvm/IR/GlobalValue.h"26#include "llvm/IR/Instruction.h"27#include "llvm/IR/Instructions.h"28#include "llvm/IR/IntrinsicInst.h"29#include "llvm/IR/LLVMContext.h"30#include "llvm/IR/Metadata.h"31#include "llvm/IR/Module.h"32#include "llvm/IR/Type.h"33#include "llvm/IR/Value.h"34#include "llvm/Support/Casting.h"35#include "llvm/Support/ErrorHandling.h"36#include "llvm/Support/InstructionCost.h"37#include "llvm/Support/Path.h"38#include "llvm/Support/ScopedPrinter.h"39#include "llvm/Support/raw_ostream.h"40#include <atomic>41#include <string>42 43using namespace llvm;44 45int llvm::getNextAvailablePluginDiagnosticKind() {46  static std::atomic<int> PluginKindID(DK_FirstPluginKind);47  return ++PluginKindID;48}49 50const char *OptimizationRemarkAnalysis::AlwaysPrint = "";51 52void DiagnosticInfoGeneric::print(DiagnosticPrinter &DP) const {53  DP << getMsgStr();54}55 56void DiagnosticInfoGenericWithLoc::print(DiagnosticPrinter &DP) const {57  DP << getLocationStr() << ": " << getMsgStr();58}59 60DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(uint64_t LocCookie,61                                                 const Twine &MsgStr,62                                                 DiagnosticSeverity Severity)63    : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),64      MsgStr(MsgStr) {}65 66DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,67                                                 const Twine &MsgStr,68                                                 DiagnosticSeverity Severity)69    : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {70  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {71    if (SrcLoc->getNumOperands() != 0)72      if (const auto *CI =73              mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))74        LocCookie = CI->getZExtValue();75  }76}77 78void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {79  DP << getMsgStr();80  if (getLocCookie())81    DP << " at line " << getLocCookie();82}83 84void DiagnosticInfoLegalizationFailure::print(DiagnosticPrinter &DP) const {85  DP << getLocationStr() << ": " << getMsgStr();86}87 88DiagnosticInfoRegAllocFailure::DiagnosticInfoRegAllocFailure(89    const Twine &MsgStr, const Function &Fn, const DiagnosticLocation &DL,90    DiagnosticSeverity Severity)91    : DiagnosticInfoWithLocationBase(DK_RegAllocFailure, Severity, Fn,92                                     DL.isValid() ? DL : Fn.getSubprogram()),93      MsgStr(MsgStr) {}94 95DiagnosticInfoRegAllocFailure::DiagnosticInfoRegAllocFailure(96    const Twine &MsgStr, const Function &Fn, DiagnosticSeverity Severity)97    : DiagnosticInfoWithLocationBase(DK_RegAllocFailure, Severity, Fn,98                                     Fn.getSubprogram()),99      MsgStr(MsgStr) {}100 101void DiagnosticInfoRegAllocFailure::print(DiagnosticPrinter &DP) const {102  DP << getLocationStr() << ": " << MsgStr << " in function '" << getFunction()103     << '\'';104}105 106DiagnosticInfoResourceLimit::DiagnosticInfoResourceLimit(107    const Function &Fn, const char *ResourceName, uint64_t ResourceSize,108    uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)109    : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),110      Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),111      ResourceLimit(ResourceLimit) {}112 113void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {114  DP << getLocationStr() << ": " << getResourceName() << " ("115     << getResourceSize() << ") exceeds limit (" << getResourceLimit()116     << ") in function '" << getFunction() << '\'';117}118 119void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {120  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()121     << ") in " << getModule();122}123 124void DiagnosticInfoIgnoringInvalidDebugMetadata::print(125    DiagnosticPrinter &DP) const {126  DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();127}128 129void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {130  if (!FileName.empty()) {131    DP << getFileName();132    if (LineNum > 0)133      DP << ":" << getLineNum();134    DP << ": ";135  }136  DP << getMsg();137}138 139void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {140  if (getFileName())141    DP << getFileName() << ": ";142  DP << getMsg();143}144 145void DiagnosticInfo::anchor() {}146void DiagnosticInfoStackSize::anchor() {}147void DiagnosticInfoWithLocationBase::anchor() {}148void DiagnosticInfoIROptimization::anchor() {}149 150DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {151  if (!DL)152    return;153  File = DL->getFile();154  Line = DL->getLine();155  Column = DL->getColumn();156}157 158DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {159  if (!SP)160    return;161 162  File = SP->getFile();163  Line = SP->getScopeLine();164  Column = 0;165}166 167StringRef DiagnosticLocation::getRelativePath() const {168  return File->getFilename();169}170 171std::string DiagnosticLocation::getAbsolutePath() const {172  StringRef Name = File->getFilename();173  if (sys::path::is_absolute(Name))174    return std::string(Name);175 176  SmallString<128> Path;177  sys::path::append(Path, File->getDirectory(), Name);178  return sys::path::remove_leading_dotslash(Path).str();179}180 181std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {182  return Loc.getAbsolutePath();183}184 185void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,186                                                 unsigned &Line,187                                                 unsigned &Column) const {188  RelativePath = Loc.getRelativePath();189  Line = Loc.getLine();190  Column = Loc.getColumn();191}192 193std::string DiagnosticInfoWithLocationBase::getLocationStr() const {194  StringRef Filename("<unknown>");195  unsigned Line = 0;196  unsigned Column = 0;197  if (isLocationAvailable())198    getLocation(Filename, Line, Column);199  return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();200}201 202DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,203                                                   const Value *V)204    : Key(std::string(Key)) {205  if (auto *F = dyn_cast<Function>(V)) {206    if (DISubprogram *SP = F->getSubprogram())207      Loc = SP;208  }209  else if (auto *I = dyn_cast<Instruction>(V))210    Loc = I->getDebugLoc();211 212  // Only include names that correspond to user variables.  FIXME: We should use213  // debug info if available to get the name of the user variable.214  if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))215    Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));216  else if (isa<Constant>(V)) {217    raw_string_ostream OS(Val);218    V->printAsOperand(OS, /*PrintType=*/false);219  } else if (auto *II = dyn_cast<IntrinsicInst>(V)) {220    raw_string_ostream OS(Val);221    OS << "call " << II->getCalledFunction()->getName();222  } else if (auto *I = dyn_cast<Instruction>(V)) {223    Val = I->getOpcodeName();224  } else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {225    if (auto *S = dyn_cast<MDString>(MD->getMetadata()))226      Val = S->getString();227  }228}229 230DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)231    : Key(std::string(Key)) {232  raw_string_ostream OS(Val);233  OS << *T;234}235 236DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)237    : Key(std::string(Key)), Val(S.str()) {}238 239DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)240    : Key(std::string(Key)), Val(itostr(N)) {}241 242DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)243    : Key(std::string(Key)), Val(llvm::to_string(N)) {}244 245DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)246    : Key(std::string(Key)), Val(itostr(N)) {}247 248DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)249    : Key(std::string(Key)), Val(itostr(N)) {}250 251DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)252    : Key(std::string(Key)), Val(utostr(N)) {}253 254DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,255                                                   unsigned long N)256    : Key(std::string(Key)), Val(utostr(N)) {}257 258DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,259                                                   unsigned long long N)260    : Key(std::string(Key)), Val(utostr(N)) {}261 262DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,263                                                   ElementCount EC)264    : Key(std::string(Key)) {265  raw_string_ostream OS(Val);266  EC.print(OS);267}268 269DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,270                                                   InstructionCost C)271    : Key(std::string(Key)) {272  raw_string_ostream OS(Val);273  C.print(OS);274}275 276DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,277                                                   BranchProbability P)278    : Key(std::string(Key)) {279  raw_string_ostream OS(Val);280  P.print(OS);281}282 283DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)284    : Key(std::string(Key)), Loc(Loc) {285  if (Loc) {286    Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +287           Twine(Loc.getCol())).str();288  } else {289    Val = "<UNKNOWN LOCATION>";290  }291}292 293void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {294  DP << getLocationStr() << ": " << getMsg();295  if (Hotness)296    DP << " (hotness: " << *Hotness << ")";297}298 299OptimizationRemark::OptimizationRemark(const char *PassName,300                                       StringRef RemarkName,301                                       const DiagnosticLocation &Loc,302                                       const BasicBlock *CodeRegion)303    : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,304                                   RemarkName, *CodeRegion->getParent(), Loc,305                                   CodeRegion) {}306 307OptimizationRemark::OptimizationRemark(const char *PassName,308                                       StringRef RemarkName,309                                       const Instruction *Inst)310    : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,311                                   RemarkName, *Inst->getParent()->getParent(),312                                   Inst->getDebugLoc(), Inst->getParent()) {}313 314static const BasicBlock *getFirstFunctionBlock(const Function *Func) {315  return Func->empty() ? nullptr : &Func->front();316}317 318OptimizationRemark::OptimizationRemark(const char *PassName,319                                       StringRef RemarkName,320                                       const Function *Func)321    : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,322                                   RemarkName, *Func, Func->getSubprogram(),323                                   getFirstFunctionBlock(Func)) {}324 325bool OptimizationRemark::isEnabled() const {326  const Function &Fn = getFunction();327  LLVMContext &Ctx = Fn.getContext();328  return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());329}330 331OptimizationRemarkMissed::OptimizationRemarkMissed(332    const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,333    const BasicBlock *CodeRegion)334    : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,335                                   PassName, RemarkName,336                                   *CodeRegion->getParent(), Loc, CodeRegion) {}337 338OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,339                                                   StringRef RemarkName,340                                                   const Instruction *Inst)341    : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,342                                   PassName, RemarkName,343                                   *Inst->getParent()->getParent(),344                                   Inst->getDebugLoc(), Inst->getParent()) {}345 346OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,347                                                   StringRef RemarkName,348                                                   const Function *Func)349    : DiagnosticInfoIROptimization(350          DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *Func,351          Func->getSubprogram(), getFirstFunctionBlock(Func)) {}352 353bool OptimizationRemarkMissed::isEnabled() const {354  const Function &Fn = getFunction();355  LLVMContext &Ctx = Fn.getContext();356  return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());357}358 359OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(360    const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,361    const BasicBlock *CodeRegion)362    : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,363                                   PassName, RemarkName,364                                   *CodeRegion->getParent(), Loc, CodeRegion) {}365 366OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,367                                                       StringRef RemarkName,368                                                       const Instruction *Inst)369    : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,370                                   PassName, RemarkName,371                                   *Inst->getParent()->getParent(),372                                   Inst->getDebugLoc(), Inst->getParent()) {}373 374OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(375    enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,376    const DiagnosticLocation &Loc, const BasicBlock *CodeRegion)377    : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,378                                   *CodeRegion->getParent(), Loc, CodeRegion) {}379 380OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,381                                                       StringRef RemarkName,382                                                       const Function *Func)383    : DiagnosticInfoIROptimization(384          DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *Func,385          Func->getSubprogram(), getFirstFunctionBlock(Func)) {}386 387bool OptimizationRemarkAnalysis::isEnabled() const {388  const Function &Fn = getFunction();389  LLVMContext &Ctx = Fn.getContext();390  return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||391         shouldAlwaysPrint();392}393 394void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {395  DP << Diagnostic;396}397 398void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {399  DP << Diagnostic;400}401 402DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(403    const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,404    const BasicBlock *CodeRegion)405    : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning, PassName,406                                   RemarkName, *CodeRegion->getParent(), Loc,407                                   CodeRegion) {}408 409bool DiagnosticInfoOptimizationFailure::isEnabled() const {410  // Only print warnings.411  return getSeverity() == DS_Warning;412}413 414void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {415  std::string Str;416  raw_string_ostream OS(Str);417 418  OS << getLocationStr() << ": in function " << getFunction().getName() << ' '419     << *getFunction().getFunctionType() << ": " << Msg << '\n';420  OS.flush();421  DP << Str;422}423 424void DiagnosticInfoInstrumentation::print(DiagnosticPrinter &DP) const {425  DP << Msg;426}427 428void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {429  DP << "Instruction selection used fallback path for " << getFunction();430}431 432void DiagnosticInfoOptimizationBase::insert(StringRef S) {433  Args.emplace_back(S);434}435 436void DiagnosticInfoOptimizationBase::insert(Argument A) {437  Args.push_back(std::move(A));438}439 440void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {441  IsVerbose = true;442}443 444void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {445  FirstExtraArgIndex = Args.size();446}447 448std::string DiagnosticInfoOptimizationBase::getMsg() const {449  std::string Str;450  raw_string_ostream OS(Str);451  for (const DiagnosticInfoOptimizationBase::Argument &Arg :452       make_range(Args.begin(), FirstExtraArgIndex == -1453                                    ? Args.end()454                                    : Args.begin() + FirstExtraArgIndex))455    OS << Arg.Val;456  return Str;457}458 459DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,460                                                 const Twine &Msg)461    : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,462                                     *Inst->getParent()->getParent(),463                                     Inst->getDebugLoc()),464      Msg(Msg) {}465 466void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {467  DP << getLocationStr() << ": " << getMsg();468}469 470void OptimizationRemarkAnalysisFPCommute::anchor() {}471void OptimizationRemarkAnalysisAliasing::anchor() {}472 473void llvm::diagnoseDontCall(const CallInst &CI) {474  const auto *F =475      dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());476 477  if (!F)478    return;479 480  for (int i = 0; i != 2; ++i) {481    auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";482    auto Sev = i == 0 ? DS_Error : DS_Warning;483 484    if (F->hasFnAttribute(AttrName)) {485      uint64_t LocCookie = 0;486      auto A = F->getFnAttribute(AttrName);487      if (MDNode *MD = CI.getMetadata("srcloc"))488        LocCookie =489            mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();490      DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,491                               LocCookie);492      F->getContext().diagnose(D);493    }494  }495}496 497void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {498  DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";499  if (getSeverity() == DiagnosticSeverity::DS_Error)500    DP << "error\"";501  else502    DP << "warn\"";503  if (!getNote().empty())504    DP << ": " << getNote();505}506