@@ -128,6 +128,14 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
128128 ArrayRef<SILValue> entryArgs,
129129 bool replaceOriginalFunctionInPlace = false );
130130
131+ // / The same as clone function body, except the caller can provide a callback
132+ // / that allows for an entry arg to be assigned to a custom old argument. This
133+ // / is useful if one re-arranges parameters when converting from inout to out.
134+ void
135+ cloneFunctionBody (SILFunction *F, SILBasicBlock *clonedEntryBB,
136+ ArrayRef<SILValue> entryArgs,
137+ llvm::function_ref<SILValue(SILValue)> entryArgToOldArgMap);
138+
131139 // / MARK: Callback utilities used from CRTP extensions during cloning.
132140 // / These should only be called from within an instruction cloning visitor.
133141
@@ -613,6 +621,29 @@ void SILCloner<ImplClass>::cloneFunctionBody(SILFunction *F,
613621 commonFixUp (F);
614622}
615623
624+ template <typename ImplClass>
625+ void SILCloner<ImplClass>::cloneFunctionBody(
626+ SILFunction *F, SILBasicBlock *clonedEntryBB, ArrayRef<SILValue> entryArgs,
627+ llvm::function_ref<SILValue(SILValue)> entryArgIndexToOldArgIndex) {
628+ assert (F != clonedEntryBB->getParent () && " Must clone into a new function." );
629+ assert (BBMap.empty () && " This API does not allow clients to map blocks." );
630+ assert (ValueMap.empty () && " Stale ValueMap." );
631+
632+ assert (entryArgs.size () == F->getArguments ().size ());
633+ for (unsigned i = 0 , e = entryArgs.size (); i != e; ++i) {
634+ ValueMap[entryArgIndexToOldArgIndex (entryArgs[i])] = entryArgs[i];
635+ }
636+
637+ BBMap.insert (std::make_pair (&*F->begin (), clonedEntryBB));
638+
639+ Builder.setInsertionPoint (clonedEntryBB);
640+
641+ // This will layout all newly cloned blocks immediate after clonedEntryBB.
642+ visitBlocksDepthFirst (&*F->begin ());
643+
644+ commonFixUp (F);
645+ }
646+
616647template <typename ImplClass>
617648void SILCloner<ImplClass>::clonePhiArgs(SILBasicBlock *oldBB) {
618649 auto *mappedBB = BBMap[oldBB];
0 commit comments