21#include "clang/AST/Attrs.inc"
27#include "llvm/ADT/SmallString.h"
28#include "llvm/ADT/SmallVector.h"
29#include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/DerivedTypes.h"
32#include "llvm/IR/GlobalVariable.h"
33#include "llvm/IR/LLVMContext.h"
34#include "llvm/IR/Metadata.h"
35#include "llvm/IR/Module.h"
36#include "llvm/IR/Type.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/Alignment.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/FormatVariadic.h"
48using llvm::hlsl::CBufferRowSizeInBytes;
52void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) {
56 if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
57 Version.getSubminor() || !Version.getMinor()) {
61 uint64_t Major = Version.getMajor();
62 uint64_t Minor = *Version.getMinor();
64 auto &Ctx = M.getContext();
65 IRBuilder<> B(M.getContext());
66 MDNode *Val = MDNode::get(Ctx, {ConstantAsMetadata::get(B.getInt32(Major)),
67 ConstantAsMetadata::get(B.getInt32(Minor))});
68 StringRef DXILValKey =
"dx.valver";
69 auto *DXILValMD = M.getOrInsertNamedMetadata(DXILValKey);
70 DXILValMD->addOperand(Val);
73void addRootSignatureMD(llvm::dxbc::RootSignatureVersion RootSigVer,
75 llvm::Function *Fn, llvm::Module &M) {
76 auto &Ctx = M.getContext();
78 llvm::hlsl::rootsig::MetadataBuilder RSBuilder(Ctx, Elements);
79 MDNode *RootSignature = RSBuilder.BuildRootSignature();
81 ConstantAsMetadata *Version = ConstantAsMetadata::get(ConstantInt::get(
82 llvm::Type::getInt32Ty(Ctx), llvm::to_underlying(RootSigVer)));
83 ValueAsMetadata *EntryFunc =
Fn ? ValueAsMetadata::get(Fn) :
nullptr;
84 MDNode *MDVals = MDNode::get(Ctx, {EntryFunc, RootSignature, Version});
86 StringRef RootSignatureValKey =
"dx.rootsignatures";
87 auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey);
88 RootSignatureValMD->addOperand(MDVals);
93 const Expr *E =
nullptr;
94 while (ASE !=
nullptr) {
98 ASE = dyn_cast<ArraySubscriptExpr>(E);
100 if (
const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(E))
101 return DRE->getDecl();
108 assert(Ty->
isArrayType() &&
"expected array type");
122 bool ExplicitBinding) {
123 std::array<QualType, 5> ExpParmTypes = {
126 ExpParmTypes[ExplicitBinding ? 2 : 1] = AST.
IntTy;
129 for (
auto *Ctor : ResDecl->
ctors()) {
130 if (Ctor->getNumParams() != ExpParmTypes.size())
132 auto *ParmIt = Ctor->param_begin();
133 auto ExpTyIt = ExpParmTypes.begin();
134 for (; ParmIt != Ctor->param_end() && ExpTyIt != ExpParmTypes.end();
135 ++ParmIt, ++ExpTyIt) {
136 if ((*ParmIt)->getType() != *ExpTyIt)
139 if (ParmIt == Ctor->param_end())
142 llvm_unreachable(
"did not find constructor for resource class");
145static Value *buildNameForResource(llvm::StringRef BaseName,
153 llvm::Value *ThisPtr, llvm::Value *Range,
154 llvm::Value *Index, StringRef Name,
155 HLSLResourceBindingAttr *RBA,
156 HLSLVkBindingAttr *VkBinding,
158 assert((VkBinding || RBA) &&
"at least one a binding attribute expected");
160 std::optional<uint32_t> RegisterSlot;
161 uint32_t SpaceNo = 0;
163 RegisterSlot = VkBinding->getBinding();
164 SpaceNo = VkBinding->getSet();
166 if (RBA->hasRegisterSlot())
167 RegisterSlot = RBA->getSlotNumber();
168 SpaceNo = RBA->getSpaceNumber();
172 Value *NameStr = buildNameForResource(Name, CGM);
173 Value *Space = llvm::ConstantInt::get(CGM.
IntTy, SpaceNo);
176 if (RegisterSlot.has_value()) {
178 auto *RegSlot = llvm::ConstantInt::get(CGM.
IntTy, RegisterSlot.value());
186 assert(RBA &&
"missing implicit binding attribute");
188 llvm::ConstantInt::get(CGM.
IntTy, RBA->getImplicitBindingOrderID());
202static Value *initializeLocalResourceArray(
205 llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
206 HLSLResourceBindingAttr *RBA, HLSLVkBindingAttr *VkBinding,
209 llvm::IntegerType *IntTy = CGF.
CGM.
IntTy;
210 llvm::Value *Index = StartIndex;
211 llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
219 GEPIndices.push_back(llvm::ConstantInt::get(IntTy, 0));
224 for (uint64_t I = 0; I < ArraySize; I++) {
226 Index = CGF.
Builder.CreateAdd(Index, One);
227 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
229 Index = initializeLocalResourceArray(
230 CGF, ValueSlot, SubArrayTy, CD, Range, Index, ResourceName, RBA,
231 VkBinding, GEPIndices, ArraySubsExprLoc);
242 for (uint64_t I = 0; I < ArraySize; I++) {
244 Index = CGF.
Builder.CreateAdd(Index, One);
245 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
252 createResourceCtorArgs(CGF.
CGM, CD, ThisPtr, Range, Index, ResourceName,
253 RBA, VkBinding, Args);
255 Args, ValueSlot.
mayOverlap(), ArraySubsExprLoc,
266 assert(
T->isHLSLSpecificType() &&
"Not an HLSL specific type!");
269 if (llvm::Type *TargetTy =
273 llvm_unreachable(
"Generic handling of HLSL types is not supported.");
276llvm::Triple::ArchType CGHLSLRuntime::getArch() {
282void CGHLSLRuntime::emitBufferGlobalsAndMetadata(
const HLSLBufferDecl *BufDecl,
283 llvm::GlobalVariable *BufGV) {
287 llvm::Type *BufType = BufGV->getValueType();
288 llvm::Type *BufLayoutType =
296 BufGlobals.push_back(ValueAsMetadata::get(BufGV));
298 const auto *ElemIt = LayoutStruct->element_begin();
308 VarDecl *VD = dyn_cast<VarDecl>(D);
324 "constant buffer decl with non-zero sized type outside of "
325 "hlsl_constant address space");
330 assert(ElemIt != LayoutStruct->element_end() &&
331 "number of elements in layout struct does not match");
332 llvm::Type *LayoutType = *ElemIt++;
338 GlobalVariable *ElemGV =
340 BufGlobals.push_back(ValueAsMetadata::get(ElemGV));
342 assert(ElemIt == LayoutStruct->element_end() &&
343 "number of elements in layout struct does not match");
347 .getOrInsertNamedMetadata(
"hlsl.cbs")
348 ->addOperand(MDNode::get(Ctx, BufGlobals));
352static const clang::HLSLAttributedResourceType *
357 HLSLAttributedResourceType::Attributes(ResourceClass::CBuffer));
376 assert(Layout.empty() &&
"expected empty vector for layout");
383 VarDecl *VD = dyn_cast<VarDecl>(D);
388 Layout.push_back(-1);
394 if (
auto *POA = dyn_cast<HLSLPackOffsetAttr>(
Attr)) {
395 Offset = POA->getOffsetInBytes();
398 auto *RBA = dyn_cast<HLSLResourceBindingAttr>(
Attr);
400 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
401 Offset = RBA->getSlotNumber() * CBufferRowSizeInBytes;
405 Layout.push_back(Offset);
412 assert(BufDecl->
isCBuffer() &&
"tbuffer codegen is not supported yet");
415 const clang::HLSLAttributedResourceType *ResHandleTy =
419 if (ResHandleTy->getContainedType()->getAsCXXRecordDecl()->isEmpty())
427 llvm::TargetExtType *TargetTy =
430 llvm::GlobalVariable *BufGV =
new GlobalVariable(
432 GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy),
433 llvm::formatv(
"{0}{1}", BufDecl->
getName(),
435 GlobalValue::NotThreadLocal);
436 CGM.
getModule().insertGlobalVariable(BufGV);
439 emitBufferGlobalsAndMetadata(BufDecl, BufGV);
442 if (HLSLVkBindingAttr *VkBinding = BufDecl->
getAttr<HLSLVkBindingAttr>()) {
443 initializeBufferFromBinding(BufDecl, BufGV, VkBinding);
445 HLSLResourceBindingAttr *RBA = BufDecl->
getAttr<HLSLResourceBindingAttr>();
447 "cbuffer/tbuffer should always have resource binding attribute");
448 initializeBufferFromBinding(BufDecl, BufGV, RBA);
455 Triple
T(M.getTargetTriple());
458 if (
T.getEnvironment() != Triple::EnvironmentType::RootSignature)
461 addRootSignatureMD(SignatureDecl->
getVersion(),
467 const auto Entry = LayoutTypes.find(StructType);
468 if (Entry != LayoutTypes.end())
469 return Entry->getSecond();
474 llvm::TargetExtType *LayoutTy) {
476 "layout type for this struct already exist");
477 LayoutTypes[StructType] = LayoutTy;
485 Triple
T(M.getTargetTriple());
486 if (
T.getArch() == Triple::ArchType::dxil)
487 addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
488 if (CodeGenOpts.ResMayAlias)
489 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.resmayalias", 1);
494 if (LangOpts.NativeHalfType)
495 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.nativelowprec",
503 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
504 assert(ShaderAttr &&
"All entry functions must have a HLSLShaderAttr");
505 const StringRef ShaderAttrKindStr =
"hlsl.shader";
506 Fn->addFnAttr(ShaderAttrKindStr,
507 llvm::Triple::getEnvironmentTypeName(ShaderAttr->getType()));
508 if (HLSLNumThreadsAttr *NumThreadsAttr = FD->
getAttr<HLSLNumThreadsAttr>()) {
509 const StringRef NumThreadsKindStr =
"hlsl.numthreads";
510 std::string NumThreadsStr =
511 formatv(
"{0},{1},{2}", NumThreadsAttr->getX(), NumThreadsAttr->getY(),
512 NumThreadsAttr->getZ());
513 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
515 if (HLSLWaveSizeAttr *WaveSizeAttr = FD->
getAttr<HLSLWaveSizeAttr>()) {
516 const StringRef WaveSizeKindStr =
"hlsl.wavesize";
517 std::string WaveSizeStr =
518 formatv(
"{0},{1},{2}", WaveSizeAttr->getMin(), WaveSizeAttr->getMax(),
519 WaveSizeAttr->getPreferred());
520 Fn->addFnAttr(WaveSizeKindStr, WaveSizeStr);
528 Fn->addFnAttr(llvm::Attribute::OptimizeNone);
529 Fn->addFnAttr(llvm::Attribute::NoInline);
533 if (
const auto *VT = dyn_cast<FixedVectorType>(Ty)) {
534 Value *Result = PoisonValue::get(Ty);
535 for (
unsigned I = 0; I < VT->getNumElements(); ++I) {
536 Value *Elt = B.CreateCall(F, {B.getInt32(I)});
537 Result = B.CreateInsertElement(Result, Elt, I);
541 return B.CreateCall(F, {B.getInt32(0)});
546 LLVMContext &Ctx = GV->getContext();
547 IRBuilder<> B(GV->getContext());
548 MDNode *Operands = MDNode::get(
550 {ConstantAsMetadata::get(B.getInt32( 11)),
551 ConstantAsMetadata::get(B.getInt32(BuiltIn))});
552 MDNode *Decoration = MDNode::get(Ctx, {Operands});
553 GV->addMetadata(
"spirv.Decorations", *Decoration);
557 llvm::Type *Ty,
const Twine &Name,
558 unsigned BuiltInID) {
559 auto *GV =
new llvm::GlobalVariable(
560 M, Ty,
true, llvm::GlobalValue::ExternalLinkage,
561 nullptr, Name,
nullptr,
562 llvm::GlobalVariable::GeneralDynamicTLSModel,
565 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
566 return B.CreateLoad(Ty, GV);
574 llvm::Function *GroupIndex =
575 CGM.
getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
576 return B.CreateCall(FunctionCallee(GroupIndex));
580 llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
581 llvm::Function *ThreadIDIntrinsic =
582 llvm::Intrinsic::isOverloaded(IntrinID)
589 llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
590 llvm::Function *GroupThreadIDIntrinsic =
591 llvm::Intrinsic::isOverloaded(IntrinID)
598 llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
599 llvm::Function *GroupIDIntrinsic =
600 llvm::Intrinsic::isOverloaded(IntrinID)
606 if (HLSLSV_PositionAttr *S =
607 dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.
Semantic)) {
608 if (CGM.
getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
610 S->getAttrName()->getName(),
614 llvm_unreachable(
"non-handled system semantic. FIXME.");
626 diag::err_hlsl_semantic_missing);
639 assert(!
Type->isStructTy());
644 llvm::Function *Fn) {
646 llvm::LLVMContext &Ctx = M.getContext();
647 auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
false);
649 Function::Create(EntryTy, Function::ExternalLinkage, FD->
getName(), &M);
653 AttributeList NewAttrs = AttributeList::get(Ctx, AttributeList::FunctionIndex,
654 Fn->getAttributes().getFnAttrs());
655 EntryFn->setAttributes(NewAttrs);
659 Fn->setLinkage(GlobalValue::InternalLinkage);
661 BasicBlock *BB = BasicBlock::Create(Ctx,
"entry", EntryFn);
667 assert(EntryFn->isConvergent());
669 B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {});
670 llvm::Value *bundleArgs[] = {I};
671 OB.emplace_back(
"convergencectrl", bundleArgs);
676 unsigned SRetOffset = 0;
677 for (
const auto &Param : Fn->args()) {
678 if (Param.hasStructRetAttr()) {
682 Args.emplace_back(PoisonValue::get(Param.getType()));
691 CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
692 CI->setCallingConv(Fn->getCallingConv());
699 if (
const auto *RSAttr = dyn_cast<RootSignatureAttr>(
Attr)) {
700 auto *RSDecl = RSAttr->getSignatureDecl();
701 addRootSignatureMD(RSDecl->getVersion(), RSDecl->getRootElements(),
710 M.getNamedGlobal(CtorOrDtor ?
"llvm.global_ctors" :
"llvm.global_dtors");
713 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
720 for (
const auto &Ctor : CA->operands()) {
726 "HLSL doesn't support setting priority for global ctors.");
728 "HLSL doesn't support COMDat for global ctors.");
743 for (
auto &F : M.functions()) {
744 if (!F.hasFnAttribute(
"hlsl.shader"))
747 Instruction *IP = &*F.getEntryBlock().begin();
750 llvm::Value *bundleArgs[] = {
Token};
751 OB.emplace_back(
"convergencectrl", bundleArgs);
752 IP =
Token->getNextNode();
755 for (
auto *Fn : CtorFns) {
756 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
757 CI->setCallingConv(Fn->getCallingConv());
761 B.SetInsertPoint(F.back().getTerminator());
762 for (
auto *Fn : DtorFns) {
763 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
764 CI->setCallingConv(Fn->getCallingConv());
770 Triple
T(M.getTargetTriple());
771 if (
T.getEnvironment() != Triple::EnvironmentType::Library) {
772 if (
auto *GV = M.getNamedGlobal(
"llvm.global_ctors"))
773 GV->eraseFromParent();
774 if (
auto *GV = M.getNamedGlobal(
"llvm.global_dtors"))
775 GV->eraseFromParent();
780 Intrinsic::ID IntrID,
784 llvm::Function *InitResFunc = llvm::Function::Create(
785 llvm::FunctionType::get(CGM.
VoidTy,
false),
786 llvm::GlobalValue::InternalLinkage,
787 (
"_init_buffer_" + GV->getName()).str(), CGM.
getModule());
788 InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
790 llvm::BasicBlock *EntryBB =
791 llvm::BasicBlock::Create(Ctx,
"entry", InitResFunc);
793 const DataLayout &DL = CGM.
getModule().getDataLayout();
794 Builder.SetInsertPoint(EntryBB);
797 llvm::Type *HandleTy = GV->getValueType();
798 assert(HandleTy->isTargetExtTy() &&
"unexpected type of the buffer global");
800 llvm::Value *CreateHandle = Builder.CreateIntrinsic(
801 HandleTy, IntrID, Args,
nullptr,
802 Twine(GV->getName()).concat(
"_h"));
804 llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
805 Builder.CreateAlignedStore(CreateHandle, HandleRef,
806 HandleRef->getPointerAlignment(DL));
807 Builder.CreateRetVoid();
812void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
813 llvm::GlobalVariable *GV,
814 HLSLVkBindingAttr *VkBinding) {
815 assert(VkBinding &&
"expect a nonnull binding attribute");
816 auto *Index = llvm::ConstantInt::get(CGM.
IntTy, 0);
817 auto *RangeSize = llvm::ConstantInt::get(CGM.
IntTy, 1);
818 auto *
Set = llvm::ConstantInt::get(CGM.
IntTy, VkBinding->getSet());
819 auto *Binding = llvm::ConstantInt::get(CGM.
IntTy, VkBinding->getBinding());
820 Value *Name = buildNameForResource(BufDecl->
getName(), CGM);
821 llvm::Intrinsic::ID IntrinsicID =
824 SmallVector<Value *> Args{
Set, Binding, RangeSize, Index, Name};
828void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
829 llvm::GlobalVariable *GV,
830 HLSLResourceBindingAttr *RBA) {
831 assert(RBA &&
"expect a nonnull binding attribute");
832 auto *Index = llvm::ConstantInt::get(CGM.
IntTy, 0);
833 auto *RangeSize = llvm::ConstantInt::get(CGM.
IntTy, 1);
834 auto *Space = llvm::ConstantInt::get(CGM.
IntTy, RBA->getSpaceNumber());
835 Value *Name = buildNameForResource(BufDecl->
getName(), CGM);
837 llvm::Intrinsic::ID IntrinsicID =
838 RBA->hasRegisterSlot()
840 : CGM.
getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
843 if (RBA->hasRegisterSlot()) {
844 auto *RegSlot = llvm::ConstantInt::get(CGM.
IntTy, RBA->getSlotNumber());
845 SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
850 llvm::ConstantInt::get(CGM.
IntTy, RBA->getImplicitBindingOrderID());
851 SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
857 llvm::GlobalVariable *GV) {
858 if (
auto Attr = VD->
getAttr<HLSLVkExtBuiltinInputAttr>())
867 for (
auto I = BB.begin(); I != E; ++I) {
868 auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
869 if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
873 llvm_unreachable(
"Convergence token should have been emitted.");
910 for (
auto *OVE : Visitor.
OVEs) {
913 if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
915 OpaqueValueMappingData::bind(CGF, OVE, LV);
918 OpaqueValueMappingData::bind(CGF, OVE, RV);
927 "expected resource array subscript expression");
933 dyn_cast_or_null<VarDecl>(getArrayDecl(ArraySubsExpr));
941 "expected array of resource classes");
947 Value *Index =
nullptr;
949 while (ASE !=
nullptr) {
951 if (
const auto *ArrayTy =
953 Value *Multiplier = llvm::ConstantInt::get(
955 SubIndex = CGF.
Builder.CreateMul(SubIndex, Multiplier);
957 Index = Index ? CGF.
Builder.CreateAdd(Index, SubIndex) : SubIndex;
963 HLSLVkBindingAttr *VkBinding = ArrayDecl->
getAttr<HLSLVkBindingAttr>();
964 HLSLResourceBindingAttr *RBA = ArrayDecl->
getAttr<HLSLResourceBindingAttr>();
965 assert((VkBinding || RBA) &&
"resource array must have a binding attribute");
975 AST, ResourceTy, VkBinding || RBA->hasRegisterSlot());
989 Address TmpVarAddress = ValueSlot.getAddress();
993 llvm::ConstantInt::get(CGM.
IntTy, getTotalArraySize(AST, ResArrayTy));
997 if (ResultTy == ResourceTy) {
1003 createResourceCtorArgs(CGM, CD, ThisPtr, Range, Index, ArrayDecl->
getName(),
1004 RBA, VkBinding, Args);
1007 Args, ValueSlot.mayOverlap(),
1009 ValueSlot.isSanitizerChecked());
1015 initializeLocalResourceArray(CGF, ValueSlot, ArrayTy, CD, Range, Index,
1016 ArrayDecl->
getName(), RBA, VkBinding,
1017 {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 VisitHLSLOutArgExpr(HLSLOutArgExpr *)
llvm::SmallVector< OpaqueValueExpr *, 8 > OVEs
bool VisitOpaqueValueExpr(OpaqueValueExpr *E)
llvm::SmallPtrSet< OpaqueValueExpr *, 8 > Visited
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.
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)
llvm::Value * handleScalarSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, SemanticInfo &ActiveSemantic)
llvm::Value * emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, SemanticInfo &ActiveSemantic)
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)
llvm::Type * convertHLSLSpecificType(const Type *T, SmallVector< int32_t > *Packoffsets=nullptr)
llvm::Value * handleSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, SemanticInfo &ActiveSemantic)
std::optional< LValue > emitResourceArraySubscriptExpr(const ArraySubscriptExpr *E, CodeGenFunction &CGF)
void addRootSignature(const HLSLRootSignatureDecl *D)
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
DiagnosticsEngine & getDiags() 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
const llvm::Triple & getTriple() 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, StringRef GlobalName=".str")
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
Represents a ValueDecl that came out of a declarator.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
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
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
const CXXRecordDecl * getLayoutStruct() const
bool hasValidPackoffset() const
buffer_decl_range buffer_decls() const
This class represents temporary values used to represent inout and out arguments in HLSL.
ArrayRef< llvm::hlsl::rootsig::RootElement > getRootElements() const
llvm::dxbc::RootSignatureVersion getVersion() const
unsigned getSemanticIndex() 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.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
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 class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
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 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.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ 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.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of βparallelβ, 'serial',...
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
clang::HLSLSemanticAttr * Semantic
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int