Skip to content

Commit cc0f1f0

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 3356818 commit cc0f1f0

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 {
@@ -4238,6 +4235,10 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
42384235
Error BitcodeReader::parseModule(uint64_t ResumeBit,
42394236
bool ShouldLazyLoadMetadata,
42404237
ParserCallbacks Callbacks) {
4238+
// Force the debug-info mode into the old format for now.
4239+
// FIXME: Remove this once all tools support RemoveDIs.
4240+
TheModule->IsNewDbgInfoFormat = false;
4241+
42414242
this->ValueTypeCallback = std::move(Callbacks.ValueType);
42424243
if (ResumeBit) {
42434244
if (Error JumpFailed = Stream.JumpToBit(ResumeBit))
@@ -6357,6 +6358,89 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
63576358
InstructionList.push_back(I);
63586359
break;
63596360
}
6361+
case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: {
6362+
// DPLabels are placed after the Instructions that they are attached to.
6363+
Instruction *Inst = getLastInstruction();
6364+
if (!Inst)
6365+
return error("Invalid dbg record: missing instruction");
6366+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[0]));
6367+
DILabel *Label = cast<DILabel>(getFnMetadataByID(Record[1]));
6368+
Inst->getParent()->insertDPValueBefore(new DPLabel(Label, DIL),
6369+
Inst->getIterator());
6370+
continue; // This isn't an instruction.
6371+
}
6372+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6373+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6374+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6375+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6376+
// DPValues are placed after the Instructions that they are attached to.
6377+
Instruction *Inst = getLastInstruction();
6378+
if (!Inst)
6379+
return error("Invalid dbg record: missing instruction");
6380+
6381+
// First 3 fields are common to all kinds:
6382+
// DILocation, DILocalVariable, DIExpression
6383+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
6384+
// ..., LocationMetadata
6385+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
6386+
// ..., Value
6387+
// dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
6388+
// ..., LocationMetadata
6389+
// dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
6390+
// ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
6391+
unsigned Slot = 0;
6392+
// Common fields (0-2).
6393+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[Slot++]));
6394+
DILocalVariable *Var =
6395+
cast<DILocalVariable>(getFnMetadataByID(Record[Slot++]));
6396+
DIExpression *Expr =
6397+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6398+
6399+
// Union field (3: LocationMetadata | Value).
6400+
Metadata *RawLocation = nullptr;
6401+
if (BitCode == bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE) {
6402+
Value *V = nullptr;
6403+
unsigned TyID = 0;
6404+
// We never expect to see a fwd reference value here because
6405+
// use-before-defs are encoded with the standard non-abbrev record
6406+
// type (they'd require encoding the type too, and they're rare). As a
6407+
// result, getValueTypePair only ever increments Slot by one here (once
6408+
// for the value, never twice for value and type).
6409+
unsigned SlotBefore = Slot;
6410+
if (getValueTypePair(Record, Slot, NextValueNo, V, TyID, CurBB))
6411+
return error("Invalid dbg record: invalid value");
6412+
(void)SlotBefore;
6413+
assert((SlotBefore == Slot - 1) && "unexpected fwd ref");
6414+
RawLocation = ValueAsMetadata::get(V);
6415+
} else {
6416+
RawLocation = getFnMetadataByID(Record[Slot++]);
6417+
}
6418+
6419+
DPValue *DPV = nullptr;
6420+
switch (BitCode) {
6421+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6422+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6423+
DPV = new DPValue(RawLocation, Var, Expr, DIL,
6424+
DPValue::LocationType::Value);
6425+
break;
6426+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6427+
DPV = new DPValue(RawLocation, Var, Expr, DIL,
6428+
DPValue::LocationType::Declare);
6429+
break;
6430+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6431+
DIAssignID *ID = cast<DIAssignID>(getFnMetadataByID(Record[Slot++]));
6432+
DIExpression *AddrExpr =
6433+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6434+
Metadata *Addr = getFnMetadataByID(Record[Slot++]);
6435+
DPV = new DPValue(RawLocation, Var, Expr, ID, Addr, AddrExpr, DIL);
6436+
break;
6437+
}
6438+
default:
6439+
llvm_unreachable("Unknown DPValue bitcode");
6440+
}
6441+
Inst->getParent()->insertDPValueBefore(DPV, Inst->getIterator());
6442+
continue; // This isn't an instruction.
6443+
}
63606444
case bitc::FUNC_CODE_INST_CALL: {
63616445
// CALL: [paramattrs, cc, fmf, fnty, fnid, arg0, arg1...]
63626446
if (Record.size() < 3)
@@ -6636,10 +6720,21 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
66366720
// Move the bit stream to the saved position of the deferred function body.
66376721
if (Error JumpFailed = Stream.JumpToBit(DFII->second))
66386722
return JumpFailed;
6723+
6724+
// Set the debug info mode to "new", forcing a mismatch between
6725+
// module and function debug modes. This is okay because we'll convert
6726+
// everything back to the old mode after parsing.
6727+
// FIXME: Remove this once all tools support RemoveDIs.
6728+
F->IsNewDbgInfoFormat = true;
6729+
66396730
if (Error Err = parseFunctionBody(F))
66406731
return Err;
66416732
F->setIsMaterializable(false);
66426733

6734+
// Convert new debug info records into intrinsics.
6735+
// FIXME: Remove this once all tools support RemoveDIs.
6736+
F->convertFromNewDbgValues();
6737+
66436738
if (StripDebugInfo)
66446739
stripDebugInfo(*F);
66456740

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
@@ -3491,25 +3495,95 @@ void ModuleBitcodeWriter::writeFunction(
34913495
NeedsMetadataAttachment |= I.hasMetadataOtherThanDebugLoc();
34923496

34933497
// If the instruction has a debug location, emit it.
3494-
DILocation *DL = I.getDebugLoc();
3495-
if (!DL)
3496-
continue;
3497-
3498-
if (DL == LastDL) {
3499-
// Just repeat the same debug loc as last time.
3500-
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3501-
continue;
3498+
if (DILocation *DL = I.getDebugLoc()) {
3499+
if (DL == LastDL) {
3500+
// Just repeat the same debug loc as last time.
3501+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3502+
} else {
3503+
Vals.push_back(DL->getLine());
3504+
Vals.push_back(DL->getColumn());
3505+
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
3506+
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
3507+
Vals.push_back(DL->isImplicitCode());
3508+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
3509+
Vals.clear();
3510+
LastDL = DL;
3511+
}
35023512
}
35033513

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

35153589
if (BlockAddress *BA = BlockAddress::lookup(&BB)) {
@@ -3750,7 +3824,17 @@ void ModuleBitcodeWriter::writeBlockInfo() {
37503824
FUNCTION_INST_GEP_ABBREV)
37513825
llvm_unreachable("Unexpected abbrev ordering!");
37523826
}
3753-
3827+
{
3828+
auto Abbv = std::make_shared<BitCodeAbbrev>();
3829+
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE));
3830+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // dbgloc
3831+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // var
3832+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // expr
3833+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // val
3834+
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
3835+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV)
3836+
llvm_unreachable("Unexpected abbrev ordering! 1");
3837+
}
37543838
Stream.ExitBlock();
37553839
}
37563840

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 DPValue 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 DPValue debug-info,
60-
// 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)