34#include "llvm/Config/llvm-config.h"
54#define DEBUG_TYPE "inline-cost"
56STATISTIC(NumCallsAnalyzed,
"Number of call sites analyzed");
83class InlineCostCallAnalyzer;
87struct InstructionCostDetail {
90 int ThresholdBefore = 0;
91 int ThresholdAfter = 0;
93 int getThresholdDelta()
const {
return ThresholdAfter - ThresholdBefore; }
95 int getCostDelta()
const {
return CostAfter - CostBefore; }
97 bool hasThresholdChanged()
const {
return ThresholdAfter != ThresholdBefore; }
102 InlineCostCallAnalyzer *
const ICCA;
105 InlineCostAnnotationWriter(InlineCostCallAnalyzer *ICCA) : ICCA(ICCA) {}
106 void emitInstructionAnnot(
const Instruction *
I,
107 formatted_raw_ostream &OS)
override;
118class CallAnalyzer :
public InstVisitor<CallAnalyzer, bool> {
119 typedef InstVisitor<CallAnalyzer, bool> Base;
120 friend class InstVisitor<CallAnalyzer, bool>;
123 virtual ~CallAnalyzer() =
default;
124 const AnalysisOptions &Opts;
127 const TargetTransformInfo &TTI;
130 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache;
133 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI;
136 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI;
139 ProfileSummaryInfo *PSI;
145 const DataLayout &DL;
148 OptimizationRemarkEmitter *ORE;
153 CallBase &CandidateCall;
156 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
nullptr;
160 virtual void onBlockStart(
const BasicBlock *BB) {}
163 virtual void onBlockAnalyzed(
const BasicBlock *BB) {}
166 virtual void onInstructionAnalysisStart(
const Instruction *
I) {}
169 virtual void onInstructionAnalysisFinish(
const Instruction *
I) {}
179 virtual bool shouldStop() {
return false; }
188 virtual void onDisableSROA(AllocaInst *Arg) {}
191 virtual void onDisableLoadElimination() {}
195 virtual bool onCallBaseVisitStart(CallBase &
Call) {
return true; }
198 virtual void onCallPenalty() {}
201 virtual void onMemAccess(){};
205 virtual void onLoadEliminationOpportunity() {}
209 virtual void onCallArgumentSetup(
const CallBase &
Call) {}
212 virtual void onLoadRelativeIntrinsic() {}
220 virtual bool onJumpTable(
unsigned JumpTableSize) {
return true; }
224 virtual bool onCaseCluster(
unsigned NumCaseCluster) {
return true; }
228 virtual void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
229 bool DefaultDestUnreachable) {}
233 virtual void onMissedSimplification() {}
236 virtual void onInlineAsm(
const InlineAsm &Arg) {}
239 virtual void onInitializeSROAArg(AllocaInst *Arg) {}
242 virtual void onAggregateSROAUse(AllocaInst *
V) {}
244 bool handleSROA(
Value *
V,
bool DoNotDisable) {
246 if (
auto *SROAArg = getSROAArgForValueOrNull(
V)) {
248 onAggregateSROAUse(SROAArg);
251 disableSROAForArg(SROAArg);
256 bool IsCallerRecursive =
false;
257 bool IsRecursiveCall =
false;
258 bool ExposesReturnsTwice =
false;
259 bool HasDynamicAlloca =
false;
260 bool ContainsNoDuplicateCall =
false;
261 bool HasReturn =
false;
262 bool HasIndirectBr =
false;
263 bool HasUninlineableIntrinsic =
false;
264 bool InitsVargArgs =
false;
268 unsigned NumInstructions = 0;
269 unsigned NumInlineAsmInstructions = 0;
270 unsigned NumVectorInstructions = 0;
280 DenseMap<Value *, Value *> SimplifiedValues;
284 DenseMap<Value *, AllocaInst *> SROAArgValues;
287 DenseSet<AllocaInst *> EnabledSROAAllocas;
290 DenseMap<Value *, std::pair<Value *, APInt>> ConstantOffsetPtrs;
293 SmallPtrSet<BasicBlock *, 16> DeadBlocks;
297 DenseMap<BasicBlock *, BasicBlock *> KnownSuccessors;
302 bool EnableLoadElimination =
true;
305 bool AllowRecursiveCall =
false;
307 SmallPtrSet<Value *, 16> LoadAddrSet;
309 AllocaInst *getSROAArgForValueOrNull(
Value *
V)
const {
310 auto It = SROAArgValues.find(
V);
311 if (It == SROAArgValues.end() || EnabledSROAAllocas.count(It->second) == 0)
318 template <
typename T>
T *getDirectOrSimplifiedValue(
Value *
V)
const {
321 return getSimplifiedValue<T>(
V);
325 bool isAllocaDerivedArg(
Value *
V);
326 void disableSROAForArg(AllocaInst *SROAArg);
327 void disableSROA(
Value *
V);
328 void findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB);
329 void disableLoadElimination();
330 bool isGEPFree(GetElementPtrInst &
GEP);
331 bool canFoldInboundsGEP(GetElementPtrInst &
I);
334 bool simplifyCmpInstForRecCall(CmpInst &Cmp);
336 bool simplifyIntrinsicCallIsConstant(CallBase &CB);
337 bool simplifyIntrinsicCallObjectSize(CallBase &CB);
338 ConstantInt *stripAndComputeInBoundsConstantOffsets(
Value *&
V);
350 bool isKnownNonNullInCallee(
Value *
V);
353 bool allowSizeGrowth(CallBase &
Call);
356 InlineResult analyzeBlock(BasicBlock *BB,
357 const SmallPtrSetImpl<const Value *> &EphValues);
365 void visit(BasicBlock *);
366 void visit(BasicBlock &);
369 bool visitInstruction(Instruction &
I);
372 bool visitAlloca(AllocaInst &
I);
373 bool visitPHI(PHINode &
I);
374 bool visitGetElementPtr(GetElementPtrInst &
I);
375 bool visitBitCast(BitCastInst &
I);
376 bool visitPtrToInt(PtrToIntInst &
I);
377 bool visitIntToPtr(IntToPtrInst &
I);
378 bool visitCastInst(CastInst &
I);
379 bool visitCmpInst(CmpInst &
I);
380 bool visitSub(BinaryOperator &
I);
381 bool visitBinaryOperator(BinaryOperator &
I);
382 bool visitFNeg(UnaryOperator &
I);
383 bool visitLoad(LoadInst &
I);
384 bool visitStore(StoreInst &
I);
385 bool visitExtractValue(ExtractValueInst &
I);
386 bool visitInsertValue(InsertValueInst &
I);
387 bool visitCallBase(CallBase &
Call);
388 bool visitReturnInst(ReturnInst &RI);
389 bool visitUncondBrInst(UncondBrInst &BI);
390 bool visitCondBrInst(CondBrInst &BI);
391 bool visitSelectInst(SelectInst &SI);
392 bool visitSwitchInst(SwitchInst &SI);
393 bool visitIndirectBrInst(IndirectBrInst &IBI);
394 bool visitResumeInst(ResumeInst &RI);
395 bool visitCleanupReturnInst(CleanupReturnInst &RI);
396 bool visitCatchReturnInst(CatchReturnInst &RI);
397 bool visitUnreachableInst(UnreachableInst &
I);
401 Function &Callee, CallBase &
Call,
const TargetTransformInfo &TTI,
402 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
403 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
404 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
405 ProfileSummaryInfo *PSI =
nullptr,
406 OptimizationRemarkEmitter *ORE =
nullptr,
407 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
410 GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI), GetTLI(GetTLI),
411 PSI(PSI), F(
Callee), DL(F.getDataLayout()), ORE(ORE),
412 CandidateCall(
Call), GetEphValuesCache(GetEphValuesCache) {}
414 InlineResult analyze();
417 Value *getSimplifiedValueUnchecked(
Value *
V)
const {
418 return SimplifiedValues.lookup(
V);
423 template <
typename T>
T *getSimplifiedValue(
Value *
V)
const {
424 Value *SimpleV = SimplifiedValues.lookup(
V);
430 if constexpr (std::is_base_of_v<Constant, T>)
435 if (
I->getFunction() != &F)
438 if (Arg->getParent() != &F)
447 unsigned NumConstantArgs = 0;
448 unsigned NumConstantOffsetPtrArgs = 0;
449 unsigned NumAllocaArgs = 0;
450 unsigned NumConstantPtrCmps = 0;
451 unsigned NumConstantPtrDiffs = 0;
452 unsigned NumInstructionsSimplified = 0;
472int64_t getExpectedNumberOfCompare(
int NumCaseCluster) {
473 return 3 *
static_cast<int64_t
>(NumCaseCluster) / 2 - 1;
478class InlineCostCallAnalyzer final :
public CallAnalyzer {
479 const bool ComputeFullInlineCost;
480 int LoadEliminationCost = 0;
485 int SingleBBBonus = 0;
488 const InlineParams &Params;
493 DenseMap<const Instruction *, InstructionCostDetail> InstructionCostDetailMap;
500 int StaticBonusApplied = 0;
503 const bool BoostIndirectCalls;
506 const bool IgnoreThreshold;
509 const bool CostBenefitAnalysisEnabled;
511 const bool PrintInstructionComments;
522 int CostAtBBStart = 0;
529 bool DecidedByCostThreshold =
false;
532 bool DecidedByCostBenefit =
false;
535 std::optional<CostBenefitPair> CostBenefit;
537 bool SingleBB =
true;
539 unsigned SROACostSavings = 0;
540 unsigned SROACostSavingsLost = 0;
545 DenseMap<AllocaInst *, int> SROAArgCosts;
556 std::optional<int> getHotCallSiteThreshold(CallBase &
Call,
557 BlockFrequencyInfo *CallerBFI);
560 void addCost(int64_t Inc) {
561 Inc = std::clamp<int64_t>(Inc, INT_MIN, INT_MAX);
562 Cost = std::clamp<int64_t>(Inc + Cost, INT_MIN, INT_MAX);
565 void onDisableSROA(AllocaInst *Arg)
override {
566 auto CostIt = SROAArgCosts.find(Arg);
567 if (CostIt == SROAArgCosts.end())
569 addCost(CostIt->second);
570 SROACostSavings -= CostIt->second;
571 SROACostSavingsLost += CostIt->second;
572 SROAArgCosts.erase(CostIt);
575 void onDisableLoadElimination()
override {
576 addCost(LoadEliminationCost);
577 LoadEliminationCost = 0;
580 bool onCallBaseVisitStart(CallBase &
Call)
override {
581 if (std::optional<int> AttrCallThresholdBonus =
583 Threshold += *AttrCallThresholdBonus;
585 if (std::optional<int> AttrCallCost =
587 addCost(*AttrCallCost);
595 void onCallPenalty()
override { addCost(Opts.inline_call_penalty); }
597 void onMemAccess()
override { addCost(Opts.inline_memaccess_cost); }
599 void onCallArgumentSetup(
const CallBase &
Call)
override {
604 void onLoadRelativeIntrinsic()
override {
606 addCost(3 * Opts.inline_instr_cost);
619 auto IndirectCallParams = Params;
620 IndirectCallParams.DefaultThreshold =
624 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
625 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
627 if (CA.analyze().isSuccess()) {
630 addCost(-std::max(0, CA.getThreshold() - CA.getCost()));
635 Opts.inline_call_penalty));
638 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
639 bool DefaultDestUnreachable)
override {
646 if (!DefaultDestUnreachable)
647 addCost(2 * Opts.inline_instr_cost);
650 static_cast<int64_t
>(JumpTableSize) * Opts.inline_instr_cost +
651 2 * Opts.inline_instr_cost;
656 if (NumCaseCluster <= 3) {
660 addCost((NumCaseCluster - DefaultDestUnreachable) * 2 *
661 Opts.inline_instr_cost);
665 int64_t ExpectedNumberOfCompare =
666 getExpectedNumberOfCompare(NumCaseCluster);
667 int64_t SwitchCost = ExpectedNumberOfCompare * 2 * Opts.inline_instr_cost;
675 void onInlineAsm(
const InlineAsm &Arg)
override {
676 if (!Opts.inline_asm_instr_cost)
680 int SectionLevel = 0;
681 int InlineAsmInstrCount = 0;
682 for (StringRef AsmStr : AsmStrs) {
684 StringRef Trimmed = AsmStr.trim();
685 size_t hashPos = Trimmed.
find(
'#');
687 Trimmed = Trimmed.
substr(0, hashPos);
706 if (SectionLevel == 0)
707 ++InlineAsmInstrCount;
709 NumInlineAsmInstructions += InlineAsmInstrCount;
710 addCost(InlineAsmInstrCount * Opts.inline_asm_instr_cost);
713 void onMissedSimplification()
override { addCost(Opts.inline_instr_cost); }
715 void onInitializeSROAArg(AllocaInst *Arg)
override {
717 "Should not initialize SROA costs for null value.");
719 SROACostSavings += SROAArgCost;
720 SROAArgCosts[Arg] = SROAArgCost;
723 void onAggregateSROAUse(AllocaInst *SROAArg)
override {
724 auto CostIt = SROAArgCosts.find(SROAArg);
725 assert(CostIt != SROAArgCosts.end() &&
726 "expected this argument to have a cost");
727 CostIt->second += Opts.inline_instr_cost;
728 SROACostSavings += Opts.inline_instr_cost;
731 void onBlockStart(
const BasicBlock *BB)
override { CostAtBBStart = Cost; }
733 void onBlockAnalyzed(
const BasicBlock *BB)
override {
734 if (CostBenefitAnalysisEnabled) {
737 assert(GetBFI &&
"GetBFI must be available");
738 BlockFrequencyInfo *BFI = &(GetBFI(
F));
739 assert(BFI &&
"BFI must be available");
741 if (*ProfileCount == 0)
742 ColdSize += Cost - CostAtBBStart;
750 if (SingleBB && TI->getNumSuccessors() > 1) {
752 Threshold -= SingleBBBonus;
757 void onInstructionAnalysisStart(
const Instruction *
I)
override {
760 if (!PrintInstructionComments)
762 auto &CostDetail = InstructionCostDetailMap[
I];
763 CostDetail.CostBefore = Cost;
764 CostDetail.ThresholdBefore = Threshold;
767 void onInstructionAnalysisFinish(
const Instruction *
I)
override {
770 if (!PrintInstructionComments)
772 auto &CostDetail = InstructionCostDetailMap[
I];
773 CostDetail.CostAfter = Cost;
774 CostDetail.ThresholdAfter = Threshold;
777 bool isCostBenefitAnalysisEnabled() {
778 if (!PSI || !PSI->hasProfileSummary())
785 if (!
valueOr(Opts.inline_enable_cost_benefit_analysis,
786 PSI->hasInstrumentationProfile()))
790 if (!
Caller->getEntryCount())
793 BlockFrequencyInfo *CallerBFI = &(GetBFI(*Caller));
798 if (!PSI->isHotCallSite(CandidateCall, CallerBFI))
802 auto EntryCount =
F.getEntryCount();
803 if (!EntryCount || *EntryCount == 0)
806 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
814 unsigned getInliningCostBenefitAnalysisSavingsMultiplier()
const {
815 return Opts.inline_savings_multiplier.value_or(
820 unsigned getInliningCostBenefitAnalysisProfitableMultiplier()
const {
821 return Opts.inline_savings_profitable_multiplier.value_or(
825 void OverrideCycleSavingsAndSizeForTesting(APInt &CycleSavings,
int &
Size) {
827 CandidateCall,
"inline-cycle-savings-for-test")) {
828 CycleSavings = *AttrCycleSavings;
832 CandidateCall,
"inline-runtime-cost-for-test")) {
833 Size = *AttrRuntimeCost;
840 std::optional<bool> costBenefitAnalysis() {
841 if (!CostBenefitAnalysisEnabled)
852 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
865 APInt CycleSavings(128, 0);
868 APInt CurrentSavings(128, 0);
872 if (getSimplifiedValue<ConstantInt>(BI->getCondition()))
873 CurrentSavings += Opts.inline_instr_cost;
875 if (getSimplifiedValue<ConstantInt>(
SI->getCondition()))
876 CurrentSavings += Opts.inline_instr_cost;
877 }
else if (SimplifiedValues.
count(&
I)) {
879 CurrentSavings += Opts.inline_instr_cost;
884 CurrentSavings *= *ProfileCount;
885 CycleSavings += CurrentSavings;
889 auto EntryProfileCount =
F.getEntryCount();
890 assert(EntryProfileCount && *EntryProfileCount);
891 CycleSavings += *EntryProfileCount / 2;
892 CycleSavings = CycleSavings.
udiv(*EntryProfileCount);
895 auto *CallerBB = CandidateCall.
getParent();
896 BlockFrequencyInfo *CallerBFI = &(GetBFI(*(CallerBB->getParent())));
903 int Size = Cost - ColdSize;
907 Size =
Size > Opts.inline_size_allowance ?
Size - Opts.inline_size_allowance
910 OverrideCycleSavingsAndSizeForTesting(CycleSavings,
Size);
911 CostBenefit.emplace(APInt(128,
Size), CycleSavings);
934 APInt Threshold(128, PSI->getOrCompHotCountThreshold());
937 APInt UpperBoundCycleSavings = CycleSavings;
938 UpperBoundCycleSavings *= getInliningCostBenefitAnalysisSavingsMultiplier();
939 if (UpperBoundCycleSavings.
uge(Threshold))
942 APInt LowerBoundCycleSavings = CycleSavings;
943 LowerBoundCycleSavings *=
944 getInliningCostBenefitAnalysisProfitableMultiplier();
945 if (LowerBoundCycleSavings.
ult(Threshold))
952 InlineResult finalizeAnalysis()
override {
959 if (
Caller->hasMinSize()) {
965 if (DeadBlocks.
count(
L->getHeader()))
975 if (NumVectorInstructions <= NumInstructions / 10)
976 Threshold -= VectorBonus;
977 else if (NumVectorInstructions <= NumInstructions / 2)
978 Threshold -= VectorBonus / 2;
980 if (std::optional<int> AttrCost =
987 Cost *= *AttrCostMult;
989 if (std::optional<int> AttrThreshold =
991 Threshold = *AttrThreshold;
993 if (
auto Result = costBenefitAnalysis()) {
994 DecidedByCostBenefit =
true;
1001 if (IgnoreThreshold)
1004 DecidedByCostThreshold =
true;
1005 return Cost < std::max(1, Threshold)
1007 : InlineResult::
failure(
"Cost over threshold.");
1010 bool shouldStop()
override {
1011 if (IgnoreThreshold || ComputeFullInlineCost)
1015 if (Cost < Threshold)
1017 DecidedByCostThreshold =
true;
1021 void onLoadEliminationOpportunity()
override {
1022 LoadEliminationCost += Opts.inline_instr_cost;
1025 InlineResult onAnalysisStart()
override {
1036 assert(NumInstructions == 0);
1037 assert(NumVectorInstructions == 0);
1040 updateThreshold(CandidateCall,
F);
1046 assert(SingleBBBonus >= 0);
1047 assert(VectorBonus >= 0);
1052 Threshold += (SingleBBBonus + VectorBonus);
1060 if (
F.getCallingConv() == CallingConv::Cold)
1066 if (Cost >= Threshold && !ComputeFullInlineCost)
1073 InlineCostCallAnalyzer(
1074 Function &Callee, CallBase &
Call,
const InlineParams &Params,
1075 const TargetTransformInfo &
TTI,
1076 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
1077 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
1078 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
1079 ProfileSummaryInfo *PSI =
nullptr,
1080 OptimizationRemarkEmitter *ORE =
nullptr,
bool BoostIndirect =
true,
1081 bool IgnoreThreshold =
false,
1082 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
1084 bool PrintInstructionComments =
false)
1085 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI, PSI,
1086 ORE, GetEphValuesCache),
1087 ComputeFullInlineCost(Opts.inline_cost_full ||
1088 Params.ComputeFullInlineCost || ORE ||
1089 isCostBenefitAnalysisEnabled()),
1090 Params(Params), Threshold(Params.DefaultThreshold),
1091 BoostIndirectCalls(BoostIndirect), IgnoreThreshold(IgnoreThreshold),
1092 CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
1093 PrintInstructionComments(Opts.print_instruction_comments ||
1094 PrintInstructionComments),
1096 AllowRecursiveCall = *Params.AllowRecursiveCall;
1100 InlineCostAnnotationWriter Writer;
1106 void print(raw_ostream &OS);
1108 std::optional<InstructionCostDetail> getCostDetails(
const Instruction *
I) {
1109 auto It = InstructionCostDetailMap.find(
I);
1110 if (It != InstructionCostDetailMap.end())
1112 return std::nullopt;
1115 ~InlineCostCallAnalyzer()
override =
default;
1116 int getThreshold()
const {
return Threshold; }
1117 int getCost()
const {
return Cost; }
1118 int getStaticBonusApplied()
const {
return StaticBonusApplied; }
1119 std::optional<CostBenefitPair> getCostBenefitPair() {
return CostBenefit; }
1120 bool wasDecidedByCostBenefit()
const {
return DecidedByCostBenefit; }
1121 bool wasDecidedByCostThreshold()
const {
return DecidedByCostThreshold; }
1129static bool isSoleCallToLocalFunction(
const CallBase &CB,
1132 (
Callee.hasLinkOnceODRLinkage() &&
1133 Callee.hasFnAttribute(Attribute::LikelyModuleLocal));
1137class InlineCostFeaturesAnalyzer final :
public CallAnalyzer {
1144 static constexpr int JTCostMultiplier = 2;
1145 static constexpr int CaseClusterCostMultiplier = 2;
1146 static constexpr int SwitchDefaultDestCostMultiplier = 2;
1147 static constexpr int SwitchCostMultiplier = 2;
1151 unsigned SROACostSavingOpportunities = 0;
1152 int VectorBonus = 0;
1153 int SingleBBBonus = 0;
1156 DenseMap<AllocaInst *, unsigned> SROACosts;
1159 Cost[
static_cast<size_t>(Feature)] += Delta;
1163 Cost[
static_cast<size_t>(Feature)] =
Value;
1166 void onDisableSROA(AllocaInst *Arg)
override {
1167 auto CostIt = SROACosts.find(Arg);
1168 if (CostIt == SROACosts.end())
1171 increment(InlineCostFeatureIndex::sroa_losses, CostIt->second);
1172 SROACostSavingOpportunities -= CostIt->second;
1173 SROACosts.erase(CostIt);
1176 void onDisableLoadElimination()
override {
1177 set(InlineCostFeatureIndex::load_elimination, 1);
1180 void onCallPenalty()
override {
1181 increment(InlineCostFeatureIndex::call_penalty, Opts.inline_call_penalty);
1184 void onCallArgumentSetup(
const CallBase &
Call)
override {
1185 increment(InlineCostFeatureIndex::call_argument_setup,
1189 void onLoadRelativeIntrinsic()
override {
1190 increment(InlineCostFeatureIndex::load_relative_intrinsic,
1191 3 * Opts.inline_instr_cost);
1196 increment(InlineCostFeatureIndex::lowered_call_arg_setup,
1200 InlineParams IndirectCallParams = { 0,
1214 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
1215 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
1217 if (CA.analyze().isSuccess()) {
1218 increment(InlineCostFeatureIndex::nested_inline_cost_estimate,
1220 increment(InlineCostFeatureIndex::nested_inlines, 1);
1227 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
1228 bool DefaultDestUnreachable)
override {
1229 if (JumpTableSize) {
1230 if (!DefaultDestUnreachable)
1231 increment(InlineCostFeatureIndex::switch_default_dest_penalty,
1232 SwitchDefaultDestCostMultiplier * Opts.inline_instr_cost);
1234 static_cast<int64_t
>(JumpTableSize) * Opts.inline_instr_cost +
1235 JTCostMultiplier * Opts.inline_instr_cost;
1236 increment(InlineCostFeatureIndex::jump_table_penalty, JTCost);
1240 if (NumCaseCluster <= 3) {
1241 increment(InlineCostFeatureIndex::case_cluster_penalty,
1242 (NumCaseCluster - DefaultDestUnreachable) *
1243 CaseClusterCostMultiplier * Opts.inline_instr_cost);
1247 int64_t ExpectedNumberOfCompare =
1248 getExpectedNumberOfCompare(NumCaseCluster);
1250 int64_t SwitchCost =
1251 ExpectedNumberOfCompare * SwitchCostMultiplier * Opts.inline_instr_cost;
1252 increment(InlineCostFeatureIndex::switch_penalty, SwitchCost);
1255 void onMissedSimplification()
override {
1256 increment(InlineCostFeatureIndex::unsimplified_common_instructions,
1257 Opts.inline_instr_cost);
1260 void onInitializeSROAArg(AllocaInst *Arg)
override {
1262 SROACosts[Arg] = SROAArgCost;
1263 SROACostSavingOpportunities += SROAArgCost;
1266 void onAggregateSROAUse(AllocaInst *Arg)
override {
1267 SROACosts.find(Arg)->second += Opts.inline_instr_cost;
1268 SROACostSavingOpportunities += Opts.inline_instr_cost;
1271 void onBlockAnalyzed(
const BasicBlock *BB)
override {
1273 set(InlineCostFeatureIndex::is_multiple_blocks, 1);
1274 Threshold -= SingleBBBonus;
1277 InlineResult finalizeAnalysis()
override {
1279 if (
Caller->hasMinSize()) {
1282 for (
Loop *L : LI) {
1284 if (DeadBlocks.
count(
L->getHeader()))
1286 increment(InlineCostFeatureIndex::num_loops,
1290 set(InlineCostFeatureIndex::dead_blocks, DeadBlocks.
size());
1291 set(InlineCostFeatureIndex::simplified_instructions,
1292 NumInstructionsSimplified);
1293 set(InlineCostFeatureIndex::constant_args, NumConstantArgs);
1294 set(InlineCostFeatureIndex::constant_offset_ptr_args,
1295 NumConstantOffsetPtrArgs);
1296 set(InlineCostFeatureIndex::sroa_savings, SROACostSavingOpportunities);
1298 if (NumVectorInstructions <= NumInstructions / 10)
1299 Threshold -= VectorBonus;
1300 else if (NumVectorInstructions <= NumInstructions / 2)
1301 Threshold -= VectorBonus / 2;
1303 set(InlineCostFeatureIndex::threshold, Threshold);
1308 bool shouldStop()
override {
return false; }
1310 void onLoadEliminationOpportunity()
override {
1311 increment(InlineCostFeatureIndex::load_elimination, 1);
1314 InlineResult onAnalysisStart()
override {
1315 increment(InlineCostFeatureIndex::callsite_cost,
1318 set(InlineCostFeatureIndex::cold_cc_penalty,
1319 (
F.getCallingConv() == CallingConv::Cold));
1321 set(InlineCostFeatureIndex::last_call_to_static_bonus,
1322 isSoleCallToLocalFunction(CandidateCall,
F));
1327 int SingleBBBonusPercent = 50;
1331 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
1332 VectorBonus = Threshold * VectorBonusPercent / 100;
1333 Threshold += (SingleBBBonus + VectorBonus);
1339 InlineCostFeaturesAnalyzer(
1340 const TargetTransformInfo &
TTI,
1341 function_ref<AssumptionCache &(
Function &)> &GetAssumptionCache,
1342 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI,
1343 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI,
1344 ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
Function &Callee,
1346 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI,
1355bool CallAnalyzer::isAllocaDerivedArg(
Value *
V) {
1356 return SROAArgValues.
count(
V);
1359void CallAnalyzer::disableSROAForArg(AllocaInst *SROAArg) {
1360 onDisableSROA(SROAArg);
1361 EnabledSROAAllocas.
erase(SROAArg);
1362 disableLoadElimination();
1365void InlineCostAnnotationWriter::emitInstructionAnnot(
1366 const Instruction *
I, formatted_raw_ostream &OS) {
1370 std::optional<InstructionCostDetail>
Record = ICCA->getCostDetails(
I);
1372 OS <<
"; No analysis for the instruction";
1374 OS <<
"; cost before = " <<
Record->CostBefore
1375 <<
", cost after = " <<
Record->CostAfter
1376 <<
", threshold before = " <<
Record->ThresholdBefore
1377 <<
", threshold after = " <<
Record->ThresholdAfter <<
", ";
1378 OS <<
"cost delta = " <<
Record->getCostDelta();
1379 if (
Record->hasThresholdChanged())
1380 OS <<
", threshold delta = " <<
Record->getThresholdDelta();
1382 auto *
V = ICCA->getSimplifiedValueUnchecked(
const_cast<Instruction *
>(
I));
1384 OS <<
", simplified to ";
1387 if (
VI->getFunction() !=
I->getFunction())
1388 OS <<
" (caller instruction)";
1390 if (VArg->getParent() !=
I->getFunction())
1391 OS <<
" (caller argument)";
1398void CallAnalyzer::disableSROA(
Value *
V) {
1399 if (
auto *SROAArg = getSROAArgForValueOrNull(
V)) {
1400 disableSROAForArg(SROAArg);
1404void CallAnalyzer::disableLoadElimination() {
1405 if (EnableLoadElimination) {
1406 onDisableLoadElimination();
1407 EnableLoadElimination =
false;
1415bool CallAnalyzer::accumulateGEPOffset(GEPOperator &
GEP, APInt &
Offset) {
1416 unsigned IntPtrWidth =
DL.getIndexTypeSizeInBits(
GEP.getType());
1420 GTI != GTE; ++GTI) {
1422 getDirectOrSimplifiedValue<ConstantInt>(GTI.getOperand());
1429 if (StructType *STy = GTI.getStructTypeOrNull()) {
1431 const StructLayout *SL =
DL.getStructLayout(STy);
1436 APInt TypeSize(IntPtrWidth, GTI.getSequentialElementStride(
DL));
1445bool CallAnalyzer::isGEPFree(GetElementPtrInst &
GEP) {
1448 for (
const Use &
Op :
GEP.indices())
1449 if (Constant *SimpleOp = getSimplifiedValue<Constant>(
Op))
1458bool CallAnalyzer::visitAlloca(AllocaInst &
I) {
1459 disableSROA(
I.getOperand(0));
1463 if (
I.isArrayAllocation()) {
1464 Constant *
Size = getSimplifiedValue<Constant>(
I.getArraySize());
1475 AllocSize->getLimitedValue(),
1476 I.getAllocationBaseSize(
DL).getKnownMinValue(), AllocatedSize);
1478 HasDynamicAlloca =
true;
1483 if (
I.isStaticAlloca()) {
1495 HasDynamicAlloca =
true;
1501bool CallAnalyzer::visitPHI(PHINode &
I) {
1513 bool CheckSROA =
I.getType()->isPointerTy();
1517 std::pair<Value *, APInt> FirstBaseAndOffset = {
nullptr, ZeroOffset};
1518 Value *FirstV =
nullptr;
1520 for (
unsigned i = 0, e =
I.getNumIncomingValues(); i != e; ++i) {
1528 if (KnownSuccessor && KnownSuccessor !=
I.getParent())
1531 Value *
V =
I.getIncomingValue(i);
1536 Constant *
C = getDirectOrSimplifiedValue<Constant>(
V);
1538 std::pair<Value *, APInt> BaseAndOffset = {
nullptr, ZeroOffset};
1539 if (!
C && CheckSROA)
1540 BaseAndOffset = ConstantOffsetPtrs.
lookup(
V);
1542 if (!
C && !BaseAndOffset.first)
1559 if (FirstBaseAndOffset == BaseAndOffset)
1573 FirstBaseAndOffset = BaseAndOffset;
1578 SimplifiedValues[&
I] = FirstC;
1583 if (FirstBaseAndOffset.first) {
1584 ConstantOffsetPtrs[&
I] = std::move(FirstBaseAndOffset);
1586 if (
auto *SROAArg = getSROAArgForValueOrNull(FirstV))
1587 SROAArgValues[&
I] = SROAArg;
1597bool CallAnalyzer::canFoldInboundsGEP(GetElementPtrInst &
I) {
1599 std::pair<Value *, APInt> BaseAndOffset =
1600 ConstantOffsetPtrs.
lookup(
I.getPointerOperand());
1601 if (!BaseAndOffset.first)
1610 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1615bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &
I) {
1616 auto *SROAArg = getSROAArgForValueOrNull(
I.getPointerOperand());
1619 auto IsGEPOffsetConstant = [&](GetElementPtrInst &
GEP) {
1620 for (
const Use &
Op :
GEP.indices())
1621 if (!getDirectOrSimplifiedValue<Constant>(
Op))
1626 if (Opts.gep_const_evaluation)
1630 if ((
I.isInBounds() && canFoldInboundsGEP(
I)) || IsGEPOffsetConstant(
I)) {
1632 SROAArgValues[&
I] = SROAArg;
1640 disableSROAForArg(SROAArg);
1641 return isGEPFree(
I);
1647bool CallAnalyzer::simplifyCmpInstForRecCall(CmpInst &Cmp) {
1651 auto *CmpOp =
Cmp.getOperand(0);
1656 auto *CallBB = CandidateCall.
getParent();
1657 auto *Predecessor = CallBB->getSinglePredecessor();
1662 if (!Br || Br->getCondition() != &Cmp)
1667 bool ArgFound =
false;
1668 Value *FuncArg =
nullptr, *CallArg =
nullptr;
1669 for (
unsigned ArgNum = 0;
1670 ArgNum <
F.arg_size() && ArgNum < CandidateCall.
arg_size(); ArgNum++) {
1671 FuncArg =
F.getArg(ArgNum);
1673 if (FuncArg == CmpOp && CallArg != CmpOp) {
1684 CondContext
CC(&Cmp);
1685 CC.Invert = (CallBB != Br->getSuccessor(0));
1687 CC.AffectedValues.insert(FuncArg);
1693 if ((ConstVal->isOne() &&
CC.Invert) ||
1694 (ConstVal->isZero() && !
CC.Invert)) {
1695 SimplifiedValues[&
Cmp] = ConstVal;
1703bool CallAnalyzer::simplifyInstruction(Instruction &
I) {
1706 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
1714 SimplifiedValues[&
I] =
C;
1727bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
1729 auto *
C = getDirectOrSimplifiedValue<Constant>(Arg);
1732 SimplifiedValues[&CB] = ConstantInt::get(RT,
C ? 1 : 0);
1736bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
1746 SimplifiedValues[&CB] =
C;
1750bool CallAnalyzer::visitBitCast(BitCastInst &
I) {
1756 std::pair<Value *, APInt> BaseAndOffset =
1757 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1759 if (BaseAndOffset.first)
1760 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1763 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1764 SROAArgValues[&
I] = SROAArg;
1770bool CallAnalyzer::visitPtrToInt(PtrToIntInst &
I) {
1778 unsigned AS =
I.getOperand(0)->getType()->getPointerAddressSpace();
1779 if (IntegerSize ==
DL.getPointerSizeInBits(AS)) {
1780 std::pair<Value *, APInt> BaseAndOffset =
1781 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1782 if (BaseAndOffset.first)
1783 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1793 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1794 SROAArgValues[&
I] = SROAArg;
1800bool CallAnalyzer::visitIntToPtr(IntToPtrInst &
I) {
1808 unsigned IntegerSize =
Op->getType()->getScalarSizeInBits();
1809 if (IntegerSize <=
DL.getPointerTypeSizeInBits(
I.getType())) {
1810 std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.
lookup(
Op);
1811 if (BaseAndOffset.first)
1812 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1816 if (
auto *SROAArg = getSROAArgForValueOrNull(
Op))
1817 SROAArgValues[&
I] = SROAArg;
1823bool CallAnalyzer::visitCastInst(CastInst &
I) {
1830 disableSROA(
I.getOperand(0));
1835 switch (
I.getOpcode()) {
1836 case Instruction::FPTrunc:
1837 case Instruction::FPExt:
1838 case Instruction::UIToFP:
1839 case Instruction::SIToFP:
1840 case Instruction::FPToUI:
1841 case Instruction::FPToSI:
1853bool CallAnalyzer::paramHasAttr(Argument *
A, Attribute::AttrKind Attr) {
1857bool CallAnalyzer::isKnownNonNullInCallee(
Value *
V) {
1870 if (isAllocaDerivedArg(
V))
1879bool CallAnalyzer::allowSizeGrowth(CallBase &
Call) {
1904bool InlineCostCallAnalyzer::isColdCallSite(CallBase &
Call,
1905 BlockFrequencyInfo *CallerBFI) {
1908 if (PSI && PSI->hasProfileSummary())
1909 return PSI->isColdCallSite(
Call, CallerBFI);
1919 const BranchProbability ColdProb(Opts.cold_callsite_rel_freq, 100);
1921 auto CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1922 auto CallerEntryFreq =
1924 return CallSiteFreq < CallerEntryFreq * ColdProb;
1928InlineCostCallAnalyzer::getHotCallSiteThreshold(CallBase &
Call,
1929 BlockFrequencyInfo *CallerBFI) {
1933 if (PSI && PSI->hasProfileSummary() && PSI->isHotCallSite(
Call, CallerBFI))
1939 return std::nullopt;
1946 BlockFrequency CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
1947 BlockFrequency CallerEntryFreq = CallerBFI->
getEntryFreq();
1948 std::optional<BlockFrequency> Limit =
1949 CallerEntryFreq.
mul(Opts.hot_callsite_rel_freq);
1950 if (Limit && CallSiteFreq >= *Limit)
1954 return std::nullopt;
1957void InlineCostCallAnalyzer::updateThreshold(CallBase &
Call,
Function &Callee) {
1959 if (!allowSizeGrowth(
Call)) {
1967 auto MinIfValid = [](
int A, std::optional<int>
B) {
1968 return B ? std::min(
A, *
B) :
A;
1972 auto MaxIfValid = [](
int A, std::optional<int>
B) {
1973 return B ? std::max(
A, *
B) :
A;
1988 int SingleBBBonusPercent = 50;
1993 auto DisallowAllBonuses = [&]() {
1994 SingleBBBonusPercent = 0;
1995 VectorBonusPercent = 0;
1996 LastCallToStaticBonus = 0;
2001 if (
Caller->hasMinSize()) {
2007 SingleBBBonusPercent = 0;
2008 VectorBonusPercent = 0;
2009 }
else if (
Caller->hasOptSize())
2014 if (!
Caller->hasMinSize()) {
2015 std::optional<int> HintThreshold =
Caller->hasOptSize()
2018 if (
Callee.hasFnAttribute(Attribute::InlineHint))
2019 Threshold = MaxIfValid(Threshold, HintThreshold);
2028 BlockFrequencyInfo *CallerBFI = GetBFI ? &(GetBFI(*Caller)) : nullptr;
2029 auto HotCallSiteThreshold = getHotCallSiteThreshold(
Call, CallerBFI);
2030 if (!
Caller->hasOptSize() && HotCallSiteThreshold) {
2036 Threshold = *HotCallSiteThreshold;
2049 DisallowAllBonuses();
2054 if (PSI->isFunctionEntryHot(&Callee)) {
2059 Threshold = MaxIfValid(Threshold, HintThreshold);
2060 }
else if (PSI->isFunctionEntryCold(&Callee)) {
2066 DisallowAllBonuses();
2078 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
2079 VectorBonus = Threshold * VectorBonusPercent / 100;
2084 if (isSoleCallToLocalFunction(
Call,
F)) {
2085 addCost(-LastCallToStaticBonus);
2086 StaticBonusApplied = LastCallToStaticBonus;
2090bool CallAnalyzer::visitCmpInst(CmpInst &
I) {
2097 if (simplifyCmpInstForRecCall(
I))
2100 if (
I.getOpcode() == Instruction::FCmp)
2105 Value *LHSBase, *RHSBase;
2106 APInt LHSOffset, RHSOffset;
2107 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2109 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2110 if (RHSBase && LHSBase == RHSBase) {
2116 ++NumConstantPtrCmps;
2121 auto isImplicitNullCheckCmp = [](
const CmpInst &
I) {
2122 for (
auto *User :
I.users())
2124 if (!
Instr->getMetadata(LLVMContext::MD_make_implicit))
2132 if (isKnownNonNullInCallee(
I.getOperand(0))) {
2140 if (isImplicitNullCheckCmp(
I))
2146bool CallAnalyzer::visitSub(BinaryOperator &
I) {
2150 Value *LHSBase, *RHSBase;
2151 APInt LHSOffset, RHSOffset;
2152 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2154 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2155 if (RHSBase && LHSBase == RHSBase) {
2161 SimplifiedValues[&
I] =
C;
2162 ++NumConstantPtrDiffs;
2170 return Base::visitSub(
I);
2173bool CallAnalyzer::visitBinaryOperator(BinaryOperator &
I) {
2175 Constant *CLHS = getDirectOrSimplifiedValue<Constant>(
LHS);
2176 Constant *CRHS = getDirectOrSimplifiedValue<Constant>(
RHS);
2178 Value *SimpleV =
nullptr;
2181 FI->getFastMathFlags(),
DL);
2187 SimplifiedValues[&
I] =
C;
2199 using namespace llvm::PatternMatch;
2201 if (
I.getType()->isFloatingPointTy() &&
2209 Type *Ty =
I.getType();
2217bool CallAnalyzer::visitFNeg(UnaryOperator &
I) {
2219 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
2225 SimplifiedValues[&
I] =
C;
2236bool CallAnalyzer::visitLoad(LoadInst &
I) {
2237 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2243 if (EnableLoadElimination &&
2244 !LoadAddrSet.
insert(
I.getPointerOperand()).second &&
I.isUnordered()) {
2245 onLoadEliminationOpportunity();
2253bool CallAnalyzer::visitStore(StoreInst &
I) {
2254 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2265 disableLoadElimination();
2271bool CallAnalyzer::visitExtractValue(ExtractValueInst &
I) {
2272 Value *
Op =
I.getAggregateOperand();
2276 if (
Value *SimpleOp = getSimplifiedValueUnchecked(
Op)) {
2277 SimplifyQuery SQ(
DL);
2280 SimplifiedValues[&
I] = SimpleV;
2286 return Base::visitExtractValue(
I);
2289bool CallAnalyzer::visitInsertValue(InsertValueInst &
I) {
2295 return Base::visitInsertValue(
I);
2304bool CallAnalyzer::simplifyCallSite(
Function *
F, CallBase &
Call) {
2313 SmallVector<Constant *, 4> ConstantArgs;
2316 Constant *
C = getDirectOrSimplifiedValue<Constant>(
I);
2323 SimplifiedValues[&
Call] =
C;
2330bool CallAnalyzer::isLoweredToCall(
Function *
F, CallBase &
Call) {
2331 const TargetLibraryInfo *
TLI = GetTLI ? &GetTLI(*
F) : nullptr;
2335 LibFunc LF =
TLI->getLibFunc(*
F);
2340 case LibFunc_memcpy_chk:
2341 case LibFunc_memmove_chk:
2342 case LibFunc_mempcpy_chk:
2343 case LibFunc_memset_chk: {
2350 auto *LenOp = getDirectOrSimplifiedValue<ConstantInt>(
Call.
getOperand(2));
2353 if (LenOp && ObjSizeOp &&
2354 LenOp->getLimitedValue() <= ObjSizeOp->getLimitedValue()) {
2366bool CallAnalyzer::visitCallBase(CallBase &
Call) {
2367 if (!onCallBaseVisitStart(
Call))
2371 !
F.hasFnAttribute(Attribute::ReturnsTwice)) {
2373 ExposesReturnsTwice =
true;
2377 ContainsNoDuplicateCall =
true;
2380 onInlineAsm(*InlineAsmOp);
2388 F = getSimplifiedValue<Function>(Callee);
2390 onCallArgumentSetup(
Call);
2393 disableLoadElimination();
2394 return Base::visitCallBase(
Call);
2398 assert(
F &&
"Expected a call to a known function");
2401 if (simplifyCallSite(
F,
Call))
2407 switch (
II->getIntrinsicID()) {
2410 disableLoadElimination();
2411 return Base::visitCallBase(
Call);
2413 case Intrinsic::load_relative:
2414 onLoadRelativeIntrinsic();
2417 case Intrinsic::memset:
2418 case Intrinsic::memcpy:
2419 case Intrinsic::memmove:
2420 disableLoadElimination();
2423 case Intrinsic::icall_branch_funnel:
2424 case Intrinsic::localescape:
2425 HasUninlineableIntrinsic =
true;
2427 case Intrinsic::vastart:
2428 InitsVargArgs =
true;
2430 case Intrinsic::launder_invariant_group:
2431 if (
auto *SROAArg = getSROAArgForValueOrNull(
II->getOperand(0)))
2432 SROAArgValues[
II] = SROAArg;
2434 case Intrinsic::is_constant:
2435 return simplifyIntrinsicCallIsConstant(
Call);
2436 case Intrinsic::objectsize:
2437 return simplifyIntrinsicCallObjectSize(
Call);
2444 IsRecursiveCall =
true;
2445 if (!AllowRecursiveCall)
2449 if (isLoweredToCall(
F,
Call)) {
2454 disableLoadElimination();
2455 return Base::visitCallBase(
Call);
2458bool CallAnalyzer::visitReturnInst(ReturnInst &RI) {
2460 bool Free = !HasReturn;
2465bool CallAnalyzer::visitUncondBrInst(UncondBrInst &BI) {
2472bool CallAnalyzer::visitCondBrInst(CondBrInst &BI) {
2474 return getDirectOrSimplifiedValue<ConstantInt>(BI.
getCondition()) ||
2478bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
2479 bool CheckSROA =
SI.getType()->isPointerTy();
2483 Constant *TrueC = getDirectOrSimplifiedValue<Constant>(TrueVal);
2484 Constant *FalseC = getDirectOrSimplifiedValue<Constant>(FalseVal);
2485 Constant *CondC = getSimplifiedValue<Constant>(
SI.getCondition());
2489 if (TrueC == FalseC && TrueC) {
2490 SimplifiedValues[&
SI] = TrueC;
2495 return Base::visitSelectInst(SI);
2497 std::pair<Value *, APInt> TrueBaseAndOffset =
2498 ConstantOffsetPtrs.
lookup(TrueVal);
2499 std::pair<Value *, APInt> FalseBaseAndOffset =
2500 ConstantOffsetPtrs.
lookup(FalseVal);
2501 if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first) {
2502 ConstantOffsetPtrs[&
SI] = std::move(TrueBaseAndOffset);
2504 if (
auto *SROAArg = getSROAArgForValueOrNull(TrueVal))
2505 SROAArgValues[&
SI] = SROAArg;
2509 return Base::visitSelectInst(SI);
2520 if (TrueC && FalseC) {
2522 SimplifiedValues[&
SI] =
C;
2526 return Base::visitSelectInst(SI);
2531 SimplifiedValues[&
SI] = SelectedC;
2538 std::pair<Value *, APInt> BaseAndOffset =
2539 ConstantOffsetPtrs.
lookup(SelectedV);
2540 if (BaseAndOffset.first) {
2541 ConstantOffsetPtrs[&
SI] = std::move(BaseAndOffset);
2543 if (
auto *SROAArg = getSROAArgForValueOrNull(SelectedV))
2544 SROAArgValues[&
SI] = SROAArg;
2550bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
2553 if (getDirectOrSimplifiedValue<ConstantInt>(
SI.getCondition()))
2568 unsigned JumpTableSize = 0;
2569 BlockFrequencyInfo *BFI = GetBFI ? &(GetBFI(
F)) : nullptr;
2570 unsigned NumCaseCluster =
2573 onFinalizeSwitch(JumpTableSize, NumCaseCluster,
SI.defaultDestUnreachable());
2577bool CallAnalyzer::visitIndirectBrInst(IndirectBrInst &IBI) {
2586 HasIndirectBr =
true;
2590bool CallAnalyzer::visitResumeInst(ResumeInst &RI) {
2596bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
2602bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
2608bool CallAnalyzer::visitUnreachableInst(UnreachableInst &
I) {
2615bool CallAnalyzer::visitInstruction(Instruction &
I) {
2624 for (
const Use &
Op :
I.operands())
2638CallAnalyzer::analyzeBlock(BasicBlock *BB,
2639 const SmallPtrSetImpl<const Value *> &EphValues) {
2640 for (Instruction &
I : *BB) {
2657 ++NumVectorInstructions;
2664 onInstructionAnalysisStart(&
I);
2666 if (Base::visit(&
I))
2667 ++NumInstructionsSimplified;
2669 onMissedSimplification();
2671 onInstructionAnalysisFinish(&
I);
2672 using namespace ore;
2675 if (IsRecursiveCall && !AllowRecursiveCall)
2677 else if (ExposesReturnsTwice)
2679 else if (HasDynamicAlloca)
2681 else if (HasIndirectBr)
2683 else if (HasUninlineableIntrinsic)
2685 else if (InitsVargArgs)
2687 if (!
IR.isSuccess()) {
2690 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2692 <<
NV(
"Callee", &
F) <<
" has uninlinable pattern ("
2693 <<
NV(
"InlineResult",
IR.getFailureReason())
2694 <<
") and cost is not fully computed";
2702 if (IsCallerRecursive &&
2703 AllocatedSize > Opts.recursive_inline_max_stacksize) {
2708 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2710 <<
NV(
"Callee", &
F) <<
" is "
2711 <<
NV(
"InlineResult",
IR.getFailureReason())
2712 <<
". Cost is not fully computed";
2719 "Call site analysis is not favorable to inlining.");
2731ConstantInt *CallAnalyzer::stripAndComputeInBoundsConstantOffsets(
Value *&
V) {
2732 if (!
V->getType()->isPointerTy())
2735 unsigned AS =
V->getType()->getPointerAddressSpace();
2736 unsigned IntPtrWidth =
DL.getIndexSizeInBits(AS);
2741 SmallPtrSet<Value *, 4> Visited;
2747 V =
GEP->getPointerOperand();
2749 if (GA->isInterposable())
2751 V = GA->getAliasee();
2755 assert(
V->getType()->isPointerTy() &&
"Unexpected operand type!");
2756 }
while (Visited.
insert(
V).second);
2758 Type *IdxPtrTy =
DL.getIndexType(
V->getType());
2769void CallAnalyzer::findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB) {
2776 return KnownSucc && KnownSucc != Succ;
2781 return (!DeadBlocks.
count(BB) &&
2783 [&](BasicBlock *
P) {
return IsEdgeDead(
P, BB); }));
2786 for (BasicBlock *Succ :
successors(CurrBB)) {
2787 if (Succ == NextBB || !IsNewlyDead(Succ))
2791 while (!NewDead.
empty()) {
2809InlineResult CallAnalyzer::analyze() {
2812 auto Result = onAnalysisStart();
2821 for (User *U :
Caller->users()) {
2824 IsCallerRecursive =
true;
2832 for (Argument &FAI :
F.args()) {
2834 SimplifiedValues[&FAI] = *CAI;
2838 Value *PtrArg = *CAI;
2839 if (ConstantInt *
C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
2840 ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg,
C->getValue());
2844 SROAArgValues[&FAI] = SROAArg;
2845 onInitializeSROAArg(SROAArg);
2846 EnabledSROAAllocas.
insert(SROAArg);
2851 NumConstantOffsetPtrArgs = ConstantOffsetPtrs.
size();
2852 NumAllocaArgs = SROAArgValues.
size();
2856 SmallPtrSet<const Value *, 32> EphValuesStorage;
2857 const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
2858 if (GetEphValuesCache)
2859 EphValues = &GetEphValuesCache(
F).ephValues();
2871 typedef SmallSetVector<BasicBlock *, 16> BBSetVector;
2872 BBSetVector BBWorklist;
2873 BBWorklist.insert(&
F.getEntryBlock());
2876 for (
unsigned Idx = 0;
Idx != BBWorklist.size(); ++
Idx) {
2899 InlineResult
IR = analyzeBlock(BB, *EphValues);
2900 if (!
IR.isSuccess())
2909 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2911 BBWorklist.insert(NextBB);
2912 KnownSuccessors[BB] = NextBB;
2913 findDeadBlocks(BB, NextBB);
2918 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
2919 BasicBlock *NextBB =
SI->findCaseValue(SimpleCond)->getCaseSuccessor();
2920 BBWorklist.insert(NextBB);
2921 KnownSuccessors[BB] = NextBB;
2922 findDeadBlocks(BB, NextBB);
2931 onBlockAnalyzed(BB);
2937 if (!isSoleCallToLocalFunction(CandidateCall,
F) && ContainsNoDuplicateCall)
2943 size_t FinalStackSizeThreshold = std::numeric_limits<size_t>::max();
2944 if (Opts.inline_max_stacksize)
2945 FinalStackSizeThreshold = *Opts.inline_max_stacksize;
2948 FinalStackSizeThreshold = *AttrMaxStackSize;
2949 if (AllocatedSize > FinalStackSizeThreshold)
2952 return finalizeAnalysis();
2955void InlineCostCallAnalyzer::print(raw_ostream &OS) {
2956#define DEBUG_PRINT_STAT(x) OS << " " #x ": " << x << "\n"
2957 if (PrintInstructionComments)
2958 F.print(OS, &Writer);
2973#undef DEBUG_PRINT_STAT
2976#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2990 auto CalleeTLI = GetTLI(*Callee);
2991 return GetTLI(*Caller).areInlineCompatible(
2992 CalleeTLI, Opts.inline_caller_superset_nobuiltin) &&
2993 AttributeFuncs::areInlineCompatible(*Caller, *Callee);
3000 for (
unsigned I = 0, E =
Call.arg_size();
I != E; ++
I) {
3001 if (
Call.isByValArgument(
I)) {
3007 unsigned PointerSize =
DL.getPointerSizeInBits(AS);
3009 unsigned NumStores = (
TypeSize + PointerSize - 1) / PointerSize;
3017 NumStores = std::min(NumStores, 8U);
3019 Cost += 2 * NumStores * Opts.inline_instr_cost;
3023 Cost += Opts.inline_instr_cost;
3027 Cost += Opts.inline_instr_cost;
3029 Opts.inline_call_penalty);
3031 return std::min<int64_t>(
Cost, INT_MAX);
3042 GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
3064 InlineCostCallAnalyzer CA(*
Call.getCalledFunction(),
Call, Params, CallerTTI,
3065 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
true,
3067 auto R = CA.analyze();
3069 return std::nullopt;
3070 return CA.getCost();
3079 InlineCostFeaturesAnalyzer CFA(CallerTTI, GetAssumptionCache, GetBFI, GetTLI,
3080 PSI, ORE, *
Call.getCalledFunction(),
Call);
3081 auto R = CFA.analyze();
3083 return std::nullopt;
3084 return CFA.features();
3099 if (Callee->isPresplitCoroutine())
3106 if (!Opts.ignore_tti_inline_compatible &&
3112 if (
Call.hasFnAttr(Attribute::AlwaysInline)) {
3113 if (
Call.getAttributes().hasFnAttr(Attribute::NoInline))
3116 if (!AttributeFuncs::isStrictFPInlineCompatible(*Caller, *Callee))
3120 if (IsViable.isSuccess())
3132 if (Caller->hasFnAttribute(Attribute::Flatten)) {
3134 if (IsViable.isSuccess())
3140 if (Caller->hasOptNone())
3144 if (Callee->isInterposable(
false))
3148 if (Callee->hasFnAttribute(Attribute::NoInline))
3152 if (
Call.isNoInline())
3156 if (Callee->hasFnAttribute(
"loader-replaceable"))
3159 return std::nullopt;
3175 if (UserDecision->isSuccess())
3183 "Inlining forced by -inline-all-viable-calls");
3186 <<
"... (caller:" <<
Call.getCaller()->getName()
3191 const bool IgnoreProfile = Params.
IgnoreProfile.value_or(
false);
3193 IgnoreProfile ?
nullptr : GetBFI;
3194 InlineCostCallAnalyzer CA(
3195 *Callee,
Call, Params, CallerTTI, GetAssumptionCache, GetBFIForAnalysis,
3196 GetTLI, IgnoreProfile ?
nullptr : PSI, ORE,
3197 true,
false, GetEphValuesCache);
3205 if (CA.wasDecidedByCostBenefit()) {
3208 CA.getCostBenefitPair());
3213 if (CA.wasDecidedByCostThreshold())
3215 CA.getStaticBonusApplied());
3224 bool ReturnsTwice =
F.hasFnAttribute(Attribute::ReturnsTwice);
3234 for (
auto &
II : BB) {
3251 switch (Callee->getIntrinsicID()) {
3254 case llvm::Intrinsic::icall_branch_funnel:
3258 "disallowed inlining of @llvm.icall.branch.funnel");
3259 case llvm::Intrinsic::localescape:
3263 "disallowed inlining of @llvm.localescape");
3264 case llvm::Intrinsic::vastart:
3268 "contains VarArgs initialized with va_start");
3321 if (!Opts.inline_threshold) {
3324 Params.
ColdThreshold = Opts.inlinecold_threshold.value_or(45);
3336 unsigned OptLevel) {
3374 InlineCostCallAnalyzer ICCA(*CalledFunction, *CB, Params,
TTI,
3375 GetAssumptionCache,
nullptr,
nullptr, PSI,
3381 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(const IPOOptions &Opts, CallBase &CB, BlockFrequencyInfo &CallerBFI)
Return true if the block containing the call site has a BlockFrequency of less than -coldcc-rel-freq ...
static bool IsIndirectCall(const MachineInstr *MI)
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.
#define DEBUG_PRINT_STAT(x)
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.
This is an important class for using LLVM in a threaded context.
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.
LLVM_ABI int getInstrCost(const LLVMContext &C)
Return -inline-instr-cost.
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[]
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.
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.
LLVM_ABI InlineParams getInlineParams(const LLVMContext &C)
Generate the parameters to tune the inline cost analysis based only on the commandline options.
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 InlineParams getInlineParamsFromOptLevel(const LLVMContext &C, unsigned OptLevel)
Generate the parameters to tune the inline cost analysis based on command line options.
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 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.
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.