LLVM 23.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 *Int32Ty = Type::getInt32Ty(Context);
266 return getOrCreateStructType("dx.types.Dimensions",
267 {Int32Ty, Int32Ty, Int32Ty, Int32Ty}, Context);
268}
269
271 if (auto *ST = StructType::getTypeByName(Context, "dx.types.fouri32"))
272 return ST;
273 Type *Int32Ty = Type::getInt32Ty(Context);
274 return getOrCreateStructType("dx.types.fouri32",
275 {Int32Ty, Int32Ty, Int32Ty, Int32Ty}, Context);
276}
277
279 Type *OverloadTy) {
280 switch (Kind) {
281 case OpParamType::VoidTy:
282 return Type::getVoidTy(Ctx);
283 case OpParamType::HalfTy:
284 return Type::getHalfTy(Ctx);
285 case OpParamType::FloatTy:
286 return Type::getFloatTy(Ctx);
287 case OpParamType::DoubleTy:
288 return Type::getDoubleTy(Ctx);
289 case OpParamType::Int1Ty:
290 return Type::getInt1Ty(Ctx);
291 case OpParamType::Int8Ty:
292 return Type::getInt8Ty(Ctx);
293 case OpParamType::Int16Ty:
294 return Type::getInt16Ty(Ctx);
295 case OpParamType::Int32Ty:
296 return Type::getInt32Ty(Ctx);
297 case OpParamType::Int64Ty:
298 return Type::getInt64Ty(Ctx);
299 case OpParamType::OverloadTy:
300 return OverloadTy;
301 case OpParamType::ResRetHalfTy:
302 return getResRetType(Type::getHalfTy(Ctx));
303 case OpParamType::ResRetFloatTy:
304 return getResRetType(Type::getFloatTy(Ctx));
305 case OpParamType::ResRetDoubleTy:
306 return getResRetType(Type::getDoubleTy(Ctx));
307 case OpParamType::ResRetInt16Ty:
308 return getResRetType(Type::getInt16Ty(Ctx));
309 case OpParamType::ResRetInt32Ty:
310 return getResRetType(Type::getInt32Ty(Ctx));
311 case OpParamType::ResRetInt64Ty:
312 return getResRetType(Type::getInt64Ty(Ctx));
313 case OpParamType::CBufRetHalfTy:
314 return getCBufRetType(Type::getHalfTy(Ctx));
315 case OpParamType::CBufRetFloatTy:
316 return getCBufRetType(Type::getFloatTy(Ctx));
317 case OpParamType::CBufRetDoubleTy:
319 case OpParamType::CBufRetInt16Ty:
320 return getCBufRetType(Type::getInt16Ty(Ctx));
321 case OpParamType::CBufRetInt32Ty:
322 return getCBufRetType(Type::getInt32Ty(Ctx));
323 case OpParamType::CBufRetInt64Ty:
324 return getCBufRetType(Type::getInt64Ty(Ctx));
325 case OpParamType::HandleTy:
326 return getHandleType(Ctx);
327 case OpParamType::ResBindTy:
328 return getResBindType(Ctx);
329 case OpParamType::ResPropsTy:
330 return getResPropsType(Ctx);
331 case OpParamType::SplitDoubleTy:
332 return getSplitDoubleType(Ctx);
333 case OpParamType::BinaryWithCarryTy:
334 return getBinaryWithCarryType(Ctx);
335 case OpParamType::DimensionsTy:
336 return getDimensionsType(Ctx);
337 case OpParamType::Fouri32s:
338 return getFouri32sType(Ctx);
339 }
340
341 llvm_unreachable("Invalid parameter kind");
342 return nullptr;
343}
344
345static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) {
346 switch (EnvType) {
347 case Triple::Pixel:
348 return ShaderKind::pixel;
349 case Triple::Vertex:
350 return ShaderKind::vertex;
351 case Triple::Geometry:
352 return ShaderKind::geometry;
353 case Triple::Hull:
354 return ShaderKind::hull;
355 case Triple::Domain:
356 return ShaderKind::domain;
357 case Triple::Compute:
358 return ShaderKind::compute;
359 case Triple::Library:
360 return ShaderKind::library;
362 return ShaderKind::raygeneration;
364 return ShaderKind::intersection;
365 case Triple::AnyHit:
366 return ShaderKind::anyhit;
368 return ShaderKind::closesthit;
369 case Triple::Miss:
370 return ShaderKind::miss;
371 case Triple::Callable:
372 return ShaderKind::callable;
373 case Triple::Mesh:
374 return ShaderKind::mesh;
376 return ShaderKind::amplification;
377 default:
378 break;
379 }
381 "Shader Kind Not Found - Invalid DXIL Environment Specified");
382}
383
386 LLVMContext &Context, Type *OverloadTy) {
387 SmallVector<Type *> ArgTys;
388 ArgTys.emplace_back(Type::getInt32Ty(Context));
389 for (dxil::OpParamType Ty : Types)
390 ArgTys.emplace_back(getTypeFromOpParamType(Ty, Context, OverloadTy));
391 return ArgTys;
392}
393
394/// Construct DXIL function type. This is the type of a function with
395/// the following prototype
396/// OverloadType dx.op.<opclass>.<return-type>(int opcode, <param types>)
397/// <param-types> are constructed from types in Prop.
399 LLVMContext &Context,
400 Type *OverloadTy) {
401
402 switch (OpCode) {
403#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...) \
404 case OpCode: \
405 return FunctionType::get( \
406 getTypeFromOpParamType(RetType, Context, OverloadTy), \
407 getArgTypesFromOpParamTypes({__VA_ARGS__}, Context, OverloadTy), \
408 /*isVarArg=*/false);
409#include "DXILOperation.inc"
410 }
411 llvm_unreachable("Invalid OpCode?");
412}
413
414/// Get index of the property from PropList valid for the most recent
415/// DXIL version not greater than DXILVer.
416/// PropList is expected to be sorted in ascending order of DXIL version.
417template <typename T>
418static std::optional<size_t> getPropIndex(ArrayRef<T> PropList,
419 const VersionTuple DXILVer) {
420 size_t Index = PropList.size() - 1;
421 for (auto Iter = PropList.rbegin(); Iter != PropList.rend();
422 Iter++, Index--) {
423 const T &Prop = *Iter;
424 if (VersionTuple(Prop.DXILVersion.Major, Prop.DXILVersion.Minor) <=
425 DXILVer) {
426 return Index;
427 }
428 }
429 return std::nullopt;
430}
431
432// Helper function to pack an OpCode and VersionTuple into a uint64_t for use
433// in a switch statement
435 uint16_t VersionMajor,
436 uint16_t VersionMinor) {
437 uint64_t OpCodePack = (uint64_t)OpCode;
438 return (OpCodePack << 32) | (VersionMajor << 16) | VersionMinor;
439}
440
441// Retreive all the set attributes for a DXIL OpCode given the targeted
442// DXILVersion
444 VersionTuple DXILVersion) {
445 // Instantiate all versions to iterate through
446 SmallVector<Version> Versions = {
447#define DXIL_VERSION(MAJOR, MINOR) {MAJOR, MINOR},
448#include "DXILOperation.inc"
449 };
450
451 dxil::Attributes Attributes;
452 for (auto Version : Versions) {
453 if (DXILVersion < VersionTuple(Version.Major, Version.Minor))
454 continue;
455
456 // Switch through and match an OpCode with the specific version and set the
457 // corresponding flag(s) if available
458 switch (computeSwitchEnum(OpCode, Version.Major, Version.Minor)) {
459#define DXIL_OP_ATTRIBUTES(OpCode, VersionMajor, VersionMinor, ...) \
460 case computeSwitchEnum(OpCode, VersionMajor, VersionMinor): { \
461 auto Other = dxil::Attributes{__VA_ARGS__}; \
462 Attributes |= Other; \
463 break; \
464 };
465#include "DXILOperation.inc"
466 }
467 }
468 return Attributes;
469}
470
471// Retreive the set of DXIL Attributes given the version and map them to an
472// llvm function attribute that is set onto the instruction
474 VersionTuple DXILVersion) {
475 dxil::Attributes Attributes = getDXILAttributes(OpCode, DXILVersion);
476 if (Attributes.ReadNone)
478 if (Attributes.ReadOnly)
479 CI->setOnlyReadsMemory();
480 if (Attributes.NoReturn)
481 CI->setDoesNotReturn();
482 if (Attributes.NoDuplicate)
483 CI->setCannotDuplicate();
484 return;
485}
486
487namespace llvm {
488namespace dxil {
489
490// No extra checks on TargetTriple need be performed to verify that the
491// Triple is well-formed or that the target is supported since these checks
492// would have been done at the time the module M is constructed in the earlier
493// stages of compilation.
494DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) {
495 const Triple &TT = M.getTargetTriple();
496 DXILVersion = TT.getDXILVersion();
497 ShaderStage = TT.getEnvironment();
498 // Ensure Environment type is known
499 if (ShaderStage == Triple::UnknownEnvironment) {
501 Twine(DXILVersion.getAsString()) +
502 ": Unknown Compilation Target Shader Stage specified ");
503 }
504}
505
508 Twine("Cannot create ") + getOpCodeName(OpCode) + " operation: " + Msg,
510}
511
514 const Twine &Name,
515 Type *RetTy) {
516 const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
517
518 Type *OverloadTy = nullptr;
519 if (Prop->OverloadParamIndex == 0) {
520 if (!RetTy)
521 return makeOpError(OpCode, "Op overloaded on unknown return type");
522 OverloadTy = RetTy;
523 } else if (Prop->OverloadParamIndex > 0) {
524 // The index counts including the return type
525 unsigned ArgIndex = Prop->OverloadParamIndex - 1;
526 if (static_cast<unsigned>(ArgIndex) >= Args.size())
527 return makeOpError(OpCode, "Wrong number of arguments");
528 OverloadTy = Args[ArgIndex]->getType();
529 }
530
531 FunctionType *DXILOpFT =
532 getDXILOpFunctionType(OpCode, M.getContext(), OverloadTy);
533
534 std::optional<size_t> OlIndexOrErr =
535 getPropIndex(ArrayRef(Prop->Overloads), DXILVersion);
536 if (!OlIndexOrErr.has_value())
537 return makeOpError(OpCode, Twine("No valid overloads for DXIL version ") +
538 DXILVersion.getAsString());
539
540 uint16_t ValidTyMask = Prop->Overloads[*OlIndexOrErr].ValidTys;
541
542 OverloadKind Kind = getOverloadKind(OverloadTy);
543
544 // Check if the operation supports overload types and OverloadTy is valid
545 // per the specified types for the operation
546 if ((ValidTyMask != OverloadKind::UNDEFINED) &&
547 (ValidTyMask & (uint16_t)Kind) == 0)
548 return makeOpError(OpCode, "Invalid overload type");
549
550 // Perform necessary checks to ensure Opcode is valid in the targeted shader
551 // kind
552 std::optional<size_t> StIndexOrErr =
553 getPropIndex(ArrayRef(Prop->Stages), DXILVersion);
554 if (!StIndexOrErr.has_value())
555 return makeOpError(OpCode, Twine("No valid stage for DXIL version ") +
556 DXILVersion.getAsString());
557
558 uint16_t ValidShaderKindMask = Prop->Stages[*StIndexOrErr].ValidStages;
559
560 // Ensure valid shader stage properties are specified
561 if (ValidShaderKindMask == ShaderKind::removed)
562 return makeOpError(OpCode, "Operation has been removed");
563
564 // Shader stage need not be validated since getShaderKindEnum() fails
565 // for unknown shader stage.
566
567 // Verify the target shader stage is valid for the DXIL operation
568 ShaderKind ModuleStagekind = getShaderKindEnum(ShaderStage);
569 if (!(ValidShaderKindMask & ModuleStagekind))
570 return makeOpError(OpCode, "Invalid stage");
571
572 std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop);
573 FunctionCallee DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT);
574
575 // We need to inject the opcode as the first argument.
577 OpArgs.push_back(IRB.getInt32(llvm::to_underlying(OpCode)));
578 OpArgs.append(Args.begin(), Args.end());
579
580 // Create the function call instruction
581 CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
582
583 // We then need to attach available function attributes
584 setDXILAttributes(CI, OpCode, DXILVersion);
585
586 return CI;
587}
588
590 const Twine &Name, Type *RetTy) {
591 Expected<CallInst *> Result = tryCreateOp(OpCode, Args, Name, RetTy);
592 if (Error E = Result.takeError())
593 llvm_unreachable("Invalid arguments for operation");
594 return *Result;
595}
596
598 return ::getResRetType(ElementTy);
599}
600
602 return ::getCBufRetType(ElementTy);
603}
604
606 return ::getHandleType(IRB.getContext());
607}
608
610 uint32_t SpaceID, dxil::ResourceClass RC) {
611 Type *Int32Ty = IRB.getInt32Ty();
612 Type *Int8Ty = IRB.getInt8Ty();
613 return ConstantStruct::get(
614 getResBindType(IRB.getContext()),
615 {ConstantInt::get(Int32Ty, LowerBound),
616 ConstantInt::get(Int32Ty, UpperBound),
617 ConstantInt::get(Int32Ty, SpaceID),
618 ConstantInt::get(Int8Ty, llvm::to_underlying(RC))});
619}
620
622 Type *Int32Ty = IRB.getInt32Ty();
623 return ConstantStruct::get(
624 getResPropsType(IRB.getContext()),
625 {ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
626}
627
629 return ::getOpCodeName(DXILOp);
630}
631} // namespace dxil
632} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static StructType * getResRetType(Type *ElementTy)
static StructType * getFouri32sType(LLVMContext &Context)
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 * getDimensionsType(LLVMContext &Context)
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:40
reverse_iterator rend() const
Definition ArrayRef.h:134
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
reverse_iterator rbegin() const
Definition ArrayRef.h:133
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:864
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:738
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:619
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
@ RayGeneration
Definition Triple.h:307
@ UnknownEnvironment
Definition Triple.h:259
@ Amplification
Definition Triple.h:314
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:297
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
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:280
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:294
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:295
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:293
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:285
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:284
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Definition Type.cpp:282
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.
Definition Types.h:26
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:94
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:559
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
llvm::SmallVector< OpOverload > Overloads
dxil::OpCodeClass OpCodeClass
unsigned OpCodeNameOffset
unsigned OpCodeClassNameOffset
llvm::SmallVector< OpStage > Stages
dxil::OpCode OpCode
uint32_t ValidStages
Version DXILVersion