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);
525 if (
const auto *VT = dyn_cast<FixedVectorType>(Ty)) {
526 Value *Result = PoisonValue::get(Ty);
527 for (
unsigned I = 0; I < VT->getNumElements(); ++I) {
528 Value *Elt = B.CreateCall(F, {B.getInt32(I)});
529 Result = B.CreateInsertElement(Result, Elt, I);
533 return B.CreateCall(F, {B.getInt32(0)});
538 LLVMContext &Ctx = GV->getContext();
539 IRBuilder<> B(GV->getContext());
540 MDNode *Operands = MDNode::get(
542 {ConstantAsMetadata::get(B.getInt32( 11)),
543 ConstantAsMetadata::get(B.getInt32(BuiltIn))});
544 MDNode *Decoration = MDNode::get(Ctx, {Operands});
545 GV->addMetadata(
"spirv.Decorations", *Decoration);
549 llvm::Type *Ty,
const Twine &Name,
550 unsigned BuiltInID) {
551 auto *GV =
new llvm::GlobalVariable(
552 M, Ty,
true, llvm::GlobalValue::ExternalLinkage,
553 nullptr, Name,
nullptr,
554 llvm::GlobalVariable::GeneralDynamicTLSModel,
557 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
558 return B.CreateLoad(Ty, GV);
566 llvm::Function *GroupIndex =
567 CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic());
568 return B.CreateCall(FunctionCallee(GroupIndex));
572 llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic();
573 llvm::Function *ThreadIDIntrinsic =
574 llvm::Intrinsic::isOverloaded(IntrinID)
575 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
576 :
CGM.getIntrinsic(IntrinID);
581 llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic();
582 llvm::Function *GroupThreadIDIntrinsic =
583 llvm::Intrinsic::isOverloaded(IntrinID)
584 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
585 :
CGM.getIntrinsic(IntrinID);
590 llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic();
591 llvm::Function *GroupIDIntrinsic =
592 llvm::Intrinsic::isOverloaded(IntrinID)
593 ?
CGM.getIntrinsic(IntrinID, {
CGM.Int32Ty})
594 :
CGM.getIntrinsic(IntrinID);
598 if (HLSLSV_PositionAttr *S =
599 dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.
Semantic)) {
600 if (
CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel)
602 S->getAttrName()->getName(),
606 llvm_unreachable(
"non-handled system semantic. FIXME.");
617 CGM.getDiags().Report(
Decl->getInnerLocStart(),
618 diag::err_hlsl_semantic_missing);
631 assert(!
Type->isStructTy());
636 llvm::Function *Fn) {
637 llvm::Module &M =
CGM.getModule();
638 llvm::LLVMContext &Ctx = M.getContext();
639 auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
false);
641 Function::Create(EntryTy, Function::ExternalLinkage, FD->
getName(), &M);
645 AttributeList NewAttrs = AttributeList::get(Ctx, AttributeList::FunctionIndex,
646 Fn->getAttributes().getFnAttrs());
647 EntryFn->setAttributes(NewAttrs);
651 Fn->setLinkage(GlobalValue::InternalLinkage);
653 BasicBlock *BB = BasicBlock::Create(Ctx,
"entry", EntryFn);
658 if (
CGM.shouldEmitConvergenceTokens()) {
659 assert(EntryFn->isConvergent());
661 B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {});
662 llvm::Value *bundleArgs[] = {I};
663 OB.emplace_back(
"convergencectrl", bundleArgs);
668 unsigned SRetOffset = 0;
669 for (
const auto &Param : Fn->args()) {
670 if (Param.hasStructRetAttr()) {
674 Args.emplace_back(PoisonValue::get(Param.getType()));
683 CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
684 CI->setCallingConv(Fn->getCallingConv());
691 if (
const auto *RSAttr = dyn_cast<RootSignatureAttr>(
Attr)) {
692 auto *RSDecl = RSAttr->getSignatureDecl();
693 addRootSignatureMD(RSDecl->getVersion(), RSDecl->getRootElements(),
702 M.getNamedGlobal(CtorOrDtor ?
"llvm.global_ctors" :
"llvm.global_dtors");
705 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
712 for (
const auto &Ctor : CA->operands()) {
718 "HLSL doesn't support setting priority for global ctors.");
720 "HLSL doesn't support COMDat for global ctors.");
726 llvm::Module &M =
CGM.getModule();
735 for (
auto &F : M.functions()) {
736 if (!F.hasFnAttribute(
"hlsl.shader"))
739 Instruction *IP = &*F.getEntryBlock().begin();
742 llvm::Value *bundleArgs[] = {
Token};
743 OB.emplace_back(
"convergencectrl", bundleArgs);
744 IP =
Token->getNextNode();
747 for (
auto *Fn : CtorFns) {
748 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
749 CI->setCallingConv(Fn->getCallingConv());
753 B.SetInsertPoint(F.back().getTerminator());
754 for (
auto *Fn : DtorFns) {
755 auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
756 CI->setCallingConv(Fn->getCallingConv());
762 Triple
T(M.getTargetTriple());
763 if (
T.getEnvironment() != Triple::EnvironmentType::Library) {
764 if (
auto *GV = M.getNamedGlobal(
"llvm.global_ctors"))
765 GV->eraseFromParent();
766 if (
auto *GV = M.getNamedGlobal(
"llvm.global_dtors"))
767 GV->eraseFromParent();
772 Intrinsic::ID IntrID,
776 llvm::Function *InitResFunc = llvm::Function::Create(
777 llvm::FunctionType::get(CGM.
VoidTy,
false),
778 llvm::GlobalValue::InternalLinkage,
779 (
"_init_buffer_" + GV->getName()).str(), CGM.
getModule());
780 InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
782 llvm::BasicBlock *EntryBB =
783 llvm::BasicBlock::Create(Ctx,
"entry", InitResFunc);
785 const DataLayout &DL = CGM.
getModule().getDataLayout();
786 Builder.SetInsertPoint(EntryBB);
789 llvm::Type *HandleTy = GV->getValueType();
790 assert(HandleTy->isTargetExtTy() &&
"unexpected type of the buffer global");
792 llvm::Value *CreateHandle = Builder.CreateIntrinsic(
793 HandleTy, IntrID, Args,
nullptr,
794 Twine(GV->getName()).concat(
"_h"));
796 llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
797 Builder.CreateAlignedStore(CreateHandle, HandleRef,
798 HandleRef->getPointerAlignment(DL));
799 Builder.CreateRetVoid();
804void CGHLSLRuntime::initializeBufferFromBinding(
const HLSLBufferDecl *BufDecl,
805 llvm::GlobalVariable *GV) {
806 ResourceBindingAttrs Binding(BufDecl);
808 "cbuffer/tbuffer should always have resource binding attribute");
810 auto *Index = llvm::ConstantInt::get(
CGM.IntTy, 0);
811 auto *RangeSize = llvm::ConstantInt::get(
CGM.IntTy, 1);
812 auto *Space = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSpace());
817 llvm::Intrinsic::ID IntrinsicID =
818 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
819 auto *RegSlot = llvm::ConstantInt::get(
CGM.IntTy, Binding.
getSlot());
820 SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
824 llvm::Intrinsic::ID IntrinsicID =
825 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
828 SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
834 llvm::GlobalVariable *GV) {
835 if (
auto Attr = VD->
getAttr<HLSLVkExtBuiltinInputAttr>())
840 if (!
CGM.shouldEmitConvergenceTokens())
844 for (
auto I = BB.begin(); I != E; ++I) {
845 auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
846 if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
850 llvm_unreachable(
"Convergence token should have been emitted.");
887 for (
auto *OVE : Visitor.
OVEs) {
890 if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
892 OpaqueValueMappingData::bind(CGF, OVE, LV);
895 OpaqueValueMappingData::bind(CGF, OVE, RV);
904 "expected resource array subscript expression");
910 dyn_cast_or_null<VarDecl>(getArrayDecl(ArraySubsExpr));
918 "expected array of resource classes");
924 Value *Index =
nullptr;
926 while (ASE !=
nullptr) {
928 if (
const auto *ArrayTy =
930 Value *Multiplier = llvm::ConstantInt::get(
932 SubIndex = CGF.
Builder.CreateMul(SubIndex, Multiplier);
934 Index = Index ? CGF.
Builder.CreateAdd(Index, SubIndex) : SubIndex;
942 "resource array must have a binding attribute");
964 llvm::ConstantInt::get(
CGM.IntTy, getTotalArraySize(AST, ResArrayTy));
968 if (ResultTy == ResourceTy) {
970 CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
972 ArrayDecl->
getName(), Binding, Args);
980 callResourceInitMethod(CGF, CreateMethod, Args, ValueSlot.getAddress());
987 std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
989 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
bool hasCounterImplicitOrderID() const
unsigned getSpace() const
unsigned getCounterImplicitOrderID() const