Skip to content

Commit b4b1103

Browse files
Split up debug info and debug abbrev section in the flatv1 schema, and add options to control which debug information blocks to split
1 parent 45ea52e commit b4b1103

File tree

11 files changed

+415
-46
lines changed

11 files changed

+415
-46
lines changed

llvm/include/llvm/CASObjectFormats/Data.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ class BlockData {
124124
/// \p Fixups add no storage cost if they are not used.
125125
static void encode(uint64_t Size, uint64_t Alignment,
126126
uint64_t AlignmentOffset, Optional<StringRef> Content,
127-
ArrayRef<Fixup> Fixups, SmallVectorImpl<char> &Data);
127+
ArrayRef<Fixup> Fixups, SmallVectorImpl<char> &Data,
128+
bool IsDebugInfoBlock = false);
128129

129130
Error decode(uint64_t &Size, uint64_t &Alignment, uint64_t &AlignmentOffset,
130131
Optional<StringRef> &Content, FixupList &Fixups) const;

llvm/include/llvm/CASObjectFormats/FlatV1.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ class BlockRef : public SpecificRef<BlockRef> {
208208
static constexpr StringLiteral KindString = "cas.o:block";
209209

210210
static Expected<BlockRef> create(CompileUnitBuilder &CUB,
211-
const jitlink::Block &Block);
211+
const jitlink::Block &Block,
212+
cas::CASID *AbbrevID = nullptr);
212213

213214
static Expected<BlockRef> get(Expected<ObjectFormatObjectProxy> Ref);
214215
static Expected<BlockRef> get(const ObjectFileSchema &Schema,
@@ -313,6 +314,8 @@ class CompileUnitBuilder {
313314

314315
Error createSection(const jitlink::Section &S);
315316
Error createBlock(const jitlink::Block &B);
317+
Expected<cas::CASID> createAbbrevBlock(const jitlink::Block &B);
318+
Error createInfoBlock(const jitlink::Block &B, cas::CASID *AbbrevID);
316319
Error createSymbol(const jitlink::Symbol &S);
317320

318321
// Lookup functions. The result must exist in the cache already.

llvm/include/llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ namespace jitlink {
2121
class DWARFRecordSectionSplitter {
2222
public:
2323
DWARFRecordSectionSplitter(StringRef SectionName);
24-
Error operator()(LinkGraph &G);
24+
Error operator()(LinkGraph &G,
25+
std::vector<uint64_t> *AbbrevOffsets = nullptr);
2526

2627
private:
27-
Error processBlock(LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache);
28+
Error processBlock(LinkGraph &G, Block &B);
29+
Error processDebugInfoBlock(LinkGraph &G, Block &B,
30+
std::vector<uint64_t> *AbbrevOffsets);
31+
Error processDebugAbbrevBlock(LinkGraph &G, Block &B,
32+
std::vector<uint64_t> *AbbrevOffsets);
2833

2934
StringRef SectionName;
3035
};

llvm/lib/CASObjectFormats/Data.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ void FixupList::iterator::decode(bool IsInit) {
6060

6161
void BlockData::encode(uint64_t Size, uint64_t Alignment,
6262
uint64_t AlignmentOffset, Optional<StringRef> Content,
63-
ArrayRef<Fixup> Fixups, SmallVectorImpl<char> &Data) {
63+
ArrayRef<Fixup> Fixups, SmallVectorImpl<char> &Data,
64+
bool IsDebugInfoBlock) {
6465
assert(!Content || Size == Content->size() && "Mismatched content size");
6566
assert(Alignment && "Expected non-zero alignment");
6667
assert(isPowerOf2_64(Alignment) && "Expected alignment to be a power of 2");
@@ -81,8 +82,48 @@ void BlockData::encode(uint64_t Size, uint64_t Alignment,
8182
(unsigned(IsZeroFill) << IsZeroFillBit));
8283

8384
encoding::writeVBR8(Size, Data);
84-
if (Content)
85-
Data.append(Content->begin(), Content->end());
85+
if (Content) {
86+
if (!IsDebugInfoBlock) {
87+
Data.append(Content->begin(), Content->end());
88+
} else {
89+
// This is a debug info block, the abbreviation offset can cause
90+
// deduplication to fail, handle it here.
91+
StringRef SizeOfUnit = Content->substr(0, 4);
92+
unsigned SizeOfUnitInt = 0;
93+
SizeOfUnitInt |= SizeOfUnit[3];
94+
SizeOfUnitInt <<= 8;
95+
SizeOfUnitInt |= SizeOfUnit[2];
96+
SizeOfUnitInt <<= 8;
97+
SizeOfUnitInt |= SizeOfUnit[1];
98+
SizeOfUnitInt <<= 8;
99+
SizeOfUnitInt |= SizeOfUnit[0];
100+
if (SizeOfUnitInt != 0xffffffff) {
101+
// This is a 32-bit DWARF format, copy the first 6 bytes for size and
102+
// DWARF version, skip the next 4 bytes and copy 0's, then copy the
103+
// rest.
104+
Data.append(Content->begin(), Content->begin() + 6);
105+
Data.push_back(0);
106+
Data.push_back(0);
107+
Data.push_back(0);
108+
Data.push_back(0);
109+
Data.append(Content->begin() + 10, Content->end());
110+
} else {
111+
// This is a 64-bit DWARF format, copy the first 16 bytes for size,
112+
// DWARF version, unit type, and address size, skip the next 8 bytes and
113+
// copy 0's, then copy the rest.
114+
Data.append(Content->begin(), Content->begin() + 16);
115+
Data.push_back(0);
116+
Data.push_back(0);
117+
Data.push_back(0);
118+
Data.push_back(0);
119+
Data.push_back(0);
120+
Data.push_back(0);
121+
Data.push_back(0);
122+
Data.push_back(0);
123+
Data.append(Content->begin() + 24, Content->end());
124+
}
125+
}
126+
}
86127
FixupList::encode(Fixups, Data);
87128

88129
if (!HasAlignmentOffset)

llvm/lib/CASObjectFormats/FlatV1.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,20 @@ static Error decodeFixup(const FlatV1ObjectReader &Reader, StringRef &Data,
321321
}
322322

323323
Expected<BlockRef> BlockRef::create(CompileUnitBuilder &CUB,
324-
const jitlink::Block &Block) {
324+
const jitlink::Block &Block,
325+
cas::CASID *AbbrevID) {
325326
Expected<Builder> B = Builder::startNode(CUB.Schema, KindString);
326327
if (!B)
327328
return B.takeError();
328329

330+
bool IsDebugInfoBlock = false;
331+
// If we are creating a cas block out of a debug_info jitlink::Block, add the
332+
// debug_abbrev cas block CAS ID as a refrence
333+
if (Block.getSection().getName() == "__DWARF,__debug_info") {
334+
B->IDs.push_back(*AbbrevID);
335+
IsDebugInfoBlock = true;
336+
}
337+
329338
// Encode Section.
330339
auto SectionIndex = CUB.getSectionIndex(Block.getSection());
331340
if (!SectionIndex)
@@ -366,11 +375,10 @@ Expected<BlockRef> BlockRef::create(CompileUnitBuilder &CUB,
366375
return std::move(E);
367376
BlockSize = Content->size();
368377
}
369-
370378
SmallString<1024> EncodeContent;
371379
data::BlockData::encode(BlockSize, Block.getAlignment(),
372380
Block.getAlignmentOffset(), Content, Fixups,
373-
EncodeContent);
381+
EncodeContent, IsDebugInfoBlock);
374382

375383
StringRef BlockData(EncodeContent);
376384
// Encode content first with size and data.
@@ -689,12 +697,37 @@ Error CompileUnitBuilder::createSection(const jitlink::Section &S) {
689697
}
690698

691699
Error CompileUnitBuilder::createBlock(const jitlink::Block &B) {
700+
if (B.getSection().getName() == "__DWARF,__debug_abbrev" ||
701+
B.getSection().getName() == "__DWARF,__debug_info")
702+
return Error::success();
703+
// Store the current idx. It is created in order so just add in the end.
704+
BlockIndexStarts.push_back(Indexes.size());
705+
auto Block = BlockRef::create(*this, B);
706+
if (!Block)
707+
return Block.takeError();
708+
commitNode(*Block);
709+
return Error::success();
710+
}
711+
712+
Expected<cas::CASID>
713+
CompileUnitBuilder::createAbbrevBlock(const jitlink::Block &B) {
692714
// Store the current idx. It is created in order so just add in the end.
693715
BlockIndexStarts.push_back(Indexes.size());
694716
auto Block = BlockRef::create(*this, B);
695717
if (!Block)
696718
return Block.takeError();
697719
commitNode(*Block);
720+
return Block->getID();
721+
}
722+
723+
Error CompileUnitBuilder::createInfoBlock(const jitlink::Block &B,
724+
cas::CASID *AbbrevID) {
725+
// Store the current idx. It is created in order so just add in the end.
726+
BlockIndexStarts.push_back(Indexes.size());
727+
auto Block = BlockRef::create(*this, B, AbbrevID);
728+
if (!Block)
729+
return Block.takeError();
730+
commitNode(*Block);
698731
return Error::success();
699732
}
700733

@@ -792,8 +825,24 @@ Expected<CompileUnitRef> CompileUnitRef::create(const ObjectFileSchema &Schema,
792825
llvm::sort(Builder.Blocks.begin() + PreviousSize, Builder.Blocks.end(),
793826
compareBlocksByAddress);
794827
};
795-
for (const jitlink::Section &Section : G.sections())
828+
SmallVector<const jitlink::Block *, 16> AbbrevBlocks;
829+
SmallVector<const jitlink::Block *, 16> InfoBlocks;
830+
for (const jitlink::Section &Section : G.sections()) {
831+
if (Section.getName() == "__DWARF,__debug_abbrev")
832+
AbbrevBlocks.append(Section.blocks().begin(), Section.blocks().end());
833+
else if (Section.getName() == "__DWARF,__debug_info")
834+
InfoBlocks.append(Section.blocks().begin(), Section.blocks().end());
796835
appendBlocks(Section.blocks());
836+
}
837+
// If the number of debug_abbrev blocks are 1, we assume that the
838+
// abbreviations could not be split up, and every debug_info compile unit
839+
// should have a reference to the same abbreviation.
840+
assert(AbbrevBlocks.size() == 1 ||
841+
AbbrevBlocks.size() == InfoBlocks.size() &&
842+
"The number of Abbreviation contributions should be equal to the "
843+
"number of Compile Units");
844+
llvm::sort(InfoBlocks.begin(), InfoBlocks.end(), compareBlocksByAddress);
845+
llvm::sort(AbbrevBlocks.begin(), AbbrevBlocks.end(), compareBlocksByAddress);
797846

798847
#ifndef NDEBUG
799848
for (auto *S : makeArrayRef(Symbols).slice(0, DefinedSymbolsSize))
@@ -815,6 +864,22 @@ Expected<CompileUnitRef> CompileUnitRef::create(const ObjectFileSchema &Schema,
815864
return std::move(E);
816865
}
817866

867+
// Create BlockRefs for Abbrevs and Compile Units
868+
SmallVector<cas::CASID, 16> AbbrevIDs;
869+
for (auto *B : AbbrevBlocks) {
870+
Expected<cas::CASID> ID = Builder.createAbbrevBlock(*B);
871+
if (!ID)
872+
return ID.takeError();
873+
AbbrevIDs.push_back(*ID);
874+
}
875+
unsigned I = 0;
876+
for (auto *B : InfoBlocks) {
877+
if (auto E = Builder.createInfoBlock(
878+
*B, AbbrevIDs.size() == 1 ? &AbbrevIDs[0] : &AbbrevIDs[I]))
879+
return std::move(E);
880+
I++;
881+
}
882+
818883
auto B = Builder::startRootNode(Schema, KindString);
819884
if (!B)
820885
return B.takeError();

0 commit comments

Comments
 (0)