From ed185daba7432e9df717f0199336889784b10da3 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 13 Dec 2012 03:17:29 +0000 Subject: [PATCH] [mips] Do not copy GOT address to register $gp if the function being called has internal linkage. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170092 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 13 ++++++++---- test/CodeGen/Mips/gpreg-lazy-binding.ll | 27 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/Mips/gpreg-lazy-binding.ll diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 65b33c12b82..f9a4d4acff4 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2849,12 +2849,14 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25 - bool GlobalOrExternal = false; + bool GlobalOrExternal = false, InternalLinkage = false; SDValue CalleeLo; if (GlobalAddressSDNode *G = dyn_cast(Callee)) { if (IsPICCall) { - if (G->getGlobal()->hasInternalLinkage()) + InternalLinkage = G->getGlobal()->hasInternalLinkage(); + + if (InternalLinkage) Callee = getAddrLocal(Callee, DAG, HasMips64); else if (LargeGOT) Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16, @@ -2901,8 +2903,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } // Insert node "GP copy globalreg" before call to function. - // Lazy-binding stubs require GP to point to the GOT. - if (IsPICCall) { + // + // R_MIPS_CALL* operators (emitted when non-internal functions are called + // in PIC mode) allow symbols to be resolved via lazy binding. + // The lazy binding stub requires GP to point to the GOT. + if (IsPICCall && !InternalLinkage) { unsigned GPReg = IsN64 ? Mips::GP_64 : Mips::GP; EVT Ty = IsN64 ? MVT::i64 : MVT::i32; RegsToPass.push_back(std::make_pair(GPReg, GetGlobalReg(DAG, Ty))); diff --git a/test/CodeGen/Mips/gpreg-lazy-binding.ll b/test/CodeGen/Mips/gpreg-lazy-binding.ll new file mode 100644 index 00000000000..85d8d4b1db1 --- /dev/null +++ b/test/CodeGen/Mips/gpreg-lazy-binding.ll @@ -0,0 +1,27 @@ +; RUN: llc -march=mipsel -disable-mips-delay-filler < %s | FileCheck %s + +@g = external global i32 + +; CHECK: addu $gp +; CHECK: jalr $25 +; CHECK: nop +; CHECK-NOT: addu $gp +; CHECK: jalr $25 + +define void @f0() nounwind { +entry: + tail call void @externalFunc() nounwind + tail call fastcc void @internalFunc() + ret void +} + +declare void @externalFunc() + +define internal fastcc void @internalFunc() nounwind noinline { +entry: + %0 = load i32* @g, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @g, align 4 + ret void +} + -- 2.34.1