28#include "llvm/IR/IntrinsicsSPIRV.h"
31#define DEBUG_TYPE "spirv-isel"
34namespace CL = SPIRV::OpenCLExtInst;
35namespace GL = SPIRV::GLSLExtInst;
38 std::vector<std::pair<SPIRV::InstructionSet::InstructionSet, uint32_t>>;
42#define GET_GLOBALISEL_PREDICATE_BITSET
43#include "SPIRVGenGlobalISel.inc"
44#undef GET_GLOBALISEL_PREDICATE_BITSET
65#define GET_GLOBALISEL_PREDICATES_DECL
66#include "SPIRVGenGlobalISel.inc"
67#undef GET_GLOBALISEL_PREDICATES_DECL
69#define GET_GLOBALISEL_TEMPORARIES_DECL
70#include "SPIRVGenGlobalISel.inc"
71#undef GET_GLOBALISEL_TEMPORARIES_DECL
88 unsigned Opcode)
const;
90 unsigned Opcode)
const;
132 bool IsSigned)
const;
134 bool IsSigned,
unsigned Opcode)
const;
136 bool IsSigned)
const;
172 GL::GLSLExtInst GLInst)
const;
177 const SPIRVType *ResType =
nullptr)
const;
186#define GET_GLOBALISEL_IMPL
187#include "SPIRVGenGlobalISel.inc"
188#undef GET_GLOBALISEL_IMPL
194 TRI(*ST.getRegisterInfo()), RBI(RBI), GR(*ST.getSPIRVGlobalRegistry()),
196#include
"SPIRVGenGlobalISel.inc"
199#include
"SPIRVGenGlobalISel.inc"
209 GR.setCurrentFunc(MF);
210 InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI);
219 assert(
I.getParent() &&
"Instruction should be in a basic block!");
220 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
225 if (Opcode == SPIRV::ASSIGN_TYPE) {
226 auto *
Def =
MRI->getVRegDef(
I.getOperand(1).getReg());
228 auto Res = selectImpl(
I, *CoverageInfo);
229 assert(Res ||
Def->getOpcode() == TargetOpcode::G_CONSTANT);
233 MRI->replaceRegWith(
I.getOperand(1).getReg(),
I.getOperand(0).getReg());
234 I.removeFromParent();
236 }
else if (
I.getNumDefs() == 1) {
243 if (
I.getNumOperands() !=
I.getNumExplicitOperands()) {
244 LLVM_DEBUG(
errs() <<
"Generic instr has unexpected implicit operands\n");
250 bool HasDefs =
I.getNumDefs() > 0;
252 SPIRVType *ResType = HasDefs ? GR.getSPIRVTypeForVReg(ResVReg) :
nullptr;
253 assert(!HasDefs || ResType ||
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
254 if (spvSelect(ResVReg, ResType,
I)) {
257 I.removeFromParent();
263bool SPIRVInstructionSelector::spvSelect(
Register ResVReg,
267 I.getOpcode() == TargetOpcode::G_CONSTANT);
268 const unsigned Opcode =
I.getOpcode();
270 case TargetOpcode::G_CONSTANT:
271 return selectConst(ResVReg, ResType,
I.getOperand(1).getCImm()->getValue(),
273 case TargetOpcode::G_GLOBAL_VALUE:
274 return selectGlobalValue(ResVReg,
I);
275 case TargetOpcode::G_IMPLICIT_DEF:
276 return selectOpUndef(ResVReg, ResType,
I);
278 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
279 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
280 return selectIntrinsic(ResVReg, ResType,
I);
281 case TargetOpcode::G_BITREVERSE:
282 return selectBitreverse(ResVReg, ResType,
I);
284 case TargetOpcode::G_BUILD_VECTOR:
285 return selectConstVector(ResVReg, ResType,
I);
287 case TargetOpcode::G_SHUFFLE_VECTOR: {
289 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorShuffle))
291 .
addUse(GR.getSPIRVTypeID(ResType))
292 .
addUse(
I.getOperand(1).getReg())
293 .
addUse(
I.getOperand(2).getReg());
294 for (
auto V :
I.getOperand(3).getShuffleMask())
298 case TargetOpcode::G_MEMMOVE:
299 case TargetOpcode::G_MEMCPY:
300 case TargetOpcode::G_MEMSET:
301 return selectMemOperation(ResVReg,
I);
303 case TargetOpcode::G_ICMP:
304 return selectICmp(ResVReg, ResType,
I);
305 case TargetOpcode::G_FCMP:
306 return selectFCmp(ResVReg, ResType,
I);
308 case TargetOpcode::G_FRAME_INDEX:
309 return selectFrameIndex(ResVReg, ResType,
I);
311 case TargetOpcode::G_LOAD:
312 return selectLoad(ResVReg, ResType,
I);
313 case TargetOpcode::G_STORE:
314 return selectStore(
I);
316 case TargetOpcode::G_BR:
317 return selectBranch(
I);
318 case TargetOpcode::G_BRCOND:
319 return selectBranchCond(
I);
321 case TargetOpcode::G_PHI:
322 return selectPhi(ResVReg, ResType,
I);
324 case TargetOpcode::G_FPTOSI:
325 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertFToS);
326 case TargetOpcode::G_FPTOUI:
327 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertFToU);
329 case TargetOpcode::G_SITOFP:
330 return selectIToF(ResVReg, ResType,
I,
true, SPIRV::OpConvertSToF);
331 case TargetOpcode::G_UITOFP:
332 return selectIToF(ResVReg, ResType,
I,
false, SPIRV::OpConvertUToF);
334 case TargetOpcode::G_CTPOP:
335 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitCount);
336 case TargetOpcode::G_SMIN:
337 return selectExtInst(ResVReg, ResType,
I, CL::s_min, GL::SMin);
338 case TargetOpcode::G_UMIN:
339 return selectExtInst(ResVReg, ResType,
I, CL::u_min, GL::UMin);
341 case TargetOpcode::G_SMAX:
342 return selectExtInst(ResVReg, ResType,
I, CL::s_max, GL::SMax);
343 case TargetOpcode::G_UMAX:
344 return selectExtInst(ResVReg, ResType,
I, CL::u_max, GL::UMax);
346 case TargetOpcode::G_FMA:
347 return selectExtInst(ResVReg, ResType,
I, CL::fma, GL::Fma);
349 case TargetOpcode::G_FPOW:
350 return selectExtInst(ResVReg, ResType,
I, CL::pow, GL::Pow);
351 case TargetOpcode::G_FPOWI:
352 return selectExtInst(ResVReg, ResType,
I, CL::pown);
354 case TargetOpcode::G_FEXP:
355 return selectExtInst(ResVReg, ResType,
I, CL::exp, GL::Exp);
356 case TargetOpcode::G_FEXP2:
357 return selectExtInst(ResVReg, ResType,
I, CL::exp2, GL::Exp2);
359 case TargetOpcode::G_FLOG:
360 return selectExtInst(ResVReg, ResType,
I, CL::log, GL::Log);
361 case TargetOpcode::G_FLOG2:
362 return selectExtInst(ResVReg, ResType,
I, CL::log2, GL::Log2);
363 case TargetOpcode::G_FLOG10:
364 return selectExtInst(ResVReg, ResType,
I, CL::log10);
366 case TargetOpcode::G_FABS:
367 return selectExtInst(ResVReg, ResType,
I, CL::fabs, GL::FAbs);
368 case TargetOpcode::G_ABS:
369 return selectExtInst(ResVReg, ResType,
I, CL::s_abs, GL::SAbs);
371 case TargetOpcode::G_FMINNUM:
372 case TargetOpcode::G_FMINIMUM:
373 return selectExtInst(ResVReg, ResType,
I, CL::fmin, GL::FMin);
374 case TargetOpcode::G_FMAXNUM:
375 case TargetOpcode::G_FMAXIMUM:
376 return selectExtInst(ResVReg, ResType,
I, CL::fmax, GL::FMax);
378 case TargetOpcode::G_FCOPYSIGN:
379 return selectExtInst(ResVReg, ResType,
I, CL::copysign);
381 case TargetOpcode::G_FCEIL:
382 return selectExtInst(ResVReg, ResType,
I, CL::ceil, GL::Ceil);
383 case TargetOpcode::G_FFLOOR:
384 return selectExtInst(ResVReg, ResType,
I, CL::floor, GL::Floor);
386 case TargetOpcode::G_FCOS:
387 return selectExtInst(ResVReg, ResType,
I, CL::cos, GL::Cos);
388 case TargetOpcode::G_FSIN:
389 return selectExtInst(ResVReg, ResType,
I, CL::sin, GL::Sin);
391 case TargetOpcode::G_FSQRT:
392 return selectExtInst(ResVReg, ResType,
I, CL::sqrt, GL::Sqrt);
394 case TargetOpcode::G_CTTZ:
395 case TargetOpcode::G_CTTZ_ZERO_UNDEF:
396 return selectExtInst(ResVReg, ResType,
I, CL::ctz);
397 case TargetOpcode::G_CTLZ:
398 case TargetOpcode::G_CTLZ_ZERO_UNDEF:
399 return selectExtInst(ResVReg, ResType,
I, CL::clz);
401 case TargetOpcode::G_INTRINSIC_ROUND:
402 return selectExtInst(ResVReg, ResType,
I, CL::round, GL::Round);
403 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
404 return selectExtInst(ResVReg, ResType,
I, CL::rint, GL::RoundEven);
405 case TargetOpcode::G_INTRINSIC_TRUNC:
406 return selectExtInst(ResVReg, ResType,
I, CL::trunc, GL::Trunc);
407 case TargetOpcode::G_FRINT:
408 case TargetOpcode::G_FNEARBYINT:
409 return selectExtInst(ResVReg, ResType,
I, CL::rint, GL::RoundEven);
411 case TargetOpcode::G_SMULH:
412 return selectExtInst(ResVReg, ResType,
I, CL::s_mul_hi);
413 case TargetOpcode::G_UMULH:
414 return selectExtInst(ResVReg, ResType,
I, CL::u_mul_hi);
416 case TargetOpcode::G_SEXT:
417 return selectExt(ResVReg, ResType,
I,
true);
418 case TargetOpcode::G_ANYEXT:
419 case TargetOpcode::G_ZEXT:
420 return selectExt(ResVReg, ResType,
I,
false);
421 case TargetOpcode::G_TRUNC:
422 return selectTrunc(ResVReg, ResType,
I);
423 case TargetOpcode::G_FPTRUNC:
424 case TargetOpcode::G_FPEXT:
425 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpFConvert);
427 case TargetOpcode::G_PTRTOINT:
428 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertPtrToU);
429 case TargetOpcode::G_INTTOPTR:
430 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpConvertUToPtr);
431 case TargetOpcode::G_BITCAST:
432 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitcast);
433 case TargetOpcode::G_ADDRSPACE_CAST:
434 return selectAddrSpaceCast(ResVReg, ResType,
I);
435 case TargetOpcode::G_PTR_ADD: {
440 assert(
I.getOperand(1).isReg() &&
I.getOperand(2).isReg());
443 assert(((*II).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
444 (*II).getOpcode() == TargetOpcode::COPY ||
445 (*II).getOpcode() == SPIRV::OpVariable) &&
447 Register Idx = buildZerosVal(GR.getOrCreateSPIRVIntegerType(32,
I,
TII),
I);
449 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSpecConstantOp))
451 .
addUse(GR.getSPIRVTypeID(ResType))
453 SPIRV::Opcode::InBoundsPtrAccessChain))
456 .
addUse(
I.getOperand(2).getReg());
460 case TargetOpcode::G_ATOMICRMW_OR:
461 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicOr);
462 case TargetOpcode::G_ATOMICRMW_ADD:
463 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicIAdd);
464 case TargetOpcode::G_ATOMICRMW_AND:
465 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicAnd);
466 case TargetOpcode::G_ATOMICRMW_MAX:
467 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicSMax);
468 case TargetOpcode::G_ATOMICRMW_MIN:
469 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicSMin);
470 case TargetOpcode::G_ATOMICRMW_SUB:
471 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicISub);
472 case TargetOpcode::G_ATOMICRMW_XOR:
473 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicXor);
474 case TargetOpcode::G_ATOMICRMW_UMAX:
475 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicUMax);
476 case TargetOpcode::G_ATOMICRMW_UMIN:
477 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicUMin);
478 case TargetOpcode::G_ATOMICRMW_XCHG:
479 return selectAtomicRMW(ResVReg, ResType,
I, SPIRV::OpAtomicExchange);
480 case TargetOpcode::G_ATOMIC_CMPXCHG:
481 return selectAtomicCmpXchg(ResVReg, ResType,
I);
483 case TargetOpcode::G_FENCE:
484 return selectFence(
I);
491bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
494 CL::OpenCLExtInst CLInst)
const {
495 return selectExtInst(ResVReg, ResType,
I,
496 {{SPIRV::InstructionSet::OpenCL_std, CLInst}});
499bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
502 CL::OpenCLExtInst CLInst,
503 GL::GLSLExtInst GLInst)
const {
504 ExtInstList ExtInsts = {{SPIRV::InstructionSet::OpenCL_std, CLInst},
505 {SPIRV::InstructionSet::GLSL_std_450, GLInst}};
506 return selectExtInst(ResVReg, ResType,
I, ExtInsts);
509bool SPIRVInstructionSelector::selectExtInst(
Register ResVReg,
514 for (
const auto &Ex : Insts) {
515 SPIRV::InstructionSet::InstructionSet Set = Ex.first;
517 if (STI.canUseExtInstSet(Set)) {
519 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpExtInst))
521 .
addUse(GR.getSPIRVTypeID(ResType))
524 const unsigned NumOps =
I.getNumOperands();
525 for (
unsigned i = 1; i < NumOps; ++i)
526 MIB.add(
I.getOperand(i));
527 return MIB.constrainAllUses(
TII,
TRI, RBI);
533bool SPIRVInstructionSelector::selectUnOpWithSrc(
Register ResVReg,
537 unsigned Opcode)
const {
538 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
540 .
addUse(GR.getSPIRVTypeID(ResType))
545bool SPIRVInstructionSelector::selectUnOp(
Register ResVReg,
548 unsigned Opcode)
const {
549 return selectUnOpWithSrc(ResVReg, ResType,
I,
I.getOperand(1).getReg(),
556 return SPIRV::Scope::Invocation;
558 return SPIRV::Scope::Device;
567 if (
MemOp->isVolatile())
568 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
569 if (
MemOp->isNonTemporal())
570 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
571 if (
MemOp->getAlign().value())
572 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned);
574 if (SpvMemOp !=
static_cast<uint32_t>(SPIRV::MemoryOperand::None)) {
576 if (SpvMemOp &
static_cast<uint32_t>(SPIRV::MemoryOperand::Aligned))
583 if (Flags & MachineMemOperand::Flags::MOVolatile)
584 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Volatile);
585 if (Flags & MachineMemOperand::Flags::MONonTemporal)
586 SpvMemOp |=
static_cast<uint32_t>(SPIRV::MemoryOperand::Nontemporal);
588 if (SpvMemOp !=
static_cast<uint32_t>(SPIRV::MemoryOperand::None))
592bool SPIRVInstructionSelector::selectLoad(
Register ResVReg,
595 unsigned OpOffset = isa<GIntrinsic>(
I) ? 1 : 0;
597 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpLoad))
599 .
addUse(GR.getSPIRVTypeID(ResType))
601 if (!
I.getNumMemOperands()) {
602 assert(
I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ||
604 TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
609 return MIB.constrainAllUses(
TII,
TRI, RBI);
612bool SPIRVInstructionSelector::selectStore(
MachineInstr &
I)
const {
613 unsigned OpOffset = isa<GIntrinsic>(
I) ? 1 : 0;
614 Register StoreVal =
I.getOperand(0 + OpOffset).getReg();
617 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpStore))
620 if (!
I.getNumMemOperands()) {
621 assert(
I.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS ||
623 TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS);
628 return MIB.constrainAllUses(
TII,
TRI, RBI);
631bool SPIRVInstructionSelector::selectMemOperation(
Register ResVReg,
634 Register SrcReg =
I.getOperand(1).getReg();
635 if (
I.getOpcode() == TargetOpcode::G_MEMSET) {
636 assert(
I.getOperand(1).isReg() &&
I.getOperand(2).isReg());
639 SPIRVType *ValTy = GR.getOrCreateSPIRVIntegerType(8,
I,
TII);
640 SPIRVType *ArrTy = GR.getOrCreateSPIRVArrayType(ValTy, Num,
I,
TII);
642 SPIRVType *VarTy = GR.getOrCreateSPIRVPointerType(
643 ArrTy,
I,
TII, SPIRV::StorageClass::UniformConstant);
645 Type *LLVMArrTy = ArrayType::get(
650 GR.add(GV, GR.CurMF, VarReg);
653 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVariable))
655 .
addUse(GR.getSPIRVTypeID(VarTy))
656 .
addImm(SPIRV::StorageClass::UniformConstant)
659 SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
660 ValTy,
I,
TII, SPIRV::StorageClass::UniformConstant);
662 selectUnOpWithSrc(SrcReg, SourceTy,
I, VarReg, SPIRV::OpBitcast);
664 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCopyMemorySized))
665 .
addUse(
I.getOperand(0).getReg())
667 .
addUse(
I.getOperand(2).getReg());
668 if (
I.getNumMemOperands())
671 if (ResVReg.
isValid() && ResVReg != MIB->getOperand(0).getReg())
672 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY), ResVReg)
673 .
addUse(MIB->getOperand(0).getReg());
677bool SPIRVInstructionSelector::selectAtomicRMW(
Register ResVReg,
680 unsigned NewOpcode)
const {
684 Register ScopeReg = buildI32Constant(Scope,
I);
692 Register MemSemReg = buildI32Constant(MemSem ,
I);
694 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(NewOpcode))
696 .
addUse(GR.getSPIRVTypeID(ResType))
700 .
addUse(
I.getOperand(2).getReg())
704bool SPIRVInstructionSelector::selectFence(
MachineInstr &
I)
const {
707 Register MemSemReg = buildI32Constant(MemSem,
I);
710 Register ScopeReg = buildI32Constant(Scope,
I);
712 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemoryBarrier))
718bool SPIRVInstructionSelector::selectAtomicCmpXchg(
Register ResVReg,
725 if (!isa<GIntrinsic>(
I)) {
729 ScopeReg = buildI32Constant(Scope,
I);
731 unsigned ScSem =
static_cast<uint32_t>(
735 MemSemEqReg = buildI32Constant(MemSemEq,
I);
739 MemSemEq == MemSemNeq ? MemSemEqReg : buildI32Constant(MemSemNeq,
I);
741 ScopeReg =
I.getOperand(5).getReg();
742 MemSemEqReg =
I.getOperand(6).getReg();
743 MemSemNeqReg =
I.getOperand(7).getReg();
748 SPIRVType *SpvValTy = GR.getSPIRVTypeForVReg(Val);
749 Register ACmpRes =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
752 BuildMI(*
I.getParent(),
I,
DL,
TII.get(SPIRV::OpAtomicCompareExchange))
754 .
addUse(GR.getSPIRVTypeID(SpvValTy))
762 Register CmpSuccReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
766 .
addUse(GR.getSPIRVTypeID(BoolTy))
770 Register TmpReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
773 .
addUse(GR.getSPIRVTypeID(ResType))
780 .
addUse(GR.getSPIRVTypeID(ResType))
790 case SPIRV::StorageClass::Workgroup:
791 case SPIRV::StorageClass::CrossWorkgroup:
792 case SPIRV::StorageClass::Function:
804bool SPIRVInstructionSelector::selectAddrSpaceCast(
Register ResVReg,
809 auto UIs =
MRI->use_instructions(ResVReg);
810 if (!UIs.empty() && ++UIs.begin() == UIs.end() &&
811 (UIs.begin()->getOpcode() == SPIRV::OpConstantComposite ||
812 UIs.begin()->getOpcode() == SPIRV::OpVariable ||
814 Register NewReg =
I.getOperand(1).getReg();
816 SPIRVType *SpvBaseTy = GR.getOrCreateSPIRVIntegerType(8,
I,
TII);
817 ResType = GR.getOrCreateSPIRVPointerType(SpvBaseTy,
I,
TII,
818 SPIRV::StorageClass::Generic);
820 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSpecConstantOp))
822 .
addUse(GR.getSPIRVTypeID(ResType))
828 Register SrcPtr =
I.getOperand(1).getReg();
829 SPIRVType *SrcPtrTy = GR.getSPIRVTypeForVReg(SrcPtr);
830 SPIRV::StorageClass::StorageClass SrcSC = GR.getPointerStorageClass(SrcPtr);
831 SPIRV::StorageClass::StorageClass DstSC = GR.getPointerStorageClass(ResVReg);
835 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpPtrCastToGeneric);
838 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpGenericCastToPtr);
841 Register Tmp =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
842 SPIRVType *GenericPtrTy = GR.getOrCreateSPIRVPointerType(
843 SrcPtrTy,
I,
TII, SPIRV::StorageClass::Generic);
848 .
addUse(GR.getSPIRVTypeID(GenericPtrTy))
853 .
addUse(GR.getSPIRVTypeID(ResType))
859 return selectUnOp(ResVReg, ResType,
I, SPIRV::OpBitcast);
866 return SPIRV::OpFOrdEqual;
868 return SPIRV::OpFOrdGreaterThanEqual;
870 return SPIRV::OpFOrdGreaterThan;
872 return SPIRV::OpFOrdLessThanEqual;
874 return SPIRV::OpFOrdLessThan;
876 return SPIRV::OpFOrdNotEqual;
878 return SPIRV::OpOrdered;
880 return SPIRV::OpFUnordEqual;
882 return SPIRV::OpFUnordGreaterThanEqual;
884 return SPIRV::OpFUnordGreaterThan;
886 return SPIRV::OpFUnordLessThanEqual;
888 return SPIRV::OpFUnordLessThan;
890 return SPIRV::OpFUnordNotEqual;
892 return SPIRV::OpUnordered;
902 return SPIRV::OpIEqual;
904 return SPIRV::OpINotEqual;
906 return SPIRV::OpSGreaterThanEqual;
908 return SPIRV::OpSGreaterThan;
910 return SPIRV::OpSLessThanEqual;
912 return SPIRV::OpSLessThan;
914 return SPIRV::OpUGreaterThanEqual;
916 return SPIRV::OpUGreaterThan;
918 return SPIRV::OpULessThanEqual;
920 return SPIRV::OpULessThan;
929 return SPIRV::OpPtrEqual;
931 return SPIRV::OpPtrNotEqual;
942 return SPIRV::OpLogicalEqual;
944 return SPIRV::OpLogicalNotEqual;
950bool SPIRVInstructionSelector::selectBitreverse(
Register ResVReg,
954 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBitReverse))
956 .
addUse(GR.getSPIRVTypeID(ResType))
957 .
addUse(
I.getOperand(1).getReg())
961bool SPIRVInstructionSelector::selectConstVector(
Register ResVReg,
971 SPIRVType *ConstTy = this->MRI->getVRegDef(MO.getReg());
972 assert(ConstTy && ConstTy->getOpcode() == SPIRV::ASSIGN_TYPE &&
973 ConstTy->getOperand(1).isReg());
974 Register ConstReg = ConstTy->getOperand(1).getReg();
975 const MachineInstr *Const = this->MRI->getVRegDef(ConstReg);
977 return (Const->getOpcode() == TargetOpcode::G_CONSTANT ||
978 Const->getOpcode() == TargetOpcode::G_FCONSTANT);
981 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
982 TII.get(SPIRV::OpConstantComposite))
984 .
addUse(GR.getSPIRVTypeID(ResType));
985 for (
unsigned i =
I.getNumExplicitDefs(); i <
I.getNumExplicitOperands(); ++i)
986 MIB.
addUse(
I.getOperand(i).getReg());
990bool SPIRVInstructionSelector::selectCmp(
Register ResVReg,
994 Register Cmp0 =
I.getOperand(2).getReg();
995 Register Cmp1 =
I.getOperand(3).getReg();
996 assert(GR.getSPIRVTypeForVReg(Cmp0)->getOpcode() ==
997 GR.getSPIRVTypeForVReg(Cmp1)->getOpcode() &&
998 "CMP operands should have the same type");
999 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(CmpOpc))
1001 .
addUse(GR.getSPIRVTypeID(ResType))
1007bool SPIRVInstructionSelector::selectICmp(
Register ResVReg,
1010 auto Pred =
I.getOperand(1).getPredicate();
1013 Register CmpOperand =
I.getOperand(2).getReg();
1014 if (GR.isScalarOfType(CmpOperand, SPIRV::OpTypePointer))
1016 else if (GR.isScalarOrVectorOfType(CmpOperand, SPIRV::OpTypeBool))
1020 return selectCmp(ResVReg, ResType, CmpOpc,
I);
1026 assert(
I.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 &&
1027 "Expected G_FCONSTANT");
1028 const ConstantFP *FPImm =
I.getOperand(1).getFPImm();
1035 assert(
I.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1036 "Expected G_CONSTANT");
1037 addNumImm(
I.getOperand(1).getCImm()->getValue(), MIB);
1045 ResType ? ResType : GR.getOrCreateSPIRVIntegerType(32,
I,
TII);
1048 Register NewReg = GR.find(ConstInt, GR.CurMF);
1051 GR.add(ConstInt, GR.CurMF, NewReg);
1055 MI =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1057 .
addUse(GR.getSPIRVTypeID(SpvI32Ty));
1059 MI =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantI))
1061 .
addUse(GR.getSPIRVTypeID(SpvI32Ty))
1069bool SPIRVInstructionSelector::selectFCmp(
Register ResVReg,
1073 return selectCmp(ResVReg, ResType, CmpOp,
I);
1078 if (ResType->
getOpcode() == SPIRV::OpTypeVector)
1079 return GR.getOrCreateConsIntVector(0,
I, ResType,
TII);
1080 return GR.getOrCreateConstInt(0,
I, ResType,
TII);
1086 unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
1089 if (ResType->
getOpcode() == SPIRV::OpTypeVector)
1094bool SPIRVInstructionSelector::selectSelect(
Register ResVReg,
1097 bool IsSigned)
const {
1099 Register ZeroReg = buildZerosVal(ResType,
I);
1100 Register OneReg = buildOnesVal(IsSigned, ResType,
I);
1102 GR.isScalarOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool);
1104 IsScalarBool ? SPIRV::OpSelectSISCond : SPIRV::OpSelectSIVCond;
1105 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
1107 .
addUse(GR.getSPIRVTypeID(ResType))
1108 .
addUse(
I.getOperand(1).getReg())
1114bool SPIRVInstructionSelector::selectIToF(
Register ResVReg,
1117 unsigned Opcode)
const {
1118 Register SrcReg =
I.getOperand(1).getReg();
1121 if (GR.isScalarOrVectorOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool)) {
1122 unsigned BitWidth = GR.getScalarOrVectorBitWidth(ResType);
1124 if (ResType->
getOpcode() == SPIRV::OpTypeVector) {
1126 TmpType = GR.getOrCreateSPIRVVectorType(TmpType, NumElts,
I,
TII);
1128 SrcReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
1129 selectSelect(SrcReg, TmpType,
I,
false);
1131 return selectUnOpWithSrc(ResVReg, ResType,
I, SrcReg, Opcode);
1134bool SPIRVInstructionSelector::selectExt(
Register ResVReg,
1137 if (GR.isScalarOrVectorOfType(
I.getOperand(1).getReg(), SPIRV::OpTypeBool))
1138 return selectSelect(ResVReg, ResType,
I, IsSigned);
1139 unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
1140 return selectUnOp(ResVReg, ResType,
I, Opcode);
1143bool SPIRVInstructionSelector::selectIntToBool(
Register IntReg,
1149 Register BitIntReg =
MRI->createVirtualRegister(&SPIRV::IDRegClass);
1150 bool IsVectorTy = IntTy->
getOpcode() == SPIRV::OpTypeVector;
1151 unsigned Opcode = IsVectorTy ? SPIRV::OpBitwiseAndV : SPIRV::OpBitwiseAndS;
1153 Register One = buildOnesVal(
false, IntTy,
I);
1157 .
addUse(GR.getSPIRVTypeID(IntTy))
1161 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpINotEqual))
1163 .
addUse(GR.getSPIRVTypeID(BoolTy))
1169bool SPIRVInstructionSelector::selectTrunc(
Register ResVReg,
1172 if (GR.isScalarOrVectorOfType(ResVReg, SPIRV::OpTypeBool)) {
1173 Register IntReg =
I.getOperand(1).getReg();
1174 const SPIRVType *ArgType = GR.getSPIRVTypeForVReg(IntReg);
1175 return selectIntToBool(IntReg, ResVReg,
I, ArgType, ResType);
1177 bool IsSigned = GR.isScalarOrVectorSigned(ResType);
1178 unsigned Opcode = IsSigned ? SPIRV::OpSConvert : SPIRV::OpUConvert;
1179 return selectUnOp(ResVReg, ResType,
I, Opcode);
1182bool SPIRVInstructionSelector::selectConst(
Register ResVReg,
1186 unsigned TyOpcode = ResType->
getOpcode();
1187 assert(TyOpcode != SPIRV::OpTypePointer ||
Imm.isZero());
1189 if ((TyOpcode == SPIRV::OpTypePointer || TyOpcode == SPIRV::OpTypeEvent) &&
1191 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1193 .
addUse(GR.getSPIRVTypeID(ResType))
1195 if (TyOpcode == SPIRV::OpTypeInt) {
1196 assert(
Imm.getBitWidth() <= 64 &&
"Unsupported integer width!");
1200 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY))
1205 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantI))
1207 .
addUse(GR.getSPIRVTypeID(ResType));
1214bool SPIRVInstructionSelector::selectOpUndef(
Register ResVReg,
1217 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUndef))
1219 .
addUse(GR.getSPIRVTypeID(ResType))
1226 if (TypeInst->
getOpcode() != SPIRV::ASSIGN_TYPE)
1230 return ImmInst->
getOpcode() == TargetOpcode::G_CONSTANT;
1240bool SPIRVInstructionSelector::selectInsertVal(
Register ResVReg,
1244 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCompositeInsert))
1246 .
addUse(GR.getSPIRVTypeID(ResType))
1248 .
addUse(
I.getOperand(3).getReg())
1250 .
addUse(
I.getOperand(2).getReg());
1251 for (
unsigned i = 4; i <
I.getNumOperands(); i++)
1256bool SPIRVInstructionSelector::selectExtractVal(
Register ResVReg,
1260 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpCompositeExtract))
1262 .
addUse(GR.getSPIRVTypeID(ResType))
1263 .
addUse(
I.getOperand(2).getReg());
1264 for (
unsigned i = 3; i <
I.getNumOperands(); i++)
1269bool SPIRVInstructionSelector::selectInsertElt(
Register ResVReg,
1273 return selectInsertVal(ResVReg, ResType,
I);
1275 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorInsertDynamic))
1277 .
addUse(GR.getSPIRVTypeID(ResType))
1278 .
addUse(
I.getOperand(2).getReg())
1279 .
addUse(
I.getOperand(3).getReg())
1280 .
addUse(
I.getOperand(4).getReg())
1284bool SPIRVInstructionSelector::selectExtractElt(
Register ResVReg,
1288 return selectExtractVal(ResVReg, ResType,
I);
1290 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVectorExtractDynamic))
1292 .
addUse(GR.getSPIRVTypeID(ResType))
1293 .
addUse(
I.getOperand(2).getReg())
1294 .
addUse(
I.getOperand(3).getReg())
1298bool SPIRVInstructionSelector::selectGEP(
Register ResVReg,
1304 unsigned Opcode =
I.getOperand(2).getImm() ? SPIRV::OpInBoundsPtrAccessChain
1305 : SPIRV::OpPtrAccessChain;
1306 auto Res =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode))
1308 .
addUse(GR.getSPIRVTypeID(ResType))
1310 .
addUse(
I.getOperand(3).getReg());
1312 for (
unsigned i = 4; i <
I.getNumExplicitOperands(); ++i)
1313 Res.
addUse(
I.getOperand(i).getReg());
1317bool SPIRVInstructionSelector::selectIntrinsic(
Register ResVReg,
1322 case Intrinsic::spv_load:
1323 return selectLoad(ResVReg, ResType,
I);
1324 case Intrinsic::spv_store:
1325 return selectStore(
I);
1326 case Intrinsic::spv_extractv:
1327 return selectExtractVal(ResVReg, ResType,
I);
1328 case Intrinsic::spv_insertv:
1329 return selectInsertVal(ResVReg, ResType,
I);
1330 case Intrinsic::spv_extractelt:
1331 return selectExtractElt(ResVReg, ResType,
I);
1332 case Intrinsic::spv_insertelt:
1333 return selectInsertElt(ResVReg, ResType,
I);
1334 case Intrinsic::spv_gep:
1335 return selectGEP(ResVReg, ResType,
I);
1336 case Intrinsic::spv_unref_global:
1337 case Intrinsic::spv_init_global: {
1340 ?
MRI->getVRegDef(
I.getOperand(2).getReg())
1343 return selectGlobalValue(
MI->getOperand(0).getReg(), *
MI,
Init);
1345 case Intrinsic::spv_undef: {
1346 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUndef))
1348 .
addUse(GR.getSPIRVTypeID(ResType));
1351 case Intrinsic::spv_const_composite: {
1353 bool IsNull =
I.getNumExplicitDefs() + 1 ==
I.getNumExplicitOperands();
1355 IsNull ? SPIRV::OpConstantNull : SPIRV::OpConstantComposite;
1356 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(Opcode))
1358 .
addUse(GR.getSPIRVTypeID(ResType));
1361 for (
unsigned i =
I.getNumExplicitDefs() + 1;
1362 i <
I.getNumExplicitOperands(); ++i) {
1363 MIB.
addUse(
I.getOperand(i).getReg());
1368 case Intrinsic::spv_assign_name: {
1369 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName));
1370 MIB.
addUse(
I.getOperand(
I.getNumExplicitDefs() + 1).getReg());
1371 for (
unsigned i =
I.getNumExplicitDefs() + 2;
1372 i <
I.getNumExplicitOperands(); ++i) {
1373 MIB.
addImm(
I.getOperand(i).getImm());
1377 case Intrinsic::spv_switch: {
1378 auto MIB =
BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpSwitch));
1379 for (
unsigned i = 1; i <
I.getNumExplicitOperands(); ++i) {
1380 if (
I.getOperand(i).isReg())
1381 MIB.
addReg(
I.getOperand(i).getReg());
1382 else if (
I.getOperand(i).isCImm())
1383 addNumImm(
I.getOperand(i).getCImm()->getValue(), MIB);
1384 else if (
I.getOperand(i).isMBB())
1385 MIB.
addMBB(
I.getOperand(i).getMBB());
1391 case Intrinsic::spv_cmpxchg:
1392 return selectAtomicCmpXchg(ResVReg, ResType,
I);
1393 case Intrinsic::spv_unreachable:
1394 BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpUnreachable));
1396 case Intrinsic::spv_alloca:
1397 return selectFrameIndex(ResVReg, ResType,
I);
1404bool SPIRVInstructionSelector::selectFrameIndex(
Register ResVReg,
1407 return BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpVariable))
1409 .
addUse(GR.getSPIRVTypeID(ResType))
1414bool SPIRVInstructionSelector::selectBranch(
MachineInstr &
I)
const {
1421 if (PrevI !=
nullptr && PrevI->
getOpcode() == TargetOpcode::G_BRCOND) {
1422 return BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBranchConditional))
1425 .
addMBB(
I.getOperand(0).getMBB())
1429 .
addMBB(
I.getOperand(0).getMBB())
1433bool SPIRVInstructionSelector::selectBranchCond(
MachineInstr &
I)
const {
1446 if (NextI !=
nullptr && NextI->
getOpcode() == SPIRV::OpBranchConditional)
1453 return BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpBranchConditional))
1454 .
addUse(
I.getOperand(0).getReg())
1455 .
addMBB(
I.getOperand(1).getMBB())
1460bool SPIRVInstructionSelector::selectPhi(
Register ResVReg,
1463 auto MIB =
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpPhi))
1465 .
addUse(GR.getSPIRVTypeID(ResType));
1466 const unsigned NumOps =
I.getNumOperands();
1467 for (
unsigned i = 1; i < NumOps; i += 2) {
1468 MIB.
addUse(
I.getOperand(i + 0).getReg());
1469 MIB.
addMBB(
I.getOperand(i + 1).getMBB());
1474bool SPIRVInstructionSelector::selectGlobalValue(
1484 SPIRV::AccessQualifier::ReadWrite,
false);
1485 PointerBaseType = GR.getOrCreateSPIRVArrayType(
1488 PointerBaseType = GR.getOrCreateSPIRVType(
1489 GVType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
false);
1491 SPIRVType *ResType = GR.getOrCreateSPIRVPointerType(
1492 PointerBaseType,
I,
TII,
1499 if (isa<Function>(GV)) {
1502 Register NewReg = GR.find(ConstVal, GR.CurMF);
1505 GR.add(ConstVal, GR.CurMF, NewReg);
1506 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpConstantNull))
1508 .
addUse(GR.getSPIRVTypeID(ResType))
1511 assert(NewReg != ResVReg);
1512 return BuildMI(BB,
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY))
1517 auto GlobalVar = cast<GlobalVariable>(GV);
1520 bool HasInit =
GlobalVar->hasInitializer() &&
1521 !isa<UndefValue>(
GlobalVar->getInitializer());
1524 if (HasInit && !
Init)
1528 SPIRV::StorageClass::StorageClass Storage =
1531 Storage != SPIRV::StorageClass::Function;
1532 SPIRV::LinkageType::LinkageType LnkType =
1534 ? SPIRV::LinkageType::Import
1535 : SPIRV::LinkageType::Export;
1537 Register Reg = GR.buildGlobalVariable(ResVReg, ResType, GlobalIdent, GV,
1539 HasLnkTy, LnkType, MIRBuilder,
true);
1540 return Reg.isValid();
1548 return new SPIRVInstructionSelector(
TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
static unsigned getIntrinsicID(const SDNode *N)
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
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
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
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).
Type * getValueType() const
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.
bool isArrayTy() const
True if this is an instance of ArrayType.
Type * getArrayElementType() const
uint64_t getArrayNumElements() const
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...
NodeAddr< DefNode * > Def
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)