25#include "llvm/IR/IntrinsicsDirectX.h"
34#define DEBUG_TYPE "dxil-op-lower"
52 : M(M), OpBuilder(M), DRM(DRM), DRTM(DRTM), MMDI(MMDI) {}
64 if (
Error E = ReplaceCall(CI)) {
65 std::string Message(
toString(std::move(
E)));
77 struct IntrinArgSelect {
79#define DXIL_OP_INTRINSIC_ARG_SELECT_TYPE(name) name,
80#include "DXILOperation.inc"
90 Error replaceNamedStructUses(CallInst *Intrin, CallInst *DXILOp) {
93 if (!IntrinTy->isLayoutIdentical(DXILOpTy))
95 "Type mismatch between intrinsic and DXIL op",
100 EVI->setOperand(0, DXILOp);
102 IVI->setOperand(0, DXILOp);
105 "be used by insert- and extractvalue",
113 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
114 OpBuilder.getIRB().SetInsertPoint(CI);
116 if (ArgSelects.
size()) {
117 for (
const IntrinArgSelect &
A : ArgSelects) {
119 case IntrinArgSelect::Type::Index:
122 case IntrinArgSelect::Type::I8:
123 Args.push_back(OpBuilder.getIRB().getInt8((uint8_t)
A.Value));
125 case IntrinArgSelect::Type::I32:
126 Args.push_back(OpBuilder.getIRB().getInt32(
A.Value));
134 Expected<CallInst *> OpCall =
135 OpBuilder.tryCreateOp(DXILOp, Args, CI->
getName(),
F.getReturnType());
140 if (
Error E = replaceNamedStructUses(CI, *OpCall))
156 CallInst *Cast = OpBuilder.getIRB().CreateIntrinsic(
157 Intrinsic::dx_resource_casthandle, {Ty,
V->getType()}, {
V});
158 CleanupCasts.push_back(Cast);
162 void cleanupHandleCasts() {
166 for (CallInst *Cast : CleanupCasts) {
175 if (Cast->
getType() != OpBuilder.getHandleType()) {
182 assert(
Def->getIntrinsicID() == Intrinsic::dx_resource_casthandle &&
183 "Unbalanced pair of temporary handle casts");
195 for (Function *
F : CastFns)
196 F->eraseFromParent();
198 CleanupCasts.clear();
201 void cleanupNonUniformResourceIndexCalls() {
212 CleanupNURI->eraseFromParent();
213 CleanupNURI =
nullptr;
221 void removeResourceGlobals(CallInst *CI) {
225 Store->eraseFromParent();
227 if (GV->use_empty()) {
228 GV->removeDeadConstantUsers();
229 GV->eraseFromParent();
235 void replaceHandleFromBindingCall(CallInst *CI,
Value *Replacement) {
237 Intrinsic::dx_resource_handlefrombinding);
239 removeResourceGlobals(CI);
246 if (NameGlobal && NameGlobal->use_empty())
247 NameGlobal->removeFromParent();
250 bool hasNonUniformIndex(
Value *IndexOp) {
254 SmallVector<Value *, 16> Worklist;
255 SmallPtrSet<Value *, 16> Visited;
258 while (!Worklist.
empty()) {
264 if (!Visited.
insert(V).second)
268 if (CI->
getIntrinsicID() == Intrinsic::dx_resource_nonuniformindex)
274 for (
Value *Incoming :
Phi->incoming_values())
280 if (Inst->getNumOperands() > 0 && !Inst->isTerminator())
281 for (
Value *
Op : Inst->operands())
287 Error validateRawBufferElementIndex(
Value *Resource,
Value *ElementIndex) {
292 if (IsStructured && IsPoison)
294 "Element index of structured buffer may not be poison",
297 if (!IsStructured && !IsPoison)
299 "Element index of raw buffer must be poison",
305 [[nodiscard]]
bool lowerToCreateHandle(Function &
F) {
311 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
314 auto *It = DRM.find(CI);
315 assert(It != DRM.end() &&
"Resource not in map?");
316 dxil::ResourceInfo &RI = *It;
326 bool HasNonUniformIndex =
327 (
Binding.Size == 1) ?
false : hasNonUniformIndex(IndexOp);
328 std::array<Value *, 4>
Args{
331 ConstantInt::get(Int1Ty, HasNonUniformIndex)};
332 Expected<CallInst *> OpCall =
333 OpBuilder.tryCreateOp(OpCode::CreateHandle, Args, CI->
getName());
337 Value *Cast = createTmpHandleCast(*OpCall, CI->
getType());
338 replaceHandleFromBindingCall(CI, Cast);
343 [[nodiscard]]
bool lowerToBindAndAnnotateHandle(Function &
F) {
348 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
351 auto *It = DRM.find(CI);
352 assert(It != DRM.end() &&
"Resource not in map?");
353 dxil::ResourceInfo &RI = *It;
356 dxil::ResourceTypeInfo &RTI = DRTM[RI.
getHandleTy()];
364 std::pair<uint32_t, uint32_t> Props =
369 uint32_t UpperBound =
Binding.Size == 0
370 ? std::numeric_limits<uint32_t>::max()
372 Constant *ResBind = OpBuilder.getResBind(
Binding.LowerBound, UpperBound,
374 bool NonUniformIndex =
375 (
Binding.Size == 1) ?
false : hasNonUniformIndex(IndexOp);
376 Constant *NonUniformOp = ConstantInt::get(Int1Ty, NonUniformIndex);
377 std::array<Value *, 3> BindArgs{ResBind, IndexOp, NonUniformOp};
378 Expected<CallInst *> OpBind = OpBuilder.tryCreateOp(
379 OpCode::CreateHandleFromBinding, BindArgs, CI->
getName());
383 std::array<Value *, 2> AnnotateArgs{
384 *OpBind, OpBuilder.getResProps(Props.first, Props.second)};
385 Expected<CallInst *> OpAnnotate = OpBuilder.tryCreateOp(
386 OpCode::AnnotateHandle, AnnotateArgs,
391 Value *Cast = createTmpHandleCast(*OpAnnotate, CI->
getType());
392 replaceHandleFromBindingCall(CI, Cast);
400 bool lowerHandleFromBinding(Function &
F) {
401 if (MMDI.DXILVersion < VersionTuple(1, 6))
402 return lowerToCreateHandle(
F);
403 return lowerToBindAndAnnotateHandle(
F);
408 Error replaceResRetUses(CallInst *Intrin, CallInst *
Op,
bool HasCheckBit) {
417 Value *CheckOp =
nullptr;
421 ArrayRef<unsigned> Indices = EVI->getIndices();
428 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
429 OpCode::CheckAccessFullyMapped, {NewEVI},
437 EVI->replaceAllUsesWith(CheckOp);
438 EVI->eraseFromParent();
450 "Expected only use to be extract of first element");
452 OldTy =
ST->getElementType(0);
460 if (OldResult != Intrin) {
467 std::array<Value *, 4> Extracts = {};
475 size_t IndexVal = IndexOp->getZExtValue();
476 assert(IndexVal < 4 &&
"Index into buffer load out of range");
477 if (!Extracts[IndexVal])
480 EEI->eraseFromParent();
488 const unsigned N = VecTy->getNumElements();
492 if (!DynamicAccesses.
empty()) {
496 Type *ElTy = VecTy->getElementType();
497 Type *ArrayTy = ArrayType::get(ElTy,
N);
500 for (
int I = 0,
E =
N;
I !=
E; ++
I) {
508 for (ExtractElementInst *EEI : DynamicAccesses) {
510 {
Zero, EEI->getIndexOperand()});
513 EEI->eraseFromParent();
521 for (
int I = 0,
E =
N;
I !=
E; ++
I)
526 for (
int I = 0,
E =
N;
I !=
E; ++
I)
532 if (OldResult != Intrin) {
540 [[nodiscard]]
bool lowerTypedBufferLoad(Function &
F,
bool HasCheckBit) {
544 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
548 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
557 std::array<Value *, 3>
Args{Handle, Index0, Index1};
558 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
559 OpCode::BufferLoad, Args, CI->
getName(), NewRetTy);
562 if (
Error E = replaceResRetUses(CI, *OpCall, HasCheckBit))
569 [[nodiscard]]
bool lowerRawBufferLoad(Function &
F) {
570 const DataLayout &
DL =
F.getDataLayout();
575 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
580 Type *NewRetTy = OpBuilder.getResRetType(ScalarTy);
583 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
586 uint64_t NumElements =
587 DL.getTypeSizeInBits(OldTy) /
DL.getTypeSizeInBits(ScalarTy);
588 Value *
Mask = ConstantInt::get(Int8Ty, ~(~0U << NumElements));
590 ConstantInt::get(
Int32Ty,
DL.getPrefTypeAlign(ScalarTy).value());
597 Expected<CallInst *> OpCall =
598 MMDI.DXILVersion >= VersionTuple(1, 2)
599 ? OpBuilder.tryCreateOp(OpCode::RawBufferLoad,
602 : OpBuilder.tryCreateOp(OpCode::BufferLoad,
603 {Handle, Index0, Index1}, CI->
getName(),
607 if (
Error E = replaceResRetUses(CI, *OpCall,
true))
614 [[nodiscard]]
bool lowerCBufferLoad(Function &
F) {
617 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
622 Type *NewRetTy = OpBuilder.getCBufRetType(ScalarTy);
625 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
628 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
629 OpCode::CBufferLoadLegacy, {Handle,
Index}, CI->
getName(), NewRetTy);
632 if (
Error E = replaceNamedStructUses(CI, *OpCall))
640 [[nodiscard]]
bool lowerUpdateCounter(Function &
F) {
644 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
647 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
650 std::array<Value *, 2>
Args{Handle, Op1};
652 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
664 [[nodiscard]]
bool lowerGetDimensionsX(Function &
F) {
668 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
671 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
674 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
686 [[nodiscard]]
bool lowerGetPointer(Function &
F) {
689 assert(
F.user_empty() &&
"getpointer operations should have been removed");
694 [[nodiscard]]
bool lowerBufferStore(Function &
F,
bool IsRaw) {
695 const DataLayout &
DL =
F.getDataLayout();
700 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
704 createTmpHandleCast(CI->
getArgOperand(0), OpBuilder.getHandleType());
719 uint64_t NumElements =
720 DL.getTypeSizeInBits(DataTy) /
DL.getTypeSizeInBits(ScalarTy);
722 ConstantInt::get(Int8Ty, IsRaw ? ~(~0U << NumElements) : 15U);
727 "Buffer store data must have at most 4 elements",
730 std::array<Value *, 4> DataElements{
nullptr,
nullptr,
nullptr,
nullptr};
731 if (DataTy == ScalarTy)
732 DataElements[0] =
Data;
742 size_t IndexVal = IndexOp->getZExtValue();
743 assert(IndexVal < 4 &&
"Too many elements for buffer store");
744 DataElements[IndexVal] = IEI->getOperand(1);
752 for (
int I = 0,
E = NumElements;
I <
E; ++
I)
753 if (DataElements[
I] ==
nullptr)
760 for (
int I = NumElements,
E = 4;
I <
E; ++
I)
761 if (DataElements[
I] ==
nullptr)
766 Handle, Index0, Index1, DataElements[0],
767 DataElements[1], DataElements[2], DataElements[3],
Mask};
768 if (IsRaw && MMDI.DXILVersion >= VersionTuple(1, 2)) {
769 Op = OpCode::RawBufferStore;
772 ConstantInt::get(
Int32Ty,
DL.getPrefTypeAlign(ScalarTy).value()));
774 Expected<CallInst *> OpCall =
775 OpBuilder.tryCreateOp(
Op, Args, CI->
getName());
782 while (IEI && IEI->use_empty()) {
783 InsertElementInst *Tmp = IEI;
792 [[nodiscard]]
bool lowerCtpopToCountBits(Function &
F) {
796 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
802 Type *FRT =
F.getReturnType();
804 RetTy = VectorType::get(RetTy, VT);
806 Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
807 dxil::OpCode::CountBits, Args, CI->
getName(), RetTy);
821 CastOp = Instruction::ZExt;
822 CastOp2 = Instruction::SExt;
825 "Currently only lowering 16, 32, or 64 bit ctpop to CountBits \
827 CastOp = Instruction::Trunc;
828 CastOp2 = Instruction::Trunc;
833 bool NeedsCast =
false;
836 if (
I && (
I->getOpcode() == CastOp ||
I->getOpcode() == CastOp2) &&
837 I->getType() == RetTy) {
838 I->replaceAllUsesWith(*OpCall);
839 I->eraseFromParent();
859 [[nodiscard]]
bool lowerLifetimeIntrinsic(Function &
F) {
861 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
865 "Expected operand of lifetime intrinsic to be a pointer");
867 auto ZeroOrUndef = [&](
Type *Ty) {
868 return MMDI.ValidatorVersion < VersionTuple(1, 6)
870 : UndefValue::
get(Ty);
873 Value *Val =
nullptr;
875 if (GV->hasInitializer() || GV->isExternallyInitialized())
877 Val = ZeroOrUndef(GV->getValueType());
879 Val = ZeroOrUndef(AI->getAllocatedType());
881 assert(Val &&
"Expected operand of lifetime intrinsic to be a global "
882 "variable or alloca instruction");
890 [[nodiscard]]
bool lowerIsFPClass(Function &
F) {
894 return replaceFunction(
F, [&](CallInst *CI) ->
Error {
903 switch (TCI->getZExtValue()) {
904 case FPClassTest::fcInf:
905 OpCode = dxil::OpCode::IsInf;
907 case FPClassTest::fcNan:
908 OpCode = dxil::OpCode::IsNaN;
910 case FPClassTest::fcNormal:
911 OpCode = dxil::OpCode::IsNormal;
913 case FPClassTest::fcFinite:
914 OpCode = dxil::OpCode::IsFinite;
917 SmallString<128> Msg =
918 formatv(
"Unsupported FPClassTest {0} for DXIL Op Lowering",
919 TCI->getZExtValue());
923 Expected<CallInst *> OpCall =
934 bool lowerIntrinsics() {
935 bool Updated =
false;
936 bool HasErrors =
false;
939 if (!
F.isDeclaration())
945 case Intrinsic::dx_resource_casthandle:
947 case Intrinsic::dbg_value:
956 SmallString<128> Msg =
formatv(
957 "Unsupported intrinsic {0} for DXIL lowering",
F.getName());
958 M.getContext().emitError(Msg);
963#define DXIL_OP_INTRINSIC(OpCode, Intrin, ...) \
965 HasErrors |= replaceFunctionWithOp( \
966 F, OpCode, ArrayRef<IntrinArgSelect>{__VA_ARGS__}); \
968#include "DXILOperation.inc"
969 case Intrinsic::dx_resource_handlefrombinding:
970 HasErrors |= lowerHandleFromBinding(
F);
972 case Intrinsic::dx_resource_getpointer:
973 HasErrors |= lowerGetPointer(
F);
975 case Intrinsic::dx_resource_nonuniformindex:
977 "overloaded llvm.dx.resource.nonuniformindex intrinsics?");
980 case Intrinsic::dx_resource_load_typedbuffer:
981 HasErrors |= lowerTypedBufferLoad(
F,
true);
983 case Intrinsic::dx_resource_store_typedbuffer:
984 HasErrors |= lowerBufferStore(
F,
false);
986 case Intrinsic::dx_resource_load_rawbuffer:
987 HasErrors |= lowerRawBufferLoad(
F);
989 case Intrinsic::dx_resource_store_rawbuffer:
990 HasErrors |= lowerBufferStore(
F,
true);
992 case Intrinsic::dx_resource_load_cbufferrow_2:
993 case Intrinsic::dx_resource_load_cbufferrow_4:
994 case Intrinsic::dx_resource_load_cbufferrow_8:
995 HasErrors |= lowerCBufferLoad(
F);
997 case Intrinsic::dx_resource_updatecounter:
998 HasErrors |= lowerUpdateCounter(
F);
1000 case Intrinsic::dx_resource_getdimensions_x:
1001 HasErrors |= lowerGetDimensionsX(
F);
1003 case Intrinsic::ctpop:
1004 HasErrors |= lowerCtpopToCountBits(
F);
1006 case Intrinsic::lifetime_start:
1007 case Intrinsic::lifetime_end:
1009 F.eraseFromParent();
1011 if (MMDI.DXILVersion < VersionTuple(1, 6))
1012 HasErrors |= lowerLifetimeIntrinsic(
F);
1017 case Intrinsic::is_fpclass:
1018 HasErrors |= lowerIsFPClass(
F);
1023 if (Updated && !HasErrors) {
1024 cleanupHandleCasts();
1025 cleanupNonUniformResourceIndexCalls();
1038 const bool MadeChanges = OpLowerer(M, DRM, DRTM, MMDI).lowerIntrinsics();
1050class DXILOpLoweringLegacy :
public ModulePass {
1052 bool runOnModule(
Module &M)
override {
1054 getAnalysis<DXILResourceWrapperPass>().getResourceMap();
1056 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
1058 getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
1060 return OpLowerer(M, DRM, DRTM, MMDI).lowerIntrinsics();
1062 StringRef getPassName()
const override {
return "DXIL Op Lowering"; }
1063 DXILOpLoweringLegacy() : ModulePass(
ID) {}
1066 void getAnalysisUsage(llvm::AnalysisUsage &AU)
const override {
1069 AU.
addRequired<DXILMetadataAnalysisWrapperPass>();
1076char DXILOpLoweringLegacy::ID = 0;
1087 return new DXILOpLoweringLegacy();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DXIL Resource Implicit Binding
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
ModuleAnalysisManager MAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
size_t size() const
size - Get the array size.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Diagnostic information for unsupported feature in backend.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Error takeError()
Take ownership of the stored error.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
TargetExtType * getHandleTy() const
LLVM_ABI std::pair< uint32_t, uint32_t > getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const
const ResourceBinding & getBinding() const
dxil::ResourceClass getResourceClass() const
An efficient, type-erasing, non-owning reference to a callable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
NodeAddr< DefNode * > Def
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto unique(Range &&R, Predicate P)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
ModulePass * createDXILOpLoweringLegacyPass()
Pass to lowering LLVM intrinsic call to DXIL op function call.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.