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 "SPIRVGlobalRegistry.h"
17 #include "SPIRVSubtarget.h"
18 #include "SPIRVUtils.h"
19 #include "llvm/ADT/PostOrderIterator.h"
20 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
21 #include "llvm/IR/Attributes.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/DebugInfoMetadata.h"
24 #include "llvm/IR/IntrinsicsSPIRV.h"
25 #include "llvm/Target/TargetIntrinsicInfo.h"
26 
27 #define DEBUG_TYPE "spirv-prelegalizer"
28 
29 using namespace llvm;
30 
31 namespace {
32 class SPIRVPreLegalizer : public MachineFunctionPass {
33 public:
34   static char ID;
35   SPIRVPreLegalizer() : MachineFunctionPass(ID) {
36     initializeSPIRVPreLegalizerPass(*PassRegistry::getPassRegistry());
37   }
38   bool runOnMachineFunction(MachineFunction &MF) override;
39 };
40 } // namespace
41 
42 static void addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR) {
43   MachineRegisterInfo &MRI = MF.getRegInfo();
44   DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
45   SmallVector<MachineInstr *, 10> ToErase, ToEraseComposites;
46   for (MachineBasicBlock &MBB : MF) {
47     for (MachineInstr &MI : MBB) {
48       if (!isSpvIntrinsic(MI, Intrinsic::spv_track_constant))
49         continue;
50       ToErase.push_back(&MI);
51       auto *Const =
52           cast<Constant>(cast<ConstantAsMetadata>(
53                              MI.getOperand(3).getMetadata()->getOperand(0))
54                              ->getValue());
55       if (auto *GV = dyn_cast<GlobalValue>(Const)) {
56         Register Reg = GR->find(GV, &MF);
57         if (!Reg.isValid())
58           GR->add(GV, &MF, MI.getOperand(2).getReg());
59         else
60           RegsAlreadyAddedToDT[&MI] = Reg;
61       } else {
62         Register Reg = GR->find(Const, &MF);
63         if (!Reg.isValid()) {
64           if (auto *ConstVec = dyn_cast<ConstantDataVector>(Const)) {
65             auto *BuildVec = MRI.getVRegDef(MI.getOperand(2).getReg());
66             assert(BuildVec &&
67                    BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
68             for (unsigned i = 0; i < ConstVec->getNumElements(); ++i)
69               GR->add(ConstVec->getElementAsConstant(i), &MF,
70                       BuildVec->getOperand(1 + i).getReg());
71           }
72           GR->add(Const, &MF, MI.getOperand(2).getReg());
73         } else {
74           RegsAlreadyAddedToDT[&MI] = Reg;
75           // This MI is unused and will be removed. If the MI uses
76           // const_composite, it will be unused and should be removed too.
77           assert(MI.getOperand(2).isReg() && "Reg operand is expected");
78           MachineInstr *SrcMI = MRI.getVRegDef(MI.getOperand(2).getReg());
79           if (SrcMI && isSpvIntrinsic(*SrcMI, Intrinsic::spv_const_composite))
80             ToEraseComposites.push_back(SrcMI);
81         }
82       }
83     }
84   }
85   for (MachineInstr *MI : ToErase) {
86     Register Reg = MI->getOperand(2).getReg();
87     if (RegsAlreadyAddedToDT.find(MI) != RegsAlreadyAddedToDT.end())
88       Reg = RegsAlreadyAddedToDT[MI];
89     MRI.replaceRegWith(MI->getOperand(0).getReg(), Reg);
90     MI->eraseFromParent();
91   }
92   for (MachineInstr *MI : ToEraseComposites)
93     MI->eraseFromParent();
94 }
95 
96 static void foldConstantsIntoIntrinsics(MachineFunction &MF) {
97   SmallVector<MachineInstr *, 10> ToErase;
98   MachineRegisterInfo &MRI = MF.getRegInfo();
99   const unsigned AssignNameOperandShift = 2;
100   for (MachineBasicBlock &MBB : MF) {
101     for (MachineInstr &MI : MBB) {
102       if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_name))
103         continue;
104       unsigned NumOp = MI.getNumExplicitDefs() + AssignNameOperandShift;
105       while (MI.getOperand(NumOp).isReg()) {
106         MachineOperand &MOp = MI.getOperand(NumOp);
107         MachineInstr *ConstMI = MRI.getVRegDef(MOp.getReg());
108         assert(ConstMI->getOpcode() == TargetOpcode::G_CONSTANT);
109         MI.removeOperand(NumOp);
110         MI.addOperand(MachineOperand::CreateImm(
111             ConstMI->getOperand(1).getCImm()->getZExtValue()));
112         if (MRI.use_empty(ConstMI->getOperand(0).getReg()))
113           ToErase.push_back(ConstMI);
114       }
115     }
116   }
117   for (MachineInstr *MI : ToErase)
118     MI->eraseFromParent();
119 }
120 
121 static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
122                            MachineIRBuilder MIB) {
123   SmallVector<MachineInstr *, 10> ToErase;
124   for (MachineBasicBlock &MBB : MF) {
125     for (MachineInstr &MI : MBB) {
126       if (!isSpvIntrinsic(MI, Intrinsic::spv_bitcast))
127         continue;
128       assert(MI.getOperand(2).isReg());
129       MIB.setInsertPt(*MI.getParent(), MI);
130       MIB.buildBitcast(MI.getOperand(0).getReg(), MI.getOperand(2).getReg());
131       ToErase.push_back(&MI);
132     }
133   }
134   for (MachineInstr *MI : ToErase)
135     MI->eraseFromParent();
136 }
137 
138 // Translating GV, IRTranslator sometimes generates following IR:
139 //   %1 = G_GLOBAL_VALUE
140 //   %2 = COPY %1
141 //   %3 = G_ADDRSPACE_CAST %2
142 // New registers have no SPIRVType and no register class info.
143 //
144 // Set SPIRVType for GV, propagate it from GV to other instructions,
145 // also set register classes.
146 static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR,
147                                      MachineRegisterInfo &MRI,
148                                      MachineIRBuilder &MIB) {
149   SPIRVType *SpirvTy = nullptr;
150   assert(MI && "Machine instr is expected");
151   if (MI->getOperand(0).isReg()) {
152     Register Reg = MI->getOperand(0).getReg();
153     SpirvTy = GR->getSPIRVTypeForVReg(Reg);
154     if (!SpirvTy) {
155       switch (MI->getOpcode()) {
156       case TargetOpcode::G_CONSTANT: {
157         MIB.setInsertPt(*MI->getParent(), MI);
158         Type *Ty = MI->getOperand(1).getCImm()->getType();
159         SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
160         break;
161       }
162       case TargetOpcode::G_GLOBAL_VALUE: {
163         MIB.setInsertPt(*MI->getParent(), MI);
164         Type *Ty = MI->getOperand(1).getGlobal()->getType();
165         SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
166         break;
167       }
168       case TargetOpcode::G_TRUNC:
169       case TargetOpcode::G_ADDRSPACE_CAST:
170       case TargetOpcode::G_PTR_ADD:
171       case TargetOpcode::COPY: {
172         MachineOperand &Op = MI->getOperand(1);
173         MachineInstr *Def = Op.isReg() ? MRI.getVRegDef(Op.getReg()) : nullptr;
174         if (Def)
175           SpirvTy = propagateSPIRVType(Def, GR, MRI, MIB);
176         break;
177       }
178       default:
179         break;
180       }
181       if (SpirvTy)
182         GR->assignSPIRVTypeToVReg(SpirvTy, Reg, MIB.getMF());
183       if (!MRI.getRegClassOrNull(Reg))
184         MRI.setRegClass(Reg, &SPIRV::IDRegClass);
185     }
186   }
187   return SpirvTy;
188 }
189 
190 // Insert ASSIGN_TYPE instuction between Reg and its definition, set NewReg as
191 // a dst of the definition, assign SPIRVType to both registers. If SpirvTy is
192 // provided, use it as SPIRVType in ASSIGN_TYPE, otherwise create it from Ty.
193 // TODO: maybe move to SPIRVUtils.
194 static Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
195                                   SPIRVGlobalRegistry *GR,
196                                   MachineIRBuilder &MIB,
197                                   MachineRegisterInfo &MRI) {
198   MachineInstr *Def = MRI.getVRegDef(Reg);
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()));
203   Register NewReg = MRI.createGenericVirtualRegister(MRI.getType(Reg));
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   MIB.buildInstr(SPIRV::ASSIGN_TYPE)
212       .addDef(Reg)
213       .addUse(NewReg)
214       .addUse(GR->getSPIRVTypeID(SpirvTy));
215   Def->getOperand(0).setReg(NewReg);
216   MRI.setRegClass(Reg, &SPIRV::ANYIDRegClass);
217   return NewReg;
218 }
219 
220 static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
221                                  MachineIRBuilder MIB) {
222   MachineRegisterInfo &MRI = MF.getRegInfo();
223   SmallVector<MachineInstr *, 10> ToErase;
224 
225   for (MachineBasicBlock *MBB : post_order(&MF)) {
226     if (MBB->empty())
227       continue;
228 
229     bool ReachedBegin = false;
230     for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();
231          !ReachedBegin;) {
232       MachineInstr &MI = *MII;
233 
234       if (isSpvIntrinsic(MI, Intrinsic::spv_assign_type)) {
235         Register Reg = MI.getOperand(1).getReg();
236         Type *Ty = getMDOperandAsType(MI.getOperand(2).getMetadata(), 0);
237         MachineInstr *Def = MRI.getVRegDef(Reg);
238         assert(Def && "Expecting an instruction that defines the register");
239         // G_GLOBAL_VALUE already has type info.
240         if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
241           insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
242         ToErase.push_back(&MI);
243       } else if (MI.getOpcode() == TargetOpcode::G_CONSTANT ||
244                  MI.getOpcode() == TargetOpcode::G_FCONSTANT ||
245                  MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
246         // %rc = G_CONSTANT ty Val
247         // ===>
248         // %cty = OpType* ty
249         // %rctmp = G_CONSTANT ty Val
250         // %rc = ASSIGN_TYPE %rctmp, %cty
251         Register Reg = MI.getOperand(0).getReg();
252         if (MRI.hasOneUse(Reg)) {
253           MachineInstr &UseMI = *MRI.use_instr_begin(Reg);
254           if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
255               isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
256             continue;
257         }
258         Type *Ty = nullptr;
259         if (MI.getOpcode() == TargetOpcode::G_CONSTANT)
260           Ty = MI.getOperand(1).getCImm()->getType();
261         else if (MI.getOpcode() == TargetOpcode::G_FCONSTANT)
262           Ty = MI.getOperand(1).getFPImm()->getType();
263         else {
264           assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
265           Type *ElemTy = nullptr;
266           MachineInstr *ElemMI = MRI.getVRegDef(MI.getOperand(1).getReg());
267           assert(ElemMI);
268 
269           if (ElemMI->getOpcode() == TargetOpcode::G_CONSTANT)
270             ElemTy = ElemMI->getOperand(1).getCImm()->getType();
271           else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT)
272             ElemTy = ElemMI->getOperand(1).getFPImm()->getType();
273           else
274             llvm_unreachable("Unexpected opcode");
275           unsigned NumElts =
276               MI.getNumExplicitOperands() - MI.getNumExplicitDefs();
277           Ty = VectorType::get(ElemTy, NumElts, false);
278         }
279         insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
280       } else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
281                  MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
282                  MI.getOpcode() == TargetOpcode::COPY ||
283                  MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
284         propagateSPIRVType(&MI, GR, MRI, MIB);
285       }
286 
287       if (MII == Begin)
288         ReachedBegin = true;
289       else
290         --MII;
291     }
292   }
293   for (MachineInstr *MI : ToErase)
294     MI->eraseFromParent();
295 }
296 
297 static std::pair<Register, unsigned>
298 createNewIdReg(Register ValReg, unsigned Opcode, MachineRegisterInfo &MRI,
299                const SPIRVGlobalRegistry &GR) {
300   LLT NewT = LLT::scalar(32);
301   SPIRVType *SpvType = GR.getSPIRVTypeForVReg(ValReg);
302   assert(SpvType && "VReg is expected to have SPIRV type");
303   bool IsFloat = SpvType->getOpcode() == SPIRV::OpTypeFloat;
304   bool IsVectorFloat =
305       SpvType->getOpcode() == SPIRV::OpTypeVector &&
306       GR.getSPIRVTypeForVReg(SpvType->getOperand(1).getReg())->getOpcode() ==
307           SPIRV::OpTypeFloat;
308   IsFloat |= IsVectorFloat;
309   auto GetIdOp = IsFloat ? SPIRV::GET_fID : SPIRV::GET_ID;
310   auto DstClass = IsFloat ? &SPIRV::fIDRegClass : &SPIRV::IDRegClass;
311   if (MRI.getType(ValReg).isPointer()) {
312     NewT = LLT::pointer(0, 32);
313     GetIdOp = SPIRV::GET_pID;
314     DstClass = &SPIRV::pIDRegClass;
315   } else if (MRI.getType(ValReg).isVector()) {
316     NewT = LLT::fixed_vector(2, NewT);
317     GetIdOp = IsFloat ? SPIRV::GET_vfID : SPIRV::GET_vID;
318     DstClass = IsFloat ? &SPIRV::vfIDRegClass : &SPIRV::vIDRegClass;
319   }
320   Register IdReg = MRI.createGenericVirtualRegister(NewT);
321   MRI.setRegClass(IdReg, DstClass);
322   return {IdReg, GetIdOp};
323 }
324 
325 static void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
326                          MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
327   unsigned Opc = MI.getOpcode();
328   assert(MI.getNumDefs() > 0 && MRI.hasOneUse(MI.getOperand(0).getReg()));
329   MachineInstr &AssignTypeInst =
330       *(MRI.use_instr_begin(MI.getOperand(0).getReg()));
331   auto NewReg = createNewIdReg(MI.getOperand(0).getReg(), Opc, MRI, *GR).first;
332   AssignTypeInst.getOperand(1).setReg(NewReg);
333   MI.getOperand(0).setReg(NewReg);
334   MIB.setInsertPt(*MI.getParent(),
335                   (MI.getNextNode() ? MI.getNextNode()->getIterator()
336                                     : MI.getParent()->end()));
337   for (auto &Op : MI.operands()) {
338     if (!Op.isReg() || Op.isDef())
339       continue;
340     auto IdOpInfo = createNewIdReg(Op.getReg(), Opc, MRI, *GR);
341     MIB.buildInstr(IdOpInfo.second).addDef(IdOpInfo.first).addUse(Op.getReg());
342     Op.setReg(IdOpInfo.first);
343   }
344 }
345 
346 // Defined in SPIRVLegalizerInfo.cpp.
347 extern bool isTypeFoldingSupported(unsigned Opcode);
348 
349 static void processInstrsWithTypeFolding(MachineFunction &MF,
350                                          SPIRVGlobalRegistry *GR,
351                                          MachineIRBuilder MIB) {
352   MachineRegisterInfo &MRI = MF.getRegInfo();
353   for (MachineBasicBlock &MBB : MF) {
354     for (MachineInstr &MI : MBB) {
355       if (isTypeFoldingSupported(MI.getOpcode()))
356         processInstr(MI, MIB, MRI, GR);
357     }
358   }
359   for (MachineBasicBlock &MBB : MF) {
360     for (MachineInstr &MI : MBB) {
361       // We need to rewrite dst types for ASSIGN_TYPE instrs to be able
362       // to perform tblgen'erated selection and we can't do that on Legalizer
363       // as it operates on gMIR only.
364       if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
365         continue;
366       Register SrcReg = MI.getOperand(1).getReg();
367       if (!isTypeFoldingSupported(MRI.getVRegDef(SrcReg)->getOpcode()))
368         continue;
369       Register DstReg = MI.getOperand(0).getReg();
370       if (MRI.getType(DstReg).isVector())
371         MRI.setRegClass(DstReg, &SPIRV::IDRegClass);
372       MRI.setType(DstReg, LLT::scalar(32));
373     }
374   }
375 }
376 
377 static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR,
378                             MachineIRBuilder MIB) {
379   DenseMap<Register, SmallDenseMap<uint64_t, MachineBasicBlock *>>
380       SwitchRegToMBB;
381   DenseMap<Register, MachineBasicBlock *> DefaultMBBs;
382   DenseSet<Register> SwitchRegs;
383   MachineRegisterInfo &MRI = MF.getRegInfo();
384   // Before IRTranslator pass, spv_switch calls are inserted before each
385   // switch instruction. IRTranslator lowers switches to ICMP+CBr+Br triples.
386   // A switch with two cases may be translated to this MIR sequesnce:
387   //   intrinsic(@llvm.spv.switch), %CmpReg, %Const0, %Const1
388   //   %Dst0 = G_ICMP intpred(eq), %CmpReg, %Const0
389   //   G_BRCOND %Dst0, %bb.2
390   //   G_BR %bb.5
391   // bb.5.entry:
392   //   %Dst1 = G_ICMP intpred(eq), %CmpReg, %Const1
393   //   G_BRCOND %Dst1, %bb.3
394   //   G_BR %bb.4
395   // bb.2.sw.bb:
396   //   ...
397   // bb.3.sw.bb1:
398   //   ...
399   // bb.4.sw.epilog:
400   //   ...
401   // Walk MIs and collect information about destination MBBs to update
402   // spv_switch call. We assume that all spv_switch precede corresponding ICMPs.
403   for (MachineBasicBlock &MBB : MF) {
404     for (MachineInstr &MI : MBB) {
405       if (isSpvIntrinsic(MI, Intrinsic::spv_switch)) {
406         assert(MI.getOperand(1).isReg());
407         Register Reg = MI.getOperand(1).getReg();
408         SwitchRegs.insert(Reg);
409         // Set the first successor as default MBB to support empty switches.
410         DefaultMBBs[Reg] = *MBB.succ_begin();
411       }
412       // Process only ICMPs that relate to spv_switches.
413       if (MI.getOpcode() == TargetOpcode::G_ICMP && MI.getOperand(2).isReg() &&
414           SwitchRegs.contains(MI.getOperand(2).getReg())) {
415         assert(MI.getOperand(0).isReg() && MI.getOperand(1).isPredicate() &&
416                MI.getOperand(3).isReg());
417         Register Dst = MI.getOperand(0).getReg();
418         // Set type info for destination register of switch's ICMP instruction.
419         if (GR->getSPIRVTypeForVReg(Dst) == nullptr) {
420           MIB.setInsertPt(*MI.getParent(), MI);
421           Type *LLVMTy = IntegerType::get(MF.getFunction().getContext(), 1);
422           SPIRVType *SpirvTy = GR->getOrCreateSPIRVType(LLVMTy, MIB);
423           MRI.setRegClass(Dst, &SPIRV::IDRegClass);
424           GR->assignSPIRVTypeToVReg(SpirvTy, Dst, MIB.getMF());
425         }
426         Register CmpReg = MI.getOperand(2).getReg();
427         MachineOperand &PredOp = MI.getOperand(1);
428         const auto CC = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
429         assert(CC == CmpInst::ICMP_EQ && MRI.hasOneUse(Dst) &&
430                MRI.hasOneDef(CmpReg));
431         uint64_t Val = getIConstVal(MI.getOperand(3).getReg(), &MRI);
432         MachineInstr *CBr = MRI.use_begin(Dst)->getParent();
433         assert(CBr->getOpcode() == SPIRV::G_BRCOND &&
434                CBr->getOperand(1).isMBB());
435         SwitchRegToMBB[CmpReg][Val] = CBr->getOperand(1).getMBB();
436         // The next MI is always BR to either the next case or the default.
437         MachineInstr *NextMI = CBr->getNextNode();
438         assert(NextMI->getOpcode() == SPIRV::G_BR &&
439                NextMI->getOperand(0).isMBB());
440         MachineBasicBlock *NextMBB = NextMI->getOperand(0).getMBB();
441         assert(NextMBB != nullptr);
442         // The default MBB is not started by ICMP with switch's cmp register.
443         if (NextMBB->front().getOpcode() != SPIRV::G_ICMP ||
444             (NextMBB->front().getOperand(2).isReg() &&
445              NextMBB->front().getOperand(2).getReg() != CmpReg))
446           DefaultMBBs[CmpReg] = NextMBB;
447       }
448     }
449   }
450   // Modify spv_switch's operands by collected values. For the example above,
451   // the result will be like this:
452   //   intrinsic(@llvm.spv.switch), %CmpReg, %bb.4, i32 0, %bb.2, i32 1, %bb.3
453   // Note that ICMP+CBr+Br sequences are not removed, but ModuleAnalysis marks
454   // them as skipped and AsmPrinter does not output them.
455   for (MachineBasicBlock &MBB : MF) {
456     for (MachineInstr &MI : MBB) {
457       if (!isSpvIntrinsic(MI, Intrinsic::spv_switch))
458         continue;
459       assert(MI.getOperand(1).isReg());
460       Register Reg = MI.getOperand(1).getReg();
461       unsigned NumOp = MI.getNumExplicitOperands();
462       SmallVector<const ConstantInt *, 3> Vals;
463       SmallVector<MachineBasicBlock *, 3> MBBs;
464       for (unsigned i = 2; i < NumOp; i++) {
465         Register CReg = MI.getOperand(i).getReg();
466         uint64_t Val = getIConstVal(CReg, &MRI);
467         MachineInstr *ConstInstr = getDefInstrMaybeConstant(CReg, &MRI);
468         Vals.push_back(ConstInstr->getOperand(1).getCImm());
469         MBBs.push_back(SwitchRegToMBB[Reg][Val]);
470       }
471       for (unsigned i = MI.getNumExplicitOperands() - 1; i > 1; i--)
472         MI.removeOperand(i);
473       MI.addOperand(MachineOperand::CreateMBB(DefaultMBBs[Reg]));
474       for (unsigned i = 0; i < Vals.size(); i++) {
475         MI.addOperand(MachineOperand::CreateCImm(Vals[i]));
476         MI.addOperand(MachineOperand::CreateMBB(MBBs[i]));
477       }
478     }
479   }
480 }
481 
482 bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
483   // Initialize the type registry.
484   const SPIRVSubtarget &ST = MF.getSubtarget<SPIRVSubtarget>();
485   SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
486   GR->setCurrentFunc(MF);
487   MachineIRBuilder MIB(MF);
488   addConstantsToTrack(MF, GR);
489   foldConstantsIntoIntrinsics(MF);
490   insertBitcasts(MF, GR, MIB);
491   generateAssignInstrs(MF, GR, MIB);
492   processInstrsWithTypeFolding(MF, GR, MIB);
493   processSwitches(MF, GR, MIB);
494 
495   return true;
496 }
497 
498 INITIALIZE_PASS(SPIRVPreLegalizer, DEBUG_TYPE, "SPIRV pre legalizer", false,
499                 false)
500 
501 char SPIRVPreLegalizer::ID = 0;
502 
503 FunctionPass *llvm::createSPIRVPreLegalizerPass() {
504   return new SPIRVPreLegalizer();
505 }
506