diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Driver')
71 files changed, 2993 insertions, 950 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/Compilation.cpp b/contrib/llvm-project/clang/lib/Driver/Compilation.cpp index 05ee5091396b..d33055739080 100644 --- a/contrib/llvm-project/clang/lib/Driver/Compilation.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Compilation.cpp @@ -193,6 +193,8 @@ int Compilation::ExecuteCommand(const Command &C, std::string Error; bool ExecutionFailed; int Res = C.Execute(Redirects, &Error, &ExecutionFailed); + if (PostCallback) + PostCallback(C, Res); if (!Error.empty()) { assert(Res && "Error string set with 0 result code!"); getDriver().Diag(diag::err_drv_command_failure) << Error; diff --git a/contrib/llvm-project/clang/lib/Driver/Distro.cpp b/contrib/llvm-project/clang/lib/Driver/Distro.cpp index 4d58ad1ae78c..ee4fe841e7ee 100644 --- a/contrib/llvm-project/clang/lib/Driver/Distro.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Distro.cpp @@ -15,76 +15,107 @@ #include "llvm/Support/ErrorOr.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Threading.h" using namespace clang::driver; using namespace clang; -static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS, - const llvm::Triple &TargetOrHost) { - // If we don't target Linux, no need to check the distro. This saves a few - // OS calls. - if (!TargetOrHost.isOSLinux()) +static Distro::DistroType DetectOsRelease(llvm::vfs::FileSystem &VFS) { + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = + VFS.getBufferForFile("/etc/os-release"); + if (!File) + File = VFS.getBufferForFile("/usr/lib/os-release"); + if (!File) return Distro::UnknownDistro; - // If the host is not running Linux, and we're backed by a real file system, - // no need to check the distro. This is the case where someone is - // cross-compiling from BSD or Windows to Linux, and it would be meaningless - // to try to figure out the "distro" of the non-Linux host. - IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS = - llvm::vfs::getRealFileSystem(); - llvm::Triple HostTriple(llvm::sys::getProcessTriple()); - if (!HostTriple.isOSLinux() && &VFS == RealFS.get()) - return Distro::UnknownDistro; + SmallVector<StringRef, 16> Lines; + File.get()->getBuffer().split(Lines, "\n"); + Distro::DistroType Version = Distro::UnknownDistro; + + // Obviously this can be improved a lot. + for (StringRef Line : Lines) + if (Version == Distro::UnknownDistro && Line.startswith("ID=")) + Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(3)) + .Case("fedora", Distro::Fedora) + .Case("gentoo", Distro::Gentoo) + .Case("arch", Distro::ArchLinux) + // On SLES, /etc/os-release was introduced in SLES 11. + .Case("sles", Distro::OpenSUSE) + .Case("opensuse", Distro::OpenSUSE) + .Case("exherbo", Distro::Exherbo) + .Default(Distro::UnknownDistro); + return Version; +} +static Distro::DistroType DetectLsbRelease(llvm::vfs::FileSystem &VFS) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = VFS.getBufferForFile("/etc/lsb-release"); - if (File) { - StringRef Data = File.get()->getBuffer(); - SmallVector<StringRef, 16> Lines; - Data.split(Lines, "\n"); - Distro::DistroType Version = Distro::UnknownDistro; - for (StringRef Line : Lines) - if (Version == Distro::UnknownDistro && Line.startswith("DISTRIB_CODENAME=")) - Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(17)) - .Case("hardy", Distro::UbuntuHardy) - .Case("intrepid", Distro::UbuntuIntrepid) - .Case("jaunty", Distro::UbuntuJaunty) - .Case("karmic", Distro::UbuntuKarmic) - .Case("lucid", Distro::UbuntuLucid) - .Case("maverick", Distro::UbuntuMaverick) - .Case("natty", Distro::UbuntuNatty) - .Case("oneiric", Distro::UbuntuOneiric) - .Case("precise", Distro::UbuntuPrecise) - .Case("quantal", Distro::UbuntuQuantal) - .Case("raring", Distro::UbuntuRaring) - .Case("saucy", Distro::UbuntuSaucy) - .Case("trusty", Distro::UbuntuTrusty) - .Case("utopic", Distro::UbuntuUtopic) - .Case("vivid", Distro::UbuntuVivid) - .Case("wily", Distro::UbuntuWily) - .Case("xenial", Distro::UbuntuXenial) - .Case("yakkety", Distro::UbuntuYakkety) - .Case("zesty", Distro::UbuntuZesty) - .Case("artful", Distro::UbuntuArtful) - .Case("bionic", Distro::UbuntuBionic) - .Case("cosmic", Distro::UbuntuCosmic) - .Case("disco", Distro::UbuntuDisco) - .Case("eoan", Distro::UbuntuEoan) - .Case("focal", Distro::UbuntuFocal) - .Case("groovy", Distro::UbuntuGroovy) - .Default(Distro::UnknownDistro); - if (Version != Distro::UnknownDistro) - return Version; - } + if (!File) + return Distro::UnknownDistro; + + SmallVector<StringRef, 16> Lines; + File.get()->getBuffer().split(Lines, "\n"); + Distro::DistroType Version = Distro::UnknownDistro; + + for (StringRef Line : Lines) + if (Version == Distro::UnknownDistro && + Line.startswith("DISTRIB_CODENAME=")) + Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(17)) + .Case("hardy", Distro::UbuntuHardy) + .Case("intrepid", Distro::UbuntuIntrepid) + .Case("jaunty", Distro::UbuntuJaunty) + .Case("karmic", Distro::UbuntuKarmic) + .Case("lucid", Distro::UbuntuLucid) + .Case("maverick", Distro::UbuntuMaverick) + .Case("natty", Distro::UbuntuNatty) + .Case("oneiric", Distro::UbuntuOneiric) + .Case("precise", Distro::UbuntuPrecise) + .Case("quantal", Distro::UbuntuQuantal) + .Case("raring", Distro::UbuntuRaring) + .Case("saucy", Distro::UbuntuSaucy) + .Case("trusty", Distro::UbuntuTrusty) + .Case("utopic", Distro::UbuntuUtopic) + .Case("vivid", Distro::UbuntuVivid) + .Case("wily", Distro::UbuntuWily) + .Case("xenial", Distro::UbuntuXenial) + .Case("yakkety", Distro::UbuntuYakkety) + .Case("zesty", Distro::UbuntuZesty) + .Case("artful", Distro::UbuntuArtful) + .Case("bionic", Distro::UbuntuBionic) + .Case("cosmic", Distro::UbuntuCosmic) + .Case("disco", Distro::UbuntuDisco) + .Case("eoan", Distro::UbuntuEoan) + .Case("focal", Distro::UbuntuFocal) + .Case("groovy", Distro::UbuntuGroovy) + .Case("hirsute", Distro::UbuntuHirsute) + .Default(Distro::UnknownDistro); + return Version; +} + +static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { + Distro::DistroType Version = Distro::UnknownDistro; + + // Newer freedesktop.org's compilant systemd-based systems + // should provide /etc/os-release or /usr/lib/os-release. + Version = DetectOsRelease(VFS); + if (Version != Distro::UnknownDistro) + return Version; + + // Older systems might provide /etc/lsb-release. + Version = DetectLsbRelease(VFS); + if (Version != Distro::UnknownDistro) + return Version; + + // Otherwise try some distro-specific quirks for RedHat... + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = + VFS.getBufferForFile("/etc/redhat-release"); - File = VFS.getBufferForFile("/etc/redhat-release"); if (File) { StringRef Data = File.get()->getBuffer(); if (Data.startswith("Fedora release")) return Distro::Fedora; if (Data.startswith("Red Hat Enterprise Linux") || - Data.startswith("CentOS") || - Data.startswith("Scientific Linux")) { + Data.startswith("CentOS") || Data.startswith("Scientific Linux")) { if (Data.find("release 7") != StringRef::npos) return Distro::RHEL7; else if (Data.find("release 6") != StringRef::npos) @@ -95,6 +126,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS, return Distro::UnknownDistro; } + // ...for Debian File = VFS.getBufferForFile("/etc/debian_version"); if (File) { StringRef Data = File.get()->getBuffer(); @@ -130,18 +162,20 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS, .Default(Distro::UnknownDistro); } + // ...for SUSE File = VFS.getBufferForFile("/etc/SuSE-release"); if (File) { StringRef Data = File.get()->getBuffer(); SmallVector<StringRef, 8> Lines; Data.split(Lines, "\n"); - for (const StringRef& Line : Lines) { + for (const StringRef &Line : Lines) { if (!Line.trim().startswith("VERSION")) continue; std::pair<StringRef, StringRef> SplitLine = Line.split('='); // Old versions have split VERSION and PATCHLEVEL // Newer versions use VERSION = x.y - std::pair<StringRef, StringRef> SplitVer = SplitLine.second.trim().split('.'); + std::pair<StringRef, StringRef> SplitVer = + SplitLine.second.trim().split('.'); int Version; // OpenSUSE/SLES 10 and older are not supported and not compatible @@ -153,6 +187,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS, return Distro::UnknownDistro; } + // ...and others. if (VFS.exists("/etc/exherbo-release")) return Distro::Exherbo; @@ -168,5 +203,34 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS, return Distro::UnknownDistro; } +static Distro::DistroType GetDistro(llvm::vfs::FileSystem &VFS, + const llvm::Triple &TargetOrHost) { + // If we don't target Linux, no need to check the distro. This saves a few + // OS calls. + if (!TargetOrHost.isOSLinux()) + return Distro::UnknownDistro; + + // True if we're backed by a real file system. + const bool onRealFS = (llvm::vfs::getRealFileSystem() == &VFS); + + // If the host is not running Linux, and we're backed by a real file + // system, no need to check the distro. This is the case where someone + // is cross-compiling from BSD or Windows to Linux, and it would be + // meaningless to try to figure out the "distro" of the non-Linux host. + llvm::Triple HostTriple(llvm::sys::getProcessTriple()); + if (!HostTriple.isOSLinux() && onRealFS) + return Distro::UnknownDistro; + + if (onRealFS) { + // If we're backed by a real file system, perform + // the detection only once and save the result. + static Distro::DistroType LinuxDistro = DetectDistro(VFS); + return LinuxDistro; + } + // This is mostly for passing tests which uses llvm::vfs::InMemoryFileSystem, + // which is not "real". + return DetectDistro(VFS); +} + Distro::Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost) - : DistroVal(DetectDistro(VFS, TargetOrHost)) {} + : DistroVal(GetDistro(VFS, TargetOrHost)) {} diff --git a/contrib/llvm-project/clang/lib/Driver/Driver.cpp b/contrib/llvm-project/clang/lib/Driver/Driver.cpp index ece8222dcf24..418e1d3e8ec9 100644 --- a/contrib/llvm-project/clang/lib/Driver/Driver.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Driver.cpp @@ -46,6 +46,8 @@ #include "ToolChains/VEToolchain.h" #include "ToolChains/WebAssembly.h" #include "ToolChains/XCore.h" +#include "ToolChains/ZOS.h" +#include "clang/Basic/TargetID.h" #include "clang/Basic/Version.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" @@ -70,6 +72,7 @@ #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ExitCodes.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Host.h" @@ -86,13 +89,17 @@ #include <utility> #if LLVM_ON_UNIX #include <unistd.h> // getpid -#include <sysexits.h> // EX_IOERR #endif using namespace clang::driver; using namespace clang; using namespace llvm::opt; +static llvm::Triple getHIPOffloadTargetTriple() { + static const llvm::Triple T("amdgcn-amd-amdhsa"); + return T; +} + // static std::string Driver::GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir) { @@ -121,12 +128,12 @@ std::string Driver::GetResourcesPath(StringRef BinaryPath, } Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, - DiagnosticsEngine &Diags, + DiagnosticsEngine &Diags, std::string Title, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), - DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr), + DriverTitle(Title), CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), @@ -204,6 +211,11 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings, std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = getIncludeExcludeOptionFlagMasks(IsClCompatMode); + // Make sure that Flang-only options don't pollute the Clang output + // TODO: Make sure that Clang-only options don't pollute Flang output + if (!IsFlangMode()) + ExcludedFlagsBitmask |= options::FlangOnlyOption; + unsigned MissingArgIndex, MissingArgCount; InputArgList Args = getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount, @@ -672,10 +684,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, } else if (IsHIP) { const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); const llvm::Triple &HostTriple = HostTC->getTriple(); - StringRef DeviceTripleStr; auto OFK = Action::OFK_HIP; - DeviceTripleStr = "amdgcn-amd-amdhsa"; - llvm::Triple HIPTriple(DeviceTripleStr); + llvm::Triple HIPTriple = getHIPOffloadTargetTriple(); // Use the HIP and host triples as the key into the ToolChains map, // because the device toolchain we create depends on both. auto &HIPTC = ToolChains[HIPTriple.str() + "/" + HostTriple.str()]; @@ -769,10 +779,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, /// by Dirs. /// static bool searchForFile(SmallVectorImpl<char> &FilePath, - ArrayRef<std::string> Dirs, - StringRef FileName) { + ArrayRef<StringRef> Dirs, StringRef FileName) { SmallString<128> WPath; - for (const std::string &Dir : Dirs) { + for (const StringRef &Dir : Dirs) { if (Dir.empty()) continue; WPath.clear(); @@ -797,7 +806,7 @@ bool Driver::readConfigFile(StringRef FileName) { // Read options from config file. llvm::SmallString<128> CfgFileName(FileName); llvm::sys::path::native(CfgFileName); - ConfigFile = std::string(CfgFileName.str()); + ConfigFile = std::string(CfgFileName); bool ContainErrors; CfgOptions = std::make_unique<InputArgList>( ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors)); @@ -854,9 +863,10 @@ bool Driver::loadConfigFile() { std::vector<std::string> ConfigFiles = CLOptions->getAllArgValues(options::OPT_config); if (ConfigFiles.size() > 1) { - if (!std::all_of( - ConfigFiles.begin(), ConfigFiles.end(), - [ConfigFiles](std::string s) { return s == ConfigFiles[0]; })) { + if (!std::all_of(ConfigFiles.begin(), ConfigFiles.end(), + [ConfigFiles](const std::string &s) { + return s == ConfigFiles[0]; + })) { Diag(diag::err_drv_duplicate_config); return true; } @@ -929,10 +939,7 @@ bool Driver::loadConfigFile() { } // Prepare list of directories where config file is searched for. - SmallVector<std::string, 3> CfgFileSearchDirs; - CfgFileSearchDirs.push_back(UserConfigDir); - CfgFileSearchDirs.push_back(SystemConfigDir); - CfgFileSearchDirs.push_back(Dir); + StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir}; // Try to find config file. First try file with corrected architecture. llvm::SmallString<128> CfgFilePath; @@ -963,7 +970,7 @@ bool Driver::loadConfigFile() { // --config. If it was deduced from executable name, it is not an error. if (FileSpecifiedExplicitly) { Diag(diag::err_drv_config_file_not_found) << CfgFileName; - for (const std::string &SearchDir : CfgFileSearchDirs) + for (const StringRef &SearchDir : CfgFileSearchDirs) if (!SearchDir.empty()) Diag(diag::note_drv_config_file_searched_in) << SearchDir; return true; @@ -978,17 +985,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // FIXME: Handle environment options which affect driver behavior, somewhere // (client?). GCC_EXEC_PREFIX, LPATH, CC_PRINT_OPTIONS. - if (Optional<std::string> CompilerPathValue = - llvm::sys::Process::GetEnv("COMPILER_PATH")) { - StringRef CompilerPath = *CompilerPathValue; - while (!CompilerPath.empty()) { - std::pair<StringRef, StringRef> Split = - CompilerPath.split(llvm::sys::EnvPathSeparator); - PrefixDirs.push_back(std::string(Split.first)); - CompilerPath = Split.second; - } - } - // We look for the driver mode option early, because the mode can affect // how other options are parsed. ParseDriverMode(ClangExecutable, ArgList.slice(1)); @@ -1013,13 +1009,15 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // objects than Args. This copies an Arg from one of those other InputArgLists // to the ownership of Args. auto appendOneArg = [&Args](const Arg *Opt, const Arg *BaseArg) { - unsigned Index = Args.MakeIndex(Opt->getSpelling()); - Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(), - Index, BaseArg); - Copy->getValues() = Opt->getValues(); - if (Opt->isClaimed()) - Copy->claim(); - Args.append(Copy); + unsigned Index = Args.MakeIndex(Opt->getSpelling()); + Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index), + Index, BaseArg); + Copy->getValues() = Opt->getValues(); + if (Opt->isClaimed()) + Copy->claim(); + Copy->setOwnsValues(Opt->getOwnsValues()); + Opt->setOwnsValues(false); + Args.append(Copy); }; if (HasConfigFile) @@ -1106,6 +1104,16 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { A->claim(); PrefixDirs.push_back(A->getValue(0)); } + if (Optional<std::string> CompilerPathValue = + llvm::sys::Process::GetEnv("COMPILER_PATH")) { + StringRef CompilerPath = *CompilerPathValue; + while (!CompilerPath.empty()) { + std::pair<StringRef, StringRef> Split = + CompilerPath.split(llvm::sys::EnvPathSeparator); + PrefixDirs.push_back(std::string(Split.first)); + CompilerPath = Split.second; + } + } if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) SysRoot = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ)) @@ -1567,6 +1575,11 @@ void Driver::PrintHelp(bool ShowHidden) const { if (!ShowHidden) ExcludedFlagsBitmask |= HelpHidden; + if (IsFlangMode()) + IncludedFlagsBitmask |= options::FlangOption; + else + ExcludedFlagsBitmask |= options::FlangOnlyOption; + std::string Usage = llvm::formatv("{0} [options] file...", Name).str(); getOpts().PrintHelp(llvm::outs(), Usage.c_str(), DriverTitle.c_str(), IncludedFlagsBitmask, ExcludedFlagsBitmask, @@ -1574,9 +1587,13 @@ void Driver::PrintHelp(bool ShowHidden) const { } void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { - // FIXME: The following handlers should use a callback mechanism, we don't - // know what the client would like to do. - OS << getClangFullVersion() << '\n'; + if (IsFlangMode()) { + OS << getClangToolFullVersion("flang-new") << '\n'; + } else { + // FIXME: The following handlers should use a callback mechanism, we don't + // know what the client would like to do. + OS << getClangFullVersion() << '\n'; + } const ToolChain &TC = C.getDefaultToolChain(); OS << "Target: " << TC.getTripleString() << '\n'; @@ -1614,9 +1631,14 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { std::vector<std::string> SuggestedCompletions; std::vector<std::string> Flags; - unsigned short DisableFlags = + unsigned int DisableFlags = options::NoDriverOption | options::Unsupported | options::Ignored; + // Make sure that Flang-only options don't pollute the Clang output + // TODO: Make sure that Clang-only options don't pollute Flang output + if (!IsFlangMode()) + DisableFlags |= options::FlangOnlyOption; + // Distinguish "--autocomplete=-someflag" and "--autocomplete=-someflag," // because the latter indicates that the user put space before pushing tab // which should end up in a file completion. @@ -1749,6 +1771,13 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; + // Print -B and COMPILER_PATH. + for (const std::string &Path : PrefixDirs) { + if (separator) + llvm::outs() << llvm::sys::EnvPathSeparator; + llvm::outs() << Path; + separator = true; + } for (const std::string &Path : TC.getProgramPaths()) { if (separator) llvm::outs() << llvm::sys::EnvPathSeparator; @@ -2067,7 +2096,7 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, if (IsCLMode()) { if (!llvm::sys::path::is_absolute(Twine(Value)) && - llvm::sys::Process::FindInEnvPath("LIB", Value)) + llvm::sys::Process::FindInEnvPath("LIB", Value, ';')) return true; if (Args.hasArg(options::OPT__SLASH_link) && Ty == types::TY_Object) { @@ -2384,8 +2413,20 @@ class OffloadingActionBuilder final { bool EmitLLVM = false; bool EmitAsm = false; + /// ID to identify each device compilation. For CUDA it is simply the + /// GPU arch string. For HIP it is either the GPU arch string or GPU + /// arch string plus feature strings delimited by a plus sign, e.g. + /// gfx906+xnack. + struct TargetID { + /// Target ID string which is persistent throughout the compilation. + const char *ID; + TargetID(CudaArch Arch) { ID = CudaArchToString(Arch); } + TargetID(const char *ID) : ID(ID) {} + operator const char *() { return ID; } + operator StringRef() { return StringRef(ID); } + }; /// List of GPU architectures to use in this compilation. - SmallVector<CudaArch, 4> GpuArchList; + SmallVector<TargetID, 4> GpuArchList; /// The CUDA actions for the current input. ActionList CudaDeviceActions; @@ -2421,8 +2462,9 @@ class OffloadingActionBuilder final { // If the host input is not CUDA or HIP, we don't need to bother about // this input. - if (IA->getType() != types::TY_CUDA && - IA->getType() != types::TY_HIP) { + if (!(IA->getType() == types::TY_CUDA || + IA->getType() == types::TY_HIP || + IA->getType() == types::TY_PP_HIP)) { // The builder will ignore this input. IsActive = false; return ABRT_Inactive; @@ -2450,7 +2492,7 @@ class OffloadingActionBuilder final { // If -fgpu-rdc is disabled, should not unbundle since there is no // device code to link. - if (!Relocatable) + if (UA->getType() == types::TY_Object && !Relocatable) return ABRT_Inactive; CudaDeviceActions.clear(); @@ -2468,7 +2510,7 @@ class OffloadingActionBuilder final { for (auto Arch : GpuArchList) { CudaDeviceActions.push_back(UA); - UA->registerDependentActionInfo(ToolChains[0], CudaArchToString(Arch), + UA->registerDependentActionInfo(ToolChains[0], Arch, AssociatedOffloadKind); } return ABRT_Success; @@ -2479,16 +2521,15 @@ class OffloadingActionBuilder final { void appendTopLevelActions(ActionList &AL) override { // Utility to append actions to the top level list. - auto AddTopLevel = [&](Action *A, CudaArch BoundArch) { + auto AddTopLevel = [&](Action *A, TargetID TargetID) { OffloadAction::DeviceDependences Dep; - Dep.add(*A, *ToolChains.front(), CudaArchToString(BoundArch), - AssociatedOffloadKind); + Dep.add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind); AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType())); }; // If we have a fat binary, add it to the list. if (CudaFatBinary) { - AddTopLevel(CudaFatBinary, CudaArch::UNKNOWN); + AddTopLevel(CudaFatBinary, CudaArch::UNUSED); CudaDeviceActions.clear(); CudaFatBinary = nullptr; return; @@ -2510,6 +2551,13 @@ class OffloadingActionBuilder final { CudaDeviceActions.clear(); } + /// Get canonicalized offload arch option. \returns empty StringRef if the + /// option is invalid. + virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0; + + virtual llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> + getConflictOffloadArchCombination(const std::set<StringRef> &GpuArchs) = 0; + bool initialize() override { assert(AssociatedOffloadKind == Action::OFK_Cuda || AssociatedOffloadKind == Action::OFK_HIP); @@ -2557,7 +2605,7 @@ class OffloadingActionBuilder final { EmitAsm = Args.getLastArg(options::OPT_S); // Collect all cuda_gpu_arch parameters, removing duplicates. - std::set<CudaArch> GpuArchs; + std::set<StringRef> GpuArchs; bool Error = false; for (Arg *A : Args) { if (!(A->getOption().matches(options::OPT_offload_arch_EQ) || @@ -2565,27 +2613,35 @@ class OffloadingActionBuilder final { continue; A->claim(); - const StringRef ArchStr = A->getValue(); + StringRef ArchStr = A->getValue(); if (A->getOption().matches(options::OPT_no_offload_arch_EQ) && ArchStr == "all") { GpuArchs.clear(); continue; } - CudaArch Arch = StringToCudaArch(ArchStr); - if (Arch == CudaArch::UNKNOWN) { - C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr; + ArchStr = getCanonicalOffloadArch(ArchStr); + if (ArchStr.empty()) { Error = true; } else if (A->getOption().matches(options::OPT_offload_arch_EQ)) - GpuArchs.insert(Arch); + GpuArchs.insert(ArchStr); else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) - GpuArchs.erase(Arch); + GpuArchs.erase(ArchStr); else llvm_unreachable("Unexpected option."); } + auto &&ConflictingArchs = getConflictOffloadArchCombination(GpuArchs); + if (ConflictingArchs) { + C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo) + << ConflictingArchs.getValue().first + << ConflictingArchs.getValue().second; + C.setContainsError(); + return true; + } + // Collect list of GPUs remaining in the set. - for (CudaArch Arch : GpuArchs) - GpuArchList.push_back(Arch); + for (auto Arch : GpuArchs) + GpuArchList.push_back(Arch.data()); // Default to sm_20 which is the lowest common denominator for // supported GPUs. sm_20 code should work correctly, if @@ -2607,6 +2663,21 @@ class OffloadingActionBuilder final { DefaultCudaArch = CudaArch::SM_20; } + StringRef getCanonicalOffloadArch(StringRef ArchStr) override { + CudaArch Arch = StringToCudaArch(ArchStr); + if (Arch == CudaArch::UNKNOWN) { + C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr; + return StringRef(); + } + return CudaArchToString(Arch); + } + + llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> + getConflictOffloadArchCombination( + const std::set<StringRef> &GpuArchs) override { + return llvm::None; + } + ActionBuilderReturnCode getDeviceDependences(OffloadAction::DeviceDependences &DA, phases::ID CurPhase, phases::ID FinalPhase, @@ -2666,8 +2737,7 @@ class OffloadingActionBuilder final { for (auto &A : {AssembleAction, BackendAction}) { OffloadAction::DeviceDependences DDep; - DDep.add(*A, *ToolChains.front(), CudaArchToString(GpuArchList[I]), - Action::OFK_Cuda); + DDep.add(*A, *ToolChains.front(), GpuArchList[I], Action::OFK_Cuda); DeviceActions.push_back( C.MakeAction<OffloadAction>(DDep, A->getType())); } @@ -2726,6 +2796,25 @@ class OffloadingActionBuilder final { bool canUseBundlerUnbundler() const override { return true; } + StringRef getCanonicalOffloadArch(StringRef IdStr) override { + llvm::StringMap<bool> Features; + auto ArchStr = + parseTargetID(getHIPOffloadTargetTriple(), IdStr, &Features); + if (!ArchStr) { + C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr; + C.setContainsError(); + return StringRef(); + } + auto CanId = getCanonicalTargetID(ArchStr.getValue(), Features); + return Args.MakeArgStringRef(CanId); + }; + + llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>> + getConflictOffloadArchCombination( + const std::set<StringRef> &GpuArchs) override { + return getConflictTargetIDCombination(GpuArchs); + } + ActionBuilderReturnCode getDeviceDependences(OffloadAction::DeviceDependences &DA, phases::ID CurPhase, phases::ID FinalPhase, @@ -2770,8 +2859,8 @@ class OffloadingActionBuilder final { // device arch of the next action being propagated to the above link // action. OffloadAction::DeviceDependences DDep; - DDep.add(*CudaDeviceActions[I], *ToolChains.front(), - CudaArchToString(GpuArchList[I]), AssociatedOffloadKind); + DDep.add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I], + AssociatedOffloadKind); CudaDeviceActions[I] = C.MakeAction<OffloadAction>( DDep, CudaDeviceActions[I]->getType()); } @@ -2838,7 +2927,7 @@ class OffloadingActionBuilder final { // LI contains all the inputs for the linker. OffloadAction::DeviceDependences DeviceLinkDeps; DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0], - CudaArchToString(GpuArchList[I]), AssociatedOffloadKind); + GpuArchList[I], AssociatedOffloadKind); AL.push_back(C.MakeAction<OffloadAction>(DeviceLinkDeps, DeviceLinkAction->getType())); ++I; @@ -3164,7 +3253,8 @@ public: // the input is not a bundle. if (CanUseBundler && isa<InputAction>(HostAction) && InputArg->getOption().getKind() == llvm::opt::Option::InputClass && - !types::isSrcFile(HostAction->getType())) { + (!types::isSrcFile(HostAction->getType()) || + HostAction->getType() == types::TY_PP_HIP)) { auto UnbundlingHostAction = C.MakeAction<OffloadUnbundlingJobAction>(HostAction); UnbundlingHostAction->registerDependentActionInfo( @@ -3799,9 +3889,15 @@ void Driver::BuildJobs(Compilation &C) const { } } + const llvm::Triple &RawTriple = C.getDefaultToolChain().getTriple(); + if (RawTriple.isOSAIX()) + if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) + Diag(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << RawTriple.str(); + // Collect the list of architectures. llvm::StringSet<> ArchNames; - if (C.getDefaultToolChain().getTriple().isOSBinFormatMachO()) + if (RawTriple.isOSBinFormatMachO()) for (const Arg *A : C.getArgs()) if (A->getOption().matches(options::OPT_arch)) ArchNames.insert(A->getValue()); @@ -3831,11 +3927,70 @@ void Driver::BuildJobs(Compilation &C) const { /*TargetDeviceOffloadKind*/ Action::OFK_None); } - // If we have more than one job, then disable integrated-cc1 for now. - if (C.getJobs().size() > 1) + StringRef StatReportFile; + bool PrintProcessStat = false; + if (const Arg *A = C.getArgs().getLastArg(options::OPT_fproc_stat_report_EQ)) + StatReportFile = A->getValue(); + if (C.getArgs().hasArg(options::OPT_fproc_stat_report)) + PrintProcessStat = true; + + // If we have more than one job, then disable integrated-cc1 for now. Do this + // also when we need to report process execution statistics. + if (C.getJobs().size() > 1 || !StatReportFile.empty() || PrintProcessStat) for (auto &J : C.getJobs()) J.InProcess = false; + if (!StatReportFile.empty() || PrintProcessStat) { + C.setPostCallback([=](const Command &Cmd, int Res) { + Optional<llvm::sys::ProcessStatistics> ProcStat = + Cmd.getProcessStatistics(); + if (!ProcStat) + return; + if (PrintProcessStat) { + using namespace llvm; + // Human readable output. + outs() << sys::path::filename(Cmd.getExecutable()) << ": " + << "output="; + if (Cmd.getOutputFilenames().empty()) + outs() << "\"\""; + else + outs() << Cmd.getOutputFilenames().front(); + outs() << ", total=" + << format("%.3f", ProcStat->TotalTime.count() / 1000.) << " ms" + << ", user=" + << format("%.3f", ProcStat->UserTime.count() / 1000.) << " ms" + << ", mem=" << ProcStat->PeakMemory << " Kb\n"; + } + if (!StatReportFile.empty()) { + // CSV format. + std::string Buffer; + llvm::raw_string_ostream Out(Buffer); + llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()), + /*Quote*/ true); + Out << ','; + if (Cmd.getOutputFilenames().empty()) + Out << "\"\""; + else + llvm::sys::printArg(Out, Cmd.getOutputFilenames().front(), true); + Out << ',' << ProcStat->TotalTime.count() << ',' + << ProcStat->UserTime.count() << ',' << ProcStat->PeakMemory + << '\n'; + Out.flush(); + std::error_code EC; + llvm::raw_fd_ostream OS(StatReportFile, EC, llvm::sys::fs::OF_Append); + if (EC) + return; + auto L = OS.lock(); + if (!L) { + llvm::errs() << "ERROR: Cannot lock file " << StatReportFile << ": " + << toString(L.takeError()) << "\n"; + return; + } + OS << Buffer; + } + }); + } + // If the user passed -Qunused-arguments or there were errors, don't warn // about any unused arguments. if (Diags.hasErrorOccurred() || @@ -4527,11 +4682,29 @@ static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, return Args.MakeArgString(Filename.c_str()); } +static bool HasPreprocessOutput(const Action &JA) { + if (isa<PreprocessJobAction>(JA)) + return true; + if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.getInputs()[0])) + return true; + if (isa<OffloadBundlingJobAction>(JA) && + HasPreprocessOutput(*(JA.getInputs()[0]))) + return true; + return false; +} + const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - StringRef BoundArch, bool AtTopLevel, + StringRef OrigBoundArch, bool AtTopLevel, bool MultipleArchs, StringRef OffloadingPrefix) const { + std::string BoundArch = OrigBoundArch.str(); +#if defined(_WIN32) + // BoundArch may contains ':', which is invalid in file names on Windows, + // therefore replace it with '%'. + std::replace(BoundArch.begin(), BoundArch.end(), ':', '@'); +#endif + llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) { @@ -4552,8 +4725,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, } // Default to writing to stdout? - if (AtTopLevel && !CCGenDiagnostics && isa<PreprocessJobAction>(JA)) + if (AtTopLevel && !CCGenDiagnostics && HasPreprocessOutput(JA)) { return "-"; + } // Is this the assembly listing for /FA? if (JA.getType() == types::TY_PP_Asm && @@ -4595,10 +4769,20 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, } SmallString<128> BasePath(BaseInput); + SmallString<128> ExternalPath(""); StringRef BaseName; // Dsymutil actions should use the full path. - if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA)) + if (isa<DsymutilJobAction>(JA) && C.getArgs().hasArg(options::OPT_dsym_dir)) { + ExternalPath += C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue(); + // We use posix style here because the tests (specifically + // darwin-dsymutil.c) demonstrate that posix style paths are acceptable + // even on Windows and if we don't then the similar test covering this + // fails. + llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix, + llvm::sys::path::filename(BasePath)); + BaseName = ExternalPath; + } else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA)) BaseName = BasePath; else BaseName = llvm::sys::path::filename(BasePath); @@ -4786,8 +4970,7 @@ void Driver::generatePrefixedToolNames( Names.emplace_back((DefaultTargetTriple + "-" + Tool).str()); } -static bool ScanDirForExecutable(SmallString<128> &Dir, - const std::string &Name) { +static bool ScanDirForExecutable(SmallString<128> &Dir, StringRef Name) { llvm::sys::path::append(Dir, Name); if (llvm::sys::fs::can_execute(Twine(Dir))) return true; @@ -4804,9 +4987,8 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { for (const auto &PrefixDir : PrefixDirs) { if (llvm::sys::fs::is_directory(PrefixDir)) { SmallString<128> P(PrefixDir); - for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) - if (ScanDirForExecutable(P, TargetSpecificExecutable)) - return std::string(P.str()); + if (ScanDirForExecutable(P, Name)) + return std::string(P.str()); } else { SmallString<128> P((PrefixDir + Name).str()); if (llvm::sys::fs::can_execute(Twine(P))) @@ -4931,9 +5113,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, !Target.hasEnvironment()) TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target, Args); - else if (Target.getArch() == llvm::Triple::ppc || - Target.getArch() == llvm::Triple::ppc64 || - Target.getArch() == llvm::Triple::ppc64le) + else if (Target.isPPC()) TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target, Args); else if (Target.getArch() == llvm::Triple::ve) @@ -4996,6 +5176,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Hurd: TC = std::make_unique<toolchains::Hurd>(*this, Target, Args); break; + case llvm::Triple::ZOS: + TC = std::make_unique<toolchains::ZOS>(*this, Target, Args); + break; default: // Of these targets, Hexagon is the only one that might have // an OS of Linux, in which case it got handled above already. @@ -5029,7 +5212,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, break; case llvm::Triple::riscv32: case llvm::Triple::riscv64: - TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args); + if (toolchains::RISCVToolChain::hasGCCToolchain(*this, Args)) + TC = + std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args); + else + TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args); break; case llvm::Triple::ve: TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args); diff --git a/contrib/llvm-project/clang/lib/Driver/Job.cpp b/contrib/llvm-project/clang/lib/Driver/Job.cpp index 4808a9f4628d..911fd5df3ca2 100644 --- a/contrib/llvm-project/clang/lib/Driver/Job.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Job.cpp @@ -38,12 +38,15 @@ using namespace driver; Command::Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, - ArrayRef<InputInfo> Inputs) + ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs) : Source(Source), Creator(Creator), ResponseSupport(ResponseSupport), Executable(Executable), Arguments(Arguments) { for (const auto &II : Inputs) if (II.isFilename()) InputFilenames.push_back(II.getFilename()); + for (const auto &II : Outputs) + if (II.isFilename()) + OutputFilenames.push_back(II.getFilename()); } /// Check if the compiler flag in question should be skipped when @@ -349,16 +352,17 @@ int Command::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects, auto Args = llvm::toStringRefArray(Argv.data()); return llvm::sys::ExecuteAndWait(Executable, Args, Env, Redirects, - /*secondsToWait*/ 0, - /*memoryLimit*/ 0, ErrMsg, ExecutionFailed); + /*secondsToWait*/ 0, /*memoryLimit*/ 0, + ErrMsg, ExecutionFailed, &ProcStat); } CC1Command::CC1Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, - ArrayRef<InputInfo> Inputs) - : Command(Source, Creator, ResponseSupport, Executable, Arguments, Inputs) { + ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs) + : Command(Source, Creator, ResponseSupport, Executable, Arguments, Inputs, + Outputs) { InProcess = true; } @@ -415,9 +419,10 @@ FallbackCommand::FallbackCommand(const Action &Source_, const Tool &Creator_, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs, + ArrayRef<InputInfo> Outputs, std::unique_ptr<Command> Fallback_) : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_, - Inputs), + Inputs, Outputs), Fallback(std::move(Fallback_)) {} void FallbackCommand::Print(raw_ostream &OS, const char *Terminator, @@ -456,9 +461,10 @@ int FallbackCommand::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects, ForceSuccessCommand::ForceSuccessCommand( const Action &Source_, const Tool &Creator_, ResponseFileSupport ResponseSupport, const char *Executable_, - const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs) + const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs, + ArrayRef<InputInfo> Outputs) : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_, - Inputs) {} + Inputs, Outputs) {} void ForceSuccessCommand::Print(raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo) const { diff --git a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp b/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp index bcc9ffc7ff8f..5c275353b679 100644 --- a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp +++ b/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp @@ -60,8 +60,7 @@ static const SanitizerMask AlwaysRecoverable = SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress; static const SanitizerMask NeedsLTO = SanitizerKind::CFI; static const SanitizerMask TrappingSupported = - (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | - SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion | + (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | SanitizerKind::Integer | SanitizerKind::Nullability | SanitizerKind::LocalBounds | SanitizerKind::CFI | SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast; @@ -240,6 +239,10 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D, return TrappingKinds; } +bool SanitizerArgs::needsFuzzerInterceptors() const { + return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt(); +} + bool SanitizerArgs::needsUbsanRt() const { // All of these include ubsan. if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() || @@ -491,8 +494,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; } - if ((Kinds & SanitizerKind::ShadowCallStack) && TC.getTriple().isAArch64() && - !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) && + if ((Kinds & SanitizerKind::ShadowCallStack) && + ((TC.getTriple().isAArch64() && + !llvm::AArch64::isX18ReservedByDefault(TC.getTriple())) || + TC.getTriple().isRISCV()) && !Args.hasArg(options::OPT_ffixed_x18)) { D.Diag(diag::err_drv_argument_only_allowed_with) << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack) @@ -862,6 +867,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, LinkCXXRuntimes) || D.CCCIsCXX(); + NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile, + options::OPT_fmemory_profile_EQ, + options::OPT_fno_memory_profile, false); + // Finally, initialize the set of available and recoverable sanitizers. Sanitizers.Mask |= Kinds; RecoverableSanitizers.Mask |= RecoverableKinds; @@ -922,10 +931,10 @@ static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) { void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const { - // NVPTX doesn't currently support sanitizers. Bailing out here means that - // e.g. -fsanitize=address applies only to host code, which is what we want - // for now. - if (TC.getTriple().isNVPTX()) + // NVPTX/AMDGPU doesn't currently support sanitizers. Bailing out here means + // that e.g. -fsanitize=address applies only to host code, which is what we + // want for now. + if (TC.getTriple().isNVPTX() || TC.getTriple().isAMDGPU()) return; // Translate available CoverageFeatures to corresponding clang-cc1 flags. @@ -1084,6 +1093,23 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, Sanitizers.has(SanitizerKind::Address)) CmdArgs.push_back("-fno-assume-sane-operator-new"); + // libFuzzer wants to intercept calls to certain library functions, so the + // following -fno-builtin-* flags force the compiler to emit interposable + // libcalls to these functions. Other sanitizers effectively do the same thing + // by marking all library call sites with NoBuiltin attribute in their LLVM + // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin) + if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) { + CmdArgs.push_back("-fno-builtin-bcmp"); + CmdArgs.push_back("-fno-builtin-memcmp"); + CmdArgs.push_back("-fno-builtin-strncmp"); + CmdArgs.push_back("-fno-builtin-strcmp"); + CmdArgs.push_back("-fno-builtin-strncasecmp"); + CmdArgs.push_back("-fno-builtin-strcasecmp"); + CmdArgs.push_back("-fno-builtin-strstr"); + CmdArgs.push_back("-fno-builtin-strcasestr"); + CmdArgs.push_back("-fno-builtin-memmem"); + } + // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is // enabled. if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() && diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp index b8c12fc9241a..b2ddef141a75 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp @@ -232,12 +232,17 @@ StringRef ToolChain::getDefaultUniversalArchName() const { // the same as the ones that appear in the triple. Roughly speaking, this is // an inverse of the darwin::getArchTypeForDarwinArchName() function. switch (Triple.getArch()) { - case llvm::Triple::aarch64: + case llvm::Triple::aarch64: { + if (getTriple().isArm64e()) + return "arm64e"; return "arm64"; + } case llvm::Triple::aarch64_32: return "arm64_32"; case llvm::Triple::ppc: return "ppc"; + case llvm::Triple::ppcle: + return "ppcle"; case llvm::Triple::ppc64: return "ppc64"; case llvm::Triple::ppc64le: @@ -391,6 +396,8 @@ StringRef ToolChain::getOSLibName() const { return "openbsd"; case llvm::Triple::Solaris: return "sunos"; + case llvm::Triple::AIX: + return "aix"; default: return getOS(); } @@ -546,19 +553,54 @@ std::string ToolChain::GetProgramPath(const char *Name) const { return D.GetProgramPath(Name, *this); } -std::string ToolChain::GetLinkerPath() const { +std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD, + bool *LinkerIsLLDDarwinNew) const { + if (LinkerIsLLD) + *LinkerIsLLD = false; + if (LinkerIsLLDDarwinNew) + *LinkerIsLLDDarwinNew = false; + + // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is + // considered as the linker flavor, e.g. "bfd", "gold", or "lld". const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ); StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; + // --ld-path= takes precedence over -fuse-ld= and specifies the executable + // name. -B, COMPILER_PATH and PATH and consulted if the value does not + // contain a path component separator. + if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) { + std::string Path(A->getValue()); + if (!Path.empty()) { + if (llvm::sys::path::parent_path(Path).empty()) + Path = GetProgramPath(A->getValue()); + if (llvm::sys::fs::can_execute(Path)) + return std::string(Path); + } + getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); + return GetProgramPath(getDefaultLinker()); + } + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") { + const char *DefaultLinker = getDefaultLinker(); + if (llvm::sys::path::is_absolute(DefaultLinker)) + return std::string(DefaultLinker); + else + return GetProgramPath(DefaultLinker); + } + + // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking + // for the linker flavor is brittle. In addition, prepending "ld." or "ld64." + // to a relative path is surprising. This is more complex due to priorities + // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead. + if (UseLinker.find('/') != StringRef::npos) + getDriver().Diag(diag::warn_drv_fuse_ld_path); + if (llvm::sys::path::is_absolute(UseLinker)) { // If we're passed what looks like an absolute path, don't attempt to // second-guess that. if (llvm::sys::fs::can_execute(UseLinker)) return std::string(UseLinker); - } else if (UseLinker.empty() || UseLinker == "ld") { - // If we're passed -fuse-ld= with no argument, or with the argument ld, - // then use whatever the default system linker is. - return GetProgramPath(getDefaultLinker()); } else { llvm::SmallString<8> LinkerName; if (Triple.isOSDarwin()) @@ -568,8 +610,14 @@ std::string ToolChain::GetLinkerPath() const { LinkerName.append(UseLinker); std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::can_execute(LinkerPath)) + if (llvm::sys::fs::can_execute(LinkerPath)) { + // FIXME: Remove lld.darwinnew here once it's the only MachO lld. + if (LinkerIsLLD) + *LinkerIsLLD = UseLinker == "lld" || UseLinker == "lld.darwinnew"; + if (LinkerIsLLDDarwinNew) + *LinkerIsLLDDarwinNew = UseLinker == "lld.darwinnew"; return LinkerPath; + } } if (A) @@ -631,9 +679,7 @@ bool ToolChain::isThreadModelSupported(const StringRef Model) const { return Triple.getArch() == llvm::Triple::arm || Triple.getArch() == llvm::Triple::armeb || Triple.getArch() == llvm::Triple::thumb || - Triple.getArch() == llvm::Triple::thumbeb || - Triple.getArch() == llvm::Triple::wasm32 || - Triple.getArch() == llvm::Triple::wasm64; + Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm(); } else if (Model == "posix") return true; @@ -665,6 +711,9 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, if (!Triple.isOSBinFormatMachO()) return getTripleString(); + if (Triple.isArm64e()) + return getTripleString(); + // FIXME: older versions of ld64 expect the "arm64" component in the actual // triple string and query it to determine whether an LTO file can be // handled. Remove this when we don't care any more. @@ -758,6 +807,37 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, } Triple.setArchName(ArchName + Suffix.str()); + bool isHardFloat = + (arm::getARMFloatABI(getDriver(), Triple, Args) == arm::FloatABI::Hard); + switch (Triple.getEnvironment()) { + case Triple::GNUEABI: + case Triple::GNUEABIHF: + Triple.setEnvironment(isHardFloat ? Triple::GNUEABIHF : Triple::GNUEABI); + break; + case Triple::EABI: + case Triple::EABIHF: + Triple.setEnvironment(isHardFloat ? Triple::EABIHF : Triple::EABI); + break; + case Triple::MuslEABI: + case Triple::MuslEABIHF: + Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF + : Triple::MuslEABI); + break; + default: { + arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); + if (DefaultABI != arm::FloatABI::Invalid && + isHardFloat != (DefaultABI == arm::FloatABI::Hard)) { + Arg *ABIArg = + Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, + options::OPT_mfloat_abi_EQ); + assert(ABIArg && "Non-default float abi expected to be from arg"); + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ABIArg->getAsString(Args) << Triple.getTriple(); + } + break; + } + } + return Triple.getTriple(); } } @@ -989,23 +1069,23 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { // Return sanitizers which don't require runtime support and are not // platform dependent. - SanitizerMask Res = (SanitizerKind::Undefined & ~SanitizerKind::Vptr & - ~SanitizerKind::Function) | - (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | - SanitizerKind::CFICastStrict | - SanitizerKind::FloatDivideByZero | - SanitizerKind::UnsignedIntegerOverflow | - SanitizerKind::ImplicitConversion | - SanitizerKind::Nullability | SanitizerKind::LocalBounds; + SanitizerMask Res = + (SanitizerKind::Undefined & ~SanitizerKind::Vptr & + ~SanitizerKind::Function) | + (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | + SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | + SanitizerKind::UnsignedIntegerOverflow | + SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion | + SanitizerKind::Nullability | SanitizerKind::LocalBounds; if (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64 || - getTriple().getArch() == llvm::Triple::arm || - getTriple().getArch() == llvm::Triple::wasm32 || - getTriple().getArch() == llvm::Triple::wasm64 || getTriple().isAArch64()) + getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() || + getTriple().isAArch64()) Res |= SanitizerKind::CFIICall; - if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().isAArch64()) + if (getTriple().getArch() == llvm::Triple::x86_64 || + getTriple().isAArch64(64) || getTriple().isRISCV()) Res |= SanitizerKind::ShadowCallStack; - if (getTriple().isAArch64()) + if (getTriple().isAArch64(64)) Res |= SanitizerKind::MemTag; return Res; } @@ -1163,15 +1243,18 @@ void ToolChain::TranslateXarchArgs( // // We also want to disallow any options which would alter the // driver behavior; that isn't going to work in our model. We - // use isDriverOption() as an approximation, although things - // like -O4 are going to slip through. + // use options::NoXarchOption to control this. if (!XarchArg || Index > Prev + 1) { getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) << A->getAsString(Args); return; - } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { - getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) - << A->getAsString(Args); + } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) { + auto &Diags = getDriver().getDiags(); + unsigned DiagID = + Diags.getCustomDiagID(DiagnosticsEngine::Error, + "invalid Xarch argument: '%0', not all driver " + "options can be forwared via Xarch argument"); + Diags.Report(DiagID) << A->getAsString(Args); return; } XarchArg->setBaseArg(A); diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp index ac5544eedb00..36fe578fcb3d 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp @@ -44,12 +44,6 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-a64"); } - // Accept an undefined symbol as an extern so that an error message is not - // displayed. Otherwise, undefined symbols are flagged with error messages. - // FIXME: This should be removed when the assembly generation from the - // compiler is able to write externs properly. - CmdArgs.push_back("-u"); - // Accept any mixture of instructions. // On Power for AIX and Linux, this behaviour matches that of GCC for both the // user-provided assembler source case and the compiler-produced assembler @@ -77,7 +71,7 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -98,6 +92,12 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("-bnso"); + // Add options for shared libraries. + if (Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-bM:SRE"); + CmdArgs.push_back("-bnoentry"); + } + // Specify linker output file. assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); if (Output.isFilename()) { @@ -129,16 +129,20 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, return IsArch32Bit ? "crt0.o" : "crt0_64.o"; }; - if (!Args.hasArg(options::OPT_nostdlib)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_shared)) { CmdArgs.push_back( Args.MakeArgString(ToolChain.GetFilePath(getCrt0Basename()))); + + CmdArgs.push_back(Args.MakeArgString( + ToolChain.GetFilePath(IsArch32Bit ? "crti.o" : "crti_64.o"))); } - // Collect all static constructor and destructor functions in CXX mode. This - // has to come before AddLinkerInputs as the implied option needs to precede - // any other '-bcdtors' settings or '-bnocdtors' that '-Wl' might forward. - if (D.CCCIsCXX()) - CmdArgs.push_back("-bcdtors:all:0:s"); + // Collect all static constructor and destructor functions in both C and CXX + // language link invocations. This has to come before AddLinkerInputs as the + // implied option needs to precede any other '-bcdtors' settings or + // '-bnocdtors' that '-Wl' might forward. + CmdArgs.push_back("-bcdtors:all:0:s"); // Specify linker input file(s). AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); @@ -146,18 +150,27 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Add directory to library search path. Args.AddAllArgs(CmdArgs, options::OPT_L); ToolChain.AddFilePathLibArgs(Args, CmdArgs); + ToolChain.addProfileRTLibs(Args, CmdArgs); + + if (getToolChain().ShouldLinkCXXStdlib(Args)) + getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); + // Support POSIX threads if "-pthreads" or "-pthread" is present. if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread)) CmdArgs.push_back("-lpthreads"); + if (D.CCCIsCXX()) + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lc"); } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } /// AIX - AIX tool chain which can call as(1) and ld(1) directly. @@ -203,6 +216,27 @@ void AIX::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addSystemInclude(DriverArgs, CC1Args, UP.str()); } +void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + switch (GetCXXStdlibType(Args)) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back("-lc++"); + return; + case ToolChain::CST_Libstdcxx: + llvm::report_fatal_error("linking libstdc++ unimplemented on AIX"); + } + + llvm_unreachable("Unexpected C++ library type; only libc++ is supported."); +} + +ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const { + return ToolChain::CST_Libcxx; +} + +ToolChain::RuntimeLibType AIX::GetDefaultRuntimeLibType() const { + return ToolChain::RLT_CompilerRT; +} + auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); } auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.h index 942bb3cceb8a..d4e593255736 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.h @@ -67,6 +67,13 @@ public: AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + CXXStdlibType GetDefaultCXXStdlibType() const override; + + RuntimeLibType GetDefaultRuntimeLibType() const override; + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp index 10ae76cb4161..0971a2da62a3 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -9,6 +9,7 @@ #include "AMDGPU.h" #include "CommonArgs.h" #include "InputInfo.h" +#include "clang/Basic/TargetID.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/DriverDiagnostic.h" #include "llvm/Option/ArgList.h" @@ -87,23 +88,30 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { } } -void RocmInstallationDetector::ParseHIPVersionFile(llvm::StringRef V) { +// Parse and extract version numbers from `.hipVersion`. Return `true` if +// the parsing fails. +bool RocmInstallationDetector::parseHIPVersionFile(llvm::StringRef V) { SmallVector<StringRef, 4> VersionParts; V.split(VersionParts, '\n'); - unsigned Major; - unsigned Minor; + unsigned Major = ~0U; + unsigned Minor = ~0U; for (auto Part : VersionParts) { - auto Splits = Part.split('='); - if (Splits.first == "HIP_VERSION_MAJOR") - Splits.second.getAsInteger(0, Major); - else if (Splits.first == "HIP_VERSION_MINOR") - Splits.second.getAsInteger(0, Minor); - else if (Splits.first == "HIP_VERSION_PATCH") + auto Splits = Part.rtrim().split('='); + if (Splits.first == "HIP_VERSION_MAJOR") { + if (Splits.second.getAsInteger(0, Major)) + return true; + } else if (Splits.first == "HIP_VERSION_MINOR") { + if (Splits.second.getAsInteger(0, Minor)) + return true; + } else if (Splits.first == "HIP_VERSION_PATCH") VersionPatch = Splits.second.str(); } + if (Major == ~0U || Minor == ~0U) + return true; VersionMajorMinor = llvm::VersionTuple(Major, Minor); DetectedVersion = (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str(); + return false; } // For candidate specified by --rocm-path we do not do strict check. @@ -244,9 +252,9 @@ void RocmInstallationDetector::detectDeviceLibrary() { // - ${ROCM_ROOT}/lib/* // - ${ROCM_ROOT}/lib/bitcode/* // so try to detect these layouts. - static llvm::SmallVector<const char *, 2> SubDirsList[] = { + static constexpr std::array<const char *, 2> SubDirsList[] = { {"amdgcn", "bitcode"}, - {"lib"}, + {"lib", ""}, {"lib", "bitcode"}, }; @@ -289,7 +297,8 @@ void RocmInstallationDetector::detectHIPRuntime() { continue; if (HIPVersionArg.empty() && VersionFile) - ParseHIPVersionFile((*VersionFile)->getBuffer()); + if (parseHIPVersionFile((*VersionFile)->getBuffer())) + continue; HasHIPRuntime = true; return; @@ -355,27 +364,40 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-shared"); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Linker), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); } void amdgpu::getAMDGPUTargetFeatures(const Driver &D, + const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector<StringRef> &Features) { - if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) - D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args); + // Add target ID features to -target-feature options. No diagnostics should + // be emitted here since invalid target ID is diagnosed at other places. + StringRef TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ); + if (!TargetID.empty()) { + llvm::StringMap<bool> FeatureMap; + auto OptionalGpuArch = parseTargetID(Triple, TargetID, &FeatureMap); + if (OptionalGpuArch) { + StringRef GpuArch = OptionalGpuArch.getValue(); + // Iterate through all possible target ID features for the given GPU. + // If it is mapped to true, add +feature. + // If it is mapped to false, add -feature. + // If it is not in the map (default), do not add it + for (auto &&Feature : getAllPossibleTargetIDFeatures(Triple, GpuArch)) { + auto Pos = FeatureMap.find(Feature); + if (Pos == FeatureMap.end()) + continue; + Features.push_back(Args.MakeArgStringRef( + (Twine(Pos->second ? "+" : "-") + Feature).str())); + } + } + } - if (Args.getLastArg(options::OPT_mwavefrontsize64)) { - Features.push_back("-wavefrontsize16"); - Features.push_back("-wavefrontsize32"); + if (Args.hasFlag(options::OPT_mwavefrontsize64, + options::OPT_mno_wavefrontsize64, false)) Features.push_back("+wavefrontsize64"); - } - if (Args.getLastArg(options::OPT_mno_wavefrontsize64)) { - Features.push_back("-wavefrontsize16"); - Features.push_back("+wavefrontsize32"); - Features.push_back("-wavefrontsize64"); - } handleTargetFeaturesGroup( Args, Features, options::OPT_m_amdgpu_Features_Group); @@ -385,8 +407,14 @@ void amdgpu::getAMDGPUTargetFeatures(const Driver &D, AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args), - OptionsDefault({{options::OPT_O, "3"}, - {options::OPT_cl_std_EQ, "CL1.2"}}) {} + OptionsDefault( + {{options::OPT_O, "3"}, {options::OPT_cl_std_EQ, "CL1.2"}}) { + // Check code object version options. Emit warnings for legacy options + // and errors for the last invalid code object version options. + // It is done here to avoid repeated warning or error messages for + // each tool invocation. + (void)getOrCheckAMDGPUCodeObjectVersion(D, Args, /*Diagnose=*/true); +} Tool *AMDGPUToolChain::buildLinker() const { return new tools::amdgpu::Linker(*this); @@ -399,16 +427,20 @@ AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, DerivedArgList *DAL = Generic_ELF::TranslateArgs(Args, BoundArch, DeviceOffloadKind); - // Do nothing if not OpenCL (-x cl) - if (!Args.getLastArgValue(options::OPT_x).equals("cl")) - return DAL; + const OptTable &Opts = getDriver().getOpts(); if (!DAL) DAL = new DerivedArgList(Args.getBaseArgs()); - for (auto *A : Args) - DAL->append(A); - const OptTable &Opts = getDriver().getOpts(); + for (Arg *A : Args) { + if (!shouldSkipArgument(A)) + DAL->append(A); + } + + checkTargetID(*DAL); + + if (!Args.getLastArgValue(options::OPT_x).equals("cl")) + return DAL; // Phase 1 (.cl -> .bc) if (Args.hasArg(options::OPT_c) && Args.hasArg(options::OPT_emit_llvm)) { @@ -453,7 +485,8 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( if (JA.getOffloadingDeviceKind() == Action::OFK_HIP || JA.getOffloadingDeviceKind() == Action::OFK_Cuda) { - auto Kind = llvm::AMDGPU::parseArchAMDGCN(JA.getOffloadingArch()); + auto Arch = getProcessorFromTargetID(getTriple(), JA.getOffloadingArch()); + auto Kind = llvm::AMDGPU::parseArchAMDGCN(Arch); if (FPType && FPType == &llvm::APFloat::IEEEsingle() && DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, options::OPT_fno_cuda_flush_denormals_to_zero, @@ -463,7 +496,7 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( return llvm::DenormalMode::getIEEE(); } - const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + const StringRef GpuArch = getGPUArch(DriverArgs); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); // TODO: There are way too many flags that change this. Do we need to check @@ -480,7 +513,7 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs, llvm::AMDGPU::GPUKind Kind) { const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind); - static bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32); + bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32); return !HasWave32 || DriverArgs.hasFlag( options::OPT_mwavefrontsize64, options::OPT_mno_wavefrontsize64, false); @@ -508,6 +541,25 @@ void AMDGPUToolChain::addClangTargetOptions( } } +StringRef +AMDGPUToolChain::getGPUArch(const llvm::opt::ArgList &DriverArgs) const { + return getProcessorFromTargetID( + getTriple(), DriverArgs.getLastArgValue(options::OPT_mcpu_EQ)); +} + +void AMDGPUToolChain::checkTargetID( + const llvm::opt::ArgList &DriverArgs) const { + StringRef TargetID = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + if (TargetID.empty()) + return; + + llvm::StringMap<bool> FeatureMap; + auto OptionalGpuArch = parseTargetID(getTriple(), TargetID, &FeatureMap); + if (!OptionalGpuArch) { + getDriver().Diag(clang::diag::err_drv_bad_target_id) << TargetID; + } +} + void ROCMToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadingKind) const { @@ -529,7 +581,7 @@ void ROCMToolChain::addClangTargetOptions( } // Get the device name and canonicalize it - const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + const StringRef GpuArch = getGPUArch(DriverArgs); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); @@ -595,3 +647,10 @@ void RocmInstallationDetector::addCommonBitcodeLibCC1Args( CC1Args.push_back(LinkBitcodeFlag); CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile)); } + +bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const { + Option O = A->getOption(); + if (O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) + return true; + return false; +} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.h index 5d44faf28b05..55ef6e01967e 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.h @@ -11,6 +11,7 @@ #include "Gnu.h" #include "ROCm.h" +#include "clang/Basic/TargetID.h" #include "clang/Driver/Options.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -36,7 +37,8 @@ public: const char *LinkingOutput) const override; }; -void getAMDGPUTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, +void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, std::vector<StringRef> &Features); } // end namespace amdgpu @@ -87,6 +89,16 @@ public: /// Needed for translating LTO options. const char *getDefaultLinker() const override { return "ld.lld"; } + + /// Should skip argument. + bool shouldSkipArgument(const llvm::opt::Arg *Arg) const; + +protected: + /// Check and diagnose invalid target ID specified by -mcpu. + void checkTargetID(const llvm::opt::ArgList &DriverArgs) const; + + /// Get GPU arch from -mcpu without checking. + StringRef getGPUArch(const llvm::opt::ArgList &DriverArgs) const; }; class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AVR.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AVR.cpp index 092bade53c63..ae56b7b5249e 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AVR.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AVR.cpp @@ -13,6 +13,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/SubtargetFeature.h" @@ -27,13 +28,272 @@ using namespace llvm::opt; namespace { -// TODO: Consider merging this into the AVR device table -// array in Targets/AVR.cpp. -llvm::Optional<StringRef> GetMcuFamilyName(StringRef MCU) { - return llvm::StringSwitch<llvm::Optional<StringRef>>(MCU) - .Case("atmega328", Optional<StringRef>("avr5")) - .Case("atmega328p", Optional<StringRef>("avr5")) - .Default(Optional<StringRef>()); +const struct { + StringRef Name; + std::string SubPath; + StringRef Family; +} MCUInfo[] = { + {"at90s1200", "", "avr1"}, + {"attiny11", "", "avr1"}, + {"attiny12", "", "avr1"}, + {"attiny15", "", "avr1"}, + {"attiny28", "", "avr1"}, + {"at90s2313", "tiny-stack", "avr2"}, + {"at90s2323", "tiny-stack", "avr2"}, + {"at90s2333", "tiny-stack", "avr2"}, + {"at90s2343", "tiny-stack", "avr2"}, + {"at90s4433", "tiny-stack", "avr2"}, + {"attiny22", "tiny-stack", "avr2"}, + {"attiny26", "tiny-stack", "avr2"}, + {"at90s4414", "", "avr2"}, + {"at90s4434", "", "avr2"}, + {"at90s8515", "", "avr2"}, + {"at90c8534", "", "avr2"}, + {"at90s8535", "", "avr2"}, + {"attiny13", "avr25/tiny-stack", "avr25"}, + {"attiny13a", "avr25/tiny-stack", "avr25"}, + {"attiny2313", "avr25/tiny-stack", "avr25"}, + {"attiny2313a", "avr25/tiny-stack", "avr25"}, + {"attiny24", "avr25/tiny-stack", "avr25"}, + {"attiny24a", "avr25/tiny-stack", "avr25"}, + {"attiny25", "avr25/tiny-stack", "avr25"}, + {"attiny261", "avr25/tiny-stack", "avr25"}, + {"attiny261a", "avr25/tiny-stack", "avr25"}, + {"at86rf401", "avr25", "avr25"}, + {"ata5272", "avr25", "avr25"}, + {"attiny4313", "avr25", "avr25"}, + {"attiny44", "avr25", "avr25"}, + {"attiny44a", "avr25", "avr25"}, + {"attiny84", "avr25", "avr25"}, + {"attiny84a", "avr25", "avr25"}, + {"attiny45", "avr25", "avr25"}, + {"attiny85", "avr25", "avr25"}, + {"attiny441", "avr25", "avr25"}, + {"attiny461", "avr25", "avr25"}, + {"attiny461a", "avr25", "avr25"}, + {"attiny841", "avr25", "avr25"}, + {"attiny861", "avr25", "avr25"}, + {"attiny861a", "avr25", "avr25"}, + {"attiny87", "avr25", "avr25"}, + {"attiny43u", "avr25", "avr25"}, + {"attiny48", "avr25", "avr25"}, + {"attiny88", "avr25", "avr25"}, + {"attiny828", "avr25", "avr25"}, + {"at43usb355", "avr3", "avr3"}, + {"at76c711", "avr3", "avr3"}, + {"atmega103", "avr31", "avr31"}, + {"at43usb320", "avr31", "avr31"}, + {"attiny167", "avr35", "avr35"}, + {"at90usb82", "avr35", "avr35"}, + {"at90usb162", "avr35", "avr35"}, + {"ata5505", "avr35", "avr35"}, + {"atmega8u2", "avr35", "avr35"}, + {"atmega16u2", "avr35", "avr35"}, + {"atmega32u2", "avr35", "avr35"}, + {"attiny1634", "avr35", "avr35"}, + {"atmega8", "avr4", "avr4"}, + {"ata6289", "avr4", "avr4"}, + {"atmega8a", "avr4", "avr4"}, + {"ata6285", "avr4", "avr4"}, + {"ata6286", "avr4", "avr4"}, + {"atmega48", "avr4", "avr4"}, + {"atmega48a", "avr4", "avr4"}, + {"atmega48pa", "avr4", "avr4"}, + {"atmega48pb", "avr4", "avr4"}, + {"atmega48p", "avr4", "avr4"}, + {"atmega88", "avr4", "avr4"}, + {"atmega88a", "avr4", "avr4"}, + {"atmega88p", "avr4", "avr4"}, + {"atmega88pa", "avr4", "avr4"}, + {"atmega88pb", "avr4", "avr4"}, + {"atmega8515", "avr4", "avr4"}, + {"atmega8535", "avr4", "avr4"}, + {"atmega8hva", "avr4", "avr4"}, + {"at90pwm1", "avr4", "avr4"}, + {"at90pwm2", "avr4", "avr4"}, + {"at90pwm2b", "avr4", "avr4"}, + {"at90pwm3", "avr4", "avr4"}, + {"at90pwm3b", "avr4", "avr4"}, + {"at90pwm81", "avr4", "avr4"}, + {"ata5790", "avr5", "avr5"}, + {"ata5795", "avr5", "avr5"}, + {"atmega16", "avr5", "avr5"}, + {"atmega16a", "avr5", "avr5"}, + {"atmega161", "avr5", "avr5"}, + {"atmega162", "avr5", "avr5"}, + {"atmega163", "avr5", "avr5"}, + {"atmega164a", "avr5", "avr5"}, + {"atmega164p", "avr5", "avr5"}, + {"atmega164pa", "avr5", "avr5"}, + {"atmega165", "avr5", "avr5"}, + {"atmega165a", "avr5", "avr5"}, + {"atmega165p", "avr5", "avr5"}, + {"atmega165pa", "avr5", "avr5"}, + {"atmega168", "avr5", "avr5"}, + {"atmega168a", "avr5", "avr5"}, + {"atmega168p", "avr5", "avr5"}, + {"atmega168pa", "avr5", "avr5"}, + {"atmega168pb", "avr5", "avr5"}, + {"atmega169", "avr5", "avr5"}, + {"atmega169a", "avr5", "avr5"}, + {"atmega169p", "avr5", "avr5"}, + {"atmega169pa", "avr5", "avr5"}, + {"atmega32", "avr5", "avr5"}, + {"atmega32a", "avr5", "avr5"}, + {"atmega323", "avr5", "avr5"}, + {"atmega324a", "avr5", "avr5"}, + {"atmega324p", "avr5", "avr5"}, + {"atmega324pa", "avr5", "avr5"}, + {"atmega325", "avr5", "avr5"}, + {"atmega325a", "avr5", "avr5"}, + {"atmega325p", "avr5", "avr5"}, + {"atmega325pa", "avr5", "avr5"}, + {"atmega3250", "avr5", "avr5"}, + {"atmega3250a", "avr5", "avr5"}, + {"atmega3250p", "avr5", "avr5"}, + {"atmega3250pa", "avr5", "avr5"}, + {"atmega328", "avr5", "avr5"}, + {"atmega328p", "avr5", "avr5"}, + {"atmega329", "avr5", "avr5"}, + {"atmega329a", "avr5", "avr5"}, + {"atmega329p", "avr5", "avr5"}, + {"atmega329pa", "avr5", "avr5"}, + {"atmega3290", "avr5", "avr5"}, + {"atmega3290a", "avr5", "avr5"}, + {"atmega3290p", "avr5", "avr5"}, + {"atmega3290pa", "avr5", "avr5"}, + {"atmega406", "avr5", "avr5"}, + {"atmega64", "avr5", "avr5"}, + {"atmega64a", "avr5", "avr5"}, + {"atmega640", "avr5", "avr5"}, + {"atmega644", "avr5", "avr5"}, + {"atmega644a", "avr5", "avr5"}, + {"atmega644p", "avr5", "avr5"}, + {"atmega644pa", "avr5", "avr5"}, + {"atmega645", "avr5", "avr5"}, + {"atmega645a", "avr5", "avr5"}, + {"atmega645p", "avr5", "avr5"}, + {"atmega649", "avr5", "avr5"}, + {"atmega649a", "avr5", "avr5"}, + {"atmega649p", "avr5", "avr5"}, + {"atmega6450", "avr5", "avr5"}, + {"atmega6450a", "avr5", "avr5"}, + {"atmega6450p", "avr5", "avr5"}, + {"atmega6490", "avr5", "avr5"}, + {"atmega6490a", "avr5", "avr5"}, + {"atmega6490p", "avr5", "avr5"}, + {"atmega64rfr2", "avr5", "avr5"}, + {"atmega644rfr2", "avr5", "avr5"}, + {"atmega16hva", "avr5", "avr5"}, + {"atmega16hva2", "avr5", "avr5"}, + {"atmega16hvb", "avr5", "avr5"}, + {"atmega16hvbrevb", "avr5", "avr5"}, + {"atmega32hvb", "avr5", "avr5"}, + {"atmega32hvbrevb", "avr5", "avr5"}, + {"atmega64hve", "avr5", "avr5"}, + {"at90can32", "avr5", "avr5"}, + {"at90can64", "avr5", "avr5"}, + {"at90pwm161", "avr5", "avr5"}, + {"at90pwm216", "avr5", "avr5"}, + {"at90pwm316", "avr5", "avr5"}, + {"atmega32c1", "avr5", "avr5"}, + {"atmega64c1", "avr5", "avr5"}, + {"atmega16m1", "avr5", "avr5"}, + {"atmega32m1", "avr5", "avr5"}, + {"atmega64m1", "avr5", "avr5"}, + {"atmega16u4", "avr5", "avr5"}, + {"atmega32u4", "avr5", "avr5"}, + {"atmega32u6", "avr5", "avr5"}, + {"at90usb646", "avr5", "avr5"}, + {"at90usb647", "avr5", "avr5"}, + {"at90scr100", "avr5", "avr5"}, + {"at94k", "avr5", "avr5"}, + {"m3000", "avr5", "avr5"}, + {"atmega128", "avr51", "avr51"}, + {"atmega128a", "avr51", "avr51"}, + {"atmega1280", "avr51", "avr51"}, + {"atmega1281", "avr51", "avr51"}, + {"atmega1284", "avr51", "avr51"}, + {"atmega1284p", "avr51", "avr51"}, + {"atmega128rfa1", "avr51", "avr51"}, + {"atmega128rfr2", "avr51", "avr51"}, + {"atmega1284rfr2", "avr51", "avr51"}, + {"at90can128", "avr51", "avr51"}, + {"at90usb1286", "avr51", "avr51"}, + {"at90usb1287", "avr51", "avr51"}, + {"atmega2560", "avr6", "avr6"}, + {"atmega2561", "avr6", "avr6"}, + {"atmega256rfr2", "avr6", "avr6"}, + {"atmega2564rfr2", "avr6", "avr6"}, + {"attiny4", "avrtiny", "avrtiny"}, + {"attiny5", "avrtiny", "avrtiny"}, + {"attiny9", "avrtiny", "avrtiny"}, + {"attiny10", "avrtiny", "avrtiny"}, + {"attiny20", "avrtiny", "avrtiny"}, + {"attiny40", "avrtiny", "avrtiny"}, + {"atxmega16a4", "avrxmega2", "avrxmega2"}, + {"atxmega16a4u", "avrxmega2", "avrxmega2"}, + {"atxmega16c4", "avrxmega2", "avrxmega2"}, + {"atxmega16d4", "avrxmega2", "avrxmega2"}, + {"atxmega32a4", "avrxmega2", "avrxmega2"}, + {"atxmega32a4u", "avrxmega2", "avrxmega2"}, + {"atxmega32c4", "avrxmega2", "avrxmega2"}, + {"atxmega32d4", "avrxmega2", "avrxmega2"}, + {"atxmega32e5", "avrxmega2", "avrxmega2"}, + {"atxmega16e5", "avrxmega2", "avrxmega2"}, + {"atxmega8e5", "avrxmega2", "avrxmega2"}, + {"atxmega64a3u", "avrxmega4", "avrxmega4"}, + {"atxmega64a4u", "avrxmega4", "avrxmega4"}, + {"atxmega64b1", "avrxmega4", "avrxmega4"}, + {"atxmega64b3", "avrxmega4", "avrxmega4"}, + {"atxmega64c3", "avrxmega4", "avrxmega4"}, + {"atxmega64d3", "avrxmega4", "avrxmega4"}, + {"atxmega64d4", "avrxmega4", "avrxmega4"}, + {"atxmega64a1", "avrxmega5", "avrxmega5"}, + {"atxmega64a1u", "avrxmega5", "avrxmega5"}, + {"atxmega128a3", "avrxmega6", "avrxmega6"}, + {"atxmega128a3u", "avrxmega6", "avrxmega6"}, + {"atxmega128b1", "avrxmega6", "avrxmega6"}, + {"atxmega128b3", "avrxmega6", "avrxmega6"}, + {"atxmega128c3", "avrxmega6", "avrxmega6"}, + {"atxmega128d3", "avrxmega6", "avrxmega6"}, + {"atxmega128d4", "avrxmega6", "avrxmega6"}, + {"atxmega192a3", "avrxmega6", "avrxmega6"}, + {"atxmega192a3u", "avrxmega6", "avrxmega6"}, + {"atxmega192c3", "avrxmega6", "avrxmega6"}, + {"atxmega192d3", "avrxmega6", "avrxmega6"}, + {"atxmega256a3", "avrxmega6", "avrxmega6"}, + {"atxmega256a3u", "avrxmega6", "avrxmega6"}, + {"atxmega256a3b", "avrxmega6", "avrxmega6"}, + {"atxmega256a3bu", "avrxmega6", "avrxmega6"}, + {"atxmega256c3", "avrxmega6", "avrxmega6"}, + {"atxmega256d3", "avrxmega6", "avrxmega6"}, + {"atxmega384c3", "avrxmega6", "avrxmega6"}, + {"atxmega384d3", "avrxmega6", "avrxmega6"}, + {"atxmega128a1", "avrxmega7", "avrxmega7"}, + {"atxmega128a1u", "avrxmega7", "avrxmega7"}, + {"atxmega128a4u", "avrxmega7", "avrxmega7"}, +}; + +std::string GetMCUSubPath(StringRef MCUName) { + for (const auto &MCU : MCUInfo) + if (MCU.Name == MCUName) + return std::string(MCU.SubPath); + return ""; +} + +llvm::Optional<StringRef> GetMCUFamilyName(StringRef MCUName) { + for (const auto &MCU : MCUInfo) + if (MCU.Name == MCUName) + return Optional<StringRef>(MCU.Family); + return Optional<StringRef>(); +} + +llvm::Optional<unsigned> GetMCUSectionAddressData(StringRef MCU) { + return llvm::StringSwitch<llvm::Optional<unsigned>>(MCU) + .Case("atmega328", Optional<unsigned>(0x800100)) + .Case("atmega328p", Optional<unsigned>(0x800100)) + .Default(Optional<unsigned>()); } const StringRef PossibleAVRLibcLocations[] = { @@ -59,7 +319,7 @@ AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, // We cannot link any standard libraries without an MCU specified. D.Diag(diag::warn_drv_avr_mcu_not_specified); } else { - Optional<StringRef> FamilyName = GetMcuFamilyName(CPU); + Optional<StringRef> FamilyName = GetMCUFamilyName(CPU); Optional<std::string> AVRLibcRoot = findAVRLibcInstallation(); if (!FamilyName.hasValue()) { @@ -76,11 +336,10 @@ AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, } else { // We have enough information to link stdlibs std::string GCCRoot = std::string(GCCInstallation.getInstallPath()); std::string LibcRoot = AVRLibcRoot.getValue(); + std::string SubPath = GetMCUSubPath(CPU); - getFilePaths().push_back(LibcRoot + std::string("/lib/") + - std::string(*FamilyName)); - getFilePaths().push_back(GCCRoot + std::string("/") + - std::string(*FamilyName)); + getFilePaths().push_back(LibcRoot + std::string("/lib/") + SubPath); + getFilePaths().push_back(GCCRoot + std::string("/") + SubPath); LinkStdlib = true; } @@ -97,12 +356,12 @@ Tool *AVRToolChain::buildLinker() const { void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, + const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { // Compute information about the target AVR. std::string CPU = getCPUName(Args, getToolChain().getTriple()); - llvm::Optional<StringRef> FamilyName = GetMcuFamilyName(CPU); + llvm::Optional<StringRef> FamilyName = GetMCUFamilyName(CPU); + llvm::Optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU); std::string Linker = getToolChain().GetProgramPath(getShortName()); ArgStringList CmdArgs; @@ -118,6 +377,17 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); + if (SectionAddressData.hasValue()) { + std::string DataSectionArg = std::string("-Tdata=0x") + + llvm::utohexstr(SectionAddressData.getValue()); + CmdArgs.push_back(Args.MakeArgString(DataSectionArg)); + } else { + // We do not have an entry for this CPU in the address mapping table yet. + getToolChain().getDriver().Diag( + diag::warn_drv_avr_linker_section_addresses_not_implemented) + << CPU; + } + // If the family name is known, we can link with the device-specific libgcc. // Without it, libgcc will simply not be linked. This matches avr-gcc // behavior. @@ -142,9 +412,9 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); } - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Linker), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); } llvm::Optional<std::string> AVRToolChain::findAVRLibcInstallation() const { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Ananas.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Ananas.cpp index a4141a57accc..e5e33fe24874 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Ananas.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Ananas.cpp @@ -39,8 +39,9 @@ void ananas::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -124,8 +125,9 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } // Ananas - Ananas tool chain which can call as(1) and ld(1) directly. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index dd4545d6c48f..a5e632fd8cdb 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -40,9 +40,20 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args, // Handle CPU name is 'native'. if (CPU == "native") return std::string(llvm::sys::getHostCPUName()); - else if (CPU.size()) + + // arm64e requires v8.3a and only runs on apple-a12 and later CPUs. + if (Triple.isArm64e()) + return "apple-a12"; + + if (CPU.size()) return CPU; + if (Triple.isTargetMachineMac() && + Triple.getArch() == llvm::Triple::aarch64) { + // Apple Silicon macs default to A12 CPUs. + return "apple-a12"; + } + // Make sure we pick the appropriate Apple CPU if -arch is used or when // targetting a Darwin OS. if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin()) @@ -68,9 +79,10 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, else return false; - // +sve implies +f32mm if the base architecture is v8.6A + // +sve implies +f32mm if the base architecture is v8.6A or v8.7A // it isn't the case in general that sve implies both f64mm and f32mm - if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A) && Feature == "sve") + if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A || + ArchKind == llvm::AArch64::ArchKind::ARMV8_7A) && Feature == "sve") Features.push_back("+f32mm"); } return true; @@ -94,7 +106,7 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, if (!llvm::AArch64::getArchFeatures(ArchKind, Features)) return false; - unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind); + uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind); if (!llvm::AArch64::getExtensionFeatures(Extension, Features)) return false; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp index afe896b4a65b..ef590db1eecd 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -32,6 +32,12 @@ bool arm::isARMMProfile(const llvm::Triple &Triple) { return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M; } +// True if A-profile. +bool arm::isARMAProfile(const llvm::Triple &Triple) { + llvm::StringRef Arch = Triple.getArchName(); + return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A; +} + // Get Arch/CPU from args. void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch, llvm::StringRef &CPU, bool FromAs) { @@ -73,14 +79,15 @@ static unsigned getARMFPUFeatures(const Driver &D, const Arg *A, } // Decode ARM features from string like +[no]featureA+[no]featureB+... -static bool DecodeARMFeatures(const Driver &D, StringRef text, - StringRef CPU, llvm::ARM::ArchKind ArchKind, - std::vector<StringRef> &Features) { +static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU, + llvm::ARM::ArchKind ArchKind, + std::vector<StringRef> &Features, + unsigned &ArgFPUID) { SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); for (StringRef Feature : Split) { - if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features)) + if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUID)) return false; } return true; @@ -102,14 +109,14 @@ static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef ArchName, llvm::StringRef CPUName, std::vector<StringRef> &Features, - const llvm::Triple &Triple) { + const llvm::Triple &Triple, unsigned &ArgFPUID) { std::pair<StringRef, StringRef> Split = ArchName.split("+"); std::string MArch = arm::getARMArch(ArchName, Triple); llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch); if (ArchKind == llvm::ARM::ArchKind::INVALID || - (Split.second.size() && !DecodeARMFeatures( - D, Split.second, CPUName, ArchKind, Features))) + (Split.second.size() && !DecodeARMFeatures(D, Split.second, CPUName, + ArchKind, Features, ArgFPUID))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -117,15 +124,15 @@ static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef CPUName, llvm::StringRef ArchName, std::vector<StringRef> &Features, - const llvm::Triple &Triple) { + const llvm::Triple &Triple, unsigned &ArgFPUID) { std::pair<StringRef, StringRef> Split = CPUName.split("+"); std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); llvm::ARM::ArchKind ArchKind = arm::getLLVMArchKindForARM(CPU, ArchName, Triple); if (ArchKind == llvm::ARM::ArchKind::INVALID || - (Split.second.size() && !DecodeARMFeatures( - D, Split.second, CPU, ArchKind, Features))) + (Split.second.size() && + !DecodeARMFeatures(D, Split.second, CPU, ArchKind, Features, ArgFPUID))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -133,6 +140,7 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) { // The backend is hardwired to assume AAPCS for M-class processors, ensure // the frontend matches that. return T.getEnvironment() == llvm::Triple::EABI || + T.getEnvironment() == llvm::Triple::EABIHF || T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } @@ -159,11 +167,73 @@ arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { return arm::getARMFloatABI(TC.getDriver(), TC.getEffectiveTriple(), Args); } +arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) { + auto SubArch = getARMSubArchVersionNumber(Triple); + switch (Triple.getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + case llvm::Triple::TvOS: + // Darwin defaults to "softfp" for v6 and v7. + if (Triple.isWatchABI()) + return FloatABI::Hard; + else + return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft; + + case llvm::Triple::WatchOS: + return FloatABI::Hard; + + // FIXME: this is invalid for WindowsCE + case llvm::Triple::Win32: + return FloatABI::Hard; + + case llvm::Triple::NetBSD: + switch (Triple.getEnvironment()) { + case llvm::Triple::EABIHF: + case llvm::Triple::GNUEABIHF: + return FloatABI::Hard; + default: + return FloatABI::Soft; + } + break; + + case llvm::Triple::FreeBSD: + switch (Triple.getEnvironment()) { + case llvm::Triple::GNUEABIHF: + return FloatABI::Hard; + default: + // FreeBSD defaults to soft float + return FloatABI::Soft; + } + break; + + case llvm::Triple::OpenBSD: + return FloatABI::SoftFP; + + default: + switch (Triple.getEnvironment()) { + case llvm::Triple::GNUEABIHF: + case llvm::Triple::MuslEABIHF: + case llvm::Triple::EABIHF: + return FloatABI::Hard; + case llvm::Triple::GNUEABI: + case llvm::Triple::MuslEABI: + case llvm::Triple::EABI: + // EABI is always AAPCS, and if it was not marked 'hard', it's softfp + return FloatABI::SoftFP; + case llvm::Triple::Android: + return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft; + default: + return FloatABI::Invalid; + } + } + return FloatABI::Invalid; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) { - auto SubArch = getARMSubArchVersionNumber(Triple); arm::FloatABI ABI = FloatABI::Invalid; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, @@ -183,95 +253,23 @@ arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple, ABI = FloatABI::Soft; } } - - // It is incorrect to select hard float ABI on MachO platforms if the ABI is - // "apcs-gnu". - if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) && - ABI == FloatABI::Hard) { - D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) - << Triple.getArchName(); - } } // If unspecified, choose the default based on the platform. - if (ABI == FloatABI::Invalid) { - switch (Triple.getOS()) { - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - case llvm::Triple::TvOS: { - // Darwin defaults to "softfp" for v6 and v7. - ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft; - ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI; - break; - } - case llvm::Triple::WatchOS: - ABI = FloatABI::Hard; - break; + if (ABI == FloatABI::Invalid) + ABI = arm::getDefaultFloatABI(Triple); - // FIXME: this is invalid for WindowsCE - case llvm::Triple::Win32: + if (ABI == FloatABI::Invalid) { + // Assume "soft", but warn the user we are guessing. + if (Triple.isOSBinFormatMachO() && + Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em) ABI = FloatABI::Hard; - break; - - case llvm::Triple::NetBSD: - switch (Triple.getEnvironment()) { - case llvm::Triple::EABIHF: - case llvm::Triple::GNUEABIHF: - ABI = FloatABI::Hard; - break; - default: - ABI = FloatABI::Soft; - break; - } - break; - - case llvm::Triple::FreeBSD: - switch (Triple.getEnvironment()) { - case llvm::Triple::GNUEABIHF: - ABI = FloatABI::Hard; - break; - default: - // FreeBSD defaults to soft float - ABI = FloatABI::Soft; - break; - } - break; - - case llvm::Triple::OpenBSD: - ABI = FloatABI::SoftFP; - break; + else + ABI = FloatABI::Soft; - default: - switch (Triple.getEnvironment()) { - case llvm::Triple::GNUEABIHF: - case llvm::Triple::MuslEABIHF: - case llvm::Triple::EABIHF: - ABI = FloatABI::Hard; - break; - case llvm::Triple::GNUEABI: - case llvm::Triple::MuslEABI: - case llvm::Triple::EABI: - // EABI is always AAPCS, and if it was not marked 'hard', it's softfp - ABI = FloatABI::SoftFP; - break; - case llvm::Triple::Android: - ABI = (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft; - break; - default: - // Assume "soft", but warn the user we are guessing. - if (Triple.isOSBinFormatMachO() && - Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em) - ABI = FloatABI::Hard; - else - ABI = FloatABI::Soft; - - if (Triple.getOS() != llvm::Triple::UnknownOS || - !Triple.isOSBinFormatMachO()) - D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; - break; - } - } + if (Triple.getOS() != llvm::Triple::UnknownOS || + !Triple.isOSBinFormatMachO()) + D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; } assert(ABI != FloatABI::Invalid && "must select an ABI"); @@ -347,6 +345,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); StringRef ArchName; StringRef CPUName; + unsigned ArchArgFPUID = llvm::ARM::FK_INVALID; + unsigned CPUArgFPUID = llvm::ARM::FK_INVALID; // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. if (WaCPU) { @@ -364,14 +364,14 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, D.Diag(clang::diag::warn_drv_unused_argument) << ArchArg->getAsString(Args); ArchName = StringRef(WaArch->getValue()).substr(7); - checkARMArchName(D, WaArch, Args, ArchName, CPUName, - ExtensionFeatures, Triple); + checkARMArchName(D, WaArch, Args, ArchName, CPUName, ExtensionFeatures, + Triple, ArchArgFPUID); // FIXME: Set Arch. D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args); } else if (ArchArg) { ArchName = ArchArg->getValue(); - checkARMArchName(D, ArchArg, Args, ArchName, CPUName, - ExtensionFeatures, Triple); + checkARMArchName(D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures, + Triple, ArchArgFPUID); } // Add CPU features for generic CPUs @@ -390,8 +390,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, } if (CPUArg) - checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, - ExtensionFeatures, Triple); + checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures, + Triple, CPUArgFPUID); // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=. unsigned FPUID = llvm::ARM::FK_INVALID; const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ); @@ -455,20 +455,26 @@ fp16_fml_fallthrough: Features.push_back("+fullfp16"); } - // Setting -msoft-float/-mfloat-abi=soft effectively disables the FPU (GCC - // ignores the -mfpu options in this case). - // Note that the ABI can also be set implicitly by the target selected. + // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to + // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in + // this case). Note that the ABI can also be set implicitly by the target + // selected. if (ABI == arm::FloatABI::Soft) { llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features); // Disable all features relating to hardware FP, not already disabled by the // above call. + Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-bf16", "-mve", + "-mve.fp", "-fpregs"}); + } else if (FPUID == llvm::ARM::FK_NONE || + ArchArgFPUID == llvm::ARM::FK_NONE || + CPUArgFPUID == llvm::ARM::FK_NONE) { + // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to + // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the + // FPU, but not the FPU registers, thus MVE-I, which depends only on the + // latter, is still supported. Features.insert(Features.end(), - {"-dotprod", "-fp16fml", "-mve", "-mve.fp", "-fpregs"}); - } else if (FPUID == llvm::ARM::FK_NONE) { - // -mfpu=none is *very* similar to -mfloat-abi=soft, only that it should not - // disable MVE-I. - Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-mve.fp"}); + {"-dotprod", "-fp16fml", "-bf16", "-mve.fp"}); if (!hasIntegerMVE(Features)) Features.emplace_back("-fpregs"); } @@ -606,6 +612,45 @@ fp16_fml_fallthrough: if (Args.hasArg(options::OPT_mno_neg_immediates)) Features.push_back("+no-neg-immediates"); + + // Enable/disable straight line speculation hardening. + if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) { + StringRef Scope = A->getValue(); + bool EnableRetBr = false; + bool EnableBlr = false; + if (Scope != "none" && Scope != "all") { + SmallVector<StringRef, 4> Opts; + Scope.split(Opts, ","); + for (auto Opt : Opts) { + Opt = Opt.trim(); + if (Opt == "retbr") { + EnableRetBr = true; + continue; + } + if (Opt == "blr") { + EnableBlr = true; + continue; + } + D.Diag(diag::err_invalid_sls_hardening) + << Scope << A->getAsString(Args); + break; + } + } else if (Scope == "all") { + EnableRetBr = true; + EnableBlr = true; + } + + if (EnableRetBr || EnableBlr) + if (!(isARMAProfile(Triple) && getARMSubArchVersionNumber(Triple) >= 7)) + D.Diag(diag::err_sls_hardening_arm_not_supported) + << Scope << A->getAsString(Args); + + if (EnableRetBr) + Features.push_back("+harden-sls-retbr"); + if (EnableBlr) + Features.push_back("+harden-sls-blr"); + } + } const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h index 0ba1a59852aa..02d91cdaee13 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -47,6 +47,7 @@ enum class FloatABI { Hard, }; +FloatABI getDefaultFloatABI(const llvm::Triple &Triple); FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args); FloatABI getARMFloatABI(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); @@ -62,6 +63,7 @@ void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, std::vector<llvm::StringRef> &Features, bool ForAS); int getARMSubArchVersionNumber(const llvm::Triple &Triple); bool isARMMProfile(const llvm::Triple &Triple); +bool isARMAProfile(const llvm::Triple &Triple); } // end namespace arm } // end namespace tools diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp index 7b4dd703c0c7..5a509dbb2bd3 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -452,8 +452,6 @@ bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) { return llvm::StringSwitch<bool>(getCPUName(Args, Triple)) .Cases("mips32r6", "mips64r6", true) .Default(false); - - return false; } bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp index 144e276a6bd8..bcaecf4b2d98 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp @@ -57,7 +57,6 @@ std::string ppc::getPPCTargetCPU(const ArgList &Args) { .Case("970", "970") .Case("G5", "g5") .Case("a2", "a2") - .Case("a2q", "a2q") .Case("e500", "e500") .Case("e500mc", "e500mc") .Case("e5500", "e5500") diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index b1ddd3d83909..469a7365c90f 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -58,12 +58,14 @@ static StringRef getExtensionType(StringRef Ext) { // extension that the compiler currently supports. static Optional<RISCVExtensionVersion> isExperimentalExtension(StringRef Ext) { - if (Ext == "b" || Ext == "zbb" || Ext == "zbc" || Ext == "zbe" || - Ext == "zbf" || Ext == "zbm" || Ext == "zbp" || Ext == "zbr" || - Ext == "zbs" || Ext == "zbt" || Ext == "zbproposedc") - return RISCVExtensionVersion{"0", "92"}; - if (Ext == "v") - return RISCVExtensionVersion{"0", "8"}; + if (Ext == "b" || Ext == "zba" || Ext == "zbb" || Ext == "zbc" || + Ext == "zbe" || Ext == "zbf" || Ext == "zbm" || Ext == "zbp" || + Ext == "zbr" || Ext == "zbs" || Ext == "zbt" || Ext == "zbproposedc") + return RISCVExtensionVersion{"0", "93"}; + if (Ext == "v" || Ext == "zvamo" || Ext == "zvlsseg") + return RISCVExtensionVersion{"1", "0"}; + if (Ext == "zfh") + return RISCVExtensionVersion{"0", "1"}; return None; } @@ -256,7 +258,11 @@ static void getExtensionFeatures(const Driver &D, << MArch << Error << Ext; return; } - if (isExperimentalExtension(Ext)) + if (Ext == "zvamo" || Ext == "zvlsseg") { + Features.push_back("+experimental-v"); + Features.push_back("+experimental-zvamo"); + Features.push_back("+experimental-zvlsseg"); + } else if (isExperimentalExtension(Ext)) Features.push_back(Args.MakeArgString("+experimental-" + Ext)); else Features.push_back(Args.MakeArgString("+" + Ext)); @@ -410,9 +416,21 @@ static bool getArchFeatures(const Driver &D, StringRef MArch, break; case 'b': Features.push_back("+experimental-b"); + Features.push_back("+experimental-zba"); + Features.push_back("+experimental-zbb"); + Features.push_back("+experimental-zbc"); + Features.push_back("+experimental-zbe"); + Features.push_back("+experimental-zbf"); + Features.push_back("+experimental-zbm"); + Features.push_back("+experimental-zbp"); + Features.push_back("+experimental-zbr"); + Features.push_back("+experimental-zbs"); + Features.push_back("+experimental-zbt"); break; case 'v': Features.push_back("+experimental-v"); + Features.push_back("+experimental-zvamo"); + Features.push_back("+experimental-zvlsseg"); break; } @@ -447,10 +465,10 @@ static bool getArchFeatures(const Driver &D, StringRef MArch, } // Get features except standard extension feature -void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args, - const llvm::opt::Arg *A, StringRef Mcpu, - std::vector<StringRef> &Features) { +static void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + const llvm::opt::Arg *A, StringRef Mcpu, + std::vector<StringRef> &Features) { bool Is64Bit = (Triple.getArch() == llvm::Triple::riscv64); llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu); if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) || diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.cpp index fa10e4810f1c..9dfd37c2106d 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.cpp @@ -18,9 +18,5 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; -const char *ve::getVEAsmModeForCPU(StringRef Name, const llvm::Triple &Triple) { - return ""; -} - void ve::getVETargetFeatures(const Driver &D, const ArgList &Args, std::vector<StringRef> &Features) {} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.h index 713e3e7d042f..531433534914 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/VE.h @@ -22,8 +22,6 @@ namespace ve { void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector<llvm::StringRef> &Features); -const char *getVEAsmModeForCPU(llvm::StringRef Name, - const llvm::Triple &Triple); } // end namespace ve } // namespace tools diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp index 6b82abec6f65..94a53f9d9e46 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -20,51 +20,52 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; -const char *x86::getX86TargetCPU(const ArgList &Args, +std::string x86::getX86TargetCPU(const ArgList &Args, const llvm::Triple &Triple) { if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) { - if (StringRef(A->getValue()) != "native") - return A->getValue(); + StringRef CPU = A->getValue(); + if (CPU != "native") + return std::string(CPU); // FIXME: Reject attempts to use -march=native unless the target matches // the host. // // FIXME: We should also incorporate the detected target features for use // with -native. - std::string CPU = std::string(llvm::sys::getHostCPUName()); + CPU = llvm::sys::getHostCPUName(); if (!CPU.empty() && CPU != "generic") - return Args.MakeArgString(CPU); + return std::string(CPU); } if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) { // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap(). StringRef Arch = A->getValue(); - const char *CPU = nullptr; + StringRef CPU; if (Triple.getArch() == llvm::Triple::x86) { // 32-bit-only /arch: flags. - CPU = llvm::StringSwitch<const char *>(Arch) + CPU = llvm::StringSwitch<StringRef>(Arch) .Case("IA32", "i386") .Case("SSE", "pentium3") .Case("SSE2", "pentium4") - .Default(nullptr); + .Default(""); } - if (CPU == nullptr) { // 32-bit and 64-bit /arch: flags. - CPU = llvm::StringSwitch<const char *>(Arch) + if (CPU.empty()) { // 32-bit and 64-bit /arch: flags. + CPU = llvm::StringSwitch<StringRef>(Arch) .Case("AVX", "sandybridge") .Case("AVX2", "haswell") .Case("AVX512F", "knl") .Case("AVX512", "skylake-avx512") - .Default(nullptr); + .Default(""); } - if (CPU) { + if (!CPU.empty()) { A->claim(); - return CPU; + return std::string(CPU); } } // Select the default CPU if none was given (or detection failed). if (!Triple.isX86()) - return nullptr; // This routine is only handling x86 targets. + return ""; // This routine is only handling x86 targets. bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.h index 9f9c2b8c4b49..14f0a26c8be4 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.h @@ -21,7 +21,7 @@ namespace driver { namespace tools { namespace x86 { -const char *getX86TargetCPU(const llvm::opt::ArgList &Args, +std::string getX86TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.cpp index 97cfa7d0e156..7619dd30da5a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -12,6 +12,7 @@ #include "InputInfo.h" #include "Gnu.h" +#include "Arch/RISCV.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -27,15 +28,83 @@ using namespace clang::driver; using namespace clang::driver::tools; using namespace clang::driver::toolchains; +static Multilib makeMultilib(StringRef commonSuffix) { + return Multilib(commonSuffix, commonSuffix, commonSuffix); +} + +static bool findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + const ArgList &Args, DetectedMultilibs &Result) { + Multilib::flags_list Flags; + StringRef Arch = riscv::getRISCVArch(Args, TargetTriple); + StringRef Abi = tools::riscv::getRISCVABI(Args, TargetTriple); + + if (TargetTriple.getArch() == llvm::Triple::riscv64) { + Multilib Imac = makeMultilib("").flag("+march=rv64imac").flag("+mabi=lp64"); + Multilib Imafdc = makeMultilib("/rv64imafdc/lp64d") + .flag("+march=rv64imafdc") + .flag("+mabi=lp64d"); + + // Multilib reuse + bool UseImafdc = + (Arch == "rv64imafdc") || (Arch == "rv64gc"); // gc => imafdc + + addMultilibFlag((Arch == "rv64imac"), "march=rv64imac", Flags); + addMultilibFlag(UseImafdc, "march=rv64imafdc", Flags); + addMultilibFlag(Abi == "lp64", "mabi=lp64", Flags); + addMultilibFlag(Abi == "lp64d", "mabi=lp64d", Flags); + + Result.Multilibs = MultilibSet().Either(Imac, Imafdc); + return Result.Multilibs.select(Flags, Result.SelectedMultilib); + } + if (TargetTriple.getArch() == llvm::Triple::riscv32) { + Multilib Imac = + makeMultilib("").flag("+march=rv32imac").flag("+mabi=ilp32"); + Multilib I = + makeMultilib("/rv32i/ilp32").flag("+march=rv32i").flag("+mabi=ilp32"); + Multilib Im = + makeMultilib("/rv32im/ilp32").flag("+march=rv32im").flag("+mabi=ilp32"); + Multilib Iac = makeMultilib("/rv32iac/ilp32") + .flag("+march=rv32iac") + .flag("+mabi=ilp32"); + Multilib Imafc = makeMultilib("/rv32imafc/ilp32f") + .flag("+march=rv32imafc") + .flag("+mabi=ilp32f"); + + // Multilib reuse + bool UseI = (Arch == "rv32i") || (Arch == "rv32ic"); // ic => i + bool UseIm = (Arch == "rv32im") || (Arch == "rv32imc"); // imc => im + bool UseImafc = (Arch == "rv32imafc") || (Arch == "rv32imafdc") || + (Arch == "rv32gc"); // imafdc,gc => imafc + + addMultilibFlag(UseI, "march=rv32i", Flags); + addMultilibFlag(UseIm, "march=rv32im", Flags); + addMultilibFlag((Arch == "rv32iac"), "march=rv32iac", Flags); + addMultilibFlag((Arch == "rv32imac"), "march=rv32imac", Flags); + addMultilibFlag(UseImafc, "march=rv32imafc", Flags); + addMultilibFlag(Abi == "ilp32", "mabi=ilp32", Flags); + addMultilibFlag(Abi == "ilp32f", "mabi=ilp32f", Flags); + + Result.Multilibs = MultilibSet().Either(I, Im, Iac, Imac, Imafc); + return Result.Multilibs.select(Flags, Result.SelectedMultilib); + } + return false; +} + BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); -} -BareMetal::~BareMetal() {} + findMultilibs(D, Triple, Args); + SmallString<128> SysRoot(computeSysRoot()); + if (!SysRoot.empty()) { + llvm::sys::path::append(SysRoot, "lib"); + getFilePaths().push_back(std::string(SysRoot)); + } +} /// Is the triple {arm,thumb}-none-none-{eabi,eabihf} ? static bool isARMBareMetal(const llvm::Triple &Triple) { @@ -56,20 +125,65 @@ static bool isARMBareMetal(const llvm::Triple &Triple) { return true; } +static bool isRISCVBareMetal(const llvm::Triple &Triple) { + if (Triple.getArch() != llvm::Triple::riscv32 && + Triple.getArch() != llvm::Triple::riscv64) + return false; + + if (Triple.getVendor() != llvm::Triple::UnknownVendor) + return false; + + if (Triple.getOS() != llvm::Triple::UnknownOS) + return false; + + return Triple.getEnvironmentName() == "elf"; +} + +void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) { + DetectedMultilibs Result; + if (isRISCVBareMetal(Triple)) { + if (findRISCVMultilibs(D, Triple, Args, Result)) { + SelectedMultilib = Result.SelectedMultilib; + Multilibs = Result.Multilibs; + } + } +} + bool BareMetal::handlesTarget(const llvm::Triple &Triple) { - return isARMBareMetal(Triple); + return isARMBareMetal(Triple) || isRISCVBareMetal(Triple); } Tool *BareMetal::buildLinker() const { return new tools::baremetal::Linker(*this); } +std::string BareMetal::getCompilerRTPath() const { return getRuntimesDir(); } + +std::string BareMetal::getCompilerRTBasename(const llvm::opt::ArgList &, + StringRef, FileType, bool) const { + return ("libclang_rt.builtins-" + getTriple().getArchName() + ".a").str(); +} + std::string BareMetal::getRuntimesDir() const { SmallString<128> Dir(getDriver().ResourceDir); llvm::sys::path::append(Dir, "lib", "baremetal"); + Dir += SelectedMultilib.gccSuffix(); return std::string(Dir.str()); } +std::string BareMetal::computeSysRoot() const { + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot + SelectedMultilib.osSuffix(); + + SmallString<128> SysRootDir; + llvm::sys::path::append(SysRootDir, getDriver().Dir, "../lib/clang-runtimes", + getDriver().getTargetTriple()); + + SysRootDir += SelectedMultilib.osSuffix(); + return std::string(SysRootDir); +} + void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (DriverArgs.hasArg(options::OPT_nostdinc)) @@ -82,9 +196,11 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs, } if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { - SmallString<128> Dir(getDriver().SysRoot); - llvm::sys::path::append(Dir, "include"); - addSystemInclude(DriverArgs, CC1Args, Dir.str()); + SmallString<128> Dir(computeSysRoot()); + if (!Dir.empty()) { + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } } } @@ -101,7 +217,7 @@ void BareMetal::AddClangCXXStdlibIncludeArgs( DriverArgs.hasArg(options::OPT_nostdincxx)) return; - StringRef SysRoot = getDriver().SysRoot; + std::string SysRoot(computeSysRoot()); if (SysRoot.empty()) return; @@ -156,8 +272,17 @@ void BareMetal::AddCXXStdlibLibArgs(const ArgList &Args, void BareMetal::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs) const { - CmdArgs.push_back(Args.MakeArgString("-lclang_rt.builtins-" + - getTriple().getArchName())); + ToolChain::RuntimeLibType RLT = GetRuntimeLibType(Args); + switch (RLT) { + case ToolChain::RLT_CompilerRT: + CmdArgs.push_back( + Args.MakeArgString("-lclang_rt.builtins-" + getTriple().getArchName())); + return; + case ToolChain::RLT_Libgcc: + CmdArgs.push_back("-lgcc"); + return; + } + llvm_unreachable("Unhandled RuntimeLibType."); } void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -175,6 +300,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-L" + TC.getRuntimesDir())); + TC.AddFilePathLibArgs(Args, CmdArgs); Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, options::OPT_e, options::OPT_s, options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); @@ -193,5 +319,5 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), Args.MakeArgString(TC.GetLinkerPath()), - CmdArgs, Inputs)); + CmdArgs, Inputs, Output)); } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.h index 4c0c739307b1..a6d4922a380f 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/BareMetal.h @@ -23,9 +23,13 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain { public: BareMetal(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); - ~BareMetal() override; + ~BareMetal() override = default; static bool handlesTarget(const llvm::Triple &Triple); + + void findMultilibs(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + protected: Tool *buildLinker() const override; @@ -37,6 +41,14 @@ public: bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } + StringRef getOSLibName() const override { return "baremetal"; } + + std::string getCompilerRTPath() const override; + std::string getCompilerRTBasename(const llvm::opt::ArgList &Args, + StringRef Component, + FileType Type = ToolChain::FT_Static, + bool AddArch = true) const override; + RuntimeLibType GetDefaultRuntimeLibType() const override { return ToolChain::RLT_CompilerRT; } @@ -59,6 +71,7 @@ public: llvm::opt::ArgStringList &CmdArgs) const override; void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + std::string computeSysRoot() const override; }; } // namespace toolchains diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 01024ee3a16a..634b1259b927 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp @@ -39,15 +39,12 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Compression.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/YAMLParser.h" -#ifdef LLVM_ON_UNIX -#include <unistd.h> // For getuid(). -#endif - using namespace clang::driver; using namespace clang::driver::tools; using namespace clang; @@ -331,6 +328,7 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, break; case llvm::Triple::ppc: + case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: ppc::getPPCTargetFeatures(D, Triple, Args, Features); @@ -365,7 +363,7 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, break; case llvm::Triple::r600: case llvm::Triple::amdgcn: - amdgpu::getAMDGPUTargetFeatures(D, Args, Features); + amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features); break; case llvm::Triple::msp430: msp430::getMSP430TargetFeatures(D, Args, Features); @@ -527,6 +525,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, // WebAssembly never wants frame pointers. return false; case llvm::Triple::ppc: + case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: @@ -603,12 +602,12 @@ getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) { bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer); bool NoOmitFP = A && A->getOption().matches(options::OPT_fno_omit_frame_pointer); - bool KeepLeaf = Args.hasFlag(options::OPT_momit_leaf_frame_pointer, - options::OPT_mno_omit_leaf_frame_pointer, - Triple.isAArch64() || Triple.isPS4CPU()); + bool OmitLeafFP = Args.hasFlag(options::OPT_momit_leaf_frame_pointer, + options::OPT_mno_omit_leaf_frame_pointer, + Triple.isAArch64() || Triple.isPS4CPU()); if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) || (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) { - if (KeepLeaf) + if (OmitLeafFP) return CodeGenOptions::FramePointerKind::NonLeaf; return CodeGenOptions::FramePointerKind::All; } @@ -657,6 +656,21 @@ static void addMacroPrefixMapArg(const Driver &D, const ArgList &Args, } } +/// Add a CC1 and CC1AS option to specify the coverage file path prefix map. +static void addProfilePrefixMapArg(const Driver &D, const ArgList &Args, + ArgStringList &CmdArgs) { + for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ, + options::OPT_fprofile_prefix_map_EQ)) { + StringRef Map = A->getValue(); + if (Map.find('=') == StringRef::npos) + D.Diag(diag::err_drv_invalid_argument_to_option) + << Map << A->getOption().getName(); + else + CmdArgs.push_back(Args.MakeArgString("-fprofile-prefix-map=" + Map)); + A->claim(); + } +} + /// Vectorize at all optimization levels greater than 1 except for -Oz. /// For -Oz the loop vectorizer is disabled, while the slp vectorizer is /// enabled. @@ -763,9 +777,11 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, D.Diag(diag::err_drv_argument_not_allowed_with) << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling(); - if (CSPGOGenerateArg && PGOGenerateArg) + if (CSPGOGenerateArg && PGOGenerateArg) { D.Diag(diag::err_drv_argument_not_allowed_with) << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling(); + PGOGenerateArg = nullptr; + } if (ProfileGenerateArg) { if (ProfileGenerateArg->getOption().matches( @@ -830,9 +846,9 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, Args.hasArg(options::OPT_coverage); bool EmitCovData = TC.needsGCovInstrumentation(Args); if (EmitCovNotes) - CmdArgs.push_back("-femit-coverage-notes"); + CmdArgs.push_back("-ftest-coverage"); if (EmitCovData) - CmdArgs.push_back("-femit-coverage-data"); + CmdArgs.push_back("-fprofile-arcs"); if (Args.hasFlag(options::OPT_fcoverage_mapping, options::OPT_fno_coverage_mapping, false)) { @@ -867,6 +883,17 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-filter-files=" + v))); } + if (const auto *A = Args.getLastArg(options::OPT_fprofile_update_EQ)) { + StringRef Val = A->getValue(); + if (Val == "atomic" || Val == "prefer-atomic") + CmdArgs.push_back("-fprofile-update=atomic"); + else if (Val != "single") + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } else if (TC.getSanitizerArgs().needsTsanRt()) { + CmdArgs.push_back("-fprofile-update=atomic"); + } + // Leave -fprofile-dir= an unused argument unless .gcda emission is // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider // the flag used. There is no -fno-profile-dir, so the user has no @@ -976,6 +1003,9 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, case codegenoptions::FullDebugInfo: CmdArgs.push_back("-debug-info-kind=standalone"); break; + case codegenoptions::UnusedTypeInfo: + CmdArgs.push_back("-debug-info-kind=unused-types"); + break; default: break; } @@ -1011,18 +1041,10 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, ArgStringList &CmdArgs, const Driver &D, const ToolChain &TC) { - const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ); + const Arg *A = Args.getLastArg(options::OPT_gz_EQ); if (!A) return; if (checkDebugInfoOption(A, Args, D, TC)) { - if (A->getOption().getID() == options::OPT_gz) { - if (llvm::zlib::isAvailable()) - CmdArgs.push_back("--compress-debug-sections"); - else - D.Diag(diag::warn_debug_compression_unavailable); - return; - } - StringRef Value = A->getValue(); if (Value == "none") { CmdArgs.push_back("--compress-debug-sections=none"); @@ -1057,6 +1079,15 @@ static const char *RelocationModelName(llvm::Reloc::Model Model) { } llvm_unreachable("Unknown Reloc::Model kind"); } +static void handleAMDGPUCodeObjectVersionOptions(const Driver &D, + const ArgList &Args, + ArgStringList &CmdArgs) { + unsigned CodeObjVer = getOrCheckAMDGPUCodeObjectVersion(D, Args); + CmdArgs.insert(CmdArgs.begin() + 1, + Args.MakeArgString(Twine("--amdhsa-code-object-version=") + + Twine(CodeObjVer))); + CmdArgs.insert(CmdArgs.begin() + 1, "-mllvm"); +} void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, const Driver &D, const ArgList &Args, @@ -1344,6 +1375,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, } addMacroPrefixMapArg(D, Args, CmdArgs); + addProfilePrefixMapArg(D, Args, CmdArgs); } // FIXME: Move to target hook. @@ -1370,6 +1402,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { return false; case llvm::Triple::hexagon: + case llvm::Triple::ppcle: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: case llvm::Triple::riscv64: @@ -1586,6 +1619,7 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple, break; case llvm::Triple::ppc: + case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: AddPPCTargetArgs(Args, CmdArgs); @@ -1719,6 +1753,21 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); } + + // Handle -msve_vector_bits=<bits> + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { + StringRef Val = A->getValue(); + const Driver &D = getToolChain().getDriver(); + if (Val.equals("128") || Val.equals("256") || Val.equals("512") || + Val.equals("1024") || Val.equals("2048")) + CmdArgs.push_back( + Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val)); + // Silently drop requests for vector-length agnostic code as it's implied. + else if (!Val.equals("scalable")) + // Handle the unsupported values passed to msve-vector-bits. + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, @@ -1872,17 +1921,6 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, if (T.isOSBinFormatELF()) { switch (getToolChain().getArch()) { case llvm::Triple::ppc64: { - // When targeting a processor that supports QPX, or if QPX is - // specifically enabled, default to using the ABI that supports QPX (so - // long as it is not specifically disabled). - bool HasQPX = false; - if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) - HasQPX = A->getValue() == StringRef("a2q"); - HasQPX = Args.hasFlag(options::OPT_mqpx, options::OPT_mno_qpx, HasQPX); - if (HasQPX) { - ABIName = "elfv1-qpx"; - break; - } if ((T.isOSFreeBSD() && T.getOSMajorVersion() >= 13) || T.isOSOpenBSD() || T.isMusl()) ABIName = "elfv2"; @@ -1974,6 +2012,20 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args, CmdArgs.push_back(ABIName.data()); SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs); + + std::string TuneCPU; + + if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) { + StringRef Name = A->getValue(); + + Name = llvm::RISCV::resolveTuneCPUAlias(Name, Triple.isArch64Bit()); + TuneCPU = std::string(Name); + } + + if (!TuneCPU.empty()) { + CmdArgs.push_back("-tune-cpu"); + CmdArgs.push_back(Args.MakeArgString(TuneCPU)); + } } void Clang::AddSparcTargetArgs(const ArgList &Args, @@ -2068,6 +2120,31 @@ void Clang::AddX86TargetArgs(const ArgList &Args, CmdArgs.push_back("soft"); CmdArgs.push_back("-mstack-alignment=4"); } + + // Handle -mtune. + + // Default to "generic" unless -march is present or targetting the PS4. + std::string TuneCPU; + if (!Args.hasArg(clang::driver::options::OPT_march_EQ) && + !getToolChain().getTriple().isPS4CPU()) + TuneCPU = "generic"; + + // Override based on -mtune. + if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)) { + StringRef Name = A->getValue(); + + if (Name == "native") { + Name = llvm::sys::getHostCPUName(); + if (!Name.empty()) + TuneCPU = std::string(Name); + } else + TuneCPU = std::string(Name); + } + + if (!TuneCPU.empty()) { + CmdArgs.push_back("-tune-cpu"); + CmdArgs.push_back(Args.MakeArgString(TuneCPU)); + } } void Clang::AddHexagonTargetArgs(const ArgList &Args, @@ -2770,9 +2847,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (TrappingMath) { // FP Exception Behavior is also set to strict assert(FPExceptionBehavior.equals("strict")); - CmdArgs.push_back("-ftrapping-math"); - } else if (TrappingMathPresent) - CmdArgs.push_back("-fno-trapping-math"); + } // The default is IEEE. if (DenormalFPMath != llvm::DenormalMode::getIEEE()) { @@ -2915,8 +2990,9 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs, Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer); } -static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs, bool KernelOrKext) { +static void RenderSSPOptions(const Driver &D, const ToolChain &TC, + const ArgList &Args, ArgStringList &CmdArgs, + bool KernelOrKext) { const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple(); // NVPTX doesn't support stack protectors; from the compiler's perspective, it @@ -2925,8 +3001,8 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args, return; // -stack-protector=0 is default. - unsigned StackProtectorLevel = 0; - unsigned DefaultStackProtectorLevel = + LangOptions::StackProtectorMode StackProtectorLevel = LangOptions::SSPOff; + LangOptions::StackProtectorMode DefaultStackProtectorLevel = TC.GetDefaultStackProtectorLevel(KernelOrKext); if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, @@ -2935,7 +3011,7 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args, options::OPT_fstack_protector)) { if (A->getOption().matches(options::OPT_fstack_protector)) StackProtectorLevel = - std::max<unsigned>(LangOptions::SSPOn, DefaultStackProtectorLevel); + std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel); else if (A->getOption().matches(options::OPT_fstack_protector_strong)) StackProtectorLevel = LangOptions::SSPStrong; else if (A->getOption().matches(options::OPT_fstack_protector_all)) @@ -2961,6 +3037,50 @@ static void RenderSSPOptions(const ToolChain &TC, const ArgList &Args, A->claim(); } } + + // First support "tls" and "global" for X86 target. + // TODO: Support "sysreg" for AArch64. + const std::string &TripleStr = EffectiveTriple.getTriple(); + if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) { + StringRef Value = A->getValue(); + if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + if (Value != "tls" && Value != "global") { + D.Diag(diag::err_drv_invalid_value_with_suggestion) + << A->getOption().getName() << Value + << "valid arguments to '-mstack-protector-guard=' are:tls global"; + return; + } + A->render(Args, CmdArgs); + } + + if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) { + StringRef Value = A->getValue(); + if (!EffectiveTriple.isX86()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + unsigned Offset; + if (Value.getAsInteger(10, Offset)) { + D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value; + return; + } + A->render(Args, CmdArgs); + } + + if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) { + StringRef Value = A->getValue(); + if (!EffectiveTriple.isX86()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) { + D.Diag(diag::err_drv_invalid_value_with_suggestion) + << A->getOption().getName() << Value + << "for X86, valid arguments to '-mstack-protector-guard-reg=' are:fs gs"; + return; + } + A->render(Args, CmdArgs); + } } static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args, @@ -3076,13 +3196,13 @@ static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args, switch (A->getOption().getID()) { default: llvm_unreachable("missed a case"); case options::OPT_ccc_arcmt_check: - CmdArgs.push_back("-arcmt-check"); + CmdArgs.push_back("-arcmt-action=check"); break; case options::OPT_ccc_arcmt_modify: - CmdArgs.push_back("-arcmt-modify"); + CmdArgs.push_back("-arcmt-action=modify"); break; case options::OPT_ccc_arcmt_migrate: - CmdArgs.push_back("-arcmt-migrate"); + CmdArgs.push_back("-arcmt-action=migrate"); CmdArgs.push_back("-mt-migrate-directory"); CmdArgs.push_back(A->getValue()); @@ -3265,6 +3385,9 @@ static void RenderModulesOptions(Compilation &C, const Driver &D, std::string("-fprebuilt-module-path=") + A->getValue())); A->claim(); } + if (Args.hasFlag(options::OPT_fprebuilt_implicit_modules, + options::OPT_fno_prebuilt_implicit_modules, false)) + CmdArgs.push_back("-fprebuilt-implicit-modules"); if (Args.hasFlag(options::OPT_fmodules_validate_input_files_content, options::OPT_fno_modules_validate_input_files_content, false)) @@ -3380,8 +3503,8 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T, } else { bool IsARM = T.isARM() || T.isThumb() || T.isAArch64(); CmdArgs.push_back("-fwchar-type=int"); - if (IsARM && !(T.isOSWindows() || T.isOSNetBSD() || - T.isOSOpenBSD())) + if (T.isOSzOS() || + (IsARM && !(T.isOSWindows() || T.isOSNetBSD() || T.isOSOpenBSD()))) CmdArgs.push_back("-fno-signed-wchar"); else CmdArgs.push_back("-fsigned-wchar"); @@ -3598,9 +3721,9 @@ enum class DwarfFissionKind { None, Split, Single }; static DwarfFissionKind getDebugFissionKind(const Driver &D, const ArgList &Args, Arg *&Arg) { - Arg = - Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ); - if (!Arg) + Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ, + options::OPT_gno_split_dwarf); + if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf)) return DwarfFissionKind::None; if (Arg->getOption().matches(options::OPT_gsplit_dwarf)) @@ -3617,9 +3740,10 @@ static DwarfFissionKind getDebugFissionKind(const Driver &D, return DwarfFissionKind::None; } -static void RenderDebugOptions(const ToolChain &TC, const Driver &D, +static void renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, const ArgList &Args, - bool EmitCodeView, ArgStringList &CmdArgs, + bool EmitCodeView, bool IRInput, + ArgStringList &CmdArgs, codegenoptions::DebugInfoKind &DebugInfoKind, DwarfFissionKind &DwarfFission) { if (Args.hasFlag(options::OPT_fdebug_info_for_profiling, @@ -3643,20 +3767,19 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, Args.hasFlag(options::OPT_fsplit_dwarf_inlining, options::OPT_fno_split_dwarf_inlining, false); - Args.ClaimAllArgs(options::OPT_g_Group); - - Arg* SplitDWARFArg; - DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg); - - if (DwarfFission != DwarfFissionKind::None && - !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) { - DwarfFission = DwarfFissionKind::None; - SplitDWARFInlining = false; + // Normally -gsplit-dwarf is only useful with -gN. For IR input, Clang does + // object file generation and no IR generation, -gN should not be needed. So + // allow -gsplit-dwarf with either -gN or IR input. + if (IRInput || Args.hasArg(options::OPT_g_Group)) { + Arg *SplitDWARFArg; + DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg); + if (DwarfFission != DwarfFissionKind::None && + !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) { + DwarfFission = DwarfFissionKind::None; + SplitDWARFInlining = false; + } } - - if (const Arg *A = - Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf, - options::OPT_gsplit_dwarf_EQ)) { + if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { DebugInfoKind = codegenoptions::LimitedDebugInfo; // If the last option explicitly specified a debug-info level, use it. @@ -3719,26 +3842,33 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, } } - unsigned DWARFVersion = 0; + unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user + unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may + // be lower than what the user wanted. unsigned DefaultDWARFVersion = ParseDebugDefaultVersion(TC, Args); if (EmitDwarf) { // Start with the platform default DWARF version - DWARFVersion = TC.GetDefaultDwarfVersion(); - assert(DWARFVersion && "toolchain default DWARF version must be nonzero"); + RequestedDWARFVersion = TC.GetDefaultDwarfVersion(); + assert(RequestedDWARFVersion && + "toolchain default DWARF version must be nonzero"); // If the user specified a default DWARF version, that takes precedence // over the platform default. if (DefaultDWARFVersion) - DWARFVersion = DefaultDWARFVersion; + RequestedDWARFVersion = DefaultDWARFVersion; // Override with a user-specified DWARF version if (GDwarfN) if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling())) - DWARFVersion = ExplicitVersion; + RequestedDWARFVersion = ExplicitVersion; + // Clamp effective DWARF version to the max supported by the toolchain. + EffectiveDWARFVersion = + std::min(RequestedDWARFVersion, TC.getMaxDwarfVersion()); } // -gline-directives-only supported only for the DWARF debug info. - if (DWARFVersion == 0 && DebugInfoKind == codegenoptions::DebugDirectivesOnly) + if (RequestedDWARFVersion == 0 && + DebugInfoKind == codegenoptions::DebugDirectivesOnly) DebugInfoKind = codegenoptions::NoDebugInfo; // We ignore flag -gstrict-dwarf for now. @@ -3782,8 +3912,14 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, TC.GetDefaultStandaloneDebug()); if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug)) (void)checkDebugInfoOption(A, Args, D, TC); - if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) - DebugInfoKind = codegenoptions::FullDebugInfo; + + if (DebugInfoKind == codegenoptions::LimitedDebugInfo) { + if (Args.hasFlag(options::OPT_fno_eliminate_unused_debug_types, + options::OPT_feliminate_unused_debug_types, false)) + DebugInfoKind = codegenoptions::UnusedTypeInfo; + else if (NeedFullDebug) + DebugInfoKind = codegenoptions::FullDebugInfo; + } if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, false)) { @@ -3792,9 +3928,15 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, // fallen back to the target default, so if this is still not at least 5 // we emit an error. const Arg *A = Args.getLastArg(options::OPT_gembed_source); - if (DWARFVersion < 5) + if (RequestedDWARFVersion < 5) D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) << "-gdwarf-5"; + else if (EffectiveDWARFVersion < 5) + // The toolchain has reduced allowed dwarf version, so we can't enable + // -gembed-source. + D.Diag(diag::warn_drv_dwarf_version_limited_by_target) + << A->getAsString(Args) << TC.getTripleString() << 5 + << EffectiveDWARFVersion; else if (checkDebugInfoOption(A, Args, D, TC)) CmdArgs.push_back("-gembed-source"); } @@ -3815,15 +3957,15 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, CmdArgs.push_back("-gno-inline-line-tables"); } - // Adjust the debug info kind for the given toolchain. - TC.adjustDebugInfoKind(DebugInfoKind, Args); - // When emitting remarks, we need at least debug lines in the output. if (willEmitRemarks(Args) && DebugInfoKind <= codegenoptions::DebugDirectivesOnly) DebugInfoKind = codegenoptions::DebugLineTablesOnly; - RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion, + // Adjust the debug info kind for the given toolchain. + TC.adjustDebugInfoKind(DebugInfoKind, Args); + + RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, EffectiveDWARFVersion, DebuggerTuning); // -fdebug-macro turns on macro debug info generation. @@ -3869,7 +4011,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, if (Args.hasFlag(options::OPT_fdebug_types_section, options::OPT_fno_debug_types_section, false)) { - if (!T.isOSBinFormatELF()) { + if (!(T.isOSBinFormatELF() || T.isOSBinFormatWasm())) { D.Diag(diag::err_drv_unsupported_opt_for_target) << Args.getLastArg(options::OPT_fdebug_types_section) ->getAsString(Args) @@ -3892,6 +4034,25 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, if (DebuggerTuning == llvm::DebuggerKind::SCE) CmdArgs.push_back("-dwarf-explicit-import"); + auto *DwarfFormatArg = + Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32); + if (DwarfFormatArg && + DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) { + const llvm::Triple &RawTriple = TC.getTriple(); + if (EffectiveDWARFVersion < 3) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater"; + else if (!RawTriple.isArch64Bit()) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "64 bit architecture"; + else if (!RawTriple.isOSBinFormatELF()) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "ELF platforms"; + } + + if (DwarfFormatArg) + DwarfFormatArg->render(Args, CmdArgs); + RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC); } @@ -4189,6 +4350,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.getLastArg(options::OPT_save_temps_EQ)) Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ); + auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile, + options::OPT_fmemory_profile_EQ, + options::OPT_fno_memory_profile); + if (MemProfArg && + !MemProfArg->getOption().matches(options::OPT_fno_memory_profile)) + MemProfArg->render(Args, CmdArgs); + // Embed-bitcode option. // Only white-listed flags below are allowed to be embedded. if (C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() && @@ -4302,9 +4470,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, II.getInputArg().renderAsInput(Args, CmdArgs); } - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(), - D.getClangProgramPath(), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileUTF8(), D.getClangProgramPath(), + CmdArgs, Inputs, Output)); return; } @@ -4433,12 +4601,31 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue()); } - // The default is -fno-semantic-interposition. We render it just because we - // require explicit -fno-semantic-interposition to infer dso_local. - if (Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition, - options::OPT_fno_semantic_interposition)) - if (RelocationModel != llvm::Reloc::Static && !IsPIE) - A->render(Args, CmdArgs); + // -fsemantic-interposition is forwarded to CC1: set the + // "SemanticInterposition" metadata to 1 (make some linkages interposable) and + // make default visibility external linkage definitions dso_preemptable. + // + // -fno-semantic-interposition: if the target supports .Lfoo$local local + // aliases (make default visibility external linkage definitions dso_local). + // This is the CC1 default for ELF to match COFF/Mach-O. + // + // Otherwise use Clang's traditional behavior: like + // -fno-semantic-interposition but local aliases are not used. So references + // can be interposed if not optimized out. + if (Triple.isOSBinFormatELF()) { + Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition, + options::OPT_fno_semantic_interposition); + if (RelocationModel != llvm::Reloc::Static && !IsPIE) { + // The supported targets need to call AsmPrinter::getSymbolPreferLocal. + bool SupportsLocalAlias = Triple.isX86(); + if (!A) + CmdArgs.push_back("-fhalf-no-semantic-interposition"); + else if (A->getOption().matches(options::OPT_fsemantic_interposition)) + A->render(Args, CmdArgs); + else if (!SupportsLocalAlias) + CmdArgs.push_back("-fhalf-no-semantic-interposition"); + } + } { std::string Model; @@ -4482,6 +4669,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (Triple.isOSAIX() && Args.hasArg(options::OPT_maltivec)) { + if (Args.getLastArg(options::OPT_mabi_EQ_vec_extabi)) { + CmdArgs.push_back("-mabi=vec-extabi"); + } else { + D.Diag(diag::err_aix_default_altivec_abi); + } + } + + if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ_vec_extabi, + options::OPT_mabi_EQ_vec_default)) { + if (!Triple.isOSAIX()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << RawTriple.str(); + if (A->getOption().getID() == options::OPT_mabi_EQ_vec_default) + D.Diag(diag::err_aix_default_altivec_abi); + } + if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) { StringRef v = A->getValue(); CmdArgs.push_back("-mllvm"); @@ -4508,7 +4712,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return, options::OPT_msvr4_struct_return)) { - if (TC.getArch() != llvm::Triple::ppc) { + if (!TC.getTriple().isPPC32()) { D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getSpelling() << RawTriple.str(); } else if (A->getOption().matches(options::OPT_maix_struct_return)) { @@ -4621,7 +4825,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) { if (TC.getTriple().isX86()) A->render(Args, CmdArgs); - else if ((TC.getArch() == llvm::Triple::ppc || TC.getTriple().isPPC64()) && + else if (TC.getTriple().isPPC() && (A->getOption().getID() != options::OPT_mlong_double_80)) A->render(Args, CmdArgs); else @@ -4636,6 +4840,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, IsIntegratedAssemblerDefault)) CmdArgs.push_back("-fno-verbose-asm"); + // Parse 'none' or '$major.$minor'. Disallow -fbinutils-version=0 because we + // use that to indicate the MC default in the backend. + if (Arg *A = Args.getLastArg(options::OPT_fbinutils_version_EQ)) { + StringRef V = A->getValue(); + unsigned Num; + if (V == "none") + A->render(Args, CmdArgs); + else if (!V.consumeInteger(10, Num) && Num > 0 && + (V.empty() || (V.consume_front(".") && + !V.consumeInteger(10, Num) && V.empty()))) + A->render(Args, CmdArgs); + else + D.Diag(diag::err_drv_invalid_argument_to_option) + << A->getValue() << A->getOption().getName(); + } + if (!TC.useIntegratedAs()) CmdArgs.push_back("-no-integrated-as"); @@ -4664,11 +4884,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-mms-bitfields"); } - if (Args.hasFlag(options::OPT_mpie_copy_relocations, - options::OPT_mno_pie_copy_relocations, - false)) { - CmdArgs.push_back("-mpie-copy-relocations"); - } + // Non-PIC code defaults to -fdirect-access-external-data while PIC code + // defaults to -fno-direct-access-external-data. Pass the option if different + // from the default. + if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data, + options::OPT_fno_direct_access_external_data)) + if (A->getOption().matches(options::OPT_fdirect_access_external_data) != + (PICLevel == 0)) + A->render(Args, CmdArgs); if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) { CmdArgs.push_back("-fno-plt"); @@ -4759,18 +4982,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (D.IsCLMode()) AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView); - DwarfFissionKind DwarfFission; - RenderDebugOptions(TC, D, RawTriple, Args, EmitCodeView, CmdArgs, - DebugInfoKind, DwarfFission); + DwarfFissionKind DwarfFission = DwarfFissionKind::None; + renderDebugOptions(TC, D, RawTriple, Args, EmitCodeView, + types::isLLVMIR(InputType), CmdArgs, DebugInfoKind, + DwarfFission); // Add the split debug info name to the command lines here so we // can propagate it to the backend. bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) && - TC.getTriple().isOSBinFormatELF() && + (TC.getTriple().isOSBinFormatELF() || + TC.getTriple().isOSBinFormatWasm()) && (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)); if (SplitDWARF) { - const char *SplitDWARFOut = SplitDebugName(Args, Input, Output); + const char *SplitDWARFOut = SplitDebugName(JA, Args, Input, Output); CmdArgs.push_back("-split-dwarf-file"); CmdArgs.push_back(SplitDWARFOut); if (DwarfFission == DwarfFissionKind::Split) { @@ -4841,17 +5066,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_sections_EQ)) { - StringRef Val = A->getValue(); - if (Val != "all" && Val != "labels" && Val != "none" && - !(Val.startswith("list=") && llvm::sys::fs::exists(Val.substr(5)))) - D.Diag(diag::err_drv_invalid_value) - << A->getAsString(Args) << A->getValue(); - else - A->render(Args, CmdArgs); + if (Triple.isX86() && Triple.isOSBinFormatELF()) { + StringRef Val = A->getValue(); + if (Val != "all" && Val != "labels" && Val != "none" && + !Val.startswith("list=")) + D.Diag(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + else + A->render(Args, CmdArgs); + } else { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + } } + bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF(); if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections, - UseSeparateSections)) { + UseSeparateSections || HasDefaultDataSections)) { CmdArgs.push_back("-fdata-sections"); } @@ -4867,6 +5098,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_unique_basic_block_section_names, false)) CmdArgs.push_back("-funique-basic-block-section-names"); + if (Arg *A = Args.getLastArg(options::OPT_fsplit_machine_functions, + options::OPT_fno_split_machine_functions)) { + // This codegen pass is only available on x86-elf targets. + if (Triple.isX86() && Triple.isOSBinFormatELF()) { + if (A->getOption().matches(options::OPT_fsplit_machine_functions)) + A->render(Args, CmdArgs); + } else { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + } + } + Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions, options::OPT_finstrument_functions_after_inlining, options::OPT_finstrument_function_entry_bare); @@ -5171,7 +5414,32 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (!RawTriple.isPS4()) + if (const Arg *A = + Args.getLastArg(options::OPT_fvisibility_from_dllstorageclass, + options::OPT_fno_visibility_from_dllstorageclass)) { + if (A->getOption().matches( + options::OPT_fvisibility_from_dllstorageclass)) { + CmdArgs.push_back("-fvisibility-from-dllstorageclass"); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_dllexport_EQ); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_nodllstorageclass_EQ); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_externs_dllimport_EQ); + Args.AddLastArg(CmdArgs, + options::OPT_fvisibility_externs_nodllstorageclass_EQ); + } + } + + if (const Arg *A = Args.getLastArg(options::OPT_mignore_xcoff_visibility)) { + if (Triple.isOSAIX()) + CmdArgs.push_back("-mignore-xcoff-visibility"); + else + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + } + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fno_visibility_inlines_hidden_static_local_var); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); @@ -5263,6 +5531,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, const XRayArgs &XRay = TC.getXRayArgs(); XRay.addArgs(TC, Args, CmdArgs, InputType); + for (const auto &Filename : + Args.getAllArgValues(options::OPT_fprofile_list_EQ)) { + if (D.getVFS().exists(Filename)) + CmdArgs.push_back(Args.MakeArgString("-fprofile-list=" + Filename)); + else + D.Diag(clang::diag::err_drv_no_such_file) << Filename; + } + if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) { StringRef S0 = A->getValue(), S = S0; unsigned Size, Offset = 0; @@ -5320,6 +5596,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); + Args.AddLastArg(CmdArgs, options::OPT_ftime_report_EQ); Args.AddLastArg(CmdArgs, options::OPT_ftime_trace); Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); @@ -5359,7 +5636,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_mno_speculative_load_hardening, false)) CmdArgs.push_back(Args.MakeArgString("-mspeculative-load-hardening")); - RenderSSPOptions(TC, Args, CmdArgs, KernelOrKext); + RenderSSPOptions(D, TC, Args, CmdArgs, KernelOrKext); RenderSCPOptions(TC, Args, CmdArgs); RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs); @@ -5406,9 +5683,26 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -cl options to -cc1 RenderOpenCLOptions(Args, CmdArgs); - if (IsHIP && Args.hasFlag(options::OPT_fhip_new_launch_api, - options::OPT_fno_hip_new_launch_api, true)) - CmdArgs.push_back("-fhip-new-launch-api"); + if (IsHIP) { + if (Args.hasFlag(options::OPT_fhip_new_launch_api, + options::OPT_fno_hip_new_launch_api, true)) + CmdArgs.push_back("-fhip-new-launch-api"); + if (Args.hasFlag(options::OPT_fgpu_allow_device_init, + options::OPT_fno_gpu_allow_device_init, false)) + CmdArgs.push_back("-fgpu-allow-device-init"); + } + + if (IsCuda || IsHIP) { + if (Args.hasFlag(options::OPT_fgpu_defer_diag, + options::OPT_fno_gpu_defer_diag, false)) + CmdArgs.push_back("-fgpu-defer-diag"); + if (Args.hasFlag(options::OPT_fgpu_exclude_wrong_side_overloads, + options::OPT_fno_gpu_exclude_wrong_side_overloads, + false)) { + CmdArgs.push_back("-fgpu-exclude-wrong-side-overloads"); + CmdArgs.push_back("-fgpu-defer-diag"); + } + } if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) { CmdArgs.push_back( @@ -5434,6 +5728,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddLastArg(CmdArgs, options::OPT_fprofile_remapping_file_EQ); + if (Args.hasFlag(options::OPT_fpseudo_probe_for_profiling, + options::OPT_fno_pseudo_probe_for_profiling, false)) + CmdArgs.push_back("-fpseudo-probe-for-profiling"); + RenderBuiltinOptions(TC, RawTriple, Args, CmdArgs); if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, @@ -5481,9 +5779,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, (RTTIMode == ToolChain::RM_Disabled))) CmdArgs.push_back("-fno-rtti"); - // -fshort-enums=0 is default for all architectures except Hexagon. + // -fshort-enums=0 is default for all architectures except Hexagon and z/OS. if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums, - TC.getArch() == llvm::Triple::hexagon)) + TC.getArch() == llvm::Triple::hexagon || Triple.isOSzOS())) CmdArgs.push_back("-fshort-enums"); RenderCharacterOptions(Args, AuxTriple ? *AuxTriple : RawTriple, CmdArgs); @@ -5557,7 +5855,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue()) .Case("c++14", "-std=c++14") .Case("c++17", "-std=c++17") - .Case("c++latest", "-std=c++2a") + .Case("c++latest", "-std=c++20") .Default(""); if (LanguageStandard.empty()) D.Diag(clang::diag::warn_drv_unused_argument) @@ -5620,7 +5918,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // FIXME: Find a better way to determine whether the language has modules // support by default, or just assume that all languages do. bool HaveModules = - Std && (Std->containsValue("c++2a") || Std->containsValue("c++latest")); + Std && (Std->containsValue("c++2a") || Std->containsValue("c++20") || + Std->containsValue("c++latest")); RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules); if (Args.hasFlag(options::OPT_fpch_validate_input_files_content, @@ -5636,8 +5935,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fmodules-debuginfo"); - Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, - options::OPT_fno_experimental_new_pass_manager); + Args.AddLastArg(CmdArgs, options::OPT_flegacy_pass_manager, + options::OPT_fno_legacy_pass_manager); ObjCRuntime Runtime = AddObjCRuntimeArgs(Args, Inputs, CmdArgs, rewriteKind); RenderObjCOptions(TC, D, RawTriple, Args, Runtime, rewriteKind != RK_None, @@ -5658,25 +5957,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (A) { const Option &Opt = A->getOption(); if (Opt.matches(options::OPT_fsjlj_exceptions)) - CmdArgs.push_back("-fsjlj-exceptions"); + CmdArgs.push_back("-exception-model=sjlj"); if (Opt.matches(options::OPT_fseh_exceptions)) - CmdArgs.push_back("-fseh-exceptions"); + CmdArgs.push_back("-exception-model=seh"); if (Opt.matches(options::OPT_fdwarf_exceptions)) - CmdArgs.push_back("-fdwarf-exceptions"); + CmdArgs.push_back("-exception-model=dwarf"); if (Opt.matches(options::OPT_fwasm_exceptions)) - CmdArgs.push_back("-fwasm-exceptions"); + CmdArgs.push_back("-exception-model=wasm"); } else { switch (TC.GetExceptionModel(Args)) { default: break; case llvm::ExceptionHandling::DwarfCFI: - CmdArgs.push_back("-fdwarf-exceptions"); + CmdArgs.push_back("-exception-model=dwarf"); break; case llvm::ExceptionHandling::SjLj: - CmdArgs.push_back("-fsjlj-exceptions"); + CmdArgs.push_back("-exception-model=sjlj"); break; case llvm::ExceptionHandling::WinEH: - CmdArgs.push_back("-fseh-exceptions"); + CmdArgs.push_back("-exception-model=seh"); break; } } @@ -5849,6 +6148,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_apple_pragma_pack, false)) CmdArgs.push_back("-fapple-pragma-pack"); + if (Args.hasFlag(options::OPT_fxl_pragma_pack, + options::OPT_fno_xl_pragma_pack, RawTriple.isOSAIX())) + CmdArgs.push_back("-fxl-pragma-pack"); + // Remarks can be enabled with any of the `-f.*optimization-record.*` flags. if (willEmitRemarks(Args) && checkRemarksOptions(D, Args, Triple)) renderRemarksOptions(Args, CmdArgs, Triple, Input, Output, JA); @@ -6030,6 +6333,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (Triple.isAMDGPU()) { + handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs); + + if (Args.hasFlag(options::OPT_munsafe_fp_atomics, + options::OPT_mno_unsafe_fp_atomics)) + CmdArgs.push_back("-munsafe-fp-atomics"); + } + // For all the host OpenMP offloading compile jobs we need to pass the targets // information using -fopenmp-targets= option. if (JA.isHostOffloading(Action::OFK_OpenMP)) { @@ -6153,35 +6464,32 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_cxx_static_destructors, true)) CmdArgs.push_back("-fno-c++-static-destructors"); - if (Arg *A = Args.getLastArg(options::OPT_moutline, - options::OPT_mno_outline)) { - if (A->getOption().matches(options::OPT_moutline)) { - // We only support -moutline in AArch64 and ARM targets right now. If - // we're not compiling for these, emit a warning and ignore the flag. - // Otherwise, add the proper mllvm flags. - if (!(Triple.isARM() || Triple.isThumb() || - Triple.getArch() == llvm::Triple::aarch64 || - Triple.getArch() == llvm::Triple::aarch64_32)) { - D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName(); + addMachineOutlinerArgs(D, Args, CmdArgs, Triple, /*IsLTO=*/false); + + if (Arg *A = Args.getLastArg(options::OPT_moutline_atomics, + options::OPT_mno_outline_atomics)) { + if (A->getOption().matches(options::OPT_moutline_atomics)) { + // Option -moutline-atomics supported for AArch64 target only. + if (!Triple.isAArch64()) { + D.Diag(diag::warn_drv_moutline_atomics_unsupported_opt) + << Triple.getArchName(); } else { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-enable-machine-outliner"); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("+outline-atomics"); } } else { - // Disable all outlining behaviour. - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-enable-machine-outliner=never"); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("-outline-atomics"); } } if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig, (TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSBinFormatCOFF()) && - !TC.getTriple().isPS4() && - !TC.getTriple().isOSNetBSD() && - !Distro(D.getVFS(), TC.getTriple()).IsGentoo() && - !TC.getTriple().isAndroid() && - TC.useIntegratedAs())) + !TC.getTriple().isPS4() && !TC.getTriple().isVE() && + !TC.getTriple().isOSNetBSD() && + !Distro(D.getVFS(), TC.getTriple()).IsGentoo() && + !TC.getTriple().isAndroid() && TC.useIntegratedAs())) CmdArgs.push_back("-faddrsig"); if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) { @@ -6234,20 +6542,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput); C.addCommand(std::make_unique<FallbackCommand>( JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs, - std::move(CLCommand))); + Output, std::move(CLCommand))); } else if (Args.hasArg(options::OPT__SLASH_fallback) && isa<PrecompileJobAction>(JA)) { // In /fallback builds, run the main compilation even if the pch generation // fails, so that the main compilation's fallback to cl.exe runs. C.addCommand(std::make_unique<ForceSuccessCommand>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs, + Output)); } else if (D.CC1Main && !D.CCGenDiagnostics) { // Invoke the CC1 directly in this process - C.addCommand(std::make_unique<CC1Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<CC1Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } else { - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } // Make the compile command echo its inputs for /showFilenames. @@ -6562,10 +6873,9 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong))); } - // Emit CodeView if -Z7, -Zd, or -gline-tables-only are present. - if (Arg *DebugInfoArg = - Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd, - options::OPT_gline_tables_only)) { + // Emit CodeView if -Z7 or -gline-tables-only are present. + if (Arg *DebugInfoArg = Args.getLastArg(options::OPT__SLASH_Z7, + options::OPT_gline_tables_only)) { *EmitCodeView = true; if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7)) *DebugInfoKind = codegenoptions::LimitedDebugInfo; @@ -6951,6 +7261,15 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, } break; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + case llvm::Triple::aarch64_be: + if (Args.hasArg(options::OPT_mmark_bti_property)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-aarch64-mark-bti-property"); + } + break; + case llvm::Triple::riscv32: case llvm::Triple::riscv64: AddRISCVTargetArgs(Args, CmdArgs); @@ -6978,15 +7297,26 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, if (getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split && T.isOSBinFormatELF()) { CmdArgs.push_back("-split-dwarf-output"); - CmdArgs.push_back(SplitDebugName(Args, Input, Output)); + CmdArgs.push_back(SplitDebugName(JA, Args, Input, Output)); } + if (Triple.isAMDGPU()) + handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs); + assert(Input.isFilename() && "Invalid input."); CmdArgs.push_back(Input.getFilename()); const char *Exec = getToolChain().getDriver().getClangProgramPath(); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + if (D.CC1Main && !D.CCGenDiagnostics) { + // Invoke cc1as directly in this process. + C.addCommand(std::make_unique<CC1Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); + } else { + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); + } } // Begin OffloadBundler @@ -7072,7 +7402,7 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(std::make_unique<Command>( JA, *this, ResponseFileSupport::None(), TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())), - CmdArgs, None)); + CmdArgs, None, Output)); } void OffloadBundler::ConstructJobMultipleOutputs( @@ -7133,12 +7463,13 @@ void OffloadBundler::ConstructJobMultipleOutputs( } CmdArgs.push_back(TCArgs.MakeArgString(UB)); CmdArgs.push_back("-unbundle"); + CmdArgs.push_back("-allow-missing-bundles"); // All the inputs are encoded as commands. C.addCommand(std::make_unique<Command>( JA, *this, ResponseFileSupport::None(), TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())), - CmdArgs, None)); + CmdArgs, None, Outputs)); } void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA, @@ -7168,5 +7499,5 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(std::make_unique<Command>( JA, *this, ResponseFileSupport::None(), Args.MakeArgString(getToolChain().GetProgramPath(getShortName())), - CmdArgs, Inputs)); + CmdArgs, Inputs, Output)); } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CloudABI.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CloudABI.cpp index 8dcfd4951bbf..3efca8776260 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CloudABI.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CloudABI.cpp @@ -92,8 +92,9 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } // CloudABI - CloudABI tool chain which can call ld(1) directly. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp index 535154e492a7..6a95aa5ec628 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -37,6 +37,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -60,6 +61,62 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; +static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs) { + if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ)) + CmdArgs.push_back(Args.MakeArgString(Twine("--plugin-opt=-pass-remarks=") + + A->getValue())); + + if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ)) + CmdArgs.push_back(Args.MakeArgString( + Twine("--plugin-opt=-pass-remarks-missed=") + A->getValue())); + + if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ)) + CmdArgs.push_back(Args.MakeArgString( + Twine("--plugin-opt=-pass-remarks-analysis=") + A->getValue())); +} + +static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, + const llvm::Triple &Triple, + const InputInfo &Input, + const InputInfo &Output) { + StringRef Format = "yaml"; + if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) + Format = A->getValue(); + + SmallString<128> F; + const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ); + if (A) + F = A->getValue(); + else if (Output.isFilename()) + F = Output.getFilename(); + + assert(!F.empty() && "Cannot determine remarks output name."); + // Append "opt.ld.<format>" to the end of the file name. + CmdArgs.push_back( + Args.MakeArgString(Twine("--plugin-opt=opt-remarks-filename=") + F + + Twine(".opt.ld.") + Format)); + + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) + CmdArgs.push_back(Args.MakeArgString( + Twine("--plugin-opt=opt-remarks-passes=") + A->getValue())); + + CmdArgs.push_back(Args.MakeArgString( + Twine("--plugin-opt=opt-remarks-format=") + Format.data())); +} + +static void renderRemarksHotnessOptions(const ArgList &Args, + ArgStringList &CmdArgs) { + if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness, + options::OPT_fno_diagnostics_show_hotness, false)) + CmdArgs.push_back("--plugin-opt=opt-remarks-with-hotness"); + + if (const Arg *A = + Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) + CmdArgs.push_back(Args.MakeArgString( + Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue())); +} + void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { if (D.getVFS().exists(Path)) @@ -244,11 +301,12 @@ void tools::AddTargetFeature(const ArgList &Args, } } -/// Get the (LLVM) name of the R600 gpu we are targeting. -static std::string getR600TargetGPU(const ArgList &Args) { +/// Get the (LLVM) name of the AMDGPU gpu we are targeting. +static std::string getAMDGPUTargetGPU(const llvm::Triple &T, + const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { - const char *GPUName = A->getValue(); - return llvm::StringSwitch<const char *>(GPUName) + auto GPUName = getProcessorFromTargetID(T, A->getValue()); + return llvm::StringSwitch<std::string>(GPUName) .Cases("rv630", "rv635", "r600") .Cases("rv610", "rv620", "rs780", "rs880") .Case("rv740", "rv770") @@ -256,7 +314,7 @@ static std::string getR600TargetGPU(const ArgList &Args) { .Cases("sumo", "sumo2", "sumo") .Case("hemlock", "cypress") .Case("aruba", "cayman") - .Default(GPUName); + .Default(GPUName.str()); } return ""; } @@ -331,6 +389,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, return ""; case llvm::Triple::ppc: + case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: { std::string TargetCPUName = ppc::getPPCTargetCPU(Args); @@ -364,6 +423,8 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, case llvm::Triple::sparcv9: if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) return A->getValue(); + if (T.getArch() == llvm::Triple::sparc && T.isOSSolaris()) + return "v9"; return ""; case llvm::Triple::x86: @@ -382,7 +443,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, case llvm::Triple::r600: case llvm::Triple::amdgcn: - return getR600TargetGPU(Args); + return getAMDGPUTargetGPU(T, Args); case llvm::Triple::wasm32: case llvm::Triple::wasm64: @@ -535,11 +596,13 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, Path)); } - // Need this flag to turn on new pass manager via Gold plugin. - if (Args.hasFlag(options::OPT_fexperimental_new_pass_manager, - options::OPT_fno_experimental_new_pass_manager, - /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER)) { - CmdArgs.push_back("-plugin-opt=new-pass-manager"); + // Pass an option to enable/disable the new pass manager. + if (auto *A = Args.getLastArg(options::OPT_flegacy_pass_manager, + options::OPT_fno_legacy_pass_manager)) { + if (A->getOption().matches(options::OPT_flegacy_pass_manager)) + CmdArgs.push_back("-plugin-opt=legacy-pass-manager"); + else + CmdArgs.push_back("-plugin-opt=new-pass-manager"); } // Setup statistics file output. @@ -549,6 +612,21 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile)); addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true); + + // Handle remark diagnostics on screen options: '-Rpass-*'. + renderRpassOptions(Args, CmdArgs); + + // Handle serialized remarks options: '-fsave-optimization-record' + // and '-foptimization-record-*'. + if (willEmitRemarks(Args)) + renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input, + Output); + + // Handle remarks hotness/threshold related options. + renderRemarksHotnessOptions(Args, CmdArgs); + + addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(), + /*IsLTO=*/true); } void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args, @@ -648,6 +726,16 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, return false; } +static const char *getAsNeededOption(const ToolChain &TC, bool as_needed) { + // While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases + // for the native forms -z ignore/-z record, they are missing in Illumos, + // so always use the native form. + if (TC.getTriple().isOSSolaris()) + return as_needed ? "-zignore" : "-zrecord"; + else + return as_needed ? "--as-needed" : "--no-as-needed"; +} + void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { // Fuchsia never needs these. Any sanitizer runtimes with system @@ -657,7 +745,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, // Force linking against the system libraries sanitizers depends on // (see PR15823 why this is necessary). - CmdArgs.push_back("--no-as-needed"); + CmdArgs.push_back(getAsNeededOption(TC, false)); // There's no libpthread or librt on RTEMS & Android. if (TC.getTriple().getOS() != llvm::Triple::RTEMS && !TC.getTriple().isAndroid()) { @@ -693,6 +781,11 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid()) HelperStaticRuntimes.push_back("asan-preinit"); } + if (SanArgs.needsMemProfRt() && SanArgs.linkRuntimes()) { + SharedRuntimes.push_back("memprof"); + if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid()) + HelperStaticRuntimes.push_back("memprof-preinit"); + } if (SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { if (SanArgs.requiresMinimalRuntime()) SharedRuntimes.push_back("ubsan_minimal"); @@ -705,6 +798,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, else SharedRuntimes.push_back("scudo"); } + if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) + SharedRuntimes.push_back("tsan"); if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) SharedRuntimes.push_back("hwasan"); } @@ -728,6 +823,13 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } + if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt() && + SanArgs.linkRuntimes()) { + StaticRuntimes.push_back("memprof"); + if (SanArgs.linkCXXRuntimes()) + StaticRuntimes.push_back("memprof_cxx"); + } + if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { StaticRuntimes.push_back("hwasan"); if (SanArgs.linkCXXRuntimes()) @@ -742,7 +844,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("msan_cxx"); } - if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt() && + SanArgs.linkRuntimes()) { StaticRuntimes.push_back("tsan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); @@ -802,8 +905,18 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, !Args.hasArg(options::OPT_shared)) { addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true); - if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) + if (SanArgs.needsFuzzerInterceptors()) + addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false, + true); + if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) { + bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && + !Args.hasArg(options::OPT_static); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bstatic"); TC.AddCXXStdlibLibArgs(Args, CmdArgs); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bdynamic"); + } } for (auto RT : SharedRuntimes) @@ -851,7 +964,7 @@ bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringLis } void tools::linkXRayRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { - CmdArgs.push_back("--no-as-needed"); + CmdArgs.push_back(getAsNeededOption(TC, false)); CmdArgs.push_back("-lpthread"); if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); @@ -871,8 +984,14 @@ bool tools::areOptimizationsEnabled(const ArgList &Args) { return false; } -const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input, +const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args, + const InputInfo &Input, const InputInfo &Output) { + auto AddPostfix = [JA](auto &F) { + if (JA.getOffloadingDeviceKind() == Action::OFK_HIP) + F += (Twine("_") + JA.getOffloadingArch()).str(); + F += ".dwo"; + }; if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ)) if (StringRef(A->getValue()) == "single") return Args.MakeArgString(Output.getFilename()); @@ -880,14 +999,16 @@ const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input, Arg *FinalOutput = Args.getLastArg(options::OPT_o); if (FinalOutput && Args.hasArg(options::OPT_c)) { SmallString<128> T(FinalOutput->getValue()); - llvm::sys::path::replace_extension(T, "dwo"); + llvm::sys::path::remove_filename(T); + llvm::sys::path::append(T, llvm::sys::path::stem(FinalOutput->getValue())); + AddPostfix(T); return Args.MakeArgString(T); } else { // Use the compilation dir. SmallString<128> T( Args.getLastArgValue(options::OPT_fdebug_compilation_dir)); SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput())); - llvm::sys::path::replace_extension(F, "dwo"); + AddPostfix(F); T += F; return Args.MakeArgString(F); } @@ -912,12 +1033,13 @@ void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename()); // First extract the dwo sections. - C.addCommand(std::make_unique<Command>( - JA, T, ResponseFileSupport::AtFileCurCP(), Exec, ExtractArgs, II)); + C.addCommand(std::make_unique<Command>(JA, T, + ResponseFileSupport::AtFileCurCP(), + Exec, ExtractArgs, II, Output)); // Then remove them from the original .o file. C.addCommand(std::make_unique<Command>( - JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II)); + JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II, Output)); } // Claim options we don't want to warn if they are unused. We do this for @@ -1018,8 +1140,6 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { break; case llvm::Triple::ppc: - case llvm::Triple::sparc: - case llvm::Triple::sparcel: case llvm::Triple::sparcv9: IsPICLevelTwo = true; // "-fPIE" break; @@ -1276,7 +1396,7 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc && !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing(); if (AsNeeded) - CmdArgs.push_back("--as-needed"); + CmdArgs.push_back(getAsNeededOption(TC, true)); switch (UNW) { case ToolChain::UNW_None: @@ -1304,7 +1424,7 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, } if (AsNeeded) - CmdArgs.push_back("--no-as-needed"); + CmdArgs.push_back(getAsNeededOption(TC, false)); } static void AddLibgcc(const ToolChain &TC, const Driver &D, @@ -1428,3 +1548,77 @@ void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args, } } } + +unsigned tools::getOrCheckAMDGPUCodeObjectVersion( + const Driver &D, const llvm::opt::ArgList &Args, bool Diagnose) { + const unsigned MinCodeObjVer = 2; + const unsigned MaxCodeObjVer = 4; + unsigned CodeObjVer = 3; + + // Emit warnings for legacy options even if they are overridden. + if (Diagnose) { + if (Args.hasArg(options::OPT_mno_code_object_v3_legacy)) + D.Diag(diag::warn_drv_deprecated_arg) << "-mno-code-object-v3" + << "-mcode-object-version=2"; + + if (Args.hasArg(options::OPT_mcode_object_v3_legacy)) + D.Diag(diag::warn_drv_deprecated_arg) << "-mcode-object-v3" + << "-mcode-object-version=3"; + } + + // The last of -mcode-object-v3, -mno-code-object-v3 and + // -mcode-object-version=<version> wins. + if (auto *CodeObjArg = + Args.getLastArg(options::OPT_mcode_object_v3_legacy, + options::OPT_mno_code_object_v3_legacy, + options::OPT_mcode_object_version_EQ)) { + if (CodeObjArg->getOption().getID() == + options::OPT_mno_code_object_v3_legacy) { + CodeObjVer = 2; + } else if (CodeObjArg->getOption().getID() == + options::OPT_mcode_object_v3_legacy) { + CodeObjVer = 3; + } else { + auto Remnant = + StringRef(CodeObjArg->getValue()).getAsInteger(0, CodeObjVer); + if (Diagnose && + (Remnant || CodeObjVer < MinCodeObjVer || CodeObjVer > MaxCodeObjVer)) + D.Diag(diag::err_drv_invalid_int_value) + << CodeObjArg->getAsString(Args) << CodeObjArg->getValue(); + } + } + return CodeObjVer; +} + +void tools::addMachineOutlinerArgs(const Driver &D, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + const llvm::Triple &Triple, bool IsLTO) { + auto addArg = [&, IsLTO](const Twine &Arg) { + if (IsLTO) { + CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg)); + } else { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(Arg)); + } + }; + + if (Arg *A = Args.getLastArg(options::OPT_moutline, + options::OPT_mno_outline)) { + if (A->getOption().matches(options::OPT_moutline)) { + // We only support -moutline in AArch64 and ARM targets right now. If + // we're not compiling for these, emit a warning and ignore the flag. + // Otherwise, add the proper mllvm flags. + if (!(Triple.isARM() || Triple.isThumb() || + Triple.getArch() == llvm::Triple::aarch64 || + Triple.getArch() == llvm::Triple::aarch64_32)) { + D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName(); + } else { + addArg(Twine("-enable-machine-outliner")); + } + } else { + // Disable all outlining behaviour. + addArg(Twine("-enable-machine-outliner=never")); + } + } +} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.h index 0028ea0ca337..187c340d1c3c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.h @@ -49,7 +49,7 @@ void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args); -const char *SplitDebugName(const llvm::opt::ArgList &Args, +const char *SplitDebugName(const JobAction &JA, const llvm::opt::ArgList &Args, const InputInfo &Input, const InputInfo &Output); void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, @@ -137,6 +137,14 @@ void addMultilibFlag(bool Enabled, const char *const Flag, void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool IsLTO); + +unsigned getOrCheckAMDGPUCodeObjectVersion(const Driver &D, + const llvm::opt::ArgList &Args, + bool Diagnose = false); + +void addMachineOutlinerArgs(const Driver &D, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + const llvm::Triple &Triple, bool IsLTO); } // end namespace tools } // end namespace driver } // end namespace clang diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.cpp index 127a8a5f24cc..07abf4f83f7d 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.cpp @@ -58,7 +58,7 @@ void tools::CrossWindows::Assembler::ConstructJob( Exec = Args.MakeArgString(Assembler); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void tools::CrossWindows::Linker::ConstructJob( @@ -203,8 +203,9 @@ void tools::CrossWindows::Linker::ConstructJob( Exec = Args.MakeArgString(TC.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D, @@ -270,10 +271,10 @@ AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, } void CrossWindowsToolChain:: -AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const { - if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) - CC1Args.push_back("-lc++"); +AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + if (GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) + CmdArgs.push_back("-lc++"); } clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.h index df9a7f71bf9f..ffe75332c2e8 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CrossWindows.h @@ -11,6 +11,7 @@ #include "Cuda.h" #include "Gnu.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -59,8 +60,9 @@ public: bool isPIEDefault() const override; bool isPICDefaultForced() const override; - unsigned int GetDefaultStackProtectorLevel(bool KernelOrKext) const override { - return 0; + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + return LangOptions::SSPOff; } void diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp index ffc606dd554b..d14776c5f5ba 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp @@ -326,13 +326,13 @@ void CudaInstallationDetector::AddCudaIncludeArgs( void CudaInstallationDetector::CheckCudaVersionSupportsArch( CudaArch Arch) const { if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN || - ArchsWithBadVersion.count(Arch) > 0) + ArchsWithBadVersion[(int)Arch]) return; auto MinVersion = MinVersionForCudaArch(Arch); auto MaxVersion = MaxVersionForCudaArch(Arch); if (Version < MinVersion || Version > MaxVersion) { - ArchsWithBadVersion.insert(Arch); + ArchsWithBadVersion[(int)Arch] = true; D.Diag(diag::err_drv_cuda_version_unsupported) << CudaArchToString(Arch) << CudaVersionToString(MinVersion) << CudaVersionToString(MaxVersion) << InstallPath @@ -384,7 +384,7 @@ static DeviceDebugInfoLevel mustEmitDebugInfo(const ArgList &Args) { } return IsDebugEnabled ? EmitSameDebugInfoAsHost : DebugDirectivesOnly; } - return DisableDebugInfo; + return willEmitRemarks(Args) ? DebugDirectivesOnly : DisableDebugInfo; } void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, @@ -494,7 +494,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, JA, *this, ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, "--options-file"}, - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } static bool shouldIncludePTX(const ArgList &Args, const char *gpu_arch) { @@ -563,7 +563,7 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, JA, *this, ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, "--options-file"}, - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, @@ -600,11 +600,6 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-arch"); CmdArgs.push_back(Args.MakeArgString(GPUArch)); - // Assume that the directory specified with --libomptarget_nvptx_path - // contains the static library libomptarget-nvptx.a. - if (const Arg *A = Args.getLastArg(options::OPT_libomptarget_nvptx_path_EQ)) - CmdArgs.push_back(Args.MakeArgString(Twine("-L") + A->getValue())); - // Add paths specified in LIBRARY_PATH environment variable as -L options. addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); @@ -614,9 +609,6 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, llvm::sys::path::append(DefaultLibPath, "lib" CLANG_LIBDIR_SUFFIX); CmdArgs.push_back(Args.MakeArgString(Twine("-L") + DefaultLibPath)); - // Add linking against library implementing OpenMP calls on NVPTX target. - CmdArgs.push_back("-lomptarget-nvptx"); - for (const auto &II : Inputs) { if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || @@ -644,7 +636,7 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, JA, *this, ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, "--options-file"}, - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } /// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary, @@ -720,33 +712,30 @@ void CudaToolChain::addClangTargetOptions( CC1Args.push_back("-mlink-builtin-bitcode"); CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile)); + std::string CudaVersionStr; + // New CUDA versions often introduce new instructions that are only supported // by new PTX version, so we need to raise PTX level to enable them in NVPTX // back-end. const char *PtxFeature = nullptr; switch (CudaInstallation.version()) { - case CudaVersion::CUDA_110: - PtxFeature = "+ptx70"; - break; - case CudaVersion::CUDA_102: - PtxFeature = "+ptx65"; - break; - case CudaVersion::CUDA_101: - PtxFeature = "+ptx64"; - break; - case CudaVersion::CUDA_100: - PtxFeature = "+ptx63"; - break; - case CudaVersion::CUDA_92: - PtxFeature = "+ptx61"; - break; - case CudaVersion::CUDA_91: - PtxFeature = "+ptx61"; - break; - case CudaVersion::CUDA_90: - PtxFeature = "+ptx60"; +#define CASE_CUDA_VERSION(CUDA_VER, PTX_VER) \ + case CudaVersion::CUDA_##CUDA_VER: \ + CudaVersionStr = #CUDA_VER; \ + PtxFeature = "+ptx" #PTX_VER; \ break; + CASE_CUDA_VERSION(110, 70); + CASE_CUDA_VERSION(102, 65); + CASE_CUDA_VERSION(101, 64); + CASE_CUDA_VERSION(100, 63); + CASE_CUDA_VERSION(92, 61); + CASE_CUDA_VERSION(91, 61); + CASE_CUDA_VERSION(90, 60); +#undef CASE_CUDA_VERSION default: + // If unknown CUDA version, we take it as CUDA 8.0. Same assumption is also + // made in libomptarget/deviceRTLs. + CudaVersionStr = "80"; PtxFeature = "+ptx42"; } CC1Args.append({"-target-feature", PtxFeature}); @@ -761,9 +750,6 @@ void CudaToolChain::addClangTargetOptions( if (DeviceOffloadingKind == Action::OFK_OpenMP) { SmallVector<StringRef, 8> LibraryPaths; - if (const Arg *A = DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_path_EQ)) - LibraryPaths.push_back(A->getValue()); - // Add user defined library paths from LIBRARY_PATH. llvm::Optional<std::string> LibPath = llvm::sys::Process::GetEnv("LIBRARY_PATH"); @@ -781,22 +767,38 @@ void CudaToolChain::addClangTargetOptions( llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX); LibraryPaths.emplace_back(DefaultLibPath.c_str()); - std::string LibOmpTargetName = - "libomptarget-nvptx-" + GpuArch.str() + ".bc"; - bool FoundBCLibrary = false; - for (StringRef LibraryPath : LibraryPaths) { - SmallString<128> LibOmpTargetFile(LibraryPath); - llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName); - if (llvm::sys::fs::exists(LibOmpTargetFile)) { + // First check whether user specifies bc library + if (const Arg *A = + DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_bc_path_EQ)) { + std::string LibOmpTargetName(A->getValue()); + if (llvm::sys::fs::exists(LibOmpTargetName)) { CC1Args.push_back("-mlink-builtin-bitcode"); - CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile)); - FoundBCLibrary = true; - break; + CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetName)); + } else { + getDriver().Diag(diag::err_drv_omp_offload_target_bcruntime_not_found) + << LibOmpTargetName; + } + } else { + bool FoundBCLibrary = false; + + std::string LibOmpTargetName = "libomptarget-nvptx-cuda_" + + CudaVersionStr + "-" + GpuArch.str() + + ".bc"; + + for (StringRef LibraryPath : LibraryPaths) { + SmallString<128> LibOmpTargetFile(LibraryPath); + llvm::sys::path::append(LibOmpTargetFile, LibOmpTargetName); + if (llvm::sys::fs::exists(LibOmpTargetFile)) { + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(LibOmpTargetFile)); + FoundBCLibrary = true; + break; + } } + if (!FoundBCLibrary) + getDriver().Diag(diag::err_drv_omp_offload_target_missingbcruntime) + << LibOmpTargetName; } - if (!FoundBCLibrary) - getDriver().Diag(diag::warn_drv_omp_offload_target_missingbcruntime) - << LibOmpTargetName; } } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.h index bbf272c468a5..6ae4415a563a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.h @@ -15,9 +15,9 @@ #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/VersionTuple.h" +#include <bitset> #include <set> #include <vector> @@ -41,7 +41,7 @@ private: // CUDA architectures for which we have raised an error in // CheckCudaVersionSupportsArch. - mutable llvm::SmallSet<CudaArch, 4> ArchsWithBadVersion; + mutable std::bitset<(int)CudaArch::LAST> ArchsWithBadVersion; public: CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, @@ -185,6 +185,8 @@ public: const llvm::opt::ArgList &Args) const override; unsigned GetDefaultDwarfVersion() const override { return 2; } + // NVPTX supports only DWARF2. + unsigned getMaxDwarfVersion() const override { return 2; } const ToolChain &HostTC; CudaInstallationDetector CudaInstallation; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.cpp index 7b879f8cb652..eb7bd4aec898 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Darwin.h" +#include "Arch/AArch64.h" #include "Arch/ARM.h" #include "CommonArgs.h" #include "clang/Basic/AlignedAllocation.h" @@ -58,7 +59,7 @@ llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) { .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm) .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm) .Cases("armv7s", "xscale", llvm::Triple::arm) - .Case("arm64", llvm::Triple::aarch64) + .Cases("arm64", "arm64e", llvm::Triple::aarch64) .Case("arm64_32", llvm::Triple::aarch64_32) .Case("r600", llvm::Triple::r600) .Case("amdgcn", llvm::Triple::amdgcn) @@ -74,7 +75,7 @@ void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) { llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Str); T.setArch(Arch); - if (Str == "x86_64h") + if (Str == "x86_64h" || Str == "arm64e") T.setArchName(Str); else if (ArchKind == llvm::ARM::ArchKind::ARMV6M || ArchKind == llvm::ARM::ArchKind::ARMV7M || @@ -149,7 +150,7 @@ void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void darwin::MachOTool::anchor() {} @@ -204,15 +205,19 @@ static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, const InputInfoList &Inputs, - unsigned Version[5]) const { + unsigned Version[5], bool LinkerIsLLD, + bool LinkerIsLLDDarwinNew) const { const Driver &D = getToolChain().getDriver(); const toolchains::MachO &MachOTC = getMachOToolChain(); // Newer linkers support -demangle. Pass it if supported and not disabled by // the user. - if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) + if ((Version[0] >= 100 || LinkerIsLLD) && + !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) CmdArgs.push_back("-demangle"); + // FIXME: Pass most of the flags below that check Version if LinkerIsLLD too. + if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137) CmdArgs.push_back("-export_dynamic"); @@ -249,7 +254,9 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, // Since this is passed unconditionally, ld64 will never look for libLTO.dylib // next to it. That's ok since ld64 using a libLTO.dylib not matching the // clang version won't work anyways. - if (Version[0] >= 133) { + // lld is built at the same revision as clang and statically links in + // LLVM libraries, so it doesn't need libLTO.dylib. + if (Version[0] >= 133 && !LinkerIsLLD) { // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib StringRef P = llvm::sys::path::parent_path(D.Dir); SmallString<128> LibLTOPath(P); @@ -332,7 +339,7 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, Args.AddAllArgs(CmdArgs, options::OPT_init); // Add the deployment target. - if (Version[0] >= 520) + if (Version[0] >= 520 || LinkerIsLLDDarwinNew) MachOTC.addPlatformVersionArgs(Args, CmdArgs); else MachOTC.addMinVersionArgs(Args, CmdArgs); @@ -522,7 +529,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetProgramPath("touch")); CmdArgs.push_back(Output.getFilename()); C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::None(), Exec, CmdArgs, None)); + JA, *this, ResponseFileSupport::None(), Exec, CmdArgs, None, Output)); return; } @@ -533,9 +540,14 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, << A->getAsString(Args); } + bool LinkerIsLLD, LinkerIsLLDDarwinNew; + const char *Exec = Args.MakeArgString( + getToolChain().GetLinkerPath(&LinkerIsLLD, &LinkerIsLLDDarwinNew)); + // I'm not sure why this particular decomposition exists in gcc, but // we follow suite for ease of comparison. - AddLinkArgs(C, Args, CmdArgs, Inputs, Version); + AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD, + LinkerIsLLDDarwinNew); if (willEmitRemarks(Args) && checkRemarksOptions(getToolChain().getDriver(), Args, @@ -686,16 +698,20 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } - ResponseFileSupport ResponseSupport = ResponseFileSupport::AtFileUTF8(); - if (Version[0] < 607) { + ResponseFileSupport ResponseSupport; + if (LinkerIsLLDDarwinNew) { + // Xcode12's ld64 added support for @response files, but it's crashy: + // https://openradar.appspot.com/radar?id=4933317065441280 + // FIXME: Pass this for ld64 once it no longer crashes. + ResponseSupport = ResponseFileSupport::AtFileUTF8(); + } else { // For older versions of the linker, use the legacy filelist method instead. ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8, "-filelist"}; } - const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); std::unique_ptr<Command> Cmd = std::make_unique<Command>( - JA, *this, ResponseSupport, Exec, CmdArgs, Inputs); + JA, *this, ResponseSupport, Exec, CmdArgs, Inputs, Output); Cmd->setInputFileList(std::move(InputFileList)); C.addCommand(std::move(Cmd)); } @@ -720,7 +736,7 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, @@ -741,7 +757,7 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, @@ -765,7 +781,7 @@ void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) @@ -884,8 +900,11 @@ StringRef MachO::getMachOArchName(const ArgList &Args) const { case llvm::Triple::aarch64_32: return "arm64_32"; - case llvm::Triple::aarch64: + case llvm::Triple::aarch64: { + if (getTriple().isArm64e()) + return "arm64e"; return "arm64"; + } case llvm::Triple::thumb: case llvm::Triple::arm: @@ -996,6 +1015,9 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args, return; if (isTargetAppleSiliconMac()) return; + // ARC runtime is supported everywhere on arm64e. + if (getTriple().isArm64e()) + return; ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); @@ -1062,10 +1084,9 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, DarwinLibName += Component; if (!(Opts & RLO_IsEmbedded)) DarwinLibName += "_"; - DarwinLibName += getOSLibraryNameSuffix(); - } else - DarwinLibName += getOSLibraryNameSuffix(true); + } + DarwinLibName += getOSLibraryNameSuffix(); DarwinLibName += IsShared ? "_dynamic.dylib" : ".a"; SmallString<128> Dir(getDriver().ResourceDir); llvm::sys::path::append( @@ -1196,8 +1217,8 @@ void Darwin::addProfileRTLibs(const ArgList &Args, // runtime's functionality. if (hasExportSymbolDirective(Args)) { if (ForGCOV) { - addExportedSymbol(CmdArgs, "___gcov_flush"); - addExportedSymbol(CmdArgs, "_flush_fn_list"); + addExportedSymbol(CmdArgs, "___gcov_dump"); + addExportedSymbol(CmdArgs, "___gcov_reset"); addExportedSymbol(CmdArgs, "_writeout_fn_list"); addExportedSymbol(CmdArgs, "_reset_fn_list"); } else { @@ -1697,7 +1718,7 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; StringRef MachOArchName = Toolchain.getMachOArchName(Args); - if (MachOArchName == "arm64") { + if (MachOArchName == "arm64" || MachOArchName == "arm64e") { #if __arm64__ // A clang running on an Apple Silicon mac defaults // to building for mac when building for arm64 rather than @@ -2021,21 +2042,42 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs( switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { - // On Darwin, libc++ is installed alongside the compiler in - // include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'. - { - llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir()); - // Note that P can be relative, so we have to '..' and not parent_path. - llvm::sys::path::append(P, "..", "include", "c++", "v1"); - addSystemInclude(DriverArgs, CC1Args, P); + // On Darwin, libc++ can be installed in one of the following two places: + // 1. Alongside the compiler in <install>/include/c++/v1 + // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1 + // + // The precendence of paths is as listed above, i.e. we take the first path + // that exists. Also note that we never include libc++ twice -- we take the + // first path that exists and don't send the other paths to CC1 (otherwise + // include_next could break). + + // Check for (1) + // Get from '<install>/bin' to '<install>/include/c++/v1'. + // Note that InstallBin can be relative, so we use '..' instead of + // parent_path. + llvm::SmallString<128> InstallBin = + llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin + llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1"); + if (getVFS().exists(InstallBin)) { + addSystemInclude(DriverArgs, CC1Args, InstallBin); + return; + } else if (DriverArgs.hasArg(options::OPT_v)) { + llvm::errs() << "ignoring nonexistent directory \"" << InstallBin + << "\"\n"; } - // Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used, - // to match the legacy behavior in CC1. - if (!DriverArgs.hasArg(options::OPT_nostdinc)) { - llvm::SmallString<128> P = Sysroot; - llvm::sys::path::append(P, "usr", "include", "c++", "v1"); - addSystemInclude(DriverArgs, CC1Args, P); + + // Otherwise, check for (2) + llvm::SmallString<128> SysrootUsr = Sysroot; + llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); + if (getVFS().exists(SysrootUsr)) { + addSystemInclude(DriverArgs, CC1Args, SysrootUsr); + return; + } else if (DriverArgs.hasArg(options::OPT_v)) { + llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr + << "\"\n"; } + + // Otherwise, don't add any path. break; } @@ -2271,11 +2313,6 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, } } - if (getTriple().isX86()) - if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) - DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ), - "core2"); - // Add the arch options based on the particular spelling of -arch, to match // how the driver driver works. if (!BoundArch.empty()) { @@ -2413,6 +2450,13 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, // Enable compatibility mode for NSItemProviderCompletionHandler in // Foundation/NSItemProvider.h. CC1Args.push_back("-fcompatibility-qualified-id-block-type-checking"); + + // Give static local variables in inline functions hidden visibility when + // -fvisibility-inlines-hidden is enabled. + if (!DriverArgs.getLastArgNoClaim( + options::OPT_fvisibility_inlines_hidden_static_local_var, + options::OPT_fno_visibility_inlines_hidden_static_local_var)) + CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var"); } DerivedArgList * @@ -2713,6 +2757,7 @@ void Darwin::CheckObjCARC() const { SanitizerMask Darwin::getSupportedSanitizers() const { const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; + const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; Res |= SanitizerKind::PointerCompare; @@ -2730,9 +2775,8 @@ SanitizerMask Darwin::getSupportedSanitizers() const { && !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))) Res |= SanitizerKind::Vptr; - if (isTargetMacOS()) { - if (IsX86_64) - Res |= SanitizerKind::Thread; + if ((IsX86_64 || IsAArch64) && isTargetMacOS()) { + Res |= SanitizerKind::Thread; } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) { if (IsX86_64) Res |= SanitizerKind::Thread; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h index 64c252efea7d..25c63fed922a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Darwin.h @@ -11,6 +11,7 @@ #include "Cuda.h" #include "ROCm.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/DarwinSDKInfo.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -62,7 +63,8 @@ class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { bool NeedsTempPath(const InputInfoList &Inputs) const; void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, - const InputInfoList &Inputs, unsigned Version[5]) const; + const InputInfoList &Inputs, unsigned Version[5], + bool LinkerIsLLD, bool LinkerIsLLDDarwinNew) const; public: Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} @@ -436,7 +438,11 @@ public: bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { assert(isTargetMacOS() && getTriple().isMacOSX() && "Unexpected call for non OS X target!"); - VersionTuple MinVers = getTriple().getMinimumSupportedOSVersion(); + // The effective triple might not be initialized yet, so construct a + // pseudo-effective triple to get the minimum supported OS version. + VersionTuple MinVers = + llvm::Triple(getTriple().getArchName(), "apple", "macos") + .getMinimumSupportedOSVersion(); return (!MinVers.empty() && MinVers > TargetVersion ? MinVers : TargetVersion) < VersionTuple(V0, V1, V2); @@ -487,17 +493,18 @@ public: return !(isTargetMacOS() && isMacosxVersionLT(10, 6)); } - unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { // Stack protectors default to on for user code on 10.5, // and for everything in 10.6 and beyond if (isTargetIOSBased() || isTargetWatchOSBased()) - return 1; + return LangOptions::SSPOn; else if (isTargetMacOS() && !isMacosxVersionLT(10, 6)) - return 1; + return LangOptions::SSPOn; else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext) - return 1; + return LangOptions::SSPOn; - return 0; + return LangOptions::SSPOff; } void CheckObjCARC() const override; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp index 88dd0c899d8a..9568b47e89e6 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp @@ -45,8 +45,9 @@ void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -119,11 +120,11 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - CmdArgs.push_back("-L/usr/lib/gcc50"); + CmdArgs.push_back("-L/usr/lib/gcc80"); if (!Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-rpath"); - CmdArgs.push_back("/usr/lib/gcc50"); + CmdArgs.push_back("/usr/lib/gcc80"); } if (D.CCCIsCXX()) { @@ -170,8 +171,9 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. @@ -187,7 +189,7 @@ DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); - getFilePaths().push_back("/usr/lib/gcc50"); + getFilePaths().push_back("/usr/lib/gcc80"); } Tool *DragonFly::buildAssembler() const { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp index 80f6db7ea642..669d911de18a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.cpp @@ -19,22 +19,36 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; +void Flang::AddPreprocessingOptions(const ArgList &Args, + ArgStringList &CmdArgs) const { + Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I}); +} + void Flang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const auto &TC = getToolChain(); - const llvm::Triple &Triple = TC.getEffectiveTriple(); - const std::string &TripleStr = Triple.getTriple(); + // TODO: Once code-generation is available, this will need to be commented + // out. + // const llvm::Triple &Triple = TC.getEffectiveTriple(); + // const std::string &TripleStr = Triple.getTriple(); ArgStringList CmdArgs; + // Invoke ourselves in -fc1 mode. CmdArgs.push_back("-fc1"); - CmdArgs.push_back("-triple"); - CmdArgs.push_back(Args.MakeArgString(TripleStr)); + // TODO: Once code-generation is available, this will need to be commented + // out. + // Add the "effective" target triple. + // CmdArgs.push_back("-triple"); + // CmdArgs.push_back(Args.MakeArgString(TripleStr)); if (isa<PreprocessJobAction>(JA)) { - CmdArgs.push_back("-E"); + if (C.getArgs().hasArg(options::OPT_test_io)) + CmdArgs.push_back("-test-io"); + else + CmdArgs.push_back("-E"); } else if (isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) { if (JA.getType() == types::TY_Nothing) { CmdArgs.push_back("-fsyntax-only"); @@ -57,6 +71,14 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, assert(false && "Unexpected action class for Flang tool."); } + const InputInfo &Input = Inputs[0]; + types::ID InputType = Input.getType(); + + // Add preprocessing options like -I, -D, etc. if we are using the + // preprocessor (i.e. skip when dealing with e.g. binary files). + if (types::getPreprocessedType(InputType) != types::TY_INVALID) + AddPreprocessingOptions(Args, CmdArgs); + if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); @@ -64,16 +86,18 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, assert(Output.isNothing() && "Invalid output."); } - const InputInfo &Input = Inputs[0]; assert(Input.isFilename() && "Invalid input."); CmdArgs.push_back(Input.getFilename()); const auto& D = C.getDriver(); - const char* Exec = Args.MakeArgString(D.GetProgramPath("flang", TC)); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + // TODO: Replace flang-new with flang once the new driver replaces the + // throwaway driver + const char *Exec = Args.MakeArgString(D.GetProgramPath("flang-new", TC)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } -Flang::Flang(const ToolChain &TC) : Tool("flang", "flang frontend", TC) {} +Flang::Flang(const ToolChain &TC) : Tool("flang-new", "flang frontend", TC) {} Flang::~Flang() {} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.h index 19e3a8c28f7e..83b79505e0a9 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Flang.h @@ -23,6 +23,15 @@ namespace tools { /// Flang compiler tool. class LLVM_LIBRARY_VISIBILITY Flang : public Tool { +private: + /// Extract preprocessing options from the driver arguments and add them to + /// the preprocessor command arguments. + /// + /// \param [in] Args The list of input driver arguments + /// \param [out] CmdArgs The list of output command arguments + void AddPreprocessingOptions(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + public: Flang(const ToolChain &TC); ~Flang() override; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp index baefb1607619..37c0a68234ed 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -42,6 +42,7 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--32"); break; case llvm::Triple::ppc: + case llvm::Triple::ppcle: CmdArgs.push_back("-a32"); break; case llvm::Triple::mips: @@ -128,8 +129,9 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -191,6 +193,11 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-m"); CmdArgs.push_back("elf32ppc_fbsd"); break; + case llvm::Triple::ppcle: + CmdArgs.push_back("-m"); + // Use generic -- only usage is for freestanding. + CmdArgs.push_back("elf32lppc"); + break; case llvm::Triple::mips: CmdArgs.push_back("-m"); CmdArgs.push_back("elf32btsmip_fbsd"); @@ -360,8 +367,9 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. @@ -373,7 +381,7 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall // back to '/usr/lib' if it doesn't exist. if ((Triple.getArch() == llvm::Triple::x86 || Triple.isMIPS32() || - Triple.getArch() == llvm::Triple::ppc) && + Triple.isPPC32()) && D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); else diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp index 94e025e3055a..8e086010a984 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -95,6 +95,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, std::string Dyld = D.DyldPrefix; if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt()) Dyld += "asan/"; + if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt()) + Dyld += "tsan/"; Dyld += "ld.so.1"; CmdArgs.push_back("-dynamic-linker"); CmdArgs.push_back(Args.MakeArgString(Dyld)); @@ -165,7 +167,7 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, } C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly. @@ -208,6 +210,23 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, .flag("+fsanitize=address") .flag("-fexceptions") .flag("+fno-exceptions")); + // Use the relative vtables ABI. + // TODO: Remove these multilibs once relative vtables are enabled by default + // for Fuchsia. + Multilibs.push_back(Multilib("relative-vtables", {}, {}, 4) + .flag("+fexperimental-relative-c++-abi-vtables")); + Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 5) + .flag("+fexperimental-relative-c++-abi-vtables") + .flag("-fexceptions") + .flag("+fno-exceptions")); + Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 6) + .flag("+fexperimental-relative-c++-abi-vtables") + .flag("+fsanitize=address")); + Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 7) + .flag("+fexperimental-relative-c++-abi-vtables") + .flag("+fsanitize=address") + .flag("-fexceptions") + .flag("+fno-exceptions")); Multilibs.FilterOut([&](const Multilib &M) { std::vector<std::string> RD = FilePaths(M); return std::all_of(RD.begin(), RD.end(), [&](std::string P) { @@ -220,6 +239,13 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true), "fexceptions", Flags); addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags); + + addMultilibFlag( + Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables, + options::OPT_fno_experimental_relative_cxx_abi_vtables, + /*default=*/false), + "fexperimental-relative-c++-abi-vtables", Flags); + Multilibs.setFilePathsCallback(FilePaths); if (Multilibs.select(Flags, SelectedMultilib)) @@ -349,6 +375,7 @@ SanitizerMask Fuchsia::getSupportedSanitizers() const { Res |= SanitizerKind::Leak; Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Scudo; + Res |= SanitizerKind::Thread; return Res; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.h index 3159a54bda06..07adf9b7101d 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_FUCHSIA_H #include "Gnu.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -59,8 +60,9 @@ public: return llvm::DebuggerKind::GDB; } - unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { - return 2; // SSPStrong + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + return LangOptions::SSPStrong; } std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp index 23e7a70f2fa7..1d8a3cdce92a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp @@ -38,10 +38,10 @@ using tools::addMultilibFlag; using tools::addPathIfExists; static bool forwardToGCC(const Option &O) { - // Don't forward inputs from the original command line. They are added from - // InputInfoList. - return O.getKind() != Option::InputClass && - !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput); + // LinkerInput options have been forwarded. Don't duplicate. + if (O.hasFlag(options::LinkerInput)) + return false; + return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption); } // Switch CPU names not recognized by GNU assembler to a close CPU that it does @@ -76,23 +76,6 @@ void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, // to get to the assembler. A->claim(); - // Don't forward any -g arguments to assembly steps. - if (isa<AssembleJobAction>(JA) && - A->getOption().matches(options::OPT_g_Group)) - continue; - - // Don't forward any -W arguments to assembly and link steps. - if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) && - A->getOption().matches(options::OPT_W_Group)) - continue; - - // Don't forward -mno-unaligned-access since GCC doesn't understand - // it and because it doesn't affect the assembly or link steps. - if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) && - (A->getOption().matches(options::OPT_munaligned_access) || - A->getOption().matches(options::OPT_mno_unaligned_access))) - continue; - A->render(Args, CmdArgs); } } @@ -116,6 +99,7 @@ void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, break; case llvm::Triple::x86: case llvm::Triple::ppc: + case llvm::Triple::ppcle: CmdArgs.push_back("-m32"); break; case llvm::Triple::x86_64: @@ -188,8 +172,9 @@ void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, GCCName = "gcc"; const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void tools::gcc::Preprocessor::RenderExtraToolArgs( @@ -270,7 +255,13 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::thumbeb: return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi"; case llvm::Triple::ppc: - return "elf32ppclinux"; + if (T.isOSLinux()) + return "elf32ppclinux"; + return "elf32ppc"; + case llvm::Triple::ppcle: + if (T.isOSLinux()) + return "elf32lppclinux"; + return "elf32lppc"; case llvm::Triple::ppc64: return "elf64ppc"; case llvm::Triple::ppc64le: @@ -358,12 +349,17 @@ void tools::gnutools::StaticLibTool::ConstructJob( // Silence warnings when linking C code with a C++ '-stdlib' argument. Args.ClaimAllArgs(options::OPT_stdlib_EQ); - // GNU ar tool command "ar <options> <output_file> <input_files>". + // ar tool command "llvm-ar <options> <output_file> <input_files>". ArgStringList CmdArgs; // Create and insert file members with a deterministic index. CmdArgs.push_back("rcsD"); CmdArgs.push_back(Output.getFilename()); - AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + for (const auto &II : Inputs) { + if (II.isFilename()) { + CmdArgs.push_back(II.getFilename()); + } + } // Delete old output archive file if it already exists before generating a new // archive file. @@ -376,8 +372,9 @@ void tools::gnutools::StaticLibTool::ConstructJob( } const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -674,8 +671,9 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_T); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void tools::gnutools::Assembler::ConstructJob(Compilation &C, @@ -733,13 +731,23 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, case llvm::Triple::ppc: { CmdArgs.push_back("-a32"); CmdArgs.push_back("-mppc"); + CmdArgs.push_back("-mbig-endian"); CmdArgs.push_back( ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); break; } + case llvm::Triple::ppcle: { + CmdArgs.push_back("-a32"); + CmdArgs.push_back("-mppc"); + CmdArgs.push_back("-mlittle-endian"); + CmdArgs.push_back( + ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); + break; + } case llvm::Triple::ppc64: { CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); + CmdArgs.push_back("-mbig-endian"); CmdArgs.push_back( ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple()))); break; @@ -942,8 +950,9 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler)); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); // Handle the debug info splitting at object creation time if we're // creating an object. @@ -951,7 +960,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, if (Args.hasArg(options::OPT_gsplit_dwarf) && getToolChain().getTriple().isOSLinux()) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Inputs[0], Output)); + SplitDebugName(JA, Args, Inputs[0], Output)); } namespace { @@ -1553,15 +1562,21 @@ static bool findMSP430Multilibs(const Driver &D, StringRef Path, const ArgList &Args, DetectedMultilibs &Result) { FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - Multilib MSP430Multilib = makeMultilib("/430"); + Multilib WithoutExceptions = makeMultilib("/430").flag("-exceptions"); + Multilib WithExceptions = makeMultilib("/430/exceptions").flag("+exceptions"); + // FIXME: when clang starts to support msp430x ISA additional logic // to select between multilib must be implemented // Multilib MSP430xMultilib = makeMultilib("/large"); - Result.Multilibs.push_back(MSP430Multilib); + Result.Multilibs.push_back(WithoutExceptions); + Result.Multilibs.push_back(WithExceptions); Result.Multilibs.FilterOut(NonExistent); Multilib::flags_list Flags; + addMultilibFlag(Args.hasFlag(options::OPT_fexceptions, + options::OPT_fno_exceptions, false), + "exceptions", Flags); if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) return true; @@ -1945,27 +1960,36 @@ void Generic_GCC::GCCInstallationDetector::init( // installation available. GCC installs are ranked by version number. Version = GCCVersion::Parse("0.0.0"); for (const std::string &Prefix : Prefixes) { - if (!D.getVFS().exists(Prefix)) + auto &VFS = D.getVFS(); + if (!VFS.exists(Prefix)) continue; for (StringRef Suffix : CandidateLibDirs) { const std::string LibDir = Prefix + Suffix.str(); - if (!D.getVFS().exists(LibDir)) + if (!VFS.exists(LibDir)) continue; + // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross. + bool GCCDirExists = VFS.exists(LibDir + "/gcc"); + bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); // Try to match the exact target triple first. - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TargetTriple.str()); + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TargetTriple.str(), + false, GCCDirExists, GCCCrossDirExists); // Try rest of possible triples. for (StringRef Candidate : ExtraTripleAliases) // Try these first. - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate); + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false, + GCCDirExists, GCCCrossDirExists); for (StringRef Candidate : CandidateTripleAliases) - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate); + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false, + GCCDirExists, GCCCrossDirExists); } for (StringRef Suffix : CandidateBiarchLibDirs) { const std::string LibDir = Prefix + Suffix.str(); - if (!D.getVFS().exists(LibDir)) + if (!VFS.exists(LibDir)) continue; + bool GCCDirExists = VFS.exists(LibDir + "/gcc"); + bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); for (StringRef Candidate : CandidateBiarchTripleAliases) - ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, - /*NeedsBiarchSuffix=*/ true); + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true, + GCCDirExists, GCCCrossDirExists); } } } @@ -2027,6 +2051,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( // Non-Solaris is much simpler - most systems just go with "/usr". if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux) { // Yet, still look for RHEL devtoolsets. + Prefixes.push_back("/opt/rh/devtoolset-10/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-9/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); @@ -2126,6 +2151,11 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux". "powerpc64-suse-linux", "powerpc-montavista-linuxspe"}; + static const char *const PPCLELibDirs[] = {"/lib32", "/lib"}; + static const char *const PPCLETriples[] = {"powerpcle-linux-gnu", + "powerpcle-unknown-linux-gnu", + "powerpcle-linux-musl"}; + static const char *const PPC64LibDirs[] = {"/lib64", "/lib"}; static const char *const PPC64Triples[] = { "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", @@ -2133,7 +2163,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"}; static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", - "powerpc64le-suse-linux", "ppc64le-redhat-linux"}; + "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux", + "ppc64le-redhat-linux"}; static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"}; static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu", @@ -2366,6 +2397,12 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); break; + case llvm::Triple::ppcle: + LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); + TripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); + BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); + BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); + break; case llvm::Triple::ppc64: LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); TripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); @@ -2375,6 +2412,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( case llvm::Triple::ppc64le: LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); + BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); + BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); break; case llvm::Triple::riscv32: LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); @@ -2456,7 +2495,7 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( const llvm::Triple &TargetTriple, const ArgList &Args, const std::string &LibDir, StringRef CandidateTriple, - bool NeedsBiarchSuffix) { + bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) { llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); // Locations relative to the system lib directory where GCC's triple-specific // directories might reside. @@ -2470,11 +2509,10 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( bool Active; } Suffixes[] = { // This is the normal place. - {"gcc/" + CandidateTriple.str(), "../..", true}, + {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists}, // Debian puts cross-compilers in gcc-cross. - {"gcc-cross/" + CandidateTriple.str(), "../..", - TargetTriple.getOS() != llvm::Triple::Solaris}, + {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists}, // The Freescale PPC SDK has the gcc libraries in // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do @@ -2541,6 +2579,9 @@ bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs( const llvm::Triple &TargetTriple, const ArgList &Args, const SmallVectorImpl<StringRef> &CandidateTriples, const SmallVectorImpl<StringRef> &CandidateBiarchTriples) { + if (!D.getVFS().exists(D.SysRoot + GentooConfigDir)) + return false; + for (StringRef CandidateTriple : CandidateTriples) { if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) return true; @@ -2557,7 +2598,7 @@ bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( const llvm::Triple &TargetTriple, const ArgList &Args, StringRef CandidateTriple, bool NeedsBiarchSuffix) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = - D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" + + D.getVFS().getBufferForFile(D.SysRoot + GentooConfigDir + "/config-" + CandidateTriple.str()); if (File) { SmallVector<StringRef, 2> Lines; @@ -2569,7 +2610,7 @@ bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( continue; // Process the config file pointed to by CURRENT. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile = - D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/" + + D.getVFS().getBufferForFile(D.SysRoot + GentooConfigDir + "/" + Line.str()); std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-'); // List of paths to scan for libraries. @@ -2663,7 +2704,17 @@ void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { } bool Generic_GCC::IsUnwindTablesDefault(const ArgList &Args) const { - return getArch() == llvm::Triple::x86_64; + switch (getArch()) { + case llvm::Triple::aarch64: + case llvm::Triple::ppc: + case llvm::Triple::ppcle: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + case llvm::Triple::x86_64: + return true; + default: + return false; + } } bool Generic_GCC::isPICDefault() const { @@ -2698,6 +2749,7 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { case llvm::Triple::thumb: case llvm::Triple::thumbeb: case llvm::Triple::ppc: + case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.h index 52690ab4b83c..90d3bafc1f00 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.h @@ -212,6 +212,9 @@ public: /// The set of multilibs that the detected installation supports. MultilibSet Multilibs; + // Gentoo-specific toolchain configurations are stored here. + const std::string GentooConfigDir = "/etc/env.d/gcc"; + public: explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, @@ -267,7 +270,8 @@ public: const llvm::opt::ArgList &Args, const std::string &LibDir, StringRef CandidateTriple, - bool NeedsBiarchSuffix = false); + bool NeedsBiarchSuffix, bool GCCDirExists, + bool GCCCrossDirExists); bool ScanGentooConfigs(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/HIP.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/HIP.cpp index 228d970c4043..a84c0c257033 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/HIP.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/HIP.cpp @@ -11,10 +11,12 @@ #include "CommonArgs.h" #include "InputInfo.h" #include "clang/Basic/Cuda.h" +#include "clang/Basic/TargetID.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/TargetParser.h" @@ -32,6 +34,7 @@ using namespace llvm::opt; #endif namespace { +const unsigned HIPCodeObjectAlign = 4096; static void addBCLib(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, ArgStringList LibraryPaths, @@ -68,7 +71,7 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, // Extract all the -m options std::vector<llvm::StringRef> Features; - amdgpu::getAMDGPUTargetFeatures(D, Args, Features); + amdgpu::getAMDGPUTargetFeatures(D, TC.getTriple(), Args, Features); // Add features to mattr such as cumode std::string MAttrString = "-plugin-opt=-mattr="; @@ -95,7 +98,7 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, LldArgs.push_back(Input.getFilename()); const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Lld, LldArgs, Inputs)); + Lld, LldArgs, Inputs, Output)); } // Construct a clang-offload-bundler command to bundle code objects for @@ -107,29 +110,39 @@ void AMDGCN::constructHIPFatbinCommand(Compilation &C, const JobAction &JA, // for different GPU archs. ArgStringList BundlerArgs; BundlerArgs.push_back(Args.MakeArgString("-type=o")); + BundlerArgs.push_back( + Args.MakeArgString("-bundle-align=" + Twine(HIPCodeObjectAlign))); // ToDo: Remove the dummy host binary entry which is required by // clang-offload-bundler. std::string BundlerTargetArg = "-targets=host-x86_64-unknown-linux"; std::string BundlerInputArg = "-inputs=" NULL_FILE; + // TODO: Change the bundle ID as requested by HIP runtime. + // For code object version 2 and 3, the offload kind in bundle ID is 'hip' + // for backward compatibility. For code object version 4 and greater, the + // offload kind in bundle ID is 'hipv4'. + std::string OffloadKind = "hip"; for (const auto &II : Inputs) { const auto* A = II.getAction(); - BundlerTargetArg = BundlerTargetArg + ",hip-amdgcn-amd-amdhsa-" + + BundlerTargetArg = BundlerTargetArg + "," + OffloadKind + + "-amdgcn-amd-amdhsa--" + StringRef(A->getOffloadingArch()).str(); BundlerInputArg = BundlerInputArg + "," + II.getFilename(); } BundlerArgs.push_back(Args.MakeArgString(BundlerTargetArg)); BundlerArgs.push_back(Args.MakeArgString(BundlerInputArg)); - auto BundlerOutputArg = Args.MakeArgString( - std::string("-outputs=").append(std::string(OutputFileName))); + std::string Output = std::string(OutputFileName); + auto BundlerOutputArg = + Args.MakeArgString(std::string("-outputs=").append(Output)); BundlerArgs.push_back(BundlerOutputArg); const char *Bundler = Args.MakeArgString( T.getToolChain().GetProgramPath("clang-offload-bundler")); - C.addCommand(std::make_unique<Command>(JA, T, ResponseFileSupport::None(), - Bundler, BundlerArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, T, ResponseFileSupport::None(), Bundler, BundlerArgs, Inputs, + InputInfo(&JA, Args.MakeArgString(Output)))); } /// Add Generated HIP Object File which has device images embedded into the @@ -171,10 +184,10 @@ void AMDGCN::Linker::constructGenerateObjFileFromHIPFatBinary( ObjStream << "# HIP Object Generator\n"; ObjStream << "# *** Automatically generated by Clang ***\n"; ObjStream << " .type __hip_fatbin,@object\n"; - ObjStream << " .section .hip_fatbin,\"aMS\",@progbits,1\n"; - ObjStream << " .data\n"; + ObjStream << " .section .hip_fatbin,\"a\",@progbits\n"; ObjStream << " .globl __hip_fatbin\n"; - ObjStream << " .p2align 3\n"; + ObjStream << " .p2align " << llvm::Log2(llvm::Align(HIPCodeObjectAlign)) + << "\n"; ObjStream << "__hip_fatbin:\n"; ObjStream << " .incbin \"" << BundleFile << "\"\n"; ObjStream.flush(); @@ -199,7 +212,7 @@ void AMDGCN::Linker::constructGenerateObjFileFromHIPFatBinary( McinFile, "--filetype=obj"}; const char *Mc = Args.MakeArgString(TC.GetProgramPath("llvm-mc")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Mc, McArgs, Inputs)); + Mc, McArgs, Inputs, Output)); } // For amdgcn the inputs of the linker job are device bitcode and output is @@ -234,7 +247,7 @@ void HIPToolChain::addClangTargetOptions( Action::OffloadKind DeviceOffloadingKind) const { HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); - StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + StringRef GpuArch = getGPUArch(DriverArgs); assert(!GpuArch.empty() && "Must have an explicit GPU arch."); (void) GpuArch; assert(DeviceOffloadingKind == Action::OFK_HIP && @@ -262,10 +275,6 @@ void HIPToolChain::addClangTargetOptions( CC1Args.push_back(DriverArgs.MakeArgStringRef(ArgStr)); } - if (DriverArgs.hasFlag(options::OPT_fgpu_allow_device_init, - options::OPT_fno_gpu_allow_device_init, false)) - CC1Args.push_back("-fgpu-allow-device-init"); - CC1Args.push_back("-fcuda-allow-variadic-functions"); // Default to "hidden" visibility, as object level linking will not be @@ -324,6 +333,17 @@ void HIPToolChain::addClangTargetOptions( RocmInstallation.addCommonBitcodeLibCC1Args( DriverArgs, CC1Args, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, FastRelaxedMath, CorrectSqrt); + + // Add instrument lib. + auto InstLib = + DriverArgs.getLastArgValue(options::OPT_gpu_instrument_lib_EQ); + if (InstLib.empty()) + return; + if (llvm::sys::fs::exists(InstLib)) { + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(InstLib)); + } else + getDriver().Diag(diag::err_drv_no_such_file) << InstLib; } } @@ -339,12 +359,14 @@ HIPToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, const OptTable &Opts = getDriver().getOpts(); for (Arg *A : Args) { - DAL->append(A); + if (!shouldSkipArgument(A)) + DAL->append(A); } if (!BoundArch.empty()) { DAL->eraseArg(options::OPT_mcpu_EQ); DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mcpu_EQ), BoundArch); + checkTargetID(*DAL); } return DAL; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp index 775f6e1094fa..fb54f73bcd4c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -189,8 +189,9 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA, } auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName)); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA, @@ -407,8 +408,9 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA, LinkingOutput); const char *Exec = Args.MakeArgString(HTC.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } // Hexagon tools end. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/InterfaceStubs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/InterfaceStubs.cpp index f7c11421e809..57acf338df5c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/InterfaceStubs.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/InterfaceStubs.cpp @@ -56,7 +56,7 @@ void Merger::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), Args.MakeArgString(Merger), CmdArgs, - Inputs)); + Inputs, Output)); } } // namespace ifstool } // namespace tools diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp index 180350476c38..e17a6bd4bdd2 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp @@ -142,6 +142,10 @@ std::string Linux::getMultiarchTriple(const Driver &D, if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")) return "powerpc-linux-gnu"; break; + case llvm::Triple::ppcle: + if (D.getVFS().exists(SysRoot + "/lib/powerpcle-linux-gnu")) + return "powerpcle-linux-gnu"; + break; case llvm::Triple::ppc64: if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) return "powerpc64-linux-gnu"; @@ -185,17 +189,17 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { return Triple.isArch32Bit() ? "lib" : "lib64"; } - // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and - // using that variant while targeting other architectures causes problems - // because the libraries are laid out in shared system roots that can't cope - // with a 'lib32' library search path being considered. So we only enable - // them when we know we may need it. + // It happens that only x86, PPC and SPARC use the 'lib32' variant of + // oslibdir, and using that variant while targeting other architectures causes + // problems because the libraries are laid out in shared system roots that + // can't cope with a 'lib32' library search path being considered. So we only + // enable them when we know we may need it. // // FIXME: This is a bit of a hack. We should really unify this code for // reasoning about oslibdir spellings with the lib dir spellings in the // GCCInstallationDetector, but that is a more significant refactoring. - if (Triple.getArch() == llvm::Triple::x86 || - Triple.getArch() == llvm::Triple::ppc) + if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() || + Triple.getArch() == llvm::Triple::sparc) return "lib32"; if (Triple.getArch() == llvm::Triple::x86_64 && @@ -232,6 +236,15 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("relro"); } + if (Triple.isAndroid() && Triple.isAndroidVersionLT(29)) { + // https://github.com/android/ndk/issues/1196 + // The unwinder used by the crash handler on versions of Android prior to + // API 29 did not correctly handle binaries built with rosegment, which is + // enabled by default for LLD. Android only supports LLD, so it's not an + // issue that this flag is not accepted by other linkers. + ExtraOpts.push_back("--no-rosegment"); + } + // Android ARM/AArch64 use max-page-size=4096 to reduce VMA usage. Note, lld // from 11 onwards default max-page-size to 65536 for both ARM and AArch64. if ((Triple.isARM() || Triple.isAArch64()) && Triple.isAndroid()) { @@ -495,6 +508,10 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { LibDir = "lib"; Loader = "ld.so.1"; break; + case llvm::Triple::ppcle: + LibDir = "lib"; + Loader = "ld.so.1"; + break; case llvm::Triple::ppc64: LibDir = "lib64"; Loader = @@ -642,6 +659,8 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, const StringRef PPCMultiarchIncludeDirs[] = { "/usr/include/powerpc-linux-gnu", "/usr/include/powerpc-linux-gnuspe"}; + const StringRef PPCLEMultiarchIncludeDirs[] = { + "/usr/include/powerpcle-linux-gnu"}; const StringRef PPC64MultiarchIncludeDirs[] = { "/usr/include/powerpc64-linux-gnu"}; const StringRef PPC64LEMultiarchIncludeDirs[] = { @@ -715,6 +734,9 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, case llvm::Triple::ppc: MultiarchIncludeDirs = PPCMultiarchIncludeDirs; break; + case llvm::Triple::ppcle: + MultiarchIncludeDirs = PPCLEMultiarchIncludeDirs; + break; case llvm::Triple::ppc64: MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; break; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.cpp index b0bc2e014b48..f3ed9967a81a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.cpp @@ -128,7 +128,7 @@ MSP430ToolChain::MSP430ToolChain(const Driver &D, const llvm::Triple &Triple, } SmallString<128> SysRootDir(computeSysRoot()); - llvm::sys::path::append(SysRootDir, "lib", MultilibSuf); + llvm::sys::path::append(SysRootDir, "msp430-elf", "lib", MultilibSuf); addPathIfExists(D, SysRootDir, getFilePaths()); } @@ -138,10 +138,9 @@ std::string MSP430ToolChain::computeSysRoot() const { SmallString<128> Dir; if (GCCInstallation.isValid()) - llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), "..", - GCCInstallation.getTriple().str()); + llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), ".."); else - llvm::sys::path::append(Dir, getDriver().Dir, "..", getTriple().str()); + llvm::sys::path::append(Dir, getDriver().Dir, ".."); return std::string(Dir.str()); } @@ -153,7 +152,7 @@ void MSP430ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; SmallString<128> Dir(computeSysRoot()); - llvm::sys::path::append(Dir, "include"); + llvm::sys::path::append(Dir, "msp430-elf", "include"); addSystemInclude(DriverArgs, CC1Args, Dir.str()); } @@ -180,6 +179,87 @@ Tool *MSP430ToolChain::buildLinker() const { return new tools::msp430::Linker(*this); } +void msp430::Linker::AddStartFiles(bool UseExceptions, const ArgList &Args, + ArgStringList &CmdArgs) const { + const ToolChain &ToolChain = getToolChain(); + + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); + const char *crtbegin = UseExceptions ? "crtbegin.o" : "crtbegin_no_eh.o"; + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); +} + +void msp430::Linker::AddDefaultLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + + CmdArgs.push_back("--start-group"); + CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args))); + CmdArgs.push_back("-lc"); + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); + CmdArgs.push_back("-lcrt"); + + if (Args.hasArg(options::OPT_msim)) { + CmdArgs.push_back("-lsim"); + + // msp430-sim.ld relies on __crt0_call_exit being implicitly .refsym-ed + // in main() by msp430-gcc. + // This workaround should work seamlessly unless the compilation unit that + // contains main() is compiled by clang and then passed to + // gcc compiler driver for linkage. + CmdArgs.push_back("--undefined=__crt0_call_exit"); + } else + CmdArgs.push_back("-lnosys"); + + CmdArgs.push_back("--end-group"); + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); +} + +void msp430::Linker::AddEndFiles(bool UseExceptions, const ArgList &Args, + ArgStringList &CmdArgs) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + + const char *crtend = UseExceptions ? "crtend.o" : "crtend_no_eh.o"; + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); +} + +static void AddSspArgs(const ArgList &Args, ArgStringList &CmdArgs) { + Arg *SspFlag = Args.getLastArg( + options::OPT_fno_stack_protector, options::OPT_fstack_protector, + options::OPT_fstack_protector_all, options::OPT_fstack_protector_strong); + + if (SspFlag && + !SspFlag->getOption().matches(options::OPT_fno_stack_protector)) { + CmdArgs.push_back("-lssp_nonshared"); + CmdArgs.push_back("-lssp"); + } +} + +static void AddImplicitLinkerScript(const std::string SysRoot, + const ArgList &Args, + ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_T)) + return; + + if (Args.hasArg(options::OPT_msim)) { + CmdArgs.push_back("-Tmsp430-sim.ld"); + return; + } + + const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ); + if (!MCUArg) + return; + + SmallString<128> MCULinkerScriptPath(SysRoot); + llvm::sys::path::append(MCULinkerScriptPath, "include"); + // -L because <mcu>.ld INCLUDEs <mcu>_symbols.ld + CmdArgs.push_back(Args.MakeArgString("-L" + MCULinkerScriptPath)); + CmdArgs.push_back( + Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld")); +} + void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -189,45 +269,50 @@ void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = ToolChain.getDriver(); std::string Linker = ToolChain.GetProgramPath(getShortName()); ArgStringList CmdArgs; - - if (!D.SysRoot.empty()) - CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + bool UseExceptions = Args.hasFlag(options::OPT_fexceptions, + options::OPT_fno_exceptions, false); + bool UseStartAndEndFiles = !Args.hasArg(options::OPT_nostdlib, options::OPT_r, + options::OPT_nostartfiles); + + if (Args.hasArg(options::OPT_mrelax)) + CmdArgs.push_back("--relax"); + if (!Args.hasArg(options::OPT_r, options::OPT_g_Group)) + CmdArgs.push_back("--gc-sections"); + + Args.AddAllArgs(CmdArgs, { + options::OPT_e, + options::OPT_n, + options::OPT_s, + options::OPT_t, + options::OPT_u, + }); + + if (UseStartAndEndFiles) + AddStartFiles(UseExceptions, Args, CmdArgs); Args.AddAllArgs(CmdArgs, options::OPT_L); ToolChain.AddFilePathLibArgs(Args, CmdArgs); - - if (!Args.hasArg(options::OPT_T)) { - if (const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ)) - CmdArgs.push_back( - Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld")); - } else { - Args.AddAllArgs(CmdArgs, options::OPT_T); - } - - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); - } - AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); - CmdArgs.push_back("--start-group"); - CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args))); - CmdArgs.push_back("-lgcc"); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - CmdArgs.push_back("-lc"); - CmdArgs.push_back("-lcrt"); - CmdArgs.push_back("-lnosys"); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r, + options::OPT_nodefaultlibs)) { + AddSspArgs(Args, CmdArgs); + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); + if (!Args.hasArg(options::OPT_nolibc)) { + AddDefaultLibs(Args, CmdArgs); + AddImplicitLinkerScript(D.SysRoot, Args, CmdArgs); + } } - CmdArgs.push_back("--end-group"); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); - } + if (UseStartAndEndFiles) + AddEndFiles(UseExceptions, Args, CmdArgs); + CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Linker), CmdArgs, Inputs)); + + Args.AddAllArgs(CmdArgs, options::OPT_T); + + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.h index 58fd158cd12f..3789e7442a23 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSP430.h @@ -40,6 +40,11 @@ public: bool isPIEDefault() const override { return false; } bool isPICDefaultForced() const override { return true; } + UnwindLibType + GetUnwindLibType(const llvm::opt::ArgList &Args) const override { + return UNW_None; + } + protected: Tool *buildLinker() const override; @@ -61,6 +66,14 @@ public: const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; + +private: + void AddStartFiles(bool UseExceptions, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + void AddDefaultLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + void AddEndFiles(bool UseExceptions, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; }; void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp index 6b3c00e2ab6d..f4b7a57e0bb7 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp @@ -66,6 +66,20 @@ using namespace llvm::opt; static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue); +// Check command line arguments to try and find a toolchain. +static bool +findVCToolChainViaCommandLine(const ArgList &Args, std::string &Path, + MSVCToolChain::ToolsetLayout &VSLayout) { + // Don't validate the input; trust the value supplied by the user. + // The primary motivation is to prevent unnecessary file and registry access. + if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir)) { + Path = A->getValue(); + VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer; + return true; + } + return false; +} + // Check various environment variables to try and find a toolchain. static bool findVCToolChainViaEnvironment(std::string &Path, MSVCToolChain::ToolsetLayout &VSLayout) { @@ -319,8 +333,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - !C.getDriver().IsCLMode()) + !C.getDriver().IsCLMode()) { CmdArgs.push_back("-defaultlib:libcmt"); + CmdArgs.push_back("-defaultlib:oldnames"); + } if (!llvm::sys::Process::GetEnv("LIB")) { // If the VC environment hasn't been configured (perhaps because the user @@ -366,8 +382,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-nologo"); - if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7, - options::OPT__SLASH_Zd)) + if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7)) CmdArgs.push_back("-debug"); // Pass on /Brepro if it was passed to the compiler. @@ -592,9 +607,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, linkPath = TC.GetProgramPath(Linker.str().c_str()); } - auto LinkCmd = - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF16(), - Args.MakeArgString(linkPath), CmdArgs, Inputs); + auto LinkCmd = std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileUTF16(), + Args.MakeArgString(linkPath), CmdArgs, Inputs, Output); if (!Environment.empty()) LinkCmd->setEnvironment(Environment); C.addCommand(std::move(LinkCmd)); @@ -734,9 +749,9 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand( CmdArgs.push_back(Fo); std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe"); - return std::make_unique<Command>(JA, *this, - ResponseFileSupport::AtFileUTF16(), - Args.MakeArgString(Exec), CmdArgs, Inputs); + return std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileUTF16(), Args.MakeArgString(Exec), + CmdArgs, Inputs, Output); } MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, @@ -747,11 +762,12 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); - // Check the environment first, since that's probably the user telling us - // what they want to use. - // Failing that, just try to find the newest Visual Studio version we can - // and use its default VC toolchain. - findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) || + // Check the command line first, that's the user explicitly telling us what to + // use. Check the environment next, in case we're being invoked from a VS + // command prompt. Failing that, just try to find the newest Visual Studio + // version we can and use its default VC toolchain. + findVCToolChainViaCommandLine(Args, VCToolChainPath, VSLayout) || + findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) || findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) || findVCToolChainViaRegistry(VCToolChainPath, VSLayout); } @@ -1263,15 +1279,18 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat. - if (llvm::Optional<std::string> cl_include_dir = - llvm::sys::Process::GetEnv("INCLUDE")) { - SmallVector<StringRef, 8> Dirs; - StringRef(*cl_include_dir) - .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); - for (StringRef Dir : Dirs) - addSystemInclude(DriverArgs, CC1Args, Dir); - if (!Dirs.empty()) - return; + // Skip if the user expressly set a vctoolsdir + if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir)) { + if (llvm::Optional<std::string> cl_include_dir = + llvm::sys::Process::GetEnv("INCLUDE")) { + SmallVector<StringRef, 8> Dirs; + StringRef(*cl_include_dir) + .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (StringRef Dir : Dirs) + addSystemInclude(DriverArgs, CC1Args, Dir); + if (!Dirs.empty()) + return; + } } // When built with access to the proper Windows APIs, try to actually find diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp index a1a1b413fb6c..f6cead412236 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp @@ -51,11 +51,11 @@ void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); if (Args.hasArg(options::OPT_gsplit_dwarf)) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Inputs[0], Output)); + SplitDebugName(JA, Args, Inputs[0], Output)); } void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, @@ -164,17 +164,14 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); const char *OutputFile = Output.getFilename(); // GCC implicitly adds an .exe extension if it is given an output file name - // that lacks an extension. However, GCC only does this when actually - // running on windows, not when operating as a cross compiler. As some users - // have come to rely on this behaviour, try to replicate it. -#ifdef _WIN32 - if (!llvm::sys::path::has_extension(OutputFile)) + // that lacks an extension. + // GCC used to do this only when the compiler itself runs on windows, but + // since GCC 8 it does the same when cross compiling as well. + if (!llvm::sys::path::has_extension(OutputFile)) { CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe")); - else + OutputFile = CmdArgs.back(); + } else CmdArgs.push_back(OutputFile); -#else - CmdArgs.push_back(OutputFile); -#endif Args.AddAllArgs(CmdArgs, options::OPT_e); // FIXME: add -N, -n flags @@ -322,8 +319,9 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. @@ -493,6 +491,7 @@ SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { Res |= SanitizerKind::Address; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; + Res |= SanitizerKind::Vptr; return Res; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Minix.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Minix.cpp index d0314795620c..44479a24ebe7 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Minix.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Minix.cpp @@ -36,8 +36,9 @@ void tools::minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -89,8 +90,9 @@ void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } /// Minix - Minix tool chain which can call as(1) and ld(1) directly. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Myriad.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Myriad.cpp index 84fe4748b6fa..ab0df5d8f168 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Myriad.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Myriad.cpp @@ -79,7 +79,7 @@ void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetProgramPath("moviCompile")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), Args.MakeArgString(Exec), CmdArgs, - Inputs)); + Inputs, Output)); } void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, @@ -115,7 +115,7 @@ void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetProgramPath("moviAsm")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), Args.MakeArgString(Exec), CmdArgs, - Inputs)); + Inputs, Output)); } void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -200,9 +200,9 @@ void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, std::string Exec = Args.MakeArgString(TC.GetProgramPath("sparc-myriad-rtems-ld")); - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Exec), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Exec), + CmdArgs, Inputs, Output)); } MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/NaCl.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/NaCl.cpp index 15a773675299..8a150c394753 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/NaCl.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/NaCl.cpp @@ -193,8 +193,9 @@ void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } /// NaCl Toolchain diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/NetBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/NetBSD.cpp index 253ee6ce0f72..48bf061c6650 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -103,8 +103,9 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as"))); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -338,8 +339,9 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.cpp index 5ca2fa0850e6..f155d74632f9 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -82,8 +82,9 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -221,8 +222,9 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); } SanitizerMask OpenBSD::getSupportedSanitizers() const { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.h index 5f9b259bf861..4932ed5c609c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OPENBSD_H #include "Gnu.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -79,8 +80,9 @@ public: std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type = ToolChain::FT_Static) const override; - unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { - return 2; + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + return LangOptions::SSPStrong; } unsigned GetDefaultDwarfVersion() const override { return 2; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp index 6dc81899cbaa..383b0c50d410 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -66,8 +66,9 @@ void tools::PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("orbis-as")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) { @@ -152,8 +153,9 @@ void tools::PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld")); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileUTF8(), + Exec, CmdArgs, Inputs, Output)); } toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, @@ -237,9 +239,8 @@ SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const { } void toolchains::PS4CPU::addClangTargetOptions( - const ArgList &DriverArgs, - ArgStringList &CC1Args, - Action::OffloadKind DeviceOffloadingKind) const { + const ArgList &DriverArgs, ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadingKind) const { // PS4 does not use init arrays. if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); @@ -248,4 +249,36 @@ void toolchains::PS4CPU::addClangTargetOptions( } CC1Args.push_back("-fno-use-init-array"); + + const Arg *A = + DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, + options::OPT_fno_visibility_from_dllstorageclass); + if (!A || + A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) { + CC1Args.push_back("-fvisibility-from-dllstorageclass"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ)) + DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ); + else + CC1Args.push_back("-fvisibility-dllexport=protected"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ)) + DriverArgs.AddLastArg(CC1Args, + options::OPT_fvisibility_nodllstorageclass_EQ); + else + CC1Args.push_back("-fvisibility-nodllstorageclass=hidden"); + + if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ)) + DriverArgs.AddLastArg(CC1Args, + options::OPT_fvisibility_externs_dllimport_EQ); + else + CC1Args.push_back("-fvisibility-externs-dllimport=default"); + + if (DriverArgs.hasArg( + options::OPT_fvisibility_externs_nodllstorageclass_EQ)) + DriverArgs.AddLastArg( + CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ); + else + CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); + } } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h index 968be015d411..5f5d0e57d4ea 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PS4CPU_H #include "Gnu.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -73,8 +74,9 @@ public: bool HasNativeLLVMSupport() const override; bool isPICDefault() const override; - unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override { - return 2; // SSPStrong + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + return LangOptions::SSPStrong; } llvm::DebuggerKind getDefaultDebuggerTuning() const override { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index cc912d94cb92..0dc12c7a84b5 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -31,6 +31,21 @@ static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, addPathIfExists(D, InstallPath + Path, Paths); } +// This function tests whether a gcc installation is present either +// through gcc-toolchain argument or in the same prefix where clang +// is installed. This helps decide whether to instantiate this toolchain +// or Baremetal toolchain. +bool RISCVToolChain::hasGCCToolchain(const Driver &D, + const llvm::opt::ArgList &Args) { + if (Args.getLastArg(options::OPT_gcc_toolchain)) + return true; + + SmallString<128> GCCDir; + llvm::sys::path::append(GCCDir, D.Dir, "..", D.getTargetTriple(), + "lib/crt0.o"); + return llvm::sys::fs::exists(GCCDir); +} + /// RISCV Toolchain RISCVToolChain::RISCVToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) @@ -191,8 +206,8 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Linker), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); } // RISCV tools end. diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.h index 4734aee5f1ab..62099bee0404 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -21,6 +21,7 @@ public: RISCVToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); + static bool hasGCCToolchain(const Driver &D, const llvm::opt::ArgList &Args); bool IsIntegratedAssemblerDefault() const override { return true; } void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/ROCm.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/ROCm.h index 962c72fedfe0..21e62a465d7b 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/ROCm.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/ROCm.h @@ -13,7 +13,6 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Options.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Triple.h" @@ -103,12 +102,8 @@ private: CorrectlyRoundedSqrt.isValid(); } - // GPU architectures for which we have raised an error in - // CheckRocmVersionSupportsArch. - mutable llvm::SmallSet<CudaArch, 4> ArchsWithBadVersion; - void scanLibDevicePath(llvm::StringRef Path); - void ParseHIPVersionFile(llvm::StringRef V); + bool parseHIPVersionFile(llvm::StringRef V); SmallVector<Candidate, 4> getInstallationPathCandidates(); public: @@ -124,12 +119,6 @@ public: bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath, bool CorrectSqrt) const; - /// Emit an error if Version does not support the given Arch. - /// - /// If either Version or Arch is unknown, does not emit an error. Emits at - /// most one error per Arch. - void CheckRocmVersionSupportsArch(CudaArch Arch) const; - /// Check whether we detected a valid HIP runtime. bool hasHIPRuntime() const { return HasHIPRuntime; } diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp index b8fdc87478bc..4ed4d839ad10 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp @@ -42,7 +42,7 @@ void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -152,7 +152,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.h index b79e626ef38d..fbac92c2c0f3 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.h @@ -65,6 +65,11 @@ public: SanitizerMask getSupportedSanitizers() const override; unsigned GetDefaultDwarfVersion() const override { return 2; } + const char *getDefaultLinker() const override { + // clang currently uses Solaris ld-only options. + return "/usr/bin/ld"; + } + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp index 6ea405c0269c..e28f340f9aad 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -102,14 +102,37 @@ void VEToolChain::addClangTargetOptions(const ArgList &DriverArgs, void VEToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - // TODO upstream VE libc++ patches - llvm_unreachable("The VE target has no C++ stdlib for Clang yet"); + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) || + DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + if (const char *cl_include_dir = getenv("NCC_CPLUS_INCLUDE_PATH")) { + SmallVector<StringRef, 4> Dirs; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; + StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); + ArrayRef<StringRef> DirVec(Dirs); + addSystemIncludes(DriverArgs, CC1Args, DirVec); + } else { + SmallString<128> P(getDriver().ResourceDir); + llvm::sys::path::append(P, "include/c++/v1"); + addSystemInclude(DriverArgs, CC1Args, P); + } } void VEToolChain::AddCXXStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - // TODO upstream VE libc++ patches - llvm_unreachable("The VE target has no C++ stdlib for Clang yet"); + assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && + "Only -lc++ (aka libxx) is supported in this toolchain."); + + tools::addArchSpecificRPath(*this, Args, CmdArgs); + + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); + // libc++ requires -lpthread under glibc environment + CmdArgs.push_back("-lpthread"); + // libunwind requires -ldl under glibc environment + CmdArgs.push_back("-ldl"); } llvm::ExceptionHandling diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.h index 59069c0a7595..b330331ca84e 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.h +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.h @@ -26,6 +26,7 @@ protected: Tool *buildLinker() const override; public: + bool IsIntegratedAssemblerDefault() const override { return true; } bool isPICDefault() const override; bool isPIEDefault() const override; bool isPICDefaultForced() const override; diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp index 10168736400f..6b654886e774 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -114,8 +114,9 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique<Command>( - JA, *this, ResponseFileSupport::AtFileCurCP(), Linker, CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Linker, CmdArgs, Inputs, Output)); // When optimizing, if wasm-opt is available, run it. if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { @@ -139,7 +140,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); C.addCommand(std::make_unique<Command>( JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, CmdArgs, - Inputs)); + Inputs, Output)); } } } @@ -243,6 +244,27 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, CC1Args.push_back("+sign-ext"); } + if (!DriverArgs.hasFlag(options::OPT_mmutable_globals, + options::OPT_mno_mutable_globals, false)) { + // -fPIC implies +mutable-globals because the PIC ABI used by the linker + // depends on importing and exporting mutable globals. + llvm::Reloc::Model RelocationModel; + unsigned PICLevel; + bool IsPIE; + std::tie(RelocationModel, PICLevel, IsPIE) = + ParsePICArgs(*this, DriverArgs); + if (RelocationModel == llvm::Reloc::PIC_) { + if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals, + options::OPT_mmutable_globals, false)) { + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-fPIC" + << "-mno-mutable-globals"; + } + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+mutable-globals"); + } + } + if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) { // '-fwasm-exceptions' is not compatible with '-mno-exception-handling' if (DriverArgs.hasFlag(options::OPT_mno_exception_handing, diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/XCore.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/XCore.cpp index 5030c73c7d82..5f94f83d3691 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/XCore.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/XCore.cpp @@ -53,7 +53,7 @@ void tools::XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -82,7 +82,7 @@ void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc")); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), - Exec, CmdArgs, Inputs)); + Exec, CmdArgs, Inputs, Output)); } /// XCore tool chain diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.cpp new file mode 100644 index 000000000000..f921227076a5 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.cpp @@ -0,0 +1,33 @@ +//===--- ZOS.cpp - z/OS ToolChain Implementations ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ZOS.h" +#include "CommonArgs.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace llvm::opt; +using namespace clang; + +ZOS::ZOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : ToolChain(D, Triple, Args) {} + +ZOS::~ZOS() {} + +void ZOS::addClangTargetOptions(const ArgList &DriverArgs, + ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const { + // Pass "-faligned-alloc-unavailable" only when the user hasn't manually + // enabled or disabled aligned allocations. + if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, + options::OPT_fno_aligned_allocation)) + CC1Args.push_back("-faligned-alloc-unavailable"); +} diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.h new file mode 100644 index 000000000000..cace85d6da77 --- /dev/null +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/ZOS.h @@ -0,0 +1,40 @@ +//===--- ZOS.h - z/OS ToolChain Implementations -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ZOS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ZOS_H + +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY ZOS : public ToolChain { +public: + ZOS(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + ~ZOS() override; + + bool isPICDefault() const override { return false; } + bool isPIEDefault() const override { return false; } + bool isPICDefaultForced() const override { return false; } + + bool IsIntegratedAssemblerDefault() const override { return true; } + + void addClangTargetOptions( + const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadingKind) const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ZOS_H diff --git a/contrib/llvm-project/clang/lib/Driver/Types.cpp b/contrib/llvm-project/clang/lib/Driver/Types.cpp index 2050dffa6fa0..e898334c3227 100644 --- a/contrib/llvm-project/clang/lib/Driver/Types.cpp +++ b/contrib/llvm-project/clang/lib/Driver/Types.cpp @@ -325,10 +325,12 @@ types::getCompilationPhases(const clang::driver::Driver &Driver, // Filter to compiler mode. When the compiler is run as a preprocessor then // compilation is not an option. // -S runs the compiler in Assembly listing mode. + // -test-io is used by Flang to run InputOutputTest action if (Driver.CCCIsCPP() || DAL.getLastArg(options::OPT_E) || DAL.getLastArg(options::OPT__SLASH_EP) || DAL.getLastArg(options::OPT_M, options::OPT_MM) || - DAL.getLastArg(options::OPT__SLASH_P)) + DAL.getLastArg(options::OPT__SLASH_P) || + DAL.getLastArg(options::OPT_test_io)) LastPhase = phases::Preprocess; // --precompile only runs up to precompilation. diff --git a/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp b/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp index f00c3906df97..b44509ad3b88 100644 --- a/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp +++ b/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp @@ -186,6 +186,21 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { Modes.push_back(std::string(M)); } + if (const Arg *A = Args.getLastArg(options::OPT_fxray_function_groups)) { + StringRef S = A->getValue(); + if (S.getAsInteger(0, XRayFunctionGroups) || XRayFunctionGroups < 1) + D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S; + } + + if (const Arg *A = + Args.getLastArg(options::OPT_fxray_selected_function_group)) { + StringRef S = A->getValue(); + if (S.getAsInteger(0, XRaySelectedFunctionGroup) || + XRaySelectedFunctionGroup < 0 || + XRaySelectedFunctionGroup >= XRayFunctionGroups) + D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S; + } + // Then we want to sort and unique the modes we've collected. llvm::sort(Modes); Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end()); @@ -210,6 +225,17 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, if (!XRayFunctionIndex) CmdArgs.push_back("-fno-xray-function-index"); + if (XRayFunctionGroups > 1) { + CmdArgs.push_back(Args.MakeArgString(Twine("-fxray-function-groups=") + + Twine(XRayFunctionGroups))); + } + + if (XRaySelectedFunctionGroup != 0) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-fxray-selected-function-group=") + + Twine(XRaySelectedFunctionGroup))); + } + CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) + Twine(InstructionThreshold))); |