// 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)) {