From 0b14bdc252a3061c6b9f2553f5b6f70f1864a0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodri=CC=81guez=20Troitin=CC=83o?= Date: Mon, 21 Oct 2024 16:14:01 -0700 Subject: [PATCH] [swiftinterface] Handle target variants the same as targets Based on preliminary work from @rhow. The compilation arguments for a swiftinterface file are preprocessed to modify the `-target` argument to match the preferred target (which comes from the command line) in cases in which the sub-architecture differs, but it is compatible (for example using `arm64e` when `arm64` is being compiled), but this was not done for the target variant, which ended up with mismatches on the sub-architecture used by the target and target variant, which fails an assert in assert toolchains. --- .../Serialization/SerializedModuleLoader.h | 3 +- lib/Frontend/ModuleInterfaceLoader.cpp | 29 ++++++++++----- lib/Serialization/SerializedModuleLoader.cpp | 35 ++++++++++++------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index 9b057afda354e..e69af69fd7045 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -571,7 +571,8 @@ class SerializedASTFile final : public LoadedFile { bool extractCompilerFlagsFromInterface( StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver, SmallVectorImpl &SubArgs, - std::optional PreferredTarget = std::nullopt); + std::optional PreferredTarget = std::nullopt, + std::optional PreferredTargetVariant = std::nullopt); /// Extract the user module version number from an interface file. llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath); diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index 9a4d6b47f2311..6102b68e9637a 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -454,7 +454,7 @@ class UpToDateModuleCheker { : ctx(ctx), fs(*ctx.SourceMgr.getFileSystem()), requiresOSSAModules(requiresOSSAModules) {} - + // Check if all the provided file dependencies are up-to-date compared to // what's currently on disk. bool dependenciesAreUpToDate(StringRef modulePath, @@ -524,7 +524,7 @@ class UpToDateModuleCheker { moduleBuffer = std::move(*OutBuf); return serializedASTBufferIsUpToDate(modulePath, *moduleBuffer, rebuildInfo, AllDeps); } - + enum class DependencyStatus { UpToDate, OutOfDate, @@ -1513,7 +1513,8 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface( static bool readSwiftInterfaceVersionAndArgs( SourceManager &SM, DiagnosticEngine &Diags, llvm::StringSaver &ArgSaver, SwiftInterfaceInfo &interfaceInfo, StringRef interfacePath, - SourceLoc diagnosticLoc, llvm::Triple preferredTarget) { + SourceLoc diagnosticLoc, llvm::Triple preferredTarget, + std::optional preferredTargetVariant) { llvm::vfs::FileSystem &fs = *SM.getFileSystem(); auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath); if (!FileOrError) { @@ -1537,7 +1538,8 @@ static bool readSwiftInterfaceVersionAndArgs( if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver, interfaceInfo.Arguments, - preferredTarget)) { + preferredTarget, + preferredTargetVariant)) { InterfaceSubContextDelegateImpl::diagnose( interfacePath, diagnosticLoc, SM, &Diags, diag::error_extracting_version_from_module_interface); @@ -1592,7 +1594,7 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface( StringRef outputPath, bool ShouldSerializeDeps, ArrayRef CompiledCandidates, DependencyTracker *tracker) { - + if (!Instance.getInvocation().getIRGenOptions().AlwaysCompile) { // First, check if the expected output already exists and possibly // up-to-date w.r.t. all of the dependencies it was built with. If so, early @@ -1613,7 +1615,7 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface( return false; } } - + // Read out the compiler version. llvm::BumpPtrAllocator alloc; llvm::StringSaver ArgSaver(alloc); @@ -1621,7 +1623,8 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface( readSwiftInterfaceVersionAndArgs( Instance.getSourceMgr(), Instance.getDiags(), ArgSaver, InterfaceInfo, interfacePath, SourceLoc(), - Instance.getInvocation().getLangOptions().Target); + Instance.getInvocation().getLangOptions().Target, + Instance.getInvocation().getLangOptions().TargetVariant); auto Builder = ExplicitModuleInterfaceBuilder( Instance, &Instance.getDiags(), Instance.getSourceMgr(), @@ -1670,6 +1673,15 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface( GenericArgs.push_back(triple); } + if (LangOpts.TargetVariant.has_value()) { + genericSubInvocation.getLangOptions().TargetVariant = LangOpts.TargetVariant; + auto variantTriple = ArgSaver.save(genericSubInvocation.getLangOptions().TargetVariant->str()); + if (!variantTriple.empty()) { + GenericArgs.push_back("-target-variant"); + GenericArgs.push_back(variantTriple); + } + } + // Inherit the target SDK name and version if (!LangOpts.SDKName.empty()) { genericSubInvocation.getLangOptions().SDKName = LangOpts.SDKName; @@ -1835,7 +1847,8 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs( StringRef interfacePath, SourceLoc diagnosticLoc) { if (readSwiftInterfaceVersionAndArgs(SM, *Diags, ArgSaver, interfaceInfo, interfacePath, diagnosticLoc, - subInvocation.getLangOptions().Target)) + subInvocation.getLangOptions().Target, + subInvocation.getLangOptions().TargetVariant)) return true; // Prior to Swift 5.9, swiftinterfaces were always built (accidentally) with diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 62616dd8d4970..74b984a1d90f7 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -1379,10 +1379,19 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive( } } +static bool tripleNeedsSubarchitectureAdjustment(const llvm::Triple &lhs, const llvm::Triple &rhs) { + return (lhs.getSubArch() != rhs.getSubArch() && + lhs.getArch() == rhs.getArch() && + lhs.getVendor() == rhs.getVendor() && + lhs.getOS() == rhs.getOS() && + lhs.getEnvironment() == rhs.getEnvironment()); +} + bool swift::extractCompilerFlagsFromInterface( StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver, SmallVectorImpl &SubArgs, - std::optional PreferredTarget) { + std::optional PreferredTarget, + std::optional PreferredTargetVariant) { SmallVector FlagMatches; auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline); if (!FlagRe.match(buffer, &FlagMatches)) @@ -1395,19 +1404,19 @@ bool swift::extractCompilerFlagsFromInterface( // we have loaded a Swift interface from a different-but-compatible // architecture slice. Use the compatible subarchitecture. for (unsigned I = 1; I < SubArgs.size(); ++I) { - // FIXME: Also fix up -target-variant (rdar://135322077). - if (strcmp(SubArgs[I - 1], "-target") != 0) { - continue; + if (strcmp(SubArgs[I - 1], "-target") == 0) { + llvm::Triple target(SubArgs[I]); + if (PreferredTarget && + tripleNeedsSubarchitectureAdjustment(target, *PreferredTarget)) + target.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch()); + SubArgs[I] = ArgSaver.save(target.str()).data(); + } else if (strcmp(SubArgs[I - 1], "-target-variant") == 0) { + llvm::Triple targetVariant(SubArgs[I]); + if (PreferredTargetVariant && + tripleNeedsSubarchitectureAdjustment(targetVariant, *PreferredTargetVariant)) + targetVariant.setArch(PreferredTargetVariant->getArch(), PreferredTargetVariant->getSubArch()); + SubArgs[I] = ArgSaver.save(targetVariant.str()).data(); } - llvm::Triple target(SubArgs[I]); - if (PreferredTarget && - target.getSubArch() != PreferredTarget->getSubArch() && - target.getArch() == PreferredTarget->getArch() && - target.getVendor() == PreferredTarget->getVendor() && - target.getOS() == PreferredTarget->getOS() && - target.getEnvironment() == PreferredTarget->getEnvironment()) - target.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch()); - SubArgs[I] = ArgSaver.save(target.str()).data(); } SmallVector IgnFlagMatches;