Skip to content

Commit 45fbd87

Browse files
authored
Merge pull request #8662 from devincoughlin/static-enforcement-update
2 parents 78a90fb + 8649165 commit 45fbd87

File tree

1 file changed

+37
-25
lines changed

1 file changed

+37
-25
lines changed

lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ class AccessInfo {
104104
if (Kind == SILAccessKind::Read) {
105105
// A read conflicts with any non-read accesses.
106106
return NonReads > 0;
107-
} else {
108-
// A non-read access conflicts any other access.
109-
return NonReads > 0 || Reads > 0;
110107
}
108+
109+
// A non-read access conflicts with any other access.
110+
return NonReads > 0 || Reads > 0;
111111
}
112112

113113
/// Returns true when there must have already been a conflict diagnosed
@@ -150,6 +150,18 @@ class AccessInfo {
150150
const BeginAccessInst *getFirstAccess() { return FirstAccess; }
151151
};
152152

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+
153165
} // end anonymous namespace
154166

155167
namespace llvm {
@@ -191,33 +203,29 @@ template <> struct DenseMapInfo<AccessedStorage> {
191203

192204
} // end namespace llvm
193205

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+
194216
/// Emits a diagnostic if beginning an access with the given in-progress
195217
/// accesses violates the law of exclusivity. Returns true when a
196218
/// diagnostic was emitted.
197219
static void diagnoseExclusivityViolation(const BeginAccessInst *PriorAccess,
198220
const BeginAccessInst *NewAccess,
199221
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 };
203222

204223
// Can't have a conflict if both accesses are reads.
205224
assert(!(PriorAccess->getAccessKind() == SILAccessKind::Read &&
206225
NewAccess->getAccessKind() == SILAccessKind::Read));
207226

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);
221229

222230
diagnose(Ctx, NewAccess->getLoc().getSourceLoc(),
223231
diag::exclusivity_access_required,
@@ -247,8 +255,6 @@ static AccessedStorage findAccessedStorage(SILValue Source) {
247255
}
248256
}
249257

250-
using StorageMap = llvm::SmallDenseMap<AccessedStorage, AccessInfo, 4>;
251-
252258
static void checkStaticExclusivity(SILFunction &Fn) {
253259
// The implementation relies on the following SIL invariants:
254260
// - All incoming edges to a block must have the same in-progress
@@ -301,11 +307,11 @@ static void checkStaticExclusivity(SILFunction &Fn) {
301307
// location.
302308
StorageMap &Accesses = *BBState;
303309

304-
for (auto I = BB->begin(), E = BB->end(); I != E; ++I) {
310+
for (auto &I : *BB) {
305311
// Apply transfer functions. Beginning an access
306312
// increments the read or write count for the storage location;
307313
// Ending onr decrements the count.
308-
if (auto *BAI = dyn_cast<BeginAccessInst>(I)) {
314+
if (auto *BAI = dyn_cast<BeginAccessInst>(&I)) {
309315
SILAccessKind Kind = BAI->getAccessKind();
310316
AccessInfo &Info = Accesses[findAccessedStorage(BAI->getSource())];
311317
if (Info.conflictsWithAccess(Kind) && !Info.alreadyHadConflict()) {
@@ -315,7 +321,10 @@ static void checkStaticExclusivity(SILFunction &Fn) {
315321
}
316322

317323
Info.beginAccess(BAI);
318-
} else if (auto *EAI = dyn_cast<EndAccessInst>(I)) {
324+
continue;
325+
}
326+
327+
if (auto *EAI = dyn_cast<EndAccessInst>(&I)) {
319328
auto It = Accesses.find(findAccessedStorage(EAI->getSource()));
320329
AccessInfo &Info = It->getSecond();
321330
Info.endAccess(EAI);
@@ -324,7 +333,10 @@ static void checkStaticExclusivity(SILFunction &Fn) {
324333
// it to keep the StorageMap lean.
325334
if (!Info.hasAccessesInProgress())
326335
Accesses.erase(It);
327-
} else if (auto *RI = dyn_cast<ReturnInst>(I)) {
336+
continue;
337+
}
338+
339+
if (auto *RI = dyn_cast<ReturnInst>(&I)) {
328340
// Sanity check to make sure entries are properly removed.
329341
assert(Accesses.size() == 0);
330342
}

0 commit comments

Comments
 (0)