LLVM 17.0.0git
NVPTXInstrInfo.cpp
Go to the documentation of this file.
1//===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the NVPTX implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "NVPTXInstrInfo.h"
14#include "NVPTX.h"
15#include "NVPTXTargetMachine.h"
16#include "llvm/ADT/STLExtras.h"
20#include "llvm/IR/Function.h"
21
22using namespace llvm;
23
24#define GET_INSTRINFO_CTOR_DTOR
25#include "NVPTXGenInstrInfo.inc"
26
27// Pin the vtable to this file.
28void NVPTXInstrInfo::anchor() {}
29
31
34 const DebugLoc &DL, MCRegister DestReg,
35 MCRegister SrcReg, bool KillSrc) const {
37 const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg);
38 const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
39
40 if (RegInfo.getRegSizeInBits(*DestRC) != RegInfo.getRegSizeInBits(*SrcRC))
41 report_fatal_error("Copy one register into another with a different width");
42
43 unsigned Op;
44 if (DestRC == &NVPTX::Int1RegsRegClass) {
45 Op = NVPTX::IMOV1rr;
46 } else if (DestRC == &NVPTX::Int16RegsRegClass) {
47 Op = NVPTX::IMOV16rr;
48 } else if (DestRC == &NVPTX::Int32RegsRegClass) {
49 Op = (SrcRC == &NVPTX::Int32RegsRegClass ? NVPTX::IMOV32rr
50 : NVPTX::BITCONVERT_32_F2I);
51 } else if (DestRC == &NVPTX::Int64RegsRegClass) {
52 Op = (SrcRC == &NVPTX::Int64RegsRegClass ? NVPTX::IMOV64rr
53 : NVPTX::BITCONVERT_64_F2I);
54 } else if (DestRC == &NVPTX::Float16RegsRegClass) {
55 Op = (SrcRC == &NVPTX::Float16RegsRegClass ? NVPTX::FMOV16rr
56 : NVPTX::BITCONVERT_16_I2F);
57 } else if (DestRC == &NVPTX::Float16x2RegsRegClass) {
58 Op = NVPTX::IMOV32rr;
59 } else if (DestRC == &NVPTX::Float32RegsRegClass) {
60 Op = (SrcRC == &NVPTX::Float32RegsRegClass ? NVPTX::FMOV32rr
61 : NVPTX::BITCONVERT_32_I2F);
62 } else if (DestRC == &NVPTX::Float64RegsRegClass) {
63 Op = (SrcRC == &NVPTX::Float64RegsRegClass ? NVPTX::FMOV64rr
64 : NVPTX::BITCONVERT_64_I2F);
65 } else {
66 llvm_unreachable("Bad register copy");
67 }
68 BuildMI(MBB, I, DL, get(Op), DestReg)
69 .addReg(SrcReg, getKillRegState(KillSrc));
70}
71
72/// analyzeBranch - Analyze the branching code at the end of MBB, returning
73/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
74/// implemented for a target). Upon success, this returns false and returns
75/// with the following information in various cases:
76///
77/// 1. If this block ends with no branches (it just falls through to its succ)
78/// just return false, leaving TBB/FBB null.
79/// 2. If this block ends with only an unconditional branch, it sets TBB to be
80/// the destination block.
81/// 3. If this block ends with an conditional branch and it falls through to
82/// an successor block, it sets TBB to be the branch destination block and a
83/// list of operands that evaluate the condition. These
84/// operands can be passed to other TargetInstrInfo methods to create new
85/// branches.
86/// 4. If this block ends with an conditional branch and an unconditional
87/// block, it returns the 'true' destination in TBB, the 'false' destination
88/// in FBB, and a list of operands that evaluate the condition. These
89/// operands can be passed to other TargetInstrInfo methods to create new
90/// branches.
91///
92/// Note that removeBranch and insertBranch must be implemented to support
93/// cases where this method returns success.
94///
99 bool AllowModify) const {
100 // If the block has no terminators, it just falls into the block after it.
102 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
103 return false;
104
105 // Get the last instruction in the block.
106 MachineInstr &LastInst = *I;
107
108 // If there is only one terminator instruction, process it.
109 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
110 if (LastInst.getOpcode() == NVPTX::GOTO) {
111 TBB = LastInst.getOperand(0).getMBB();
112 return false;
113 } else if (LastInst.getOpcode() == NVPTX::CBranch) {
114 // Block ends with fall-through condbranch.
115 TBB = LastInst.getOperand(1).getMBB();
116 Cond.push_back(LastInst.getOperand(0));
117 return false;
118 }
119 // Otherwise, don't know what this is.
120 return true;
121 }
122
123 // Get the instruction before it if it's a terminator.
124 MachineInstr &SecondLastInst = *I;
125
126 // If there are three terminators, we don't know what sort of block this is.
127 if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
128 return true;
129
130 // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
131 if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
132 LastInst.getOpcode() == NVPTX::GOTO) {
133 TBB = SecondLastInst.getOperand(1).getMBB();
134 Cond.push_back(SecondLastInst.getOperand(0));
135 FBB = LastInst.getOperand(0).getMBB();
136 return false;
137 }
138
139 // If the block ends with two NVPTX:GOTOs, handle it. The second one is not
140 // executed, so remove it.
141 if (SecondLastInst.getOpcode() == NVPTX::GOTO &&
142 LastInst.getOpcode() == NVPTX::GOTO) {
143 TBB = SecondLastInst.getOperand(0).getMBB();
144 I = LastInst;
145 if (AllowModify)
146 I->eraseFromParent();
147 return false;
148 }
149
150 // Otherwise, can't handle this.
151 return true;
152}
153
155 int *BytesRemoved) const {
156 assert(!BytesRemoved && "code size not handled");
158 if (I == MBB.begin())
159 return 0;
160 --I;
161 if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
162 return 0;
163
164 // Remove the branch.
165 I->eraseFromParent();
166
167 I = MBB.end();
168
169 if (I == MBB.begin())
170 return 1;
171 --I;
172 if (I->getOpcode() != NVPTX::CBranch)
173 return 1;
174
175 // Remove the branch.
176 I->eraseFromParent();
177 return 2;
178}
179
184 const DebugLoc &DL,
185 int *BytesAdded) const {
186 assert(!BytesAdded && "code size not handled");
187
188 // Shouldn't be a fall through.
189 assert(TBB && "insertBranch must not be told to insert a fallthrough");
190 assert((Cond.size() == 1 || Cond.size() == 0) &&
191 "NVPTX branch conditions have two components!");
192
193 // One-way branch.
194 if (!FBB) {
195 if (Cond.empty()) // Unconditional branch
196 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
197 else // Conditional branch
198 BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
199 return 1;
200 }
201
202 // Two-way Conditional Branch.
203 BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
204 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
205 return 2;
206}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
SmallVector< MachineOperand, 4 > Cond
#define I(x, y, z)
Definition: MD5.cpp:58
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A debug info location.
Definition: DebugLoc.h:33
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
MachineBasicBlock * getMBB() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
analyzeBranch - Analyze the branching code at the end of MBB, returning true if it cannot be understo...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
unsigned getKillRegState(bool B)