forked from OSchip/llvm-project
[Shave]: Drive sparc-myriad-elf-ld directly rather than via gcc.
Differential Revision: http://reviews.llvm.org/D12541 llvm-svn: 247924
This commit is contained in:
parent
f6681b4ace
commit
d6e597c2be
|
@ -2262,15 +2262,14 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
|
|||
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);
|
||||
|
|
|
@ -1170,7 +1170,8 @@ static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
|
|||
/// 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::GCCInstallationDetector::init(
|
|||
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(const ArgList &Args,
|
|||
// 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 JobAction &JA) const {
|
|||
}
|
||||
}
|
||||
|
||||
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");
|
||||
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::buildLinker() const {
|
||||
// SHAVEToolChain executables can not be linked except by the vendor tools.
|
||||
llvm_unreachable("SHAVEToolChain can't buildLinker");
|
||||
}
|
||||
|
||||
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; }
|
||||
|
|
|
@ -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 {
|
||||
/// 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:
|
||||
SHAVEToolChain(const Driver &D, const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args);
|
||||
~SHAVEToolChain() override;
|
||||
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;
|
||||
|
|
|
@ -9736,3 +9736,81 @@ void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue