[PATCH] D13319: Eliminate __llvm_profile_register calls

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 23:07:28 PDT 2015


Xinliang David Li <davidxl at google.com> writes:
> 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.

For the record, three reviews on phab (with three unrelated email
threads) is not better. Phab just can't handle this kind of thing and
you're better off sending an email with three patches attached.

> 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 llvm-commits mailing list