Skip to content

Commit 9f73681

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 cdeef58 commit 9f73681

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;
@@ -552,9 +553,10 @@ class SerializedASTFile final : public LoadedFile {
552553
};
553554

554555
/// Extract compiler arguments from an interface file buffer.
555-
bool extractCompilerFlagsFromInterface(StringRef interfacePath,
556-
StringRef buffer, llvm::StringSaver &ArgSaver,
557-
SmallVectorImpl<const char *> &SubArgs);
556+
bool extractCompilerFlagsFromInterface(
557+
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
558+
SmallVectorImpl<const char *> &SubArgs,
559+
std::optional<llvm::Triple> PreferredTarget = std::nullopt);
558560

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

lib/Frontend/ModuleInterfaceLoader.cpp

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

1436-
static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
1437-
DiagnosticEngine &Diags,
1438-
llvm::StringSaver &ArgSaver,
1439-
SwiftInterfaceInfo &interfaceInfo,
1440-
StringRef interfacePath,
1441-
SourceLoc diagnosticLoc) {
1436+
static bool readSwiftInterfaceVersionAndArgs(
1437+
SourceManager &SM, DiagnosticEngine &Diags, llvm::StringSaver &ArgSaver,
1438+
SwiftInterfaceInfo &interfaceInfo, StringRef interfacePath,
1439+
SourceLoc diagnosticLoc, llvm::Triple preferredTarget) {
14421440
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
14431441
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
14441442
if (!FileOrError) {
@@ -1461,7 +1459,8 @@ static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
14611459
}
14621460

14631461
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver,
1464-
interfaceInfo.Arguments)) {
1462+
interfaceInfo.Arguments,
1463+
preferredTarget)) {
14651464
InterfaceSubContextDelegateImpl::diagnose(
14661465
interfacePath, diagnosticLoc, SM, &Diags,
14671466
diag::error_extracting_version_from_module_interface);
@@ -1543,9 +1542,10 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface(
15431542
llvm::BumpPtrAllocator alloc;
15441543
llvm::StringSaver ArgSaver(alloc);
15451544
SwiftInterfaceInfo InterfaceInfo;
1546-
readSwiftInterfaceVersionAndArgs(Instance.getSourceMgr(), Instance.getDiags(),
1547-
ArgSaver, InterfaceInfo, interfacePath,
1548-
SourceLoc());
1545+
readSwiftInterfaceVersionAndArgs(
1546+
Instance.getSourceMgr(), Instance.getDiags(), ArgSaver, InterfaceInfo,
1547+
interfacePath, SourceLoc(),
1548+
Instance.getInvocation().getLangOptions().Target);
15491549

15501550
auto Builder = ExplicitModuleInterfaceBuilder(
15511551
Instance, &Instance.getDiags(), Instance.getSourceMgr(),
@@ -1707,7 +1707,8 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
17071707
CompilerInvocation &subInvocation, SwiftInterfaceInfo &interfaceInfo,
17081708
StringRef interfacePath, SourceLoc diagnosticLoc) {
17091709
if (readSwiftInterfaceVersionAndArgs(SM, *Diags, ArgSaver, interfaceInfo,
1710-
interfacePath, diagnosticLoc))
1710+
interfacePath, diagnosticLoc,
1711+
subInvocation.getLangOptions().Target))
17111712
return true;
17121713

17131714
// Prior to Swift 5.9, swiftinterfaces were always built (accidentally) with
@@ -1795,9 +1796,6 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
17951796
GenericArgs.push_back("-application-extension");
17961797
}
17971798

1798-
// Save the parent invocation's Target Triple
1799-
ParentInvocationTarget = langOpts.Target;
1800-
18011799
// Pass down -explicit-swift-module-map-file
18021800
StringRef explicitSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
18031801
genericSubInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
@@ -2060,31 +2058,6 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
20602058
BuildArgs.insert(BuildArgs.end(), interfaceInfo.Arguments.begin(),
20612059
interfaceInfo.Arguments.end());
20622060

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

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,37 +1265,34 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive(
12651265
}
12661266
}
12671267

1268-
bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
1269-
StringRef buffer,
1270-
llvm::StringSaver &ArgSaver,
1271-
SmallVectorImpl<const char *> &SubArgs) {
1268+
bool swift::extractCompilerFlagsFromInterface(
1269+
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
1270+
SmallVectorImpl<const char *> &SubArgs,
1271+
std::optional<llvm::Triple> PreferredTarget) {
12721272
SmallVector<StringRef, 1> FlagMatches;
12731273
auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline);
12741274
if (!FlagRe.match(buffer, &FlagMatches))
12751275
return true;
12761276
assert(FlagMatches.size() == 2);
12771277
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
12781278

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

13011298
SmallVector<StringRef, 1> IgnFlagMatches;

0 commit comments

Comments
 (0)