summaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
diff options
context:
space:
mode:
authorOrlando Cazalet-Hyams <orlando.hyams@sony.com>2024-03-15 10:47:48 +0000
committerGitHub <noreply@github.com>2024-03-15 10:47:48 +0000
commitd6d3d96b654012d72ad170d272cb2fe2c8def90d (patch)
treeef1ca39627258f01da11d44cb1c366103de67877 /llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
parentb890a48a12aa5c851185ae2fd6273cd853fe0bc5 (diff)
[RemoveDIs] Read/write DbgRecords directly from/to bitcode (#83251)
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.
Diffstat (limited to 'llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp120
1 files changed, 102 insertions, 18 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 597f49332fad..6f0879a4e0ee 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -99,6 +99,9 @@ namespace llvm {
extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold;
}
+extern bool WriteNewDbgInfoFormatToBitcode;
+extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
+
namespace {
/// These are manifest constants used by the bitcode writer. They do not need to
@@ -128,6 +131,7 @@ enum {
FUNCTION_INST_RET_VAL_ABBREV,
FUNCTION_INST_UNREACHABLE_ABBREV,
FUNCTION_INST_GEP_ABBREV,
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV,
};
/// Abstract class to manage the bitcode writing, subclassed for each bitcode
@@ -3512,25 +3516,95 @@ void ModuleBitcodeWriter::writeFunction(
NeedsMetadataAttachment |= I.hasMetadataOtherThanDebugLoc();
// If the instruction has a debug location, emit it.
- DILocation *DL = I.getDebugLoc();
- if (!DL)
- continue;
-
- if (DL == LastDL) {
- // Just repeat the same debug loc as last time.
- Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
- continue;
+ if (DILocation *DL = I.getDebugLoc()) {
+ if (DL == LastDL) {
+ // Just repeat the same debug loc as last time.
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+ } else {
+ Vals.push_back(DL->getLine());
+ Vals.push_back(DL->getColumn());
+ Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+ Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+ Vals.push_back(DL->isImplicitCode());
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+ Vals.clear();
+ LastDL = DL;
+ }
}
- Vals.push_back(DL->getLine());
- Vals.push_back(DL->getColumn());
- Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
- Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
- Vals.push_back(DL->isImplicitCode());
- Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
- Vals.clear();
-
- LastDL = DL;
+ // If the instruction has DbgRecords attached to it, emit them. Note that
+ // they come after the instruction so that it's easy to attach them again
+ // when reading the bitcode, even though conceptually the debug locations
+ // start "before" the instruction.
+ if (I.hasDbgRecords() && WriteNewDbgInfoFormatToBitcode) {
+ /// Try to push the value only (unwrapped), otherwise push the
+ /// metadata wrapped value. Returns true if the value was pushed
+ /// without the ValueAsMetadata wrapper.
+ auto PushValueOrMetadata = [&Vals, InstID,
+ this](Metadata *RawLocation) {
+ assert(RawLocation && "RawLocation unexpectedly null in DPValue");
+ if (ValueAsMetadata *VAM = dyn_cast<ValueAsMetadata>(RawLocation)) {
+ SmallVector<unsigned, 2> ValAndType;
+ // If the value is a fwd-ref the type is also pushed. We don't
+ // want the type, so fwd-refs are kept wrapped (pushValueAndType
+ // returns false if the value is pushed without type).
+ if (!pushValueAndType(VAM->getValue(), InstID, ValAndType)) {
+ Vals.push_back(ValAndType[0]);
+ return true;
+ }
+ }
+ // The metadata is a DIArgList, or ValueAsMetadata wrapping a
+ // fwd-ref. Push the metadata ID.
+ Vals.push_back(VE.getMetadataID(RawLocation));
+ return false;
+ };
+
+ // Write out non-instruction debug information attached to this
+ // instruction. Write it after the instruction so that it's easy to
+ // re-attach to the instruction reading the records in.
+ for (DbgRecord &DR : I.DbgMarker->getDbgRecordRange()) {
+ if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+ Vals.push_back(VE.getMetadataID(&*DPL->getDebugLoc()));
+ Vals.push_back(VE.getMetadataID(DPL->getLabel()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_LABEL, Vals);
+ Vals.clear();
+ continue;
+ }
+
+ // First 3 fields are common to all kinds:
+ // DILocation, DILocalVariable, DIExpression
+ // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE)
+ // ..., LocationMetadata
+ // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd)
+ // ..., Value
+ // dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE)
+ // ..., LocationMetadata
+ // dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN)
+ // ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata
+ DPValue &DPV = cast<DPValue>(DR);
+ Vals.push_back(VE.getMetadataID(&*DPV.getDebugLoc()));
+ Vals.push_back(VE.getMetadataID(DPV.getVariable()));
+ Vals.push_back(VE.getMetadataID(DPV.getExpression()));
+ if (DPV.isDbgValue()) {
+ if (PushValueOrMetadata(DPV.getRawLocation()))
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE, Vals,
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV);
+ else
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE, Vals);
+ } else if (DPV.isDbgDeclare()) {
+ Vals.push_back(VE.getMetadataID(DPV.getRawLocation()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals);
+ } else {
+ assert(DPV.isDbgAssign() && "Unexpected DbgRecord kind");
+ Vals.push_back(VE.getMetadataID(DPV.getRawLocation()));
+ Vals.push_back(VE.getMetadataID(DPV.getAssignID()));
+ Vals.push_back(VE.getMetadataID(DPV.getAddressExpression()));
+ Vals.push_back(VE.getMetadataID(DPV.getRawAddress()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN, Vals);
+ }
+ Vals.clear();
+ }
+ }
}
if (BlockAddress *BA = BlockAddress::lookup(&BB)) {
@@ -3771,7 +3845,17 @@ void ModuleBitcodeWriter::writeBlockInfo() {
FUNCTION_INST_GEP_ABBREV)
llvm_unreachable("Unexpected abbrev ordering!");
}
-
+ {
+ auto Abbv = std::make_shared<BitCodeAbbrev>();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // dbgloc
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // var
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 7)); // expr
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // val
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
+ FUNCTION_DEBUG_RECORD_VALUE_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering! 1");
+ }
Stream.ExitBlock();
}