@@ -115,6 +115,15 @@ class ControlFlowConversionState::Impl : public ControlFlowConversionState {
115115 Instruction *persistedCombinedDivergentExitMask = nullptr ;
116116 };
117117
118+ struct LoopMasksInfoMap : DenseMap<Loop *, LoopMasksInfo> {
119+ using DenseMap::DenseMap;
120+
121+ using DenseMap::at;
122+ LoopMasksInfo &at (Loop *val) {
123+ return const_cast <LoopMasksInfo &>(DenseMap::at (val));
124+ }
125+ };
126+
118127 // / @brief Create loop masks for the specified loop and its subloops.
119128 // / @param[in] L Loop which should have its LoopMasksInfo created.
120129 void createLoopMasks (Loop *L);
@@ -360,7 +369,7 @@ class ControlFlowConversionState::Impl : public ControlFlowConversionState {
360369
361370 BasicBlock *functionExitBlock = nullptr ;
362371 DenseSet<const Instruction *> blends;
363- DenseMap<Loop *, LoopMasksInfo> LoopMasks;
372+ LoopMasksInfoMap LoopMasks;
364373};
365374
366375STATISTIC (VeczCFGFail,
@@ -555,11 +564,6 @@ bool ControlFlowConversionState::Impl::convertToDataFlow() {
555564 LI = &AM.getResult <LoopAnalysis>(F);
556565 UVR = &AM.getResult <UniformValueAnalysis>(F);
557566
558- // Make sure every loop has an entry in the masks table before we start.
559- for (auto *L : *LI) {
560- createLoopMasks (L);
561- }
562-
563567 if (!VU.choices ().linearizeBOSCC ()) {
564568 ROSCCGadget ROSCC (*this );
565569 ROSCC.run (F);
@@ -579,6 +583,13 @@ bool ControlFlowConversionState::Impl::convertToDataFlow() {
579583 }
580584 }
581585
586+ // Make sure every loop has an entry in the masks table.
587+ // Do this after duplicateUniformRegions() since it may create additional
588+ // loops.
589+ for (auto *L : *LI) {
590+ createLoopMasks (L);
591+ }
592+
582593 // Reserve space for the masks table and default-construct all entries, to
583594 // avoid re-hashing/element relocation on access.
584595 MaskInfos.reserve (F.size ());
@@ -960,7 +971,7 @@ bool ControlFlowConversionState::Impl::createExitMasks(BasicBlock &BB,
960971}
961972
962973bool ControlFlowConversionState::Impl::createLoopExitMasks (LoopTag <ag) {
963- auto &LMask = LoopMasks[ LTag.loop ] ;
974+ auto &LMask = LoopMasks. at ( LTag.loop ) ;
964975 // If the Loop already has a CombinedExitMasks we have already processed it.
965976 if (LMask.combinedDivergentExitMask ) {
966977 return true ;
@@ -1038,7 +1049,7 @@ bool ControlFlowConversionState::Impl::createLoopExitMasks(LoopTag <ag) {
10381049 if (exitingLTag->loop != LTag.loop ) {
10391050 if (Loop *nestedLoop = nextInnerLoopLeft (exitingBlock, exitBlock)) {
10401051 maskUpdateOperand =
1041- LoopMasks[ nestedLoop]
1052+ LoopMasks. at ( nestedLoop)
10421053 .updatedPersistedDivergentExitMasks [exitingBlock];
10431054 }
10441055 }
@@ -1095,7 +1106,7 @@ bool ControlFlowConversionState::Impl::createCombinedLoopExitMask(
10951106 SmallVector<Loop::Edge, 1 > exitEdges;
10961107 auto *const Loop = LTag.loop ;
10971108 Loop->getExitEdges (exitEdges);
1098- auto &LMask = LoopMasks[ Loop] ;
1109+ auto &LMask = LoopMasks. at ( Loop) ;
10991110 for (const Loop::Edge &EE : exitEdges) {
11001111 BasicBlock *exitingBlock = const_cast <BasicBlock *>(EE.first );
11011112 BasicBlock *exitBlock = const_cast <BasicBlock *>(EE.second );
@@ -1836,7 +1847,7 @@ bool ControlFlowConversionState::Impl::computeDivergentLoopPureExit(
18361847 BasicBlockTag &pureExitTag = DR->getOrCreateTag (pureExit);
18371848
18381849 // Set the tags.
1839- auto &LMask = LoopMasks[ LTag.loop ] ;
1850+ auto &LMask = LoopMasks. at ( LTag.loop ) ;
18401851 MaskInfos[pureExit].entryMask = LMask.persistedCombinedDivergentExitMask ;
18411852 pureExitTag.outermostExitedLoop = <ag;
18421853
@@ -2174,7 +2185,7 @@ bool ControlFlowConversionState::Impl::generateDivergentLoopResults(
21742185
21752186bool ControlFlowConversionState::Impl::generateDivergentLoopResultUpdates (
21762187 Value *LLV, LoopTag <ag) {
2177- auto &LMask = LoopMasks[ LTag.loop ] ;
2188+ auto &LMask = LoopMasks. at ( LTag.loop ) ;
21782189 Value *mask = LMask.combinedDivergentExitMask ;
21792190 VECZ_ERROR_IF (!mask, " Divergent loop does not have an exit mask" );
21802191 PHINode *PHI = LTag.loopResultPrevs [LLV];
@@ -2285,7 +2296,7 @@ bool ControlFlowConversionState::Impl::blendDivergentLoopExitMasks(
22852296 }
22862297 }
22872298
2288- auto &LMask = LoopMasks[ LTag.loop ] ;
2299+ auto &LMask = LoopMasks. at ( LTag.loop ) ;
22892300 for (const Loop::Edge &EE : exitEdges) {
22902301 BasicBlock *exitingBlock = const_cast <BasicBlock *>(EE.first );
22912302 BasicBlock *exitBlock = const_cast <BasicBlock *>(EE.second );
@@ -3055,7 +3066,7 @@ bool ControlFlowConversionState::Impl::blendInstructions() {
30553066 }
30563067 }
30573068
3058- auto &LMask = LoopMasks[ LTag->loop ] ;
3069+ auto &LMask = LoopMasks. at ( LTag->loop ) ;
30593070 for (auto &UPREM : LMask.updatedPersistedDivergentExitMasks ) {
30603071 if (UPREM.first != header) {
30613072 blendMap[UPREM.second ][header] =
@@ -3122,7 +3133,7 @@ bool ControlFlowConversionState::Impl::blendInstructions() {
31223133 auto *const srcLoop = srcTag.loop ;
31233134 if (srcLoop && srcLoop->isLoopDivergent ()) {
31243135 if (dst != srcLoop->header ) {
3125- auto &srcMasks = LoopMasks[ srcLoop->loop ] ;
3136+ auto &srcMasks = LoopMasks. at ( srcLoop->loop ) ;
31263137 const auto &headerTag = DR->getTag (srcLoop->header );
31273138
31283139 // If 'opDef' is an update loop exit mask, set an entry point in
0 commit comments