Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -21,6 +21,7 @@ #include "MSP430.h" #include "InputInfo.h" #include "PS4CPU.h" +#include "RISCVToolchain.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/ObjCRuntime.h" @@ -1799,6 +1800,13 @@ CmdArgs.push_back("-target-abi"); CmdArgs.push_back(ABIName); + + // Passing small data section limitaion. + StringRef G = toolchains::RISCVToolChain::getSmallDataThreshold(Args, Triple); + if (!G.empty()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-riscv-ssection-threshold=" + G)); + } } void Clang::AddSparcTargetArgs(const ArgList &Args, Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -15,6 +15,7 @@ #include "Arch/SystemZ.h" #include "CommonArgs.h" #include "Linux.h" +#include "RISCVToolchain.h" #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" @@ -460,6 +461,22 @@ assert(!Inputs.empty() && "Must have at least one input."); AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0], D.getLTOMode() == LTOK_Thin); + + if (Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64) { + // Passing small data section limitaion. + StringRef G = + toolchains::RISCVToolChain::getSmallDataThreshold(Args, Triple); + if (!G.empty()) { + if (Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld")) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-riscv-ssection-threshold=" + G)); + } else { + CmdArgs.push_back( + Args.MakeArgString("-plugin-opt=-riscv-ssection-threshold=" + G)); + } + } + } } if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) Index: lib/Driver/ToolChains/RISCVToolchain.h =================================================================== --- lib/Driver/ToolChains/RISCVToolchain.h +++ lib/Driver/ToolChains/RISCVToolchain.h @@ -32,7 +32,11 @@ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + static StringRef getSmallDataThreshold(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); + protected: + bool HasNativeLLVMSupport() const override { return true; } Tool *buildLinker() const override; private: Index: lib/Driver/ToolChains/RISCVToolchain.cpp =================================================================== --- lib/Driver/ToolChains/RISCVToolchain.cpp +++ lib/Driver/ToolChains/RISCVToolchain.cpp @@ -86,6 +86,25 @@ return SysRootDir; } +StringRef RISCVToolChain::getSmallDataThreshold(const ArgList &Args, + const llvm::Triple &Triple) { + StringRef Gn = ""; + if (Arg *A = Args.getLastArg(options::OPT_G)) { + Gn = A->getValue(); + // Not support linker relaxation for PIC. + } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic, + options::OPT_fPIC)) { + Gn = "0"; + // Not support linker relaxation for RV64 with large code model. + } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ) + .equals_lower("large") && + (Triple.getArch() == llvm::Triple::riscv64)) { + Gn = "0"; + } + + return Gn; +} + void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -114,6 +133,25 @@ {options::OPT_T_Group, options::OPT_e, options::OPT_s, options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); + if (D.isUsingLTO()) { + assert(!Inputs.empty() && "Must have at least one input."); + AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0], + D.getLTOMode() == LTOK_Thin); + + // Passing small data section limitaion. + StringRef G = toolchains::RISCVToolChain::getSmallDataThreshold( + Args, ToolChain.getTriple()); + if (!G.empty()) { + if (Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld")) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-riscv-ssection-threshold=" + G)); + } else { + CmdArgs.push_back( + Args.MakeArgString("-plugin-opt=-riscv-ssection-threshold=" + G)); + } + } + } + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); // TODO: add C++ includes and libs if compiling C++. Index: test/Driver/riscv-features.c =================================================================== --- test/Driver/riscv-features.c +++ test/Driver/riscv-features.c @@ -11,3 +11,41 @@ // NO-RELAX: "-target-feature" "-relax" // DEFAULT-NOT: "-target-feature" "+relax" // DEFAULT-NOT: "-target-feature" "-relax" + +/// Small data section limitaion setting. +// RUN: %clang -target riscv32 -### -S %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32 %s +// CHECK-RV32-NOT: "-mllvm" "-riscv-ssection-threshold" +// RUN: %clang -target riscv64 -### -S %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64 %s +// CHECK-RV64-NOT: "-mllvm" "-riscv-ssection-threshold" +// RUN: %clang -target riscv32 -flto -### %s \ +// RUN: -G 16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-G16-LTO %s +// CHECK-RV32-G16-LTO: "-plugin-opt=-riscv-ssection-threshold=16" +// RUN: %clang -target riscv32-unknown-linux-gnu -flto -### %s \ +// RUN: -G 16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-LINUX-G16-LTO %s +// CHECK-RV32-LINUX-G16-LTO: "-plugin-opt=-riscv-ssection-threshold=16" +// RUN: %clang -target riscv32 -### %s \ +// RUN: -G 0 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-G0 %s +// CHECK-RV32-G0: "-mllvm" "-riscv-ssection-threshold=0" +// RUN: %clang -target riscv64 -mcmodel=large -### -S %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-LARGE %s +// CHECK-RV64-LARGE: "-mllvm" "-riscv-ssection-threshold=0" +// RUN: %clang -target riscv32 -fpic -### -S %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-PIC %s +// CHECK-RV32-PIC: "-mllvm" "-riscv-ssection-threshold=0" +// RUN: %clang -target riscv64 -fpic -### -S %s \ +// RUN: -G 16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-PIC-G16 %s +// CHECK-RV64-PIC-G16: "-mllvm" "-riscv-ssection-threshold=16" +// RUN: %clang -target riscv32 -### -S %s \ +// RUN: -G 16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-G16 %s +// CHECK-RV32-G16: "-mllvm" "-riscv-ssection-threshold=16" +// RUN: %clang -target riscv64 -mcmodel=large -### -S %s \ +// RUN: -G 16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-LARGE-G16 %s +// CHECK-RV64-LARGE-G16: "-mllvm" "-riscv-ssection-threshold=16"