-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Bridging: Implement bridges required for ongoing AutoDiff changes #84648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Bridging: Implement bridges required for ongoing AutoDiff changes #84648
Conversation
Tagging @JaapWijnen |
@kovdan01 Will you please summarize the list of changes in the PR description? Overall, while these are prerequisites for autodiff-related closure specialization pass, overall these bridges are not autodiff-specific. |
In #83926, part of the changes resolving #68944 is submitted. The AutoDiff closure specialization optimizer pass relies on several bridges not implemented yet. This patch introduces these missing bridges. See the list of the changes below. **AST:** * Define `.asValueDecl` on each BridgedXXXDecl type that's also a ValueDecl. * Define `.asNominalTypeDecl` on each BridgedXXXDecl type that's also a NominalTypeDecl. * Define `.asGenericContext` on each BridgedXXXDecl type that's also a GenericContext. * `class BridgedSourceFile`: - Make nullable - `func addTopLevelDecl(_ decl: BridgedDecl)` * `class BridgedFileUnit`: - `func castToSourceFile() -> BridgedNullableSourceFile` * `class BridgedDecl`: - `func getDeclContext() -> BridgedDeclContext` * `class BridgedParamDecl`: - `func cloneWithoutType() -> BridgedParamDecl` - `func setInterfaceType(_ type : BridgedASTType)` * Define `BridgedDecl.setImplicit()` instead of `BridgedParamDecl.setImplicit()` * `class BridgedGenericContext`: - `setGenericSignature(_ genSig: BridgedGenericSignature)` * Change return type of `BridgedEnumDecl.createParsed(/*...*/)` from `BridgedNominalTypeDecl` to `BridgedEnumDecl` * `class BridgedValueDecl`: - `func setAccess(_ accessLevel: swift.AccessLevel)` * `class BridgedNominalTypeDecl`: - `func addMember(_ member: BridgedDecl)` * `class BridgedGenericTypeParamDecl`: - `func createImplicit(declContext: BridgedDeclContext, name: swift.Identifier, depth: UInt, index: UInt, paramKind: swift.GenericTypeParamKind)` * `class ValueDecl`: - `var baseIdentifier: swift.Identifier` * `class NominalTypeDecl`: - `var declaredInterfaceType: Type` * `class EnumElementDecl`: - `var parameterList: BridgedParameterList` - `var nameStr: StringRef` * `struct GenericSignature`: - `var canonicalSignature: CanGenericSignature` * `struct CanGenericSignature`: - `var isEmpty: Bool` - `var genericSignature: GenericSignature` * `struct Type`: - `func mapTypeOutOfContext() -> Type` - `func getReducedType(sig: GenericSignature) -> CanonicalType` - `func GenericTypeParam_getName() -> swift.Identifier` - `func GenericTypeParam_getDepth() -> UInt` - `func GenericTypeParam_getIndex() -> UInt` - `func GenericTypeParam_getParamKind() -> swift.GenericTypeParamKind` * `struct CanonicalType`: - `func SILFunctionType_getSubstGenericSignature() -> CanGenericSignature` - `func loweredType(in function: SIL.Function) -> SIL.Type` **SIL:** * `class Argument`: - `func replaceAllUsesWith(newArg: Argument)` * `class BasicBlock`: - `func insertPhiArgument(atPosition: Int, type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument` * `struct Builder`: - `func createTuple(elements: [Value]) -> TupleInst` * `protocol Context`: - `func getTupleType(elements: [AST.Type]) -> AST.Type` - `func getTupleTypeWithLabels(elements: [AST.Type], labels: [swift.Identifier]) -> AST.Type` * `class Function`: - `var sourceFile: BridgedNullableSourceFile` - `func mapTypeIntoContext(_ type: Type) -> Type` * `class PartialApplyInst`: - `var substitutionMap: SubstitutionMap` * `class SwitchEnumInst`: - `var numCases: Int` - `public func getSuccessorForDefault() -> BasicBlock?` * `Type`: - `var category: ValueCategory` - `func getEnumCasePayload(caseIdx: Int, function: Function) -> Type` - `func mapTypeOutOfContext() -> Type` - `static func getPrimitiveType(canType: CanonicalType, silValueCategory: ValueCategory) -> Type` * `struct EnumCase`: - `let enumElementDecl: EnumElementDecl` * `struct TupleElementArray`: - `func label(at index: Int) -> swift.Identifier` * Define `enum ValueCategory` with `address` and `object` elements
10085d6
to
b3d31c7
Compare
@swift-ci please test |
@kovdan01 I'll review this tomorrow |
public class ValueDecl: Decl { | ||
final public var nameLoc: SourceLoc? { SourceLoc(bridged: bridged.Value_getNameLoc()) } | ||
final public var userFacingName: StringRef { StringRef(bridged: bridged.Value_getUserFacingName()) } | ||
final public var baseIdentifier: swift.Identifier { bridged.Value_getBaseIdentifier() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't expose the swift
namespace in APIs. Instead add a type alias:
typealias Identifier = swift.Identifier
bridged.NominalType_getValueTypeDestructor().getAs(DestructorDecl.self) | ||
} | ||
|
||
public var declaredInterfaceType : AST.`Type` { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to qualify Type
in the AST module. Just use Type
|
||
final public class EnumElementDecl: ValueDecl { | ||
public var hasAssociatedValues: Bool { bridged.EnumElementDecl_hasAssociatedValues() } | ||
public var parameterList: BridgedParameterList { bridged.EnumElementDecl_getParameterList() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't expose bridged data structures in APIs. Create a native swift ParameterList
containing a var bridged: BridgedParameterList
final public class EnumElementDecl: ValueDecl { | ||
public var hasAssociatedValues: Bool { bridged.EnumElementDecl_hasAssociatedValues() } | ||
public var parameterList: BridgedParameterList { bridged.EnumElementDecl_getParameterList() } | ||
public var nameStr: StringRef { StringRef(bridged: bridged.EnumElementDecl_getNameStr()) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just call it name
public var canonicalSignature: CanGenericSignature { CanGenericSignature(bridged: bridged.getCanonicalSignature()) } | ||
} | ||
|
||
public struct CanGenericSignature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid abbreviations. Better: CanonicalGenericSignature
We should follow the general swift API design guidelines. You can take a look at https://www.swift.org/documentation/api-design-guidelines/
#define ABSTRACT_DECL(Id, Parent) DECL(Id, Parent) | ||
#include "swift/AST/DeclNodes.def" | ||
|
||
// Define `.asValueDecl` on each BridgedXXXDecl type that's also a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for? Doing this kind of unchecked cast (for all kind of decls) looks dangerous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only handling VALUE_DECL
so it should be safe. Otherwise, the compiler should complain at static_cast
. Same for .asNominalTypeDecl
.
Apparently .asValueDecl
is not used, but assuming this is going to be used in subsequent PRs for #68944, I think it's fine to have it.
} | ||
#include "swift/AST/DeclNodes.def" | ||
|
||
// Define `.asNominalTypeDecl` on each BridgedXXXDecl type that's also a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
}); | ||
} | ||
|
||
BridgedDeclContext BridgedDecl_getDeclContext(BridgedDecl decl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you need this?
return decl.unbridged()->getDeclContext(); | ||
} | ||
|
||
void BridgedValueDecl_setAccess(BridgedValueDecl decl, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
return decl; | ||
} | ||
|
||
BridgedGenericTypeParamDecl BridgedGenericTypeParamDecl_createImplicit( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this?
void BridgedDecl_forEachDeclToHoist(BridgedDecl decl, | ||
BridgedSwiftClosure closure); | ||
|
||
SWIFT_NAME("BridgedDecl.getDeclContext(self:)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SWIFT_NAME("BridgedDecl.getDeclContext(self:)") | |
SWIFT_NAME("getter:BridgedDecl.declContext(self:)") |
In #83926, part of the changes resolving #68944 is submitted. The AutoDiff closure specialization optimizer pass relies on several AST-level bridges not implemented yet.
This patch introduces these missing bridges. See the list of the changes below.
AST:
Define
.asValueDecl
on each BridgedXXXDecl type that's also a ValueDecl.Define
.asNominalTypeDecl
on each BridgedXXXDecl type that's also a NominalTypeDecl.Define
.asGenericContext
on each BridgedXXXDecl type that's also a GenericContext.class BridgedSourceFile
:func addTopLevelDecl(_ decl: BridgedDecl)
class BridgedFileUnit
:func castToSourceFile() -> BridgedNullableSourceFile
class BridgedDecl
:func getDeclContext() -> BridgedDeclContext
class BridgedParamDecl
:func cloneWithoutType() -> BridgedParamDecl
func setInterfaceType(_ type : BridgedASTType)
Define
BridgedDecl.setImplicit()
instead ofBridgedParamDecl.setImplicit()
class BridgedGenericContext
:setGenericSignature(_ genSig: BridgedGenericSignature)
Change return type of
BridgedEnumDecl.createParsed(/*...*/)
fromBridgedNominalTypeDecl
toBridgedEnumDecl
class BridgedValueDecl
:func setAccess(_ accessLevel: swift.AccessLevel)
class BridgedNominalTypeDecl
:func addMember(_ member: BridgedDecl)
class BridgedGenericTypeParamDecl
:func createImplicit(declContext: BridgedDeclContext, name: swift.Identifier, depth: UInt, index: UInt, paramKind: swift.GenericTypeParamKind)
class ValueDecl
:var baseIdentifier: swift.Identifier
class NominalTypeDecl
:var declaredInterfaceType: Type
class EnumElementDecl
:var parameterList: BridgedParameterList
var nameStr: StringRef
struct GenericSignature
:var canonicalSignature: CanGenericSignature
struct CanGenericSignature
:var isEmpty: Bool
var genericSignature: GenericSignature
struct Type
:func mapTypeOutOfContext() -> Type
func getReducedType(sig: GenericSignature) -> CanonicalType
func GenericTypeParam_getName() -> swift.Identifier
func GenericTypeParam_getDepth() -> UInt
func GenericTypeParam_getIndex() -> UInt
func GenericTypeParam_getParamKind() -> swift.GenericTypeParamKind
struct CanonicalType
:func SILFunctionType_getSubstGenericSignature() -> CanGenericSignature
func loweredType(in function: SIL.Function) -> SIL.Type
SIL:
class Argument
:func replaceAllUsesWith(newArg: Argument)
class BasicBlock
:func insertPhiArgument(atPosition: Int, type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument
struct Builder
:func createTuple(elements: [Value]) -> TupleInst
protocol Context
:func getTupleType(elements: [AST.Type]) -> AST.Type
func getTupleTypeWithLabels(elements: [AST.Type], labels: [swift.Identifier]) -> AST.Type
class Function
:var sourceFile: BridgedNullableSourceFile
func mapTypeIntoContext(_ type: Type) -> Type
class PartialApplyInst
:var substitutionMap: SubstitutionMap
class SwitchEnumInst
:var numCases: Int
public func getSuccessorForDefault() -> BasicBlock?
Type
:var category: ValueCategory
func getEnumCasePayload(caseIdx: Int, function: Function) -> Type
func mapTypeOutOfContext() -> Type
static func getPrimitiveType(canType: CanonicalType, silValueCategory: ValueCategory) -> Type
struct EnumCase
:let enumElementDecl: EnumElementDecl
struct TupleElementArray
:func label(at index: Int) -> swift.Identifier
Define
enum ValueCategory
withaddress
andobject
elements