Skip to content

SIL: Add fields to SILFunctionType for substituted function types. #27887

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

Merged

Conversation

jckarter
Copy link
Contributor

https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

  • A substitution map, accessed by getSubstitutions(), which maps the generic signature
    of the function to its concrete implementation. This will allow, for instance, a protocol
    witness for a requirement of type <Self: P> (Self, ...) -> ... for a concrete conforming
    type Foo to express its type as <Self: P> (Self, ...) -> ... for <Foo>, preserving the relation
    to the protocol interface without relying on the pile of hacks that is the witness_method
    protocol.

  • A bool for whether the generic signature of the function is "implied" by the substitutions.
    If true, the generic signature isn't really part of the calling convention of the function.
    This will allow closure types to distinguish a closure being passed to a generic function, like
    <T, U> in (*T, *U) -> T for <Int, String>, from the concrete type (*Int, *String) -> Int,
    which will make it easier for us to differentiate the representation of those as types, for
    instance by giving them different pointer authentication discriminators to harden arm64e
    code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

  • SILFunctionType now has two accessors to get its generic signature.
    getSubstGenericSignature gets the generic signature that is used to apply its
    substitution map, if any. getInvocationGenericSignature gets the generic signature
    used to invoke the function at apply sites. These differ if the generic signature is
    implied.
  • SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
    and results of the function. They now have two APIs to get that type. getInterfaceType
    returns the unsubstituted type of the generic interface, and
    getArgumentType/getReturnValueType produce the substituted type that is used at
    apply sites.

https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
@jckarter
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 03c7919

@jckarter
Copy link
Contributor Author

@swift-ci Please test OS X

@jckarter jckarter merged commit 1a1d9e6 into swiftlang:master Oct 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants