[clang] fc37526 - [RISCV] Passing small data limitation value to RISCV backend

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 19 20:05:51 PDT 2020


Author: Shiva Chen
Date: 2020-03-20T11:03:51+08:00
New Revision: fc3752665f4b7ae2ec3faad4204512687800c1ec

URL: https://github.com/llvm/llvm-project/commit/fc3752665f4b7ae2ec3faad4204512687800c1ec
DIFF: https://github.com/llvm/llvm-project/commit/fc3752665f4b7ae2ec3faad4204512687800c1ec.diff

LOG: [RISCV] Passing small data limitation value to RISCV backend

Passing small data limit to RISCVELFTargetObjectFile by module flag,
So the backend can set small data section threshold by the value.
The data will be put into the small data section if the data smaller than
the threshold.

Differential Revision: https://reviews.llvm.org/D57497

Added: 
    clang/test/CodeGen/riscv-sdata-module-flag.c
    clang/test/Driver/riscv-sdata-warning.c

Modified: 
    clang/docs/ClangCommandLineReference.rst
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Basic/DiagnosticDriverKinds.td
    clang/include/clang/Driver/CC1Options.td
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/CodeGen/CodeGenModule.h
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst
index 74e831c36eb9..3f0e471e852a 100644
--- a/clang/docs/ClangCommandLineReference.rst
+++ b/clang/docs/ClangCommandLineReference.rst
@@ -2403,7 +2403,7 @@ Target-dependent compilation options
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .. option:: -G<size>, -G=<arg>, -msmall-data-threshold=<arg>
 
-Put objects of at most <size> bytes into small data section (MIPS / Hexagon)
+Put objects of at most <size> bytes into small data section (MIPS / Hexagon / RISCV)
 
 .. option:: -ffixed-x1
 
@@ -3201,6 +3201,10 @@ Enable linker relaxation
 
 Enable using library calls for save and restore
 
+.. option:: -msmall-data-limit=<limit>
+
+Put global and static data smaller than the limit into a special section
+
 Long double flags
 -----------------
 Selects the long double implementation

diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index e047054447f3..5b59954fae7b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -306,6 +306,9 @@ CODEGENOPT(LTOVisibilityPublicStd, 1, 0)
 /// or 0 if unspecified.
 VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
 
+/// The threshold to put data into small data section.
+VALUE_CODEGENOPT(SmallDataLimit, 32, 0)
+
 /// The lower bound for a buffer to be considered for stack protection.
 VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
 

diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 48ece91d3c45..2d13295bd301 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -399,6 +399,9 @@ def warn_drv_unsupported_gpopt : Warning<
   "ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
   " usage of }0-mabicalls">,
   InGroup<UnsupportedGPOpt>;
+def warn_drv_unsupported_sdata : Warning<
+  "ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">,
+  InGroup<OptionIgnored>;
 def warn_drv_unsupported_longcalls : Warning<
   "ignoring '-mlong-calls' option as it is not currently supported with "
   "%select{|the implicit usage of }0-mabicalls">,

diff  --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index cc30893703df..66a443b0d0f4 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -313,6 +313,8 @@ def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
   HelpText<"Do not put zero initialized data in the BSS">;
 def mregparm : Separate<["-"], "mregparm">,
   HelpText<"Limit the number of registers available for integer arguments">;
+def msmall_data_limit : Separate<["-"], "msmall-data-limit">,
+  HelpText<"Put global and static data smaller than the limit into a special section">;
 def munwind_tables : Flag<["-"], "munwind-tables">,
   HelpText<"Generate unwinding tables for all functions">;
 def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3a4830c84483..19bb72c55aa8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2300,6 +2300,9 @@ def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>,
   HelpText<"Enable linker relaxation">;
 def mno_relax : Flag<["-"], "mno-relax">, Group<m_riscv_Features_Group>,
   HelpText<"Disable linker relaxation">;
+def msmall_data_limit_EQ : Joined<["-"], "msmall-data-limit=">, Group<m_Group>,
+  Alias<G>,
+  HelpText<"Put global and static data smaller than the limit into a special section">;
 def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
   HelpText<"Enable using library calls for save and restore">;
 def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index cd77a727231b..9a8aee1a7157 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -660,6 +660,8 @@ void CodeGenModule::Release() {
     EmitCommandLineMetadata();
 
   EmitTargetMetadata();
+
+  EmitBackendOptionsMetadata(getCodeGenOpts());
 }
 
 void CodeGenModule::EmitOpenCLMetadata() {
@@ -679,6 +681,19 @@ void CodeGenModule::EmitOpenCLMetadata() {
   OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
 }
 
+void CodeGenModule::EmitBackendOptionsMetadata(
+    const CodeGenOptions CodeGenOpts) {
+  switch (getTriple().getArch()) {
+  default:
+    break;
+  case llvm::Triple::riscv32:
+  case llvm::Triple::riscv64:
+    getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit",
+                              CodeGenOpts.SmallDataLimit);
+    break;
+  }
+}
+
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
   // Make sure that this type is translated.
   Types.UpdateCompletedType(TD);

diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index fc4486659426..391aa70621c6 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1512,6 +1512,10 @@ class CodeGenModule : public CodeGenTypeCache {
   /// Emits target specific Metadata for global declarations.
   void EmitTargetMetadata();
 
+  /// Emit the module flag metadata used to pass options controlling the
+  /// the backend to LLVM.
+  void EmitBackendOptionsMetadata(const CodeGenOptions CodeGenOpts);
+
   /// Emits OpenCL specific Metadata e.g. OpenCL version.
   void EmitOpenCLMetadata();
 

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1193dde5a679..3ff361643c05 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1960,6 +1960,36 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
   }
 }
 
+static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args,
+                                   ArgStringList &CmdArgs) {
+  const Driver &D = TC.getDriver();
+  const llvm::Triple &Triple = TC.getTriple();
+  // Default small data limitation is eight.
+  const char *SmallDataLimit = "8";
+  // Get small data limitation.
+  if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
+                      options::OPT_fPIC)) {
+    // Not support linker relaxation for PIC.
+    SmallDataLimit = "0";
+    if (Args.hasArg(options::OPT_G)) {
+      D.Diag(diag::warn_drv_unsupported_sdata);
+    }
+  } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ)
+                 .equals_lower("large") &&
+             (Triple.getArch() == llvm::Triple::riscv64)) {
+    // Not support linker relaxation for RV64 with large code model.
+    SmallDataLimit = "0";
+    if (Args.hasArg(options::OPT_G)) {
+      D.Diag(diag::warn_drv_unsupported_sdata);
+    }
+  } else if (Arg *A = Args.getLastArg(options::OPT_G)) {
+    SmallDataLimit = A->getValue();
+  }
+  // Forward the -msmall-data-limit= option.
+  CmdArgs.push_back("-msmall-data-limit");
+  CmdArgs.push_back(SmallDataLimit);
+}
+
 void Clang::AddRISCVTargetArgs(const ArgList &Args,
                                ArgStringList &CmdArgs) const {
   const llvm::Triple &Triple = getToolChain().getTriple();
@@ -1967,6 +1997,8 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
 
   CmdArgs.push_back("-target-abi");
   CmdArgs.push_back(ABIName.data());
+
+  SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs);
 }
 
 void Clang::AddSparcTargetArgs(const ArgList &Args,

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2e432ad9ce14..802df03f2dcf 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -921,6 +921,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
   Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags);
   Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
+  Opts.SmallDataLimit =
+      getLastArgIntValue(Args, OPT_msmall_data_limit, 0, Diags);
   Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
   Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn);
   Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks);

diff  --git a/clang/test/CodeGen/riscv-sdata-module-flag.c b/clang/test/CodeGen/riscv-sdata-module-flag.c
new file mode 100644
index 000000000000..4ad83b2c6d7c
--- /dev/null
+++ b/clang/test/CodeGen/riscv-sdata-module-flag.c
@@ -0,0 +1,48 @@
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-DEFAULT
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -G4 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-G4
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -msmall-data-limit=0 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-S0
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -msmall-data-limit=2 -G4 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-S2G4
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -msmall-data-threshold=16 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-T16
+// RUN: %clang -target riscv32-unknown-elf %s -S -emit-llvm -fpic -o - \
+// RUN:   | FileCheck %s -check-prefix=RV32-PIC
+
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-DEFAULT
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -G4 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-G4
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -msmall-data-limit=0 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-S0
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -msmall-data-limit=2 -G4 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-S2G4
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -msmall-data-threshold=16 -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-T16
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -fpic -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-PIC
+// RUN: %clang -target riscv64-unknown-elf %s -S -emit-llvm -mcmodel=large -o - \
+// RUN:   | FileCheck %s -check-prefix=RV64-LARGE
+
+void test() {}
+
+// RV32-DEFAULT: !{i32 1, !"SmallDataLimit", i32 8}
+// RV32-G4:      !{i32 1, !"SmallDataLimit", i32 4}
+// RV32-S0:      !{i32 1, !"SmallDataLimit", i32 0}
+// RV32-S2G4:    !{i32 1, !"SmallDataLimit", i32 4}
+// RV32-T16:     !{i32 1, !"SmallDataLimit", i32 16}
+// RV32-PIC:     !{i32 1, !"SmallDataLimit", i32 0}
+
+// RV64-DEFAULT: !{i32 1, !"SmallDataLimit", i32 8}
+// RV64-G4:      !{i32 1, !"SmallDataLimit", i32 4}
+// RV64-S0:      !{i32 1, !"SmallDataLimit", i32 0}
+// RV64-S2G4:    !{i32 1, !"SmallDataLimit", i32 4}
+// RV64-T16:     !{i32 1, !"SmallDataLimit", i32 16}
+// RV64-PIC:     !{i32 1, !"SmallDataLimit", i32 0}
+// RV64-LARGE:   !{i32 1, !"SmallDataLimit", i32 0}
+
+// The value will be passed by module flag instead of target feature.
+// RV32-S0-NOT: +small-data-limit=
+// RV64-S0-NOT: +small-data-limit=

diff  --git a/clang/test/Driver/riscv-sdata-warning.c b/clang/test/Driver/riscv-sdata-warning.c
new file mode 100644
index 000000000000..7f1eeec6e99f
--- /dev/null
+++ b/clang/test/Driver/riscv-sdata-warning.c
@@ -0,0 +1,8 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang -S -target riscv32-unknown-elf -fpic -msmall-data-limit=8 %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-PIC-SDATA %s
+// CHECK-PIC-SDATA: warning: ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64
+
+// RUN: %clang -S -target riscv64-unknown-elf -mcmodel=large -msmall-data-limit=8 %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RV64-LARGE-SDATA %s
+// CHECK-RV64-LARGE-SDATA: warning: ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64


        


More information about the cfe-commits mailing list