[PATCH] D13319: Eliminate __llvm_profile_register calls
Justin Bogner via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 30 17:42:55 PDT 2015
David Li <davidxl at google.com> writes:
> davidxl created this revision.
> davidxl added reviewers: bogner, rsmith.
> davidxl added subscribers: cfe-commits, llvm-commits.
> Herald added subscribers: srhines, danalbert, tberghammer.
>
> With PGO, the instrumented binary needs to dump __llvm_prf_data,
> __llvm_prf_cnts, and __llvm_prf_names data sections. The runtime needs
> to figure out the start and end addresses of the sections. The way it
> is implemented for Linux is emit function calls during start up time
> to register the __llvm_profile_data variables created for the
> functions, and runtime library tracks the start and end. On Darwin,
> special section symbol is used so this is avoided.
>
> This is not only inefficient, but also wastes lots of space in text.
>
> This patch proposes using linker script to solve the problem. The
> changes in clang FE is basically refactoring. The core changes are in
> projects/compiler_rt/profile and llvm.
I think Phabricator did something really funny with these patches - I
see one patch that seems to reference files from three repos. Obviously
this can't be applied or anything. Can you attach the individual patches
please?
I haven't really looked at the changes, but at a high level, you'll want
to add an InstrProfilingPlatformLinux.c or InstrProfilingPlatformGnu.c
or something rather than changing *Other.c - we want that to be
available as a fall back on other platforms.
> http://reviews.llvm.org/D13319
>
> Files:
> include/clang/Driver/ToolChain.h
> lib/Driver/SanitizerArgs.cpp
> lib/Driver/ToolChain.cpp
> lib/Driver/ToolChains.cpp
> lib/Driver/ToolChains.h
> lib/Driver/Tools.cpp
> lib/Transforms/Instrumentation/InstrProfiling.cpp
> lib/profile/CMakeLists.txt
> lib/profile/InstrProfilingPlatformOther.c
> lib/profile/prf_data.x
> test/Instrumentation/InstrProfiling/platform.ll
>
> Index: lib/profile/prf_data.x
> ===================================================================
> --- /dev/null
> +++ lib/profile/prf_data.x
> @@ -0,0 +1,8 @@
> +SECTIONS {
> + __llvm_prf_data_start = ADDR(__llvm_prf_data);
> + __llvm_prf_data_end = ADDR(__llvm_prf_data) + SIZEOF(__llvm_prf_data);
> + __llvm_prf_cnts_start = ADDR(__llvm_prf_cnts);
> + __llvm_prf_cnts_end = ADDR(__llvm_prf_cnts) + SIZEOF(__llvm_prf_cnts);
> + __llvm_prf_names_start = ADDR(__llvm_prf_names);
> + __llvm_prf_names_end = ADDR(__llvm_prf_names) + SIZEOF(__llvm_prf_names);
> +};
> Index: lib/profile/InstrProfilingPlatformOther.c
> ===================================================================
> --- lib/profile/InstrProfilingPlatformOther.c
> +++ lib/profile/InstrProfilingPlatformOther.c
> @@ -12,63 +12,35 @@
> #if !defined(__APPLE__)
> #include <stdlib.h>
>
> -static const __llvm_profile_data *DataFirst = NULL;
> -static const __llvm_profile_data *DataLast = NULL;
> -static const char *NamesFirst = NULL;
> -static const char *NamesLast = NULL;
> -static uint64_t *CountersFirst = NULL;
> -static uint64_t *CountersLast = NULL;
> -
> -/*!
> - * \brief Register an instrumented function.
> - *
> - * Calls to this are emitted by clang with -fprofile-instr-generate. Such
> - * calls are only required (and only emitted) on targets where we haven't
> - * implemented linker magic to find the bounds of the sections.
> - */
> -__attribute__((visibility("hidden")))
> -void __llvm_profile_register_function(void *Data_) {
> - /* TODO: Only emit this function if we can't use linker magic. */
> - const __llvm_profile_data *Data = (__llvm_profile_data*)Data_;
> - if (!DataFirst) {
> - DataFirst = Data;
> - DataLast = Data + 1;
> - NamesFirst = Data->Name;
> - NamesLast = Data->Name + Data->NameSize;
> - CountersFirst = Data->Counters;
> - CountersLast = Data->Counters + Data->NumCounters;
> - return;
> - }
> -
> -#define UPDATE_FIRST(First, New) \
> - First = New < First ? New : First
> - UPDATE_FIRST(DataFirst, Data);
> - UPDATE_FIRST(NamesFirst, Data->Name);
> - UPDATE_FIRST(CountersFirst, Data->Counters);
> -#undef UPDATE_FIRST
> -
> -#define UPDATE_LAST(Last, New) \
> - Last = New > Last ? New : Last
> - UPDATE_LAST(DataLast, Data + 1);
> - UPDATE_LAST(NamesLast, Data->Name + Data->NameSize);
> - UPDATE_LAST(CountersLast, Data->Counters + Data->NumCounters);
> -#undef UPDATE_LAST
> -}
> +extern __llvm_profile_data __llvm_prf_data_start;
> +extern __llvm_profile_data __llvm_prf_data_end;
> +extern uint64_t __llvm_prf_cnts_start;
> +extern uint64_t __llvm_prf_cnts_end;
> +extern char __llvm_prf_names_start;
> +extern char __llvm_prf_names_end;
>
> __attribute__((visibility("hidden")))
> const __llvm_profile_data *__llvm_profile_begin_data(void) {
> - return DataFirst;
> + return &__llvm_prf_data_start;
> }
> __attribute__((visibility("hidden")))
> const __llvm_profile_data *__llvm_profile_end_data(void) {
> - return DataLast;
> + return &__llvm_prf_data_end;
> +}
> +__attribute__((visibility("hidden"))) const char *__llvm_profile_begin_names(
> + void) {
> + return &__llvm_prf_names_start;
> +}
> +__attribute__((visibility("hidden"))) const char *__llvm_profile_end_names(
> + void) {
> + return &__llvm_prf_names_end;
> +}
> +__attribute__((visibility("hidden"))) uint64_t *__llvm_profile_begin_counters(
> + void) {
> + return &__llvm_prf_cnts_start;
> +}
> +__attribute__((visibility("hidden"))) uint64_t *__llvm_profile_end_counters(
> + void) {
> + return &__llvm_prf_cnts_end;
> }
> -__attribute__((visibility("hidden")))
> -const char *__llvm_profile_begin_names(void) { return NamesFirst; }
> -__attribute__((visibility("hidden")))
> -const char *__llvm_profile_end_names(void) { return NamesLast; }
> -__attribute__((visibility("hidden")))
> -uint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; }
> -__attribute__((visibility("hidden")))
> -uint64_t *__llvm_profile_end_counters(void) { return CountersLast; }
> #endif
> Index: lib/profile/CMakeLists.txt
> ===================================================================
> --- lib/profile/CMakeLists.txt
> +++ lib/profile/CMakeLists.txt
> @@ -24,6 +24,11 @@
> CFLAGS -fPIC
> SOURCES ${PROFILE_SOURCES}
> PARENT_TARGET profile)
> + if(UNIX)
> + # Assume Linux
> + add_compiler_rt_resource_file(profile_x prf_data.x)
> + add_dependencies(profile profile_x)
> + endif()
> endif()
>
> add_dependencies(compiler-rt profile)
> Index: lib/Driver/Tools.cpp
> ===================================================================
> --- lib/Driver/Tools.cpp
> +++ lib/Driver/Tools.cpp
> @@ -2402,83 +2402,12 @@
> }
> }
>
> -// Until ARM libraries are build separately, we have them all in one library
> -static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
> - const ArgList &Args) {
> - const llvm::Triple &Triple = TC.getTriple();
> - bool IsWindows = Triple.isOSWindows();
> -
> - if (Triple.isWindowsMSVCEnvironment() && TC.getArch() == llvm::Triple::x86)
> - return "i386";
> -
> - if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
> - return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
> - ? "armhf"
> - : "arm";
> -
> - return TC.getArchName();
> -}
> -
> -static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
> - // The runtimes are located in the OS-specific resource directory.
> - SmallString<128> Res(TC.getDriver().ResourceDir);
> - const llvm::Triple &Triple = TC.getTriple();
> - // TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected.
> - StringRef OSLibName =
> - (Triple.getOS() == llvm::Triple::FreeBSD) ? "freebsd" : TC.getOS();
> - llvm::sys::path::append(Res, "lib", OSLibName);
> - return Res;
> -}
> -
> -SmallString<128> tools::getCompilerRT(const ToolChain &TC, const ArgList &Args,
> - StringRef Component, bool Shared) {
> - const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android
> - ? "-android"
> - : "";
> -
> - bool IsOSWindows = TC.getTriple().isOSWindows();
> - bool IsITANMSVCWindows = TC.getTriple().isWindowsMSVCEnvironment() ||
> - TC.getTriple().isWindowsItaniumEnvironment();
> - StringRef Arch = getArchNameForCompilerRTLib(TC, Args);
> - const char *Prefix = IsITANMSVCWindows ? "" : "lib";
> - const char *Suffix =
> - Shared ? (IsOSWindows ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a");
> -
> - SmallString<128> Path = getCompilerRTLibDir(TC);
> - llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
> - Arch + Env + Suffix);
> -
> - return Path;
> -}
> -
> -static const char *getCompilerRTArgString(const ToolChain &TC,
> - const llvm::opt::ArgList &Args,
> - StringRef Component,
> - bool Shared = false) {
> - return Args.MakeArgString(getCompilerRT(TC, 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 {
> @@ -2559,7 +2488,7 @@
> // whole-archive.
> if (!IsShared)
> CmdArgs.push_back("-whole-archive");
> - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Sanitizer, IsShared));
> + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared));
> if (!IsShared)
> CmdArgs.push_back("-no-whole-archive");
> }
> @@ -2569,7 +2498,7 @@
> static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
> ArgStringList &CmdArgs,
> StringRef Sanitizer) {
> - SmallString<128> SanRT = getCompilerRT(TC, Args, Sanitizer);
> + SmallString<128> SanRT = TC.getCompilerRT(Args, Sanitizer);
> if (llvm::sys::fs::exists(SanRT + ".syms")) {
> CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
> return true;
> @@ -7014,7 +6943,7 @@
> }
> 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<Command>(JA, *this, Exec, CmdArgs, Inputs));
> @@ -7605,7 +7534,7 @@
> 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<Command>(JA, *this, Exec, CmdArgs, Inputs));
> @@ -7894,7 +7823,7 @@
> 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<Command>(JA, *this, Exec, CmdArgs, Inputs));
> @@ -8419,7 +8348,7 @@
> 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)) {
> @@ -8730,7 +8659,7 @@
>
> AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
>
> - addProfileRT(getToolChain(), Args, CmdArgs);
> + getToolChain().addProfileRTLibs(Args, CmdArgs);
>
> if (!Args.hasArg(options::OPT_nostdlib) &&
> !Args.hasArg(options::OPT_nodefaultlibs)) {
> @@ -8922,7 +8851,7 @@
> 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<Command>(JA, *this, Exec, CmdArgs, Inputs));
> @@ -9028,18 +8957,18 @@
> "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 *CompilerRTComponents[] = {
> "asan", "asan_cxx",
> };
> for (const auto &Component : CompilerRTComponents)
> - CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component));
> + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Component));
> }
> }
>
> Index: lib/Driver/ToolChains.h
> ===================================================================
> --- lib/Driver/ToolChains.h
> +++ lib/Driver/ToolChains.h
> @@ -275,9 +275,11 @@
>
> /// 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 {
> + virtual bool addProfileRTLibs(
> + const llvm::opt::ArgList &Args,
> + llvm::opt::ArgStringList &CmdArgs) const override {
> // There aren't any profiling libs for embedded targets currently.
> + return false;
> }
>
> /// }
> @@ -378,7 +380,7 @@
> return !isTargetIPhoneOS() || isIPhoneOSVersionLT(6, 0);
> }
>
> - void addProfileRTLibs(const llvm::opt::ArgList &Args,
> + bool addProfileRTLibs(const llvm::opt::ArgList &Args,
> llvm::opt::ArgStringList &CmdArgs) const override;
>
> protected:
> @@ -526,6 +528,8 @@
>
> void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
> llvm::opt::ArgStringList &CC1Args) const override;
> + bool addProfileRTLibs(const llvm::opt::ArgList &Args,
> + llvm::opt::ArgStringList &CmdArgs) const override;
> };
>
> class LLVM_LIBRARY_VISIBILITY CloudABI : public Generic_ELF {
> Index: lib/Driver/ToolChains.cpp
> ===================================================================
> --- lib/Driver/ToolChains.cpp
> +++ lib/Driver/ToolChains.cpp
> @@ -298,7 +298,7 @@
> }
> }
>
> -void Darwin::addProfileRTLibs(const ArgList &Args,
> +bool Darwin::addProfileRTLibs(const ArgList &Args,
> ArgStringList &CmdArgs) const {
> if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
> false) ||
> @@ -308,15 +308,16 @@
> Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
> Args.hasArg(options::OPT_fcreate_profile) ||
> Args.hasArg(options::OPT_coverage)))
> - return;
> + return false;
>
> // Select the appropriate runtime library for the target.
> if (isTargetIOSBased())
> AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a",
> /*AlwaysLink*/ true);
> else
> AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a",
> /*AlwaysLink*/ true);
> + return true;
> }
>
> void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
> @@ -2183,6 +2184,16 @@
> CC1Args.push_back("-fuse-init-array");
> }
>
> +bool Generic_ELF::addProfileRTLibs(const llvm::opt::ArgList &Args,
> + llvm::opt::ArgStringList &CmdArgs) const {
> + if (!ToolChain::addProfileRTLibs(Args, CmdArgs)) return false;
> +
> + SmallString<128> Path(getDriver().ResourceDir);
> + llvm::sys::path::append(Path, "prf_data.x");
> + CmdArgs.push_back(Args.MakeArgString(Path));
> + return true;
> +}
> +
> /// Hexagon Toolchain
>
> std::string HexagonToolChain::GetGnuDir(const std::string &InstalledDir,
> Index: lib/Driver/ToolChain.cpp
> ===================================================================
> --- lib/Driver/ToolChain.cpp
> +++ lib/Driver/ToolChain.cpp
> @@ -456,6 +456,78 @@
>
> void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
>
> +bool ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
> + llvm::opt::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 false;
> +
> + CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
> + return true;
> +}
> +
> +StringRef ToolChain::getArchNameForCompilerRTLib(
> + const llvm::opt::ArgList &Args) const {
> + const llvm::Triple &Triple = getTriple();
> + bool IsWindows = Triple.isOSWindows();
> +
> + if (Triple.isWindowsMSVCEnvironment() && getArch() == llvm::Triple::x86)
> + return "i386";
> +
> + if (getArch() == llvm::Triple::arm || getArch() == llvm::Triple::armeb)
> + return (tools::arm::getARMFloatABI(*this, Args) ==
> + tools::arm::FloatABI::Hard &&
> + !IsWindows)
> + ? "armhf"
> + : "arm";
> +
> + return getArchName();
> +}
> +
> +SmallString<128> ToolChain::getCompilerRTLibDir() const {
> + // The runtimes are located in the OS-specific resource directory.
> + SmallString<128> Res(getDriver().ResourceDir);
> + const llvm::Triple &Triple = getTriple();
> + // TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected.
> + StringRef OSLibName =
> + (Triple.getOS() == llvm::Triple::FreeBSD) ? "freebsd" : getOS();
> + llvm::sys::path::append(Res, "lib", OSLibName);
> + return Res;
> +}
> +
> +SmallString<128> ToolChain::getCompilerRT(const llvm::opt::ArgList &Args,
> + StringRef Component,
> + bool Shared) const {
> + const char *Env =
> + getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : "";
> +
> + bool IsOSWindows = getTriple().isOSWindows();
> + bool IsITANMSVCWindows = getTriple().isWindowsMSVCEnvironment() ||
> + getTriple().isWindowsItaniumEnvironment();
> + StringRef Arch = getArchNameForCompilerRTLib(Args);
> + const char *Prefix = IsITANMSVCWindows ? "" : "lib";
> + const char *Suffix = Shared ? (IsOSWindows ? ".dll" : ".so")
> + : (IsITANMSVCWindows ? ".lib" : ".a");
> +
> + SmallString<128> Path = getCompilerRTLibDir();
> + llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
> + Arch + Env + Suffix);
> +
> + return Path;
> +}
> +
> +const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
> + StringRef Component,
> + bool Shared) const {
> + return Args.MakeArgString(getCompilerRT(Args, Component, Shared));
> +}
> +
> ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
> const ArgList &Args) const
> {
> Index: lib/Driver/SanitizerArgs.cpp
> ===================================================================
> --- lib/Driver/SanitizerArgs.cpp
> +++ lib/Driver/SanitizerArgs.cpp
> @@ -609,13 +609,11 @@
> if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
> // Instruct the code generator to embed linker directives in the object file
> // that cause the required runtime libraries to be linked.
> - CmdArgs.push_back(
> - Args.MakeArgString("--dependent-lib=" +
> - tools::getCompilerRT(TC, Args, "ubsan_standalone")));
> + CmdArgs.push_back(Args.MakeArgString(
> + "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone")));
> if (types::isCXX(InputType))
> CmdArgs.push_back(Args.MakeArgString(
> - "--dependent-lib=" +
> - tools::getCompilerRT(TC, Args, "ubsan_standalone_cxx")));
> + "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx")));
> }
> }
>
> Index: include/clang/Driver/ToolChain.h
> ===================================================================
> --- include/clang/Driver/ToolChain.h
> +++ include/clang/Driver/ToolChain.h
> @@ -96,6 +96,8 @@
> virtual Tool *buildAssembler() const;
> virtual Tool *buildLinker() const;
> virtual Tool *getTool(Action::ActionClass AC) const;
> + SmallString<128> getCompilerRTLibDir() const;
> + StringRef getArchNameForCompilerRTLib(const llvm::opt::ArgList &Args) const;
>
> /// \name Utilities for implementing subclasses.
> ///@{
> @@ -165,6 +167,13 @@
> static std::pair<std::string, std::string>
> getTargetAndModeFromProgramName(StringRef ProgName);
>
> + /// Return link commmand line arguments for clang runtime libraries.
> + SmallString<128> getCompilerRT(const llvm::opt::ArgList &Args,
> + StringRef Component,
> + bool Shared = false) const;
> + const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
> + StringRef Component,
> + bool Shared = false) const;
> // Tool access.
>
> /// TranslateArgs - Create a new derived argument list for any argument
> @@ -364,6 +373,11 @@
> 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 bool addProfileRTLibs(const llvm::opt::ArgList &Args,
> + llvm::opt::ArgStringList &CmdArgs) const;
> +
> /// \brief Return sanitizers which are available in this toolchain.
> virtual SanitizerMask getSupportedSanitizers() const;
> };
> Index: test/Instrumentation/InstrProfiling/platform.ll
> ===================================================================
> --- test/Instrumentation/InstrProfiling/platform.ll
> +++ test/Instrumentation/InstrProfiling/platform.ll
> @@ -23,7 +23,7 @@
> ;; symbols by their sections.
>
> ; MACHO-NOT: define internal void @__llvm_profile_register_functions
> -; ELF: define internal void @__llvm_profile_register_functions
> +; ELF-NOT: define internal void @__llvm_profile_register_functions
>
> ; MACHO-NOT: define internal void @__llvm_profile_init
> -; ELF: define internal void @__llvm_profile_init
> +; ELF-NOT: define internal void @__llvm_profile_init
> Index: lib/Transforms/Instrumentation/InstrProfiling.cpp
> ===================================================================
> --- lib/Transforms/Instrumentation/InstrProfiling.cpp
> +++ lib/Transforms/Instrumentation/InstrProfiling.cpp
> @@ -257,6 +257,9 @@
> if (Triple(M->getTargetTriple()).isOSDarwin())
> return;
>
> + // Use linker script magic to get data/cnts/name start/end.
> + if (Triple(M->getTargetTriple()).isOSLinux()) return;
> +
> // Construct the function.
> auto *VoidTy = Type::getVoidTy(M->getContext());
> auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
More information about the cfe-commits
mailing list