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
104 lines
3.4 KiB
C++
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
|