Skip to content

Commit 1321b58

Browse files
authored
Merge pull request #60998 from eeckstein/fix-caller-analysis
CallerAnalysis: be more tolerant about missing FunctionInfos
2 parents 925a211 + b4e6788 commit 1321b58

File tree

2 files changed

+31
-21
lines changed

2 files changed

+31
-21
lines changed

include/swift/SILOptimizer/Analysis/CallerAnalysis.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,7 @@ class CallerAnalysis final : public SILAnalysis {
9191

9292
/// Notify the analysis about a function which will be deleted from the
9393
/// module.
94-
void notifyWillDeleteFunction(SILFunction *f) override {
95-
invalidateAllInfo(f);
96-
recomputeFunctionList.remove(f);
97-
// Now that we have invalidated all references to the function, delete it.
98-
funcInfos.erase(f);
99-
}
94+
void notifyWillDeleteFunction(SILFunction *f) override;
10095

10196
/// Notify the analysis about changed witness or vtables.
10297
///
@@ -107,6 +102,9 @@ class CallerAnalysis final : public SILAnalysis {
107102

108103
/// Look up the function info that we have stored for f, recomputing all
109104
/// invalidating parts of the call graph.
105+
///
106+
/// Warning: The returned FunctionInfo is only alive until the next call to
107+
/// `getFunctionInfo`.
110108
const FunctionInfo &getFunctionInfo(SILFunction *f) const;
111109

112110
SWIFT_DEBUG_DUMP;
@@ -146,7 +144,7 @@ class CallerAnalysis final : public SILAnalysis {
146144
void invalidateKnownCallees(SILFunction *caller, FunctionInfo &callerInfo);
147145

148146
/// Invalidate both the known callees of f and the known callers of f.
149-
void invalidateAllInfo(SILFunction *f);
147+
void invalidateAllInfo(SILFunction *f, FunctionInfo &fInfo);
150148

151149
/// Helper method that reprocesses all elements of recomputeFunctionList and
152150
/// then clears the function list.

lib/SILOptimizer/Analysis/CallerAnalysis.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,14 @@ struct CallerAnalysis::ApplySiteFinderVisitor
4848
: SILInstructionVisitor<ApplySiteFinderVisitor, bool> {
4949
CallerAnalysis *analysis;
5050
SILFunction *callerFn;
51-
FunctionInfo &callerInfo;
5251

5352
#ifndef NDEBUG
5453
SmallPtrSet<SILInstruction *, 8> visitedCallSites;
5554
SmallSetVector<SILInstruction *, 8> callSitesThatMustBeVisited;
5655
#endif
5756

5857
ApplySiteFinderVisitor(CallerAnalysis *analysis, SILFunction *callerFn)
59-
: analysis(analysis), callerFn(callerFn),
60-
callerInfo(analysis->unsafeGetFunctionInfo(callerFn)) {}
58+
: analysis(analysis), callerFn(callerFn) {}
6159
~ApplySiteFinderVisitor();
6260

6361
bool visitSILInstruction(SILInstruction *) { return false; }
@@ -120,14 +118,14 @@ bool CallerAnalysis::ApplySiteFinderVisitor::visitFunctionRefBaseInst(
120118
FunctionRefBaseInst *fri) {
121119
auto optResult = findLocalApplySites(fri);
122120
auto *calleeFn = fri->getInitiallyReferencedFunction();
123-
FunctionInfo &calleeInfo = analysis->unsafeGetFunctionInfo(calleeFn);
124121

125122
// First make an edge from our callerInfo to our calleeState for invalidation
126123
// purposes.
127-
callerInfo.calleeStates.insert(calleeFn);
124+
analysis->getOrInsertFunctionInfo(callerFn).calleeStates.insert(calleeFn);
128125

129126
// Then grab our callee state and update it with state for this caller.
130-
auto iter = calleeInfo.callerStates.insert({callerFn, {}});
127+
auto iter = analysis->getOrInsertFunctionInfo(calleeFn).callerStates.
128+
insert({callerFn, {}});
131129
// If we succeeded in inserting a new value, put in an optimistic
132130
// value for escaping.
133131
if (iter.second) {
@@ -222,6 +220,10 @@ const FunctionInfo &CallerAnalysis::getFunctionInfo(SILFunction *f) const {
222220
// Recompute every function in the invalidated function list and empty the
223221
// list.
224222
auto &self = const_cast<CallerAnalysis &>(*this);
223+
if (funcInfos.find(f) == funcInfos.end()) {
224+
(void)self.getOrInsertFunctionInfo(f);
225+
self.recomputeFunctionList.insert(f);
226+
}
225227
self.processRecomputeFunctionList();
226228
return self.unsafeGetFunctionInfo(f);
227229
}
@@ -262,11 +264,7 @@ void CallerAnalysis::processFunctionCallSites(SILFunction *callerFn) {
262264
visitor.process();
263265
}
264266

265-
void CallerAnalysis::invalidateAllInfo(SILFunction *f) {
266-
// Look up the callees that our caller refers to and invalidate any
267-
// values that point back at the caller.
268-
FunctionInfo &fInfo = unsafeGetFunctionInfo(f);
269-
267+
void CallerAnalysis::invalidateAllInfo(SILFunction *f, FunctionInfo &fInfo) {
270268
// Then we first eliminate any callees that we point at.
271269
invalidateKnownCallees(f, fInfo);
272270

@@ -303,9 +301,12 @@ void CallerAnalysis::invalidateKnownCallees(SILFunction *caller,
303301
}
304302

305303
void CallerAnalysis::invalidateKnownCallees(SILFunction *caller) {
306-
// Look up the callees that our caller refers to and invalidate any
307-
// values that point back at the caller.
308-
invalidateKnownCallees(caller, unsafeGetFunctionInfo(caller));
304+
auto iter = funcInfos.find(caller);
305+
if (iter != funcInfos.end()) {
306+
// Look up the callees that our caller refers to and invalidate any
307+
// values that point back at the caller.
308+
invalidateKnownCallees(caller, iter->second);
309+
}
309310
}
310311

311312
void CallerAnalysis::verify(SILFunction *caller) const {
@@ -377,6 +378,17 @@ void CallerAnalysis::invalidate() {
377378
}
378379
}
379380

381+
void CallerAnalysis::notifyWillDeleteFunction(SILFunction *f) {
382+
auto iter = funcInfos.find(f);
383+
if (iter == funcInfos.end())
384+
return;
385+
386+
invalidateAllInfo(f, iter->second);
387+
recomputeFunctionList.remove(f);
388+
// Now that we have invalidated all references to the function, delete it.
389+
funcInfos.erase(iter);
390+
}
391+
380392
//===----------------------------------------------------------------------===//
381393
// CallerAnalysis YAML Dumper
382394
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)