LLVM 22.0.0git
SPIRVGlobalRegistry.cpp
Go to the documentation of this file.
1//===-- SPIRVGlobalRegistry.cpp - SPIR-V Global Registry --------*- 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// This file contains the implementation of the SPIRVGlobalRegistry class,
10// which is used to maintain rich type information required for SPIR-V even
11// after lowering from LLVM IR to GMIR. It can convert an llvm::Type into
12// an OpTypeXXX instruction, and map it to a virtual register. Also it builds
13// and supports consistency of constants and global variables.
14//
15//===----------------------------------------------------------------------===//
16
17#include "SPIRVGlobalRegistry.h"
18#include "SPIRV.h"
19#include "SPIRVBuiltins.h"
20#include "SPIRVSubtarget.h"
21#include "SPIRVUtils.h"
22#include "llvm/ADT/APInt.h"
23#include "llvm/IR/Constants.h"
25#include "llvm/IR/Intrinsics.h"
26#include "llvm/IR/IntrinsicsSPIRV.h"
27#include "llvm/IR/Type.h"
30#include <cassert>
31#include <functional>
32
33using namespace llvm;
34
35static bool allowEmitFakeUse(const Value *Arg) {
36 if (isSpvIntrinsic(Arg))
37 return false;
38 if (isa<AtomicCmpXchgInst, InsertValueInst, UndefValue>(Arg))
39 return false;
40 if (const auto *LI = dyn_cast<LoadInst>(Arg))
41 if (LI->getType()->isAggregateType())
42 return false;
43 return true;
44}
45
46static unsigned typeToAddressSpace(const Type *Ty) {
47 if (auto PType = dyn_cast<TypedPointerType>(Ty))
48 return PType->getAddressSpace();
49 if (auto PType = dyn_cast<PointerType>(Ty))
50 return PType->getAddressSpace();
51 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
52 ExtTy && isTypedPointerWrapper(ExtTy))
53 return ExtTy->getIntParameter(0);
54 reportFatalInternalError("Unable to convert LLVM type to SPIRVType");
55}
56
57static bool
58storageClassRequiresExplictLayout(SPIRV::StorageClass::StorageClass SC) {
59 switch (SC) {
60 case SPIRV::StorageClass::Uniform:
61 case SPIRV::StorageClass::PushConstant:
62 case SPIRV::StorageClass::StorageBuffer:
63 case SPIRV::StorageClass::PhysicalStorageBufferEXT:
64 return true;
65 case SPIRV::StorageClass::UniformConstant:
66 case SPIRV::StorageClass::Input:
67 case SPIRV::StorageClass::Output:
68 case SPIRV::StorageClass::Workgroup:
69 case SPIRV::StorageClass::CrossWorkgroup:
70 case SPIRV::StorageClass::Private:
71 case SPIRV::StorageClass::Function:
72 case SPIRV::StorageClass::Generic:
73 case SPIRV::StorageClass::AtomicCounter:
74 case SPIRV::StorageClass::Image:
75 case SPIRV::StorageClass::CallableDataNV:
76 case SPIRV::StorageClass::IncomingCallableDataNV:
77 case SPIRV::StorageClass::RayPayloadNV:
78 case SPIRV::StorageClass::HitAttributeNV:
79 case SPIRV::StorageClass::IncomingRayPayloadNV:
80 case SPIRV::StorageClass::ShaderRecordBufferNV:
81 case SPIRV::StorageClass::CodeSectionINTEL:
82 case SPIRV::StorageClass::DeviceOnlyINTEL:
83 case SPIRV::StorageClass::HostOnlyINTEL:
84 return false;
85 }
86 llvm_unreachable("Unknown SPIRV::StorageClass enum");
87}
88
90 : PointerSize(PointerSize), Bound(0), CurMF(nullptr) {}
91
93 Register VReg,
95 const SPIRVInstrInfo &TII) {
97 assignSPIRVTypeToVReg(SpirvType, VReg, *CurMF);
98 return SpirvType;
99}
100
101SPIRVType *
104 const SPIRVInstrInfo &TII) {
106 assignSPIRVTypeToVReg(SpirvType, VReg, *CurMF);
107 return SpirvType;
108}
109
111 SPIRVType *BaseType, unsigned NumElements, Register VReg, MachineInstr &I,
112 const SPIRVInstrInfo &TII) {
113 SPIRVType *SpirvType =
115 assignSPIRVTypeToVReg(SpirvType, VReg, *CurMF);
116 return SpirvType;
117}
118
120 const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder,
121 SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
122 SPIRVType *SpirvType =
123 getOrCreateSPIRVType(Type, MIRBuilder, AccessQual, EmitIR);
124 assignSPIRVTypeToVReg(SpirvType, VReg, MIRBuilder.getMF());
125 return SpirvType;
126}
127
129 Register VReg,
130 const MachineFunction &MF) {
131 VRegToTypeMap[&MF][VReg] = SpirvType;
132}
133
135 auto Res = MRI.createGenericVirtualRegister(LLT::scalar(64));
136 MRI.setRegClass(Res, &SPIRV::TYPERegClass);
137 return Res;
138}
139
141 return createTypeVReg(MIRBuilder.getMF().getRegInfo());
142}
143
144SPIRVType *SPIRVGlobalRegistry::getOpTypeBool(MachineIRBuilder &MIRBuilder) {
145 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
146 return MIRBuilder.buildInstr(SPIRV::OpTypeBool)
147 .addDef(createTypeVReg(MIRBuilder));
148 });
149}
150
151unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(unsigned Width) const {
152 if (Width > 64)
153 report_fatal_error("Unsupported integer width!");
154 const SPIRVSubtarget &ST = cast<SPIRVSubtarget>(CurMF->getSubtarget());
155 if (ST.canUseExtension(
156 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
157 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4))
158 return Width;
159 if (Width <= 8)
160 Width = 8;
161 else if (Width <= 16)
162 Width = 16;
163 else if (Width <= 32)
164 Width = 32;
165 else
166 Width = 64;
167 return Width;
168}
169
170SPIRVType *SPIRVGlobalRegistry::getOpTypeInt(unsigned Width,
171 MachineIRBuilder &MIRBuilder,
172 bool IsSigned) {
173 Width = adjustOpTypeIntWidth(Width);
174 const SPIRVSubtarget &ST =
175 cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
176 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
177 if (Width == 4 && ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
178 MIRBuilder.buildInstr(SPIRV::OpExtension)
179 .addImm(SPIRV::Extension::SPV_INTEL_int4);
180 MIRBuilder.buildInstr(SPIRV::OpCapability)
181 .addImm(SPIRV::Capability::Int4TypeINTEL);
182 } else if ((!isPowerOf2_32(Width) || Width < 8) &&
183 ST.canUseExtension(
184 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers)) {
185 MIRBuilder.buildInstr(SPIRV::OpExtension)
186 .addImm(SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers);
187 MIRBuilder.buildInstr(SPIRV::OpCapability)
188 .addImm(SPIRV::Capability::ArbitraryPrecisionIntegersINTEL);
189 }
190 return MIRBuilder.buildInstr(SPIRV::OpTypeInt)
191 .addDef(createTypeVReg(MIRBuilder))
192 .addImm(Width)
193 .addImm(IsSigned ? 1 : 0);
194 });
195}
196
197SPIRVType *SPIRVGlobalRegistry::getOpTypeFloat(uint32_t Width,
198 MachineIRBuilder &MIRBuilder) {
199 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
200 return MIRBuilder.buildInstr(SPIRV::OpTypeFloat)
201 .addDef(createTypeVReg(MIRBuilder))
202 .addImm(Width);
203 });
204}
205
206SPIRVType *SPIRVGlobalRegistry::getOpTypeVoid(MachineIRBuilder &MIRBuilder) {
207 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
208 return MIRBuilder.buildInstr(SPIRV::OpTypeVoid)
209 .addDef(createTypeVReg(MIRBuilder));
210 });
211}
212
214 // TODO:
215 // - review other data structure wrt. possible issues related to removal
216 // of a machine instruction during instruction selection.
217 const MachineFunction *MF = MI->getMF();
218 auto It = LastInsertedTypeMap.find(MF);
219 if (It == LastInsertedTypeMap.end())
220 return;
221 if (It->second == MI)
222 LastInsertedTypeMap.erase(MF);
223 // remove from the duplicate tracker to avoid incorrect reuse
224 erase(MI);
225}
226
227SPIRVType *SPIRVGlobalRegistry::createOpType(
228 MachineIRBuilder &MIRBuilder,
229 std::function<MachineInstr *(MachineIRBuilder &)> Op) {
230 auto oldInsertPoint = MIRBuilder.getInsertPt();
231 MachineBasicBlock *OldMBB = &MIRBuilder.getMBB();
232 MachineBasicBlock *NewMBB = &*MIRBuilder.getMF().begin();
233
234 auto LastInsertedType = LastInsertedTypeMap.find(CurMF);
235 if (LastInsertedType != LastInsertedTypeMap.end()) {
236 auto It = LastInsertedType->second->getIterator();
237 // It might happen that this instruction was removed from the first MBB,
238 // hence the Parent's check.
240 if (It->getParent() != NewMBB)
241 InsertAt = oldInsertPoint->getParent() == NewMBB
242 ? oldInsertPoint
243 : getInsertPtValidEnd(NewMBB);
244 else if (It->getNextNode())
245 InsertAt = It->getNextNode()->getIterator();
246 else
247 InsertAt = getInsertPtValidEnd(NewMBB);
248 MIRBuilder.setInsertPt(*NewMBB, InsertAt);
249 } else {
250 MIRBuilder.setInsertPt(*NewMBB, NewMBB->begin());
251 auto Result = LastInsertedTypeMap.try_emplace(CurMF, nullptr);
252 assert(Result.second);
253 LastInsertedType = Result.first;
254 }
255
256 MachineInstr *Type = Op(MIRBuilder);
257 // We expect all users of this function to insert definitions at the insertion
258 // point set above that is always the first MBB.
259 assert(Type->getParent() == NewMBB);
260 LastInsertedType->second = Type;
261
262 MIRBuilder.setInsertPt(*OldMBB, oldInsertPoint);
263 return Type;
264}
265
266SPIRVType *SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
267 SPIRVType *ElemType,
268 MachineIRBuilder &MIRBuilder) {
269 auto EleOpc = ElemType->getOpcode();
270 (void)EleOpc;
271 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
272 EleOpc == SPIRV::OpTypeBool) &&
273 "Invalid vector element type");
274
275 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
276 return MIRBuilder.buildInstr(SPIRV::OpTypeVector)
277 .addDef(createTypeVReg(MIRBuilder))
278 .addUse(getSPIRVTypeID(ElemType))
279 .addImm(NumElems);
280 });
281}
282
284 SPIRVType *SpvType,
285 const SPIRVInstrInfo &TII,
286 bool ZeroAsNull) {
288 auto *const CF = ConstantFP::get(Ctx, Val);
289 const MachineInstr *MI = findMI(CF, CurMF);
290 if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
291 MI->getOpcode() == SPIRV::OpConstantF))
292 return MI->getOperand(0).getReg();
293 return createConstFP(CF, I, SpvType, TII, ZeroAsNull);
294}
295
297 MachineInstr &I, SPIRVType *SpvType,
298 const SPIRVInstrInfo &TII,
299 bool ZeroAsNull) {
300 unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
301 LLT LLTy = LLT::scalar(BitWidth);
303 CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
305
306 MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
307 MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
308 SPIRVType *NewType =
309 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
311 // In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
312 if (CF->getValue().isPosZero() && ZeroAsNull) {
313 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
314 .addDef(Res)
315 .addUse(getSPIRVTypeID(SpvType));
316 } else {
317 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
318 .addDef(Res)
319 .addUse(getSPIRVTypeID(SpvType));
320 addNumImm(APInt(BitWidth,
321 CF->getValueAPF().bitcastToAPInt().getZExtValue()),
322 MIB);
323 }
324 const auto &ST = CurMF->getSubtarget();
325 constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
326 *ST.getRegisterInfo(),
327 *ST.getRegBankInfo());
328 return MIB;
329 });
330 add(CF, NewType);
331 return Res;
332}
333
335 SPIRVType *SpvType,
336 const SPIRVInstrInfo &TII,
337 bool ZeroAsNull) {
338 const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
339 auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
340 const MachineInstr *MI = findMI(CI, CurMF);
341 if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
342 MI->getOpcode() == SPIRV::OpConstantI))
343 return MI->getOperand(0).getReg();
344 return createConstInt(CI, I, SpvType, TII, ZeroAsNull);
345}
346
349 SPIRVType *SpvType,
350 const SPIRVInstrInfo &TII,
351 bool ZeroAsNull) {
352 unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
353 LLT LLTy = LLT::scalar(BitWidth);
355 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
357
358 MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
359 MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
360 SPIRVType *NewType =
361 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
363 if (BitWidth == 1) {
364 MIB = MIRBuilder
365 .buildInstr(CI->isZero() ? SPIRV::OpConstantFalse
366 : SPIRV::OpConstantTrue)
367 .addDef(Res)
368 .addUse(getSPIRVTypeID(SpvType));
369 } else if (!CI->isZero() || !ZeroAsNull) {
370 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
371 .addDef(Res)
372 .addUse(getSPIRVTypeID(SpvType));
373 addNumImm(APInt(BitWidth, CI->getZExtValue()), MIB);
374 } else {
375 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
376 .addDef(Res)
377 .addUse(getSPIRVTypeID(SpvType));
378 }
379 const auto &ST = CurMF->getSubtarget();
380 constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
381 *ST.getRegisterInfo(),
382 *ST.getRegBankInfo());
383 return MIB;
384 });
385 add(CI, NewType);
386 return Res;
387}
388
390 MachineIRBuilder &MIRBuilder,
391 SPIRVType *SpvType, bool EmitIR,
392 bool ZeroAsNull) {
393 assert(SpvType);
394 auto &MF = MIRBuilder.getMF();
395 const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
396 auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
397 Register Res = find(CI, &MF);
398 if (Res.isValid())
399 return Res;
400
401 unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
402 LLT LLTy = LLT::scalar(BitWidth);
403 MachineRegisterInfo &MRI = MF.getRegInfo();
404 Res = MRI.createGenericVirtualRegister(LLTy);
405 MRI.setRegClass(Res, &SPIRV::iIDRegClass);
406 assignTypeToVReg(Ty, Res, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
407 EmitIR);
408
409 SPIRVType *NewType =
410 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
411 if (EmitIR)
412 return MIRBuilder.buildConstant(Res, *CI);
413 Register SpvTypeReg = getSPIRVTypeID(SpvType);
415 if (Val || !ZeroAsNull) {
416 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
417 .addDef(Res)
418 .addUse(SpvTypeReg);
419 addNumImm(APInt(BitWidth, Val), MIB);
420 } else {
421 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
422 .addDef(Res)
423 .addUse(SpvTypeReg);
424 }
425 const auto &Subtarget = CurMF->getSubtarget();
426 constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
427 *Subtarget.getRegisterInfo(),
428 *Subtarget.getRegBankInfo());
429 return MIB;
430 });
431 add(CI, NewType);
432 return Res;
433}
434
436 MachineIRBuilder &MIRBuilder,
437 SPIRVType *SpvType) {
438 auto &MF = MIRBuilder.getMF();
439 LLVMContext &Ctx = MF.getFunction().getContext();
440 if (!SpvType)
441 SpvType = getOrCreateSPIRVType(Type::getFloatTy(Ctx), MIRBuilder,
442 SPIRV::AccessQualifier::ReadWrite, true);
443 auto *const CF = ConstantFP::get(Ctx, Val);
444 Register Res = find(CF, &MF);
445 if (Res.isValid())
446 return Res;
447
449 Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
450 MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
451 assignSPIRVTypeToVReg(SpvType, Res, MF);
452
453 SPIRVType *NewType =
454 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
456 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
457 .addDef(Res)
458 .addUse(getSPIRVTypeID(SpvType));
459 addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
460 return MIB;
461 });
462 add(CF, NewType);
463 return Res;
464}
465
466Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
467 Constant *Val, MachineInstr &I, SPIRVType *SpvType,
468 const SPIRVInstrInfo &TII, unsigned BitWidth, bool ZeroAsNull) {
469 SPIRVType *Type = SpvType;
470 if (SpvType->getOpcode() == SPIRV::OpTypeVector ||
471 SpvType->getOpcode() == SPIRV::OpTypeArray) {
472 auto EleTypeReg = SpvType->getOperand(1).getReg();
473 Type = getSPIRVTypeForVReg(EleTypeReg);
474 }
475 if (Type->getOpcode() == SPIRV::OpTypeFloat) {
477 return getOrCreateConstFP(cast<ConstantFP>(Val)->getValue(), I, SpvBaseType,
478 TII, ZeroAsNull);
479 }
480 assert(Type->getOpcode() == SPIRV::OpTypeInt);
483 SpvBaseType, TII, ZeroAsNull);
484}
485
486Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
487 Constant *Val, MachineInstr &I, SPIRVType *SpvType,
488 const SPIRVInstrInfo &TII, Constant *CA, unsigned BitWidth,
489 unsigned ElemCnt, bool ZeroAsNull) {
490 if (Register R = find(CA, CurMF); R.isValid())
491 return R;
492
493 bool IsNull = Val->isNullValue() && ZeroAsNull;
494 Register ElemReg;
495 if (!IsNull)
496 ElemReg =
497 getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
498
499 LLT LLTy = LLT::scalar(64);
501 CurMF->getRegInfo().setRegClass(Res, getRegClass(SpvType));
502 assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
503
504 MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
505 MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
506 const MachineInstr *NewMI =
507 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
509 if (!IsNull) {
510 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
511 .addDef(Res)
512 .addUse(getSPIRVTypeID(SpvType));
513 for (unsigned i = 0; i < ElemCnt; ++i)
514 MIB.addUse(ElemReg);
515 } else {
516 MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
517 .addDef(Res)
518 .addUse(getSPIRVTypeID(SpvType));
519 }
520 const auto &Subtarget = CurMF->getSubtarget();
521 constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
522 *Subtarget.getRegisterInfo(),
523 *Subtarget.getRegBankInfo());
524 return MIB;
525 });
526 add(CA, NewMI);
527 return Res;
528}
529
532 SPIRVType *SpvType,
533 const SPIRVInstrInfo &TII,
534 bool ZeroAsNull) {
535 const Type *LLVMTy = getTypeForSPIRVType(SpvType);
536 assert(LLVMTy->isVectorTy());
537 const FixedVectorType *LLVMVecTy = cast<FixedVectorType>(LLVMTy);
538 Type *LLVMBaseTy = LLVMVecTy->getElementType();
539 assert(LLVMBaseTy->isIntegerTy());
540 auto *ConstVal = ConstantInt::get(LLVMBaseTy, Val);
541 auto *ConstVec =
542 ConstantVector::getSplat(LLVMVecTy->getElementCount(), ConstVal);
543 unsigned BW = getScalarOrVectorBitWidth(SpvType);
544 return getOrCreateCompositeOrNull(ConstVal, I, SpvType, TII, ConstVec, BW,
545 SpvType->getOperand(2).getImm(),
546 ZeroAsNull);
547}
548
551 SPIRVType *SpvType,
552 const SPIRVInstrInfo &TII,
553 bool ZeroAsNull) {
554 const Type *LLVMTy = getTypeForSPIRVType(SpvType);
555 assert(LLVMTy->isVectorTy());
556 const FixedVectorType *LLVMVecTy = cast<FixedVectorType>(LLVMTy);
557 Type *LLVMBaseTy = LLVMVecTy->getElementType();
558 assert(LLVMBaseTy->isFloatingPointTy());
559 auto *ConstVal = ConstantFP::get(LLVMBaseTy, Val);
560 auto *ConstVec =
561 ConstantVector::getSplat(LLVMVecTy->getElementCount(), ConstVal);
562 unsigned BW = getScalarOrVectorBitWidth(SpvType);
563 return getOrCreateCompositeOrNull(ConstVal, I, SpvType, TII, ConstVec, BW,
564 SpvType->getOperand(2).getImm(),
565 ZeroAsNull);
566}
567
569 uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType,
570 const SPIRVInstrInfo &TII) {
571 const Type *LLVMTy = getTypeForSPIRVType(SpvType);
572 assert(LLVMTy->isArrayTy());
573 const ArrayType *LLVMArrTy = cast<ArrayType>(LLVMTy);
574 Type *LLVMBaseTy = LLVMArrTy->getElementType();
575 Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
576 SPIRVType *SpvBaseTy = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
577 unsigned BW = getScalarOrVectorBitWidth(SpvBaseTy);
578 // The following is reasonably unique key that is better that [Val]. The naive
579 // alternative would be something along the lines of:
580 // SmallVector<Constant *> NumCI(Num, CI);
581 // Constant *UniqueKey =
582 // ConstantArray::get(const_cast<ArrayType*>(LLVMArrTy), NumCI);
583 // that would be a truly unique but dangerous key, because it could lead to
584 // the creation of constants of arbitrary length (that is, the parameter of
585 // memset) which were missing in the original module.
587 {PoisonValue::get(const_cast<ArrayType *>(LLVMArrTy)),
588 ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(LLVMBaseTy, Num)});
589 return getOrCreateCompositeOrNull(CI, I, SpvType, TII, UniqueKey, BW,
590 LLVMArrTy->getNumElements());
591}
592
593Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
594 uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR,
595 Constant *CA, unsigned BitWidth, unsigned ElemCnt) {
596 if (Register R = find(CA, CurMF); R.isValid())
597 return R;
598
599 Register ElemReg;
600 if (Val || EmitIR) {
601 SPIRVType *SpvBaseType = getOrCreateSPIRVIntegerType(BitWidth, MIRBuilder);
602 ElemReg = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
603 }
604 LLT LLTy = EmitIR ? LLT::fixed_vector(ElemCnt, BitWidth) : LLT::scalar(64);
606 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
607 assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
608
609 const MachineInstr *NewMI =
610 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
611 if (EmitIR)
612 return MIRBuilder.buildSplatBuildVector(Res, ElemReg);
613
614 if (Val) {
615 auto MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
616 .addDef(Res)
617 .addUse(getSPIRVTypeID(SpvType));
618 for (unsigned i = 0; i < ElemCnt; ++i)
619 MIB.addUse(ElemReg);
620 return MIB;
621 }
622
623 return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
624 .addDef(Res)
625 .addUse(getSPIRVTypeID(SpvType));
626 });
627 add(CA, NewMI);
628 return Res;
629}
630
633 MachineIRBuilder &MIRBuilder,
634 SPIRVType *SpvType, bool EmitIR) {
635 const Type *LLVMTy = getTypeForSPIRVType(SpvType);
636 assert(LLVMTy->isVectorTy());
637 const FixedVectorType *LLVMVecTy = cast<FixedVectorType>(LLVMTy);
638 Type *LLVMBaseTy = LLVMVecTy->getElementType();
639 const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
640 auto ConstVec =
641 ConstantVector::getSplat(LLVMVecTy->getElementCount(), ConstInt);
642 unsigned BW = getScalarOrVectorBitWidth(SpvType);
643 return getOrCreateIntCompositeOrNull(Val, MIRBuilder, SpvType, EmitIR,
644 ConstVec, BW,
645 SpvType->getOperand(2).getImm());
646}
647
650 SPIRVType *SpvType) {
651 const Type *Ty = getTypeForSPIRVType(SpvType);
652 unsigned AddressSpace = typeToAddressSpace(Ty);
653 Type *ElemTy = ::getPointeeType(Ty);
654 assert(ElemTy);
656 dyn_cast<TargetExtType>(getTypedPointerWrapper(ElemTy, AddressSpace)));
657 Register Res = find(CP, CurMF);
658 if (Res.isValid())
659 return Res;
660
661 LLT LLTy = LLT::pointer(AddressSpace, PointerSize);
663 CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
664 assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
665
666 const MachineInstr *NewMI =
667 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
668 return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
669 .addDef(Res)
670 .addUse(getSPIRVTypeID(SpvType));
671 });
672 add(CP, NewMI);
673 return Res;
674}
675
678 unsigned Param, unsigned FilerMode,
679 MachineIRBuilder &MIRBuilder) {
680 auto Sampler =
681 ResReg.isValid()
682 ? ResReg
683 : MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
684 SPIRVType *TypeSampler = getOrCreateOpTypeSampler(MIRBuilder);
685 Register TypeSamplerReg = getSPIRVTypeID(TypeSampler);
686 // We cannot use createOpType() logic here, because of the
687 // GlobalISel/IRTranslator.cpp check for a tail call that expects that
688 // MIRBuilder.getInsertPt() has a previous instruction. If this constant is
689 // inserted as a result of "__translate_sampler_initializer()" this would
690 // break this IRTranslator assumption.
691 MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
692 .addDef(Sampler)
693 .addUse(TypeSamplerReg)
695 .addImm(Param)
696 .addImm(FilerMode);
697 return Sampler;
698}
699
702 const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage,
703 const MachineInstr *Init, bool IsConst, bool HasLinkageTy,
704 SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder,
705 bool IsInstSelector) {
706 const GlobalVariable *GVar = nullptr;
707 if (GV) {
708 GVar = cast<const GlobalVariable>(GV);
709 } else {
710 // If GV is not passed explicitly, use the name to find or construct
711 // the global variable.
712 Module *M = MIRBuilder.getMF().getFunction().getParent();
713 GVar = M->getGlobalVariable(Name);
714 if (GVar == nullptr) {
715 const Type *Ty = getTypeForSPIRVType(BaseType); // TODO: check type.
716 // Module takes ownership of the global var.
717 GVar = new GlobalVariable(*M, const_cast<Type *>(Ty), false,
719 Twine(Name));
720 }
721 GV = GVar;
722 }
723
724 const MachineFunction *MF = &MIRBuilder.getMF();
725 Register Reg = find(GVar, MF);
726 if (Reg.isValid()) {
727 if (Reg != ResVReg)
728 MIRBuilder.buildCopy(ResVReg, Reg);
729 return ResVReg;
730 }
731
732 auto MIB = MIRBuilder.buildInstr(SPIRV::OpVariable)
733 .addDef(ResVReg)
735 .addImm(static_cast<uint32_t>(Storage));
736 if (Init != 0)
737 MIB.addUse(Init->getOperand(0).getReg());
738 // ISel may introduce a new register on this step, so we need to add it to
739 // DT and correct its type avoiding fails on the next stage.
740 if (IsInstSelector) {
741 const auto &Subtarget = CurMF->getSubtarget();
742 constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
743 *Subtarget.getRegisterInfo(),
744 *Subtarget.getRegBankInfo());
745 }
746 add(GVar, MIB);
747
748 Reg = MIB->getOperand(0).getReg();
749 addGlobalObject(GVar, MF, Reg);
750
751 // Set to Reg the same type as ResVReg has.
752 auto MRI = MIRBuilder.getMRI();
753 if (Reg != ResVReg) {
754 LLT RegLLTy =
755 LLT::pointer(MRI->getType(ResVReg).getAddressSpace(), getPointerSize());
756 MRI->setType(Reg, RegLLTy);
757 assignSPIRVTypeToVReg(BaseType, Reg, MIRBuilder.getMF());
758 } else {
759 // Our knowledge about the type may be updated.
760 // If that's the case, we need to update a type
761 // associated with the register.
762 SPIRVType *DefType = getSPIRVTypeForVReg(ResVReg);
763 if (!DefType || DefType != BaseType)
764 assignSPIRVTypeToVReg(BaseType, Reg, MIRBuilder.getMF());
765 }
766
767 // If it's a global variable with name, output OpName for it.
768 if (GVar && GVar->hasName())
769 buildOpName(Reg, GVar->getName(), MIRBuilder);
770
771 // Output decorations for the GV.
772 // TODO: maybe move to GenerateDecorations pass.
773 const SPIRVSubtarget &ST =
774 cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
775 if (IsConst && !ST.isShader())
776 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Constant, {});
777
778 if (GVar && GVar->getAlign().valueOrOne().value() != 1 && !ST.isShader()) {
779 unsigned Alignment = (unsigned)GVar->getAlign().valueOrOne().value();
780 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::Alignment, {Alignment});
781 }
782
783 if (HasLinkageTy)
784 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::LinkageAttributes,
785 {static_cast<uint32_t>(LinkageType)}, Name);
786
787 SPIRV::BuiltIn::BuiltIn BuiltInId;
788 if (getSpirvBuiltInIdByName(Name, BuiltInId))
789 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::BuiltIn,
790 {static_cast<uint32_t>(BuiltInId)});
791
792 // If it's a global variable with "spirv.Decorations" metadata node
793 // recognize it as a SPIR-V friendly LLVM IR and parse "spirv.Decorations"
794 // arguments.
795 MDNode *GVarMD = nullptr;
796 if (GVar && (GVarMD = GVar->getMetadata("spirv.Decorations")) != nullptr)
797 buildOpSpirvDecorations(Reg, MIRBuilder, GVarMD);
798
799 return Reg;
800}
801
802// Returns a name based on the Type. Notes that this does not look at
803// decorations, and will return the same string for two types that are the same
804// except for decorations.
806 const SPIRVType *VarType, uint32_t Set, uint32_t Binding, StringRef Name,
807 MachineIRBuilder &MIRBuilder) {
808 Register VarReg =
809 MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
810
811 buildGlobalVariable(VarReg, VarType, Name, nullptr,
812 getPointerStorageClass(VarType), nullptr, false, false,
813 SPIRV::LinkageType::Import, MIRBuilder, false);
814
815 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
816 buildOpDecorate(VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
817 return VarReg;
818}
819
820// TODO: Double check the calls to getOpTypeArray to make sure that `ElemType`
821// is explicitly laid out when required.
822SPIRVType *SPIRVGlobalRegistry::getOpTypeArray(uint32_t NumElems,
823 SPIRVType *ElemType,
824 MachineIRBuilder &MIRBuilder,
825 bool ExplicitLayoutRequired,
826 bool EmitIR) {
827 assert((ElemType->getOpcode() != SPIRV::OpTypeVoid) &&
828 "Invalid array element type");
829 SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
830 SPIRVType *ArrayType = nullptr;
831 const SPIRVSubtarget &ST =
832 cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
833 if (NumElems != 0) {
834 Register NumElementsVReg =
835 buildConstantInt(NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
836 ArrayType = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
837 return MIRBuilder.buildInstr(SPIRV::OpTypeArray)
838 .addDef(createTypeVReg(MIRBuilder))
839 .addUse(getSPIRVTypeID(ElemType))
840 .addUse(NumElementsVReg);
841 });
842 } else {
843 assert(ST.isShader() && "Runtime arrays are not allowed in non-shader "
844 "SPIR-V modules.");
845 if (!ST.isShader())
846 return nullptr;
847 ArrayType = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
848 return MIRBuilder.buildInstr(SPIRV::OpTypeRuntimeArray)
849 .addDef(createTypeVReg(MIRBuilder))
850 .addUse(getSPIRVTypeID(ElemType));
851 });
852 }
853
854 if (ExplicitLayoutRequired && !isResourceType(ElemType)) {
855 Type *ET = const_cast<Type *>(getTypeForSPIRVType(ElemType));
856 addArrayStrideDecorations(ArrayType->defs().begin()->getReg(), ET,
857 MIRBuilder);
858 }
859
860 return ArrayType;
861}
862
863SPIRVType *SPIRVGlobalRegistry::getOpTypeOpaque(const StructType *Ty,
864 MachineIRBuilder &MIRBuilder) {
865 assert(Ty->hasName());
866 const StringRef Name = Ty->hasName() ? Ty->getName() : "";
867 Register ResVReg = createTypeVReg(MIRBuilder);
868 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
869 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeOpaque).addDef(ResVReg);
870 addStringImm(Name, MIB);
871 buildOpName(ResVReg, Name, MIRBuilder);
872 return MIB;
873 });
874}
875
876SPIRVType *SPIRVGlobalRegistry::getOpTypeStruct(
877 const StructType *Ty, MachineIRBuilder &MIRBuilder,
878 SPIRV::AccessQualifier::AccessQualifier AccQual,
879 StructOffsetDecorator Decorator, bool EmitIR) {
880 const SPIRVSubtarget &ST =
881 cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
882 SmallVector<Register, 4> FieldTypes;
883 constexpr unsigned MaxWordCount = UINT16_MAX;
884 const size_t NumElements = Ty->getNumElements();
885
886 size_t MaxNumElements = MaxWordCount - 2;
887 size_t SPIRVStructNumElements = NumElements;
888 if (NumElements > MaxNumElements) {
889 // Do adjustments for continued instructions.
890 SPIRVStructNumElements = MaxNumElements;
891 MaxNumElements = MaxWordCount - 1;
892 }
893
894 for (const auto &Elem : Ty->elements()) {
895 SPIRVType *ElemTy = findSPIRVType(
896 toTypedPointer(Elem), MIRBuilder, AccQual,
897 /* ExplicitLayoutRequired= */ Decorator != nullptr, EmitIR);
898 assert(ElemTy && ElemTy->getOpcode() != SPIRV::OpTypeVoid &&
899 "Invalid struct element type");
900 FieldTypes.push_back(getSPIRVTypeID(ElemTy));
901 }
902 Register ResVReg = createTypeVReg(MIRBuilder);
903 if (Ty->hasName())
904 buildOpName(ResVReg, Ty->getName(), MIRBuilder);
905 if (Ty->isPacked() && !ST.isShader())
906 buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
907
908 SPIRVType *SPVType =
909 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
910 auto MIBStruct =
911 MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
912 for (size_t I = 0; I < SPIRVStructNumElements; ++I)
913 MIBStruct.addUse(FieldTypes[I]);
914 for (size_t I = SPIRVStructNumElements; I < NumElements;
915 I += MaxNumElements) {
916 auto MIBCont =
917 MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
918 for (size_t J = I; J < std::min(I + MaxNumElements, NumElements); ++J)
919 MIBCont.addUse(FieldTypes[I]);
920 }
921 return MIBStruct;
922 });
923
924 if (Decorator)
925 Decorator(SPVType->defs().begin()->getReg());
926
927 return SPVType;
928}
929
930SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
931 const Type *Ty, MachineIRBuilder &MIRBuilder,
932 SPIRV::AccessQualifier::AccessQualifier AccQual) {
933 assert(isSpecialOpaqueType(Ty) && "Not a special opaque builtin type");
934 return SPIRV::lowerBuiltinType(Ty, AccQual, MIRBuilder, this);
935}
936
937SPIRVType *SPIRVGlobalRegistry::getOpTypePointer(
938 SPIRV::StorageClass::StorageClass SC, SPIRVType *ElemType,
939 MachineIRBuilder &MIRBuilder, Register Reg) {
940 if (!Reg.isValid())
941 Reg = createTypeVReg(MIRBuilder);
942
943 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
944 return MIRBuilder.buildInstr(SPIRV::OpTypePointer)
945 .addDef(Reg)
946 .addImm(static_cast<uint32_t>(SC))
947 .addUse(getSPIRVTypeID(ElemType));
948 });
949}
950
951SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
952 SPIRV::StorageClass::StorageClass SC, MachineIRBuilder &MIRBuilder) {
953 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
954 return MIRBuilder.buildInstr(SPIRV::OpTypeForwardPointer)
955 .addUse(createTypeVReg(MIRBuilder))
956 .addImm(static_cast<uint32_t>(SC));
957 });
958}
959
960SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
961 SPIRVType *RetType, const SmallVectorImpl<SPIRVType *> &ArgTypes,
962 MachineIRBuilder &MIRBuilder) {
963 return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
964 auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
965 .addDef(createTypeVReg(MIRBuilder))
966 .addUse(getSPIRVTypeID(RetType));
967 for (const SPIRVType *ArgType : ArgTypes)
968 MIB.addUse(getSPIRVTypeID(ArgType));
969 return MIB;
970 });
971}
972
974 const Type *Ty, SPIRVType *RetType,
975 const SmallVectorImpl<SPIRVType *> &ArgTypes,
976 MachineIRBuilder &MIRBuilder) {
977 if (const MachineInstr *MI = findMI(Ty, false, &MIRBuilder.getMF()))
978 return MI;
979 const MachineInstr *NewMI = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
980 add(Ty, false, NewMI);
981 return finishCreatingSPIRVType(Ty, NewMI);
982}
983
984SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
985 const Type *Ty, MachineIRBuilder &MIRBuilder,
986 SPIRV::AccessQualifier::AccessQualifier AccQual,
987 bool ExplicitLayoutRequired, bool EmitIR) {
988 Ty = adjustIntTypeByWidth(Ty);
989 // TODO: findMI needs to know if a layout is required.
990 if (const MachineInstr *MI =
991 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.getMF()))
992 return MI;
993 if (auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
994 return It->second;
995 return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, ExplicitLayoutRequired,
996 EmitIR);
997}
998
1000 assert(SpirvType && "Attempting to get type id for nullptr type.");
1001 if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer ||
1002 SpirvType->getOpcode() == SPIRV::OpTypeStructContinuedINTEL)
1003 return SpirvType->uses().begin()->getReg();
1004 return SpirvType->defs().begin()->getReg();
1005}
1006
1007// We need to use a new LLVM integer type if there is a mismatch between
1008// number of bits in LLVM and SPIRV integer types to let DuplicateTracker
1009// ensure uniqueness of a SPIRV type by the corresponding LLVM type. Without
1010// such an adjustment SPIRVGlobalRegistry::getOpTypeInt() could create the
1011// same "OpTypeInt 8" type for a series of LLVM integer types with number of
1012// bits less than 8. This would lead to duplicate type definitions
1013// eventually due to the method that DuplicateTracker utilizes to reason
1014// about uniqueness of type records.
1015const Type *SPIRVGlobalRegistry::adjustIntTypeByWidth(const Type *Ty) const {
1016 if (auto IType = dyn_cast<IntegerType>(Ty)) {
1017 unsigned SrcBitWidth = IType->getBitWidth();
1018 if (SrcBitWidth > 1) {
1019 unsigned BitWidth = adjustOpTypeIntWidth(SrcBitWidth);
1020 // Maybe change source LLVM type to keep DuplicateTracker consistent.
1021 if (SrcBitWidth != BitWidth)
1023 }
1024 }
1025 return Ty;
1026}
1027
1028SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
1029 const Type *Ty, MachineIRBuilder &MIRBuilder,
1030 SPIRV::AccessQualifier::AccessQualifier AccQual,
1031 bool ExplicitLayoutRequired, bool EmitIR) {
1032 if (isSpecialOpaqueType(Ty))
1033 return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
1034
1035 if (const MachineInstr *MI =
1036 findMI(Ty, ExplicitLayoutRequired, &MIRBuilder.getMF()))
1037 return MI;
1038
1039 if (auto IType = dyn_cast<IntegerType>(Ty)) {
1040 const unsigned Width = IType->getBitWidth();
1041 return Width == 1 ? getOpTypeBool(MIRBuilder)
1042 : getOpTypeInt(Width, MIRBuilder, false);
1043 }
1044 if (Ty->isFloatingPointTy())
1045 return getOpTypeFloat(Ty->getPrimitiveSizeInBits(), MIRBuilder);
1046 if (Ty->isVoidTy())
1047 return getOpTypeVoid(MIRBuilder);
1048 if (Ty->isVectorTy()) {
1049 SPIRVType *El =
1050 findSPIRVType(cast<FixedVectorType>(Ty)->getElementType(), MIRBuilder,
1051 AccQual, ExplicitLayoutRequired, EmitIR);
1052 return getOpTypeVector(cast<FixedVectorType>(Ty)->getNumElements(), El,
1053 MIRBuilder);
1054 }
1055 if (Ty->isArrayTy()) {
1056 SPIRVType *El = findSPIRVType(Ty->getArrayElementType(), MIRBuilder,
1057 AccQual, ExplicitLayoutRequired, EmitIR);
1058 return getOpTypeArray(Ty->getArrayNumElements(), El, MIRBuilder,
1059 ExplicitLayoutRequired, EmitIR);
1060 }
1061 if (auto SType = dyn_cast<StructType>(Ty)) {
1062 if (SType->isOpaque())
1063 return getOpTypeOpaque(SType, MIRBuilder);
1064
1065 StructOffsetDecorator Decorator = nullptr;
1066 if (ExplicitLayoutRequired) {
1067 Decorator = [&MIRBuilder, SType, this](Register Reg) {
1068 addStructOffsetDecorations(Reg, const_cast<StructType *>(SType),
1069 MIRBuilder);
1070 };
1071 }
1072 return getOpTypeStruct(SType, MIRBuilder, AccQual, std::move(Decorator),
1073 EmitIR);
1074 }
1075 if (auto FType = dyn_cast<FunctionType>(Ty)) {
1076 SPIRVType *RetTy = findSPIRVType(FType->getReturnType(), MIRBuilder,
1077 AccQual, ExplicitLayoutRequired, EmitIR);
1078 SmallVector<SPIRVType *, 4> ParamTypes;
1079 for (const auto &ParamTy : FType->params())
1080 ParamTypes.push_back(findSPIRVType(ParamTy, MIRBuilder, AccQual,
1081 ExplicitLayoutRequired, EmitIR));
1082 return getOpTypeFunction(RetTy, ParamTypes, MIRBuilder);
1083 }
1084
1085 unsigned AddrSpace = typeToAddressSpace(Ty);
1086 SPIRVType *SpvElementType = nullptr;
1087 if (Type *ElemTy = ::getPointeeType(Ty))
1088 SpvElementType = getOrCreateSPIRVType(ElemTy, MIRBuilder, AccQual, EmitIR);
1089 else
1090 SpvElementType = getOrCreateSPIRVIntegerType(8, MIRBuilder);
1091
1092 // Get access to information about available extensions
1093 const SPIRVSubtarget *ST =
1094 static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
1095 auto SC = addressSpaceToStorageClass(AddrSpace, *ST);
1096
1097 Type *ElemTy = ::getPointeeType(Ty);
1098 if (!ElemTy) {
1099 ElemTy = Type::getInt8Ty(MIRBuilder.getContext());
1100 }
1101
1102 // If we have forward pointer associated with this type, use its register
1103 // operand to create OpTypePointer.
1104 if (auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end()) {
1105 Register Reg = getSPIRVTypeID(It->second);
1106 // TODO: what does getOpTypePointer do?
1107 return getOpTypePointer(SC, SpvElementType, MIRBuilder, Reg);
1108 }
1109
1110 return getOrCreateSPIRVPointerType(ElemTy, MIRBuilder, SC);
1111}
1112
1113SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
1114 const Type *Ty, MachineIRBuilder &MIRBuilder,
1115 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1116 bool ExplicitLayoutRequired, bool EmitIR) {
1117 // TODO: Could this create a problem if one requires an explicit layout, and
1118 // the next time it does not?
1119 if (TypesInProcessing.count(Ty) && !isPointerTyOrWrapper(Ty))
1120 return nullptr;
1121 TypesInProcessing.insert(Ty);
1122 SPIRVType *SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual,
1123 ExplicitLayoutRequired, EmitIR);
1124 TypesInProcessing.erase(Ty);
1125 VRegToTypeMap[&MIRBuilder.getMF()][getSPIRVTypeID(SpirvType)] = SpirvType;
1126
1127 // TODO: We could end up with two SPIR-V types pointing to the same llvm type.
1128 // Is that a problem?
1129 SPIRVToLLVMType[SpirvType] = unifyPtrType(Ty);
1130
1131 if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer ||
1132 findMI(Ty, false, &MIRBuilder.getMF()) || isSpecialOpaqueType(Ty))
1133 return SpirvType;
1134
1135 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
1136 ExtTy && isTypedPointerWrapper(ExtTy))
1137 add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
1138 else if (!isPointerTy(Ty))
1139 add(Ty, ExplicitLayoutRequired, SpirvType);
1140 else if (isTypedPointerTy(Ty))
1141 add(cast<TypedPointerType>(Ty)->getElementType(),
1142 getPointerAddressSpace(Ty), SpirvType);
1143 else
1145 getPointerAddressSpace(Ty), SpirvType);
1146 return SpirvType;
1147}
1148
1149SPIRVType *
1151 const MachineFunction *MF) const {
1152 auto t = VRegToTypeMap.find(MF ? MF : CurMF);
1153 if (t != VRegToTypeMap.end()) {
1154 auto tt = t->second.find(VReg);
1155 if (tt != t->second.end())
1156 return tt->second;
1157 }
1158 return nullptr;
1159}
1160
1162 MachineFunction *MF) {
1163 if (!MF)
1164 MF = CurMF;
1165 MachineInstr *Instr = getVRegDef(MF->getRegInfo(), VReg);
1166 return getSPIRVTypeForVReg(Instr->getOperand(1).getReg(), MF);
1167}
1168
1170 const Type *Ty, MachineIRBuilder &MIRBuilder,
1171 SPIRV::AccessQualifier::AccessQualifier AccessQual,
1172 bool ExplicitLayoutRequired, bool EmitIR) {
1173 const MachineFunction *MF = &MIRBuilder.getMF();
1174 Register Reg;
1175 if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
1176 ExtTy && isTypedPointerWrapper(ExtTy))
1177 Reg = find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
1178 else if (!isPointerTy(Ty))
1179 Reg = find(Ty = adjustIntTypeByWidth(Ty), ExplicitLayoutRequired, MF);
1180 else if (isTypedPointerTy(Ty))
1181 Reg = find(cast<TypedPointerType>(Ty)->getElementType(),
1182 getPointerAddressSpace(Ty), MF);
1183 else
1184 Reg = find(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
1185 getPointerAddressSpace(Ty), MF);
1186 if (Reg.isValid() && !isSpecialOpaqueType(Ty))
1187 return getSPIRVTypeForVReg(Reg);
1188
1189 TypesInProcessing.clear();
1190 SPIRVType *STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual,
1191 ExplicitLayoutRequired, EmitIR);
1192 // Create normal pointer types for the corresponding OpTypeForwardPointers.
1193 for (auto &CU : ForwardPointerTypes) {
1194 // Pointer type themselves do not require an explicit layout. The types
1195 // they pointer to might, but that is taken care of when creating the type.
1196 bool PtrNeedsLayout = false;
1197 const Type *Ty2 = CU.first;
1198 SPIRVType *STy2 = CU.second;
1199 if ((Reg = find(Ty2, PtrNeedsLayout, MF)).isValid())
1200 STy2 = getSPIRVTypeForVReg(Reg);
1201 else
1202 STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, PtrNeedsLayout,
1203 EmitIR);
1204 if (Ty == Ty2)
1205 STy = STy2;
1206 }
1207 ForwardPointerTypes.clear();
1208 return STy;
1209}
1210
1212 unsigned TypeOpcode) const {
1214 assert(Type && "isScalarOfType VReg has no type assigned");
1215 return Type->getOpcode() == TypeOpcode;
1216}
1217
1219 unsigned TypeOpcode) const {
1221 assert(Type && "isScalarOrVectorOfType VReg has no type assigned");
1222 if (Type->getOpcode() == TypeOpcode)
1223 return true;
1224 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1225 Register ScalarTypeVReg = Type->getOperand(1).getReg();
1226 SPIRVType *ScalarType = getSPIRVTypeForVReg(ScalarTypeVReg);
1227 return ScalarType->getOpcode() == TypeOpcode;
1228 }
1229 return false;
1230}
1231
1233 switch (Type->getOpcode()) {
1234 case SPIRV::OpTypeImage:
1235 case SPIRV::OpTypeSampler:
1236 case SPIRV::OpTypeSampledImage:
1237 return true;
1238 case SPIRV::OpTypeStruct:
1239 return hasBlockDecoration(Type);
1240 default:
1241 return false;
1242 }
1243 return false;
1244}
1245unsigned
1248}
1249
1250unsigned
1252 if (!Type)
1253 return 0;
1254 return Type->getOpcode() == SPIRV::OpTypeVector
1255 ? static_cast<unsigned>(Type->getOperand(2).getImm())
1256 : 1;
1257}
1258
1259SPIRVType *
1262}
1263
1264SPIRVType *
1266 if (!Type)
1267 return nullptr;
1268 Register ScalarReg = Type->getOpcode() == SPIRV::OpTypeVector
1269 ? Type->getOperand(1).getReg()
1270 : Type->getOperand(0).getReg();
1271 SPIRVType *ScalarType = getSPIRVTypeForVReg(ScalarReg);
1272 assert(isScalarOrVectorOfType(Type->getOperand(0).getReg(),
1273 ScalarType->getOpcode()));
1274 return ScalarType;
1275}
1276
1277unsigned
1279 assert(Type && "Invalid Type pointer");
1280 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1281 auto EleTypeReg = Type->getOperand(1).getReg();
1282 Type = getSPIRVTypeForVReg(EleTypeReg);
1283 }
1284 if (Type->getOpcode() == SPIRV::OpTypeInt ||
1285 Type->getOpcode() == SPIRV::OpTypeFloat)
1286 return Type->getOperand(1).getImm();
1287 if (Type->getOpcode() == SPIRV::OpTypeBool)
1288 return 1;
1289 llvm_unreachable("Attempting to get bit width of non-integer/float type.");
1290}
1291
1293 const SPIRVType *Type) const {
1294 assert(Type && "Invalid Type pointer");
1295 unsigned NumElements = 1;
1296 if (Type->getOpcode() == SPIRV::OpTypeVector) {
1297 NumElements = static_cast<unsigned>(Type->getOperand(2).getImm());
1298 Type = getSPIRVTypeForVReg(Type->getOperand(1).getReg());
1299 }
1300 return Type->getOpcode() == SPIRV::OpTypeInt ||
1301 Type->getOpcode() == SPIRV::OpTypeFloat
1302 ? NumElements * Type->getOperand(1).getImm()
1303 : 0;
1304}
1305
1307 const SPIRVType *Type) const {
1308 if (Type && Type->getOpcode() == SPIRV::OpTypeVector)
1309 Type = getSPIRVTypeForVReg(Type->getOperand(1).getReg());
1310 return Type && Type->getOpcode() == SPIRV::OpTypeInt ? Type : nullptr;
1311}
1312
1315 return IntType && IntType->getOperand(2).getImm() != 0;
1316}
1317
1319 return PtrType && PtrType->getOpcode() == SPIRV::OpTypePointer
1320 ? getSPIRVTypeForVReg(PtrType->getOperand(2).getReg())
1321 : nullptr;
1322}
1323
1325 SPIRVType *ElemType = getPointeeType(getSPIRVTypeForVReg(PtrReg));
1326 return ElemType ? ElemType->getOpcode() : 0;
1327}
1328
1330 const SPIRVType *Type2) const {
1331 if (!Type1 || !Type2)
1332 return false;
1333 auto Op1 = Type1->getOpcode(), Op2 = Type2->getOpcode();
1334 // Ignore difference between <1.5 and >=1.5 protocol versions:
1335 // it's valid if either Result Type or Operand is a pointer, and the other
1336 // is a pointer, an integer scalar, or an integer vector.
1337 if (Op1 == SPIRV::OpTypePointer &&
1338 (Op2 == SPIRV::OpTypePointer || retrieveScalarOrVectorIntType(Type2)))
1339 return true;
1340 if (Op2 == SPIRV::OpTypePointer &&
1341 (Op1 == SPIRV::OpTypePointer || retrieveScalarOrVectorIntType(Type1)))
1342 return true;
1343 unsigned Bits1 = getNumScalarOrVectorTotalBitWidth(Type1),
1345 return Bits1 > 0 && Bits1 == Bits2;
1346}
1347
1348SPIRV::StorageClass::StorageClass
1351 assert(Type && Type->getOpcode() == SPIRV::OpTypePointer &&
1352 Type->getOperand(1).isImm() && "Pointer type is expected");
1354}
1355
1356SPIRV::StorageClass::StorageClass
1358 return static_cast<SPIRV::StorageClass::StorageClass>(
1359 Type->getOperand(1).getImm());
1360}
1361
1363 MachineIRBuilder &MIRBuilder, Type *ElemType,
1364 SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr) {
1365 auto Key = SPIRV::irhandle_vkbuffer(ElemType, SC, IsWritable);
1366 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1367 return MI;
1368
1369 bool ExplicitLayoutRequired = storageClassRequiresExplictLayout(SC);
1370 // We need to get the SPIR-V type for the element here, so we can add the
1371 // decoration to it.
1372 auto *T = StructType::create(ElemType);
1373 auto *BlockType =
1374 getOrCreateSPIRVType(T, MIRBuilder, SPIRV::AccessQualifier::None,
1375 ExplicitLayoutRequired, EmitIr);
1376
1377 buildOpDecorate(BlockType->defs().begin()->getReg(), MIRBuilder,
1378 SPIRV::Decoration::Block, {});
1379
1380 if (!IsWritable) {
1381 buildOpMemberDecorate(BlockType->defs().begin()->getReg(), MIRBuilder,
1382 SPIRV::Decoration::NonWritable, 0, {});
1383 }
1384
1385 SPIRVType *R = getOrCreateSPIRVPointerTypeInternal(BlockType, MIRBuilder, SC);
1386 add(Key, R);
1387 return R;
1388}
1389
1391 MachineIRBuilder &MIRBuilder, const TargetExtType *T, bool EmitIr) {
1392 auto Key = SPIRV::handle(T);
1393 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1394 return MI;
1395
1396 StructType *ST = cast<StructType>(T->getTypeParameter(0));
1397 ArrayRef<uint32_t> Offsets = T->int_params().slice(1);
1398 assert(ST->getNumElements() == Offsets.size());
1399
1400 StructOffsetDecorator Decorator = [&MIRBuilder, &Offsets](Register Reg) {
1401 for (uint32_t I = 0; I < Offsets.size(); ++I) {
1402 buildOpMemberDecorate(Reg, MIRBuilder, SPIRV::Decoration::Offset, I,
1403 {Offsets[I]});
1404 }
1405 };
1406
1407 // We need a new OpTypeStruct instruction because decorations will be
1408 // different from a struct with an explicit layout created from a different
1409 // entry point.
1410 SPIRVType *SPIRVStructType =
1411 getOpTypeStruct(ST, MIRBuilder, SPIRV::AccessQualifier::None,
1412 std::move(Decorator), EmitIr);
1413 add(Key, SPIRVStructType);
1414 return SPIRVStructType;
1415}
1416
1418 const TargetExtType *ExtensionType,
1419 const SPIRV::AccessQualifier::AccessQualifier Qualifier,
1420 MachineIRBuilder &MIRBuilder) {
1421 assert(ExtensionType->getNumTypeParameters() == 1 &&
1422 "SPIR-V image builtin type must have sampled type parameter!");
1423 const SPIRVType *SampledType =
1424 getOrCreateSPIRVType(ExtensionType->getTypeParameter(0), MIRBuilder,
1425 SPIRV::AccessQualifier::ReadWrite, true);
1426 assert((ExtensionType->getNumIntParameters() == 7 ||
1427 ExtensionType->getNumIntParameters() == 6) &&
1428 "Invalid number of parameters for SPIR-V image builtin!");
1429
1430 SPIRV::AccessQualifier::AccessQualifier accessQualifier =
1431 SPIRV::AccessQualifier::None;
1432 if (ExtensionType->getNumIntParameters() == 7) {
1433 accessQualifier = Qualifier == SPIRV::AccessQualifier::WriteOnly
1434 ? SPIRV::AccessQualifier::WriteOnly
1435 : SPIRV::AccessQualifier::AccessQualifier(
1436 ExtensionType->getIntParameter(6));
1437 }
1438
1439 // Create or get an existing type from GlobalRegistry.
1440 SPIRVType *R = getOrCreateOpTypeImage(
1441 MIRBuilder, SampledType,
1442 SPIRV::Dim::Dim(ExtensionType->getIntParameter(0)),
1443 ExtensionType->getIntParameter(1), ExtensionType->getIntParameter(2),
1444 ExtensionType->getIntParameter(3), ExtensionType->getIntParameter(4),
1445 SPIRV::ImageFormat::ImageFormat(ExtensionType->getIntParameter(5)),
1446 accessQualifier);
1447 SPIRVToLLVMType[R] = ExtensionType;
1448 return R;
1449}
1450
1451SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
1452 MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, SPIRV::Dim::Dim Dim,
1453 uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
1454 SPIRV::ImageFormat::ImageFormat ImageFormat,
1455 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1456 auto Key = SPIRV::irhandle_image(SPIRVToLLVMType.lookup(SampledType), Dim,
1457 Depth, Arrayed, Multisampled, Sampled,
1458 ImageFormat, AccessQual);
1459 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1460 return MI;
1461 const MachineInstr *NewMI =
1462 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1463 auto MIB =
1464 MIRBuilder.buildInstr(SPIRV::OpTypeImage)
1465 .addDef(createTypeVReg(MIRBuilder))
1466 .addUse(getSPIRVTypeID(SampledType))
1467 .addImm(Dim)
1468 .addImm(Depth) // Depth (whether or not it is a Depth image).
1469 .addImm(Arrayed) // Arrayed.
1470 .addImm(Multisampled) // Multisampled (0 = only single-sample).
1471 .addImm(Sampled) // Sampled (0 = usage known at runtime).
1472 .addImm(ImageFormat);
1473 if (AccessQual != SPIRV::AccessQualifier::None)
1474 MIB.addImm(AccessQual);
1475 return MIB;
1476 });
1477 add(Key, NewMI);
1478 return NewMI;
1479}
1480
1481SPIRVType *
1483 auto Key = SPIRV::irhandle_sampler();
1484 const MachineFunction *MF = &MIRBuilder.getMF();
1485 if (const MachineInstr *MI = findMI(Key, MF))
1486 return MI;
1487 const MachineInstr *NewMI =
1488 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1489 return MIRBuilder.buildInstr(SPIRV::OpTypeSampler)
1490 .addDef(createTypeVReg(MIRBuilder));
1491 });
1492 add(Key, NewMI);
1493 return NewMI;
1494}
1495
1497 MachineIRBuilder &MIRBuilder,
1498 SPIRV::AccessQualifier::AccessQualifier AccessQual) {
1499 auto Key = SPIRV::irhandle_pipe(AccessQual);
1500 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1501 return MI;
1502 const MachineInstr *NewMI =
1503 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1504 return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
1505 .addDef(createTypeVReg(MIRBuilder))
1506 .addImm(AccessQual);
1507 });
1508 add(Key, NewMI);
1509 return NewMI;
1510}
1511
1513 MachineIRBuilder &MIRBuilder) {
1514 auto Key = SPIRV::irhandle_event();
1515 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1516 return MI;
1517 const MachineInstr *NewMI =
1518 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1519 return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent)
1520 .addDef(createTypeVReg(MIRBuilder));
1521 });
1522 add(Key, NewMI);
1523 return NewMI;
1524}
1525
1527 SPIRVType *ImageType, MachineIRBuilder &MIRBuilder) {
1529 SPIRVToLLVMType.lookup(MIRBuilder.getMF().getRegInfo().getVRegDef(
1530 ImageType->getOperand(1).getReg())),
1531 ImageType);
1532 if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
1533 return MI;
1534 const MachineInstr *NewMI =
1535 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1536 return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
1537 .addDef(createTypeVReg(MIRBuilder))
1538 .addUse(getSPIRVTypeID(ImageType));
1539 });
1540 add(Key, NewMI);
1541 return NewMI;
1542}
1543
1545 MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType,
1546 const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns,
1547 uint32_t Use, bool EmitIR) {
1548 if (const MachineInstr *MI =
1549 findMI(ExtensionType, false, &MIRBuilder.getMF()))
1550 return MI;
1551 const MachineInstr *NewMI =
1552 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1553 SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
1554 const Type *ET = getTypeForSPIRVType(ElemType);
1555 if (ET->isIntegerTy() && ET->getIntegerBitWidth() == 4 &&
1556 cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget())
1557 .canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1558 MIRBuilder.buildInstr(SPIRV::OpCapability)
1559 .addImm(SPIRV::Capability::Int4CooperativeMatrixINTEL);
1560 }
1561 return MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
1562 .addDef(createTypeVReg(MIRBuilder))
1563 .addUse(getSPIRVTypeID(ElemType))
1564 .addUse(buildConstantInt(Scope, MIRBuilder, SpvTypeInt32, EmitIR))
1565 .addUse(buildConstantInt(Rows, MIRBuilder, SpvTypeInt32, EmitIR))
1566 .addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
1567 .addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
1568 });
1569 add(ExtensionType, false, NewMI);
1570 return NewMI;
1571}
1572
1574 const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode) {
1575 if (const MachineInstr *MI = findMI(Ty, false, &MIRBuilder.getMF()))
1576 return MI;
1577 const MachineInstr *NewMI =
1578 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1579 return MIRBuilder.buildInstr(Opcode).addDef(createTypeVReg(MIRBuilder));
1580 });
1581 add(Ty, false, NewMI);
1582 return NewMI;
1583}
1584
1586 const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode,
1588 if (const MachineInstr *MI = findMI(Ty, false, &MIRBuilder.getMF()))
1589 return MI;
1590 Register ResVReg = createTypeVReg(MIRBuilder);
1591 const MachineInstr *NewMI =
1592 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1593 MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::UNKNOWN_type)
1594 .addDef(ResVReg)
1595 .addImm(Opcode);
1596 for (MCOperand Operand : Operands) {
1597 if (Operand.isReg()) {
1598 MIB.addUse(Operand.getReg());
1599 } else if (Operand.isImm()) {
1600 MIB.addImm(Operand.getImm());
1601 }
1602 }
1603 return MIB;
1604 });
1605 add(Ty, false, NewMI);
1606 return NewMI;
1607}
1608
1609// Returns nullptr if unable to recognize SPIRV type name
1611 StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR,
1612 SPIRV::StorageClass::StorageClass SC,
1613 SPIRV::AccessQualifier::AccessQualifier AQ) {
1614 unsigned VecElts = 0;
1615 auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
1616
1617 // Parse strings representing either a SPIR-V or OpenCL builtin type.
1618 if (hasBuiltinTypePrefix(TypeStr))
1620 TypeStr.str(), MIRBuilder.getContext()),
1621 MIRBuilder, AQ, false, true);
1622
1623 // Parse type name in either "typeN" or "type vector[N]" format, where
1624 // N is the number of elements of the vector.
1625 Type *Ty;
1626
1627 Ty = parseBasicTypeName(TypeStr, Ctx);
1628 if (!Ty)
1629 // Unable to recognize SPIRV type name
1630 return nullptr;
1631
1632 const SPIRVType *SpirvTy =
1633 getOrCreateSPIRVType(Ty, MIRBuilder, AQ, false, true);
1634
1635 // Handle "type*" or "type* vector[N]".
1636 if (TypeStr.consume_front("*"))
1637 SpirvTy = getOrCreateSPIRVPointerType(Ty, MIRBuilder, SC);
1638
1639 // Handle "typeN*" or "type vector[N]*".
1640 bool IsPtrToVec = TypeStr.consume_back("*");
1641
1642 if (TypeStr.consume_front(" vector[")) {
1643 TypeStr = TypeStr.substr(0, TypeStr.find(']'));
1644 }
1645 TypeStr.getAsInteger(10, VecElts);
1646 if (VecElts > 0)
1647 SpirvTy = getOrCreateSPIRVVectorType(SpirvTy, VecElts, MIRBuilder, EmitIR);
1648
1649 if (IsPtrToVec)
1650 SpirvTy = getOrCreateSPIRVPointerType(SpirvTy, MIRBuilder, SC);
1651
1652 return SpirvTy;
1653}
1654
1655SPIRVType *
1657 MachineIRBuilder &MIRBuilder) {
1658 return getOrCreateSPIRVType(
1660 MIRBuilder, SPIRV::AccessQualifier::ReadWrite, false, true);
1661}
1662
1663SPIRVType *SPIRVGlobalRegistry::finishCreatingSPIRVType(const Type *LLVMTy,
1664 SPIRVType *SpirvType) {
1665 assert(CurMF == SpirvType->getMF());
1666 VRegToTypeMap[CurMF][getSPIRVTypeID(SpirvType)] = SpirvType;
1667 SPIRVToLLVMType[SpirvType] = unifyPtrType(LLVMTy);
1668 return SpirvType;
1669}
1670
1672 MachineInstr &I,
1673 const SPIRVInstrInfo &TII,
1674 unsigned SPIRVOPcode,
1675 Type *Ty) {
1676 if (const MachineInstr *MI = findMI(Ty, false, CurMF))
1677 return MI;
1678 MachineBasicBlock &DepMBB = I.getMF()->front();
1679 MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
1680 const MachineInstr *NewMI =
1681 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1682 return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
1683 MIRBuilder.getDL(), TII.get(SPIRVOPcode))
1686 .addImm(0);
1687 });
1688 add(Ty, false, NewMI);
1689 return finishCreatingSPIRVType(Ty, NewMI);
1690}
1691
1693 unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII) {
1694 // Maybe adjust bit width to keep DuplicateTracker consistent. Without
1695 // such an adjustment SPIRVGlobalRegistry::getOpTypeInt() could create, for
1696 // example, the same "OpTypeInt 8" type for a series of LLVM integer types
1697 // with number of bits less than 8, causing duplicate type definitions.
1698 if (BitWidth > 1)
1699 BitWidth = adjustOpTypeIntWidth(BitWidth);
1701 return getOrCreateSPIRVType(BitWidth, I, TII, SPIRV::OpTypeInt, LLVMTy);
1702}
1703
1705 unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII) {
1707 Type *LLVMTy;
1708 switch (BitWidth) {
1709 case 16:
1710 LLVMTy = Type::getHalfTy(Ctx);
1711 break;
1712 case 32:
1713 LLVMTy = Type::getFloatTy(Ctx);
1714 break;
1715 case 64:
1716 LLVMTy = Type::getDoubleTy(Ctx);
1717 break;
1718 default:
1719 llvm_unreachable("Bit width is of unexpected size.");
1720 }
1721 return getOrCreateSPIRVType(BitWidth, I, TII, SPIRV::OpTypeFloat, LLVMTy);
1722}
1723
1724SPIRVType *
1726 bool EmitIR) {
1727 return getOrCreateSPIRVType(
1728 IntegerType::get(MIRBuilder.getMF().getFunction().getContext(), 1),
1729 MIRBuilder, SPIRV::AccessQualifier::ReadWrite, false, EmitIR);
1730}
1731
1732SPIRVType *
1734 const SPIRVInstrInfo &TII) {
1736 if (const MachineInstr *MI = findMI(Ty, false, CurMF))
1737 return MI;
1738 MachineBasicBlock &DepMBB = I.getMF()->front();
1739 MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
1740 const MachineInstr *NewMI =
1741 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1742 return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
1743 MIRBuilder.getDL(), TII.get(SPIRV::OpTypeBool))
1745 });
1746 add(Ty, false, NewMI);
1747 return finishCreatingSPIRVType(Ty, NewMI);
1748}
1749
1751 SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder,
1752 bool EmitIR) {
1753 return getOrCreateSPIRVType(
1755 NumElements),
1756 MIRBuilder, SPIRV::AccessQualifier::ReadWrite, false, EmitIR);
1757}
1758
1760 SPIRVType *BaseType, unsigned NumElements, MachineInstr &I,
1761 const SPIRVInstrInfo &TII) {
1763 const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
1764 if (const MachineInstr *MI = findMI(Ty, false, CurMF))
1765 return MI;
1766 MachineInstr *DepMI = const_cast<MachineInstr *>(BaseType);
1767 MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
1768 const MachineInstr *NewMI =
1769 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1770 return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
1771 MIRBuilder.getDL(), TII.get(SPIRV::OpTypeVector))
1774 .addImm(NumElements);
1775 });
1776 add(Ty, false, NewMI);
1777 return finishCreatingSPIRVType(Ty, NewMI);
1778}
1779
1781 const Type *BaseType, MachineInstr &I,
1782 SPIRV::StorageClass::StorageClass SC) {
1783 MachineIRBuilder MIRBuilder(I);
1784 return getOrCreateSPIRVPointerType(BaseType, MIRBuilder, SC);
1785}
1786
1788 const Type *BaseType, MachineIRBuilder &MIRBuilder,
1789 SPIRV::StorageClass::StorageClass SC) {
1790 // TODO: Need to check if EmitIr should always be true.
1791 SPIRVType *SpirvBaseType = getOrCreateSPIRVType(
1792 BaseType, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
1794 assert(SpirvBaseType);
1795 return getOrCreateSPIRVPointerTypeInternal(SpirvBaseType, MIRBuilder, SC);
1796}
1797
1799 SPIRVType *PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I) {
1800 [[maybe_unused]] SPIRV::StorageClass::StorageClass OldSC =
1801 getPointerStorageClass(PtrType);
1804
1805 SPIRVType *PointeeType = getPointeeType(PtrType);
1806 MachineIRBuilder MIRBuilder(I);
1807 return getOrCreateSPIRVPointerTypeInternal(PointeeType, MIRBuilder, SC);
1808}
1809
1811 SPIRVType *BaseType, MachineIRBuilder &MIRBuilder,
1812 SPIRV::StorageClass::StorageClass SC) {
1813 const Type *LLVMType = getTypeForSPIRVType(BaseType);
1815 SPIRVType *R = getOrCreateSPIRVPointerType(LLVMType, MIRBuilder, SC);
1816 assert(
1817 getPointeeType(R) == BaseType &&
1818 "The base type was not correctly laid out for the given storage class.");
1819 return R;
1820}
1821
1822SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerTypeInternal(
1823 SPIRVType *BaseType, MachineIRBuilder &MIRBuilder,
1824 SPIRV::StorageClass::StorageClass SC) {
1825 const Type *PointerElementType = getTypeForSPIRVType(BaseType);
1827 if (const MachineInstr *MI = findMI(PointerElementType, AddressSpace, CurMF))
1828 return MI;
1829 Type *Ty = TypedPointerType::get(const_cast<Type *>(PointerElementType),
1830 AddressSpace);
1831 const MachineInstr *NewMI =
1832 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1833 return BuildMI(MIRBuilder.getMBB(), MIRBuilder.getInsertPt(),
1834 MIRBuilder.getDebugLoc(),
1835 MIRBuilder.getTII().get(SPIRV::OpTypePointer))
1837 .addImm(static_cast<uint32_t>(SC))
1839 });
1840 add(PointerElementType, AddressSpace, NewMI);
1841 return finishCreatingSPIRVType(Ty, NewMI);
1842}
1843
1845 SPIRVType *SpvType,
1846 const SPIRVInstrInfo &TII) {
1847 UndefValue *UV =
1848 UndefValue::get(const_cast<Type *>(getTypeForSPIRVType(SpvType)));
1849 Register Res = find(UV, CurMF);
1850 if (Res.isValid())
1851 return Res;
1852
1853 LLT LLTy = LLT::scalar(64);
1855 CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
1856 assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
1857
1858 MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
1859 MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
1860 const MachineInstr *NewMI =
1861 createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
1862 auto MIB = BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
1863 MIRBuilder.getDL(), TII.get(SPIRV::OpUndef))
1864 .addDef(Res)
1865 .addUse(getSPIRVTypeID(SpvType));
1866 const auto &ST = CurMF->getSubtarget();
1867 constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
1868 *ST.getRegisterInfo(),
1869 *ST.getRegBankInfo());
1870 return MIB;
1871 });
1872 add(UV, NewMI);
1873 return Res;
1874}
1875
1876const TargetRegisterClass *
1878 unsigned Opcode = SpvType->getOpcode();
1879 switch (Opcode) {
1880 case SPIRV::OpTypeFloat:
1881 return &SPIRV::fIDRegClass;
1882 case SPIRV::OpTypePointer:
1883 return &SPIRV::pIDRegClass;
1884 case SPIRV::OpTypeVector: {
1885 SPIRVType *ElemType = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
1886 unsigned ElemOpcode = ElemType ? ElemType->getOpcode() : 0;
1887 if (ElemOpcode == SPIRV::OpTypeFloat)
1888 return &SPIRV::vfIDRegClass;
1889 if (ElemOpcode == SPIRV::OpTypePointer)
1890 return &SPIRV::vpIDRegClass;
1891 return &SPIRV::vIDRegClass;
1892 }
1893 }
1894 return &SPIRV::iIDRegClass;
1895}
1896
1897inline unsigned getAS(SPIRVType *SpvType) {
1899 static_cast<SPIRV::StorageClass::StorageClass>(
1900 SpvType->getOperand(1).getImm()));
1901}
1902
1904 unsigned Opcode = SpvType ? SpvType->getOpcode() : 0;
1905 switch (Opcode) {
1906 case SPIRV::OpTypeInt:
1907 case SPIRV::OpTypeFloat:
1908 case SPIRV::OpTypeBool:
1909 return LLT::scalar(getScalarOrVectorBitWidth(SpvType));
1910 case SPIRV::OpTypePointer:
1911 return LLT::pointer(getAS(SpvType), getPointerSize());
1912 case SPIRV::OpTypeVector: {
1913 SPIRVType *ElemType = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
1914 LLT ET;
1915 switch (ElemType ? ElemType->getOpcode() : 0) {
1916 case SPIRV::OpTypePointer:
1917 ET = LLT::pointer(getAS(ElemType), getPointerSize());
1918 break;
1919 case SPIRV::OpTypeInt:
1920 case SPIRV::OpTypeFloat:
1921 case SPIRV::OpTypeBool:
1922 ET = LLT::scalar(getScalarOrVectorBitWidth(ElemType));
1923 break;
1924 default:
1925 ET = LLT::scalar(64);
1926 }
1927 return LLT::fixed_vector(
1928 static_cast<unsigned>(SpvType->getOperand(2).getImm()), ET);
1929 }
1930 }
1931 return LLT::scalar(64);
1932}
1933
1934// Aliasing list MD contains several scope MD nodes whithin it. Each scope MD
1935// has a selfreference and an extra MD node for aliasing domain and also it
1936// can contain an optional string operand. Domain MD contains a self-reference
1937// with an optional string operand. Here we unfold the list, creating SPIR-V
1938// aliasing instructions.
1939// TODO: add support for an optional string operand.
1941 MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD) {
1942 if (AliasingListMD->getNumOperands() == 0)
1943 return nullptr;
1944 if (auto L = AliasInstMDMap.find(AliasingListMD); L != AliasInstMDMap.end())
1945 return L->second;
1946
1948 MachineRegisterInfo *MRI = MIRBuilder.getMRI();
1949 for (const MDOperand &MDListOp : AliasingListMD->operands()) {
1950 if (MDNode *ScopeMD = dyn_cast<MDNode>(MDListOp)) {
1951 if (ScopeMD->getNumOperands() < 2)
1952 return nullptr;
1953 MDNode *DomainMD = dyn_cast<MDNode>(ScopeMD->getOperand(1));
1954 if (!DomainMD)
1955 return nullptr;
1956 auto *Domain = [&] {
1957 auto D = AliasInstMDMap.find(DomainMD);
1958 if (D != AliasInstMDMap.end())
1959 return D->second;
1960 const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1961 auto MIB =
1962 MIRBuilder.buildInstr(SPIRV::OpAliasDomainDeclINTEL).addDef(Ret);
1963 return MIB.getInstr();
1964 }();
1965 AliasInstMDMap.insert(std::make_pair(DomainMD, Domain));
1966 auto *Scope = [&] {
1967 auto S = AliasInstMDMap.find(ScopeMD);
1968 if (S != AliasInstMDMap.end())
1969 return S->second;
1970 const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1971 auto MIB = MIRBuilder.buildInstr(SPIRV::OpAliasScopeDeclINTEL)
1972 .addDef(Ret)
1973 .addUse(Domain->getOperand(0).getReg());
1974 return MIB.getInstr();
1975 }();
1976 AliasInstMDMap.insert(std::make_pair(ScopeMD, Scope));
1977 ScopeList.push_back(Scope);
1978 }
1979 }
1980
1981 const Register Ret = MRI->createVirtualRegister(&SPIRV::IDRegClass);
1982 auto MIB =
1983 MIRBuilder.buildInstr(SPIRV::OpAliasScopeListDeclINTEL).addDef(Ret);
1984 for (auto *Scope : ScopeList)
1985 MIB.addUse(Scope->getOperand(0).getReg());
1986 auto List = MIB.getInstr();
1987 AliasInstMDMap.insert(std::make_pair(AliasingListMD, List));
1988 return List;
1989}
1990
1992 Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec,
1993 const MDNode *AliasingListMD) {
1994 MachineInstr *AliasList =
1995 getOrAddMemAliasingINTELInst(MIRBuilder, AliasingListMD);
1996 if (!AliasList)
1997 return;
1998 MIRBuilder.buildInstr(SPIRV::OpDecorate)
1999 .addUse(Reg)
2000 .addImm(Dec)
2001 .addUse(AliasList->getOperand(0).getReg());
2002}
2004 bool DeleteOld) {
2005 Old->replaceAllUsesWith(New);
2006 updateIfExistDeducedElementType(Old, New, DeleteOld);
2007 updateIfExistAssignPtrTypeInstr(Old, New, DeleteOld);
2008}
2009
2011 Value *Arg) {
2012 Value *OfType = getNormalizedPoisonValue(Ty);
2013 CallInst *AssignCI = nullptr;
2014 if (Arg->getType()->isAggregateType() && Ty->isAggregateType() &&
2015 allowEmitFakeUse(Arg)) {
2016 LLVMContext &Ctx = Arg->getContext();
2019 MDString::get(Ctx, Arg->getName())};
2020 B.CreateIntrinsic(Intrinsic::spv_value_md,
2021 {MetadataAsValue::get(Ctx, MDTuple::get(Ctx, ArgMDs))});
2022 AssignCI = B.CreateIntrinsic(Intrinsic::fake_use, {Arg});
2023 } else {
2024 AssignCI = buildIntrWithMD(Intrinsic::spv_assign_type, {Arg->getType()},
2025 OfType, Arg, {}, B);
2026 }
2027 addAssignPtrTypeInstr(Arg, AssignCI);
2028}
2029
2031 Value *Arg) {
2032 Value *OfType = PoisonValue::get(ElemTy);
2033 CallInst *AssignPtrTyCI = findAssignPtrTypeInstr(Arg);
2034 Function *CurrF =
2035 B.GetInsertBlock() ? B.GetInsertBlock()->getParent() : nullptr;
2036 if (AssignPtrTyCI == nullptr ||
2037 AssignPtrTyCI->getParent()->getParent() != CurrF) {
2038 AssignPtrTyCI = buildIntrWithMD(
2039 Intrinsic::spv_assign_ptr_type, {Arg->getType()}, OfType, Arg,
2040 {B.getInt32(getPointerAddressSpace(Arg->getType()))}, B);
2041 addDeducedElementType(AssignPtrTyCI, ElemTy);
2042 addDeducedElementType(Arg, ElemTy);
2043 addAssignPtrTypeInstr(Arg, AssignPtrTyCI);
2044 } else {
2045 updateAssignType(AssignPtrTyCI, Arg, OfType);
2046 }
2047}
2048
2050 Value *OfType) {
2051 AssignCI->setArgOperand(1, buildMD(OfType));
2052 if (cast<IntrinsicInst>(AssignCI)->getIntrinsicID() !=
2053 Intrinsic::spv_assign_ptr_type)
2054 return;
2055
2056 // update association with the pointee type
2057 Type *ElemTy = OfType->getType();
2058 addDeducedElementType(AssignCI, ElemTy);
2059 addDeducedElementType(Arg, ElemTy);
2060}
2061
2062void SPIRVGlobalRegistry::addStructOffsetDecorations(
2063 Register Reg, StructType *Ty, MachineIRBuilder &MIRBuilder) {
2064 DataLayout DL;
2065 ArrayRef<TypeSize> Offsets = DL.getStructLayout(Ty)->getMemberOffsets();
2066 for (uint32_t I = 0; I < Ty->getNumElements(); ++I) {
2067 buildOpMemberDecorate(Reg, MIRBuilder, SPIRV::Decoration::Offset, I,
2068 {static_cast<uint32_t>(Offsets[I])});
2069 }
2070}
2071
2072void SPIRVGlobalRegistry::addArrayStrideDecorations(
2073 Register Reg, Type *ElementType, MachineIRBuilder &MIRBuilder) {
2074 uint32_t SizeInBytes = DataLayout().getTypeSizeInBits(ElementType) / 8;
2075 buildOpDecorate(Reg, MIRBuilder, SPIRV::Decoration::ArrayStride,
2076 {SizeInBytes});
2077}
2078
2079bool SPIRVGlobalRegistry::hasBlockDecoration(SPIRVType *Type) const {
2081 for (const MachineInstr &Use :
2082 Type->getMF()->getRegInfo().use_instructions(Def)) {
2083 if (Use.getOpcode() != SPIRV::OpDecorate)
2084 continue;
2085
2086 if (Use.getOperand(1).getImm() == SPIRV::Decoration::Block)
2087 return true;
2088 }
2089 return false;
2090}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Resource Implicit Binding
return RetTy
std::string Name
ELFYAML::ELF_REL Type2
Definition: ELFYAML.cpp:1850
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
if(PassOpts->AAPipeline)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static unsigned getNumElements(Type *Ty)
static bool storageClassRequiresExplictLayout(SPIRV::StorageClass::StorageClass SC)
static Register createTypeVReg(MachineRegisterInfo &MRI)
unsigned getAS(SPIRVType *SpvType)
static bool allowEmitFakeUse(const Value *Arg)
static unsigned typeToAddressSpace(const Type *Ty)
bool isPosZero() const
Definition: APFloat.h:1460
Class for arbitrary precision integers.
Definition: APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1540
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Class to represent array types.
Definition: DerivedTypes.h:398
uint64_t getNumElements() const
Definition: DerivedTypes.h:410
Type * getElementType() const
Definition: DerivedTypes.h:411
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1297
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:277
const APFloat & getValue() const
Definition: Constants.h:321
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:214
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition: Constants.h:486
static LLVM_ABI ConstantTargetNone * get(TargetExtType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1850
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
Definition: Constants.cpp:1474
This is an important base class in LLVM.
Definition: Constant.h:43
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
Definition: Constants.cpp:1778
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:90
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition: DataLayout.h:674
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:592
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:803
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:359
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
Definition: Value.h:576
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:663
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:53
MaybeAlign getAlign() const
Returns the alignment of the given variable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
Class to represent integer types.
Definition: DerivedTypes.h:42
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:319
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:43
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:58
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:101
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:64
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:40
Metadata node.
Definition: Metadata.h:1077
ArrayRef< MDOperand > operands() const
Definition: Metadata.h:1443
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1451
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:899
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:607
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1522
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Helper class to build MachineInstr.
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
LLVMContext & getContext() const
const TargetInstrInfo & getTII()
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
const DebugLoc & getDL()
Getter for DebugLoc.
MachineFunction & getMF()
Getter for the function we currently build.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
Definition: MachineInstr.h:72
mop_range defs()
Returns all explicit operands that are register definitions.
Definition: MachineInstr.h:724
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:587
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:359
mop_range uses()
Returns all operands which may be register uses.
Definition: MachineInstr.h:731
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
int64_t getImm() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static LLVM_ABI MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:103
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1885
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:107
SPIRVType * getOrCreateOpTypePipe(MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AccQual)
unsigned getNumScalarOrVectorTotalBitWidth(const SPIRVType *Type) const
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
SPIRVType * getResultType(Register VReg, MachineFunction *MF=nullptr)
void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI)
SPIRVType * getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder, bool EmitIR)
void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg)
SPIRVType * assignFloatTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
MachineInstr * getOrAddMemAliasingINTELInst(MachineIRBuilder &MIRBuilder, const MDNode *AliasingListMD)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * assignVectTypeToVReg(SPIRVType *BaseType, unsigned NumElements, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
void replaceAllUsesWith(Value *Old, Value *New, bool DeleteOld=true)
SPIRVType * changePointerStorageClass(SPIRVType *PtrType, SPIRV::StorageClass::StorageClass SC, MachineInstr &I)
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
SPIRVType * getOrCreateUnknownType(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode, const ArrayRef< MCOperand > Operands)
bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const
unsigned getScalarOrVectorComponentCount(Register VReg) const
Register createConstInt(const ConstantInt *CI, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
SPIRVType * getOrCreateSPIRVFloatType(unsigned BitWidth, MachineInstr &I, const SPIRVInstrInfo &TII)
bool isScalarOrVectorSigned(const SPIRVType *Type) const
void addDeducedElementType(Value *Val, Type *Ty)
SPIRVGlobalRegistry(unsigned PointerSize)
Register getOrCreateGlobalVariableWithBinding(const SPIRVType *VarType, uint32_t Set, uint32_t Binding, StringRef Name, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
SPIRVType * getOrCreateSPIRVPointerType(const Type *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SC)
SPIRVType * getOrCreateOpTypeByOpcode(const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode)
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr)
SPIRVType * getPointeeType(SPIRVType *PtrType)
void invalidateMachineInstr(MachineInstr *MI)
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
Register createConstFP(const ConstantFP *CF, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull)
void updateIfExistDeducedElementType(Value *OldVal, Value *NewVal, bool DeleteOld)
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass::StorageClass Storage, const MachineInstr *Init, bool IsConst, bool HasLinkageTy, SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
SPIRVType * assignIntTypeToVReg(unsigned BitWidth, Register VReg, MachineInstr &I, const SPIRVInstrInfo &TII)
unsigned getPointeeTypeOp(Register PtrReg)
SPIRVType * getOrCreateOpTypeSampledImage(SPIRVType *ImageType, MachineIRBuilder &MIRBuilder)
SPIRVType * getOrCreateVulkanBufferType(MachineIRBuilder &MIRBuilder, Type *ElemType, SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr=false)
SPIRVType * getOrCreateSPIRVTypeByName(StringRef TypeStr, MachineIRBuilder &MIRBuilder, bool EmitIR, SPIRV::StorageClass::StorageClass SC=SPIRV::StorageClass::Function, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite)
SPIRVType * getOrCreateLayoutType(MachineIRBuilder &MIRBuilder, const TargetExtType *T, bool EmitIr=false)
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R)
SPIRVType * getScalarOrVectorComponentType(Register VReg) const
SPIRVType * getOrCreateOpTypeFunctionWithArgs(const Type *Ty, SPIRVType *RetType, const SmallVectorImpl< SPIRVType * > &ArgTypes, MachineIRBuilder &MIRBuilder)
void buildAssignType(IRBuilder<> &B, Type *Ty, Value *Arg)
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR)
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
void updateIfExistAssignPtrTypeInstr(Value *OldVal, Value *NewVal, bool DeleteOld)
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder, bool EmitIR)
SPIRVType * getOrCreateOpTypeCoopMatr(MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType, const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns, uint32_t Use, bool EmitIR)
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII)
Register getOrCreateConstVector(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
SPIRVType * getOrCreateOpTypeDeviceEvent(MachineIRBuilder &MIRBuilder)
SPIRVType * getImageType(const TargetExtType *ExtensionType, const SPIRV::AccessQualifier::AccessQualifier Qualifier, MachineIRBuilder &MIRBuilder)
bool isResourceType(SPIRVType *Type) const
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR, bool ZeroAsNull=true)
SPIRVType * assignTypeToVReg(const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
LLT getRegType(SPIRVType *SpvType) const
void buildMemAliasingOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, uint32_t Dec, const MDNode *GVarMD)
SPIRV::StorageClass::StorageClass getPointerStorageClass(Register VReg) const
SPIRVType * getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder)
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param, unsigned FilerMode, MachineIRBuilder &MIRBuilder)
void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType)
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII, bool ZeroAsNull=true)
CallInst * findAssignPtrTypeInstr(const Value *Val)
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder, SPIRVType *SpvType)
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
const SPIRVType * retrieveScalarOrVectorIntType(const SPIRVType *Type) const
const MachineInstr * findMI(SPIRV::IRHandle Handle, const MachineFunction *MF)
bool erase(const MachineInstr *MI)
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI)
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:665
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:480
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:581
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:645
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:301
Class to represent struct types.
Definition: DerivedTypes.h:218
ArrayRef< Type * > elements() const
Definition: DerivedTypes.h:360
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:620
bool isPacked() const
Definition: DerivedTypes.h:286
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:368
bool hasName() const
Return true if this is a named struct that has a non-empty name.
Definition: DerivedTypes.h:328
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
Definition: Type.cpp:697
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:781
unsigned getNumIntParameters() const
Definition: DerivedTypes.h:838
Type * getTypeParameter(unsigned i) const
Definition: DerivedTypes.h:828
unsigned getNumTypeParameters() const
Definition: DerivedTypes.h:829
unsigned getIntParameter(unsigned i) const
Definition: DerivedTypes.h:837
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:273
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition: Type.h:264
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getArrayElementType() const
Definition: Type.h:408
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition: Type.h:304
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition: Type.h:184
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM_ABI uint64_t getArrayNumElements() const
static LLVM_ABI TypedPointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
'undef' values are things that do not have specified contents.
Definition: Constants.h:1420
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1866
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
static ConstantAsMetadata * getConstant(Value *C)
Definition: Metadata.h:479
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1098
bool hasName() const
Definition: Value.h:262
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Definition: DerivedTypes.h:695
Type * getElementType() const
Definition: DerivedTypes.h:463
const ParentTy * getParent() const
Definition: ilist_node.h:34
self_iterator getIterator()
Definition: ilist_node.h:134
IteratorT begin() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
IRHandle handle(const Type *Ty)
IRHandle irhandle_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
IRHandle irhandle_vkbuffer(const Type *ElementType, StorageClass::StorageClass SC, bool IsWriteable)
IRHandle irhandle_sampler()
TargetExtType * parseBuiltinTypeNameToTargetExtType(std::string TypeName, LLVMContext &Context)
Translates a string representing a SPIR-V or OpenCL builtin type to a TargetExtType that can be furth...
SPIRVType * lowerBuiltinType(const Type *OpaqueType, SPIRV::AccessQualifier::AccessQualifier AccessQual, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR)
IRHandle irhandle_event()
IRHandle irhandle_pipe(uint8_t AQ)
IRHandle irhandle_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
Reg
All possible values of the reg field in the ModR/M byte.
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
Definition: SPIRVUtils.cpp:113
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
Definition: SPIRVUtils.h:330
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getPointerAddressSpace(const Type *T)
Definition: SPIRVUtils.h:294
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
Definition: SPIRVUtils.cpp:93
LLVM_ABI 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...
Definition: Utils.cpp:155
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
Definition: SPIRVUtils.cpp:821
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition: Error.cpp:177
constexpr unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
Definition: SPIRVUtils.h:191
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
MetadataAsValue * buildMD(Value *Arg)
Definition: SPIRVUtils.h:440
bool isTypedPointerTy(const Type *T)
Definition: SPIRVUtils.h:278
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Definition: SPIRVUtils.cpp:140
Type * getTypedPointerWrapper(Type *ElemTy, unsigned AS)
Definition: SPIRVUtils.h:325
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:288
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Definition: SPIRVUtils.cpp:159
Type * toTypedPointer(Type *Ty)
Definition: SPIRVUtils.h:385
bool isSpecialOpaqueType(const Type *Ty)
Definition: SPIRVUtils.cpp:480
bool isPointerTy(const Type *T)
Definition: SPIRVUtils.h:288
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
Definition: SPIRVUtils.cpp:231
const Type * unifyPtrType(const Type *Ty)
Definition: SPIRVUtils.h:412
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
Definition: SPIRVUtils.cpp:245
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
Definition: SPIRVUtils.cpp:503
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:223
bool hasBuiltinTypePrefix(StringRef Name)
Definition: SPIRVUtils.cpp:473
bool isPointerTyOrWrapper(const Type *Ty)
Definition: SPIRVUtils.h:337
std::function< void(Register)> StructOffsetDecorator
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
Definition: SPIRVUtils.cpp:374
PoisonValue * getNormalizedPoisonValue(Type *Ty)
Definition: SPIRVUtils.h:436
void addStringImm(const StringRef &Str, MCInst &Inst)
Definition: SPIRVUtils.cpp:54
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
Definition: SPIRVUtils.cpp:747
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)
Definition: SPIRVUtils.cpp:183
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141