Index: docs/ClangCommandLineReference.rst =================================================================== --- docs/ClangCommandLineReference.rst +++ docs/ClangCommandLineReference.rst @@ -2754,6 +2754,10 @@ Enable linker relaxation +.. option:: -msmall-data-limit= + +Put global and static data smaller than the limitation into a special section (RISCV only) + Optimization level ~~~~~~~~~~~~~~~~~~ Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2099,6 +2099,8 @@ HelpText<"Enable linker relaxation">; def mno_relax : Flag<["-"], "mno-relax">, Group, HelpText<"Disable linker relaxation">; +def msmall_data_limit_EQ : Joined<["-"], "msmall-data-limit=">, Group, Alias, + HelpText<"Put global and static data smaller than the limitation into a special section">; def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; 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 T = toolchains::RISCVToolChain::getSmallDataThreshold(Args, Triple); + if (!T.empty()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-riscv-ssection-threshold=" + T)); + } } void Clang::AddSparcTargetArgs(const ArgList &Args, Index: lib/Driver/ToolChains/RISCVToolchain.h =================================================================== --- lib/Driver/ToolChains/RISCVToolchain.h +++ lib/Driver/ToolChains/RISCVToolchain.h @@ -32,6 +32,9 @@ 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: Tool *buildLinker() const override; 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, Index: test/Driver/riscv-features.c =================================================================== --- test/Driver/riscv-features.c +++ test/Driver/riscv-features.c @@ -11,3 +11,37 @@ // 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 -### %s \ +// RUN: -msmall-data-limit=0 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-T0 %s +// CHECK-RV32-T0: "-mllvm" "-riscv-ssection-threshold=0" +// RUN: %clang -target riscv64 -### %s \ +// RUN: -G0 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-G0 %s +// CHECK-RV64-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: -msmall-data-limit=16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-PIC-T16 %s +// CHECK-RV64-PIC-T16: "-mllvm" "-riscv-ssection-threshold=16" +// RUN: %clang -target riscv32 -### -S %s \ +// RUN: -msmall-data-limit=16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV32-T16 %s +// CHECK-RV32-T16: "-mllvm" "-riscv-ssection-threshold=16" +// RUN: %clang -target riscv64 -mcmodel=large -### -S %s \ +// RUN: -G16 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RV64-LARGE-G16 %s +// CHECK-RV64-LARGE-G16: "-mllvm" "-riscv-ssection-threshold=16"