27#include "llvm/IR/IntrinsicsSPIRV.h"
30#define DEBUG_TYPE "spirv-isel"
33namespace CL = SPIRV::OpenCLExtInst;
34namespace GL = SPIRV::GLSLExtInst;
37 std::vector<std::pair<SPIRV::InstructionSet::InstructionSet, uint32_t>>;
41#define GET_GLOBALISEL_PREDICATE_BITSET
42#include "SPIRVGenGlobalISel.inc"
43#undef GET_GLOBALISEL_PREDICATE_BITSET
64#define GET_GLOBALISEL_PREDICATES_DECL
65#include "SPIRVGenGlobalISel.inc"
66#undef GET_GLOBALISEL_PREDICATES_DECL
68#define GET_GLOBALISEL_TEMPORARIES_DECL
69#include "SPIRVGenGlobalISel.inc"
70#undef GET_GLOBALISEL_TEMPORARIES_DECL
87 unsigned Opcode)
const;
89 unsigned Opcode)
const;
131 bool IsSigned)
const;
133 bool IsSigned,
unsigned Opcode)
const;
135 bool IsSigned)
const;
171 GL::GLSLExtInst GLInst)
const;
176 const SPIRVType *ResType =
nullptr)
const;
185#define GET_GLOBALISEL_IMPL
186#include "SPIRVGenGlobalISel.inc"
187#undef GET_GLOBALISEL_IMPL
193 TRI(*ST.getRegisterInfo()), RBI(RBI), GR(*ST.getSPIRVGlobalRegistry()),
195#include
"SPIRVGenGlobalISel.inc"
198#include
"SPIRVGenGlobalISel.inc"
208 GR.setCurrentFunc(MF);
218 assert(
I.getParent() &&
"Instruction should be in a basic block!");
219 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
224 if (Opcode == SPIRV::ASSIGN_TYPE) {
225 auto *
Def =
MRI->getVRegDef(
I.getOperand(1).getReg());
227 auto Res = selectImpl(
I, *CoverageInfo);
228 assert(Res ||
Def->getOpcode() == TargetOpcode::G_CONSTANT);
232 MRI->replaceRegWith(
I.getOperand(1).getReg(),
I.getOperand(0).getReg());
233 I.removeFromParent();
235 }
else if (
I.getNumDefs() == 1) {
242 if (
I.getNumOperands() !=
I.getNumExplicitOperands()) {
243 LLVM_DEBUG(
errs() <<
"Generic instr has unexpected implicit operands\n");
249 bool HasDefs =
I.getNumDefs() > 0;
251 SPIRVType *ResType = HasDefs ? GR.getSPIRVTypeForVReg(ResVReg) :
nullptr;
252 assert(!HasDefs || ResType ||
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
253 if (spvSelect(ResVReg, ResType,
I)) {
256 I.removeFromParent();
262bool SPIRVInstructionSelector::spvSelect(
Register ResVReg,
266 I.getOpcode() == TargetOpcode::G_CONSTANT);
267 const unsigned Opcode =
I.getOpcode();
269 case TargetOpcode::G_CONSTANT:
270 return selectConst(ResVReg, ResType,
I.getOperand(1).getCImm()->getValue(),
272 case TargetOpcode::G_GLOBAL_VALUE:
273 return selectGlobalValue(ResVReg,
I);
274 case TargetOpcode::G_IMPLICIT_DEF:
275 return selectOpUndef(ResVReg, ResType,
I);
277 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
278 return selectIntrinsic(ResVReg, ResType,
I);
279 case TargetOpcode::G_BITREVERSE:
280 return selectBitreverse(ResVReg, ResType,
I);
282 case TargetOpcode::G_BUILD_VECTOR:
283 return selectConstVector(ResVReg, ResType,
I);
285 case TargetOpcode::G_SHUFFLE_VECTOR: {
287 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorShuffle))
289 .
addUse(GR.getSPIRVTypeID(ResType))
290 .
addUse(
I.getOperand(1).getReg())
291 .
addUse(
I.getOperand(2).getReg());
292 for (
auto V :
I.getOperand(3).getShuffleMask())
296 case TargetOpcode::G_MEMMOVE:
297 case TargetOpcode::G_MEMCPY:
298 case TargetOpcode::G_MEMSET:
299 return selectMemOperation(ResVReg,
I);
301 case TargetOpcode::G_ICMP:
302 return selectICmp(ResVReg, ResType,
I);
303 case TargetOpcode::G_FCMP:
304 return selectFCmp(ResVReg, ResType,
I);
306 case TargetOpcode::G_FRAME_INDEX:
307 return selectFrameIndex(ResVReg, ResType,
I);
309 case TargetOpcode::G_LOAD:
310 return selectLoad(ResVReg, ResType,
I);
311 case TargetOpcode::G_STORE:
312 return selectStore(
I);
314 case TargetOpcode::G_BR:
315 return selectBranch(
I);
316 case TargetOpcode::G_BRCOND:
317 return selectBranchCond(
I);
319 case TargetOpcode::G_PHI:
320 return selectPhi(ResVReg, ResType,
I);
322 case TargetOpcode::G_FPTOSI:
323 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertFToS);
324 case TargetOpcode::G_FPTOUI:
325 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertFToU);
327 case TargetOpcode::G_SITOFP:
328 return selectIToF(ResVReg, ResType,
I,
true, SPIRV::OpConvertSToF);
329 case TargetOpcode::G_UITOFP:
330 return selectIToF(ResVReg, ResType,
I,
false, SPIRV::OpConvertUToF);
332 case TargetOpcode::G_CTPOP:
333 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitCount);
334 case TargetOpcode::G_SMIN:
335 return selectExtInst(ResVReg, ResType,
I, CL::s_min, GL::SMin);
336 case TargetOpcode::G_UMIN:
337 return selectExtInst(ResVReg, ResType,
I, CL::u_min, GL::UMin);
339 case TargetOpcode::G_SMAX:
340 return selectExtInst(ResVReg, ResType,
I, CL::s_max, GL::SMax);
341 case TargetOpcode::G_UMAX:
342 return selectExtInst(ResVReg, ResType,
I, CL::u_max, GL::UMax);
344 case TargetOpcode::G_FMA:
345 return selectExtInst(ResVReg, ResType,
I, CL::fma, GL::Fma);
347 case TargetOpcode::G_FPOW:
348 return selectExtInst(ResVReg, ResType,
I, CL::pow, GL::Pow);
349 case TargetOpcode::G_FPOWI:
350 return selectExtInst(ResVReg, ResType,
I, CL::pown);
352 case TargetOpcode::G_FEXP:
353 return selectExtInst(ResVReg, ResType,
I, CL::exp, GL::Exp);
354 case TargetOpcode::G_FEXP2:
355 return selectExtInst(ResVReg, ResType,
I, CL::exp2, GL::Exp2);
357 case TargetOpcode::G_FLOG:
358 return selectExtInst(ResVReg, ResType,
I, CL::log, GL::Log);
359 case TargetOpcode::G_FLOG2:
360 return selectExtInst(ResVReg, ResType,
I, CL::log2, GL::Log2);
361 case TargetOpcode::G_FLOG10:
362 return selectExtInst(ResVReg, ResType,
I, CL::log10);
364 case TargetOpcode::G_FABS:
365 return selectExtInst(ResVReg, ResType,
I, CL::fabs, GL::FAbs);
366 case TargetOpcode::G_ABS:
367 return selectExtInst(ResVReg, ResType,
I, CL::s_abs, GL::SAbs);
369 case TargetOpcode::G_FMINNUM:
370 case TargetOpcode::G_FMINIMUM:
371 return selectExtInst(ResVReg, ResType,
I, CL::fmin, GL::FMin);
372 case TargetOpcode::G_FMAXNUM:
373 case TargetOpcode::G_FMAXIMUM:
374 return selectExtInst(ResVReg, ResType,
I, CL::fmax, GL::FMax);
376 case TargetOpcode::G_FCOPYSIGN:
377 return selectExtInst(ResVReg, ResType,
I, CL::copysign);
379 case TargetOpcode::G_FCEIL:
380 return selectExtInst(ResVReg, ResType,
I, CL::ceil, GL::Ceil);
381 case TargetOpcode::G_FFLOOR:
382 return selectExtInst(ResVReg, ResType,
I, CL::floor, GL::Floor);
384 case TargetOpcode::G_FCOS:
385 return selectExtInst(ResVReg, ResType,
I, CL::cos, GL::Cos);
386 case TargetOpcode::G_FSIN:
387 return selectExtInst(ResVReg, ResType,
I, CL::sin, GL::Sin);
389 case TargetOpcode::G_FSQRT:
390 return selectExtInst(ResVReg, ResType,
I, CL::sqrt, GL::Sqrt);
392 case TargetOpcode::G_CTTZ:
393 case TargetOpcode::G_CTTZ_ZERO_UNDEF:
394 return selectExtInst(ResVReg, ResType,
I, CL::ctz);
395 case TargetOpcode::G_CTLZ:
396 case TargetOpcode::G_CTLZ_ZERO_UNDEF:
397 return selectExtInst(ResVReg, ResType,
I, CL::clz);
399 case TargetOpcode::G_INTRINSIC_ROUND:
400 return selectExtInst(ResVReg, ResType,
I, CL::round, GL::Round);
401 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
402 return selectExtInst(ResVReg, ResType,
I, CL::rint, GL::RoundEven);
403 case TargetOpcode::G_INTRINSIC_TRUNC:
404 return selectExtInst(ResVReg, ResType,
I, CL::trunc, GL::Trunc);
405 case TargetOpcode::G_FRINT:
406 case TargetOpcode::G_FNEARBYINT:
407 return selectExtInst(ResVReg, ResType,
I, CL::rint, GL::RoundEven);
409 case TargetOpcode::G_SMULH:
410 return selectExtInst(ResVReg, ResType,
I, CL::s_mul_hi);
411 case TargetOpcode::G_UMULH:
412 return selectExtInst(ResVReg, ResType,
I, CL::u_mul_hi);
414 case TargetOpcode::G_SEXT:
415 return selectExt(ResVReg, ResType,
I,
true);
416 case TargetOpcode::G_ANYEXT:
417 case TargetOpcode::G_ZEXT:
418 return selectExt(ResVReg, ResType,
I,
false);
419 case TargetOpcode::G_TRUNC:
420 return selectTrunc(ResVReg, ResType,
I);
421 case TargetOpcode::G_FPTRUNC:
422 case TargetOpcode::G_FPEXT:
423 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpFConvert);
425 case TargetOpcode::G_PTRTOINT:
426 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertPtrToU);
427 case TargetOpcode::G_INTTOPTR:
428 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertUToPtr);
429 case TargetOpcode::G_BITCAST:
430 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitcast);
431 case TargetOpcode::G_ADDRSPACE_CAST:
432 return selectAddrSpaceCast(ResVReg, ResType,
I);
433 case TargetOpcode::G_PTR_ADD: {
438 assert(
I.getOperand(1).isReg() &&
I.getOperand(2).isReg());
441 assert(((*II).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
442 (*II).getOpcode() == TargetOpcode::COPY ||
443 (*II).getOpcode() == SPIRV::OpVariable) &&
445 Register Idx = buildZerosVal(GR.getOrCreateSPIRVIntegerType(32,
I,
TII),
I);
447 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSpecConstantOp))
449 .
addUse(GR.getSPIRVTypeID(ResType))
451 SPIRV::Opcode::InBoundsPtrAccessChain))
454 .
addUse(
I.getOperand(2).getReg());
458 case TargetOpcode::G_ATOMICRMW_OR:
459 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicOr);
460 case TargetOpcode::G_ATOMICRMW_ADD:
461 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicIAdd);
462 case TargetOpcode::G_ATOMICRMW_AND:
463 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicAnd);
464 case TargetOpcode::G_ATOMICRMW_MAX:
465 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicSMax);
466 case TargetOpcode::G_ATOMICRMW_MIN:
467 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicSMin);
468 case TargetOpcode::G_ATOMICRMW_SUB:
469 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicISub);
470 case TargetOpcode::G_ATOMICRMW_XOR:
471 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicXor);
472 case TargetOpcode::G_ATOMICRMW_UMAX:
473 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicUMax);
474 case TargetOpcode::G_ATOMICRMW_UMIN:
475 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicUMin);
476 case TargetOpcode::G_ATOMICRMW_XCHG:
477 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicExchange);
478 case TargetOpcode::G_ATOMIC_CMPXCHG:
479 return selectAtomicCmpXchg(ResVReg, ResType,
I);
481 case TargetOpcode::G_FENCE:
482 return selectFence(
I);
489bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
492 CL::OpenCLExtInst CLInst)
const {
493 return selectExtInst(ResVReg, ResType,
I,
494 {{SPIRV::InstructionSet::OpenCL_std, CLInst}});
497bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
500 CL::OpenCLExtInst CLInst,
501 GL::GLSLExtInst GLInst)
const {
502 ExtInstList ExtInsts = {{SPIRV::InstructionSet::OpenCL_std, CLInst},
503 {SPIRV::InstructionSet::GLSL_std_450, GLInst}};
504 return selectExtInst(ResVReg, ResType,
I, ExtInsts);
507bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
512 for (
const auto &Ex : Insts) {
513 SPIRV::InstructionSet::InstructionSet Set = Ex.first;
515 if (STI.canUseExtInstSet(Set)) {
517 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpExtInst))
519 .
addUse(GR.getSPIRVTypeID(ResType))
522 const unsigned NumOps =
I.getNumOperands();
523 for (
unsigned i = 1; i < NumOps; ++i)
524 MIB.add(
I.getOperand(i));
525 return MIB.constrainAllUses(
TII,
TRI, RBI);
531bool SPIRVInstructionSelector::selectUnOpWithSrc(
Register ResVReg,
535 unsigned Opcode)
const {
536 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
538 .
addUse(GR.getSPIRVTypeID(ResType))
543bool SPIRVInstructionSelector::selectUnOp(
Register ResVReg,
546 unsigned Opcode)
const {
547 return selectUnOpWithSrc(ResVReg, ResType,
I,
I.getOperand(1).getReg(),
554 return SPIRV::Scope::Invocation;
556 return SPIRV::Scope::Device;
565 if (
MemOp->isVolatile())
566 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
567 if (
MemOp->isNonTemporal())
568 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
569 if (
MemOp->getAlign().value())
570 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned);
572 if (SpvMemOp !=
static_cast<uint32_t>(SPIRV::MemoryOperand::None)) {
574 if (SpvMemOp &
static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned))
581 if (
Flags & MachineMemOperand::Flags::MOVolatile)
582 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
583 if (
Flags & MachineMemOperand::Flags::MONonTemporal)
584 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
586 if (SpvMemOp !=
static_cast<uint32_t>(SPIRV::MemoryOperand::None))
590bool SPIRVInstructionSelector::selectLoad(
Register ResVReg,
594 I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ? 1 : 0;
596 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpLoad))
598 .
addUse(GR.getSPIRVTypeID(ResType))
600 if (!
I.getNumMemOperands()) {
601 assert(
I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS);
606 return MIB.constrainAllUses(
TII,
TRI, RBI);
609bool SPIRVInstructionSelector::selectStore(
MachineInstr &
I)
const {
611 I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ? 1 : 0;
612 Register StoreVal =
I.getOperand(0 + OpOffset).getReg();
615 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpStore))
618 if (!
I.getNumMemOperands()) {
619 assert(
I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS);
624 return MIB.constrainAllUses(
TII,
TRI, RBI);
627bool SPIRVInstructionSelector::selectMemOperation(
Register ResVReg,
630 Register SrcReg =
I.getOperand(1).getReg();
631 if (
I.getOpcode() == TargetOpcode::G_MEMSET) {
632 assert(
I.getOperand(1).isReg() &&
I.getOperand(2).isReg());
635 SPIRVType *ValTy = GR.getOrCreateSPIRVIntegerType(8,
I,
TII);
636 SPIRVType *ArrTy = GR.getOrCreateSPIRVArrayType(ValTy, Num,
I,
TII);
638 SPIRVType *VarTy = GR.getOrCreateSPIRVPointerType(
639 ArrTy,
I,
TII, SPIRV::StorageClass::UniformConstant);
641 Type *LLVMArrTy = ArrayType::get(
646 GR.add(GV, GR.CurMF, VarReg);
649 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVariable))
651 .
addUse(GR.getSPIRVTypeID(VarTy))
652 .
addImm(SPIRV::StorageClass::UniformConstant)
655 SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
656 ValTy,
I,
TII, SPIRV::StorageClass::UniformConstant);
658 selectUnOpWithSrc(SrcReg, SourceTy,
I, VarReg, SPIRV::OpBitcast);
660 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCopyMemorySized))
661 .
addUse(
I.getOperand(0).getReg())
663 .
addUse(
I.getOperand(2).getReg());
664 if (
I.getNumMemOperands())
667 if (ResVReg.
isValid() && ResVReg != MIB->getOperand(0).getReg())
668 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY), ResVReg)
669 .
addUse(MIB->getOperand(0).getReg());
673bool SPIRVInstructionSelector::selectAtomicRMW(
Register ResVReg,
676 unsigned NewOpcode)
const {
680 Register ScopeReg = buildI32Constant(Scope,
I);
688 Register MemSemReg = buildI32Constant(MemSem ,
I);
690 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(NewOpcode))
692 .
addUse(GR.getSPIRVTypeID(ResType))
696 .
addUse(
I.getOperand(2).getReg())
700bool SPIRVInstructionSelector::selectFence(
MachineInstr &
I)
const {
703 Register MemSemReg = buildI32Constant(MemSem,
I);
706 Register ScopeReg = buildI32Constant(Scope,
I);
708 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemoryBarrier))
714bool SPIRVInstructionSelector::selectAtomicCmpXchg(
Register ResVReg,
721 if (
I.getOpcode() != TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS) {
725 ScopeReg = buildI32Constant(Scope,
I);
727 unsigned ScSem =
static_cast<uint32_t>(
731 MemSemEqReg = buildI32Constant(MemSemEq,
I);
735 MemSemEq == MemSemNeq ? MemSemEqReg : buildI32Constant(MemSemNeq,
I);
737 ScopeReg =
I.getOperand(5).getReg();
738 MemSemEqReg =
I.getOperand(6).getReg();
739 MemSemNeqReg =
I.getOperand(7).getReg();
744 SPIRVType *SpvValTy = GR.getSPIRVTypeForVReg(Val);
745 Register ACmpRes =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
748 BuildMI(*
I.getParent(),
I,
DL,
TII.get(SPIRV::OpAtomicCompareExchange))
750 .
addUse(GR.getSPIRVTypeID(SpvValTy))
758 Register CmpSuccReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
762 .
addUse(GR.getSPIRVTypeID(BoolTy))
766 Register TmpReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
769 .
addUse(GR.getSPIRVTypeID(ResType))
776 .
addUse(GR.getSPIRVTypeID(ResType))
786 case SPIRV::StorageClass::Workgroup:
787 case SPIRV::StorageClass::CrossWorkgroup:
788 case SPIRV::StorageClass::Function:
800bool SPIRVInstructionSelector::selectAddrSpaceCast(
Register ResVReg,
805 auto UIs =
MRI->use_instructions(ResVReg);
806 if (!UIs.empty() && ++UIs.begin() == UIs.end() &&
807 (UIs.begin()->getOpcode() == SPIRV::OpConstantComposite ||
808 UIs.begin()->getOpcode() == SPIRV::OpVariable ||
810 Register NewReg =
I.getOperand(1).getReg();
812 SPIRVType *SpvBaseTy = GR.getOrCreateSPIRVIntegerType(8,
I,
TII);
813 ResType = GR.getOrCreateSPIRVPointerType(SpvBaseTy,
I,
TII,
814 SPIRV::StorageClass::Generic);
816 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSpecConstantOp))
818 .
addUse(GR.getSPIRVTypeID(ResType))
824 Register SrcPtr =
I.getOperand(1).getReg();
825 SPIRVType *SrcPtrTy = GR.getSPIRVTypeForVReg(SrcPtr);
826 SPIRV::StorageClass::StorageClass SrcSC = GR.getPointerStorageClass(SrcPtr);
827 SPIRV::StorageClass::StorageClass DstSC = GR.getPointerStorageClass(ResVReg);
831 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpPtrCastToGeneric);
834 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpGenericCastToPtr);
837 Register Tmp =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
838 SPIRVType *GenericPtrTy = GR.getOrCreateSPIRVPointerType(
839 SrcPtrTy,
I,
TII, SPIRV::StorageClass::Generic);
844 .
addUse(GR.getSPIRVTypeID(GenericPtrTy))
849 .
addUse(GR.getSPIRVTypeID(ResType))
855 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitcast);
862 return SPIRV::OpFOrdEqual;
864 return SPIRV::OpFOrdGreaterThanEqual;
866 return SPIRV::OpFOrdGreaterThan;
868 return SPIRV::OpFOrdLessThanEqual;
870 return SPIRV::OpFOrdLessThan;
872 return SPIRV::OpFOrdNotEqual;
874 return SPIRV::OpOrdered;
876 return SPIRV::OpFUnordEqual;
878 return SPIRV::OpFUnordGreaterThanEqual;
880 return SPIRV::OpFUnordGreaterThan;
882 return SPIRV::OpFUnordLessThanEqual;
884 return SPIRV::OpFUnordLessThan;
886 return SPIRV::OpFUnordNotEqual;
888 return SPIRV::OpUnordered;
898 return SPIRV::OpIEqual;
900 return SPIRV::OpINotEqual;
902 return SPIRV::OpSGreaterThanEqual;
904 return SPIRV::OpSGreaterThan;
906 return SPIRV::OpSLessThanEqual;
908 return SPIRV::OpSLessThan;
910 return SPIRV::OpUGreaterThanEqual;
912 return SPIRV::OpUGreaterThan;
914 return SPIRV::OpULessThanEqual;
916 return SPIRV::OpULessThan;
925 return SPIRV::OpPtrEqual;
927 return SPIRV::OpPtrNotEqual;
938 return SPIRV::OpLogicalEqual;
940 return SPIRV::OpLogicalNotEqual;
946bool SPIRVInstructionSelector::selectBitreverse(
Register ResVReg,
950 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBitReverse))
952 .
addUse(GR.getSPIRVTypeID(ResType))
953 .
addUse(
I.getOperand(1).getReg())
957bool SPIRVInstructionSelector::selectConstVector(
Register ResVReg,
967 SPIRVType *ConstTy = this->MRI->getVRegDef(MO.getReg());
968 assert(ConstTy && ConstTy->getOpcode() == SPIRV::ASSIGN_TYPE &&
969 ConstTy->getOperand(1).isReg());
970 Register ConstReg = ConstTy->getOperand(1).getReg();
971 const MachineInstr *Const = this->MRI->getVRegDef(ConstReg);
973 return (Const->getOpcode() == TargetOpcode::G_CONSTANT ||
974 Const->getOpcode() == TargetOpcode::G_FCONSTANT);
977 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
978 TII.get(SPIRV::OpConstantComposite))
980 .
addUse(GR.getSPIRVTypeID(ResType));
981 for (
unsigned i =
I.getNumExplicitDefs(); i <
I.getNumExplicitOperands(); ++i)
982 MIB.
addUse(
I.getOperand(i).getReg());
986bool SPIRVInstructionSelector::selectCmp(
Register ResVReg,
990 Register Cmp0 =
I.getOperand(2).getReg();
991 Register Cmp1 =
I.getOperand(3).getReg();
992 assert(GR.getSPIRVTypeForVReg(Cmp0)->getOpcode() ==
993 GR.getSPIRVTypeForVReg(Cmp1)->getOpcode() &&
994 "CMP operands should have the same type");
995 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(CmpOpc))
997 .
addUse(GR.getSPIRVTypeID(ResType))
1003bool SPIRVInstructionSelector::selectICmp(
Register ResVReg,
1006 auto Pred =
I.getOperand(1).getPredicate();
1009 Register CmpOperand =
I.getOperand(2).getReg();
1010 if (GR.isScalarOfType(CmpOperand, SPIRV::OpTypePointer))
1012 else if (GR.isScalarOrVectorOfType(CmpOperand, SPIRV::OpTypeBool))
1016 return selectCmp(ResVReg, ResType, CmpOpc,
I);
1022 assert(
I.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 &&
1023 "Expected G_FCONSTANT");
1024 const ConstantFP *FPImm =
I.getOperand(1).getFPImm();
1031 assert(
I.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1032 "Expected G_CONSTANT");
1033 addNumImm(
I.getOperand(1).getCImm()->getValue(), MIB);
1041 ResType ? ResType : GR.getOrCreateSPIRVIntegerType(32,
I,
TII);
1044 Register NewReg = GR.find(ConstInt, GR.CurMF);
1047 GR.add(ConstInt, GR.CurMF, NewReg);
1051 MI =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1053 .
addUse(GR.getSPIRVTypeID(SpvI32Ty));
1055 MI =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantI))
1057 .
addUse(GR.getSPIRVTypeID(SpvI32Ty))
1065bool SPIRVInstructionSelector::selectFCmp(
Register ResVReg,
1069 return selectCmp(ResVReg, ResType, CmpOp,
I);
1074 if (ResType->
getOpcode() == SPIRV::OpTypeVector)
1075 return GR.getOrCreateConsIntVector(0,
I, ResType,
TII);
1076 return GR.getOrCreateConstInt(0,
I, ResType,
TII);
1082 unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
1085 if (ResType->
getOpcode() == SPIRV::OpTypeVector)
1090bool SPIRVInstructionSelector::selectSelect(
Register ResVReg,
1093 bool IsSigned)
const {
1095 Register ZeroReg = buildZerosVal(ResType,
I);
1096 Register OneReg = buildOnesVal(IsSigned, ResType,
I);
1098 GR.isScalarOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool);
1100 IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectSIVCond;
1101 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
1103 .
addUse(GR.getSPIRVTypeID(ResType))
1104 .
addUse(
I.getOperand(1).getReg())
1110bool SPIRVInstructionSelector::selectIToF(
Register ResVReg,
1113 unsigned Opcode)
const {
1114 Register SrcReg =
I.getOperand(1).getReg();
1117 if (GR.isScalarOrVectorOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool)) {
1118 unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
1120 if (ResType->
getOpcode() == SPIRV::OpTypeVector) {
1122 TmpType = GR.getOrCreateSPIRVVectorType(TmpType, NumElts,
I,
TII);
1124 SrcReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
1125 selectSelect(SrcReg, TmpType,
I,
false);
1127 return selectUnOpWithSrc(ResVReg, ResType,
I, SrcReg, Opcode);
1130bool SPIRVInstructionSelector::selectExt(
Register ResVReg,
1133 if (GR.isScalarOrVectorOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool))
1134 return selectSelect(ResVReg, ResType,
I, IsSigned);
1135 unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
1136 return selectUnOp(ResVReg, ResType,
I, Opcode);
1139bool SPIRVInstructionSelector::selectIntToBool(
Register IntReg,
1145 Register BitIntReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
1146 bool IsVectorTy = IntTy->
getOpcode() == SPIRV::OpTypeVector;
1147 unsigned Opcode = IsVectorTy ? SPIRV::OpBitwiseAndV : SPIRV::OpBitwiseAndS;
1149 Register One = buildOnesVal(
false, IntTy,
I);
1153 .
addUse(GR.getSPIRVTypeID(IntTy))
1157 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpINotEqual))
1159 .
addUse(GR.getSPIRVTypeID(BoolTy))
1165bool SPIRVInstructionSelector::selectTrunc(
Register ResVReg,
1168 if (GR.isScalarOrVectorOfType(ResVReg, SPIRV::OpTypeBool)) {
1169 Register IntReg =
I.getOperand(1).getReg();
1170 const SPIRVType *ArgType = GR.getSPIRVTypeForVReg(IntReg);
1171 return selectIntToBool(IntReg, ResVReg,
I, ArgType, ResType);
1173 bool IsSigned = GR.isScalarOrVectorSigned(ResType);
1174 unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
1175 return selectUnOp(ResVReg, ResType,
I, Opcode);
1178bool SPIRVInstructionSelector::selectConst(
Register ResVReg,
1182 unsigned TyOpcode = ResType->
getOpcode();
1183 assert(TyOpcode != SPIRV::OpTypePointer ||
Imm.isZero());
1185 if ((TyOpcode == SPIRV::OpTypePointer || TyOpcode == SPIRV::OpTypeEvent) &&
1187 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1189 .
addUse(GR.getSPIRVTypeID(ResType))
1191 if (TyOpcode == SPIRV::OpTypeInt) {
1192 assert(
Imm.getBitWidth() <= 64 &&
"Unsupported integer width!");
1196 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY))
1201 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantI))
1203 .
addUse(GR.getSPIRVTypeID(ResType));
1210bool SPIRVInstructionSelector::selectOpUndef(
Register ResVReg,
1213 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUndef))
1215 .
addUse(GR.getSPIRVTypeID(ResType))
1222 if (TypeInst->
getOpcode() != SPIRV::ASSIGN_TYPE)
1226 return ImmInst->
getOpcode() == TargetOpcode::G_CONSTANT;
1236bool SPIRVInstructionSelector::selectInsertVal(
Register ResVReg,
1240 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCompositeInsert))
1242 .
addUse(GR.getSPIRVTypeID(ResType))
1244 .
addUse(
I.getOperand(3).getReg())
1246 .
addUse(
I.getOperand(2).getReg());
1247 for (
unsigned i = 4; i <
I.getNumOperands(); i++)
1252bool SPIRVInstructionSelector::selectExtractVal(
Register ResVReg,
1256 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCompositeExtract))
1258 .
addUse(GR.getSPIRVTypeID(ResType))
1259 .
addUse(
I.getOperand(2).getReg());
1260 for (
unsigned i = 3; i <
I.getNumOperands(); i++)
1265bool SPIRVInstructionSelector::selectInsertElt(
Register ResVReg,
1269 return selectInsertVal(ResVReg, ResType,
I);
1271 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorInsertDynamic))
1273 .
addUse(GR.getSPIRVTypeID(ResType))
1274 .
addUse(
I.getOperand(2).getReg())
1275 .
addUse(
I.getOperand(3).getReg())
1276 .
addUse(
I.getOperand(4).getReg())
1280bool SPIRVInstructionSelector::selectExtractElt(
Register ResVReg,
1284 return selectExtractVal(ResVReg, ResType,
I);
1286 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorExtractDynamic))
1288 .
addUse(GR.getSPIRVTypeID(ResType))
1289 .
addUse(
I.getOperand(2).getReg())
1290 .
addUse(
I.getOperand(3).getReg())
1294bool SPIRVInstructionSelector::selectGEP(
Register ResVReg,
1300 unsigned Opcode =
I.getOperand(2).getImm() ? SPIRV::OpInBoundsPtrAccessChain
1301 : SPIRV::OpPtrAccessChain;
1302 auto Res =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
1304 .
addUse(GR.getSPIRVTypeID(ResType))
1306 .
addUse(
I.getOperand(3).getReg());
1308 for (
unsigned i = 4; i <
I.getNumExplicitOperands(); ++i)
1309 Res.
addUse(
I.getOperand(i).getReg());
1313bool SPIRVInstructionSelector::selectIntrinsic(
Register ResVReg,
1317 switch (
I.getIntrinsicID()) {
1318 case Intrinsic::spv_load:
1319 return selectLoad(ResVReg, ResType,
I);
1320 case Intrinsic::spv_store:
1321 return selectStore(
I);
1322 case Intrinsic::spv_extractv:
1323 return selectExtractVal(ResVReg, ResType,
I);
1324 case Intrinsic::spv_insertv:
1325 return selectInsertVal(ResVReg, ResType,
I);
1326 case Intrinsic::spv_extractelt:
1327 return selectExtractElt(ResVReg, ResType,
I);
1328 case Intrinsic::spv_insertelt:
1329 return selectInsertElt(ResVReg, ResType,
I);
1330 case Intrinsic::spv_gep:
1331 return selectGEP(ResVReg, ResType,
I);
1332 case Intrinsic::spv_unref_global:
1333 case Intrinsic::spv_init_global: {
1336 ?
MRI->getVRegDef(
I.getOperand(2).getReg())
1339 return selectGlobalValue(
MI->getOperand(0).getReg(), *
MI,
Init);
1341 case Intrinsic::spv_undef: {
1342 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUndef))
1344 .
addUse(GR.getSPIRVTypeID(ResType));
1347 case Intrinsic::spv_const_composite: {
1349 bool IsNull =
I.getNumExplicitDefs() + 1 ==
I.getNumExplicitOperands();
1351 IsNull ? SPIRV::OpConstantNull : SPIRV::OpConstantComposite;
1352 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(Opcode))
1354 .
addUse(GR.getSPIRVTypeID(ResType));
1357 for (
unsigned i =
I.getNumExplicitDefs() + 1;
1358 i <
I.getNumExplicitOperands(); ++i) {
1359 MIB.
addUse(
I.getOperand(i).getReg());
1364 case Intrinsic::spv_assign_name: {
1365 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName));
1366 MIB.
addUse(
I.getOperand(
I.getNumExplicitDefs() + 1).getReg());
1367 for (
unsigned i =
I.getNumExplicitDefs() + 2;
1368 i <
I.getNumExplicitOperands(); ++i) {
1369 MIB.
addImm(
I.getOperand(i).getImm());
1373 case Intrinsic::spv_switch: {
1374 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSwitch));
1375 for (
unsigned i = 1; i <
I.getNumExplicitOperands(); ++i) {
1376 if (
I.getOperand(i).isReg())
1377 MIB.
addReg(
I.getOperand(i).getReg());
1378 else if (
I.getOperand(i).isCImm())
1379 addNumImm(
I.getOperand(i).getCImm()->getValue(), MIB);
1380 else if (
I.getOperand(i).isMBB())
1381 MIB.
addMBB(
I.getOperand(i).getMBB());
1387 case Intrinsic::spv_cmpxchg:
1388 return selectAtomicCmpXchg(ResVReg, ResType,
I);
1389 case Intrinsic::spv_unreachable:
1390 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUnreachable));
1392 case Intrinsic::spv_alloca:
1393 return selectFrameIndex(ResVReg, ResType,
I);
1400bool SPIRVInstructionSelector::selectFrameIndex(
Register ResVReg,
1403 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVariable))
1405 .
addUse(GR.getSPIRVTypeID(ResType))
1410bool SPIRVInstructionSelector::selectBranch(
MachineInstr &
I)
const {
1417 if (PrevI !=
nullptr && PrevI->
getOpcode() == TargetOpcode::G_BRCOND) {
1418 return BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBranchConditional))
1421 .
addMBB(
I.getOperand(0).getMBB())
1425 .
addMBB(
I.getOperand(0).getMBB())
1429bool SPIRVInstructionSelector::selectBranchCond(
MachineInstr &
I)
const {
1442 if (NextI !=
nullptr && NextI->
getOpcode() == SPIRV::OpBranchConditional)
1449 return BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBranchConditional))
1450 .
addUse(
I.getOperand(0).getReg())
1451 .
addMBB(
I.getOperand(1).getMBB())
1456bool SPIRVInstructionSelector::selectPhi(
Register ResVReg,
1459 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpPhi))
1461 .
addUse(GR.getSPIRVTypeID(ResType));
1462 const unsigned NumOps =
I.getNumOperands();
1463 for (
unsigned i = 1; i < NumOps; i += 2) {
1464 MIB.
addUse(
I.getOperand(i + 0).getReg());
1465 MIB.
addMBB(
I.getOperand(i + 1).getMBB());
1470bool SPIRVInstructionSelector::selectGlobalValue(
1475 SPIRVType *ResType = GR.getOrCreateSPIRVType(
1476 GV->
getType(), MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false);
1483 if (isa<Function>(GV)) {
1486 Register NewReg = GR.find(ConstVal, GR.CurMF);
1488 SPIRVType *SpvBaseTy = GR.getOrCreateSPIRVIntegerType(8,
I,
TII);
1489 ResType = GR.getOrCreateSPIRVPointerType(SpvBaseTy,
I,
TII);
1491 GR.add(ConstVal, GR.CurMF, NewReg);
1492 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1494 .
addUse(GR.getSPIRVTypeID(ResType))
1497 assert(NewReg != ResVReg);
1498 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY))
1503 auto GlobalVar = cast<GlobalVariable>(GV);
1506 bool HasInit =
GlobalVar->hasInitializer() &&
1507 !isa<UndefValue>(
GlobalVar->getInitializer());
1510 if (HasInit && !
Init)
1514 SPIRV::StorageClass::StorageClass Storage =
1517 Storage != SPIRV::StorageClass::Function;
1518 SPIRV::LinkageType::LinkageType LnkType =
1520 ? SPIRV::LinkageType::Import
1521 : SPIRV::LinkageType::Export;
1523 Register Reg = GR.buildGlobalVariable(ResVReg, ResType, GlobalIdent, GV,
1525 HasLnkTy, LnkType, MIRBuilder,
true);
1526 return Reg.isValid();
1534 return new SPIRVInstructionSelector(
TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file declares a class to represent arbitrary precision floating point values and provide a varie...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< std::pair< SPIRV::InstructionSet::InstructionSet, uint32_t > > ExtInstList
static SPIRV::Scope::Scope getScope(SyncScope::ID Ord)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static void addMemoryOperands(MachineMemOperand *MemOp, MachineInstrBuilder &MIB)
static unsigned getFCmpOpcode(unsigned PredNum)
bool isTypeFoldingSupported(unsigned Opcode)
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
static unsigned getBoolCmpOpcode(unsigned PredNum)
static unsigned getICmpOpcode(unsigned PredNum)
static int64_t foldImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
static bool isGenericCastablePtr(SPIRV::StorageClass::StorageClass SC)
static unsigned getPtrCmpOpcode(unsigned Pred)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
uint64_t getZExtValue() const
Get zero extended value.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
unsigned getAddressSpace() const
PointerType * getType() const
Global values are always pointers.
static std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
bool hasAvailableExternallyLinkage() const
@ InternalLinkage
Rename collisions when linking (static functions).
Provides the logic to select generic machine instructions.
virtual void setupMF(MachineFunction &mf, GISelKnownBits *KB, CodeGenCoverage &covinfo, ProfileSummaryInfo *psi, BlockFrequencyInfo *bfi)
Setup per-MF selector state.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Helper class to build MachineInstr.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
Register getReg() const
getReg - Returns the register number.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
The instances of the Type class are immutable: once they are created, they are never changed.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
@ System
Synchronized with respect to all concurrently executing threads.
Reg
All possible values of the reg field in the ModR/M byte.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace)
bool isSpvIntrinsic(MachineInstr &MI, Intrinsic::ID IntrinsicID)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
InstructionSelector * createSPIRVInstructionSelector(const SPIRVTargetMachine &TM, const SPIRVSubtarget &Subtarget, const RegisterBankInfo &RBI)
constexpr unsigned BitWidth
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)