1313#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H
1414#define SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H
1515
16- #include " swift/Basic/ValueEnumerator.h"
1716#include " swift/SIL/ApplySite.h"
1817#include " swift/SIL/SILInstruction.h"
1918#include " swift/SILOptimizer/Analysis/Analysis.h"
20- #include " swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
2119#include " llvm/ADT/DenseMap.h"
2220
23- using swift::RetainObserveKind;
24-
25- namespace {
26-
27- // / A key used for the AliasAnalysis cache.
28- // /
29- // / This struct represents the argument list to the method 'alias'. The two
30- // / SILValue pointers are mapped to integer indices because we need an
31- // / efficient way to invalidate them (the mechanism is described below). The
32- // / Type arguments are translated to void* because their underlying storage is
33- // / opaque pointers that never goes away.
34- struct AliasKeyTy {
35- // The SILValue pair:
36- swift::ValueIndexTy V1, V2;
37- // The TBAAType pair:
38- void *T1, *T2;
39- };
40-
41- // / A key used for the MemoryBehavior Analysis cache.
42- // /
43- // / The two SILValue pointers are mapped to integer indices because we need an
44- // / efficient way to invalidate them (the mechanism is described below). The
45- // / RetainObserveKind represents the inspection mode for the memory behavior
46- // / analysis.
47- struct MemBehaviorKeyTy {
48- // The SILValue pair:
49- swift::ValueIndexTy V1, V2;
50- };
51- }
52-
5321namespace swift {
5422
55- class SILInstruction ;
56- class ValueBase ;
5723class SideEffectAnalysis ;
5824class EscapeAnalysis ;
5925
6026// / This class is a simple wrapper around an alias analysis cache. This is
6127// / needed since we do not have an "analysis" infrastructure.
62- class AliasAnalysis : public SILAnalysis {
28+ class AliasAnalysis {
6329public:
6430
6531 // / This enum describes the different kinds of aliasing relations between
@@ -89,12 +55,28 @@ class AliasAnalysis : public SILAnalysis {
8955 };
9056
9157private:
92- SILModule *Mod;
93- SideEffectAnalysis *SEA;
94- EscapeAnalysis *EA;
58+ // / A key used for the AliasAnalysis cache.
59+ // /
60+ // / This struct represents the argument list to the method 'alias'.
61+ struct AliasCacheKey {
62+ // The SILValue pair:
63+ SILValue V1, V2;
64+ // The TBAAType pair:
65+ void *T1, *T2;
66+ };
67+
68+ friend struct ::llvm::DenseMapInfo<swift::AliasAnalysis::AliasCacheKey>;
69+
70+ // / A key used for the MemoryBehavior Analysis cache.
71+ using MemBehaviorCacheKey = std::pair<SILValue, SILInstruction *>;
72+
73+ using ScopeCacheKey = std::pair<SILInstruction *, SILInstruction *>;
9574
9675 using TBAACacheKey = std::pair<SILType, SILType>;
9776
77+ SideEffectAnalysis *SEA;
78+ EscapeAnalysis *EA;
79+
9880 // / A cache for the computation of TBAA. True means that the types may
9981 // / alias. False means that the types must not alias.
10082 // /
@@ -105,33 +87,27 @@ class AliasAnalysis : public SILAnalysis {
10587 // / AliasAnalysis value cache.
10688 // /
10789 // / The alias() method uses this map to cache queries.
108- llvm::DenseMap<AliasKeyTy , AliasResult> AliasCache;
90+ llvm::DenseMap<AliasCacheKey , AliasResult> AliasCache;
10991
11092 using MemoryBehavior = SILInstruction::MemoryBehavior;
93+
11194 // / MemoryBehavior value cache.
11295 // /
11396 // / The computeMemoryBehavior() method uses this map to cache queries.
114- llvm::DenseMap<MemBehaviorKeyTy , MemoryBehavior> MemoryBehaviorCache;
97+ llvm::DenseMap<MemBehaviorCacheKey , MemoryBehavior> MemoryBehaviorCache;
11598
11699 // / Set of instructions inside immutable-scopes.
117100 // /
118- // / Contains pairs of intruction indices : the first instruction is the begin-
119- // / scope instruction (e.g. begin_access), the second instruction is an
101+ // / Contains pairs of intructions : the first instruction is the begin-scope
102+ // / instruction (e.g. begin_access), the second instruction is an
120103 // / instruction inside the scope (only may-write instructions are considered).
121- llvm::DenseSet<MemBehaviorKeyTy > instsInImmutableScopes;
104+ llvm::DenseSet<ScopeCacheKey > instsInImmutableScopes;
122105
123106 // / Computed immutable scopes.
124107 // /
125- // / Contains the begin-scope instruction's indices (e.g. begin_access) of
126- // / all computed scopes.
127- llvm::DenseSet<ValueIndexTy> immutableScopeComputed;
128-
129- // / The caches can't directly map a pair of value/instruction pointers
130- // / to results because we'd like to be able to remove deleted instruction
131- // / pointers without having to scan the whole map. So, instead of storing
132- // / pointers we map pointers to indices and store the indices.
133- ValueEnumerator<ValueBase *> ValueToIndex;
134- ValueEnumerator<SILInstruction *> InstructionToIndex;
108+ // / Contains the begin-scope instructions (e.g. begin_access) of all computed
109+ // / scopes.
110+ llvm::SmallPtrSet<SILInstruction *, 16 > immutableScopeComputed;
135111
136112 AliasResult aliasAddressProjection (SILValue V1, SILValue V2,
137113 SILValue O1, SILValue O2);
@@ -144,34 +120,15 @@ class AliasAnalysis : public SILAnalysis {
144120 // / Returns True if memory of type \p T1 and \p T2 may alias.
145121 bool typesMayAlias (SILType T1, SILType T2, const SILFunction &F);
146122
147- virtual void handleDeleteNotification (SILNode *node) override ;
148-
149- virtual bool needsNotifications () override { return true ; }
150-
151- void computeImmutableScope (SingleValueInstruction *beginScopeInst,
152- ValueIndexTy beginIdx);
123+ void computeImmutableScope (SingleValueInstruction *beginScopeInst);
153124
154125 bool isInImmutableScope (SILInstruction *inst, SILValue V);
155126
156127public:
157- AliasAnalysis (SILModule *M)
158- : SILAnalysis(SILAnalysisKind::Alias), Mod(M), SEA(nullptr ), EA(nullptr ) {
159- }
160-
161- static bool classof (const SILAnalysis *S) {
162- return S->getKind () == SILAnalysisKind::Alias;
163- }
164-
165- virtual void initialize (SILPassManager *PM) override ;
128+ AliasAnalysis (SideEffectAnalysis *SEA, EscapeAnalysis *EA)
129+ : SEA(SEA), EA(EA) {}
166130
167- // / Explicitly invalidate an instruction.
168- // /
169- // / This can be useful to update the alias analysis within a pass.
170- // / It's needed if e.g. \p inst is an address projection and its operand gets
171- // / replaced with a different underlying object.
172- void invalidateInstruction (SILInstruction *inst) {
173- handleDeleteNotification (inst->asSILNode ());
174- }
131+ static SILAnalysisKind getAnalysisKind () { return SILAnalysisKind::Alias; }
175132
176133 // / Perform an alias query to see if V1, V2 refer to the same values.
177134 AliasResult alias (SILValue V1, SILValue V2, SILType TBAAType1 = SILType(),
@@ -249,37 +206,6 @@ class AliasAnalysis : public SILAnalysis {
249206
250207 // / Returns true if \p Ptr may be released by the builtin \p BI.
251208 bool canBuiltinDecrementRefCount (BuiltinInst *BI, SILValue Ptr);
252-
253- // / Encodes the alias query as a AliasKeyTy.
254- // / The parameters to this function are identical to the parameters of alias()
255- // / and this method serializes them into a key for the alias analysis cache.
256- AliasKeyTy toAliasKey (SILValue V1, SILValue V2, SILType Type1, SILType Type2);
257-
258- // / Encodes the memory behavior query as a MemBehaviorKeyTy.
259- MemBehaviorKeyTy toMemoryBehaviorKey (SILInstruction *V1, SILValue V2);
260-
261- virtual void invalidate () override {
262- AliasCache.clear ();
263- MemoryBehaviorCache.clear ();
264- InstructionToIndex.clear ();
265- ValueToIndex.clear ();
266- instsInImmutableScopes.clear ();
267- immutableScopeComputed.clear ();
268- }
269-
270- virtual void invalidate (SILFunction *,
271- SILAnalysis::InvalidationKind K) override {
272- invalidate ();
273- }
274-
275- // / Notify the analysis about a newly created function.
276- virtual void notifyAddedOrModifiedFunction (SILFunction *F) override {}
277-
278- // / Notify the analysis about a function which will be deleted from the
279- // / module.
280- virtual void notifyWillDeleteFunction (SILFunction *F) override {}
281-
282- virtual void invalidateFunctionTables () override { }
283209};
284210
285211
@@ -293,51 +219,32 @@ SILType computeTBAAType(SILValue V);
293219} // end namespace swift
294220
295221namespace llvm {
296- template <> struct DenseMapInfo <AliasKeyTy> {
297- static inline AliasKeyTy getEmptyKey () {
298- auto Allone = std::numeric_limits<swift::ValueIndexTy>::max ();
299- return {0 , Allone, nullptr , nullptr };
300- }
301- static inline AliasKeyTy getTombstoneKey () {
302- auto Allone = std::numeric_limits<swift::ValueIndexTy>::max ();
303- return {Allone, 0 , nullptr , nullptr };
304- }
305- static unsigned getHashValue (const AliasKeyTy Val) {
306- unsigned H = 0 ;
307- H ^= DenseMapInfo<swift::ValueIndexTy>::getHashValue (Val.V1 );
308- H ^= DenseMapInfo<swift::ValueIndexTy>::getHashValue (Val.V2 );
309- H ^= DenseMapInfo<void *>::getHashValue (Val.T1 );
310- H ^= DenseMapInfo<void *>::getHashValue (Val.T2 );
311- return H;
312- }
313- static bool isEqual (const AliasKeyTy LHS, const AliasKeyTy RHS) {
314- return LHS.V1 == RHS.V1 &&
315- LHS.V2 == RHS.V2 &&
316- LHS.T1 == RHS.T1 &&
317- LHS.T2 == RHS.T2 ;
318- }
319- };
222+ template <> struct DenseMapInfo <swift::AliasAnalysis::AliasCacheKey> {
223+ using AliasCacheKey = swift::AliasAnalysis::AliasCacheKey;
320224
321- template <> struct DenseMapInfo <MemBehaviorKeyTy> {
322- static inline MemBehaviorKeyTy getEmptyKey () {
323- auto Allone = std::numeric_limits<swift::ValueIndexTy>::max ();
324- return {0 , Allone};
325- }
326- static inline MemBehaviorKeyTy getTombstoneKey () {
327- auto Allone = std::numeric_limits<swift::ValueIndexTy>::max ();
328- return {Allone, 0 };
329- }
330- static unsigned getHashValue (const MemBehaviorKeyTy V) {
331- unsigned H = 0 ;
332- H ^= DenseMapInfo<swift::ValueIndexTy>::getHashValue (V.V1 );
333- H ^= DenseMapInfo<swift::ValueIndexTy>::getHashValue (V.V2 );
334- return H;
335- }
336- static bool isEqual (const MemBehaviorKeyTy LHS,
337- const MemBehaviorKeyTy RHS) {
338- return LHS.V1 == RHS.V1 && LHS.V2 == RHS.V2 ;
339- }
340- };
225+ static inline AliasCacheKey getEmptyKey () {
226+ return {DenseMapInfo<swift::SILValue>::getEmptyKey (), swift::SILValue (),
227+ nullptr , nullptr };
228+ }
229+ static inline AliasCacheKey getTombstoneKey () {
230+ return {DenseMapInfo<swift::SILValue>::getTombstoneKey (), swift::SILValue (),
231+ nullptr , nullptr };
232+ }
233+ static unsigned getHashValue (const AliasCacheKey Val) {
234+ unsigned H = 0 ;
235+ H ^= DenseMapInfo<swift::SILValue>::getHashValue (Val.V1 );
236+ H ^= DenseMapInfo<swift::SILValue>::getHashValue (Val.V2 );
237+ H ^= DenseMapInfo<void *>::getHashValue (Val.T1 );
238+ H ^= DenseMapInfo<void *>::getHashValue (Val.T2 );
239+ return H;
240+ }
241+ static bool isEqual (const AliasCacheKey LHS, const AliasCacheKey RHS) {
242+ return LHS.V1 == RHS.V1 &&
243+ LHS.V2 == RHS.V2 &&
244+ LHS.T1 == RHS.T1 &&
245+ LHS.T2 == RHS.T2 ;
246+ }
247+ };
341248}
342249
343250#endif
0 commit comments