23#define DEBUG_TYPE "inline-order"
33 .getCachedResult<ProfileSummaryAnalysis>(
34 *CB.
getParent()->getParent()->getParent());
50 Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
52 return getInlineCost(CB, Params, CallerTTI, GetAssumptionCache, GetTLI,
53 GetBFI, PSI, RemarksEnabled ? &ORE :
nullptr);
58 SizePriority() =
default;
62 Size = Callee->getInstructionCount();
65 static bool isMoreDesirable(
const SizePriority &P1,
const SizePriority &P2) {
66 return P1.Size < P2.Size;
70 unsigned Size = UINT_MAX;
75 CostPriority() =
default;
78 auto IC = getInlineCostWrapper(
const_cast<CallBase &
>(*CB),
FAM, Params);
82 Cost = IC.isNever() ? INT_MAX : INT_MIN;
85 static bool isMoreDesirable(
const CostPriority &P1,
const CostPriority &P2) {
86 return P1.Cost < P2.Cost;
93class CostBenefitPriority {
95 CostBenefitPriority() =
default;
98 auto IC = getInlineCostWrapper(
const_cast<CallBase &
>(*CB),
FAM, Params);
99 int StaticBonusApplied = 0;
100 if (IC.isVariable()) {
102 StaticBonusApplied = IC.getStaticBonusApplied();
105 Cost = IC.isNever() ? INT_MAX : INT_MIN;
112 .module_inliner_top_priority_threshold;
115 static bool isMoreDesirable(
const CostBenefitPriority &P1,
116 const CostBenefitPriority &P2) {
129 if (P1.ReducesCallerSize || P2.ReducesCallerSize) {
132 if (P1.ReducesCallerSize != P2.ReducesCallerSize)
133 return P1.ReducesCallerSize;
137 return P1.Cost < P2.Cost;
140 bool P1HasCB = P1.CostBenefit.has_value();
141 bool P2HasCB = P2.CostBenefit.has_value();
142 if (P1HasCB || P2HasCB) {
145 if (P1HasCB != P2HasCB)
150 APInt LHS = P1.CostBenefit->getBenefit() * P2.CostBenefit->getCost();
151 APInt RHS = P2.CostBenefit->getBenefit() * P1.CostBenefit->getCost();
156 return P1.Cost < P2.Cost;
161 bool ReducesCallerSize =
false;
167 MLPriority() =
default;
170 auto IC = getInlineCostWrapper(
const_cast<CallBase &
>(*CB),
FAM, Params);
174 Cost = IC.isNever() ? INT_MAX : INT_MIN;
177 static bool isMoreDesirable(
const MLPriority &P1,
const MLPriority &P2) {
178 return P1.Cost < P2.Cost;
185template <
typename PriorityT>
class PriorityInlineOrder :
public InlineOrder {
187 const auto I1 = Priorities.find(L);
188 const auto I2 = Priorities.find(R);
189 assert(I1 != Priorities.end() && I2 != Priorities.end());
190 return PriorityT::isMoreDesirable(I2->second, I1->second);
193 bool updateAndCheckDecreased(
const CallBase *CB) {
194 auto It = Priorities.find(CB);
195 const auto OldPriority = It->second;
196 It->second = PriorityT(CB,
FAM, Params);
197 const auto NewPriority = It->second;
198 return PriorityT::isMoreDesirable(OldPriority, NewPriority);
208 void pop_heap_adjust() {
209 std::pop_heap(Heap.begin(), Heap.end(), isLess);
210 while (updateAndCheckDecreased(Heap.back())) {
211 std::push_heap(Heap.begin(), Heap.end(), isLess);
212 std::pop_heap(Heap.begin(), Heap.end(), isLess);
218 :
FAM(
FAM), Params(Params) {
220 return hasLowerPriority(L, R);
224 size_t size()
override {
return Heap.size(); }
228 Priorities[CB] = PriorityT(CB,
FAM, Params);
229 std::push_heap(Heap.begin(), Heap.end(), isLess);
236 return Heap.pop_back_val();
241 std::make_heap(Heap.begin(), Heap.end(), isLess);
256std::unique_ptr<InlineOrder>
262 LLVM_DEBUG(
dbgs() <<
" Current used priority: Size priority ---- \n");
263 return std::make_unique<PriorityInlineOrder<SizePriority>>(
FAM, Params);
266 LLVM_DEBUG(
dbgs() <<
" Current used priority: Cost priority ---- \n");
267 return std::make_unique<PriorityInlineOrder<CostPriority>>(
FAM, Params);
271 dbgs() <<
" Current used priority: cost-benefit priority ---- \n");
272 return std::make_unique<PriorityInlineOrder<CostBenefitPriority>>(
FAM,
275 LLVM_DEBUG(
dbgs() <<
" Current used priority: ML priority ---- \n");
276 return std::make_unique<PriorityInlineOrder<MLPriority>>(
FAM, Params);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This is the interface for a simple mod/ref and alias analysis over globals.
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
Class for arbitrary precision integers.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
Represents the cost of inlining a function.
A Module instance is used to store all the information related to an LLVM module.
Used for dynamically loading instances of InlineOrder as plugins.
static LLVM_ABI AnalysisKey Key
Analysis providing profile information.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr, function_ref< EphemeralValuesCache &(Function &)> GetEphValuesCache=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI std::unique_ptr< InlineOrder > getDefaultInlineOrder(FunctionAnalysisManager &FAM, const InlineParams &Params, ModuleAnalysisManager &MAM, Module &M)
LLVM_ABI std::unique_ptr< InlineOrder > getInlineOrder(FunctionAnalysisManager &FAM, const InlineParams &Params, ModuleAnalysisManager &MAM, Module &M)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Thresholds to tune inline cost analysis.