diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "CGCXXABI.h" +#include "CGHLSLRuntime.h" #include "CGObjCRuntime.h" #include "CGOpenMPRuntime.h" #include "CodeGenFunction.h" @@ -808,6 +809,9 @@ EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit); } + if (getLangOpts().HLSL) + CGM.getHLSLRuntime().annotateHLSLResource(D, Addr); + FinishFunction(); } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -15,7 +15,18 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H +#include "clang/Basic/HLSLRuntime.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { +class Value; +class GlobalVariable; +} // namespace llvm namespace clang { +class CallExpr; +class Type; +class VarDecl; namespace CodeGen { @@ -24,11 +35,19 @@ class CGHLSLRuntime { protected: CodeGenModule &CGM; + using ResourceGlobal = + std::pair; + llvm::SmallVector UAVs; public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} virtual ~CGHLSLRuntime() {} + void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV); + void addResourceAnnotations(); + void addResourceAnnotation(llvm::SmallVector &Globals, + llvm::StringRef MDName); + void finishCodeGen(); }; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -20,6 +20,7 @@ using namespace clang; using namespace CodeGen; +using namespace hlsl; using namespace llvm; namespace { @@ -49,4 +50,48 @@ llvm::Module &M = CGM.getModule(); addDxilValVersion(TargetOpts.DxilValidatorVersion, M); + addResourceAnnotations(); +} + +void CGHLSLRuntime::addResourceAnnotation(SmallVector &Globals, + StringRef MDName) { + llvm::Module &M = CGM.getModule(); + auto &Ctx = M.getContext(); + IRBuilder<> B(M.getContext()); + + llvm::SmallVector ResourceMDs; + for (uint32_t Idx = 0; Idx < Globals.size(); ++Idx) { + QualType Ty(Globals[Idx].first->getType()->getPointeeOrArrayElementType(), + 0); + ResourceMDs.push_back( + MDNode::get(Ctx, {ValueAsMetadata::get(Globals[Idx].second), + MDString::get(Ctx, Ty.getAsString()), + ConstantAsMetadata::get(B.getInt32(Idx))})); + } + MDNode *NewMD = MDNode::get(Ctx, ResourceMDs); + M.addModuleFlag(llvm::Module::ModFlagBehavior::AppendUnique, MDName, NewMD); +} + +void CGHLSLRuntime::addResourceAnnotations() { + addResourceAnnotation(UAVs, "hlsl.uavs"); +} + +void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { + const Type *Ty = D->getType()->getPointeeOrArrayElementType(); + if (!Ty) + return; + auto *RD = Ty->getAsCXXRecordDecl(); + if (!RD) + return; + if (!RD->hasAttr()) + return; + HLSLResourceAttr::ResourceClass RC = + Ty->getAsCXXRecordDecl()->getAttr()->getResourceType(); + switch (RC) { + case HLSLResourceAttr::ResourceClass::UAV: + UAVs.push_back(std::make_pair(D, GV)); + return; + default: + llvm_unreachable("Unsupported buffer type!"); + } } diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-annotations.hlsl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +RWBuffer Buffer1; +RWBuffer > BufferArray[4]; + +[numthreads(1,1,1)] +void main() { +} + +// CHECK-DAG: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"hlsl.uavs", ![[UAVList:[0-9]+]]} +// CHECK-DAG: ![[UAVList]] = !{![[Single:[0-9]+]], ![[Array:[0-9]+]]} +// CHECK-DAG: ![[Single]] = !{ptr @"?Buffer1@@3V?$RWBuffer@M@hlsl@@A", !"RWBuffer", i32 0} +// CHECK-DAG: ![[Array]] = !{ptr @"?BufferArray@@3PAV?$RWBuffer@T?$__vector@M$03@__clang@@@hlsl@@A", !"RWBuffer >", i32 1}