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
28 changes: 27 additions & 1 deletion llvm/include/llvm/ProfileData/SampleProf.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ enum SecType {
SecFuncOffsetTable = 4,
SecFuncMetadata = 5,
SecCSNameTable = 6,
// Substitution to SecFuncOffsetTable when we have non-LBR profile types
SecTypifiedFuncOffsetTable = 7,
// marker for the first type of profile.
SecFuncProfileFirst = 32,
SecLBRProfile = SecFuncProfileFirst
SecLBRProfile = SecFuncProfileFirst,
// Substitution to SecLBRProfile when we have non-LBR profile types
SecTypifiedProfile = 33
};

static inline std::string getSecName(SecType Type) {
Expand All @@ -149,13 +153,20 @@ static inline std::string getSecName(SecType Type) {
return "FunctionMetadata";
case SecCSNameTable:
return "CSNameTableSection";
case SecTypifiedFuncOffsetTable:
return "TypifiedFuncOffsetTableSection";
case SecLBRProfile:
return "LBRProfileSection";
case SecTypifiedProfile:
return "TypifiedProfileSection";
default:
return "UnknownSection";
}
}

// Types of sample profile which can be placed in SecTypifiedProfile
enum ProfTypes { ProfTypeLBR = 0, ProfTypeNum };

// Entry type of section header table used by SampleProfileExtBinaryBaseReader
// and SampleProfileExtBinaryBaseWriter.
struct SecHdrTableEntry {
Expand Down Expand Up @@ -1341,6 +1352,12 @@ class FunctionSamples {
return !(*this == Other);
}

bool hasNonLBRSamples() const {
// Currently just a stub - should be implemented when
// first non-LBR profile is encountered.
return false;
}

private:
/// CFG hash value for the function.
uint64_t FunctionHash = 0;
Expand Down Expand Up @@ -1466,6 +1483,15 @@ class SampleProfileMap
size_t erase(const key_type &Key) { return base_type::erase(Key); }

iterator erase(iterator It) { return base_type::erase(It); }

bool hasNonLBRProfile() const {
for (const auto &[Context, FuncSamples] : *this) {
if (FuncSamples.hasNonLBRSamples()) {
return true;
}
}
return false;
}
};

using NameFunctionSamples = std::pair<hash_code, const FunctionSamples *>;
Expand Down
7 changes: 6 additions & 1 deletion llvm/include/llvm/ProfileData/SampleProfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ class SampleProfileReader {
FuncMetadataIndex;

std::pair<const uint8_t *, const uint8_t *> ProfileSecRange;
bool IsProfileTypified = false;

/// Whether the profile has attribute metadata.
bool ProfileHasAttribute = false;
Expand Down Expand Up @@ -685,7 +686,11 @@ class LLVM_ABI SampleProfileReaderBinary : public SampleProfileReader {
SampleProfileMap &Profiles);

/// Read the contents of the given profile instance.
std::error_code readProfile(FunctionSamples &FProfile);
std::error_code readProfile(FunctionSamples &FProfile, bool IsNested);

/// Read specific profile types.
std::error_code readLBRProfile(FunctionSamples &FProfile, bool IsNested);
std::error_code readTypifiedProfile(FunctionSamples &FProfile, bool IsNested);

/// Read the contents of Magic number and Version number.
std::error_code readMagicIdent();
Expand Down
19 changes: 18 additions & 1 deletion llvm/include/llvm/ProfileData/SampleProfWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,15 @@ class LLVM_ABI SampleProfileWriterBinary : public SampleProfileWriter {
std::error_code writeSummary();
virtual std::error_code writeContextIdx(const SampleContext &Context);
std::error_code writeNameIdx(FunctionId FName);
std::error_code writeBody(const FunctionSamples &S);
std::error_code writeBody(const FunctionSamples &S, bool IsNested);
void writeLBRProfile(const FunctionSamples &S, bool IsNested);

/// Interfaces for typified profile writing.
void writeTypifiedProfile(const FunctionSamples &S, bool IsNested);
std::pair<uint64_t, uint64_t> startProfileType(ProfTypes Type);
void finishProfileType(uint64_t SizeOffset, uint64_t BodyOffset);
void writeTypifiedLBRProfile(const FunctionSamples &S, bool IsNested);

inline void stablizeNameTable(MapVector<FunctionId, uint32_t> &NameTable,
std::set<FunctionId> &V);

Expand All @@ -230,6 +238,7 @@ class LLVM_ABI SampleProfileWriterBinary : public SampleProfileWriter {
raw_ostream &OS);

bool WriteVTableProf = false;
bool WriteTypifiedProf = false;

private:
LLVM_ABI friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
Expand Down Expand Up @@ -427,6 +436,9 @@ class LLVM_ABI SampleProfileWriterExtBinary

std::error_code writeSections(const SampleProfileMap &ProfileMap) override;

// Configure whether to use typified profile sections.
void configureTypifiedProfile(const SampleProfileMap &ProfileMap);

std::error_code writeCustomSection(SecType Type) override {
return sampleprof_error::success;
};
Expand All @@ -435,6 +447,11 @@ class LLVM_ABI SampleProfileWriterExtBinary
assert((SL == DefaultLayout || SL == CtxSplitLayout) &&
"Unsupported layout");
}

/// Section types for profile storage and bookkeeping (used to switch between
/// typified and non-typified profiles).
SecType ProfSection = SecLBRProfile;
SecType FuncOffsetSection = SecFuncOffsetTable;
};

} // end namespace sampleprof
Expand Down
77 changes: 69 additions & 8 deletions llvm/lib/ProfileData/SampleProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,14 @@ SampleProfileReaderBinary::readCallsiteVTableProf(FunctionSamples &FProfile) {
}

std::error_code
SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
SampleProfileReaderBinary::readLBRProfile(FunctionSamples &FProfile,
bool IsNested) {
if (IsProfileTypified && !IsNested) {
auto NumHeadSamples = readNumber<uint64_t>();
if (std::error_code EC = NumHeadSamples.getError())
return EC;
FProfile.addHeadSamples(*NumHeadSamples);
}
auto NumSamples = readNumber<uint64_t>();
if (std::error_code EC = NumSamples.getError())
return EC;
Expand Down Expand Up @@ -761,6 +768,54 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
FProfile.addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
}

return sampleprof_error::success;
}

std::error_code
SampleProfileReaderBinary::readTypifiedProfile(FunctionSamples &FProfile,
bool IsNested) {
// Read the number of profile types.
auto ProfNum = readNumber<uint64_t>();
if (std::error_code EC = ProfNum.getError())
return EC;

// read specified number of typified profiles
for (uint64_t i = 0; i < *ProfNum; i++) {
auto Type = readNumber<uint64_t>();
if (std::error_code EC = Type.getError())
return EC;
auto Size = readUnencodedNumber<uint64_t>();
if (std::error_code EC = Size.getError())
return EC;

switch (*Type) {
case ProfTypeLBR:
if (std::error_code EC = readLBRProfile(FProfile, IsNested))
return EC;
break;
default:
// skip unknown profile type for forward compatibility
Data += *Size;
if (Data > End)
return sampleprof_error::truncated;
break;
}
}

return sampleprof_error::success;
}

std::error_code
SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile,
bool IsNested) {
if (IsProfileTypified) {
if (std::error_code EC = readTypifiedProfile(FProfile, IsNested))
return EC;
} else {
if (std::error_code EC = readLBRProfile(FProfile, IsNested))
return EC;
}

// Read all the samples for inlined function calls.
auto NumCallsites = readNumber<uint32_t>();
if (std::error_code EC = NumCallsites.getError())
Expand All @@ -785,7 +840,7 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
LineLocation(*LineOffset, DiscriminatorVal))[*FName];
CalleeProfile.setFunction(*FName);
if (std::error_code EC = readProfile(CalleeProfile))
if (std::error_code EC = readProfile(CalleeProfile, true))
return EC;
}

Expand All @@ -799,10 +854,12 @@ std::error_code
SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start,
SampleProfileMap &Profiles) {
Data = Start;
auto NumHeadSamples = readNumber<uint64_t>();
if (std::error_code EC = NumHeadSamples.getError())
return EC;

ErrorOr<uint64_t> NumHeadSamples = 0;
if (!IsProfileTypified) {
NumHeadSamples = readNumber<uint64_t>();
if (std::error_code EC = NumHeadSamples.getError())
return EC;
}
auto FContextHash(readSampleContextFromTable());
if (std::error_code EC = FContextHash.getError())
return EC;
Expand All @@ -812,12 +869,13 @@ SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start,
auto Res = Profiles.try_emplace(Hash, FContext, FunctionSamples());
FunctionSamples &FProfile = Res.first->second;
FProfile.setContext(FContext);
FProfile.addHeadSamples(*NumHeadSamples);
if (!IsProfileTypified)
FProfile.addHeadSamples(*NumHeadSamples);

if (FContext.hasContext())
CSProfileCount++;

if (std::error_code EC = readProfile(FProfile))
if (std::error_code EC = readProfile(FProfile, false))
return EC;
return sampleprof_error::success;
}
Expand Down Expand Up @@ -876,11 +934,14 @@ std::error_code SampleProfileReaderExtBinaryBase::readOneSection(
break;
}
case SecLBRProfile:
case SecTypifiedProfile:
ProfileSecRange = std::make_pair(Data, End);
IsProfileTypified = Entry.Type == SecTypifiedProfile;
if (std::error_code EC = readFuncProfiles())
return EC;
break;
case SecFuncOffsetTable:
case SecTypifiedFuncOffsetTable:
// If module is absent, we are using LLVM tools, and need to read all
// profiles, so skip reading the function offset table.
if (!M) {
Expand Down
Loading
Loading