11f05b1a9Swlei //===-- ProfileGenerator.h - Profile Generator -----------------*- C++ -*-===// 21f05b1a9Swlei // 31f05b1a9Swlei // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41f05b1a9Swlei // See https://llvm.org/LICENSE.txt for license information. 51f05b1a9Swlei // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61f05b1a9Swlei // 71f05b1a9Swlei //===----------------------------------------------------------------------===// 81f05b1a9Swlei 91f05b1a9Swlei #ifndef LLVM_TOOLS_LLVM_PROGEN_PROFILEGENERATOR_H 101f05b1a9Swlei #define LLVM_TOOLS_LLVM_PROGEN_PROFILEGENERATOR_H 1130b02323SWenlei He #include "CSPreInliner.h" 121f05b1a9Swlei #include "ErrorHandling.h" 131f05b1a9Swlei #include "PerfReader.h" 141f05b1a9Swlei #include "ProfiledBinary.h" 15f1985a3fSserge-sans-paille #include "llvm/IR/DebugInfoMetadata.h" 161f05b1a9Swlei #include "llvm/ProfileData/SampleProfWriter.h" 17ce6bfe94SWenlei He #include <memory> 1800ef28efSWenlei He #include <unordered_set> 191f05b1a9Swlei 201f05b1a9Swlei using namespace llvm; 211f05b1a9Swlei using namespace sampleprof; 221f05b1a9Swlei 231f05b1a9Swlei namespace llvm { 241f05b1a9Swlei namespace sampleprof { 251f05b1a9Swlei 2623391febSHongtao Yu using ProbeCounterMap = 2723391febSHongtao Yu std::unordered_map<const MCDecodedPseudoProbe *, uint64_t>; 2823391febSHongtao Yu 29d5f20130Swlei // This base class for profile generation of sample-based PGO. We reuse all 30d5f20130Swlei // structures relating to function profiles and profile writers as seen in 31d5f20130Swlei // /ProfileData/SampleProf.h. 32d5f20130Swlei class ProfileGeneratorBase { 331f05b1a9Swlei 341f05b1a9Swlei public: ProfileGeneratorBase(ProfiledBinary * Binary)35aa58b7b1Swlei ProfileGeneratorBase(ProfiledBinary *Binary) : Binary(Binary){}; ProfileGeneratorBase(ProfiledBinary * Binary,const ContextSampleCounterMap * Counters)36d5f20130Swlei ProfileGeneratorBase(ProfiledBinary *Binary, 37937924ebSHongtao Yu const ContextSampleCounterMap *Counters) 38d5f20130Swlei : Binary(Binary), SampleCounters(Counters){}; ProfileGeneratorBase(ProfiledBinary * Binary,const SampleProfileMap && Profiles)39937924ebSHongtao Yu ProfileGeneratorBase(ProfiledBinary *Binary, 40937924ebSHongtao Yu const SampleProfileMap &&Profiles) 41937924ebSHongtao Yu : Binary(Binary), ProfileMap(std::move(Profiles)){}; 42937924ebSHongtao Yu 43d5f20130Swlei virtual ~ProfileGeneratorBase() = default; 44d5f20130Swlei static std::unique_ptr<ProfileGeneratorBase> 45937924ebSHongtao Yu create(ProfiledBinary *Binary, const ContextSampleCounterMap *Counters, 46e36786d1SHongtao Yu bool profileIsCS); 47937924ebSHongtao Yu static std::unique_ptr<ProfileGeneratorBase> 48aa58b7b1Swlei create(ProfiledBinary *Binary, SampleProfileMap &ProfileMap, 49e36786d1SHongtao Yu bool profileIsCS); 501f05b1a9Swlei virtual void generateProfile() = 0; 511f05b1a9Swlei void write(); 521f05b1a9Swlei 5341a681ceSwlei static uint32_t 5441a681ceSwlei getDuplicationFactor(unsigned Discriminator, 5541a681ceSwlei bool UseFSD = ProfileGeneratorBase::UseFSDiscriminator) { 5641a681ceSwlei return UseFSD ? 1 5741a681ceSwlei : llvm::DILocation::getDuplicationFactorFromDiscriminator( 5846cf7d75Swlei Discriminator); 5946cf7d75Swlei } 6046cf7d75Swlei 6141a681ceSwlei static uint32_t 6241a681ceSwlei getBaseDiscriminator(unsigned Discriminator, 6341a681ceSwlei bool UseFSD = ProfileGeneratorBase::UseFSDiscriminator) { 6441a681ceSwlei return UseFSD ? Discriminator 6541a681ceSwlei : DILocation::getBaseDiscriminatorFromDiscriminator( 6646cf7d75Swlei Discriminator, /* IsFSDiscriminator */ false); 6746cf7d75Swlei } 6846cf7d75Swlei 6941a681ceSwlei static bool UseFSDiscriminator; 7041a681ceSwlei 711f05b1a9Swlei protected: 72d5f20130Swlei // Use SampleProfileWriter to serialize profile map 73d5f20130Swlei void write(std::unique_ptr<SampleProfileWriter> Writer, 74d5f20130Swlei SampleProfileMap &ProfileMap); 751f05b1a9Swlei /* 761f05b1a9Swlei For each region boundary point, mark if it is begin or end (or both) of 771f05b1a9Swlei the region. Boundary points are inclusive. Log the sample count as well 781f05b1a9Swlei so we can use it when we compute the sample count of each disjoint region 791f05b1a9Swlei later. Note that there might be multiple ranges with different sample 801f05b1a9Swlei count that share same begin/end point. We need to accumulate the sample 811f05b1a9Swlei count for the boundary point for such case, because for the example 821f05b1a9Swlei below, 831f05b1a9Swlei 841f05b1a9Swlei |<--100-->| 851f05b1a9Swlei |<------200------>| 861f05b1a9Swlei A B C 871f05b1a9Swlei 881f05b1a9Swlei sample count for disjoint region [A,B] would be 300. 891f05b1a9Swlei */ 901f05b1a9Swlei void findDisjointRanges(RangeSample &DisjointRanges, 911f05b1a9Swlei const RangeSample &Ranges); 9223391febSHongtao Yu 9323391febSHongtao Yu // Go through each address from range to extract the top frame probe by 9423391febSHongtao Yu // looking up in the Address2ProbeMap 9523391febSHongtao Yu void extractProbesFromRange(const RangeSample &RangeCounter, 9623391febSHongtao Yu ProbeCounterMap &ProbeCounter, 9723391febSHongtao Yu bool FindDisjointRanges = true); 9823391febSHongtao Yu 99d5f20130Swlei // Helper function for updating body sample for a leaf location in 100d5f20130Swlei // FunctionProfile 101d5f20130Swlei void updateBodySamplesforFunctionProfile(FunctionSamples &FunctionProfile, 102d5f20130Swlei const SampleContextFrame &LeafLoc, 103d5f20130Swlei uint64_t Count); 104acfd0a34SHongtao Yu 105acfd0a34SHongtao Yu void updateFunctionSamples(); 106acfd0a34SHongtao Yu 107f5537643Swlei void updateTotalSamples(); 108c2e08abaSwlei 109acfd0a34SHongtao Yu void updateCallsiteSamples(); 110acfd0a34SHongtao Yu 11124f02517SLei Wang void filterAmbiguousProfile(SampleProfileMap &Profiles); 11224f02517SLei Wang 11324f02517SLei Wang bool filterAmbiguousProfile(FunctionSamples &FS); 11424f02517SLei Wang 11546765248Swlei StringRef getCalleeNameForAddress(uint64_t TargetAddress); 116c2e08abaSwlei 117aa58b7b1Swlei void computeSummaryAndThreshold(SampleProfileMap &ProfileMap); 118c2e08abaSwlei 119*b9d40a7aSLei Wang void calculateBodySamplesAndSize(const FunctionSamples &FSamples, 120*b9d40a7aSLei Wang uint64_t &TotalBodySamples, 121*b9d40a7aSLei Wang uint64_t &FuncBodySize); 122c2e08abaSwlei 123*b9d40a7aSLei Wang double calculateDensity(const SampleProfileMap &Profiles); 124*b9d40a7aSLei Wang 125*b9d40a7aSLei Wang void calculateAndShowDensity(const SampleProfileMap &Profiles); 126c2e08abaSwlei 127c2e08abaSwlei void showDensitySuggestion(double Density); 128c2e08abaSwlei 1293f970168SHongtao Yu void collectProfiledFunctions(); 1303f970168SHongtao Yu 131aa58b7b1Swlei bool collectFunctionsFromRawProfile( 132aa58b7b1Swlei std::unordered_set<const BinaryFunction *> &ProfiledFunctions); 133aa58b7b1Swlei 134aa58b7b1Swlei // Collect profiled Functions for llvm sample profile input. 135aa58b7b1Swlei virtual bool collectFunctionsFromLLVMProfile( 136aa58b7b1Swlei std::unordered_set<const BinaryFunction *> &ProfiledFunctions) = 0; 137aa58b7b1Swlei 13824f02517SLei Wang // List of function prefix to filter out. 13924f02517SLei Wang static constexpr const char *FuncPrefixsToFilter[] = {"__cxx_global_var_init", 14024f02517SLei Wang "__tls_init"}; 14124f02517SLei Wang 142c2e08abaSwlei // Thresholds from profile summary to answer isHotCount/isColdCount queries. 143c2e08abaSwlei uint64_t HotCountThreshold; 144c2e08abaSwlei 145c2e08abaSwlei uint64_t ColdCountThreshold; 146c2e08abaSwlei 147937924ebSHongtao Yu ProfiledBinary *Binary = nullptr; 148937924ebSHongtao Yu 149a4190037SHongtao Yu std::unique_ptr<ProfileSummary> Summary; 150a4190037SHongtao Yu 1511f05b1a9Swlei // Used by SampleProfileWriter 152b9db7036SHongtao Yu SampleProfileMap ProfileMap; 153f812c192Swlei 154937924ebSHongtao Yu const ContextSampleCounterMap *SampleCounters = nullptr; 1551f05b1a9Swlei }; 1561f05b1a9Swlei 157d5f20130Swlei class ProfileGenerator : public ProfileGeneratorBase { 1581f05b1a9Swlei 1591f05b1a9Swlei public: ProfileGenerator(ProfiledBinary * Binary,const ContextSampleCounterMap * Counters)160d5f20130Swlei ProfileGenerator(ProfiledBinary *Binary, 161937924ebSHongtao Yu const ContextSampleCounterMap *Counters) 162d5f20130Swlei : ProfileGeneratorBase(Binary, Counters){}; ProfileGenerator(ProfiledBinary * Binary,const SampleProfileMap && Profiles)163937924ebSHongtao Yu ProfileGenerator(ProfiledBinary *Binary, const SampleProfileMap &&Profiles) 164937924ebSHongtao Yu : ProfileGeneratorBase(Binary, std::move(Profiles)){}; 165d5f20130Swlei void generateProfile() override; 166d5f20130Swlei 167d5f20130Swlei private: 168d5f20130Swlei void generateLineNumBasedProfile(); 16923391febSHongtao Yu void generateProbeBasedProfile(); 17028277e9bSwlei RangeSample preprocessRangeCounter(const RangeSample &RangeCounter); 171ef0e0adcSWilliam Junda Huang FunctionSamples &getTopLevelFunctionProfile(FunctionId FuncName); 172d5f20130Swlei // Helper function to get the leaf frame's FunctionProfile by traversing the 173d5f20130Swlei // inline stack and meanwhile it adds the total samples for each frame's 174d5f20130Swlei // function profile. 175d5f20130Swlei FunctionSamples & 176484a569eSwlei getLeafProfileAndAddTotalSamples(const SampleContextFrameVector &FrameVec, 177484a569eSwlei uint64_t Count); 178d5f20130Swlei void populateBodySamplesForAllFunctions(const RangeSample &RangeCounter); 179d5f20130Swlei void 180d5f20130Swlei populateBoundarySamplesForAllFunctions(const BranchSample &BranchCounters); 18123391febSHongtao Yu void 182937924ebSHongtao Yu populateBodySamplesWithProbesForAllFunctions(const RangeSample &RangeCounter); 183937924ebSHongtao Yu void populateBoundarySamplesWithProbesForAllFunctions( 184937924ebSHongtao Yu const BranchSample &BranchCounters); 185c2e08abaSwlei void postProcessProfiles(); 18627cb3707Swlei void trimColdProfiles(const SampleProfileMap &Profiles, 18727cb3707Swlei uint64_t ColdCntThreshold); 188aa58b7b1Swlei bool collectFunctionsFromLLVMProfile( 189aa58b7b1Swlei std::unordered_set<const BinaryFunction *> &ProfiledFunctions) override; 190d5f20130Swlei }; 191d5f20130Swlei 192d5f20130Swlei class CSProfileGenerator : public ProfileGeneratorBase { 193d5f20130Swlei public: CSProfileGenerator(ProfiledBinary * Binary,const ContextSampleCounterMap * Counters)194f812c192Swlei CSProfileGenerator(ProfiledBinary *Binary, 195937924ebSHongtao Yu const ContextSampleCounterMap *Counters) 196d5f20130Swlei : ProfileGeneratorBase(Binary, Counters){}; CSProfileGenerator(ProfiledBinary * Binary,SampleProfileMap & Profiles)197aa58b7b1Swlei CSProfileGenerator(ProfiledBinary *Binary, SampleProfileMap &Profiles) 198aa58b7b1Swlei : ProfileGeneratorBase(Binary), ContextTracker(Profiles, nullptr){}; 199a5d30421SWenlei He void generateProfile() override; 2001f05b1a9Swlei 201856a6a50Swlei // Trim the context stack at a given depth. 202856a6a50Swlei template <typename T> 203856a6a50Swlei static void trimContext(SmallVectorImpl<T> &S, int Depth = MaxContextDepth) { 204856a6a50Swlei if (Depth < 0 || static_cast<size_t>(Depth) >= S.size()) 205856a6a50Swlei return; 206856a6a50Swlei std::copy(S.begin() + S.size() - static_cast<size_t>(Depth), S.end(), 207856a6a50Swlei S.begin()); 208856a6a50Swlei S.resize(Depth); 209856a6a50Swlei } 210856a6a50Swlei 211ac14bb14Swlei // Remove adjacent repeated context sequences up to a given sequence length, 212ac14bb14Swlei // -1 means no size limit. Note that repeated sequences are identified based 213ac14bb14Swlei // on the exact call site, this is finer granularity than function recursion. 214ac14bb14Swlei template <typename T> 215ac14bb14Swlei static void compressRecursionContext(SmallVectorImpl<T> &Context, 216ac14bb14Swlei int32_t CSize = MaxCompressionSize) { 217ac14bb14Swlei uint32_t I = 1; 218ac14bb14Swlei uint32_t HS = static_cast<uint32_t>(Context.size() / 2); 219ac14bb14Swlei uint32_t MaxDedupSize = 220ac14bb14Swlei CSize == -1 ? HS : std::min(static_cast<uint32_t>(CSize), HS); 221ac14bb14Swlei auto BeginIter = Context.begin(); 222ac14bb14Swlei // Use an in-place algorithm to save memory copy 223ac14bb14Swlei // End indicates the end location of current iteration's data 224ac14bb14Swlei uint32_t End = 0; 225ac14bb14Swlei // Deduplicate from length 1 to the max possible size of a repeated 226ac14bb14Swlei // sequence. 227ac14bb14Swlei while (I <= MaxDedupSize) { 228ac14bb14Swlei // This is a linear algorithm that deduplicates adjacent repeated 229ac14bb14Swlei // sequences of size I. The deduplication detection runs on a sliding 230ac14bb14Swlei // window whose size is 2*I and it keeps sliding the window to deduplicate 231ac14bb14Swlei // the data inside. Once duplication is detected, deduplicate it by 232ac14bb14Swlei // skipping the right half part of the window, otherwise just copy back 233ac14bb14Swlei // the new one by appending them at the back of End pointer(for the next 234ac14bb14Swlei // iteration). 235ac14bb14Swlei // 236ac14bb14Swlei // For example: 237ac14bb14Swlei // Input: [a1, a2, b1, b2] 238ac14bb14Swlei // (Added index to distinguish the same char, the origin is [a, a, b, 239ac14bb14Swlei // b], the size of the dedup window is 2(I = 1) at the beginning) 240ac14bb14Swlei // 241ac14bb14Swlei // 1) The initial status is a dummy window[null, a1], then just copy the 242ac14bb14Swlei // right half of the window(End = 0), then slide the window. 243ac14bb14Swlei // Result: [a1], a2, b1, b2 (End points to the element right before ], 244ac14bb14Swlei // after ] is the data of the previous iteration) 245ac14bb14Swlei // 246ac14bb14Swlei // 2) Next window is [a1, a2]. Since a1 == a2, then skip the right half of 247ac14bb14Swlei // the window i.e the duplication happen. Only slide the window. 248ac14bb14Swlei // Result: [a1], a2, b1, b2 249ac14bb14Swlei // 250ac14bb14Swlei // 3) Next window is [a2, b1], copy the right half of the window(b1 is 251ac14bb14Swlei // new) to the End and slide the window. 252ac14bb14Swlei // Result: [a1, b1], b1, b2 253ac14bb14Swlei // 254ac14bb14Swlei // 4) Next window is [b1, b2], same to 2), skip b2. 255ac14bb14Swlei // Result: [a1, b1], b1, b2 256ac14bb14Swlei // After resize, it will be [a, b] 257ac14bb14Swlei 258ac14bb14Swlei // Use pointers like below to do comparison inside the window 259ac14bb14Swlei // [a b c a b c] 260ac14bb14Swlei // | | | | | 261ac14bb14Swlei // LeftBoundary Left Right Left+I Right+I 262ac14bb14Swlei // A duplication found if Left < LeftBoundry. 263ac14bb14Swlei 264ac14bb14Swlei int32_t Right = I - 1; 265ac14bb14Swlei End = I; 266ac14bb14Swlei int32_t LeftBoundary = 0; 267ac14bb14Swlei while (Right + I < Context.size()) { 268ac14bb14Swlei // To avoids scanning a part of a sequence repeatedly, it finds out 269ac14bb14Swlei // the common suffix of two hald in the window. The common suffix will 270ac14bb14Swlei // serve as the common prefix of next possible pair of duplicate 271ac14bb14Swlei // sequences. The non-common part will be ignored and never scanned 272ac14bb14Swlei // again. 273ac14bb14Swlei 274ac14bb14Swlei // For example. 275ac14bb14Swlei // Input: [a, b1], c1, b2, c2 276ac14bb14Swlei // I = 2 277ac14bb14Swlei // 278ac14bb14Swlei // 1) For the window [a, b1, c1, b2], non-common-suffix for the right 279ac14bb14Swlei // part is 'c1', copy it and only slide the window 1 step. 280ac14bb14Swlei // Result: [a, b1, c1], b2, c2 281ac14bb14Swlei // 282ac14bb14Swlei // 2) Next window is [b1, c1, b2, c2], so duplication happen. 283ac14bb14Swlei // Result after resize: [a, b, c] 284ac14bb14Swlei 285ac14bb14Swlei int32_t Left = Right; 286ac14bb14Swlei while (Left >= LeftBoundary && Context[Left] == Context[Left + I]) { 287ac14bb14Swlei // Find the longest suffix inside the window. When stops, Left points 288ac14bb14Swlei // at the diverging point in the current sequence. 289ac14bb14Swlei Left--; 290ac14bb14Swlei } 291ac14bb14Swlei 292ac14bb14Swlei bool DuplicationFound = (Left < LeftBoundary); 293ac14bb14Swlei // Don't need to recheck the data before Right 294ac14bb14Swlei LeftBoundary = Right + 1; 295ac14bb14Swlei if (DuplicationFound) { 296ac14bb14Swlei // Duplication found, skip right half of the window. 297ac14bb14Swlei Right += I; 298ac14bb14Swlei } else { 299ac14bb14Swlei // Copy the non-common-suffix part of the adjacent sequence. 300ac14bb14Swlei std::copy(BeginIter + Right + 1, BeginIter + Left + I + 1, 301ac14bb14Swlei BeginIter + End); 302ac14bb14Swlei End += Left + I - Right; 303ac14bb14Swlei // Only slide the window by the size of non-common-suffix 304ac14bb14Swlei Right = Left + I; 305ac14bb14Swlei } 306ac14bb14Swlei } 307ac14bb14Swlei // Don't forget the remaining part that's not scanned. 308ac14bb14Swlei std::copy(BeginIter + Right + 1, Context.end(), BeginIter + End); 309ac14bb14Swlei End += Context.size() - Right - 1; 310ac14bb14Swlei I++; 311ac14bb14Swlei Context.resize(End); 312ac14bb14Swlei MaxDedupSize = std::min(static_cast<uint32_t>(End / 2), MaxDedupSize); 313ac14bb14Swlei } 314ac14bb14Swlei } 315ac14bb14Swlei 316d5f20130Swlei private: 317d5f20130Swlei void generateLineNumBasedProfile(); 318eba57492Swlei 319eba57492Swlei FunctionSamples *getOrCreateFunctionSamples(ContextTrieNode *ContextNode, 3201410db70SWenlei He bool WasLeafInlined = false); 321eba57492Swlei 322eba57492Swlei // Lookup or create ContextTrieNode for the context, FunctionSamples is 323eba57492Swlei // created inside this function. 324eba57492Swlei ContextTrieNode *getOrCreateContextNode(const SampleContextFrames Context, 325eba57492Swlei bool WasLeafInlined = false); 326eba57492Swlei 327ce40843aSwlei // For profiled only functions, on-demand compute their inline context 328ce40843aSwlei // function byte size which is used by the pre-inliner. 329ce40843aSwlei void computeSizeForProfiledFunctions(); 33030b02323SWenlei He // Post processing for profiles before writing out, such as mermining 33130b02323SWenlei He // and trimming cold profiles, running preinliner on profiles. 33230b02323SWenlei He void postProcessProfiles(); 333d5f20130Swlei 334d5f20130Swlei void populateBodySamplesForFunction(FunctionSamples &FunctionProfile, 335f812c192Swlei const RangeSample &RangeCounters); 336eba57492Swlei 337eba57492Swlei void populateBoundarySamplesForFunction(ContextTrieNode *CallerNode, 338f812c192Swlei const BranchSample &BranchCounters); 339eba57492Swlei 340eba57492Swlei void populateInferredFunctionSamples(ContextTrieNode &Node); 341eba57492Swlei 342eba57492Swlei void updateFunctionSamples(); 343ac14bb14Swlei 344d5f20130Swlei void generateProbeBasedProfile(); 34523391febSHongtao Yu 346c82b24f4Swlei // Fill in function body samples from probes 347b9db7036SHongtao Yu void populateBodySamplesWithProbes(const RangeSample &RangeCounter, 3485d7950a4SHongtao Yu const AddrBasedCtxKey *CtxKey); 349c82b24f4Swlei // Fill in boundary samples for a call probe 350b9db7036SHongtao Yu void populateBoundarySamplesWithProbes(const BranchSample &BranchCounter, 3515d7950a4SHongtao Yu const AddrBasedCtxKey *CtxKey); 352eba57492Swlei 353eba57492Swlei ContextTrieNode * 3545d7950a4SHongtao Yu getContextNodeForLeafProbe(const AddrBasedCtxKey *CtxKey, 355eba57492Swlei const MCDecodedPseudoProbe *LeafProbe); 356eba57492Swlei 357c82b24f4Swlei // Helper function to get FunctionSamples for the leaf probe 358ac14bb14Swlei FunctionSamples & 3595d7950a4SHongtao Yu getFunctionProfileForLeafProbe(const AddrBasedCtxKey *CtxKey, 360f812c192Swlei const MCDecodedPseudoProbe *LeafProbe); 361d5f20130Swlei 362eba57492Swlei void convertToProfileMap(ContextTrieNode &Node, 363eba57492Swlei SampleContextFrameVector &Context); 364eba57492Swlei 365eba57492Swlei void convertToProfileMap(); 366eba57492Swlei 367aa58b7b1Swlei void computeSummaryAndThreshold(); 368aa58b7b1Swlei 369aa58b7b1Swlei bool collectFunctionsFromLLVMProfile( 370aa58b7b1Swlei std::unordered_set<const BinaryFunction *> &ProfiledFunctions) override; 371aa58b7b1Swlei 3725d7950a4SHongtao Yu void initializeMissingFrameInferrer(); 3735d7950a4SHongtao Yu 3745d7950a4SHongtao Yu // Given an input `Context`, output `NewContext` with inferred missing tail 3755d7950a4SHongtao Yu // call frames. 3765d7950a4SHongtao Yu void inferMissingFrames(const SmallVectorImpl<uint64_t> &Context, 3775d7950a4SHongtao Yu SmallVectorImpl<uint64_t> &NewContext); 3785d7950a4SHongtao Yu getRootContext()379eba57492Swlei ContextTrieNode &getRootContext() { return ContextTracker.getRootContext(); }; 380eba57492Swlei 381eba57492Swlei // The container for holding the FunctionSamples used by context trie. 382eba57492Swlei std::list<FunctionSamples> FSamplesList; 383eba57492Swlei 384d5f20130Swlei // Underlying context table serves for sample profile writer. 385d5f20130Swlei std::unordered_set<SampleContextFrameVector, SampleContextFrameHash> Contexts; 386d5f20130Swlei 387eba57492Swlei SampleContextTracker ContextTracker; 388eba57492Swlei 389eba57492Swlei bool IsProfileValidOnTrie = true; 390eba57492Swlei 391d5f20130Swlei public: 392d5f20130Swlei // Deduplicate adjacent repeated context sequences up to a given sequence 393d5f20130Swlei // length. -1 means no size limit. 394d5f20130Swlei static int32_t MaxCompressionSize; 395d5f20130Swlei static int MaxContextDepth; 396c681400bSwlei }; 397c681400bSwlei 3981f05b1a9Swlei } // end namespace sampleprof 3991f05b1a9Swlei } // end namespace llvm 4001f05b1a9Swlei 4011f05b1a9Swlei #endif 402