From 37bc78dc7ac5d7d9029363d788ea7149db0d70a8 Mon Sep 17 00:00:00 2001 From: Xinliang David Li Date: Thu, 22 Oct 2015 06:15:31 +0000 Subject: [PATCH] clang driver toolchain refactoring In this patch, the file static method addProfileRT is moved to be a virtual member function of base ToolChain class. This allows derived toolchain to override the default behavior easily and make it consistent with Darwin toolchain (a TODO was added for this refactoring - now removed). A new helper method is also introduced to test if instrumentation profile option is turned on or not. Differential Revision: http://reviews.llvm.org/D13326 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@250994 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/ToolChain.h | 13 ++++++-- lib/Driver/ToolChain.cpp | 34 +++++++++++++++++--- lib/Driver/ToolChains.cpp | 11 ++----- lib/Driver/ToolChains.h | 4 +-- lib/Driver/Tools.cpp | 53 ++++++++------------------------ 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 7457ef0610..edbf56200f 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -258,6 +258,12 @@ public: StringRef Component, bool Shared = false) const; + const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared = false) const; + /// needsProfileRT - returns true if instrumentation profile is on. + static bool needsProfileRT(const llvm::opt::ArgList &Args); + /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. virtual bool IsUnwindTablesDefault() const; @@ -378,8 +384,11 @@ public: /// global flags for unsafe floating point math, add it and return true. /// /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. - virtual bool - AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, + virtual bool AddFastMathRuntimeIfAvailable( + const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// addProfileRTLibs - When -fprofile-instr-profile is specified, add profile + /// runtime library, otherwise return false. + virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; /// \brief Return sanitizers which are available in this toolchain. diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 65d4f4f4e0..2002a9ae8b 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -301,9 +301,28 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, return Path.str(); } +const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared) const { + return Args.MakeArgString(getCompilerRT(Args, Component, Shared)); +} + +bool ToolChain::needsProfileRT(const ArgList &Args) { + if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, + false) || + Args.hasArg(options::OPT_fprofile_generate) || + Args.hasArg(options::OPT_fprofile_generate_EQ) || + Args.hasArg(options::OPT_fprofile_instr_generate) || + Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || + Args.hasArg(options::OPT_fcreate_profile) || + Args.hasArg(options::OPT_coverage)) + return true; + + return false; +} + Tool *ToolChain::SelectTool(const JobAction &JA) const { - if (getDriver().ShouldUseClangCompiler(JA)) - return getClang(); + if (getDriver().ShouldUseClangCompiler(JA)) return getClang(); Action::ActionClass AC = JA.getKind(); if (AC == Action::AssembleJobClass && useIntegratedAs()) return getClangAs(); @@ -491,9 +510,16 @@ void ToolChain::addClangTargetOptions(const ArgList &DriverArgs, void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} +void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + if (!needsProfileRT(Args)) return; + + CmdArgs.push_back(getCompilerRTArgString(Args, "profile")); + return; +} + ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( - const ArgList &Args) const -{ + const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { StringRef Value = A->getValue(); if (Value == "compiler-rt") diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 6438ea7606..e8a2d833d3 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -300,15 +300,7 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, void Darwin::addProfileRTLibs(const ArgList &Args, ArgStringList &CmdArgs) const { - if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, - false) || - Args.hasArg(options::OPT_fprofile_generate) || - Args.hasArg(options::OPT_fprofile_generate_EQ) || - Args.hasArg(options::OPT_fprofile_instr_generate) || - Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage))) - return; + if (!needsProfileRT(Args)) return; // Select the appropriate runtime library for the target. if (isTargetIOSBased()) @@ -317,6 +309,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args, else AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a", /*AlwaysLink*/ true); + return; } void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 630ffb85e0..01ff328779 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -282,8 +282,8 @@ public: /// Add any profiling runtime libraries that are needed. This is essentially a /// MachO specific version of addProfileRT in Tools.cpp. - virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const { + void addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override { // There aren't any profiling libs for embedded targets currently. } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 3596a6a031..74a49580b0 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2444,34 +2444,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } } -static const char *getCompilerRTArgString(const ToolChain &TC, - const llvm::opt::ArgList &Args, - StringRef Component, - bool Shared = false) { - return Args.MakeArgString(TC.getCompilerRT(Args, Component, Shared)); -} - // This adds the static libclang_rt.builtins-arch.a directly to the command line // FIXME: Make sure we can also emit shared objects if they're requested // and available, check for possible errors, etc. static void addClangRT(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "builtins")); -} - -static void addProfileRT(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { - if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, - false) || - Args.hasArg(options::OPT_fprofile_generate) || - Args.hasArg(options::OPT_fprofile_generate_EQ) || - Args.hasArg(options::OPT_fprofile_instr_generate) || - Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile) || - Args.hasArg(options::OPT_coverage))) - return; - - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "profile")); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins")); } namespace { @@ -2550,11 +2528,9 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, bool IsShared) { // Static runtimes must be forced into executable, so we wrap them in // whole-archive. - if (!IsShared) - CmdArgs.push_back("-whole-archive"); - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Sanitizer, IsShared)); - if (!IsShared) - CmdArgs.push_back("-no-whole-archive"); + if (!IsShared) CmdArgs.push_back("-whole-archive"); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared)); + if (!IsShared) CmdArgs.push_back("-no-whole-archive"); } // Tries to use a file with the list of dynamic symbols that need to be exported @@ -6876,9 +6852,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fnested_functions)) CmdArgs.push_back("-allow_stack_execute"); - // TODO: It would be nice to use addProfileRT() here, but darwin's compiler-rt - // paths are different enough from other toolchains that this needs a fair - // amount of refactoring done first. getMachOToolChain().addProfileRTLibs(Args, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib) && @@ -7084,7 +7057,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, } CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -7676,7 +7649,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); } - addProfileRT(ToolChain, Args, CmdArgs); + ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -7965,7 +7938,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -8489,7 +8462,7 @@ void gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); // The profile runtime also needs access to system libraries. - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { @@ -8800,7 +8773,7 @@ void minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs)) { @@ -8992,7 +8965,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } - addProfileRT(getToolChain(), Args, CmdArgs); + getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); @@ -9098,18 +9071,18 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, "asan_dynamic", "asan_dynamic_runtime_thunk", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Component)); // Make sure the dynamic runtime thunk is not optimized out at link time // to ensure proper SEH handling. CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor")); } else if (DLL) { - CmdArgs.push_back(getCompilerRTArgString(TC, Args, "asan_dll_thunk")); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk")); } else { static const char *const CompilerRTComponents[] = { "asan", "asan_cxx", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Component)); } } -- 2.40.0