Path: blob/main/contrib/llvm-project/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.cpp
96353 views
//===- NVPTXRegisterInfo.cpp - NVPTX Register Information -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the NVPTX implementation of the TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "NVPTXRegisterInfo.h"13#include "NVPTX.h"14#include "NVPTXSubtarget.h"15#include "NVPTXTargetMachine.h"16#include "llvm/ADT/BitVector.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineFunction.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/TargetInstrInfo.h"21#include "llvm/MC/MachineLocation.h"2223using namespace llvm;2425#define DEBUG_TYPE "nvptx-reg-info"2627namespace llvm {28std::string getNVPTXRegClassName(TargetRegisterClass const *RC) {29if (RC == &NVPTX::Float32RegsRegClass)30return ".f32";31if (RC == &NVPTX::Float64RegsRegClass)32return ".f64";33if (RC == &NVPTX::Int128RegsRegClass)34return ".b128";35if (RC == &NVPTX::Int64RegsRegClass)36// We use untyped (.b) integer registers here as NVCC does.37// Correctness of generated code does not depend on register type,38// but using .s/.u registers runs into ptxas bug that prevents39// assembly of otherwise valid PTX into SASS. Despite PTX ISA40// specifying only argument size for fp16 instructions, ptxas does41// not allow using .s16 or .u16 arguments for .fp1642// instructions. At the same time it allows using .s32/.u3243// arguments for .fp16v2 instructions:44//45// .reg .b16 rb1646// .reg .s16 rs1647// add.f16 rb16,rb16,rb16; // OK48// add.f16 rs16,rs16,rs16; // Arguments mismatch for instruction 'add'49// but:50// .reg .b32 rb3251// .reg .s32 rs3252// add.f16v2 rb32,rb32,rb32; // OK53// add.f16v2 rs32,rs32,rs32; // OK54return ".b64";55if (RC == &NVPTX::Int32RegsRegClass)56return ".b32";57if (RC == &NVPTX::Int16RegsRegClass)58return ".b16";59if (RC == &NVPTX::Int1RegsRegClass)60return ".pred";61if (RC == &NVPTX::SpecialRegsRegClass)62return "!Special!";63return "INTERNAL";64}6566std::string getNVPTXRegClassStr(TargetRegisterClass const *RC) {67if (RC == &NVPTX::Float32RegsRegClass)68return "%f";69if (RC == &NVPTX::Float64RegsRegClass)70return "%fd";71if (RC == &NVPTX::Int128RegsRegClass)72return "%rq";73if (RC == &NVPTX::Int64RegsRegClass)74return "%rd";75if (RC == &NVPTX::Int32RegsRegClass)76return "%r";77if (RC == &NVPTX::Int16RegsRegClass)78return "%rs";79if (RC == &NVPTX::Int1RegsRegClass)80return "%p";81if (RC == &NVPTX::SpecialRegsRegClass)82return "!Special!";83return "INTERNAL";84}85}8687NVPTXRegisterInfo::NVPTXRegisterInfo()88: NVPTXGenRegisterInfo(0), StrPool(StrAlloc) {}8990#define GET_REGINFO_TARGET_DESC91#include "NVPTXGenRegisterInfo.inc"9293/// NVPTX Callee Saved Registers94const MCPhysReg *95NVPTXRegisterInfo::getCalleeSavedRegs(const MachineFunction *) const {96static const MCPhysReg CalleeSavedRegs[] = { 0 };97return CalleeSavedRegs;98}99100BitVector NVPTXRegisterInfo::getReservedRegs(const MachineFunction &MF) const {101BitVector Reserved(getNumRegs());102for (unsigned Reg = NVPTX::ENVREG0; Reg <= NVPTX::ENVREG31; ++Reg) {103markSuperRegs(Reserved, Reg);104}105markSuperRegs(Reserved, NVPTX::VRFrame32);106markSuperRegs(Reserved, NVPTX::VRFrameLocal32);107markSuperRegs(Reserved, NVPTX::VRFrame64);108markSuperRegs(Reserved, NVPTX::VRFrameLocal64);109markSuperRegs(Reserved, NVPTX::VRDepot);110return Reserved;111}112113bool NVPTXRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,114int SPAdj, unsigned FIOperandNum,115RegScavenger *RS) const {116assert(SPAdj == 0 && "Unexpected");117118MachineInstr &MI = *II;119int FrameIndex = MI.getOperand(FIOperandNum).getIndex();120121MachineFunction &MF = *MI.getParent()->getParent();122int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +123MI.getOperand(FIOperandNum + 1).getImm();124125// Using I0 as the frame pointer126MI.getOperand(FIOperandNum).ChangeToRegister(getFrameRegister(MF), false);127MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);128return false;129}130131Register NVPTXRegisterInfo::getFrameRegister(const MachineFunction &MF) const {132const NVPTXTargetMachine &TM =133static_cast<const NVPTXTargetMachine &>(MF.getTarget());134return TM.is64Bit() ? NVPTX::VRFrame64 : NVPTX::VRFrame32;135}136137Register138NVPTXRegisterInfo::getFrameLocalRegister(const MachineFunction &MF) const {139const NVPTXTargetMachine &TM =140static_cast<const NVPTXTargetMachine &>(MF.getTarget());141return TM.is64Bit() ? NVPTX::VRFrameLocal64 : NVPTX::VRFrameLocal32;142}143144145