-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
Conversation
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.
@swift-ci please test |
if (Ctx.LangOpts.Target.getArch() == llvm::Triple::ArchType::arm) | ||
alternateArchName = "arm"; | ||
ModuleFilenamePair alternateArchFileNames(alternateArchName); | ||
targetFileNamePairs.push_back(StringRef("arm")); |
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.
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); |
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 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.)
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.
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.
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.
Would you want to not have a default, and conditionalize calling this based on the OS instead?
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 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"; |
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.
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.
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.
There should probably be a comment explaining why you're doing this.
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. |
I think SwiftPM's okay for now, but if it ever wants to support multi-arch products then it'll become interesting. |
@swift-ci please test |
Build failed |
Build failed |
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.
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); |
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.
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"; |
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.
There should probably be a comment explaining why you're doing this.
lib/Basic/Platform.cpp
Outdated
if (swift::tripleIsAnySimulator(triple)) | ||
return StringRef("simulator"); | ||
else | ||
return None; |
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.
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 |
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.
It seems like renaming 'ARCH' to something more specific ("MODULE_TARGET"?) would make it more clear that this is not just the architecture.
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.
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 | ||
|
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.
I feel like a comment describing what this test does would be helpful to future maintainers.
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.
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" |
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.
Nitpick: alphabet
.Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986", | ||
"i386") | ||
.Cases("unknown", "", "unknown") | ||
.Default(tripleArchName); |
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.
Would you want to not have a default, and conditionalize calling this based on the OS instead?
lib/Basic/Platform.cpp
Outdated
return llvm::StringSwitch<StringRef>(tripleOSNameNoVersion) | ||
.Cases("macos", "macosx", "darwin", "macos") | ||
.Case ("ios", "ios") | ||
.Case ("tvos", "tvos") |
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.
…watchOS?
lib/Basic/Platform.cpp
Outdated
else | ||
return llvm::Triple(newArch, newVendor, newOS); | ||
} else { | ||
return triple; |
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.
Nitpick: I'd suggest changing this one in particular to an early return.
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.
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.
d39d959
to
6476098
Compare
@swift-ci please test |
Swift currently looks up platform-specific .swiftmodule, .swiftdoc, and .swiftinterface files by architecture name:
As part of module stability, we'd like to clean this up by using a normalized form of the target triple instead:
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.