92 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- 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,
 | |
|                ProfileSummary *Summary);
 | |
|   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;
 | |
|   ProfileSummary *Summary;
 | |
| };
 | |
| 
 | |
| } // end namespace sampleprof
 | |
| } // end namespace llvm
 | |
| 
 | |
| #endif
 |