mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Capture Promotion: have new closures inserted before their original versions
Swift SVN r10554
This commit is contained in:
@@ -84,7 +84,8 @@ public:
|
||||
SILFunction(SILModule &Module, SILLinkage Linkage,
|
||||
StringRef MangledName, SILType LoweredType,
|
||||
Optional<SILLocation> Loc = Nothing,
|
||||
IsTransparent_t isTrans = IsNotTransparent);
|
||||
IsTransparent_t isTrans = IsNotTransparent,
|
||||
SILFunction *InsertBefore = nullptr);
|
||||
|
||||
~SILFunction();
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ using namespace swift;
|
||||
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
|
||||
StringRef Name, SILType LoweredType,
|
||||
Optional<SILLocation> Loc,
|
||||
IsTransparent_t isTrans)
|
||||
IsTransparent_t isTrans,
|
||||
SILFunction *InsertBefore)
|
||||
: ModuleAndLinkage(&Module, Linkage),
|
||||
Name(Name),
|
||||
LoweredType(LoweredType),
|
||||
@@ -26,7 +27,10 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
|
||||
DeclCtx(nullptr),
|
||||
DebugScope(nullptr),
|
||||
Transparent(isTrans) {
|
||||
Module.functions.push_back(this);
|
||||
if (InsertBefore)
|
||||
Module.functions.insert(SILModule::iterator(InsertBefore), this);
|
||||
else
|
||||
Module.functions.push_back(this);
|
||||
}
|
||||
|
||||
SILFunction::~SILFunction() {
|
||||
|
||||
@@ -305,13 +305,10 @@ ClosureCloner::initCloned(SILFunction *Orig, IndicesSet &PromotableIndices) {
|
||||
OrigLoweredTy.getAs<AnyFunctionType>().getResult(),
|
||||
M.getASTContext()));
|
||||
|
||||
// FIXME: This should insert the cloned function right before the existing
|
||||
// SILFunction for the closure, so that these naturally clump together and
|
||||
// so that testcases are easier to write. This can be done by creating the
|
||||
// function then using the splice method on the module's ilist of functions.
|
||||
// This inserts the new cloned function before the original function.
|
||||
return new (M) SILFunction(M, SILLinkage::Internal, ClonedName,
|
||||
M.Types.getLoweredType(ClonedTy),
|
||||
Orig->getLocation());
|
||||
Orig->getLocation(), IsNotTransparent, Orig);
|
||||
}
|
||||
|
||||
/// \brief Populate the body of the cloned closure, modifying instructions as
|
||||
|
||||
@@ -82,6 +82,31 @@ bb0:
|
||||
return %21 : $() -> Int64
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil internal @closure0_promote0 : $@thin (Foo, Baz, Int64) -> Int64
|
||||
// CHECK: [[DUMMY_FUNC:%.*]] = function_ref @dummy_func : $@thin (a: Int64, b: Int64, c: Int64) -> Int64
|
||||
|
||||
// The load of %1 is removed, and its uses replaced with the Foo argument
|
||||
// CHECK-NEXT: strong_retain {{.*}} : $Foo
|
||||
// CHECK-NEXT: [[METHOD_FOO:%.*]] = class_method {{.*}} : $Foo, #Foo.foo!1 : $@cc(method) @thin ((), Foo) -> Int64
|
||||
// CHECK-NEXT: [[APPLY_FOO:%.*]] = apply [[METHOD_FOO]]({{.*}}) : $@cc(method) @thin ((), Foo) -> Int64
|
||||
|
||||
// The struct_element_addr of %3 followed by a load is replaced by a struct_extract of the Baz argument
|
||||
// CHECK-NEXT: [[EXTRACT_BAZ_X:%.*]] = struct_extract {{.*}} : $Baz, #x
|
||||
|
||||
// CHECK-NEXT: [[RETVAL:%.*]] = apply [[DUMMY_FUNC]]([[APPLY_FOO]], [[EXTRACT_BAZ_X]], {{.*}}) : $@thin (a: Int64, b: Int64, c: Int64) -> Int64
|
||||
|
||||
// The release of %4 is removed because the Int64 type is trivial
|
||||
|
||||
// The release of %2 is replaced by a destroy_value of the Baz argument, since
|
||||
// it is a non-trivial aggregate
|
||||
// CHECK-NEXT: destroy_value {{.*}} : $Baz
|
||||
|
||||
// The release of %0 is replaced by a strong_release of the Foo argument, since
|
||||
// is is a reference type
|
||||
// CHECK-NEXT: strong_release {{.*}} : $Foo
|
||||
|
||||
// CHECK-NEXT: return [[RETVAL]] : $Int64
|
||||
|
||||
sil internal @closure0 : $@thin ((), (Builtin.ObjectPointer, @inout Foo, Builtin.ObjectPointer, @inout Baz, Builtin.ObjectPointer, @inout Int64)) -> Int64 {
|
||||
bb0(%0 : $Builtin.ObjectPointer, %1 : $*Foo, %2 : $Builtin.ObjectPointer, %3 : $*Baz, %4 : $Builtin.ObjectPointer, %5 : $*Int64):
|
||||
%6 = tuple ()
|
||||
@@ -136,28 +161,3 @@ bb0(%0 : $Builtin.ObjectPointer, %1 : $*Foo):
|
||||
strong_release %0 : $Builtin.ObjectPointer
|
||||
return %11 : $Int64
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil internal @closure0_promote0 : $@thin (Foo, Baz, Int64) -> Int64
|
||||
// CHECK: [[DUMMY_FUNC:%.*]] = function_ref @dummy_func : $@thin (a: Int64, b: Int64, c: Int64) -> Int64
|
||||
|
||||
// The load of %1 is removed, and its uses replaced with the Foo argument
|
||||
// CHECK-NEXT: strong_retain {{.*}} : $Foo
|
||||
// CHECK-NEXT: [[METHOD_FOO:%.*]] = class_method {{.*}} : $Foo, #Foo.foo!1 : $@cc(method) @thin ((), Foo) -> Int64
|
||||
// CHECK-NEXT: [[APPLY_FOO:%.*]] = apply [[METHOD_FOO]]({{.*}}) : $@cc(method) @thin ((), Foo) -> Int64
|
||||
|
||||
// The struct_element_addr of %3 followed by a load is replaced by a struct_extract of the Baz argument
|
||||
// CHECK-NEXT: [[EXTRACT_BAZ_X:%.*]] = struct_extract {{.*}} : $Baz, #x
|
||||
|
||||
// CHECK-NEXT: [[RETVAL:%.*]] = apply [[DUMMY_FUNC]]([[APPLY_FOO]], [[EXTRACT_BAZ_X]], {{.*}}) : $@thin (a: Int64, b: Int64, c: Int64) -> Int64
|
||||
|
||||
// The release of %4 is removed because the Int64 type is trivial
|
||||
|
||||
// The release of %2 is replaced by a destroy_value of the Baz argument, since
|
||||
// it is a non-trivial aggregate
|
||||
// CHECK-NEXT: destroy_value {{.*}} : $Baz
|
||||
|
||||
// The release of %0 is replaced by a strong_release of the Foo argument, since
|
||||
// is is a reference type
|
||||
// CHECK-NEXT: strong_release {{.*}} : $Foo
|
||||
|
||||
// CHECK-NEXT: return [[RETVAL]] : $Int64
|
||||
|
||||
Reference in New Issue
Block a user