[PATCH] D13319: Eliminate __llvm_profile_register calls

Xinliang David Li via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 30 18:35:05 PDT 2015


On Wed, Sep 30, 2015 at 5:42 PM, Justin Bogner <mail at justinbogner.com> wrote:
> 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?

Ok.

>
> 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.
>

Indeed.

I will abandon this patch and create 3 individual patches.

thanks,

David

>> 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