Optimizer: improve the SpecializationCloner

* add `cloneFunctionBody` without an `entryBlockArguments` argument
* remove the `swift::ClosureSpecializationCloner` from the bridging code and replace it with a more general `SpecializationCloner`
This commit is contained in:
Erik Eckstein
2025-06-18 20:35:54 +02:00
parent 7deec66ffe
commit 28dd6f7064
4 changed files with 52 additions and 40 deletions

View File

@@ -216,6 +216,18 @@ public:
ArrayRef<SILValue> entryArgs,
bool replaceOriginalFunctionInPlace = false);
/// Clone all blocks in this function and all instructions in those
/// blocks.
///
/// This is used to clone an entire function without mutating the original
/// function.
///
/// The new function is expected to be completely empty. Clone the entry
/// blocks arguments here. The cloned arguments become the inputs to the
/// general SILCloner, which expects the new entry block to be ready to emit
/// instructions into.
void cloneFunction(SILFunction *origF);
/// The same as clone function body, except the caller can provide a callback
/// that allows for an entry arg to be assigned to a custom old argument. This
/// is useful if one re-arranges parameters when converting from inout to out.
@@ -703,32 +715,6 @@ class SILFunctionCloner : public SILClonerWithScopes<SILFunctionCloner> {
public:
SILFunctionCloner(SILFunction *newF) : SILClonerWithScopes(*newF) {}
/// Clone all blocks in this function and all instructions in those
/// blocks.
///
/// This is used to clone an entire function without mutating the original
/// function.
///
/// The new function is expected to be completely empty. Clone the entry
/// blocks arguments here. The cloned arguments become the inputs to the
/// general SILCloner, which expects the new entry block to be ready to emit
/// instructions into.
void cloneFunction(SILFunction *origF) {
SILFunction *newF = &Builder.getFunction();
auto *newEntryBB = newF->createBasicBlock();
newEntryBB->cloneArgumentList(origF->getEntryBlock());
// Copy the new entry block arguments into a separate vector purely to
// resolve the type mismatch between SILArgument* and SILValue.
SmallVector<SILValue, 8> entryArgs;
entryArgs.reserve(newF->getArguments().size());
llvm::transform(newF->getArguments(), std::back_inserter(entryArgs),
[](SILArgument *arg) -> SILValue { return arg; });
SuperTy::cloneFunctionBody(origF, newEntryBB, entryArgs);
}
};
template<typename ImplClass>
@@ -848,6 +834,23 @@ void SILCloner<ImplClass>::cloneFunctionBody(SILFunction *F,
commonFixUp(F);
}
template <typename ImplClass>
void SILCloner<ImplClass>::cloneFunction(SILFunction *origF) {
SILFunction *newF = &Builder.getFunction();
auto *newEntryBB = newF->createBasicBlock();
newEntryBB->cloneArgumentList(origF->getEntryBlock());
// Copy the new entry block arguments into a separate vector purely to
// resolve the type mismatch between SILArgument* and SILValue.
SmallVector<SILValue, 8> entryArgs;
entryArgs.reserve(newF->getArguments().size());
llvm::transform(newF->getArguments(), std::back_inserter(entryArgs),
[](SILArgument *arg) -> SILValue { return arg; });
cloneFunctionBody(origF, newEntryBB, entryArgs);
}
template <typename ImplClass>
void SILCloner<ImplClass>::cloneFunctionBody(
SILFunction *F, SILBasicBlock *clonedEntryBB, ArrayRef<SILValue> entryArgs,

View File

@@ -53,7 +53,7 @@ class SwiftPassInvocation;
class FixedSizeSlabPayload;
class FixedSizeSlab;
class SILVTable;
class ClosureSpecializationCloner;
class SpecializationCloner;
}
struct BridgedPassContext;
@@ -182,12 +182,14 @@ struct BridgedCloner {
};
struct BridgedSpecializationCloner {
swift::ClosureSpecializationCloner * _Nonnull closureSpecCloner;
swift::SpecializationCloner * _Nonnull cloner;
SWIFT_IMPORT_UNSAFE BridgedSpecializationCloner(BridgedFunction emptySpecializedFunction);
SWIFT_IMPORT_UNSAFE BridgedFunction getCloned() const;
SWIFT_IMPORT_UNSAFE BridgedBasicBlock getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const;
void cloneFunctionBody(BridgedFunction originalFunction, BridgedBasicBlock clonedEntryBlock, BridgedValueArray clonedEntryBlockArgs) const;
void cloneFunctionBody(BridgedFunction originalFunction, BridgedBasicBlock clonedEntryBlock,
BridgedValueArray clonedEntryBlockArgs) const;
void cloneFunctionBody(BridgedFunction originalFunction) const;
};
struct BridgedPassContext {