[Autodiff] Adds logic to generate specialized functions in the closure-spec pass

This commit is contained in:
Kshitij
2024-04-03 16:00:27 -07:00
parent 15cab3a19f
commit ab751d57ab
21 changed files with 1279 additions and 268 deletions

View File

@@ -19,11 +19,12 @@ public struct Builder {
public enum InsertionPoint {
case before(Instruction)
case atEndOf(BasicBlock)
case atStartOf(Function)
case staticInitializer(GlobalVariable)
}
let insertAt: InsertionPoint
let location: Location
let location: Location?
private let notificationHandler: BridgedChangeNotificationHandler
private let notifyNewInstruction: (Instruction) -> ()
@@ -31,13 +32,15 @@ public struct Builder {
switch insertAt {
case .before(let inst):
return BridgedBuilder(insertAt: .beforeInst, insertionObj: inst.bridged.obj,
loc: location.bridged)
loc: location!.bridged)
case .atEndOf(let block):
return BridgedBuilder(insertAt: .endOfBlock, insertionObj: block.bridged.obj,
loc: location.bridged)
loc: location!.bridged)
case .atStartOf(let function):
return BridgedBuilder(insertAt: .startOfFunction, function: function.bridged)
case .staticInitializer(let global):
return BridgedBuilder(insertAt: .intoGlobal, insertionObj: global.bridged.obj,
loc: location.bridged)
loc: location!.bridged)
}
}
@@ -53,9 +56,26 @@ public struct Builder {
return instruction
}
public init(insertAt: InsertionPoint,
_ notifyNewInstruction: @escaping (Instruction) -> (),
_ notificationHandler: BridgedChangeNotificationHandler) {
guard case let .atStartOf(_) = insertAt else {
fatalError("Initializer must only be used to initialize builders that insert at the start of functions.")
}
self.insertAt = insertAt
self.location = nil;
self.notifyNewInstruction = notifyNewInstruction
self.notificationHandler = notificationHandler
}
public init(insertAt: InsertionPoint, location: Location,
_ notifyNewInstruction: @escaping (Instruction) -> (),
_ notificationHandler: BridgedChangeNotificationHandler) {
if case let .atStartOf(_) = insertAt {
fatalError("Initializer must not be used to initialize builders that insert at the start of functions.")
}
self.insertAt = insertAt
self.location = location;
self.notifyNewInstruction = notifyNewInstruction
@@ -147,6 +167,18 @@ public struct Builder {
return notifyNew(endInit.getAs(EndInitLetRefInst.self))
}
@discardableResult
public func createRetainValue(operand: Value) -> RetainValueInst {
let retain = bridged.createRetainValue(operand.bridged)
return notifyNew(retain.getAs(RetainValueInst.self))
}
@discardableResult
public func createReleaseValue(operand: Value) -> ReleaseValueInst {
let release = bridged.createReleaseValue(operand.bridged)
return notifyNew(release.getAs(ReleaseValueInst.self))
}
@discardableResult
public func createStrongRetain(operand: Value) -> StrongRetainInst {
let retain = bridged.createStrongRetain(operand.bridged)
@@ -290,6 +322,20 @@ public struct Builder {
return notifyNew(tttf.getAs(ThinToThickFunctionInst.self))
}
public func createPartialApply(
forFunction function: Value,
substitutionMap: SubstitutionMap,
capturedArgs: [Value],
calleeConvention: ArgumentConvention,
hasUnknownResultIsolation: Bool,
isOnStack: Bool
) -> PartialApplyInst {
return capturedArgs.withBridgedValues { capturedArgsRef in
let pai = bridged.createPartialApply(function.bridged, capturedArgsRef, calleeConvention.bridged, substitutionMap.bridged, hasUnknownResultIsolation, isOnStack)
return notifyNew(pai.getAs(PartialApplyInst.self))
}
}
@discardableResult
public func createSwitchEnum(enum enumVal: Value,
cases: [(Int, BasicBlock)],
@@ -434,4 +480,14 @@ public struct Builder {
let endAccess = bridged.createEndAccess(beginAccess.bridged)
return notifyNew(endAccess.getAs(EndAccessInst.self))
}
public func createConvertFunction(originalFunction: Value, resultType: Type, withoutActuallyEscaping: Bool) -> ConvertFunctionInst {
let convertFunction = bridged.createConvertFunction(originalFunction.bridged, resultType.bridged, withoutActuallyEscaping)
return notifyNew(convertFunction.getAs(ConvertFunctionInst.self))
}
public func createConvertEscapeToNoEscape(originalFunction: Value, resultType: Type, isLifetimeGuaranteed: Bool) -> ConvertEscapeToNoEscapeInst {
let convertFunction = bridged.createConvertEscapeToNoEscape(originalFunction.bridged, resultType.bridged, isLifetimeGuaranteed)
return notifyNew(convertFunction.getAs(ConvertEscapeToNoEscapeInst.self))
}
}