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