Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions llvm/include/llvm/Analysis/EphemeralValuesCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,13 @@ class Function;
class AssumptionCache;
class Value;

/// A cache of ephemeral values within a function.
class EphemeralValuesCache {
SmallPtrSet<const Value *, 32> EphValues;
Function &F;
AssumptionCache &AC;
bool Collected = false;

void collectEphemeralValues();

public:
EphemeralValuesCache(Function &F, AssumptionCache &AC) : F(F), AC(AC) {}
void clear() {
EphValues.clear();
Collected = false;
}
const SmallPtrSetImpl<const Value *> &ephValues() {
if (!Collected)
collectEphemeralValues();
return EphValues;
}
};

class EphemeralValuesAnalysis
: public AnalysisInfoMixin<EphemeralValuesAnalysis> {
friend AnalysisInfoMixin<EphemeralValuesAnalysis>;
static AnalysisKey Key;

public:
using Result = EphemeralValuesCache;
using Result = SmallPtrSet<const Value *, 32>;
Result run(Function &F, FunctionAnalysisManager &FAM);
};

Expand Down
25 changes: 13 additions & 12 deletions llvm/include/llvm/Analysis/InlineCost.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Analysis/EphemeralValuesCache.h"
#include "llvm/Analysis/InlineModelFeatureMaps.h"
#include "llvm/IR/PassManager.h"
#include <cassert>
Expand All @@ -31,7 +32,6 @@ class Function;
class ProfileSummaryInfo;
class TargetTransformInfo;
class TargetLibraryInfo;
class EphemeralValuesCache;

namespace InlineConstants {
// Various thresholds used by inline cost analysis.
Expand Down Expand Up @@ -280,23 +280,24 @@ InlineCost getInlineCost(
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
ProfileSummaryInfo *PSI = nullptr, OptimizationRemarkEmitter *ORE = nullptr,
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache =
nullptr);
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache = nullptr);

/// Get an InlineCost with the callee explicitly specified.
/// This allows you to calculate the cost of inlining a function via a
/// pointer. This behaves exactly as the version with no explicit callee
/// parameter in all other respects.
//
InlineCost getInlineCost(
CallBase &Call, Function *Callee, 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);
InlineCost
getInlineCost(CallBase &Call, Function *Callee, 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<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache = nullptr);

/// Returns InlineResult::success() if the call site should be always inlined
/// because of user directives, and the inlining is viable. Returns
Expand Down
11 changes: 4 additions & 7 deletions llvm/lib/Analysis/EphemeralValuesCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@

namespace llvm {

void EphemeralValuesCache::collectEphemeralValues() {
CodeMetrics::collectEphemeralValues(&F, &AC, EphValues);
Collected = true;
}

AnalysisKey EphemeralValuesAnalysis::Key;

EphemeralValuesCache
EphemeralValuesAnalysis::Result
EphemeralValuesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
auto &AC = FAM.getResult<AssumptionAnalysis>(F);
return EphemeralValuesCache(F, AC);
SmallPtrSet<const Value *, 32> EphValues;
CodeMetrics::collectEphemeralValues(&F, &AC, EphValues);
return EphValues;
}

} // namespace llvm
19 changes: 11 additions & 8 deletions llvm/lib/Analysis/InlineCost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
CallBase &CandidateCall;

/// Getter for the cache of ephemeral values.
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache = nullptr;
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache = nullptr;

/// Extension points for handling callsite features.
// Called before a basic block was analyzed.
Expand Down Expand Up @@ -515,8 +516,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
function_ref<const TargetLibraryInfo &(Function &)> GetTLI = nullptr,
ProfileSummaryInfo *PSI = nullptr,
OptimizationRemarkEmitter *ORE = nullptr,
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache =
nullptr)
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache = nullptr)
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI),
GetTLI(GetTLI), PSI(PSI), F(Callee), DL(F.getDataLayout()), ORE(ORE),
CandidateCall(Call), GetEphValuesCache(GetEphValuesCache) {}
Expand Down Expand Up @@ -1133,8 +1134,8 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
ProfileSummaryInfo *PSI = nullptr,
OptimizationRemarkEmitter *ORE = nullptr, bool BoostIndirect = true,
bool IgnoreThreshold = false,
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache =
nullptr)
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache = nullptr)
: CallAnalyzer(Callee, Call, TTI, GetAssumptionCache, GetBFI, GetTLI, PSI,
ORE, GetEphValuesCache),
ComputeFullInlineCost(OptComputeFullInlineCost ||
Expand Down Expand Up @@ -2794,7 +2795,7 @@ InlineResult CallAnalyzer::analyze() {
SmallPtrSet<const Value *, 32> EphValuesStorage;
const SmallPtrSetImpl<const Value *> *EphValues = &EphValuesStorage;
if (GetEphValuesCache)
EphValues = &GetEphValuesCache(F).ephValues();
EphValues = &GetEphValuesCache(F);
else
CodeMetrics::collectEphemeralValues(&F, &GetAssumptionCache(F),
EphValuesStorage);
Expand Down Expand Up @@ -2980,7 +2981,8 @@ InlineCost llvm::getInlineCost(
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache) {
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache) {
return getInlineCost(Call, Call.getCalledFunction(), Params, CalleeTTI,
GetAssumptionCache, GetTLI, GetBFI, PSI, ORE,
GetEphValuesCache);
Expand Down Expand Up @@ -3104,7 +3106,8 @@ InlineCost llvm::getInlineCost(
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE,
function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache) {
function_ref<EphemeralValuesAnalysis::Result &(Function &)>
GetEphValuesCache) {

auto UserDecision =
llvm::getAttributeBasedInliningDecision(Call, Callee, CalleeTTI, GetTLI);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Transforms/IPO/Inliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
}
// TODO: Shouldn't we be invalidating all analyses on F here?
// The caller was modified, so invalidate Ephemeral Values.
FAM.getResult<EphemeralValuesAnalysis>(F).clear();
FAM.invalidate(
F, PreservedAnalyses::all().abandon(EphemeralValuesAnalysis::ID()));

DidInline = true;
InlinedCallees.insert(&Callee);
Expand Down
3 changes: 0 additions & 3 deletions llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,15 @@
; CHECK: Invalidating analysis: LoopAnalysis on test1_f
; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_f
; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_f
; CHECK: Invalidating analysis: EphemeralValuesAnalysis on test1_f
; CHECK: Running analysis: DominatorTreeAnalysis on test1_g
; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_g
; CHECK: Invalidating analysis: LoopAnalysis on test1_g
; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_g
; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_g
; CHECK: Invalidating analysis: EphemeralValuesAnalysis on test1_g
; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_h
; CHECK: Invalidating analysis: LoopAnalysis on test1_h
; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_h
; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_h
; CHECK: Invalidating analysis: EphemeralValuesAnalysis on test1_h
; CHECK-NOT: Invalidating analysis:
; CHECK: Running pass: DominatorTreeVerifierPass on test1_g
; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_g
Expand Down
29 changes: 15 additions & 14 deletions llvm/unittests/Analysis/EphemeralValuesCacheTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

#include "llvm/Analysis/EphemeralValuesCache.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassInstrumentation.h"
#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -46,29 +48,28 @@ define void @foo(i8 %arg0, i8 %arg1) {
)IR");
Function *F = M->getFunction("foo");
auto *BB = &*F->begin();
AssumptionCache AC(*F);
EphemeralValuesCache EVC(*F, AC);
auto It = BB->begin();
auto *C0 = &*It++;
auto *Assume0 = &*It++;
[[maybe_unused]] auto *NotEph = &*It++;
auto *C1 = &*It++;
auto *Assume1 = &*It++;
[[maybe_unused]] auto *Ret = &*It++;
// Check emphemeral values.
EXPECT_THAT(EVC.ephValues(),
testing::UnorderedElementsAre(C0, Assume0, C1, Assume1));
// Clear the cache and try again.
EVC.clear();
EXPECT_THAT(EVC.ephValues(),
testing::UnorderedElementsAre(C0, Assume0, C1, Assume1));
// Modify the IR, clear cache and recompute.
// Check ephemeral values.
FunctionAnalysisManager FAM;
FAM.registerPass([] { return EphemeralValuesAnalysis(); });
FAM.registerPass([] { return PassInstrumentationAnalysis(); });
FAM.registerPass([] { return AssumptionAnalysis(); });
FAM.registerPass([] { return TargetIRAnalysis(); });
auto Result = FAM.getResult<EphemeralValuesAnalysis>(*F);
EXPECT_THAT(Result, testing::UnorderedElementsAre(C0, Assume0, C1, Assume1));
// Modify the IR, invalidate and recompute.
Assume1->eraseFromParent();
C1->eraseFromParent();
EXPECT_THAT(EVC.ephValues(),
testing::UnorderedElementsAre(C0, Assume0, C1, Assume1));
EVC.clear();
EXPECT_THAT(EVC.ephValues(), testing::UnorderedElementsAre(C0, Assume0));
FAM.invalidate(
*F, PreservedAnalyses::all().abandon(EphemeralValuesAnalysis::ID()));
EXPECT_THAT(FAM.getResult<EphemeralValuesAnalysis>(*F),
testing::UnorderedElementsAre(C0, Assume0));
}

} // namespace
Loading