]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Add support to annotate tablejump
authorXi Ruoyao <xry111@xry111.site>
Thu, 11 Jul 2024 11:43:48 +0000 (19:43 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Tue, 8 Oct 2024 02:41:25 +0000 (10:41 +0800)
This is per the request from the kernel developers.  For generating the
ORC unwind info, the objtool program needs to analysis the control flow
of a .o file.  If a jump table is used, objtool has to correlate the
jump instruction with the table.

On x86 (where objtool was initially developed) it's simple: a relocation
entry natrually correlates them because one single instruction is used
for table-based jump.  But on an RISC machine objtool would have to
reconstruct the data flow if it must find out the correlation on its
own.

So, emit an additional section to store the correlation info as pairs of
addresses, each pair contains the address of a jump instruction (jr) and
the address of the jump table.  This is very trivial to implement in
GCC.

gcc/ChangeLog:

* config/loongarch/genopts/loongarch.opt.in
(mannotate-tablejump): New option.
* config/loongarch/loongarch.opt: Regenerate.
* config/loongarch/loongarch.md (tablejump<mode>): Emit
additional correlation info between the jump instruction and the
jump table, if -mannotate-tablejump.
* doc/invoke.texi: Document -mannotate-tablejump.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/jump-table-annotate.c: New test.

Suggested-by: Tiezhu Yang <yangtiezhu@loongson.cn>
gcc/config/loongarch/genopts/loongarch.opt.in
gcc/config/loongarch/loongarch.md
gcc/config/loongarch/loongarch.opt
gcc/doc/invoke.texi
gcc/testsuite/gcc.target/loongarch/jump-table-annotate.c [new file with mode: 0644]

index d00950cb4f43aabacbc0758f8e26cdcb6f89f676..d5bbf01d85ed19e9a57e78af0824fcff3ddd3083 100644 (file)
@@ -301,3 +301,7 @@ default value is 4.
 ; CPUCFG independently, so we use bit flags to specify them.
 TargetVariable
 HOST_WIDE_INT la_isa_evolution = 0
+
+mannotate-tablejump
+Target Mask(ANNOTATE_TABLEJUMP) Save
+Annotate table jump instruction (jr {reg}) to correlate it with the jump table.
index f70ca85bfb386ad1a30f3241d94bcfd761e87af6..bd0825002387c40c62d61df61c257091269f9330 100644 (file)
   DONE;
 })
 
+(define_mode_attr mode_size [(DI "8") (SI "4")])
+
 (define_insn "@tablejump<mode>"
   [(set (pc)
        (match_operand:P 0 "register_operand" "e"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
-  "jr\t%0"
+  {
+    return TARGET_ANNOTATE_TABLEJUMP
+      ? "1:jr\t%0\n\t"
+       ".pushsection\t.discard.tablejump_annotate\n\t"
+       "\t.<mode_size>byte\t1b\n\t"
+       "\t.<mode_size>byte\t%1\n\t"
+       ".popsection"
+      : "jr\t%0";
+  }
   [(set_attr "type" "jump")
    (set_attr "mode" "none")])
 
index 91cb5236ad892f4933d16383db9cfe8cf6ee166b..6a396b539c465d6ca6a35b3fa28fbaabb0f45c51 100644 (file)
@@ -310,6 +310,10 @@ default value is 4.
 TargetVariable
 HOST_WIDE_INT la_isa_evolution = 0
 
+mannotate-tablejump
+Target Mask(ANNOTATE_TABLEJUMP) Save
+Annotate table jump instruction (jr {reg}) to correlate it with the jump table
+
 mfrecipe
 Target Mask(ISA_FRECIPE) Var(la_isa_evolution)
 Support frecipe.{s/d} and frsqrte.{s/d} instructions.
index 987b63601520d3ec1868dcd0fa800ef0509bc73c..b2f16b45eaf4ae53fe511bb3bfa22b84851d30bc 100644 (file)
@@ -1071,7 +1071,7 @@ Objective-C and Objective-C++ Dialects}.
 -mcmodel=@var{code-model} -mrelax -mpass-mrelax-to-as
 -mrecip  -mrecip=@var{opt} -mfrecipe -mno-frecipe -mdiv32 -mno-div32
 -mlam-bh -mno-lam-bh -mlamcas -mno-lamcas -mld-seq-sa -mno-ld-seq-sa
--mtls-dialect=@var{opt}}
+-mtls-dialect=@var{opt} -mannotate-tablejump -mno-annotate-tablejump}
 
 @emph{M32R/D Options}
 @gccoptlist{-m32r2  -m32rx  -m32r
@@ -27512,6 +27512,17 @@ Whether a load-load barrier (@code{dbar 0x700}) is needed.  When build with
 This option controls which tls dialect may be used for general dynamic and
 local dynamic TLS models.
 
+@opindex mannotate-tablejump
+@opindex mno-annotate-tablejump
+@item -mannotate-tablejump
+@itemx -mno-annotate-tablejump
+Create an annotation section @code{.discard.tablejump_annotate} to
+correlate the @code{jirl} instruction and the jump table when a jump
+table is used to optimize the @code{switch} statement.  Some external
+tools, for example @file{objtool} of the Linux kernel building system,
+need the annotation to analysis the control flow.  The default is
+@option{-mno-annotate-tablejump}.
+
 @table @samp
 @item trad
 Use traditional TLS. This is the default.
diff --git a/gcc/testsuite/gcc.target/loongarch/jump-table-annotate.c b/gcc/testsuite/gcc.target/loongarch/jump-table-annotate.c
new file mode 100644 (file)
index 0000000..9d58e60
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mannotate-tablejump" } */
+
+extern void asdf(int);
+void foo(int x) {
+  switch (x) {
+  case 0: asdf(10); break;
+  case 1: asdf(11); break;
+  case 2: asdf(12); break;
+  case 3: asdf(13); break;
+  case 4: asdf(14); break;
+  }
+}
+
+/* { dg-final { scan-assembler "\\.discard\\.tablejump_annotate" } } */