mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
Fix a crash in the assumption cache when inlining indirect function calls
Summary: Instances of the AssumptionCache are per function, so we can't re-use the same AssumptionCache instance when recursing in the CallAnalyzer to analyze a different function. Instead we have to pass the AssumptionCacheTracker to the CallAnalyzer so it can get the right AssumptionCache on demand. Reviewers: hfinkel Subscribers: llvm-commits, hans Differential Revision: http://reviews.llvm.org/D7533 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
82f9916923
commit
53a7b568b2
@ -52,7 +52,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
||||
const TargetTransformInfo &TTI;
|
||||
|
||||
/// The cache of @llvm.assume intrinsics.
|
||||
AssumptionCache &AC;
|
||||
AssumptionCacheTracker *ACT;
|
||||
|
||||
// The called function.
|
||||
Function &F;
|
||||
@ -146,8 +146,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
||||
|
||||
public:
|
||||
CallAnalyzer(const DataLayout *DL, const TargetTransformInfo &TTI,
|
||||
AssumptionCache &AC, Function &Callee, int Threshold)
|
||||
: DL(DL), TTI(TTI), AC(AC), F(Callee), Threshold(Threshold), Cost(0),
|
||||
AssumptionCacheTracker *ACT, Function &Callee, int Threshold)
|
||||
: DL(DL), TTI(TTI), ACT(ACT), F(Callee), Threshold(Threshold), Cost(0),
|
||||
IsCallerRecursive(false), IsRecursiveCall(false),
|
||||
ExposesReturnsTwice(false), HasDynamicAlloca(false),
|
||||
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
|
||||
@ -789,7 +789,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
|
||||
// during devirtualization and so we want to give it a hefty bonus for
|
||||
// inlining, but cap that bonus in the event that inlining wouldn't pan
|
||||
// out. Pretend to inline the function, with a custom threshold.
|
||||
CallAnalyzer CA(DL, TTI, AC, *F, InlineConstants::IndirectCallThreshold);
|
||||
CallAnalyzer CA(DL, TTI, ACT, *F, InlineConstants::IndirectCallThreshold);
|
||||
if (CA.analyzeCall(CS)) {
|
||||
// We were able to inline the indirect call! Subtract the cost from the
|
||||
// bonus we want to apply, but don't go below zero.
|
||||
@ -1135,7 +1135,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
|
||||
// the ephemeral values multiple times (and they're completely determined by
|
||||
// the callee, so this is purely duplicate work).
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(&F, &AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(&F, &ACT->getAssumptionCache(F), EphValues);
|
||||
|
||||
// The worklist of live basic blocks in the callee *after* inlining. We avoid
|
||||
// adding basic blocks of the callee which can be proven to be dead for this
|
||||
@ -1335,7 +1335,7 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,
|
||||
<< "...\n");
|
||||
|
||||
CallAnalyzer CA(Callee->getDataLayout(), TTIWP->getTTI(*Callee),
|
||||
ACT->getAssumptionCache(*Callee), *Callee, Threshold);
|
||||
ACT, *Callee, Threshold);
|
||||
bool ShouldInline = CA.analyzeCall(CS);
|
||||
|
||||
DEBUG(CA.dump());
|
||||
|
19
test/Transforms/Inline/inline-indirect.ll
Normal file
19
test/Transforms/Inline/inline-indirect.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: opt < %s -inline -disable-output 2>/dev/null
|
||||
; This test used to trigger an assertion in the assumption cache when
|
||||
; inlining the indirect call
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @bar(void ()*) {
|
||||
call void @llvm.assume(i1 true)
|
||||
call void %0();
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @baz() {
|
||||
call void @bar(void ()* @foo)
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user