diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-11 00:53:32 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-11 00:53:32 +0000 |
commit | ba584fe8feb840a82ad5966cb9eca6df0eeaafc2 (patch) | |
tree | 268af3d1949025309d0dd67d6cc63d0d28de9fa7 | |
parent | bb78930489aceab797eecffe6771c6e52ff0c80c (diff) | |
download | external_llvm-ba584fe8feb840a82ad5966cb9eca6df0eeaafc2.zip external_llvm-ba584fe8feb840a82ad5966cb9eca6df0eeaafc2.tar.gz external_llvm-ba584fe8feb840a82ad5966cb9eca6df0eeaafc2.tar.bz2 |
Lower RETURNADDR node in Mips backend.
Patch by Sasa Stankovic.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160031 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.cpp | 17 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 18 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 1 | ||||
-rw-r--r-- | test/CodeGen/Mips/return_address.ll | 23 |
4 files changed, 54 insertions, 5 deletions
diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp index 95e2357..cb55995 100644 --- a/lib/Target/Mips/MipsFrameLowering.cpp +++ b/lib/Target/Mips/MipsFrameLowering.cpp @@ -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); } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ca002c0..6858d84 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -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 { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index b4b1d25..c8b96ac 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -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; diff --git a/test/CodeGen/Mips/return_address.ll b/test/CodeGen/Mips/return_address.ll new file mode 100644 index 0000000..e1c9241 --- /dev/null +++ b/test/CodeGen/Mips/return_address.ll @@ -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() |