Skip to content

Commit 544ae88

Browse files
[swiftinterface] Improve target overwrite for the swiftinterface
In certain cases (e.g. using arm64e interface to build arm64 target), the target needs to be updated when building swiftinterface. Push the target overwrite as early as possible to swiftinterface parsing by providing a preferred target to relevant functions. In such cases, the wrong target is never observed by other functions to avoid errors like the sub-invocation was partially setup for the wrong target.
1 parent 8654db7 commit 544ae88

File tree

4 files changed

+37
-66
lines changed

4 files changed

+37
-66
lines changed

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,6 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
643643
llvm::StringSaver ArgSaver;
644644
std::vector<StringRef> GenericArgs;
645645
CompilerInvocation genericSubInvocation;
646-
llvm::Triple ParentInvocationTarget;
647646

648647
template<typename ...ArgTypes>
649648
InFlightDiagnostic diagnose(StringRef interfacePath,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/ModuleLoader.h"
1919
#include "llvm/Support/MemoryBuffer.h"
2020
#include "llvm/Support/PrefixMapper.h"
21+
#include "llvm/TargetParser/Triple.h"
2122

2223
namespace swift {
2324
class ModuleFile;
@@ -547,9 +548,10 @@ class SerializedASTFile final : public LoadedFile {
547548
};
548549

549550
/// Extract compiler arguments from an interface file buffer.
550-
bool extractCompilerFlagsFromInterface(StringRef interfacePath,
551-
StringRef buffer, llvm::StringSaver &ArgSaver,
552-
SmallVectorImpl<const char *> &SubArgs);
551+
bool extractCompilerFlagsFromInterface(
552+
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
553+
SmallVectorImpl<const char *> &SubArgs,
554+
std::optional<llvm::Triple> PreferredTarget = std::nullopt);
553555

554556
/// Extract the user module version number from an interface file.
555557
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,12 +1431,10 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
14311431
SearchPathOpts.CandidateCompiledModules);
14321432
}
14331433

1434-
static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
1435-
DiagnosticEngine &Diags,
1436-
llvm::StringSaver &ArgSaver,
1437-
SwiftInterfaceInfo &interfaceInfo,
1438-
StringRef interfacePath,
1439-
SourceLoc diagnosticLoc) {
1434+
static bool readSwiftInterfaceVersionAndArgs(
1435+
SourceManager &SM, DiagnosticEngine &Diags, llvm::StringSaver &ArgSaver,
1436+
SwiftInterfaceInfo &interfaceInfo, StringRef interfacePath,
1437+
SourceLoc diagnosticLoc, llvm::Triple preferredTarget) {
14401438
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
14411439
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
14421440
if (!FileOrError) {
@@ -1459,7 +1457,8 @@ static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
14591457
}
14601458

14611459
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver,
1462-
interfaceInfo.Arguments)) {
1460+
interfaceInfo.Arguments,
1461+
preferredTarget)) {
14631462
InterfaceSubContextDelegateImpl::diagnose(
14641463
interfacePath, diagnosticLoc, SM, &Diags,
14651464
diag::error_extracting_version_from_module_interface);
@@ -1541,9 +1540,10 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface(
15411540
llvm::BumpPtrAllocator alloc;
15421541
llvm::StringSaver ArgSaver(alloc);
15431542
SwiftInterfaceInfo InterfaceInfo;
1544-
readSwiftInterfaceVersionAndArgs(Instance.getSourceMgr(), Instance.getDiags(),
1545-
ArgSaver, InterfaceInfo, interfacePath,
1546-
SourceLoc());
1543+
readSwiftInterfaceVersionAndArgs(
1544+
Instance.getSourceMgr(), Instance.getDiags(), ArgSaver, InterfaceInfo,
1545+
interfacePath, SourceLoc(),
1546+
Instance.getInvocation().getLangOptions().Target);
15471547

15481548
auto Builder = ExplicitModuleInterfaceBuilder(
15491549
Instance, &Instance.getDiags(), Instance.getSourceMgr(),
@@ -1702,7 +1702,8 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
17021702
CompilerInvocation &subInvocation, SwiftInterfaceInfo &interfaceInfo,
17031703
StringRef interfacePath, SourceLoc diagnosticLoc) {
17041704
if (readSwiftInterfaceVersionAndArgs(SM, *Diags, ArgSaver, interfaceInfo,
1705-
interfacePath, diagnosticLoc))
1705+
interfacePath, diagnosticLoc,
1706+
subInvocation.getLangOptions().Target))
17061707
return true;
17071708

17081709
SmallString<32> ExpectedModuleName = subInvocation.getModuleName();
@@ -1779,9 +1780,6 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
17791780
GenericArgs.push_back("-application-extension");
17801781
}
17811782

1782-
// Save the parent invocation's Target Triple
1783-
ParentInvocationTarget = langOpts.Target;
1784-
17851783
// Pass down -explicit-swift-module-map-file
17861784
StringRef explicitSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
17871785
genericSubInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
@@ -2054,31 +2052,6 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
20542052
return std::make_error_code(std::errc::not_supported);
20552053
}
20562054

2057-
// If the target triple parsed from the Swift interface file differs
2058-
// only in subarchitecture from the original target triple, then
2059-
// we have loaded a Swift interface from a different-but-compatible
2060-
// architecture slice. Use the original subarchitecture.
2061-
llvm::Triple parsedTargetTriple(subInvocation.getTargetTriple());
2062-
if (parsedTargetTriple.getSubArch() != originalTargetTriple.getSubArch() &&
2063-
parsedTargetTriple.getArch() == originalTargetTriple.getArch() &&
2064-
parsedTargetTriple.getVendor() == originalTargetTriple.getVendor() &&
2065-
parsedTargetTriple.getOS() == originalTargetTriple.getOS() &&
2066-
parsedTargetTriple.getEnvironment()
2067-
== originalTargetTriple.getEnvironment()) {
2068-
parsedTargetTriple.setArchName(originalTargetTriple.getArchName());
2069-
subInvocation.setTargetTriple(parsedTargetTriple.str());
2070-
}
2071-
2072-
// Find and overload all "-target" to be parsedTargetTriple. This make sure
2073-
// the build command for the interface is the same no matter what the parent
2074-
// triple is so there is no need to spawn identical jobs.
2075-
assert(llvm::find(BuildArgs, "-target") != BuildArgs.end() &&
2076-
"missing target option");
2077-
for (unsigned idx = 0, end = BuildArgs.size(); idx < end; ++idx) {
2078-
if (BuildArgs[idx] == "-target" && ++idx < end)
2079-
BuildArgs[idx] = parsedTargetTriple.str();
2080-
}
2081-
20822055
// restore `StrictImplicitModuleContext`
20832056
subInvocation.getFrontendOptions().StrictImplicitModuleContext =
20842057
StrictImplicitModuleContext;

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,37 +1254,34 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive(
12541254
}
12551255
}
12561256

1257-
bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
1258-
StringRef buffer,
1259-
llvm::StringSaver &ArgSaver,
1260-
SmallVectorImpl<const char *> &SubArgs) {
1257+
bool swift::extractCompilerFlagsFromInterface(
1258+
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
1259+
SmallVectorImpl<const char *> &SubArgs,
1260+
std::optional<llvm::Triple> PreferredTarget) {
12611261
SmallVector<StringRef, 1> FlagMatches;
12621262
auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline);
12631263
if (!FlagRe.match(buffer, &FlagMatches))
12641264
return true;
12651265
assert(FlagMatches.size() == 2);
12661266
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
12671267

1268-
auto intFileName = llvm::sys::path::filename(interfacePath);
1269-
1270-
// Sanitize arch if the file name and the encoded flags disagree.
1271-
// It's a known issue that we are using arm64e interfaces contents for the arm64 target,
1272-
// meaning the encoded module flags are using -target arm64e-x-x. Fortunately,
1273-
// we can tell the target arch from the interface file name, so we could sanitize
1274-
// the target to use by inferring target from the file name.
1275-
StringRef arm64 = "arm64";
1276-
StringRef arm64e = "arm64e";
1277-
if (intFileName.contains(arm64) && !intFileName.contains(arm64e)) {
1278-
for (unsigned I = 1; I < SubArgs.size(); ++I) {
1279-
if (strcmp(SubArgs[I - 1], "-target") != 0) {
1280-
continue;
1281-
}
1282-
StringRef triple(SubArgs[I]);
1283-
if (triple.startswith(arm64e)) {
1284-
SubArgs[I] = ArgSaver.save((llvm::Twine(arm64) +
1285-
triple.substr(arm64e.size())).str()).data();
1286-
}
1268+
// If the target triple parsed from the Swift interface file differs
1269+
// only in subarchitecture from the compatible target triple, then
1270+
// we have loaded a Swift interface from a different-but-compatible
1271+
// architecture slice. Use the compatible subarchitecture.
1272+
for (unsigned I = 1; I < SubArgs.size(); ++I) {
1273+
if (strcmp(SubArgs[I - 1], "-target") != 0) {
1274+
continue;
12871275
}
1276+
llvm::Triple target(SubArgs[I]);
1277+
if (PreferredTarget &&
1278+
target.getSubArch() != PreferredTarget->getSubArch() &&
1279+
target.getArch() == PreferredTarget->getArch() &&
1280+
target.getVendor() == PreferredTarget->getVendor() &&
1281+
target.getOS() == PreferredTarget->getOS() &&
1282+
target.getEnvironment() == PreferredTarget->getEnvironment())
1283+
target.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
1284+
SubArgs[I] = ArgSaver.save(target.str()).data();
12881285
}
12891286

12901287
SmallVector<StringRef, 1> IgnFlagMatches;

0 commit comments

Comments
 (0)