[PATCH] D35480: [mips] Support `long_call/far/near` attributes passed by front-end

Simon Atanasyan via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 17 05:30:52 PDT 2017


atanasyan created this revision.
Herald added a subscriber: arichardson.

This patch adds handling of the `long_call`, `far`, and `near` attributes passed by front-end. The patch depends on https://reviews.llvm.org/D35479.


Repository:
  rL LLVM

https://reviews.llvm.org/D35480

Files:
  lib/Target/Mips/MipsISelLowering.cpp
  test/CodeGen/Mips/long-call-attr.ll


Index: test/CodeGen/Mips/long-call-attr.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Mips/long-call-attr.ll
@@ -0,0 +1,30 @@
+; RUN: llc -march=mips -mcpu=mips32 --mattr=+long-calls,+noabicalls < %s \
+; RUN:   | FileCheck %s
+; RUN: llc -march=mips -mcpu=mips32 --mattr=-long-calls,+noabicalls < %s \
+; RUN:   | FileCheck %s
+
+declare void @far() #0
+
+define void @near() #1 {
+  ret void
+}
+
+define void @foo() #2 {
+  call void @far() #3
+
+; CHECK:      lui     $1, %hi(far)
+; CHECK-NEXT: addiu   $25, $1, %lo(far)
+; CHECK-NEXT: jalr    $25
+
+  call void @near() #4
+
+; CHECK:      jal near
+
+  ret void
+}
+
+attributes #0 = { "long-call" }
+attributes #1 = { noinline nounwind "near-call" }
+attributes #2 = { noinline nounwind }
+attributes #3 = { "long-call" }
+attributes #4 = { "near-call" }
Index: lib/Target/Mips/MipsISelLowering.cpp
===================================================================
--- lib/Target/Mips/MipsISelLowering.cpp
+++ lib/Target/Mips/MipsISelLowering.cpp
@@ -3152,15 +3152,27 @@
   // The long-calls feature is ignored in case of PIC.
   // While we do not support -mshared / -mno-shared properly,
   // ignore long-calls in case of -mabicalls too.
-  if (Subtarget.useLongCalls() && !Subtarget.isABICalls() && !IsPIC) {
-    // Get the address of the callee into a register to prevent
-    // using of the `jal` instruction for the direct call.
-    if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee))
-      Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
-                                    : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
-    else if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee))
-      Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
-                                    : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+  if (!Subtarget.isABICalls() && !IsPIC) {
+    if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+      if (Subtarget.useLongCalls())
+        Callee = Subtarget.hasSym32()
+                     ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                     : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+    } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) {
+      bool UseLongCalls = Subtarget.useLongCalls();
+      // If the function has long-call/far/near attribute
+      // it overrides command line switch pased to the backend.
+      if (auto *F = dyn_cast<Function>(N->getGlobal())) {
+        if (F->hasFnAttribute("long-call"))
+          UseLongCalls = true;
+        else if (F->hasFnAttribute("near-call"))
+          UseLongCalls = false;
+      }
+      if (UseLongCalls)
+        Callee = Subtarget.hasSym32()
+                     ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+                     : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+    }
   }
 
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35480.106853.patch
Type: text/x-patch
Size: 2944 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170717/eda70599/attachment.bin>


More information about the llvm-commits mailing list