r247924 - [Shave]: Drive sparc-myriad-elf-ld directly rather than via gcc.

Douglas Katzman via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 17 12:56:40 PDT 2015


Author: dougk
Date: Thu Sep 17 14:56:40 2015
New Revision: 247924

URL: http://llvm.org/viewvc/llvm-project?rev=247924&view=rev
Log:
[Shave]: Drive sparc-myriad-elf-ld directly rather than via gcc.

Differential Revision: http://reviews.llvm.org/D12541

Added:
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/
    cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtbegin.o
Modified:
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/ToolChains.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/Tools.h
    cfe/trunk/test/Driver/shave-toolchain.c

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Sep 17 14:56:40 2015
@@ -2262,15 +2262,14 @@ const ToolChain &Driver::getToolChain(co
       case llvm::Triple::xcore:
         TC = new toolchains::XCoreToolChain(*this, Target, Args);
         break;
-      case llvm::Triple::shave:
-        TC = new toolchains::SHAVEToolChain(*this, Target, Args);
-        break;
       case llvm::Triple::wasm32:
       case llvm::Triple::wasm64:
         TC = new toolchains::WebAssembly(*this, Target, Args);
         break;
       default:
-        if (Target.isOSBinFormatELF())
+        if (Target.getVendor() == llvm::Triple::Myriad)
+          TC = new toolchains::MyriadToolChain(*this, Target, Args);
+        else if (Target.isOSBinFormatELF())
           TC = new toolchains::Generic_ELF(*this, Target, Args);
         else if (Target.isOSBinFormatMachO())
           TC = new toolchains::MachO(*this, Target, Args);

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Thu Sep 17 14:56:40 2015
@@ -1170,7 +1170,8 @@ static llvm::StringRef getGCCToolchainDi
 /// necessary because the driver doesn't store the final version of the target
 /// triple.
 void Generic_GCC::GCCInstallationDetector::init(
-    const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args) {
+    const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args,
+    const ArrayRef<std::string> ExtraTripleAliases) {
   llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
                                          ? TargetTriple.get64BitArchVariant()
                                          : TargetTriple.get32BitArchVariant();
@@ -1218,6 +1219,8 @@ void Generic_GCC::GCCInstallationDetecto
       const std::string LibDir = Prefix + Suffix.str();
       if (!llvm::sys::fs::exists(LibDir))
         continue;
+      for (const StringRef Candidate : ExtraTripleAliases) // Try these first.
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
       for (const StringRef Candidate : CandidateTripleAliases)
         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
     }
@@ -3920,9 +3923,33 @@ void XCoreToolChain::AddCXXStdlibLibArgs
   // We don't output any lib args. This is handled by xcc.
 }
 
-// SHAVEToolChain does not call Clang's C compiler.
-// We override SelectTool to avoid testing ShouldUseClangCompiler().
-Tool *SHAVEToolChain::SelectTool(const JobAction &JA) const {
+MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
+                                 const ArgList &Args)
+    : Generic_GCC(D, Triple, Args) {
+  // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
+  // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
+  // This won't work to find gcc. Instead we give the installation detector an
+  // extra triple, which is preferable to further hacks of the logic that at
+  // present is based solely on getArch(). In particular, it would be wrong to
+  // choose the myriad installation when targeting a non-myriad sparc install.
+  switch (Triple.getArch()) {
+  default:
+    D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName() << "myriad";
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::shave:
+    GCCInstallation.init(D, Triple, Args, {"sparc-myriad-elf"});
+  }
+}
+
+MyriadToolChain::~MyriadToolChain() {}
+
+// MyriadToolChain handles several triples:
+//  {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
+Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
+  // The inherited method works fine if not targeting the SHAVE.
+  if (!isShaveCompilation(getTriple()))
+    return ToolChain::SelectTool(JA);
   switch (JA.getKind()) {
   case Action::CompileJobClass:
     if (!Compiler)
@@ -3937,30 +3964,29 @@ Tool *SHAVEToolChain::SelectTool(const J
   }
 }
 
-SHAVEToolChain::SHAVEToolChain(const Driver &D, const llvm::Triple &Triple,
-                               const ArgList &Args)
-    : Generic_GCC(D, Triple, Args) {}
-
-SHAVEToolChain::~SHAVEToolChain() {}
-
-/// Following are methods necessary to avoid having moviClang be an abstract
-/// class.
-
-Tool *SHAVEToolChain::getTool(Action::ActionClass AC) const {
-  // SelectTool() must find a tool using the method in the superclass.
-  // There's nothing we can do if that fails.
-  llvm_unreachable("SHAVEToolChain can't getTool");
-}
-
-Tool *SHAVEToolChain::buildLinker() const {
-  // SHAVEToolChain executables can not be linked except by the vendor tools.
-  llvm_unreachable("SHAVEToolChain can't buildLinker");
+void MyriadToolChain::getCompilerSupportDir(std::string &Dir) const {
+  // This directory contains crt{i,n,begin,end}.o as well as libgcc.
+  // These files are tied to a particular version of gcc.
+  SmallString<128> Result(GCCInstallation.getInstallPath());
+  // There are actually 4 choices: {le,be} x {fpu,nofpu}
+  // but as this toolchain is for LEON sparc, it can assume FPU.
+  if (this->getTriple().getArch() == llvm::Triple::sparcel)
+    llvm::sys::path::append(Result, "le");
+  Dir.assign(Result.str());
+}
+void MyriadToolChain::getBuiltinLibDir(std::string &Dir) const {
+  // The contents of LibDir are independent of the version of gcc.
+  // This contains libc, libg (a superset of libc), libm, libstdc++, libssp.
+  SmallString<128> Result(GCCInstallation.getParentLibPath());
+  if (this->getTriple().getArch() == llvm::Triple::sparcel)
+    llvm::sys::path::append(Result, "../sparc-myriad-elf/lib/le");
+  else
+    llvm::sys::path::append(Result, "../sparc-myriad-elf/lib");
+  Dir.assign(Result.str());
 }
 
-Tool *SHAVEToolChain::buildAssembler() const {
-  // This one you'd think should be reachable since we expose an
-  // assembler to the driver, except not the way it expects.
-  llvm_unreachable("SHAVEToolChain can't buildAssembler");
+Tool *MyriadToolChain::buildLinker() const {
+  return new tools::Myriad::Linker(*this);
 }
 
 bool WebAssembly::IsMathErrnoDefault() const { return false; }

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Thu Sep 17 14:56:40 2015
@@ -101,7 +101,8 @@ public:
   public:
     GCCInstallationDetector() : IsValid(false) {}
     void init(const Driver &D, const llvm::Triple &TargetTriple,
-              const llvm::opt::ArgList &Args);
+              const llvm::opt::ArgList &Args,
+              const ArrayRef<std::string> ExtraTripleAliases = {});
 
     /// \brief Check whether we detected a valid GCC install.
     bool isValid() const { return IsValid; }
@@ -918,21 +919,23 @@ public:
                            llvm::opt::ArgStringList &CmdArgs) const override;
 };
 
-/// SHAVEToolChain - A tool chain using the compiler installed by the
-/// Movidius SDK into MV_TOOLS_DIR (which we assume will be copied to llvm's
-/// installation dir) to perform all subcommands.
-class LLVM_LIBRARY_VISIBILITY SHAVEToolChain : public Generic_GCC {
-public:
-  SHAVEToolChain(const Driver &D, const llvm::Triple &Triple,
-                 const llvm::opt::ArgList &Args);
-  ~SHAVEToolChain() override;
+/// MyriadToolChain - A tool chain using either clang or the external compiler
+/// installed by the Movidius SDK to perform all subcommands.
+class LLVM_LIBRARY_VISIBILITY MyriadToolChain : public Generic_GCC {
+public:
+  MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
+                  const llvm::opt::ArgList &Args);
+  ~MyriadToolChain() override;
 
   Tool *SelectTool(const JobAction &JA) const override;
+  void getCompilerSupportDir(std::string &Dir) const;
+  void getBuiltinLibDir(std::string &Dir) const;
 
 protected:
-  Tool *getTool(Action::ActionClass AC) const override;
-  Tool *buildAssembler() const override;
   Tool *buildLinker() const override;
+  bool isShaveCompilation(const llvm::Triple &T) const {
+    return T.getArch() == llvm::Triple::shave;
+  }
 
 private:
   mutable std::unique_ptr<Tool> Compiler;

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Sep 17 14:56:40 2015
@@ -9736,3 +9736,81 @@ void tools::SHAVE::Assembler::ConstructJ
   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
                                           CmdArgs, Inputs));
 }
+
+void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                         const InputInfo &Output,
+                                         const InputInfoList &Inputs,
+                                         const ArgList &Args,
+                                         const char *LinkingOutput) const {
+  const auto &TC =
+      static_cast<const toolchains::MyriadToolChain &>(getToolChain());
+  const llvm::Triple &T = TC.getTriple();
+  ArgStringList CmdArgs;
+  bool UseStartfiles = !Args.hasArg(options::OPT_nostartfiles);
+
+  std::string StartFilesDir, BuiltinLibDir;
+  TC.getCompilerSupportDir(StartFilesDir);
+  TC.getBuiltinLibDir(BuiltinLibDir);
+
+  if (T.getArch() == llvm::Triple::sparc)
+    CmdArgs.push_back("-EB");
+  else // SHAVE assumes little-endian, and sparcel is expressly so.
+    CmdArgs.push_back("-EL");
+
+  // The remaining logic is mostly like gnutools::Linker::ConstructJob,
+  // but we never pass through a --sysroot option and various other bits.
+  // For example, there are no sanitizers (yet) nor gold linker.
+
+  // Eat some arguments that may be present but have no effect.
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  Args.ClaimAllArgs(options::OPT_w);
+  Args.ClaimAllArgs(options::OPT_static_libgcc);
+
+  if (Args.hasArg(options::OPT_s)) // Pass the 'strip' option.
+    CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (UseStartfiles) {
+    // If you want startfiles, it means you want the builtin crti and crtbegin,
+    // but not crt0. Myriad link commands provide their own crt0.o as needed.
+    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crti.o"));
+    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crtbegin.o"));
+  }
+
+  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});
+
+  // The linker doesn't use these builtin paths unless directed to,
+  // because it was not compiled for support with sysroots, nor does
+  // it have a default of little-endian with FPU.
+  CmdArgs.push_back(Args.MakeArgString("-L" + BuiltinLibDir));
+  CmdArgs.push_back(Args.MakeArgString("-L" + StartFilesDir));
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+  if (T.getOS() == llvm::Triple::RTEMS) {
+    CmdArgs.push_back("--start-group");
+    CmdArgs.push_back("-lc");
+    // You must provide your own "-L" option to enable finding these.
+    CmdArgs.push_back("-lrtemscpu");
+    CmdArgs.push_back("-lrtemsbsp");
+    CmdArgs.push_back("--end-group");
+  } else {
+    CmdArgs.push_back("-lc");
+  }
+  if (C.getDriver().CCCIsCXX())
+    CmdArgs.push_back("-lstdc++");
+  CmdArgs.push_back("-lgcc");
+  if (UseStartfiles) {
+    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crtend.o"));
+    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crtn.o"));
+  }
+
+  std::string Exec =
+      Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld"));
+  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
+                                          CmdArgs, Inputs));
+}

Modified: cfe/trunk/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.h (original)
+++ cfe/trunk/lib/Driver/Tools.h Thu Sep 17 14:56:40 2015
@@ -794,6 +794,23 @@ public:
 };
 } // end namespace SHAVE
 
+/// The Myriad toolchain uses tools that are in two different namespaces.
+/// The Compiler and Assembler as defined above are in the SHAVE namespace,
+/// whereas the linker, which accepts code for a mixture of Sparc and SHAVE,
+/// is in the Myriad namespace.
+namespace Myriad {
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+  Linker(const ToolChain &TC) : GnuTool("shave::Linker", "ld", TC) {}
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace Myriad
+
 } // end namespace tools
 } // end namespace driver
 } // end namespace clang

Added: cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtbegin.o
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtbegin.o?rev=247924&view=auto
==============================================================================
    (empty)

Modified: cfe/trunk/test/Driver/shave-toolchain.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/shave-toolchain.c?rev=247924&r1=247923&r2=247924&view=diff
==============================================================================
--- cfe/trunk/test/Driver/shave-toolchain.c (original)
+++ cfe/trunk/test/Driver/shave-toolchain.c Thu Sep 17 14:56:40 2015
@@ -1,3 +1,16 @@
+// RUN: %clang -no-canonical-prefixes -### -target sparc-myriad-rtems-elf %s \
+// RUN: -B %S/Inputs/basic_myriad_tree 2>&1 | FileCheck %s -check-prefix=LINK_WITH_RTEMS
+// LINK_WITH_RTEMS: Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crti.o
+// LINK_WITH_RTEMS: Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtbegin.o
+// LINK_WITH_RTEMS: "-L{{.*}}Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/../../../../sparc-myriad-elf/lib"
+// LINK_WITH_RTEMS: "-L{{.*}}Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2"
+// LINK_WITH_RTEMS: "--start-group" "-lc" "-lrtemscpu" "-lrtemsbsp" "--end-group" "-lgcc"
+// LINK_WITH_RTEMS: Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtend.o
+// LINK_WITH_RTEMS: Inputs/basic_myriad_tree/lib/gcc/sparc-myriad-elf/4.8.2/crtn.o
+
+// RUN: %clang -### -target what-myriad %s 2>&1 | FileCheck %s -check-prefix=BAD_ARCH
+// BAD_ARCH: the target architecture 'what' is not supported by the target 'myriad'
+
 // Ensure that '-target shave' picks a different compiler.
 // Also check that '-I' is turned into '-i:' for the assembler.
 
@@ -8,26 +21,26 @@
 // As such, we test only for a trailing quote in its rendering.
 // The same goes for "moviAsm".
 
-// RUN: %clang -target shave -c -### %s -isystem somewhere -Icommon -Wa,-yippee 2>&1 \
+// RUN: %clang -target shave-myriad -c -### %s -isystem somewhere -Icommon -Wa,-yippee 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=MOVICOMPILE
 // MOVICOMPILE: moviCompile" "-DMYRIAD2" "-mcpu=myriad2" "-S" "-isystem" "somewhere" "-I" "common"
 // MOVICOMPILE: moviAsm" "-no6thSlotCompression" "-cv:myriad2" "-noSPrefixing" "-a"
 // MOVICOMPILE: "-yippee" "-i:somewhere" "-i:common" "-elf"
 
-// RUN: %clang -target shave -c -### %s -DEFINE_ME -UNDEFINE_ME 2>&1 \
+// RUN: %clang -target shave-myriad -c -### %s -DEFINE_ME -UNDEFINE_ME 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=DEFINES
 // DEFINES: "-D" "EFINE_ME" "-U" "NDEFINE_ME"
 
-// RUN: %clang -target shave -c -### %s -Icommon -iquote quotepath -isystem syspath 2>&1 \
+// RUN: %clang -target shave-myriad -c -### %s -Icommon -iquote quotepath -isystem syspath 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=INCLUDES
 // INCLUDES: "-iquote" "quotepath" "-isystem" "syspath"
 
-// RUN: %clang -target shave -c -### %s -g -fno-inline-functions \
+// RUN: %clang -target shave-myriad -c -### %s -g -fno-inline-functions \
 // RUN: -fno-inline-functions-called-once -Os -Wall -MF dep.d \
 // RUN: -ffunction-sections 2>&1 | FileCheck %s -check-prefix=PASSTHRU_OPTIONS
 // PASSTHRU_OPTIONS: "-g" "-fno-inline-functions" "-fno-inline-functions-called-once"
 // PASSTHRU_OPTIONS: "-Os" "-Wall" "-MF" "dep.d" "-ffunction-sections"
 
-// RUN: %clang -target shave -c %s -o foo.o -### -MD -MF dep.d 2>&1 \
+// RUN: %clang -target shave-myriad -c %s -o foo.o -### -MD -MF dep.d 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=MDMF
 // MDMF: "-S" "-MD" "-MF" "dep.d" "-MT" "foo.o"




More information about the cfe-commits mailing list