Skip to content

Commit 1ec3fcc

Browse files
committed
Initial commit for serializing/deserializing debug value instructions
1 parent de44fe4 commit 1ec3fcc

File tree

4 files changed

+218
-3
lines changed

4 files changed

+218
-3
lines changed

lib/Serialization/DeserializeSIL.cpp

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
14181418
switch (RecordKind) {
14191419
default:
14201420
llvm_unreachable("Record kind for a SIL instruction is not supported.");
1421+
case SIL_DEBUG_VALUE_DELIMITER:
1422+
return false;
14211423
case SIL_ONE_VALUE_ONE_OPERAND:
14221424
SILOneValueOneOperandLayout::readRecord(scratch, RawOpCode, Attr,
14231425
ValID, TyID, TyCategory,
@@ -1590,20 +1592,119 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
15901592
SILThunkLayout::readRecord(scratch, Attr, TyID, TyCategory, ValID, SubID);
15911593
RawOpCode = unsigned(SILInstructionKind::ThunkInst);
15921594
break;
1595+
1596+
case SIL_DEBUG_VALUE:
1597+
SILDebugValueLayout::readRecord(scratch, TyCategory, TyCategory2, Attr,
1598+
ListOfValues);
1599+
RawOpCode = (unsigned)SILInstructionKind::DebugValueInst;
1600+
1601+
break;
15931602
}
15941603

15951604
// FIXME: validate
15961605
SILInstructionKind OpCode = (SILInstructionKind) RawOpCode;
15971606

15981607
SILInstruction *ResultInst;
15991608
switch (OpCode) {
1600-
case SILInstructionKind::DebugValueInst:
16011609
case SILInstructionKind::DebugStepInst:
16021610
case SILInstructionKind::SpecifyTestInst:
16031611
case SILInstructionKind::AllocPackMetadataInst:
16041612
case SILInstructionKind::DeallocPackMetadataInst:
16051613
llvm_unreachable("not supported");
16061614

1615+
case SILInstructionKind::DebugValueInst: {
1616+
assert(ListOfValues.size() >= 2 && "Unexpected number of values");
1617+
SILValue Value =
1618+
getLocalValue(Fn, ListOfValues[0],
1619+
getSILType(MF->getType(ListOfValues[1]),
1620+
(SILValueCategory)TyCategory, Fn));
1621+
1622+
auto PoisonRefs = PoisonRefs_t(Attr & 0x1);
1623+
auto UsesMoveableValDebugInfo =
1624+
UsesMoveableValueDebugInfo_t((Attr >> 1) & 0x1);
1625+
auto HasTrace = (Attr >> 2) & 0x1;
1626+
1627+
bool HaveDebugVar = (Attr >> 3) & 0x1;
1628+
1629+
SILDebugVariable DebugVar;
1630+
if (HaveDebugVar) {
1631+
assert(ListOfValues.size() >= 4 && "Unexpected number of values");
1632+
bool IsLet = (Attr >> 4) & 0x1;
1633+
unsigned IsDenseMapSingleton = (Attr >> 5) & 0x3;
1634+
bool HasType = (Attr >> 7) & 0x1;
1635+
bool HasScope = (Attr >> 8) & 0x1;
1636+
bool HasLoc = (Attr >> 9) & 0x1;
1637+
1638+
auto VarName = MF->getIdentifierText(ListOfValues[2]);
1639+
auto ArgNo = ListOfValues[3];
1640+
std::optional<SILType> Type;
1641+
1642+
unsigned I = 4;
1643+
unsigned Row, Col;
1644+
StringRef FileName;
1645+
std::optional<SILLocation> Loc;
1646+
if (HasType) {
1647+
Type = getSILType(MF->getType(ListOfValues[I++]),
1648+
(SILValueCategory)TyCategory2, Fn);
1649+
}
1650+
1651+
if (HasLoc) {
1652+
Row = ListOfValues[I++];
1653+
Col = ListOfValues[I++];
1654+
FileName = MF->getIdentifierText(ListOfValues[I++]);
1655+
Loc = RegularLocation(SILLocation::FilenameAndLocation::alloc(
1656+
Row, Col, FileName, Fn->getModule()));
1657+
}
1658+
1659+
SILDebugInfoExpression Expressions;
1660+
while (I < ListOfValues.size()) {
1661+
using DIExpr = SILDIExprElement;
1662+
SILDIExprElement::Kind Kind = (SILDIExprElement::Kind)ListOfValues[I++];
1663+
switch (Kind) {
1664+
case DIExpr::OperatorKind:
1665+
Expressions.push_back(
1666+
DIExpr::createOperator((SILDIExprOperator)ListOfValues[I++]));
1667+
break;
1668+
case DIExpr::DeclKind:
1669+
Expressions.push_back(
1670+
DIExpr::createDecl(MF->getDecl(ListOfValues[I++])));
1671+
break;
1672+
case DIExpr::ConstIntKind: {
1673+
auto Str = MF->getIdentifierText(ListOfValues[I++]);
1674+
APInt Int;
1675+
Str.getAsInteger(10, Int);
1676+
Expressions.push_back(DIExpr::createConstInt(Int.getLimitedValue()));
1677+
break;
1678+
}
1679+
case SILDIExprElement::Kind::TypeKind:
1680+
Expressions.push_back(
1681+
DIExpr::createType(MF->getType(ListOfValues[I++])));
1682+
break;
1683+
}
1684+
}
1685+
1686+
const SILDebugScope *Scope = nullptr;
1687+
if (HasScope) {
1688+
SmallVector<uint64_t, 64> scratch;
1689+
auto maybeKind = readNextRecord(scratch);
1690+
if (!maybeKind) MF->fatal(maybeKind.takeError());
1691+
auto maybeScope = readDebugScopes(Fn, scratch, Builder, maybeKind.get());
1692+
if (!maybeScope) MF->fatal(maybeScope.takeError());
1693+
Scope = maybeScope.get();
1694+
}
1695+
1696+
DebugVar = SILDebugVariable(
1697+
VarName, IsLet, ArgNo, Type, Loc, Scope,
1698+
llvm::ArrayRef<SILDIExprElement>(Expressions.element_begin(),
1699+
Expressions.element_end()));
1700+
DebugVar.isDenseMapSingleton = IsDenseMapSingleton;
1701+
}
1702+
1703+
ResultInst = Builder.createDebugValue(Loc, Value, DebugVar, PoisonRefs,
1704+
UsesMoveableValDebugInfo, HasTrace);
1705+
1706+
break;
1707+
}
16071708
case SILInstructionKind::AllocBoxInst: {
16081709
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
16091710
auto hasDynamicLifetime = HasDynamicLifetime_t(Attr & 0x1);

lib/Serialization/SILFormat.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,9 @@ namespace sil_block {
179179
SIL_DEBUG_SCOPE,
180180
SIL_DEBUG_SCOPE_REF,
181181
SIL_SOURCE_LOC,
182-
SIL_SOURCE_LOC_REF
182+
SIL_SOURCE_LOC_REF,
183+
SIL_DEBUG_VALUE_DELIMITER,
184+
SIL_DEBUG_VALUE,
183185
};
184186

185187
using SILInstNoOperandLayout = BCRecordLayout<
@@ -312,6 +314,19 @@ namespace sil_block {
312314
SILTypeCategoryField
313315
>;
314316

317+
using SILDebugValueLayout = BCRecordLayout<
318+
SIL_DEBUG_VALUE,
319+
320+
SILTypeCategoryField, // operand type category
321+
SILTypeCategoryField, // debug var type category
322+
BCFixed<11>,// poison, movableValueDebuginfo, trace, hasDebugVar, isLet, isDenseMapSingleton(two bits), hasSource, hasLoc, hasExpr
323+
BCArray<ValueIDField> // operand info: operand, type, debug var info: name, argno, optional stuff: typeid
324+
>;
325+
326+
using DebugValueDelimiterLayout = BCRecordLayout<
327+
SIL_DEBUG_VALUE_DELIMITER
328+
>;
329+
315330
using SourceLocLayout = BCRecordLayout<
316331
SIL_SOURCE_LOC,
317332
ValueIDField,

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,8 @@ void Serializer::writeBlockInfoBlock() {
962962
BLOCK_RECORD(sil_block, SIL_DEBUG_SCOPE_REF);
963963
BLOCK_RECORD(sil_block, SIL_SOURCE_LOC);
964964
BLOCK_RECORD(sil_block, SIL_SOURCE_LOC_REF);
965+
BLOCK_RECORD(sil_block, SIL_DEBUG_VALUE);
966+
BLOCK_RECORD(sil_block, SIL_DEBUG_VALUE_DELIMITER);
965967

966968

967969
BLOCK(SIL_INDEX_BLOCK);

lib/Serialization/SerializeSIL.cpp

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,102 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
974974
break;
975975
}
976976

977-
case SILInstructionKind::DebugValueInst:
977+
case SILInstructionKind::DebugValueInst: {
978+
if (!SerializeDebugInfoSIL)
979+
return;
980+
auto DVI = cast<DebugValueInst>(&SI);
981+
if (SI.getParent()->getParent()->getName().contains("sSTsE21_copySequenceContents12initializing8IteratorQz_SitSry7ElementQzG_tFSs8UTF8ViewV_Tgq5"))
982+
llvm::errs() << "HERE\n";
983+
unsigned attrs = unsigned(DVI->poisonRefs() & 0x1);
984+
attrs |= unsigned(DVI->usesMoveableValueDebugInfo()) << 1;
985+
attrs |= unsigned(DVI->hasTrace()) << 2;
986+
987+
auto Operand = DVI->getOperand();
988+
auto Type = Operand->getType();
989+
990+
unsigned DebugVarTypeCategory = 0;
991+
auto DebugVar = DVI->getVarInfo();
992+
const SILDebugScope *ScopeToWrite = nullptr;
993+
994+
auto &SM = SI.getFunction()->getModule().getSourceManager();
995+
996+
SmallVector<uint64_t, 8> ListOfValues;
997+
ListOfValues.push_back(addValueRef(Operand));
998+
ListOfValues.push_back(S.addTypeRef(Type.getRawASTType()));
999+
1000+
if (DebugVar) {
1001+
attrs |= 1 << 3; // has debug var
1002+
attrs |= DebugVar->isLet() << 4;
1003+
attrs |= DebugVar->isDenseMapSingleton << 5; // needs two bits
1004+
1005+
ListOfValues.push_back(S.addUniquedStringRef(DebugVar->Name));
1006+
ListOfValues.push_back(DebugVar->ArgNo);
1007+
1008+
if (DebugVar->Type.has_value()) {
1009+
attrs |= 1 << 7;
1010+
ListOfValues.push_back(S.addTypeRef(DebugVar->Type->getRawASTType()));
1011+
DebugVarTypeCategory = (unsigned)DebugVar->Type->getCategory();
1012+
}
1013+
1014+
if (DebugVar->Scope) {
1015+
attrs |= 1 << 8;
1016+
ScopeToWrite = DebugVar->Scope;
1017+
}
1018+
1019+
if (DebugVar->Loc) {
1020+
auto RawLoc = DebugVar->Loc.value();
1021+
SourceLoc Loc = RawLoc.getSourceLoc();
1022+
if (Loc.isValid()) {
1023+
attrs |= 1 << 9;
1024+
auto LC = SM.getPresumedLineAndColumnForLoc(Loc);
1025+
auto FName = SM.getDisplayNameForLoc(Loc);
1026+
auto FNameID = S.addUniquedStringRef(FName);
1027+
1028+
ListOfValues.push_back(LC.first);
1029+
ListOfValues.push_back(LC.second);
1030+
ListOfValues.push_back(FNameID);
1031+
}
1032+
}
1033+
1034+
for (auto &Expr : DebugVar->DIExpr.elements()) {
1035+
attrs |= 1 << 10;
1036+
ListOfValues.push_back(Expr.getKind());
1037+
switch (Expr.getKind()) {
1038+
case SILDIExprElement::Kind::OperatorKind:
1039+
ListOfValues.push_back((unsigned)Expr.getAsOperator());
1040+
break;
1041+
case SILDIExprElement::Kind::DeclKind:
1042+
ListOfValues.push_back(S.addDeclRef(Expr.getAsDecl()));
1043+
break;
1044+
case SILDIExprElement::Kind::ConstIntKind: {
1045+
llvm::SmallString<10> Str;
1046+
APInt(64, Expr.getAsConstInt().value()).toStringUnsigned(Str);
1047+
ListOfValues.push_back(S.addUniquedStringRef(Str));
1048+
break;
1049+
}
1050+
case SILDIExprElement::Kind::TypeKind:
1051+
ListOfValues.push_back(S.addTypeRef(Expr.getAsType()));
1052+
}
1053+
}
1054+
}
1055+
SILDebugValueLayout::emitRecord(
1056+
Out, ScratchRecord, SILAbbrCodes[SILDebugValueLayout::Code],
1057+
(unsigned)Type.getCategory(), DebugVarTypeCategory, attrs,
1058+
ListOfValues);
1059+
1060+
if (ScopeToWrite) {
1061+
assert(DebugVar->Scope->getInlinedFunction() == DVI->getDebugScope()->getInlinedFunction());
1062+
writeDebugScopes(ScopeToWrite, SM);
1063+
// Add a delimiter record since debug scope records are read by the
1064+
// deserializer in a loop until the first non debug scope record is
1065+
// found. As a result, the deserializer might read debug scopes of
1066+
// subsequent instructions while deserializing scopes for the current
1067+
// DebugValue instruction.
1068+
// TODO: Maybe add a bit to the debug scope layout to mark the ending.
1069+
DebugValueDelimiterLayout::emitRecord(Out, ScratchRecord, SILAbbrCodes[DebugValueDelimiterLayout::Code]);
1070+
}
1071+
break;
1072+
}
9781073
case SILInstructionKind::DebugStepInst:
9791074
// Currently we don't serialize debug info, so it doesn't make
9801075
// sense to write those instructions at all.
@@ -3439,10 +3534,12 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) {
34393534
registerSILAbbr<DefaultWitnessTableNoEntryLayout>();
34403535
registerSILAbbr<PropertyLayout>();
34413536
registerSILAbbr<DifferentiabilityWitnessLayout>();
3537+
registerSILAbbr<SILDebugValueLayout>();
34423538
registerSILAbbr<SILDebugScopeLayout>();
34433539
registerSILAbbr<SILDebugScopeRefLayout>();
34443540
registerSILAbbr<SourceLocLayout>();
34453541
registerSILAbbr<SourceLocRefLayout>();
3542+
registerSILAbbr<DebugValueDelimiterLayout>();
34463543

34473544
// Write out VTables first because it may require serializations of
34483545
// non-transparent SILFunctions (body is not needed).

0 commit comments

Comments
 (0)