LLVM: lib/Target/DirectX/DXILOpBuilder.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
17#include
18
19using namespace llvm;
21
23
24namespace {
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;
47};
48}
49
54
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 }
81}
82
84 if (!Ty)
85 return OverloadKind::VOID;
86
88 switch (T) {
90 return OverloadKind::VOID;
92 return OverloadKind::HALF;
94 return OverloadKind::FLOAT;
96 return OverloadKind::DOUBLE;
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:
113 return OverloadKind::VOID;
114 }
115 }
117 return OverloadKind::UserDefineType;
119
120
123 }
124 default:
125 return OverloadKind::UNDEFINED;
126 }
127}
128
130 if (Kind < OverloadKind::UserDefineType) {
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;
141 Ty->print(OS);
142 return OS.str();
143 }
144}
145
146
159
160
161
162#define DXIL_OP_OPERATION_TABLE
163#include "DXILOperation.inc"
164#undef DXIL_OP_OPERATION_TABLE
165
168 if (Kind == OverloadKind::VOID) {
170 }
173 .str();
174}
175
178 if (Kind == OverloadKind::VOID)
179 return TypeName.str();
180
181 assert(Kind < OverloadKind::UserDefineType && "invalid overload kind");
183}
184
189 if (ST)
190 return ST;
191
193}
194
199 Type *FieldTypes[5] = {ElementTy, ElementTy, ElementTy, ElementTy,
202}
203
208
209
212
213
214
216 TypeName += ".8";
218 {ElementTy, ElementTy, ElementTy, ElementTy,
219 ElementTy, ElementTy, ElementTy, ElementTy},
220 Ctx);
221 }
222
224 TypeName, {ElementTy, ElementTy, ElementTy, ElementTy}, Ctx);
225}
226
231
234 return ST;
238 "dx.types.ResBind");
239}
240
242 if (auto *ST =
244 return ST;
247}
248
255
263
269
271 Type *OverloadTy) {
272 switch (Kind) {
273 case OpParamType::VoidTy:
275 case OpParamType::HalfTy:
277 case OpParamType::FloatTy:
279 case OpParamType::DoubleTy:
281 case OpParamType::Int1Ty:
283 case OpParamType::Int8Ty:
285 case OpParamType::Int16Ty:
287 case OpParamType::Int32Ty:
289 case OpParamType::Int64Ty:
291 case OpParamType::OverloadTy:
292 return OverloadTy;
293 case OpParamType::ResRetHalfTy:
295 case OpParamType::ResRetFloatTy:
297 case OpParamType::ResRetDoubleTy:
299 case OpParamType::ResRetInt16Ty:
301 case OpParamType::ResRetInt32Ty:
303 case OpParamType::ResRetInt64Ty:
305 case OpParamType::CBufRetHalfTy:
307 case OpParamType::CBufRetFloatTy:
309 case OpParamType::CBufRetDoubleTy:
311 case OpParamType::CBufRetInt16Ty:
313 case OpParamType::CBufRetInt32Ty:
315 case OpParamType::CBufRetInt64Ty:
317 case OpParamType::HandleTy:
319 case OpParamType::ResBindTy:
321 case OpParamType::ResPropsTy:
323 case OpParamType::SplitDoubleTy:
325 case OpParamType::BinaryWithCarryTy:
327 case OpParamType::DimensionsTy:
329 }
331 return nullptr;
332}
333
335 switch (EnvType) {
337 return ShaderKind::pixel;
339 return ShaderKind::vertex;
341 return ShaderKind::geometry;
343 return ShaderKind::hull;
345 return ShaderKind::domain;
347 return ShaderKind::compute;
349 return ShaderKind::library;
351 return ShaderKind::raygeneration;
353 return ShaderKind::intersection;
355 return ShaderKind::anyhit;
357 return ShaderKind::closesthit;
359 return ShaderKind::miss;
361 return ShaderKind::callable;
363 return ShaderKind::mesh;
365 return ShaderKind::amplification;
366 default:
367 break;
368 }
370 "Shader Kind Not Found - Invalid DXIL Environment Specified");
371}
372
382
383
384
385
386
389 Type *OverloadTy) {
390
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 false);
398#include "DXILOperation.inc"
399 }
401}
402
403
404
405
406template
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
422
427 return (OpCodePack << 32) | (VersionMajor << 16) | VersionMinor;
428}
429
430
431
434
436#define DXIL_VERSION(MAJOR, MINOR) {MAJOR, MINOR},
437#include "DXILOperation.inc"
438 };
439
441 for (auto Version : Versions) {
442 if (DXILVersion < VersionTuple(Version.Major, Version.Minor))
443 continue;
444
445
446
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
461
465 if (Attributes.ReadNone)
467 if (Attributes.ReadOnly)
469 if (Attributes.NoReturn)
471 if (Attributes.NoDuplicate)
473 return;
474}
475
476namespace llvm {
477namespace dxil {
478
479
480
481
482
484 const Triple &TT = M.getTargetTriple();
485 DXILVersion = TT.getDXILVersion();
486 ShaderStage = TT.getEnvironment();
487
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) {
506
507 Type *OverloadTy = nullptr;
509 if (!RetTy)
510 return makeOpError(OpCode, "Op overloaded on unknown return type");
511 OverloadTy = RetTy;
513
515 if (static_cast<unsigned>(ArgIndex) >= Args.size())
517 OverloadTy = Args[ArgIndex]->getType();
518 }
519
522
523 std::optional<size_t> OlIndexOrErr =
525 if (!OlIndexOrErr.has_value())
527 DXILVersion.getAsString());
528
530
532
533
534
535 if ((ValidTyMask != OverloadKind::UNDEFINED) &&
536 (ValidTyMask & (uint16_t)Kind) == 0)
538
539
540
541 std::optional<size_t> StIndexOrErr =
543 if (!StIndexOrErr.has_value())
545 DXILVersion.getAsString());
546
547 uint16_t ValidShaderKindMask = Prop->Stages[*StIndexOrErr].ValidStages;
548
549
550 if (ValidShaderKindMask == ShaderKind::removed)
552
553
554
555
556
558 if (!(ValidShaderKindMask & ModuleStagekind))
560
562 FunctionCallee DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT);
563
564
567 OpArgs.append(Args.begin(), Args.end());
568
569
570 CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
571
572
574
575 return CI;
576}
577
579 const Twine &Name, Type *RetTy) {
581 if (Error E = Result.takeError())
583 return *Result;
584}
585
587 return ::getResRetType(ElementTy);
588}
589
591 return ::getCBufRetType(ElementTy);
592}
593
595 return ::getHandleType(IRB.getContext());
596}
597
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
614 {ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
615}
616
618 return ::getOpCodeName(DXILOp);
619}
620}
621}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static StructType * getResRetType(Type *ElementTy)
Definition DXILOpBuilder.cpp:195
static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType)
Definition DXILOpBuilder.cpp:334
static Type * getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx, Type *OverloadTy)
Definition DXILOpBuilder.cpp:270
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...
Definition DXILOpBuilder.cpp:407
static SmallVector< Type * > getArgTypesFromOpParamTypes(ArrayRef< dxil::OpParamType > Types, LLVMContext &Context, Type *OverloadTy)
Definition DXILOpBuilder.cpp:374
static void setDXILAttributes(CallInst *CI, dxil::OpCode OpCode, VersionTuple DXILVersion)
Definition DXILOpBuilder.cpp:462
static const char * getOverloadTypeName(OverloadKind Kind)
Definition DXILOpBuilder.cpp:55
static StructType * getCBufRetType(Type *ElementTy)
Definition DXILOpBuilder.cpp:204
static StructType * getSplitDoubleType(LLVMContext &Context)
Definition DXILOpBuilder.cpp:249
static OverloadKind getOverloadKind(Type *Ty)
Definition DXILOpBuilder.cpp:83
static constexpr uint64_t computeSwitchEnum(dxil::OpCode OpCode, uint16_t VersionMajor, uint16_t VersionMinor)
Definition DXILOpBuilder.cpp:423
static StructType * getBinaryWithCarryType(LLVMContext &Context)
Definition DXILOpBuilder.cpp:256
static StructType * getOrCreateStructType(StringRef Name, ArrayRef< Type * > EltTys, LLVMContext &Ctx)
Definition DXILOpBuilder.cpp:185
static StructType * getHandleType(LLVMContext &Ctx)
Definition DXILOpBuilder.cpp:227
static dxil::Attributes getDXILAttributes(dxil::OpCode OpCode, VersionTuple DXILVersion)
Definition DXILOpBuilder.cpp:432
static std::string constructOverloadName(OverloadKind Kind, Type *Ty, const OpCodeProperty &Prop)
Definition DXILOpBuilder.cpp:166
static FunctionType * getDXILOpFunctionType(dxil::OpCode OpCode, LLVMContext &Context, Type *OverloadTy)
Construct DXIL function type.
Definition DXILOpBuilder.cpp:387
constexpr StringLiteral DXILOpNamePrefix
Definition DXILOpBuilder.cpp:22
static std::string constructOverloadTypeName(OverloadKind Kind, StringRef TypeName)
Definition DXILOpBuilder.cpp:176
static StructType * getDimensionsType(LLVMContext &Ctx)
Definition DXILOpBuilder.cpp:264
static StructType * getResPropsType(LLVMContext &Context)
Definition DXILOpBuilder.cpp:241
static StructType * getResBindType(LLVMContext &Context)
Definition DXILOpBuilder.cpp:232
Module.h This file contains the declarations for the Module class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
reverse_iterator rend() const
size_t size() const
size - Get the array size.
reverse_iterator rbegin() const
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.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
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.
A Module instance is used to store all the information related to an LLVM module.
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...
StringRef - Represent a constant reference to a string, i.e.
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.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
TypeID
Definitions of all of the base types for the Type system.
@ HalfTyID
16-bit floating point type
@ VoidTyID
type with no size
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ DoubleTyID
64-bit floating point type
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Represents a version number in the form major[.minor[.subminor[.build]]].
DXILOpBuilder(Module &M)
Definition DXILOpBuilder.cpp:483
StructType * getResRetType(Type *ElementTy)
Get a dx.types.ResRet type with the given element type.
Definition DXILOpBuilder.cpp:586
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.
Definition DXILOpBuilder.cpp:501
CallInst * createOp(dxil::OpCode Op, ArrayRef< Value * > Args, const Twine &Name="", Type *RetTy=nullptr)
Create a call instruction for the given DXIL op.
Definition DXILOpBuilder.cpp:578
Constant * getResBind(uint32_t LowerBound, uint32_t UpperBound, uint32_t SpaceID, dxil::ResourceClass RC)
Get a constant dx.types.ResBind value.
Definition DXILOpBuilder.cpp:598
static const char * getOpCodeName(dxil::OpCode DXILOp)
Return the name of the given opcode.
Definition DXILOpBuilder.cpp:617
Constant * getResProps(uint32_t Word0, uint32_t Word1)
Get a constant dx.types.ResourceProperties value.
Definition DXILOpBuilder.cpp:610
StructType * getHandleType()
Get the dx.types.Handle type.
Definition DXILOpBuilder.cpp:594
StructType * getCBufRetType(Type *ElementTy)
Get a dx.types.CBufRet type with the given element type.
Definition DXILOpBuilder.cpp:590
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)
Definition DXILOpBuilder.cpp:495
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition DXILOpBuilder.cpp:147
llvm::SmallVector< OpOverload > Overloads
Definition DXILOpBuilder.cpp:154
dxil::OpCodeClass OpCodeClass
Definition DXILOpBuilder.cpp:151
unsigned OpCodeNameOffset
Definition DXILOpBuilder.cpp:150
unsigned OpCodeClassNameOffset
Definition DXILOpBuilder.cpp:153
int OverloadParamIndex
Definition DXILOpBuilder.cpp:156
llvm::SmallVector< OpStage > Stages
Definition DXILOpBuilder.cpp:155
dxil::OpCode OpCode
Definition DXILOpBuilder.cpp:148
Definition DXILOpBuilder.cpp:50
uint32_t ValidStages
Definition DXILOpBuilder.cpp:52
Version DXILVersion
Definition DXILOpBuilder.cpp:51