33#include "llvm/Config/llvm-config.h"
54#define DEBUG_TYPE "inline-cost"
56STATISTIC(NumCallsAnalyzed,
"Number of call sites analyzed");
60 cl::desc(
"Default amount of inlining to perform"));
69 cl::desc(
"Ignore TTI attributes compatibility check between callee/caller "
70 "during inline cost calculation"));
74 cl::desc(
"Prints comments for instruction based on inline cost analysis"));
78 cl::desc(
"Control the amount of inlining to perform (default = 225)"));
82 cl::desc(
"Threshold for inlining functions with inline hint"));
87 cl::desc(
"Threshold for inlining cold callsites"));
91 cl::desc(
"Enable the cost-benefit analysis for the inliner"));
98 cl::desc(
"Multiplier to multiply cycle savings by during inlining"));
105 cl::desc(
"A multiplier on top of cycle savings to decide whether the "
106 "savings won't justify the cost"));
110 cl::desc(
"The maximum size of a callee that get's "
111 "inlined without sufficient cycle savings"));
118 cl::desc(
"Threshold for inlining functions with cold attribute"));
122 cl::desc(
"Threshold for hot callsites "));
126 cl::desc(
"Threshold for locally hot callsites "));
130 cl::desc(
"Maximum block frequency, expressed as a percentage of caller's "
131 "entry frequency, for a callsite to be cold in the absence of "
132 "profile information."));
136 cl::desc(
"Minimum block frequency, expressed as a multiple of caller's "
137 "entry frequency, for a callsite to be hot in the absence of "
138 "profile information."));
142 cl::desc(
"Cost of a single instruction when inlining"));
146 cl::desc(
"Cost of a single inline asm instruction when inlining"));
150 cl::desc(
"Cost of load/store instruction when inlining"));
154 cl::desc(
"Call penalty that is applied per callsite when inlining"));
158 cl::init(std::numeric_limits<size_t>::max()),
159 cl::desc(
"Do not inline functions with a stack size "
160 "that exceeds the specified limit"));
165 cl::desc(
"Do not inline recursive functions with a stack "
166 "size that exceeds the specified limit"));
170 cl::desc(
"Compute the full inline cost of a call site even when the cost "
171 "exceeds the threshold."));
175 cl::desc(
"Allow inlining when caller has a superset of callee's nobuiltin "
180 cl::desc(
"Disables evaluation of GetElementPtr with constant operands"));
184 cl::desc(
"Inline all viable calls, even if they exceed the inlining "
212class InlineCostCallAnalyzer;
216struct InstructionCostDetail {
219 int ThresholdBefore = 0;
220 int ThresholdAfter = 0;
222 int getThresholdDelta()
const {
return ThresholdAfter - ThresholdBefore; }
224 int getCostDelta()
const {
return CostAfter - CostBefore; }
226 bool hasThresholdChanged()
const {
return ThresholdAfter != ThresholdBefore; }
231 InlineCostCallAnalyzer *
const ICCA;
234 InlineCostAnnotationWriter(InlineCostCallAnalyzer *ICCA) : ICCA(ICCA) {}
235 void emitInstructionAnnot(
const Instruction *
I,
236 formatted_raw_ostream &OS)
override;
247class CallAnalyzer :
public InstVisitor<CallAnalyzer, bool> {
248 typedef InstVisitor<CallAnalyzer, bool> Base;
249 friend class InstVisitor<CallAnalyzer, bool>;
252 virtual ~CallAnalyzer() =
default;
254 const TargetTransformInfo &TTI;
257 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache;
260 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI;
263 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI;
266 ProfileSummaryInfo *PSI;
272 const DataLayout &DL;
275 OptimizationRemarkEmitter *ORE;
280 CallBase &CandidateCall;
283 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
nullptr;
287 virtual void onBlockStart(
const BasicBlock *BB) {}
290 virtual void onBlockAnalyzed(
const BasicBlock *BB) {}
293 virtual void onInstructionAnalysisStart(
const Instruction *
I) {}
296 virtual void onInstructionAnalysisFinish(
const Instruction *
I) {}
306 virtual bool shouldStop() {
return false; }
315 virtual void onDisableSROA(AllocaInst *Arg) {}
318 virtual void onDisableLoadElimination() {}
322 virtual bool onCallBaseVisitStart(CallBase &
Call) {
return true; }
325 virtual void onCallPenalty() {}
328 virtual void onMemAccess(){};
332 virtual void onLoadEliminationOpportunity() {}
336 virtual void onCallArgumentSetup(
const CallBase &
Call) {}
339 virtual void onLoadRelativeIntrinsic() {}
347 virtual bool onJumpTable(
unsigned JumpTableSize) {
return true; }
351 virtual bool onCaseCluster(
unsigned NumCaseCluster) {
return true; }
355 virtual void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
356 bool DefaultDestUnreachable) {}
360 virtual void onMissedSimplification() {}
363 virtual void onInlineAsm(
const InlineAsm &Arg) {}
366 virtual void onInitializeSROAArg(AllocaInst *Arg) {}
369 virtual void onAggregateSROAUse(AllocaInst *V) {}
371 bool handleSROA(
Value *V,
bool DoNotDisable) {
373 if (
auto *SROAArg = getSROAArgForValueOrNull(V)) {
375 onAggregateSROAUse(SROAArg);
378 disableSROAForArg(SROAArg);
383 bool IsCallerRecursive =
false;
384 bool IsRecursiveCall =
false;
385 bool ExposesReturnsTwice =
false;
386 bool HasDynamicAlloca =
false;
387 bool ContainsNoDuplicateCall =
false;
388 bool HasReturn =
false;
389 bool HasIndirectBr =
false;
390 bool HasUninlineableIntrinsic =
false;
391 bool InitsVargArgs =
false;
394 uint64_t AllocatedSize = 0;
395 unsigned NumInstructions = 0;
396 unsigned NumInlineAsmInstructions = 0;
397 unsigned NumVectorInstructions = 0;
407 DenseMap<Value *, Value *> SimplifiedValues;
411 DenseMap<Value *, AllocaInst *> SROAArgValues;
414 DenseSet<AllocaInst *> EnabledSROAAllocas;
417 DenseMap<Value *, std::pair<Value *, APInt>> ConstantOffsetPtrs;
420 SmallPtrSet<BasicBlock *, 16> DeadBlocks;
424 DenseMap<BasicBlock *, BasicBlock *> KnownSuccessors;
429 bool EnableLoadElimination =
true;
432 bool AllowRecursiveCall =
false;
434 SmallPtrSet<Value *, 16> LoadAddrSet;
436 AllocaInst *getSROAArgForValueOrNull(
Value *V)
const {
437 auto It = SROAArgValues.find(V);
438 if (It == SROAArgValues.end() || EnabledSROAAllocas.count(It->second) == 0)
445 template <
typename T>
T *getDirectOrSimplifiedValue(
Value *V)
const {
448 return getSimplifiedValue<T>(V);
452 bool isAllocaDerivedArg(
Value *V);
453 void disableSROAForArg(AllocaInst *SROAArg);
454 void disableSROA(
Value *V);
455 void findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB);
456 void disableLoadElimination();
457 bool isGEPFree(GetElementPtrInst &
GEP);
458 bool canFoldInboundsGEP(GetElementPtrInst &
I);
459 bool accumulateGEPOffset(GEPOperator &
GEP, APInt &
Offset);
461 bool simplifyCmpInstForRecCall(CmpInst &Cmp);
463 bool simplifyIntrinsicCallIsConstant(CallBase &CB);
464 bool simplifyIntrinsicCallObjectSize(CallBase &CB);
465 ConstantInt *stripAndComputeInBoundsConstantOffsets(
Value *&V);
473 bool paramHasAttr(Argument *
A, Attribute::AttrKind Attr);
477 bool isKnownNonNullInCallee(
Value *V);
480 bool allowSizeGrowth(CallBase &
Call);
483 InlineResult analyzeBlock(BasicBlock *BB,
484 const SmallPtrSetImpl<const Value *> &EphValues);
492 void visit(BasicBlock *);
493 void visit(BasicBlock &);
496 bool visitInstruction(Instruction &
I);
499 bool visitAlloca(AllocaInst &
I);
500 bool visitPHI(PHINode &
I);
501 bool visitGetElementPtr(GetElementPtrInst &
I);
502 bool visitBitCast(BitCastInst &
I);
503 bool visitPtrToInt(PtrToIntInst &
I);
504 bool visitIntToPtr(IntToPtrInst &
I);
505 bool visitCastInst(CastInst &
I);
506 bool visitCmpInst(CmpInst &
I);
507 bool visitSub(BinaryOperator &
I);
508 bool visitBinaryOperator(BinaryOperator &
I);
509 bool visitFNeg(UnaryOperator &
I);
510 bool visitLoad(LoadInst &
I);
511 bool visitStore(StoreInst &
I);
512 bool visitExtractValue(ExtractValueInst &
I);
513 bool visitInsertValue(InsertValueInst &
I);
514 bool visitCallBase(CallBase &
Call);
515 bool visitReturnInst(ReturnInst &RI);
516 bool visitUncondBrInst(UncondBrInst &BI);
517 bool visitCondBrInst(CondBrInst &BI);
518 bool visitSelectInst(SelectInst &SI);
519 bool visitSwitchInst(SwitchInst &SI);
520 bool visitIndirectBrInst(IndirectBrInst &IBI);
521 bool visitResumeInst(ResumeInst &RI);
522 bool visitCleanupReturnInst(CleanupReturnInst &RI);
523 bool visitCatchReturnInst(CatchReturnInst &RI);
524 bool visitUnreachableInst(UnreachableInst &
I);
528 Function &Callee, CallBase &
Call,
const TargetTransformInfo &TTI,
529 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
530 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
531 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
532 ProfileSummaryInfo *PSI =
nullptr,
533 OptimizationRemarkEmitter *ORE =
nullptr,
534 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
536 : TTI(TTI), GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI),
537 GetTLI(GetTLI), PSI(PSI), F(
Callee), DL(F.getDataLayout()), ORE(ORE),
538 CandidateCall(
Call), GetEphValuesCache(GetEphValuesCache) {}
540 InlineResult analyze();
543 Value *getSimplifiedValueUnchecked(
Value *V)
const {
544 return SimplifiedValues.lookup(V);
549 template <
typename T>
T *getSimplifiedValue(
Value *V)
const {
550 Value *SimpleV = SimplifiedValues.lookup(V);
556 if constexpr (std::is_base_of_v<Constant, T>)
561 if (
I->getFunction() != &F)
564 if (Arg->getParent() != &F)
573 unsigned NumConstantArgs = 0;
574 unsigned NumConstantOffsetPtrArgs = 0;
575 unsigned NumAllocaArgs = 0;
576 unsigned NumConstantPtrCmps = 0;
577 unsigned NumConstantPtrDiffs = 0;
578 unsigned NumInstructionsSimplified = 0;
598int64_t getExpectedNumberOfCompare(
int NumCaseCluster) {
599 return 3 *
static_cast<int64_t
>(NumCaseCluster) / 2 - 1;
604class InlineCostCallAnalyzer final :
public CallAnalyzer {
605 const bool ComputeFullInlineCost;
606 int LoadEliminationCost = 0;
611 int SingleBBBonus = 0;
614 const InlineParams &Params;
619 DenseMap<const Instruction *, InstructionCostDetail> InstructionCostDetailMap;
626 int StaticBonusApplied = 0;
629 const bool BoostIndirectCalls;
632 const bool IgnoreThreshold;
635 const bool CostBenefitAnalysisEnabled;
646 int CostAtBBStart = 0;
653 bool DecidedByCostThreshold =
false;
656 bool DecidedByCostBenefit =
false;
659 std::optional<CostBenefitPair> CostBenefit;
661 bool SingleBB =
true;
663 unsigned SROACostSavings = 0;
664 unsigned SROACostSavingsLost = 0;
669 DenseMap<AllocaInst *, int> SROAArgCosts;
680 std::optional<int> getHotCallSiteThreshold(CallBase &
Call,
681 BlockFrequencyInfo *CallerBFI);
684 void addCost(int64_t Inc) {
685 Inc = std::clamp<int64_t>(Inc, INT_MIN, INT_MAX);
686 Cost = std::clamp<int64_t>(Inc + Cost, INT_MIN, INT_MAX);
689 void onDisableSROA(AllocaInst *Arg)
override {
690 auto CostIt = SROAArgCosts.find(Arg);
691 if (CostIt == SROAArgCosts.end())
693 addCost(CostIt->second);
694 SROACostSavings -= CostIt->second;
695 SROACostSavingsLost += CostIt->second;
696 SROAArgCosts.erase(CostIt);
699 void onDisableLoadElimination()
override {
700 addCost(LoadEliminationCost);
701 LoadEliminationCost = 0;
704 bool onCallBaseVisitStart(CallBase &
Call)
override {
705 if (std::optional<int> AttrCallThresholdBonus =
707 Threshold += *AttrCallThresholdBonus;
709 if (std::optional<int> AttrCallCost =
711 addCost(*AttrCallCost);
719 void onCallPenalty()
override { addCost(
CallPenalty); }
723 void onCallArgumentSetup(
const CallBase &
Call)
override {
728 void onLoadRelativeIntrinsic()
override {
743 auto IndirectCallParams = Params;
744 IndirectCallParams.DefaultThreshold =
748 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
749 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
751 if (CA.analyze().isSuccess()) {
754 addCost(-std::max(0, CA.getThreshold() - CA.getCost()));
762 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
763 bool DefaultDestUnreachable)
override {
770 if (!DefaultDestUnreachable)
779 if (NumCaseCluster <= 3) {
783 addCost((NumCaseCluster - DefaultDestUnreachable) * 2 *
InstrCost);
787 int64_t ExpectedNumberOfCompare =
788 getExpectedNumberOfCompare(NumCaseCluster);
789 int64_t SwitchCost = ExpectedNumberOfCompare * 2 *
InstrCost;
797 void onInlineAsm(
const InlineAsm &Arg)
override {
802 int SectionLevel = 0;
803 int InlineAsmInstrCount = 0;
804 for (StringRef AsmStr : AsmStrs) {
806 StringRef Trimmed = AsmStr.trim();
807 size_t hashPos = Trimmed.
find(
'#');
809 Trimmed = Trimmed.
substr(0, hashPos);
828 if (SectionLevel == 0)
829 ++InlineAsmInstrCount;
831 NumInlineAsmInstructions += InlineAsmInstrCount;
835 void onMissedSimplification()
override { addCost(
InstrCost); }
837 void onInitializeSROAArg(AllocaInst *Arg)
override {
839 "Should not initialize SROA costs for null value.");
841 SROACostSavings += SROAArgCost;
842 SROAArgCosts[Arg] = SROAArgCost;
845 void onAggregateSROAUse(AllocaInst *SROAArg)
override {
846 auto CostIt = SROAArgCosts.find(SROAArg);
847 assert(CostIt != SROAArgCosts.end() &&
848 "expected this argument to have a cost");
853 void onBlockStart(
const BasicBlock *BB)
override { CostAtBBStart = Cost; }
855 void onBlockAnalyzed(
const BasicBlock *BB)
override {
856 if (CostBenefitAnalysisEnabled) {
859 assert(GetBFI &&
"GetBFI must be available");
860 BlockFrequencyInfo *BFI = &(GetBFI(
F));
861 assert(BFI &&
"BFI must be available");
863 if (*ProfileCount == 0)
864 ColdSize += Cost - CostAtBBStart;
872 if (SingleBB && TI->getNumSuccessors() > 1) {
874 Threshold -= SingleBBBonus;
879 void onInstructionAnalysisStart(
const Instruction *
I)
override {
884 auto &CostDetail = InstructionCostDetailMap[
I];
885 CostDetail.CostBefore = Cost;
886 CostDetail.ThresholdBefore = Threshold;
889 void onInstructionAnalysisFinish(
const Instruction *
I)
override {
894 auto &CostDetail = InstructionCostDetailMap[
I];
895 CostDetail.CostAfter = Cost;
896 CostDetail.ThresholdAfter = Threshold;
899 bool isCostBenefitAnalysisEnabled() {
900 if (!PSI || !PSI->hasProfileSummary())
912 if (!PSI->hasInstrumentationProfile())
917 if (!
Caller->getEntryCount())
920 BlockFrequencyInfo *CallerBFI = &(GetBFI(*Caller));
925 if (!PSI->isHotCallSite(CandidateCall, CallerBFI))
929 auto EntryCount =
F.getEntryCount();
930 if (!EntryCount || *EntryCount == 0)
933 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
941 unsigned getInliningCostBenefitAnalysisSavingsMultiplier()
const {
948 unsigned getInliningCostBenefitAnalysisProfitableMultiplier()
const {
954 void OverrideCycleSavingsAndSizeForTesting(APInt &CycleSavings,
int &
Size) {
956 CandidateCall,
"inline-cycle-savings-for-test")) {
957 CycleSavings = *AttrCycleSavings;
961 CandidateCall,
"inline-runtime-cost-for-test")) {
962 Size = *AttrRuntimeCost;
969 std::optional<bool> costBenefitAnalysis() {
970 if (!CostBenefitAnalysisEnabled)
981 BlockFrequencyInfo *CalleeBFI = &(GetBFI(
F));
994 APInt CycleSavings(128, 0);
997 APInt CurrentSavings(128, 0);
1001 if (getSimplifiedValue<ConstantInt>(BI->getCondition()))
1004 if (getSimplifiedValue<ConstantInt>(
SI->getCondition()))
1006 }
else if (SimplifiedValues.
count(&
I)) {
1013 CurrentSavings *= *ProfileCount;
1014 CycleSavings += CurrentSavings;
1018 auto EntryProfileCount =
F.getEntryCount();
1019 assert(EntryProfileCount && *EntryProfileCount);
1020 CycleSavings += *EntryProfileCount / 2;
1021 CycleSavings = CycleSavings.
udiv(*EntryProfileCount);
1024 auto *CallerBB = CandidateCall.
getParent();
1025 BlockFrequencyInfo *CallerBFI = &(GetBFI(*(CallerBB->getParent())));
1032 int Size = Cost - ColdSize;
1038 OverrideCycleSavingsAndSizeForTesting(CycleSavings,
Size);
1039 CostBenefit.emplace(APInt(128,
Size), CycleSavings);
1062 APInt Threshold(128, PSI->getOrCompHotCountThreshold());
1065 APInt UpperBoundCycleSavings = CycleSavings;
1066 UpperBoundCycleSavings *= getInliningCostBenefitAnalysisSavingsMultiplier();
1067 if (UpperBoundCycleSavings.
uge(Threshold))
1070 APInt LowerBoundCycleSavings = CycleSavings;
1071 LowerBoundCycleSavings *=
1072 getInliningCostBenefitAnalysisProfitableMultiplier();
1073 if (LowerBoundCycleSavings.
ult(Threshold))
1077 return std::nullopt;
1080 InlineResult finalizeAnalysis()
override {
1087 if (
Caller->hasMinSize()) {
1091 for (
Loop *L : LI) {
1093 if (DeadBlocks.
count(
L->getHeader()))
1103 if (NumVectorInstructions <= NumInstructions / 10)
1104 Threshold -= VectorBonus;
1105 else if (NumVectorInstructions <= NumInstructions / 2)
1106 Threshold -= VectorBonus / 2;
1108 if (std::optional<int> AttrCost =
1115 Cost *= *AttrCostMult;
1117 if (std::optional<int> AttrThreshold =
1119 Threshold = *AttrThreshold;
1121 if (
auto Result = costBenefitAnalysis()) {
1122 DecidedByCostBenefit =
true;
1129 if (IgnoreThreshold)
1132 DecidedByCostThreshold =
true;
1133 return Cost < std::max(1, Threshold)
1135 : InlineResult::
failure(
"Cost over threshold.");
1138 bool shouldStop()
override {
1139 if (IgnoreThreshold || ComputeFullInlineCost)
1143 if (Cost < Threshold)
1145 DecidedByCostThreshold =
true;
1149 void onLoadEliminationOpportunity()
override {
1153 InlineResult onAnalysisStart()
override {
1164 assert(NumInstructions == 0);
1165 assert(NumVectorInstructions == 0);
1168 updateThreshold(CandidateCall,
F);
1174 assert(SingleBBBonus >= 0);
1175 assert(VectorBonus >= 0);
1180 Threshold += (SingleBBBonus + VectorBonus);
1188 if (
F.getCallingConv() == CallingConv::Cold)
1194 if (Cost >= Threshold && !ComputeFullInlineCost)
1201 InlineCostCallAnalyzer(
1202 Function &Callee, CallBase &
Call,
const InlineParams &Params,
1203 const TargetTransformInfo &
TTI,
1204 function_ref<AssumptionCache &(
Function &)> GetAssumptionCache,
1205 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI =
nullptr,
1206 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI =
nullptr,
1207 ProfileSummaryInfo *PSI =
nullptr,
1208 OptimizationRemarkEmitter *ORE =
nullptr,
bool BoostIndirect =
true,
1209 bool IgnoreThreshold =
false,
1210 function_ref<EphemeralValuesCache &(
Function &)> GetEphValuesCache =
1212 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI, PSI,
1213 ORE, GetEphValuesCache),
1215 Params.ComputeFullInlineCost || ORE ||
1216 isCostBenefitAnalysisEnabled()),
1218 BoostIndirectCalls(BoostIndirect), IgnoreThreshold(IgnoreThreshold),
1219 CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
1221 AllowRecursiveCall = *Params.AllowRecursiveCall;
1225 InlineCostAnnotationWriter Writer;
1231 void print(raw_ostream &OS);
1233 std::optional<InstructionCostDetail> getCostDetails(
const Instruction *
I) {
1234 auto It = InstructionCostDetailMap.find(
I);
1235 if (It != InstructionCostDetailMap.end())
1237 return std::nullopt;
1240 ~InlineCostCallAnalyzer()
override =
default;
1241 int getThreshold()
const {
return Threshold; }
1242 int getCost()
const {
return Cost; }
1243 int getStaticBonusApplied()
const {
return StaticBonusApplied; }
1244 std::optional<CostBenefitPair> getCostBenefitPair() {
return CostBenefit; }
1245 bool wasDecidedByCostBenefit()
const {
return DecidedByCostBenefit; }
1246 bool wasDecidedByCostThreshold()
const {
return DecidedByCostThreshold; }
1250static bool isSoleCallToLocalFunction(
const CallBase &CB,
1252 return Callee.hasLocalLinkage() &&
Callee.hasOneLiveUse() &&
1256class InlineCostFeaturesAnalyzer final :
public CallAnalyzer {
1263 static constexpr int JTCostMultiplier = 2;
1264 static constexpr int CaseClusterCostMultiplier = 2;
1265 static constexpr int SwitchDefaultDestCostMultiplier = 2;
1266 static constexpr int SwitchCostMultiplier = 2;
1270 unsigned SROACostSavingOpportunities = 0;
1271 int VectorBonus = 0;
1272 int SingleBBBonus = 0;
1275 DenseMap<AllocaInst *, unsigned> SROACosts;
1278 Cost[
static_cast<size_t>(Feature)] += Delta;
1282 Cost[
static_cast<size_t>(Feature)] =
Value;
1285 void onDisableSROA(AllocaInst *Arg)
override {
1286 auto CostIt = SROACosts.find(Arg);
1287 if (CostIt == SROACosts.end())
1290 increment(InlineCostFeatureIndex::sroa_losses, CostIt->second);
1291 SROACostSavingOpportunities -= CostIt->second;
1292 SROACosts.erase(CostIt);
1295 void onDisableLoadElimination()
override {
1296 set(InlineCostFeatureIndex::load_elimination, 1);
1299 void onCallPenalty()
override {
1300 increment(InlineCostFeatureIndex::call_penalty,
CallPenalty);
1303 void onCallArgumentSetup(
const CallBase &
Call)
override {
1304 increment(InlineCostFeatureIndex::call_argument_setup,
1308 void onLoadRelativeIntrinsic()
override {
1309 increment(InlineCostFeatureIndex::load_relative_intrinsic, 3 *
InstrCost);
1314 increment(InlineCostFeatureIndex::lowered_call_arg_setup,
1318 InlineParams IndirectCallParams = { 0,
1332 InlineCostCallAnalyzer CA(*
F,
Call, IndirectCallParams,
TTI,
1333 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
1335 if (CA.analyze().isSuccess()) {
1336 increment(InlineCostFeatureIndex::nested_inline_cost_estimate,
1338 increment(InlineCostFeatureIndex::nested_inlines, 1);
1345 void onFinalizeSwitch(
unsigned JumpTableSize,
unsigned NumCaseCluster,
1346 bool DefaultDestUnreachable)
override {
1347 if (JumpTableSize) {
1348 if (!DefaultDestUnreachable)
1349 increment(InlineCostFeatureIndex::switch_default_dest_penalty,
1350 SwitchDefaultDestCostMultiplier *
InstrCost);
1351 int64_t JTCost =
static_cast<int64_t
>(JumpTableSize) *
InstrCost +
1353 increment(InlineCostFeatureIndex::jump_table_penalty, JTCost);
1357 if (NumCaseCluster <= 3) {
1358 increment(InlineCostFeatureIndex::case_cluster_penalty,
1359 (NumCaseCluster - DefaultDestUnreachable) *
1364 int64_t ExpectedNumberOfCompare =
1365 getExpectedNumberOfCompare(NumCaseCluster);
1367 int64_t SwitchCost =
1368 ExpectedNumberOfCompare * SwitchCostMultiplier *
InstrCost;
1369 increment(InlineCostFeatureIndex::switch_penalty, SwitchCost);
1372 void onMissedSimplification()
override {
1373 increment(InlineCostFeatureIndex::unsimplified_common_instructions,
1377 void onInitializeSROAArg(AllocaInst *Arg)
override {
1379 SROACosts[Arg] = SROAArgCost;
1380 SROACostSavingOpportunities += SROAArgCost;
1383 void onAggregateSROAUse(AllocaInst *Arg)
override {
1384 SROACosts.find(Arg)->second +=
InstrCost;
1385 SROACostSavingOpportunities +=
InstrCost;
1388 void onBlockAnalyzed(
const BasicBlock *BB)
override {
1390 set(InlineCostFeatureIndex::is_multiple_blocks, 1);
1391 Threshold -= SingleBBBonus;
1394 InlineResult finalizeAnalysis()
override {
1396 if (
Caller->hasMinSize()) {
1399 for (
Loop *L : LI) {
1401 if (DeadBlocks.
count(
L->getHeader()))
1403 increment(InlineCostFeatureIndex::num_loops,
1407 set(InlineCostFeatureIndex::dead_blocks, DeadBlocks.
size());
1408 set(InlineCostFeatureIndex::simplified_instructions,
1409 NumInstructionsSimplified);
1410 set(InlineCostFeatureIndex::constant_args, NumConstantArgs);
1411 set(InlineCostFeatureIndex::constant_offset_ptr_args,
1412 NumConstantOffsetPtrArgs);
1413 set(InlineCostFeatureIndex::sroa_savings, SROACostSavingOpportunities);
1415 if (NumVectorInstructions <= NumInstructions / 10)
1416 Threshold -= VectorBonus;
1417 else if (NumVectorInstructions <= NumInstructions / 2)
1418 Threshold -= VectorBonus / 2;
1420 set(InlineCostFeatureIndex::threshold, Threshold);
1425 bool shouldStop()
override {
return false; }
1427 void onLoadEliminationOpportunity()
override {
1428 increment(InlineCostFeatureIndex::load_elimination, 1);
1431 InlineResult onAnalysisStart()
override {
1432 increment(InlineCostFeatureIndex::callsite_cost,
1435 set(InlineCostFeatureIndex::cold_cc_penalty,
1436 (
F.getCallingConv() == CallingConv::Cold));
1438 set(InlineCostFeatureIndex::last_call_to_static_bonus,
1439 isSoleCallToLocalFunction(CandidateCall,
F));
1444 int SingleBBBonusPercent = 50;
1448 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
1449 VectorBonus = Threshold * VectorBonusPercent / 100;
1450 Threshold += (SingleBBBonus + VectorBonus);
1456 InlineCostFeaturesAnalyzer(
1457 const TargetTransformInfo &
TTI,
1458 function_ref<AssumptionCache &(
Function &)> &GetAssumptionCache,
1459 function_ref<BlockFrequencyInfo &(
Function &)> GetBFI,
1460 function_ref<
const TargetLibraryInfo &(
Function &)> GetTLI,
1461 ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
Function &Callee,
1463 : CallAnalyzer(
Callee,
Call,
TTI, GetAssumptionCache, GetBFI, GetTLI,
1472bool CallAnalyzer::isAllocaDerivedArg(
Value *V) {
1473 return SROAArgValues.
count(V);
1476void CallAnalyzer::disableSROAForArg(AllocaInst *SROAArg) {
1477 onDisableSROA(SROAArg);
1478 EnabledSROAAllocas.
erase(SROAArg);
1479 disableLoadElimination();
1482void InlineCostAnnotationWriter::emitInstructionAnnot(
1483 const Instruction *
I, formatted_raw_ostream &OS) {
1487 std::optional<InstructionCostDetail>
Record = ICCA->getCostDetails(
I);
1489 OS <<
"; No analysis for the instruction";
1491 OS <<
"; cost before = " <<
Record->CostBefore
1492 <<
", cost after = " <<
Record->CostAfter
1493 <<
", threshold before = " <<
Record->ThresholdBefore
1494 <<
", threshold after = " <<
Record->ThresholdAfter <<
", ";
1495 OS <<
"cost delta = " <<
Record->getCostDelta();
1496 if (
Record->hasThresholdChanged())
1497 OS <<
", threshold delta = " <<
Record->getThresholdDelta();
1499 auto *
V = ICCA->getSimplifiedValueUnchecked(
const_cast<Instruction *
>(
I));
1501 OS <<
", simplified to ";
1504 if (
VI->getFunction() !=
I->getFunction())
1505 OS <<
" (caller instruction)";
1507 if (VArg->getParent() !=
I->getFunction())
1508 OS <<
" (caller argument)";
1515void CallAnalyzer::disableSROA(
Value *V) {
1516 if (
auto *SROAArg = getSROAArgForValueOrNull(V)) {
1517 disableSROAForArg(SROAArg);
1521void CallAnalyzer::disableLoadElimination() {
1522 if (EnableLoadElimination) {
1523 onDisableLoadElimination();
1524 EnableLoadElimination =
false;
1532bool CallAnalyzer::accumulateGEPOffset(GEPOperator &
GEP, APInt &
Offset) {
1533 unsigned IntPtrWidth =
DL.getIndexTypeSizeInBits(
GEP.getType());
1537 GTI != GTE; ++GTI) {
1539 getDirectOrSimplifiedValue<ConstantInt>(GTI.getOperand());
1546 if (StructType *STy = GTI.getStructTypeOrNull()) {
1548 const StructLayout *SL =
DL.getStructLayout(STy);
1553 APInt TypeSize(IntPtrWidth, GTI.getSequentialElementStride(
DL));
1562bool CallAnalyzer::isGEPFree(GetElementPtrInst &
GEP) {
1565 for (
const Use &
Op :
GEP.indices())
1566 if (Constant *SimpleOp = getSimplifiedValue<Constant>(
Op))
1575bool CallAnalyzer::visitAlloca(AllocaInst &
I) {
1576 disableSROA(
I.getOperand(0));
1580 if (
I.isArrayAllocation()) {
1581 Constant *
Size = getSimplifiedValue<Constant>(
I.getArraySize());
1591 Type *Ty =
I.getAllocatedType();
1593 AllocSize->getLimitedValue(),
1594 DL.getTypeAllocSize(Ty).getKnownMinValue(), AllocatedSize);
1596 HasDynamicAlloca =
true;
1601 if (
I.isStaticAlloca()) {
1613 HasDynamicAlloca =
true;
1619bool CallAnalyzer::visitPHI(PHINode &
I) {
1631 bool CheckSROA =
I.getType()->isPointerTy();
1635 std::pair<Value *, APInt> FirstBaseAndOffset = {
nullptr, ZeroOffset};
1636 Value *FirstV =
nullptr;
1638 for (
unsigned i = 0, e =
I.getNumIncomingValues(); i != e; ++i) {
1641 if (DeadBlocks.
count(Pred))
1645 BasicBlock *KnownSuccessor = KnownSuccessors[Pred];
1646 if (KnownSuccessor && KnownSuccessor !=
I.getParent())
1649 Value *
V =
I.getIncomingValue(i);
1654 Constant *
C = getDirectOrSimplifiedValue<Constant>(V);
1656 std::pair<Value *, APInt> BaseAndOffset = {
nullptr, ZeroOffset};
1657 if (!
C && CheckSROA)
1658 BaseAndOffset = ConstantOffsetPtrs.
lookup(V);
1660 if (!
C && !BaseAndOffset.first)
1677 if (FirstBaseAndOffset == BaseAndOffset)
1691 FirstBaseAndOffset = BaseAndOffset;
1696 SimplifiedValues[&
I] = FirstC;
1701 if (FirstBaseAndOffset.first) {
1702 ConstantOffsetPtrs[&
I] = std::move(FirstBaseAndOffset);
1704 if (
auto *SROAArg = getSROAArgForValueOrNull(FirstV))
1705 SROAArgValues[&
I] = SROAArg;
1715bool CallAnalyzer::canFoldInboundsGEP(GetElementPtrInst &
I) {
1717 std::pair<Value *, APInt> BaseAndOffset =
1718 ConstantOffsetPtrs.
lookup(
I.getPointerOperand());
1719 if (!BaseAndOffset.first)
1728 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1733bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &
I) {
1734 auto *SROAArg = getSROAArgForValueOrNull(
I.getPointerOperand());
1737 auto IsGEPOffsetConstant = [&](GetElementPtrInst &
GEP) {
1738 for (
const Use &
Op :
GEP.indices())
1739 if (!getDirectOrSimplifiedValue<Constant>(
Op))
1748 if ((
I.isInBounds() && canFoldInboundsGEP(
I)) || IsGEPOffsetConstant(
I)) {
1750 SROAArgValues[&
I] = SROAArg;
1758 disableSROAForArg(SROAArg);
1759 return isGEPFree(
I);
1765bool CallAnalyzer::simplifyCmpInstForRecCall(CmpInst &Cmp) {
1769 auto *CmpOp =
Cmp.getOperand(0);
1774 auto *CallBB = CandidateCall.
getParent();
1775 auto *Predecessor = CallBB->getSinglePredecessor();
1780 if (!Br || Br->getCondition() != &Cmp)
1785 bool ArgFound =
false;
1786 Value *FuncArg =
nullptr, *CallArg =
nullptr;
1787 for (
unsigned ArgNum = 0;
1788 ArgNum <
F.arg_size() && ArgNum < CandidateCall.
arg_size(); ArgNum++) {
1789 FuncArg =
F.getArg(ArgNum);
1791 if (FuncArg == CmpOp && CallArg != CmpOp) {
1802 CondContext CC(&Cmp);
1803 CC.Invert = (CallBB != Br->getSuccessor(0));
1805 CC.AffectedValues.insert(FuncArg);
1811 if ((ConstVal->isOne() && CC.Invert) ||
1812 (ConstVal->isZero() && !CC.Invert)) {
1813 SimplifiedValues[&
Cmp] = ConstVal;
1821bool CallAnalyzer::simplifyInstruction(Instruction &
I) {
1824 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
1832 SimplifiedValues[&
I] =
C;
1845bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
1847 auto *
C = getDirectOrSimplifiedValue<Constant>(Arg);
1850 SimplifiedValues[&CB] = ConstantInt::get(RT,
C ? 1 : 0);
1854bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
1864 SimplifiedValues[&CB] =
C;
1868bool CallAnalyzer::visitBitCast(BitCastInst &
I) {
1874 std::pair<Value *, APInt> BaseAndOffset =
1875 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1877 if (BaseAndOffset.first)
1878 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1881 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1882 SROAArgValues[&
I] = SROAArg;
1888bool CallAnalyzer::visitPtrToInt(PtrToIntInst &
I) {
1896 unsigned AS =
I.getOperand(0)->getType()->getPointerAddressSpace();
1897 if (IntegerSize ==
DL.getPointerSizeInBits(AS)) {
1898 std::pair<Value *, APInt> BaseAndOffset =
1899 ConstantOffsetPtrs.
lookup(
I.getOperand(0));
1900 if (BaseAndOffset.first)
1901 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1911 if (
auto *SROAArg = getSROAArgForValueOrNull(
I.getOperand(0)))
1912 SROAArgValues[&
I] = SROAArg;
1918bool CallAnalyzer::visitIntToPtr(IntToPtrInst &
I) {
1926 unsigned IntegerSize =
Op->getType()->getScalarSizeInBits();
1927 if (IntegerSize <=
DL.getPointerTypeSizeInBits(
I.getType())) {
1928 std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.
lookup(
Op);
1929 if (BaseAndOffset.first)
1930 ConstantOffsetPtrs[&
I] = std::move(BaseAndOffset);
1934 if (
auto *SROAArg = getSROAArgForValueOrNull(
Op))
1935 SROAArgValues[&
I] = SROAArg;
1941bool CallAnalyzer::visitCastInst(CastInst &
I) {
1948 disableSROA(
I.getOperand(0));
1953 switch (
I.getOpcode()) {
1954 case Instruction::FPTrunc:
1955 case Instruction::FPExt:
1956 case Instruction::UIToFP:
1957 case Instruction::SIToFP:
1958 case Instruction::FPToUI:
1959 case Instruction::FPToSI:
1971bool CallAnalyzer::paramHasAttr(Argument *
A, Attribute::AttrKind Attr) {
1975bool CallAnalyzer::isKnownNonNullInCallee(
Value *V) {
1982 if (paramHasAttr(
A, Attribute::NonNull))
1988 if (isAllocaDerivedArg(V))
1997bool CallAnalyzer::allowSizeGrowth(CallBase &
Call) {
2022bool InlineCostCallAnalyzer::isColdCallSite(CallBase &
Call,
2023 BlockFrequencyInfo *CallerBFI) {
2026 if (PSI && PSI->hasProfileSummary())
2027 return PSI->isColdCallSite(
Call, CallerBFI);
2039 auto CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
2040 auto CallerEntryFreq =
2042 return CallSiteFreq < CallerEntryFreq * ColdProb;
2046InlineCostCallAnalyzer::getHotCallSiteThreshold(CallBase &
Call,
2047 BlockFrequencyInfo *CallerBFI) {
2051 if (PSI && PSI->hasProfileSummary() && PSI->isHotCallSite(
Call, CallerBFI))
2057 return std::nullopt;
2064 BlockFrequency CallSiteFreq = CallerBFI->
getBlockFreq(CallSiteBB);
2065 BlockFrequency CallerEntryFreq = CallerBFI->
getEntryFreq();
2067 if (Limit && CallSiteFreq >= *Limit)
2071 return std::nullopt;
2074void InlineCostCallAnalyzer::updateThreshold(CallBase &
Call,
Function &Callee) {
2076 if (!allowSizeGrowth(
Call)) {
2084 auto MinIfValid = [](
int A, std::optional<int>
B) {
2085 return B ? std::min(
A, *
B) :
A;
2089 auto MaxIfValid = [](
int A, std::optional<int>
B) {
2090 return B ? std::max(
A, *
B) :
A;
2105 int SingleBBBonusPercent = 50;
2110 auto DisallowAllBonuses = [&]() {
2111 SingleBBBonusPercent = 0;
2112 VectorBonusPercent = 0;
2113 LastCallToStaticBonus = 0;
2118 if (
Caller->hasMinSize()) {
2124 SingleBBBonusPercent = 0;
2125 VectorBonusPercent = 0;
2126 }
else if (
Caller->hasOptSize())
2131 if (!
Caller->hasMinSize()) {
2135 if (
Callee.hasFnAttribute(Attribute::InlineHint))
2145 BlockFrequencyInfo *CallerBFI = GetBFI ? &(GetBFI(*Caller)) : nullptr;
2166 DisallowAllBonuses();
2171 if (PSI->isFunctionEntryHot(&Callee)) {
2177 }
else if (PSI->isFunctionEntryCold(&Callee)) {
2183 DisallowAllBonuses();
2195 SingleBBBonus = Threshold * SingleBBBonusPercent / 100;
2196 VectorBonus = Threshold * VectorBonusPercent / 100;
2201 if (isSoleCallToLocalFunction(
Call,
F)) {
2202 addCost(-LastCallToStaticBonus);
2203 StaticBonusApplied = LastCallToStaticBonus;
2207bool CallAnalyzer::visitCmpInst(CmpInst &
I) {
2214 if (simplifyCmpInstForRecCall(
I))
2217 if (
I.getOpcode() == Instruction::FCmp)
2222 Value *LHSBase, *RHSBase;
2223 APInt LHSOffset, RHSOffset;
2224 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2226 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2227 if (RHSBase && LHSBase == RHSBase) {
2233 ++NumConstantPtrCmps;
2238 auto isImplicitNullCheckCmp = [](
const CmpInst &
I) {
2239 for (
auto *User :
I.users())
2241 if (!
Instr->getMetadata(LLVMContext::MD_make_implicit))
2249 if (isKnownNonNullInCallee(
I.getOperand(0))) {
2257 if (isImplicitNullCheckCmp(
I))
2263bool CallAnalyzer::visitSub(BinaryOperator &
I) {
2267 Value *LHSBase, *RHSBase;
2268 APInt LHSOffset, RHSOffset;
2269 std::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.
lookup(
LHS);
2271 std::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.
lookup(
RHS);
2272 if (RHSBase && LHSBase == RHSBase) {
2278 SimplifiedValues[&
I] =
C;
2279 ++NumConstantPtrDiffs;
2287 return Base::visitSub(
I);
2290bool CallAnalyzer::visitBinaryOperator(BinaryOperator &
I) {
2292 Constant *CLHS = getDirectOrSimplifiedValue<Constant>(
LHS);
2293 Constant *CRHS = getDirectOrSimplifiedValue<Constant>(
RHS);
2295 Value *SimpleV =
nullptr;
2298 FI->getFastMathFlags(),
DL);
2304 SimplifiedValues[&
I] =
C;
2316 using namespace llvm::PatternMatch;
2317 if (
I.getType()->isFloatingPointTy() &&
2325bool CallAnalyzer::visitFNeg(UnaryOperator &
I) {
2327 Constant *COp = getDirectOrSimplifiedValue<Constant>(
Op);
2333 SimplifiedValues[&
I] =
C;
2344bool CallAnalyzer::visitLoad(LoadInst &
I) {
2345 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2351 if (EnableLoadElimination &&
2352 !LoadAddrSet.
insert(
I.getPointerOperand()).second &&
I.isUnordered()) {
2353 onLoadEliminationOpportunity();
2361bool CallAnalyzer::visitStore(StoreInst &
I) {
2362 if (handleSROA(
I.getPointerOperand(),
I.isSimple()))
2373 disableLoadElimination();
2379bool CallAnalyzer::visitExtractValue(ExtractValueInst &
I) {
2380 Value *
Op =
I.getAggregateOperand();
2384 if (
Value *SimpleOp = getSimplifiedValueUnchecked(
Op)) {
2385 SimplifyQuery SQ(
DL);
2388 SimplifiedValues[&
I] = SimpleV;
2394 return Base::visitExtractValue(
I);
2397bool CallAnalyzer::visitInsertValue(InsertValueInst &
I) {
2403 return Base::visitInsertValue(
I);
2412bool CallAnalyzer::simplifyCallSite(
Function *
F, CallBase &
Call) {
2421 SmallVector<Constant *, 4> ConstantArgs;
2424 Constant *
C = getDirectOrSimplifiedValue<Constant>(
I);
2431 SimplifiedValues[&
Call] =
C;
2438bool CallAnalyzer::isLoweredToCall(
Function *
F, CallBase &
Call) {
2439 const TargetLibraryInfo *TLI = GetTLI ? &GetTLI(*
F) : nullptr;
2445 case LibFunc_memcpy_chk:
2446 case LibFunc_memmove_chk:
2447 case LibFunc_mempcpy_chk:
2448 case LibFunc_memset_chk: {
2455 auto *LenOp = getDirectOrSimplifiedValue<ConstantInt>(
Call.
getOperand(2));
2458 if (LenOp && ObjSizeOp &&
2459 LenOp->getLimitedValue() <= ObjSizeOp->getLimitedValue()) {
2471bool CallAnalyzer::visitCallBase(CallBase &
Call) {
2472 if (!onCallBaseVisitStart(
Call))
2476 !
F.hasFnAttribute(Attribute::ReturnsTwice)) {
2478 ExposesReturnsTwice =
true;
2482 ContainsNoDuplicateCall =
true;
2485 onInlineAsm(*InlineAsmOp);
2493 F = getSimplifiedValue<Function>(Callee);
2495 onCallArgumentSetup(
Call);
2498 disableLoadElimination();
2499 return Base::visitCallBase(
Call);
2503 assert(
F &&
"Expected a call to a known function");
2506 if (simplifyCallSite(
F,
Call))
2512 switch (
II->getIntrinsicID()) {
2515 disableLoadElimination();
2516 return Base::visitCallBase(
Call);
2518 case Intrinsic::load_relative:
2519 onLoadRelativeIntrinsic();
2522 case Intrinsic::memset:
2523 case Intrinsic::memcpy:
2524 case Intrinsic::memmove:
2525 disableLoadElimination();
2528 case Intrinsic::icall_branch_funnel:
2529 case Intrinsic::localescape:
2530 HasUninlineableIntrinsic =
true;
2532 case Intrinsic::vastart:
2533 InitsVargArgs =
true;
2535 case Intrinsic::launder_invariant_group:
2536 case Intrinsic::strip_invariant_group:
2537 if (
auto *SROAArg = getSROAArgForValueOrNull(
II->getOperand(0)))
2538 SROAArgValues[
II] = SROAArg;
2540 case Intrinsic::is_constant:
2541 return simplifyIntrinsicCallIsConstant(
Call);
2542 case Intrinsic::objectsize:
2543 return simplifyIntrinsicCallObjectSize(
Call);
2550 IsRecursiveCall =
true;
2551 if (!AllowRecursiveCall)
2555 if (isLoweredToCall(
F,
Call)) {
2560 disableLoadElimination();
2561 return Base::visitCallBase(
Call);
2564bool CallAnalyzer::visitReturnInst(ReturnInst &RI) {
2566 bool Free = !HasReturn;
2571bool CallAnalyzer::visitUncondBrInst(UncondBrInst &BI) {
2578bool CallAnalyzer::visitCondBrInst(CondBrInst &BI) {
2580 return getDirectOrSimplifiedValue<ConstantInt>(BI.
getCondition()) ||
2584bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
2585 bool CheckSROA =
SI.getType()->isPointerTy();
2589 Constant *TrueC = getDirectOrSimplifiedValue<Constant>(TrueVal);
2590 Constant *FalseC = getDirectOrSimplifiedValue<Constant>(FalseVal);
2591 Constant *CondC = getSimplifiedValue<Constant>(
SI.getCondition());
2595 if (TrueC == FalseC && TrueC) {
2596 SimplifiedValues[&
SI] = TrueC;
2601 return Base::visitSelectInst(SI);
2603 std::pair<Value *, APInt> TrueBaseAndOffset =
2604 ConstantOffsetPtrs.
lookup(TrueVal);
2605 std::pair<Value *, APInt> FalseBaseAndOffset =
2606 ConstantOffsetPtrs.
lookup(FalseVal);
2607 if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first) {
2608 ConstantOffsetPtrs[&
SI] = std::move(TrueBaseAndOffset);
2610 if (
auto *SROAArg = getSROAArgForValueOrNull(TrueVal))
2611 SROAArgValues[&
SI] = SROAArg;
2615 return Base::visitSelectInst(SI);
2626 if (TrueC && FalseC) {
2628 SimplifiedValues[&
SI] =
C;
2632 return Base::visitSelectInst(SI);
2637 SimplifiedValues[&
SI] = SelectedC;
2644 std::pair<Value *, APInt> BaseAndOffset =
2645 ConstantOffsetPtrs.
lookup(SelectedV);
2646 if (BaseAndOffset.first) {
2647 ConstantOffsetPtrs[&
SI] = std::move(BaseAndOffset);
2649 if (
auto *SROAArg = getSROAArgForValueOrNull(SelectedV))
2650 SROAArgValues[&
SI] = SROAArg;
2656bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
2659 if (getDirectOrSimplifiedValue<ConstantInt>(
SI.getCondition()))
2674 unsigned JumpTableSize = 0;
2675 BlockFrequencyInfo *BFI = GetBFI ? &(GetBFI(
F)) : nullptr;
2676 unsigned NumCaseCluster =
2679 onFinalizeSwitch(JumpTableSize, NumCaseCluster,
SI.defaultDestUnreachable());
2683bool CallAnalyzer::visitIndirectBrInst(IndirectBrInst &IBI) {
2692 HasIndirectBr =
true;
2696bool CallAnalyzer::visitResumeInst(ResumeInst &RI) {
2702bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
2708bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
2714bool CallAnalyzer::visitUnreachableInst(UnreachableInst &
I) {
2721bool CallAnalyzer::visitInstruction(Instruction &
I) {
2730 for (
const Use &
Op :
I.operands())
2744CallAnalyzer::analyzeBlock(BasicBlock *BB,
2745 const SmallPtrSetImpl<const Value *> &EphValues) {
2746 for (Instruction &
I : *BB) {
2755 if (
I.isDebugOrPseudoInst())
2764 ++NumVectorInstructions;
2771 onInstructionAnalysisStart(&
I);
2773 if (Base::visit(&
I))
2774 ++NumInstructionsSimplified;
2776 onMissedSimplification();
2778 onInstructionAnalysisFinish(&
I);
2779 using namespace ore;
2782 if (IsRecursiveCall && !AllowRecursiveCall)
2784 else if (ExposesReturnsTwice)
2786 else if (HasDynamicAlloca)
2788 else if (HasIndirectBr)
2790 else if (HasUninlineableIntrinsic)
2792 else if (InitsVargArgs)
2794 if (!
IR.isSuccess()) {
2797 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2799 <<
NV(
"Callee", &
F) <<
" has uninlinable pattern ("
2800 <<
NV(
"InlineResult",
IR.getFailureReason())
2801 <<
") and cost is not fully computed";
2814 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NeverInline",
2816 <<
NV(
"Callee", &
F) <<
" is "
2817 <<
NV(
"InlineResult",
IR.getFailureReason())
2818 <<
". Cost is not fully computed";
2825 "Call site analysis is not favorable to inlining.");
2837ConstantInt *CallAnalyzer::stripAndComputeInBoundsConstantOffsets(
Value *&V) {
2838 if (!
V->getType()->isPointerTy())
2841 unsigned AS =
V->getType()->getPointerAddressSpace();
2842 unsigned IntPtrWidth =
DL.getIndexSizeInBits(AS);
2847 SmallPtrSet<Value *, 4> Visited;
2851 if (!
GEP->isInBounds() || !accumulateGEPOffset(*
GEP,
Offset))
2853 V =
GEP->getPointerOperand();
2855 if (GA->isInterposable())
2857 V = GA->getAliasee();
2861 assert(
V->getType()->isPointerTy() &&
"Unexpected operand type!");
2862 }
while (Visited.
insert(V).second);
2864 Type *IdxPtrTy =
DL.getIndexType(
V->getType());
2875void CallAnalyzer::findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB) {
2879 if (DeadBlocks.
count(Pred))
2881 BasicBlock *KnownSucc = KnownSuccessors[Pred];
2882 return KnownSucc && KnownSucc != Succ;
2887 return (!DeadBlocks.
count(BB) &&
2889 [&](BasicBlock *
P) {
return IsEdgeDead(
P, BB); }));
2892 for (BasicBlock *Succ :
successors(CurrBB)) {
2893 if (Succ == NextBB || !IsNewlyDead(Succ))
2897 while (!NewDead.
empty()) {
2915InlineResult CallAnalyzer::analyze() {
2918 auto Result = onAnalysisStart();
2927 for (User *U :
Caller->users()) {
2930 IsCallerRecursive =
true;
2938 for (Argument &FAI :
F.args()) {
2940 SimplifiedValues[&FAI] = *CAI;
2944 Value *PtrArg = *CAI;
2945 if (ConstantInt *
C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
2946 ConstantOffsetPtrs[&FAI] = std::make_pair(PtrArg,
C->getValue());
2950 SROAArgValues[&FAI] = SROAArg;
2951 onInitializeSROAArg(SROAArg);
2952 EnabledSROAAllocas.
insert(SROAArg);
2957 NumConstantOffsetPtrArgs = ConstantOffsetPtrs.
size();
2958 NumAllocaArgs = SROAArgValues.
size();
2962 SmallPtrSet<const Value *, 32> EphValuesStorage;
2963 const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
2964 if (GetEphValuesCache)
2965 EphValues = &GetEphValuesCache(
F).ephValues();
2977 typedef SmallSetVector<BasicBlock *, 16> BBSetVector;
2978 BBSetVector BBWorklist;
2979 BBWorklist.insert(&
F.getEntryBlock());
2982 for (
unsigned Idx = 0; Idx != BBWorklist.size(); ++Idx) {
3005 InlineResult
IR = analyzeBlock(BB, *EphValues);
3006 if (!
IR.isSuccess())
3015 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
3017 BBWorklist.insert(NextBB);
3018 KnownSuccessors[BB] = NextBB;
3019 findDeadBlocks(BB, NextBB);
3024 if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(
Cond)) {
3025 BasicBlock *NextBB =
SI->findCaseValue(SimpleCond)->getCaseSuccessor();
3026 BBWorklist.insert(NextBB);
3027 KnownSuccessors[BB] = NextBB;
3028 findDeadBlocks(BB, NextBB);
3037 onBlockAnalyzed(BB);
3043 if (!isSoleCallToLocalFunction(CandidateCall,
F) && ContainsNoDuplicateCall)
3053 FinalStackSizeThreshold = *AttrMaxStackSize;
3054 if (AllocatedSize > FinalStackSizeThreshold)
3057 return finalizeAnalysis();
3060void InlineCostCallAnalyzer::print(raw_ostream &OS) {
3061#define DEBUG_PRINT_STAT(x) OS << " " #x ": " << x << "\n"
3063 F.print(OS, &Writer);
3078#undef DEBUG_PRINT_STAT
3081#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3095 auto CalleeTLI = GetTLI(*Callee);
3096 return GetTLI(*Caller).areInlineCompatible(CalleeTLI,
3098 AttributeFuncs::areInlineCompatible(*Caller, *Callee);
3104 for (
unsigned I = 0, E =
Call.arg_size();
I != E; ++
I) {
3105 if (
Call.isByValArgument(
I)) {
3111 unsigned PointerSize =
DL.getPointerSizeInBits(AS);
3113 unsigned NumStores = (
TypeSize + PointerSize - 1) / PointerSize;
3121 NumStores = std::min(NumStores, 8U);
3134 return std::min<int64_t>(
Cost, INT_MAX);
3145 GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
3167 InlineCostCallAnalyzer CA(*
Call.getCalledFunction(),
Call, Params, CalleeTTI,
3168 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
true,
3170 auto R = CA.analyze();
3172 return std::nullopt;
3173 return CA.getCost();
3182 InlineCostFeaturesAnalyzer CFA(CalleeTTI, GetAssumptionCache, GetBFI, GetTLI,
3183 PSI, ORE, *
Call.getCalledFunction(),
Call);
3184 auto R = CFA.analyze();
3186 return std::nullopt;
3187 return CFA.features();
3202 if (Callee->isPresplitCoroutine())
3214 if (
Call.hasFnAttr(Attribute::AlwaysInline)) {
3215 if (
Call.getAttributes().hasFnAttr(Attribute::NoInline))
3218 if (!AttributeFuncs::isStrictFPInlineCompatible(*Caller, *Callee))
3222 if (IsViable.isSuccess())
3234 if (Caller->hasFnAttribute(Attribute::Flatten)) {
3236 if (IsViable.isSuccess())
3242 if (Caller->hasOptNone())
3246 if (Callee->isInterposable(
false))
3250 if (Callee->hasFnAttribute(Attribute::NoInline))
3254 if (
Call.isNoInline())
3258 if (Callee->hasFnAttribute(
"loader-replaceable"))
3261 return std::nullopt;
3277 if (UserDecision->isSuccess())
3284 "Inlining forced by -inline-all-viable-calls");
3287 <<
"... (caller:" <<
Call.getCaller()->getName()
3290 InlineCostCallAnalyzer CA(*Callee,
Call, Params, CalleeTTI,
3291 GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
3301 if (CA.wasDecidedByCostBenefit()) {
3304 CA.getCostBenefitPair());
3309 if (CA.wasDecidedByCostThreshold())
3311 CA.getStaticBonusApplied());
3320 bool ReturnsTwice =
F.hasFnAttribute(Attribute::ReturnsTwice);
3330 for (
auto &
II : BB) {
3347 switch (Callee->getIntrinsicID()) {
3350 case llvm::Intrinsic::icall_branch_funnel:
3354 "disallowed inlining of @llvm.icall.branch.funnel");
3355 case llvm::Intrinsic::localescape:
3359 "disallowed inlining of @llvm.localescape");
3360 case llvm::Intrinsic::vastart:
3364 "contains VarArgs initialized with va_start");
3473 InlineCostCallAnalyzer ICCA(*CalledFunction, *CB, Params,
TTI,
3474 GetAssumptionCache,
nullptr,
nullptr, PSI,
3477 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(Instruction &Inst, TTI::TargetCostKind CostKind, TargetTransformInfo &TTI)
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 > InlineAsmInstrCost("inline-asm-instr-cost", cl::Hidden, cl::init(0), cl::desc("Cost of a single inline asm instruction when inlining"))
static cl::opt< int > InlineSavingsMultiplier("inline-savings-multiplier", cl::Hidden, cl::init(8), cl::desc("Multiplier to multiply cycle savings by during inlining"))
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 > CallPenalty("inline-call-penalty", cl::Hidden, cl::init(25), cl::desc("Call penalty that is applied per callsite when inlining"))
static cl::opt< int > HotCallSiteThreshold("hot-callsite-threshold", cl::Hidden, cl::init(3000), cl::desc("Threshold for hot callsites "))
static cl::opt< int > ColdThreshold("inlinecold-threshold", cl::Hidden, cl::init(45), cl::desc("Threshold for inlining functions with cold attribute"))
static cl::opt< size_t > RecurStackSizeThreshold("recursive-inline-max-stacksize", cl::Hidden, cl::init(InlineConstants::TotalAllocaSizeRecursiveCaller), cl::desc("Do not inline recursive functions with a stack " "size that exceeds the specified limit"))
static cl::opt< bool > PrintInstructionComments("print-instruction-comments", cl::Hidden, cl::init(false), cl::desc("Prints comments for instruction based on inline cost analysis"))
static cl::opt< int > LocallyHotCallSiteThreshold("locally-hot-callsite-threshold", cl::Hidden, cl::init(525), cl::desc("Threshold for locally hot callsites "))
static cl::opt< bool > InlineCallerSupersetNoBuiltin("inline-caller-superset-nobuiltin", cl::Hidden, cl::init(true), cl::desc("Allow inlining when caller has a superset of callee's nobuiltin " "attributes."))
static cl::opt< int > HintThreshold("inlinehint-threshold", cl::Hidden, cl::init(325), cl::desc("Threshold for inlining functions with inline hint"))
static cl::opt< size_t > StackSizeThreshold("inline-max-stacksize", cl::Hidden, cl::init(std::numeric_limits< size_t >::max()), cl::desc("Do not inline functions with a stack size " "that exceeds the specified limit"))
static cl::opt< uint64_t > HotCallSiteRelFreq("hot-callsite-rel-freq", cl::Hidden, cl::init(60), cl::desc("Minimum block frequency, expressed as a multiple of caller's " "entry frequency, for a callsite to be hot in the absence of " "profile information."))
static cl::opt< int > InlineSavingsProfitableMultiplier("inline-savings-profitable-multiplier", cl::Hidden, cl::init(4), cl::desc("A multiplier on top of cycle savings to decide whether the " "savings won't justify the cost"))
static cl::opt< int > MemAccessCost("inline-memaccess-cost", cl::Hidden, cl::init(0), cl::desc("Cost of load/store instruction when inlining"))
static cl::opt< int > ColdCallSiteThreshold("inline-cold-callsite-threshold", cl::Hidden, cl::init(45), cl::desc("Threshold for inlining cold callsites"))
static cl::opt< bool > IgnoreTTIInlineCompatible("ignore-tti-inline-compatible", cl::Hidden, cl::init(false), cl::desc("Ignore TTI attributes compatibility check between callee/caller " "during inline cost calculation"))
static cl::opt< bool > OptComputeFullInlineCost("inline-cost-full", cl::Hidden, cl::desc("Compute the full inline cost of a call site even when the cost " "exceeds the threshold."))
#define DEBUG_PRINT_STAT(x)
static cl::opt< bool > InlineEnableCostBenefitAnalysis("inline-enable-cost-benefit-analysis", cl::Hidden, cl::init(false), cl::desc("Enable the cost-benefit analysis for the inliner"))
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< bool > InlineAllViableCalls("inline-all-viable-calls", cl::Hidden, cl::init(false), cl::desc("Inline all viable calls, even if they exceed the inlining " "threshold"))
static cl::opt< int > InlineSizeAllowance("inline-size-allowance", cl::Hidden, cl::init(100), cl::desc("The maximum size of a callee that get's " "inlined without sufficient cycle savings"))
static cl::opt< int > ColdCallSiteRelFreq("cold-callsite-rel-freq", cl::Hidden, cl::init(2), cl::desc("Maximum block frequency, expressed as a percentage of caller's " "entry frequency, for a callsite to be cold in the absence of " "profile information."))
static cl::opt< bool > DisableGEPConstOperand("disable-gep-const-evaluation", cl::Hidden, cl::init(false), cl::desc("Disables evaluation of GetElementPtr with constant operands"))
static bool functionsHaveCompatibleAttributes(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 > 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
const SmallVectorImpl< MachineOperand > & 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)
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, bool AllowSynthetic=false) 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.
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.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
bool getLibFunc(StringRef funcName, LibFunc &F) 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.
int getNumOccurrences() const
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[]
const unsigned TotalAllocaSizeRecursiveCaller
Do not inline functions which allocate this many bytes on the stack when the caller is recursive.
LLVM_ABI int getInstrCost()
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as '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.
LLVM_ABI bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
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...
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...
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)
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.
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.