22#include "clang/AST/Attrs.inc"
29#include "llvm/ADT/SmallString.h"
30#include "llvm/ADT/SmallVector.h"
31#include "llvm/Frontend/HLSL/RootSignatureMetadata.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DerivedTypes.h"
34#include "llvm/IR/GlobalVariable.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Metadata.h"
37#include "llvm/IR/Module.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Value.h"
40#include "llvm/Support/Alignment.h"
41#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/FormatVariadic.h"
51using llvm::hlsl::CBufferRowSizeInBytes;
55void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) {
59 if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
60 Version.getSubminor() || !Version.getMinor()) {
64 uint64_t Major = Version.getMajor();
65 uint64_t Minor = *Version.getMinor();
67 auto &Ctx = M.getContext();
68 IRBuilder<> B(M.getContext());
69 MDNode *Val = MDNode::get(Ctx, {ConstantAsMetadata::get(B.getInt32(Major)),
70 ConstantAsMetadata::get(B.getInt32(Minor))});
71 StringRef DXILValKey =
"dx.valver";
72 auto *DXILValMD = M.getOrInsertNamedMetadata(DXILValKey);
73 DXILValMD->addOperand(Val);
76void addRootSignatureMD(llvm::dxbc::RootSignatureVersion RootSigVer,
78 llvm::Function *Fn, llvm::Module &M) {
79 auto &Ctx = M.getContext();
81 llvm::hlsl::rootsig::MetadataBuilder RSBuilder(Ctx, Elements);
82 MDNode *RootSignature = RSBuilder.BuildRootSignature();
84 ConstantAsMetadata *Version = ConstantAsMetadata::get(ConstantInt::get(
85 llvm::Type::getInt32Ty(Ctx), llvm::to_underlying(RootSigVer)));
86 ValueAsMetadata *EntryFunc =
Fn ? ValueAsMetadata::get(Fn) :
nullptr;
87 MDNode *MDVals = MDNode::get(Ctx, {EntryFunc, RootSignature, Version});
89 StringRef RootSignatureValKey =
"dx.rootsignatures";
90 auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey);
91 RootSignatureValMD->addOperand(MDVals);
96 const Expr *E =
nullptr;
97 while (ASE !=
nullptr) {
101 ASE = dyn_cast<ArraySubscriptExpr>(E);
103 if (
const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(E))
104 return DRE->getDecl();
111 assert(Ty->
isArrayType() &&
"expected array type");
117static Value *buildNameForResource(llvm::StringRef BaseName,
126 for (
auto *Method :
Record->methods()) {
127 if (Method->getStorageClass() == SC && Method->getName() == Name)
137 assert(Binding.
hasBinding() &&
"at least one binding attribute expected");
141 Value *NameStr = buildNameForResource(Name, CGM);
146 auto *RegSlot = llvm::ConstantInt::get(CGM.
IntTy, Binding.
getSlot());
149 ?
"__createFromBindingWithImplicitCounter"
150 :
"__createFromBinding";
151 CreateMethod = lookupMethod(ResourceDecl, Name,
SC_Static);
158 ?
"__createFromImplicitBindingWithImplicitCounter"
159 :
"__createFromImplicitBinding";
160 CreateMethod = lookupMethod(ResourceDecl, Name,
SC_Static);
168 auto *CounterOrderID = llvm::ConstantInt::get(CGM.
IntTy, CounterBinding);
185 CGF.
EmitCall(FnInfo, Callee, ReturnValue, Args,
nullptr);
193static std::optional<llvm::Value *> initializeLocalResourceArray(
196 llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
201 llvm::IntegerType *IntTy = CGF.
CGM.
IntTy;
202 llvm::Value *Index = StartIndex;
203 llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
211 GEPIndices.push_back(llvm::ConstantInt::get(IntTy, 0));
216 for (uint64_t I = 0; I < ArraySize; I++) {
218 Index = CGF.
Builder.CreateAdd(Index, One);
219 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
221 std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
222 CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
223 Binding, GEPIndices, ArraySubsExprLoc);
237 for (uint64_t I = 0; I < ArraySize; I++) {
239 Index = CGF.
Builder.CreateAdd(Index, One);
240 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
246 CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
247 CGF.
CGM, ResourceDecl, Range, Index, ResourceName, Binding, Args);
255 callResourceInitMethod(CGF, CreateMethod, Args, ReturnAddress);
265 assert(
T->isHLSLSpecificType() &&
"Not an HLSL specific type!");
268 if (llvm::Type *TargetTy =
269 CGM.getTargetCodeGenInfo().getHLSLType(
CGM,
T, Packoffsets))
272 llvm_unreachable(
"Generic handling of HLSL types is not supported.");
275llvm::Triple::ArchType CGHLSLRuntime::getArch() {
281void CGHLSLRuntime::emitBufferGlobalsAndMetadata(
const HLSLBufferDecl *BufDecl,
282 llvm::GlobalVariable *BufGV) {
286 llvm::Type *BufType = BufGV->getValueType();
287 llvm::Type *BufLayoutType =
295 BufGlobals.push_back(ValueAsMetadata::get(BufGV));
297 const auto *ElemIt = LayoutStruct->element_begin();
307 VarDecl *VD = dyn_cast<VarDecl>(D);
323 "constant buffer decl with non-zero sized type outside of "
324 "hlsl_constant address space");
329 assert(ElemIt != LayoutStruct->element_end() &&
330 "number of elements in layout struct does not match");
331 llvm::Type *LayoutType = *ElemIt++;
337 GlobalVariable *ElemGV =
339 BufGlobals.push_back(ValueAsMetadata::get(ElemGV));
341 assert(ElemIt == LayoutStruct->element_end() &&
342 "number of elements in layout struct does not match");
346 .getOrInsertNamedMetadata(
"hlsl.cbs")
347 ->addOperand(MDNode::get(Ctx, BufGlobals));
351static const clang::HLSLAttributedResourceType *
356 HLSLAttributedResourceType::Attributes(ResourceClass::CBuffer));
375 assert(Layout.empty() &&
"expected empty vector for layout");
382 VarDecl *VD = dyn_cast<VarDecl>(D);
387 Layout.push_back(-1);
393 if (
auto *POA = dyn_cast<HLSLPackOffsetAttr>(
Attr)) {
394 Offset = POA->getOffsetInBytes();
397 auto *RBA = dyn_cast<HLSLResourceBindingAttr>(
Attr);
399 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
400 Offset = RBA->getSlotNumber() * CBufferRowSizeInBytes;
404 Layout.push_back(Offset);
411 assert(BufDecl->
isCBuffer() &&
"tbuffer codegen is not supported yet");
414 const clang::HLSLAttributedResourceType *ResHandleTy =
418 if (ResHandleTy->getContainedType()->getAsCXXRecordDecl()->isEmpty())
426 llvm::TargetExtType *TargetTy =
429 llvm::GlobalVariable *BufGV =
new GlobalVariable(
431 GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy),
432 llvm::formatv(
"{0}{1}", BufDecl->
getName(),
434 GlobalValue::NotThreadLocal);
435 CGM.getModule().insertGlobalVariable(BufGV);
438 emitBufferGlobalsAndMetadata(BufDecl, BufGV);
441 initializeBufferFromBinding(BufDecl, BufGV);
446 llvm::Module &M =
CGM.getModule();
447 Triple
T(M.getTargetTriple());
450 if (
T.getEnvironment() != Triple::EnvironmentType::RootSignature)
453 addRootSignatureMD(SignatureDecl->
getVersion(),
459 const auto Entry = LayoutTypes.find(StructType);
460 if (Entry != LayoutTypes.end())
461 return Entry->getSecond();
466 llvm::TargetExtType *LayoutTy) {
468 "layout type for this struct already exist");
469 LayoutTypes[StructType] = LayoutTy;
473 auto &TargetOpts =
CGM.getTarget().getTargetOpts();
474 auto &CodeGenOpts =
CGM.getCodeGenOpts();
475 auto &LangOpts =
CGM.getLangOpts();
476 llvm::Module &M =
CGM.getModule();
477 Triple
T(M.getTargetTriple());
478 if (
T.getArch() == Triple::ArchType::dxil)
479 addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
480 if (CodeGenOpts.ResMayAlias)
481 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.resmayalias", 1);
486 if (LangOpts.NativeHalfType)
487 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.nativelowprec",
495 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
496 assert(ShaderAttr &&
"All entry functions must have a HLSLShaderAttr");
497 const StringRef ShaderAttrKindStr =
"hlsl.shader";
498 Fn->addFnAttr(ShaderAttrKindStr,
499 llvm::Triple::getEnvironmentTypeName(ShaderAttr->getType()));
500 if (HLSLNumThreadsAttr *NumThreadsAttr = FD->
getAttr<HLSLNumThreadsAttr>()) {
501 const StringRef NumThreadsKindStr =
"hlsl.numthreads";
502 std::string NumThreadsStr =
503 formatv(
"{0},{1},{2}", NumThreadsAttr->getX(), NumThreadsAttr->getY(),
504 NumThreadsAttr->getZ());
505 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
507 if (HLSLWaveSizeAttr *WaveSizeAttr = FD->
getAttr<HLSLWaveSizeAttr>()) {
508 const StringRef WaveSizeKindStr =
"hlsl.wavesize";
509 std::string WaveSizeStr =
510 formatv(
"{0},{1},{2}", WaveSizeAttr->getMin(), WaveSizeAttr->getMax(),
511 WaveSizeAttr->getPreferred());
512 Fn->addFnAttr(WaveSizeKindStr, WaveSizeStr);
519 if (
CGM.getCodeGenOpts().OptimizationLevel == 0)
520 Fn->addFnAttr(llvm::Attribute::OptimizeNone);
521 Fn->addFnAttr(llvm::Attribute::NoInline);
523 if (
CGM.getLangOpts().HLSLSpvEnableMaximalReconvergence) {
524 Fn->addFnAttr(
"enable-maximal-reconvergence",
"true");
529 if (
const auto *VT = dyn_cast<FixedVectorType>(Ty)) {
530 Value *Result = PoisonValue::get(Ty);
531 for (
unsigned I = 0; I < VT->getNumElements(); ++I) {
532 Value *Elt = B.CreateCall(F, {B.getInt32(I)});
533 Result = B.CreateInsertElement(Result, Elt, I);
537 return B.CreateCall(F, {B.getInt32(0)});
542 LLVMContext &Ctx = GV->getContext();
543 IRBuilder<> B(GV->getContext());
544 MDNode *Operands = MDNode::get(
546 {ConstantAsMetadata::get(B.getInt32( 11)),
547 ConstantAsMetadata::get(B.getInt32(BuiltIn))});
548 MDNode *Decoration = MDNode::get(Ctx, {Operands});
549 GV->addMetadata(
"spirv.Decorations", *Decoration);
553 llvm::Type *Ty,
const Twine &Name,
554 unsigned BuiltInID) {
555 auto *GV =
new llvm::GlobalVariable(
556 M, Ty,
true, llvm::GlobalValue::ExternalLinkage,
557 nullptr, Name,
nullptr,
558 llvm::GlobalVariable::GeneralDynamicTLSModel,
561 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
562 return B.CreateLoad(Ty, GV);
567 Attr *Semantic, std::optional<unsigned> Index) {
569 llvm::Function *GroupIndex =
570 CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
571 return B.CreateCall(FunctionCallee(GroupIndex));
575 llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
576 llvm::Function *ThreadIDIntrinsic =
577 llvm::Intrinsic::isOverloaded(IntrinID)
578 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
579 :
CGM.getIntrinsic(IntrinID);
584 llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
585 llvm::Function *GroupThreadIDIntrinsic =
586 llvm::Intrinsic::isOverloaded(IntrinID)
587 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
588 :
CGM.getIntrinsic(IntrinID);
593 llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
594 llvm::Function *GroupIDIntrinsic =
595 llvm::Intrinsic::isOverloaded(IntrinID)
596 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
597 :
CGM.getIntrinsic(IntrinID);
601 if (HLSLSV_PositionAttr *S = dyn_cast<HLSLSV_PositionAttr>(Semantic)) {
602 if (
CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
604 S->getAttrName()->getName(),
608 llvm_unreachable(
"non-handled system semantic. FIXME.");
618 if (Item->getTargetDecl() ==
Decl) {
626 std::optional<unsigned> Index = std::nullopt;
640 ST->getNumElements());
644 for (
unsigned I = 0; I < ST->getNumElements(); ++I) {
645 llvm::Value *ChildValue =
659 if (
Type->isStructTy())
665 llvm::Function *Fn) {
666 llvm::Module &M =
CGM.getModule();
667 llvm::LLVMContext &Ctx = M.getContext();
668 auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
false);
670 Function::Create(EntryTy, Function::ExternalLinkage, FD->
getName(), &M);
674 AttributeList NewAttrs = AttributeList::get(Ctx, AttributeList::FunctionIndex,
675 Fn->getAttributes().getFnAttrs());
676 EntryFn->setAttributes(NewAttrs);
680 Fn->setLinkage(GlobalValue::InternalLinkage);
682 BasicBlock *BB = BasicBlock::Create(Ctx,
"entry", EntryFn);
687 if (
CGM.shouldEmitConvergenceTokens()) {
688 assert(EntryFn->isConvergent());
690 B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {});
691 llvm::Value *bundleArgs[] = {I};
692 OB.emplace_back(
"convergencectrl", bundleArgs);
697 unsigned SRetOffset = 0;
698 for (
const auto &Param : Fn->args()) {
699 if (Param.hasStructRetAttr()) {
703 Args.emplace_back(PoisonValue::get(Param.getType()));
708 llvm::Value *SemanticValue =
nullptr;
709 if ([[maybe_unused]] HLSLParamModifierAttr *MA =
710 PD->
getAttr<HLSLParamModifierAttr>()) {
711 llvm_unreachable(
"Not handled yet");
713 llvm::Type *ParamType =
714 Param.hasByValAttr() ? Param.getParamByValType() : Param.getType();
718 if (Param.hasByValAttr()) {
719 llvm::Value *Var = B.CreateAlloca(Param.getParamByValType());
720 B.CreateStore(SemanticValue, Var);
725 assert(SemanticValue);
726 Args.push_back(SemanticValue);
729 CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
730 CI->setCallingConv(Fn->getCallingConv());
737 if (
const auto *RSAttr = dyn_cast<RootSignatureAttr>(
Attr)) {
738 auto *RSDecl = RSAttr->getSignatureDecl();
739 addRootSignatureMD(RSDecl->getVersion(), RSDecl->getRootElements(),
748 M.getNamedGlobal(CtorOrDtor ?
"llvm.global_ctors" :
"llvm.global_dtors");
751 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
758 for (
const auto &Ctor : CA->operands()) {
764 "HLSL doesn't support setting priority for global ctors.");
766 "HLSL doesn't support COMDat for global ctors.");
772 llvm::Module &M =
CGM.getModule();
781 for (
auto &F : M.functions()) {
782 if (!F.hasFnAttribute(
"hlsl.shader"))
785 Instruction *IP = &*F.getEntryBlock().begin();
788 llvm::Value *bundleArgs[] = {
Token};
789 OB.emplace_back(
"convergencectrl", bundleArgs);
790 IP =
Token->getNextNode();
793 for (
auto *Fn : CtorFns) {
794 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
795 CI->setCallingConv(Fn->getCallingConv());
799 B.SetInsertPoint(F.back().getTerminator());
800 for (
auto *Fn : DtorFns) {
801 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
802 CI->setCallingConv(Fn->getCallingConv());
808 Triple
T(M.getTargetTriple());
809 if (
T.getEnvironment() != Triple::EnvironmentType::Library) {
810 if (
auto *GV = M.getNamedGlobal(
"llvm.global_ctors"))
811 GV->eraseFromParent();
812 if (
auto *GV = M.getNamedGlobal(
"llvm.global_dtors"))
813 GV->eraseFromParent();
818 Intrinsic::ID IntrID,
822 llvm::Function *InitResFunc = llvm::Function::Create(
823 llvm::FunctionType::get(CGM.
VoidTy,
false),
824 llvm::GlobalValue::InternalLinkage,
825 (
"_init_buffer_" + GV->getName()).str(), CGM.
getModule());
826 InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
828 llvm::BasicBlock *EntryBB =
829 llvm::BasicBlock::Create(Ctx,
"entry", InitResFunc);
831 const DataLayout &DL = CGM.
getModule().getDataLayout();
832 Builder.SetInsertPoint(EntryBB);
835 llvm::Type *HandleTy = GV->getValueType();
836 assert(HandleTy->isTargetExtTy() &&
"unexpected type of the buffer global");
838 llvm::Value *CreateHandle = Builder.CreateIntrinsic(
839 HandleTy, IntrID, Args,
nullptr,
840 Twine(GV->getName()).concat(
"_h"));
842 llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
843 Builder.CreateAlignedStore(CreateHandle, HandleRef,
844 HandleRef->getPointerAlignment(DL));
845 Builder.CreateRetVoid();
850void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
851 llvm::GlobalVariable *GV) {
852 ResourceBindingAttrs Binding(BufDecl);
854 "cbuffer/tbuffer should always have resource binding attribute");
856 auto *Index = llvm::ConstantInt::get(
CGM.IntTy, 0);
857 auto *RangeSize = llvm::ConstantInt::get(
CGM.IntTy, 1);
858 auto *Space = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSpace());
863 llvm::Intrinsic::ID IntrinsicID =
864 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
865 auto *RegSlot = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSlot());
866 SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
870 llvm::Intrinsic::ID IntrinsicID =
871 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
874 SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
880 llvm::GlobalVariable *GV) {
881 if (
auto Attr = VD->
getAttr<HLSLVkExtBuiltinInputAttr>())
886 if (!
CGM.shouldEmitConvergenceTokens())
890 for (
auto I = BB.begin(); I != E; ++I) {
891 auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
892 if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
896 llvm_unreachable(
"Convergence token should have been emitted.");
933 for (
auto *OVE : Visitor.
OVEs) {
936 if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
938 OpaqueValueMappingData::bind(CGF, OVE, LV);
941 OpaqueValueMappingData::bind(CGF, OVE, RV);
950 "expected resource array subscript expression");
956 dyn_cast_or_null<VarDecl>(getArrayDecl(ArraySubsExpr));
964 "expected array of resource classes");
970 Value *Index =
nullptr;
972 while (ASE !=
nullptr) {
974 if (
const auto *ArrayTy =
976 Value *Multiplier = llvm::ConstantInt::get(
978 SubIndex = CGF.
Builder.CreateMul(SubIndex, Multiplier);
980 Index = Index ? CGF.
Builder.CreateAdd(Index, SubIndex) : SubIndex;
988 "resource array must have a binding attribute");
1009 llvm::Value *Range =
1010 llvm::ConstantInt::get(
CGM.IntTy, getTotalArraySize(AST, ResArrayTy));
1014 if (ResultTy == ResourceTy) {
1016 CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
1018 ArrayDecl->
getName(), Binding, Args);
1024 return std::nullopt;
1026 callResourceInitMethod(CGF, CreateMethod, Args, ValueSlot.getAddress());
1033 std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
1035 ArrayDecl->
getName(), Binding, {llvm::ConstantInt::get(CGM.IntTy, 0)},
1038 return std::nullopt;
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)
llvm::MachO::Record Record
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 static or instance method of a struct/union/class.
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
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.
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Abstract information about a function or function prototype.
All available information about a concrete callee.
CGFunctionInfo - Class to encapsulate the information about a function definition.
llvm::Instruction * getConvergenceToken(llvm::BasicBlock &BB)
void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn)
llvm::Value * handleStructSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, const clang::DeclaratorDecl *Decl)
void addHLSLBufferLayoutType(const RecordType *LayoutStructTy, llvm::TargetExtType *LayoutTy)
llvm::Value * emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, Attr *Semantic, std::optional< unsigned > Index)
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn)
void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var)
llvm::TargetExtType * getHLSLBufferLayoutType(const RecordType *LayoutStructTy)
llvm::Value * handleScalarSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, const clang::DeclaratorDecl *Decl)
llvm::Type * convertHLSLSpecificType(const Type *T, SmallVector< int32_t > *Packoffsets=nullptr)
llvm::Value * handleSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type, const clang::DeclaratorDecl *Decl)
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...
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
bool EmitLifetimeStart(llvm::Value *Addr)
Emit a lifetime.begin marker if some criteria are satisfied.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
ASTContext & getContext() const
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.
llvm::Module & getModule() const
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
void AddCXXGlobalInit(llvm::Function *F)
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
ASTContext & getContext() const
llvm::LLVMContext & getLLVMContext()
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.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
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
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
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
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Represents a ValueDecl that came out of a declarator.
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 member of a struct/union/class.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Represents a prototype with parameter type info, e.g.
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
bool isSemanticIndexExplicit() 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.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
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.
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...
bool isHLSLResourceRecord() const
const T * getAs() const
Member-template getAs<specific type>'.
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.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
llvm::IntegerType * IntTy
int
unsigned getImplicitOrderID() const
bool hasCounterImplicitOrderID() const
unsigned getSpace() const
unsigned getCounterImplicitOrderID() const