Skip to content

Commit 5714bf0

Browse files
committed
[RemoveDIs] Add bitcode format
If --write-experimental-debuginfo-iterators-to-bitcode is true (default false) and --expermental-debuginfo-iterators is also true then the new debug info format (non-instruction records) is written to bitcode directly. Added the following records: FUNC_CODE_DEBUG_RECORD_LABEL FUNC_CODE_DEBUG_RECORD_VALUE FUNC_CODE_DEBUG_RECORD_DECLARE FUNC_CODE_DEBUG_RECORD_ASSIGN FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE The last one has an abbrev in FUNCTION_BLOCK BLOCK_INFO. Incidentally, this uses the last value available without widening the code-length for FUNCTION_BLOCK from 4 to 5 bits. Records are formatted as follows: All DbgRecord start with: 1. DILocation FUNC_CODE_DEBUG_RECORD_LABEL 2. DILabel DPValues then share common fields: 2. DILocalVariable 3. DIExpression FUNC_CODE_DEBUG_RECORD_VALUE 4. Location Metadata FUNC_CODE_DEBUG_RECORD_DECLARE 4. Location Metadata FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE 4. Location Value (single) FUNC_CODE_DEBUG_RECORD_ASSIGN 4. Location Metadata 5. DIAssignID 6. DIExpression (address) 7. Location Metadata (address) Encoding the DILocation metadata reference directly appeared to yield smaller bitcode files than encoding the operands seperately (as is done with instruction DILocations). FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE is by far the most common DbgRecord record in optimized code (order of 5x-10x over other kinds). Unoptimized code should only contain FUNC_CODE_DEBUG_RECORD_DECLARE.
1 parent 8310fd3 commit 5714bf0

File tree

12 files changed

+500
-87
lines changed

12 files changed

+500
-87
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,17 @@ enum FunctionCodes {
624624
// operation, align, vol,
625625
// ordering, synchscope]
626626
FUNC_CODE_BLOCKADDR_USERS = 60, // BLOCKADDR_USERS: [value...]
627+
628+
FUNC_CODE_DEBUG_RECORD_VALUE =
629+
61, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
630+
FUNC_CODE_DEBUG_RECORD_DECLARE =
631+
62, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
632+
FUNC_CODE_DEBUG_RECORD_ASSIGN =
633+
63, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata,
634+
// DIAssignID, DIExpression (addr), ValueAsMetadata (addr)]
635+
FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE =
636+
64, // [DILocation, DILocalVariable, DIExpression, Value]
637+
FUNC_CODE_DEBUG_RECORD_LABEL = 65, // DPVALUE: [DILocation, DILabel]
627638
};
628639

629640
enum UseListCodes {

llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ GetCodeName(unsigned CodeID, unsigned BlockID,
270270
STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG)
271271
STRINGIFY_CODE(FUNC_CODE, INST_CALLBR)
272272
STRINGIFY_CODE(FUNC_CODE, BLOCKADDR_USERS)
273+
STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_DECLARE)
274+
STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE)
275+
STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_ASSIGN)
276+
STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE_SIMPLE)
277+
STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_LABEL)
273278
}
274279
case bitc::VALUE_SYMTAB_BLOCK_ID:
275280
switch (CodeID) {

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ static cl::opt<bool> ExpandConstantExprs(
100100
cl::desc(
101101
"Expand constant expressions to instructions for testing purposes"));
102102

103-
// Declare external flag for whether we're using the new debug-info format.
104-
extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
105-
106103
namespace {
107104

108105
enum {
@@ -4279,6 +4276,10 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
42794276
Error BitcodeReader::parseModule(uint64_t ResumeBit,
42804277
bool ShouldLazyLoadMetadata,
42814278
ParserCallbacks Callbacks) {
4279+
// Force the debug-info mode into the old format for now.
4280+
// FIXME: Remove this once all tools support RemoveDIs.
4281+
TheModule->IsNewDbgInfoFormat = false;
4282+
42824283
this->ValueTypeCallback = std::move(Callbacks.ValueType);
42834284
if (ResumeBit) {
42844285
if (Error JumpFailed = Stream.JumpToBit(ResumeBit))
@@ -6398,6 +6399,89 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
63986399
InstructionList.push_back(I);
63996400
break;
64006401
}
6402+
case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: {
6403+
// DPLabels are placed after the Instructions that they are attached to.
6404+
Instruction *Inst = getLastInstruction();
6405+
if (!Inst)
6406+
return error("Invalid dbg record: missing instruction");
6407+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[0]));
6408+
DILabel *Label = cast<DILabel>(getFnMetadataByID(Record[1]));
6409+
Inst->getParent()->insertDPValueBefore(new DPLabel(Label, DIL),
6410+
Inst->getIterator());
6411+
continue; // This isn't an instruction.
6412+
}
6413+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6414+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6415+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6416+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6417+
// DPValues are placed after the Instructions that they are attached to.
6418+
Instruction *Inst = getLastInstruction();
6419+
if (!Inst)
6420+
return error("Invalid dbg record: missing instruction");
6421+
6422+
// First 3 fields are common to all kinds:
6423+
// DILocation, DILocalVariable, DIExpression
6424+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
6425+
// ..., LocationMetadata
6426+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
6427+
// ..., Value
6428+
// dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
6429+
// ..., LocationMetadata
6430+
// dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
6431+
// ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
6432+
unsigned Slot = 0;
6433+
// Common fields (0-2).
6434+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[Slot++]));
6435+
DILocalVariable *Var =
6436+
cast<DILocalVariable>(getFnMetadataByID(Record[Slot++]));
6437+
DIExpression *Expr =
6438+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6439+
6440+
// Union field (3: LocationMetadata | Value).
6441+
Metadata *RawLocation = nullptr;
6442+
if (BitCode == bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE) {
6443+
Value *V = nullptr;
6444+
unsigned TyID = 0;
6445+
// We never expect to see a fwd reference value here because
6446+
// use-before-defs are encoded with the standard non-abbrev record
6447+
// type (they'd require encoding the type too, and they're rare). As a
6448+
// result, getValueTypePair only ever increments Slot by one here (once
6449+
// for the value, never twice for value and type).
6450+
unsigned SlotBefore = Slot;
6451+
if (getValueTypePair(Record, Slot, NextValueNo, V, TyID, CurBB))
6452+
return error("Invalid dbg record: invalid value");
6453+
(void)SlotBefore;
6454+
assert((SlotBefore == Slot - 1) && "unexpected fwd ref");
6455+
RawLocation = ValueAsMetadata::get(V);
6456+
} else {
6457+
RawLocation = getFnMetadataByID(Record[Slot++]);
6458+
}
6459+
6460+
DPValue *DPV = nullptr;
6461+
switch (BitCode) {
6462+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6463+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6464+
DPV = new DPValue(RawLocation, Var, Expr, DIL,
6465+
DPValue::LocationType::Value);
6466+
break;
6467+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6468+
DPV = new DPValue(RawLocation, Var, Expr, DIL,
6469+
DPValue::LocationType::Declare);
6470+
break;
6471+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6472+
DIAssignID *ID = cast<DIAssignID>(getFnMetadataByID(Record[Slot++]));
6473+
DIExpression *AddrExpr =
6474+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6475+
Metadata *Addr = getFnMetadataByID(Record[Slot++]);
6476+
DPV = new DPValue(RawLocation, Var, Expr, ID, Addr, AddrExpr, DIL);
6477+
break;
6478+
}
6479+
default:
6480+
llvm_unreachable("Unknown DPValue bitcode");
6481+
}
6482+
Inst->getParent()->insertDPValueBefore(DPV, Inst->getIterator());
6483+
continue; // This isn't an instruction.
6484+
}
64016485
case bitc::FUNC_CODE_INST_CALL: {
64026486
// CALL: [paramattrs, cc, fmf, fnty, fnid, arg0, arg1...]
64036487
if (Record.size() < 3)
@@ -6677,10 +6761,21 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
66776761
// Move the bit stream to the saved position of the deferred function body.
66786762
if (Error JumpFailed = Stream.JumpToBit(DFII->second))
66796763
return JumpFailed;
6764+
6765+
// Set the debug info mode to "new", forcing a mismatch between
6766+
// module and function debug modes. This is okay because we'll convert
6767+
// everything back to the old mode after parsing.
6768+
// FIXME: Remove this once all tools support RemoveDIs.
6769+
F->IsNewDbgInfoFormat = true;
6770+
66806771
if (Error Err = parseFunctionBody(F))
66816772
return Err;
66826773
F->setIsMaterializable(false);
66836774

6775+
// Convert new debug info records into intrinsics.
6776+
// FIXME: Remove this once all tools support RemoveDIs.
6777+
F->convertFromNewDbgValues();
6778+
66846779
if (StripDebugInfo)
66856780
stripDebugInfo(*F);
66866781

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ namespace llvm {
9999
extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold;
100100
}
101101

102+
extern bool WriteNewDbgInfoFormatToBitcode;
103+
extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
104+
102105
namespace {
103106

104107
/// These are manifest constants used by the bitcode writer. They do not need to
@@ -128,6 +131,7 @@ enum {
128131
FUNCTION_INST_RET_VAL_ABBREV,
129132
FUNCTION_INST_UNREACHABLE_ABBREV,
130133
FUNCTION_INST_GEP_ABBREV,
134+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV,
131135
};
132136

133137
/// Abstract class to manage the bitcode writing, subclassed for each bitcode
@@ -3512,25 +3516,95 @@ void ModuleBitcodeWriter::writeFunction(
35123516
NeedsMetadataAttachment |= I.hasMetadataOtherThanDebugLoc();
35133517

35143518
// If the instruction has a debug location, emit it.
3515-
DILocation *DL = I.getDebugLoc();
3516-
if (!DL)
3517-
continue;
3518-
3519-
if (DL == LastDL) {
3520-
// Just repeat the same debug loc as last time.
3521-
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3522-
continue;
3519+
if (DILocation *DL = I.getDebugLoc()) {
3520+
if (DL == LastDL) {
3521+
// Just repeat the same debug loc as last time.
3522+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3523+
} else {
3524+
Vals.push_back(DL->getLine());
3525+
Vals.push_back(DL->getColumn());
3526+
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
3527+
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
3528+
Vals.push_back(DL->isImplicitCode());
3529+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
3530+
Vals.clear();
3531+
LastDL = DL;
3532+
}
35233533
}
35243534

3525-
Vals.push_back(DL->getLine());
3526-
Vals.push_back(DL->getColumn());
3527-
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
3528-
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
3529-
Vals.push_back(DL->isImplicitCode());
3530-
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
3531-
Vals.clear();
3532-
3533-
LastDL = DL;
3535+
// If the instruction has DPValues attached to it, emit them. Note that
3536+
// they come after the instruction so that it's easy to attach them again
3537+
// when reading the bitcode, even though conceptually the debug locations
3538+
// start "before" the instruction.
3539+
if (I.hasDbgValues() && WriteNewDbgInfoFormatToBitcode) {
3540+
/// Try to push the value only (unwrapped), otherwise push the
3541+
/// metadata wrapped value. Returns true if the value was pushed
3542+
/// without the ValueAsMetadata wrapper.
3543+
auto PushValueOrMetadata = [&Vals, InstID,
3544+
this](Metadata *RawLocation) {
3545+
assert(RawLocation && "RawLocation unexpectedly null in DPValue");
3546+
if (ValueAsMetadata *VAM = dyn_cast<ValueAsMetadata>(RawLocation)) {
3547+
SmallVector<unsigned, 2> ValAndType;
3548+
// If the value is a fwd-ref the type is also pushed. We don't
3549+
// want the type, so fwd-refs are kept wrapped (pushValueAndType
3550+
// returns false if the value is pushed without type).
3551+
if (!pushValueAndType(VAM->getValue(), InstID, ValAndType)) {
3552+
Vals.push_back(ValAndType[0]);
3553+
return true;
3554+
}
3555+
}
3556+
// The metadata is a DIArgList, or ValueAsMetadata wrapping a
3557+
// fwd-ref. Push the metadata ID.
3558+
Vals.push_back(VE.getMetadataID(RawLocation));
3559+
return false;
3560+
};
3561+
3562+
// Write out non-instruction debug information attached to this
3563+
// instruction. Write it after the instruction so that it's easy to
3564+
// re-attach to the instruction reading the records in.
3565+
for (DbgRecord &DR : I.DbgMarker->getDbgValueRange()) {
3566+
if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
3567+
Vals.push_back(VE.getMetadataID(&*DPL->getDebugLoc()));
3568+
Vals.push_back(VE.getMetadataID(DPL->getLabel()));
3569+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_LABEL, Vals);
3570+
Vals.clear();
3571+
continue;
3572+
}
3573+
3574+
// First 3 fields are common to all kinds:
3575+
// DILocation, DILocalVariable, DIExpression
3576+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
3577+
// ..., LocationMetadata
3578+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
3579+
// ..., Value
3580+
// dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
3581+
// ..., LocationMetadata
3582+
// dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
3583+
// ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
3584+
DPValue &DPV = cast<DPValue>(DR);
3585+
Vals.push_back(VE.getMetadataID(&*DPV.getDebugLoc()));
3586+
Vals.push_back(VE.getMetadataID(DPV.getVariable()));
3587+
Vals.push_back(VE.getMetadataID(DPV.getExpression()));
3588+
if (DPV.isDbgValue()) {
3589+
if (PushValueOrMetadata(DPV.getRawLocation()))
3590+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE, Vals,
3591+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV);
3592+
else
3593+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE, Vals);
3594+
} else if (DPV.isDbgDeclare()) {
3595+
Vals.push_back(VE.getMetadataID(DPV.getRawLocation()));
3596+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals);
3597+
} else {
3598+
assert(DPV.isDbgAssign() && "Unexpected DbgRecord kind");
3599+
Vals.push_back(VE.getMetadataID(DPV.getRawLocation()));
3600+
Vals.push_back(VE.getMetadataID(DPV.getAssignID()));
3601+
Vals.push_back(VE.getMetadataID(DPV.getAddressExpression()));
3602+
Vals.push_back(VE.getMetadataID(DPV.getRawAddress()));
3603+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN, Vals);
3604+
}
3605+
Vals.clear();
3606+
}
3607+
}
35343608
}
35353609

35363610
if (BlockAddress *BA = BlockAddress::lookup(&BB)) {
@@ -3771,7 +3845,17 @@ void ModuleBitcodeWriter::writeBlockInfo() {
37713845
FUNCTION_INST_GEP_ABBREV)
37723846
llvm_unreachable("Unexpected abbrev ordering!");
37733847
}
3774-
3848+
{
3849+
auto Abbv = std::make_shared<BitCodeAbbrev>();
3850+
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE));
3851+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // dbgloc
3852+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // var
3853+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // expr
3854+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // val
3855+
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
3856+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV)
3857+
llvm_unreachable("Unexpected abbrev ordering! 1");
3858+
}
37753859
Stream.ExitBlock();
37763860
}
37773861

llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@
1818
#include "llvm/Pass.h"
1919
using namespace llvm;
2020

21+
extern bool WriteNewDbgInfoFormatToBitcode;
22+
2123
PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
22-
// RemoveDIs: there's no bitcode representation of the DbgRecord debug-info,
23-
// convert to dbg.values before writing out.
24-
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
25-
if (IsNewDbgInfoFormat)
24+
bool ConvertToOldDbgFormatForWrite =
25+
M.IsNewDbgInfoFormat && !WriteNewDbgInfoFormatToBitcode;
26+
if (ConvertToOldDbgFormatForWrite)
2627
M.convertFromNewDbgValues();
2728

2829
const ModuleSummaryIndex *Index =
2930
EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
3031
: nullptr;
3132
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
3233

33-
if (IsNewDbgInfoFormat)
34+
if (ConvertToOldDbgFormatForWrite)
3435
M.convertToNewDbgValues();
3536

3637
return PreservedAnalyses::all();
@@ -56,16 +57,15 @@ namespace {
5657
StringRef getPassName() const override { return "Bitcode Writer"; }
5758

5859
bool runOnModule(Module &M) override {
59-
// RemoveDIs: there's no bitcode representation of the DbgRecord
60-
// debug-info, convert to dbg.values before writing out.
61-
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
62-
if (IsNewDbgInfoFormat)
60+
bool ConvertToOldDbgFormatForWrite =
61+
M.IsNewDbgInfoFormat && !WriteNewDbgInfoFormatToBitcode;
62+
if (ConvertToOldDbgFormatForWrite)
6363
M.convertFromNewDbgValues();
6464

6565
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, /*Index=*/nullptr,
6666
/*EmitModuleHash=*/false);
6767

68-
if (IsNewDbgInfoFormat)
68+
if (ConvertToOldDbgFormatForWrite)
6969
M.convertToNewDbgValues();
7070
return false;
7171
}

0 commit comments

Comments
 (0)