xref: /openbsd/gnu/llvm/llvm/lib/IR/DiagnosticInfo.cpp (revision d415bd75)
1*d415bd75Srobert //===- llvm/IR/DiagnosticInfo.cpp - Diagnostic Definitions ------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file defines the different classes involved in low level diagnostics.
1009467b48Spatrick //
1109467b48Spatrick // Diagnostics reporting is still done as part of the LLVMContext.
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "llvm/IR/DiagnosticInfo.h"
1509467b48Spatrick #include "llvm/ADT/StringExtras.h"
1609467b48Spatrick #include "llvm/ADT/Twine.h"
1709467b48Spatrick #include "llvm/ADT/iterator_range.h"
1809467b48Spatrick #include "llvm/IR/BasicBlock.h"
1909467b48Spatrick #include "llvm/IR/Constants.h"
2009467b48Spatrick #include "llvm/IR/DebugInfoMetadata.h"
2109467b48Spatrick #include "llvm/IR/DerivedTypes.h"
2209467b48Spatrick #include "llvm/IR/DiagnosticPrinter.h"
2309467b48Spatrick #include "llvm/IR/Function.h"
2409467b48Spatrick #include "llvm/IR/GlobalValue.h"
2509467b48Spatrick #include "llvm/IR/Instruction.h"
26*d415bd75Srobert #include "llvm/IR/Instructions.h"
2709467b48Spatrick #include "llvm/IR/LLVMContext.h"
2809467b48Spatrick #include "llvm/IR/Metadata.h"
2909467b48Spatrick #include "llvm/IR/Module.h"
3009467b48Spatrick #include "llvm/IR/Type.h"
3109467b48Spatrick #include "llvm/IR/Value.h"
3209467b48Spatrick #include "llvm/Support/Casting.h"
3309467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3473471bf0Spatrick #include "llvm/Support/InstructionCost.h"
3509467b48Spatrick #include "llvm/Support/Path.h"
3609467b48Spatrick #include "llvm/Support/ScopedPrinter.h"
3709467b48Spatrick #include "llvm/Support/raw_ostream.h"
3809467b48Spatrick #include <atomic>
3909467b48Spatrick #include <string>
4009467b48Spatrick 
4109467b48Spatrick using namespace llvm;
4209467b48Spatrick 
getNextAvailablePluginDiagnosticKind()4309467b48Spatrick int llvm::getNextAvailablePluginDiagnosticKind() {
4409467b48Spatrick   static std::atomic<int> PluginKindID(DK_FirstPluginKind);
4509467b48Spatrick   return ++PluginKindID;
4609467b48Spatrick }
4709467b48Spatrick 
4809467b48Spatrick const char *OptimizationRemarkAnalysis::AlwaysPrint = "";
4909467b48Spatrick 
DiagnosticInfoInlineAsm(const Instruction & I,const Twine & MsgStr,DiagnosticSeverity Severity)5009467b48Spatrick DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
5109467b48Spatrick                                                  const Twine &MsgStr,
5209467b48Spatrick                                                  DiagnosticSeverity Severity)
5309467b48Spatrick     : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr), Instr(&I) {
5409467b48Spatrick   if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
5509467b48Spatrick     if (SrcLoc->getNumOperands() != 0)
5609467b48Spatrick       if (const auto *CI =
5709467b48Spatrick               mdconst::dyn_extract<ConstantInt>(SrcLoc->getOperand(0)))
5809467b48Spatrick         LocCookie = CI->getZExtValue();
5909467b48Spatrick   }
6009467b48Spatrick }
6109467b48Spatrick 
print(DiagnosticPrinter & DP) const6209467b48Spatrick void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
6309467b48Spatrick   DP << getMsgStr();
6409467b48Spatrick   if (getLocCookie())
6509467b48Spatrick     DP << " at line " << getLocCookie();
6609467b48Spatrick }
6709467b48Spatrick 
DiagnosticInfoResourceLimit(const Function & Fn,const char * ResourceName,uint64_t ResourceSize,uint64_t ResourceLimit,DiagnosticSeverity Severity,DiagnosticKind Kind)68*d415bd75Srobert DiagnosticInfoResourceLimit::DiagnosticInfoResourceLimit(
69*d415bd75Srobert     const Function &Fn, const char *ResourceName, uint64_t ResourceSize,
70*d415bd75Srobert     uint64_t ResourceLimit, DiagnosticSeverity Severity, DiagnosticKind Kind)
71*d415bd75Srobert     : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Fn.getSubprogram()),
72*d415bd75Srobert       Fn(Fn), ResourceName(ResourceName), ResourceSize(ResourceSize),
73*d415bd75Srobert       ResourceLimit(ResourceLimit) {}
74*d415bd75Srobert 
print(DiagnosticPrinter & DP) const7509467b48Spatrick void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const {
76*d415bd75Srobert   DP << getLocationStr() << ": " << getResourceName() << " ("
77*d415bd75Srobert      << getResourceSize() << ") exceeds limit (" << getResourceLimit()
78*d415bd75Srobert      << ") in function '" << getFunction() << '\'';
7909467b48Spatrick }
8009467b48Spatrick 
print(DiagnosticPrinter & DP) const8109467b48Spatrick void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
8209467b48Spatrick   DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
8309467b48Spatrick      << ") in " << getModule();
8409467b48Spatrick }
8509467b48Spatrick 
print(DiagnosticPrinter & DP) const8609467b48Spatrick void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
8709467b48Spatrick     DiagnosticPrinter &DP) const {
8809467b48Spatrick   DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
8909467b48Spatrick }
9009467b48Spatrick 
print(DiagnosticPrinter & DP) const9109467b48Spatrick void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
9209467b48Spatrick   if (!FileName.empty()) {
9309467b48Spatrick     DP << getFileName();
9409467b48Spatrick     if (LineNum > 0)
9509467b48Spatrick       DP << ":" << getLineNum();
9609467b48Spatrick     DP << ": ";
9709467b48Spatrick   }
9809467b48Spatrick   DP << getMsg();
9909467b48Spatrick }
10009467b48Spatrick 
print(DiagnosticPrinter & DP) const10109467b48Spatrick void DiagnosticInfoPGOProfile::print(DiagnosticPrinter &DP) const {
10209467b48Spatrick   if (getFileName())
10309467b48Spatrick     DP << getFileName() << ": ";
10409467b48Spatrick   DP << getMsg();
10509467b48Spatrick }
10609467b48Spatrick 
anchor()10709467b48Spatrick void DiagnosticInfo::anchor() {}
anchor()10809467b48Spatrick void DiagnosticInfoStackSize::anchor() {}
anchor()10909467b48Spatrick void DiagnosticInfoWithLocationBase::anchor() {}
anchor()11009467b48Spatrick void DiagnosticInfoIROptimization::anchor() {}
11109467b48Spatrick 
DiagnosticLocation(const DebugLoc & DL)11209467b48Spatrick DiagnosticLocation::DiagnosticLocation(const DebugLoc &DL) {
11309467b48Spatrick   if (!DL)
11409467b48Spatrick     return;
11509467b48Spatrick   File = DL->getFile();
11609467b48Spatrick   Line = DL->getLine();
11709467b48Spatrick   Column = DL->getColumn();
11809467b48Spatrick }
11909467b48Spatrick 
DiagnosticLocation(const DISubprogram * SP)12009467b48Spatrick DiagnosticLocation::DiagnosticLocation(const DISubprogram *SP) {
12109467b48Spatrick   if (!SP)
12209467b48Spatrick     return;
12309467b48Spatrick 
12409467b48Spatrick   File = SP->getFile();
12509467b48Spatrick   Line = SP->getScopeLine();
12609467b48Spatrick   Column = 0;
12709467b48Spatrick }
12809467b48Spatrick 
getRelativePath() const12909467b48Spatrick StringRef DiagnosticLocation::getRelativePath() const {
13009467b48Spatrick   return File->getFilename();
13109467b48Spatrick }
13209467b48Spatrick 
getAbsolutePath() const13309467b48Spatrick std::string DiagnosticLocation::getAbsolutePath() const {
13409467b48Spatrick   StringRef Name = File->getFilename();
13509467b48Spatrick   if (sys::path::is_absolute(Name))
136097a140dSpatrick     return std::string(Name);
13709467b48Spatrick 
13809467b48Spatrick   SmallString<128> Path;
13909467b48Spatrick   sys::path::append(Path, File->getDirectory(), Name);
14009467b48Spatrick   return sys::path::remove_leading_dotslash(Path).str();
14109467b48Spatrick }
14209467b48Spatrick 
getAbsolutePath() const14309467b48Spatrick std::string DiagnosticInfoWithLocationBase::getAbsolutePath() const {
14409467b48Spatrick   return Loc.getAbsolutePath();
14509467b48Spatrick }
14609467b48Spatrick 
getLocation(StringRef & RelativePath,unsigned & Line,unsigned & Column) const14709467b48Spatrick void DiagnosticInfoWithLocationBase::getLocation(StringRef &RelativePath,
14809467b48Spatrick                                                  unsigned &Line,
14909467b48Spatrick                                                  unsigned &Column) const {
15009467b48Spatrick   RelativePath = Loc.getRelativePath();
15109467b48Spatrick   Line = Loc.getLine();
15209467b48Spatrick   Column = Loc.getColumn();
15309467b48Spatrick }
15409467b48Spatrick 
getLocationStr() const15573471bf0Spatrick std::string DiagnosticInfoWithLocationBase::getLocationStr() const {
15609467b48Spatrick   StringRef Filename("<unknown>");
15709467b48Spatrick   unsigned Line = 0;
15809467b48Spatrick   unsigned Column = 0;
15909467b48Spatrick   if (isLocationAvailable())
16009467b48Spatrick     getLocation(Filename, Line, Column);
16109467b48Spatrick   return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
16209467b48Spatrick }
16309467b48Spatrick 
Argument(StringRef Key,const Value * V)164097a140dSpatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
165097a140dSpatrick                                                    const Value *V)
166097a140dSpatrick     : Key(std::string(Key)) {
16709467b48Spatrick   if (auto *F = dyn_cast<Function>(V)) {
16809467b48Spatrick     if (DISubprogram *SP = F->getSubprogram())
16909467b48Spatrick       Loc = SP;
17009467b48Spatrick   }
17109467b48Spatrick   else if (auto *I = dyn_cast<Instruction>(V))
17209467b48Spatrick     Loc = I->getDebugLoc();
17309467b48Spatrick 
17409467b48Spatrick   // Only include names that correspond to user variables.  FIXME: We should use
17509467b48Spatrick   // debug info if available to get the name of the user variable.
17609467b48Spatrick   if (isa<llvm::Argument>(V) || isa<GlobalValue>(V))
177097a140dSpatrick     Val = std::string(GlobalValue::dropLLVMManglingEscape(V->getName()));
17809467b48Spatrick   else if (isa<Constant>(V)) {
17909467b48Spatrick     raw_string_ostream OS(Val);
18009467b48Spatrick     V->printAsOperand(OS, /*PrintType=*/false);
18109467b48Spatrick   } else if (auto *I = dyn_cast<Instruction>(V))
18209467b48Spatrick     Val = I->getOpcodeName();
18309467b48Spatrick }
18409467b48Spatrick 
Argument(StringRef Key,const Type * T)18509467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)
186097a140dSpatrick     : Key(std::string(Key)) {
18709467b48Spatrick   raw_string_ostream OS(Val);
18809467b48Spatrick   OS << *T;
18909467b48Spatrick }
19009467b48Spatrick 
Argument(StringRef Key,StringRef S)19109467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
192097a140dSpatrick     : Key(std::string(Key)), Val(S.str()) {}
19309467b48Spatrick 
Argument(StringRef Key,int N)19409467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
195097a140dSpatrick     : Key(std::string(Key)), Val(itostr(N)) {}
19609467b48Spatrick 
Argument(StringRef Key,float N)19709467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
198097a140dSpatrick     : Key(std::string(Key)), Val(llvm::to_string(N)) {}
19909467b48Spatrick 
Argument(StringRef Key,long N)20009467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
201097a140dSpatrick     : Key(std::string(Key)), Val(itostr(N)) {}
20209467b48Spatrick 
Argument(StringRef Key,long long N)20309467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long long N)
204097a140dSpatrick     : Key(std::string(Key)), Val(itostr(N)) {}
20509467b48Spatrick 
Argument(StringRef Key,unsigned N)20609467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, unsigned N)
207097a140dSpatrick     : Key(std::string(Key)), Val(utostr(N)) {}
20809467b48Spatrick 
Argument(StringRef Key,unsigned long N)20909467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
21009467b48Spatrick                                                    unsigned long N)
211097a140dSpatrick     : Key(std::string(Key)), Val(utostr(N)) {}
21209467b48Spatrick 
Argument(StringRef Key,unsigned long long N)21309467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
21409467b48Spatrick                                                    unsigned long long N)
215097a140dSpatrick     : Key(std::string(Key)), Val(utostr(N)) {}
21609467b48Spatrick 
Argument(StringRef Key,ElementCount EC)21773471bf0Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
21873471bf0Spatrick                                                    ElementCount EC)
21973471bf0Spatrick     : Key(std::string(Key)) {
22073471bf0Spatrick   raw_string_ostream OS(Val);
22173471bf0Spatrick   EC.print(OS);
22273471bf0Spatrick }
22373471bf0Spatrick 
Argument(StringRef Key,InstructionCost C)22473471bf0Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
22573471bf0Spatrick                                                    InstructionCost C)
22673471bf0Spatrick     : Key(std::string(Key)) {
22773471bf0Spatrick   raw_string_ostream OS(Val);
22873471bf0Spatrick   C.print(OS);
22973471bf0Spatrick }
23073471bf0Spatrick 
Argument(StringRef Key,DebugLoc Loc)23109467b48Spatrick DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
232097a140dSpatrick     : Key(std::string(Key)), Loc(Loc) {
23309467b48Spatrick   if (Loc) {
23409467b48Spatrick     Val = (Loc->getFilename() + ":" + Twine(Loc.getLine()) + ":" +
23509467b48Spatrick            Twine(Loc.getCol())).str();
23609467b48Spatrick   } else {
23709467b48Spatrick     Val = "<UNKNOWN LOCATION>";
23809467b48Spatrick   }
23909467b48Spatrick }
24009467b48Spatrick 
print(DiagnosticPrinter & DP) const24109467b48Spatrick void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
24209467b48Spatrick   DP << getLocationStr() << ": " << getMsg();
24309467b48Spatrick   if (Hotness)
24409467b48Spatrick     DP << " (hotness: " << *Hotness << ")";
24509467b48Spatrick }
24609467b48Spatrick 
OptimizationRemark(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)24709467b48Spatrick OptimizationRemark::OptimizationRemark(const char *PassName,
24809467b48Spatrick                                        StringRef RemarkName,
24909467b48Spatrick                                        const DiagnosticLocation &Loc,
25009467b48Spatrick                                        const Value *CodeRegion)
25109467b48Spatrick     : DiagnosticInfoIROptimization(
25209467b48Spatrick           DK_OptimizationRemark, DS_Remark, PassName, RemarkName,
25309467b48Spatrick           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
25409467b48Spatrick 
OptimizationRemark(const char * PassName,StringRef RemarkName,const Instruction * Inst)25509467b48Spatrick OptimizationRemark::OptimizationRemark(const char *PassName,
25609467b48Spatrick                                        StringRef RemarkName,
25709467b48Spatrick                                        const Instruction *Inst)
25809467b48Spatrick     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
25909467b48Spatrick                                    RemarkName, *Inst->getParent()->getParent(),
26009467b48Spatrick                                    Inst->getDebugLoc(), Inst->getParent()) {}
26109467b48Spatrick 
getFirstFunctionBlock(const Function * Func)262097a140dSpatrick static const BasicBlock *getFirstFunctionBlock(const Function *Func) {
263097a140dSpatrick   return Func->empty() ? nullptr : &Func->front();
26409467b48Spatrick }
26509467b48Spatrick 
OptimizationRemark(const char * PassName,StringRef RemarkName,const Function * Func)26609467b48Spatrick OptimizationRemark::OptimizationRemark(const char *PassName,
26709467b48Spatrick                                        StringRef RemarkName,
26809467b48Spatrick                                        const Function *Func)
26909467b48Spatrick     : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
27009467b48Spatrick                                    RemarkName, *Func, Func->getSubprogram(),
271097a140dSpatrick                                    getFirstFunctionBlock(Func)) {}
27209467b48Spatrick 
isEnabled() const27309467b48Spatrick bool OptimizationRemark::isEnabled() const {
27409467b48Spatrick   const Function &Fn = getFunction();
27509467b48Spatrick   LLVMContext &Ctx = Fn.getContext();
27609467b48Spatrick   return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
27709467b48Spatrick }
27809467b48Spatrick 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)27909467b48Spatrick OptimizationRemarkMissed::OptimizationRemarkMissed(
28009467b48Spatrick     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
28109467b48Spatrick     const Value *CodeRegion)
28209467b48Spatrick     : DiagnosticInfoIROptimization(
28309467b48Spatrick           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName,
28409467b48Spatrick           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
28509467b48Spatrick 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const Instruction * Inst)28609467b48Spatrick OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
28709467b48Spatrick                                                    StringRef RemarkName,
28809467b48Spatrick                                                    const Instruction *Inst)
28909467b48Spatrick     : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
29009467b48Spatrick                                    PassName, RemarkName,
29109467b48Spatrick                                    *Inst->getParent()->getParent(),
29209467b48Spatrick                                    Inst->getDebugLoc(), Inst->getParent()) {}
29309467b48Spatrick 
OptimizationRemarkMissed(const char * PassName,StringRef RemarkName,const Function * Func)29473471bf0Spatrick OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
29573471bf0Spatrick                                                    StringRef RemarkName,
29673471bf0Spatrick                                                    const Function *Func)
29773471bf0Spatrick     : DiagnosticInfoIROptimization(
29873471bf0Spatrick           DK_OptimizationRemarkMissed, DS_Remark, PassName, RemarkName, *Func,
29973471bf0Spatrick           Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
30073471bf0Spatrick 
isEnabled() const30109467b48Spatrick bool OptimizationRemarkMissed::isEnabled() const {
30209467b48Spatrick   const Function &Fn = getFunction();
30309467b48Spatrick   LLVMContext &Ctx = Fn.getContext();
30409467b48Spatrick   return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
30509467b48Spatrick }
30609467b48Spatrick 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)30709467b48Spatrick OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
30809467b48Spatrick     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
30909467b48Spatrick     const Value *CodeRegion)
31009467b48Spatrick     : DiagnosticInfoIROptimization(
31109467b48Spatrick           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName,
31209467b48Spatrick           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
31309467b48Spatrick 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const Instruction * Inst)31409467b48Spatrick OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
31509467b48Spatrick                                                        StringRef RemarkName,
31609467b48Spatrick                                                        const Instruction *Inst)
31709467b48Spatrick     : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
31809467b48Spatrick                                    PassName, RemarkName,
31909467b48Spatrick                                    *Inst->getParent()->getParent(),
32009467b48Spatrick                                    Inst->getDebugLoc(), Inst->getParent()) {}
32109467b48Spatrick 
OptimizationRemarkAnalysis(enum DiagnosticKind Kind,const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)32209467b48Spatrick OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
32309467b48Spatrick     enum DiagnosticKind Kind, const char *PassName, StringRef RemarkName,
32409467b48Spatrick     const DiagnosticLocation &Loc, const Value *CodeRegion)
32509467b48Spatrick     : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, RemarkName,
32609467b48Spatrick                                    *cast<BasicBlock>(CodeRegion)->getParent(),
32709467b48Spatrick                                    Loc, CodeRegion) {}
32809467b48Spatrick 
OptimizationRemarkAnalysis(const char * PassName,StringRef RemarkName,const Function * Func)32973471bf0Spatrick OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
33073471bf0Spatrick                                                        StringRef RemarkName,
33173471bf0Spatrick                                                        const Function *Func)
33273471bf0Spatrick     : DiagnosticInfoIROptimization(
33373471bf0Spatrick           DK_OptimizationRemarkAnalysis, DS_Remark, PassName, RemarkName, *Func,
33473471bf0Spatrick           Func->getSubprogram(), getFirstFunctionBlock(Func)) {}
33573471bf0Spatrick 
isEnabled() const33609467b48Spatrick bool OptimizationRemarkAnalysis::isEnabled() const {
33709467b48Spatrick   const Function &Fn = getFunction();
33809467b48Spatrick   LLVMContext &Ctx = Fn.getContext();
33909467b48Spatrick   return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
34009467b48Spatrick          shouldAlwaysPrint();
34109467b48Spatrick }
34209467b48Spatrick 
print(DiagnosticPrinter & DP) const34309467b48Spatrick void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
34409467b48Spatrick   DP << Diagnostic;
34509467b48Spatrick }
34609467b48Spatrick 
print(DiagnosticPrinter & DP) const34773471bf0Spatrick void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {
34873471bf0Spatrick   DP << Diagnostic;
34973471bf0Spatrick }
35073471bf0Spatrick 
DiagnosticInfoOptimizationFailure(const char * PassName,StringRef RemarkName,const DiagnosticLocation & Loc,const Value * CodeRegion)35109467b48Spatrick DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
35209467b48Spatrick     const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
35309467b48Spatrick     const Value *CodeRegion)
35409467b48Spatrick     : DiagnosticInfoIROptimization(
35509467b48Spatrick           DK_OptimizationFailure, DS_Warning, PassName, RemarkName,
35609467b48Spatrick           *cast<BasicBlock>(CodeRegion)->getParent(), Loc, CodeRegion) {}
35709467b48Spatrick 
isEnabled() const35809467b48Spatrick bool DiagnosticInfoOptimizationFailure::isEnabled() const {
35909467b48Spatrick   // Only print warnings.
36009467b48Spatrick   return getSeverity() == DS_Warning;
36109467b48Spatrick }
36209467b48Spatrick 
print(DiagnosticPrinter & DP) const36309467b48Spatrick void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
36409467b48Spatrick   std::string Str;
36509467b48Spatrick   raw_string_ostream OS(Str);
36609467b48Spatrick 
36709467b48Spatrick   OS << getLocationStr() << ": in function " << getFunction().getName() << ' '
36809467b48Spatrick      << *getFunction().getFunctionType() << ": " << Msg << '\n';
36909467b48Spatrick   OS.flush();
37009467b48Spatrick   DP << Str;
37109467b48Spatrick }
37209467b48Spatrick 
print(DiagnosticPrinter & DP) const37309467b48Spatrick void DiagnosticInfoISelFallback::print(DiagnosticPrinter &DP) const {
37409467b48Spatrick   DP << "Instruction selection used fallback path for " << getFunction();
37509467b48Spatrick }
37609467b48Spatrick 
insert(StringRef S)37709467b48Spatrick void DiagnosticInfoOptimizationBase::insert(StringRef S) {
37809467b48Spatrick   Args.emplace_back(S);
37909467b48Spatrick }
38009467b48Spatrick 
insert(Argument A)38109467b48Spatrick void DiagnosticInfoOptimizationBase::insert(Argument A) {
38209467b48Spatrick   Args.push_back(std::move(A));
38309467b48Spatrick }
38409467b48Spatrick 
insert(setIsVerbose V)38509467b48Spatrick void DiagnosticInfoOptimizationBase::insert(setIsVerbose V) {
38609467b48Spatrick   IsVerbose = true;
38709467b48Spatrick }
38809467b48Spatrick 
insert(setExtraArgs EA)38909467b48Spatrick void DiagnosticInfoOptimizationBase::insert(setExtraArgs EA) {
39009467b48Spatrick   FirstExtraArgIndex = Args.size();
39109467b48Spatrick }
39209467b48Spatrick 
getMsg() const39309467b48Spatrick std::string DiagnosticInfoOptimizationBase::getMsg() const {
39409467b48Spatrick   std::string Str;
39509467b48Spatrick   raw_string_ostream OS(Str);
39609467b48Spatrick   for (const DiagnosticInfoOptimizationBase::Argument &Arg :
39709467b48Spatrick        make_range(Args.begin(), FirstExtraArgIndex == -1
39809467b48Spatrick                                     ? Args.end()
39909467b48Spatrick                                     : Args.begin() + FirstExtraArgIndex))
40009467b48Spatrick     OS << Arg.Val;
40109467b48Spatrick   return OS.str();
40209467b48Spatrick }
40309467b48Spatrick 
DiagnosticInfoMisExpect(const Instruction * Inst,Twine & Msg)404*d415bd75Srobert DiagnosticInfoMisExpect::DiagnosticInfoMisExpect(const Instruction *Inst,
405*d415bd75Srobert                                                  Twine &Msg)
406*d415bd75Srobert     : DiagnosticInfoWithLocationBase(DK_MisExpect, DS_Warning,
407*d415bd75Srobert                                      *Inst->getParent()->getParent(),
408*d415bd75Srobert                                      Inst->getDebugLoc()),
409*d415bd75Srobert       Msg(Msg) {}
410*d415bd75Srobert 
print(DiagnosticPrinter & DP) const411*d415bd75Srobert void DiagnosticInfoMisExpect::print(DiagnosticPrinter &DP) const {
412*d415bd75Srobert   DP << getLocationStr() << ": " << getMsg();
413*d415bd75Srobert }
414*d415bd75Srobert 
anchor()41509467b48Spatrick void OptimizationRemarkAnalysisFPCommute::anchor() {}
anchor()41609467b48Spatrick void OptimizationRemarkAnalysisAliasing::anchor() {}
417*d415bd75Srobert 
diagnoseDontCall(const CallInst & CI)418*d415bd75Srobert void llvm::diagnoseDontCall(const CallInst &CI) {
419*d415bd75Srobert   const auto *F =
420*d415bd75Srobert       dyn_cast<Function>(CI.getCalledOperand()->stripPointerCasts());
421*d415bd75Srobert 
422*d415bd75Srobert   if (!F)
423*d415bd75Srobert     return;
424*d415bd75Srobert 
425*d415bd75Srobert   for (int i = 0; i != 2; ++i) {
426*d415bd75Srobert     auto AttrName = i == 0 ? "dontcall-error" : "dontcall-warn";
427*d415bd75Srobert     auto Sev = i == 0 ? DS_Error : DS_Warning;
428*d415bd75Srobert 
429*d415bd75Srobert     if (F->hasFnAttribute(AttrName)) {
430*d415bd75Srobert       unsigned LocCookie = 0;
431*d415bd75Srobert       auto A = F->getFnAttribute(AttrName);
432*d415bd75Srobert       if (MDNode *MD = CI.getMetadata("srcloc"))
433*d415bd75Srobert         LocCookie =
434*d415bd75Srobert             mdconst::extract<ConstantInt>(MD->getOperand(0))->getZExtValue();
435*d415bd75Srobert       DiagnosticInfoDontCall D(F->getName(), A.getValueAsString(), Sev,
436*d415bd75Srobert                                LocCookie);
437*d415bd75Srobert       F->getContext().diagnose(D);
438*d415bd75Srobert     }
439*d415bd75Srobert   }
440*d415bd75Srobert }
441*d415bd75Srobert 
print(DiagnosticPrinter & DP) const442*d415bd75Srobert void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
443*d415bd75Srobert   DP << "call to " << getFunctionName() << " marked \"dontcall-";
444*d415bd75Srobert   if (getSeverity() == DiagnosticSeverity::DS_Error)
445*d415bd75Srobert     DP << "error\"";
446*d415bd75Srobert   else
447*d415bd75Srobert     DP << "warn\"";
448*d415bd75Srobert   if (!getNote().empty())
449*d415bd75Srobert     DP << ": " << getNote();
450*d415bd75Srobert }
451