[lld] r372951 - [mips] Relax jalr/jr instructions using R_MIPS_JALR relocation

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 26 02:13:21 PDT 2019


Author: atanasyan
Date: Thu Sep 26 02:13:20 2019
New Revision: 372951

URL: http://llvm.org/viewvc/llvm-project?rev=372951&view=rev
Log:
[mips] Relax jalr/jr instructions using R_MIPS_JALR relocation

The R_MIPS_JALR relocation denotes jalr/jr instructions in position
independent code. Both these instructions take a target's address from
the $25 register. If offset to the target symbol fits into the 18-bits,
it's more efficient to replace jalr/jr by bal/b instructions.

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

Modified:
    lld/trunk/ELF/Arch/Mips.cpp
    lld/trunk/test/ELF/mips-jalr.s

Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=372951&r1=372950&r2=372951&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Thu Sep 26 02:13:20 2019
@@ -85,8 +85,14 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType t
 
   switch (type) {
   case R_MIPS_JALR:
+    // If the target symbol is not preemptible and is not microMIPS,
+    // it might be possible to replace jalr/jr instruction by bal/b.
+    // It depends on the target symbol's offset.
+    if (!s.isPreemptible && !(s.getVA() & 0x1))
+      return R_PC;
+    return R_NONE;
   case R_MICROMIPS_JALR:
-    return R_HINT;
+    return R_NONE;
   case R_MIPS_GPREL16:
   case R_MIPS_GPREL32:
   case R_MICROMIPS_GPREL16:
@@ -633,6 +639,20 @@ void MIPS<ELFT>::relocateOne(uint8_t *lo
     writeValue<e>(loc, val + 0x800080008000, 16, 48);
     break;
   case R_MIPS_JALR:
+    val -= 4;
+    // Replace jalr/jr instructions by bal/b if the target
+    // offset fits into the 18-bit range.
+    if (isInt<18>(val)) {
+      switch (read32<e>(loc)) {
+      case 0x0320f809:  // jalr $25 => bal sym
+        write32<e>(loc, 0x04110000 | ((val >> 2) & 0xffff));
+        break;
+      case 0x03200008:  // jr $25 => b sym
+        write32<e>(loc, 0x10000000 | ((val >> 2) & 0xffff));
+        break;
+      }
+    }
+    break;
   case R_MICROMIPS_JALR:
     // Ignore this optimization relocation for now
     break;

Modified: lld/trunk/test/ELF/mips-jalr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-jalr.s?rev=372951&r1=372950&r2=372951&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-jalr.s (original)
+++ lld/trunk/test/ELF/mips-jalr.s Thu Sep 26 02:13:20 2019
@@ -1,20 +1,56 @@
 # REQUIRES: mips
-# Check that lld ignores R_MIPS_JALR relocation for now.
 
-# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
-# RUN: ld.lld %t.o -o %t.exe 
+## Check handling of the R_MIPS_JALR relocation.
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o
 # RUN: llvm-readelf -r %t.o | FileCheck -check-prefix=REL %s
-# RUN: llvm-objdump -d --no-show-raw-insn %t.exe | FileCheck %s
 
-# REL: R_MIPS_CALL16 {{.*}} foo
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck -check-prefix=SO %s
+
+# RUN: ld.lld %t.o --defsym=bar=__start -o %t.so
+# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck -check-prefix=EXE %s
+
+# REL: R_MIPS_JALR   {{.*}} bar
 # REL: R_MIPS_JALR   {{.*}} foo
+# REL: R_MIPS_JALR   {{.*}} far
+
+# SO: jalr  $25
+# SO: bal   -24 <foo>
+# SO: jalr  $25
+
+# SO: jr    $25
+# SO: b     -64 <foo>
+# SO: jr    $25
 
-# CHECK: jalr  $25
+# EXE: bal   -4 <foo>
+# EXE: bal   -24 <foo>
+# EXE: jalr  $25
+
+# EXE: b     -56 <foo>
+# EXE: b     -64 <foo>
+# EXE: jr    $25
 
   .text
-  .global  __start
+  .global bar
+  .global __start
   .option pic2
+far:
+  .space 0x4fff0
 __start:
-  jal foo
 foo:
+  jal bar
+  nop
+  jal foo
+  nop
+  jal far
   nop
+l1:
+  jr $25
+  .reloc l1, R_MIPS_JALR, bar
+l2:
+  jr $25
+  .reloc l2, R_MIPS_JALR, foo
+l3:
+  jr $25
+  .reloc l3, R_MIPS_JALR, far




More information about the llvm-commits mailing list