Skip to content

Commit 9806161

Browse files
authored
Merge pull request #3546 from swiftix/cse-of-open-existentials
[sil-serializer] Do not use RPOT order for serializing SIL basic blocks
2 parents 888ff1a + 2f9ee20 commit 9806161

File tree

8 files changed

+247
-202
lines changed

8 files changed

+247
-202
lines changed

include/swift/SIL/SILOpenedArchetypesTracker.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,8 @@ class SILOpenedArchetypesTracker : public DeleteNotificationHandler {
4949

5050
const SILFunction &getFunction() const { return F; }
5151

52-
void addOpenedArchetypeDef(Type archetype, SILValue Def) {
53-
assert(!getOpenedArchetypeDef(archetype) &&
54-
"There can be only one definition of an opened archetype");
55-
OpenedArchetypeDefs[archetype] = Def;
56-
}
52+
// Register a definiton of a given opened archetype.
53+
void addOpenedArchetypeDef(Type archetype, SILValue Def);
5754

5855
void removeOpenedArchetypeDef(Type archetype, SILValue Def) {
5956
auto FoundDef = getOpenedArchetypeDef(archetype);

lib/SIL/SILOpenedArchetypesTracker.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@
1414

1515
using namespace swift;
1616

17+
void SILOpenedArchetypesTracker::addOpenedArchetypeDef(Type archetype,
18+
SILValue Def) {
19+
auto OldDef = getOpenedArchetypeDef(archetype);
20+
if (OldDef && isa<GlobalAddrInst>(OldDef)) {
21+
// It is a forward definition created during deserialization.
22+
// Replace it with the real definition now.
23+
OldDef->replaceAllUsesWith(Def);
24+
OldDef = SILValue();
25+
}
26+
assert(!OldDef &&
27+
"There can be only one definition of an opened archetype");
28+
OpenedArchetypeDefs[archetype] = Def;
29+
}
30+
1731
// Register archetypes opened by a given instruction.
1832
// Can be used to incrementally populate the mapping, e.g.
1933
// if it is done when performing a scan of all instructions

lib/Serialization/DeserializeSIL.cpp

Lines changed: 205 additions & 167 deletions
Large diffs are not rendered by default.

lib/Serialization/DeserializeSIL.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ namespace swift {
108108
readDefaultWitnessTable(serialization::DeclID,
109109
SILDefaultWitnessTable *existingWt);
110110

111+
/// A helper method to get a type based on a TypeID.
112+
/// If this type is an opened archetype and its
113+
/// definition is not seen yet, create a placeholder
114+
/// SILValue representing a forward definition and
115+
/// register it as a definition of this opened archetype.
116+
Type getType(SILBuilder &Builder, ModuleFile *MF,
117+
serialization::TypeID TID);
118+
111119
public:
112120
Identifier getModuleIdentifier() const {
113121
return MF->getAssociatedModule()->getName();

lib/Serialization/SerializeSIL.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -392,31 +392,20 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
392392
// Assign a value ID to each SILInstruction that has value and to each basic
393393
// block argument.
394394
unsigned ValueID = 0;
395-
llvm::ReversePostOrderTraversal<SILFunction *> RPOT(
396-
const_cast<SILFunction *>(&F));
397-
for (auto Iter = RPOT.begin(), E = RPOT.end(); Iter != E; ++Iter) {
398-
auto &BB = **Iter;
395+
for (const auto &BB : F) {
399396
BasicBlockMap.insert(std::make_pair(&BB, BasicID++));
400397

401398
for (auto I = BB.bbarg_begin(), E = BB.bbarg_end(); I != E; ++I)
402399
ValueIDs[static_cast<const ValueBase*>(*I)] = ++ValueID;
403400

404-
for (const SILInstruction &SI : BB)
401+
for (const auto &SI : BB)
405402
if (SI.hasValue())
406403
ValueIDs[&SI] = ++ValueID;
407404
}
408405

409-
// Write SIL basic blocks in the RPOT order
410-
// to make sure that instructions defining open archetypes
411-
// are serialized before instructions using those opened
412-
// archetypes.
413-
unsigned SerializedBBNum = 0;
414-
for (auto Iter = RPOT.begin(), E = RPOT.end(); Iter != E; ++Iter) {
415-
auto *BB = *Iter;
416-
writeSILBasicBlock(*BB);
417-
SerializedBBNum++;
406+
for (const auto &BB : F) {
407+
writeSILBasicBlock(BB);
418408
}
419-
assert(BasicID == SerializedBBNum && "Wrong number of BBs was serialized");
420409
}
421410

422411
void SILSerializer::writeSILBasicBlock(const SILBasicBlock &BB) {

test/ClangModules/serialization-sil.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,36 @@ public func testPartialApply(_ obj: Test) {
1010
// CHECK-LABEL: @_TF4Test16testPartialApplyFPSo4Test_T_ : $@convention(thin) (@owned Test) -> () {
1111
if let curried1 = obj.normalObject {
1212
// CHECK: dynamic_method_br [[CURRIED1_OBJ:%.+]] : $@opened([[CURRIED1_EXISTENTIAL:.+]]) Test, #Test.normalObject!1.foreign, [[CURRIED1_TRUE:[^,]+]], [[CURRIED1_FALSE:[^,]+]]
13-
// CHECK: [[CURRIED1_FALSE]]:
1413
// CHECK: [[CURRIED1_TRUE]]([[CURRIED1_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject):
1514
// CHECK: [[CURRIED1_PARTIAL:%.+]] = partial_apply [[CURRIED1_METHOD]]([[CURRIED1_OBJ]]) : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject
1615
// CHECK: [[CURRIED1_THUNK:%.+]] = function_ref @_TTRXFo__oPs9AnyObject__XFo_iT__iPS___ : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnyObject) -> @out AnyObject
1716
// CHECK: = partial_apply [[CURRIED1_THUNK]]([[CURRIED1_PARTIAL]]) : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnyObject) -> @out AnyObject
17+
// CHECK: [[CURRIED1_FALSE]]:
1818
curried1()
1919
}
2020
if let curried2 = obj.innerPointer {
2121
// CHECK: dynamic_method_br [[CURRIED2_OBJ:%.+]] : $@opened([[CURRIED2_EXISTENTIAL:.+]]) Test, #Test.innerPointer!1.foreign, [[CURRIED2_TRUE:[^,]+]], [[CURRIED2_FALSE:[^,]+]]
22-
// CHECK: [[CURRIED2_FALSE]]:
2322
// CHECK: [[CURRIED2_TRUE]]([[CURRIED2_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutablePointer<()>):
2423
// CHECK: [[CURRIED2_PARTIAL:%.+]] = partial_apply [[CURRIED2_METHOD]]([[CURRIED2_OBJ]]) : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutablePointer<()>
2524
// CHECK: [[CURRIED2_THUNK:%.+]] = function_ref @_TTRXFo__dGSpT___XFo_iT__iGSpT___ : $@convention(thin) (@in (), @owned @callee_owned () -> UnsafeMutablePointer<()>) -> @out UnsafeMutablePointer<()>
2625
// CHECK: = partial_apply [[CURRIED2_THUNK]]([[CURRIED2_PARTIAL]]) : $@convention(thin) (@in (), @owned @callee_owned () -> UnsafeMutablePointer<()>) -> @out UnsafeMutablePointer<()>
26+
// CHECK: [[CURRIED2_FALSE]]:
2727
curried2()
2828
}
2929
if let prop1 = obj.normalObjectProp {
3030
// CHECK: dynamic_method_br [[PROP1_OBJ:%.+]] : $@opened([[PROP1_EXISTENTIAL:.+]]) Test, #Test.normalObjectProp!getter.1.foreign, [[PROP1_TRUE:[^,]+]], [[PROP1_FALSE:[^,]+]]
31-
// CHECK: [[PROP1_FALSE]]:
3231
// CHECK: [[PROP1_TRUE]]([[PROP1_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject):
3332
// CHECK: [[PROP1_PARTIAL:%.+]] = partial_apply [[PROP1_METHOD]]([[PROP1_OBJ]]) : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject
3433
// CHECK: = apply [[PROP1_PARTIAL]]() : $@callee_owned () -> @owned AnyObject
34+
// CHECK: [[PROP1_FALSE]]:
3535
_ = prop1
3636
}
3737
if let prop2 = obj.innerPointerProp {
3838
// CHECK: dynamic_method_br [[PROP2_OBJ:%.+]] : $@opened([[PROP2_EXISTENTIAL:.+]]) Test, #Test.innerPointerProp!getter.1.foreign, [[PROP2_TRUE:[^,]+]], [[PROP2_FALSE:[^,]+]]
39-
// CHECK: [[PROP2_FALSE]]:
4039
// CHECK: [[PROP2_TRUE]]([[PROP2_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutablePointer<()>):
4140
// CHECK: [[PROP2_PARTIAL:%.+]] = partial_apply [[PROP2_METHOD]]([[PROP2_OBJ]]) : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutablePointer<()>
4241
// CHECK: = apply [[PROP2_PARTIAL]]() : $@callee_owned () -> UnsafeMutablePointer<()>
42+
// CHECK: [[PROP2_FALSE]]:
4343
_ = prop2
4444
}
4545
} // CHECK: {{^}$}}

test/Serialization/Inputs/def_basic.sil

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ bb1:
7777
// CHECK-LABEL: sil public_external [fragile] @test2 : $@convention(thin) (Int) -> ()
7878
sil [fragile] @test2 : $@convention(thin) (Int) -> () {
7979
// CHECK: bb1:
80-
// CHECK: %[[VAL:[0-9]+]] = tuple ()
81-
// CHECK: br bb2
80+
// CHECK: return %5 : $()
8281
// CHECK: bb2:
83-
// CHECK: return %[[VAL]] : $()
82+
// CHECK: %5 = tuple ()
83+
// CHECK: br bb1
8484
bb0(%0 : $Int):
8585
br bb2
8686
bb1:
@@ -602,7 +602,7 @@ bb3(%6 : $Builtin.Word):
602602
sil [fragile] @test_cond_branch_basic_block_args : $@convention(thin) (Int, Builtin.Int1) -> Int {
603603
bb0(%0 : $Int, %1 : $Builtin.Int1):
604604
cond_br %1, bb1(%0 : $Int), bb2(%0 : $Int)
605-
// CHECK: cond_br %1, bb2(%0 : $Int), bb1(%0 : $Int)
605+
// CHECK: cond_br %1, bb1(%0 : $Int), bb2(%0 : $Int)
606606
bb1(%3 : $Int):
607607
br bb3 (%3 : $Int)
608608
bb2(%2 : $Int):
@@ -716,13 +716,12 @@ bb1:
716716
bb2:
717717
%7 = function_ref @_TF6switch1aFT_T_ : $@convention(thin) () -> ()
718718
%8 = apply %7() : $@convention(thin) () -> ()
719-
br bb5
719+
br bb5 // CHECK: br
720720

721721
bb3(%10 : $Int):
722722
// CHECK: unchecked_enum_data {{%.*}} : $MaybePair, #MaybePair.Left!enumelt.1
723723
%x = unchecked_enum_data %3 : $MaybePair, #MaybePair.Left!enumelt.1
724724
br bb4(%x : $Int)
725-
// CHECK: br
726725

727726
bb4(%y : $Int):
728727
%12 = function_ref @_TF6switch1bFT_T_ : $@convention(thin) () -> ()
@@ -764,7 +763,7 @@ bb3:
764763
// CHECK-LABEL: sil public_external [fragile] @test_switch_value : $@convention(thin) (Builtin.Word) -> ()
765764
sil [fragile] @test_switch_value : $@convention(thin) (Builtin.Word) -> () {
766765
bb0(%0 : $Builtin.Word):
767-
// CHECK: switch_value %{{.*}} : $Builtin.Word, case %1: bb2, case %2: bb1
766+
// CHECK: switch_value %{{.*}} : $Builtin.Word, case %1: bb1, case %2: bb2
768767
%1 = integer_literal $Builtin.Word, 1
769768
%2 = integer_literal $Builtin.Word, 2
770769
switch_value %0 : $Builtin.Word, case %1: bb1, case %2: bb2
@@ -1017,7 +1016,7 @@ sil [fragile] @block_invoke : $@convention(c) (@inout_aliasable @block_storage I
10171016
// CHECK-LABEL: sil public_external [fragile] @test_try_apply : $@convention(thin) (@convention(thin) () -> @error Error) -> @error Error {
10181017
sil [fragile] @test_try_apply : $@convention(thin) (@convention(thin) () -> @error Error) -> @error Error {
10191018
bb0(%0 : $@convention(thin) () -> @error Error):
1020-
// CHECK: try_apply %0() : $@convention(thin) () -> @error Error, normal bb2, error bb1
1019+
// CHECK: try_apply %0() : $@convention(thin) () -> @error Error, normal bb1, error bb2
10211020
try_apply %0() : $@convention(thin) () -> @error Error, normal bb1, error bb2
10221021

10231022
bb1(%1 : $()):

test/Serialization/transparent.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ func wrap_br() {
4444
// SIL: bb0(%0 : $MaybePair):
4545
// SIL: retain_value %0 : $MaybePair
4646
// SIL: switch_enum %0 : $MaybePair, case #MaybePair.Neither!enumelt: bb[[CASE1:[0-9]+]], case #MaybePair.Left!enumelt.1: bb[[CASE2:[0-9]+]], case #MaybePair.Right!enumelt.1: bb[[CASE3:[0-9]+]], case #MaybePair.Both!enumelt.1: bb[[CASE4:[0-9]+]]
47-
// SIL: bb[[CASE4]](%{{.*}} : $(Int32, String)):
48-
// SIL: bb[[CASE3]](%{{.*}} : $String):
49-
// SIL: bb[[CASE2]](%{{.*}} : $Int32):
5047
// SIL: bb[[CASE1]]:
48+
// SIL: bb[[CASE2]](%{{.*}} : $Int32):
49+
// SIL: bb[[CASE3]](%{{.*}} : $String):
50+
// SIL: bb[[CASE4]](%{{.*}} : $(Int32, String)):
5151
func test_switch(u: MaybePair) {
5252
do_switch(u: u)
5353
}

0 commit comments

Comments
 (0)