Skip to content

Conversation

kovdan01
Copy link
Contributor

@kovdan01 kovdan01 commented Oct 2, 2025

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:

    • 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

@kovdan01 kovdan01 requested a review from asl October 2, 2025 14:49
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 2, 2025

Tagging @JaapWijnen

@asl
Copy link
Contributor

asl commented Oct 2, 2025

@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
@kovdan01 kovdan01 force-pushed the users/kovdan01/ast-bridges-for-autodiff-closure-spec branch from 10085d6 to b3d31c7 Compare October 6, 2025 14:58
@kovdan01 kovdan01 added the bridging Feature → casting: type bridging label Oct 6, 2025
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 6, 2025

@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.

@asl Thanks for suggestion, updated the comment

@kovdan01 kovdan01 marked this pull request as ready for review October 6, 2025 15:09
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 6, 2025

@swift-ci please test

@eeckstein
Copy link
Contributor

@kovdan01 I'll review this tomorrow

@eeckstein eeckstein marked this pull request as draft October 6, 2025 16:23
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() }
Copy link
Contributor

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` {
Copy link
Contributor

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() }
Copy link
Contributor

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()) }
Copy link
Contributor

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 {
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Member

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
Copy link
Contributor

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) {
Copy link
Contributor

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,
Copy link
Contributor

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(
Copy link
Contributor

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:)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SWIFT_NAME("BridgedDecl.getDeclContext(self:)")
SWIFT_NAME("getter:BridgedDecl.declContext(self:)")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bridging Feature → casting: type bridging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants