mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[mips] For indirect calls we don't need $gp to point to .got. Mips linker
doesn't generate lazy binding stub for a function whose address is taken in the program. Differential Revision: http://reviews.llvm.org/D5067 llvm-svn: 218744
This commit is contained in:
parent
47571604c9
commit
f65f1c04c4
@ -424,7 +424,8 @@ void Mips16TargetLowering::
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const {
|
||||
SelectionDAG &DAG = CLI.DAG;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
|
||||
@ -514,7 +515,8 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
Ops.push_back(JumpTarget);
|
||||
|
||||
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
||||
InternalLinkage, CLI, Callee, Chain);
|
||||
InternalLinkage, IsCallReloc, CLI, Callee,
|
||||
Chain);
|
||||
}
|
||||
|
||||
MachineBasicBlock *Mips16TargetLowering::
|
||||
|
@ -47,7 +47,7 @@ namespace llvm {
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee,
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const override;
|
||||
|
||||
MachineBasicBlock *emitSel16(unsigned Opc, MachineInstr *MI,
|
||||
|
@ -2466,13 +2466,19 @@ void MipsTargetLowering::
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const {
|
||||
// Insert node "GP copy globalreg" before call to function.
|
||||
//
|
||||
// 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) {
|
||||
// Note that we don't need GP to point to the GOT for indirect calls
|
||||
// (when R_MIPS_CALL* is not used for the call) because Mips linker generates
|
||||
// lazy binding stub for a function only when R_MIPS_CALL* are the only relocs
|
||||
// used for the function (that is, Mips linker doesn't generate lazy binding
|
||||
// stub for a function whose address is taken in the program).
|
||||
if (IsPICCall && !InternalLinkage && IsCallReloc) {
|
||||
unsigned GPReg = Subtarget.isABI_N64() ? Mips::GP_64 : Mips::GP;
|
||||
EVT Ty = Subtarget.isABI_N64() ? MVT::i64 : MVT::i32;
|
||||
RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));
|
||||
@ -2667,7 +2673,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
bool IsPICCall =
|
||||
(Subtarget.isABI_N64() || IsPIC); // true if calls are translated to
|
||||
// jalr $25
|
||||
bool GlobalOrExternal = false, InternalLinkage = false;
|
||||
bool GlobalOrExternal = false, InternalLinkage = false, IsCallReloc = false;
|
||||
SDValue CalleeLo;
|
||||
EVT Ty = Callee.getValueType();
|
||||
|
||||
@ -2679,13 +2685,16 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
if (InternalLinkage)
|
||||
Callee = getAddrLocal(G, Ty, DAG,
|
||||
Subtarget.isABI_N32() || Subtarget.isABI_N64());
|
||||
else if (LargeGOT)
|
||||
else if (LargeGOT) {
|
||||
Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16,
|
||||
MipsII::MO_CALL_LO16, Chain,
|
||||
FuncInfo->callPtrInfo(Val));
|
||||
else
|
||||
IsCallReloc = true;
|
||||
} else {
|
||||
Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
||||
FuncInfo->callPtrInfo(Val));
|
||||
IsCallReloc = true;
|
||||
}
|
||||
} else
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
|
||||
MipsII::MO_NO_FLAG);
|
||||
@ -2697,13 +2706,16 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
if (!Subtarget.isABI_N64() && !IsPIC) // !N64 && static
|
||||
Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy(),
|
||||
MipsII::MO_NO_FLAG);
|
||||
else if (LargeGOT)
|
||||
else if (LargeGOT) {
|
||||
Callee = getAddrGlobalLargeGOT(S, Ty, DAG, MipsII::MO_CALL_HI16,
|
||||
MipsII::MO_CALL_LO16, Chain,
|
||||
FuncInfo->callPtrInfo(Sym));
|
||||
else // N64 || PIC
|
||||
IsCallReloc = true;
|
||||
} else { // N64 || PIC
|
||||
Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
||||
FuncInfo->callPtrInfo(Sym));
|
||||
IsCallReloc = true;
|
||||
}
|
||||
|
||||
GlobalOrExternal = true;
|
||||
}
|
||||
@ -2712,7 +2724,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||
|
||||
getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
|
||||
CLI, Callee, Chain);
|
||||
IsCallReloc, CLI, Callee, Chain);
|
||||
|
||||
if (IsTailCall)
|
||||
return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
|
||||
|
@ -336,7 +336,8 @@ namespace llvm {
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const;
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const;
|
||||
|
||||
/// ByValArgInfo - Byval argument information.
|
||||
struct ByValArgInfo {
|
||||
|
@ -1187,10 +1187,12 @@ void MipsSETargetLowering::
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const {
|
||||
Ops.push_back(Callee);
|
||||
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
||||
InternalLinkage, CLI, Callee, Chain);
|
||||
InternalLinkage, IsCallReloc, CLI, Callee,
|
||||
Chain);
|
||||
}
|
||||
|
||||
SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
@ -59,7 +59,7 @@ namespace llvm {
|
||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||
CallLoweringInfo &CLI, SDValue Callee,
|
||||
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||
SDValue Chain) const override;
|
||||
|
||||
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -25,3 +25,11 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @no_lazy(void (i32)* %pf) {
|
||||
|
||||
; CHECK-LABEL: no_lazy
|
||||
; CHECK-NOT: gp_disp
|
||||
|
||||
tail call void %pf(i32 1)
|
||||
ret void
|
||||
}
|
||||
|
@ -10,16 +10,19 @@
|
||||
|
||||
; CHECK-LABEL: readLumaCoeff8x8_CABAC
|
||||
|
||||
; The check for "addiu" instruction is added so that we can match the correct "b" instruction.
|
||||
; The check for first "addiu" instruction is added so that we can match the correct "b" instruction.
|
||||
; CHECK: addiu ${{[0-9]+}}, $zero, -1
|
||||
; CHECK: b $[[BB0:BB[0-9_]+]]
|
||||
; CHECK-NEXT: addiu ${{[0-9]+}}, $zero, 0
|
||||
|
||||
; Check that sll instruction that writes to $1 starts basic block.
|
||||
; CHECK: {{BB[0-9_#]+}}:
|
||||
; Check that at the start of a fallthrough block there is a instruction that writes to $1.
|
||||
; CHECK-NEXT: {{BB[0-9_#]+}}:
|
||||
; CHECK-NEXT: lw $[[R1:[0-9]+]], %got(assignSE2partition)($[[R2:[0-9]+]])
|
||||
; CHECK-NEXT: sll $1, $[[R0:[0-9]+]], 4
|
||||
|
||||
; Check that identical sll instruction starts another basic block.
|
||||
; Check that identical instructions are at the start of a target block.
|
||||
; CHECK: [[BB0]]:
|
||||
; CHECK-NEXT: lw $[[R1]], %got(assignSE2partition)($[[R2]])
|
||||
; CHECK-NEXT: sll $1, $[[R0]], 4
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user