Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions llvm/include/llvm/CASObjectFormats/FlatV1.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLVM_CASOBJECTFORMATS_FLATV1_H
#define LLVM_CASOBJECTFORMATS_FLATV1_H

#include "llvm/ADT/StringMap.h"
#include "llvm/CAS/CASDB.h"
#include "llvm/CASObjectFormats/Data.h"
#include "llvm/CASObjectFormats/SchemaBase.h"
Expand Down Expand Up @@ -311,7 +312,8 @@ class CompileUnitBuilder {

CompileUnitBuilder(const ObjectFileSchema &Schema, Triple Target,
raw_ostream *DebugOS)
: CAS(Schema.CAS), Schema(Schema), TT(Target), DebugOS(DebugOS) {}
: CAS(Schema.CAS), Schema(Schema), TT(Target), DebugOS(DebugOS),
TargetInfoPool(TargetInfoAlloc) {}

Error createAndReferenceName(StringRef S);
Error createAndReferenceContent(StringRef Content);
Expand All @@ -328,6 +330,9 @@ class CompileUnitBuilder {
// Encode the index into compile unit.
void encodeIndex(unsigned Index);

// Encode a target info list and return the offset.
Expected<size_t> encodeTargetInfo(ArrayRef<const jitlink::Edge *> Edges);

private:
friend class CompileUnitRef;

Expand All @@ -349,6 +354,11 @@ class CompileUnitBuilder {
SmallVector<const jitlink::Block *, 16> Blocks;
std::vector<unsigned> BlockIndexStarts;

// TargetInfoList storage.
SmallString<256> FlatTargetInfo;
BumpPtrAllocator TargetInfoAlloc;
StringMap<uint32_t, BumpPtrAllocator> TargetInfoPool;

// Temp storage.
SmallString<256> InlineBuffer;
};
Expand Down Expand Up @@ -422,16 +432,19 @@ class LinkGraphBuilder {
struct BlockInfo {
jitlink::Block *Block;
Optional<BlockRef> Ref;
Optional<data::BlockData> Data;
Optional<data::FixupList> Fixups;
unsigned BlockIdx = 0;
unsigned Remaining = 0;
};

Expected<BlockInfo &> getBlockInfo(unsigned BlockIdx);

Error addSymbol(unsigned SymbolIdx, jitlink::Symbol *S);
Expected<jitlink::Symbol *> getSymbol(unsigned SymbolIdx);

/// Returns a list starting from \p Start, but that iterates past the end of
/// the edges.
data::TargetInfoList getTargetInfoFrom(unsigned Start);

private:
friend class CompileUnitRef;
std::string Name;
Expand All @@ -447,6 +460,9 @@ class LinkGraphBuilder {
unsigned SymbolsSize;
unsigned BlocksSize;

// Target info.
StringRef FlatTargetInfo;

// Lookup Cache.
SmallVector<SectionInfo, 16> Sections;
SmallVector<BlockInfo, 16> Blocks;
Expand Down
151 changes: 105 additions & 46 deletions llvm/lib/CASObjectFormats/FlatV1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,42 +293,107 @@ Expected<SectionRef> SectionRef::get(Expected<ObjectFormatNodeRef> Ref) {
return SectionRef(*Specific);
}

static Error encodeEdge(CompileUnitBuilder &CUB, SmallVectorImpl<char> &Data,
static Error encodeEdge(CompileUnitBuilder &CUB,
SmallVectorImpl<data::TargetInfo> &List,
const jitlink::Edge *E) {

auto SymbolIndex = CUB.getSymbolIndex(E->getTarget());
if (!SymbolIndex)
return SymbolIndex.takeError();
List.push_back({E->getAddend(), *SymbolIndex});
return Error::success();
}

static Error encodeEdges(CompileUnitBuilder &CUB,
ArrayRef<const jitlink::Edge *> Edges) {
assert(!Edges.empty() && "Expected edges");
bool HasAddends = false;
for (const jitlink::Edge *E : Edges)
if ((HasAddends = E->getAddend()))
break;

if (HasAddends) {
size_t Start;
if (Error Err = CUB.encodeTargetInfo(Edges).moveInto(Start))
return Err;
CUB.encodeIndex((Start << 1) | 1U);
return Error::success();
}

unsigned IdxAndHasAddend = *SymbolIndex << 1 | (E->getAddend() != 0);
CUB.encodeIndex(IdxAndHasAddend);
bool IsFirst = true;
for (const jitlink::Edge *E : Edges) {
auto SymbolIndex = CUB.getSymbolIndex(E->getTarget());
if (!SymbolIndex)
return SymbolIndex.takeError();

if (E->getAddend() != 0)
encoding::writeVBR8(E->getAddend(), Data);
// First symbol is left-shifted to differentiate from TargetInfo.
unsigned IndexToEncode = IsFirst ? *SymbolIndex << 1 : *SymbolIndex;
IsFirst = false;
CUB.encodeIndex(IndexToEncode);
}
return Error::success();
}

static Error decodeEdge(LinkGraphBuilder &LGB, StringRef &Data,
jitlink::Block &Parent, unsigned BlockIdx,
const data::Fixup &Fixup) {
unsigned SymbolIdx = LGB.nextIdxForBlock(BlockIdx);
Expected<size_t> CompileUnitBuilder::encodeTargetInfo(
ArrayRef<const jitlink::Edge *> Edges) {
SmallVector<data::TargetInfo> List;
for (const jitlink::Edge *E : Edges)
if (Error Err = encodeEdge(*this, List, E))
return std::move(Err);

bool HasAddend = SymbolIdx & 1U;
auto Symbol = LGB.getSymbol(SymbolIdx >> 1);
size_t Start = FlatTargetInfo.size();
data::TargetInfoList::encode(List, FlatTargetInfo);
size_t Length = FlatTargetInfo.size() - Start;
auto &MaybeExisting =
TargetInfoPool[StringRef(FlatTargetInfo).take_back(Length)];
if (MaybeExisting) {
// Truncate FlatTargetInfo again since this is already in the pool.
FlatTargetInfo.resize(Start);
Start = MaybeExisting - 1;
} else {
MaybeExisting = Start + 1;
}

return Start;
}

data::TargetInfoList LinkGraphBuilder::getTargetInfoFrom(unsigned Start) {
assert(Start < FlatTargetInfo.size() && "Start out of range");
return data::TargetInfoList(StringRef(FlatTargetInfo).drop_front(Start));
}

static Error decodeEdge(LinkGraphBuilder &LGB, jitlink::Block &Parent,
const data::TargetInfo &TI, const data::Fixup &Fixup) {
auto Symbol = LGB.getSymbol(TI.Index);
if (!Symbol)
return Symbol.takeError();

jitlink::Edge::AddendT Addend = 0;
if (HasAddend) {
if (auto E = encoding::consumeVBR8(Data, Addend))
return E;
}
auto BlockInfo = LGB.getBlockInfo(BlockIdx);
if (!BlockInfo)
return BlockInfo.takeError();
Parent.addEdge(Fixup.Kind, Fixup.Offset, **Symbol, TI.Addend);
return Error::success();
}

Parent.addEdge(Fixup.Kind, Fixup.Offset, **Symbol, Addend);
static Error decodeEdges(LinkGraphBuilder &LGB, jitlink::Block &Parent,
unsigned BlockIdx, const data::FixupList &FL) {
assert(!FL.empty() && "Expected edges");

unsigned TargetInfoIndex = LGB.nextIdxForBlock(BlockIdx);
if (TargetInfoIndex & 1U) {
unsigned TargetInfoStart = TargetInfoIndex >> 1;
data::TargetInfoList TIL(LGB.getTargetInfoFrom(TargetInfoStart));
data::TargetInfoList::iterator TI = TIL.begin();
for (data::Fixup Fixup : FL)
if (Error E = decodeEdge(LGB, Parent, *TI++, Fixup))
return E;
return Error::success();
}

// No addends.
bool IsFirst = true;
for (data::Fixup Fixup : FL) {
unsigned SymbolIndex = IsFirst ? TargetInfoIndex >> 1 : LGB.nextIdxForBlock(BlockIdx);
IsFirst = false;
if (Error Err = decodeEdge(LGB, Parent, data::TargetInfo{0, SymbolIndex}, Fixup))
return Err;
}
return Error::success();
}

Expand Down Expand Up @@ -390,23 +455,19 @@ Expected<BlockRef> BlockRef::create(CompileUnitBuilder &CUB,
if (auto E = CUB.createAndReferenceContent(BlockData))
return std::move(E);
} else {
encoding::writeVBR8(BlockData.size(), B->Data);
B->Data.append(BlockData);
}

for (const auto *E : Edges) {
// Nest the Edge in block.
if (auto Err = encodeEdge(CUB, B->Data, E))
if (!Edges.empty())
if (Error Err = encodeEdges(CUB, Edges))
return std::move(Err);
}

return get(B->build());
}

Error BlockRef::materializeBlock(LinkGraphBuilder &LGB,
unsigned BlockIdx) const {
uint64_t SectionIdx;
auto Remaining = getData();
SectionIdx = LGB.nextIdxForBlock(BlockIdx);

auto SectionInfo = LGB.getSectionInfo(SectionIdx);
Expand All @@ -420,21 +481,14 @@ Error BlockRef::materializeBlock(LinkGraphBuilder &LGB,
return ContentRef.takeError();
ContentData = ContentRef->getData();
} else {
unsigned ContentSize;
if (auto E = encoding::consumeVBR8(Remaining, ContentSize))
return E;
auto Data = consumeDataOfSize(Remaining, ContentSize);
if (!Data)
return Data.takeError();
ContentData = *Data;
ContentData = getData();
}

auto BlockInfo = LGB.getBlockInfo(BlockIdx);
if (!BlockInfo)
return BlockInfo.takeError();

BlockInfo->Data.emplace(ContentData);
auto &Block = *BlockInfo->Data;
data::BlockData Block(ContentData);
auto Address =
getAlignedAddress(*SectionInfo, Block.getSize(), Block.getAlignment(),
Block.getAlignmentOffset());
Expand All @@ -447,7 +501,7 @@ Error BlockRef::materializeBlock(LinkGraphBuilder &LGB,
Block.getAlignment(), Block.getAlignmentOffset());

BlockInfo->Block = &B;
BlockInfo->Remaining = Remaining.size();
BlockInfo->Fixups = Block.getFixups();
return Error::success();
}

Expand All @@ -458,17 +512,10 @@ Error BlockRef::materializeEdges(LinkGraphBuilder &LGB,
return BlockInfo.takeError();

// Nothing remains, no edges.
if (!BlockInfo->Remaining)
if (BlockInfo->Fixups->empty())
return Error::success();

auto Remaining = getData().take_back(BlockInfo->Remaining);
for (const data::Fixup &Fixup : BlockInfo->Data->getFixups()) {
if (Error Err =
decodeEdge(LGB, Remaining, *BlockInfo->Block, BlockIdx, Fixup))
return Err;
}

return Error::success();
return decodeEdges(LGB, *BlockInfo->Block, BlockIdx, *BlockInfo->Fixups);
}

Expected<BlockRef> BlockRef::get(Expected<ObjectFormatNodeRef> Ref) {
Expand Down Expand Up @@ -844,6 +891,10 @@ Expected<CompileUnitRef> CompileUnitRef::create(const ObjectFileSchema &Schema,
for (auto Idx : Builder.BlockIndexStarts)
encoding::writeVBR8(Idx, B->Data);

/// Write the flat TargetInfoList data.
encoding::writeVBR8(Builder.FlatTargetInfo.size(), B->Data);
B->Data.append(Builder.FlatTargetInfo);

// Inlined symbols if set.
if (InlineSymbols)
B->Data.append(Builder.InlineBuffer);
Expand Down Expand Up @@ -914,6 +965,14 @@ Error CompileUnitRef::materialize(LinkGraphBuilder &LGB) const {
LGB.Blocks[I].BlockIdx = Idx;
}

/// Write the flat TargetInfoList data.
size_t FlatTargetInfoSize;
if (Error Err = encoding::consumeVBR8(Remaining, FlatTargetInfoSize))
return Err;
if (Error Err = consumeDataOfSize(Remaining, FlatTargetInfoSize)
.moveInto(LGB.FlatTargetInfo))
return Err;

if (InlineSymbols)
LGB.InlineBuffer = Remaining;
else if (!Remaining.empty())
Expand Down