10b57cec5SDimitry Andric //=======- NVPTXFrameLowering.cpp - NVPTX Frame Information ---*- C++ -*-=====// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the NVPTX implementation of TargetFrameLowering class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "NVPTXFrameLowering.h" 140b57cec5SDimitry Andric #include "NVPTX.h" 150b57cec5SDimitry Andric #include "NVPTXRegisterInfo.h" 160b57cec5SDimitry Andric #include "NVPTXSubtarget.h" 170b57cec5SDimitry Andric #include "NVPTXTargetMachine.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 230b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric using namespace llvm; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric NVPTXFrameLowering::NVPTXFrameLowering() 288bcb0991SDimitry Andric : TargetFrameLowering(TargetFrameLowering::StackGrowsUp, Align(8), 0) {} 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric bool NVPTXFrameLowering::hasFP(const MachineFunction &MF) const { return true; } 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric void NVPTXFrameLowering::emitPrologue(MachineFunction &MF, 330b57cec5SDimitry Andric MachineBasicBlock &MBB) const { 340b57cec5SDimitry Andric if (MF.getFrameInfo().hasStackObjects()) { 350b57cec5SDimitry Andric assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 36bdd1243dSDimitry Andric MachineBasicBlock::iterator MBBI = MBB.begin(); 370b57cec5SDimitry Andric MachineRegisterInfo &MR = MF.getRegInfo(); 380b57cec5SDimitry Andric 39349cc55cSDimitry Andric const NVPTXRegisterInfo *NRI = 40349cc55cSDimitry Andric MF.getSubtarget<NVPTXSubtarget>().getRegisterInfo(); 41349cc55cSDimitry Andric 420b57cec5SDimitry Andric // This instruction really occurs before first instruction 430b57cec5SDimitry Andric // in the BB, so giving it no debug location. 440b57cec5SDimitry Andric DebugLoc dl = DebugLoc(); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // Emits 470b57cec5SDimitry Andric // mov %SPL, %depot; 480b57cec5SDimitry Andric // cvta.local %SP, %SPL; 490b57cec5SDimitry Andric // for local address accesses in MF. 500b57cec5SDimitry Andric bool Is64Bit = 510b57cec5SDimitry Andric static_cast<const NVPTXTargetMachine &>(MF.getTarget()).is64Bit(); 520b57cec5SDimitry Andric unsigned CvtaLocalOpcode = 530fca6ea1SDimitry Andric (Is64Bit ? NVPTX::cvta_local_64 : NVPTX::cvta_local); 540b57cec5SDimitry Andric unsigned MovDepotOpcode = 550b57cec5SDimitry Andric (Is64Bit ? NVPTX::MOV_DEPOT_ADDR_64 : NVPTX::MOV_DEPOT_ADDR); 56349cc55cSDimitry Andric if (!MR.use_empty(NRI->getFrameRegister(MF))) { 570b57cec5SDimitry Andric // If %SP is not used, do not bother emitting "cvta.local %SP, %SPL". 58bdd1243dSDimitry Andric MBBI = BuildMI(MBB, MBBI, dl, 590b57cec5SDimitry Andric MF.getSubtarget().getInstrInfo()->get(CvtaLocalOpcode), 60349cc55cSDimitry Andric NRI->getFrameRegister(MF)) 61349cc55cSDimitry Andric .addReg(NRI->getFrameLocalRegister(MF)); 620b57cec5SDimitry Andric } 630fca6ea1SDimitry Andric if (!MR.use_empty(NRI->getFrameLocalRegister(MF))) { 64bdd1243dSDimitry Andric BuildMI(MBB, MBBI, dl, 65bdd1243dSDimitry Andric MF.getSubtarget().getInstrInfo()->get(MovDepotOpcode), 66349cc55cSDimitry Andric NRI->getFrameLocalRegister(MF)) 670b57cec5SDimitry Andric .addImm(MF.getFunctionNumber()); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric } 700fca6ea1SDimitry Andric } 710b57cec5SDimitry Andric 72e8d8bef9SDimitry Andric StackOffset 73e8d8bef9SDimitry Andric NVPTXFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, 745ffd83dbSDimitry Andric Register &FrameReg) const { 750b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 760b57cec5SDimitry Andric FrameReg = NVPTX::VRDepot; 77e8d8bef9SDimitry Andric return StackOffset::getFixed(MFI.getObjectOffset(FI) - 78e8d8bef9SDimitry Andric getOffsetOfLocalArea()); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric void NVPTXFrameLowering::emitEpilogue(MachineFunction &MF, 820b57cec5SDimitry Andric MachineBasicBlock &MBB) const {} 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // This function eliminates ADJCALLSTACKDOWN, 850b57cec5SDimitry Andric // ADJCALLSTACKUP pseudo instructions 860b57cec5SDimitry Andric MachineBasicBlock::iterator NVPTXFrameLowering::eliminateCallFramePseudoInstr( 870b57cec5SDimitry Andric MachineFunction &MF, MachineBasicBlock &MBB, 880b57cec5SDimitry Andric MachineBasicBlock::iterator I) const { 890b57cec5SDimitry Andric // Simply discard ADJCALLSTACKDOWN, 900b57cec5SDimitry Andric // ADJCALLSTACKUP instructions. 910b57cec5SDimitry Andric return MBB.erase(I); 920b57cec5SDimitry Andric } 935ffd83dbSDimitry Andric 945ffd83dbSDimitry Andric TargetFrameLowering::DwarfFrameBase 955ffd83dbSDimitry Andric NVPTXFrameLowering::getDwarfFrameBase(const MachineFunction &MF) const { 96*52418fc2SDimitry Andric DwarfFrameBase FrameBase; 97*52418fc2SDimitry Andric FrameBase.Kind = DwarfFrameBase::CFA; 98*52418fc2SDimitry Andric FrameBase.Location.Offset = 0; 99*52418fc2SDimitry Andric return FrameBase; 1005ffd83dbSDimitry Andric } 101