Go to the documentation of this file.
31 #define DEBUG_TYPE "debugify"
38 cl::desc(
"Suppress verbose debugify output"));
41 "debugify-func-limit",
42 cl::desc(
"Set max number of processed functions per pass."),
51 "debugify-level",
cl::desc(
"Kind of debug info to add"),
53 clEnumValN(Level::LocationsAndVariables,
"location+variables",
54 "Locations and Variables")),
55 cl::init(Level::LocationsAndVariables));
60 return Ty->
isSized() ?
M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
64 return F.isDeclaration() || !
F.hasExactDefinition();
72 if (
auto *
I =
BB.getTerminatingMustTailCall())
74 if (
auto *
I =
BB.getTerminatingDeoptimizeCall())
76 return BB.getTerminator();
84 if (
M.getNamedMetadata(
"llvm.dbg.cu")) {
85 dbg() << Banner <<
"Skipping module with debug info\n";
95 auto getCachedDIType = [&](
Type *Ty) ->
DIType * {
99 std::string
Name =
"ty" + utostr(Size);
105 unsigned NextLine = 1;
106 unsigned NextVar = 1;
113 if (isFunctionSkipped(
F))
116 bool InsertedDbgVal =
false;
119 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
120 if (
F.hasPrivateLinkage() ||
F.hasInternalLinkage())
121 SPFlags |= DISubprogram::SPFlagLocalToUnit;
123 SPType, NextLine, DINode::FlagZero, SPFlags);
130 std::string
Name = utostr(NextVar++);
131 Value *V = &TemplateInst;
147 if (DebugifyLevel < Level::LocationsAndVariables)
157 assert(LastInst &&
"Expected basic block with a terminator");
162 assert(InsertPt !=
BB.end() &&
"Expected to find an insertion point");
168 if (
I->getType()->isVoidTy())
173 if (!isa<PHINode>(
I) && !
I->isEHPad())
174 InsertBefore =
I->getNextNode();
176 insertDbgVal(*
I, InsertBefore);
177 InsertedDbgVal =
true;
185 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
186 auto *
Term = findTerminatingInstruction(
F.getEntryBlock());
196 NamedMDNode *NMD =
M.getOrInsertNamedMetadata(
"llvm.debugify");
197 auto addDebugifyOperand = [&](
unsigned N) {
201 addDebugifyOperand(NextLine - 1);
202 addDebugifyOperand(NextVar - 1);
204 "llvm.debugify should have exactly 2 operands!");
207 StringRef DIVersionKey =
"Debug Info Version";
208 if (!
M.getModuleFlag(DIVersionKey))
220 auto FuncIt =
F.getIterator();
223 "FunctionDebugify: ",
nullptr);
224 assert(DebugInfoBeforePass);
226 "FunctionDebugify (original debuginfo)",
237 "ModuleDebugify: ",
nullptr);
239 "ModuleDebugify (original debuginfo)",
244 bool Changed =
false;
247 NamedMDNode *DebugifyMD =
M.getNamedMetadata(
"llvm.debugify");
249 M.eraseNamedMetadata(DebugifyMD);
258 Function *DbgValF =
M.getFunction(
"llvm.dbg.value");
261 "Not all debug info stripped?");
274 auto *
Key = cast<MDString>(
Flag->getOperand(1));
275 if (
Key->getString() ==
"Debug Info Version") {
293 LLVM_DEBUG(
dbgs() << Banner <<
": (before) " << NameOfWrappedPass <<
'\n');
295 if (!
M.getNamedMetadata(
"llvm.dbg.cu")) {
296 dbg() << Banner <<
": Skipping module without debug info\n";
307 if (isFunctionSkipped(
F))
311 if (++FunctionsCnt >= DebugifyFunctionsLimit)
314 auto *SP =
F.getSubprogram();
318 for (
const DINode *DN : SP->getRetainedNodes()) {
319 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
333 if (DebugifyLevel > Level::Locations) {
334 if (
auto *DVI = dyn_cast<DbgVariableIntrinsic>(&
I)) {
338 if (
I.getDebugLoc().getInlinedAt())
344 auto *Var = DVI->getVariable();
351 if (isa<DbgInfoIntrinsic>(&
I))
358 bool HasLoc = Loc !=
nullptr;
371 StringRef FileNameFromCU,
bool ShouldWriteIntoJSON,
373 bool Preserved =
true;
374 for (
const auto &
F : DIFunctionsAfter) {
377 auto SPIt = DIFunctionsBefore.
find(
F.first);
378 if (SPIt == DIFunctionsBefore.
end()) {
379 if (ShouldWriteIntoJSON)
381 {
"name",
F.first->getName()},
382 {
"action",
"not-generate"}}));
384 dbg() <<
"ERROR: " << NameOfWrappedPass
385 <<
" did not generate DISubprogram for " <<
F.first->getName()
386 <<
" from " << FileNameFromCU <<
'\n';
389 auto SP = SPIt->second;
394 if (ShouldWriteIntoJSON)
396 {
"name",
F.first->getName()},
397 {
"action",
"drop"}}));
399 dbg() <<
"ERROR: " << NameOfWrappedPass <<
" dropped DISubprogram of "
400 <<
F.first->getName() <<
" from " << FileNameFromCU <<
'\n';
415 bool ShouldWriteIntoJSON,
417 bool Preserved =
true;
418 for (
const auto &L : DILocsAfter) {
421 auto Instr = L.first;
425 auto WeakInstrPtr = InstToDelete.
find(Instr);
426 if (WeakInstrPtr != InstToDelete.
end() && !WeakInstrPtr->second)
429 auto FnName = Instr->getFunction()->getName();
430 auto BB = Instr->getParent();
431 auto BBName =
BB->hasName() ?
BB->getName() :
"no-name";
434 auto InstrIt = DILocsBefore.
find(Instr);
435 if (InstrIt == DILocsBefore.
end()) {
436 if (ShouldWriteIntoJSON)
438 {
"fn-name", FnName.str()},
439 {
"bb-name", BBName.str()},
441 {
"action",
"not-generate"}}));
443 dbg() <<
"WARNING: " << NameOfWrappedPass
444 <<
" did not generate DILocation for " << *Instr
445 <<
" (BB: " << BBName <<
", Fn: " << FnName
446 <<
", File: " << FileNameFromCU <<
")\n";
449 if (!InstrIt->second)
453 if (ShouldWriteIntoJSON)
455 {
"fn-name", FnName.str()},
456 {
"bb-name", BBName.str()},
458 {
"action",
"drop"}}));
460 dbg() <<
"WARNING: " << NameOfWrappedPass <<
" dropped DILocation of "
461 << *Instr <<
" (BB: " << BBName <<
", Fn: " << FnName
462 <<
", File: " << FileNameFromCU <<
")\n";
475 bool Preserved =
true;
476 for (
const auto &V : DIVarsBefore) {
477 auto VarIt = DIVarsAfter.
find(V.first);
478 if (VarIt == DIVarsAfter.
end())
481 unsigned NumOfDbgValsAfter = VarIt->second;
483 if (V.second > NumOfDbgValsAfter) {
484 if (ShouldWriteIntoJSON)
486 {{
"metadata",
"dbg-var-intrinsic"},
489 {
"action",
"drop"}}));
491 dbg() <<
"WARNING: " << NameOfWrappedPass
492 <<
" drops dbg.value()/dbg.declare() for " << V.first->
getName()
494 <<
"function " << V.first->getScope()->getSubprogram()->
getName()
495 <<
" (file " << FileNameFromCU <<
")\n";
511 errs() <<
"Could not open file: " << EC.message() <<
", "
512 << OrigDIVerifyBugsReportFilePath <<
'\n';
516 OS_FILE <<
"{\"file\":\"" << FileNameFromCU <<
"\", ";
519 OS_FILE <<
"\"pass\":\"" <<
PassName <<
"\", ";
522 OS_FILE <<
"\"bugs\": " << BugsToPrint;
531 StringRef OrigDIVerifyBugsReportFilePath) {
532 LLVM_DEBUG(
dbgs() << Banner <<
": (after) " << NameOfWrappedPass <<
'\n');
534 if (!
M.getNamedMetadata(
"llvm.dbg.cu")) {
535 dbg() << Banner <<
": Skipping module without debug info\n";
544 if (isFunctionSkipped(
F))
552 auto *SP =
F.getSubprogram();
557 for (
const DINode *DN : SP->getRetainedNodes()) {
558 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
572 if (DebugifyLevel > Level::Locations) {
573 if (
auto *DVI = dyn_cast<DbgVariableIntrinsic>(&
I)) {
577 if (
I.getDebugLoc().getInlinedAt())
583 auto *Var = DVI->getVariable();
590 if (isa<DbgInfoIntrinsic>(&
I))
596 bool HasLoc = Loc !=
nullptr;
605 (cast<DICompileUnit>(
M.getNamedMetadata(
"llvm.dbg.cu")->getOperand(0)))
608 auto DIFunctionsBefore = DebugInfoBeforePass.
DIFunctions;
609 auto DIFunctionsAfter = DebugInfoAfterPass.
DIFunctions;
611 auto DILocsBefore = DebugInfoBeforePass.
DILocations;
616 auto DIVarsBefore = DebugInfoBeforePass.
DIVariables;
619 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.
empty();
623 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
624 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
626 DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
627 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
629 bool ResultForVars =
checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
630 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
632 bool Result = ResultForFunc && ResultForInsts && ResultForVars;
634 StringRef ResultBanner = NameOfWrappedPass !=
"" ? NameOfWrappedPass : Banner;
635 if (ShouldWriteIntoJSON && !Bugs.
empty())
636 writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
640 dbg() << ResultBanner <<
": PASS\n";
642 dbg() << ResultBanner <<
": FAIL\n";
647 DebugInfoBeforePass = DebugInfoAfterPass;
672 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
674 if (!ValueOperandSize || !DbgVarSize)
677 bool HasBadSize =
false;
681 HasBadSize = ValueOperandSize < *DbgVarSize;
683 HasBadSize = ValueOperandSize != *DbgVarSize;
687 dbg() <<
"ERROR: dbg.value operand has size " << ValueOperandSize
688 <<
", but its variable has size " << *DbgVarSize <<
": ";
695 bool checkDebugifyMetadata(
Module &M,
702 dbg() << Banner <<
": Skipping module without debugify metadata\n";
706 auto getDebugifyOperand = [&](
unsigned Idx) ->
unsigned {
711 "llvm.debugify should have exactly 2 operands!");
712 unsigned OriginalNumLines = getDebugifyOperand(0);
713 unsigned OriginalNumVars = getDebugifyOperand(1);
714 bool HasErrors =
false;
718 if (StatsMap && !NameOfWrappedPass.
empty())
719 Stats = &StatsMap->operator[](NameOfWrappedPass);
721 BitVector MissingLines{OriginalNumLines,
true};
722 BitVector MissingVars{OriginalNumVars,
true};
724 if (isFunctionSkipped(
F))
729 if (isa<DbgValueInst>(&
I))
732 auto DL =
I.getDebugLoc();
733 if (
DL &&
DL.getLine() != 0) {
734 MissingLines.reset(
DL.getLine() - 1);
738 if (!isa<PHINode>(&
I) && !
DL) {
739 dbg() <<
"WARNING: Instruction with empty DebugLoc in function ";
740 dbg() <<
F.getName() <<
" --";
748 auto *DVI = dyn_cast<DbgValueInst>(&
I);
754 assert(Var <= OriginalNumVars &&
"Unexpected name for DILocalVariable");
755 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
757 MissingVars.reset(Var - 1);
758 HasErrors |= HasBadSize;
763 for (
unsigned Idx : MissingLines.set_bits())
764 dbg() <<
"WARNING: Missing line " << Idx + 1 <<
"\n";
766 for (
unsigned Idx : MissingVars.set_bits())
767 dbg() <<
"WARNING: Missing variable " << Idx + 1 <<
"\n";
771 Stats->NumDbgLocsExpected += OriginalNumLines;
772 Stats->NumDbgLocsMissing += MissingLines.count();
773 Stats->NumDbgValuesExpected += OriginalNumVars;
774 Stats->NumDbgValuesMissing += MissingVars.count();
778 if (!NameOfWrappedPass.
empty())
779 dbg() <<
" [" << NameOfWrappedPass <<
"]";
780 dbg() <<
": " << (HasErrors ?
"FAIL" :
"PASS") <<
'\n';
791 struct DebugifyModulePass :
public ModulePass {
792 bool runOnModule(
Module &M)
override {
800 DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode) {}
821 DebugifyFunctionPass(
826 DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode) {}
842 struct CheckDebugifyModulePass :
public ModulePass {
843 bool runOnModule(
Module &M)
override {
845 return checkDebugifyMetadata(M,
M.functions(), NameOfWrappedPass,
846 "CheckModuleDebugify", Strip, StatsMap);
848 M,
M.functions(), *DebugInfoBeforePass,
849 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
850 OrigDIVerifyBugsReportFilePath);
853 CheckDebugifyModulePass(
854 bool Strip =
false,
StringRef NameOfWrappedPass =
"",
858 StringRef OrigDIVerifyBugsReportFilePath =
"")
860 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
861 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode),
872 StringRef OrigDIVerifyBugsReportFilePath;
881 struct CheckDebugifyFunctionPass :
public FunctionPass {
884 auto FuncIt =
F.getIterator();
886 return checkDebugifyMetadata(M,
make_range(FuncIt, std::next(FuncIt)),
887 NameOfWrappedPass,
"CheckFunctionDebugify",
890 M,
make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
891 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
892 OrigDIVerifyBugsReportFilePath);
895 CheckDebugifyFunctionPass(
896 bool Strip =
false,
StringRef NameOfWrappedPass =
"",
900 StringRef OrigDIVerifyBugsReportFilePath =
"")
902 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
903 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass),
Mode(
Mode),
914 StringRef OrigDIVerifyBugsReportFilePath;
927 errs() <<
"Could not open file: " << EC.message() <<
", " << Path <<
'\n';
931 OS <<
"Pass Name" <<
',' <<
"# of missing debug values" <<
','
932 <<
"# of missing locations" <<
',' <<
"Missing/Expected value ratio" <<
','
933 <<
"Missing/Expected location ratio" <<
'\n';
934 for (
const auto &Entry : Map) {
938 OS <<
Pass <<
',' <<
Stats.NumDbgValuesMissing <<
','
939 <<
Stats.NumDbgLocsMissing <<
',' <<
Stats.getMissingValueRatio() <<
','
940 <<
Stats.getEmptyLocationRatio() <<
'\n';
948 return new DebugifyModulePass();
950 return new DebugifyModulePass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
958 return new DebugifyFunctionPass();
960 return new DebugifyFunctionPass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
965 "ModuleDebugify: ",
nullptr);
972 StringRef OrigDIVerifyBugsReportFilePath) {
974 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
976 return new CheckDebugifyModulePass(
false, NameOfWrappedPass,
nullptr,
Mode,
978 OrigDIVerifyBugsReportFilePath);
984 StringRef OrigDIVerifyBugsReportFilePath) {
986 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
988 return new CheckDebugifyFunctionPass(
false, NameOfWrappedPass,
nullptr,
Mode,
990 OrigDIVerifyBugsReportFilePath);
995 checkDebugifyMetadata(
M,
M.functions(),
"",
"CheckModuleDebugify",
false,
1002 "AnalysisManagerProxy",
"PrintFunctionPass",
1003 "PrintModulePass",
"BitcodeWriterPass",
1004 "ThinLTOBitcodeWriterPass",
"VerifierPass"});
1012 if (any_isa<const Function *>(
IR))
1014 else if (any_isa<const Module *>(
IR))
1021 if (any_isa<const Function *>(
IR)) {
1022 auto &
F = *
const_cast<Function *
>(any_cast<const Function *>(
IR));
1024 auto It =
F.getIterator();
1025 checkDebugifyMetadata(
M,
make_range(It, std::next(It)),
P,
1026 "CheckFunctionDebugify",
true, &
StatsMap);
1027 }
else if (any_isa<const Module *>(
IR)) {
1028 auto &
M = *
const_cast<Module *
>(any_cast<const Module *>(
IR));
1029 checkDebugifyMetadata(
M,
M.functions(),
P,
"CheckModuleDebugify",
1037 "Attach debug info to everything");
1041 CDM(
"check-debugify",
"Check debug info from -debugify");
1045 "Attach debug info to a function");
1049 CDF(
"check-debugify-function",
"Check debug info from -debugify-function");
RegisterPass<t> template - This template class is used to notify the system that a Pass is available ...
A set of analyses that are preserved following a run of a transformation pass.
DIExpression * getExpression() const
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static RegisterPass< CheckDebugifyFunctionPass > CDF("check-debugify-function", "Check debug info from -debugify-function")
static StringRef getName(Value *V)
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
A Value is an JSON value of unknown type.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
DITypeRefArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeRefArray, create one if required.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void finalize()
Construct any deferred debug info descriptors.
DebugifyMode
Used to check whether we track synthetic or original debug info.
unsigned getNumOperands() const
InstListType::iterator iterator
Instruction iterators...
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
void finalizeSubprogram(DISubprogram *SP)
Finalize a specific subprogram - no new variables may be added to this subprogram afterwards.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, const DebugFnMap &DIFunctionsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
void registerBeforeNonSkippedPassCallback(CallableT C)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
FunctionPass * createDebugifyFunctionPass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
The instances of the Type class are immutable: once they are created, they are never changed.
ModulePass * createDebugifyModulePass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
PassInstrumentationCallbacks PIC
DILocalVariable * getVariable() const
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool applyDebugifyMetadata(Module &M, iterator_range< Module::iterator > Functions, StringRef Banner, std::function< bool(DIBuilder &, Function &)> ApplyToMF)
Add synthesized debug information to a module.
DISubroutineType * createSubroutineType(DITypeRefArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
static bool checkInstructions(const DebugInstMap &DILocsBefore, const DebugInstMap &DILocsAfter, const WeakInstValueMap &InstToDelete, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
void push_back(const Value &E)
static IntegerType * getInt32Ty(LLVMContext &C)
Value * getVariableLocationOp(unsigned OpIdx) const
DIFile * createFile(StringRef Filename, StringRef Directory, Optional< DIFile::ChecksumInfo< StringRef >> Checksum=None, Optional< StringRef > Source=None)
Create a file descriptor to hold debugging information for a file.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVM Basic Block Representation.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void addOperand(MDNode *M)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static bool applyDebugify(Function &F, enum DebugifyMode Mode=DebugifyMode::SyntheticDebugInfo, DebugInfoPerPass *DebugInfoBeforePass=nullptr, StringRef NameOfWrappedPass="")
static bool isIgnoredPass(StringRef PassID)
This represents the llvm.dbg.value instruction.
bool collectDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass)
Collect original debug information before a pass.
Represent the analysis usage information of a pass.
DISPFlags
Debug info subprogram flags.
bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
const char * getOpcodeName() const
Flag
These should be considered private to the implementation of the MCInstrDesc class.
void eraseFromParent()
Drop all references and remove the node from parent module.
An Array is a JSON array, which contains heterogeneous JSON values.
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
Statically lint checks LLVM IR
void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map)
WeakInstValueMap InstToDelete
bool stripDebugifyMetadata(Module &M)
Strip out all of the metadata and debug info inserted by debugify.
static SmallString< 128 > getFilename(const DISubprogram *SP)
Extract a filename for a DISubprogram.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const MDOperand & getOperand(unsigned I) const
FunctionPass * createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
inst_range instructions(Function *F)
Used to track the Debug Info Metadata information.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
iterator find(const KeyT &Key)
DebugifyStatsMap StatsMap
DIExpression * createExpression(ArrayRef< uint64_t > Addr=None)
Create a new descriptor for the specified variable which has a complex address expression for its add...
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
This is an important class for using LLVM in a threaded context.
DILocation * get() const
Get the underlying DILocation.
initializer< Ty > init(const Ty &Val)
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
bool checkDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass, StringRef OrigDIVerifyBugsReportFilePath)
Check original debug information after a pass.
MDNode * getOperand(unsigned i) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Track how much debugify information (in the synthetic mode only) has been lost.
print Print MemDeps of function
bool isVoidTy() const
Return true if this is 'void'.
A Module instance is used to store all the information related to an LLVM module.
StringRef getName() const
Optional< DIBasicType::Signedness > getSignedness() const
Return the signedness of this variable's type, or None if this type is neither signed nor unsigned.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
@ Warning
Emits a warning if two values disagree.
StringRef - Represent a constant reference to a string, i.e.
Tagged DWARF-like metadata node.
Type * getType() const
All values are typed, get the type of this value.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Optional< uint64_t > getFragmentSizeInBits() const
Get the size (in bits) of the variable, or fragment of the variable that is described.
StringRef getName() const
Return a constant reference to the value's name.
A raw_ostream that writes to a file descriptor.
iterator_range< op_iterator > operands()
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...
static bool runOnFunction(Function &F, bool PostInlining)
size_type count(const KeyT &Key) const
block placement Basic Block Placement Stats
void setPreservesAll()
Set by analyses that do not transform their input at all.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
static RegisterPass< CheckDebugifyModulePass > CDM("check-debugify", "Check debug info from -debugify")
static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath, StringRef FileNameFromCU, StringRef NameOfWrappedPass, llvm::json::Array &Bugs)
void registerAfterPassCallback(CallableT C)
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.
Pass interface - Implemented by all 'passes'.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
ModulePass * createCheckDebugifyModulePass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
@ OF_Append
The file should be opened in append mode.
A range adaptor for a pair of iterators.
unsigned getNumElements() const
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero)
Create debugging information entry for a basic type.
void registerCallbacks(PassInstrumentationCallbacks &PIC)
An Object is a JSON object, which maps strings to heterogenous JSON values.
void clearOperands()
Drop all references to this node's operands.
LLVM Value Representation.
static const char PassName[]
static bool checkVars(const DebugVarMap &DIVarsBefore, const DebugVarMap &DIVarsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)