LLVM  16.0.0git
SPIRVInstrInfo.cpp
Go to the documentation of this file.
1 //===-- SPIRVInstrInfo.cpp - SPIR-V Instruction Information ------*- C++-*-===//
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 SPIR-V implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "SPIRVInstrInfo.h"
14 #include "SPIRV.h"
15 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/IR/DebugLoc.h"
20 
21 #define GET_INSTRINFO_CTOR_DTOR
22 #include "SPIRVGenInstrInfo.inc"
23 
24 using namespace llvm;
25 
27 
29  switch (MI.getOpcode()) {
30  case SPIRV::OpConstantTrue:
31  case SPIRV::OpConstantFalse:
32  case SPIRV::OpConstantI:
33  case SPIRV::OpConstantF:
34  case SPIRV::OpConstantComposite:
35  case SPIRV::OpConstantSampler:
36  case SPIRV::OpConstantNull:
37  case SPIRV::OpSpecConstantTrue:
38  case SPIRV::OpSpecConstantFalse:
39  case SPIRV::OpSpecConstant:
40  case SPIRV::OpSpecConstantComposite:
41  case SPIRV::OpSpecConstantOp:
42  case SPIRV::OpUndef:
43  return true;
44  default:
45  return false;
46  }
47 }
48 
50  auto &MRI = MI.getMF()->getRegInfo();
51  if (MI.getNumDefs() >= 1 && MI.getOperand(0).isReg()) {
52  auto DefRegClass = MRI.getRegClassOrNull(MI.getOperand(0).getReg());
53  return DefRegClass && DefRegClass->getID() == SPIRV::TYPERegClass.getID();
54  } else {
55  return MI.getOpcode() == SPIRV::OpTypeForwardPointer;
56  }
57 }
58 
60  switch (MI.getOpcode()) {
61  case SPIRV::OpDecorate:
62  case SPIRV::OpDecorateId:
63  case SPIRV::OpDecorateString:
64  case SPIRV::OpMemberDecorate:
65  case SPIRV::OpMemberDecorateString:
66  return true;
67  default:
68  return false;
69  }
70 }
71 
73  switch (MI.getOpcode()) {
74  case SPIRV::OpCapability:
75  case SPIRV::OpExtension:
76  case SPIRV::OpExtInstImport:
77  case SPIRV::OpMemoryModel:
78  case SPIRV::OpEntryPoint:
79  case SPIRV::OpExecutionMode:
80  case SPIRV::OpExecutionModeId:
81  case SPIRV::OpString:
82  case SPIRV::OpSourceExtension:
83  case SPIRV::OpSource:
84  case SPIRV::OpSourceContinued:
85  case SPIRV::OpName:
86  case SPIRV::OpMemberName:
87  case SPIRV::OpModuleProcessed:
88  return true;
89  default:
91  }
92 }
93 
95  switch (MI.getOpcode()) {
96  case SPIRV::OpFAddS:
97  case SPIRV::OpFSubS:
98  case SPIRV::OpFMulS:
99  case SPIRV::OpFDivS:
100  case SPIRV::OpFRemS:
101  case SPIRV::OpFAddV:
102  case SPIRV::OpFSubV:
103  case SPIRV::OpFMulV:
104  case SPIRV::OpFDivV:
105  case SPIRV::OpFRemV:
106  case SPIRV::OpFMod:
107  return true;
108  default:
109  return false;
110  }
111 }
112 
114  switch (MI.getOpcode()) {
115  case SPIRV::OpIAddS:
116  case SPIRV::OpIAddV:
117  case SPIRV::OpISubS:
118  case SPIRV::OpISubV:
119  case SPIRV::OpIMulS:
120  case SPIRV::OpIMulV:
121  case SPIRV::OpShiftLeftLogicalS:
122  case SPIRV::OpShiftLeftLogicalV:
123  case SPIRV::OpSNegate:
124  return true;
125  default:
126  return false;
127  }
128 }
129 
131  switch (MI.getOpcode()) {
132  case SPIRV::OpIAddS:
133  case SPIRV::OpIAddV:
134  case SPIRV::OpISubS:
135  case SPIRV::OpISubV:
136  case SPIRV::OpIMulS:
137  case SPIRV::OpIMulV:
138  return true;
139  default:
140  return false;
141  }
142 }
143 
144 // Analyze the branching code at the end of MBB, returning
145 // true if it cannot be understood (e.g. it's a switch dispatch or isn't
146 // implemented for a target). Upon success, this returns false and returns
147 // with the following information in various cases:
148 //
149 // 1. If this block ends with no branches (it just falls through to its succ)
150 // just return false, leaving TBB/FBB null.
151 // 2. If this block ends with only an unconditional branch, it sets TBB to be
152 // the destination block.
153 // 3. If this block ends with a conditional branch and it falls through to a
154 // successor block, it sets TBB to be the branch destination block and a
155 // list of operands that evaluate the condition. These operands can be
156 // passed to other TargetInstrInfo methods to create new branches.
157 // 4. If this block ends with a conditional branch followed by an
158 // unconditional branch, it returns the 'true' destination in TBB, the
159 // 'false' destination in FBB, and a list of operands that evaluate the
160 // condition. These operands can be passed to other TargetInstrInfo
161 // methods to create new branches.
162 //
163 // Note that removeBranch and insertBranch must be implemented to support
164 // cases where this method returns success.
165 //
166 // If AllowModify is true, then this routine is allowed to modify the basic
167 // block (e.g. delete instructions after the unconditional branch).
168 //
169 // The CFG information in MBB.Predecessors and MBB.Successors must be valid
170 // before calling this function.
173  MachineBasicBlock *&FBB,
175  bool AllowModify) const {
176  TBB = nullptr;
177  FBB = nullptr;
178  if (MBB.empty())
179  return false;
180  auto MI = MBB.getLastNonDebugInstr();
181  if (!MI.isValid())
182  return false;
183  if (MI->getOpcode() == SPIRV::OpBranch) {
184  TBB = MI->getOperand(0).getMBB();
185  return false;
186  } else if (MI->getOpcode() == SPIRV::OpBranchConditional) {
187  Cond.push_back(MI->getOperand(0));
188  TBB = MI->getOperand(1).getMBB();
189  if (MI->getNumOperands() == 3) {
190  FBB = MI->getOperand(2).getMBB();
191  }
192  return false;
193  } else {
194  return true;
195  }
196 }
197 
198 // Remove the branching code at the end of the specific MBB.
199 // This is only invoked in cases where analyzeBranch returns success. It
200 // returns the number of instructions that were removed.
201 // If \p BytesRemoved is non-null, report the change in code size from the
202 // removed instructions.
204  int *BytesRemoved) const {
205  report_fatal_error("Branch removal not supported, as MBB info not propagated"
206  " to OpPhi instructions. Try using -O0 instead.");
207 }
208 
209 // Insert branch code into the end of the specified MachineBasicBlock. The
210 // operands to this method are the same as those returned by analyzeBranch.
211 // This is only invoked in cases where analyzeBranch returns success. It
212 // returns the number of instructions inserted. If \p BytesAdded is non-null,
213 // report the change in code size from the added instructions.
214 //
215 // It is also invoked by tail merging to add unconditional branches in
216 // cases where analyzeBranch doesn't apply because there was no original
217 // branch to analyze. At least this much must be implemented, else tail
218 // merging needs to be disabled.
219 //
220 // The CFG information in MBB.Predecessors and MBB.Successors must be valid
221 // before calling this function.
224  ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
225  report_fatal_error("Branch insertion not supported, as MBB info not "
226  "propagated to OpPhi instructions. Try using "
227  "-O0 instead.");
228 }
229 
232  const DebugLoc &DL, MCRegister DestReg,
233  MCRegister SrcReg, bool KillSrc) const {
234  // Actually we don't need this COPY instruction. However if we do nothing with
235  // it, post RA pseudo instrs expansion just removes it and we get the code
236  // with undef registers. Therefore, we need to replace all uses of dst with
237  // the src register. COPY instr itself will be safely removed later.
238  assert(I->isCopy() && "Copy instruction is expected");
239  auto DstOp = I->getOperand(0);
240  auto SrcOp = I->getOperand(1);
241  assert(DstOp.isReg() && SrcOp.isReg() &&
242  "Register operands are expected in COPY");
243  auto &MRI = I->getMF()->getRegInfo();
245 }
246 
248  if (MI.getOpcode() == SPIRV::GET_ID || MI.getOpcode() == SPIRV::GET_fID ||
249  MI.getOpcode() == SPIRV::GET_pID || MI.getOpcode() == SPIRV::GET_vfID ||
250  MI.getOpcode() == SPIRV::GET_vID) {
251  auto &MRI = MI.getMF()->getRegInfo();
252  MRI.replaceRegWith(MI.getOperand(0).getReg(), MI.getOperand(1).getReg());
253  MI.eraseFromParent();
254  return true;
255  }
256  return false;
257 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:75
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
SPIRVGenInstrInfo
llvm::SPIRVInstrInfo::isDecorationInstr
bool isDecorationInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:59
llvm::SPIRVInstrInfo::canUseNUW
bool canUseNUW(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:130
ErrorHandling.h
MachineBasicBlock.h
llvm::SPIRVInstrInfo::analyzeBranch
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Definition: SPIRVInstrInfo.cpp:171
llvm::SPIRVInstrInfo::insertBranch
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Definition: SPIRVInstrInfo.cpp:222
MachineIRBuilder.h
llvm::SPIRVInstrInfo::isConstantInstr
bool isConstantInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:28
llvm::SPIRVInstrInfo::isTypeDeclInstr
bool isTypeDeclInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:49
llvm::SPIRVInstrInfo::canUseFastMathFlags
bool canUseFastMathFlags(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:94
llvm::DstOp::getReg
Register getReg() const
Definition: MachineIRBuilder.h:108
llvm::SPIRVInstrInfo::isHeaderInstr
bool isHeaderInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:72
TBB
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
Definition: RISCVRedundantCopyElimination.cpp:76
llvm::SPIRVInstrInfo::canUseNSW
bool canUseNSW(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:113
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
DebugLoc.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
SPIRVInstrInfo.h
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MachineBasicBlock::getLastNonDebugInstr
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Definition: MachineBasicBlock.cpp:264
llvm::MachineRegisterInfo::getRegClassOrNull
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
Definition: MachineRegisterInfo.h:664
SPIRV.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SPIRVInstrInfo::SPIRVInstrInfo
SPIRVInstrInfo()
Definition: SPIRVInstrInfo.cpp:26
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::SrcOp::getReg
Register getReg() const
Definition: MachineIRBuilder.h:180
Cond
SmallVector< MachineOperand, 4 > Cond
Definition: BasicBlockSections.cpp:138
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::MachineRegisterInfo::replaceRegWith
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Definition: MachineRegisterInfo.cpp:378
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::SPIRVInstrInfo::removeBranch
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Definition: SPIRVInstrInfo.cpp:203
SmallVector.h
llvm::SPIRVInstrInfo::copyPhysReg
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
Definition: SPIRVInstrInfo.cpp:230
llvm::DstOp
Definition: MachineIRBuilder.h:67
llvm::MachineBasicBlock::empty
bool empty() const
Definition: MachineBasicBlock.h:277
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::SPIRVInstrInfo::expandPostRAPseudo
bool expandPostRAPseudo(MachineInstr &MI) const override
Definition: SPIRVInstrInfo.cpp:247
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::SrcOp
Definition: MachineIRBuilder.h:128
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24