Skip to content

Commit 10a9e74

Browse files
committed
[DebugInfo][RemoveDIs] Add conversion utilities for new-debug-info format
This patch plumbs the command line --experimental-debuginfo-iterators flag in to the pass managers, so that modules can be converted to the new format, passes run, then converted back to the old format. That allows developers to test-out the new debuginfo representation across some part of LLVM with no further work, and from the command line. It also installs flag-catchers at the various points that bitcode and textual IR can egress from a process, and temporarily convert the module to dbg.value format when doing so. No tests alas as it's designed to be transparent. Differential Revision: https://reviews.llvm.org/D154372
1 parent 1d1fede commit 10a9e74

File tree

8 files changed

+244
-1
lines changed

8 files changed

+244
-1
lines changed

llvm/include/llvm/IR/PassManager.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/IR/Module.h"
4747
#include "llvm/IR/PassInstrumentation.h"
4848
#include "llvm/IR/PassManagerInternal.h"
49+
#include "llvm/Support/CommandLine.h"
4950
#include "llvm/Support/TimeProfiler.h"
5051
#include "llvm/Support/TypeName.h"
5152
#include <cassert>
@@ -58,8 +59,27 @@
5859
#include <utility>
5960
#include <vector>
6061

62+
extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
63+
6164
namespace llvm {
6265

66+
// RemoveDIs: Provide facilities for converting debug-info from one form to
67+
// another, which are no-ops for everything but modules.
68+
template <class IRUnitT> inline bool shouldConvertDbgInfo(IRUnitT &IR) {
69+
return false;
70+
}
71+
template <> inline bool shouldConvertDbgInfo(Module &IR) {
72+
return !IR.IsNewDbgInfoFormat && UseNewDbgInfoFormat;
73+
}
74+
template <class IRUnitT> inline void doConvertDbgInfoToNew(IRUnitT &IR) {}
75+
template <> inline void doConvertDbgInfoToNew(Module &IR) {
76+
IR.convertToNewDbgValues();
77+
}
78+
template <class IRUnitT> inline void doConvertDebugInfoToOld(IRUnitT &IR) {}
79+
template <> inline void doConvertDebugInfoToOld(Module &IR) {
80+
IR.convertFromNewDbgValues();
81+
}
82+
6383
/// A special type used by analysis passes to provide an address that
6484
/// identifies that particular analysis pass type.
6585
///
@@ -507,6 +527,12 @@ class PassManager : public PassInfoMixin<
507527
detail::getAnalysisResult<PassInstrumentationAnalysis>(
508528
AM, IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
509529

530+
// RemoveDIs: if requested, convert debug-info to DPValue representation
531+
// for duration of these passes.
532+
bool ShouldConvertDbgInfo = shouldConvertDbgInfo(IR);
533+
if (ShouldConvertDbgInfo)
534+
doConvertDbgInfoToNew(IR);
535+
510536
for (auto &Pass : Passes) {
511537
// Check the PassInstrumentation's BeforePass callbacks before running the
512538
// pass, skip its execution completely if asked to (callback returns
@@ -529,6 +555,9 @@ class PassManager : public PassInfoMixin<
529555
PA.intersect(std::move(PassPA));
530556
}
531557

558+
if (ShouldConvertDbgInfo)
559+
doConvertDebugInfoToOld(IR);
560+
532561
// Invalidation was handled after each pass in the above loop for the
533562
// current unit of IR. Therefore, the remaining analysis results in the
534563
// AnalysisManager are preserved. We mark this with a set so that we don't

llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,20 @@
1919
using namespace llvm;
2020

2121
PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
22+
// RemoveDIs: there's no bitcode representation of the DPValue debug-info,
23+
// convert to dbg.values before writing out.
24+
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
25+
if (IsNewDbgInfoFormat)
26+
M.convertFromNewDbgValues();
27+
2228
const ModuleSummaryIndex *Index =
2329
EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
2430
: nullptr;
2531
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
32+
33+
if (IsNewDbgInfoFormat)
34+
M.convertToNewDbgValues();
35+
2636
return PreservedAnalyses::all();
2737
}
2838

@@ -54,8 +64,17 @@ namespace {
5464
EmitSummaryIndex
5565
? &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex())
5666
: nullptr;
67+
// RemoveDIs: there's no bitcode representation of the DPValue debug-info,
68+
// convert to dbg.values before writing out.
69+
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
70+
if (IsNewDbgInfoFormat)
71+
M.convertFromNewDbgValues();
72+
5773
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index,
5874
EmitModuleHash);
75+
76+
if (IsNewDbgInfoFormat)
77+
M.convertToNewDbgValues();
5978
return false;
6079
}
6180
void getAnalysisUsage(AnalysisUsage &AU) const override {

llvm/lib/CodeGen/MIRPrinter.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,11 +981,29 @@ void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V,
981981
}
982982

983983
void llvm::printMIR(raw_ostream &OS, const Module &M) {
984+
// RemoveDIs: as there's no textual form for DPValues yet, print debug-info
985+
// in dbg.value format.
986+
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
987+
if (IsNewDbgInfoFormat)
988+
const_cast<Module &>(M).convertFromNewDbgValues();
989+
984990
yaml::Output Out(OS);
985991
Out << const_cast<Module &>(M);
992+
993+
if (IsNewDbgInfoFormat)
994+
const_cast<Module &>(M).convertToNewDbgValues();
986995
}
987996

988997
void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
998+
// RemoveDIs: as there's no textual form for DPValues yet, print debug-info
999+
// in dbg.value format.
1000+
bool IsNewDbgInfoFormat = MF.getFunction().IsNewDbgInfoFormat;
1001+
if (IsNewDbgInfoFormat)
1002+
const_cast<Function &>(MF.getFunction()).convertFromNewDbgValues();
1003+
9891004
MIRPrinter Printer(OS);
9901005
Printer.print(MF);
1006+
1007+
if (IsNewDbgInfoFormat)
1008+
const_cast<Function &>(MF.getFunction()).convertToNewDbgValues();
9911009
}

llvm/lib/IR/AsmWriter.cpp

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "llvm/IR/Constant.h"
4040
#include "llvm/IR/Constants.h"
4141
#include "llvm/IR/DebugInfoMetadata.h"
42+
#include "llvm/IR/DebugProgramInstruction.h"
4243
#include "llvm/IR/DerivedTypes.h"
4344
#include "llvm/IR/Function.h"
4445
#include "llvm/IR/GlobalAlias.h"
@@ -285,6 +286,16 @@ static const Module *getModuleFromVal(const Value *V) {
285286
return nullptr;
286287
}
287288

289+
static const Module *getModuleFromDPI(const DPMarker *Marker) {
290+
const Function *M =
291+
Marker->getParent() ? Marker->getParent()->getParent() : nullptr;
292+
return M ? M->getParent() : nullptr;
293+
}
294+
295+
static const Module *getModuleFromDPI(const DPValue *DPV) {
296+
return getModuleFromDPI(DPV->getMarker());
297+
}
298+
288299
static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
289300
switch (cc) {
290301
default: Out << "cc" << cc; break;
@@ -2612,6 +2623,8 @@ class AssemblyWriter {
26122623
void printBasicBlock(const BasicBlock *BB);
26132624
void printInstructionLine(const Instruction &I);
26142625
void printInstruction(const Instruction &I);
2626+
void printDPMarker(const DPMarker &DPI);
2627+
void printDPValue(const DPValue &DPI);
26152628

26162629
void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
26172630
void printUseLists(const Function *F);
@@ -3771,6 +3784,9 @@ void AssemblyWriter::printTypeIdentities() {
37713784

37723785
/// printFunction - Print all aspects of a function.
37733786
void AssemblyWriter::printFunction(const Function *F) {
3787+
bool ConvertBack = F->IsNewDbgInfoFormat;
3788+
if (ConvertBack)
3789+
const_cast<Function *>(F)->convertFromNewDbgValues();
37743790
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
37753791

37763792
if (F->isMaterializable())
@@ -3913,6 +3929,8 @@ void AssemblyWriter::printFunction(const Function *F) {
39133929
Out << "}\n";
39143930
}
39153931

3932+
if (ConvertBack)
3933+
const_cast<Function *>(F)->convertToNewDbgValues();
39163934
Machine.purgeFunction();
39173935
}
39183936

@@ -4007,8 +4025,15 @@ void AssemblyWriter::printInfoComment(const Value &V) {
40074025
if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
40084026
printGCRelocateComment(*Relocate);
40094027

4010-
if (AnnotationWriter)
4028+
if (AnnotationWriter) {
40114029
AnnotationWriter->printInfoComment(V, Out);
4030+
} else if (const Instruction *I = dyn_cast<Instruction>(&V)) {
4031+
if (I->DbgMarker) {
4032+
// In the new, experimental DPValue representation of debug-info, print
4033+
// out which instructions have DPMarkers and where they are.
4034+
Out << "; dbgmarker @ " << I->DbgMarker;
4035+
}
4036+
}
40124037
}
40134038

40144039
static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,
@@ -4468,6 +4493,36 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
44684493
printInfoComment(I);
44694494
}
44704495

4496+
void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
4497+
// There's no formal representation of a DPMarker -- print purely as a
4498+
// debugging aid.
4499+
for (const DPValue &DPI2 : Marker.StoredDPValues) {
4500+
printDPValue(DPI2);
4501+
Out << "\n";
4502+
}
4503+
4504+
Out << " DPMarker -> { ";
4505+
printInstruction(*Marker.MarkedInstr);
4506+
Out << " }";
4507+
return;
4508+
}
4509+
4510+
void AssemblyWriter::printDPValue(const DPValue &Value) {
4511+
// There's no formal representation of a DPValue -- print purely as a
4512+
// debugging aid.
4513+
Out << " DPValue { ";
4514+
auto WriterCtx = getContext();
4515+
WriteAsOperandInternal(Out, Value.getRawLocation(), WriterCtx, true);
4516+
Out << ", ";
4517+
WriteAsOperandInternal(Out, Value.getVariable(), WriterCtx, true);
4518+
Out << ", ";
4519+
WriteAsOperandInternal(Out, Value.getExpression(), WriterCtx, true);
4520+
Out << ", ";
4521+
WriteAsOperandInternal(Out, Value.getDebugLoc().get(), WriterCtx, true);
4522+
Out << " marker @" << Value.getMarker();
4523+
Out << " }";
4524+
}
4525+
44714526
void AssemblyWriter::printMetadataAttachments(
44724527
const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
44734528
StringRef Separator) {
@@ -4613,11 +4668,19 @@ void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
46134668

46144669
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
46154670
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
4671+
// RemoveDIs: always print with debug-info in intrinsic format.
4672+
bool ConvertAfter = IsNewDbgInfoFormat;
4673+
if (IsNewDbgInfoFormat)
4674+
const_cast<Module *>(this)->convertFromNewDbgValues();
4675+
46164676
SlotTracker SlotTable(this);
46174677
formatted_raw_ostream OS(ROS);
46184678
AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
46194679
ShouldPreserveUseListOrder);
46204680
W.printModule(this);
4681+
4682+
if (ConvertAfter)
4683+
const_cast<Module *>(this)->convertToNewDbgValues();
46214684
}
46224685

46234686
void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
@@ -4694,6 +4757,53 @@ static bool isReferencingMDNode(const Instruction &I) {
46944757
return false;
46954758
}
46964759

4760+
void DPMarker::print(raw_ostream &ROS, bool IsForDebug) const {
4761+
4762+
ModuleSlotTracker MST(getModuleFromDPI(this), true);
4763+
print(ROS, MST, IsForDebug);
4764+
}
4765+
4766+
void DPValue::print(raw_ostream &ROS, bool IsForDebug) const {
4767+
4768+
ModuleSlotTracker MST(getModuleFromDPI(this), true);
4769+
print(ROS, MST, IsForDebug);
4770+
}
4771+
4772+
void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4773+
bool IsForDebug) const {
4774+
// There's no formal representation of a DPMarker -- print purely as a
4775+
// debugging aid.
4776+
formatted_raw_ostream OS(ROS);
4777+
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
4778+
SlotTracker &SlotTable =
4779+
MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
4780+
auto incorporateFunction = [&](const Function *F) {
4781+
if (F)
4782+
MST.incorporateFunction(*F);
4783+
};
4784+
incorporateFunction(getParent() ? getParent()->getParent() : nullptr);
4785+
AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug);
4786+
W.printDPMarker(*this);
4787+
}
4788+
4789+
void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
4790+
bool IsForDebug) const {
4791+
// There's no formal representation of a DPValue -- print purely as a
4792+
// debugging aid.
4793+
formatted_raw_ostream OS(ROS);
4794+
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
4795+
SlotTracker &SlotTable =
4796+
MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
4797+
auto incorporateFunction = [&](const Function *F) {
4798+
if (F)
4799+
MST.incorporateFunction(*F);
4800+
};
4801+
incorporateFunction(Marker->getParent() ? Marker->getParent()->getParent()
4802+
: nullptr);
4803+
AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug);
4804+
W.printDPValue(*this);
4805+
}
4806+
46974807
void Value::print(raw_ostream &ROS, bool IsForDebug) const {
46984808
bool ShouldInitializeAllMetadata = false;
46994809
if (auto *I = dyn_cast<Instruction>(this))
@@ -4939,6 +5049,14 @@ void ModuleSlotTracker::collectMDNodes(MachineMDNodeListType &L, unsigned LB,
49395049
LLVM_DUMP_METHOD
49405050
void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
49415051

5052+
// Value::dump - allow easy printing of Values from the debugger.
5053+
LLVM_DUMP_METHOD
5054+
void DPMarker::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5055+
5056+
// Value::dump - allow easy printing of Values from the debugger.
5057+
LLVM_DUMP_METHOD
5058+
void DPValue::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
5059+
49425060
// Type::dump - allow easy printing of Types from the debugger.
49435061
LLVM_DUMP_METHOD
49445062
void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }

llvm/lib/IR/BasicBlock.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,18 @@ bool BasicBlock::validateDbgValues(bool Assert, bool Msg, raw_ostream *OS) {
179179
return RetVal;
180180
}
181181

182+
#ifndef NDEBUG
183+
void BasicBlock::dumpDbgValues() const {
184+
for (auto &Inst : *this) {
185+
if (!Inst.DbgMarker)
186+
continue;
187+
188+
dbgs() << "@ " << Inst.DbgMarker << " ";
189+
Inst.DbgMarker->dump();
190+
};
191+
}
192+
#endif
193+
182194
void BasicBlock::setIsNewDbgInfoFormat(bool NewFlag) {
183195
if (NewFlag && !IsNewDbgInfoFormat)
184196
convertToNewDbgValues();

llvm/lib/IR/IRPrintingPasses.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ class PrintModulePassWrapper : public ModulePass {
3939
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
4040

4141
bool runOnModule(Module &M) override {
42+
// RemoveDIs: there's no textual representation of the DPValue debug-info,
43+
// convert to dbg.values before writing out.
44+
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
45+
if (IsNewDbgInfoFormat)
46+
M.convertFromNewDbgValues();
47+
4248
if (llvm::isFunctionInPrintList("*")) {
4349
if (!Banner.empty())
4450
OS << Banner << "\n";
@@ -55,6 +61,10 @@ class PrintModulePassWrapper : public ModulePass {
5561
}
5662
}
5763
}
64+
65+
if (IsNewDbgInfoFormat)
66+
M.convertToNewDbgValues();
67+
5868
return false;
5969
}
6070

@@ -77,13 +87,23 @@ class PrintFunctionPassWrapper : public FunctionPass {
7787

7888
// This pass just prints a banner followed by the function as it's processed.
7989
bool runOnFunction(Function &F) override {
90+
// RemoveDIs: there's no textual representation of the DPValue debug-info,
91+
// convert to dbg.values before writing out.
92+
bool IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
93+
if (IsNewDbgInfoFormat)
94+
F.convertFromNewDbgValues();
95+
8096
if (isFunctionInPrintList(F.getName())) {
8197
if (forcePrintModuleIR())
8298
OS << Banner << " (function: " << F.getName() << ")\n"
8399
<< *F.getParent();
84100
else
85101
OS << Banner << '\n' << static_cast<Value &>(F);
86102
}
103+
104+
if (IsNewDbgInfoFormat)
105+
F.convertToNewDbgValues();
106+
87107
return false;
88108
}
89109

0 commit comments

Comments
 (0)