Skip to content

Fix LoadableByAddress to handle convert_functions. #12506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2542,6 +2542,10 @@ void LoadableByAddress::run() {
SILFunction *RefF = FRI->getReferencedFunction();
if (modFuncs.count(RefF) != 0) {
// Go over the uses and add them to lists to modify
//
// FIXME: Why aren't function_ref uses processed transitively? And
// why is it necessary to visit uses at all if they will be visited
// later in this loop?
for (auto *user : FRI->getUses()) {
SILInstruction *currInstr = user->getUser();
switch (currInstr->getKind()) {
Expand Down Expand Up @@ -2584,6 +2588,14 @@ void LoadableByAddress::run() {
if (modifiableFunction(CanSILFunctionType(fType))) {
conversionInstrs.insert(CFI);
}
} else if (auto *TTI = dyn_cast<ThinToThickFunctionInst>(&I)) {

CanType canType = TTI->getCallee()->getType().getSwiftRValueType();
auto *fType = canType->castTo<SILFunctionType>();

if (modifiableFunction(CanSILFunctionType(fType)))
conversionInstrs.insert(TTI);

} else if (auto *LI = dyn_cast<LoadInst>(&I)) {
SILType currType = LI->getType();
if (auto *fType = getInnerFunctionType(currType)) {
Expand Down
20 changes: 20 additions & 0 deletions test/IRGen/big_types_corner_cases.sil
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,26 @@ bb0:
return %99 : $()
}

sil @convertToThickHelper : $@convention(thin) (@owned BigStruct) -> ()

// CHECK-LABAL: define {{.*}} swiftcc void @convertToThick(%T22big_types_corner_cases9BigStructV* noalias nocapture dereferenceable({{.*}})) #0 {
// CHECK: entry:
// CHECK: [[ALLOC:%.*]] = alloca %T22big_types_corner_cases9BigStructV, align 4
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
// CHECK: call swiftcc void bitcast (void (%T22big_types_corner_cases9BigStructV*)* @convertToThickHelper to void (%T22big_types_corner_cases9BigStructV*, %swift.refcounted*)*)(%T22big_types_corner_cases9BigStructV* noalias nocapture dereferenceable({{.*}}) [[ALLOC]], %swift.refcounted* swiftself null)
// CHECK: ret void
// CHECK-LABEL: }
sil @convertToThick : $@convention(thin) (@in BigStruct) -> () {
bb0(%0 : $*BigStruct):
%3 = function_ref @convertToThickHelper : $@convention(thin) (@owned BigStruct) -> ()
%4 = convert_function %3 : $@convention(thin) (@owned BigStruct) -> () to $@convention(thin) @noescape (@owned BigStruct) -> ()
%5 = thin_to_thick_function %4 : $@convention(thin) @noescape (@owned BigStruct) -> () to $@noescape @callee_owned (@owned BigStruct) -> ()
%8 = load %0 : $*BigStruct
%10 = apply %5(%8) : $@noescape @callee_owned (@owned BigStruct) -> ()
%12 = tuple ()
return %12 : $()
}

sil_vtable SuperBase {
}

Expand Down