34#include "llvm/Config/llvm-config.h"
55#define DEBUG_TYPE "inline-cost"
57STATISTIC(NumCallsAnalyzed,
"Number of call sites analyzed");
61 cl::desc(
"Default amount of inlining to perform"));
65 cl::desc(
"Control the amount of inlining to perform (default = 225)"));
69 cl::desc(
"Threshold for inlining functions with inline hint"));
74 cl::desc(
"Threshold for inlining cold callsites"));
81 cl::desc(
"Threshold for inlining functions with cold attribute"));
85 cl::desc(
"Threshold for hot callsites "));
89 cl::desc(
"Threshold for locally hot callsites "));
93 cl::desc(
"Cost of a single instruction when inlining"));
121class InlineCostCallAnalyzer;
125struct InstructionCostDetail {
128 int ThresholdBefore = 0;
129 int ThresholdAfter = 0;
131 int getThresholdDelta()
const {
return ThresholdAfter - ThresholdBefore; }
133 int getCostDelta()
const {
return CostAfter - CostBefore; }
135 bool hasThresholdChanged()
const {
return ThresholdAfter != ThresholdBefore; }
140 InlineCostCallAnalyzer *
const ICCA;
143 InlineCostAnnotationWriter(InlineCostCallAnalyzer *ICCA) : ICCA(ICCA) {}
144 void emitInstructionAnnot(
const Instruction *
I,
145 formatted_raw_ostream &OS)
override;
156class CallAnalyzer :
public InstVisitor<CallAnalyzer, bool> {
157 typedef InstVisitor<CallAnalyzer, bool> Base;
158 friend class InstVisitor<CallAnalyzer, bool>;
161 virtual ~CallAnalyzer() =
default;
162 const AnalysisOptions &Opts;
165 const TargetTransformInfo &TTI;
168 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache;
171 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI;
174 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI;
177 ProfileSummaryInfo *PSI;
183 const DataLayout &DL;
186 OptimizationRemarkEmitter *ORE;
191 CallBase &CandidateCall;
194 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
nullptr;
198 virtual void onBlockStart(
const BasicBlock *BB) {}
201 virtual void onBlockAnalyzed(
const BasicBlock *BB) {}
204 virtual void onInstructionAnalysisStart(
const Instruction *
I) {}
207 virtual void onInstructionAnalysisFinish(
const Instruction *
I) {}
217 virtual bool shouldStop() {
return false; }
226 virtual void onDisableSROA(AllocaInst *Arg) {}
229 virtual void onDisableLoadElimination() {}
233 virtual bool onCallBaseVisitStart(CallBase &
Call) {
return true; }
236 virtual void onCallPenalty() {}
239 virtual void onMemAccess(){};
243 virtual void onLoadEliminationOpportunity() {}
247 virtual void onCallArgumentSetup(
const CallBase &
Call) {}
250 virtual void onLoadRelativeIntrinsic() {}
258 virtual bool onJumpTable(
unsigned JumpTableSize) {
return true; }
262 virtual bool onCaseCluster(
unsigned NumCaseCluster) {
return true; }
266 virtual void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
267 bool DefaultDestUnreachable) {}
271 virtual void onMissedSimplification() {}
274 virtual void onInlineAsm(
const InlineAsm &Arg) {}
277 virtual void onInitializeSROAArg(AllocaInst *Arg) {}
280 virtual void onAggregateSROAUse(AllocaInst *
V) {}
282 bool handleSROA(
Value *
V,
bool DoNotDisable) {
284 if (
auto *SROAArg = getSROAArgForValueOrNull(
V)) {
286 onAggregateSROAUse(SROAArg);
289 disableSROAForArg(SROAArg);
294 bool IsCallerRecursive =
false;
295 bool IsRecursiveCall =
false;
296 bool ExposesReturnsTwice =
false;
297 bool HasDynamicAlloca =
false;
298 bool ContainsNoDuplicateCall =
false;
299 bool HasReturn =
false;
300 bool HasIndirectBr =
false;
301 bool HasUninlineableIntrinsic =
false;
302 bool InitsVargArgs =
false;
306 unsigned NumInstructions = 0;
307 unsigned NumInlineAsmInstructions = 0;
308 unsigned NumVectorInstructions = 0;
318 DenseMap<Value *, Value *> SimplifiedValues;
322 DenseMap<Value *, AllocaInst *> SROAArgValues;
325 DenseSet<AllocaInst *> EnabledSROAAllocas;
328 DenseMap<Value *, std::pair<Value *, APInt>> ConstantOffsetPtrs;
331 SmallPtrSet<BasicBlock *, 16> DeadBlocks;
335 DenseMap<BasicBlock *, BasicBlock *> KnownSuccessors;
340 bool EnableLoadElimination =
true;
343 bool AllowRecursiveCall =
false;
345 SmallPtrSet<Value *, 16> LoadAddrSet;
347 AllocaInst *getSROAArgForValueOrNull(
Value *
V)
const {
348 auto It = SROAArgValues.find(
V);
349 if (It == SROAArgValues.end() || EnabledSROAAllocas.count(It->second) == 0)
356 template <
typename T>
T *getDirectOrSimplifiedValue(
Value *
V)
const {
359 return getSimplifiedValue<T>(
V);
363 bool isAllocaDerivedArg(
Value *
V);
364 void disableSROAForArg(AllocaInst *SROAArg);
365 void disableSROA(
Value *
V);
366 void findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB);
367 void disableLoadElimination();
368 bool isGEPFree(GetElementPtrInst &
GEP);
369 bool canFoldInboundsGEP(GetElementPtrInst &
I);
372 bool simplifyCmpInstForRecCall(CmpInst &Cmp);
374 bool simplifyIntrinsicCallIsConstant(CallBase &CB);
375 bool simplifyIntrinsicCallObjectSize(CallBase &CB);
376 ConstantInt *stripAndComputeInBoundsConstantOffsets(
Value *&
V);
388 bool isKnownNonNullInCallee(
Value *
V);
391 bool allowSizeGrowth(CallBase &
Call);
394 InlineResult analyzeBlock(BasicBlock *BB,
395 const SmallPtrSetImpl<const Value *> &EphValues);
403 void visit(BasicBlock *);
404 void visit(BasicBlock &);
407 bool visitInstruction(Instruction &
I);
410 bool visitAlloca(AllocaInst &
I);
411 bool visitPHI(PHINode &
I);
412 bool visitGetElementPtr(GetElementPtrInst &
I);
413 bool visitBitCast(BitCastInst &
I);
414 bool visitPtrToInt(PtrToIntInst &
I);
415 bool visitIntToPtr(IntToPtrInst &
I);
416 bool visitCastInst(CastInst &
I);
417 bool visitCmpInst(CmpInst &
I);
418 bool visitSub(BinaryOperator &
I);
419 bool visitBinaryOperator(BinaryOperator &
I);
420 bool visitFNeg(UnaryOperator &
I);
421 bool visitLoad(LoadInst &
I);
422 bool visitStore(StoreInst &
I);
423 bool visitExtractValue(ExtractValueInst &
I);
424 bool visitInsertValue(InsertValueInst &
I);
425 bool visitCallBase(CallBase &
Call);
426 bool visitReturnInst(ReturnInst &RI);
427 bool visitUncondBrInst(UncondBrInst &BI);
428 bool visitCondBrInst(CondBrInst &BI);
429 bool visitSelectInst(SelectInst &SI);
430 bool visitSwitchInst(SwitchInst &SI);
431 bool visitIndirectBrInst(IndirectBrInst &IBI);
432 bool visitResumeInst(ResumeInst &RI);
433 bool visitCleanupReturnInst(CleanupReturnInst &RI);
434 bool visitCatchReturnInst(CatchReturnInst &RI);
435 bool visitUnreachableInst(UnreachableInst &
I);
439 Function &Callee, CallBase &
Call,
const TargetTransformInfo &TTI,
440 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
441 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
442 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
443 ProfileSummaryInfo *PSI =
nullptr,
444 OptimizationRemarkEmitter *ORE =
nullptr,
445 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
448 GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI), GetTLI(GetTLI),
449 PSI(PSI), F(
Callee), DL(F.getDataLayout()), ORE(ORE),
450 CandidateCall(
Call), GetEphValuesCache(GetEphValuesCache) {}
452 InlineResult analyze();
455 Value *getSimplifiedValueUnchecked(
Value *
V)
const {
456 return SimplifiedValues.lookup(
V);
461 template <
typename T>
T *getSimplifiedValue(
Value *
V)
const {
462 Value *SimpleV = SimplifiedValues.lookup(
V);
468 if constexpr (std::is_base_of_v<Constant, T>)
473 if (
I->getFunction() != &F)
476 if (Arg->getParent() != &F)
485 unsigned NumConstantArgs = 0;
486 unsigned NumConstantOffsetPtrArgs = 0;
487 unsigned NumAllocaArgs = 0;
488 unsigned NumConstantPtrCmps = 0;
489 unsigned NumConstantPtrDiffs = 0;
490 unsigned NumInstructionsSimplified = 0;
510int64_t getExpectedNumberOfCompare(
int NumCaseCluster) {
511 return 3 *
static_cast<int64_t
>(NumCaseCluster) / 2 - 1;
516class InlineCostCallAnalyzer final :
public CallAnalyzer {
517 const bool ComputeFullInlineCost;
518 int LoadEliminationCost = 0;
523 int SingleBBBonus = 0;
526 const InlineParams &Params;
531 DenseMap<const Instruction *, InstructionCostDetail> InstructionCostDetailMap;
538 int StaticBonusApplied = 0;
541 const bool BoostIndirectCalls;
544 const bool IgnoreThreshold;
547 const bool CostBenefitAnalysisEnabled;
549 const bool PrintInstructionComments;
560 int CostAtBBStart = 0;
567 bool DecidedByCostThreshold =
false;
570 bool DecidedByCostBenefit =
false;
573 std::optional<CostBenefitPair> CostBenefit;
575 bool SingleBB =
true;
577 unsigned SROACostSavings = 0;
578 unsigned SROACostSavingsLost = 0;
583 DenseMap<AllocaInst *, int> SROAArgCosts;
594 std::optional<int> getHotCallSiteThreshold(CallBase &
Call,
595 BlockFrequencyInfo *CallerBFI);
598 void addCost(int64_t Inc) {
599 Inc = std::clamp<int64_t>(Inc, INT_MIN, INT_MAX);
600 Cost = std::clamp<int64_t>(Inc + Cost, INT_MIN, INT_MAX);
603 void onDisableSROA(AllocaInst *Arg)
override {
604 auto CostIt = SROAArgCosts.find(Arg);
605 if (CostIt == SROAArgCosts.end())
607 addCost(CostIt->second);
608 SROACostSavings -= CostIt->second;
609 SROACostSavingsLost += CostIt->second;
610 SROAArgCosts.erase(CostIt);
613 void onDisableLoadElimination()
override {
614 addCost(LoadEliminationCost);
615 LoadEliminationCost = 0;
618 bool onCallBaseVisitStart(CallBase &
Call)
override {
619 if (std::optional<int> AttrCallThresholdBonus =
621 Threshold += *AttrCallThresholdBonus;
623 if (std::optional<int> AttrCallCost =
625 addCost(*AttrCallCost);
633 void onCallPenalty()
override { addCost(Opts.inline_call_penalty); }
635 void onMemAccess()
override { addCost(Opts.inline_memaccess_cost); }
637 void onCallArgumentSetup(
const CallBase &
Call)
override {
642 void onLoadRelativeIntrinsic()
override {
657 auto IndirectCallParams = Params;
658 IndirectCallParams.DefaultThreshold =
662 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
663 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
665 if (CA.analyze().isSuccess()) {
668 addCost(-std::max(0, CA.getThreshold() - CA.getCost()));
673 Opts.inline_call_penalty));
676 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
677 bool DefaultDestUnreachable)
override {
684 if (!DefaultDestUnreachable)
693 if (NumCaseCluster <= 3) {
697 addCost((NumCaseCluster - DefaultDestUnreachable) * 2 *
InstrCost);
701 int64_t ExpectedNumberOfCompare =
702 getExpectedNumberOfCompare(NumCaseCluster);
703 int64_t SwitchCost = ExpectedNumberOfCompare * 2 *
InstrCost;
711 void onInlineAsm(
const InlineAsm &Arg)
override {
712 if (!Opts.inline_asm_instr_cost)
716 int SectionLevel = 0;
717 int InlineAsmInstrCount = 0;
718 for (StringRef AsmStr : AsmStrs) {
720 StringRef Trimmed = AsmStr.trim();
721 size_t hashPos = Trimmed.
find(
'#');
723 Trimmed = Trimmed.
substr(0, hashPos);
742 if (SectionLevel == 0)
743 ++InlineAsmInstrCount;
745 NumInlineAsmInstructions += InlineAsmInstrCount;
746 addCost(InlineAsmInstrCount * Opts.inline_asm_instr_cost);
749 void onMissedSimplification()
override { addCost(
InstrCost); }
751 void onInitializeSROAArg(AllocaInst *Arg)
override {
753 "Should not initialize SROA costs for null value.");
755 SROACostSavings += SROAArgCost;
756 SROAArgCosts[Arg] = SROAArgCost;
759 void onAggregateSROAUse(AllocaInst *SROAArg)
override {
760 auto CostIt = SROAArgCosts.find(SROAArg);
761 assert(CostIt != SROAArgCosts.end() &&
762 "expected this argument to have a cost");
767 void onBlockStart(
const BasicBlock *BB)
override { CostAtBBStart = Cost; }
769 void onBlockAnalyzed(
const BasicBlock *BB)
override {
770 if (CostBenefitAnalysisEnabled) {
773 assert(GetBFI &&
"GetBFI must be available");
774 BlockFrequencyInfo *BFI = &(GetBFI(
F));
775 assert(BFI &&
"BFI must be available");
777 if (*ProfileCount == 0)
778 ColdSize += Cost - CostAtBBStart;
786 if (SingleBB && TI->getNumSuccessors() > 1) {
788 Threshold -= SingleBBBonus;
793 void onInstructionAnalysisStart(
const Instruction *
I)
override {
796 if (!PrintInstructionComments)
798 auto &CostDetail = InstructionCostDetailMap[
I];
799 CostDetail.CostBefore = Cost;
800 CostDetail.ThresholdBefore = Threshold;
803 void onInstructionAnalysisFinish(
const Instruction *
I)
override {
806 if (!PrintInstructionComments)
808 auto &CostDetail = InstructionCostDetailMap[
I];
809 CostDetail.CostAfter = Cost;
810 CostDetail.ThresholdAfter = Threshold;
813 bool isCostBenefitAnalysisEnabled() {
814 if (!PSI || !PSI->hasProfileSummary())
821 if (!
valueOr(Opts.inline_enable_cost_benefit_analysis,
822 PSI->hasInstrumentationProfile()))
826 if (!
Caller->getEntryCount())
829 BlockFrequencyInfo *CallerBFI = &(GetBFI(*Caller));
834 if (!PSI->isHotCallSite(CandidateCall, CallerBFI))
838 auto EntryCount =
F.getEntryCount();
839 if (!EntryCount || *EntryCount == 0)
842 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
850 unsigned getInliningCostBenefitAnalysisSavingsMultiplier()
const {
851 return Opts.inline_savings_multiplier.value_or(
856 unsigned getInliningCostBenefitAnalysisProfitableMultiplier()
const {
857 return Opts.inline_savings_profitable_multiplier.value_or(
861 void OverrideCycleSavingsAndSizeForTesting(APInt &CycleSavings,
int &
Size) {
863 CandidateCall,
"inline-cycle-savings-for-test")) {
864 CycleSavings = *AttrCycleSavings;
868 CandidateCall,
"inline-runtime-cost-for-test")) {
869 Size = *AttrRuntimeCost;
876 std::optional<bool> costBenefitAnalysis() {
877 if (!CostBenefitAnalysisEnabled)
888 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
901 APInt CycleSavings(128, 0);
904 APInt CurrentSavings(128, 0);
908 if (getSimplifiedValue<ConstantInt>(BI->getCondition()))
911 if (getSimplifiedValue<ConstantInt>(
SI->getCondition()))
913 }
else if (SimplifiedValues.
count(&
I)) {
920 CurrentSavings *= *ProfileCount;
921 CycleSavings += CurrentSavings;
925 auto EntryProfileCount =
F.getEntryCount();
926 assert(EntryProfileCount && *EntryProfileCount);
927 CycleSavings += *EntryProfileCount / 2;
928 CycleSavings = CycleSavings.
udiv(*EntryProfileCount);
931 auto *CallerBB = CandidateCall.
getParent();
932 BlockFrequencyInfo *CallerBFI = &(GetBFI(*(CallerBB->getParent())));
939 int Size = Cost - ColdSize;
943 Size =
Size > Opts.inline_size_allowance ?
Size - Opts.inline_size_allowance
946 OverrideCycleSavingsAndSizeForTesting(CycleSavings,
Size);
947 CostBenefit.emplace(APInt(128,
Size), CycleSavings);
970 APInt Threshold(128, PSI->getOrCompHotCountThreshold());
973 APInt UpperBoundCycleSavings = CycleSavings;
974 UpperBoundCycleSavings *= getInliningCostBenefitAnalysisSavingsMultiplier();
975 if (UpperBoundCycleSavings.
uge(Threshold))
978 APInt LowerBoundCycleSavings = CycleSavings;
979 LowerBoundCycleSavings *=
980 getInliningCostBenefitAnalysisProfitableMultiplier();
981 if (LowerBoundCycleSavings.
ult(Threshold))
988 InlineResult finalizeAnalysis()
override {
995 if (
Caller->hasMinSize()) {
1001 if (DeadBlocks.
count(
L->getHeader()))
1011 if (NumVectorInstructions <= NumInstructions / 10)
1012 Threshold -= VectorBonus;
1013 else if (NumVectorInstructions <= NumInstructions / 2)
1014 Threshold -= VectorBonus / 2;
1016 if (std::optional<int> AttrCost =
1023 Cost *= *AttrCostMult;
1025 if (std::optional<int> AttrThreshold =
1027 Threshold = *AttrThreshold;
1029 if (
auto Result = costBenefitAnalysis()) {
1030 DecidedByCostBenefit =
true;
1037 if (IgnoreThreshold)
1040 DecidedByCostThreshold =
true;
1041 return Cost < std::max(1, Threshold)
1043 : InlineResult::
failure(
"Cost over threshold.");
1046 bool shouldStop()
override {
1047 if (IgnoreThreshold || ComputeFullInlineCost)
1051 if (Cost < Threshold)
1053 DecidedByCostThreshold =
true;
1057 void onLoadEliminationOpportunity()
override {
1061 InlineResult onAnalysisStart()
override {
1072 assert(NumInstructions == 0);
1073 assert(NumVectorInstructions == 0);
1076 updateThreshold(CandidateCall,
F);
1082 assert(SingleBBBonus >= 0);
1083 assert(VectorBonus >= 0);
1088 Threshold += (SingleBBBonus + VectorBonus);
1096 if (
F.getCallingConv() == CallingConv::Cold)
1102 if (Cost >= Threshold && !ComputeFullInlineCost)
1109 InlineCostCallAnalyzer(
1110 Function &Callee, CallBase &
Call,
const InlineParams &Params,
1111 const TargetTransformInfo &
TTI,
1112 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
1113 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
1114 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
1115 ProfileSummaryInfo *PSI =
nullptr,
1116 OptimizationRemarkEmitter *ORE =
nullptr,
bool BoostIndirect =
true,
1117 bool IgnoreThreshold =
false,
1118 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
1120 bool PrintInstructionComments =
false)
1121 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI, PSI,
1122 ORE, GetEphValuesCache),
1123 ComputeFullInlineCost(Opts.inline_cost_full ||
1124 Params.ComputeFullInlineCost || ORE ||
1125 isCostBenefitAnalysisEnabled()),
1127 BoostIndirectCalls(BoostIndirect), IgnoreThreshold(IgnoreThreshold),
1128 CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
1129 PrintInstructionComments(Opts.print_instruction_comments ||
1130 PrintInstructionComments),
1132 AllowRecursiveCall = *Params.AllowRecursiveCall;
1136 InlineCostAnnotationWriter Writer;
1142 void print(raw_ostream &OS);
1144 std::optional<InstructionCostDetail> getCostDetails(
const Instruction *
I) {
1145 auto It = InstructionCostDetailMap.find(
I);
1146 if (It != InstructionCostDetailMap.end())
1148 return std::nullopt;
1151 ~InlineCostCallAnalyzer()
override =
default;
1152 int getThreshold()
const {
return Threshold; }
1153 int getCost()
const {
return Cost; }
1154 int getStaticBonusApplied()
const {
return StaticBonusApplied; }
1155 std::optional<CostBenefitPair> getCostBenefitPair() {
return CostBenefit; }
1156 bool wasDecidedByCostBenefit()
const {
return DecidedByCostBenefit; }
1157 bool wasDecidedByCostThreshold()
const {
return DecidedByCostThreshold; }
1165static bool isSoleCallToLocalFunction(
const CallBase &CB,
1168 (
Callee.hasLinkOnceODRLinkage() &&
1169 Callee.hasFnAttribute(Attribute::LikelyModuleLocal));
1173class InlineCostFeaturesAnalyzer final :
public CallAnalyzer {
1180 static constexpr int JTCostMultiplier = 2;
1181 static constexpr int CaseClusterCostMultiplier = 2;
1182 static constexpr int SwitchDefaultDestCostMultiplier = 2;
1183 static constexpr int SwitchCostMultiplier = 2;
1187 unsigned SROACostSavingOpportunities = 0;
1188 int VectorBonus = 0;
1189 int SingleBBBonus = 0;
1192 DenseMap<AllocaInst *, unsigned> SROACosts;
1195 Cost[
static_cast<size_t>(Feature)] += Delta;
1199 Cost[
static_cast<size_t>(Feature)] =
Value;
1202 void onDisableSROA(AllocaInst *Arg)
override {
1203 auto CostIt = SROACosts.find(Arg);
1204 if (CostIt == SROACosts.end())
1207 increment(InlineCostFeatureIndex::sroa_losses, CostIt->second);
1208 SROACostSavingOpportunities -= CostIt->second;
1209 SROACosts.erase(CostIt);
1212 void onDisableLoadElimination()
override {
1213 set(InlineCostFeatureIndex::load_elimination, 1);
1216 void onCallPenalty()
override {
1217 increment(InlineCostFeatureIndex::call_penalty, Opts.inline_call_penalty);
1220 void onCallArgumentSetup(
const CallBase &
Call)
override {
1221 increment(InlineCostFeatureIndex::call_argument_setup,
1225 void onLoadRelativeIntrinsic()
override {
1226 increment(InlineCostFeatureIndex::load_relative_intrinsic, 3 *
InstrCost);
1231 increment(InlineCostFeatureIndex::lowered_call_arg_setup,
1235 InlineParams IndirectCallParams = { 0,
1249 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
1250 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
1252 if (CA.analyze().isSuccess()) {
1253 increment(InlineCostFeatureIndex::nested_inline_cost_estimate,
1255 increment(InlineCostFeatureIndex::nested_inlines, 1);
1262 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
1263 bool DefaultDestUnreachable)
override {
1264 if (JumpTableSize) {
1265 if (!DefaultDestUnreachable)
1266 increment(InlineCostFeatureIndex::switch_default_dest_penalty,
1267 SwitchDefaultDestCostMultiplier *
InstrCost);
1268 int64_t JTCost =
static_cast<int64_t
>(JumpTableSize) *
InstrCost +
1270 increment(InlineCostFeatureIndex::jump_table_penalty, JTCost);
1274 if (NumCaseCluster <= 3) {
1275 increment(InlineCostFeatureIndex::case_cluster_penalty,
1276 (NumCaseCluster - DefaultDestUnreachable) *
1281 int64_t ExpectedNumberOfCompare =
1282 getExpectedNumberOfCompare(NumCaseCluster);
1284 int64_t SwitchCost =
1285 ExpectedNumberOfCompare * SwitchCostMultiplier *
InstrCost;
1286 increment(InlineCostFeatureIndex::switch_penalty, SwitchCost);
1289 void onMissedSimplification()
override {
1290 increment(InlineCostFeatureIndex::unsimplified_common_instructions,
1294 void onInitializeSROAArg(AllocaInst *Arg)
override {
1296 SROACosts[Arg] = SROAArgCost;
1297 SROACostSavingOpportunities += SROAArgCost;
1300 void onAggregateSROAUse(AllocaInst *Arg)
override {
1301 SROACosts.find(Arg)->second +=
InstrCost;
1302 SROACostSavingOpportunities +=
InstrCost;
1305 void onBlockAnalyzed(
const BasicBlock *BB)
override {
1307 set(InlineCostFeatureIndex::is_multiple_blocks, 1);
1308 Threshold -= SingleBBBonus;
1311 InlineResult finalizeAnalysis()
override {
1313 if (
Caller->hasMinSize()) {
1316 for (
Loop *L : LI) {
1318 if (DeadBlocks.
count(
L->getHeader()))
1320 increment(InlineCostFeatureIndex::num_loops,
1324 set(InlineCostFeatureIndex::dead_blocks, DeadBlocks.
size());
1325 set(InlineCostFeatureIndex::simplified_instructions,
1326 NumInstructionsSimplified);
1327 set(InlineCostFeatureIndex::constant_args, NumConstantArgs);
1328 set(InlineCostFeatureIndex::constant_offset_ptr_args,
1329 NumConstantOffsetPtrArgs);
1330 set(InlineCostFeatureIndex::sroa_savings, SROACostSavingOpportunities);
1332 if (NumVectorInstructions <= NumInstructions / 10)
1333 Threshold -= VectorBonus;
1334 else if (NumVectorInstructions <= NumInstructions / 2)
1335 Threshold -= VectorBonus / 2;
1337 set(InlineCostFeatureIndex::threshold, Threshold);
1342 bool shouldStop()
override {
return false; }
1344 void onLoadEliminationOpportunity()
override {
1345 increment(InlineCostFeatureIndex::load_elimination, 1);
1348 InlineResult onAnalysisStart()
override {
1349 increment(InlineCostFeatureIndex::callsite_cost,
1352 set(InlineCostFeatureIndex::cold_cc_penalty,
1353 (
F.getCallingConv() == CallingConv::Cold));
1355 set(InlineCostFeatureIndex::last_call_to_static_bonus,
1356 isSoleCallToLocalFunction(CandidateCall,
F));
1361 int SingleBBBonusPercent = 50;
1365 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
1366 VectorBonus = Threshold * VectorBonusPercent / 100;
1367 Threshold += (SingleBBBonus + VectorBonus);
1373 InlineCostFeaturesAnalyzer(
1374 const TargetTransformInfo &
TTI,
1375 function_ref<AssumptionCache &(
Function &)> &GetAssumptionCache,
1376 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI,
1377 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI,
1378 ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
Function &Callee,
1380 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI,
1389bool CallAnalyzer::isAllocaDerivedArg(
Value *
V) {
1390 return SROAArgValues.
count(
V);
1393void CallAnalyzer::disableSROAForArg(AllocaInst *SROAArg) {
1394 onDisableSROA(SROAArg);
1395 EnabledSROAAllocas.
erase(SROAArg);
1396 disableLoadElimination();
1399void InlineCostAnnotationWriter::emitInstructionAnnot(
1400 const Instruction *
I, formatted_raw_ostream &OS) {
1404 std::optional<InstructionCostDetail>
Record = ICCA->getCostDetails(
I);
1406 OS <<
"; No analysis for the instruction";
1408 OS <<
"; cost before = " <<
Record->CostBefore
1409 <<
", cost after = " <<
Record->CostAfter
1410 <<
", threshold before = " <<
Record->ThresholdBefore
1411 <<
", threshold after = " <<
Record->ThresholdAfter <<
", ";
1412 OS <<
"cost delta = " <<
Record->getCostDelta();
1413 if (
Record->hasThresholdChanged())
1414 OS <<
", threshold delta = " <<
Record->getThresholdDelta();
1416 auto *
V = ICCA->getSimplifiedValueUnchecked(
const_cast<Instruction *
>(
I));
1418 OS <<
", simplified to ";
1421 if (
VI->getFunction() !=
I->getFunction())
1422 OS <<
" (caller instruction)";
1424 if (VArg->getParent() !=
I->getFunction())
1425 OS <<
" (caller argument)";
1432void CallAnalyzer::disableSROA(
Value *
V) {
1433 if (
auto *SROAArg = getSROAArgForValueOrNull(
V)) {
1434 disableSROAForArg(SROAArg);
1438void CallAnalyzer::disableLoadElimination() {
1439 if (EnableLoadElimination) {
1440 onDisableLoadElimination();
1441 EnableLoadElimination =
false;
1449bool CallAnalyzer::accumulateGEPOffset(GEPOperator &
GEP, APInt &
Offset) {
1450 unsigned IntPtrWidth =
DL.getIndexTypeSizeInBits(
GEP.getType());
1454 GTI != GTE; ++GTI) {
1456 getDirectOrSimplifiedValue<ConstantInt>(GTI.getOperand());
1463 if (StructType *STy = GTI.getStructTypeOrNull()) {
1465 const StructLayout *SL =
DL.getStructLayout(STy);
1470 APInt TypeSize(IntPtrWidth, GTI.getSequentialElementStride(
DL));
1479bool CallAnalyzer::isGEPFree(GetElementPtrInst &
GEP) {
1482 for (
const Use &
Op :
GEP.indices())
1483 if (Constant *SimpleOp = getSimplifiedValue<Constant>(
Op))
1492bool CallAnalyzer::visitAlloca(AllocaInst &
I) {
1493 disableSROA(
I.getOperand(0));
1497 if (
I.isArrayAllocation()) {
1498 Constant *
Size = getSimplifiedValue<Constant>(
I.getArraySize());
1509 AllocSize->getLimitedValue(),
1510 I.getAllocationBaseSize(
DL).getKnownMinValue(), AllocatedSize);
1512 HasDynamicAlloca =
true;
1517 if (
I.isStaticAlloca()) {
1529 HasDynamicAlloca =
true;
1535bool CallAnalyzer::visitPHI(PHINode &
I) {
1547 bool CheckSROA =
I.getType()->isPointerTy();
1551 std::pair<Value *, APInt> FirstBaseAndOffset = {
nullptr, ZeroOffset};
1552 Value *FirstV =
nullptr;
1554 for (
unsigned i = 0, e =
I.getNumIncomingValues(); i != e; ++i) {
1562 if (KnownSuccessor && KnownSuccessor !=
I.getParent())
1565 Value *
V =
I.getIncomingValue(i);
1570 Constant *
C = getDirectOrSimplifiedValue<Constant>(
V);
1572 std::pair<Value *, APInt> BaseAndOffset = {
nullptr, ZeroOffset};
1573 if (!
C && CheckSROA)
1574 BaseAndOffset = ConstantOffsetPtrs.
lookup(
V);
1576 if (!
C && !BaseAndOffset.first)
1593 if (FirstBaseAndOffset == BaseAndOffset)
1607 FirstBaseAndOffset = BaseAndOffset;
1612 SimplifiedValues[&
I] = FirstC;
1617 if (FirstBaseAndOffset.first) {
1618 ConstantOffsetPtrs[&
I] = std::move(FirstBaseAndOffset);
1620 if (
auto *SROAArg = getSROAArgForValueOrNull(FirstV))
1621 SROAArgValues[&
I] = SROAArg;
1631bool CallAnalyzer::canFoldInboundsGEP(GetElementPtrInst &
I) {
1633 std::pair<Value *, APInt> BaseAndOffset =
1634 ConstantOffsetPtrs.
lookup(
I.getPointerOperand());
1635 if (!BaseAndOffset.first)
1644 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1649bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &
I) {
1650 auto *SROAArg = getSROAArgForValueOrNull(
I.getPointerOperand());
1653 auto IsGEPOffsetConstant = [&](GetElementPtrInst &
GEP) {
1654 for (
const Use &
Op :
GEP.indices())
1655 if (!getDirectOrSimplifiedValue<Constant>(
Op))
1660 if (Opts.gep_const_evaluation)
1664 if ((
I.isInBounds() && canFoldInboundsGEP(
I)) || IsGEPOffsetConstant(
I)) {
1666 SROAArgValues[&
I] = SROAArg;
1674 disableSROAForArg(SROAArg);
1675 return isGEPFree(
I);
1681bool CallAnalyzer::simplifyCmpInstForRecCall(CmpInst &Cmp) {
1685 auto *CmpOp =
Cmp.getOperand(0);
1690 auto *CallBB = CandidateCall.
getParent();
1691 auto *Predecessor = CallBB->getSinglePredecessor();
1696 if (!Br || Br->getCondition() != &Cmp)
1701 bool ArgFound =
false;
1702 Value *FuncArg =
nullptr, *CallArg =
nullptr;
1703 for (
unsigned ArgNum = 0;
1704 ArgNum <
F.arg_size() && ArgNum < CandidateCall.
arg_size(); ArgNum++) {
1705 FuncArg =
F.getArg(ArgNum);
1707 if (FuncArg == CmpOp && CallArg != CmpOp) {
1718 CondContext
CC(&Cmp);
1719 CC.Invert = (CallBB != Br->getSuccessor(0));
1721 CC.AffectedValues.insert(FuncArg);
1727 if ((ConstVal->isOne() &&
CC.Invert) ||
1728 (ConstVal->isZero() && !
CC.Invert)) {
1729 SimplifiedValues[&
Cmp] = ConstVal;
1737bool CallAnalyzer::simplifyInstruction(Instruction &
I) {
1740 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
1748 SimplifiedValues[&
I] =
C;
1761bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
1763 auto *
C = getDirectOrSimplifiedValue<Constant>(Arg);
1766 SimplifiedValues[&CB] = ConstantInt::get(RT,
C ? 1 : 0);
1770bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
1780 SimplifiedValues[&CB] =
C;
1784bool CallAnalyzer::visitBitCast(BitCastInst &
I) {
1790 std::pair<Value *, APInt> BaseAndOffset =
1791 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1793 if (BaseAndOffset.first)
1794 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1797 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1798 SROAArgValues[&
I] = SROAArg;
1804bool CallAnalyzer::visitPtrToInt(PtrToIntInst &
I) {
1812 unsigned AS =
I.getOperand(0)->getType()->getPointerAddressSpace();
1813 if (IntegerSize ==
DL.getPointerSizeInBits(AS)) {
1814 std::pair<Value *, APInt> BaseAndOffset =
1815 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1816 if (BaseAndOffset.first)
1817 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1827 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1828 SROAArgValues[&
I] = SROAArg;
1834bool CallAnalyzer::visitIntToPtr(IntToPtrInst &
I) {
1842 unsigned IntegerSize =
Op->getType()->getScalarSizeInBits();
1843 if (IntegerSize <=
DL.getPointerTypeSizeInBits(
I.getType())) {
1844 std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.
lookup(
Op);
1845 if (BaseAndOffset.first)
1846 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1850 if (
auto *SROAArg = getSROAArgForValueOrNull(
Op))
1851 SROAArgValues[&
I] = SROAArg;
1857bool CallAnalyzer::visitCastInst(CastInst &
I) {
1864 disableSROA(
I.getOperand(0));
1869 switch (
I.getOpcode()) {
1870 case Instruction::FPTrunc:
1871 case Instruction::FPExt:
1872 case Instruction::UIToFP:
1873 case Instruction::SIToFP:
1874 case Instruction::FPToUI:
1875 case Instruction::FPToSI:
1887bool CallAnalyzer::paramHasAttr(Argument *
A, Attribute::AttrKind Attr) {
1891bool CallAnalyzer::isKnownNonNullInCallee(
Value *
V) {
1904 if (isAllocaDerivedArg(
V))
1913bool CallAnalyzer::allowSizeGrowth(CallBase &
Call) {
1938bool InlineCostCallAnalyzer::isColdCallSite(CallBase &
Call,
1939 BlockFrequencyInfo *CallerBFI) {
1942 if (PSI && PSI->hasProfileSummary())
1943 return PSI->isColdCallSite(
Call, CallerBFI);
1953 const BranchProbability ColdProb(Opts.cold_callsite_rel_freq, 100);
1955 auto CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1956 auto CallerEntryFreq =
1958 return CallSiteFreq < CallerEntryFreq * ColdProb;
1962InlineCostCallAnalyzer::getHotCallSiteThreshold(CallBase &
Call,
1963 BlockFrequencyInfo *CallerBFI) {
1967 if (PSI && PSI->hasProfileSummary() && PSI->isHotCallSite(
Call, CallerBFI))
1973 return std::nullopt;
1980 BlockFrequency CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1981 BlockFrequency CallerEntryFreq = CallerBFI->
getEntryFreq();
1982 std::optional<BlockFrequency> Limit =
1983 CallerEntryFreq.
mul(Opts.hot_callsite_rel_freq);
1984 if (Limit && CallSiteFreq >= *Limit)
1988 return std::nullopt;
1991void InlineCostCallAnalyzer::updateThreshold(CallBase &
Call,
Function &Callee) {
1993 if (!allowSizeGrowth(
Call)) {
2001 auto MinIfValid = [](
int A, std::optional<int>
B) {
2002 return B ? std::min(
A, *
B) :
A;
2006 auto MaxIfValid = [](
int A, std::optional<int>
B) {
2007 return B ? std::max(
A, *
B) :
A;
2022 int SingleBBBonusPercent = 50;
2027 auto DisallowAllBonuses = [&]() {
2028 SingleBBBonusPercent = 0;
2029 VectorBonusPercent = 0;
2030 LastCallToStaticBonus = 0;
2035 if (
Caller->hasMinSize()) {
2041 SingleBBBonusPercent = 0;
2042 VectorBonusPercent = 0;
2043 }
else if (
Caller->hasOptSize())
2048 if (!
Caller->hasMinSize()) {
2052 if (
Callee.hasFnAttribute(Attribute::InlineHint))
2062 BlockFrequencyInfo *CallerBFI = GetBFI ? &(GetBFI(*Caller)) : nullptr;
2083 DisallowAllBonuses();
2088 if (PSI->isFunctionEntryHot(&Callee)) {
2094 }
else if (PSI->isFunctionEntryCold(&Callee)) {
2100 DisallowAllBonuses();
2112 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
2113 VectorBonus = Threshold * VectorBonusPercent / 100;
2118 if (isSoleCallToLocalFunction(
Call,
F)) {
2119 addCost(-LastCallToStaticBonus);
2120 StaticBonusApplied = LastCallToStaticBonus;
2124bool CallAnalyzer::visitCmpInst(CmpInst &
I) {
2131 if (simplifyCmpInstForRecCall(
I))
2134 if (
I.getOpcode() == Instruction::FCmp)
2139 Value *LHSBase, *RHSBase;
2140 APInt LHSOffset, RHSOffset;
2141 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2143 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2144 if (RHSBase && LHSBase == RHSBase) {
2150 ++NumConstantPtrCmps;
2155 auto isImplicitNullCheckCmp = [](
const CmpInst &
I) {
2156 for (
auto *User :
I.users())
2158 if (!
Instr->getMetadata(LLVMContext::MD_make_implicit))
2166 if (isKnownNonNullInCallee(
I.getOperand(0))) {
2174 if (isImplicitNullCheckCmp(
I))
2180bool CallAnalyzer::visitSub(BinaryOperator &
I) {
2184 Value *LHSBase, *RHSBase;
2185 APInt LHSOffset, RHSOffset;
2186 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2188 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2189 if (RHSBase && LHSBase == RHSBase) {
2195 SimplifiedValues[&
I] =
C;
2196 ++NumConstantPtrDiffs;
2204 return Base::visitSub(
I);
2207bool CallAnalyzer::visitBinaryOperator(BinaryOperator &
I) {
2209 Constant *CLHS = getDirectOrSimplifiedValue<Constant>(
LHS);
2210 Constant *CRHS = getDirectOrSimplifiedValue<Constant>(
RHS);
2212 Value *SimpleV =
nullptr;
2215 FI->getFastMathFlags(),
DL);
2221 SimplifiedValues[&
I] =
C;
2233 using namespace llvm::PatternMatch;
2235 if (
I.getType()->isFloatingPointTy() &&
2243 Type *Ty =
I.getType();
2251bool CallAnalyzer::visitFNeg(UnaryOperator &
I) {
2253 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
2259 SimplifiedValues[&
I] =
C;
2270bool CallAnalyzer::visitLoad(LoadInst &
I) {
2271 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2277 if (EnableLoadElimination &&
2278 !LoadAddrSet.
insert(
I.getPointerOperand()).second &&
I.isUnordered()) {
2279 onLoadEliminationOpportunity();
2287bool CallAnalyzer::visitStore(StoreInst &
I) {
2288 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2299 disableLoadElimination();
2305bool CallAnalyzer::visitExtractValue(ExtractValueInst &
I) {
2306 Value *
Op =
I.getAggregateOperand();
2310 if (
Value *SimpleOp = getSimplifiedValueUnchecked(
Op)) {
2311 SimplifyQuery SQ(
DL);
2314 SimplifiedValues[&
I] = SimpleV;
2320 return Base::visitExtractValue(
I);
2323bool CallAnalyzer::visitInsertValue(InsertValueInst &
I) {
2329 return Base::visitInsertValue(
I);
2338bool CallAnalyzer::simplifyCallSite(
Function *
F, CallBase &
Call) {
2347 SmallVector<Constant *, 4> ConstantArgs;
2350 Constant *
C = getDirectOrSimplifiedValue<Constant>(
I);
2357 SimplifiedValues[&
Call] =
C;
2364bool CallAnalyzer::isLoweredToCall(
Function *
F, CallBase &
Call) {
2365 const TargetLibraryInfo *
TLI = GetTLI ? &GetTLI(*
F) : nullptr;
2369 LibFunc LF =
TLI->getLibFunc(*
F);
2374 case LibFunc_memcpy_chk:
2375 case LibFunc_memmove_chk:
2376 case LibFunc_mempcpy_chk:
2377 case LibFunc_memset_chk: {
2384 auto *LenOp = getDirectOrSimplifiedValue<ConstantInt>(
Call.
getOperand(2));
2387 if (LenOp && ObjSizeOp &&
2388 LenOp->getLimitedValue() <= ObjSizeOp->getLimitedValue()) {
2400bool CallAnalyzer::visitCallBase(CallBase &
Call) {
2401 if (!onCallBaseVisitStart(
Call))
2405 !
F.hasFnAttribute(Attribute::ReturnsTwice)) {
2407 ExposesReturnsTwice =
true;
2411 ContainsNoDuplicateCall =
true;
2414 onInlineAsm(*InlineAsmOp);
2422 F = getSimplifiedValue<Function>(Callee);
2424 onCallArgumentSetup(
Call);
2427 disableLoadElimination();
2428 return Base::visitCallBase(
Call);
2432 assert(
F &&
"Expected a call to a known function");
2435 if (simplifyCallSite(
F,
Call))
2441 switch (
II->getIntrinsicID()) {
2444 disableLoadElimination();
2445 return Base::visitCallBase(
Call);
2447 case Intrinsic::load_relative:
2448 onLoadRelativeIntrinsic();
2451 case Intrinsic::memset:
2452 case Intrinsic::memcpy:
2453 case Intrinsic::memmove:
2454 disableLoadElimination();
2457 case Intrinsic::icall_branch_funnel:
2458 case Intrinsic::localescape:
2459 HasUninlineableIntrinsic =
true;
2461 case Intrinsic::vastart:
2462 InitsVargArgs =
true;
2464 case Intrinsic::launder_invariant_group:
2465 if (
auto *SROAArg = getSROAArgForValueOrNull(
II->getOperand(0)))
2466 SROAArgValues[
II] = SROAArg;
2468 case Intrinsic::is_constant:
2469 return simplifyIntrinsicCallIsConstant(
Call);
2470 case Intrinsic::objectsize:
2471 return simplifyIntrinsicCallObjectSize(
Call);
2478 IsRecursiveCall =
true;
2479 if (!AllowRecursiveCall)
2483 if (isLoweredToCall(
F,
Call)) {
2488 disableLoadElimination();
2489 return Base::visitCallBase(
Call);
2492bool CallAnalyzer::visitReturnInst(ReturnInst &RI) {
2494 bool Free = !HasReturn;
2499bool CallAnalyzer::visitUncondBrInst(UncondBrInst &BI) {
2506bool CallAnalyzer::visitCondBrInst(CondBrInst &BI) {
2508 return getDirectOrSimplifiedValue<ConstantInt>(BI.
getCondition()) ||
2512bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
2513 bool CheckSROA =
SI.getType()->isPointerTy();
2517 Constant *TrueC = getDirectOrSimplifiedValue<Constant>(TrueVal);
2518 Constant *FalseC = getDirectOrSimplifiedValue<Constant>(FalseVal);
2519 Constant *CondC = getSimplifiedValue<Constant>(
SI.getCondition());
2523 if (TrueC == FalseC && TrueC) {
2524 SimplifiedValues[&
SI] = TrueC;
2529 return Base::visitSelectInst(SI);
2531 std::pair<Value *, APInt> TrueBaseAndOffset =
2532 ConstantOffsetPtrs.
lookup(TrueVal);
2533 std::pair<Value *, APInt> FalseBaseAndOffset =
2534 ConstantOffsetPtrs.
lookup(FalseVal);
2535 if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first) {
2536 ConstantOffsetPtrs[&
SI] = std::move(TrueBaseAndOffset);
2538 if (
auto *SROAArg = getSROAArgForValueOrNull(TrueVal))
2539 SROAArgValues[&
SI] = SROAArg;
2543 return Base::visitSelectInst(SI);
2554 if (TrueC && FalseC) {
2556 SimplifiedValues[&
SI] =
C;
2560 return Base::visitSelectInst(SI);
2565 SimplifiedValues[&
SI] = SelectedC;
2572 std::pair<Value *, APInt> BaseAndOffset =
2573 ConstantOffsetPtrs.
lookup(SelectedV);
2574 if (BaseAndOffset.first) {
2575 ConstantOffsetPtrs[&
SI] = std::move(BaseAndOffset);
2577 if (
auto *SROAArg = getSROAArgForValueOrNull(SelectedV))
2578 SROAArgValues[&
SI] = SROAArg;
2584bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
2587 if (getDirectOrSimplifiedValue<ConstantInt>(
SI.getCondition()))
2602 unsigned JumpTableSize = 0;
2603 BlockFrequencyInfo *BFI = GetBFI ? &(GetBFI(
F)) : nullptr;
2604 unsigned NumCaseCluster =
2607 onFinalizeSwitch(JumpTableSize, NumCaseCluster,
SI.defaultDestUnreachable());
2611bool CallAnalyzer::visitIndirectBrInst(IndirectBrInst &IBI) {
2620 HasIndirectBr =
true;
2624bool CallAnalyzer::visitResumeInst(ResumeInst &RI) {
2630bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
2636bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
2642bool CallAnalyzer::visitUnreachableInst(UnreachableInst &
I) {
2649bool CallAnalyzer::visitInstruction(Instruction &
I) {
2658 for (
const Use &
Op :
I.operands())
2672CallAnalyzer::analyzeBlock(BasicBlock *BB,
2673 const SmallPtrSetImpl<const Value *> &EphValues) {
2674 for (Instruction &
I : *BB) {
2691 ++NumVectorInstructions;
2698 onInstructionAnalysisStart(&
I);
2700 if (Base::visit(&
I))
2701 ++NumInstructionsSimplified;
2703 onMissedSimplification();
2705 onInstructionAnalysisFinish(&
I);
2706 using namespace ore;
2709 if (IsRecursiveCall && !AllowRecursiveCall)
2711 else if (ExposesReturnsTwice)
2713 else if (HasDynamicAlloca)
2715 else if (HasIndirectBr)
2717 else if (HasUninlineableIntrinsic)
2719 else if (InitsVargArgs)
2721 if (!
IR.isSuccess()) {
2724 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2726 <<
NV(
"Callee", &
F) <<
" has uninlinable pattern ("
2727 <<
NV(
"InlineResult",
IR.getFailureReason())
2728 <<
") and cost is not fully computed";
2736 if (IsCallerRecursive &&
2737 AllocatedSize > Opts.recursive_inline_max_stacksize) {
2742 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2744 <<
NV(
"Callee", &
F) <<
" is "
2745 <<
NV(
"InlineResult",
IR.getFailureReason())
2746 <<
". Cost is not fully computed";
2753 "Call site analysis is not favorable to inlining.");
2765ConstantInt *CallAnalyzer::stripAndComputeInBoundsConstantOffsets(
Value *&
V) {
2766 if (!
V->getType()->isPointerTy())
2769 unsigned AS =
V->getType()->getPointerAddressSpace();
2770 unsigned IntPtrWidth =
DL.getIndexSizeInBits(AS);
2775 SmallPtrSet<Value *, 4> Visited;
2781 V =
GEP->getPointerOperand();
2783 if (GA->isInterposable())
2785 V = GA->getAliasee();
2789 assert(
V->getType()->isPointerTy() &&
"Unexpected operand type!");
2790 }
while (Visited.
insert(
V).second);
2792 Type *IdxPtrTy =
DL.getIndexType(
V->getType());
2803void CallAnalyzer::findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB) {
2810 return KnownSucc && KnownSucc != Succ;
2815 return (!DeadBlocks.
count(BB) &&
2817 [&](BasicBlock *
P) {
return IsEdgeDead(
P, BB); }));
2820 for (BasicBlock *Succ :
successors(CurrBB)) {
2821 if (Succ == NextBB || !IsNewlyDead(Succ))
2825 while (!NewDead.
empty()) {
2843InlineResult CallAnalyzer::analyze() {
2846 auto Result = onAnalysisStart();
2855 for (User *U :
Caller->users()) {
2858 IsCallerRecursive =
true;
2866 for (Argument &FAI :
F.args()) {
2868 SimplifiedValues[&FAI] = *CAI;
2872 Value *PtrArg = *CAI;
2873 if (ConstantInt *
C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
2874 ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg,
C->getValue());
2878 SROAArgValues[&FAI] = SROAArg;
2879 onInitializeSROAArg(SROAArg);
2880 EnabledSROAAllocas.
insert(SROAArg);
2885 NumConstantOffsetPtrArgs = ConstantOffsetPtrs.
size();
2886 NumAllocaArgs = SROAArgValues.
size();
2890 SmallPtrSet<const Value *, 32> EphValuesStorage;
2891 const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
2892 if (GetEphValuesCache)
2893 EphValues = &GetEphValuesCache(
F).ephValues();
2905 typedef SmallSetVector<BasicBlock *, 16> BBSetVector;
2906 BBSetVector BBWorklist;
2907 BBWorklist.insert(&
F.getEntryBlock());
2910 for (
unsigned Idx = 0;
Idx != BBWorklist.size(); ++
Idx) {
2933 InlineResult
IR = analyzeBlock(BB, *EphValues);
2934 if (!
IR.isSuccess())
2943 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2945 BBWorklist.insert(NextBB);
2946 KnownSuccessors[BB] = NextBB;
2947 findDeadBlocks(BB, NextBB);
2952 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2953 BasicBlock *NextBB =
SI->findCaseValue(SimpleCond)->getCaseSuccessor();
2954 BBWorklist.insert(NextBB);
2955 KnownSuccessors[BB] = NextBB;
2956 findDeadBlocks(BB, NextBB);
2965 onBlockAnalyzed(BB);
2971 if (!isSoleCallToLocalFunction(CandidateCall,
F) && ContainsNoDuplicateCall)
2977 size_t FinalStackSizeThreshold = std::numeric_limits<size_t>::max();
2978 if (Opts.inline_max_stacksize)
2979 FinalStackSizeThreshold = *Opts.inline_max_stacksize;
2982 FinalStackSizeThreshold = *AttrMaxStackSize;
2983 if (AllocatedSize > FinalStackSizeThreshold)
2986 return finalizeAnalysis();
2989void InlineCostCallAnalyzer::print(raw_ostream &OS) {
2990#define DEBUG_PRINT_STAT(x) OS << " " #x ": " << x << "\n"
2991 if (PrintInstructionComments)
2992 F.print(OS, &Writer);
3007#undef DEBUG_PRINT_STAT
3010#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3024 auto CalleeTLI = GetTLI(*Callee);
3025 return GetTLI(*Caller).areInlineCompatible(
3026 CalleeTLI, Opts.inline_caller_superset_nobuiltin) &&
3027 AttributeFuncs::areInlineCompatible(*Caller, *Callee);
3033 for (
unsigned I = 0, E =
Call.arg_size();
I != E; ++
I) {
3034 if (
Call.isByValArgument(
I)) {
3040 unsigned PointerSize =
DL.getPointerSizeInBits(AS);
3042 unsigned NumStores = (
TypeSize + PointerSize - 1) / PointerSize;
3050 NumStores = std::min(NumStores, 8U);
3061 Cost +=
TTI.getInlineCallPenalty(
3065 return std::min<int64_t>(
Cost, INT_MAX);
3076 GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
3098 InlineCostCallAnalyzer CA(*
Call.getCalledFunction(),
Call, Params, CallerTTI,
3099 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
true,
3101 auto R = CA.analyze();
3103 return std::nullopt;
3104 return CA.getCost();
3113 InlineCostFeaturesAnalyzer CFA(CallerTTI, GetAssumptionCache, GetBFI, GetTLI,
3114 PSI, ORE, *
Call.getCalledFunction(),
Call);
3115 auto R = CFA.analyze();
3117 return std::nullopt;
3118 return CFA.features();
3133 if (Callee->isPresplitCoroutine())
3140 if (!Opts.ignore_tti_inline_compatible &&
3146 if (
Call.hasFnAttr(Attribute::AlwaysInline)) {
3147 if (
Call.getAttributes().hasFnAttr(Attribute::NoInline))
3150 if (!AttributeFuncs::isStrictFPInlineCompatible(*Caller, *Callee))
3154 if (IsViable.isSuccess())
3166 if (Caller->hasFnAttribute(Attribute::Flatten)) {
3168 if (IsViable.isSuccess())
3174 if (Caller->hasOptNone())
3178 if (Callee->isInterposable(
false))
3182 if (Callee->hasFnAttribute(Attribute::NoInline))
3186 if (
Call.isNoInline())
3190 if (Callee->hasFnAttribute(
"loader-replaceable"))
3193 return std::nullopt;
3209 if (UserDecision->isSuccess())
3217 "Inlining forced by -inline-all-viable-calls");
3220 <<
"... (caller:" <<
Call.getCaller()->getName()
3225 const bool IgnoreProfile = Params.
IgnoreProfile.value_or(
false);
3227 IgnoreProfile ?
nullptr : GetBFI;
3228 InlineCostCallAnalyzer CA(
3229 *Callee,
Call, Params, CallerTTI, GetAssumptionCache, GetBFIForAnalysis,
3230 GetTLI, IgnoreProfile ?
nullptr : PSI, ORE,
3231 true,
false, GetEphValuesCache);
3239 if (CA.wasDecidedByCostBenefit()) {
3242 CA.getCostBenefitPair());
3247 if (CA.wasDecidedByCostThreshold())
3249 CA.getStaticBonusApplied());
3258 bool ReturnsTwice =
F.hasFnAttribute(Attribute::ReturnsTwice);
3268 for (
auto &
II : BB) {
3285 switch (Callee->getIntrinsicID()) {
3288 case llvm::Intrinsic::icall_branch_funnel:
3292 "disallowed inlining of @llvm.icall.branch.funnel");
3293 case llvm::Intrinsic::localescape:
3297 "disallowed inlining of @llvm.localescape");
3298 case llvm::Intrinsic::vastart:
3302 "contains VarArgs initialized with va_start");
3410 InlineCostCallAnalyzer ICCA(*CalledFunction, *CB, Params,
TTI,
3411 GetAssumptionCache,
nullptr,
nullptr, PSI,
3417 OS <<
" Analyzing call of " << CalledFunction->
getName()
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static InstructionCost getCost(const AnalysisOptions &Opts, Instruction &Inst, TTI::TargetCostKind CostKind, TargetTransformInfo &TTI)
static Value * accumulateGEPOffset(GetElementPtrInst *GEP, IRBuilder<> &Builder)
static bool isColdCallSite(CallBase &CB, BlockFrequencyInfo &CallerBFI)
Return true if the block containing the call site has a BlockFrequency of less than ColdCCRelFreq% of...
static bool IsIndirectCall(const MachineInstr *MI)
static cl::opt< int > InlineThreshold("inline-threshold", cl::Hidden, cl::init(225), cl::desc("Control the amount of inlining to perform (default = 225)"))
static cl::opt< int > HotCallSiteThreshold("hot-callsite-threshold", cl::Hidden, cl::init(3000), cl::desc("Threshold for hot callsites "))
static bool functionsHaveCompatibleAttributes(const AnalysisOptions &Opts, Function *Caller, Function *Callee, function_ref< const TargetLibraryInfo &(Function &)> &GetTLI)
Test that there are no attribute conflicts between Caller and Callee that prevent inlining.
static cl::opt< int > ColdThreshold("inlinecold-threshold", cl::Hidden, cl::init(45), cl::desc("Threshold for inlining functions with cold attribute"))
static cl::opt< int > LocallyHotCallSiteThreshold("locally-hot-callsite-threshold", cl::Hidden, cl::init(525), cl::desc("Threshold for locally hot callsites "))
static cl::opt< int > HintThreshold("inlinehint-threshold", cl::Hidden, cl::init(325), cl::desc("Threshold for inlining functions with inline hint"))
static cl::opt< int > ColdCallSiteThreshold("inline-cold-callsite-threshold", cl::Hidden, cl::init(45), cl::desc("Threshold for inlining cold callsites"))
#define DEBUG_PRINT_STAT(x)
static cl::opt< int > InstrCost("inline-instr-cost", cl::Hidden, cl::init(5), cl::desc("Cost of a single instruction when inlining"))
static cl::opt< int > DefaultThreshold("inlinedefault-threshold", cl::Hidden, cl::init(225), cl::desc("Default amount of inlining to perform"))
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false.
Legalize the Machine IR a function s Machine IR
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
SmallVector< MachineOperand, 4 > Cond
static unsigned getFastMathFlags(const MachineInstr &I, const SPIRVSubtarget &ST)
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
static bool paramHasAttr(const CallBase &Call, unsigned ArgIdx, Attribute::AttrKind Kind)
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
PointerType * getType() const
Overload to return most specific pointer type.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
LLVM Basic Block Representation.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
LLVM_ABI BlockFrequency getEntryFreq() const
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
LLVM_ABI std::optional< BlockFrequency > mul(uint64_t Factor) const
Multiplies frequency with Factor. Returns nullopt in case of overflow.
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...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool onlyReadsMemory(unsigned OpNo) const
Value * getCalledOperand() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
A parsed version of the target data layout string in and methods for querying it.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
A cache of ephemeral values within a function.
Type * getReturnType() const
const BasicBlock & getEntryBlock() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
LLVM_ABI void collectAsmStrs(SmallVectorImpl< StringRef > &AsmStrs) const
Represents the cost of inlining a function.
static InlineCost getNever(const char *Reason, std::optional< CostBenefitPair > CostBenefit=std::nullopt)
static InlineCost getAlways(const char *Reason, std::optional< CostBenefitPair > CostBenefit=std::nullopt)
static InlineCost get(int Cost, int Threshold, int StaticBonus=0)
InlineResult is basically true or false.
static InlineResult success()
static InlineResult failure(const char *Reason)
const char * getFailureReason() const
Base class for instruction visitors.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void analyze(ParentT F)
Create the loop forest for a function.
Class to represent pointers.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void reserve(size_type N)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
TypeSize getElementOffset(unsigned Idx) const
Analysis pass providing the TargetTransformInfo.
Provides information about what library functions are available for the current target.
static constexpr TypeSize getZero()
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Value * getOperand(unsigned i) const
LLVM Value Representation.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool erase(const ValueT &V)
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
@ BasicBlock
Various leaf nodes.
const char FunctionInlineCostMultiplierAttributeName[]
const int OptSizeThreshold
Use when optsize (-Os) is specified.
const int OptMinSizeThreshold
Use when minsize (-Oz) is specified.
const uint64_t MaxSimplifiedDynamicAllocaToInline
Do not inline dynamic allocas that have been constant propagated to be static allocas above this amou...
const int IndirectCallThreshold
const int OptAggressiveThreshold
Use when -O3 is specified.
const char MaxInlineStackSizeAttributeName[]
LLVM_ABI int getInstrCost()
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or fsub -0.0, X.
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< InstrNode * > Instr
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
LLVM_ABI Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)
Attempt to constant fold a select instruction with the specified operands.
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.
LLVM_ABI bool isAssumeLikeIntrinsic(const Instruction *I)
Return true if it is an intrinsic that cannot be speculated but also cannot trap.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< int > getStringFnAttrAsInt(CallBase &CB, StringRef AttrKind)
auto successors(const MachineBasicBlock *BB)
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)
Try to turn a call to @llvm.objectsize into an integer value of the given Type.
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
LogicalResult failure(bool IsFailure=true)
Utility function to generate a LogicalResult.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
LLVM_ABI std::optional< InlineResult > getAttributeBasedInliningDecision(CallBase &Call, Function *Callee, TargetTransformInfo &CallerTTI, function_ref< const TargetLibraryInfo &(Function &)> GetTLI)
Returns InlineResult::success() if the call site should be always inlined because of user directives,...
LLVM_ABI bool canConstantFoldCallTo(const CallBase *Call, const Function *F, const TargetLibraryInfo *TLI=nullptr)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI InlineResult isInlineViable(Function &Callee)
Check if it is mechanically possible to inline the function Callee, based on the contents of the func...
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q)
Given operand for an FNeg, fold the result or return null.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
generic_gep_type_iterator<> gep_type_iterator
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an ExtractValueInst, fold the result or return null.
LLVM_ABI std::optional< int > getInliningCostEstimate(CallBase &Call, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, function_ref< const TargetLibraryInfo &(Function &)> GetTLI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
Get the cost estimate ignoring thresholds.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
LLVM_ABI InlineParams getInlineParams()
Generate the parameters to tune the inline cost analysis based only on the commandline options.
LLVM_ABI int getCallsiteCost(const TargetTransformInfo &TTI, const CallBase &Call, const DataLayout &DL)
Return the cost associated with a callsite, including parameter passing and the call/return instructi...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
auto predecessors(const MachineBasicBlock *BB)
constexpr bool valueOr(BoolOrDefault X, bool Default)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
LLVM_ABI InlineParams getInlineParamsFromOptLevel(unsigned OptLevel)
Generate the parameters to tune the inline cost analysis based on command line options.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingAdd(T X, T Y, bool *ResultOverflowed=nullptr)
Add two unsigned integers, X and Y, of type T.
constexpr bool isCallableCC(CallingConv::ID CC)
std::array< int, static_cast< size_t >(InlineCostFeatureIndex::NumberOfFeatures)> InlineCostFeatures
LLVM_ABI std::optional< InlineCostFeatures > getInliningCostFeatures(CallBase &Call, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, function_ref< const TargetLibraryInfo &(Function &)> GetTLI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
Get the expanded cost features.
static LLVM_ABI void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Thresholds to tune inline cost analysis.
std::optional< int > OptMinSizeThreshold
Threshold to use when the caller is optimized for minsize.
std::optional< int > OptSizeThreshold
Threshold to use when the caller is optimized for size.
std::optional< int > OptSizeHintThreshold
Threshold to use for callees with inline hint, when the caller is optimized for size.
std::optional< int > ColdCallSiteThreshold
Threshold to use when the callsite is considered cold.
std::optional< int > ColdThreshold
Threshold to use for cold callees.
std::optional< int > HotCallSiteThreshold
Threshold to use when the callsite is considered hot.
std::optional< bool > IgnoreProfile
Indicate whether to ignore profile information.
int DefaultThreshold
The default threshold to start with for a callee.
std::optional< int > HintThreshold
Threshold to use for callees with inline hint.
std::optional< int > LocallyHotCallSiteThreshold
Threshold to use when the callsite is considered hot relative to function entry.