LLVM 20.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::Int128RegsRegClass) {
55 Op = NVPTX::IMOV128rr;
56 } else if (DestRC == &NVPTX::Float32RegsRegClass) {
57 Op = (SrcRC == &NVPTX::Float32RegsRegClass ? NVPTX::FMOV32rr
58 : NVPTX::BITCONVERT_32_I2F);
59 } else if (DestRC == &NVPTX::Float64RegsRegClass) {
60 Op = (SrcRC == &NVPTX::Float64RegsRegClass ? NVPTX::FMOV64rr
61 : NVPTX::BITCONVERT_64_I2F);
62 } else {
63 llvm_unreachable("Bad register copy");
64 }
65 BuildMI(MBB, I, DL, get(Op), DestReg)
66 .addReg(SrcReg, getKillRegState(KillSrc));
67}
68
69/// analyzeBranch - Analyze the branching code at the end of MBB, returning
70/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
71/// implemented for a target). Upon success, this returns false and returns
72/// with the following information in various cases:
73///
74/// 1. If this block ends with no branches (it just falls through to its succ)
75/// just return false, leaving TBB/FBB null.
76/// 2. If this block ends with only an unconditional branch, it sets TBB to be
77/// the destination block.
78/// 3. If this block ends with an conditional branch and it falls through to
79/// an successor block, it sets TBB to be the branch destination block and a
80/// list of operands that evaluate the condition. These
81/// operands can be passed to other TargetInstrInfo methods to create new
82/// branches.
83/// 4. If this block ends with an conditional branch and an unconditional
84/// block, it returns the 'true' destination in TBB, the 'false' destination
85/// in FBB, and a list of operands that evaluate the condition. These
86/// operands can be passed to other TargetInstrInfo methods to create new
87/// branches.
88///
89/// Note that removeBranch and insertBranch must be implemented to support
90/// cases where this method returns success.
91///
96 bool AllowModify) const {
97 // If the block has no terminators, it just falls into the block after it.
99 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
100 return false;
101
102 // Get the last instruction in the block.
103 MachineInstr &LastInst = *I;
104
105 // If there is only one terminator instruction, process it.
106 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
107 if (LastInst.getOpcode() == NVPTX::GOTO) {
108 TBB = LastInst.getOperand(0).getMBB();
109 return false;
110 } else if (LastInst.getOpcode() == NVPTX::CBranch) {
111 // Block ends with fall-through condbranch.
112 TBB = LastInst.getOperand(1).getMBB();
113 Cond.push_back(LastInst.getOperand(0));
114 return false;
115 }
116 // Otherwise, don't know what this is.
117 return true;
118 }
119
120 // Get the instruction before it if it's a terminator.
121 MachineInstr &SecondLastInst = *I;
122
123 // If there are three terminators, we don't know what sort of block this is.
124 if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
125 return true;
126
127 // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
128 if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
129 LastInst.getOpcode() == NVPTX::GOTO) {
130 TBB = SecondLastInst.getOperand(1).getMBB();
131 Cond.push_back(SecondLastInst.getOperand(0));
132 FBB = LastInst.getOperand(0).getMBB();
133 return false;
134 }
135
136 // If the block ends with two NVPTX:GOTOs, handle it. The second one is not
137 // executed, so remove it.
138 if (SecondLastInst.getOpcode() == NVPTX::GOTO &&
139 LastInst.getOpcode() == NVPTX::GOTO) {
140 TBB = SecondLastInst.getOperand(0).getMBB();
141 I = LastInst;
142 if (AllowModify)
143 I->eraseFromParent();
144 return false;
145 }
146
147 // Otherwise, can't handle this.
148 return true;
149}
150
152 int *BytesRemoved) const {
153 assert(!BytesRemoved && "code size not handled");
155 if (I == MBB.begin())
156 return 0;
157 --I;
158 if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
159 return 0;
160
161 // Remove the branch.
162 I->eraseFromParent();
163
164 I = MBB.end();
165
166 if (I == MBB.begin())
167 return 1;
168 --I;
169 if (I->getOpcode() != NVPTX::CBranch)
170 return 1;
171
172 // Remove the branch.
173 I->eraseFromParent();
174 return 2;
175}
176
181 const DebugLoc &DL,
182 int *BytesAdded) const {
183 assert(!BytesAdded && "code size not handled");
184
185 // Shouldn't be a fall through.
186 assert(TBB && "insertBranch must not be told to insert a fallthrough");
187 assert((Cond.size() == 1 || Cond.size() == 0) &&
188 "NVPTX branch conditions have two components!");
189
190 // One-way branch.
191 if (!FBB) {
192 if (Cond.empty()) // Unconditional branch
193 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
194 else // Conditional branch
195 BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
196 return 1;
197 }
198
199 // Two-way Conditional Branch.
200 BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
201 BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
202 return 2;
203}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define I(x, y, z)
Definition: MD5.cpp:58
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:569
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
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:586
#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:167
unsigned getKillRegState(bool B)
DWARFExpression::Operation Op