1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- //===-- CSPreInliner.h - Profile guided preinliner ---------------- 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 LLVM_TOOLS_LLVM_PROFGEN_PGOINLINEADVISOR_H
- #define LLVM_TOOLS_LLVM_PROFGEN_PGOINLINEADVISOR_H
- #include "ProfiledBinary.h"
- #include "llvm/ADT/PriorityQueue.h"
- #include "llvm/ProfileData/ProfileCommon.h"
- #include "llvm/ProfileData/SampleProf.h"
- #include "llvm/Transforms/IPO/ProfiledCallGraph.h"
- #include "llvm/Transforms/IPO/SampleContextTracker.h"
- using namespace llvm;
- using namespace sampleprof;
- namespace llvm {
- namespace sampleprof {
- // Inline candidate seen from profile
- struct ProfiledInlineCandidate {
- ProfiledInlineCandidate(const FunctionSamples *Samples, uint64_t Count,
- uint32_t Size)
- : CalleeSamples(Samples), CallsiteCount(Count), SizeCost(Size) {}
- // Context-sensitive function profile for inline candidate
- const FunctionSamples *CalleeSamples;
- // Call site count for an inline candidate
- // TODO: make sure entry count for context profile and call site
- // target count for corresponding call are consistent.
- uint64_t CallsiteCount;
- // Size proxy for function under particular call context.
- uint64_t SizeCost;
- };
- // Inline candidate comparer using call site weight
- struct ProfiledCandidateComparer {
- bool operator()(const ProfiledInlineCandidate &LHS,
- const ProfiledInlineCandidate &RHS) {
- if (LHS.CallsiteCount != RHS.CallsiteCount)
- return LHS.CallsiteCount < RHS.CallsiteCount;
- if (LHS.SizeCost != RHS.SizeCost)
- return LHS.SizeCost > RHS.SizeCost;
- // Tie breaker using GUID so we have stable/deterministic inlining order
- assert(LHS.CalleeSamples && RHS.CalleeSamples &&
- "Expect non-null FunctionSamples");
- return LHS.CalleeSamples->getGUID(LHS.CalleeSamples->getName()) <
- RHS.CalleeSamples->getGUID(RHS.CalleeSamples->getName());
- }
- };
- using ProfiledCandidateQueue =
- PriorityQueue<ProfiledInlineCandidate, std::vector<ProfiledInlineCandidate>,
- ProfiledCandidateComparer>;
- // Pre-compilation inliner based on context-sensitive profile.
- // The PreInliner estimates inline decision using hotness from profile
- // and cost estimation from machine code size. It helps merges context
- // profile globally and achieves better post-inine profile quality, which
- // otherwise won't be possible for ThinLTO. It also reduce context profile
- // size by only keep context that is estimated to be inlined.
- class CSPreInliner {
- public:
- CSPreInliner(SampleProfileMap &Profiles, ProfiledBinary &Binary,
- uint64_t HotThreshold, uint64_t ColdThreshold);
- void run();
- private:
- bool getInlineCandidates(ProfiledCandidateQueue &CQueue,
- const FunctionSamples *FCallerContextSamples);
- std::vector<StringRef> buildTopDownOrder();
- void processFunction(StringRef Name);
- bool shouldInline(ProfiledInlineCandidate &Candidate);
- uint32_t getFuncSize(const FunctionSamples &FSamples);
- bool UseContextCost;
- SampleContextTracker ContextTracker;
- SampleProfileMap &ProfileMap;
- ProfiledBinary &Binary;
- // Count thresholds to answer isHotCount and isColdCount queries.
- // Mirrors the threshold in ProfileSummaryInfo.
- uint64_t HotCountThreshold;
- uint64_t ColdCountThreshold;
- };
- } // end namespace sampleprof
- } // end namespace llvm
- #endif
|