Path: blob/main/contrib/llvm-project/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
35271 views
//===- NVPTXInstrInfo.cpp - NVPTX Instruction 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 TargetInstrInfo class.9//10//===----------------------------------------------------------------------===//1112#include "NVPTXInstrInfo.h"13#include "NVPTX.h"14#include "NVPTXTargetMachine.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/MachineInstrBuilder.h"18#include "llvm/CodeGen/MachineRegisterInfo.h"19#include "llvm/IR/Function.h"2021using namespace llvm;2223#define GET_INSTRINFO_CTOR_DTOR24#include "NVPTXGenInstrInfo.inc"2526// Pin the vtable to this file.27void NVPTXInstrInfo::anchor() {}2829NVPTXInstrInfo::NVPTXInstrInfo() : RegInfo() {}3031void NVPTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,32MachineBasicBlock::iterator I,33const DebugLoc &DL, MCRegister DestReg,34MCRegister SrcReg, bool KillSrc) const {35const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();36const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg);37const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);3839if (RegInfo.getRegSizeInBits(*DestRC) != RegInfo.getRegSizeInBits(*SrcRC))40report_fatal_error("Copy one register into another with a different width");4142unsigned Op;43if (DestRC == &NVPTX::Int1RegsRegClass) {44Op = NVPTX::IMOV1rr;45} else if (DestRC == &NVPTX::Int16RegsRegClass) {46Op = NVPTX::IMOV16rr;47} else if (DestRC == &NVPTX::Int32RegsRegClass) {48Op = (SrcRC == &NVPTX::Int32RegsRegClass ? NVPTX::IMOV32rr49: NVPTX::BITCONVERT_32_F2I);50} else if (DestRC == &NVPTX::Int64RegsRegClass) {51Op = (SrcRC == &NVPTX::Int64RegsRegClass ? NVPTX::IMOV64rr52: NVPTX::BITCONVERT_64_F2I);53} else if (DestRC == &NVPTX::Int128RegsRegClass) {54Op = NVPTX::IMOV128rr;55} else if (DestRC == &NVPTX::Float32RegsRegClass) {56Op = (SrcRC == &NVPTX::Float32RegsRegClass ? NVPTX::FMOV32rr57: NVPTX::BITCONVERT_32_I2F);58} else if (DestRC == &NVPTX::Float64RegsRegClass) {59Op = (SrcRC == &NVPTX::Float64RegsRegClass ? NVPTX::FMOV64rr60: NVPTX::BITCONVERT_64_I2F);61} else {62llvm_unreachable("Bad register copy");63}64BuildMI(MBB, I, DL, get(Op), DestReg)65.addReg(SrcReg, getKillRegState(KillSrc));66}6768/// analyzeBranch - Analyze the branching code at the end of MBB, returning69/// true if it cannot be understood (e.g. it's a switch dispatch or isn't70/// implemented for a target). Upon success, this returns false and returns71/// with the following information in various cases:72///73/// 1. If this block ends with no branches (it just falls through to its succ)74/// just return false, leaving TBB/FBB null.75/// 2. If this block ends with only an unconditional branch, it sets TBB to be76/// the destination block.77/// 3. If this block ends with an conditional branch and it falls through to78/// an successor block, it sets TBB to be the branch destination block and a79/// list of operands that evaluate the condition. These80/// operands can be passed to other TargetInstrInfo methods to create new81/// branches.82/// 4. If this block ends with an conditional branch and an unconditional83/// block, it returns the 'true' destination in TBB, the 'false' destination84/// in FBB, and a list of operands that evaluate the condition. These85/// operands can be passed to other TargetInstrInfo methods to create new86/// branches.87///88/// Note that removeBranch and insertBranch must be implemented to support89/// cases where this method returns success.90///91bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,92MachineBasicBlock *&TBB,93MachineBasicBlock *&FBB,94SmallVectorImpl<MachineOperand> &Cond,95bool AllowModify) const {96// If the block has no terminators, it just falls into the block after it.97MachineBasicBlock::iterator I = MBB.end();98if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))99return false;100101// Get the last instruction in the block.102MachineInstr &LastInst = *I;103104// If there is only one terminator instruction, process it.105if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {106if (LastInst.getOpcode() == NVPTX::GOTO) {107TBB = LastInst.getOperand(0).getMBB();108return false;109} else if (LastInst.getOpcode() == NVPTX::CBranch) {110// Block ends with fall-through condbranch.111TBB = LastInst.getOperand(1).getMBB();112Cond.push_back(LastInst.getOperand(0));113return false;114}115// Otherwise, don't know what this is.116return true;117}118119// Get the instruction before it if it's a terminator.120MachineInstr &SecondLastInst = *I;121122// If there are three terminators, we don't know what sort of block this is.123if (I != MBB.begin() && isUnpredicatedTerminator(*--I))124return true;125126// If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.127if (SecondLastInst.getOpcode() == NVPTX::CBranch &&128LastInst.getOpcode() == NVPTX::GOTO) {129TBB = SecondLastInst.getOperand(1).getMBB();130Cond.push_back(SecondLastInst.getOperand(0));131FBB = LastInst.getOperand(0).getMBB();132return false;133}134135// If the block ends with two NVPTX:GOTOs, handle it. The second one is not136// executed, so remove it.137if (SecondLastInst.getOpcode() == NVPTX::GOTO &&138LastInst.getOpcode() == NVPTX::GOTO) {139TBB = SecondLastInst.getOperand(0).getMBB();140I = LastInst;141if (AllowModify)142I->eraseFromParent();143return false;144}145146// Otherwise, can't handle this.147return true;148}149150unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,151int *BytesRemoved) const {152assert(!BytesRemoved && "code size not handled");153MachineBasicBlock::iterator I = MBB.end();154if (I == MBB.begin())155return 0;156--I;157if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)158return 0;159160// Remove the branch.161I->eraseFromParent();162163I = MBB.end();164165if (I == MBB.begin())166return 1;167--I;168if (I->getOpcode() != NVPTX::CBranch)169return 1;170171// Remove the branch.172I->eraseFromParent();173return 2;174}175176unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,177MachineBasicBlock *TBB,178MachineBasicBlock *FBB,179ArrayRef<MachineOperand> Cond,180const DebugLoc &DL,181int *BytesAdded) const {182assert(!BytesAdded && "code size not handled");183184// Shouldn't be a fall through.185assert(TBB && "insertBranch must not be told to insert a fallthrough");186assert((Cond.size() == 1 || Cond.size() == 0) &&187"NVPTX branch conditions have two components!");188189// One-way branch.190if (!FBB) {191if (Cond.empty()) // Unconditional branch192BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);193else // Conditional branch194BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);195return 1;196}197198// Two-way Conditional Branch.199BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);200BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);201return 2;202}203204205