Skip to content

Commit 7cf67e7

Browse files
authored
Fix computation of dominance frontier (#59278)
1 parent 51659f0 commit 7cf67e7

File tree

4 files changed

+75
-22
lines changed

4 files changed

+75
-22
lines changed

include/swift/SIL/Dominance.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,12 @@ class DominanceInfo : public DominatorTreeBase {
9292
///
9393
/// Precondition: no critical edges (OSSA)
9494
///
95-
/// Postcondition: each block in \p frontier is dominated by \p root and either
96-
/// exits the function or has a single successor that is not dominated by \p
97-
/// root.
98-
///
99-
/// With no critical edges, the dominance frontier is identified simply by leaf
100-
/// blocks in the dominance subtree.
101-
void computeDominanceFrontier(SILBasicBlock *root, DominanceInfo *domTree,
102-
SmallVectorImpl<SILBasicBlock *> &frontier);
95+
/// Postcondition: each block in \p boundary is dominated by \p root and either
96+
/// exits the function or has a single successor which has a predecessor that is
97+
/// not dominated by \p root.
98+
99+
void computeDominatedBoundaryBlocks(SILBasicBlock *root, DominanceInfo *domTree,
100+
SmallVectorImpl<SILBasicBlock *> &boundary);
103101

104102
/// Helper class for visiting basic blocks in dominance order, based on a
105103
/// worklist algorithm. Example usage:

lib/SIL/Utils/Dominance.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,27 @@ void PostDominanceInfo::verify() const {
142142
}
143143
}
144144

145-
void
146-
swift::computeDominanceFrontier(SILBasicBlock *root,
147-
DominanceInfo *domTree,
148-
SmallVectorImpl<SILBasicBlock *> &frontier) {
145+
void swift::computeDominatedBoundaryBlocks(
146+
SILBasicBlock *root, DominanceInfo *domTree,
147+
SmallVectorImpl<SILBasicBlock *> &boundary) {
149148
auto *function = root->getParent();
150149
assert(function->hasOwnership());
151-
assert(frontier.empty());
150+
assert(boundary.empty());
152151

153152
DominanceOrder domOrder(root, domTree);
154153
while (SILBasicBlock *block = domOrder.getNext()) {
155154
DominanceInfoNode *domNode = domTree->getNode(block);
156-
if (domNode->isLeaf()) {
157-
frontier.push_back(block);
155+
if (!domNode->isLeaf()) {
156+
domOrder.pushChildren(block);
158157
continue;
159158
}
160-
domOrder.pushChildren(block);
159+
if (block->getNumSuccessors() == 0) {
160+
boundary.push_back(block);
161+
continue;
162+
}
163+
auto *succ = block->getSingleSuccessorBlock();
164+
if (!domTree->properlyDominates(root, succ)) {
165+
boundary.push_back(block);
166+
}
161167
}
162168
}

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,12 +1244,13 @@ AllocStackInst *OpaqueStorageAllocation::createStackAllocation(SILValue value) {
12441244
deallocBuilder.createDeallocStack(pass.genLoc(), alloc);
12451245
};
12461246
if (latestOpeningInst) {
1247-
// Deallocate at the dominance frontier to ensure that allocation encloses
1248-
// not only the uses of the current value, but also of any values reusing
1249-
// this storage as a use projection.
1250-
SmallVector<SILBasicBlock *, 4> frontier;
1251-
computeDominanceFrontier(alloc->getParent(), pass.domInfo, frontier);
1252-
for (SILBasicBlock *deallocBlock : frontier) {
1247+
// Deallocate at the predecessors of dominance frontier blocks that are
1248+
// dominated by the alloc to ensure that allocation encloses not only the
1249+
// uses of the current value, but also of any values reusing this storage as
1250+
// a use projection.
1251+
SmallVector<SILBasicBlock *, 4> boundary;
1252+
computeDominatedBoundaryBlocks(alloc->getParent(), pass.domInfo, boundary);
1253+
for (SILBasicBlock *deallocBlock : boundary) {
12531254
dealloc(deallocBlock->getTerminator()->getIterator());
12541255
}
12551256
} else {

test/SILOptimizer/address_lowering.sil

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,54 @@ bb0(%0 : @owned $P):
973973
return %16 : $()
974974
}
975975

976+
// CHECK-LABEL: sil [ossa] @f162_testOpenedArchetype :
977+
// CHECK: [[STK:%.*]] = alloc_stack $Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P>
978+
// CHECK: bb6:
979+
// CHECK: dealloc_stack [[STK]] : $*Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P>
980+
// CHECK: br bb7
981+
// CHECK-LABEL: } // end sil function 'f162_testOpenedArchetype'
982+
sil [ossa] @f162_testOpenedArchetype : $@convention(thin) (@in P) -> () {
983+
bb0(%0 : @owned $P):
984+
cond_br undef, bb1, bb5
985+
986+
bb1:
987+
%2 = alloc_stack $P, var, name "q"
988+
%3 = copy_value %0 : $P
989+
store %3 to [init] %2 : $*P
990+
%5 = begin_borrow %0 : $P
991+
%6 = open_existential_value %5 : $P to $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P
992+
%7 = witness_method $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P, #P.foo : <Self where Self : P> (Self) -> () -> (), %6 : $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
993+
%8 = copy_value %6 : $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P
994+
end_borrow %5 : $P
995+
%10 = enum $Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P>, #Optional.some!enumelt, %8 : $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P
996+
%11 = unchecked_enum_data %10 : $Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P>, #Optional.some!enumelt
997+
%12 = apply %7<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P>(%11) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
998+
destroy_value %11 : $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541") P
999+
destroy_addr %2 : $*P
1000+
dealloc_stack %2 : $*P
1001+
cond_br undef, bb2, bb3
1002+
1003+
bb2:
1004+
br bb4
1005+
1006+
bb3:
1007+
br bb4
1008+
1009+
bb4:
1010+
br bb6
1011+
1012+
bb5:
1013+
br bb7
1014+
1015+
bb6:
1016+
br bb7
1017+
1018+
bb7:
1019+
destroy_value %0 : $P
1020+
%23 = tuple ()
1021+
return %23 : $()
1022+
}
1023+
9761024
// CHECK-LABEL: sil [ossa] @f170_compare : $@convention(thin) <T where T : Comparable> (@in_guaranteed T, @in_guaranteed T) -> @out T {
9771025
// CHECK: bb0(%0 : $*T, %1 : $*T, %2 : $*T):
9781026
// CHECK: [[WT:%.*]] = witness_method $T, #Comparable."<" : <Self where Self : Comparable> (Self.Type) -> (Self, Self) -> Builtin.Int1 : $@convention(witness_method: Comparable) <τ_0_0 where τ_0_0 : Comparable> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> Builtin.Int1

0 commit comments

Comments
 (0)