Skip to content

Commit bf85bfc

Browse files
Merge pull request #12122 from aschwaighofer/swift-4.0-branch_fix_dom_tree_array_specialization
[4.0] Fix dominator tree update in array specialization
2 parents cf73ead + 5f040ec commit bf85bfc

File tree

2 files changed

+94
-12
lines changed

2 files changed

+94
-12
lines changed

lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,24 @@ static void replaceArrayPropsCall(SILBuilder &B, ArraySemanticsCall C) {
22132213
C.removeCall();
22142214
}
22152215

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+
22162234
void ArrayPropertiesSpecializer::specializeLoopNest() {
22172235
auto *Lp = getLoop();
22182236
assert(Lp);
@@ -2225,22 +2243,19 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
22252243
auto *CheckBlock = splitBasicBlockAndBranch(B,
22262244
HoistableLoopPreheader->getTerminator(), DomTree, nullptr);
22272245

2228-
// Get the exit blocks of the original loop.
22292246
auto *Header = CheckBlock->getSingleSuccessorBlock();
22302247
assert(Header);
22312248

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.
22342256
SmallVector<SILBasicBlock *, 16> ExitBlocks;
22352257
Lp->getExitBlocks(ExitBlocks);
22362258

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-
22442259
// Split the preheader before the first instruction.
22452260
SILBasicBlock *NewPreheader =
22462261
splitBasicBlockAndBranch(B, &*CheckBlock->begin(), DomTree, nullptr);
@@ -2269,8 +2284,8 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
22692284
IsFastNativeArray, ClonedPreheader, NewPreheader);
22702285
CheckBlock->getTerminator()->eraseFromParent();
22712286

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)
22742289
DomTree->changeImmediateDominator(DomTree->getNode(BB),
22752290
DomTree->getNode(CheckBlock));
22762291

test/SILOptimizer/array_specialize.sil

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,70 @@ bb4:
109109
bb5(%9 : $Error):
110110
throw %9 : $Error
111111
}
112+
113+
sil @dominator_update_outside_non_exit_block : $@convention(thin) (@inout MyArray<MyClass>, @inout Builtin.Int1) -> Builtin.Int1 {
114+
bb0(%0 : $*MyArray<MyClass>, %1 : $*Builtin.Int1):
115+
%3 = load %0 : $*MyArray<MyClass>
116+
br bb1
117+
118+
bb1:
119+
%2 = function_ref @arrayPropertyIsNative : $@convention(method) (@owned MyArray<MyClass>) -> Bool
120+
%4 = load %1 : $*Builtin.Int1
121+
retain_value %3 : $MyArray<MyClass>
122+
%5 = apply %2(%3) : $@convention(method) (@owned MyArray<MyClass>) -> Bool
123+
cond_br %4, bb2, bb4
124+
125+
bb2:
126+
cond_br undef, bb3, bb5
127+
128+
bb3:
129+
%6 = integer_literal $Builtin.Int1, -1
130+
cond_br %6, bb1, bb7
131+
132+
bb4: // Exit block; b1 dom b4
133+
cond_br undef, bb5, bb6
134+
135+
bb5: // Exit Block; b1 dom b4
136+
br bb6
137+
138+
bb6: // Non-exit Dominated by bb1
139+
br bb7
140+
141+
bb7:
142+
return %4 : $Builtin.Int1
143+
}
144+
145+
sil @dominator_update_outside_non_exit_block_2 : $@convention(thin) (@inout MyArray<MyClass>, @inout Builtin.Int1) -> Builtin.Int1 {
146+
bb0(%0 : $*MyArray<MyClass>, %1 : $*Builtin.Int1):
147+
%3 = load %0 : $*MyArray<MyClass>
148+
br bb1
149+
150+
bb1:
151+
%2 = function_ref @arrayPropertyIsNative : $@convention(method) (@owned MyArray<MyClass>) -> Bool
152+
%4 = load %1 : $*Builtin.Int1
153+
retain_value %3 : $MyArray<MyClass>
154+
%5 = apply %2(%3) : $@convention(method) (@owned MyArray<MyClass>) -> Bool
155+
cond_br %4, bb2, bb4
156+
157+
bb2:
158+
cond_br undef, bb3, bb5
159+
160+
bb3:
161+
%6 = integer_literal $Builtin.Int1, -1
162+
cond_br %6, bb1, bb7
163+
164+
bb4: // Exit block; b1 dom b4
165+
cond_br undef, bb5, bb6
166+
167+
bb5: // Exit Block; b1 dom b4
168+
br bb6
169+
170+
bb6: // Non-exit Dominated by bb1
171+
br bb8
172+
173+
bb7: // Exit dominated by bb3
174+
br bb8
175+
176+
bb8: // Non-exit dominated by bb1
177+
return %4 : $Builtin.Int1
178+
}

0 commit comments

Comments
 (0)