On 10/25/23 19:49, KuanLin Chen wrote:
This is a RFC patch for large code model implementation.

gcc/ChangeLog:
* gcc/config/riscv/predicates.md(move_operand): Check SYMBOL_REF
and LABEL_REF type.
(call_insn_operand): Support for CM_Large.
(pcrel_symbol_operand): New.
* gcc/config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add builtin_define
"__riscv_cmodel_large".
* gcc/config/riscv/riscv-opts.h (riscv_code_model): Define CM_LARGE.
* gcc/config/riscv/riscv-protos.h (riscv_symbol_type): Define
SYMBOL_FORCE_TO_MEM.
(riscv_asm_output_pool_epilogue): New.
* gcc/config/riscv/riscv.cc (riscv_classify_symbol) Support CM_LARGE model.
(riscv_symbol_insns) Add SYMBOL_FORCE_TO_MEM.
(riscv_cannot_force_const_mem): Ditto.
(riscv_split_symbol): Ditto.
(riscv_force_address): Check pseudo reg available before force_reg.
(riscv_size_ok_for_small_data_p): Disable in CM_LARGE model.
(riscv_can_use_per_function_literal_pools_p): New.
(riscv_asm_output_pool_epilogue): New. Hook ASM_OUTPUT_POOL_EPILOGUE.
(riscv_output_mi_thunk): Add riscv_in_thunk_func.
(riscv_option_override): Support CM_LARGE model.
(riscv_function_ok_for_sibcall): Disable sibcalls in CM_LARGE model.
* gcc/config/riscv/riscv.h (ASM_OUTPUT_POOL_EPILOGUE): Hookfg
* gcc/config/riscv/riscv.md (unspec): Define UNSPEC_FORCE_FOR_MEM.
(*large_load_address"): New.
* gcc/config/riscv/riscv.opt (code_model): New.

gcc/testsuite/ChangeLog:

   * gcc/testsuite/gcc.target/riscv/large-model.c: New test.
First, thank you so much for tackling this. It's one of the many missing components that we need to round out the implementation.




0001-RISC-V-Support-mcmodel-large.patch

 From b09ba36220db1dbce3b1934685b1783125b5cb66 Mon Sep 17 00:00:00 2001
From: Kuan-Lin Chen<ru...@andestech.com>
Date: Sun, 18 Feb 2018 20:19:49 +0800
Subject: [PATCH] RISC-V: Support -mcmodel=large.

---
  gcc/config/riscv/predicates.md               | 23 +++++-
  gcc/config/riscv/riscv-c.cc                  |  4 +
  gcc/config/riscv/riscv-opts.h                |  1 +
  gcc/config/riscv/riscv-protos.h              |  4 +-
  gcc/config/riscv/riscv.cc                    | 77 +++++++++++++++++++-
  gcc/config/riscv/riscv.h                     |  2 +
  gcc/config/riscv/riscv.md                    |  9 +++
  gcc/config/riscv/riscv.opt                   |  3 +
  gcc/testsuite/gcc.target/riscv/large-model.c | 11 +++
  9 files changed, 127 insertions(+), 7 deletions(-)
  create mode 100644 gcc/testsuite/gcc.target/riscv/large-model.c

@@ -312,9 +313,15 @@
  })
(define_predicate "call_insn_operand"
-  (ior (match_operand 0 "absolute_symbolic_operand")
-       (match_operand 0 "plt_symbolic_operand")
-       (match_operand 0 "register_operand")))
+  (match_operand 0 "general_operand")
+{
+  if (riscv_cmodel == CM_LARGE)
+    return register_operand (op, mode);
+  else
+    return (absolute_symbolic_operand (op, mode) ||
+           plt_symbolic_operand (op, mode) ||
+           register_operand (op, mode));
+})
Formatting nit. When wrapping a long line, bring the operator down to the next line, indented just beyond the open paren. Like this:

    return (absolute_symbolic_oeprand (op, mode)
            || plt_symbolic_operand (op, mode)
            || register_operand (op, mode);


Also make sure to use a tab when indenting something 8 spaces. It's an annoyance, but it's the standard way things are formatted in GCC. THere are some scripts in the contrib subdirectory which can help find formatting problems, though I'm not sure they work on .md files.

@@ -1972,7 +1992,19 @@ static rtx
  riscv_force_address (rtx x, machine_mode mode)
  {
    if (!riscv_legitimate_address_p (mode, x, false))
-    x = force_reg (Pmode, x);
+    {
+      if (can_create_pseudo_p ())
+       return force_reg (Pmode, x);
Note that $ra is fixed now. So if you need a scratch register, you can fall back to $ra.

More importantly, what are the circumstances where you can be asked to force an address after the register allocation/reloading phase is complete? Or does it happen within the register allocators (the latter would be an indicator we need a secondary reload).


@@ -5665,6 +5697,9 @@ riscv_size_ok_for_small_data_p (int size)
  static bool
  riscv_in_small_data_p (const_tree x)
  {
+  if (riscv_cmodel == CM_LARGE)
+    return false;
+
    if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
      return false;
How does large code model impact our ability to access small data through $gp? Aren't they independent?

+void
+riscv_asm_output_pool_epilogue (FILE *f, const char *, tree,
+                               HOST_WIDE_INT offset)
+{
+  /* When using per-function literal pools, we must ensure that any code
+     section is aligned to the minimal instruction length, lest we get
+     errors from the assembler re "unaligned instructions".  */
+  if ((offset & 3) && riscv_can_use_per_function_literal_pools_p ())
+    ASM_OUTPUT_ALIGN (f, 2);
+}
So the comment implies you're aligning the section. If that were the case, then why doesn't the function alignment come from FUNCTION_BOUNDARY when we first start emitting the function?

Or is it the case that the comment is incorrect and you've actually got mixed code/rodata?




+(define_insn "*large_load_address"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (mem:DI (match_operand 1 "pcrel_symbol_operand" "")))]
+  "TARGET_64BIT && riscv_cmodel == CM_LARGE"
+  "ld\t%0,%1"
+  [(set_attr "type" "load")
+   (set (attr "length") (const_int 8))])
So it would seem like you're relying on the assembler to expand the ld? Is there any reasonable way to expose this properly to the compiler? I'd start by emitting the right instructions in the template. Once that's working, then we could look to split the components into distinct insns.

I also worry that we've got a mem->reg move instruction that is not implemented in the standard movXX patterns. Traditionally that's been a recipe for problems. It was certainly a requirement for reload, but I don't know offhand if it's a hard requirement for LRA.

Can you try to merge that in with the standard movdi pattern?

Overall it looks pretty good. Does Andestech have a copyright assignment in place? Or are you contributing under the DCO rule?

https://gcc.gnu.org/dco.html

JeJeff

Reply via email to