Skip to content

[BOLT][NFC] Disambiguate sample as basic sample #139350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
10 changes: 5 additions & 5 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ class BinaryFunction {
/// Types of profile the function can use. Could be a combination.
enum {
PF_NONE = 0, /// No profile.
PF_LBR = 1, /// Profile is based on last branch records.
PF_SAMPLE = 2, /// Non-LBR sample-based profile.
PF_BRANCH = 1, /// Profile is based on branches or branch stacks.
PF_BASIC = 2, /// Non-branch IP sample-based profile.
PF_MEMEVENT = 4, /// Profile has mem events.
};

Expand Down Expand Up @@ -392,7 +392,7 @@ class BinaryFunction {
float ProfileMatchRatio{0.0f};

/// Raw branch count for this function in the profile.
uint64_t RawBranchCount{0};
uint64_t RawSampleCount{0};

/// Dynamically executed function bytes, used for density computation.
uint64_t SampleCountInBytes{0};
Expand Down Expand Up @@ -1893,11 +1893,11 @@ class BinaryFunction {

/// Return the raw profile information about the number of branch
/// executions corresponding to this function.
uint64_t getRawBranchCount() const { return RawBranchCount; }
uint64_t getRawSampleCount() const { return RawSampleCount; }

/// Set the profile data about the number of branch executions corresponding
/// to this function.
void setRawBranchCount(uint64_t Count) { RawBranchCount = Count; }
void setRawSampleCount(uint64_t Count) { RawSampleCount = Count; }

/// Return the number of dynamically executed bytes, from raw perf data.
uint64_t getSampleCountInBytes() const { return SampleCountInBytes; }
Expand Down
3 changes: 2 additions & 1 deletion bolt/include/bolt/Profile/DataAggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ class DataAggregator : public DataReader {

/// Semantic actions - parser hooks to interpret parsed perf samples
/// Register a sample (non-LBR mode), i.e. a new hit at \p Address
bool doSample(BinaryFunction &Func, const uint64_t Address, uint64_t Count);
bool doBasicSample(BinaryFunction &Func, const uint64_t Address,
uint64_t Count);

/// Register an intraprocedural branch \p Branch.
bool doIntraBranch(BinaryFunction &Func, uint64_t From, uint64_t To,
Expand Down
28 changes: 15 additions & 13 deletions bolt/include/bolt/Profile/DataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,16 @@ struct FuncMemData {
/// Similar to BranchInfo, but instead of recording from-to address (an edge),
/// it records the address of a perf event and the number of times samples hit
/// this address.
struct SampleInfo {
struct BasicSampleInfo {
Location Loc;
int64_t Hits;

SampleInfo(Location Loc, int64_t Hits) : Loc(std::move(Loc)), Hits(Hits) {}
BasicSampleInfo(Location Loc, int64_t Hits)
: Loc(std::move(Loc)), Hits(Hits) {}

bool operator==(const SampleInfo &RHS) const { return Loc == RHS.Loc; }
bool operator==(const BasicSampleInfo &RHS) const { return Loc == RHS.Loc; }

bool operator<(const SampleInfo &RHS) const {
bool operator<(const BasicSampleInfo &RHS) const {
if (Loc < RHS.Loc)
return true;

Expand All @@ -229,18 +230,18 @@ struct SampleInfo {

void print(raw_ostream &OS) const;

void mergeWith(const SampleInfo &SI);
void mergeWith(const BasicSampleInfo &SI);
};

/// Helper class to store samples recorded in the address space of a given
/// function, analogous to FuncBranchData but for samples instead of branches.
struct FuncSampleData {
typedef std::vector<SampleInfo> ContainerTy;
struct FuncBasicSampleData {
typedef std::vector<BasicSampleInfo> ContainerTy;

StringRef Name;
ContainerTy Data;

FuncSampleData(StringRef Name, ContainerTy Data)
FuncBasicSampleData(StringRef Name, ContainerTy Data)
: Name(Name), Data(std::move(Data)) {}

/// Get the number of samples recorded in [Start, End)
Expand Down Expand Up @@ -308,7 +309,7 @@ class DataReader : public ProfileReaderBase {
/// The last step is to infer edge counts based on BB execution count. Note
/// this is the opposite of the LBR way, where we infer BB execution count
/// based on edge counts.
void readSampleData(BinaryFunction &BF);
void readBasicSampleData(BinaryFunction &BF);

/// Convert function-level branch data into instruction annotations.
void convertBranchData(BinaryFunction &BF) const;
Expand Down Expand Up @@ -382,7 +383,8 @@ class DataReader : public ProfileReaderBase {
/// Return mem data matching one of the names in \p FuncNames.
FuncMemData *getMemDataForNames(const std::vector<StringRef> &FuncNames);

FuncSampleData *getFuncSampleData(const std::vector<StringRef> &FuncNames);
FuncBasicSampleData *
getFuncBasicSampleData(const std::vector<StringRef> &FuncNames);

/// Return a vector of all FuncBranchData matching the list of names.
/// Internally use fuzzy matching to match special names like LTO-generated
Expand Down Expand Up @@ -425,7 +427,7 @@ class DataReader : public ProfileReaderBase {
}

using NamesToBranchesMapTy = std::map<StringRef, FuncBranchData>;
using NamesToSamplesMapTy = std::map<StringRef, FuncSampleData>;
using NamesToBasicSamplesMapTy = std::map<StringRef, FuncBasicSampleData>;
using NamesToMemEventsMapTy = std::map<StringRef, FuncMemData>;
using FuncsToBranchesMapTy =
std::unordered_map<const BinaryFunction *, FuncBranchData *>;
Expand Down Expand Up @@ -474,7 +476,7 @@ class DataReader : public ProfileReaderBase {
return parseLocation(EndChar, EndNl, true);
}
ErrorOr<BranchInfo> parseBranchInfo();
ErrorOr<SampleInfo> parseSampleInfo();
ErrorOr<BasicSampleInfo> parseSampleInfo();
ErrorOr<MemInfo> parseMemInfo();
ErrorOr<bool> maybeParseNoLBRFlag();
ErrorOr<bool> maybeParseBATFlag();
Expand All @@ -488,7 +490,7 @@ class DataReader : public ProfileReaderBase {
unsigned Line{0};
unsigned Col{0};
NamesToBranchesMapTy NamesToBranches;
NamesToSamplesMapTy NamesToSamples;
NamesToBasicSamplesMapTy NamesToBasicSamples;
NamesToMemEventsMapTy NamesToMemEvents;
FuncsToBranchesMapTy FuncsToBranches;
FuncsToMemDataMapTy FuncsToMemData;
Expand Down
4 changes: 2 additions & 2 deletions bolt/include/bolt/Profile/ProfileYAMLMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ LLVM_YAML_STRONG_TYPEDEF(uint16_t, PROFILE_PF)

template <> struct ScalarBitSetTraits<PROFILE_PF> {
static void bitset(IO &io, PROFILE_PF &value) {
io.bitSetCase(value, "lbr", BinaryFunction::PF_LBR);
io.bitSetCase(value, "sample", BinaryFunction::PF_SAMPLE);
io.bitSetCase(value, "lbr", BinaryFunction::PF_BRANCH);
io.bitSetCase(value, "sample", BinaryFunction::PF_BASIC);
io.bitSetCase(value, "memevent", BinaryFunction::PF_MEMEVENT);
}
};
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) {
OS << "\n Image : 0x" << Twine::utohexstr(getImageAddress());
if (ExecutionCount != COUNT_NO_PROFILE) {
OS << "\n Exec Count : " << ExecutionCount;
OS << "\n Branch Count: " << RawBranchCount;
OS << "\n Sample Count: " << RawSampleCount;
OS << "\n Profile Acc : " << format("%.1f%%", ProfileMatchRatio * 100.0f);
}

Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Core/BinaryFunctionProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void BinaryFunction::postProcessProfile() {
return;
}

if (!(getProfileFlags() & PF_LBR))
if (!(getProfileFlags() & PF_BRANCH))
return;

// If we have at least some branch data for the function indicate that it
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Passes/BinaryPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1445,7 +1445,7 @@ Error PrintProgramStats::runOnFunctions(BinaryContext &BC) {
if (!Function.hasProfile())
continue;

uint64_t SampleCount = Function.getRawBranchCount();
uint64_t SampleCount = Function.getRawSampleCount();
TotalSampleCount += SampleCount;

if (Function.hasValidProfile()) {
Expand Down
4 changes: 2 additions & 2 deletions bolt/lib/Passes/MCF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,15 +458,15 @@ void EstimateEdgeCounts::runOnFunction(BinaryFunction &BF) {
Error EstimateEdgeCounts::runOnFunctions(BinaryContext &BC) {
if (llvm::none_of(llvm::make_second_range(BC.getBinaryFunctions()),
[](const BinaryFunction &BF) {
return BF.getProfileFlags() == BinaryFunction::PF_SAMPLE;
return BF.getProfileFlags() == BinaryFunction::PF_BASIC;
}))
return Error::success();

ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
runOnFunction(BF);
};
ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
return BF.getProfileFlags() != BinaryFunction::PF_SAMPLE;
return BF.getProfileFlags() != BinaryFunction::PF_BASIC;
};

ParallelUtilities::runOnEachFunction(
Expand Down
37 changes: 19 additions & 18 deletions bolt/lib/Profile/DataAggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,11 +568,12 @@ void DataAggregator::processProfile(BinaryContext &BC) {
for (auto &BFI : BC.getBinaryFunctions()) {
BinaryFunction &BF = BFI.second;
if (FuncBranchData *FBD = getBranchData(BF)) {
BF.markProfiled(BinaryFunction::PF_LBR);
BF.RawBranchCount = FBD->getNumExecutedBranches();
} else if (FuncSampleData *FSD = getFuncSampleData(BF.getNames())) {
BF.markProfiled(BinaryFunction::PF_SAMPLE);
BF.RawBranchCount = FSD->getSamples();
BF.markProfiled(BinaryFunction::PF_BRANCH);
BF.RawSampleCount = FBD->getNumExecutedBranches();
} else if (FuncBasicSampleData *FSD =
getFuncBasicSampleData(BF.getNames())) {
BF.markProfiled(BinaryFunction::PF_BASIC);
BF.RawSampleCount = FSD->getSamples();
}
}

Expand Down Expand Up @@ -627,8 +628,8 @@ StringRef DataAggregator::getLocationName(const BinaryFunction &Func,
return OrigFunc->getOneName();
}

bool DataAggregator::doSample(BinaryFunction &OrigFunc, uint64_t Address,
uint64_t Count) {
bool DataAggregator::doBasicSample(BinaryFunction &OrigFunc, uint64_t Address,
uint64_t Count) {
// To record executed bytes, use basic block size as is regardless of BAT.
uint64_t BlockSize = 0;
if (BinaryBasicBlock *BB = OrigFunc.getBasicBlockContainingOffset(
Expand All @@ -642,13 +643,13 @@ bool DataAggregator::doSample(BinaryFunction &OrigFunc, uint64_t Address,
// Attach executed bytes to parent function in case of cold fragment.
Func.SampleCountInBytes += Count * BlockSize;

auto I = NamesToSamples.find(Func.getOneName());
if (I == NamesToSamples.end()) {
auto I = NamesToBasicSamples.find(Func.getOneName());
if (I == NamesToBasicSamples.end()) {
bool Success;
StringRef LocName = getLocationName(Func, BAT);
std::tie(I, Success) = NamesToSamples.insert(
std::make_pair(Func.getOneName(),
FuncSampleData(LocName, FuncSampleData::ContainerTy())));
std::tie(I, Success) = NamesToBasicSamples.insert(std::make_pair(
Func.getOneName(),
FuncBasicSampleData(LocName, FuncBasicSampleData::ContainerTy())));
}

Address -= Func.getAddress();
Expand Down Expand Up @@ -1661,7 +1662,7 @@ void DataAggregator::processBasicEvents() {
continue;
}

doSample(*Func, PC, HitCount);
doBasicSample(*Func, PC, HitCount);
}
outs() << "PERF2BOLT: read " << NumTotalSamples << " samples\n";

Expand Down Expand Up @@ -2192,9 +2193,9 @@ DataAggregator::writeAggregatedFile(StringRef OutputFilename) const {
OutFile << " " << Entry.getKey();
OutFile << "\n";

for (const auto &KV : NamesToSamples) {
const FuncSampleData &FSD = KV.second;
for (const SampleInfo &SI : FSD.Data) {
for (const auto &KV : NamesToBasicSamples) {
const FuncBasicSampleData &FSD = KV.second;
for (const BasicSampleInfo &SI : FSD.Data) {
writeLocation(SI.Loc);
OutFile << SI.Hits << "\n";
++BranchValues;
Expand Down Expand Up @@ -2267,8 +2268,8 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
for (const StringMapEntry<std::nullopt_t> &EventEntry : EventNames)
EventNamesOS << LS << EventEntry.first().str();

BP.Header.Flags = opts::BasicAggregation ? BinaryFunction::PF_SAMPLE
: BinaryFunction::PF_LBR;
BP.Header.Flags = opts::BasicAggregation ? BinaryFunction::PF_BASIC
: BinaryFunction::PF_BRANCH;

// Add probe inline tree nodes.
YAMLProfileWriter::InlineTreeDesc InlineTree;
Expand Down
Loading
Loading