LLVM  16.0.0git
SPIRVPreLegalizer.cpp
Go to the documentation of this file.
1 //===-- SPIRVPreLegalizer.cpp - prepare IR for legalization -----*- 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 // The pass prepares IR for legalization: it assigns SPIR-V types to registers
10 // and removes intrinsics which holded these types during IR translation.
11 // Also it processes constants and registers them in GR to avoid duplication.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "SPIRV.h"
16 #include "SPIRVSubtarget.h"
17 #include "SPIRVUtils.h"
20 #include "llvm/IR/Attributes.h"
21 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/IntrinsicsSPIRV.h"
25 
26 #define DEBUG_TYPE "spirv-prelegalizer"
27 
28 using namespace llvm;
29 
30 namespace {
31 class SPIRVPreLegalizer : public MachineFunctionPass {
32 public:
33  static char ID;
34  SPIRVPreLegalizer() : MachineFunctionPass(ID) {
36  }
37  bool runOnMachineFunction(MachineFunction &MF) override;
38 };
39 } // namespace
40 
43  DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
44  SmallVector<MachineInstr *, 10> ToErase, ToEraseComposites;
45  for (MachineBasicBlock &MBB : MF) {
46  for (MachineInstr &MI : MBB) {
47  if (!isSpvIntrinsic(MI, Intrinsic::spv_track_constant))
48  continue;
49  ToErase.push_back(&MI);
50  auto *Const =
51  cast<Constant>(cast<ConstantAsMetadata>(
52  MI.getOperand(3).getMetadata()->getOperand(0))
53  ->getValue());
54  if (auto *GV = dyn_cast<GlobalValue>(Const)) {
55  Register Reg = GR->find(GV, &MF);
56  if (!Reg.isValid())
57  GR->add(GV, &MF, MI.getOperand(2).getReg());
58  else
59  RegsAlreadyAddedToDT[&MI] = Reg;
60  } else {
61  Register Reg = GR->find(Const, &MF);
62  if (!Reg.isValid()) {
63  if (auto *ConstVec = dyn_cast<ConstantDataVector>(Const)) {
64  auto *BuildVec = MRI.getVRegDef(MI.getOperand(2).getReg());
65  assert(BuildVec &&
66  BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
67  for (unsigned i = 0; i < ConstVec->getNumElements(); ++i)
68  GR->add(ConstVec->getElementAsConstant(i), &MF,
69  BuildVec->getOperand(1 + i).getReg());
70  }
71  GR->add(Const, &MF, MI.getOperand(2).getReg());
72  } else {
73  RegsAlreadyAddedToDT[&MI] = Reg;
74  // This MI is unused and will be removed. If the MI uses
75  // const_composite, it will be unused and should be removed too.
76  assert(MI.getOperand(2).isReg() && "Reg operand is expected");
77  MachineInstr *SrcMI = MRI.getVRegDef(MI.getOperand(2).getReg());
78  if (SrcMI && isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
79  ToEraseComposites.push_back(SrcMI);
80  }
81  }
82  }
83  }
84  for (MachineInstr *MI : ToErase) {
85  Register Reg = MI->getOperand(2).getReg();
86  if (RegsAlreadyAddedToDT.find(MI) != RegsAlreadyAddedToDT.end())
87  Reg = RegsAlreadyAddedToDT[MI];
88  MRI.replaceRegWith(MI->getOperand(0).getReg(), Reg);
89  MI->eraseFromParent();
90  }
91  for (MachineInstr *MI : ToEraseComposites)
92  MI->eraseFromParent();
93 }
94 
98  const unsigned AssignNameOperandShift = 2;
99  for (MachineBasicBlock &MBB : MF) {
100  for (MachineInstr &MI : MBB) {
101  if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_name))
102  continue;
103  unsigned NumOp = MI.getNumExplicitDefs() + AssignNameOperandShift;
104  while (MI.getOperand(NumOp).isReg()) {
105  MachineOperand &MOp = MI.getOperand(NumOp);
106  MachineInstr *ConstMI = MRI.getVRegDef(MOp.getReg());
107  assert(ConstMI->getOpcode() == TargetOpcode::G_CONSTANT);
108  MI.removeOperand(NumOp);
109  MI.addOperand(MachineOperand::CreateImm(
110  ConstMI->getOperand(1).getCImm()->getZExtValue()));
111  if (MRI.use_empty(ConstMI->getOperand(0).getReg()))
112  ToErase.push_back(ConstMI);
113  }
114  }
115  }
116  for (MachineInstr *MI : ToErase)
117  MI->eraseFromParent();
118 }
119 
121  MachineIRBuilder MIB) {
123  for (MachineBasicBlock &MBB : MF) {
124  for (MachineInstr &MI : MBB) {
125  if (!isSpvIntrinsic(MI, Intrinsic::spv_bitcast))
126  continue;
127  assert(MI.getOperand(2).isReg());
128  MIB.setInsertPt(*MI.getParent(), MI);
129  MIB.buildBitcast(MI.getOperand(0).getReg(), MI.getOperand(2).getReg());
130  ToErase.push_back(&MI);
131  }
132  }
133  for (MachineInstr *MI : ToErase)
134  MI->eraseFromParent();
135 }
136 
137 // Translating GV, IRTranslator sometimes generates following IR:
138 // %1 = G_GLOBAL_VALUE
139 // %2 = COPY %1
140 // %3 = G_ADDRSPACE_CAST %2
141 // New registers have no SPIRVType and no register class info.
142 //
143 // Set SPIRVType for GV, propagate it from GV to other instructions,
144 // also set register classes.
147  MachineIRBuilder &MIB) {
148  SPIRVType *SpirvTy = nullptr;
149  assert(MI && "Machine instr is expected");
150  if (MI->getOperand(0).isReg()) {
151  Register Reg = MI->getOperand(0).getReg();
152  SpirvTy = GR->getSPIRVTypeForVReg(Reg);
153  if (!SpirvTy) {
154  switch (MI->getOpcode()) {
155  case TargetOpcode::G_CONSTANT: {
156  MIB.setInsertPt(*MI->getParent(), MI);
157  Type *Ty = MI->getOperand(1).getCImm()->getType();
158  SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
159  break;
160  }
161  case TargetOpcode::G_GLOBAL_VALUE: {
162  MIB.setInsertPt(*MI->getParent(), MI);
163  Type *Ty = MI->getOperand(1).getGlobal()->getType();
164  SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
165  break;
166  }
167  case TargetOpcode::G_TRUNC:
168  case TargetOpcode::G_ADDRSPACE_CAST:
169  case TargetOpcode::G_PTR_ADD:
170  case TargetOpcode::COPY: {
171  MachineOperand &Op = MI->getOperand(1);
172  MachineInstr *Def = Op.isReg() ? MRI.getVRegDef(Op.getReg()) : nullptr;
173  if (Def)
174  SpirvTy = propagateSPIRVType(Def, GR, MRI, MIB);
175  break;
176  }
177  default:
178  break;
179  }
180  if (SpirvTy)
181  GR->assignSPIRVTypeToVReg(SpirvTy, Reg, MIB.getMF());
182  if (!MRI.getRegClassOrNull(Reg))
183  MRI.setRegClass(Reg, &SPIRV::IDRegClass);
184  }
185  }
186  return SpirvTy;
187 }
188 
189 // Insert ASSIGN_TYPE instuction between Reg and its definition, set NewReg as
190 // a dst of the definition, assign SPIRVType to both registers. If SpirvTy is
191 // provided, use it as SPIRVType in ASSIGN_TYPE, otherwise create it from Ty.
192 // It's used also in SPIRVBuiltins.cpp.
193 // TODO: maybe move to SPIRVUtils.
194 namespace llvm {
199  assert((Ty || SpirvTy) && "Either LLVM or SPIRV type is expected.");
200  MIB.setInsertPt(*Def->getParent(),
201  (Def->getNextNode() ? Def->getNextNode()->getIterator()
202  : Def->getParent()->end()));
204  if (auto *RC = MRI.getRegClassOrNull(Reg))
205  MRI.setRegClass(NewReg, RC);
206  SpirvTy = SpirvTy ? SpirvTy : GR->getOrCreateSPIRVType(Ty, MIB);
207  GR->assignSPIRVTypeToVReg(SpirvTy, Reg, MIB.getMF());
208  // This is to make it convenient for Legalizer to get the SPIRVType
209  // when processing the actual MI (i.e. not pseudo one).
210  GR->assignSPIRVTypeToVReg(SpirvTy, NewReg, MIB.getMF());
211  // Copy MIFlags from Def to ASSIGN_TYPE instruction. It's required to keep
212  // the flags after instruction selection.
213  const uint16_t Flags = Def->getFlags();
214  MIB.buildInstr(SPIRV::ASSIGN_TYPE)
215  .addDef(Reg)
216  .addUse(NewReg)
217  .addUse(GR->getSPIRVTypeID(SpirvTy))
218  .setMIFlags(Flags);
219  Def->getOperand(0).setReg(NewReg);
220  MRI.setRegClass(Reg, &SPIRV::ANYIDRegClass);
221  return NewReg;
222 }
223 } // namespace llvm
224 
226  MachineIRBuilder MIB) {
229 
230  for (MachineBasicBlock *MBB : post_order(&MF)) {
231  if (MBB->empty())
232  continue;
233 
234  bool ReachedBegin = false;
235  for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();
236  !ReachedBegin;) {
237  MachineInstr &MI = *MII;
238 
239  if (isSpvIntrinsic(MI, Intrinsic::spv_assign_type)) {
240  Register Reg = MI.getOperand(1).getReg();
241  Type *Ty = getMDOperandAsType(MI.getOperand(2).getMetadata(), 0);
243  assert(Def && "Expecting an instruction that defines the register");
244  // G_GLOBAL_VALUE already has type info.
245  if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
246  insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
247  ToErase.push_back(&MI);
248  } else if (MI.getOpcode() == TargetOpcode::G_CONSTANT ||
249  MI.getOpcode() == TargetOpcode::G_FCONSTANT ||
250  MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
251  // %rc = G_CONSTANT ty Val
252  // ===>
253  // %cty = OpType* ty
254  // %rctmp = G_CONSTANT ty Val
255  // %rc = ASSIGN_TYPE %rctmp, %cty
256  Register Reg = MI.getOperand(0).getReg();
257  if (MRI.hasOneUse(Reg)) {
259  if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
260  isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
261  continue;
262  }
263  Type *Ty = nullptr;
264  if (MI.getOpcode() == TargetOpcode::G_CONSTANT)
265  Ty = MI.getOperand(1).getCImm()->getType();
266  else if (MI.getOpcode() == TargetOpcode::G_FCONSTANT)
267  Ty = MI.getOperand(1).getFPImm()->getType();
268  else {
269  assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
270  Type *ElemTy = nullptr;
271  MachineInstr *ElemMI = MRI.getVRegDef(MI.getOperand(1).getReg());
272  assert(ElemMI);
273 
274  if (ElemMI->getOpcode() == TargetOpcode::G_CONSTANT)
275  ElemTy = ElemMI->getOperand(1).getCImm()->getType();
276  else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT)
277  ElemTy = ElemMI->getOperand(1).getFPImm()->getType();
278  else
279  llvm_unreachable("Unexpected opcode");
280  unsigned NumElts =
281  MI.getNumExplicitOperands() - MI.getNumExplicitDefs();
282  Ty = VectorType::get(ElemTy, NumElts, false);
283  }
284  insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
285  } else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
286  MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
287  MI.getOpcode() == TargetOpcode::COPY ||
288  MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
289  propagateSPIRVType(&MI, GR, MRI, MIB);
290  }
291 
292  if (MII == Begin)
293  ReachedBegin = true;
294  else
295  --MII;
296  }
297  }
298  for (MachineInstr *MI : ToErase)
299  MI->eraseFromParent();
300 }
301 
302 static std::pair<Register, unsigned>
303 createNewIdReg(Register ValReg, unsigned Opcode, MachineRegisterInfo &MRI,
304  const SPIRVGlobalRegistry &GR) {
305  LLT NewT = LLT::scalar(32);
306  SPIRVType *SpvType = GR.getSPIRVTypeForVReg(ValReg);
307  assert(SpvType && "VReg is expected to have SPIRV type");
308  bool IsFloat = SpvType->getOpcode() == SPIRV::OpTypeFloat;
309  bool IsVectorFloat =
310  SpvType->getOpcode() == SPIRV::OpTypeVector &&
311  GR.getSPIRVTypeForVReg(SpvType->getOperand(1).getReg())->getOpcode() ==
312  SPIRV::OpTypeFloat;
313  IsFloat |= IsVectorFloat;
314  auto GetIdOp = IsFloat ? SPIRV::GET_fID : SPIRV::GET_ID;
315  auto DstClass = IsFloat ? &SPIRV::fIDRegClass : &SPIRV::IDRegClass;
316  if (MRI.getType(ValReg).isPointer()) {
317  NewT = LLT::pointer(0, 32);
318  GetIdOp = SPIRV::GET_pID;
319  DstClass = &SPIRV::pIDRegClass;
320  } else if (MRI.getType(ValReg).isVector()) {
321  NewT = LLT::fixed_vector(2, NewT);
322  GetIdOp = IsFloat ? SPIRV::GET_vfID : SPIRV::GET_vID;
323  DstClass = IsFloat ? &SPIRV::vfIDRegClass : &SPIRV::vIDRegClass;
324  }
326  MRI.setRegClass(IdReg, DstClass);
327  return {IdReg, GetIdOp};
328 }
329 
332  unsigned Opc = MI.getOpcode();
333  assert(MI.getNumDefs() > 0 && MRI.hasOneUse(MI.getOperand(0).getReg()));
334  MachineInstr &AssignTypeInst =
335  *(MRI.use_instr_begin(MI.getOperand(0).getReg()));
336  auto NewReg = createNewIdReg(MI.getOperand(0).getReg(), Opc, MRI, *GR).first;
337  AssignTypeInst.getOperand(1).setReg(NewReg);
338  MI.getOperand(0).setReg(NewReg);
339  MIB.setInsertPt(*MI.getParent(),
340  (MI.getNextNode() ? MI.getNextNode()->getIterator()
341  : MI.getParent()->end()));
342  for (auto &Op : MI.operands()) {
343  if (!Op.isReg() || Op.isDef())
344  continue;
345  auto IdOpInfo = createNewIdReg(Op.getReg(), Opc, MRI, *GR);
346  MIB.buildInstr(IdOpInfo.second).addDef(IdOpInfo.first).addUse(Op.getReg());
347  Op.setReg(IdOpInfo.first);
348  }
349 }
350 
351 // Defined in SPIRVLegalizerInfo.cpp.
352 extern bool isTypeFoldingSupported(unsigned Opcode);
353 
356  MachineIRBuilder MIB) {
358  for (MachineBasicBlock &MBB : MF) {
359  for (MachineInstr &MI : MBB) {
360  if (isTypeFoldingSupported(MI.getOpcode()))
361  processInstr(MI, MIB, MRI, GR);
362  }
363  }
364  for (MachineBasicBlock &MBB : MF) {
365  for (MachineInstr &MI : MBB) {
366  // We need to rewrite dst types for ASSIGN_TYPE instrs to be able
367  // to perform tblgen'erated selection and we can't do that on Legalizer
368  // as it operates on gMIR only.
369  if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
370  continue;
371  Register SrcReg = MI.getOperand(1).getReg();
372  unsigned Opcode = MRI.getVRegDef(SrcReg)->getOpcode();
373  if (!isTypeFoldingSupported(Opcode))
374  continue;
375  Register DstReg = MI.getOperand(0).getReg();
376  if (MRI.getType(DstReg).isVector())
377  MRI.setRegClass(DstReg, &SPIRV::IDRegClass);
378  // Don't need to reset type of register holding constant and used in
379  // G_ADDRSPACE_CAST, since it braaks legalizer.
380  if (Opcode == TargetOpcode::G_CONSTANT && MRI.hasOneUse(DstReg)) {
382  if (UseMI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST)
383  continue;
384  }
385  MRI.setType(DstReg, LLT::scalar(32));
386  }
387  }
388 }
389 
391  MachineIRBuilder MIB) {
393  SwitchRegToMBB;
395  DenseSet<Register> SwitchRegs;
397  // Before IRTranslator pass, spv_switch calls are inserted before each
398  // switch instruction. IRTranslator lowers switches to ICMP+CBr+Br triples.
399  // A switch with two cases may be translated to this MIR sequesnce:
400  // intrinsic(@llvm.spv.switch), %CmpReg, %Const0, %Const1
401  // %Dst0 = G_ICMP intpred(eq), %CmpReg, %Const0
402  // G_BRCOND %Dst0, %bb.2
403  // G_BR %bb.5
404  // bb.5.entry:
405  // %Dst1 = G_ICMP intpred(eq), %CmpReg, %Const1
406  // G_BRCOND %Dst1, %bb.3
407  // G_BR %bb.4
408  // bb.2.sw.bb:
409  // ...
410  // bb.3.sw.bb1:
411  // ...
412  // bb.4.sw.epilog:
413  // ...
414  // Walk MIs and collect information about destination MBBs to update
415  // spv_switch call. We assume that all spv_switch precede corresponding ICMPs.
416  for (MachineBasicBlock &MBB : MF) {
417  for (MachineInstr &MI : MBB) {
418  if (isSpvIntrinsic(MI, Intrinsic::spv_switch)) {
419  assert(MI.getOperand(1).isReg());
420  Register Reg = MI.getOperand(1).getReg();
421  SwitchRegs.insert(Reg);
422  // Set the first successor as default MBB to support empty switches.
423  DefaultMBBs[Reg] = *MBB.succ_begin();
424  }
425  // Process G_SUB coming from switch range-compare lowering.
426  if (MI.getOpcode() == TargetOpcode::G_SUB && MI.getOperand(1).isReg() &&
427  SwitchRegs.contains(MI.getOperand(1).getReg())) {
428  assert(MI.getOperand(0).isReg() && MI.getOperand(1).isReg());
429  Register Dst = MI.getOperand(0).getReg();
430  SwitchRegs.insert(Dst);
431  SPIRVType *Ty = GR->getSPIRVTypeForVReg(MI.getOperand(1).getReg());
432  insertAssignInstr(Dst, nullptr, Ty, GR, MIB, MRI);
433  }
434  // Process only ICMPs that relate to spv_switches.
435  if (MI.getOpcode() == TargetOpcode::G_ICMP && MI.getOperand(2).isReg() &&
436  SwitchRegs.contains(MI.getOperand(2).getReg())) {
437  assert(MI.getOperand(0).isReg() && MI.getOperand(1).isPredicate() &&
438  MI.getOperand(3).isReg());
439  Register Dst = MI.getOperand(0).getReg();
440  // Set type info for destination register of switch's ICMP instruction.
441  if (GR->getSPIRVTypeForVReg(Dst) == nullptr) {
442  MIB.setInsertPt(*MI.getParent(), MI);
443  Type *LLVMTy = IntegerType::get(MF.getFunction().getContext(), 1);
444  SPIRVType *SpirvTy = GR->getOrCreateSPIRVType(LLVMTy, MIB);
445  MRI.setRegClass(Dst, &SPIRV::IDRegClass);
446  GR->assignSPIRVTypeToVReg(SpirvTy, Dst, MIB.getMF());
447  }
448  Register CmpReg = MI.getOperand(2).getReg();
449  MachineOperand &PredOp = MI.getOperand(1);
450  const auto CC = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
452  MRI.hasOneUse(Dst) && MRI.hasOneDef(CmpReg));
453  uint64_t Val = getIConstVal(MI.getOperand(3).getReg(), &MRI);
454  MachineInstr *CBr = MRI.use_begin(Dst)->getParent();
455  assert(CBr->getOpcode() == SPIRV::G_BRCOND &&
456  CBr->getOperand(1).isMBB());
457  SwitchRegToMBB[CmpReg][Val] = CBr->getOperand(1).getMBB();
458  // The next MI is always BR to either the next case or the default.
459  MachineInstr *NextMI = CBr->getNextNode();
460  assert(NextMI->getOpcode() == SPIRV::G_BR &&
461  NextMI->getOperand(0).isMBB());
462  MachineBasicBlock *NextMBB = NextMI->getOperand(0).getMBB();
463  assert(NextMBB != nullptr);
464  // The default MBB is not started by ICMP with switch's cmp register.
465  if (NextMBB->front().getOpcode() != SPIRV::G_ICMP ||
466  (NextMBB->front().getOperand(2).isReg() &&
467  NextMBB->front().getOperand(2).getReg() != CmpReg))
468  DefaultMBBs[CmpReg] = NextMBB;
469  }
470  }
471  }
472  // Modify spv_switch's operands by collected values. For the example above,
473  // the result will be like this:
474  // intrinsic(@llvm.spv.switch), %CmpReg, %bb.4, i32 0, %bb.2, i32 1, %bb.3
475  // Note that ICMP+CBr+Br sequences are not removed, but ModuleAnalysis marks
476  // them as skipped and AsmPrinter does not output them.
477  for (MachineBasicBlock &MBB : MF) {
478  for (MachineInstr &MI : MBB) {
479  if (!isSpvIntrinsic(MI, Intrinsic::spv_switch))
480  continue;
481  assert(MI.getOperand(1).isReg());
482  Register Reg = MI.getOperand(1).getReg();
483  unsigned NumOp = MI.getNumExplicitOperands();
486  for (unsigned i = 2; i < NumOp; i++) {
487  Register CReg = MI.getOperand(i).getReg();
488  uint64_t Val = getIConstVal(CReg, &MRI);
489  MachineInstr *ConstInstr = getDefInstrMaybeConstant(CReg, &MRI);
490  if (!SwitchRegToMBB[Reg][Val])
491  continue;
492  Vals.push_back(ConstInstr->getOperand(1).getCImm());
493  MBBs.push_back(SwitchRegToMBB[Reg][Val]);
494  }
495  for (unsigned i = MI.getNumExplicitOperands() - 1; i > 1; i--)
496  MI.removeOperand(i);
497  MI.addOperand(MachineOperand::CreateMBB(DefaultMBBs[Reg]));
498  for (unsigned i = 0; i < Vals.size(); i++) {
499  MI.addOperand(MachineOperand::CreateCImm(Vals[i]));
500  MI.addOperand(MachineOperand::CreateMBB(MBBs[i]));
501  }
502  }
503  }
504 }
505 
506 bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
507  // Initialize the type registry.
509  SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
510  GR->setCurrentFunc(MF);
511  MachineIRBuilder MIB(MF);
512  addConstantsToTrack(MF, GR);
514  insertBitcasts(MF, GR, MIB);
515  generateAssignInstrs(MF, GR, MIB);
516  processSwitches(MF, GR, MIB);
517  processInstrsWithTypeFolding(MF, GR, MIB);
518 
519  return true;
520 }
521 
522 INITIALIZE_PASS(SPIRVPreLegalizer, DEBUG_TYPE, "SPIRV pre legalizer", false,
523  false)
524 
525 char SPIRVPreLegalizer::ID = 0;
526 
528  return new SPIRVPreLegalizer();
529 }
i
i
Definition: README.txt:29
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
llvm::CmpInst::ICMP_EQ
@ ICMP_EQ
equal
Definition: InstrTypes.h:740
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:107
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:719
llvm::ConstantInt::getType
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
Definition: Constants.h:173
DebugInfoMetadata.h
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::ilist_node_with_parent::getNextNode
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:289
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
DEBUG_TYPE
#define DEBUG_TYPE
Definition: SPIRVPreLegalizer.cpp:26
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
OptimizationRemarkEmitter.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::SPIRVGlobalRegistry::assignSPIRVTypeToVReg
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, MachineFunction &MF)
Definition: SPIRVGlobalRegistry.cpp:56
llvm::SPIRVSubtarget
Definition: SPIRVSubtarget.h:35
addConstantsToTrack
static void addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR)
Definition: SPIRVPreLegalizer.cpp:41
SPIRVSubtarget.h
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::SPIRVGlobalRegistry::getSPIRVTypeForVReg
SPIRVType * getSPIRVTypeForVReg(Register VReg) const
Definition: SPIRVGlobalRegistry.cpp:734
llvm::LLT::fixed_vector
static LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelTypeImpl.h:74
llvm::MachineInstrBuilder::addDef
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Definition: MachineInstrBuilder.h:116
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
Constants.h
llvm::MachineRegisterInfo::setType
void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
Definition: MachineRegisterInfo.cpp:180
llvm::MachineOperand::CreateImm
static MachineOperand CreateImm(int64_t Val)
Definition: MachineOperand.h:782
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
llvm::CmpInst::ICMP_ULE
@ ICMP_ULE
unsigned less or equal
Definition: InstrTypes.h:745
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:37
llvm::MachineOperand::isMBB
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
Definition: MachineOperand.h:328
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:271
SPIRVUtils.h
generateAssignInstrs
static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition: SPIRVPreLegalizer.cpp:225
createNewIdReg
static std::pair< Register, unsigned > createNewIdReg(Register ValReg, unsigned Opcode, MachineRegisterInfo &MRI, const SPIRVGlobalRegistry &GR)
Definition: SPIRVPreLegalizer.cpp:303
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:396
llvm::MachineOperand::getParent
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Definition: MachineOperand.h:237
llvm::MachineRegisterInfo::use_empty
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
Definition: MachineRegisterInfo.h:514
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::getMDOperandAsType
Type * getMDOperandAsType(const MDNode *N, unsigned I)
Definition: SPIRVUtils.cpp:239
processInstrsWithTypeFolding
static void processInstrsWithTypeFolding(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition: SPIRVPreLegalizer.cpp:354
llvm::LLT::pointer
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelTypeImpl.h:49
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::MachineIRBuilder::setInsertPt
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
Definition: MachineIRBuilder.h:315
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:221
llvm::SPIRVGlobalRegistry::add
void add(const Constant *C, MachineFunction *MF, Register R)
Definition: SPIRVGlobalRegistry.h:71
llvm::getIConstVal
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
Definition: SPIRVUtils.cpp:228
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineOperand::getCImm
const ConstantInt * getCImm() const
Definition: MachineOperand.h:551
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
llvm::MachineOperand::CreateMBB
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
Definition: MachineOperand.h:825
propagateSPIRVType
static SPIRVType * propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, MachineRegisterInfo &MRI, MachineIRBuilder &MIB)
Definition: SPIRVPreLegalizer.cpp:145
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::MachineRegisterInfo::use_instr_begin
use_instr_iterator use_instr_begin(Register RegNo) const
Definition: MachineRegisterInfo.h:485
llvm::MachineIRBuilder::buildBitcast
MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_BITCAST Src.
Definition: MachineIRBuilder.h:677
llvm::DenseMap
Definition: DenseMap.h:714
insertBitcasts
static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition: SPIRVPreLegalizer.cpp:120
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:122
llvm::MachineOperand::getFPImm
const ConstantFP * getFPImm() const
Definition: MachineOperand.h:556
llvm::MachineOperand::getPredicate
unsigned getPredicate() const
Definition: MachineOperand.h:597
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
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
SPIRV.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LLT::isPointer
bool isPointer() const
Definition: LowLevelTypeImpl.h:120
llvm::getDefInstrMaybeConstant
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
Definition: SPIRVUtils.cpp:214
llvm::MachineBasicBlock::succ_begin
succ_iterator succ_begin()
Definition: MachineBasicBlock.h:369
llvm::MachineRegisterInfo::createGenericVirtualRegister
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Definition: MachineRegisterInfo.cpp:186
llvm::SPIRVGlobalRegistry
Definition: SPIRVGlobalRegistry.h:27
llvm::MachineInstrBuilder::addUse
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Definition: MachineInstrBuilder.h:123
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MachineRegisterInfo::hasOneDef
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
Definition: MachineRegisterInfo.h:452
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::initializeSPIRVPreLegalizerPass
void initializeSPIRVPreLegalizerPass(PassRegistry &)
llvm::MachineIRBuilder::buildInstr
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.h:383
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:561
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::MachineRegisterInfo::use_begin
use_iterator use_begin(Register RegNo) const
Definition: MachineRegisterInfo.h:472
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::contains
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
llvm::MachineOperand::CreateCImm
static MachineOperand CreateCImm(const ConstantInt *CI)
Definition: MachineOperand.h:788
llvm::SPIRVGlobalRegistry::getSPIRVTypeID
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
Definition: SPIRVGlobalRegistry.cpp:632
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ConstantInt::getZExtValue
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:142
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
Attributes.h
llvm::createSPIRVPreLegalizerPass
FunctionPass * createSPIRVPreLegalizerPass()
llvm::insertAssignInstr
Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Helper external function for inserting ASSIGN_TYPE instuction between Reg and its definition,...
Definition: SPIRVPreLegalizer.cpp:195
processInstr
static void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)
Definition: SPIRVPreLegalizer.cpp:330
uint16_t
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::post_order
iterator_range< po_iterator< T > > post_order(const T &G)
Definition: PostOrderIterator.h:189
llvm::MachineBasicBlock::front
MachineInstr & front()
Definition: MachineBasicBlock.h:284
llvm::SPIRVGlobalRegistry::find
Register find(const Constant *C, MachineFunction *MF)
Definition: SPIRVGlobalRegistry.h:87
PostOrderIterator.h
llvm::MachineRegisterInfo::hasOneUse
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
Definition: MachineRegisterInfo.h:518
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:305
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:745
TargetIntrinsicInfo.h
llvm::MachineInstrBuilder::setMIFlags
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Definition: MachineInstrBuilder.h:273
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:56
llvm::MachineBasicBlock::empty
bool empty() const
Definition: MachineBasicBlock.h:277
foldConstantsIntoIntrinsics
static void foldConstantsIntoIntrinsics(MachineFunction &MF)
Definition: SPIRVPreLegalizer.cpp:95
llvm::IntegerType::get
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:311
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::isSpvIntrinsic
bool isSpvIntrinsic(MachineInstr &MI, Intrinsic::ID IntrinsicID)
Definition: SPIRVUtils.cpp:234
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:42
llvm::VectorType::get
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:668
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:307
llvm::MachineRegisterInfo::setRegClass
void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
Definition: MachineRegisterInfo.cpp:56
isTypeFoldingSupported
bool isTypeFoldingSupported(unsigned Opcode)
Definition: SPIRVLegalizerInfo.cpp:53
processSwitches
static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition: SPIRVPreLegalizer.cpp:390
llvm::LLT
Definition: LowLevelTypeImpl.h:39
llvm::SPIRVGlobalRegistry::getOrCreateSPIRVType
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
Definition: SPIRVGlobalRegistry.cpp:744