@@ -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
148148struct 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
336336void 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
680682void 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
700708void AccessConflictAndMergeAnalysis::visitFullApply (FullApplySite fullApply,
@@ -709,26 +717,32 @@ void AccessConflictAndMergeAnalysis::visitFullApply(FullApplySite fullApply,
709717}
710718
711719void 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
734748void AccessConflictAndMergeAnalysis::visitMayRelease (SILInstruction *instr,
@@ -776,7 +790,7 @@ void AccessConflictAndMergeAnalysis::mergePredAccesses(
776790}
777791
778792void 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