@@ -122,8 +122,6 @@ template <> struct DenseMapInfo<swift::StorageAccessInfo> {
122
122
}
123
123
124
124
namespace swift {
125
- // / The per-function result of AccessedStorageAnalysis.
126
- // /
127
125
// / Records each unique AccessedStorage in a set of StorageAccessInfo
128
126
// / objects. Hashing and equality only sees the AccesedStorage data. The
129
127
// / additional StorageAccessInfo bits are recorded as results of this analysis.
@@ -133,28 +131,32 @@ namespace swift {
133
131
// / results, either because the call graph is unknown or the access sets are too
134
132
// / large. It does not imply that all accesses have Unidentified
135
133
// / AccessedStorage, which is never allowed for class or global access.
136
- class FunctionAccessedStorage {
134
+ class AccessedStorageResult {
135
+
137
136
using AccessedStorageSet = llvm::SmallDenseSet<StorageAccessInfo, 8 >;
138
137
139
138
AccessedStorageSet storageAccessSet;
140
139
Optional<SILAccessKind> unidentifiedAccess;
141
-
142
140
public:
143
- FunctionAccessedStorage () {}
141
+ AccessedStorageResult () {}
144
142
145
143
// ---------------------------------------------------------------------------
146
144
// Accessing the results.
147
145
146
+ bool isEmpty () const {
147
+ return storageAccessSet.empty () && !unidentifiedAccess;
148
+ }
149
+
148
150
bool hasUnidentifiedAccess () const { return unidentifiedAccess != None; }
149
151
150
152
// / Return true if the analysis has determined all accesses of otherStorage
151
153
// / have the [no_nested_conflict] flag set.
152
154
// /
153
- // / Only call this if there is no unidentifiedAccess in the function and the
155
+ // / Only call this if there is no unidentifiedAccess in the region and the
154
156
// / given storage is uniquely identified.
155
157
bool hasNoNestedConflict (const AccessedStorage &otherStorage) const ;
156
158
157
- // / Does any of the accesses represented by this FunctionAccessedStorage
159
+ // / Does any of the accesses represented by this AccessedStorageResult
158
160
// / object conflict with the given access kind and storage.
159
161
bool mayConflictWith (SILAccessKind otherAccessKind,
160
162
const AccessedStorage &otherStorage) const ;
@@ -181,6 +183,97 @@ class FunctionAccessedStorage {
181
183
unidentifiedAccess = SILAccessKind::Modify;
182
184
}
183
185
186
+ void setUnidentifiedAccess (SILAccessKind kind) { unidentifiedAccess = kind; }
187
+
188
+ // / Merge effects directly from \p RHS.
189
+ bool mergeFrom (const AccessedStorageResult &other);
190
+
191
+ // / Merge the effects represented in calleeAccess into this
192
+ // / FunctionAccessedStorage object. calleeAccess must correspond to at least
193
+ // / one callee at the apply site `fullApply`. Merging drops any local effects,
194
+ // / and translates parameter effects into effects on the caller-side
195
+ // / arguments.
196
+ // /
197
+ // / The full caller-side effects at a call site can be obtained with
198
+ // / AccessedStorageAnalysis::getCallSiteEffects().
199
+ bool mergeFromApply (const AccessedStorageResult &calleeAccess,
200
+ FullApplySite fullApply);
201
+
202
+ // / Record any access scopes entered by the given single SIL instruction. 'I'
203
+ // / must not be a FullApply; use mergeFromApply instead.
204
+ void analyzeInstruction (SILInstruction *I);
205
+
206
+ void print (raw_ostream &os) const ;
207
+ void dump () const ;
208
+
209
+ protected:
210
+ std::pair<AccessedStorageSet::iterator, bool >
211
+ insertStorageAccess (StorageAccessInfo storageAccess) {
212
+ storageAccess.setStorageIndex (storageAccessSet.size ());
213
+ return storageAccessSet.insert (storageAccess);
214
+ }
215
+
216
+ bool updateUnidentifiedAccess (SILAccessKind accessKind);
217
+
218
+ bool mergeAccesses (const AccessedStorageResult &other,
219
+ std::function<StorageAccessInfo(const StorageAccessInfo &)>
220
+ transformStorage);
221
+
222
+ template <typename B> void visitBeginAccess (B *beginAccess);
223
+ };
224
+ } // namespace swift
225
+
226
+ namespace swift {
227
+ // / The per-function result of AccessedStorageAnalysis.
228
+ class FunctionAccessedStorage {
229
+ AccessedStorageResult accessResult;
230
+
231
+ public:
232
+ FunctionAccessedStorage () {}
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Accessing the results.
236
+
237
+ const AccessedStorageResult &getResult () const { return accessResult; }
238
+
239
+ bool hasUnidentifiedAccess () const {
240
+ return accessResult.hasUnidentifiedAccess ();
241
+ }
242
+
243
+ // / Return true if the analysis has determined all accesses of otherStorage
244
+ // / have the [no_nested_conflict] flag set.
245
+ // /
246
+ // / Only call this if there is no unidentifiedAccess in the function and the
247
+ // / given storage is uniquely identified.
248
+ bool hasNoNestedConflict (const AccessedStorage &otherStorage) const {
249
+ return accessResult.hasNoNestedConflict (otherStorage);
250
+ }
251
+
252
+ // / Does any of the accesses represented by this FunctionAccessedStorage
253
+ // / object conflict with the given access kind and storage.
254
+ bool mayConflictWith (SILAccessKind otherAccessKind,
255
+ const AccessedStorage &otherStorage) const {
256
+ return accessResult.mayConflictWith (otherAccessKind, otherStorage);
257
+ }
258
+
259
+ // / Raw access to the result for a given AccessedStorage location.
260
+ StorageAccessInfo
261
+ getStorageAccessInfo (const AccessedStorage &otherStorage) const {
262
+ return accessResult.getStorageAccessInfo (otherStorage);
263
+ }
264
+
265
+ // ---------------------------------------------------------------------------
266
+ // Constructing the results.
267
+
268
+ void clear () { accessResult.clear (); }
269
+
270
+ // / Return true if these effects are fully conservative.
271
+ bool hasWorstEffects () { return accessResult.hasWorstEffects (); }
272
+
273
+ // / Sets the most conservative effects, if we don't know anything about the
274
+ // / function.
275
+ void setWorstEffects () { accessResult.setWorstEffects (); }
276
+
184
277
// / Summarize the given function's effects using this FunctionAccessedStorage
185
278
// / object.
186
279
//
@@ -201,12 +294,14 @@ class FunctionAccessedStorage {
201
294
// /
202
295
// / TODO: Summarize ArraySemanticsCall accesses.
203
296
bool summarizeCall (FullApplySite fullApply) {
204
- assert (storageAccessSet. empty () && " expected uninitialized results." );
297
+ assert (accessResult. isEmpty () && " expected uninitialized results." );
205
298
return false ;
206
299
}
207
300
208
301
// / Merge effects directly from \p RHS.
209
- bool mergeFrom (const FunctionAccessedStorage &RHS);
302
+ bool mergeFrom (const FunctionAccessedStorage &RHS) {
303
+ return accessResult.mergeFrom (RHS.accessResult );
304
+ }
210
305
211
306
// / Merge the effects represented in calleeAccess into this
212
307
// / FunctionAccessedStorage object. calleeAccess must correspond to at least
@@ -217,31 +312,19 @@ class FunctionAccessedStorage {
217
312
// / The full caller-side effects at a call site can be obtained with
218
313
// / AccessedStorageAnalysis::getCallSiteEffects().
219
314
bool mergeFromApply (const FunctionAccessedStorage &calleeAccess,
220
- FullApplySite fullApply);
315
+ FullApplySite fullApply) {
316
+ return accessResult.mergeFromApply (calleeAccess.accessResult , fullApply);
317
+ }
221
318
222
319
// / Analyze the side-effects of a single SIL instruction \p I.
223
320
// / Visited callees are added to \p BottomUpOrder until \p RecursionDepth
224
321
// / reaches MaxRecursionDepth.
225
- void analyzeInstruction (SILInstruction *I);
226
-
227
- void print (raw_ostream &os) const ;
228
- void dump () const ;
229
-
230
- protected:
231
- std::pair<AccessedStorageSet::iterator, bool >
232
- insertStorageAccess (StorageAccessInfo storageAccess) {
233
- storageAccess.setStorageIndex (storageAccessSet.size ());
234
- return storageAccessSet.insert (storageAccess);
322
+ void analyzeInstruction (SILInstruction *I) {
323
+ accessResult.analyzeInstruction (I);
235
324
}
236
325
237
- bool updateUnidentifiedAccess (SILAccessKind accessKind);
238
-
239
- bool mergeAccesses (
240
- const FunctionAccessedStorage &other,
241
- std::function<StorageAccessInfo(const StorageAccessInfo &)>
242
- transformStorage);
243
-
244
- template <typename B> void visitBeginAccess (B *beginAccess);
326
+ void print (raw_ostream &os) const { accessResult.print (os); }
327
+ void dump () const { accessResult.dump (); }
245
328
};
246
329
247
330
// / Summarizes the dynamic accesses performed within a function and its
0 commit comments