[BOLT] Fix crash while writing new profile

Summary:
New profile writer was crashing as functions were lacking a profile
flags. Fix it by requiring flags when marking function as profiled.

Generate new profile for clang. The new profile has more coverage and
results in better overall improvement from BOLT. It was generated by
merging multiple runs of:

% perf record -e cycles:u -j any,u -F32000 -- \
    ./clang bf.cpp -O2 -std=c++11 -c -o /tmp/bf.o

(cherry picked from FBD7798580)
This commit is contained in:
Maksim Panchenko 2018-04-27 14:16:42 -07:00
parent d6003e94eb
commit caad4bcf3a
5 changed files with 11 additions and 27 deletions

View File

@ -1496,34 +1496,18 @@ public:
}
/// Mark this function as having a valid profile.
void markProfiled() {
void markProfiled(uint16_t Flags) {
if (ExecutionCount == COUNT_NO_PROFILE)
ExecutionCount = 0;
ProfileFlags = Flags;
ProfileMatchRatio = 1.0f;
}
/// Check if the function profile used LBR.
bool hasLBRProfile() const {
return ProfileFlags & PF_LBR;
}
/// Set status of the function profile.
void setHasLBRProfile(bool Value) {
assert(!(ProfileFlags & PF_SAMPLE) &&
"cannot combine LBR and samples profile");
ProfileFlags |= PF_LBR;
}
/// Return flags describing a profile for this function.
uint16_t getProfileFlags() const {
return ProfileFlags;
}
/// Set profile flags for the function to \p Flags.
void setProfileFlags(uint16_t Flags) {
ProfileFlags = Flags;
}
void addCFIInstruction(uint64_t Offset, MCCFIInstruction &&Inst) {
assert(!Instructions.empty());

View File

@ -306,7 +306,7 @@ void BinaryFunction::postProcessProfile() {
return;
}
if (!hasLBRProfile())
if (!(getProfileFlags() & PF_LBR))
return;
// Pre-sort branch data.

View File

@ -419,12 +419,13 @@ bool DataAggregator::aggregate(BinaryContext &BC,
for (auto &BFI : BFs) {
auto &BF = BFI.second;
if (BF.getBranchData()) {
BF.markProfiled();
const auto Flags = opts::BasicAggregation ? BinaryFunction::PF_SAMPLE
: BinaryFunction::PF_LBR;
BF.markProfiled(Flags);
}
}
auto PI3 = sys::Wait(MemEventsPI, 0, true, &Error);
if (PI3.ReturnCode != 0) {
ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
MemoryBuffer::getFileOrSTDIN(PerfMemEventsErrPath.data());
@ -455,8 +456,9 @@ bool DataAggregator::aggregate(BinaryContext &BC,
ParsingBuf = FileBuf->getBuffer();
Col = 0;
Line = 1;
if (parseMemEvents()) {
outs() << "PERF2BOLT: Failed to parse memory events\n";
if (const auto EC = parseMemEvents()) {
errs() << "PERF2BOLT: Failed to parse memory events: "
<< EC.message() << '\n';
}
deleteTempFiles();

View File

@ -55,8 +55,6 @@ ProfileReader::parseFunctionProfile(BinaryFunction &BF,
uint64_t MismatchedCalls = 0;
uint64_t MismatchedEdges = 0;
BF.setProfileFlags(YamlBP.Header.Flags);
uint64_t FunctionExecutionCount = 0;
BF.setExecutionCount(YamlBF.ExecCount);
@ -206,7 +204,7 @@ ProfileReader::parseFunctionProfile(BinaryFunction &BF,
ProfileMatched &= !MismatchedBlocks && !MismatchedCalls && !MismatchedEdges;
if (ProfileMatched)
BF.markProfiled();
BF.markProfiled(YamlBP.Header.Flags);
if (!ProfileMatched && opts::Verbosity >= 1) {
errs() << "BOLT-WARNING: " << MismatchedBlocks << " blocks, "

View File

@ -32,7 +32,7 @@ void
convert(const BinaryFunction &BF, yaml::bolt::BinaryFunctionProfile &YamlBF) {
auto &BC = BF.getBinaryContext();
const auto LBRProfile = BF.hasLBRProfile();
const auto LBRProfile = BF.getProfileFlags() & BinaryFunction::PF_LBR;
YamlBF.Name = BF.getPrintName();
YamlBF.Id = BF.getFunctionNumber();