diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-09-28 00:12:32 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-09-28 00:12:32 +0000 |
commit | af4211ad940025c2a1eb8b25d20196c1c1362d88 (patch) | |
tree | cbe47d337f4e356f0062dd0291424b1aee61c2db /llvm/lib | |
parent | d6ffae91d535402b240128467bbcc5b09bd948aa (diff) | |
download | bcm5719-llvm-af4211ad940025c2a1eb8b25d20196c1c1362d88.tar.gz bcm5719-llvm-af4211ad940025c2a1eb8b25d20196c1c1362d88.zip |
[mips] Make sure loads from lazy-binding entries do not get CSE'd or hoisted out
of loops.
Previously, two consecutive calls to function "func" would result in the
following sequence of instructions:
1. load $16, %got(func)($gp) // load address of lazy-binding stub.
2. move $25, $16
3. jalr $25 // jump to lazy-binding stub.
4. nop
5. move $25, $16
6. jalr $25 // jump to lazy-binding stub again.
With this patch, the second call directly jumps to func's address, bypassing
the lazy-binding resolution routine:
1. load $25, %got(func)($gp) // load address of lazy-binding stub.
2. jalr $25 // jump to lazy-binding stub.
3. nop
4. load $25, %got(func)($gp) // load resolved address of func.
5. jalr $25 // directly jump to func.
llvm-svn: 191591
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/Mips16ISelLowering.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.h | 14 |
4 files changed, 33 insertions, 19 deletions
diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp index 89f3d3ba175..ab649bd9882 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp @@ -419,6 +419,8 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { SelectionDAG &DAG = CLI.DAG; + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); const char* Mips16HelperFunction = 0; bool NeedMips16Helper = false; @@ -474,9 +476,10 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, if (NeedMips16Helper) { RegsToPass.push_front(std::make_pair(V0Reg, Callee)); JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy()); - JumpTarget = getAddrGlobal(cast<ExternalSymbolSDNode>(JumpTarget), - JumpTarget.getValueType(), DAG, - MipsII::MO_GOT); + ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget); + JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG, + MipsII::MO_GOT, Chain, + FuncInfo->callPtrInfo(S->getSymbol())); } else RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee)); } diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index 545a38dba32..34286db16af 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -421,8 +421,7 @@ bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) { return false; if (const PseudoSourceValue *PSV = dyn_cast<const PseudoSourceValue>(V)) - return !PSV->PseudoSourceValue::isConstant(0) && - (V != PseudoSourceValue::getStack()); + return !PSV->isConstant(0) && V != PseudoSourceValue::getStack(); return true; } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 5aab3f8dd2f..3eb2dfb6d67 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -1468,10 +1468,12 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, if (LargeGOT) return getAddrGlobalLargeGOT(N, Ty, DAG, MipsII::MO_GOT_HI16, - MipsII::MO_GOT_LO16); + MipsII::MO_GOT_LO16, DAG.getEntryNode(), + MachinePointerInfo::getGOT()); return getAddrGlobal(N, Ty, DAG, - HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16); + HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16, + DAG.getEntryNode(), MachinePointerInfo::getGOT()); } SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op, @@ -2313,6 +2315,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); const TargetFrameLowering *TFL = MF.getTarget().getFrameLowering(); + MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; // Analyze operands of the call, assigning locations to each operand. @@ -2446,29 +2449,36 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { if (IsPICCall) { - InternalLinkage = G->getGlobal()->hasInternalLinkage(); + const GlobalValue *Val = G->getGlobal(); + InternalLinkage = Val->hasInternalLinkage(); if (InternalLinkage) Callee = getAddrLocal(G, Ty, DAG, HasMips64); else if (LargeGOT) Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16, - MipsII::MO_CALL_LO16); + MipsII::MO_CALL_LO16, Chain, + FuncInfo->callPtrInfo(Val)); else - Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL); + Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL, Chain, + FuncInfo->callPtrInfo(Val)); } else Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0, MipsII::MO_NO_FLAG); GlobalOrExternal = true; } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { + const char *Sym = S->getSymbol(); + if (!IsN64 && !IsPIC) // !N64 && static - Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), + Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy(), MipsII::MO_NO_FLAG); else if (LargeGOT) Callee = getAddrGlobalLargeGOT(S, Ty, DAG, MipsII::MO_CALL_HI16, - MipsII::MO_CALL_LO16); + MipsII::MO_CALL_LO16, Chain, + FuncInfo->callPtrInfo(Sym)); else // N64 || PIC - Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL); + Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL, Chain, + FuncInfo->callPtrInfo(Sym)); GlobalOrExternal = true; } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index 7d9ab6a82e7..aa4bcc97214 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -275,12 +275,12 @@ namespace llvm { // (load (wrapper $gp, %got(sym))) template<class NodeTy> SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG, - unsigned Flag) const { + unsigned Flag, SDValue Chain, + const MachinePointerInfo &PtrInfo) const { SDLoc DL(N); SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), getTargetNode(N, Ty, DAG, Flag)); - return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Tgt, - MachinePointerInfo::getGOT(), false, false, false, 0); + return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo, false, false, false, 0); } // This method creates the following nodes, which are necessary for @@ -289,15 +289,17 @@ namespace llvm { // (load (wrapper (add %hi(sym), $gp), %lo(sym))) template<class NodeTy> SDValue getAddrGlobalLargeGOT(NodeTy *N, EVT Ty, SelectionDAG &DAG, - unsigned HiFlag, unsigned LoFlag) const { + unsigned HiFlag, unsigned LoFlag, + SDValue Chain, + const MachinePointerInfo &PtrInfo) const { SDLoc DL(N); SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(N, Ty, DAG, HiFlag)); Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty)); SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi, getTargetNode(N, Ty, DAG, LoFlag)); - return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Wrapper, - MachinePointerInfo::getGOT(), false, false, false, 0); + return DAG.getLoad(Ty, DL, Chain, Wrapper, PtrInfo, false, false, false, + 0); } // This method creates the following nodes, which are necessary for |