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 if (auto *ST = StructType::getTypeByName(Context, "dx.types.twoi32"))
280 return ST;
281 Type *Int32Ty = Type::getInt32Ty(Context);
282 return StructType::create({Int32Ty, Int32Ty}, "dx.types.twoi32");
283}
284
286 Type *OverloadTy) {
287 switch (Kind) {
288 case OpParamType::VoidTy:
289 return Type::getVoidTy(Ctx);
290 case OpParamType::HalfTy:
291 return Type::getHalfTy(Ctx);
292 case OpParamType::FloatTy:
293 return Type::getFloatTy(Ctx);
294 case OpParamType::DoubleTy:
295 return Type::getDoubleTy(Ctx);
296 case OpParamType::Int1Ty:
297 return Type::getInt1Ty(Ctx);
298 case OpParamType::Int8Ty:
299 return Type::getInt8Ty(Ctx);
300 case OpParamType::Int16Ty:
301 return Type::getInt16Ty(Ctx);
302 case OpParamType::Int32Ty:
303 return Type::getInt32Ty(Ctx);
304 case OpParamType::Int64Ty:
305 return Type::getInt64Ty(Ctx);
306 case OpParamType::OverloadTy:
307 return OverloadTy;
308 case OpParamType::ResRetHalfTy:
309 return getResRetType(Type::getHalfTy(Ctx));
310 case OpParamType::ResRetFloatTy:
311 return getResRetType(Type::getFloatTy(Ctx));
312 case OpParamType::ResRetDoubleTy:
313 return getResRetType(Type::getDoubleTy(Ctx));
314 case OpParamType::ResRetInt16Ty:
315 return getResRetType(Type::getInt16Ty(Ctx));
316 case OpParamType::ResRetInt32Ty:
317 return getResRetType(Type::getInt32Ty(Ctx));
318 case OpParamType::ResRetInt64Ty:
319 return getResRetType(Type::getInt64Ty(Ctx));
320 case OpParamType::CBufRetHalfTy:
321 return getCBufRetType(Type::getHalfTy(Ctx));
322 case OpParamType::CBufRetFloatTy:
323 return getCBufRetType(Type::getFloatTy(Ctx));
324 case OpParamType::CBufRetDoubleTy:
326 case OpParamType::CBufRetInt16Ty:
327 return getCBufRetType(Type::getInt16Ty(Ctx));
328 case OpParamType::CBufRetInt32Ty:
329 return getCBufRetType(Type::getInt32Ty(Ctx));
330 case OpParamType::CBufRetInt64Ty:
331 return getCBufRetType(Type::getInt64Ty(Ctx));
332 case OpParamType::HandleTy:
333 return getHandleType(Ctx);
334 case OpParamType::ResBindTy:
335 return getResBindType(Ctx);
336 case OpParamType::ResPropsTy:
337 return getResPropsType(Ctx);
338 case OpParamType::SplitDoubleTy:
339 return getSplitDoubleType(Ctx);
340 case OpParamType::BinaryWithCarryTy:
341 return getBinaryWithCarryType(Ctx);
342 case OpParamType::DimensionsTy:
343 return getDimensionsType(Ctx);
344 case OpParamType::Fouri32s:
345 return getFouri32sType(Ctx);
346 case OpParamType::TwoI32Ty:
347 return getTwoI32Type(Ctx);
348 }
349
350 llvm_unreachable("Invalid parameter kind");
351 return nullptr;
352}
353
354static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) {
355 switch (EnvType) {
356 case Triple::Pixel:
357 return ShaderKind::pixel;
358 case Triple::Vertex:
359 return ShaderKind::vertex;
360 case Triple::Geometry:
361 return ShaderKind::geometry;
362 case Triple::Hull:
363 return ShaderKind::hull;
364 case Triple::Domain:
365 return ShaderKind::domain;
366 case Triple::Compute:
367 return ShaderKind::compute;
368 case Triple::Library:
369 return ShaderKind::library;
371 return ShaderKind::raygeneration;
373 return ShaderKind::intersection;
374 case Triple::AnyHit:
375 return ShaderKind::anyhit;
377 return ShaderKind::closesthit;
378 case Triple::Miss:
379 return ShaderKind::miss;
380 case Triple::Callable:
381 return ShaderKind::callable;
382 case Triple::Mesh:
383 return ShaderKind::mesh;
385 return ShaderKind::amplification;
386 default:
387 break;
388 }
390 "Shader Kind Not Found - Invalid DXIL Environment Specified");
391}
392
395 LLVMContext &Context, Type *OverloadTy) {
396 SmallVector<Type *> ArgTys;
397 ArgTys.emplace_back(Type::getInt32Ty(Context));
398 for (dxil::OpParamType Ty : Types)
399 ArgTys.emplace_back(getTypeFromOpParamType(Ty, Context, OverloadTy));
400 return ArgTys;
401}
402
403/// Construct DXIL function type. This is the type of a function with
404/// the following prototype
405/// OverloadType dx.op.<opclass>.<return-type>(int opcode, <param types>)
406/// <param-types> are constructed from types in Prop.
408 LLVMContext &Context,
409 Type *OverloadTy) {
410
411 switch (OpCode) {
412#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...) \
413 case OpCode: \
414 return FunctionType::get( \
415 getTypeFromOpParamType(RetType, Context, OverloadTy), \
416 getArgTypesFromOpParamTypes({__VA_ARGS__}, Context, OverloadTy), \
417 /*isVarArg=*/false);
418#include "DXILOperation.inc"
419 }
420 llvm_unreachable("Invalid OpCode?");
421}
422
423/// Get index of the property from PropList valid for the most recent
424/// DXIL version not greater than DXILVer.
425/// PropList is expected to be sorted in ascending order of DXIL version.
426template <typename T>
427static std::optional<size_t> getPropIndex(ArrayRef<T> PropList,
428 const VersionTuple DXILVer) {
429 size_t Index = PropList.size() - 1;
430 for (auto Iter = PropList.rbegin(); Iter != PropList.rend();
431 Iter++, Index--) {
432 const T &Prop = *Iter;
433 if (VersionTuple(Prop.DXILVersion.Major, Prop.DXILVersion.Minor) <=
434 DXILVer) {
435 return Index;
436 }
437 }
438 return std::nullopt;
439}
440
441// Helper function to pack an OpCode and VersionTuple into a uint64_t for use
442// in a switch statement
444 uint16_t VersionMajor,
445 uint16_t VersionMinor) {
446 uint64_t OpCodePack = (uint64_t)OpCode;
447 return (OpCodePack << 32) | (VersionMajor << 16) | VersionMinor;
448}
449
450/// Get the set of attributes for a given DXIL OpCode and the DXIL version.
452 VersionTuple DXILVersion) {
453 // Instantiate all versions to iterate through
454 SmallVector<Version> Versions = {
455#define DXIL_VERSION(MAJOR, MINOR) {MAJOR, MINOR},
456#include "DXILOperation.inc"
457 };
458
459 dxil::Attributes Attributes;
460 for (auto Version : Versions) {
461 if (DXILVersion < VersionTuple(Version.Major, Version.Minor))
462 continue;
463
464 // Switch through and match an OpCode with the specific version and set the
465 // corresponding flag(s) if available
466 switch (computeSwitchEnum(OpCode, Version.Major, Version.Minor)) {
467#define DXIL_OP_ATTRIBUTES(OpCode, VersionMajor, VersionMinor, ...) \
468 case computeSwitchEnum(OpCode, VersionMajor, VersionMinor): { \
469 auto Other = dxil::Attributes{__VA_ARGS__}; \
470 Attributes |= Other; \
471 break; \
472 };
473#include "DXILOperation.inc"
474 }
475 }
476 return Attributes;
477}
478
479/// Get the attributes to apply to the function for the DXIL operation with the
480/// given OpCode and DXIL version.
481static AttributeList getDXILFnAttributeList(LLVMContext &Ctx,
483 VersionTuple DXILVersion) {
484 dxil::Attributes Attributes = getDXILAttributes(OpCode, DXILVersion);
485 AttrBuilder FnAttrs(Ctx);
486
487 if (Attributes.ReadNone)
488 FnAttrs.addMemoryAttr(MemoryEffects::none());
489 if (Attributes.ReadOnly)
490 FnAttrs.addMemoryAttr(MemoryEffects::readOnly());
491 if (Attributes.NoReturn)
492 FnAttrs.addAttribute(Attribute::NoReturn);
493 if (Attributes.NoDuplicate)
494 FnAttrs.addAttribute(Attribute::NoDuplicate);
495 FnAttrs.addAttribute(Attribute::NoUnwind);
496
497 return AttributeList::get(Ctx, AttributeList::FunctionIndex, FnAttrs);
498}
499
500namespace llvm {
501namespace dxil {
502
503// No extra checks on TargetTriple need be performed to verify that the
504// Triple is well-formed or that the target is supported since these checks
505// would have been done at the time the module M is constructed in the earlier
506// stages of compilation.
508 const Triple &TT = M.getTargetTriple();
509 DXILVersion = TT.getDXILVersion();
510 ShaderStage = TT.getEnvironment();
511 // Ensure Environment type is known
512 if (ShaderStage == Triple::UnknownEnvironment) {
514 Twine(DXILVersion.getAsString()) +
515 ": Unknown Compilation Target Shader Stage specified ");
516 }
517}
518
521 Twine("Cannot create ") + getOpCodeName(OpCode) + " operation: " + Msg,
523}
524
527 const Twine &Name,
528 Type *RetTy) {
529 const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
530
531 Type *OverloadTy = nullptr;
532 if (Prop->OverloadParamIndex == 0) {
533 if (!RetTy)
534 return makeOpError(OpCode, "Op overloaded on unknown return type");
535 OverloadTy = RetTy;
536 } else if (Prop->OverloadParamIndex > 0) {
537 // The index counts including the return type
538 unsigned ArgIndex = Prop->OverloadParamIndex - 1;
539 if (static_cast<unsigned>(ArgIndex) >= Args.size())
540 return makeOpError(OpCode, "Wrong number of arguments");
541 OverloadTy = Args[ArgIndex]->getType();
542 }
543
544 FunctionType *DXILOpFT =
545 getDXILOpFunctionType(OpCode, M.getContext(), OverloadTy);
546
547 std::optional<size_t> OlIndexOrErr =
548 getPropIndex(ArrayRef(Prop->Overloads), DXILVersion);
549 if (!OlIndexOrErr.has_value())
550 return makeOpError(OpCode, Twine("No valid overloads for DXIL version ") +
551 DXILVersion.getAsString());
552
553 uint16_t ValidTyMask = Prop->Overloads[*OlIndexOrErr].ValidTys;
554
555 OverloadKind Kind = getOverloadKind(OverloadTy);
556
557 // Check if the operation supports overload types and OverloadTy is valid
558 // per the specified types for the operation
559 if ((ValidTyMask != OverloadKind::UNDEFINED) &&
560 (ValidTyMask & (uint16_t)Kind) == 0)
561 return makeOpError(OpCode, "Invalid overload type");
562
563 // Perform necessary checks to ensure Opcode is valid in the targeted shader
564 // kind
565 std::optional<size_t> StIndexOrErr =
566 getPropIndex(ArrayRef(Prop->Stages), DXILVersion);
567 if (!StIndexOrErr.has_value())
568 return makeOpError(OpCode, Twine("No valid stage for DXIL version ") +
569 DXILVersion.getAsString());
570
571 uint16_t ValidShaderKindMask = Prop->Stages[*StIndexOrErr].ValidStages;
572
573 // Ensure valid shader stage properties are specified
574 if (ValidShaderKindMask == ShaderKind::removed)
575 return makeOpError(OpCode, "Operation has been removed");
576
577 // Shader stage need not be validated since getShaderKindEnum() fails
578 // for unknown shader stage.
579
580 // Verify the target shader stage is valid for the DXIL operation
581 ShaderKind ModuleStagekind = getShaderKindEnum(ShaderStage);
582 if (!(ValidShaderKindMask & ModuleStagekind))
583 return makeOpError(OpCode, "Invalid stage");
584
585 AttributeList DXILFnAttrs =
586 getDXILFnAttributeList(M.getContext(), OpCode, DXILVersion);
587 std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop);
588 FunctionCallee DXILFn =
589 M.getOrInsertFunction(DXILFnName, DXILOpFT, DXILFnAttrs);
590
591 // We need to inject the opcode as the first argument.
593 OpArgs.push_back(IRB.getInt32(llvm::to_underlying(OpCode)));
594 OpArgs.append(Args.begin(), Args.end());
595
596 // Create the function call instruction
597 CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
598
599 return CI;
600}
601
603 const Twine &Name, Type *RetTy) {
604 Expected<CallInst *> Result = tryCreateOp(OpCode, Args, Name, RetTy);
605 if (Error E = Result.takeError())
606 llvm_unreachable("Invalid arguments for operation");
607 return *Result;
608}
609
611 return ::getResRetType(ElementTy);
612}
613
615 return ::getCBufRetType(ElementTy);
616}
617
619 return ::getHandleType(IRB.getContext());
620}
621
623 uint32_t SpaceID, dxil::ResourceClass RC) {
624 Type *Int32Ty = IRB.getInt32Ty();
625 Type *Int8Ty = IRB.getInt8Ty();
626 return ConstantStruct::get(
627 getResBindType(IRB.getContext()),
628 {ConstantInt::get(Int32Ty, LowerBound),
629 ConstantInt::get(Int32Ty, UpperBound),
630 ConstantInt::get(Int32Ty, SpaceID),
631 ConstantInt::get(Int8Ty, llvm::to_underlying(RC))});
632}
633
635 Type *Int32Ty = IRB.getInt32Ty();
636 return ConstantStruct::get(
637 getResPropsType(IRB.getContext()),
638 {ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
639}
640
642 return ::getOpCodeName(DXILOp);
643}
644} // namespace dxil
645} // 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 StructType * getTwoI32Type(LLVMContext &Context)
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 AttributeList getDXILFnAttributeList(LLVMContext &Ctx, dxil::OpCode OpCode, VersionTuple DXILVersion)
Get the attributes to apply to the function for the DXIL operation with the given OpCode and DXIL ver...
static dxil::Attributes getDXILAttributes(dxil::OpCode OpCode, VersionTuple DXILVersion)
Get the set of attributes for a given DXIL OpCode and the DXIL version.
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
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
const char * Msg
@ UNDEFINED
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:133
size_t size() const
Get the array size.
Definition ArrayRef.h:141
reverse_iterator rbegin() const
Definition ArrayRef.h:132
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
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
static MemoryEffectsBase none()
Definition ModRef.h:128
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:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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:802
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:683
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
@ RayGeneration
Definition Triple.h:401
@ UnknownEnvironment
Definition Triple.h:353
@ Amplification
Definition Triple.h:408
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:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
TypeID
Definitions of all of the base types for the Type system.
Definition Type.h:55
@ HalfTyID
16-bit floating point type
Definition Type.h:57
@ VoidTyID
type with no size
Definition Type.h:64
@ FloatTyID
32-bit floating point type
Definition Type.h:59
@ StructTyID
Structures.
Definition Type.h:75
@ IntegerTyID
Arbitrary bit width integers.
Definition Type.h:71
@ DoubleTyID
64-bit floating point type
Definition Type.h:60
@ PointerTyID
Pointers.
Definition Type.h:74
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:282
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:308
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Definition Type.cpp:284
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.
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