@@ -142,13 +142,13 @@ namespace {
142
142
// / Reachability results are stored here because very few accesses are
143
143
// / typically in-progress at a particular program point,
144
144
// / particularly at block boundaries.
145
- using DenseAccessVec = llvm::SmallSetVector<BeginAccessInst *, 4 >;
145
+ using DenseAccessSet = llvm::SmallSetVector<BeginAccessInst *, 4 >;
146
146
147
147
// Tracks the local data flow result for a basic block
148
148
struct RegionInfo {
149
149
struct AccessSummary {
150
150
// The actual begin_access instructions
151
- DenseAccessVec conflictFreeAccesses;
151
+ DenseAccessSet conflictFreeAccesses;
152
152
// Flag to Indicate if we started a merging process
153
153
bool merged;
154
154
AccessSummary (unsigned size) : merged(false ) {}
@@ -170,11 +170,11 @@ struct RegionInfo {
170
170
unidentifiedAccess = false ;
171
171
}
172
172
173
- const DenseAccessVec &getInScopeAccesses () {
173
+ const DenseAccessSet &getInScopeAccesses () {
174
174
return inScopeConflictFreeAccesses.conflictFreeAccesses ;
175
175
}
176
176
177
- const DenseAccessVec &getOutOfScopeAccesses () {
177
+ const DenseAccessSet &getOutOfScopeAccesses () {
178
178
return outOfScopeConflictFreeAccesses.conflictFreeAccesses ;
179
179
}
180
180
};
@@ -321,26 +321,23 @@ class AccessConflictAndMergeAnalysis {
321
321
RegionInfo::AccessSummary &accessStruct,
322
322
const AccessedStorage &storage, bool isInScope);
323
323
void visitSetForConflicts (
324
- const DenseAccessVec &accessSet, RegionInfo &info,
324
+ const DenseAccessSet &accessSet, RegionInfo &info,
325
325
AccessConflictAndMergeAnalysis::AccessedStorageSet &loopStorage);
326
326
void
327
327
detectApplyConflicts (const swift::FunctionAccessedStorage &callSiteAccesses,
328
- const DenseAccessVec &conflictFreeSet,
328
+ const DenseAccessSet &conflictFreeSet,
329
329
const swift::FullApplySite &fullApply, RegionInfo &info);
330
330
331
- void detectMayReleaseConflicts (const DenseAccessVec &conflictFreeSet,
331
+ void detectMayReleaseConflicts (const DenseAccessSet &conflictFreeSet,
332
332
SILInstruction *instr, RegionInfo &info);
333
333
};
334
334
} // namespace
335
335
336
336
void AccessConflictAndMergeAnalysis::addInScopeAccess (
337
337
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." );
344
341
info.inScopeConflictFreeAccesses .conflictFreeAccesses .insert (beginAccess);
345
342
}
346
343
@@ -451,9 +448,7 @@ void AccessConflictAndMergeAnalysis::mergeAccessStruct(
451
448
}
452
449
453
450
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 ;
457
452
};
458
453
accessStruct.conflictFreeAccesses .remove_if (pred);
459
454
}
@@ -630,23 +625,30 @@ void AccessConflictAndMergeAnalysis::visitBeginAccess(
630
625
}
631
626
SILAccessKind beginAccessKind = beginAccess->getAccessKind ();
632
627
// 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
+ }
639
637
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 ;
644
642
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 ());
647
646
648
- recordConflict (info, outerAccessInfo);
649
- }
647
+ recordConflict (info, outerAccessInfo);
648
+ changed = true ;
649
+ break ;
650
+ }
651
+ } while (changed);
650
652
651
653
// Record the current access to InScopeAccesses.
652
654
// It can potentially be folded
@@ -679,22 +681,28 @@ void AccessConflictAndMergeAnalysis::visitEndAccess(EndAccessInst *endAccess,
679
681
680
682
void AccessConflictAndMergeAnalysis::detectApplyConflicts (
681
683
const swift::FunctionAccessedStorage &callSiteAccesses,
682
- const DenseAccessVec &conflictFreeSet,
684
+ const DenseAccessSet &conflictFreeSet,
683
685
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 ;
690
695
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 ());
695
700
696
- recordConflict (info, outerAccessInfo);
697
- }
701
+ recordConflict (info, outerAccessInfo);
702
+ changed = true ;
703
+ break ;
704
+ }
705
+ } while (changed);
698
706
}
699
707
700
708
void AccessConflictAndMergeAnalysis::visitFullApply (FullApplySite fullApply,
@@ -709,26 +717,32 @@ void AccessConflictAndMergeAnalysis::visitFullApply(FullApplySite fullApply,
709
717
}
710
718
711
719
void AccessConflictAndMergeAnalysis::detectMayReleaseConflicts (
712
- const DenseAccessVec &conflictFreeSet, SILInstruction *instr,
720
+ const DenseAccessSet &conflictFreeSet, SILInstruction *instr,
713
721
RegionInfo &info) {
714
722
// TODO Introduce "Pure Swift" deinitializers
715
723
// We can then make use of alias information for instr's operands
716
724
// 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 ;
724
744
}
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);
732
746
}
733
747
734
748
void AccessConflictAndMergeAnalysis::visitMayRelease (SILInstruction *instr,
@@ -776,7 +790,7 @@ void AccessConflictAndMergeAnalysis::mergePredAccesses(
776
790
}
777
791
778
792
void AccessConflictAndMergeAnalysis::visitSetForConflicts (
779
- const DenseAccessVec &accessSet, RegionInfo &info,
793
+ const DenseAccessSet &accessSet, RegionInfo &info,
780
794
AccessConflictAndMergeAnalysis::AccessedStorageSet &loopStorage) {
781
795
bool changed = false ;
782
796
do {
0 commit comments