Skip to content

Commit 28dd6f7

Browse files
committed
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`
1 parent 7deec66 commit 28dd6f7

File tree

4 files changed

+52
-40
lines changed

4 files changed

+52
-40
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/SpecializationCloner.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,7 @@ struct SpecializationCloner {
4646
}
4747
}
4848

49-
}
49+
func cloneFunctionBody(from originalFunction: Function) {
50+
bridged.cloneFunctionBody(originalFunction.bridged)
51+
}
52+
}

include/swift/SIL/SILCloner.h

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
216216
ArrayRef<SILValue> entryArgs,
217217
bool replaceOriginalFunctionInPlace = false);
218218

219+
/// Clone all blocks in this function and all instructions in those
220+
/// blocks.
221+
///
222+
/// This is used to clone an entire function without mutating the original
223+
/// function.
224+
///
225+
/// The new function is expected to be completely empty. Clone the entry
226+
/// blocks arguments here. The cloned arguments become the inputs to the
227+
/// general SILCloner, which expects the new entry block to be ready to emit
228+
/// instructions into.
229+
void cloneFunction(SILFunction *origF);
230+
219231
/// The same as clone function body, except the caller can provide a callback
220232
/// that allows for an entry arg to be assigned to a custom old argument. This
221233
/// is useful if one re-arranges parameters when converting from inout to out.
@@ -703,32 +715,6 @@ class SILFunctionCloner : public SILClonerWithScopes<SILFunctionCloner> {
703715

704716
public:
705717
SILFunctionCloner(SILFunction *newF) : SILClonerWithScopes(*newF) {}
706-
707-
/// Clone all blocks in this function and all instructions in those
708-
/// blocks.
709-
///
710-
/// This is used to clone an entire function without mutating the original
711-
/// function.
712-
///
713-
/// The new function is expected to be completely empty. Clone the entry
714-
/// blocks arguments here. The cloned arguments become the inputs to the
715-
/// general SILCloner, which expects the new entry block to be ready to emit
716-
/// instructions into.
717-
void cloneFunction(SILFunction *origF) {
718-
SILFunction *newF = &Builder.getFunction();
719-
720-
auto *newEntryBB = newF->createBasicBlock();
721-
newEntryBB->cloneArgumentList(origF->getEntryBlock());
722-
723-
// Copy the new entry block arguments into a separate vector purely to
724-
// resolve the type mismatch between SILArgument* and SILValue.
725-
SmallVector<SILValue, 8> entryArgs;
726-
entryArgs.reserve(newF->getArguments().size());
727-
llvm::transform(newF->getArguments(), std::back_inserter(entryArgs),
728-
[](SILArgument *arg) -> SILValue { return arg; });
729-
730-
SuperTy::cloneFunctionBody(origF, newEntryBB, entryArgs);
731-
}
732718
};
733719

734720
template<typename ImplClass>
@@ -848,6 +834,23 @@ void SILCloner<ImplClass>::cloneFunctionBody(SILFunction *F,
848834
commonFixUp(F);
849835
}
850836

837+
template <typename ImplClass>
838+
void SILCloner<ImplClass>::cloneFunction(SILFunction *origF) {
839+
SILFunction *newF = &Builder.getFunction();
840+
841+
auto *newEntryBB = newF->createBasicBlock();
842+
newEntryBB->cloneArgumentList(origF->getEntryBlock());
843+
844+
// Copy the new entry block arguments into a separate vector purely to
845+
// resolve the type mismatch between SILArgument* and SILValue.
846+
SmallVector<SILValue, 8> entryArgs;
847+
entryArgs.reserve(newF->getArguments().size());
848+
llvm::transform(newF->getArguments(), std::back_inserter(entryArgs),
849+
[](SILArgument *arg) -> SILValue { return arg; });
850+
851+
cloneFunctionBody(origF, newEntryBB, entryArgs);
852+
}
853+
851854
template <typename ImplClass>
852855
void SILCloner<ImplClass>::cloneFunctionBody(
853856
SILFunction *F, SILBasicBlock *clonedEntryBB, ArrayRef<SILValue> entryArgs,

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class SwiftPassInvocation;
5353
class FixedSizeSlabPayload;
5454
class FixedSizeSlab;
5555
class SILVTable;
56-
class ClosureSpecializationCloner;
56+
class SpecializationCloner;
5757
}
5858

5959
struct BridgedPassContext;
@@ -182,12 +182,14 @@ struct BridgedCloner {
182182
};
183183

184184
struct BridgedSpecializationCloner {
185-
swift::ClosureSpecializationCloner * _Nonnull closureSpecCloner;
185+
swift::SpecializationCloner * _Nonnull cloner;
186186

187187
SWIFT_IMPORT_UNSAFE BridgedSpecializationCloner(BridgedFunction emptySpecializedFunction);
188188
SWIFT_IMPORT_UNSAFE BridgedFunction getCloned() const;
189189
SWIFT_IMPORT_UNSAFE BridgedBasicBlock getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const;
190-
void cloneFunctionBody(BridgedFunction originalFunction, BridgedBasicBlock clonedEntryBlock, BridgedValueArray clonedEntryBlockArgs) const;
190+
void cloneFunctionBody(BridgedFunction originalFunction, BridgedBasicBlock clonedEntryBlock,
191+
BridgedValueArray clonedEntryBlockArgs) const;
192+
void cloneFunctionBody(BridgedFunction originalFunction) const;
191193
};
192194

193195
struct BridgedPassContext {

lib/SILOptimizer/Utils/OptimizerBridging.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -649,30 +649,34 @@ void BridgedCloner::recordFoldedValue(BridgedValue origValue, BridgedValue mappe
649649
}
650650

651651
namespace swift {
652-
class ClosureSpecializationCloner: public SILClonerWithScopes<ClosureSpecializationCloner> {
653-
friend class SILInstructionVisitor<ClosureSpecializationCloner>;
654-
friend class SILCloner<ClosureSpecializationCloner>;
655-
public:
656-
using SuperTy = SILClonerWithScopes<ClosureSpecializationCloner>;
657-
ClosureSpecializationCloner(SILFunction &emptySpecializedFunction): SuperTy(emptySpecializedFunction) {}
652+
class SpecializationCloner: public SILClonerWithScopes<SpecializationCloner> {
653+
friend class SILInstructionVisitor<SpecializationCloner>;
654+
friend class SILCloner<SpecializationCloner>;
655+
public:
656+
using SuperTy = SILClonerWithScopes<SpecializationCloner>;
657+
SpecializationCloner(SILFunction &emptySpecializedFunction): SuperTy(emptySpecializedFunction) {}
658658
};
659659
} // namespace swift
660660

661661
BridgedSpecializationCloner::BridgedSpecializationCloner(BridgedFunction emptySpecializedFunction):
662-
closureSpecCloner(new ClosureSpecializationCloner(*emptySpecializedFunction.getFunction())) {}
662+
cloner(new SpecializationCloner(*emptySpecializedFunction.getFunction())) {}
663663

664664
BridgedFunction BridgedSpecializationCloner::getCloned() const {
665-
return { &closureSpecCloner->getBuilder().getFunction() };
665+
return { &cloner->getBuilder().getFunction() };
666666
}
667667

668668
BridgedBasicBlock BridgedSpecializationCloner::getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const {
669-
return { closureSpecCloner->getOpBasicBlock(originalBasicBlock.unbridged()) };
669+
return { cloner->getOpBasicBlock(originalBasicBlock.unbridged()) };
670670
}
671671

672672
void BridgedSpecializationCloner::cloneFunctionBody(BridgedFunction originalFunction, BridgedBasicBlock clonedEntryBlock, BridgedValueArray clonedEntryBlockArgs) const {
673673
llvm::SmallVector<swift::SILValue, 16> clonedEntryBlockArgsStorage;
674674
auto clonedEntryBlockArgsArrayRef = clonedEntryBlockArgs.getValues(clonedEntryBlockArgsStorage);
675-
closureSpecCloner->cloneFunctionBody(originalFunction.getFunction(), clonedEntryBlock.unbridged(), clonedEntryBlockArgsArrayRef);
675+
cloner->cloneFunctionBody(originalFunction.getFunction(), clonedEntryBlock.unbridged(), clonedEntryBlockArgsArrayRef);
676+
}
677+
678+
void BridgedSpecializationCloner::cloneFunctionBody(BridgedFunction originalFunction) const {
679+
cloner->cloneFunction(originalFunction.getFunction());
676680
}
677681

678682
void BridgedBuilder::destroyCapturedArgs(BridgedInstruction partialApply) const {

0 commit comments

Comments
 (0)