summaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
diff options
context:
space:
mode:
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();
}