Skip to content

SIL optimizations: Implement the new API for analysis invalidation. #8083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 11 additions & 2 deletions include/swift/SILOptimizer/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,15 +263,24 @@ class AliasAnalysis : public SILAnalysis {
/// Encodes the memory behavior query as a MemBehaviorKeyTy.
MemBehaviorKeyTy toMemoryBehaviorKey(SILValue V1, SILValue V2, RetainObserveKind K);

virtual void invalidate(SILAnalysis::InvalidationKind K) override {
virtual void invalidate() override {
AliasCache.clear();
MemoryBehaviorCache.clear();
}

virtual void invalidate(SILFunction *,
SILAnalysis::InvalidationKind K) override {
invalidate(K);
invalidate();
}

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override { }

virtual void invalidateFunctionTables() override { }
};


Expand Down
66 changes: 35 additions & 31 deletions include/swift/SILOptimizer/Analysis/Analysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,14 @@ namespace swift {
/// has been modified.
Branches = 0x4,

/// The pass delete or created new functions.
///
/// The intent behind this is so that analyses that cache
/// SILFunction* to be able to be invalidated and later
/// recomputed so that they are not holding dangling pointers.
Functions = 0x8,

/// Convenience states:
FunctionBody = Calls | Branches | Instructions,

CallsAndInstructions = Calls | Instructions,

BranchesAndInstructions = Branches | Instructions,

Everything = Functions | Calls | Branches | Instructions,
Everything = Calls | Branches | Instructions,
};

/// A list of the known analysis.
Expand Down Expand Up @@ -112,22 +105,20 @@ namespace swift {
bool isLocked() { return invalidationLock; }

/// Invalidate all information in this analysis.
virtual void invalidate(InvalidationKind K) {}
virtual void invalidate() = 0;

/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) {}

/// Invalidate all of the information for a specific function. Also, we
/// know that this function is a dead function and going to be deleted from
/// the module.
virtual void invalidateForDeadFunction(SILFunction *F, InvalidationKind K) {
// Call the normal invalidate function unless overridden by specific
// analysis.
invalidate(F, K);
}

virtual void invalidate(SILFunction *F, InvalidationKind K) = 0;

/// Notify the analysis about a newly created function.
virtual void notifyAnalysisOfFunction(SILFunction *F) {}
virtual void notifyAddFunction(SILFunction *F) = 0;

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) = 0;

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() = 0;

/// Verify the state of this analysis.
virtual void verify() const {}
Expand Down Expand Up @@ -190,26 +181,39 @@ namespace swift {
return it.second;
}

virtual void invalidate(SILAnalysis::InvalidationKind K) override {
if (!shouldInvalidate(K)) return;

for (auto D : Storage)
delete D.second;

/// Invalidate all information in this analysis.
virtual void invalidate() override {
Storage.clear();
}

virtual void invalidate(SILFunction *F,
SILAnalysis::InvalidationKind K) override {
if (!shouldInvalidate(K)) return;

/// Helper function to remove the analysis data for a function.
void invalidateFunction(SILFunction *F) {
auto &it = Storage.FindAndConstruct(F);
if (it.second) {
delete it.second;
it.second = nullptr;
}
}

/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F,
SILAnalysis::InvalidationKind K) override {
if (shouldInvalidate(K))
invalidateFunction(F);
}

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override {
invalidateFunction(F);
}

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }

FunctionAnalysisBase() {}
virtual ~FunctionAnalysisBase() {
for (auto D : Storage)
Expand Down
30 changes: 26 additions & 4 deletions include/swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,34 @@ class BasicCalleeAnalysis : public SILAnalysis {
return S->getKind() == AnalysisKind::BasicCallee;
}

virtual void invalidate(SILAnalysis::InvalidationKind K) {
if (K & InvalidationKind::Functions)
Cache.reset();
/// Invalidate all information in this analysis.
virtual void invalidate() override {
Cache.reset();
}

virtual void invalidate(SILFunction *F, InvalidationKind K) { invalidate(K); }
/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override {
// No invalidation needed because the analysis does not cache anything
// per call-site in functions.
}

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override {
// Nothing to be done because the analysis does not cache anything
// per call-site in functions.
}

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override {
// No invalidation needed because the analysis does not cache anything
// per call-site in functions.
};

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override {
Cache.reset();
}

CalleeList getCalleeList(FullApplySite FAS) {
if (!Cache)
Expand Down
35 changes: 19 additions & 16 deletions include/swift/SILOptimizer/Analysis/CallerAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,17 @@ class CallerAnalysis : public SILAnalysis {
return S->getKind() == AnalysisKind::Caller;
}

virtual void notifyAnalysisOfFunction(SILFunction *F) {
RecomputeFunctionList.insert(F);
/// Invalidate all information in this analysis.
virtual void invalidate() override {
FuncInfos.clear();
RecomputeFunctionList.clear();
for (auto &F : Mod) {
RecomputeFunctionList.insert(&F);
}
}

virtual void invalidate(SILFunction *F, InvalidationKind K) {
/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override {
// Should we invalidate based on the invalidation kind.
bool shouldInvalidate = K & InvalidationKind::CallsAndInstructions;
if (!shouldInvalidate)
Expand All @@ -138,23 +144,20 @@ class CallerAnalysis : public SILAnalysis {
RecomputeFunctionList.insert(F);
}

virtual void invalidateForDeadFunction(SILFunction *F, InvalidationKind K) {
/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override {
RecomputeFunctionList.insert(F);
}

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override {
invalidateExistingCalleeRelation(F);
RecomputeFunctionList.remove(F);
}

virtual void invalidate(InvalidationKind K) {
// Should we invalidate based on the invalidation kind.
bool shouldInvalidate = K & InvalidationKind::Calls;
if (!shouldInvalidate)
return;

FuncInfos.clear();
RecomputeFunctionList.clear();
for (auto &F : Mod) {
RecomputeFunctionList.insert(&F);
}
}
/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }

const FunctionInfo &getCallerInfo(SILFunction *F) {
// Recompute every function in the invalidated function list and empty the
Expand Down
22 changes: 16 additions & 6 deletions include/swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,24 @@ class ClassHierarchyAnalysis : public SILAnalysis {
return S->getKind() == AnalysisKind::ClassHierarchy;
}

virtual void invalidate(SILAnalysis::InvalidationKind K) {
// Nothing can invalidate the ClassHierarchyAnalysis!
/// Invalidate all information in this analysis.
virtual void invalidate() override {
// Nothing can invalidate, because types are static and cannot be changed
// during the SIL pass pipeline.
}

/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override { }

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override { }

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }

/// Returns a list of the known direct subclasses of a class \p C in
/// the current module.
Expand Down Expand Up @@ -87,10 +101,6 @@ class ClassHierarchyAnalysis : public SILAnalysis {
return ProtocolImplementationsCache.count(C);
}

virtual void invalidate(SILFunction *F, SILAnalysis::InvalidationKind K) {
invalidate(K);
}

private:
/// Compute inheritance properties.
void init();
Expand Down
22 changes: 22 additions & 0 deletions include/swift/SILOptimizer/Analysis/DestructorAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ class DestructorAnalysis : public SILAnalysis {
/// Returns true if destruction of T may store to memory.
bool mayStoreToMemoryOnDestruction(SILType T);

/// No invalidation is needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment: explain why no invalidation is needed.

virtual void invalidate() override {
// Nothing can invalidate, because types are static and cannot be changed
// during the SIL pass pipeline.
}

/// No invalidation is needed.
virtual void invalidate(SILFunction *F, InvalidationKind K) override {
// Nothing can invalidate, because types are static and cannot be changed
// during the SIL pass pipeline.
}

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override { }

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }

protected:
bool cacheResult(CanType Type, bool Result);
bool isSafeType(CanType Ty);
Expand Down
16 changes: 15 additions & 1 deletion include/swift/SILOptimizer/Analysis/EscapeAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,10 +791,24 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
/// node, the pointers do not alias.
bool canPointToSameMemory(SILValue V1, SILValue V2);

virtual void invalidate(InvalidationKind K) override;
/// Invalidate all information in this analysis.
virtual void invalidate() override;

/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override;

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override {
invalidate(F, InvalidationKind::Nothing);
}

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }

virtual void handleDeleteNotification(ValueBase *I) override;

virtual bool needsNotifications() override { return true; }
Expand Down
18 changes: 15 additions & 3 deletions include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,23 @@ class SideEffectAnalysis : public BottomUpIPAnalysis {
/// Get the side-effects of a call site.
void getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS);

/// No invalidation is needed. See comment for SideEffectAnalysis.
virtual void invalidate(InvalidationKind K) override;
/// Invalidate all information in this analysis.
virtual void invalidate() override;

/// No invalidation is needed. See comment for SideEffectAnalysis.
/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override;

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override {
invalidate(F, InvalidationKind::Nothing);
}

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }
};

} // end namespace swift
Expand Down
19 changes: 19 additions & 0 deletions include/swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ class TypeExpansionAnalysis : public SILAnalysis {

/// Return ProjectionPath to every leaf or intermediate node of the given type.
const ProjectionPathList &getTypeExpansion(SILType B, SILModule *Mod);

/// Invalidate all information in this analysis.
virtual void invalidate() override {
// Nothing can invalidate, because types are static and cannot be changed
// during the SIL pass pipeline.
}

/// Invalidate all of the information for a specific function.
virtual void invalidate(SILFunction *F, InvalidationKind K) override { }

/// Notify the analysis about a newly created function.
virtual void notifyAddFunction(SILFunction *F) override { }

/// Notify the analysis about a function which will be deleted from the
/// module.
virtual void notifyDeleteFunction(SILFunction *F) override { }

/// Notify the analysis about changed witness or vtables.
virtual void invalidateFunctionTables() override { }
};

}
Expand Down
Loading