21#include "clang/AST/Attrs.inc"
26#include "llvm/ADT/SmallString.h"
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DerivedTypes.h"
31#include "llvm/IR/GlobalVariable.h"
32#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Metadata.h"
34#include "llvm/IR/Module.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Support/Alignment.h"
38#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/FormatVariadic.h"
43using namespace CodeGen;
47using llvm::hlsl::CBufferRowSizeInBytes;
51void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) {
55 if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
56 Version.getSubminor() || !Version.getMinor()) {
61 uint64_t Minor = *Version.getMinor();
63 auto &Ctx = M.getContext();
64 IRBuilder<> B(M.getContext());
65 MDNode *Val = MDNode::get(Ctx, {ConstantAsMetadata::get(B.getInt32(Major)),
66 ConstantAsMetadata::get(B.getInt32(Minor))});
67 StringRef DXILValKey =
"dx.valver";
68 auto *DXILValMD = M.getOrInsertNamedMetadata(DXILValKey);
69 DXILValMD->addOperand(Val);
72void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer,
74 llvm::Function *Fn, llvm::Module &M) {
75 auto &Ctx = M.getContext();
77 llvm::hlsl::rootsig::MetadataBuilder RSBuilder(Ctx, Elements);
78 MDNode *RootSignature = RSBuilder.BuildRootSignature();
80 ConstantAsMetadata *Version = ConstantAsMetadata::get(ConstantInt::get(
81 llvm::Type::getInt32Ty(Ctx), llvm::to_underlying(RootSigVer)));
83 MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature, Version});
85 StringRef RootSignatureValKey =
"dx.rootsignatures";
86 auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey);
87 RootSignatureValMD->addOperand(MDVals);
92 const Expr *
E =
nullptr;
93 while (ASE !=
nullptr) {
97 ASE = dyn_cast<ArraySubscriptExpr>(
E);
99 if (
const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(
E))
100 return DRE->getDecl();
107 assert(Ty->
isArrayType() &&
"expected array type");
121 bool ExplicitBinding) {
122 std::array<QualType, 5> ExpParmTypes = {
125 ExpParmTypes[ExplicitBinding ? 2 : 1] = AST.
IntTy;
128 for (
auto *Ctor : ResDecl->
ctors()) {
129 if (Ctor->getNumParams() != ExpParmTypes.size())
131 auto *ParmIt = Ctor->param_begin();
132 auto ExpTyIt = ExpParmTypes.begin();
133 for (; ParmIt != Ctor->param_end() && ExpTyIt != ExpParmTypes.end();
134 ++ParmIt, ++ExpTyIt) {
135 if ((*ParmIt)->getType() != *ExpTyIt)
138 if (ParmIt == Ctor->param_end())
141 llvm_unreachable(
"did not find constructor for resource class");
144static Value *buildNameForResource(llvm::StringRef BaseName,
152 llvm::Value *ThisPtr, llvm::Value *
Range,
153 llvm::Value *Index, StringRef Name,
154 HLSLResourceBindingAttr *RBA,
155 HLSLVkBindingAttr *VkBinding,
157 assert((VkBinding || RBA) &&
"at least one a binding attribute expected");
159 std::optional<uint32_t> RegisterSlot;
162 RegisterSlot = VkBinding->getBinding();
163 SpaceNo = VkBinding->getSet();
165 if (RBA->hasRegisterSlot())
166 RegisterSlot = RBA->getSlotNumber();
167 SpaceNo = RBA->getSpaceNumber();
171 Value *NameStr = buildNameForResource(Name, CGM);
172 Value *Space = llvm::ConstantInt::get(CGM.
IntTy, SpaceNo);
175 if (RegisterSlot.has_value()) {
177 auto *RegSlot = llvm::ConstantInt::get(CGM.
IntTy, RegisterSlot.value());
186 llvm::ConstantInt::get(CGM.
IntTy, RBA->getImplicitBindingOrderID());
200static Value *initializeLocalResourceArray(
203 llvm::Value *
Range, llvm::Value *StartIndex, StringRef ResourceName,
204 HLSLResourceBindingAttr *RBA, HLSLVkBindingAttr *VkBinding,
207 llvm::IntegerType *IntTy = CGF.
CGM.
IntTy;
208 llvm::Value *Index = StartIndex;
209 llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
217 GEPIndices.push_back(llvm::ConstantInt::get(IntTy, 0));
222 for (uint64_t I = 0; I < ArraySize; I++) {
224 Index = CGF.
Builder.CreateAdd(Index, One);
225 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
227 Index = initializeLocalResourceArray(
228 CGF, ValueSlot, SubArrayTy, CD,
Range, Index, ResourceName, RBA,
229 VkBinding, GEPIndices, ArraySubsExprLoc);
240 for (uint64_t I = 0; I < ArraySize; I++) {
242 Index = CGF.
Builder.CreateAdd(Index, One);
243 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
250 createResourceCtorArgs(CGF.
CGM, CD, ThisPtr,
Range, Index, ResourceName,
251 RBA, VkBinding, Args);
253 Args, ValueSlot.
mayOverlap(), ArraySubsExprLoc,
267 if (llvm::Type *TargetTy =
271 llvm_unreachable(
"Generic handling of HLSL types is not supported.");
274llvm::Triple::ArchType CGHLSLRuntime::getArch() {
280void CGHLSLRuntime::emitBufferGlobalsAndMetadata(
const HLSLBufferDecl *BufDecl,
281 llvm::GlobalVariable *BufGV) {
285 llvm::Type *BufType = BufGV->getValueType();
286 llvm::Type *BufLayoutType =
287 cast<llvm::TargetExtType>(BufType)->getTypeParameter(0);
288 llvm::StructType *LayoutStruct = cast<llvm::StructType>(
289 cast<llvm::TargetExtType>(BufLayoutType)->getTypeParameter(0));
294 BufGlobals.push_back(ValueAsMetadata::get(BufGV));
296 const auto *ElemIt = LayoutStruct->element_begin();
298 if (isa<CXXRecordDecl, EmptyDecl>(
D))
301 if (isa<FunctionDecl>(
D)) {
322 "constant buffer decl with non-zero sized type outside of "
323 "hlsl_constant address space");
328 assert(ElemIt != LayoutStruct->element_end() &&
329 "number of elements in layout struct does not match");
330 llvm::Type *LayoutType = *ElemIt++;
336 GlobalVariable *ElemGV =
338 BufGlobals.push_back(ValueAsMetadata::get(ElemGV));
340 assert(ElemIt == LayoutStruct->element_end() &&
341 "number of elements in layout struct does not match");
345 .getOrInsertNamedMetadata(
"hlsl.cbs")
346 ->addOperand(MDNode::get(Ctx, BufGlobals));
356 return cast<HLSLAttributedResourceType>(QT.
getTypePtr());
374 assert(Layout.empty() &&
"expected empty vector for layout");
378 if (isa<CXXRecordDecl, EmptyDecl>(
D) || isa<FunctionDecl>(
D)) {
386 Layout.push_back(-1);
392 if (
auto *POA = dyn_cast<HLSLPackOffsetAttr>(
Attr)) {
393 Offset = POA->getOffsetInBytes();
396 auto *RBA = dyn_cast<HLSLResourceBindingAttr>(
Attr);
398 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
399 Offset = RBA->getSlotNumber() * CBufferRowSizeInBytes;
403 Layout.push_back(Offset);
410 assert(BufDecl->
isCBuffer() &&
"tbuffer codegen is not supported yet");
425 llvm::TargetExtType *TargetTy =
428 llvm::GlobalVariable *BufGV =
new GlobalVariable(
430 GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy),
431 llvm::formatv(
"{0}{1}", BufDecl->
getName(),
433 GlobalValue::NotThreadLocal);
434 CGM.
getModule().insertGlobalVariable(BufGV);
437 emitBufferGlobalsAndMetadata(BufDecl, BufGV);
440 if (HLSLVkBindingAttr *VkBinding = BufDecl->
getAttr<HLSLVkBindingAttr>()) {
441 initializeBufferFromBinding(BufDecl, BufGV, VkBinding);
443 HLSLResourceBindingAttr *RBA = BufDecl->
getAttr<HLSLResourceBindingAttr>();
445 "cbuffer/tbuffer should always have resource binding attribute");
446 initializeBufferFromBinding(BufDecl, BufGV, RBA);
452 const auto Entry = LayoutTypes.find(StructType);
453 if (Entry != LayoutTypes.end())
454 return Entry->getSecond();
459 llvm::TargetExtType *LayoutTy) {
461 "layout type for this struct already exist");
462 LayoutTypes[StructType] = LayoutTy;
470 Triple
T(M.getTargetTriple());
471 if (
T.getArch() == Triple::ArchType::dxil)
472 addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
473 if (CodeGenOpts.ResMayAlias)
474 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.resmayalias", 1);
479 if (LangOpts.NativeHalfType)
480 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.nativelowprec",
488 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
489 assert(ShaderAttr &&
"All entry functions must have a HLSLShaderAttr");
490 const StringRef ShaderAttrKindStr =
"hlsl.shader";
491 Fn->addFnAttr(ShaderAttrKindStr,
492 llvm::Triple::getEnvironmentTypeName(ShaderAttr->getType()));
493 if (HLSLNumThreadsAttr *NumThreadsAttr = FD->
getAttr<HLSLNumThreadsAttr>()) {
494 const StringRef NumThreadsKindStr =
"hlsl.numthreads";
495 std::string NumThreadsStr =
496 formatv(
"{0},{1},{2}", NumThreadsAttr->getX(), NumThreadsAttr->getY(),
497 NumThreadsAttr->getZ());
498 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
500 if (HLSLWaveSizeAttr *WaveSizeAttr = FD->
getAttr<HLSLWaveSizeAttr>()) {
501 const StringRef WaveSizeKindStr =
"hlsl.wavesize";
502 std::string WaveSizeStr =
503 formatv(
"{0},{1},{2}", WaveSizeAttr->getMin(), WaveSizeAttr->getMax(),
504 WaveSizeAttr->getPreferred());
505 Fn->addFnAttr(WaveSizeKindStr, WaveSizeStr);
513 Fn->addFnAttr(llvm::Attribute::OptimizeNone);
514 Fn->addFnAttr(llvm::Attribute::NoInline);
518 if (
const auto *VT = dyn_cast<FixedVectorType>(Ty)) {
520 for (
unsigned I = 0; I < VT->getNumElements(); ++I) {
521 Value *Elt = B.CreateCall(F, {B.getInt32(I)});
526 return B.CreateCall(F, {B.getInt32(0)});
531 LLVMContext &Ctx = GV->getContext();
532 IRBuilder<> B(GV->getContext());
533 MDNode *Operands = MDNode::get(
535 {ConstantAsMetadata::get(B.getInt32( 11)),
536 ConstantAsMetadata::get(B.getInt32(BuiltIn))});
537 MDNode *Decoration = MDNode::get(Ctx, {Operands});
538 GV->addMetadata(
"spirv.Decorations", *Decoration);
542 llvm::Type *Ty,
const Twine &Name,
543 unsigned BuiltInID) {
544 auto *GV =
new llvm::GlobalVariable(
545 M, Ty,
true, llvm::GlobalValue::ExternalLinkage,
546 nullptr, Name,
nullptr,
547 llvm::GlobalVariable::GeneralDynamicTLSModel,
550 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
551 return B.CreateLoad(Ty, GV);
557 assert(
D.
hasAttrs() &&
"Entry parameter missing annotation attribute!");
558 if (
D.
hasAttr<HLSLSV_GroupIndexAttr>()) {
559 llvm::Function *GroupIndex =
560 CGM.
getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
561 return B.CreateCall(FunctionCallee(GroupIndex));
563 if (
D.
hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
564 llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
565 llvm::Function *ThreadIDIntrinsic =
566 llvm::Intrinsic::isOverloaded(IntrinID)
571 if (
D.
hasAttr<HLSLSV_GroupThreadIDAttr>()) {
572 llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
573 llvm::Function *GroupThreadIDIntrinsic =
574 llvm::Intrinsic::isOverloaded(IntrinID)
579 if (
D.
hasAttr<HLSLSV_GroupIDAttr>()) {
580 llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
581 llvm::Function *GroupIDIntrinsic =
582 llvm::Intrinsic::isOverloaded(IntrinID)
587 if (
D.
hasAttr<HLSLSV_PositionAttr>()) {
588 if (getArch() == llvm::Triple::spirv)
591 llvm_unreachable(
"SV_Position semantic not implemented for this target.");
593 assert(
false &&
"Unhandled parameter attribute");
598 llvm::Function *Fn) {
600 llvm::LLVMContext &Ctx = M.getContext();
601 auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
false);
603 Function::Create(EntryTy, Function::ExternalLinkage, FD->
getName(), &M);
607 AttributeList NewAttrs = AttributeList::get(Ctx, AttributeList::FunctionIndex,
608 Fn->getAttributes().getFnAttrs());
609 EntryFn->setAttributes(NewAttrs);
613 Fn->setLinkage(GlobalValue::InternalLinkage);
615 BasicBlock *BB = BasicBlock::Create(Ctx,
"entry", EntryFn);
621 assert(EntryFn->isConvergent());
623 B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {});
624 llvm::Value *bundleArgs[] = {I};
625 OB.emplace_back(
"convergencectrl", bundleArgs);
630 unsigned SRetOffset = 0;
631 for (
const auto &Param : Fn->args()) {
632 if (Param.hasStructRetAttr()) {
636 Args.emplace_back(PoisonValue::get(Param.getType()));
643 CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
644 CI->setCallingConv(Fn->getCallingConv());
651 if (
const auto *RSAttr = dyn_cast<RootSignatureAttr>(
Attr)) {
652 auto *RSDecl = RSAttr->getSignatureDecl();
653 addRootSignature(RSDecl->getVersion(), RSDecl->getRootElements(), EntryFn,
662 M.getNamedGlobal(CtorOrDtor ?
"llvm.global_ctors" :
"llvm.global_dtors");
665 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
672 for (
const auto &Ctor : CA->operands()) {
673 if (isa<ConstantAggregateZero>(Ctor))
675 ConstantStruct *CS = cast<ConstantStruct>(Ctor);
677 assert(cast<ConstantInt>(CS->getOperand(0))->getValue() == 65535 &&
678 "HLSL doesn't support setting priority for global ctors.");
679 assert(isa<ConstantPointerNull>(CS->getOperand(2)) &&
680 "HLSL doesn't support COMDat for global ctors.");
681 Fns.push_back(cast<Function>(CS->getOperand(1)));
695 for (
auto &F : M.functions()) {
696 if (!F.hasFnAttribute(
"hlsl.shader"))
699 Instruction *IP = &*F.getEntryBlock().begin();
702 llvm::Value *bundleArgs[] = {
Token};
703 OB.emplace_back(
"convergencectrl", bundleArgs);
704 IP =
Token->getNextNode();
707 for (
auto *Fn : CtorFns) {
708 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
709 CI->setCallingConv(Fn->getCallingConv());
713 B.SetInsertPoint(F.back().getTerminator());
714 for (
auto *Fn : DtorFns) {
715 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
716 CI->setCallingConv(Fn->getCallingConv());
722 Triple
T(M.getTargetTriple());
723 if (
T.getEnvironment() != Triple::EnvironmentType::Library) {
724 if (
auto *GV = M.getNamedGlobal(
"llvm.global_ctors"))
725 GV->eraseFromParent();
726 if (
auto *GV = M.getNamedGlobal(
"llvm.global_dtors"))
727 GV->eraseFromParent();
732 Intrinsic::ID IntrID,
736 llvm::Function *InitResFunc = llvm::Function::Create(
737 llvm::FunctionType::get(CGM.
VoidTy,
false),
738 llvm::GlobalValue::InternalLinkage,
739 (
"_init_buffer_" + GV->getName()).str(), CGM.
getModule());
740 InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
742 llvm::BasicBlock *EntryBB =
743 llvm::BasicBlock::Create(Ctx,
"entry", InitResFunc);
745 const DataLayout &DL = CGM.
getModule().getDataLayout();
746 Builder.SetInsertPoint(EntryBB);
749 llvm::Type *HandleTy = GV->getValueType();
750 assert(HandleTy->isTargetExtTy() &&
"unexpected type of the buffer global");
752 llvm::Value *CreateHandle = Builder.CreateIntrinsic(
753 HandleTy, IntrID, Args,
nullptr,
754 Twine(GV->getName()).concat(
"_h"));
756 llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
757 Builder.CreateAlignedStore(CreateHandle, HandleRef,
758 HandleRef->getPointerAlignment(DL));
759 Builder.CreateRetVoid();
764void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
765 llvm::GlobalVariable *GV,
766 HLSLVkBindingAttr *VkBinding) {
767 assert(VkBinding &&
"expect a nonnull binding attribute");
768 auto *Index = llvm::ConstantInt::get(CGM.
IntTy, 0);
769 auto *RangeSize = llvm::ConstantInt::get(CGM.
IntTy, 1);
770 auto *
Set = llvm::ConstantInt::get(CGM.
IntTy, VkBinding->getSet());
771 auto *Binding = llvm::ConstantInt::get(CGM.
IntTy, VkBinding->getBinding());
772 Value *Name = buildNameForResource(BufDecl->
getName(), CGM);
773 llvm::Intrinsic::ID IntrinsicID =
780void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
781 llvm::GlobalVariable *GV,
782 HLSLResourceBindingAttr *RBA) {
783 assert(RBA &&
"expect a nonnull binding attribute");
784 auto *Index = llvm::ConstantInt::get(CGM.
IntTy, 0);
785 auto *RangeSize = llvm::ConstantInt::get(CGM.
IntTy, 1);
786 auto *Space = llvm::ConstantInt::get(CGM.
IntTy, RBA->getSpaceNumber());
787 Value *Name = buildNameForResource(BufDecl->
getName(), CGM);
789 llvm::Intrinsic::ID IntrinsicID =
790 RBA->hasRegisterSlot()
792 : CGM.
getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
795 if (RBA->hasRegisterSlot()) {
796 auto *RegSlot = llvm::ConstantInt::get(CGM.
IntTy, RBA->getSlotNumber());
802 llvm::ConstantInt::get(CGM.
IntTy, RBA->getImplicitBindingOrderID());
809 llvm::GlobalVariable *GV) {
810 if (
auto Attr = VD->
getAttr<HLSLVkExtBuiltinInputAttr>())
819 for (
auto I = BB.begin(); I !=
E; ++I) {
820 auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
821 if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
825 llvm_unreachable(
"Convergence token should have been emitted.");
846 for (
auto *OVE : Visitor.
OVEs) {
849 if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
851 OpaqueValueMappingData::bind(CGF, OVE, LV);
854 OpaqueValueMappingData::bind(CGF, OVE, RV);
863 "expected resource array subscript expression");
869 dyn_cast_or_null<VarDecl>(getArrayDecl(ArraySubsExpr));
877 "expected array of resource classes");
883 Value *Index =
nullptr;
885 while (ASE !=
nullptr) {
887 if (
const auto *ArrayTy =
889 Value *Multiplier = llvm::ConstantInt::get(
891 SubIndex = CGF.
Builder.CreateMul(SubIndex, Multiplier);
893 Index = Index ? CGF.
Builder.CreateAdd(Index, SubIndex) : SubIndex;
899 HLSLVkBindingAttr *VkBinding = ArrayDecl->
getAttr<HLSLVkBindingAttr>();
900 HLSLResourceBindingAttr *RBA = ArrayDecl->
getAttr<HLSLResourceBindingAttr>();
901 assert((VkBinding || RBA) &&
"resource array must have a binding attribute");
911 AST, ResourceTy, VkBinding || RBA->hasRegisterSlot());
925 Address TmpVarAddress = ValueSlot.getAddress();
929 llvm::ConstantInt::get(CGM.
IntTy, getTotalArraySize(AST, ResArrayTy));
933 if (ResultTy == ResourceTy) {
939 createResourceCtorArgs(CGM, CD, ThisPtr,
Range, Index, ArrayDecl->
getName(),
940 RBA, VkBinding, Args);
943 Args, ValueSlot.mayOverlap(),
945 ValueSlot.isSanitizerChecked());
950 cast<ConstantArrayType>(ResultTy.
getTypePtr());
951 initializeLocalResourceArray(CGF, ValueSlot, ArrayTy, CD,
Range, Index,
952 ArrayDecl->
getName(), RBA, VkBinding,
953 {llvm::ConstantInt::get(CGM.IntTy, 0)},
Defines the clang::ASTContext interface.
static llvm::Value * createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, llvm::Type *Ty, const Twine &Name, unsigned BuiltInID)
static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl, SmallVector< int32_t > &Layout)
static void addSPIRVBuiltinDecoration(llvm::GlobalVariable *GV, unsigned BuiltIn)
static void gatherFunctions(SmallVectorImpl< Function * > &Fns, llvm::Module &M, bool CtorOrDtor)
static Value * buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty)
static void initializeBuffer(CodeGenModule &CGM, llvm::GlobalVariable *GV, Intrinsic::ID IntrID, ArrayRef< llvm::Value * > Args)
static const clang::HLSLAttributedResourceType * createBufferHandleType(const HLSLBufferDecl *BufDecl)
Defines the clang::TargetOptions class.
C Language Family Type Representation.
bool VisitOpaqueValueExpr(OpaqueValueExpr *E)
llvm::SmallPtrSet< OpaqueValueExpr *, 8 > OVEs
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getHLSLAttributedResourceType(QualType Wrapped, QualType Contained, const HLSLAttributedResourceType::Attributes &Attrs)
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getExprLoc() const LLVM_READONLY
QualType getElementType() const
Attr - This represents one attribute.
Represents a C++ constructor within a class.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
QualType withConst() const
Retrieves a version of this type with const applied.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
CharUnits getAlignment() const
bool isSanitizerChecked() const
Address getAddress() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
Overlap_t mayOverlap() const
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::Instruction * getConvergenceToken(llvm::BasicBlock &BB)
void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn)
void addHLSLBufferLayoutType(const RecordType *LayoutStructTy, llvm::TargetExtType *LayoutTy)
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn)
void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var)
llvm::TargetExtType * getHLSLBufferLayoutType(const RecordType *LayoutStructTy)
resource_getpointer resource_handlefromimplicitbinding GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync, group_memory_barrier_with_group_sync) protected llvm::Value * emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D, llvm::Type *Ty)
llvm::Type * convertHLSLSpecificType(const Type *T, SmallVector< int32_t > *Packoffsets=nullptr)
std::optional< LValue > emitResourceArraySubscriptExpr(const ArraySubscriptExpr *E, CodeGenFunction &CGF)
void addBuffer(const HLSLBufferDecl *D)
void generateGlobalCtorDtorCalls()
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
A non-RAII class containing all the information about a bound opaque value.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
bool EmitLifetimeStart(llvm::Value *Addr)
Emit a lifetime.begin marker if some criteria are satisfied.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
llvm::Type * ConvertTypeForMem(QualType T)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
bool isOpaqueValueEmitted(const OpaqueValueExpr *E)
isOpaqueValueEmitted - Return true if the opaque value expression has already been emitted.
This class organizes the cross-function state that is used while generating LLVM code.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Module & getModule() const
void AddCXXGlobalInit(llvm::Function *F)
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
bool shouldEmitConvergenceTokens() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
void EmitTopLevelDecl(Decl *D)
Emit code for a single top level declaration.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::Constant * getPointer() const
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
An abstract representation of an aligned address.
llvm::Value * getPointer() const
virtual llvm::Type * getHLSLType(CodeGenModule &CGM, const Type *T, const SmallVector< int32_t > *Packoffsets=nullptr) const
Return an LLVM type that corresponds to a HLSL type.
Represents the canonical version of C arrays with a specified constant size.
int64_t getSExtSize() const
Return the size sign-extended as a uint64_t.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
This represents one expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getContainedType() const
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
const CXXRecordDecl * getLayoutStruct() const
bool hasValidPackoffset() const
buffer_decl_range buffer_decls() const
Describes an C or C++ initializer list.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Represents a parameter to a function.
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
The collection of all-type qualifiers we support.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
Encodes a location in the source.
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Token - This structure provides full information about a lexed token.
The base class of the type hierarchy.
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isHLSLSpecificType() const
bool isHLSLResourceRecord() const
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
bool isHLSLResourceRecordArray() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
@ Ctor_Complete
Complete object ctor.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int