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