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());
148 CreateMethod = lookupMethod(ResourceDecl,
"__createFromBinding",
SC_Static);
155 lookupMethod(ResourceDecl,
"__createFromImplicitBinding",
SC_Static);
175 CGF.
EmitCall(FnInfo, Callee, ReturnValue, Args,
nullptr);
183static std::optional<llvm::Value *> initializeLocalResourceArray(
186 llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
191 llvm::IntegerType *IntTy = CGF.
CGM.
IntTy;
192 llvm::Value *Index = StartIndex;
193 llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
201 GEPIndices.push_back(llvm::ConstantInt::get(IntTy, 0));
206 for (uint64_t I = 0; I < ArraySize; I++) {
208 Index = CGF.
Builder.CreateAdd(Index, One);
209 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
211 std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
212 CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
213 Binding, GEPIndices, ArraySubsExprLoc);
227 for (uint64_t I = 0; I < ArraySize; I++) {
229 Index = CGF.
Builder.CreateAdd(Index, One);
230 GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
236 CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
237 CGF.
CGM, ResourceDecl, Range, Index, ResourceName, Binding, Args);
245 callResourceInitMethod(CGF, CreateMethod, Args, ReturnAddress);
255 assert(
T->isHLSLSpecificType() &&
"Not an HLSL specific type!");
258 if (llvm::Type *TargetTy =
259 CGM.getTargetCodeGenInfo().getHLSLType(
CGM,
T, Packoffsets))
262 llvm_unreachable(
"Generic handling of HLSL types is not supported.");
265llvm::Triple::ArchType CGHLSLRuntime::getArch() {
271void CGHLSLRuntime::emitBufferGlobalsAndMetadata(
const HLSLBufferDecl *BufDecl,
272 llvm::GlobalVariable *BufGV) {
276 llvm::Type *BufType = BufGV->getValueType();
277 llvm::Type *BufLayoutType =
285 BufGlobals.push_back(ValueAsMetadata::get(BufGV));
287 const auto *ElemIt = LayoutStruct->element_begin();
297 VarDecl *VD = dyn_cast<VarDecl>(D);
313 "constant buffer decl with non-zero sized type outside of "
314 "hlsl_constant address space");
319 assert(ElemIt != LayoutStruct->element_end() &&
320 "number of elements in layout struct does not match");
321 llvm::Type *LayoutType = *ElemIt++;
327 GlobalVariable *ElemGV =
329 BufGlobals.push_back(ValueAsMetadata::get(ElemGV));
331 assert(ElemIt == LayoutStruct->element_end() &&
332 "number of elements in layout struct does not match");
336 .getOrInsertNamedMetadata(
"hlsl.cbs")
337 ->addOperand(MDNode::get(Ctx, BufGlobals));
341static const clang::HLSLAttributedResourceType *
346 HLSLAttributedResourceType::Attributes(ResourceClass::CBuffer));
365 assert(Layout.empty() &&
"expected empty vector for layout");
372 VarDecl *VD = dyn_cast<VarDecl>(D);
377 Layout.push_back(-1);
383 if (
auto *POA = dyn_cast<HLSLPackOffsetAttr>(
Attr)) {
384 Offset = POA->getOffsetInBytes();
387 auto *RBA = dyn_cast<HLSLResourceBindingAttr>(
Attr);
389 RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
390 Offset = RBA->getSlotNumber() * CBufferRowSizeInBytes;
394 Layout.push_back(Offset);
401 assert(BufDecl->
isCBuffer() &&
"tbuffer codegen is not supported yet");
404 const clang::HLSLAttributedResourceType *ResHandleTy =
408 if (ResHandleTy->getContainedType()->getAsCXXRecordDecl()->isEmpty())
416 llvm::TargetExtType *TargetTy =
419 llvm::GlobalVariable *BufGV =
new GlobalVariable(
421 GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy),
422 llvm::formatv(
"{0}{1}", BufDecl->
getName(),
424 GlobalValue::NotThreadLocal);
425 CGM.getModule().insertGlobalVariable(BufGV);
428 emitBufferGlobalsAndMetadata(BufDecl, BufGV);
431 initializeBufferFromBinding(BufDecl, BufGV);
436 llvm::Module &M =
CGM.getModule();
437 Triple
T(M.getTargetTriple());
440 if (
T.getEnvironment() != Triple::EnvironmentType::RootSignature)
443 addRootSignatureMD(SignatureDecl->
getVersion(),
449 const auto Entry = LayoutTypes.find(StructType);
450 if (Entry != LayoutTypes.end())
451 return Entry->getSecond();
456 llvm::TargetExtType *LayoutTy) {
458 "layout type for this struct already exist");
459 LayoutTypes[StructType] = LayoutTy;
463 auto &TargetOpts =
CGM.getTarget().getTargetOpts();
464 auto &CodeGenOpts =
CGM.getCodeGenOpts();
465 auto &LangOpts =
CGM.getLangOpts();
466 llvm::Module &M =
CGM.getModule();
467 Triple
T(M.getTargetTriple());
468 if (
T.getArch() == Triple::ArchType::dxil)
469 addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
470 if (CodeGenOpts.ResMayAlias)
471 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.resmayalias", 1);
476 if (LangOpts.NativeHalfType)
477 M.setModuleFlag(llvm::Module::ModFlagBehavior::Error,
"dx.nativelowprec",
485 const auto *ShaderAttr = FD->
getAttr<HLSLShaderAttr>();
486 assert(ShaderAttr &&
"All entry functions must have a HLSLShaderAttr");
487 const StringRef ShaderAttrKindStr =
"hlsl.shader";
488 Fn->addFnAttr(ShaderAttrKindStr,
489 llvm::Triple::getEnvironmentTypeName(ShaderAttr->getType()));
490 if (HLSLNumThreadsAttr *NumThreadsAttr = FD->
getAttr<HLSLNumThreadsAttr>()) {
491 const StringRef NumThreadsKindStr =
"hlsl.numthreads";
492 std::string NumThreadsStr =
493 formatv(
"{0},{1},{2}", NumThreadsAttr->getX(), NumThreadsAttr->getY(),
494 NumThreadsAttr->getZ());
495 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
497 if (HLSLWaveSizeAttr *WaveSizeAttr = FD->
getAttr<HLSLWaveSizeAttr>()) {
498 const StringRef WaveSizeKindStr =
"hlsl.wavesize";
499 std::string WaveSizeStr =
500 formatv(
"{0},{1},{2}", WaveSizeAttr->getMin(), WaveSizeAttr->getMax(),
501 WaveSizeAttr->getPreferred());
502 Fn->addFnAttr(WaveSizeKindStr, WaveSizeStr);
509 if (
CGM.getCodeGenOpts().OptimizationLevel == 0)
510 Fn->addFnAttr(llvm::Attribute::OptimizeNone);
511 Fn->addFnAttr(llvm::Attribute::NoInline);
515 if (
const auto *VT = dyn_cast<FixedVectorType>(Ty)) {
516 Value *Result = PoisonValue::get(Ty);
517 for (
unsigned I = 0; I < VT->getNumElements(); ++I) {
518 Value *Elt = B.CreateCall(F, {B.getInt32(I)});
519 Result = B.CreateInsertElement(Result, Elt, I);
523 return B.CreateCall(F, {B.getInt32(0)});
528 LLVMContext &Ctx = GV->getContext();
529 IRBuilder<> B(GV->getContext());
530 MDNode *Operands = MDNode::get(
532 {ConstantAsMetadata::get(B.getInt32( 11)),
533 ConstantAsMetadata::get(B.getInt32(BuiltIn))});
534 MDNode *Decoration = MDNode::get(Ctx, {Operands});
535 GV->addMetadata(
"spirv.Decorations", *Decoration);
539 llvm::Type *Ty,
const Twine &Name,
540 unsigned BuiltInID) {
541 auto *GV =
new llvm::GlobalVariable(
542 M, Ty,
true, llvm::GlobalValue::ExternalLinkage,
543 nullptr, Name,
nullptr,
544 llvm::GlobalVariable::GeneralDynamicTLSModel,
547 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
548 return B.CreateLoad(Ty, GV);
556 llvm::Function *GroupIndex =
557 CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
558 return B.CreateCall(FunctionCallee(GroupIndex));
562 llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
563 llvm::Function *ThreadIDIntrinsic =
564 llvm::Intrinsic::isOverloaded(IntrinID)
565 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
566 :
CGM.getIntrinsic(IntrinID);
571 llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
572 llvm::Function *GroupThreadIDIntrinsic =
573 llvm::Intrinsic::isOverloaded(IntrinID)
574 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
575 :
CGM.getIntrinsic(IntrinID);
580 llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
581 llvm::Function *GroupIDIntrinsic =
582 llvm::Intrinsic::isOverloaded(IntrinID)
583 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
584 :
CGM.getIntrinsic(IntrinID);
588 if (HLSLSV_PositionAttr *S =
589 dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.
Semantic)) {
590 if (
CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
592 S->getAttrName()->getName(),
596 llvm_unreachable(
"non-handled system semantic. FIXME.");
607 CGM.getDiags().Report(
Decl->getInnerLocStart(),
608 diag::err_hlsl_semantic_missing);
621 assert(!
Type->isStructTy());
626 llvm::Function *Fn) {
627 llvm::Module &M =
CGM.getModule();
628 llvm::LLVMContext &Ctx = M.getContext();
629 auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
false);
631 Function::Create(EntryTy, Function::ExternalLinkage, FD->
getName(), &M);
635 AttributeList NewAttrs = AttributeList::get(Ctx, AttributeList::FunctionIndex,
636 Fn->getAttributes().getFnAttrs());
637 EntryFn->setAttributes(NewAttrs);
641 Fn->setLinkage(GlobalValue::InternalLinkage);
643 BasicBlock *BB = BasicBlock::Create(Ctx,
"entry", EntryFn);
648 if (
CGM.shouldEmitConvergenceTokens()) {
649 assert(EntryFn->isConvergent());
651 B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {});
652 llvm::Value *bundleArgs[] = {I};
653 OB.emplace_back(
"convergencectrl", bundleArgs);
658 unsigned SRetOffset = 0;
659 for (
const auto &Param : Fn->args()) {
660 if (Param.hasStructRetAttr()) {
664 Args.emplace_back(PoisonValue::get(Param.getType()));
673 CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
674 CI->setCallingConv(Fn->getCallingConv());
681 if (
const auto *RSAttr = dyn_cast<RootSignatureAttr>(
Attr)) {
682 auto *RSDecl = RSAttr->getSignatureDecl();
683 addRootSignatureMD(RSDecl->getVersion(), RSDecl->getRootElements(),
692 M.getNamedGlobal(CtorOrDtor ?
"llvm.global_ctors" :
"llvm.global_dtors");
695 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
702 for (
const auto &Ctor : CA->operands()) {
708 "HLSL doesn't support setting priority for global ctors.");
710 "HLSL doesn't support COMDat for global ctors.");
716 llvm::Module &M =
CGM.getModule();
725 for (
auto &F : M.functions()) {
726 if (!F.hasFnAttribute(
"hlsl.shader"))
729 Instruction *IP = &*F.getEntryBlock().begin();
732 llvm::Value *bundleArgs[] = {
Token};
733 OB.emplace_back(
"convergencectrl", bundleArgs);
734 IP =
Token->getNextNode();
737 for (
auto *Fn : CtorFns) {
738 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
739 CI->setCallingConv(Fn->getCallingConv());
743 B.SetInsertPoint(F.back().getTerminator());
744 for (
auto *Fn : DtorFns) {
745 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
746 CI->setCallingConv(Fn->getCallingConv());
752 Triple
T(M.getTargetTriple());
753 if (
T.getEnvironment() != Triple::EnvironmentType::Library) {
754 if (
auto *GV = M.getNamedGlobal(
"llvm.global_ctors"))
755 GV->eraseFromParent();
756 if (
auto *GV = M.getNamedGlobal(
"llvm.global_dtors"))
757 GV->eraseFromParent();
762 Intrinsic::ID IntrID,
766 llvm::Function *InitResFunc = llvm::Function::Create(
767 llvm::FunctionType::get(CGM.
VoidTy,
false),
768 llvm::GlobalValue::InternalLinkage,
769 (
"_init_buffer_" + GV->getName()).str(), CGM.
getModule());
770 InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
772 llvm::BasicBlock *EntryBB =
773 llvm::BasicBlock::Create(Ctx,
"entry", InitResFunc);
775 const DataLayout &DL = CGM.
getModule().getDataLayout();
776 Builder.SetInsertPoint(EntryBB);
779 llvm::Type *HandleTy = GV->getValueType();
780 assert(HandleTy->isTargetExtTy() &&
"unexpected type of the buffer global");
782 llvm::Value *CreateHandle = Builder.CreateIntrinsic(
783 HandleTy, IntrID, Args,
nullptr,
784 Twine(GV->getName()).concat(
"_h"));
786 llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
787 Builder.CreateAlignedStore(CreateHandle, HandleRef,
788 HandleRef->getPointerAlignment(DL));
789 Builder.CreateRetVoid();
794void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
795 llvm::GlobalVariable *GV) {
796 ResourceBindingAttrs Binding(BufDecl);
798 "cbuffer/tbuffer should always have resource binding attribute");
800 auto *Index = llvm::ConstantInt::get(
CGM.IntTy, 0);
801 auto *RangeSize = llvm::ConstantInt::get(
CGM.IntTy, 1);
802 auto *Space = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSpace());
807 llvm::Intrinsic::ID IntrinsicID =
808 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
809 auto *RegSlot = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSlot());
810 SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
814 llvm::Intrinsic::ID IntrinsicID =
815 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
818 SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
824 llvm::GlobalVariable *GV) {
825 if (
auto Attr = VD->
getAttr<HLSLVkExtBuiltinInputAttr>())
830 if (!
CGM.shouldEmitConvergenceTokens())
834 for (
auto I = BB.begin(); I != E; ++I) {
835 auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
836 if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
840 llvm_unreachable(
"Convergence token should have been emitted.");
877 for (
auto *OVE : Visitor.
OVEs) {
880 if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
882 OpaqueValueMappingData::bind(CGF, OVE, LV);
885 OpaqueValueMappingData::bind(CGF, OVE, RV);
894 "expected resource array subscript expression");
900 dyn_cast_or_null<VarDecl>(getArrayDecl(ArraySubsExpr));
908 "expected array of resource classes");
914 Value *Index =
nullptr;
916 while (ASE !=
nullptr) {
918 if (
const auto *ArrayTy =
920 Value *Multiplier = llvm::ConstantInt::get(
922 SubIndex = CGF.
Builder.CreateMul(SubIndex, Multiplier);
924 Index = Index ? CGF.
Builder.CreateAdd(Index, SubIndex) : SubIndex;
932 "resource array must have a binding attribute");
954 llvm::ConstantInt::get(
CGM.IntTy, getTotalArraySize(AST, ResArrayTy));
958 if (ResultTy == ResourceTy) {
960 CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
962 ArrayDecl->
getName(), Binding, Args);
970 callResourceInitMethod(CGF, CreateMethod, Args, ValueSlot.getAddress());
977 std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
979 ArrayDecl->
getName(), Binding, {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)
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 * 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...
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
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 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
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.
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.
clang::HLSLSemanticAttr * Semantic
llvm::IntegerType * IntTy
int
unsigned getImplicitOrderID() const
unsigned getSpace() const