Skip to content

Commit 1fa2b6c

Browse files
OCHyamsronlieb
authored andcommitted
Reapply [RemoveDIs] Read/write DbgRecords directly from/to bitcode (llvm#83251)
RL: rebased on top of latest amd-staging Reaplying after revert in llvm#85382 (861ebe6). Fixed intermittent test failure by avoiding piping output in some RUN lines. 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. Change-Id: I1bbd2237f9d6a80eeedfaf155922b972249dc78a
1 parent 577092a commit 1fa2b6c

File tree

12 files changed

+373
-92
lines changed

12 files changed

+373
-92
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,17 @@ enum FunctionCodes {
628628
// operation, align, vol,
629629
// ordering, synchscope]
630630
FUNC_CODE_BLOCKADDR_USERS = 60, // BLOCKADDR_USERS: [value...]
631+
632+
FUNC_CODE_DEBUG_RECORD_VALUE =
633+
61, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
634+
FUNC_CODE_DEBUG_RECORD_DECLARE =
635+
62, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata]
636+
FUNC_CODE_DEBUG_RECORD_ASSIGN =
637+
63, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata,
638+
// DIAssignID, DIExpression (addr), ValueAsMetadata (addr)]
639+
FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE =
640+
64, // [DILocation, DILocalVariable, DIExpression, Value]
641+
FUNC_CODE_DEBUG_RECORD_LABEL = 65, // [DILocation, DILabel]
631642
};
632643

633644
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: 99 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
/// Load bitcode directly into RemoveDIs format (use debug records instead
107104
/// of debug intrinsics). UNSET is treated as FALSE, so the default action
108105
/// is to do nothing. Individual tools can override this to incrementally add
@@ -4305,6 +4302,10 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
43054302
Error BitcodeReader::parseModule(uint64_t ResumeBit,
43064303
bool ShouldLazyLoadMetadata,
43074304
ParserCallbacks Callbacks) {
4305+
// Force the debug-info mode into the old format for now.
4306+
// FIXME: Remove this once all tools support RemoveDIs.
4307+
TheModule->IsNewDbgInfoFormat = false;
4308+
43084309
this->ValueTypeCallback = std::move(Callbacks.ValueType);
43094310
if (ResumeBit) {
43104311
if (Error JumpFailed = Stream.JumpToBit(ResumeBit))
@@ -6424,6 +6425,89 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
64246425
InstructionList.push_back(I);
64256426
break;
64266427
}
6428+
case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: {
6429+
// DPLabels are placed after the Instructions that they are attached to.
6430+
Instruction *Inst = getLastInstruction();
6431+
if (!Inst)
6432+
return error("Invalid dbg record: missing instruction");
6433+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[0]));
6434+
DILabel *Label = cast<DILabel>(getFnMetadataByID(Record[1]));
6435+
Inst->getParent()->insertDbgRecordBefore(
6436+
new DPLabel(Label, DebugLoc(DIL)), Inst->getIterator());
6437+
continue; // This isn't an instruction.
6438+
}
6439+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6440+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6441+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6442+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6443+
// DPValues are placed after the Instructions that they are attached to.
6444+
Instruction *Inst = getLastInstruction();
6445+
if (!Inst)
6446+
return error("Invalid dbg record: missing instruction");
6447+
6448+
// First 3 fields are common to all kinds:
6449+
// DILocation, DILocalVariable, DIExpression
6450+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
6451+
// ..., LocationMetadata
6452+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
6453+
// ..., Value
6454+
// dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
6455+
// ..., LocationMetadata
6456+
// dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
6457+
// ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
6458+
unsigned Slot = 0;
6459+
// Common fields (0-2).
6460+
DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[Slot++]));
6461+
DILocalVariable *Var =
6462+
cast<DILocalVariable>(getFnMetadataByID(Record[Slot++]));
6463+
DIExpression *Expr =
6464+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6465+
6466+
// Union field (3: LocationMetadata | Value).
6467+
Metadata *RawLocation = nullptr;
6468+
if (BitCode == bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE) {
6469+
Value *V = nullptr;
6470+
unsigned TyID = 0;
6471+
// We never expect to see a fwd reference value here because
6472+
// use-before-defs are encoded with the standard non-abbrev record
6473+
// type (they'd require encoding the type too, and they're rare). As a
6474+
// result, getValueTypePair only ever increments Slot by one here (once
6475+
// for the value, never twice for value and type).
6476+
unsigned SlotBefore = Slot;
6477+
if (getValueTypePair(Record, Slot, NextValueNo, V, TyID, CurBB))
6478+
return error("Invalid dbg record: invalid value");
6479+
(void)SlotBefore;
6480+
assert((SlotBefore == Slot - 1) && "unexpected fwd ref");
6481+
RawLocation = ValueAsMetadata::get(V);
6482+
} else {
6483+
RawLocation = getFnMetadataByID(Record[Slot++]);
6484+
}
6485+
6486+
DbgVariableRecord *DVR = nullptr;
6487+
switch (BitCode) {
6488+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE:
6489+
case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE:
6490+
DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL,
6491+
DbgVariableRecord::LocationType::Value);
6492+
break;
6493+
case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE:
6494+
DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL,
6495+
DbgVariableRecord::LocationType::Declare);
6496+
break;
6497+
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
6498+
DIAssignID *ID = cast<DIAssignID>(getFnMetadataByID(Record[Slot++]));
6499+
DIExpression *AddrExpr =
6500+
cast<DIExpression>(getFnMetadataByID(Record[Slot++]));
6501+
Metadata *Addr = getFnMetadataByID(Record[Slot++]);
6502+
DVR = new DbgVariableRecord(RawLocation, Var, Expr, ID, Addr, AddrExpr, DIL);
6503+
break;
6504+
}
6505+
default:
6506+
llvm_unreachable("Unknown DbgVariableRecord bitcode");
6507+
}
6508+
Inst->getParent()->insertDbgRecordBefore(DVR, Inst->getIterator());
6509+
continue; // This isn't an instruction.
6510+
}
64276511
case bitc::FUNC_CODE_INST_CALL: {
64286512
// CALL: [paramattrs, cc, fmf, fnty, fnid, arg0, arg1...]
64296513
if (Record.size() < 3)
@@ -6703,10 +6787,22 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
67036787
// Move the bit stream to the saved position of the deferred function body.
67046788
if (Error JumpFailed = Stream.JumpToBit(DFII->second))
67056789
return JumpFailed;
6790+
6791+
// Set the debug info mode to "new", possibly creating a mismatch between
6792+
// module and function debug modes. This is okay because we'll convert
6793+
// everything back to the old mode after parsing if needed.
6794+
// FIXME: Remove this once all tools support RemoveDIs.
6795+
F->IsNewDbgInfoFormat = true;
6796+
67066797
if (Error Err = parseFunctionBody(F))
67076798
return Err;
67086799
F->setIsMaterializable(false);
67096800

6801+
// Convert new debug info records into intrinsics.
6802+
// FIXME: Remove this once all tools support RemoveDIs.
6803+
if (!F->getParent()->IsNewDbgInfoFormat)
6804+
F->convertFromNewDbgValues();
6805+
67106806
if (StripDebugInfo)
67116807
stripDebugInfo(*F);
67126808

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
@@ -3608,25 +3612,95 @@ void ModuleBitcodeWriter::writeFunction(
36083612
NeedsMetadataAttachment |= I.hasMetadataOtherThanDebugLoc();
36093613

36103614
// If the instruction has a debug location, emit it.
3611-
DILocation *DL = I.getDebugLoc();
3612-
if (!DL)
3613-
continue;
3614-
3615-
if (DL == LastDL) {
3616-
// Just repeat the same debug loc as last time.
3617-
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3618-
continue;
3615+
if (DILocation *DL = I.getDebugLoc()) {
3616+
if (DL == LastDL) {
3617+
// Just repeat the same debug loc as last time.
3618+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
3619+
} else {
3620+
Vals.push_back(DL->getLine());
3621+
Vals.push_back(DL->getColumn());
3622+
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
3623+
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
3624+
Vals.push_back(DL->isImplicitCode());
3625+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
3626+
Vals.clear();
3627+
LastDL = DL;
3628+
}
36193629
}
36203630

3621-
Vals.push_back(DL->getLine());
3622-
Vals.push_back(DL->getColumn());
3623-
Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
3624-
Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
3625-
Vals.push_back(DL->isImplicitCode());
3626-
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
3627-
Vals.clear();
3628-
3629-
LastDL = DL;
3631+
// If the instruction has DbgRecords attached to it, emit them. Note that
3632+
// they come after the instruction so that it's easy to attach them again
3633+
// when reading the bitcode, even though conceptually the debug locations
3634+
// start "before" the instruction.
3635+
if (I.hasDbgRecords() && WriteNewDbgInfoFormatToBitcode) {
3636+
/// Try to push the value only (unwrapped), otherwise push the
3637+
/// metadata wrapped value. Returns true if the value was pushed
3638+
/// without the ValueAsMetadata wrapper.
3639+
auto PushValueOrMetadata = [&Vals, InstID,
3640+
this](Metadata *RawLocation) {
3641+
assert(RawLocation && "RawLocation unexpectedly null in DPValue");
3642+
if (ValueAsMetadata *VAM = dyn_cast<ValueAsMetadata>(RawLocation)) {
3643+
SmallVector<unsigned, 2> ValAndType;
3644+
// If the value is a fwd-ref the type is also pushed. We don't
3645+
// want the type, so fwd-refs are kept wrapped (pushValueAndType
3646+
// returns false if the value is pushed without type).
3647+
if (!pushValueAndType(VAM->getValue(), InstID, ValAndType)) {
3648+
Vals.push_back(ValAndType[0]);
3649+
return true;
3650+
}
3651+
}
3652+
// The metadata is a DIArgList, or ValueAsMetadata wrapping a
3653+
// fwd-ref. Push the metadata ID.
3654+
Vals.push_back(VE.getMetadataID(RawLocation));
3655+
return false;
3656+
};
3657+
3658+
// Write out non-instruction debug information attached to this
3659+
// instruction. Write it after the instruction so that it's easy to
3660+
// re-attach to the instruction reading the records in.
3661+
for (DbgRecord &DR : I.DbgMarker->getDbgRecordRange()) {
3662+
if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
3663+
Vals.push_back(VE.getMetadataID(&*DPL->getDebugLoc()));
3664+
Vals.push_back(VE.getMetadataID(DPL->getLabel()));
3665+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_LABEL, Vals);
3666+
Vals.clear();
3667+
continue;
3668+
}
3669+
3670+
// First 3 fields are common to all kinds:
3671+
// DILocation, DILocalVariable, DIExpression
3672+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
3673+
// ..., LocationMetadata
3674+
// dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
3675+
// ..., Value
3676+
// dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
3677+
// ..., LocationMetadata
3678+
// dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
3679+
// ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
3680+
DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR);
3681+
Vals.push_back(VE.getMetadataID(&*DVR.getDebugLoc()));
3682+
Vals.push_back(VE.getMetadataID(DVR.getVariable()));
3683+
Vals.push_back(VE.getMetadataID(DVR.getExpression()));
3684+
if (DVR.isDbgValue()) {
3685+
if (PushValueOrMetadata(DVR.getRawLocation()))
3686+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE, Vals,
3687+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV);
3688+
else
3689+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE, Vals);
3690+
} else if (DVR.isDbgDeclare()) {
3691+
Vals.push_back(VE.getMetadataID(DVR.getRawLocation()));
3692+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals);
3693+
} else {
3694+
assert(DVR.isDbgAssign() && "Unexpected DbgRecord kind");
3695+
Vals.push_back(VE.getMetadataID(DVR.getRawLocation()));
3696+
Vals.push_back(VE.getMetadataID(DVR.getAssignID()));
3697+
Vals.push_back(VE.getMetadataID(DVR.getAddressExpression()));
3698+
Vals.push_back(VE.getMetadataID(DVR.getRawAddress()));
3699+
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN, Vals);
3700+
}
3701+
Vals.clear();
3702+
}
3703+
}
36303704
}
36313705

36323706
if (BlockAddress *BA = BlockAddress::lookup(&BB)) {
@@ -3867,7 +3941,17 @@ void ModuleBitcodeWriter::writeBlockInfo() {
38673941
FUNCTION_INST_GEP_ABBREV)
38683942
llvm_unreachable("Unexpected abbrev ordering!");
38693943
}
3870-
3944+
{
3945+
auto Abbv = std::make_shared<BitCodeAbbrev>();
3946+
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE));
3947+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // dbgloc
3948+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // var
3949+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // expr
3950+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // val
3951+
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
3952+
FUNCTION_DEBUG_RECORD_VALUE_ABBREV)
3953+
llvm_unreachable("Unexpected abbrev ordering! 1");
3954+
}
38713955
Stream.ExitBlock();
38723956
}
38733957

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)