@@ -104,10 +104,10 @@ class AccessInfo {
104
104
if (Kind == SILAccessKind::Read) {
105
105
// A read conflicts with any non-read accesses.
106
106
return NonReads > 0 ;
107
- } else {
108
- // A non-read access conflicts any other access.
109
- return NonReads > 0 || Reads > 0 ;
110
107
}
108
+
109
+ // A non-read access conflicts with any other access.
110
+ return NonReads > 0 || Reads > 0 ;
111
111
}
112
112
113
113
// / Returns true when there must have already been a conflict diagnosed
@@ -150,6 +150,18 @@ class AccessInfo {
150
150
const BeginAccessInst *getFirstAccess () { return FirstAccess; }
151
151
};
152
152
153
+ // / Indicates whether a 'begin_access' requires exclusive access
154
+ // / or allows shared acceess. This needs to be kept in sync with
155
+ // / diag::exclusivity_access_required and diag::exclusivity_conflicting_access.
156
+ enum class ExclusiveOrShared_t : unsigned {
157
+ ExclusiveAccess = 0 ,
158
+ SharedAccess = 1
159
+ };
160
+
161
+
162
+ // / Tracks the in-progress accesses on per-storage-location basis.
163
+ using StorageMap = llvm::SmallDenseMap<AccessedStorage, AccessInfo, 4 >;
164
+
153
165
} // end anonymous namespace
154
166
155
167
namespace llvm {
@@ -191,33 +203,29 @@ template <> struct DenseMapInfo<AccessedStorage> {
191
203
192
204
} // end namespace llvm
193
205
206
+
207
+ // / Returns whether a 'begin_access' requires exclusive or shared access
208
+ // / to its storage.
209
+ static ExclusiveOrShared_t getRequiredAccess (const BeginAccessInst *BAI) {
210
+ if (BAI->getAccessKind () == SILAccessKind::Read)
211
+ return ExclusiveOrShared_t::SharedAccess;
212
+
213
+ return ExclusiveOrShared_t::ExclusiveAccess;
214
+ }
215
+
194
216
// / Emits a diagnostic if beginning an access with the given in-progress
195
217
// / accesses violates the law of exclusivity. Returns true when a
196
218
// / diagnostic was emitted.
197
219
static void diagnoseExclusivityViolation (const BeginAccessInst *PriorAccess,
198
220
const BeginAccessInst *NewAccess,
199
221
ASTContext &Ctx) {
200
- // This enum needs to be kept in sync with diag::exclusivity_access_required
201
- // and diag::exclusivity_conflicting_access.
202
- enum ExclusiveOrShared_t : unsigned { ExclusiveAccess = 0 , SharedAccess = 1 };
203
222
204
223
// Can't have a conflict if both accesses are reads.
205
224
assert (!(PriorAccess->getAccessKind () == SILAccessKind::Read &&
206
225
NewAccess->getAccessKind () == SILAccessKind::Read));
207
226
208
- ExclusiveOrShared_t NewRequires;
209
- if (NewAccess->getAccessKind () == SILAccessKind::Read) {
210
- NewRequires = SharedAccess;
211
- } else {
212
- NewRequires = ExclusiveAccess;
213
- }
214
-
215
- ExclusiveOrShared_t PriorRequires;
216
- if (PriorAccess->getAccessKind () == SILAccessKind::Read) {
217
- PriorRequires = SharedAccess;
218
- } else {
219
- PriorRequires = ExclusiveAccess;
220
- }
227
+ ExclusiveOrShared_t NewRequires = getRequiredAccess (NewAccess);
228
+ ExclusiveOrShared_t PriorRequires = getRequiredAccess (PriorAccess);
221
229
222
230
diagnose (Ctx, NewAccess->getLoc ().getSourceLoc (),
223
231
diag::exclusivity_access_required,
@@ -247,8 +255,6 @@ static AccessedStorage findAccessedStorage(SILValue Source) {
247
255
}
248
256
}
249
257
250
- using StorageMap = llvm::SmallDenseMap<AccessedStorage, AccessInfo, 4 >;
251
-
252
258
static void checkStaticExclusivity (SILFunction &Fn) {
253
259
// The implementation relies on the following SIL invariants:
254
260
// - All incoming edges to a block must have the same in-progress
@@ -301,11 +307,11 @@ static void checkStaticExclusivity(SILFunction &Fn) {
301
307
// location.
302
308
StorageMap &Accesses = *BBState;
303
309
304
- for (auto I = BB-> begin (), E = BB-> end (); I != E; ++I ) {
310
+ for (auto &I : *BB ) {
305
311
// Apply transfer functions. Beginning an access
306
312
// increments the read or write count for the storage location;
307
313
// Ending onr decrements the count.
308
- if (auto *BAI = dyn_cast<BeginAccessInst>(I)) {
314
+ if (auto *BAI = dyn_cast<BeginAccessInst>(& I)) {
309
315
SILAccessKind Kind = BAI->getAccessKind ();
310
316
AccessInfo &Info = Accesses[findAccessedStorage (BAI->getSource ())];
311
317
if (Info.conflictsWithAccess (Kind) && !Info.alreadyHadConflict ()) {
@@ -315,7 +321,10 @@ static void checkStaticExclusivity(SILFunction &Fn) {
315
321
}
316
322
317
323
Info.beginAccess (BAI);
318
- } else if (auto *EAI = dyn_cast<EndAccessInst>(I)) {
324
+ continue ;
325
+ }
326
+
327
+ if (auto *EAI = dyn_cast<EndAccessInst>(&I)) {
319
328
auto It = Accesses.find (findAccessedStorage (EAI->getSource ()));
320
329
AccessInfo &Info = It->getSecond ();
321
330
Info.endAccess (EAI);
@@ -324,7 +333,10 @@ static void checkStaticExclusivity(SILFunction &Fn) {
324
333
// it to keep the StorageMap lean.
325
334
if (!Info.hasAccessesInProgress ())
326
335
Accesses.erase (It);
327
- } else if (auto *RI = dyn_cast<ReturnInst>(I)) {
336
+ continue ;
337
+ }
338
+
339
+ if (auto *RI = dyn_cast<ReturnInst>(&I)) {
328
340
// Sanity check to make sure entries are properly removed.
329
341
assert (Accesses.size () == 0 );
330
342
}
0 commit comments