LLVM 22.0.0git
DXILOpBuilder.cpp
Go to the documentation of this file.
1//===- DXILOpBuilder.cpp - Helper class for build DIXLOp functions --------===//
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/// \file This file contains class to help build DXIL op functions.
10//===----------------------------------------------------------------------===//
11
12#include "DXILOpBuilder.h"
13#include "DXILConstants.h"
14#include "llvm/IR/Module.h"
17#include <optional>
18
19using namespace llvm;
20using namespace llvm::dxil;
21
22constexpr StringLiteral DXILOpNamePrefix = "dx.op.";
23
24namespace {
25enum OverloadKind : uint16_t {
26 UNDEFINED = 0,
27 VOID = 1,
28 HALF = 1 << 1,
29 FLOAT = 1 << 2,
30 DOUBLE = 1 << 3,
31 I1 = 1 << 4,
32 I8 = 1 << 5,
33 I16 = 1 << 6,
34 I32 = 1 << 7,
35 I64 = 1 << 8,
36 UserDefineType = 1 << 9,
37 ObjectType = 1 << 10,
38};
39struct Version {
40 unsigned Major = 0;
41 unsigned Minor = 0;
42};
43
44struct OpOverload {
45 Version DXILVersion;
46 uint16_t ValidTys;
47};
48} // namespace
49
54
55static const char *getOverloadTypeName(OverloadKind Kind) {
56 switch (Kind) {
57 case OverloadKind::HALF:
58 return "f16";
59 case OverloadKind::FLOAT:
60 return "f32";
61 case OverloadKind::DOUBLE:
62 return "f64";
63 case OverloadKind::I1:
64 return "i1";
65 case OverloadKind::I8:
66 return "i8";
67 case OverloadKind::I16:
68 return "i16";
69 case OverloadKind::I32:
70 return "i32";
71 case OverloadKind::I64:
72 return "i64";
73 case OverloadKind::VOID:
74 case OverloadKind::UNDEFINED:
75 return "void";
76 case OverloadKind::ObjectType:
77 case OverloadKind::UserDefineType:
78 break;
79 }
80 llvm_unreachable("invalid overload type for name");
81}
82
83static OverloadKind getOverloadKind(Type *Ty) {
84 if (!Ty)
85 return OverloadKind::VOID;
86
87 Type::TypeID T = Ty->getTypeID();
88 switch (T) {
89 case Type::VoidTyID:
90 return OverloadKind::VOID;
91 case Type::HalfTyID:
92 return OverloadKind::HALF;
93 case Type::FloatTyID:
94 return OverloadKind::FLOAT;
96 return OverloadKind::DOUBLE;
97 case Type::IntegerTyID: {
99 unsigned Bits = ITy->getBitWidth();
100 switch (Bits) {
101 case 1:
102 return OverloadKind::I1;
103 case 8:
104 return OverloadKind::I8;
105 case 16:
106 return OverloadKind::I16;
107 case 32:
108 return OverloadKind::I32;
109 case 64:
110 return OverloadKind::I64;
111 default:
112 llvm_unreachable("invalid overload type");
113 return OverloadKind::VOID;
114 }
115 }
117 return OverloadKind::UserDefineType;
118 case Type::StructTyID: {
119 // TODO: This is a hack. As described in DXILEmitter.cpp, we need to rework
120 // how we're handling overloads and remove the `OverloadKind` proxy enum.
122 return getOverloadKind(ST->getElementType(0));
123 }
124 default:
125 return OverloadKind::UNDEFINED;
126 }
127}
128
129static std::string getTypeName(OverloadKind Kind, Type *Ty) {
130 if (Kind < OverloadKind::UserDefineType) {
131 return getOverloadTypeName(Kind);
132 } else if (Kind == OverloadKind::UserDefineType) {
134 return ST->getStructName().str();
135 } else if (Kind == OverloadKind::ObjectType) {
137 return ST->getStructName().str();
138 } else {
139 std::string Str;
140 raw_string_ostream OS(Str);
141 Ty->print(OS);
142 return OS.str();
143 }
144}
145
146// Static properties.
149 // Offset in DXILOpCodeNameTable.
152 // Offset in DXILOpCodeClassNameTable.
156 int OverloadParamIndex; // parameter index which control the overload.
157 // When < 0, should be only 1 overload type.
158};
159
160// Include getOpCodeClassName getOpCodeProperty, getOpCodeName and
161// getOpCodeParameterKind which generated by tableGen.
162#define DXIL_OP_OPERATION_TABLE
163#include "DXILOperation.inc"
164#undef DXIL_OP_OPERATION_TABLE
165
166static std::string constructOverloadName(OverloadKind Kind, Type *Ty,
167 const OpCodeProperty &Prop) {
168 if (Kind == OverloadKind::VOID) {
169 return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop)).str();
170 }
171 return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop) + "." +
172 getTypeName(Kind, Ty))
173 .str();
174}
175
176static std::string constructOverloadTypeName(OverloadKind Kind,
177 StringRef TypeName) {
178 if (Kind == OverloadKind::VOID)
179 return TypeName.str();
180
181 assert(Kind < OverloadKind::UserDefineType && "invalid overload kind");
182 return (Twine(TypeName) + getOverloadTypeName(Kind)).str();
183}
184
186 ArrayRef<Type *> EltTys,
187 LLVMContext &Ctx) {
188 StructType *ST = StructType::getTypeByName(Ctx, Name);
189 if (ST)
190 return ST;
191
192 return StructType::create(Ctx, EltTys, Name);
193}
194
195static StructType *getResRetType(Type *ElementTy) {
196 LLVMContext &Ctx = ElementTy->getContext();
197 OverloadKind Kind = getOverloadKind(ElementTy);
198 std::string TypeName = constructOverloadTypeName(Kind, "dx.types.ResRet.");
199 Type *FieldTypes[5] = {ElementTy, ElementTy, ElementTy, ElementTy,
200 Type::getInt32Ty(Ctx)};
201 return getOrCreateStructType(TypeName, FieldTypes, Ctx);
202}
203
204static StructType *getCBufRetType(Type *ElementTy) {
205 LLVMContext &Ctx = ElementTy->getContext();
206 OverloadKind Kind = getOverloadKind(ElementTy);
207 std::string TypeName = constructOverloadTypeName(Kind, "dx.types.CBufRet.");
208
209 // 64-bit types only have two elements
210 if (ElementTy->isDoubleTy() || ElementTy->isIntegerTy(64))
211 return getOrCreateStructType(TypeName, {ElementTy, ElementTy}, Ctx);
212
213 // 16-bit types pack 8 elements and have .8 in their name to differentiate
214 // from min-precision types.
215 if (ElementTy->isHalfTy() || ElementTy->isIntegerTy(16)) {
216 TypeName += ".8";
217 return getOrCreateStructType(TypeName,
218 {ElementTy, ElementTy, ElementTy, ElementTy,
219 ElementTy, ElementTy, ElementTy, ElementTy},
220 Ctx);
221 }
222
224 TypeName, {ElementTy, ElementTy, ElementTy, ElementTy}, Ctx);
225}
226
228 return getOrCreateStructType("dx.types.Handle", PointerType::getUnqual(Ctx),
229 Ctx);
230}
231
233 if (auto *ST = StructType::getTypeByName(Context, "dx.types.ResBind"))
234 return ST;
235 Type *Int32Ty = Type::getInt32Ty(Context);
236 Type *Int8Ty = Type::getInt8Ty(Context);
237 return StructType::create({Int32Ty, Int32Ty, Int32Ty, Int8Ty},
238 "dx.types.ResBind");
239}
240
242 if (auto *ST =
243 StructType::getTypeByName(Context, "dx.types.ResourceProperties"))
244 return ST;
245 Type *Int32Ty = Type::getInt32Ty(Context);
246 return StructType::create({Int32Ty, Int32Ty}, "dx.types.ResourceProperties");
247}
248
250 if (auto *ST = StructType::getTypeByName(Context, "dx.types.splitdouble"))
251 return ST;
252 Type *Int32Ty = Type::getInt32Ty(Context);
253 return StructType::create({Int32Ty, Int32Ty}, "dx.types.splitdouble");
254}
255
257 if (auto *ST = StructType::getTypeByName(Context, "dx.types.i32c"))
258 return ST;
259 Type *Int32Ty = Type::getInt32Ty(Context);
260 Type *Int1Ty = Type::getInt1Ty(Context);
261 return StructType::create({Int32Ty, Int1Ty}, "dx.types.i32c");
262}
263
265 Type *OverloadTy) {
266 switch (Kind) {
267 case OpParamType::VoidTy:
268 return Type::getVoidTy(Ctx);
269 case OpParamType::HalfTy:
270 return Type::getHalfTy(Ctx);
271 case OpParamType::FloatTy:
272 return Type::getFloatTy(Ctx);
273 case OpParamType::DoubleTy:
274 return Type::getDoubleTy(Ctx);
275 case OpParamType::Int1Ty:
276 return Type::getInt1Ty(Ctx);
277 case OpParamType::Int8Ty:
278 return Type::getInt8Ty(Ctx);
279 case OpParamType::Int16Ty:
280 return Type::getInt16Ty(Ctx);
281 case OpParamType::Int32Ty:
282 return Type::getInt32Ty(Ctx);
283 case OpParamType::Int64Ty:
284 return Type::getInt64Ty(Ctx);
285 case OpParamType::OverloadTy:
286 return OverloadTy;
287 case OpParamType::ResRetHalfTy:
288 return getResRetType(Type::getHalfTy(Ctx));
289 case OpParamType::ResRetFloatTy:
290 return getResRetType(Type::getFloatTy(Ctx));
291 case OpParamType::ResRetDoubleTy:
292 return getResRetType(Type::getDoubleTy(Ctx));
293 case OpParamType::ResRetInt16Ty:
294 return getResRetType(Type::getInt16Ty(Ctx));
295 case OpParamType::ResRetInt32Ty:
296 return getResRetType(Type::getInt32Ty(Ctx));
297 case OpParamType::ResRetInt64Ty:
298 return getResRetType(Type::getInt64Ty(Ctx));
299 case OpParamType::CBufRetHalfTy:
300 return getCBufRetType(Type::getHalfTy(Ctx));
301 case OpParamType::CBufRetFloatTy:
302 return getCBufRetType(Type::getFloatTy(Ctx));
303 case OpParamType::CBufRetDoubleTy:
305 case OpParamType::CBufRetInt16Ty:
306 return getCBufRetType(Type::getInt16Ty(Ctx));
307 case OpParamType::CBufRetInt32Ty:
308 return getCBufRetType(Type::getInt32Ty(Ctx));
309 case OpParamType::CBufRetInt64Ty:
310 return getCBufRetType(Type::getInt64Ty(Ctx));
311 case OpParamType::HandleTy:
312 return getHandleType(Ctx);
313 case OpParamType::ResBindTy:
314 return getResBindType(Ctx);
315 case OpParamType::ResPropsTy:
316 return getResPropsType(Ctx);
317 case OpParamType::SplitDoubleTy:
318 return getSplitDoubleType(Ctx);
319 case OpParamType::BinaryWithCarryTy:
320 return getBinaryWithCarryType(Ctx);
321 }
322 llvm_unreachable("Invalid parameter kind");
323 return nullptr;
324}
325
326static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) {
327 switch (EnvType) {
328 case Triple::Pixel:
329 return ShaderKind::pixel;
330 case Triple::Vertex:
331 return ShaderKind::vertex;
332 case Triple::Geometry:
333 return ShaderKind::geometry;
334 case Triple::Hull:
335 return ShaderKind::hull;
336 case Triple::Domain:
337 return ShaderKind::domain;
338 case Triple::Compute:
339 return ShaderKind::compute;
340 case Triple::Library:
341 return ShaderKind::library;
343 return ShaderKind::raygeneration;
345 return ShaderKind::intersection;
346 case Triple::AnyHit:
347 return ShaderKind::anyhit;
349 return ShaderKind::closesthit;
350 case Triple::Miss:
351 return ShaderKind::miss;
352 case Triple::Callable:
353 return ShaderKind::callable;
354 case Triple::Mesh:
355 return ShaderKind::mesh;
357 return ShaderKind::amplification;
358 default:
359 break;
360 }
362 "Shader Kind Not Found - Invalid DXIL Environment Specified");
363}
364
367 LLVMContext &Context, Type *OverloadTy) {
368 SmallVector<Type *> ArgTys;
369 ArgTys.emplace_back(Type::getInt32Ty(Context));
370 for (dxil::OpParamType Ty : Types)
371 ArgTys.emplace_back(getTypeFromOpParamType(Ty, Context, OverloadTy));
372 return ArgTys;
373}
374
375/// Construct DXIL function type. This is the type of a function with
376/// the following prototype
377/// OverloadType dx.op.<opclass>.<return-type>(int opcode, <param types>)
378/// <param-types> are constructed from types in Prop.
380 LLVMContext &Context,
381 Type *OverloadTy) {
382
383 switch (OpCode) {
384#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...) \
385 case OpCode: \
386 return FunctionType::get( \
387 getTypeFromOpParamType(RetType, Context, OverloadTy), \
388 getArgTypesFromOpParamTypes({__VA_ARGS__}, Context, OverloadTy), \
389 /*isVarArg=*/false);
390#include "DXILOperation.inc"
391 }
392 llvm_unreachable("Invalid OpCode?");
393}
394
395/// Get index of the property from PropList valid for the most recent
396/// DXIL version not greater than DXILVer.
397/// PropList is expected to be sorted in ascending order of DXIL version.
398template <typename T>
399static std::optional<size_t> getPropIndex(ArrayRef<T> PropList,
400 const VersionTuple DXILVer) {
401 size_t Index = PropList.size() - 1;
402 for (auto Iter = PropList.rbegin(); Iter != PropList.rend();
403 Iter++, Index--) {
404 const T &Prop = *Iter;
405 if (VersionTuple(Prop.DXILVersion.Major, Prop.DXILVersion.Minor) <=
406 DXILVer) {
407 return Index;
408 }
409 }
410 return std::nullopt;
411}
412
413// Helper function to pack an OpCode and VersionTuple into a uint64_t for use
414// in a switch statement
416 uint16_t VersionMajor,
417 uint16_t VersionMinor) {
418 uint64_t OpCodePack = (uint64_t)OpCode;
419 return (OpCodePack << 32) | (VersionMajor << 16) | VersionMinor;
420}
421
422// Retreive all the set attributes for a DXIL OpCode given the targeted
423// DXILVersion
425 VersionTuple DXILVersion) {
426 // Instantiate all versions to iterate through
427 SmallVector<Version> Versions = {
428#define DXIL_VERSION(MAJOR, MINOR) {MAJOR, MINOR},
429#include "DXILOperation.inc"
430 };
431
432 dxil::Attributes Attributes;
433 for (auto Version : Versions) {
434 if (DXILVersion < VersionTuple(Version.Major, Version.Minor))
435 continue;
436
437 // Switch through and match an OpCode with the specific version and set the
438 // corresponding flag(s) if available
439 switch (computeSwitchEnum(OpCode, Version.Major, Version.Minor)) {
440#define DXIL_OP_ATTRIBUTES(OpCode, VersionMajor, VersionMinor, ...) \
441 case computeSwitchEnum(OpCode, VersionMajor, VersionMinor): { \
442 auto Other = dxil::Attributes{__VA_ARGS__}; \
443 Attributes |= Other; \
444 break; \
445 };
446#include "DXILOperation.inc"
447 }
448 }
449 return Attributes;
450}
451
452// Retreive the set of DXIL Attributes given the version and map them to an
453// llvm function attribute that is set onto the instruction
455 VersionTuple DXILVersion) {
456 dxil::Attributes Attributes = getDXILAttributes(OpCode, DXILVersion);
457 if (Attributes.ReadNone)
459 if (Attributes.ReadOnly)
460 CI->setOnlyReadsMemory();
461 if (Attributes.NoReturn)
462 CI->setDoesNotReturn();
463 if (Attributes.NoDuplicate)
464 CI->setCannotDuplicate();
465 return;
466}
467
468namespace llvm {
469namespace dxil {
470
471// No extra checks on TargetTriple need be performed to verify that the
472// Triple is well-formed or that the target is supported since these checks
473// would have been done at the time the module M is constructed in the earlier
474// stages of compilation.
475DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) {
476 const Triple &TT = M.getTargetTriple();
477 DXILVersion = TT.getDXILVersion();
478 ShaderStage = TT.getEnvironment();
479 // Ensure Environment type is known
480 if (ShaderStage == Triple::UnknownEnvironment) {
482 Twine(DXILVersion.getAsString()) +
483 ": Unknown Compilation Target Shader Stage specified ");
484 }
485}
486
489 Twine("Cannot create ") + getOpCodeName(OpCode) + " operation: " + Msg,
491}
492
495 const Twine &Name,
496 Type *RetTy) {
497 const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
498
499 Type *OverloadTy = nullptr;
500 if (Prop->OverloadParamIndex == 0) {
501 if (!RetTy)
502 return makeOpError(OpCode, "Op overloaded on unknown return type");
503 OverloadTy = RetTy;
504 } else if (Prop->OverloadParamIndex > 0) {
505 // The index counts including the return type
506 unsigned ArgIndex = Prop->OverloadParamIndex - 1;
507 if (static_cast<unsigned>(ArgIndex) >= Args.size())
508 return makeOpError(OpCode, "Wrong number of arguments");
509 OverloadTy = Args[ArgIndex]->getType();
510 }
511
512 FunctionType *DXILOpFT =
513 getDXILOpFunctionType(OpCode, M.getContext(), OverloadTy);
514
515 std::optional<size_t> OlIndexOrErr =
516 getPropIndex(ArrayRef(Prop->Overloads), DXILVersion);
517 if (!OlIndexOrErr.has_value())
518 return makeOpError(OpCode, Twine("No valid overloads for DXIL version ") +
519 DXILVersion.getAsString());
520
521 uint16_t ValidTyMask = Prop->Overloads[*OlIndexOrErr].ValidTys;
522
523 OverloadKind Kind = getOverloadKind(OverloadTy);
524
525 // Check if the operation supports overload types and OverloadTy is valid
526 // per the specified types for the operation
527 if ((ValidTyMask != OverloadKind::UNDEFINED) &&
528 (ValidTyMask & (uint16_t)Kind) == 0)
529 return makeOpError(OpCode, "Invalid overload type");
530
531 // Perform necessary checks to ensure Opcode is valid in the targeted shader
532 // kind
533 std::optional<size_t> StIndexOrErr =
534 getPropIndex(ArrayRef(Prop->Stages), DXILVersion);
535 if (!StIndexOrErr.has_value())
536 return makeOpError(OpCode, Twine("No valid stage for DXIL version ") +
537 DXILVersion.getAsString());
538
539 uint16_t ValidShaderKindMask = Prop->Stages[*StIndexOrErr].ValidStages;
540
541 // Ensure valid shader stage properties are specified
542 if (ValidShaderKindMask == ShaderKind::removed)
543 return makeOpError(OpCode, "Operation has been removed");
544
545 // Shader stage need not be validated since getShaderKindEnum() fails
546 // for unknown shader stage.
547
548 // Verify the target shader stage is valid for the DXIL operation
549 ShaderKind ModuleStagekind = getShaderKindEnum(ShaderStage);
550 if (!(ValidShaderKindMask & ModuleStagekind))
551 return makeOpError(OpCode, "Invalid stage");
552
553 std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop);
554 FunctionCallee DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT);
555
556 // We need to inject the opcode as the first argument.
558 OpArgs.push_back(IRB.getInt32(llvm::to_underlying(OpCode)));
559 OpArgs.append(Args.begin(), Args.end());
560
561 // Create the function call instruction
562 CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
563
564 // We then need to attach available function attributes
565 setDXILAttributes(CI, OpCode, DXILVersion);
566
567 return CI;
568}
569
571 const Twine &Name, Type *RetTy) {
572 Expected<CallInst *> Result = tryCreateOp(OpCode, Args, Name, RetTy);
573 if (Error E = Result.takeError())
574 llvm_unreachable("Invalid arguments for operation");
575 return *Result;
576}
577
579 return ::getResRetType(ElementTy);
580}
581
583 return ::getCBufRetType(ElementTy);
584}
585
587 return ::getHandleType(IRB.getContext());
588}
589
591 uint32_t SpaceID, dxil::ResourceClass RC) {
592 Type *Int32Ty = IRB.getInt32Ty();
593 Type *Int8Ty = IRB.getInt8Ty();
594 return ConstantStruct::get(
595 getResBindType(IRB.getContext()),
596 {ConstantInt::get(Int32Ty, LowerBound),
597 ConstantInt::get(Int32Ty, UpperBound),
598 ConstantInt::get(Int32Ty, SpaceID),
599 ConstantInt::get(Int8Ty, llvm::to_underlying(RC))});
600}
601
603 Type *Int32Ty = IRB.getInt32Ty();
604 return ConstantStruct::get(
605 getResPropsType(IRB.getContext()),
606 {ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
607}
608
610 return ::getOpCodeName(DXILOp);
611}
612} // namespace dxil
613} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static StructType * getResRetType(Type *ElementTy)
static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType)
static Type * getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx, Type *OverloadTy)
static std::optional< size_t > getPropIndex(ArrayRef< T > PropList, const VersionTuple DXILVer)
Get index of the property from PropList valid for the most recent DXIL version not greater than DXILV...
static SmallVector< Type * > getArgTypesFromOpParamTypes(ArrayRef< dxil::OpParamType > Types, LLVMContext &Context, Type *OverloadTy)
static void setDXILAttributes(CallInst *CI, dxil::OpCode OpCode, VersionTuple DXILVersion)
static const char * getOverloadTypeName(OverloadKind Kind)
static StructType * getCBufRetType(Type *ElementTy)
static StructType * getSplitDoubleType(LLVMContext &Context)
static OverloadKind getOverloadKind(Type *Ty)
static constexpr uint64_t computeSwitchEnum(dxil::OpCode OpCode, uint16_t VersionMajor, uint16_t VersionMinor)
static StructType * getBinaryWithCarryType(LLVMContext &Context)
static StructType * getOrCreateStructType(StringRef Name, ArrayRef< Type * > EltTys, LLVMContext &Ctx)
static StructType * getHandleType(LLVMContext &Ctx)
static dxil::Attributes getDXILAttributes(dxil::OpCode OpCode, VersionTuple DXILVersion)
static std::string constructOverloadName(OverloadKind Kind, Type *Ty, const OpCodeProperty &Prop)
static FunctionType * getDXILOpFunctionType(dxil::OpCode OpCode, LLVMContext &Context, Type *OverloadTy)
Construct DXIL function type.
constexpr StringLiteral DXILOpNamePrefix
static std::string constructOverloadTypeName(OverloadKind Kind, StringRef TypeName)
static StructType * getResPropsType(LLVMContext &Context)
static StructType * getResBindType(LLVMContext &Context)
Module.h This file contains the declarations for the Module class.
#define T
@ UNDEFINED
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
reverse_iterator rend() const
Definition ArrayRef.h:139
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
reverse_iterator rbegin() const
Definition ArrayRef.h:138
void setDoesNotReturn()
LLVM_ABI void setDoesNotAccessMemory()
LLVM_ABI void setOnlyReadsMemory()
void setCannotDuplicate()
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:43
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Class to represent function types.
Class to represent integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:862
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Class to represent struct types.
static LLVM_ABI StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
Definition Type.cpp:739
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:620
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
@ RayGeneration
Definition Triple.h:300
@ UnknownEnvironment
Definition Triple.h:253
@ Amplification
Definition Triple.h:307
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 IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:298
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:297
TypeID
Definitions of all of the base types for the Type system.
Definition Type.h:54
@ HalfTyID
16-bit floating point type
Definition Type.h:56
@ VoidTyID
type with no size
Definition Type.h:63
@ FloatTyID
32-bit floating point type
Definition Type.h:58
@ StructTyID
Structures.
Definition Type.h:73
@ IntegerTyID
Arbitrary bit width integers.
Definition Type.h:70
@ DoubleTyID
64-bit floating point type
Definition Type.h:59
@ PointerTyID
Pointers.
Definition Type.h:72
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:281
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:295
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:296
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:142
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:128
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:156
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:294
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:286
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:285
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Definition Type.cpp:283
Represents a version number in the form major[.minor[.subminor[.build]]].
StructType * getResRetType(Type *ElementTy)
Get a dx.types.ResRet type with the given element type.
Expected< CallInst * > tryCreateOp(dxil::OpCode Op, ArrayRef< Value * > Args, const Twine &Name="", Type *RetTy=nullptr)
Try to create a call instruction for the given DXIL op.
CallInst * createOp(dxil::OpCode Op, ArrayRef< Value * > Args, const Twine &Name="", Type *RetTy=nullptr)
Create a call instruction for the given DXIL op.
Constant * getResBind(uint32_t LowerBound, uint32_t UpperBound, uint32_t SpaceID, dxil::ResourceClass RC)
Get a constant dx.types.ResBind value.
static const char * getOpCodeName(dxil::OpCode DXILOp)
Return the name of the given opcode.
Constant * getResProps(uint32_t Word0, uint32_t Word1)
Get a constant dx.types.ResourceProperties value.
StructType * getHandleType()
Get the dx.types.Handle type.
StructType * getCBufRetType(Type *ElementTy)
Get a dx.types.CBufRet type with the given element type.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static Error makeOpError(dxil::OpCode OpCode, Twine Msg)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:296
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:98
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition TypeName.h:40
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:180
llvm::SmallVector< OpOverload > Overloads
dxil::OpCodeClass OpCodeClass
unsigned OpCodeNameOffset
unsigned OpCodeClassNameOffset
llvm::SmallVector< OpStage > Stages
dxil::OpCode OpCode
uint32_t ValidStages
Version DXILVersion