Skip to content

Name platform-specific module files using a normalized target triple #22842

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 6 commits into from
Mar 1, 2019

Conversation

beccadax
Copy link
Contributor

Swift currently looks up platform-specific .swiftmodule, .swiftdoc, and .swiftinterface files by architecture name:

Foo.swiftmodule/
    x86_64.swiftmodule
    x86_64.swiftdoc
    arm64.swiftmodule
    arm64.swiftdoc

As part of module stability, we'd like to clean this up by using a normalized form of the target triple instead:

Foo.swiftmodule/
    x86_64-apple-ios-simulator.swiftmodule
    x86_64-apple-ios-simulator.swiftdoc
    arm64-apple-ios.swiftmodule
    arm64-apple-ios.swiftdoc

We will still support the architecture-only names for backwards compatibility, but we'll prefer the target triple names.

Normalization covers architectures ("amd64" -> "x86_64"), OSes ("macosx10.11" -> "macos"), and vendors ("unknown" -> "apple"); it also makes implicit "simulator" environments explicit. Apple platforms are the only ones that currently build for multiple architectures in practice, so normalization is only applied on those; other platforms will look for the full triple passed to the compiler (if they ever see a swiftmodule directory, which again, they won't).


This PR is best reviewed commit-by-commit. The first three commits should be NFC; if they aren't, I'd like to know, because I may have broken something subtle. There is a diagnostic I'd like to add too, but I'll do that in a separate PR.

(@aciidb0mb3r, this shouldn't break you, but you may want to be aware of it.)

Resolves rdar://problem/47094708.

Create a helper type to represent the .swiftmodule/.swiftdoc filename pair and use it in SerializedModuleLoaderBase::findModule().
…from 1-2 target-specific names to 0-N target-specific names.
@beccadax
Copy link
Contributor Author

@swift-ci please test

if (Ctx.LangOpts.Target.getArch() == llvm::Triple::ArchType::arm)
alternateArchName = "arm";
ModuleFilenamePair alternateArchFileNames(alternateArchName);
targetFileNamePairs.push_back(StringRef("arm"));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The next commit will change StringRef("arm") to ModuleFilenamePair("arm") to improve clarity. (Forgot to amend that in.)

.Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986",
"i386")
.Cases("unknown", "", "unknown")
.Default(tripleArchName);
Copy link
Contributor Author

@beccadax beccadax Feb 23, 2019

Choose a reason for hiding this comment

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

This catch-all would cover many of the cases above; I mention them separately because I expect that build system engineers and others who don't often work in the Swift compiler may need to read this code, and I want to be extra-clear about what's supported. (A few other parts of this implementation, like the use of arguably unnecessary helper functions with wordy names, are also influenced by that.)

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to add a comment about why you mention them separately so that future maintainers will know why this is the case and how to add support for additional architectures.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would you want to not have a default, and conditionalize calling this based on the OS instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This already is effectively conditionalized on Triple::isOSDarwin(). I just couldn't think of a good behavior if we didn't recognize the architecture (or, in other functions, the OS or environment)—this isn't a great place to diagnose an error, there's no sensible fixed default, and other parts of the compiler will diagnose anything the compiler is truly incapable of handling.

(I suppose one answer is that we ought to centralize our many disparate notions of OS, architecture, and environment into a single source of truth, but that's not something I want to tackle in this PR.)


static StringRef
getVendorForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
return "apple";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although we previously considered not normalizing the vendor, I discovered later that the Swift benchmark suite currently builds with an empty vendor field. I plan to fix that, but it made me rethink that decision.

Copy link
Contributor

Choose a reason for hiding this comment

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

There should probably be a comment explaining why you're doing this.

@aciidgh
Copy link
Contributor

aciidgh commented Feb 23, 2019

Thanks for notifying. I wonder if SwiftPM should also switch to this structure instead of emitting swiftmodule and swiftdoc files directly in the build dir.

@jrose-apple
Copy link
Contributor

I think SwiftPM's okay for now, but if it ever wants to support multi-arch products then it'll become interesting.

@beccadax
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 1d360222b4cc9a15083fe997d157c7a0f5c3cdd7

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 1d360222b4cc9a15083fe997d157c7a0f5c3cdd7

Copy link
Contributor

@devincoughlin devincoughlin left a comment

Choose a reason for hiding this comment

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

LGTM. You should have Jordan take a look as well. I have some minor comments inline.

.Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986",
"i386")
.Cases("unknown", "", "unknown")
.Default(tripleArchName);
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to add a comment about why you mention them separately so that future maintainers will know why this is the case and how to add support for additional architectures.


static StringRef
getVendorForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
return "apple";
Copy link
Contributor

Choose a reason for hiding this comment

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

There should probably be a comment explaining why you're doing this.

if (swift::tripleIsAnySimulator(triple))
return StringRef("simulator");
else
return None;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: LLVM style guidelines discourge using 'else' after a return. http://www.llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return

You do that here and elsewhere.

@@ -60,12 +60,12 @@
// RUN: %empty-directory(%t/Lib.swiftmodule)
// RUN: touch %t/Lib.swiftmodule/garbage.swiftmodule
// RUN: touch %t/Lib.swiftmodule/garbage.swiftinterface
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-serialized %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%target-cpu %s
// RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s -I %t 2>&1 | %FileCheck -check-prefix=WRONG-ARCH -DARCH=%module-target-triple %s
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like renaming 'ARCH' to something more specific ("MODULE_TARGET"?) would make it more clear that this is not just the architecture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would, but there's a lot that ought to be renamed in this file (WRONG-ARCH, the filename) and ParseableInterface is still under active development, so I'm worried about conflicts if I change too much.

// RUN: mkdir %t/TargetLibrary.swiftmodule
// RUN: %target-swift-frontend -emit-module -o %t/TargetLibrary.swiftmodule/%module-target-triple.swiftmodule %S/Inputs/def_func.swift -module-name TargetLibrary
// RUN: touch %t/TargetLibrary.swiftmodule/%target-cpu.swiftmodule

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like a comment describing what this test does would be helpful to future maintainers.

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

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

Looks pretty good! I agree with Devin's comments and add a few of my own, but this pretty much covers everything already.

@@ -12,6 +12,8 @@

#include "swift/Basic/Platform.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringExtras.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: alphabet

.Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986",
"i386")
.Cases("unknown", "", "unknown")
.Default(tripleArchName);
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you want to not have a default, and conditionalize calling this based on the OS instead?

return llvm::StringSwitch<StringRef>(tripleOSNameNoVersion)
.Cases("macos", "macosx", "darwin", "macos")
.Case ("ios", "ios")
.Case ("tvos", "tvos")
Copy link
Contributor

Choose a reason for hiding this comment

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

…watchOS?

else
return llvm::Triple(newArch, newVendor, newOS);
} else {
return triple;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: I'd suggest changing this one in particular to an early return.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would normally agree with you. My concern is that, if written with an if (!triple.isDarwinOS()) early return, the natural way to add a normalization for non-Darwin OSes will be to change it to is (!triple.isDarwinOS() && !triple.isMyOtherOS()) and then modify the Apple code to handle both platforms. I really want new platforms have a separate branch, but you would need to refactor the code into something like this shape to do it. So I've essentially done that refactoring up front to make it easier.

When loading a module supporting multiple targets, the module loader now looks for a file named with a normalized version of the target triple first, and only falls back to the architecture name if the normalized triple is not found.
* Adds documentation comments.
* Turns redundant cases into comments.
* Removes the else branch in a couple “if (…) return …; else return …;” patterns.
@beccadax
Copy link
Contributor Author

@swift-ci please test

@beccadax beccadax merged commit f1d1df3 into swiftlang:master Mar 1, 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.

5 participants