@@ -2213,6 +2213,24 @@ static void replaceArrayPropsCall(SILBuilder &B, ArraySemanticsCall C) {
2213
2213
C.removeCall ();
2214
2214
}
2215
2215
2216
+ // / Collects all loop dominated blocks outside the loop that are immediately
2217
+ // / dominated by the loop.
2218
+ static void
2219
+ collectImmediateLoopDominatedBlocks (const SILLoop *Lp, DominanceInfoNode *Node,
2220
+ SmallVectorImpl<SILBasicBlock *> &Blocks) {
2221
+ SILBasicBlock *BB = Node->getBlock ();
2222
+
2223
+ // Base case: First loop dominated block outside of loop.
2224
+ if (!Lp->contains (BB)) {
2225
+ Blocks.push_back (BB);
2226
+ return ;
2227
+ }
2228
+
2229
+ // Loop contains the basic block. Look at immediately dominated nodes.
2230
+ for (auto *Child : *Node)
2231
+ collectImmediateLoopDominatedBlocks (Lp, Child, Blocks);
2232
+ }
2233
+
2216
2234
void ArrayPropertiesSpecializer::specializeLoopNest () {
2217
2235
auto *Lp = getLoop ();
2218
2236
assert (Lp);
@@ -2225,22 +2243,19 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
2225
2243
auto *CheckBlock = splitBasicBlockAndBranch (B,
2226
2244
HoistableLoopPreheader->getTerminator (), DomTree, nullptr );
2227
2245
2228
- // Get the exit blocks of the original loop.
2229
2246
auto *Header = CheckBlock->getSingleSuccessorBlock ();
2230
2247
assert (Header);
2231
2248
2232
- // Our loop info is not really completely valid anymore since the cloner does
2233
- // not update it. However, exit blocks of the original loop are still valid.
2249
+ // Collect all loop dominated blocks (e.g exit blocks could be among them). We
2250
+ // need to update their dominator.
2251
+ SmallVector<SILBasicBlock *, 16 > LoopDominatedBlocks;
2252
+ collectImmediateLoopDominatedBlocks (Lp, DomTree->getNode (Header),
2253
+ LoopDominatedBlocks);
2254
+
2255
+ // Collect all exit blocks.
2234
2256
SmallVector<SILBasicBlock *, 16 > ExitBlocks;
2235
2257
Lp->getExitBlocks (ExitBlocks);
2236
2258
2237
- // Collect the exit blocks dominated by the loop - they will be dominated by
2238
- // the check block.
2239
- SmallVector<SILBasicBlock *, 16 > ExitBlocksDominatedByPreheader;
2240
- for (auto *ExitBlock: ExitBlocks)
2241
- if (DomTree->dominates (CheckBlock, ExitBlock))
2242
- ExitBlocksDominatedByPreheader.push_back (ExitBlock);
2243
-
2244
2259
// Split the preheader before the first instruction.
2245
2260
SILBasicBlock *NewPreheader =
2246
2261
splitBasicBlockAndBranch (B, &*CheckBlock->begin (), DomTree, nullptr );
@@ -2269,8 +2284,8 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
2269
2284
IsFastNativeArray, ClonedPreheader, NewPreheader);
2270
2285
CheckBlock->getTerminator ()->eraseFromParent ();
2271
2286
2272
- // Fixup the exit blocks. They are now dominated by the check block.
2273
- for (auto *BB : ExitBlocksDominatedByPreheader )
2287
+ // Fixup the loop dominated blocks. They are now dominated by the check block.
2288
+ for (auto *BB : LoopDominatedBlocks )
2274
2289
DomTree->changeImmediateDominator (DomTree->getNode (BB),
2275
2290
DomTree->getNode (CheckBlock));
2276
2291
0 commit comments