131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===// 2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// The LLVM Compiler Infrastructure 4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source 6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details. 7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 10f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer 1179aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonFrameLowering.h" 12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "Hexagon.h" 13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonInstrInfo.h" 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "HexagonMachineFunctionInfo.h" 15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonRegisterInfo.h" 16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonSubtarget.h" 17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonTargetMachine.h" 18f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/ADT/BitVector.h" 19f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/ADT/STLExtras.h" 20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/AsmPrinter.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFrameInfo.h" 22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunction.h" 23f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineFunctionPass.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h" 25f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineModuleInfo.h" 26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineRegisterInfo.h" 27f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/RegisterScavenging.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 30b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MCAsmInfo.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MachineLocation.h" 32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CommandLine.h" 33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetInstrInfo.h" 34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetMachine.h" 35b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetOptions.h" 36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm; 38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic cl::opt<bool> DisableDeallocRet( 40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum "disable-hexagon-dealloc-ret", 41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cl::Hidden, 42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cl::desc("Disable Dealloc Return for Hexagon target")); 43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// determineFrameLayout - Determine the size of the frame and maximum call 45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// frame size. 46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const { 47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineFrameInfo *MFI = MF.getFrameInfo(); 48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the number of bytes to allocate from the FrameInfo. 50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned FrameSize = MFI->getStackSize(); 51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the alignments provided by the target. 53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); 54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the maximum call frame size of all the calls. 55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // that allocations will be aligned. 59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MFI->hasVarSizedObjects()) 60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign); 61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Update maximum call frame size. 63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MFI->setMaxCallFrameSize(maxCallFrameSize); 64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Include call frame size in total. 66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum FrameSize += maxCallFrameSize; 67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Make sure the frame is aligned. 69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum FrameSize = RoundUpToAlignment(FrameSize, TargetAlign); 70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Update frame info. 72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MFI->setStackSize(FrameSize); 73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { 77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock &MBB = MF.front(); 78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineFrameInfo *MFI = MF.getFrameInfo(); 79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator MBBI = MBB.begin(); 80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const HexagonRegisterInfo *QRI = 81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo()); 82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum determineFrameLayout(MF); 84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the number of bytes to allocate from the FrameInfo. 86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int NumBytes = (int) MFI->getStackSize(); 87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // LLVM expects allocframe not to be the first instruction in the 89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // basic block. 90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator InsertPt = MBB.begin(); 91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset. 94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum HexagonMachineFunctionInfo *FuncInfo = 96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MF.getInfo<HexagonMachineFunctionInfo>(); 97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const std::vector<MachineInstr*>& AdjustRegs = 98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum FuncInfo->getAllocaAdjustInsts(); 99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(), 100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum e = AdjustRegs.end(); 101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum i != e; ++i) { 102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineInstr* MI = *i; 103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) && 104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum "Expected adjust alloca node"); 105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineOperand& MO = MI->getOperand(2); 107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum assert(MO.isImm() && "Expected immediate"); 108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MO.setImm(MFI->getMaxCallFrameSize()); 109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Only insert ALLOCFRAME if we need to. 113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (hasFP(MF)) { 115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Check for overflow. 116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? 11722614a02eb8855548a892139e54e478c70050f9fTony Linthicum const int ALLOCFRAME_MAX = 16384; 118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (NumBytes >= ALLOCFRAME_MAX) { 121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Emit allocframe(#0). 122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0); 123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Subtract offset from frame pointer. 125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), 126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum HEXAGON_RESERVED_REG_1).addImm(NumBytes); 127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr), 128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum QRI->getStackRegister()). 129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum addReg(QRI->getStackRegister()). 130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum addReg(HEXAGON_RESERVED_REG_1); 131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes); 133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Returns true if MBB has a machine instructions that indicates a tail call 137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// in the block. 138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const { 139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned RetOpcode = MBBI->getOpcode(); 141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 14273714eac00958b072e7356360ebc6e818b51367bMatthew Curtis return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext; 14373714eac00958b072e7356360ebc6e818b51367bMatthew Curtis} 144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::emitEpilogue(MachineFunction &MF, 146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock &MBB) const { 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); 148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = MBBI->getDebugLoc(); 149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 1501a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Only insert deallocframe if we need to. Also at -O0. See comment 1511a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // in emitPrologue above. 152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 1531a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) { 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); 155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator MBBI_end = MBB.end(); 156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1581a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Handle EH_RETURN. 1591a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) { 160fd4ccda4a56d1664b43ca7ed9909254f6de592bbJyotsna Verma assert(MBBI->getOperand(0).isReg() && "Offset should be in register!"); 1611a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); 1621a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr), 1631a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28); 1641a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return; 1651a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma } 166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher 167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // versions. 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MF.getTarget().getSubtarget<HexagonSubtarget>().hasV4TOps() && 169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) { 1701a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC 1711a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // instruction if we encounter it. 1721a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MachineBasicBlock::iterator BeforeJMPR = 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MBB.begin() == MBBI ? MBBI : std::prev(MBBI); 1741a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (BeforeJMPR != MBBI && 1751a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) { 1761a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Remove the JMPR node. 1771a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MBB.erase(MBBI); 1781a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return; 1791a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma } 1801a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma 181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Add dealloc_return. 1821a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MachineInstrBuilder MIB = 1831a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)); 1841a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Transfer the function live-out registers. 1851a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MIB->copyImplicitOps(*MBB.getParent(), &*MBBI); 1861a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Remove the JUMPR node. 1871a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MBB.erase(MBBI); 1881a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma } else { // Add deallocframe for V2 and V3, and V4 tail calls. 1891a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra 1901a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma // DEALLOCFRAME instruction after it. 1911a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MachineBasicBlock::iterator Term = MBB.getFirstTerminator(); 1921a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma MachineBasicBlock::iterator I = 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Term == MBB.begin() ? MBB.end() : std::prev(Term); 1941a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (I != MBB.end() && 1951a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4) 1961a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return; 1971a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma 1981a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); 199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { 204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const MachineFrameInfo *MFI = MF.getFrameInfo(); 205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const HexagonMachineFunctionInfo *FuncInfo = 206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MF.getInfo<HexagonMachineFunctionInfo>(); 207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (MFI->hasCalls() || (MFI->getStackSize() > 0) || 208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum FuncInfo->hasClobberLR() ); 209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 2114aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesenstatic inline 2124aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesenunsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) { 2134aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen MCSuperRegIterator SRI(Reg, TRI); 2144aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen assert(SRI.isValid() && "Expected a superreg"); 2154aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen unsigned SuperReg = *SRI; 2164aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen ++SRI; 2174aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen assert(!SRI.isValid() && "Expected exactly one superreg"); 2184aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen return SuperReg; 2194aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen} 2204aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen 221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool 222b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonFrameLowering::spillCalleeSavedRegisters( 223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock &MBB, 224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator MI, 225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const std::vector<CalleeSavedInfo> &CSI, 226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetRegisterInfo *TRI) const { 227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineFunction *MF = MBB.getParent(); 228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (CSI.empty()) { 231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; 232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // We can only schedule double loads if we spill contiguous callee-saved regs 235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For instance, we cannot scheduled double-word loads if we spill r24, 236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // r26, and r27. 237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // above. 239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool ContiguousRegs = true; 240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum for (unsigned i = 0; i < CSI.size(); ++i) { 242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Reg = CSI[i].getReg(); 243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Check if we can use a double-word store. 246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 2474aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen unsigned SuperReg = uniqueSuperReg(Reg, TRI); 248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool CanUseDblStore = false; 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetRegisterClass* SuperRegClass = nullptr; 250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ContiguousRegs && (i < CSI.size()-1)) { 2524aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 2534aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 2544aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen CanUseDblStore = (SuperRegNext == SuperReg); 255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (CanUseDblStore) { 2594aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen TII.storeRegToStackSlot(MBB, MI, SuperReg, true, 260b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CSI[i+1].getFrameIdx(), SuperRegClass, TRI); 2614aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen MBB.addLiveIn(SuperReg); 262b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ++i; 263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Cannot use a double-word store. 265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ContiguousRegs = false; 266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC, 268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TRI); 269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MBB.addLiveIn(Reg); 270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::restoreCalleeSavedRegisters( 277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock &MBB, 278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator MI, 279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const std::vector<CalleeSavedInfo> &CSI, 280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetRegisterInfo *TRI) const { 281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineFunction *MF = MBB.getParent(); 283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (CSI.empty()) { 286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; 287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // We can only schedule double loads if we spill contiguous callee-saved regs 290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For instance, we cannot scheduled double-word loads if we spill r24, 291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // r26, and r27. 292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Hexagon_TODO: We can try to double-word align odd registers for -O2 and 293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // above. 294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool ContiguousRegs = true; 295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum for (unsigned i = 0; i < CSI.size(); ++i) { 297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Reg = CSI[i].getReg(); 298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Check if we can use a double-word load. 301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 3024aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen unsigned SuperReg = uniqueSuperReg(Reg, TRI); 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetRegisterClass* SuperRegClass = nullptr; 304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool CanUseDblLoad = false; 305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ContiguousRegs && (i < CSI.size()-1)) { 3064aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); 3074aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); 3084aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen CanUseDblLoad = (SuperRegNext == SuperReg); 309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (CanUseDblLoad) { 3134aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(), 314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SuperRegClass, TRI); 3154aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen MBB.addLiveIn(SuperReg); 316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ++i; 317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Cannot use a double-word load. 319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ContiguousRegs = false; 320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI); 322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MBB.addLiveIn(Reg); 323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 328700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid HexagonFrameLowering:: 329700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 330700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator I) const { 331700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr &MI = *I; 332700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 333700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { 334700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Hexagon_TODO: add code 335700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { 336700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Hexagon_TODO: add code 337700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else { 338700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky llvm_unreachable("Cannot handle this call frame pseudo instruction"); 339700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 340700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.erase(I); 341700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 342700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumint HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int FI) const { 345b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return MF.getFrameInfo()->getObjectOffset(FI); 346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 347