@@ -149,7 +149,6 @@ using DenseAccessSet = llvm::SmallSetVector<BeginAccessInst *, 4>;
149
149
struct RegionState {
150
150
DenseAccessSet inScopeConflictFreeAccesses;
151
151
DenseAccessSet outOfScopeConflictFreeAccesses;
152
- bool unidentifiedAccess = false ;
153
152
154
153
public:
155
154
RegionState (unsigned size) {
@@ -161,7 +160,6 @@ struct RegionState {
161
160
void reset () {
162
161
inScopeConflictFreeAccesses.clear ();
163
162
outOfScopeConflictFreeAccesses.clear ();
164
- unidentifiedAccess = false ;
165
163
}
166
164
167
165
const DenseAccessSet &getInScopeAccesses () {
@@ -224,7 +222,7 @@ class AccessConflictAndMergeAnalysis {
224
222
using AccessMap = llvm::SmallDenseMap<BeginAccessInst *, AccessInfo, 32 >;
225
223
using AccessedStorageSet = llvm::SmallDenseSet<AccessedStorage, 8 >;
226
224
using LoopRegionToAccessedStorage =
227
- llvm::SmallDenseMap<unsigned , AccessedStorageSet >;
225
+ llvm::SmallDenseMap<unsigned , AccessedStorageResult >;
228
226
using RegionIDToLocalStateMap = llvm::DenseMap<unsigned , RegionState>;
229
227
// Instruction pairs we can merge from dominating instruction to dominated
230
228
using MergeablePairs =
@@ -299,15 +297,10 @@ class AccessConflictAndMergeAnalysis {
299
297
300
298
void visitMayRelease (SILInstruction *instr, RegionState &state);
301
299
302
- void mergePredAccesses (unsigned regionID,
303
- RegionIDToLocalStateMap &localRegionStates);
300
+ RegionState & mergePredAccesses (unsigned regionID,
301
+ RegionIDToLocalStateMap &localRegionStates);
304
302
305
- void detectConflictsInLoop (LoopRegion *loopRegion,
306
- RegionIDToLocalStateMap &localRegionStates,
307
- LoopRegionToAccessedStorage &accessSetsOfRegions);
308
-
309
- void localDataFlowInBlock (LoopRegion *bbRegion,
310
- RegionIDToLocalStateMap &localRegionStates);
303
+ void localDataFlowInBlock (RegionState &state, SILBasicBlock *bb);
311
304
312
305
private:
313
306
void recordInScopeConflicts (RegionState &state,
@@ -369,9 +362,7 @@ void AccessConflictAndMergeAnalysis::recordUnknownConflict(RegionState &state) {
369
362
LLVM_DEBUG (llvm::dbgs () << " may conflict with:\n " ; accessInfo.dump ());
370
363
});
371
364
// Clear data flow.
372
- state.inScopeConflictFreeAccesses .clear ();
373
- state.outOfScopeConflictFreeAccesses .clear ();
374
- // FIXME!!!: call reset() after removing RegionState.unidentifiedAccess.
365
+ state.reset ();
375
366
}
376
367
377
368
// Update data flow `state` by removing accesses that conflict with the
@@ -495,31 +486,16 @@ void AccessConflictAndMergeAnalysis::analyze() {
495
486
RegionIDToLocalStateMap localRegionStates;
496
487
// This is RPO order of the sub-regions
497
488
for (auto subID : region->getSubregions ()) {
498
- auto *subRegion = LRFI->getRegion (subID);
499
- // testIrreducibleGraph2 in test/SILOptimizer/access_enforcement_opts:
500
- // If the sub-region is the source of a previously visited backedge,
501
- // Then the in-state is an empty set.
502
- bool disableCrossBlock = false ;
503
- if (localRegionStates.find (subID) != localRegionStates.end ())
504
- // Irreducible loop - we already set the predecessor to empty set
505
- disableCrossBlock = true ;
506
- else
507
- mergePredAccesses (subID, localRegionStates);
489
+ RegionState &state = mergePredAccesses (subID, localRegionStates);
508
490
491
+ auto *subRegion = LRFI->getRegion (subID);
509
492
if (subRegion->isBlock ()) {
510
- localDataFlowInBlock (subRegion, localRegionStates );
493
+ localDataFlowInBlock (state, subRegion-> getBlock () );
511
494
} else {
512
495
assert (subRegion->isLoop () && " Expected a loop sub-region" );
513
- detectConflictsInLoop (subRegion, localRegionStates,
514
- accessSetsOfRegions);
515
- }
516
- // After doing the control flow on the region, and as mentioned above,
517
- // the sub-region is the source of a previously visited backedge,
518
- // we want to remove the merging candidates from its final state
519
- if (disableCrossBlock) {
520
- // Clear-out the out state: this is risky irreducible control flow
521
- // Only in-block conflict and merging is allowed
522
- localRegionStates.find (subID)->getSecond ().reset ();
496
+
497
+ const AccessedStorageResult &loopStorage = accessSetsOfRegions[subID];
498
+ recordConflicts (state, loopStorage);
523
499
}
524
500
}
525
501
}
@@ -572,33 +548,33 @@ void AccessConflictAndMergeAnalysis::propagateAccessSetsBottomUp(
572
548
const llvm::SmallVector<unsigned , 16 > &worklist) {
573
549
for (unsigned regionID : reverse (worklist)) {
574
550
auto *region = LRFI->getRegion (regionID);
575
- assert (regionToStorageMap.find (regionID) == regionToStorageMap.end () &&
576
- " Should not process a region twice" );
577
- AccessedStorageSet &accessedStorageSet = regionToStorageMap[regionID];
551
+ auto iterAndInserted =
552
+ regionToStorageMap.try_emplace (regionID, AccessedStorageResult ());
553
+ assert (iterAndInserted.second && " Should not process a region twice" );
554
+ AccessedStorageResult &accessResult = iterAndInserted.first ->second ;
578
555
for (auto subID : region->getSubregions ()) {
579
556
auto *subRegion = LRFI->getRegion (subID);
580
557
if (subRegion->isLoop ()) {
581
558
// propagate access sets bottom-up from nested loops.
582
- auto subRegionStorageIt = regionToStorageMap.find (subID);
583
- assert (subRegionStorageIt != regionToStorageMap.end () &&
584
- " Should have processed sub-region" );
585
- for (auto storage : subRegionStorageIt->getSecond ()) {
586
- accessedStorageSet.insert (storage);
587
- }
559
+ auto subRegionResultIter = regionToStorageMap.find (subID);
560
+ assert (subRegionResultIter != regionToStorageMap.end ()
561
+ && " Should have processed sub-region" );
562
+ accessResult.mergeFrom (subRegionResultIter->second );
588
563
} else {
589
564
assert (subRegion->isBlock () && " Expected a block region" );
590
565
auto *bb = subRegion->getBlock ();
591
566
for (auto &instr : *bb) {
592
- if (auto *beginAccess = dyn_cast<BeginAccessInst>(&instr)) {
593
- const AccessedStorage &storage =
594
- findAccessedStorageNonNested (beginAccess->getSource ());
595
- accessedStorageSet.insert (storage);
596
- }
597
- if (auto *beginAccess = dyn_cast<BeginUnpairedAccessInst>(&instr)) {
598
- const AccessedStorage &storage =
599
- findAccessedStorageNonNested (beginAccess->getSource ());
600
- accessedStorageSet.insert (storage);
567
+ if (auto fullApply = FullApplySite::isa (&instr)) {
568
+ FunctionAccessedStorage calleeAccess;
569
+ // Instead of calling getCallSiteEffects, call getCalleeEffects and
570
+ // merge ourselves to avoid an extra merge step.
571
+ ASA->getCalleeEffects (calleeAccess, fullApply);
572
+ accessResult.mergeFrom (calleeAccess.getResult ());
573
+ continue ;
601
574
}
575
+ // FIXME: Treat may-release conservatively in the anlysis itself by
576
+ // adding a mayRelease flag, in addition to the unidentified flag.
577
+ accessResult.analyzeInstruction (&instr);
602
578
}
603
579
}
604
580
}
@@ -633,7 +609,6 @@ void AccessConflictAndMergeAnalysis::visitBeginAccess(
633
609
// Get the Access info:
634
610
auto &beginAccessInfo = result.getAccessInfo (beginAccess);
635
611
if (beginAccessInfo.getKind () == AccessedStorage::Unidentified) {
636
- state.unidentifiedAccess = true ;
637
612
recordUnknownConflict (state);
638
613
return ;
639
614
}
@@ -752,14 +727,13 @@ void AccessConflictAndMergeAnalysis::mergeAccessSet(
752
727
void AccessConflictAndMergeAnalysis::mergeState (RegionState &state,
753
728
const RegionState &otherState,
754
729
bool isInitialized) {
755
- state.unidentifiedAccess |= otherState.unidentifiedAccess ;
756
730
mergeAccessSet (state.inScopeConflictFreeAccesses ,
757
731
otherState.inScopeConflictFreeAccesses , isInitialized);
758
732
mergeAccessSet (state.outOfScopeConflictFreeAccesses ,
759
733
otherState.outOfScopeConflictFreeAccesses , isInitialized);
760
734
}
761
735
762
- void AccessConflictAndMergeAnalysis::mergePredAccesses (
736
+ RegionState & AccessConflictAndMergeAnalysis::mergePredAccesses (
763
737
unsigned regionID, RegionIDToLocalStateMap &localRegionStates) {
764
738
auto regionStateIterAndInserted = localRegionStates.try_emplace (
765
739
regionID, RegionState (result.accessMap .size ()));
@@ -780,42 +754,16 @@ void AccessConflictAndMergeAnalysis::mergePredAccesses(
780
754
if (predStateIter == localRegionStates.end ()) {
781
755
// Backedge / irreducable control flow - bail
782
756
state.reset ();
783
- return ;
757
+ break ;
784
758
}
785
759
mergeState (state, predStateIter->second , isInitialized);
786
760
isInitialized = true ;
787
761
}
762
+ return state;
788
763
}
789
764
790
- void AccessConflictAndMergeAnalysis::detectConflictsInLoop (
791
- LoopRegion *loopRegion, RegionIDToLocalStateMap &localRegionStates,
792
- LoopRegionToAccessedStorage &accessSetsOfRegions) {
793
- assert (loopRegion->isLoop () && " Expected a loop region" );
794
- auto loopID = loopRegion->getID ();
795
- RegionState &state = localRegionStates.find (loopID)->getSecond ();
796
-
797
- // FIXME!!!: just call recordConflicts instead one loop summaries are fixed.
798
- if (state.unidentifiedAccess ) {
799
- recordUnknownConflict (state);
800
- return ;
801
- }
802
- AccessedStorageSet &loopStorage =
803
- accessSetsOfRegions.find (loopID)->getSecond ();
804
- for (const AccessedStorage &currStorage : loopStorage) {
805
- // FIXME: The access kind will be part of the loop summary soon.
806
- recordInScopeConflicts (state, currStorage, SILAccessKind::Modify);
807
-
808
- removeConflicts (state.inScopeConflictFreeAccesses , currStorage);
809
-
810
- removeConflicts (state.outOfScopeConflictFreeAccesses , currStorage);
811
- }
812
- }
813
-
814
- void AccessConflictAndMergeAnalysis::localDataFlowInBlock (
815
- LoopRegion *bbRegion, RegionIDToLocalStateMap &localRegionStates) {
816
- assert (bbRegion->isBlock () && " Expected a block region" );
817
- auto *bb = bbRegion->getBlock ();
818
- RegionState &state = localRegionStates.find (bbRegion->getID ())->getSecond ();
765
+ void AccessConflictAndMergeAnalysis::localDataFlowInBlock (RegionState &state,
766
+ SILBasicBlock *bb) {
819
767
for (auto &instr : *bb) {
820
768
if (auto *beginAccess = dyn_cast<BeginAccessInst>(&instr)) {
821
769
visitBeginAccess (beginAccess, state);
0 commit comments