Skip to content

Stabilize the ABI of libswiftSwiftOnoneSupport #23518

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
merged 5 commits into from
Mar 26, 2019

Conversation

eeckstein
Copy link
Contributor

We have to make sure that the ABI of libswiftSwiftOnoneSupport does not change compared to the swift 5.0 version, i.e. excecutables, compiled with -Onone, must be linkable to older and newer versions of libswiftSwiftOnoneSupport.
This PR tries to fix this with a brute-force approach:

  • backward deployment: Hard-code the list of available symbols and, when compiling a -Onone executable, only use presepcializations from this list.

  • forward deployment: Explicitly force pre-specialization of library symbols when compiling SwiftOnoneSupport, with the help of a new @_semantics("prespecialize.") attribute. Also add a check at the end of the SIL compilation pipeline, which lets the compiler issue and error if not all required symbols are prespecialized (when compiling SwiftOnoneSupport).

This fix is not perfect but it should work for now. We might want to replace it by something nicer in the future, e.g. specialize-attributes on library functions.

rdar://problem/48924409

@eeckstein
Copy link
Contributor Author

@swift-ci test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - c0fafaff26042cb63d75fd58193aef884433b814

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - c0fafaff26042cb63d75fd58193aef884433b814

@eeckstein
Copy link
Contributor Author

@swift-ci test

1 similar comment
@eeckstein
Copy link
Contributor Author

@swift-ci test

Copy link
Contributor

@bob-wilson bob-wilson left a comment

Choose a reason for hiding this comment

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

I have a few minor comments. Beyond those, I don't see the connection between this change and adding the demangler -strip-specialization option. What's the connection there?

@@ -416,6 +416,9 @@ def import_module : Separate<["-"], "import-module">,
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print various statistics">;

def check_onone_completeness : Flag<["-"], "check-onone-completness">,
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a typo here: missing an "e" in "check-onone-completeness"

@@ -6,7 +6,7 @@ add_swift_target_library(swiftSwiftOnoneSupport ${SWIFT_STDLIB_LIBRARY_BUILD_TYP
# _explicitly_ special-cased to result in extra symbols generated by the
# optimizer, meaning TBDGen can't (and shouldn't: it has to run
# pre-optimization for performance) list them.
SWIFT_COMPILE_FLAGS "-parse-stdlib" "-Xllvm" "-sil-inline-generics=false" "-Xfrontend" "-validate-tbd-against-ir=none" "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
SWIFT_COMPILE_FLAGS "-parse-stdlib" "-Xllvm" "-sil-inline-generics=false" "-Xfrontend" "-validate-tbd-against-ir=none" "-Xfrontend" "-check-onone-completness" "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
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 use of the new option has the same typo as the definition

@@ -2287,6 +2291,69 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments(
return ReturnValueAddr;
}

/// Create a pre-specializations of the library function with
Copy link
Contributor

Choose a reason for hiding this comment

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

"pre-specializations" should be singular in this comment

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - aa7c4187fe2cdffefc26209b14f485b2e3bf431a

… compiler.

Add the list of symbols from the swift-5.0 release and only use that symbols to refer to pre-specializations in a Onone build.
This ensures that future Onone executables can link to an old swift 5.0 libswiftSwiftOnoneSupport library.

rdar://problem/48924409
…ls for OnoneSupport.

When compiling the OnoneSupport library, the compiler checks for @_semantics("prespecialize.X") attributes to pre-specialize function X.

rdar://problem/48924409
…oneSupport

It's very unlikely that those functions are really referenced by Onone executables, but we want to be ABI compatible.
Also, there is no guarantee that this version of SwiftOnoneSupport will always trigger all symbol to be pre-specialized.
If the optimizer changes, we might need to add other explicit pre-specializations of internal stdlib symbols.

rdar://problem/48924409
…l name of the origin of a specialized function.
When compiling SwiftOnoneSupport, issue errors for missing functions which are expected in the module.
This ensures ABI compatibility.

rdar://problem/48924409
@eeckstein eeckstein requested a review from bob-wilson March 25, 2019 22:57
@eeckstein
Copy link
Contributor Author

@bob-wilson Thanks, I fixed the typos. Regarding -strip-specialization: I needed that for the work on this PR. The change is in a separate commit anyway.

@eeckstein
Copy link
Contributor Author

@swift-ci test

1 similar comment
@eeckstein
Copy link
Contributor Author

@swift-ci test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - aa7c4187fe2cdffefc26209b14f485b2e3bf431a

@eeckstein
Copy link
Contributor Author

@swift-ci test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 00599ee

@rintaro
Copy link
Member

rintaro commented Mar 26, 2019

@swift-ci test macOS

@eeckstein eeckstein merged commit ba5e344 into swiftlang:master Mar 26, 2019
@eeckstein eeckstein deleted the onone-support-abi branch March 26, 2019 18:18
Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

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

This looks good, thanks for the quick fix. I only have a couple of questions to understand the new code better.

@@ -67,6 +132,14 @@ internal enum _Prespecialize {
// force specialization of append.
a.append(a[0])

#if _runtime(_ObjC)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this specific to ObjC?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we compile different code without ObjC, so the symbols in the stdlib core are different.

@@ -67,6 +132,14 @@ internal enum _Prespecialize {
// force specialization of append.
a.append(a[0])

#if _runtime(_ObjC)
// Explicitly specialize some private functions.
Copy link
Contributor

Choose a reason for hiding this comment

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

Which ones are actually private? We should definitely not be emitting public pre-specializations of any; I would suggest removing any private functions from the list and only adding them back if we know we broke something.

However looking at a few, eg the _ArrayBuffer members, I don't think they're actually private at the SIL level. _ArrayBuffer is @usableFromInline internal and it has a bunch of @inlinable internal members. This means that those members are not visible in the source language but can be linked against publicly from SIL that has been deserialized into the client binary. So they're emitted with public linkage in the stdlib.

Do we know why we need special code to ensure that they're pre-specialized here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, theses are not real "private" symbols, but @inlinable internal. Otherwise we wouldn't be able to specialize them.

We eagerly specialize a whole call tree, starting from a public function (referenced from the SwiftOnoneSupport.swift code). But because we compile the stdlib with generic inlining, it's not guaranteed that we see the complete (not-inlined) original call tree when specializing.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's still not entirely clear to me why we need two lists of symbols in two different places though. Perhaps we can just resolve this if you update the comment with your explanation, making it clear that we're not actually specializing private symbols (which would impact future library evolution).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I'll update the comment.

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.

5 participants