Skip to content

Swift 4.1 branch #12522

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 2 commits into from
Oct 25, 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
8 changes: 6 additions & 2 deletions lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ cleanupCalleeValue(SILValue CalleeValue, ArrayRef<SILValue> CaptureArgs,
}

SILValue CalleeSource = CalleeValue;
// Handle partial_apply/thin_to_thick -> convert_function:
// tryDeleteDeadClosure must run before deleting a ConvertFunction that
// uses the PartialApplyInst or ThinToThickFunctionInst. tryDeleteDeadClosure
// will delete any uses of the closure, including this ConvertFunction.
if (auto *CFI = dyn_cast<ConvertFunctionInst>(CalleeValue))
CalleeSource = CFI->getOperand();

Expand All @@ -190,15 +194,15 @@ cleanupCalleeValue(SILValue CalleeValue, ArrayRef<SILValue> CaptureArgs,
if (!tryDeleteDeadClosure(PAI))
return;
CalleeValue = Callee;
}

if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(CalleeSource)) {
} else if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(CalleeSource)) {
SILValue Callee = TTTFI->getCallee();
if (!tryDeleteDeadClosure(TTTFI))
return;
CalleeValue = Callee;
}

// Handle function_ref -> convert_function -> partial_apply/thin_to_thick.
if (auto *CFI = dyn_cast<ConvertFunctionInst>(CalleeValue)) {
if (isInstructionTriviallyDead(CFI)) {
recursivelyDeleteTriviallyDeadInstructions(CFI, true);
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