Skip to content

Commit b8a4969

Browse files
committed
Optimizer: add TypeSubstitutionCloner and func cloneAndSpecializeFunction
Also move `func cloneFunction` from ContextCommon.swift to OptUtils.swift
1 parent c15f76f commit b8a4969

File tree

5 files changed

+113
-6
lines changed

5 files changed

+113
-6
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/ContextCommon.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,3 @@ extension Instruction {
163163
context.notifyInstructionsChanged()
164164
}
165165
}
166-
167-
func cloneFunction(from originalFunction: Function, toEmpty targetFunction: Function, _ context: FunctionPassContext) {
168-
var cloner = Cloner(cloneToEmptyFunction: targetFunction, context)
169-
defer { cloner.deinitialize() }
170-
cloner.cloneFunctionBody(from: originalFunction)
171-
}

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,3 +1092,20 @@ func isInLoop(block startBlock: BasicBlock, _ context: FunctionPassContext) -> B
10921092
}
10931093
return false
10941094
}
1095+
1096+
func cloneFunction(from originalFunction: Function, toEmpty targetFunction: Function, _ context: FunctionPassContext) {
1097+
var cloner = Cloner(cloneToEmptyFunction: targetFunction, context)
1098+
defer { cloner.deinitialize() }
1099+
cloner.cloneFunctionBody(from: originalFunction)
1100+
}
1101+
1102+
func cloneAndSpecializeFunction(from originalFunction: Function,
1103+
toEmpty targetFunction: Function,
1104+
substitutions: SubstitutionMap,
1105+
_ context: FunctionPassContext
1106+
) {
1107+
var cloner = TypeSubstitutionCloner(fromFunction: originalFunction, toEmptyFunction: targetFunction,
1108+
substitutions: substitutions, context)
1109+
defer { cloner.deinitialize() }
1110+
cloner.cloneFunctionBody()
1111+
}

SwiftCompilerSources/Sources/SIL/Utilities/Cloner.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SILBridging
14+
import AST
1415

1516
/// Clones the initializer value of a GlobalVariable.
1617
///
@@ -161,3 +162,34 @@ public struct Cloner<Context: MutatingContext> {
161162
bridged.recordFoldedValue(origValue.bridged, mappedValue.bridged)
162163
}
163164
}
165+
166+
public struct TypeSubstitutionCloner<Context: MutatingContext> {
167+
public private(set) var bridged: BridgedTypeSubstCloner
168+
public let context: Context
169+
170+
public init(fromFunction: Function,
171+
toEmptyFunction: Function,
172+
substitutions: SubstitutionMap, _ context: Context
173+
) {
174+
context.verifyIsTransforming(function: toEmptyFunction)
175+
self.bridged = BridgedTypeSubstCloner(fromFunction.bridged, toEmptyFunction.bridged,
176+
substitutions.bridged, context._bridged)
177+
self.context = context
178+
}
179+
180+
public mutating func deinitialize() {
181+
bridged.destroy(context._bridged)
182+
}
183+
184+
public mutating func getClonedValue(of originalValue: Value) -> Value {
185+
bridged.getClonedValue(originalValue.bridged).value
186+
}
187+
188+
public func getClonedBlock(for originalBlock: BasicBlock) -> BasicBlock {
189+
bridged.getClonedBasicBlock(originalBlock.bridged).block
190+
}
191+
192+
public func cloneFunctionBody() {
193+
bridged.cloneFunctionBody()
194+
}
195+
}

include/swift/SIL/SILBridging.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class SILDefaultWitnessTable;
6363
class SILLoopInfo;
6464
class SILLoop;
6565
class BridgedClonerImpl;
66+
class BridgedTypeSubstClonerImpl;
6667
class SILDebugLocation;
6768
class NominalTypeDecl;
6869
class VarDecl;
@@ -1541,6 +1542,17 @@ struct BridgedCloner {
15411542
BridgedInstruction clone(BridgedInstruction inst) const;
15421543
};
15431544

1545+
struct BridgedTypeSubstCloner {
1546+
swift::BridgedTypeSubstClonerImpl * _Nonnull cloner;
1547+
1548+
BridgedTypeSubstCloner(BridgedFunction fromFunction, BridgedFunction toFunction,
1549+
BridgedSubstitutionMap substitutions, BridgedContext context);
1550+
void destroy(BridgedContext context);
1551+
void cloneFunctionBody() const;
1552+
SWIFT_IMPORT_UNSAFE BridgedBasicBlock getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const;
1553+
SWIFT_IMPORT_UNSAFE BridgedValue getClonedValue(BridgedValue v);
1554+
};
1555+
15441556
struct BridgedVerifier {
15451557
typedef void (* _Nonnull VerifyFunctionFn)(BridgedContext, BridgedFunction);
15461558

lib/SIL/Utils/SILBridging.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/Basic/Assertions.h"
2323
#include "swift/SIL/SILContext.h"
2424
#include "swift/SIL/SILCloner.h"
25+
#include "swift/SIL/TypeSubstCloner.h"
2526
#include "swift/SIL/MemAccessUtils.h"
2627
#include "swift/SIL/OwnershipUtils.h"
2728
#include "swift/SIL/ParseTestSpecification.h"
@@ -620,7 +621,32 @@ class BridgedClonerImpl : public SILCloner<BridgedClonerImpl> {
620621
result = Cloned;
621622
SILCloner<BridgedClonerImpl>::postProcess(Orig, Cloned);
622623
}
624+
};
625+
626+
class BridgedTypeSubstClonerImpl : public TypeSubstCloner<BridgedTypeSubstClonerImpl> {
627+
SILInstruction *result = nullptr;
628+
629+
public:
630+
BridgedTypeSubstClonerImpl(SILFunction &from, SILFunction &toEmptyFunction, SubstitutionMap subs)
631+
: TypeSubstCloner<BridgedTypeSubstClonerImpl>(toEmptyFunction, from, subs) {}
632+
633+
SILValue getClonedValue(SILValue v) {
634+
return getMappedValue(v);
635+
}
636+
637+
SILInstruction *cloneInst(SILInstruction *inst) {
638+
result = nullptr;
639+
visit(inst);
640+
ASSERT(result && "instruction not cloned");
641+
return result;
642+
}
643+
644+
void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
645+
result = Cloned;
646+
SILClonerWithScopes<BridgedTypeSubstClonerImpl>::postProcess(Orig, Cloned);
647+
}
623648

649+
SILFunction *getOriginal() { return &Original; }
624650
};
625651

626652
} // namespace swift
@@ -687,6 +713,32 @@ void BridgedCloner::cloneFunctionBody(BridgedFunction originalFunction) const {
687713
cloner->cloneFunction(originalFunction.getFunction());
688714
}
689715

716+
BridgedTypeSubstCloner::BridgedTypeSubstCloner(BridgedFunction fromFunction, BridgedFunction toFunction,
717+
BridgedSubstitutionMap substitutions,
718+
BridgedContext context)
719+
: cloner(new BridgedTypeSubstClonerImpl(*fromFunction.getFunction(), *toFunction.getFunction(),
720+
substitutions.unbridged())) {
721+
context.context->notifyNewCloner();
722+
}
723+
724+
void BridgedTypeSubstCloner::destroy(BridgedContext context) {
725+
delete cloner;
726+
cloner = nullptr;
727+
context.context->notifyClonerDestroyed();
728+
}
729+
730+
void BridgedTypeSubstCloner::cloneFunctionBody() const {
731+
cloner->cloneFunction(cloner->getOriginal());
732+
}
733+
734+
BridgedBasicBlock BridgedTypeSubstCloner::getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const {
735+
return { cloner->getOpBasicBlock(originalBasicBlock.unbridged()) };
736+
}
737+
738+
BridgedValue BridgedTypeSubstCloner::getClonedValue(BridgedValue v) {
739+
return {cloner->getClonedValue(v.getSILValue())};
740+
}
741+
690742
//===----------------------------------------------------------------------===//
691743
// BridgedContext
692744
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)