[llvm] r308606 - [mips] Support `long_call/far/near` attributes passed by front-end
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 20 05:19:26 PDT 2017
Author: atanasyan
Date: Thu Jul 20 05:19:26 2017
New Revision: 308606
URL: http://llvm.org/viewvc/llvm-project?rev=308606&view=rev
Log:
[mips] Support `long_call/far/near` attributes passed by front-end
This patch adds handling of the `long_call`, `far`, and `near`
attributes passed by front-end. The patch depends on D35479.
Differential revision: https://reviews.llvm.org/D35480.
Added:
llvm/trunk/test/CodeGen/Mips/long-call-attr.ll
Modified:
llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=308606&r1=308605&r2=308606&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Thu Jul 20 05:19:26 2017
@@ -3152,15 +3152,30 @@ MipsTargetLowering::LowerCall(TargetLowe
// 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 the function should be called using "long call",
+ // get its address into a register to prevent using
+ // of the `jal` instruction for the direct call.
+ 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("short-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)) {
Added: llvm/trunk/test/CodeGen/Mips/long-call-attr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/long-call-attr.ll?rev=308606&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/long-call-attr.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/long-call-attr.ll Thu Jul 20 05:19:26 2017
@@ -0,0 +1,42 @@
+; RUN: llc -march=mips -target-abi o32 --mattr=+long-calls,+noabicalls < %s \
+; RUN: | FileCheck -check-prefix=O32 %s
+; RUN: llc -march=mips -target-abi o32 --mattr=-long-calls,+noabicalls < %s \
+; RUN: | FileCheck -check-prefix=O32 %s
+; RUN: llc -march=mips64 -target-abi n64 --mattr=+long-calls,+noabicalls < %s \
+; RUN: | FileCheck -check-prefix=N64 %s
+; RUN: llc -march=mips64 -target-abi n64 --mattr=-long-calls,+noabicalls < %s \
+; RUN: | FileCheck -check-prefix=N64 %s
+
+declare void @far() #0
+
+define void @near() #1 {
+ ret void
+}
+
+define void @foo() {
+ call void @far()
+
+; O32-LABEL: foo:
+; O32: lui $1, %hi(far)
+; O32-NEXT: addiu $25, $1, %lo(far)
+; O32-NEXT: jalr $25
+
+; N64-LABEL: foo:
+; N64: lui $1, %highest(far)
+; N64-NEXT: daddiu $1, $1, %higher(far)
+; N64-NEXT: dsll $1, $1, 16
+; N64-NEXT: daddiu $1, $1, %hi(far)
+; N64-NEXT: dsll $1, $1, 16
+; N64-NEXT: daddiu $25, $1, %lo(far)
+; N64-NEXT: jalr $25
+
+ call void @near()
+
+; O32: jal near
+; N64: jal near
+
+ ret void
+}
+
+attributes #0 = { "long-call" }
+attributes #1 = { "short-call" }
More information about the llvm-commits
mailing list