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
NVPTXFrameLowering()270b57cec5SDimitry Andric NVPTXFrameLowering::NVPTXFrameLowering()
288bcb0991SDimitry Andric : TargetFrameLowering(TargetFrameLowering::StackGrowsUp, Align(8), 0) {}
290b57cec5SDimitry Andric
hasFP(const MachineFunction & MF) const300b57cec5SDimitry Andric bool NVPTXFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
310b57cec5SDimitry Andric
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const320b57cec5SDimitry 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
getFrameIndexReference(const MachineFunction & MF,int FI,Register & FrameReg) const73e8d8bef9SDimitry 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
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const810b57cec5SDimitry Andric void NVPTXFrameLowering::emitEpilogue(MachineFunction &MF,
820b57cec5SDimitry Andric MachineBasicBlock &MBB) const {}
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric // This function eliminates ADJCALLSTACKDOWN,
850b57cec5SDimitry Andric // ADJCALLSTACKUP pseudo instructions
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const860b57cec5SDimitry 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
getDwarfFrameBase(const MachineFunction & MF) const955ffd83dbSDimitry 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