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; }
1161static bool isSoleCallToLocalFunction(
const CallBase &CB,
1163 return Callee.hasLocalLinkage() &&
Callee.hasOneLiveUse() &&
1167class InlineCostFeaturesAnalyzer final :
public CallAnalyzer {
1174 static constexpr int JTCostMultiplier = 2;
1175 static constexpr int CaseClusterCostMultiplier = 2;
1176 static constexpr int SwitchDefaultDestCostMultiplier = 2;
1177 static constexpr int SwitchCostMultiplier = 2;
1181 unsigned SROACostSavingOpportunities = 0;
1182 int VectorBonus = 0;
1183 int SingleBBBonus = 0;
1186 DenseMap<AllocaInst *, unsigned> SROACosts;
1189 Cost[
static_cast<size_t>(Feature)] += Delta;
1193 Cost[
static_cast<size_t>(Feature)] =
Value;
1196 void onDisableSROA(AllocaInst *Arg)
override {
1197 auto CostIt = SROACosts.find(Arg);
1198 if (CostIt == SROACosts.end())
1201 increment(InlineCostFeatureIndex::sroa_losses, CostIt->second);
1202 SROACostSavingOpportunities -= CostIt->second;
1203 SROACosts.erase(CostIt);
1206 void onDisableLoadElimination()
override {
1207 set(InlineCostFeatureIndex::load_elimination, 1);
1210 void onCallPenalty()
override {
1211 increment(InlineCostFeatureIndex::call_penalty, Opts.inline_call_penalty);
1214 void onCallArgumentSetup(
const CallBase &
Call)
override {
1215 increment(InlineCostFeatureIndex::call_argument_setup,
1219 void onLoadRelativeIntrinsic()
override {
1220 increment(InlineCostFeatureIndex::load_relative_intrinsic, 3 *
InstrCost);
1225 increment(InlineCostFeatureIndex::lowered_call_arg_setup,
1229 InlineParams IndirectCallParams = { 0,
1243 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
1244 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
1246 if (CA.analyze().isSuccess()) {
1247 increment(InlineCostFeatureIndex::nested_inline_cost_estimate,
1249 increment(InlineCostFeatureIndex::nested_inlines, 1);
1256 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
1257 bool DefaultDestUnreachable)
override {
1258 if (JumpTableSize) {
1259 if (!DefaultDestUnreachable)
1260 increment(InlineCostFeatureIndex::switch_default_dest_penalty,
1261 SwitchDefaultDestCostMultiplier *
InstrCost);
1262 int64_t JTCost =
static_cast<int64_t
>(JumpTableSize) *
InstrCost +
1264 increment(InlineCostFeatureIndex::jump_table_penalty, JTCost);
1268 if (NumCaseCluster <= 3) {
1269 increment(InlineCostFeatureIndex::case_cluster_penalty,
1270 (NumCaseCluster - DefaultDestUnreachable) *
1275 int64_t ExpectedNumberOfCompare =
1276 getExpectedNumberOfCompare(NumCaseCluster);
1278 int64_t SwitchCost =
1279 ExpectedNumberOfCompare * SwitchCostMultiplier *
InstrCost;
1280 increment(InlineCostFeatureIndex::switch_penalty, SwitchCost);
1283 void onMissedSimplification()
override {
1284 increment(InlineCostFeatureIndex::unsimplified_common_instructions,
1288 void onInitializeSROAArg(AllocaInst *Arg)
override {
1290 SROACosts[Arg] = SROAArgCost;
1291 SROACostSavingOpportunities += SROAArgCost;
1294 void onAggregateSROAUse(AllocaInst *Arg)
override {
1295 SROACosts.find(Arg)->second +=
InstrCost;
1296 SROACostSavingOpportunities +=
InstrCost;
1299 void onBlockAnalyzed(
const BasicBlock *BB)
override {
1301 set(InlineCostFeatureIndex::is_multiple_blocks, 1);
1302 Threshold -= SingleBBBonus;
1305 InlineResult finalizeAnalysis()
override {
1307 if (
Caller->hasMinSize()) {
1310 for (
Loop *L : LI) {
1312 if (DeadBlocks.
count(
L->getHeader()))
1314 increment(InlineCostFeatureIndex::num_loops,
1318 set(InlineCostFeatureIndex::dead_blocks, DeadBlocks.
size());
1319 set(InlineCostFeatureIndex::simplified_instructions,
1320 NumInstructionsSimplified);
1321 set(InlineCostFeatureIndex::constant_args, NumConstantArgs);
1322 set(InlineCostFeatureIndex::constant_offset_ptr_args,
1323 NumConstantOffsetPtrArgs);
1324 set(InlineCostFeatureIndex::sroa_savings, SROACostSavingOpportunities);
1326 if (NumVectorInstructions <= NumInstructions / 10)
1327 Threshold -= VectorBonus;
1328 else if (NumVectorInstructions <= NumInstructions / 2)
1329 Threshold -= VectorBonus / 2;
1331 set(InlineCostFeatureIndex::threshold, Threshold);
1336 bool shouldStop()
override {
return false; }
1338 void onLoadEliminationOpportunity()
override {
1339 increment(InlineCostFeatureIndex::load_elimination, 1);
1342 InlineResult onAnalysisStart()
override {
1343 increment(InlineCostFeatureIndex::callsite_cost,
1346 set(InlineCostFeatureIndex::cold_cc_penalty,
1347 (
F.getCallingConv() == CallingConv::Cold));
1349 set(InlineCostFeatureIndex::last_call_to_static_bonus,
1350 isSoleCallToLocalFunction(CandidateCall,
F));
1355 int SingleBBBonusPercent = 50;
1359 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
1360 VectorBonus = Threshold * VectorBonusPercent / 100;
1361 Threshold += (SingleBBBonus + VectorBonus);
1367 InlineCostFeaturesAnalyzer(
1368 const TargetTransformInfo &
TTI,
1369 function_ref<AssumptionCache &(
Function &)> &GetAssumptionCache,
1370 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI,
1371 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI,
1372 ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
Function &Callee,
1374 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI,
1383bool CallAnalyzer::isAllocaDerivedArg(
Value *V) {
1384 return SROAArgValues.
count(V);
1387void CallAnalyzer::disableSROAForArg(AllocaInst *SROAArg) {
1388 onDisableSROA(SROAArg);
1389 EnabledSROAAllocas.
erase(SROAArg);
1390 disableLoadElimination();
1393void InlineCostAnnotationWriter::emitInstructionAnnot(
1394 const Instruction *
I, formatted_raw_ostream &OS) {
1398 std::optional<InstructionCostDetail>
Record = ICCA->getCostDetails(
I);
1400 OS <<
"; No analysis for the instruction";
1402 OS <<
"; cost before = " <<
Record->CostBefore
1403 <<
", cost after = " <<
Record->CostAfter
1404 <<
", threshold before = " <<
Record->ThresholdBefore
1405 <<
", threshold after = " <<
Record->ThresholdAfter <<
", ";
1406 OS <<
"cost delta = " <<
Record->getCostDelta();
1407 if (
Record->hasThresholdChanged())
1408 OS <<
", threshold delta = " <<
Record->getThresholdDelta();
1410 auto *
V = ICCA->getSimplifiedValueUnchecked(
const_cast<Instruction *
>(
I));
1412 OS <<
", simplified to ";
1415 if (
VI->getFunction() !=
I->getFunction())
1416 OS <<
" (caller instruction)";
1418 if (VArg->getParent() !=
I->getFunction())
1419 OS <<
" (caller argument)";
1426void CallAnalyzer::disableSROA(
Value *V) {
1427 if (
auto *SROAArg = getSROAArgForValueOrNull(V)) {
1428 disableSROAForArg(SROAArg);
1432void CallAnalyzer::disableLoadElimination() {
1433 if (EnableLoadElimination) {
1434 onDisableLoadElimination();
1435 EnableLoadElimination =
false;
1443bool CallAnalyzer::accumulateGEPOffset(GEPOperator &
GEP, APInt &
Offset) {
1444 unsigned IntPtrWidth =
DL.getIndexTypeSizeInBits(
GEP.getType());
1448 GTI != GTE; ++GTI) {
1450 getDirectOrSimplifiedValue<ConstantInt>(GTI.getOperand());
1457 if (StructType *STy = GTI.getStructTypeOrNull()) {
1459 const StructLayout *SL =
DL.getStructLayout(STy);
1464 APInt TypeSize(IntPtrWidth, GTI.getSequentialElementStride(
DL));
1473bool CallAnalyzer::isGEPFree(GetElementPtrInst &
GEP) {
1476 for (
const Use &
Op :
GEP.indices())
1477 if (Constant *SimpleOp = getSimplifiedValue<Constant>(
Op))
1486bool CallAnalyzer::visitAlloca(AllocaInst &
I) {
1487 disableSROA(
I.getOperand(0));
1491 if (
I.isArrayAllocation()) {
1492 Constant *
Size = getSimplifiedValue<Constant>(
I.getArraySize());
1503 AllocSize->getLimitedValue(),
1504 I.getAllocationBaseSize(
DL).getKnownMinValue(), AllocatedSize);
1506 HasDynamicAlloca =
true;
1511 if (
I.isStaticAlloca()) {
1523 HasDynamicAlloca =
true;
1529bool CallAnalyzer::visitPHI(PHINode &
I) {
1541 bool CheckSROA =
I.getType()->isPointerTy();
1545 std::pair<Value *, APInt> FirstBaseAndOffset = {
nullptr, ZeroOffset};
1546 Value *FirstV =
nullptr;
1548 for (
unsigned i = 0, e =
I.getNumIncomingValues(); i != e; ++i) {
1551 if (DeadBlocks.
count(Pred))
1555 BasicBlock *KnownSuccessor = KnownSuccessors[Pred];
1556 if (KnownSuccessor && KnownSuccessor !=
I.getParent())
1559 Value *
V =
I.getIncomingValue(i);
1564 Constant *
C = getDirectOrSimplifiedValue<Constant>(V);
1566 std::pair<Value *, APInt> BaseAndOffset = {
nullptr, ZeroOffset};
1567 if (!
C && CheckSROA)
1568 BaseAndOffset = ConstantOffsetPtrs.
lookup(V);
1570 if (!
C && !BaseAndOffset.first)
1587 if (FirstBaseAndOffset == BaseAndOffset)
1601 FirstBaseAndOffset = BaseAndOffset;
1606 SimplifiedValues[&
I] = FirstC;
1611 if (FirstBaseAndOffset.first) {
1612 ConstantOffsetPtrs[&
I] = std::move(FirstBaseAndOffset);
1614 if (
auto *SROAArg = getSROAArgForValueOrNull(FirstV))
1615 SROAArgValues[&
I] = SROAArg;
1625bool CallAnalyzer::canFoldInboundsGEP(GetElementPtrInst &
I) {
1627 std::pair<Value *, APInt> BaseAndOffset =
1628 ConstantOffsetPtrs.
lookup(
I.getPointerOperand());
1629 if (!BaseAndOffset.first)
1638 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1643bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &
I) {
1644 auto *SROAArg = getSROAArgForValueOrNull(
I.getPointerOperand());
1647 auto IsGEPOffsetConstant = [&](GetElementPtrInst &
GEP) {
1648 for (
const Use &
Op :
GEP.indices())
1649 if (!getDirectOrSimplifiedValue<Constant>(
Op))
1654 if (Opts.gep_const_evaluation)
1658 if ((
I.isInBounds() && canFoldInboundsGEP(
I)) || IsGEPOffsetConstant(
I)) {
1660 SROAArgValues[&
I] = SROAArg;
1668 disableSROAForArg(SROAArg);
1669 return isGEPFree(
I);
1675bool CallAnalyzer::simplifyCmpInstForRecCall(CmpInst &Cmp) {
1679 auto *CmpOp =
Cmp.getOperand(0);
1684 auto *CallBB = CandidateCall.
getParent();
1685 auto *Predecessor = CallBB->getSinglePredecessor();
1690 if (!Br || Br->getCondition() != &Cmp)
1695 bool ArgFound =
false;
1696 Value *FuncArg =
nullptr, *CallArg =
nullptr;
1697 for (
unsigned ArgNum = 0;
1698 ArgNum <
F.arg_size() && ArgNum < CandidateCall.
arg_size(); ArgNum++) {
1699 FuncArg =
F.getArg(ArgNum);
1701 if (FuncArg == CmpOp && CallArg != CmpOp) {
1712 CondContext
CC(&Cmp);
1713 CC.Invert = (CallBB != Br->getSuccessor(0));
1715 CC.AffectedValues.insert(FuncArg);
1721 if ((ConstVal->isOne() &&
CC.Invert) ||
1722 (ConstVal->isZero() && !
CC.Invert)) {
1723 SimplifiedValues[&
Cmp] = ConstVal;
1731bool CallAnalyzer::simplifyInstruction(Instruction &
I) {
1734 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
1742 SimplifiedValues[&
I] =
C;
1755bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
1757 auto *
C = getDirectOrSimplifiedValue<Constant>(Arg);
1760 SimplifiedValues[&CB] = ConstantInt::get(RT,
C ? 1 : 0);
1764bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
1774 SimplifiedValues[&CB] =
C;
1778bool CallAnalyzer::visitBitCast(BitCastInst &
I) {
1784 std::pair<Value *, APInt> BaseAndOffset =
1785 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1787 if (BaseAndOffset.first)
1788 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1791 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1792 SROAArgValues[&
I] = SROAArg;
1798bool CallAnalyzer::visitPtrToInt(PtrToIntInst &
I) {
1806 unsigned AS =
I.getOperand(0)->getType()->getPointerAddressSpace();
1807 if (IntegerSize ==
DL.getPointerSizeInBits(AS)) {
1808 std::pair<Value *, APInt> BaseAndOffset =
1809 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1810 if (BaseAndOffset.first)
1811 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1821 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1822 SROAArgValues[&
I] = SROAArg;
1828bool CallAnalyzer::visitIntToPtr(IntToPtrInst &
I) {
1836 unsigned IntegerSize =
Op->getType()->getScalarSizeInBits();
1837 if (IntegerSize <=
DL.getPointerTypeSizeInBits(
I.getType())) {
1838 std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.
lookup(
Op);
1839 if (BaseAndOffset.first)
1840 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1844 if (
auto *SROAArg = getSROAArgForValueOrNull(
Op))
1845 SROAArgValues[&
I] = SROAArg;
1851bool CallAnalyzer::visitCastInst(CastInst &
I) {
1858 disableSROA(
I.getOperand(0));
1863 switch (
I.getOpcode()) {
1864 case Instruction::FPTrunc:
1865 case Instruction::FPExt:
1866 case Instruction::UIToFP:
1867 case Instruction::SIToFP:
1868 case Instruction::FPToUI:
1869 case Instruction::FPToSI:
1881bool CallAnalyzer::paramHasAttr(Argument *
A, Attribute::AttrKind Attr) {
1885bool CallAnalyzer::isKnownNonNullInCallee(
Value *V) {
1898 if (isAllocaDerivedArg(V))
1907bool CallAnalyzer::allowSizeGrowth(CallBase &
Call) {
1932bool InlineCostCallAnalyzer::isColdCallSite(CallBase &
Call,
1933 BlockFrequencyInfo *CallerBFI) {
1936 if (PSI && PSI->hasProfileSummary())
1937 return PSI->isColdCallSite(
Call, CallerBFI);
1947 const BranchProbability ColdProb(Opts.cold_callsite_rel_freq, 100);
1949 auto CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1950 auto CallerEntryFreq =
1952 return CallSiteFreq < CallerEntryFreq * ColdProb;
1956InlineCostCallAnalyzer::getHotCallSiteThreshold(CallBase &
Call,
1957 BlockFrequencyInfo *CallerBFI) {
1961 if (PSI && PSI->hasProfileSummary() && PSI->isHotCallSite(
Call, CallerBFI))
1967 return std::nullopt;
1974 BlockFrequency CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1975 BlockFrequency CallerEntryFreq = CallerBFI->
getEntryFreq();
1976 std::optional<BlockFrequency> Limit =
1977 CallerEntryFreq.
mul(Opts.hot_callsite_rel_freq);
1978 if (Limit && CallSiteFreq >= *Limit)
1982 return std::nullopt;
1985void InlineCostCallAnalyzer::updateThreshold(CallBase &
Call,
Function &Callee) {
1987 if (!allowSizeGrowth(
Call)) {
1995 auto MinIfValid = [](
int A, std::optional<int>
B) {
1996 return B ? std::min(
A, *
B) :
A;
2000 auto MaxIfValid = [](
int A, std::optional<int>
B) {
2001 return B ? std::max(
A, *
B) :
A;
2016 int SingleBBBonusPercent = 50;
2021 auto DisallowAllBonuses = [&]() {
2022 SingleBBBonusPercent = 0;
2023 VectorBonusPercent = 0;
2024 LastCallToStaticBonus = 0;
2029 if (
Caller->hasMinSize()) {
2035 SingleBBBonusPercent = 0;
2036 VectorBonusPercent = 0;
2037 }
else if (
Caller->hasOptSize())
2042 if (!
Caller->hasMinSize()) {
2046 if (
Callee.hasFnAttribute(Attribute::InlineHint))
2056 BlockFrequencyInfo *CallerBFI = GetBFI ? &(GetBFI(*Caller)) : nullptr;
2077 DisallowAllBonuses();
2082 if (PSI->isFunctionEntryHot(&Callee)) {
2088 }
else if (PSI->isFunctionEntryCold(&Callee)) {
2094 DisallowAllBonuses();
2106 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
2107 VectorBonus = Threshold * VectorBonusPercent / 100;
2112 if (isSoleCallToLocalFunction(
Call,
F)) {
2113 addCost(-LastCallToStaticBonus);
2114 StaticBonusApplied = LastCallToStaticBonus;
2118bool CallAnalyzer::visitCmpInst(CmpInst &
I) {
2125 if (simplifyCmpInstForRecCall(
I))
2128 if (
I.getOpcode() == Instruction::FCmp)
2133 Value *LHSBase, *RHSBase;
2134 APInt LHSOffset, RHSOffset;
2135 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2137 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2138 if (RHSBase && LHSBase == RHSBase) {
2144 ++NumConstantPtrCmps;
2149 auto isImplicitNullCheckCmp = [](
const CmpInst &
I) {
2150 for (
auto *User :
I.users())
2152 if (!
Instr->getMetadata(LLVMContext::MD_make_implicit))
2160 if (isKnownNonNullInCallee(
I.getOperand(0))) {
2168 if (isImplicitNullCheckCmp(
I))
2174bool CallAnalyzer::visitSub(BinaryOperator &
I) {
2178 Value *LHSBase, *RHSBase;
2179 APInt LHSOffset, RHSOffset;
2180 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2182 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2183 if (RHSBase && LHSBase == RHSBase) {
2189 SimplifiedValues[&
I] =
C;
2190 ++NumConstantPtrDiffs;
2198 return Base::visitSub(
I);
2201bool CallAnalyzer::visitBinaryOperator(BinaryOperator &
I) {
2203 Constant *CLHS = getDirectOrSimplifiedValue<Constant>(
LHS);
2204 Constant *CRHS = getDirectOrSimplifiedValue<Constant>(
RHS);
2206 Value *SimpleV =
nullptr;
2209 FI->getFastMathFlags(),
DL);
2215 SimplifiedValues[&
I] =
C;
2227 using namespace llvm::PatternMatch;
2229 if (
I.getType()->isFloatingPointTy() &&
2237bool CallAnalyzer::visitFNeg(UnaryOperator &
I) {
2239 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
2245 SimplifiedValues[&
I] =
C;
2256bool CallAnalyzer::visitLoad(LoadInst &
I) {
2257 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2263 if (EnableLoadElimination &&
2264 !LoadAddrSet.
insert(
I.getPointerOperand()).second &&
I.isUnordered()) {
2265 onLoadEliminationOpportunity();
2273bool CallAnalyzer::visitStore(StoreInst &
I) {
2274 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2285 disableLoadElimination();
2291bool CallAnalyzer::visitExtractValue(ExtractValueInst &
I) {
2292 Value *
Op =
I.getAggregateOperand();
2296 if (
Value *SimpleOp = getSimplifiedValueUnchecked(
Op)) {
2297 SimplifyQuery SQ(
DL);
2300 SimplifiedValues[&
I] = SimpleV;
2306 return Base::visitExtractValue(
I);
2309bool CallAnalyzer::visitInsertValue(InsertValueInst &
I) {
2315 return Base::visitInsertValue(
I);
2324bool CallAnalyzer::simplifyCallSite(
Function *
F, CallBase &
Call) {
2333 SmallVector<Constant *, 4> ConstantArgs;
2336 Constant *
C = getDirectOrSimplifiedValue<Constant>(
I);
2343 SimplifiedValues[&
Call] =
C;
2350bool CallAnalyzer::isLoweredToCall(
Function *
F, CallBase &
Call) {
2351 const TargetLibraryInfo *TLI = GetTLI ? &GetTLI(*
F) : nullptr;
2360 case LibFunc_memcpy_chk:
2361 case LibFunc_memmove_chk:
2362 case LibFunc_mempcpy_chk:
2363 case LibFunc_memset_chk: {
2370 auto *LenOp = getDirectOrSimplifiedValue<ConstantInt>(
Call.
getOperand(2));
2373 if (LenOp && ObjSizeOp &&
2374 LenOp->getLimitedValue() <= ObjSizeOp->getLimitedValue()) {
2386bool CallAnalyzer::visitCallBase(CallBase &
Call) {
2387 if (!onCallBaseVisitStart(
Call))
2391 !
F.hasFnAttribute(Attribute::ReturnsTwice)) {
2393 ExposesReturnsTwice =
true;
2397 ContainsNoDuplicateCall =
true;
2400 onInlineAsm(*InlineAsmOp);
2408 F = getSimplifiedValue<Function>(Callee);
2410 onCallArgumentSetup(
Call);
2413 disableLoadElimination();
2414 return Base::visitCallBase(
Call);
2418 assert(
F &&
"Expected a call to a known function");
2421 if (simplifyCallSite(
F,
Call))
2427 switch (
II->getIntrinsicID()) {
2430 disableLoadElimination();
2431 return Base::visitCallBase(
Call);
2433 case Intrinsic::load_relative:
2434 onLoadRelativeIntrinsic();
2437 case Intrinsic::memset:
2438 case Intrinsic::memcpy:
2439 case Intrinsic::memmove:
2440 disableLoadElimination();
2443 case Intrinsic::icall_branch_funnel:
2444 case Intrinsic::localescape:
2445 HasUninlineableIntrinsic =
true;
2447 case Intrinsic::vastart:
2448 InitsVargArgs =
true;
2450 case Intrinsic::launder_invariant_group:
2451 if (
auto *SROAArg = getSROAArgForValueOrNull(
II->getOperand(0)))
2452 SROAArgValues[
II] = SROAArg;
2454 case Intrinsic::is_constant:
2455 return simplifyIntrinsicCallIsConstant(
Call);
2456 case Intrinsic::objectsize:
2457 return simplifyIntrinsicCallObjectSize(
Call);
2464 IsRecursiveCall =
true;
2465 if (!AllowRecursiveCall)
2469 if (isLoweredToCall(
F,
Call)) {
2474 disableLoadElimination();
2475 return Base::visitCallBase(
Call);
2478bool CallAnalyzer::visitReturnInst(ReturnInst &RI) {
2480 bool Free = !HasReturn;
2485bool CallAnalyzer::visitUncondBrInst(UncondBrInst &BI) {
2492bool CallAnalyzer::visitCondBrInst(CondBrInst &BI) {
2494 return getDirectOrSimplifiedValue<ConstantInt>(BI.
getCondition()) ||
2498bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
2499 bool CheckSROA =
SI.getType()->isPointerTy();
2503 Constant *TrueC = getDirectOrSimplifiedValue<Constant>(TrueVal);
2504 Constant *FalseC = getDirectOrSimplifiedValue<Constant>(FalseVal);
2505 Constant *CondC = getSimplifiedValue<Constant>(
SI.getCondition());
2509 if (TrueC == FalseC && TrueC) {
2510 SimplifiedValues[&
SI] = TrueC;
2515 return Base::visitSelectInst(SI);
2517 std::pair<Value *, APInt> TrueBaseAndOffset =
2518 ConstantOffsetPtrs.
lookup(TrueVal);
2519 std::pair<Value *, APInt> FalseBaseAndOffset =
2520 ConstantOffsetPtrs.
lookup(FalseVal);
2521 if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first) {
2522 ConstantOffsetPtrs[&
SI] = std::move(TrueBaseAndOffset);
2524 if (
auto *SROAArg = getSROAArgForValueOrNull(TrueVal))
2525 SROAArgValues[&
SI] = SROAArg;
2529 return Base::visitSelectInst(SI);
2540 if (TrueC && FalseC) {
2542 SimplifiedValues[&
SI] =
C;
2546 return Base::visitSelectInst(SI);
2551 SimplifiedValues[&
SI] = SelectedC;
2558 std::pair<Value *, APInt> BaseAndOffset =
2559 ConstantOffsetPtrs.
lookup(SelectedV);
2560 if (BaseAndOffset.first) {
2561 ConstantOffsetPtrs[&
SI] = std::move(BaseAndOffset);
2563 if (
auto *SROAArg = getSROAArgForValueOrNull(SelectedV))
2564 SROAArgValues[&
SI] = SROAArg;
2570bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
2573 if (getDirectOrSimplifiedValue<ConstantInt>(
SI.getCondition()))
2588 unsigned JumpTableSize = 0;
2589 BlockFrequencyInfo *BFI = GetBFI ? &(GetBFI(
F)) : nullptr;
2590 unsigned NumCaseCluster =
2593 onFinalizeSwitch(JumpTableSize, NumCaseCluster,
SI.defaultDestUnreachable());
2597bool CallAnalyzer::visitIndirectBrInst(IndirectBrInst &IBI) {
2606 HasIndirectBr =
true;
2610bool CallAnalyzer::visitResumeInst(ResumeInst &RI) {
2616bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
2622bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
2628bool CallAnalyzer::visitUnreachableInst(UnreachableInst &
I) {
2635bool CallAnalyzer::visitInstruction(Instruction &
I) {
2644 for (
const Use &
Op :
I.operands())
2658CallAnalyzer::analyzeBlock(BasicBlock *BB,
2659 const SmallPtrSetImpl<const Value *> &EphValues) {
2660 for (Instruction &
I : *BB) {
2677 ++NumVectorInstructions;
2684 onInstructionAnalysisStart(&
I);
2686 if (Base::visit(&
I))
2687 ++NumInstructionsSimplified;
2689 onMissedSimplification();
2691 onInstructionAnalysisFinish(&
I);
2692 using namespace ore;
2695 if (IsRecursiveCall && !AllowRecursiveCall)
2697 else if (ExposesReturnsTwice)
2699 else if (HasDynamicAlloca)
2701 else if (HasIndirectBr)
2703 else if (HasUninlineableIntrinsic)
2705 else if (InitsVargArgs)
2707 if (!
IR.isSuccess()) {
2710 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2712 <<
NV(
"Callee", &
F) <<
" has uninlinable pattern ("
2713 <<
NV(
"InlineResult",
IR.getFailureReason())
2714 <<
") and cost is not fully computed";
2722 if (IsCallerRecursive &&
2723 AllocatedSize > Opts.recursive_inline_max_stacksize) {
2728 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2730 <<
NV(
"Callee", &
F) <<
" is "
2731 <<
NV(
"InlineResult",
IR.getFailureReason())
2732 <<
". Cost is not fully computed";
2739 "Call site analysis is not favorable to inlining.");
2751ConstantInt *CallAnalyzer::stripAndComputeInBoundsConstantOffsets(
Value *&V) {
2752 if (!
V->getType()->isPointerTy())
2755 unsigned AS =
V->getType()->getPointerAddressSpace();
2756 unsigned IntPtrWidth =
DL.getIndexSizeInBits(AS);
2761 SmallPtrSet<Value *, 4> Visited;
2767 V =
GEP->getPointerOperand();
2769 if (GA->isInterposable())
2771 V = GA->getAliasee();
2775 assert(
V->getType()->isPointerTy() &&
"Unexpected operand type!");
2776 }
while (Visited.
insert(V).second);
2778 Type *IdxPtrTy =
DL.getIndexType(
V->getType());
2789void CallAnalyzer::findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB) {
2793 if (DeadBlocks.
count(Pred))
2795 BasicBlock *KnownSucc = KnownSuccessors[Pred];
2796 return KnownSucc && KnownSucc != Succ;
2801 return (!DeadBlocks.
count(BB) &&
2803 [&](BasicBlock *
P) {
return IsEdgeDead(
P, BB); }));
2806 for (BasicBlock *Succ :
successors(CurrBB)) {
2807 if (Succ == NextBB || !IsNewlyDead(Succ))
2811 while (!NewDead.
empty()) {
2829InlineResult CallAnalyzer::analyze() {
2832 auto Result = onAnalysisStart();
2841 for (User *U :
Caller->users()) {
2844 IsCallerRecursive =
true;
2852 for (Argument &FAI :
F.args()) {
2854 SimplifiedValues[&FAI] = *CAI;
2858 Value *PtrArg = *CAI;
2859 if (ConstantInt *
C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
2860 ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg,
C->getValue());
2864 SROAArgValues[&FAI] = SROAArg;
2865 onInitializeSROAArg(SROAArg);
2866 EnabledSROAAllocas.
insert(SROAArg);
2871 NumConstantOffsetPtrArgs = ConstantOffsetPtrs.
size();
2872 NumAllocaArgs = SROAArgValues.
size();
2876 SmallPtrSet<const Value *, 32> EphValuesStorage;
2877 const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
2878 if (GetEphValuesCache)
2879 EphValues = &GetEphValuesCache(
F).ephValues();
2891 typedef SmallSetVector<BasicBlock *, 16> BBSetVector;
2892 BBSetVector BBWorklist;
2893 BBWorklist.insert(&
F.getEntryBlock());
2896 for (
unsigned Idx = 0;
Idx != BBWorklist.size(); ++
Idx) {
2919 InlineResult
IR = analyzeBlock(BB, *EphValues);
2920 if (!
IR.isSuccess())
2929 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2931 BBWorklist.insert(NextBB);
2932 KnownSuccessors[BB] = NextBB;
2933 findDeadBlocks(BB, NextBB);
2938 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2939 BasicBlock *NextBB =
SI->findCaseValue(SimpleCond)->getCaseSuccessor();
2940 BBWorklist.insert(NextBB);
2941 KnownSuccessors[BB] = NextBB;
2942 findDeadBlocks(BB, NextBB);
2951 onBlockAnalyzed(BB);
2957 if (!isSoleCallToLocalFunction(CandidateCall,
F) && ContainsNoDuplicateCall)
2963 size_t FinalStackSizeThreshold = std::numeric_limits<size_t>::max();
2964 if (Opts.inline_max_stacksize)
2965 FinalStackSizeThreshold = *Opts.inline_max_stacksize;
2968 FinalStackSizeThreshold = *AttrMaxStackSize;
2969 if (AllocatedSize > FinalStackSizeThreshold)
2972 return finalizeAnalysis();
2975void InlineCostCallAnalyzer::print(raw_ostream &OS) {
2976#define DEBUG_PRINT_STAT(x) OS << " " #x ": " << x << "\n"
2977 if (PrintInstructionComments)
2978 F.print(OS, &Writer);
2993#undef DEBUG_PRINT_STAT
2996#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3010 auto CalleeTLI = GetTLI(*Callee);
3011 return GetTLI(*Caller).areInlineCompatible(
3012 CalleeTLI, Opts.inline_caller_superset_nobuiltin) &&
3013 AttributeFuncs::areInlineCompatible(*Caller, *Callee);
3019 for (
unsigned I = 0, E =
Call.arg_size();
I != E; ++
I) {
3020 if (
Call.isByValArgument(
I)) {
3026 unsigned PointerSize =
DL.getPointerSizeInBits(AS);
3028 unsigned NumStores = (
TypeSize + PointerSize - 1) / PointerSize;
3036 NumStores = std::min(NumStores, 8U);
3047 Cost +=
TTI.getInlineCallPenalty(
3051 return std::min<int64_t>(
Cost, INT_MAX);
3062 GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
3084 InlineCostCallAnalyzer CA(*
Call.getCalledFunction(),
Call, Params, CalleeTTI,
3085 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
true,
3087 auto R = CA.analyze();
3089 return std::nullopt;
3090 return CA.getCost();
3099 InlineCostFeaturesAnalyzer CFA(CalleeTTI, GetAssumptionCache, GetBFI, GetTLI,
3100 PSI, ORE, *
Call.getCalledFunction(),
Call);
3101 auto R = CFA.analyze();
3103 return std::nullopt;
3104 return CFA.features();
3119 if (Callee->isPresplitCoroutine())
3126 if (!Opts.ignore_tti_inline_compatible &&
3132 if (
Call.hasFnAttr(Attribute::AlwaysInline)) {
3133 if (
Call.getAttributes().hasFnAttr(Attribute::NoInline))
3136 if (!AttributeFuncs::isStrictFPInlineCompatible(*Caller, *Callee))
3140 if (IsViable.isSuccess())
3152 if (Caller->hasFnAttribute(Attribute::Flatten)) {
3154 if (IsViable.isSuccess())
3160 if (Caller->hasOptNone())
3164 if (Callee->isInterposable(
false))
3168 if (Callee->hasFnAttribute(Attribute::NoInline))
3172 if (
Call.isNoInline())
3176 if (Callee->hasFnAttribute(
"loader-replaceable"))
3179 return std::nullopt;
3195 if (UserDecision->isSuccess())
3203 "Inlining forced by -inline-all-viable-calls");
3206 <<
"... (caller:" <<
Call.getCaller()->getName()
3211 const bool IgnoreProfile = Params.
IgnoreProfile.value_or(
false);
3213 IgnoreProfile ?
nullptr : GetBFI;
3214 InlineCostCallAnalyzer CA(
3215 *Callee,
Call, Params, CalleeTTI, GetAssumptionCache, GetBFIForAnalysis,
3216 GetTLI, IgnoreProfile ?
nullptr : PSI, ORE,
3217 true,
false, GetEphValuesCache);
3225 if (CA.wasDecidedByCostBenefit()) {
3228 CA.getCostBenefitPair());
3233 if (CA.wasDecidedByCostThreshold())
3235 CA.getStaticBonusApplied());
3244 bool ReturnsTwice =
F.hasFnAttribute(Attribute::ReturnsTwice);
3254 for (
auto &
II : BB) {
3271 switch (Callee->getIntrinsicID()) {
3274 case llvm::Intrinsic::icall_branch_funnel:
3278 "disallowed inlining of @llvm.icall.branch.funnel");
3279 case llvm::Intrinsic::localescape:
3283 "disallowed inlining of @llvm.localescape");
3284 case llvm::Intrinsic::vastart:
3288 "contains VarArgs initialized with va_start");
3396 InlineCostCallAnalyzer ICCA(*CalledFunction, *CB, Params,
TTI,
3397 GetAssumptionCache,
nullptr,
nullptr, PSI,
3403 OS <<
" Analyzing call of " << CalledFunction->
getName()
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.
bool has(LibFunc F) const
Tests whether a library function is available.
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
static constexpr TypeSize getZero()
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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 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 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.
LLVM_ABI std::optional< InlineCostFeatures > getInliningCostFeatures(CallBase &Call, TargetTransformInfo &CalleeTTI, 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.
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 InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, 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 std::optional< InlineResult > getAttributeBasedInliningDecision(CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, function_ref< const TargetLibraryInfo &(Function &)> GetTLI)
Returns InlineResult::success() if the call site should be always inlined because of user directives,...
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)
LLVM_ABI std::optional< int > getInliningCostEstimate(CallBase &Call, TargetTransformInfo &CalleeTTI, 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.
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
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.