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