summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2017-07-20 12:19:26 +0000
committerSimon Atanasyan <simon@atanasyan.com>2017-07-20 12:19:26 +0000
commitfb953926b155448f1ca460a4cb39f6a4a8cbbdb5 (patch)
treea05e05394b9c177c70e617aa90018346949a5610 /llvm/lib
parentb1c74321170863330ef4a849b21cf778fcc05823 (diff)
downloadbcm5719-llvm-fb953926b155448f1ca460a4cb39f6a4a8cbbdb5.tar.gz
bcm5719-llvm-fb953926b155448f1ca460a4cb39f6a4a8cbbdb5.zip
[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. llvm-svn: 308606
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 20319f85696..dd41fefb55f 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3152,15 +3152,30 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// 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)) {
OpenPOWER on IntegriCloud