llvm-project/bolt/include/bolt/Profile/YAMLProfileReader.h
Amir Ayupov 7b750943d7 [BOLT][NFC] Speedup YAML profile processing
Reduce YAML profile processing times:
- preprocessProfile: speed up buildNameMaps by replacing ProfileNameToProfile
  mapping with ProfileFunctionNames set and ProfileBFs vector.
  Pre-look up YamlBF->BF correspondence, memoize in ProfileBFs.
- readProfile: replace iteration over all functions in the binary by iteration
  over profile functions (strict match and LTO name match).

On a large binary (1.9M functions) and large YAML profile (121MB, 30k functions)
reduces profile steps runtime:
pre-process profile data: 12.4953s -> 10.7123s
process profile data: 9.8195s -> 5.6639s

Compared to fdata profile reading:
pre-process profile data: 8.0268s
process profile data: 1.0265s
process profile data pre-CFG: 0.1644s

Reviewed By: #bolt, maksfb

Differential Revision: https://reviews.llvm.org/D159460
2023-09-11 16:07:57 -07:00

104 lines
3.4 KiB
C++

//===- bolt/Profile/YAMLProfileReader.h - YAML profile reader ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef BOLT_PROFILE_YAML_PROFILE_READER_H
#define BOLT_PROFILE_YAML_PROFILE_READER_H
#include "bolt/Profile/ProfileReaderBase.h"
#include "bolt/Profile/ProfileYAMLMapping.h"
#include <unordered_set>
namespace llvm {
namespace bolt {
class YAMLProfileReader : public ProfileReaderBase {
public:
explicit YAMLProfileReader(StringRef Filename)
: ProfileReaderBase(Filename) {}
StringRef getReaderName() const override { return "YAML profile reader"; }
bool isTrustedSource() const override { return false; }
Error readProfilePreCFG(BinaryContext &BC) override {
return Error::success();
}
Error readProfile(BinaryContext &BC) override;
Error preprocessProfile(BinaryContext &BC) override;
bool hasLocalsWithFileName() const override;
bool mayHaveProfileData(const BinaryFunction &BF) override;
/// Check if the file contains YAML.
static bool isYAML(StringRef Filename);
private:
/// Adjustments for basic samples profiles (without LBR).
bool NormalizeByInsnCount{false};
bool NormalizeByCalls{false};
/// Binary profile in YAML format.
yaml::bolt::BinaryProfile YamlBP;
/// Map a function ID from a YAML profile to a BinaryFunction object.
std::vector<BinaryFunction *> YamlProfileToFunction;
using FunctionSet = std::unordered_set<const BinaryFunction *>;
/// To keep track of functions that have a matched profile before the profile
/// is attributed.
FunctionSet ProfiledFunctions;
/// For LTO symbol resolution.
/// Map a common LTO prefix to a list of YAML profiles matching the prefix.
StringMap<std::vector<yaml::bolt::BinaryFunctionProfile *>> LTOCommonNameMap;
/// Map a common LTO prefix to a set of binary functions.
StringMap<std::unordered_set<BinaryFunction *>> LTOCommonNameFunctionMap;
/// Function names in profile.
StringSet<> ProfileFunctionNames;
/// BinaryFunction pointers indexed by YamlBP functions.
std::vector<BinaryFunction *> ProfileBFs;
/// Populate \p Function profile with the one supplied in YAML format.
bool parseFunctionProfile(BinaryFunction &Function,
const yaml::bolt::BinaryFunctionProfile &YamlBF);
/// Infer function profile from stale data (collected on older binaries).
bool inferStaleProfile(BinaryFunction &Function,
const yaml::bolt::BinaryFunctionProfile &YamlBF);
/// Initialize maps for profile matching.
void buildNameMaps(BinaryContext &BC);
/// Update matched YAML -> BinaryFunction pair.
void matchProfileToFunction(yaml::bolt::BinaryFunctionProfile &YamlBF,
BinaryFunction &BF) {
if (YamlBF.Id >= YamlProfileToFunction.size())
YamlProfileToFunction.resize(YamlBF.Id + 1);
YamlProfileToFunction[YamlBF.Id] = &BF;
YamlBF.Used = true;
assert(!ProfiledFunctions.count(&BF) &&
"function already has an assigned profile");
ProfiledFunctions.emplace(&BF);
}
/// Check if the profile uses an event with a given \p Name.
bool usesEvent(StringRef Name) const;
};
} // namespace bolt
} // namespace llvm
#endif