Skip to content

[opt] dead thin to thick in mand combine #30475

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
26 changes: 26 additions & 0 deletions lib/SILOptimizer/Mandatory/MandatoryCombine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define DEBUG_TYPE "sil-mandatory-combiner"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/STLExtras.h"
#include "swift/SIL/InstructionUtils.h"
#include "swift/SIL/SILInstructionWorklist.h"
#include "swift/SIL/SILVisitor.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
Expand Down Expand Up @@ -129,6 +130,7 @@ class MandatoryCombiner final
/// Base visitor that does not do anything.
SILInstruction *visitSILInstruction(SILInstruction *) { return nullptr; }
SILInstruction *visitApplyInst(ApplyInst *instruction);
SILInstruction *visitThinToThickFunctionInst(ThinToThickFunctionInst *i);
};

} // end anonymous namespace
Expand Down Expand Up @@ -225,6 +227,17 @@ bool MandatoryCombiner::doOneIteration(SILFunction &function,
return madeChange;
}

template <class InstT> static FunctionRefInst *getRemovableRef(InstT *i) {
// If the only use of the function_ref is us, then remove it.
auto funcRef = dyn_cast<FunctionRefInst>(i->getCallee());
if (funcRef &&
(funcRef->use_empty() ||
(funcRef->getSingleUse() && funcRef->getSingleUse()->getUser() == i))) {
return funcRef;
}
return nullptr;
}

//===----------------------------------------------------------------------===//
// MandatoryCombiner Visitor Methods
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -287,6 +300,19 @@ SILInstruction *MandatoryCombiner::visitApplyInst(ApplyInst *instruction) {
return nullptr;
}

/// Try to remove thing to thick instructions that are no longer used
SILInstruction *
MandatoryCombiner::visitThinToThickFunctionInst(ThinToThickFunctionInst *i) {
auto *ref = getRemovableRef(i);
if (tryDeleteDeadClosure(i, instModCallbacks, /*needKeepArgsAlive=*/false)) {
if (ref) {
instModCallbacks.deleteInst(ref);
}
}

return nullptr;
}

//===----------------------------------------------------------------------===//
// Top Level Entrypoint
//===----------------------------------------------------------------------===//
Expand Down
32 changes: 32 additions & 0 deletions test/SILOptimizer/mandatory_combine_closure_cleanup.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -mandatory-combine | %FileCheck %s

import Builtin

func test()

sil [ossa] @closure : $@convention(thin) (Builtin.Int32) -> Builtin.Int32

// CHECK-LABEL: remove_dead_thin_to_thick
// CHECK: bb0
// TODO: one of these will be removed by #30429.
// CHECK-NEXT: tuple
// CHECK-NEXT: tuple
// CHECK-NEXT: return
// CHECK-LABEL: end sil function 'remove_dead_thin_to_thick'
sil hidden [ossa] @remove_dead_thin_to_thick : $@convention(thin) () -> () {
bb0:
%0 = function_ref @closure : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
%1 = thin_to_thick_function %0 : $@convention(thin) (Builtin.Int32) -> Builtin.Int32 to $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32
debug_value %1 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32, let, name "c"

%3 = begin_borrow %1 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32
%4 = copy_value %3 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32
// This is all we got from the closure so we should be able to remove *everything* in this function.
%5 = tuple ()
destroy_value %4 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32
end_borrow %3 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32
destroy_value %1 : $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32

%9 = tuple ()
return %9 : $()
} // end sil function 'remove_dead_thin_to_thick'