Skip to content

Commit e7eb78e

Browse files
author
Joe Shajrawi
committed
AccessEnforcementOpts continued refactoring
1 parent a9df586 commit e7eb78e

File tree

1 file changed

+73
-59
lines changed

1 file changed

+73
-59
lines changed

lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,13 @@ namespace {
142142
/// Reachability results are stored here because very few accesses are
143143
/// typically in-progress at a particular program point,
144144
/// particularly at block boundaries.
145-
using DenseAccessVec = llvm::SmallSetVector<BeginAccessInst *, 4>;
145+
using DenseAccessSet = llvm::SmallSetVector<BeginAccessInst *, 4>;
146146

147147
// Tracks the local data flow result for a basic block
148148
struct RegionInfo {
149149
struct AccessSummary {
150150
// The actual begin_access instructions
151-
DenseAccessVec conflictFreeAccesses;
151+
DenseAccessSet conflictFreeAccesses;
152152
// Flag to Indicate if we started a merging process
153153
bool merged;
154154
AccessSummary(unsigned size) : merged(false) {}
@@ -170,11 +170,11 @@ struct RegionInfo {
170170
unidentifiedAccess = false;
171171
}
172172

173-
const DenseAccessVec &getInScopeAccesses() {
173+
const DenseAccessSet &getInScopeAccesses() {
174174
return inScopeConflictFreeAccesses.conflictFreeAccesses;
175175
}
176176

177-
const DenseAccessVec &getOutOfScopeAccesses() {
177+
const DenseAccessSet &getOutOfScopeAccesses() {
178178
return outOfScopeConflictFreeAccesses.conflictFreeAccesses;
179179
}
180180
};
@@ -321,26 +321,23 @@ class AccessConflictAndMergeAnalysis {
321321
RegionInfo::AccessSummary &accessStruct,
322322
const AccessedStorage &storage, bool isInScope);
323323
void visitSetForConflicts(
324-
const DenseAccessVec &accessSet, RegionInfo &info,
324+
const DenseAccessSet &accessSet, RegionInfo &info,
325325
AccessConflictAndMergeAnalysis::AccessedStorageSet &loopStorage);
326326
void
327327
detectApplyConflicts(const swift::FunctionAccessedStorage &callSiteAccesses,
328-
const DenseAccessVec &conflictFreeSet,
328+
const DenseAccessSet &conflictFreeSet,
329329
const swift::FullApplySite &fullApply, RegionInfo &info);
330330

331-
void detectMayReleaseConflicts(const DenseAccessVec &conflictFreeSet,
331+
void detectMayReleaseConflicts(const DenseAccessSet &conflictFreeSet,
332332
SILInstruction *instr, RegionInfo &info);
333333
};
334334
} // namespace
335335

336336
void AccessConflictAndMergeAnalysis::addInScopeAccess(
337337
RegionInfo &info, BeginAccessInst *beginAccess) {
338-
assert(
339-
std::find(info.inScopeConflictFreeAccesses.conflictFreeAccesses.begin(),
340-
info.inScopeConflictFreeAccesses.conflictFreeAccesses.end(),
341-
beginAccess) ==
342-
info.inScopeConflictFreeAccesses.conflictFreeAccesses.end() &&
343-
"the begin_access should not have been in Vec.");
338+
assert(info.inScopeConflictFreeAccesses.conflictFreeAccesses.count(
339+
beginAccess) == 0 &&
340+
"the begin_access should not have been in Vec.");
344341
info.inScopeConflictFreeAccesses.conflictFreeAccesses.insert(beginAccess);
345342
}
346343

@@ -451,9 +448,7 @@ void AccessConflictAndMergeAnalysis::mergeAccessStruct(
451448
}
452449

453450
auto pred = [&](BeginAccessInst *it) {
454-
auto rhsIt = std::find(RHSAccessStruct.conflictFreeAccesses.begin(),
455-
RHSAccessStruct.conflictFreeAccesses.end(), it);
456-
return rhsIt == RHSAccessStruct.conflictFreeAccesses.end();
451+
return RHSAccessStruct.conflictFreeAccesses.count(it) == 0;
457452
};
458453
accessStruct.conflictFreeAccesses.remove_if(pred);
459454
}
@@ -630,23 +625,30 @@ void AccessConflictAndMergeAnalysis::visitBeginAccess(
630625
}
631626
SILAccessKind beginAccessKind = beginAccess->getAccessKind();
632627
// check the current in-scope accesses for conflicts:
633-
for (auto *outerBeginAccess : info.getInScopeAccesses()) {
634-
// If both are reads, keep the mapped access.
635-
if (!accessKindMayConflict(beginAccessKind,
636-
outerBeginAccess->getAccessKind())) {
637-
continue;
638-
}
628+
bool changed = false;
629+
do {
630+
changed = false;
631+
for (auto *outerBeginAccess : info.getInScopeAccesses()) {
632+
// If both are reads, keep the mapped access.
633+
if (!accessKindMayConflict(beginAccessKind,
634+
outerBeginAccess->getAccessKind())) {
635+
continue;
636+
}
639637

640-
auto &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
641-
// If there is no potential conflict, leave the outer access mapped.
642-
if (!outerAccessInfo.isDistinctFrom(beginAccessInfo))
643-
continue;
638+
auto &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
639+
// If there is no potential conflict, leave the outer access mapped.
640+
if (!outerAccessInfo.isDistinctFrom(beginAccessInfo))
641+
continue;
644642

645-
LLVM_DEBUG(beginAccessInfo.dump(); llvm::dbgs() << " may conflict with:\n";
646-
outerAccessInfo.dump());
643+
LLVM_DEBUG(beginAccessInfo.dump();
644+
llvm::dbgs() << " may conflict with:\n";
645+
outerAccessInfo.dump());
647646

648-
recordConflict(info, outerAccessInfo);
649-
}
647+
recordConflict(info, outerAccessInfo);
648+
changed = true;
649+
break;
650+
}
651+
} while (changed);
650652

651653
// Record the current access to InScopeAccesses.
652654
// It can potentially be folded
@@ -679,22 +681,28 @@ void AccessConflictAndMergeAnalysis::visitEndAccess(EndAccessInst *endAccess,
679681

680682
void AccessConflictAndMergeAnalysis::detectApplyConflicts(
681683
const swift::FunctionAccessedStorage &callSiteAccesses,
682-
const DenseAccessVec &conflictFreeSet,
684+
const DenseAccessSet &conflictFreeSet,
683685
const swift::FullApplySite &fullApply, RegionInfo &info) {
684-
for (auto *outerBeginAccess : conflictFreeSet) {
685-
// If there is no potential conflict, leave the outer access mapped.
686-
SILAccessKind accessKind = outerBeginAccess->getAccessKind();
687-
AccessInfo &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
688-
if (!callSiteAccesses.mayConflictWith(accessKind, outerAccessInfo))
689-
continue;
686+
bool changed = false;
687+
do {
688+
changed = false;
689+
for (auto *outerBeginAccess : conflictFreeSet) {
690+
// If there is no potential conflict, leave the outer access mapped.
691+
SILAccessKind accessKind = outerBeginAccess->getAccessKind();
692+
AccessInfo &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
693+
if (!callSiteAccesses.mayConflictWith(accessKind, outerAccessInfo))
694+
continue;
690695

691-
LLVM_DEBUG(
692-
llvm::dbgs() << *fullApply.getInstruction() << " call site access: ";
693-
callSiteAccesses.dump(); llvm::dbgs() << " may conflict with:\n";
694-
outerAccessInfo.dump());
696+
LLVM_DEBUG(
697+
llvm::dbgs() << *fullApply.getInstruction() << " call site access: ";
698+
callSiteAccesses.dump(); llvm::dbgs() << " may conflict with:\n";
699+
outerAccessInfo.dump());
695700

696-
recordConflict(info, outerAccessInfo);
697-
}
701+
recordConflict(info, outerAccessInfo);
702+
changed = true;
703+
break;
704+
}
705+
} while (changed);
698706
}
699707

700708
void AccessConflictAndMergeAnalysis::visitFullApply(FullApplySite fullApply,
@@ -709,26 +717,32 @@ void AccessConflictAndMergeAnalysis::visitFullApply(FullApplySite fullApply,
709717
}
710718

711719
void AccessConflictAndMergeAnalysis::detectMayReleaseConflicts(
712-
const DenseAccessVec &conflictFreeSet, SILInstruction *instr,
720+
const DenseAccessSet &conflictFreeSet, SILInstruction *instr,
713721
RegionInfo &info) {
714722
// TODO Introduce "Pure Swift" deinitializers
715723
// We can then make use of alias information for instr's operands
716724
// If they don't alias - we might get away with not recording a conflict
717-
for (auto *outerBeginAccess : conflictFreeSet) {
718-
// Only class and global access that may alias would conflict
719-
AccessInfo &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
720-
const AccessedStorage::Kind outerKind = outerAccessInfo.getKind();
721-
if (outerKind != AccessedStorage::Class &&
722-
outerKind != AccessedStorage::Global) {
723-
continue;
725+
bool changed = false;
726+
do {
727+
changed = false;
728+
for (auto *outerBeginAccess : conflictFreeSet) {
729+
// Only class and global access that may alias would conflict
730+
AccessInfo &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
731+
const AccessedStorage::Kind outerKind = outerAccessInfo.getKind();
732+
if (outerKind != AccessedStorage::Class &&
733+
outerKind != AccessedStorage::Global) {
734+
continue;
735+
}
736+
// We can't prove what the deinitializer might do
737+
// TODO Introduce "Pure Swift" deinitializers
738+
LLVM_DEBUG(llvm::dbgs() << "MayRelease Instruction: " << *instr
739+
<< " may conflict with:\n";
740+
outerAccessInfo.dump());
741+
recordConflict(info, outerAccessInfo);
742+
changed = true;
743+
break;
724744
}
725-
// We can't prove what the deinitializer might do
726-
// TODO Introduce "Pure Swift" deinitializers
727-
LLVM_DEBUG(llvm::dbgs() << "MayRelease Instruction: " << *instr
728-
<< " may conflict with:\n";
729-
outerAccessInfo.dump());
730-
recordConflict(info, outerAccessInfo);
731-
}
745+
} while (changed);
732746
}
733747

734748
void AccessConflictAndMergeAnalysis::visitMayRelease(SILInstruction *instr,
@@ -776,7 +790,7 @@ void AccessConflictAndMergeAnalysis::mergePredAccesses(
776790
}
777791

778792
void AccessConflictAndMergeAnalysis::visitSetForConflicts(
779-
const DenseAccessVec &accessSet, RegionInfo &info,
793+
const DenseAccessSet &accessSet, RegionInfo &info,
780794
AccessConflictAndMergeAnalysis::AccessedStorageSet &loopStorage) {
781795
bool changed = false;
782796
do {

0 commit comments

Comments
 (0)