forked from OSchip/llvm-project
Lower RETURNADDR node in Mips backend.
Patch by Sasa Stankovic. llvm-svn: 160031
This commit is contained in:
parent
8889cf008d
commit
878ad8b28d
|
@ -273,14 +273,21 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||
const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
|
||||
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
// Add the callee-saved register as live-in.
|
||||
// It's killed at the spill.
|
||||
EntryBlock->addLiveIn(CSI[i].getReg());
|
||||
// Add the callee-saved register as live-in. Do not add if the register is
|
||||
// RA and return address is taken, because it has already been added in
|
||||
// method MipsTargetLowering::LowerRETURNADDR.
|
||||
// It's killed at the spill, unless the register is RA and return address
|
||||
// is taken.
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
|
||||
&& MF->getFrameInfo()->isReturnAddressTaken();
|
||||
if (!IsRAAndRetAddrIsTaken)
|
||||
EntryBlock->addLiveIn(Reg);
|
||||
|
||||
// Insert the spill to the stack frame.
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
bool IsKill = !IsRAAndRetAddrIsTaken;
|
||||
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
|
||||
TII.storeRegToStackSlot(*EntryBlock, MI, Reg, true,
|
||||
TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
|
||||
CSI[i].getFrameIdx(), RC, TRI);
|
||||
}
|
||||
|
||||
|
|
|
@ -806,6 +806,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
|||
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
||||
case ISD::FABS: return LowerFABS(Op, DAG);
|
||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
|
||||
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
|
||||
case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
|
||||
|
@ -2009,6 +2010,23 @@ LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
|||
return FrameAddr;
|
||||
}
|
||||
|
||||
SDValue MipsTargetLowering::LowerRETURNADDR(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
// check the depth
|
||||
assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
|
||||
"Return address can be determined only for current frame.");
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
EVT VT = Op.getValueType();
|
||||
unsigned RA = IsN64 ? Mips::RA_64 : Mips::RA;
|
||||
MFI->setReturnAddressIsTaken(true);
|
||||
|
||||
// Return RA, which contains the return address. Mark it an implicit live-in.
|
||||
unsigned Reg = MF.addLiveIn(RA, getRegClassFor(VT));
|
||||
return DAG.getCopyFromReg(DAG.getEntryNode(), Op.getDebugLoc(), Reg, VT);
|
||||
}
|
||||
|
||||
// TODO: set SType according to the desired memory barrier behavior.
|
||||
SDValue
|
||||
MipsTargetLowering::LowerMEMBARRIER(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
|
|
@ -143,6 +143,7 @@ namespace llvm {
|
|||
SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
|
||||
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
|
||||
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
; RUN: llc -march=mipsel < %s | FileCheck %s
|
||||
|
||||
define i8* @f1() nounwind {
|
||||
entry:
|
||||
%0 = call i8* @llvm.returnaddress(i32 0)
|
||||
ret i8* %0
|
||||
|
||||
; CHECK: addu $2, $zero, $ra
|
||||
}
|
||||
|
||||
define i8* @f2() nounwind {
|
||||
entry:
|
||||
call void @g()
|
||||
%0 = call i8* @llvm.returnaddress(i32 0)
|
||||
ret i8* %0
|
||||
|
||||
; CHECK: addu $[[R0:[0-9]+]], $zero, $ra
|
||||
; CHECK: jal
|
||||
; CHECK: addu $2, $zero, $[[R0]]
|
||||
}
|
||||
|
||||
declare i8* @llvm.returnaddress(i32) nounwind readnone
|
||||
declare void @g()
|
Loading…
Reference in New Issue