mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Optimizer: add TypeSubstitutionCloner and func cloneAndSpecializeFunction
Also move `func cloneFunction` from ContextCommon.swift to OptUtils.swift
This commit is contained in:
@@ -163,9 +163,3 @@ extension Instruction {
|
||||
context.notifyInstructionsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
func cloneFunction(from originalFunction: Function, toEmpty targetFunction: Function, _ context: FunctionPassContext) {
|
||||
var cloner = Cloner(cloneToEmptyFunction: targetFunction, context)
|
||||
defer { cloner.deinitialize() }
|
||||
cloner.cloneFunctionBody(from: originalFunction)
|
||||
}
|
||||
|
||||
@@ -1092,3 +1092,20 @@ func isInLoop(block startBlock: BasicBlock, _ context: FunctionPassContext) -> B
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func cloneFunction(from originalFunction: Function, toEmpty targetFunction: Function, _ context: FunctionPassContext) {
|
||||
var cloner = Cloner(cloneToEmptyFunction: targetFunction, context)
|
||||
defer { cloner.deinitialize() }
|
||||
cloner.cloneFunctionBody(from: originalFunction)
|
||||
}
|
||||
|
||||
func cloneAndSpecializeFunction(from originalFunction: Function,
|
||||
toEmpty targetFunction: Function,
|
||||
substitutions: SubstitutionMap,
|
||||
_ context: FunctionPassContext
|
||||
) {
|
||||
var cloner = TypeSubstitutionCloner(fromFunction: originalFunction, toEmptyFunction: targetFunction,
|
||||
substitutions: substitutions, context)
|
||||
defer { cloner.deinitialize() }
|
||||
cloner.cloneFunctionBody()
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SILBridging
|
||||
import AST
|
||||
|
||||
/// Clones the initializer value of a GlobalVariable.
|
||||
///
|
||||
@@ -161,3 +162,34 @@ public struct Cloner<Context: MutatingContext> {
|
||||
bridged.recordFoldedValue(origValue.bridged, mappedValue.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
public struct TypeSubstitutionCloner<Context: MutatingContext> {
|
||||
public private(set) var bridged: BridgedTypeSubstCloner
|
||||
public let context: Context
|
||||
|
||||
public init(fromFunction: Function,
|
||||
toEmptyFunction: Function,
|
||||
substitutions: SubstitutionMap, _ context: Context
|
||||
) {
|
||||
context.verifyIsTransforming(function: toEmptyFunction)
|
||||
self.bridged = BridgedTypeSubstCloner(fromFunction.bridged, toEmptyFunction.bridged,
|
||||
substitutions.bridged, context._bridged)
|
||||
self.context = context
|
||||
}
|
||||
|
||||
public mutating func deinitialize() {
|
||||
bridged.destroy(context._bridged)
|
||||
}
|
||||
|
||||
public mutating func getClonedValue(of originalValue: Value) -> Value {
|
||||
bridged.getClonedValue(originalValue.bridged).value
|
||||
}
|
||||
|
||||
public func getClonedBlock(for originalBlock: BasicBlock) -> BasicBlock {
|
||||
bridged.getClonedBasicBlock(originalBlock.bridged).block
|
||||
}
|
||||
|
||||
public func cloneFunctionBody() {
|
||||
bridged.cloneFunctionBody()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ class SILDefaultWitnessTable;
|
||||
class SILLoopInfo;
|
||||
class SILLoop;
|
||||
class BridgedClonerImpl;
|
||||
class BridgedTypeSubstClonerImpl;
|
||||
class SILDebugLocation;
|
||||
class NominalTypeDecl;
|
||||
class VarDecl;
|
||||
@@ -1541,6 +1542,17 @@ struct BridgedCloner {
|
||||
BridgedInstruction clone(BridgedInstruction inst) const;
|
||||
};
|
||||
|
||||
struct BridgedTypeSubstCloner {
|
||||
swift::BridgedTypeSubstClonerImpl * _Nonnull cloner;
|
||||
|
||||
BridgedTypeSubstCloner(BridgedFunction fromFunction, BridgedFunction toFunction,
|
||||
BridgedSubstitutionMap substitutions, BridgedContext context);
|
||||
void destroy(BridgedContext context);
|
||||
void cloneFunctionBody() const;
|
||||
SWIFT_IMPORT_UNSAFE BridgedBasicBlock getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const;
|
||||
SWIFT_IMPORT_UNSAFE BridgedValue getClonedValue(BridgedValue v);
|
||||
};
|
||||
|
||||
struct BridgedVerifier {
|
||||
typedef void (* _Nonnull VerifyFunctionFn)(BridgedContext, BridgedFunction);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include "swift/SIL/SILContext.h"
|
||||
#include "swift/SIL/SILCloner.h"
|
||||
#include "swift/SIL/TypeSubstCloner.h"
|
||||
#include "swift/SIL/MemAccessUtils.h"
|
||||
#include "swift/SIL/OwnershipUtils.h"
|
||||
#include "swift/SIL/ParseTestSpecification.h"
|
||||
@@ -620,7 +621,32 @@ public:
|
||||
result = Cloned;
|
||||
SILCloner<BridgedClonerImpl>::postProcess(Orig, Cloned);
|
||||
}
|
||||
};
|
||||
|
||||
class BridgedTypeSubstClonerImpl : public TypeSubstCloner<BridgedTypeSubstClonerImpl> {
|
||||
SILInstruction *result = nullptr;
|
||||
|
||||
public:
|
||||
BridgedTypeSubstClonerImpl(SILFunction &from, SILFunction &toEmptyFunction, SubstitutionMap subs)
|
||||
: TypeSubstCloner<BridgedTypeSubstClonerImpl>(toEmptyFunction, from, subs) {}
|
||||
|
||||
SILValue getClonedValue(SILValue v) {
|
||||
return getMappedValue(v);
|
||||
}
|
||||
|
||||
SILInstruction *cloneInst(SILInstruction *inst) {
|
||||
result = nullptr;
|
||||
visit(inst);
|
||||
ASSERT(result && "instruction not cloned");
|
||||
return result;
|
||||
}
|
||||
|
||||
void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
|
||||
result = Cloned;
|
||||
SILClonerWithScopes<BridgedTypeSubstClonerImpl>::postProcess(Orig, Cloned);
|
||||
}
|
||||
|
||||
SILFunction *getOriginal() { return &Original; }
|
||||
};
|
||||
|
||||
} // namespace swift
|
||||
@@ -687,6 +713,32 @@ void BridgedCloner::cloneFunctionBody(BridgedFunction originalFunction) const {
|
||||
cloner->cloneFunction(originalFunction.getFunction());
|
||||
}
|
||||
|
||||
BridgedTypeSubstCloner::BridgedTypeSubstCloner(BridgedFunction fromFunction, BridgedFunction toFunction,
|
||||
BridgedSubstitutionMap substitutions,
|
||||
BridgedContext context)
|
||||
: cloner(new BridgedTypeSubstClonerImpl(*fromFunction.getFunction(), *toFunction.getFunction(),
|
||||
substitutions.unbridged())) {
|
||||
context.context->notifyNewCloner();
|
||||
}
|
||||
|
||||
void BridgedTypeSubstCloner::destroy(BridgedContext context) {
|
||||
delete cloner;
|
||||
cloner = nullptr;
|
||||
context.context->notifyClonerDestroyed();
|
||||
}
|
||||
|
||||
void BridgedTypeSubstCloner::cloneFunctionBody() const {
|
||||
cloner->cloneFunction(cloner->getOriginal());
|
||||
}
|
||||
|
||||
BridgedBasicBlock BridgedTypeSubstCloner::getClonedBasicBlock(BridgedBasicBlock originalBasicBlock) const {
|
||||
return { cloner->getOpBasicBlock(originalBasicBlock.unbridged()) };
|
||||
}
|
||||
|
||||
BridgedValue BridgedTypeSubstCloner::getClonedValue(BridgedValue v) {
|
||||
return {cloner->getClonedValue(v.getSILValue())};
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BridgedContext
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user