13
13
#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H
14
14
#define SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H
15
15
16
- #include " swift/Basic/ValueEnumerator.h"
17
16
#include " swift/SIL/ApplySite.h"
18
17
#include " swift/SIL/SILInstruction.h"
19
18
#include " swift/SILOptimizer/Analysis/Analysis.h"
20
- #include " swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
21
19
#include " llvm/ADT/DenseMap.h"
22
20
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
-
53
21
namespace swift {
54
22
55
- class SILInstruction ;
56
- class ValueBase ;
57
23
class SideEffectAnalysis ;
58
24
class EscapeAnalysis ;
59
25
60
26
// / This class is a simple wrapper around an alias analysis cache. This is
61
27
// / needed since we do not have an "analysis" infrastructure.
62
- class AliasAnalysis : public SILAnalysis {
28
+ class AliasAnalysis {
63
29
public:
64
30
65
31
// / This enum describes the different kinds of aliasing relations between
@@ -89,12 +55,28 @@ class AliasAnalysis : public SILAnalysis {
89
55
};
90
56
91
57
private:
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 *>;
95
74
96
75
using TBAACacheKey = std::pair<SILType, SILType>;
97
76
77
+ SideEffectAnalysis *SEA;
78
+ EscapeAnalysis *EA;
79
+
98
80
// / A cache for the computation of TBAA. True means that the types may
99
81
// / alias. False means that the types must not alias.
100
82
// /
@@ -105,33 +87,27 @@ class AliasAnalysis : public SILAnalysis {
105
87
// / AliasAnalysis value cache.
106
88
// /
107
89
// / The alias() method uses this map to cache queries.
108
- llvm::DenseMap<AliasKeyTy , AliasResult> AliasCache;
90
+ llvm::DenseMap<AliasCacheKey , AliasResult> AliasCache;
109
91
110
92
using MemoryBehavior = SILInstruction::MemoryBehavior;
93
+
111
94
// / MemoryBehavior value cache.
112
95
// /
113
96
// / The computeMemoryBehavior() method uses this map to cache queries.
114
- llvm::DenseMap<MemBehaviorKeyTy , MemoryBehavior> MemoryBehaviorCache;
97
+ llvm::DenseMap<MemBehaviorCacheKey , MemoryBehavior> MemoryBehaviorCache;
115
98
116
99
// / Set of instructions inside immutable-scopes.
117
100
// /
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
120
103
// / instruction inside the scope (only may-write instructions are considered).
121
- llvm::DenseSet<MemBehaviorKeyTy > instsInImmutableScopes;
104
+ llvm::DenseSet<ScopeCacheKey > instsInImmutableScopes;
122
105
123
106
// / Computed immutable scopes.
124
107
// /
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;
135
111
136
112
AliasResult aliasAddressProjection (SILValue V1, SILValue V2,
137
113
SILValue O1, SILValue O2);
@@ -144,34 +120,15 @@ class AliasAnalysis : public SILAnalysis {
144
120
// / Returns True if memory of type \p T1 and \p T2 may alias.
145
121
bool typesMayAlias (SILType T1, SILType T2, const SILFunction &F);
146
122
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);
153
124
154
125
bool isInImmutableScope (SILInstruction *inst, SILValue V);
155
126
156
127
public:
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) {}
166
130
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; }
175
132
176
133
// / Perform an alias query to see if V1, V2 refer to the same values.
177
134
AliasResult alias (SILValue V1, SILValue V2, SILType TBAAType1 = SILType(),
@@ -249,37 +206,6 @@ class AliasAnalysis : public SILAnalysis {
249
206
250
207
// / Returns true if \p Ptr may be released by the builtin \p BI.
251
208
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 { }
283
209
};
284
210
285
211
@@ -293,51 +219,32 @@ SILType computeTBAAType(SILValue V);
293
219
} // end namespace swift
294
220
295
221
namespace 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;
320
224
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
+ };
341
248
}
342
249
343
250
#endif
0 commit comments