forked from OSchip/llvm-project
[RISCV] enable LTO support, pass some options to linker.
Summary: 1. enable LTO need to pass target feature and abi to LTO code generation RISCV backend need the target feature to decide which extension used in code generation. 2. move getTargetFeatures to CommonArgs.h and add ForLTOPlugin flag 3. add general tools::getTargetABI in CommonArgs.h because different target uses different way to get the target ABI. Patch by Kuan Hsu Chen (khchen) Reviewers: lenary, lewis-revill, asb, MaskRay Reviewed By: lenary Subscribers: hiraditya, dschuff, aheejin, fedor.sergeev, mehdi_amini, inglorion, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, MaskRay, zzheng, edward-jones, steven_wu, rogfer01, MartinMosbeck, brucehoult, the_o, dexonsmith, rkruppe, PkmX, jocewei, psnobl, benna, Jim, lenary, s.egerton, pzheng, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67409 llvm-svn: 374774
This commit is contained in:
parent
ce56e1a1cc
commit
cdcf58e5af
|
@ -302,95 +302,6 @@ static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getWebAssemblyTargetFeatures(const ArgList &Args,
|
|
||||||
std::vector<StringRef> &Features) {
|
|
||||||
handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
|
|
||||||
const ArgList &Args, ArgStringList &CmdArgs,
|
|
||||||
bool ForAS) {
|
|
||||||
const Driver &D = TC.getDriver();
|
|
||||||
std::vector<StringRef> Features;
|
|
||||||
switch (Triple.getArch()) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case llvm::Triple::mips:
|
|
||||||
case llvm::Triple::mipsel:
|
|
||||||
case llvm::Triple::mips64:
|
|
||||||
case llvm::Triple::mips64el:
|
|
||||||
mips::getMIPSTargetFeatures(D, Triple, Args, Features);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case llvm::Triple::arm:
|
|
||||||
case llvm::Triple::armeb:
|
|
||||||
case llvm::Triple::thumb:
|
|
||||||
case llvm::Triple::thumbeb:
|
|
||||||
arm::getARMTargetFeatures(TC, Triple, Args, CmdArgs, Features, ForAS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case llvm::Triple::ppc:
|
|
||||||
case llvm::Triple::ppc64:
|
|
||||||
case llvm::Triple::ppc64le:
|
|
||||||
ppc::getPPCTargetFeatures(D, Triple, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::riscv32:
|
|
||||||
case llvm::Triple::riscv64:
|
|
||||||
riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::systemz:
|
|
||||||
systemz::getSystemZTargetFeatures(Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::aarch64:
|
|
||||||
case llvm::Triple::aarch64_be:
|
|
||||||
aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::x86:
|
|
||||||
case llvm::Triple::x86_64:
|
|
||||||
x86::getX86TargetFeatures(D, Triple, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::hexagon:
|
|
||||||
hexagon::getHexagonTargetFeatures(D, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::wasm32:
|
|
||||||
case llvm::Triple::wasm64:
|
|
||||||
getWebAssemblyTargetFeatures(Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::sparc:
|
|
||||||
case llvm::Triple::sparcel:
|
|
||||||
case llvm::Triple::sparcv9:
|
|
||||||
sparc::getSparcTargetFeatures(D, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::r600:
|
|
||||||
case llvm::Triple::amdgcn:
|
|
||||||
amdgpu::getAMDGPUTargetFeatures(D, Args, Features);
|
|
||||||
break;
|
|
||||||
case llvm::Triple::msp430:
|
|
||||||
msp430::getMSP430TargetFeatures(D, Args, Features);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the last of each feature.
|
|
||||||
llvm::StringMap<unsigned> LastOpt;
|
|
||||||
for (unsigned I = 0, N = Features.size(); I < N; ++I) {
|
|
||||||
StringRef Name = Features[I];
|
|
||||||
assert(Name[0] == '-' || Name[0] == '+');
|
|
||||||
LastOpt[Name.drop_front(1)] = I;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned I = 0, N = Features.size(); I < N; ++I) {
|
|
||||||
// If this feature was overridden, ignore it.
|
|
||||||
StringRef Name = Features[I];
|
|
||||||
llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1));
|
|
||||||
assert(LastI != LastOpt.end());
|
|
||||||
unsigned Last = LastI->second;
|
|
||||||
if (Last != I)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CmdArgs.push_back("-target-feature");
|
|
||||||
CmdArgs.push_back(Name.data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
|
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
|
||||||
const llvm::Triple &Triple) {
|
const llvm::Triple &Triple) {
|
||||||
|
|
|
@ -11,8 +11,12 @@
|
||||||
#include "Arch/ARM.h"
|
#include "Arch/ARM.h"
|
||||||
#include "Arch/Mips.h"
|
#include "Arch/Mips.h"
|
||||||
#include "Arch/PPC.h"
|
#include "Arch/PPC.h"
|
||||||
|
#include "Arch/RISCV.h"
|
||||||
|
#include "Arch/Sparc.h"
|
||||||
#include "Arch/SystemZ.h"
|
#include "Arch/SystemZ.h"
|
||||||
#include "Arch/X86.h"
|
#include "Arch/X86.h"
|
||||||
|
#include "AMDGPU.h"
|
||||||
|
#include "MSP430.h"
|
||||||
#include "HIP.h"
|
#include "HIP.h"
|
||||||
#include "Hexagon.h"
|
#include "Hexagon.h"
|
||||||
#include "InputInfo.h"
|
#include "InputInfo.h"
|
||||||
|
@ -484,6 +488,14 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
|
||||||
if (!StatsFile.empty())
|
if (!StatsFile.empty())
|
||||||
CmdArgs.push_back(
|
CmdArgs.push_back(
|
||||||
Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
|
Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
|
||||||
|
|
||||||
|
getTargetFeatures(ToolChain, ToolChain.getTriple(), Args, CmdArgs,
|
||||||
|
/* ForAS= */ false, /* ForLTOPlugin= */ true);
|
||||||
|
|
||||||
|
StringRef ABIName = tools::getTargetABI(Args, ToolChain.getTriple());
|
||||||
|
if (!ABIName.empty())
|
||||||
|
CmdArgs.push_back(
|
||||||
|
Args.MakeArgString(Twine("-plugin-opt=-target-abi=") + ABIName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
|
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
|
||||||
|
@ -1380,3 +1392,111 @@ void tools::addMultilibFlag(bool Enabled, const char *const Flag,
|
||||||
Multilib::flags_list &Flags) {
|
Multilib::flags_list &Flags) {
|
||||||
Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
|
Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void getWebAssemblyTargetFeatures(const ArgList &Args,
|
||||||
|
std::vector<StringRef> &Features) {
|
||||||
|
handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tools::getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
|
||||||
|
const ArgList &Args, ArgStringList &CmdArgs, bool ForAS,
|
||||||
|
bool ForLTOPlugin) {
|
||||||
|
|
||||||
|
const Driver &D = TC.getDriver();
|
||||||
|
std::vector<StringRef> Features;
|
||||||
|
switch (Triple.getArch()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case llvm::Triple::mips:
|
||||||
|
case llvm::Triple::mipsel:
|
||||||
|
case llvm::Triple::mips64:
|
||||||
|
case llvm::Triple::mips64el:
|
||||||
|
mips::getMIPSTargetFeatures(D, Triple, Args, Features);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case llvm::Triple::arm:
|
||||||
|
case llvm::Triple::armeb:
|
||||||
|
case llvm::Triple::thumb:
|
||||||
|
case llvm::Triple::thumbeb:
|
||||||
|
arm::getARMTargetFeatures(TC, Triple, Args, CmdArgs, Features, ForAS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case llvm::Triple::ppc:
|
||||||
|
case llvm::Triple::ppc64:
|
||||||
|
case llvm::Triple::ppc64le:
|
||||||
|
ppc::getPPCTargetFeatures(D, Triple, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::riscv32:
|
||||||
|
case llvm::Triple::riscv64:
|
||||||
|
riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::systemz:
|
||||||
|
systemz::getSystemZTargetFeatures(Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::aarch64:
|
||||||
|
case llvm::Triple::aarch64_be:
|
||||||
|
aarch64::getAArch64TargetFeatures(D, Triple, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::x86:
|
||||||
|
case llvm::Triple::x86_64:
|
||||||
|
x86::getX86TargetFeatures(D, Triple, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::hexagon:
|
||||||
|
hexagon::getHexagonTargetFeatures(D, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::wasm32:
|
||||||
|
case llvm::Triple::wasm64:
|
||||||
|
getWebAssemblyTargetFeatures(Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::sparc:
|
||||||
|
case llvm::Triple::sparcel:
|
||||||
|
case llvm::Triple::sparcv9:
|
||||||
|
sparc::getSparcTargetFeatures(D, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::r600:
|
||||||
|
case llvm::Triple::amdgcn:
|
||||||
|
amdgpu::getAMDGPUTargetFeatures(D, Args, Features);
|
||||||
|
break;
|
||||||
|
case llvm::Triple::msp430:
|
||||||
|
msp430::getMSP430TargetFeatures(D, Args, Features);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the last of each feature.
|
||||||
|
llvm::StringMap<unsigned> LastOpt;
|
||||||
|
for (unsigned I = 0, N = Features.size(); I < N; ++I) {
|
||||||
|
StringRef Name = Features[I];
|
||||||
|
assert(Name[0] == '-' || Name[0] == '+');
|
||||||
|
LastOpt[Name.drop_front(1)] = I;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned I = 0, N = Features.size(); I < N; ++I) {
|
||||||
|
// If this feature was overridden, ignore it.
|
||||||
|
StringRef Name = Features[I];
|
||||||
|
llvm::StringMap<unsigned>::iterator LastI =
|
||||||
|
LastOpt.find(Name.drop_front(1));
|
||||||
|
assert(LastI != LastOpt.end());
|
||||||
|
unsigned Last = LastI->second;
|
||||||
|
if (Last != I)
|
||||||
|
continue;
|
||||||
|
if (!ForLTOPlugin) {
|
||||||
|
CmdArgs.push_back("-target-feature");
|
||||||
|
CmdArgs.push_back(Name.data());
|
||||||
|
} else {
|
||||||
|
CmdArgs.push_back(
|
||||||
|
Args.MakeArgString(Twine("-plugin-opt=-mattr=") + Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef tools::getTargetABI(const ArgList &Args, const llvm::Triple &Triple) {
|
||||||
|
// TODO: Support the other target ABI
|
||||||
|
switch (Triple.getArch()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case llvm::Triple::riscv32:
|
||||||
|
case llvm::Triple::riscv64:
|
||||||
|
return tools::riscv::getRISCVABI(Args, Triple);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return StringRef();
|
||||||
|
}
|
||||||
|
|
|
@ -118,6 +118,14 @@ SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
|
||||||
void addMultilibFlag(bool Enabled, const char *const Flag,
|
void addMultilibFlag(bool Enabled, const char *const Flag,
|
||||||
Multilib::flags_list &Flags);
|
Multilib::flags_list &Flags);
|
||||||
|
|
||||||
|
StringRef getTargetABI(const llvm::opt::ArgList &Args,
|
||||||
|
const llvm::Triple &Triple);
|
||||||
|
|
||||||
|
void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
|
||||||
|
const llvm::opt::ArgList &Args,
|
||||||
|
llvm::opt::ArgStringList &CmdArgs, bool ForAS,
|
||||||
|
bool ForLTOPlugin = false);
|
||||||
|
|
||||||
} // end namespace tools
|
} // end namespace tools
|
||||||
} // end namespace driver
|
} // end namespace driver
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "RISCVToolchain.h"
|
#include "RISCVToolchain.h"
|
||||||
|
#include "Arch/RISCV.h"
|
||||||
#include "CommonArgs.h"
|
#include "CommonArgs.h"
|
||||||
#include "InputInfo.h"
|
#include "InputInfo.h"
|
||||||
#include "clang/Driver/Compilation.h"
|
#include "clang/Driver/Compilation.h"
|
||||||
|
@ -100,6 +101,12 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
|
|
||||||
std::string Linker = getToolChain().GetProgramPath(getShortName());
|
std::string Linker = getToolChain().GetProgramPath(getShortName());
|
||||||
|
|
||||||
|
if (D.isUsingLTO()) {
|
||||||
|
assert(!Inputs.empty() && "Must have at least one input.");
|
||||||
|
AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0],
|
||||||
|
D.getLTOMode() == LTOK_Thin);
|
||||||
|
}
|
||||||
|
|
||||||
bool WantCRTs =
|
bool WantCRTs =
|
||||||
!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
|
!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
|
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args,
|
llvm::opt::ArgStringList &CC1Args,
|
||||||
Action::OffloadKind) const override;
|
Action::OffloadKind) const override;
|
||||||
|
bool HasNativeLLVMSupport() const override { return true; }
|
||||||
void
|
void
|
||||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
|
|
|
@ -26,3 +26,21 @@
|
||||||
// RUN: %clang -target i686-linux-android -### %t.o -flto 2>&1 \
|
// RUN: %clang -target i686-linux-android -### %t.o -flto 2>&1 \
|
||||||
// RUN: | FileCheck %s --check-prefix=CHECK-X86-ANDROID
|
// RUN: | FileCheck %s --check-prefix=CHECK-X86-ANDROID
|
||||||
// CHECK-X86-ANDROID: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
|
// CHECK-X86-ANDROID: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
|
||||||
|
//
|
||||||
|
// RUN: %clang -target riscv64-unknown-elf -### %t.o -flto 2>&1 \
|
||||||
|
// RUN: -march=rv64imf -mabi=lp64f \
|
||||||
|
// RUN: | FileCheck %s --check-prefix=CHECK-RISCV-BAREMETAL
|
||||||
|
// CHECK-RISCV-BAREMETAL: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
|
||||||
|
// CHECK-RISCV-BAREMETAL: "-plugin-opt=-mattr=+m"
|
||||||
|
// CHECK-RISCV-BAREMETAL: "-plugin-opt=-mattr=+f"
|
||||||
|
// CHECK-RISCV-BAREMETAL: "-plugin-opt=-mattr=+relax"
|
||||||
|
// CHECK-RISCV-BAREMETAL: "-plugin-opt=-target-abi=lp64f"
|
||||||
|
//
|
||||||
|
// RUN: %clang -target riscv64-unknown-linux-gnu -### %t.o -flto 2>&1 \
|
||||||
|
// RUN: -march=rv64imf -mabi=lp64f \
|
||||||
|
// RUN: | FileCheck %s --check-prefix=CHECK-RISCV-LINUX
|
||||||
|
// CHECK-RISCV-LINUX: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
|
||||||
|
// CHECK-RISCV-LINUX: "-plugin-opt=-mattr=+m"
|
||||||
|
// CHECK-RISCV-LINUX: "-plugin-opt=-mattr=+f"
|
||||||
|
// CHECK-RISCV-LINUX: "-plugin-opt=-mattr=+relax"
|
||||||
|
// CHECK-RISCV-LINUX: "-plugin-opt=-target-abi=lp64f"
|
||||||
|
|
Loading…
Reference in New Issue