LLVM 20.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
50struct OpStage {
51 Version DXILVersion;
53};
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: {
98 IntegerType *ITy = cast<IntegerType>(Ty);
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.
121 StructType *ST = cast<StructType>(Ty);
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) {
133 StructType *ST = cast<StructType>(Ty);
134 return ST->getStructName().str();
135 } else if (Kind == OverloadKind::ObjectType) {
136 StructType *ST = cast<StructType>(Ty);
137 return ST->getStructName().str();
138 } else {
139 std::string 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) {
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
205 return getOrCreateStructType("dx.types.Handle", PointerType::getUnqual(Ctx),
206 Ctx);
207}
208
210 if (auto *ST = StructType::getTypeByName(Context, "dx.types.ResBind"))
211 return ST;
212 Type *Int32Ty = Type::getInt32Ty(Context);
213 Type *Int8Ty = Type::getInt8Ty(Context);
214 return StructType::create({Int32Ty, Int32Ty, Int32Ty, Int8Ty},
215 "dx.types.ResBind");
216}
217
219 if (auto *ST =
220 StructType::getTypeByName(Context, "dx.types.ResourceProperties"))
221 return ST;
222 Type *Int32Ty = Type::getInt32Ty(Context);
223 return StructType::create({Int32Ty, Int32Ty}, "dx.types.ResourceProperties");
224}
225
227 if (auto *ST = StructType::getTypeByName(Context, "dx.types.splitdouble"))
228 return ST;
229 Type *Int32Ty = Type::getInt32Ty(Context);
230 return StructType::create({Int32Ty, Int32Ty}, "dx.types.splitdouble");
231}
232
234 Type *OverloadTy) {
235 switch (Kind) {
236 case OpParamType::VoidTy:
237 return Type::getVoidTy(Ctx);
238 case OpParamType::HalfTy:
239 return Type::getHalfTy(Ctx);
240 case OpParamType::FloatTy:
241 return Type::getFloatTy(Ctx);
242 case OpParamType::DoubleTy:
243 return Type::getDoubleTy(Ctx);
244 case OpParamType::Int1Ty:
245 return Type::getInt1Ty(Ctx);
246 case OpParamType::Int8Ty:
247 return Type::getInt8Ty(Ctx);
248 case OpParamType::Int16Ty:
249 return Type::getInt16Ty(Ctx);
250 case OpParamType::Int32Ty:
251 return Type::getInt32Ty(Ctx);
252 case OpParamType::Int64Ty:
253 return Type::getInt64Ty(Ctx);
254 case OpParamType::OverloadTy:
255 return OverloadTy;
256 case OpParamType::ResRetHalfTy:
257 return getResRetType(Type::getHalfTy(Ctx));
258 case OpParamType::ResRetFloatTy:
259 return getResRetType(Type::getFloatTy(Ctx));
260 case OpParamType::ResRetDoubleTy:
261 return getResRetType(Type::getDoubleTy(Ctx));
262 case OpParamType::ResRetInt16Ty:
263 return getResRetType(Type::getInt16Ty(Ctx));
264 case OpParamType::ResRetInt32Ty:
265 return getResRetType(Type::getInt32Ty(Ctx));
266 case OpParamType::ResRetInt64Ty:
267 return getResRetType(Type::getInt64Ty(Ctx));
268 case OpParamType::HandleTy:
269 return getHandleType(Ctx);
270 case OpParamType::ResBindTy:
271 return getResBindType(Ctx);
272 case OpParamType::ResPropsTy:
273 return getResPropsType(Ctx);
274 case OpParamType::SplitDoubleTy:
275 return getSplitDoubleType(Ctx);
276 }
277 llvm_unreachable("Invalid parameter kind");
278 return nullptr;
279}
280
281static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) {
282 switch (EnvType) {
283 case Triple::Pixel:
284 return ShaderKind::pixel;
285 case Triple::Vertex:
286 return ShaderKind::vertex;
287 case Triple::Geometry:
288 return ShaderKind::geometry;
289 case Triple::Hull:
290 return ShaderKind::hull;
291 case Triple::Domain:
292 return ShaderKind::domain;
293 case Triple::Compute:
294 return ShaderKind::compute;
295 case Triple::Library:
296 return ShaderKind::library;
298 return ShaderKind::raygeneration;
300 return ShaderKind::intersection;
301 case Triple::AnyHit:
302 return ShaderKind::anyhit;
304 return ShaderKind::closesthit;
305 case Triple::Miss:
306 return ShaderKind::miss;
307 case Triple::Callable:
308 return ShaderKind::callable;
309 case Triple::Mesh:
310 return ShaderKind::mesh;
312 return ShaderKind::amplification;
313 default:
314 break;
315 }
317 "Shader Kind Not Found - Invalid DXIL Environment Specified");
318}
319
322 LLVMContext &Context, Type *OverloadTy) {
323 SmallVector<Type *> ArgTys;
324 ArgTys.emplace_back(Type::getInt32Ty(Context));
325 for (dxil::OpParamType Ty : Types)
326 ArgTys.emplace_back(getTypeFromOpParamType(Ty, Context, OverloadTy));
327 return ArgTys;
328}
329
330/// Construct DXIL function type. This is the type of a function with
331/// the following prototype
332/// OverloadType dx.op.<opclass>.<return-type>(int opcode, <param types>)
333/// <param-types> are constructed from types in Prop.
335 LLVMContext &Context,
336 Type *OverloadTy) {
337
338 switch (OpCode) {
339#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...) \
340 case OpCode: \
341 return FunctionType::get( \
342 getTypeFromOpParamType(RetType, Context, OverloadTy), \
343 getArgTypesFromOpParamTypes({__VA_ARGS__}, Context, OverloadTy), \
344 /*isVarArg=*/false);
345#include "DXILOperation.inc"
346 }
347 llvm_unreachable("Invalid OpCode?");
348}
349
350/// Get index of the property from PropList valid for the most recent
351/// DXIL version not greater than DXILVer.
352/// PropList is expected to be sorted in ascending order of DXIL version.
353template <typename T>
354static std::optional<size_t> getPropIndex(ArrayRef<T> PropList,
355 const VersionTuple DXILVer) {
356 size_t Index = PropList.size() - 1;
357 for (auto Iter = PropList.rbegin(); Iter != PropList.rend();
358 Iter++, Index--) {
359 const T &Prop = *Iter;
360 if (VersionTuple(Prop.DXILVersion.Major, Prop.DXILVersion.Minor) <=
361 DXILVer) {
362 return Index;
363 }
364 }
365 return std::nullopt;
366}
367
368// Helper function to pack an OpCode and VersionTuple into a uint64_t for use
369// in a switch statement
371 uint16_t VersionMajor,
372 uint16_t VersionMinor) {
373 uint64_t OpCodePack = (uint64_t)OpCode;
374 return (OpCodePack << 32) | (VersionMajor << 16) | VersionMinor;
375}
376
377// Retreive all the set attributes for a DXIL OpCode given the targeted
378// DXILVersion
380 VersionTuple DXILVersion) {
381 // Instantiate all versions to iterate through
382 SmallVector<Version> Versions = {
383#define DXIL_VERSION(MAJOR, MINOR) {MAJOR, MINOR},
384#include "DXILOperation.inc"
385 };
386
388 for (auto Version : Versions) {
389 if (DXILVersion < VersionTuple(Version.Major, Version.Minor))
390 continue;
391
392 // Switch through and match an OpCode with the specific version and set the
393 // corresponding flag(s) if available
394 switch (computeSwitchEnum(OpCode, Version.Major, Version.Minor)) {
395#define DXIL_OP_ATTRIBUTES(OpCode, VersionMajor, VersionMinor, ...) \
396 case computeSwitchEnum(OpCode, VersionMajor, VersionMinor): { \
397 auto Other = dxil::Attributes{__VA_ARGS__}; \
398 Attributes |= Other; \
399 break; \
400 };
401#include "DXILOperation.inc"
402 }
403 }
404 return Attributes;
405}
406
407// Retreive the set of DXIL Attributes given the version and map them to an
408// llvm function attribute that is set onto the instruction
410 VersionTuple DXILVersion) {
412 if (Attributes.ReadNone)
414 if (Attributes.ReadOnly)
415 CI->setOnlyReadsMemory();
416 if (Attributes.NoReturn)
417 CI->setDoesNotReturn();
418 if (Attributes.NoDuplicate)
419 CI->setCannotDuplicate();
420 return;
421}
422
423namespace llvm {
424namespace dxil {
425
426// No extra checks on TargetTriple need be performed to verify that the
427// Triple is well-formed or that the target is supported since these checks
428// would have been done at the time the module M is constructed in the earlier
429// stages of compilation.
430DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) {
431 Triple TT(Triple(M.getTargetTriple()));
432 DXILVersion = TT.getDXILVersion();
433 ShaderStage = TT.getEnvironment();
434 // Ensure Environment type is known
435 if (ShaderStage == Triple::UnknownEnvironment) {
437 Twine(DXILVersion.getAsString()) +
438 ": Unknown Compilation Target Shader Stage specified ",
439 /*gen_crash_diag*/ false);
440 }
441}
442
444 return make_error<StringError>(
445 Twine("Cannot create ") + getOpCodeName(OpCode) + " operation: " + Msg,
447}
448
451 const Twine &Name,
452 Type *RetTy) {
453 const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
454
455 Type *OverloadTy = nullptr;
456 if (Prop->OverloadParamIndex == 0) {
457 if (!RetTy)
458 return makeOpError(OpCode, "Op overloaded on unknown return type");
459 OverloadTy = RetTy;
460 } else if (Prop->OverloadParamIndex > 0) {
461 // The index counts including the return type
462 unsigned ArgIndex = Prop->OverloadParamIndex - 1;
463 if (static_cast<unsigned>(ArgIndex) >= Args.size())
464 return makeOpError(OpCode, "Wrong number of arguments");
465 OverloadTy = Args[ArgIndex]->getType();
466 }
467
468 FunctionType *DXILOpFT =
469 getDXILOpFunctionType(OpCode, M.getContext(), OverloadTy);
470
471 std::optional<size_t> OlIndexOrErr =
472 getPropIndex(ArrayRef(Prop->Overloads), DXILVersion);
473 if (!OlIndexOrErr.has_value())
474 return makeOpError(OpCode, Twine("No valid overloads for DXIL version ") +
475 DXILVersion.getAsString());
476
477 uint16_t ValidTyMask = Prop->Overloads[*OlIndexOrErr].ValidTys;
478
479 OverloadKind Kind = getOverloadKind(OverloadTy);
480
481 // Check if the operation supports overload types and OverloadTy is valid
482 // per the specified types for the operation
483 if ((ValidTyMask != OverloadKind::UNDEFINED) &&
484 (ValidTyMask & (uint16_t)Kind) == 0)
485 return makeOpError(OpCode, "Invalid overload type");
486
487 // Perform necessary checks to ensure Opcode is valid in the targeted shader
488 // kind
489 std::optional<size_t> StIndexOrErr =
490 getPropIndex(ArrayRef(Prop->Stages), DXILVersion);
491 if (!StIndexOrErr.has_value())
492 return makeOpError(OpCode, Twine("No valid stage for DXIL version ") +
493 DXILVersion.getAsString());
494
495 uint16_t ValidShaderKindMask = Prop->Stages[*StIndexOrErr].ValidStages;
496
497 // Ensure valid shader stage properties are specified
498 if (ValidShaderKindMask == ShaderKind::removed)
499 return makeOpError(OpCode, "Operation has been removed");
500
501 // Shader stage need not be validated since getShaderKindEnum() fails
502 // for unknown shader stage.
503
504 // Verify the target shader stage is valid for the DXIL operation
505 ShaderKind ModuleStagekind = getShaderKindEnum(ShaderStage);
506 if (!(ValidShaderKindMask & ModuleStagekind))
507 return makeOpError(OpCode, "Invalid stage");
508
509 std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop);
510 FunctionCallee DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT);
511
512 // We need to inject the opcode as the first argument.
515 OpArgs.append(Args.begin(), Args.end());
516
517 // Create the function call instruction
518 CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
519
520 // We then need to attach available function attributes
521 setDXILAttributes(CI, OpCode, DXILVersion);
522
523 return CI;
524}
525
527 const Twine &Name, Type *RetTy) {
529 if (Error E = Result.takeError())
530 llvm_unreachable("Invalid arguments for operation");
531 return *Result;
532}
533
535 return ::getResRetType(ElementTy);
536}
537
539 return ::getSplitDoubleType(Context);
540}
541
543 return ::getHandleType(IRB.getContext());
544}
545
547 uint32_t SpaceID, dxil::ResourceClass RC) {
548 Type *Int32Ty = IRB.getInt32Ty();
549 Type *Int8Ty = IRB.getInt8Ty();
550 return ConstantStruct::get(
552 {ConstantInt::get(Int32Ty, LowerBound),
553 ConstantInt::get(Int32Ty, UpperBound),
554 ConstantInt::get(Int32Ty, SpaceID),
555 ConstantInt::get(Int8Ty, llvm::to_underlying(RC))});
556}
557
559 Type *Int32Ty = IRB.getInt32Ty();
560 return ConstantStruct::get(
562 {ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
563}
564
566 return ::getOpCodeName(DXILOp);
567}
568} // namespace dxil
569} // namespace llvm
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 * getSplitDoubleType(LLVMContext &Context)
static OverloadKind getOverloadKind(Type *Ty)
static constexpr uint64_t computeSwitchEnum(dxil::OpCode OpCode, uint16_t VersionMajor, uint16_t VersionMinor)
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)
return RetTy
std::string Name
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
@ 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:160
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
reverse_iterator rbegin() const
Definition: ArrayRef.h:159
void setDoesNotReturn()
Definition: InstrTypes.h:1919
void setDoesNotAccessMemory()
void setOnlyReadsMemory()
void setCannotDuplicate()
Definition: InstrTypes.h:1930
This class represents a function call, abstracting a target machine's calling convention.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1378
This is an important base class in LLVM.
Definition: Constant.h:42
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:481
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
Class to represent function types.
Definition: DerivedTypes.h:105
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:545
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:505
LLVMContext & getContext() const
Definition: IRBuilder.h:195
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2449
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:535
Class to represent integer types.
Definition: DerivedTypes.h:42
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:74
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:302
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:204
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:853
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Class to represent struct types.
Definition: DerivedTypes.h:218
static 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:731
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:612
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
@ RayGeneration
Definition: Triple.h:292
@ UnknownEnvironment
Definition: Triple.h:245
@ ClosestHit
Definition: Triple.h:295
@ Amplification
Definition: Triple.h:299
@ Intersection
Definition: Triple.h:293
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
static IntegerType * getInt1Ty(LLVMContext &C)
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
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt16Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
std::string getAsString() const
Retrieve a string representation of the version number.
StructType * getResRetType(Type *ElementTy)
Get a dx.types.ResRet type with the given element type.
StructType * getSplitDoubleType(LLVMContext &Context)
Get the dx.types.splitdouble 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.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ResourceClass
Definition: DXILABI.h:25
static Error makeOpError(dxil::OpCode OpCode, Twine Msg)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition: TypeName.h:63
llvm::SmallVector< OpOverload > Overloads
dxil::OpCodeClass OpCodeClass
unsigned OpCodeNameOffset
unsigned OpCodeClassNameOffset
llvm::SmallVector< OpStage > Stages
dxil::OpCode OpCode
uint32_t ValidStages
Version DXILVersion