Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 2 additions & 3 deletions bolt/include/bolt/Core/BinaryBasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ class BinaryBasicBlock {
uint64_t MispredictedCount; /// number of branches mispredicted

bool operator<(const BinaryBranchInfo &Other) const {
return (Count < Other.Count) ||
(Count == Other.Count &&
MispredictedCount < Other.MispredictedCount);
return std::tie(Count, MispredictedCount) <
std::tie(Other.Count, Other.MispredictedCount);
}
};

Expand Down
12 changes: 12 additions & 0 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,10 @@ class BinaryFunction {
/// The profile data for the number of times the function was executed.
uint64_t ExecutionCount{COUNT_NO_PROFILE};

/// Profile data for the number of times this function was entered from
/// external code (DSO, JIT, etc).
uint64_t ExternEntryCount{0};

/// Profile match ratio.
float ProfileMatchRatio{0.0f};

Expand Down Expand Up @@ -1877,6 +1881,10 @@ class BinaryFunction {
return *this;
}

/// Set the profile data for the number of times the function was entered from
/// external code (DSO/JIT).
void setExternEntryCount(uint64_t Count) { ExternEntryCount = Count; }

/// Adjust execution count for the function by a given \p Count. The value
/// \p Count will be subtracted from the current function count.
///
Expand Down Expand Up @@ -1904,6 +1912,10 @@ class BinaryFunction {
/// Return COUNT_NO_PROFILE if there's no profile info.
uint64_t getExecutionCount() const { return ExecutionCount; }

/// Return the profile information about the number of times the function was
/// entered from external code (DSO/JIT).
uint64_t getExternEntryCount() const { return ExternEntryCount; }

/// Return the raw profile information about the number of branch
/// executions corresponding to this function.
uint64_t getRawSampleCount() const { return RawSampleCount; }
Expand Down
2 changes: 1 addition & 1 deletion bolt/include/bolt/Core/MCPlusBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ class MCPlusBuilder {

bool equals(const MCExpr &A, const MCExpr &B, CompFuncTy Comp) const;

virtual bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
virtual bool equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
CompFuncTy Comp) const;

virtual bool isBranch(const MCInst &Inst) const {
Expand Down
4 changes: 1 addition & 3 deletions bolt/include/bolt/Passes/PAuthGadgetScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ struct MCInstInBFReference {
return BF == RHS.BF && Offset == RHS.Offset;
}
bool operator<(const MCInstInBFReference &RHS) const {
if (BF != RHS.BF)
return BF < RHS.BF;
return Offset < RHS.Offset;
return std::tie(BF, Offset) < std::tie(RHS.BF, RHS.Offset);
}
operator MCInst &() const {
assert(BF != nullptr);
Expand Down
14 changes: 13 additions & 1 deletion bolt/include/bolt/Profile/DataAggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ class DataAggregator : public DataReader {
static bool checkPerfDataMagic(StringRef FileName);

private:
struct LBREntry {
uint64_t From;
uint64_t To;
bool Mispred;
};
friend raw_ostream &operator<<(raw_ostream &OS, const LBREntry &);

struct PerfBranchSample {
SmallVector<LBREntry, 32> LBR;
};
Expand Down Expand Up @@ -476,7 +483,6 @@ class DataAggregator : public DataReader {

/// Debugging dump methods
void dump() const;
void dump(const LBREntry &LBR) const;
void dump(const PerfBranchSample &Sample) const;
void dump(const PerfMemSample &Sample) const;

Expand Down Expand Up @@ -504,6 +510,12 @@ class DataAggregator : public DataReader {

friend class YAMLProfileWriter;
};

inline raw_ostream &operator<<(raw_ostream &OS,
const DataAggregator::LBREntry &L) {
OS << formatv("{0:x} -> {1:x}/{2}", L.From, L.To, L.Mispred ? 'M' : 'P');
return OS;
}
} // namespace bolt
} // namespace llvm

Expand Down
15 changes: 3 additions & 12 deletions bolt/include/bolt/Profile/DataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,6 @@ namespace bolt {

class BinaryFunction;

struct LBREntry {
uint64_t From;
uint64_t To;
bool Mispred;
};

inline raw_ostream &operator<<(raw_ostream &OS, const LBREntry &LBR) {
OS << "0x" << Twine::utohexstr(LBR.From) << " -> 0x"
<< Twine::utohexstr(LBR.To);
return OS;
}

struct Location {
bool IsSymbol;
StringRef Name;
Expand Down Expand Up @@ -109,6 +97,9 @@ struct FuncBranchData {
/// Total execution count for the function.
int64_t ExecutionCount{0};

/// Total entry count from external code for the function.
uint64_t ExternEntryCount{0};

/// Indicate if the data was used.
bool Used{false};

Expand Down
2 changes: 2 additions & 0 deletions bolt/include/bolt/Profile/ProfileYAMLMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ struct BinaryFunctionProfile {
uint32_t Id{0};
llvm::yaml::Hex64 Hash{0};
uint64_t ExecCount{0};
uint64_t ExternEntryCount{0};
std::vector<BinaryBasicBlockProfile> Blocks;
std::vector<InlineTreeNode> InlineTree;
bool Used{false};
Expand All @@ -218,6 +219,7 @@ template <> struct MappingTraits<bolt::BinaryFunctionProfile> {
YamlIO.mapRequired("fid", BFP.Id);
YamlIO.mapRequired("hash", BFP.Hash);
YamlIO.mapRequired("exec", BFP.ExecCount);
YamlIO.mapOptional("extern", BFP.ExternEntryCount, 0);
YamlIO.mapRequired("nblocks", BFP.NumBasicBlocks);
YamlIO.mapOptional("blocks", BFP.Blocks,
std::vector<bolt::BinaryBasicBlockProfile>());
Expand Down
2 changes: 2 additions & 0 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) {
OS << "\n Sample Count: " << RawSampleCount;
OS << "\n Profile Acc : " << format("%.1f%%", ProfileMatchRatio * 100.0f);
}
if (ExternEntryCount)
OS << "\n Extern Entry Count: " << ExternEntryCount;

if (opts::PrintDynoStats && !getLayout().block_empty()) {
OS << '\n';
Expand Down
1 change: 1 addition & 0 deletions bolt/lib/Core/HashUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ std::string hashExpr(BinaryContext &BC, const MCExpr &Expr) {
.append(hashInteger(BinaryExpr.getOpcode()))
.append(hashExpr(BC, *BinaryExpr.getRHS()));
}
case MCExpr::Specifier:
case MCExpr::Target:
return std::string();
}
Expand Down
10 changes: 6 additions & 4 deletions bolt/lib/Core/MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,19 @@ bool MCPlusBuilder::equals(const MCExpr &A, const MCExpr &B,
equals(*BinaryA.getRHS(), *BinaryB.getRHS(), Comp);
}

case MCExpr::Target: {
const auto &TargetExprA = cast<MCTargetExpr>(A);
const auto &TargetExprB = cast<MCTargetExpr>(B);
case MCExpr::Specifier: {
const auto &TargetExprA = cast<MCSpecifierExpr>(A);
const auto &TargetExprB = cast<MCSpecifierExpr>(B);
return equals(TargetExprA, TargetExprB, Comp);
}
case MCExpr::Target:
llvm_unreachable("Not implemented");
}

llvm_unreachable("Invalid expression kind!");
}

bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B,
bool MCPlusBuilder::equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
CompFuncTy Comp) const {
llvm_unreachable("target-specific expressions are unsupported");
}
Expand Down
3 changes: 3 additions & 0 deletions bolt/lib/Passes/ProfileQualityStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ void computeFlowMappings(const BinaryContext &BC, FlowInfo &TotalFlowMap) {
std::vector<uint64_t> &MaxCountMap = TotalMaxCountMaps[FunctionNum];
std::vector<uint64_t> &MinCountMap = TotalMinCountMaps[FunctionNum];

// Record external entry count into CallGraphIncomingFlows
CallGraphIncomingFlows[FunctionNum] += Function->getExternEntryCount();

// Update MaxCountMap, MinCountMap, and CallGraphIncomingFlows
auto recordCall = [&](const BinaryBasicBlock *SourceBB,
const MCSymbol *DestSymbol, uint64_t Count,
Expand Down
67 changes: 14 additions & 53 deletions bolt/lib/Profile/DataAggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,10 @@ void DataAggregator::processProfile(BinaryContext &BC) {
}
}

for (auto &FuncBranches : NamesToBranches)
for (auto &FuncBranches : NamesToBranches) {
llvm::stable_sort(FuncBranches.second.Data);
llvm::stable_sort(FuncBranches.second.EntryData);
}

for (auto &MemEvents : NamesToMemEvents)
llvm::stable_sort(MemEvents.second.Data);
Expand Down Expand Up @@ -733,8 +735,10 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
// corresponds to a return (if \p IsFrom) or a call continuation (otherwise).
auto handleAddress = [&](uint64_t &Addr, bool IsFrom) {
BinaryFunction *Func = getBinaryFunctionContainingAddress(Addr);
if (!Func)
if (!Func) {
Addr = 0;
return std::pair{Func, false};
}

Addr -= Func->getAddress();

Expand Down Expand Up @@ -972,7 +976,7 @@ bool DataAggregator::recordExit(BinaryFunction &BF, uint64_t From, bool Mispred,
return true;
}

ErrorOr<LBREntry> DataAggregator::parseLBREntry() {
ErrorOr<DataAggregator::LBREntry> DataAggregator::parseLBREntry() {
LBREntry Res;
ErrorOr<StringRef> FromStrRes = parseString('/');
if (std::error_code EC = FromStrRes.getError())
Expand Down Expand Up @@ -1430,54 +1434,16 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
const uint64_t TraceTo = NextLBR->From;
const BinaryFunction *TraceBF =
getBinaryFunctionContainingAddress(TraceFrom);
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)];
FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)];
if (TraceBF && TraceBF->containsAddress(LBR.From))
++Info.InternCount;
} else if (TraceBF && TraceBF->containsAddress(TraceTo)) {
FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)];
if (TraceBF->containsAddress(LBR.From))
++Info.InternCount;
else
++Info.ExternCount;
} else {
const BinaryFunction *ToFunc =
getBinaryFunctionContainingAddress(TraceTo);
if (TraceBF && ToFunc) {
LLVM_DEBUG({
dbgs() << "Invalid trace starting in " << TraceBF->getPrintName()
<< formatv(" @ {0:x}", TraceFrom - TraceBF->getAddress())
<< formatv(" and ending @ {0:x}\n", TraceTo);
});
++NumInvalidTraces;
} else {
LLVM_DEBUG({
dbgs() << "Out of range trace starting in "
<< (TraceBF ? TraceBF->getPrintName() : "None")
<< formatv(" @ {0:x}",
TraceFrom - (TraceBF ? TraceBF->getAddress() : 0))
<< " and ending in "
<< (ToFunc ? ToFunc->getPrintName() : "None")
<< formatv(" @ {0:x}\n",
TraceTo - (ToFunc ? ToFunc->getAddress() : 0));
});
++NumLongRangeTraces;
}
}
else
++Info.ExternCount;
++NumTraces;
}
NextLBR = &LBR;

// Record branches outside binary functions for heatmap.
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
TakenBranchInfo &Info = BranchLBRs[Trace(LBR.From, LBR.To)];
++Info.TakenCount;
continue;
}
uint64_t From = getBinaryFunctionContainingAddress(LBR.From) ? LBR.From : 0;
uint64_t To = getBinaryFunctionContainingAddress(LBR.To) ? LBR.To : 0;
if (!From && !To)
continue;
TakenBranchInfo &Info = BranchLBRs[Trace(From, To)];
TakenBranchInfo &Info = BranchLBRs[Trace(LBR.From, LBR.To)];
++Info.TakenCount;
Info.MispredCount += LBR.Mispred;
}
Expand Down Expand Up @@ -2289,6 +2255,7 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
YamlBF.Id = BF->getFunctionNumber();
YamlBF.Hash = BAT->getBFHash(FuncAddress);
YamlBF.ExecCount = BF->getKnownExecutionCount();
YamlBF.ExternEntryCount = BF->getExternEntryCount();
YamlBF.NumBasicBlocks = BAT->getNumBasicBlocks(FuncAddress);
const BoltAddressTranslation::BBHashMapTy &BlockMap =
BAT->getBBHashMap(FuncAddress);
Expand Down Expand Up @@ -2398,16 +2365,10 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,

void DataAggregator::dump() const { DataReader::dump(); }

void DataAggregator::dump(const LBREntry &LBR) const {
Diag << "From: " << Twine::utohexstr(LBR.From)
<< " To: " << Twine::utohexstr(LBR.To) << " Mispred? " << LBR.Mispred
<< "\n";
}

void DataAggregator::dump(const PerfBranchSample &Sample) const {
Diag << "Sample LBR entries: " << Sample.LBR.size() << "\n";
for (const LBREntry &LBR : Sample.LBR)
dump(LBR);
Diag << LBR << '\n';
}

void DataAggregator::dump(const PerfMemSample &Sample) const {
Expand Down
6 changes: 6 additions & 0 deletions bolt/lib/Profile/DataReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ void FuncBranchData::appendFrom(const FuncBranchData &FBD, uint64_t Offset) {
}
llvm::stable_sort(Data);
ExecutionCount += FBD.ExecutionCount;
ExternEntryCount += FBD.ExternEntryCount;
for (auto I = FBD.EntryData.begin(), E = FBD.EntryData.end(); I != E; ++I) {
assert(I->To.Name == FBD.Name);
auto NewElmt = EntryData.insert(EntryData.end(), *I);
Expand Down Expand Up @@ -269,6 +270,7 @@ Error DataReader::preprocessProfile(BinaryContext &BC) {
if (FuncBranchData *FuncData = getBranchDataForNames(Function.getNames())) {
setBranchData(Function, FuncData);
Function.ExecutionCount = FuncData->ExecutionCount;
Function.ExternEntryCount = FuncData->ExternEntryCount;
FuncData->Used = true;
}
}
Expand Down Expand Up @@ -419,6 +421,7 @@ void DataReader::matchProfileData(BinaryFunction &BF) {
if (fetchProfileForOtherEntryPoints(BF)) {
BF.ProfileMatchRatio = evaluateProfileData(BF, *FBD);
BF.ExecutionCount = FBD->ExecutionCount;
BF.ExternEntryCount = FBD->ExternEntryCount;
BF.RawSampleCount = FBD->getNumExecutedBranches();
}
return;
Expand Down Expand Up @@ -449,6 +452,7 @@ void DataReader::matchProfileData(BinaryFunction &BF) {
setBranchData(BF, NewBranchData);
NewBranchData->Used = true;
BF.ExecutionCount = NewBranchData->ExecutionCount;
BF.ExternEntryCount = NewBranchData->ExternEntryCount;
BF.ProfileMatchRatio = 1.0f;
break;
}
Expand Down Expand Up @@ -1190,6 +1194,8 @@ std::error_code DataReader::parse() {
if (BI.To.IsSymbol && BI.To.Offset == 0) {
I = GetOrCreateFuncEntry(BI.To.Name);
I->second.ExecutionCount += BI.Branches;
if (!BI.From.IsSymbol)
I->second.ExternEntryCount += BI.Branches;
}
}

Expand Down
1 change: 1 addition & 0 deletions bolt/lib/Profile/YAMLProfileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ bool YAMLProfileReader::parseFunctionProfile(
uint64_t FunctionExecutionCount = 0;

BF.setExecutionCount(YamlBF.ExecCount);
BF.setExternEntryCount(YamlBF.ExternEntryCount);

uint64_t FuncRawBranchCount = 0;
for (const yaml::bolt::BinaryBasicBlockProfile &YamlBB : YamlBF.Blocks)
Expand Down
6 changes: 3 additions & 3 deletions bolt/lib/Profile/YAMLProfileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
YamlBF.Hash = BF.getHash();
YamlBF.NumBasicBlocks = BF.size();
YamlBF.ExecCount = BF.getKnownExecutionCount();
YamlBF.ExternEntryCount = BF.getExternEntryCount();
DenseMap<const MCDecodedPseudoProbeInlineTree *, uint32_t> InlineTreeNodeId;
if (PseudoProbeDecoder && BF.getGUID()) {
std::tie(YamlBF.InlineTree, InlineTreeNodeId) =
Expand Down Expand Up @@ -303,9 +304,8 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
}
// Sort targets in a similar way to getBranchData, see Location::operator<
llvm::sort(CSTargets, [](const auto &RHS, const auto &LHS) {
if (RHS.first != LHS.first)
return RHS.first < LHS.first;
return RHS.second.Offset < LHS.second.Offset;
return std::tie(RHS.first, RHS.second.Offset) <
std::tie(LHS.first, LHS.second.Offset);
});
for (auto &KV : CSTargets)
YamlBB.CallSites.push_back(KV.second);
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
return true;
}

bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
bool equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
CompFuncTy Comp) const override {
const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
const auto &AArch64ExprB = cast<AArch64MCExpr>(B);
Expand Down
Loading