[mips] Define getTargetNode as a template function.

No intended functionality change.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2013-09-25 00:30:25 +00:00
parent ce734f1f43
commit 7938034498
3 changed files with 96 additions and 57 deletions

View File

@ -474,7 +474,9 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
if (NeedMips16Helper) { if (NeedMips16Helper) {
RegsToPass.push_front(std::make_pair(V0Reg, Callee)); RegsToPass.push_front(std::make_pair(V0Reg, Callee));
JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy()); JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy());
JumpTarget = getAddrGlobal(JumpTarget, DAG, MipsII::MO_GOT); JumpTarget = getAddrGlobal(cast<ExternalSymbolSDNode>(JumpTarget),
JumpTarget.getValueType(), DAG,
MipsII::MO_GOT);
} else } else
RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee)); RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
} }

View File

@ -80,70 +80,91 @@ SDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty) const {
return DAG.getRegister(FI->getGlobalBaseReg(), Ty); return DAG.getRegister(FI->getGlobalBaseReg(), Ty);
} }
static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) { template<class NodeTy>
EVT Ty = Op.getValueType(); static SDValue getTargetNode(NodeTy *Node, EVT Ty, SelectionDAG &DAG,
unsigned Flag) {
if (GlobalAddressSDNode *N = dyn_cast<GlobalAddressSDNode>(Op))
return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(Op), Ty, 0,
Flag);
if (ExternalSymbolSDNode *N = dyn_cast<ExternalSymbolSDNode>(Op))
return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);
if (BlockAddressSDNode *N = dyn_cast<BlockAddressSDNode>(Op))
return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);
if (JumpTableSDNode *N = dyn_cast<JumpTableSDNode>(Op))
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);
if (ConstantPoolSDNode *N = dyn_cast<ConstantPoolSDNode>(Op))
return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlignment(),
N->getOffset(), Flag);
llvm_unreachable("Unexpected node type."); llvm_unreachable("Unexpected node type.");
return SDValue(); return SDValue();
} }
static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) { template<>
SDLoc DL(Op); SDValue getTargetNode<GlobalAddressSDNode>(GlobalAddressSDNode *N, EVT Ty,
EVT Ty = Op.getValueType(); SelectionDAG &DAG, unsigned Flag) {
SDValue Hi = getTargetNode(Op, DAG, MipsII::MO_ABS_HI); return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag);
SDValue Lo = getTargetNode(Op, DAG, MipsII::MO_ABS_LO); }
template<>
SDValue getTargetNode<ExternalSymbolSDNode>(ExternalSymbolSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flag) {
return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);
}
template<>
SDValue getTargetNode<BlockAddressSDNode>(BlockAddressSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flag) {
return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);
}
template<>
SDValue getTargetNode<JumpTableSDNode>(JumpTableSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flag) {
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);
}
template<>
SDValue getTargetNode<ConstantPoolSDNode>(ConstantPoolSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flag) {
return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlignment(),
N->getOffset(), Flag);
}
template<class NodeTy>
static SDValue getAddrNonPIC(NodeTy *N, EVT Ty, SelectionDAG &DAG) {
SDLoc DL(N);
SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
return DAG.getNode(ISD::ADD, DL, Ty, return DAG.getNode(ISD::ADD, DL, Ty,
DAG.getNode(MipsISD::Hi, DL, Ty, Hi), DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
DAG.getNode(MipsISD::Lo, DL, Ty, Lo)); DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
} }
SDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG, template<class NodeTy>
SDValue MipsTargetLowering::getAddrLocal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
bool HasMips64) const { bool HasMips64) const {
SDLoc DL(Op); SDLoc DL(N);
EVT Ty = Op.getValueType();
unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT; unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
getTargetNode(Op, DAG, GOTFlag)); getTargetNode(N, Ty, DAG, GOTFlag));
SDValue Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT, SDValue Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,
MachinePointerInfo::getGOT(), false, false, false, MachinePointerInfo::getGOT(), false, false, false,
0); 0);
unsigned LoFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO; unsigned LoFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty, getTargetNode(Op, DAG, LoFlag)); SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
getTargetNode(N, Ty, DAG, LoFlag));
return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo); return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);
} }
SDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG, template<class NodeTy>
SDValue MipsTargetLowering::getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
unsigned Flag) const { unsigned Flag) const {
SDLoc DL(Op); SDLoc DL(N);
EVT Ty = Op.getValueType();
SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
getTargetNode(Op, DAG, Flag)); getTargetNode(N, Ty, DAG, Flag));
return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Tgt, return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Tgt,
MachinePointerInfo::getGOT(), false, false, false, 0); MachinePointerInfo::getGOT(), false, false, false, 0);
} }
SDValue MipsTargetLowering::getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG, template<class NodeTy>
SDValue MipsTargetLowering::getAddrGlobalLargeGOT(NodeTy *N, EVT Ty,
SelectionDAG &DAG,
unsigned HiFlag, unsigned HiFlag,
unsigned LoFlag) const { unsigned LoFlag) const {
SDLoc DL(Op); SDLoc DL(N);
EVT Ty = Op.getValueType(); SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty,
SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(Op, DAG, HiFlag)); getTargetNode(N, Ty, DAG, HiFlag));
Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty)); Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi, SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
getTargetNode(Op, DAG, LoFlag)); getTargetNode(N, Ty, DAG, LoFlag));
return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Wrapper, return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Wrapper,
MachinePointerInfo::getGOT(), false, false, false, 0); MachinePointerInfo::getGOT(), false, false, false, 0);
} }
@ -1478,7 +1499,9 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
SelectionDAG &DAG) const { SelectionDAG &DAG) const {
// FIXME there isn't actually debug info here // FIXME there isn't actually debug info here
SDLoc DL(Op); SDLoc DL(Op);
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); EVT Ty = Op.getValueType();
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
const GlobalValue *GV = N->getGlobal();
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) { if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
const MipsTargetObjectFile &TLOF = const MipsTargetObjectFile &TLOF =
@ -1495,26 +1518,29 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
} }
// %hi/%lo relocation // %hi/%lo relocation
return getAddrNonPIC(Op, DAG); return getAddrNonPIC(N, Ty, DAG);
} }
if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa<Function>(GV))) if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa<Function>(GV)))
return getAddrLocal(Op, DAG, HasMips64); return getAddrLocal(N, Ty, DAG, HasMips64);
if (LargeGOT) if (LargeGOT)
return getAddrGlobalLargeGOT(Op, DAG, MipsII::MO_GOT_HI16, return getAddrGlobalLargeGOT(N, Ty, DAG, MipsII::MO_GOT_HI16,
MipsII::MO_GOT_LO16); MipsII::MO_GOT_LO16);
return getAddrGlobal(Op, DAG, return getAddrGlobal(N, Ty, DAG,
HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16); HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16);
} }
SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op, SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op,
SelectionDAG &DAG) const { SelectionDAG &DAG) const {
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
return getAddrNonPIC(Op, DAG); EVT Ty = Op.getValueType();
return getAddrLocal(Op, DAG, HasMips64); if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
return getAddrNonPIC(N, Ty, DAG);
return getAddrLocal(N, Ty, DAG, HasMips64);
} }
SDValue MipsTargetLowering:: SDValue MipsTargetLowering::
@ -1601,10 +1627,13 @@ lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
SDValue MipsTargetLowering:: SDValue MipsTargetLowering::
lowerJumpTable(SDValue Op, SelectionDAG &DAG) const lowerJumpTable(SDValue Op, SelectionDAG &DAG) const
{ {
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
return getAddrNonPIC(Op, DAG); EVT Ty = Op.getValueType();
return getAddrLocal(Op, DAG, HasMips64); if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
return getAddrNonPIC(N, Ty, DAG);
return getAddrLocal(N, Ty, DAG, HasMips64);
} }
SDValue MipsTargetLowering:: SDValue MipsTargetLowering::
@ -1619,11 +1648,13 @@ lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
// SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP); // SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP);
// SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32); // SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
// ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode);
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
EVT Ty = Op.getValueType();
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
return getAddrNonPIC(Op, DAG); return getAddrNonPIC(N, Ty, DAG);
return getAddrLocal(Op, DAG, HasMips64); return getAddrLocal(N, Ty, DAG, HasMips64);
} }
SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const {
@ -2469,18 +2500,19 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25 bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25
bool GlobalOrExternal = false, InternalLinkage = false; bool GlobalOrExternal = false, InternalLinkage = false;
SDValue CalleeLo; SDValue CalleeLo;
EVT Ty = Callee.getValueType();
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
if (IsPICCall) { if (IsPICCall) {
InternalLinkage = G->getGlobal()->hasInternalLinkage(); InternalLinkage = G->getGlobal()->hasInternalLinkage();
if (InternalLinkage) if (InternalLinkage)
Callee = getAddrLocal(Callee, DAG, HasMips64); Callee = getAddrLocal(G, Ty, DAG, HasMips64);
else if (LargeGOT) else if (LargeGOT)
Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16, Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16,
MipsII::MO_CALL_LO16); MipsII::MO_CALL_LO16);
else else
Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL); Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL);
} else } else
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0, Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
MipsII::MO_NO_FLAG); MipsII::MO_NO_FLAG);
@ -2491,10 +2523,10 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
MipsII::MO_NO_FLAG); MipsII::MO_NO_FLAG);
else if (LargeGOT) else if (LargeGOT)
Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16, Callee = getAddrGlobalLargeGOT(S, Ty, DAG, MipsII::MO_CALL_HI16,
MipsII::MO_CALL_LO16); MipsII::MO_CALL_LO16);
else // N64 || PIC else // N64 || PIC
Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL); Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL);
GlobalOrExternal = true; GlobalOrExternal = true;
} }

View File

@ -248,11 +248,16 @@ namespace llvm {
protected: protected:
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const; SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
SDValue getAddrLocal(SDValue Op, SelectionDAG &DAG, bool HasMips64) const; template<class NodeTy>
SDValue getAddrLocal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
bool HasMips64) const;
SDValue getAddrGlobal(SDValue Op, SelectionDAG &DAG, unsigned Flag) const; template<class NodeTy>
SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
unsigned Flag) const;
SDValue getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG, template<class NodeTy>
SDValue getAddrGlobalLargeGOT(NodeTy *N, EVT Ty, SelectionDAG &DAG,
unsigned HiFlag, unsigned LoFlag) const; unsigned HiFlag, unsigned LoFlag) const;
/// This function fills Ops, which is the list of operands that will later /// This function fills Ops, which is the list of operands that will later