20
20
#include " llvm/Analysis/BlockFrequencyInfo.h"
21
21
#include " llvm/Analysis/CodeMetrics.h"
22
22
#include " llvm/Analysis/ConstantFolding.h"
23
+ #include " llvm/Analysis/EphemeralValuesCache.h"
23
24
#include " llvm/Analysis/InstructionSimplify.h"
24
25
#include " llvm/Analysis/LoopInfo.h"
25
26
#include " llvm/Analysis/MemoryBuiltins.h"
@@ -269,6 +270,10 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
269
270
// / easily cacheable. Instead, use the cover function paramHasAttr.
270
271
CallBase &CandidateCall;
271
272
273
+ // / Getter for the cache of ephemeral values.
274
+ std::optional<function_ref<EphemeralValuesCache &(Function &)>>
275
+ GetEphValuesCache;
276
+
272
277
// / Extension points for handling callsite features.
273
278
// Called before a basic block was analyzed.
274
279
virtual void onBlockStart (const BasicBlock *BB) {}
@@ -462,7 +467,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
462
467
463
468
// Custom analysis routines.
464
469
InlineResult analyzeBlock (BasicBlock *BB,
465
- SmallPtrSetImpl<const Value *> &EphValues);
470
+ const SmallPtrSetImpl<const Value *> &EphValues);
466
471
467
472
// Disable several entry points to the visitor so we don't accidentally use
468
473
// them by declaring but not defining them here.
@@ -510,10 +515,12 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
510
515
function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr ,
511
516
function_ref<const TargetLibraryInfo &(Function &)> GetTLI = nullptr ,
512
517
ProfileSummaryInfo *PSI = nullptr ,
513
- OptimizationRemarkEmitter *ORE = nullptr )
518
+ OptimizationRemarkEmitter *ORE = nullptr ,
519
+ std::optional<function_ref<EphemeralValuesCache &(Function &)>>
520
+ GetEphValuesCache = std::nullopt)
514
521
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI),
515
522
GetTLI (GetTLI), PSI(PSI), F(Callee), DL(F.getDataLayout()), ORE(ORE),
516
- CandidateCall(Call) {}
523
+ CandidateCall(Call), GetEphValuesCache(GetEphValuesCache) {}
517
524
518
525
InlineResult analyze ();
519
526
@@ -1126,9 +1133,11 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
1126
1133
function_ref<const TargetLibraryInfo &(Function &)> GetTLI = nullptr ,
1127
1134
ProfileSummaryInfo *PSI = nullptr ,
1128
1135
OptimizationRemarkEmitter *ORE = nullptr , bool BoostIndirect = true ,
1129
- bool IgnoreThreshold = false )
1136
+ bool IgnoreThreshold = false ,
1137
+ std::optional<function_ref<EphemeralValuesCache &(Function &)>>
1138
+ GetEphValuesCache = std::nullopt)
1130
1139
: CallAnalyzer(Callee, Call, TTI, GetAssumptionCache, GetBFI, GetTLI, PSI,
1131
- ORE),
1140
+ ORE, GetEphValuesCache ),
1132
1141
ComputeFullInlineCost (OptComputeFullInlineCost ||
1133
1142
Params.ComputeFullInlineCost || ORE ||
1134
1143
isCostBenefitAnalysisEnabled ()),
@@ -2566,7 +2575,7 @@ bool CallAnalyzer::visitInstruction(Instruction &I) {
2566
2575
// / viable, and true if inlining remains viable.
2567
2576
InlineResult
2568
2577
CallAnalyzer::analyzeBlock (BasicBlock *BB,
2569
- SmallPtrSetImpl<const Value *> &EphValues) {
2578
+ const SmallPtrSetImpl<const Value *> &EphValues) {
2570
2579
for (Instruction &I : *BB) {
2571
2580
// FIXME: Currently, the number of instructions in a function regardless of
2572
2581
// our ability to simplify them during inline to constants or dead code,
@@ -2781,11 +2790,15 @@ InlineResult CallAnalyzer::analyze() {
2781
2790
NumConstantOffsetPtrArgs = ConstantOffsetPtrs.size ();
2782
2791
NumAllocaArgs = SROAArgValues.size ();
2783
2792
2784
- // FIXME: If a caller has multiple calls to a callee, we end up recomputing
2785
- // the ephemeral values multiple times (and they're completely determined by
2786
- // the callee, so this is purely duplicate work).
2787
- SmallPtrSet<const Value *, 32 > EphValues;
2788
- CodeMetrics::collectEphemeralValues (&F, &GetAssumptionCache (F), EphValues);
2793
+ // Collecting the ephemeral values of `F` can be expensive, so use the
2794
+ // ephemeral values cache if available.
2795
+ SmallPtrSet<const Value *, 32 > EphValuesStorage;
2796
+ const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
2797
+ auto &AC = GetAssumptionCache (F);
2798
+ if (GetEphValuesCache)
2799
+ EphValues = &(*GetEphValuesCache)(F).ephValues ();
2800
+ else
2801
+ CodeMetrics::collectEphemeralValues (&F, &AC, EphValuesStorage);
2789
2802
2790
2803
// The worklist of live basic blocks in the callee *after* inlining. We avoid
2791
2804
// adding basic blocks of the callee which can be proven to be dead for this
@@ -2824,7 +2837,7 @@ InlineResult CallAnalyzer::analyze() {
2824
2837
2825
2838
// Analyze the cost of this block. If we blow through the threshold, this
2826
2839
// returns false, and we can bail on out.
2827
- InlineResult IR = analyzeBlock (BB, EphValues);
2840
+ InlineResult IR = analyzeBlock (BB, * EphValues);
2828
2841
if (!IR.isSuccess ())
2829
2842
return IR;
2830
2843
@@ -2967,9 +2980,12 @@ InlineCost llvm::getInlineCost(
2967
2980
function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
2968
2981
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
2969
2982
function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
2970
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) {
2983
+ ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
2984
+ std::optional<function_ref<EphemeralValuesCache &(Function &)>>
2985
+ GetEphValuesCache) {
2971
2986
return getInlineCost (Call, Call.getCalledFunction (), Params, CalleeTTI,
2972
- GetAssumptionCache, GetTLI, GetBFI, PSI, ORE);
2987
+ GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
2988
+ GetEphValuesCache);
2973
2989
}
2974
2990
2975
2991
std::optional<int > llvm::getInliningCostEstimate (
@@ -3089,7 +3105,9 @@ InlineCost llvm::getInlineCost(
3089
3105
function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
3090
3106
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
3091
3107
function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
3092
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) {
3108
+ ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
3109
+ std::optional<function_ref<EphemeralValuesCache &(Function &)>>
3110
+ GetEphValuesCache) {
3093
3111
3094
3112
auto UserDecision =
3095
3113
llvm::getAttributeBasedInliningDecision (Call, Callee, CalleeTTI, GetTLI);
@@ -3105,7 +3123,9 @@ InlineCost llvm::getInlineCost(
3105
3123
<< " )\n " );
3106
3124
3107
3125
InlineCostCallAnalyzer CA (*Callee, Call, Params, CalleeTTI,
3108
- GetAssumptionCache, GetBFI, GetTLI, PSI, ORE);
3126
+ GetAssumptionCache, GetBFI, GetTLI, PSI, ORE,
3127
+ /* BoostIndirect=*/ true , /* IgnoreThreshold=*/ false ,
3128
+ GetEphValuesCache);
3109
3129
InlineResult ShouldInline = CA.analyze ();
3110
3130
3111
3131
LLVM_DEBUG (CA.dump ());
0 commit comments