32#define DEBUG_TYPE "debugify"
39 cl::desc(
"Suppress verbose debugify output"));
42 "debugify-func-limit",
43 cl::desc(
"Set max number of processed functions per pass."),
52 "debugify-level",
cl::desc(
"Kind of debug info to add"),
54 clEnumValN(Level::LocationsAndVariables,
"location+variables",
55 "Locations and Variables")),
56 cl::init(Level::LocationsAndVariables));
61 return Ty->
isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
65 return F.isDeclaration() || !
F.hasExactDefinition();
85 if (
M.getNamedMetadata(
"llvm.dbg.cu")) {
86 dbg() << Banner <<
"Skipping module with debug info\n";
96 auto getCachedDIType = [&](
Type *Ty) ->
DIType * {
100 std::string
Name =
"ty" + utostr(
Size);
106 unsigned NextLine = 1;
107 unsigned NextVar = 1;
114 if (isFunctionSkipped(
F))
117 bool InsertedDbgVal =
false;
121 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
122 if (
F.hasPrivateLinkage() ||
F.hasInternalLinkage())
123 SPFlags |= DISubprogram::SPFlagLocalToUnit;
125 SPType, NextLine, DINode::FlagZero, SPFlags);
132 std::string
Name = utostr(NextVar++);
138 getCachedDIType(
V->getType()),
147 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
149 if (DebugifyLevel < Level::LocationsAndVariables)
158 Instruction *LastInst = findTerminatingInstruction(BB);
159 assert(LastInst &&
"Expected basic block with a terminator");
164 assert(InsertPt != BB.end() &&
"Expected to find an insertion point");
168 for (
Instruction *
I = &*BB.begin();
I != LastInst;
I =
I->getNextNode()) {
170 if (
I->getType()->isVoidTy())
175 if (!isa<PHINode>(
I) && !
I->isEHPad())
176 InsertBefore =
I->getNextNode();
178 insertDbgVal(*
I, InsertBefore);
179 InsertedDbgVal =
true;
187 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
188 auto *
Term = findTerminatingInstruction(
F.getEntryBlock());
189 insertDbgVal(*Term, Term);
198 NamedMDNode *NMD =
M.getOrInsertNamedMetadata(
"llvm.debugify");
199 auto addDebugifyOperand = [&](
unsigned N) {
203 addDebugifyOperand(NextLine - 1);
204 addDebugifyOperand(NextVar - 1);
206 "llvm.debugify should have exactly 2 operands!");
209 StringRef DIVersionKey =
"Debug Info Version";
210 if (!
M.getModuleFlag(DIVersionKey))
222 auto FuncIt =
F.getIterator();
225 "FunctionDebugify: ",
nullptr);
226 assert(DebugInfoBeforePass);
228 "FunctionDebugify (original debuginfo)",
239 "ModuleDebugify: ",
nullptr);
241 "ModuleDebugify (original debuginfo)",
246 bool Changed =
false;
249 NamedMDNode *DebugifyMD = M.getNamedMetadata(
"llvm.debugify");
251 M.eraseNamedMetadata(DebugifyMD);
255 if (
auto *MIRDebugifyMD = M.getNamedMetadata(
"llvm.mir.debugify")) {
256 M.eraseNamedMetadata(MIRDebugifyMD);
265 Function *DbgValF = M.getFunction(
"llvm.dbg.value");
268 "Not all debug info stripped?");
281 auto *Key = cast<MDString>(Flag->getOperand(1));
282 if (Key->getString() ==
"Debug Info Version") {
300 LLVM_DEBUG(
dbgs() << Banner <<
": (before) " << NameOfWrappedPass <<
'\n');
302 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
303 dbg() << Banner <<
": Skipping module without debug info\n";
314 if (isFunctionSkipped(
F))
318 if (++FunctionsCnt >= DebugifyFunctionsLimit)
321 auto *SP =
F.getSubprogram();
325 for (
const DINode *DN : SP->getRetainedNodes()) {
326 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
340 if (DebugifyLevel > Level::Locations) {
341 if (
auto *DVI = dyn_cast<DbgVariableIntrinsic>(&
I)) {
345 if (
I.getDebugLoc().getInlinedAt())
348 if (DVI->isKillLocation())
351 auto *Var = DVI->getVariable();
358 if (isa<DbgInfoIntrinsic>(&
I))
365 bool HasLoc = Loc !=
nullptr;
378 StringRef FileNameFromCU,
bool ShouldWriteIntoJSON,
380 bool Preserved =
true;
381 for (
const auto &
F : DIFunctionsAfter) {
384 auto SPIt = DIFunctionsBefore.
find(
F.first);
385 if (SPIt == DIFunctionsBefore.
end()) {
386 if (ShouldWriteIntoJSON)
388 {
"name",
F.first->getName()},
389 {
"action",
"not-generate"}}));
391 dbg() <<
"ERROR: " << NameOfWrappedPass
392 <<
" did not generate DISubprogram for " <<
F.first->getName()
393 <<
" from " << FileNameFromCU <<
'\n';
396 auto SP = SPIt->second;
401 if (ShouldWriteIntoJSON)
403 {
"name",
F.first->getName()},
404 {
"action",
"drop"}}));
406 dbg() <<
"ERROR: " << NameOfWrappedPass <<
" dropped DISubprogram of "
407 <<
F.first->getName() <<
" from " << FileNameFromCU <<
'\n';
422 bool ShouldWriteIntoJSON,
424 bool Preserved =
true;
425 for (
const auto &L : DILocsAfter) {
428 auto Instr = L.first;
432 auto WeakInstrPtr = InstToDelete.
find(Instr);
433 if (WeakInstrPtr != InstToDelete.
end() && !WeakInstrPtr->second)
436 auto FnName = Instr->getFunction()->getName();
437 auto BB = Instr->getParent();
438 auto BBName = BB->hasName() ? BB->getName() :
"no-name";
441 auto InstrIt = DILocsBefore.
find(Instr);
442 if (InstrIt == DILocsBefore.
end()) {
443 if (ShouldWriteIntoJSON)
445 {
"fn-name", FnName.str()},
446 {
"bb-name", BBName.str()},
448 {
"action",
"not-generate"}}));
450 dbg() <<
"WARNING: " << NameOfWrappedPass
451 <<
" did not generate DILocation for " << *Instr
452 <<
" (BB: " << BBName <<
", Fn: " << FnName
453 <<
", File: " << FileNameFromCU <<
")\n";
456 if (!InstrIt->second)
460 if (ShouldWriteIntoJSON)
462 {
"fn-name", FnName.str()},
463 {
"bb-name", BBName.str()},
465 {
"action",
"drop"}}));
467 dbg() <<
"WARNING: " << NameOfWrappedPass <<
" dropped DILocation of "
468 << *Instr <<
" (BB: " << BBName <<
", Fn: " << FnName
469 <<
", File: " << FileNameFromCU <<
")\n";
482 bool Preserved =
true;
483 for (
const auto &V : DIVarsBefore) {
484 auto VarIt = DIVarsAfter.
find(V.first);
485 if (VarIt == DIVarsAfter.
end())
488 unsigned NumOfDbgValsAfter = VarIt->second;
490 if (V.second > NumOfDbgValsAfter) {
491 if (ShouldWriteIntoJSON)
493 {{
"metadata",
"dbg-var-intrinsic"},
494 {
"name", V.first->getName()},
496 {
"action",
"drop"}}));
498 dbg() <<
"WARNING: " << NameOfWrappedPass
499 <<
" drops dbg.value()/dbg.declare() for " << V.first->getName()
501 <<
"function " << V.first->getScope()->getSubprogram()->getName()
502 <<
" (file " << FileNameFromCU <<
")\n";
518 errs() <<
"Could not open file: " << EC.message() <<
", "
519 << OrigDIVerifyBugsReportFilePath <<
'\n';
523 if (
auto L = OS_FILE.lock()) {
524 OS_FILE <<
"{\"file\":\"" << FileNameFromCU <<
"\", ";
527 NameOfWrappedPass !=
"" ? NameOfWrappedPass :
"no-name";
528 OS_FILE <<
"\"pass\":\"" <<
PassName <<
"\", ";
531 OS_FILE <<
"\"bugs\": " << BugsToPrint;
542 StringRef OrigDIVerifyBugsReportFilePath) {
543 LLVM_DEBUG(
dbgs() << Banner <<
": (after) " << NameOfWrappedPass <<
'\n');
545 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
546 dbg() << Banner <<
": Skipping module without debug info\n";
555 if (isFunctionSkipped(
F))
563 auto *SP =
F.getSubprogram();
568 for (
const DINode *DN : SP->getRetainedNodes()) {
569 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
583 if (DebugifyLevel > Level::Locations) {
584 if (
auto *DVI = dyn_cast<DbgVariableIntrinsic>(&
I)) {
588 if (
I.getDebugLoc().getInlinedAt())
591 if (DVI->isKillLocation())
594 auto *Var = DVI->getVariable();
601 if (isa<DbgInfoIntrinsic>(&
I))
607 bool HasLoc = Loc !=
nullptr;
616 (cast<DICompileUnit>(M.getNamedMetadata(
"llvm.dbg.cu")->getOperand(0)))
619 auto DIFunctionsBefore = DebugInfoBeforePass.
DIFunctions;
620 auto DIFunctionsAfter = DebugInfoAfterPass.
DIFunctions;
622 auto DILocsBefore = DebugInfoBeforePass.
DILocations;
627 auto DIVarsBefore = DebugInfoBeforePass.
DIVariables;
630 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.
empty();
634 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
635 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
637 DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
638 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
640 bool ResultForVars =
checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
641 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
643 bool Result = ResultForFunc && ResultForInsts && ResultForVars;
645 StringRef ResultBanner = NameOfWrappedPass !=
"" ? NameOfWrappedPass : Banner;
646 if (ShouldWriteIntoJSON && !Bugs.
empty())
647 writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
651 dbg() << ResultBanner <<
": PASS\n";
653 dbg() << ResultBanner <<
": FAIL\n";
658 DebugInfoBeforePass = DebugInfoAfterPass;
682 Type *Ty = V->getType();
683 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
685 if (!ValueOperandSize || !DbgVarSize)
688 bool HasBadSize =
false;
691 if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
692 HasBadSize = ValueOperandSize < *DbgVarSize;
694 HasBadSize = ValueOperandSize != *DbgVarSize;
698 dbg() <<
"ERROR: dbg.value operand has size " << ValueOperandSize
699 <<
", but its variable has size " << *DbgVarSize <<
": ";
706bool checkDebugifyMetadata(
Module &M,
713 dbg() << Banner <<
": Skipping module without debugify metadata\n";
717 auto getDebugifyOperand = [&](
unsigned Idx) ->
unsigned {
722 "llvm.debugify should have exactly 2 operands!");
723 unsigned OriginalNumLines = getDebugifyOperand(0);
724 unsigned OriginalNumVars = getDebugifyOperand(1);
725 bool HasErrors =
false;
729 if (StatsMap && !NameOfWrappedPass.
empty())
730 Stats = &StatsMap->operator[](NameOfWrappedPass);
732 BitVector MissingLines{OriginalNumLines,
true};
733 BitVector MissingVars{OriginalNumVars,
true};
735 if (isFunctionSkipped(
F))
740 if (isa<DbgValueInst>(&
I))
743 auto DL =
I.getDebugLoc();
744 if (
DL &&
DL.getLine() != 0) {
745 MissingLines.reset(
DL.getLine() - 1);
749 if (!isa<PHINode>(&
I) && !
DL) {
750 dbg() <<
"WARNING: Instruction with empty DebugLoc in function ";
751 dbg() <<
F.getName() <<
" --";
759 auto *DVI = dyn_cast<DbgValueInst>(&
I);
765 assert(Var <= OriginalNumVars &&
"Unexpected name for DILocalVariable");
766 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
768 MissingVars.reset(Var - 1);
769 HasErrors |= HasBadSize;
774 for (
unsigned Idx : MissingLines.set_bits())
775 dbg() <<
"WARNING: Missing line " <<
Idx + 1 <<
"\n";
777 for (
unsigned Idx : MissingVars.set_bits())
778 dbg() <<
"WARNING: Missing variable " <<
Idx + 1 <<
"\n";
782 Stats->NumDbgLocsExpected += OriginalNumLines;
783 Stats->NumDbgLocsMissing += MissingLines.count();
784 Stats->NumDbgValuesExpected += OriginalNumVars;
785 Stats->NumDbgValuesMissing += MissingVars.count();
789 if (!NameOfWrappedPass.
empty())
790 dbg() <<
" [" << NameOfWrappedPass <<
"]";
791 dbg() <<
": " << (HasErrors ?
"FAIL" :
"PASS") <<
'\n';
802struct DebugifyModulePass :
public ModulePass {
804 return applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
807 DebugifyModulePass(
enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
811 DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode) {}
829 return applyDebugify(
F, Mode, DebugInfoBeforePass, NameOfWrappedPass);
832 DebugifyFunctionPass(
833 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
837 DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode) {}
853struct CheckDebugifyModulePass :
public ModulePass {
855 if (Mode == DebugifyMode::SyntheticDebugInfo)
856 return checkDebugifyMetadata(M,
M.functions(), NameOfWrappedPass,
857 "CheckModuleDebugify", Strip, StatsMap);
859 M,
M.functions(), *DebugInfoBeforePass,
860 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
861 OrigDIVerifyBugsReportFilePath);
864 CheckDebugifyModulePass(
865 bool Strip =
false,
StringRef NameOfWrappedPass =
"",
867 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
869 StringRef OrigDIVerifyBugsReportFilePath =
"")
871 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
872 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode),
883 StringRef OrigDIVerifyBugsReportFilePath;
895 auto FuncIt =
F.getIterator();
896 if (Mode == DebugifyMode::SyntheticDebugInfo)
897 return checkDebugifyMetadata(M,
make_range(FuncIt, std::next(FuncIt)),
898 NameOfWrappedPass,
"CheckFunctionDebugify",
901 M,
make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
902 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
903 OrigDIVerifyBugsReportFilePath);
906 CheckDebugifyFunctionPass(
907 bool Strip =
false,
StringRef NameOfWrappedPass =
"",
909 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
911 StringRef OrigDIVerifyBugsReportFilePath =
"")
913 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
914 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode),
925 StringRef OrigDIVerifyBugsReportFilePath;
938 errs() <<
"Could not open file: " << EC.message() <<
", " << Path <<
'\n';
942 OS <<
"Pass Name" <<
',' <<
"# of missing debug values" <<
','
943 <<
"# of missing locations" <<
',' <<
"Missing/Expected value ratio" <<
','
944 <<
"Missing/Expected location ratio" <<
'\n';
945 for (
const auto &Entry : Map) {
949 OS <<
Pass <<
',' <<
Stats.NumDbgValuesMissing <<
','
950 <<
Stats.NumDbgLocsMissing <<
',' <<
Stats.getMissingValueRatio() <<
','
951 <<
Stats.getEmptyLocationRatio() <<
'\n';
959 return new DebugifyModulePass();
961 return new DebugifyModulePass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
969 return new DebugifyFunctionPass();
971 return new DebugifyFunctionPass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
975 if (Mode == DebugifyMode::SyntheticDebugInfo)
977 "ModuleDebugify: ",
nullptr);
980 "ModuleDebugify (original debuginfo)",
990 StringRef OrigDIVerifyBugsReportFilePath) {
992 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
994 return new CheckDebugifyModulePass(
false, NameOfWrappedPass,
nullptr, Mode,
996 OrigDIVerifyBugsReportFilePath);
1002 StringRef OrigDIVerifyBugsReportFilePath) {
1004 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
1006 return new CheckDebugifyFunctionPass(
false, NameOfWrappedPass,
nullptr, Mode,
1007 DebugInfoBeforePass,
1008 OrigDIVerifyBugsReportFilePath);
1013 if (Mode == DebugifyMode::SyntheticDebugInfo)
1014 checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
1015 "CheckModuleDebugify", Strip, StatsMap);
1018 M, M.functions(), *DebugInfoBeforePass,
1019 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
1020 OrigDIVerifyBugsReportFilePath);
1026 "AnalysisManagerProxy",
"PrintFunctionPass",
1027 "PrintModulePass",
"BitcodeWriterPass",
1028 "ThinLTOBitcodeWriterPass",
"VerifierPass"});
1038 if (
const auto **CF = any_cast<const Function *>(&
IR)) {
1044 }
else if (
const auto **CM = any_cast<const Module *>(&
IR)) {
1056 if (
const auto **CF = any_cast<const Function *>(&
IR)) {
1059 auto It =
F.getIterator();
1060 if (Mode == DebugifyMode::SyntheticDebugInfo)
1061 checkDebugifyMetadata(M,
make_range(It, std::next(It)),
P,
1062 "CheckFunctionDebugify",
true,
1066 *DebugInfoBeforePass,
1067 "CheckModuleDebugify (original debuginfo)",
1068 P, OrigDIVerifyBugsReportFilePath);
1072 }
else if (
const auto **CM = any_cast<const Module *>(&
IR)) {
1074 if (Mode == DebugifyMode::SyntheticDebugInfo)
1075 checkDebugifyMetadata(M, M.functions(),
P,
"CheckModuleDebugify",
1079 "CheckModuleDebugify (original debuginfo)",
1080 P, OrigDIVerifyBugsReportFilePath);
1086char DebugifyModulePass::ID = 0;
1088 "Attach debug info to everything");
1090char CheckDebugifyModulePass::ID = 0;
1092 CDM(
"check-debugify",
"Check debug info from -debugify");
1094char DebugifyFunctionPass::ID = 0;
1096 "Attach debug info to a function");
1098char CheckDebugifyFunctionPass::ID = 0;
1100 CDF(
"check-debugify-function",
"Check debug info from -debugify-function");
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< CheckDebugifyModulePass > CDM("check-debugify", "Check debug info from -debugify")
ModulePass * createDebugifyModulePass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
FunctionPass * createDebugifyFunctionPass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
static bool isIgnoredPass(StringRef PassID)
static bool applyDebugify(Function &F, enum DebugifyMode Mode=DebugifyMode::SyntheticDebugInfo, DebugInfoPerPass *DebugInfoBeforePass=nullptr, StringRef NameOfWrappedPass="")
ModulePass * createCheckDebugifyModulePass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath, StringRef FileNameFromCU, StringRef NameOfWrappedPass, llvm::json::Array &Bugs)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, const DebugFnMap &DIFunctionsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
static RegisterPass< CheckDebugifyFunctionPass > CDF("check-debugify-function", "Check debug info from -debugify-function")
FunctionPass * createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
static bool checkVars(const DebugVarMap &DIVarsBefore, const DebugVarMap &DIVarsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
static bool checkInstructions(const DebugInstMap &DILocsBefore, const DebugInstMap &DILocsAfter, const WeakInstValueMap &InstToDelete, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
DebugifyMode
Used to check whether we track synthetic or original debug info.
static SmallString< 128 > getFilename(const DISubprogram *SP)
Extract a filename for a DISubprogram.
This file supports working with JSON data.
Legalize the Machine IR a function s Machine IR
block placement Basic Block Placement Stats
Module.h This file contains the declarations for the Module class.
print must be executed print the must be executed context for all instructions
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char PassName[]
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
A container for analyses that lazily runs them and caches their results.
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
const CallInst * getTerminatingDeoptimizeCall() const
Returns the call instruction calling @llvm.experimental.deoptimize prior to the terminating return in...
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
const CallInst * getTerminatingMustTailCall() const
Returns the call instruction marked 'musttail' prior to the terminating return instruction of this ba...
Represents analyses that only rely on functions' control flow.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void finalize()
Construct any deferred debug info descriptors.
DISubroutineType * createSubroutineType(DITypeRefArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
void finalizeSubprogram(DISubprogram *SP)
Finalize a specific subprogram - no new variables may be added to this subprogram afterwards.
DICompileUnit * createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, StringRef SplitName=StringRef(), DICompileUnit::DebugEmissionKind Kind=DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId=0, bool SplitDebugInlining=true, bool DebugInfoForProfiling=false, DICompileUnit::DebugNameTableKind NameTableKind=DICompileUnit::DebugNameTableKind::Default, bool RangesBaseAddress=false, StringRef SysRoot={}, StringRef SDK={})
A CompileUnit provides an anchor for all debugging information generated during this instance of comp...
DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="")
Create a new descriptor for the specified subprogram.
DIExpression * createExpression(ArrayRef< uint64_t > Addr=std::nullopt)
Create a new descriptor for the specified variable which has a complex address expression for its add...
DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero)
Create debugging information entry for a basic type.
DITypeRefArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeRefArray, create one if required.
DILocalVariable * createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve=false, DINode::DIFlags Flags=DINode::FlagZero, uint32_t AlignInBits=0)
Create a new descriptor for an auto variable.
DIFile * createFile(StringRef Filename, StringRef Directory, std::optional< DIFile::ChecksumInfo< StringRef > > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt)
Create a file descriptor to hold debugging information for a file.
unsigned getNumElements() const
Tagged DWARF-like metadata node.
DISPFlags
Debug info subprogram flags.
std::optional< DIBasicType::Signedness > getSignedness() const
Return the signedness of this variable's type, or std::nullopt if this type is neither signed nor uns...
StringRef getName() const
This represents the llvm.dbg.value instruction.
Value * getVariableLocationOp(unsigned OpIdx) const
DILocalVariable * getVariable() const
std::optional< uint64_t > getFragmentSizeInBits() const
Get the size (in bits) of the variable, or fragment of the variable that is described.
DIExpression * getExpression() const
DILocation * get() const
Get the underlying DILocation.
void registerCallbacks(PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM)
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const char * getOpcodeName() const
This is an important class for using LLVM in a threaded context.
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
size_type count(const KeyT &Key) const
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
@ Warning
Emits a warning if two values disagree.
void eraseFromParent()
Drop all references and remove the node from parent module.
MDNode * getOperand(unsigned i) const
unsigned getNumOperands() const
void clearOperands()
Drop all references to this node's operands.
iterator_range< op_iterator > operands()
void addOperand(MDNode *M)
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
void registerBeforeNonSkippedPassCallback(CallableT C)
void registerAfterPassCallback(CallableT C, bool ToFront=false)
Pass interface - Implemented by all 'passes'.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
A range adaptor for a pair of iterators.
An Array is a JSON array, which contains heterogeneous JSON values.
void push_back(const Value &E)
An Object is a JSON object, which maps strings to heterogenous JSON values.
A Value is an JSON value of unknown type.
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
@ OF_Append
The file should be opened in append mode.
This is an optimization pass for GlobalISel generic memory operations.
bool applyDebugifyMetadata(Module &M, iterator_range< Module::iterator > Functions, StringRef Banner, std::function< bool(DIBuilder &, Function &)> ApplyToMF)
Add synthesized debug information to a module.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool stripDebugifyMetadata(Module &M)
Strip out all of the metadata and debug info inserted by debugify.
void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map)
bool collectDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass)
Collect original debug information before a pass.
bool checkDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass, StringRef OrigDIVerifyBugsReportFilePath)
Check original debug information after a pass.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Used to track the Debug Info Metadata information.
WeakInstValueMap InstToDelete
Track how much debugify information (in the synthetic mode only) has been lost.
RegisterPass<t> template - This template class is used to notify the system that a Pass is available ...