[llvm-branch-commits] [DXIL][Analysis] Implement enough of DXILResourceAnalysis for buffers (PR #100699)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/100699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DXIL][Analysis] Implement enough of DXILResourceAnalysis for buffers (PR #100699)
@@ -0,0 +1,126 @@ +; RUN: opt -S -disable-output -passes="print" < %s 2>&1 | FileCheck %s + +@G = external constant <4 x float>, align 4 + +define void @test_typedbuffer() { + ; RWBuffer Buf : register(u5, space3) + %typed0 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) + @llvm.dx.handle.fromBinding.tdx.TypedBuffer_f32_1_0( + i32 3, i32 5, i32 1, i32 0, i1 false) + ; CHECK: Binding for %typed0 + ; CHECK: Symbol: ptr undef + ; CHECK: Name: "" + ; CHECK: Binding: + ; CHECK: Record ID: 0 + ; CHECK: Space: 3 + ; CHECK: Lower Bound: 5 + ; CHECK: Size: 1 + ; CHECK: Class: UAV + ; CHECK: Kind: TypedBuffer + ; CHECK: Globally Coherent: 0 + ; CHECK: HasCounter: 0 + ; CHECK: IsROV: 0 + ; CHECK: Element Type: f32 + ; CHECK: Element Count: 4 + + ; RWBuffer Buf : register(u7, space2) + %typed1 = call target("dx.TypedBuffer", i32, 1, 0, 1) + @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t( + i32 2, i32 7, i32 1, i32 0, i1 false) + ; CHECK: Binding for %typed1 + ; CHECK: Symbol: ptr undef + ; CHECK: Name: "" + ; CHECK: Binding: + ; CHECK: Record ID: 1 + ; CHECK: Space: 2 + ; CHECK: Lower Bound: 7 + ; CHECK: Size: 1 + ; CHECK: Class: UAV + ; CHECK: Kind: TypedBuffer + ; CHECK: Globally Coherent: 0 + ; CHECK: HasCounter: 0 + ; CHECK: IsROV: 0 + ; CHECK: Element Type: i32 + ; CHECK: Element Count: 1 + + ; Buffer Buf[24] : register(t3, space5) + %typed2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0) + @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_0_0t( + i32 2, i32 7, i32 24, i32 0, i1 false) + ; CHECK: Binding for %typed2 hekota wrote: This should probably be `i32 5, i32 3, ..`? https://github.com/llvm/llvm-project/pull/100699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DXIL][Analysis] Implement enough of DXILResourceAnalysis for buffers (PR #100699)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/100699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Implement metadata lowering for resources (PR #104447)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104447 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Add resource handling to the DXIL pretty printer (PR #104448)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/104448 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Add resource handling to the DXIL pretty printer (PR #104448)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104448 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Add resource handling to the DXIL pretty printer (PR #104448)
@@ -10,23 +10,235 @@ #include "DXILResourceAnalysis.h" #include "DirectX.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/PassManager.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" +#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; -static void prettyPrintResources(raw_ostream &OS, +static constexpr StringRef getRCName(dxil::ResourceClass RC) { + switch (RC) { + case dxil::ResourceClass::SRV: +return "SRV"; + case dxil::ResourceClass::UAV: +return "UAV"; + case dxil::ResourceClass::CBuffer: +return "cbuffer"; + case dxil::ResourceClass::Sampler: +return "sampler"; + } + llvm_unreachable("covered switch"); +} + +static constexpr StringRef getRCPrefix(dxil::ResourceClass RC) { + switch (RC) { + case dxil::ResourceClass::SRV: +return "t"; + case dxil::ResourceClass::UAV: +return "u"; + case dxil::ResourceClass::CBuffer: +return "cb"; + case dxil::ResourceClass::Sampler: +return "s"; + } +} + +static constexpr StringRef getFormatName(const dxil::ResourceInfo &RI) { + if (RI.isTyped()) { +switch (RI.getTyped().ElementTy) { +case dxil::ElementType::I1: + return "i1"; +case dxil::ElementType::I16: + return "i16"; +case dxil::ElementType::U16: + return "u16"; +case dxil::ElementType::I32: + return "i32"; +case dxil::ElementType::U32: + return "u32"; +case dxil::ElementType::I64: + return "i64"; +case dxil::ElementType::U64: + return "u64"; +case dxil::ElementType::F16: + return "f16"; +case dxil::ElementType::F32: + return "f32"; +case dxil::ElementType::F64: + return "f64"; +case dxil::ElementType::SNormF16: + return "snorm_f16"; +case dxil::ElementType::UNormF16: + return "unorm_f16"; +case dxil::ElementType::SNormF32: + return "snorm_f32"; +case dxil::ElementType::UNormF32: + return "unorm_f32"; +case dxil::ElementType::SNormF64: + return "snorm_f64"; +case dxil::ElementType::UNormF64: + return "unorm_f64"; +case dxil::ElementType::PackedS8x32: + return "p32i8"; +case dxil::ElementType::PackedU8x32: + return "p32u8"; +case dxil::ElementType::Invalid: + llvm_unreachable("Invalid ElementType"); +} +llvm_unreachable("Unhandled ElementType"); + } else if (RI.isStruct()) +return "struct"; + else if (RI.isCBuffer() || RI.isSampler()) +return "NA"; + return "byte"; +} + +static constexpr StringRef getTextureDimName(dxil::ResourceKind RK) { + switch (RK) { + case dxil::ResourceKind::Texture1D: +return "1d"; + case dxil::ResourceKind::Texture2D: +return "2d"; + case dxil::ResourceKind::Texture3D: +return "3d"; + case dxil::ResourceKind::TextureCube: +return "cube"; + case dxil::ResourceKind::Texture1DArray: +return "1darray"; + case dxil::ResourceKind::Texture2DArray: +return "2darray"; + case dxil::ResourceKind::TextureCubeArray: +return "cubearray"; + case dxil::ResourceKind::TBuffer: +return "tbuffer"; + case dxil::ResourceKind::FeedbackTexture2D: +return "fbtex2d"; + case dxil::ResourceKind::FeedbackTexture2DArray: +return "fbtex2darray"; + case dxil::ResourceKind::Texture2DMS: +return "2dMS"; + case dxil::ResourceKind::Texture2DMSArray: +return "2darrayMS"; + case dxil::ResourceKind::Invalid: + case dxil::ResourceKind::NumEntries: + case dxil::ResourceKind::CBuffer: + case dxil::ResourceKind::RawBuffer: + case dxil::ResourceKind::Sampler: + case dxil::ResourceKind::StructuredBuffer: + case dxil::ResourceKind::TypedBuffer: + case dxil::ResourceKind::RTAccelerationStructure: +llvm_unreachable("Invalid ResourceKind for texture"); + } + llvm_unreachable("Unhandled ResourceKind"); +} + +namespace { +struct FormatResourceDimension +: public llvm::FormatAdapter { + explicit FormatResourceDimension(const dxil::ResourceInfo &RI) + : llvm::FormatAdapter(RI) {} + + void format(llvm::raw_ostream &OS, StringRef Style) override { +dxil::ResourceKind RK = Item.getResourceKind(); +switch (RK) { +default: { + OS << getTextureDimName(RK); + if (Item.isMultiSample()) +OS << Item.getMultiSample().Count; + break;; +} +case dxil::ResourceKind::RawBuffer: +case dxil::ResourceKind::StructuredBuffer: + if (!Item.isUAV()) +OS << "r/o"; + else if (Item.getUAV().HasCounter) +OS << "r/w+cnt"; + else +OS << "r/w"; + break; +case dxil::ResourceKind::TypedBuffer: + OS << "buf"; + break; +case dxil::ResourceKind::RTAccelerationStructure: + // TODO: dxc would print "ras" here. Can/should this happen? + llvm_unreachable("RTAccelerationStructure printing is not implemented"); +} + } +}; + +struct FormatBindingID +: public llvm
[llvm-branch-commits] [DirectX] Add resource handling to the DXIL pretty printer (PR #104448)
@@ -1,4 +1,13 @@ ; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s +; RUN: opt -S -passes=dxil-pretty-printer %s 2>&1 >/dev/null | FileCheck --check-prefix=CHECK-PRETTY %s + +; CHECK-PRETTY: Type Format Dim ID HLSL Bind Count +; CHECK-PRETTY: -- --- --- --- -- - +; CHECK-PRETTY:UAV f32 buf U0 u5,space3 1 +; CHECK-PRETTY:UAV i32 buf U1 u7,space2 1 +; CHECK-PRETTY:SRV u32 buf T0 t3,space524 +; CHECK-PRETTY:SRV struct r/o T1 t2,space4 1 +; CHECK-PRETTY:SRVbyte r/o T2 t8,space1 1 hekota wrote: Change one of the cases to use the default `space0`? https://github.com/llvm/llvm-project/pull/104448 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Move resource logic into PrettyPrinter and TranslateMetadata. NFC (PR #104446)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104446 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Revert specialized createOp methods part of #101250 (PR #104245)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104245 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Register a few DXIL passes with the new PM (PR #104250)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104250 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Lower `@llvm.dx.typedBufferStore` to DXIL ops (PR #104253)
@@ -0,0 +1,34 @@ +; We use llc for this test so that we don't abort after the first error. +; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s + +target triple = "dxil-pc-shadermodel6.6-compute" + +; CHECK: error: +; CHECK-SAME: in function storetoofew +; CHECK-SAME: typedBufferStore data must be a vector of 4 elements +define void @storetoomany(<5 x float> %data, i32 %index) { hekota wrote: The checks for `storetoofew` and `storetoomany` seem to be swapped. https://github.com/llvm/llvm-project/pull/104253 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Lower `@llvm.dx.typedBufferStore` to DXIL ops (PR #104253)
https://github.com/hekota approved this pull request. https://github.com/llvm/llvm-project/pull/104253 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Lower `@llvm.dx.handle.fromBinding` to DXIL ops (PR #104251)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/104251 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [DirectX] Lower `@llvm.dx.typedBufferStore` to DXIL ops (PR #104253)
https://github.com/hekota approved this pull request. https://github.com/llvm/llvm-project/pull/104253 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.load.rawbuffer intrinsic (PR #121012)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/121012 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
@@ -548,3 +550,85 @@ Examples: target("dx.TypedBuffer", f16, 1, 0) %buf, i32 %index, <4 x f16> %data) call void @llvm.dx.resource.store.typedbuffer.tdx.Buffer_v2f64_1_0_0t( target("dx.TypedBuffer", f64, 1, 0) %buf, i32 %index, <2 x f64> %data) + +For RawBuffer, we need two indices and we accept scalars and vectors of less +than 4 elements. Note that we do allow vectors of 4 64-bit elements here. + +Examples: + +.. list-table:: ``@llvm.dx.resource.store.rawbuffer`` + :header-rows: 1 + + * - Argument + - + - Type + - Description + * - Return value + - + - ``void`` + - + * - ``%buffer`` + - 0 + - ``target(dx.TypedBuffer, ...)`` hekota wrote: ```suggestion - ``target(dx.RawBuffer, ...)`` ``` https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
@@ -548,3 +550,85 @@ Examples: target("dx.TypedBuffer", f16, 1, 0) %buf, i32 %index, <4 x f16> %data) call void @llvm.dx.resource.store.typedbuffer.tdx.Buffer_v2f64_1_0_0t( target("dx.TypedBuffer", f64, 1, 0) %buf, i32 %index, <2 x f64> %data) + +For RawBuffer, we need two indices and we accept scalars and vectors of less +than 4 elements. Note that we do allow vectors of 4 64-bit elements here. hekota wrote: ```suggestion For RawBuffer, we need two indices and we accept scalars and vectors of 4 or less elements. Note that we do allow vectors of 4 64-bit elements here. ``` https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
@@ -548,3 +550,85 @@ Examples: target("dx.TypedBuffer", f16, 1, 0) %buf, i32 %index, <4 x f16> %data) call void @llvm.dx.resource.store.typedbuffer.tdx.Buffer_v2f64_1_0_0t( target("dx.TypedBuffer", f64, 1, 0) %buf, i32 %index, <2 x f64> %data) + +For RawBuffer, we need two indices and we accept scalars and vectors of less +than 4 elements. Note that we do allow vectors of 4 64-bit elements here. + +Examples: + +.. list-table:: ``@llvm.dx.resource.store.rawbuffer`` + :header-rows: 1 + + * - Argument + - + - Type + - Description + * - Return value + - + - ``void`` + - + * - ``%buffer`` + - 0 + - ``target(dx.TypedBuffer, ...)`` + - The buffer to store into + * - ``%index`` + - 1 + - ``i32`` + - Index into the buffer + * - ``%offset`` + - 2 + - ``i32`` + - Byte offset into structured buffer elements + * - ``%data`` + - 3 + - Scalar or vector + - The data to store + +Examples: + +.. code-block:: llvm + + ; float + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_f32_1_0_0t.f32( + target("dx.RawBuffer", float, 1, 0, 0) %buffer, + i32 %index, i32 %offset, float %data) + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i8_1_0_0t.f32( + target("dx.RawBuffer", i8, 1, 0, 0) %buffer, + i32 %index, i32 0, float %data) + + ; float4 + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_v4f32_1_0_0t.v4f32( + target("dx.RawBuffer", <4 x float>, 1, 0, 0) %buffer, + i32 %index, i32 0, <4 x float> %data) + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i8_1_0_0t.v4f32( + target("dx.RawBuffer", i8, 1, 0, 0) %buffer, + i32 %index, i32 0, <4 x float> %data) hekota wrote: ```suggestion i32 %offset, i32 0, <4 x float> %data) ``` You seem to use the name `offset` here when the buffer type is `i8`, right? https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
@@ -548,3 +550,85 @@ Examples: target("dx.TypedBuffer", f16, 1, 0) %buf, i32 %index, <4 x f16> %data) call void @llvm.dx.resource.store.typedbuffer.tdx.Buffer_v2f64_1_0_0t( target("dx.TypedBuffer", f64, 1, 0) %buf, i32 %index, <2 x f64> %data) + +For RawBuffer, we need two indices and we accept scalars and vectors of less +than 4 elements. Note that we do allow vectors of 4 64-bit elements here. + +Examples: + +.. list-table:: ``@llvm.dx.resource.store.rawbuffer`` + :header-rows: 1 + + * - Argument + - + - Type + - Description + * - Return value + - + - ``void`` + - + * - ``%buffer`` + - 0 + - ``target(dx.TypedBuffer, ...)`` + - The buffer to store into + * - ``%index`` + - 1 + - ``i32`` + - Index into the buffer + * - ``%offset`` + - 2 + - ``i32`` + - Byte offset into structured buffer elements + * - ``%data`` + - 3 + - Scalar or vector + - The data to store + +Examples: + +.. code-block:: llvm + + ; float + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_f32_1_0_0t.f32( + target("dx.RawBuffer", float, 1, 0, 0) %buffer, + i32 %index, i32 %offset, float %data) hekota wrote: ```suggestion i32 %index, i32 0, float %data) ``` https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.store.rawbuffer intrinsic (PR #121282)
https://github.com/hekota commented: LGTM! Just a few typos in the docs. https://github.com/llvm/llvm-project/pull/121282 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.load.rawbuffer intrinsic (PR #121012)
@@ -0,0 +1,232 @@ +; RUN: opt -S -dxil-op-lower %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.6-compute" + +declare void @f32_user(float) +declare void @v4f32_user(<4 x float>) +declare void @i32_user(i32) +declare void @v4i32_user(<4 x i32>) +declare void @v3f16_user(<3 x half>) +declare void @v4f64_user(<4 x double>) + +; CHECK-LABEL: define void @loadf32_struct +define void @loadf32_struct(i32 %index) { + %buffer = call target("dx.RawBuffer", float, 0, 0, 0) + @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0_0( + i32 0, i32 0, i32 1, i32 0, i1 false) + + ; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %index, i32 0, i8 1, i32 4) + %load = call {float, i1} + @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_0_0_0t( + target("dx.RawBuffer", float, 0, 0, 0) %buffer, + i32 %index, + i32 0) + %data = extractvalue {float, i1} %load, 0 + + ; CHECK: [[VAL:%.*]] = extractvalue %dx.types.ResRet.f32 [[DATA]], 0 + ; CHECK: call void @f32_user(float [[VAL]]) + call void @f32_user(float %data) + + ret void +} + +; CHECK-LABEL: define void @loadf32_byte +define void @loadf32_byte(i32 %offset) { + %buffer = call target("dx.RawBuffer", i8, 0, 0, 0) + @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0( + i32 0, i32 0, i32 1, i32 0, i1 false) + + ; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, i8 1, i32 4) + %load = call {float, i1} + @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t( + target("dx.RawBuffer", i8, 0, 0, 0) %buffer, + i32 %offset, + i32 0) + %data = extractvalue {float, i1} %load, 0 + + ; CHECK: [[VAL:%.*]] = extractvalue %dx.types.ResRet.f32 [[DATA]], 0 + ; CHECK: call void @f32_user(float [[VAL]]) + call void @f32_user(float %data) + + ret void +} + +; CHECK-LABEL: define void @loadv4f32_struct +define void @loadv4f32_struct(i32 %index) { + %buffer = call target("dx.RawBuffer", <4 x float>, 0, 0, 0) + @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_v4f32_0_0_0( + i32 0, i32 0, i32 1, i32 0, i1 false) + + ; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %index, i32 0, i8 15, i32 4) + %load = call {<4 x float>, i1} + @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_v4f32_0_0_0t( + target("dx.RawBuffer", <4 x float>, 0, 0, 0) %buffer, + i32 %index, + i32 0) + %data = extractvalue {<4 x float>, i1} %load, 0 + + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 0 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 1 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 2 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 3 + ; CHECK: insertelement <4 x float> undef + ; CHECK: insertelement <4 x float> + ; CHECK: insertelement <4 x float> + ; CHECK: insertelement <4 x float> + ; CHECK: call void @v4f32_user(<4 x float> + call void @v4f32_user(<4 x float> %data) + + ret void +} + +; CHECK-LABEL: define void @loadv4f32_byte +define void @loadv4f32_byte(i32 %offset) { + %buffer = call target("dx.RawBuffer", i8, 0, 0, 0) + @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0( + i32 0, i32 0, i32 1, i32 0, i1 false) + + ; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, i8 15, i32 4) + %load = call {<4 x float>, i1} + @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t( + target("dx.RawBuffer", i8, 0, 0, 0) %buffer, + i32 %offset, + i32 0) + %data = extractvalue {<4 x float>, i1} %load, 0 + + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 0 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 1 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 2 + ; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 3 + ; CHECK: insertelement <4 x float> undef + ; CHECK: insertelement <4 x float> + ; CHECK: insertelement <4 x float> + ; CHECK: insertelement <4 x float> + ; CHECK: call void @v4f32_user(<4 x float> + call void @v4f32_user(<4 x float> %data) + + ret void +} + +; CHECK-LABEL: define void @loadelements +define void @loadelements(i32 %index) { + %buffer = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0, 0) + @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0_0( + i32 0, i32 0, i32 1, i32 0, i1 false) + + ; CHECK: [[DATAF32:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %index, i32 0, i8 15, i32 4) + %loadf32 = call {<4 x float>, i1} + @llvm.dx.resource.load.rawbuffer.v4f32( + target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0, 0) %buffer, + i32 %index, + i32 0) + %
[llvm-branch-commits] [llvm] [DirectX] Implement the resource.load.rawbuffer intrinsic (PR #121012)
https://github.com/hekota approved this pull request. LGTM! Just one small test issue. https://github.com/llvm/llvm-project/pull/121012 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/124886 >From cf08adb6b9e181613e81d2cfbadbbb68e645fe33 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 28 Jan 2025 14:46:26 -0800 Subject: [PATCH 1/4] [HLSL] Translate cbuffer declarations to target type dx.CBuffer - initial commit --- clang/include/clang/AST/Decl.h| 6 + clang/include/clang/AST/Type.h| 4 +- clang/lib/AST/Decl.cpp| 17 +- clang/lib/CodeGen/CGHLSLRuntime.cpp | 409 -- clang/lib/CodeGen/CGHLSLRuntime.h | 31 +- clang/lib/CodeGen/Targets/DirectX.cpp | 11 +- clang/lib/Sema/SemaHLSL.cpp | 3 + clang/test/CodeGenHLSL/cbuf.hlsl | 33 -- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 29 -- clang/test/CodeGenHLSL/cbuffer.hlsl | 200 + .../CodeGenHLSL/cbuffer_and_namespaces.hlsl | 63 +++ .../CodeGenHLSL/cbuffer_with_packoffset.hlsl | 40 ++ ...uffer_with_static_global_and_function.hlsl | 32 ++ clang/test/CodeGenHLSL/resource-bindings.hlsl | 4 + .../static_global_and_function_in_cb.hlsl | 22 - 15 files changed, 679 insertions(+), 225 deletions(-) delete mode 100644 clang/test/CodeGenHLSL/cbuf.hlsl delete mode 100644 clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl delete mode 100644 clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 16403774e72b31..e1c7e3817699ce 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5032,6 +5032,9 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { SourceLocation KwLoc; /// IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer). bool IsCBuffer; + /// HasValidPackoffset - Whether the buffer has valid packoffset annotations + // on all declarations + bool HasPackoffset; HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, @@ -5052,6 +5055,9 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } bool isCBuffer() const { return IsCBuffer; } + void setHasPackoffset(bool PO) { HasPackoffset = PO; } + bool hasPackoffset() const { return HasPackoffset; } + const CXXRecordDecl *getLayoutStruct() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1d9743520654eb..c3ff7ebd88516c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6266,8 +6266,8 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode { LLVM_PREFERRED_TYPE(bool) uint8_t RawBuffer : 1; -Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV, - bool RawBuffer) +Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV = false, + bool RawBuffer = false) : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {} Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {} diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index beb5fcaefac535..fa7d03354a9937 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1747,6 +1747,10 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, } } +// Suppress transparent contexts like export or HLSLBufferDecl context +if (Ctx->isTransparentContext()) + continue; + // Skip non-named contexts such as linkage specifications and ExportDecls. const NamedDecl *ND = dyn_cast(Ctx); if (!ND) @@ -5713,7 +5717,7 @@ HLSLBufferDecl::HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation IDLoc, SourceLocation LBrace) : NamedDecl(Decl::Kind::HLSLBuffer, DC, IDLoc, DeclarationName(ID)), DeclContext(Decl::Kind::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc), - IsCBuffer(CBuffer) {} + IsCBuffer(CBuffer), HasPackoffset(false) {} HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, DeclContext *LexicalParent, bool CBuffer, @@ -5743,6 +5747,17 @@ HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, SourceLocation(), SourceLocation()); } +const CXXRecordDecl *HLSLBufferDecl::getLayoutStruct() const { + // Layout st
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/125807 All variable declarations in the global scope that are not resources, static or empty are implicitly added to implicit constant buffer `$Globals`. Fixes #123801 Depends on #124886. >From 42bb34f66f0030f55e1055c4ee0b362511b7f45b Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 4 Feb 2025 22:01:49 -0800 Subject: [PATCH] [HLSL] Implement default constant buffer `$Globals` All variable declarations in the global scope that are not resources, static or empty are implicitly added to implicit constant buffer `$Globals`. Fixes #123801 --- clang/include/clang/AST/Decl.h | 22 +++ clang/include/clang/Sema/SemaHLSL.h | 7 ++- clang/lib/AST/Decl.cpp | 41 - clang/lib/CodeGen/CGHLSLRuntime.cpp | 7 +-- clang/lib/CodeGen/CodeGenModule.cpp | 5 ++ clang/lib/Sema/Sema.cpp | 3 +- clang/lib/Sema/SemaHLSL.cpp | 47 +-- clang/test/AST/HLSL/default_cbuffer.hlsl| 50 clang/test/CodeGenHLSL/basic_types.hlsl | 64 ++--- clang/test/CodeGenHLSL/default_cbuffer.hlsl | 43 ++ 10 files changed, 242 insertions(+), 47 deletions(-) create mode 100644 clang/test/AST/HLSL/default_cbuffer.hlsl create mode 100644 clang/test/CodeGenHLSL/default_cbuffer.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 05e56978977f2b1..f86ddaf89bd9cfa 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5038,6 +5038,11 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { // LayoutStruct - Layout struct for the buffer CXXRecordDecl *LayoutStruct; + // For default (implicit) constant buffer, a lisf of references of global + // decls that belong to the buffer. The decls are already parented by the + // translation unit context. + SmallVector DefaultBufferDecls; + HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); @@ -5047,6 +5052,8 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); + static HLSLBufferDecl *CreateDefaultCBuffer(ASTContext &C, + DeclContext *LexicalParent); static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { @@ -5061,6 +5068,7 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool hasPackoffset() const { return HasPackoffset; } const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; } void addLayoutStruct(CXXRecordDecl *LS); + void addDefaultBufferDecl(Decl *D); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -5072,6 +5080,20 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { return static_cast(const_cast(DC)); } + // Iterator for the buffer decls. Concatenates the list of decls parented + // by this HLSLBufferDecl with the list of default buffer decls. + using buffer_decl_iterator = + llvm::concat_iterator::const_iterator, +decl_iterator>; + using buffer_decl_range = llvm::iterator_range; + + buffer_decl_range buffer_decls() const { +return buffer_decl_range(buffer_decls_begin(), buffer_decls_end()); + } + buffer_decl_iterator buffer_decls_begin() const; + buffer_decl_iterator buffer_decls_end() const; + bool buffer_decls_empty(); + friend class ASTDeclReader; friend class ASTDeclWriter; }; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f4cd11f423a84a0..b1cc856975532fa 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -103,13 +103,13 @@ class SemaHLSL : public SemaBase { HLSLParamModifierAttr::Spelling Spelling); void ActOnTopLevelFunction(FunctionDecl *FD); void ActOnVariableDeclarator(VarDecl *VD); + void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU); void CheckEntryPoint(FunctionDecl *FD); void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr); void DiagnoseAttrStageMismatch( const Attr *A, llvm::Triple::EnvironmentType Stage, std::initializer_list AllowedStages); - void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType,
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/125807 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/124886 >From cf08adb6b9e181613e81d2cfbadbbb68e645fe33 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 28 Jan 2025 14:46:26 -0800 Subject: [PATCH 1/4] [HLSL] Translate cbuffer declarations to target type dx.CBuffer - initial commit --- clang/include/clang/AST/Decl.h| 6 + clang/include/clang/AST/Type.h| 4 +- clang/lib/AST/Decl.cpp| 17 +- clang/lib/CodeGen/CGHLSLRuntime.cpp | 409 -- clang/lib/CodeGen/CGHLSLRuntime.h | 31 +- clang/lib/CodeGen/Targets/DirectX.cpp | 11 +- clang/lib/Sema/SemaHLSL.cpp | 3 + clang/test/CodeGenHLSL/cbuf.hlsl | 33 -- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 29 -- clang/test/CodeGenHLSL/cbuffer.hlsl | 200 + .../CodeGenHLSL/cbuffer_and_namespaces.hlsl | 63 +++ .../CodeGenHLSL/cbuffer_with_packoffset.hlsl | 40 ++ ...uffer_with_static_global_and_function.hlsl | 32 ++ clang/test/CodeGenHLSL/resource-bindings.hlsl | 4 + .../static_global_and_function_in_cb.hlsl | 22 - 15 files changed, 679 insertions(+), 225 deletions(-) delete mode 100644 clang/test/CodeGenHLSL/cbuf.hlsl delete mode 100644 clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl create mode 100644 clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl delete mode 100644 clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 16403774e72b31c..e1c7e3817699ce0 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5032,6 +5032,9 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { SourceLocation KwLoc; /// IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer). bool IsCBuffer; + /// HasValidPackoffset - Whether the buffer has valid packoffset annotations + // on all declarations + bool HasPackoffset; HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, @@ -5052,6 +5055,9 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } bool isCBuffer() const { return IsCBuffer; } + void setHasPackoffset(bool PO) { HasPackoffset = PO; } + bool hasPackoffset() const { return HasPackoffset; } + const CXXRecordDecl *getLayoutStruct() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1d9743520654ebd..c3ff7ebd88516c7 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6266,8 +6266,8 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode { LLVM_PREFERRED_TYPE(bool) uint8_t RawBuffer : 1; -Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV, - bool RawBuffer) +Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV = false, + bool RawBuffer = false) : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {} Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {} diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index beb5fcaefac5353..fa7d03354a99379 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1747,6 +1747,10 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, } } +// Suppress transparent contexts like export or HLSLBufferDecl context +if (Ctx->isTransparentContext()) + continue; + // Skip non-named contexts such as linkage specifications and ExportDecls. const NamedDecl *ND = dyn_cast(Ctx); if (!ND) @@ -5713,7 +5717,7 @@ HLSLBufferDecl::HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation IDLoc, SourceLocation LBrace) : NamedDecl(Decl::Kind::HLSLBuffer, DC, IDLoc, DeclarationName(ID)), DeclContext(Decl::Kind::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc), - IsCBuffer(CBuffer) {} + IsCBuffer(CBuffer), HasPackoffset(false) {} HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, DeclContext *LexicalParent, bool CBuffer, @@ -5743,6 +5747,17 @@ HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, SourceLocation(), SourceLocation()); } +const CXXRecordDecl *HLSLBufferDecl::getLayoutStruct() const { + // Lay
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota ready_for_review https://github.com/llvm/llvm-project/pull/125807 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -5743,6 +5747,17 @@ HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, SourceLocation(), SourceLocation()); } +const CXXRecordDecl *HLSLBufferDecl::getLayoutStruct() const { + // Layout struct is the last decl in the HLSLBufferDecl. + if (CXXRecordDecl *RD = llvm::dyn_cast_or_null(LastDecl)) { hekota wrote: My thoughts were that since we are creating the layout struct, we can guarantee it is going to be the last one in the `HLSLBufferDecl` context, and there is an assert verifying that. I used `LastDecl` to avoid adding additional member to `HLSLBufferDecl` and it seemed to be a safe option (the FIXME comment is 17 years old). I will add an explicit field for the layout struct to make it cleaner. https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Define the HLSLRootSignature Attr (PR #123985)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/123985 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Define the HLSLRootSignature Attr (PR #123985)
@@ -647,6 +648,43 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, << NewFnName << FixItHint::CreateReplacement(FullRange, OS.str()); } +void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { + using namespace llvm::hlsl::root_signature; + using namespace clang::hlsl; hekota wrote: These are usually places at the top of the file after `#include`s. If this is the only function where it is needed it might be cleaner to just use fully qualified names. https://github.com/llvm/llvm-project/pull/123985 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Define the HLSLRootSignature Attr (PR #123985)
@@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \ +// RUN: -disable-llvm-passes -o - %s | FileCheck %s + +// This test ensures that the sample root signature is parsed without error and +// the Attr AST Node is created succesfully. If an invalid root signature was +// passed in then we would exit out of Sema before the Attr is created. + +#define SampleRS \ + "DescriptorTable( " \ + " CBV(b1), " \ + " SRV(t1, numDescriptors = 8, " \ + " flags = DESCRIPTORS_VOLATILE), " \ + " UAV(u1, numDescriptors = 0, " \ + " flags = DESCRIPTORS_VOLATILE) " \ + "), " \ + "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" + +// CHECK: HLSLRootSignatureAttr 0x{{[0-9A-Fa-f]+}} hekota wrote: ```suggestion // CHECK: HLSLRootSignatureAttr ``` https://github.com/llvm/llvm-project/pull/123985 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Define the HLSLRootSignature Attr (PR #123985)
https://github.com/hekota approved this pull request. LGMT! Couple of minor comments. https://github.com/llvm/llvm-project/pull/123985 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota converted_to_draft https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] TypedUAVLoadAdditionalFormats shader flag (PR #120280)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/120280 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
@@ -303,44 +289,157 @@ class ResourceInfo { dxil::SamplerFeedbackType getFeedbackType() const; uint32_t getMultiSampleCount() const; - StringRef getName() const { -// TODO: Get the name from the symbol once we include one here. -return ""; - } dxil::ResourceClass getResourceClass() const { return RC; } dxil::ResourceKind getResourceKind() const { return Kind; } + bool operator==(const ResourceTypeInfo &RHS) const; + bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); } + bool operator<(const ResourceTypeInfo &RHS) const; + + void print(raw_ostream &OS, const DataLayout &DL) const; +}; + +//===--===// + +class ResourceBindingInfo { +public: + struct ResourceBinding { +uint32_t RecordID; +uint32_t Space; +uint32_t LowerBound; +uint32_t Size; + +bool operator==(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) == + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); +} +bool operator!=(const ResourceBinding &RHS) const { + return !(*this == RHS); +} +bool operator<(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) < + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); +} + }; + +private: + ResourceBinding Binding; + TargetExtType *HandleTy; + +public: + ResourceBindingInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound, + uint32_t Size, TargetExtType *HandleTy) + : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {} + void setBindingID(unsigned ID) { Binding.RecordID = ID; } const ResourceBinding &getBinding() const { return Binding; } + TargetExtType *getHandleTy() const { return HandleTy; } + const StringRef getName() const { +// TODO: Get the name from the symbol once we include one here. +return ""; + } - MDTuple *getAsMetadata(Module &M) const; - std::pair getAnnotateProps(Module &M) const; + MDTuple *getAsMetadata(Module &M, DXILResourceTypeMap &DRTM) const; + MDTuple *getAsMetadata(Module &M, dxil::ResourceTypeInfo RTI) const; - bool operator==(const ResourceInfo &RHS) const; - bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); } - bool operator<(const ResourceInfo &RHS) const; + std::pair + getAnnotateProps(Module &M, DXILResourceTypeMap &DRTM) const; + std::pair + getAnnotateProps(Module &M, dxil::ResourceTypeInfo RTI) const; - void print(raw_ostream &OS, const DataLayout &DL) const; + bool operator==(const ResourceBindingInfo &RHS) const { +return std::tie(Binding, HandleTy) == std::tie(RHS.Binding, RHS.HandleTy); + } + bool operator!=(const ResourceBindingInfo &RHS) const { +return !(*this == RHS); + } + bool operator<(const ResourceBindingInfo &RHS) const { +return Binding < RHS.Binding; + } + + void print(raw_ostream &OS, DXILResourceTypeMap &DRTM, + const DataLayout &DL) const; + void print(raw_ostream &OS, dxil::ResourceTypeInfo RTI, + const DataLayout &DL) const; }; } // namespace dxil //===--===// -class DXILResourceMap { - SmallVector Infos; +class DXILResourceTypeMap { + struct Info { +dxil::ResourceClass RC; +dxil::ResourceKind Kind; +bool GloballyCoherent; +bool HasCounter; + }; + DenseMap Infos; + +public: + bool invalidate(Module &M, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &Inv); + + dxil::ResourceTypeInfo operator[](TargetExtType *Ty) { +Info I = Infos[Ty]; +return dxil::ResourceTypeInfo(Ty, I.RC, I.Kind, I.GloballyCoherent, + I.HasCounter); + } + + void setGloballyCoherent(TargetExtType *Ty, bool GloballyCoherent) { +Infos[Ty].GloballyCoherent = GloballyCoherent; + } + + void setHasCounter(TargetExtType *Ty, bool HasCounter) { +Infos[Ty].HasCounter = HasCounter; + } +}; + +class DXILResourceTypeAnalysis +: public AnalysisInfoMixin { + friend AnalysisInfoMixin; + + static AnalysisKey Key; + +public: + using Result = DXILResourceTypeMap; + + DXILResourceTypeMap run(Module &M, ModuleAnalysisManager &AM) { +return Result(); + } hekota wrote: It would be nice to add a comment on this class explaining how will the DXILResourceTypeMap get populated (that it happens in the DXILResourceBindingAnalysis, if I understand it correctly). https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Create symbols for resource handles (PR #119775)
@@ -0,0 +1,48 @@ +; RUN: opt -S -passes=dxil-translate-metadata %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.6-compute" + +%struct.S = type { <4 x float>, <4 x i32> } + +define void @test() { + ; Buffer + %float4 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0) + @llvm.dx.handle.fromBinding(i32 0, i32 0, i32 1, i32 0, i1 false) + ; CHECK: %TypedBuffer = type { <4 x float> } + + ; Buffer + %int = call target("dx.TypedBuffer", i32, 0, 0, 1) + @llvm.dx.handle.fromBinding(i32 0, i32 1, i32 1, i32 0, i1 false) + ; CHECK: %TypedBuffer.0 = type { i32 } + + ; Buffer + %uint3 = call target("dx.TypedBuffer", <3 x i32>, 0, 0, 0) + @llvm.dx.handle.fromBinding(i32 0, i32 2, i32 1, i32 0, i1 false) + ; CHECK: %TypedBuffer.1 = type { <3 x i32> } + + ; StructuredBuffer + %struct0 = call target("dx.RawBuffer", %struct.S, 0, 0) + @llvm.dx.handle.fromBinding(i32 0, i32 10, i32 1, i32 0, i1 true) + ; CHECK: %StructuredBuffer = type { %struct.S } + + ; ByteAddressBuffer + %byteaddr = call target("dx.RawBuffer", i8, 0, 0) + @llvm.dx.handle.fromBinding(i32 0, i32 20, i32 1, i32 0, i1 false) + ; CHECK: %ByteAddressBuffer = type { i32 } + + ret void +} + +; CHECK: @[[T0:.*]] = external constant %TypedBuffer +; CHECK-NEXT: @[[T1:.*]] = external constant %TypedBuffer.0 +; CHECK-NEXT: @[[T2:.*]] = external constant %TypedBuffer.1 +; CHECK-NEXT: @[[S0:.*]] = external constant %StructuredBuffer +; CHECK-NEXT: @[[B0:.*]] = external constant %ByteAddressBuffer + +; CHECK: !{i32 0, ptr @[[T0]], !"" hekota wrote: Is the name of the symbol expected to be empty string here? https://github.com/llvm/llvm-project/pull/119775 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Create symbols for resource handles (PR #119775)
hekota wrote: If there already is a global variable for the resource in the module, shouldn't we be using that instead of creating a new symbol? https://github.com/llvm/llvm-project/pull/119775 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
@@ -303,44 +289,157 @@ class ResourceInfo { dxil::SamplerFeedbackType getFeedbackType() const; uint32_t getMultiSampleCount() const; - StringRef getName() const { -// TODO: Get the name from the symbol once we include one here. -return ""; - } dxil::ResourceClass getResourceClass() const { return RC; } dxil::ResourceKind getResourceKind() const { return Kind; } + bool operator==(const ResourceTypeInfo &RHS) const; + bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); } + bool operator<(const ResourceTypeInfo &RHS) const; + + void print(raw_ostream &OS, const DataLayout &DL) const; +}; + +//===--===// + +class ResourceBindingInfo { +public: + struct ResourceBinding { +uint32_t RecordID; +uint32_t Space; +uint32_t LowerBound; +uint32_t Size; + +bool operator==(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) == + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); +} +bool operator!=(const ResourceBinding &RHS) const { + return !(*this == RHS); +} +bool operator<(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) < + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); +} + }; + +private: + ResourceBinding Binding; + TargetExtType *HandleTy; + +public: + ResourceBindingInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound, + uint32_t Size, TargetExtType *HandleTy) + : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {} + void setBindingID(unsigned ID) { Binding.RecordID = ID; } const ResourceBinding &getBinding() const { return Binding; } + TargetExtType *getHandleTy() const { return HandleTy; } + const StringRef getName() const { +// TODO: Get the name from the symbol once we include one here. +return ""; + } - MDTuple *getAsMetadata(Module &M) const; - std::pair getAnnotateProps(Module &M) const; + MDTuple *getAsMetadata(Module &M, DXILResourceTypeMap &DRTM) const; + MDTuple *getAsMetadata(Module &M, dxil::ResourceTypeInfo RTI) const; - bool operator==(const ResourceInfo &RHS) const; - bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); } - bool operator<(const ResourceInfo &RHS) const; + std::pair + getAnnotateProps(Module &M, DXILResourceTypeMap &DRTM) const; + std::pair + getAnnotateProps(Module &M, dxil::ResourceTypeInfo RTI) const; - void print(raw_ostream &OS, const DataLayout &DL) const; + bool operator==(const ResourceBindingInfo &RHS) const { +return std::tie(Binding, HandleTy) == std::tie(RHS.Binding, RHS.HandleTy); + } + bool operator!=(const ResourceBindingInfo &RHS) const { +return !(*this == RHS); + } + bool operator<(const ResourceBindingInfo &RHS) const { +return Binding < RHS.Binding; + } + + void print(raw_ostream &OS, DXILResourceTypeMap &DRTM, + const DataLayout &DL) const; + void print(raw_ostream &OS, dxil::ResourceTypeInfo RTI, + const DataLayout &DL) const; }; } // namespace dxil //===--===// -class DXILResourceMap { - SmallVector Infos; +class DXILResourceTypeMap { + struct Info { +dxil::ResourceClass RC; +dxil::ResourceKind Kind; +bool GloballyCoherent; +bool HasCounter; + }; + DenseMap Infos; hekota wrote: Why not `DenseMap Infos;` and return reference to the ResourceTypeInfo in the map in `operator[]` implementation? How is `Infos` even populated? https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Split resource info into type and binding info. NFC (PR #119773)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/119773 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Add RWBuffer::Load(Index) (PR #117018)
@@ -189,12 +189,28 @@ struct BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addArraySubscriptOperators(Sema &S) { if (Record->isCompleteDefinition()) return *this; -addArraySubscriptOperator(S, true); -addArraySubscriptOperator(S, false); +ASTContext &AST = Record->getASTContext(); +DeclarationName Subscript = +AST.DeclarationNames.getCXXOperatorName(OO_Subscript); +addHandleAccessFunction(S, Subscript, /*IsConst=*/true, /*IsRef=*/true); +addHandleAccessFunction(S, Subscript, /*IsConst=*/false, /*IsRef=*/true); +return *this; + } + + BuiltinTypeDeclBuilder &addLoadMethods(Sema &S) { hekota wrote: Sounds good. Maybe add a FIXME comment that the other Load methods will be added later? https://github.com/llvm/llvm-project/pull/117018 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Add RWBuffer::Load(Index) (PR #117018)
https://github.com/hekota approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/117018 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Add RWBuffer::Load(Index) (PR #117018)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/117018 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Add RWBuffer::Load(Index) (PR #117018)
@@ -189,12 +189,28 @@ struct BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addArraySubscriptOperators(Sema &S) { if (Record->isCompleteDefinition()) return *this; -addArraySubscriptOperator(S, true); -addArraySubscriptOperator(S, false); +ASTContext &AST = Record->getASTContext(); +DeclarationName Subscript = +AST.DeclarationNames.getCXXOperatorName(OO_Subscript); +addHandleAccessFunction(S, Subscript, /*IsConst=*/true, /*IsRef=*/true); +addHandleAccessFunction(S, Subscript, /*IsConst=*/false, /*IsRef=*/true); +return *this; + } + + BuiltinTypeDeclBuilder &addLoadMethods(Sema &S) { hekota wrote: 1. The name `addLoadMethods` implies that it will add multiple methods yet it is adding a single one. 2. What about Load with the `out uint status` parameter? 3. There are many other `Load` methods for different kinds of buffers/textures. Should the name reflect that? https://github.com/llvm/llvm-project/pull/117018 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -1,16 +1,21 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK-DAG: @[[CB:.+]] = external constant { float } +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s cbuffer A { -float a; - // CHECK-DAG:@_ZL1b = internal global float 3.00e+00, align 4 + // CHECK: @a = external addrspace(2) externally_initialized global float, align 4 + float a; + // CHECK: @_ZL1b = internal global float 3.00e+00, align 4 static float b = 3; hekota wrote: Ideally no, but DXC currently allows it (https://godbolt.org/z/G6G4eob7b) and at this point Clang does as well. We have an issue tracking it here: https://github.com/llvm/llvm-project/issues/118524 https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/123411 >From 6aba475e4af789fc03594560ad9937e3502cce51 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Fri, 17 Jan 2025 13:31:01 -0800 Subject: [PATCH 1/3] [HLSL] Add address space `hlsl_constant(2)` for constant buffer declarations --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp| 1 + clang/lib/Basic/Targets/DirectX.h | 1 + clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h| 2 + clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 16 clang/lib/Sema/SemaHLSL.cpp | 15 ++-- .../ast-dump-comment-cbuffer-tbuffer.hlsl | 16 clang/test/AST/HLSL/cbuffer.hlsl | 24 ++-- clang/test/AST/HLSL/packoffset.hlsl | 38 +-- clang/test/AST/HLSL/pch_hlsl_buffer.hlsl | 12 +++--- .../test/AST/HLSL/resource_binding_attr.hlsl | 8 ++-- clang/test/CodeGenHLSL/cbuf.hlsl | 13 +-- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 8 +++- .../static_global_and_function_in_cb.hlsl | 14 --- 21 files changed, 97 insertions(+), 80 deletions(-) diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff17..d18bfe54931f93 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_constant, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index a850410ffc8468..6cad74fef3fe33 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2556,6 +2556,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_constant: +return "hlsl_constant"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ecf80b23a508c9..600940f5e4e23c 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast(AArch64AddrSpace::ptr32_uptr), static_cast(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared +0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e2796..824134d52ec139 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -83,6 +83,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared +llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant }; } // namespace targets diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df7..4e6bc0e040398b 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared +2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac0..c6531148fe30ce 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared +0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 5a328b9ceeb1d1..c0849b69dcdb32 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -47,6 +47,7 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared +2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -1,7 +1,14 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s \ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: @a = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @b = external addrspace(2) externally_initialized global double, align 8 +// CHECK: @c = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @d = external addrspace(2) externally_initialized global double, align 8 + // CHECK: @[[CB:.+]] = external constant { float, double } hekota wrote: There is going to be a pass after codegen that will translate all of the addrspace(2) globals and loads to constant buffer load intrinsics. An update to the constant buffers design document that explains this coming soon. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/123411 >From 6aba475e4af789fc03594560ad9937e3502cce51 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Fri, 17 Jan 2025 13:31:01 -0800 Subject: [PATCH 1/2] [HLSL] Add address space `hlsl_constant(2)` for constant buffer declarations --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp| 1 + clang/lib/Basic/Targets/DirectX.h | 1 + clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h| 2 + clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 16 clang/lib/Sema/SemaHLSL.cpp | 15 ++-- .../ast-dump-comment-cbuffer-tbuffer.hlsl | 16 clang/test/AST/HLSL/cbuffer.hlsl | 24 ++-- clang/test/AST/HLSL/packoffset.hlsl | 38 +-- clang/test/AST/HLSL/pch_hlsl_buffer.hlsl | 12 +++--- .../test/AST/HLSL/resource_binding_attr.hlsl | 8 ++-- clang/test/CodeGenHLSL/cbuf.hlsl | 13 +-- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 8 +++- .../static_global_and_function_in_cb.hlsl | 14 --- 21 files changed, 97 insertions(+), 80 deletions(-) diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff17..d18bfe54931f93 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_constant, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index a850410ffc8468..6cad74fef3fe33 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2556,6 +2556,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_constant: +return "hlsl_constant"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ecf80b23a508c9..600940f5e4e23c 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast(AArch64AddrSpace::ptr32_uptr), static_cast(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared +0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e2796..824134d52ec139 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -83,6 +83,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared +llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant }; } // namespace targets diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df7..4e6bc0e040398b 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared +2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac0..c6531148fe30ce 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared +0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 5a328b9ceeb1d1..c0849b69dcdb32 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -47,6 +47,7 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared +2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
hekota wrote: I have added SPIR-V variants of the 3 codegen tests. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -455,14 +456,22 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) { LS->setImplicit(true); LS->startDefinition(); - for (const Decl *D : BufDecl->decls()) { -const VarDecl *VD = dyn_cast(D); + for (Decl *D : BufDecl->decls()) { +VarDecl *VD = dyn_cast(D); if (!VD || VD->getStorageClass() == SC_Static) continue; const Type *Ty = VD->getType()->getUnqualifiedDesugaredType(); if (FieldDecl *FD = createFieldForHostLayoutStruct( -S, Ty, VD->getIdentifier(), LS, BufDecl)) +S, Ty, VD->getIdentifier(), LS, BufDecl)) { + // add the field decl to the layout struct LS->addDecl(FD); + // update address space of the original decl to hlsl_constant + // and disable initialization + QualType NewTy = + AST.getAddrSpaceQualType(VD->getType(), LangAS::hlsl_constant); + VD->setType(NewTy); + VD->setInit(nullptr); hekota wrote: If we need to preserve the initializers in the AST even though they are not used, we could mark the generated global variable as `externally_initialized`. The global gets removed in the final DXIL after all. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -1,16 +1,21 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK-DAG: @[[CB:.+]] = external constant { float } +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s cbuffer A { -float a; - // CHECK-DAG:@_ZL1b = internal global float 3.00e+00, align 4 + // CHECK: @a = external addrspace(2) externally_initialized global float, align 4 + float a; + // CHECK: @_ZL1b = internal global float 3.00e+00, align 4 static float b = 3; hekota wrote: At this point it is not clear what is the end goal. The static decl here tests that is does not get added to the cbuffer layout struct or the new address space. When/if we prohibit static decls in cbuffers this test will surely flare up and will be fixed up. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Add address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/123411 Introduces a new address space `hlsl_constant(2)` for constant buffer declarations. This address space is applied to declarations inside `cbuffer` block. Later on, it will also be applied to `ConstantBuffer` syntax and the default `$Globals` constant buffer. Clang codegen translates constant buffer declarations to global variables and loads from `hlsl_constant(2)` address space. More work coming soon will include addition of metadata that will map these globals to individual constant buffers and enable their transformation to appropriate constant buffer load intrinsics later on in an LLVM pass. Fixes #123406 >From 6aba475e4af789fc03594560ad9937e3502cce51 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Fri, 17 Jan 2025 13:31:01 -0800 Subject: [PATCH] [HLSL] Add address space `hlsl_constant(2)` for constant buffer declarations --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp| 1 + clang/lib/Basic/Targets/DirectX.h | 1 + clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h| 2 + clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 16 clang/lib/Sema/SemaHLSL.cpp | 15 ++-- .../ast-dump-comment-cbuffer-tbuffer.hlsl | 16 clang/test/AST/HLSL/cbuffer.hlsl | 24 ++-- clang/test/AST/HLSL/packoffset.hlsl | 38 +-- clang/test/AST/HLSL/pch_hlsl_buffer.hlsl | 12 +++--- .../test/AST/HLSL/resource_binding_attr.hlsl | 8 ++-- clang/test/CodeGenHLSL/cbuf.hlsl | 13 +-- clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl | 8 +++- .../static_global_and_function_in_cb.hlsl | 14 --- 21 files changed, 97 insertions(+), 80 deletions(-) diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff17..d18bfe54931f93 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_constant, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index a850410ffc8468..6cad74fef3fe33 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2556,6 +2556,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_constant: +return "hlsl_constant"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ecf80b23a508c9..600940f5e4e23c 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast(AArch64AddrSpace::ptr32_uptr), static_cast(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared +0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e2796..824134d52ec139 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -83,6 +83,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared +llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant }; } // namespace targets diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df7..4e6bc0e040398b 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared +2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac0..c6531148fe30ce 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -100,22 +100,6 @@ GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) { llvm::formatv("{0}{1}", Buf.Name, Buf.IsCBuffer ? ".cb." : ".tb."), GlobalValue::NotThreadLocal); - IRBuilder<> B(CBGV->getContext()); - Value *ZeroIdx = B.getInt32(0); - // Replace Const use with CB use. - for (auto &[GV, Offset] : Buf.Constants) { -Value *GEP = -B.CreateGEP(Buf.LayoutStruct, CBGV, {ZeroIdx, B.getInt32(Offset)}); - -assert(Buf.LayoutStruct->getElementType(Offset) == GV->getValueType() && - "constant type mismatch"); - -// Replace. -GV->replaceAllUsesWith(GEP); -// Erase GV. -GV->removeDeadConstantUsers(); -GV->eraseFromParent(); - } hekota wrote: I am removing this part to make sure we preserve the loads in the new address space, but there is more reworking to be done in this area. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota ready_for_review https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
https://github.com/hekota ready_for_review https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -83,6 +83,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared +llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_constant hekota wrote: Interesting. Sounds like it is useful to use `static const unsigned[]` then instead of `LangASMap` since it gives you a compile error when the dimension does not match. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Introduce address space `hlsl_constant(2)` for constant buffer declarations (PR #123411)
@@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared +2, // hlsl_constant hekota wrote: Yes, not updating all of the maps produces a compile error. https://github.com/llvm/llvm-project/pull/123411 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -56,9 +75,18 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM, return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints); } - case llvm::dxil::ResourceClass::CBuffer: -llvm_unreachable("dx.CBuffer handles are not implemented yet"); -break; + case llvm::dxil::ResourceClass::CBuffer: { +QualType ContainedTy = ResType->getContainedType(); +if (ContainedTy.isNull() || !ContainedTy->isStructureType()) hekota wrote: Contained type of the CBuffer resource handle is always a layout struct of the constant buffer (implicitly created by Sema [here](https://github.com/llvm/llvm-project/blob/e9fb2391210e20d1d4dcf8bbe37085df902ed028/clang/lib/Sema/SemaHLSL.cpp#L475)). https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -0,0 +1,201 @@ +//===- HLSLTargetInto.cpp--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "HLSLTargetInfo.h" +#include "CGHLSLRuntime.h" +#include "TargetInfo.h" +#include "clang/AST/DeclCXX.h" + +//===--===// +// Target codegen info implementation common between DirectX and SPIR/SPIR-V. +//===--===// + +namespace { + +// Creates a new array type with the same dimentions +// but with the new element type. +static llvm::Type * +createArrayWithNewElementType(CodeGenModule &CGM, + const ConstantArrayType *ArrayType, + llvm::Type *NewElemType) { + const clang::Type *ArrayElemType = ArrayType->getArrayElementTypeNoTypeQual(); + if (ArrayElemType->isConstantArrayType()) +NewElemType = createArrayWithNewElementType( +CGM, cast(ArrayElemType), NewElemType); + return llvm::ArrayType::get(NewElemType, ArrayType->getSExtSize()); +} + +// Returns the size of a scalar or vector in bytes/ +static unsigned getScalarOrVectorSize(llvm::Type *Ty) { hekota wrote: I like `getScalarOrVectorSizeInBytes`. https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -0,0 +1,201 @@ +//===- HLSLTargetInto.cpp--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "HLSLTargetInfo.h" +#include "CGHLSLRuntime.h" +#include "TargetInfo.h" +#include "clang/AST/DeclCXX.h" + +//===--===// +// Target codegen info implementation common between DirectX and SPIR/SPIR-V. +//===--===// + +namespace { + +// Creates a new array type with the same dimentions +// but with the new element type. +static llvm::Type * +createArrayWithNewElementType(CodeGenModule &CGM, + const ConstantArrayType *ArrayType, + llvm::Type *NewElemType) { + const clang::Type *ArrayElemType = ArrayType->getArrayElementTypeNoTypeQual(); + if (ArrayElemType->isConstantArrayType()) +NewElemType = createArrayWithNewElementType( +CGM, cast(ArrayElemType), NewElemType); + return llvm::ArrayType::get(NewElemType, ArrayType->getSExtSize()); +} + +// Returns the size of a scalar or vector in bytes/ +static unsigned getScalarOrVectorSize(llvm::Type *Ty) { + assert(Ty->isVectorTy() || Ty->isIntegerTy() || Ty->isFloatingPointTy()); + if (Ty->isVectorTy()) { +llvm::FixedVectorType *FVT = cast(Ty); +return FVT->getNumElements() * + (FVT->getElementType()->getScalarSizeInBits() / 8); + } + return Ty->getScalarSizeInBits() / 8; +} + +} // namespace + +// Creates a layout type for given struct with HLSL constant buffer layout +// taking into account Packoffsets, if provided. +// Previously created layout types are cached in CGHLSLRuntime because +// TargetCodeGenInto info is cannot store any data +// (CGM.getTargetCodeGenInfo() returns a const reference to TargetCondegenInfo). +// +// The function iterates over all fields of the StructType (including base +// classes), converts each field to its corresponding LLVM type and calculated +// it's HLSL constant bufffer layout (offset and size). Any embedded struct (or +// arrays of structs) are converted to target layout types as well. +llvm::Type *CommonHLSLTargetCodeGenInfo::createHLSLBufferLayoutType( +CodeGenModule &CGM, const RecordType *StructType, +const SmallVector *Packoffsets) const { + + // check if we already have the layout type for this struct + if (llvm::Type *Ty = CGM.getHLSLRuntime().getHLSLBufferLayoutType(StructType)) +return Ty; + + SmallVector Layout; + SmallVector LayoutElements; + unsigned Index = 0; // packoffset index + unsigned EndOffset = 0; + + // reserve first spot in the layout vector for buffer size + Layout.push_back(0); + + // iterate over all fields of the record, including fields on base classes + llvm::SmallVector RecordTypes; + RecordTypes.push_back(StructType); + while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { +CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); +assert(D->getNumBases() == 1 && + "HLSL doesn't support multiple inheritance"); +RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + } + while (!RecordTypes.empty()) { +const RecordType *RT = RecordTypes.back(); +RecordTypes.pop_back(); + +for (const auto *FD : RT->getDecl()->fields()) { + assert(!Packoffsets || Index < Packoffsets->size() && + "number of elements in layout struct does not " + "match number of packoffset annotations"); + // Size of element; for arrays this is a size of a single element in the + // array. Total array size of calculated as (ArrayCount-1) * ArrayStride + + // ElemSize. + unsigned ElemSize = 0; + + unsigned ElemOffset = 0; + unsigned ArrayCount = 1; + unsigned ArrayStride = 0; + unsigned NextRowOffset = llvm::alignTo(EndOffset, 16U); + llvm::Type *ElemLayoutTy = nullptr; + + QualType FieldTy = FD->getType(); + + if (FieldTy->isConstantArrayType()) { +// Unwrap array to find the element type and get combined array size. +QualType Ty = FieldTy; +while (Ty->isConstantArrayType()) { + const ConstantArrayType *ArrayTy = cast(Ty); + ArrayCount *= ArrayTy->getSExtSize(); + Ty = ArrayTy->getElementType(); +} +// For array of structures, create a new array with a layout type +// instead of the structure type. +if (Ty->isStructureType()) { + llvm::Type *NewTy = cast( + createHLSLBufferLayoutType(CGM, Ty->getAsStructureType())); + if (!NewTy) +return nullptr; + asser
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/125807 >From 42bb34f66f0030f55e1055c4ee0b362511b7f45b Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 4 Feb 2025 22:01:49 -0800 Subject: [PATCH 1/4] [HLSL] Implement default constant buffer `$Globals` All variable declarations in the global scope that are not resources, static or empty are implicitly added to implicit constant buffer `$Globals`. Fixes #123801 --- clang/include/clang/AST/Decl.h | 22 +++ clang/include/clang/Sema/SemaHLSL.h | 7 ++- clang/lib/AST/Decl.cpp | 41 - clang/lib/CodeGen/CGHLSLRuntime.cpp | 7 +-- clang/lib/CodeGen/CodeGenModule.cpp | 5 ++ clang/lib/Sema/Sema.cpp | 3 +- clang/lib/Sema/SemaHLSL.cpp | 47 +-- clang/test/AST/HLSL/default_cbuffer.hlsl| 50 clang/test/CodeGenHLSL/basic_types.hlsl | 64 ++--- clang/test/CodeGenHLSL/default_cbuffer.hlsl | 43 ++ 10 files changed, 242 insertions(+), 47 deletions(-) create mode 100644 clang/test/AST/HLSL/default_cbuffer.hlsl create mode 100644 clang/test/CodeGenHLSL/default_cbuffer.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 05e56978977f2..f86ddaf89bd9c 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5038,6 +5038,11 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { // LayoutStruct - Layout struct for the buffer CXXRecordDecl *LayoutStruct; + // For default (implicit) constant buffer, a lisf of references of global + // decls that belong to the buffer. The decls are already parented by the + // translation unit context. + SmallVector DefaultBufferDecls; + HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); @@ -5047,6 +5052,8 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); + static HLSLBufferDecl *CreateDefaultCBuffer(ASTContext &C, + DeclContext *LexicalParent); static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { @@ -5061,6 +5068,7 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool hasPackoffset() const { return HasPackoffset; } const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; } void addLayoutStruct(CXXRecordDecl *LS); + void addDefaultBufferDecl(Decl *D); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -5072,6 +5080,20 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { return static_cast(const_cast(DC)); } + // Iterator for the buffer decls. Concatenates the list of decls parented + // by this HLSLBufferDecl with the list of default buffer decls. + using buffer_decl_iterator = + llvm::concat_iterator::const_iterator, +decl_iterator>; + using buffer_decl_range = llvm::iterator_range; + + buffer_decl_range buffer_decls() const { +return buffer_decl_range(buffer_decls_begin(), buffer_decls_end()); + } + buffer_decl_iterator buffer_decls_begin() const; + buffer_decl_iterator buffer_decls_end() const; + bool buffer_decls_empty(); + friend class ASTDeclReader; friend class ASTDeclWriter; }; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f4cd11f423a84..b1cc856975532 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -103,13 +103,13 @@ class SemaHLSL : public SemaBase { HLSLParamModifierAttr::Spelling Spelling); void ActOnTopLevelFunction(FunctionDecl *FD); void ActOnVariableDeclarator(VarDecl *VD); + void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU); void CheckEntryPoint(FunctionDecl *FD); void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr); void DiagnoseAttrStageMismatch( const Attr *A, llvm::Triple::EnvironmentType Stage, std::initializer_list AllowedStages); - void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, @@ -159,11 +159,16 @@ class SemaHLSL : public SemaBase { // List of all resource bindings ResourceBindings Bindings; + // default constant buffer $Globals + HLSL
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -0,0 +1,39 @@ +//===- HLSLTargetInfo.h ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ABIInfoImpl.h" +#include "TargetInfo.h" + +using namespace clang; +using namespace clang::CodeGen; + +//===--===// +// Target codegen info implementation common between DirectX and SPIR/SPIR-V. +//===--===// + +class CommonHLSLTargetCodeGenInfo : public TargetCodeGenInfo { +public: + CommonHLSLTargetCodeGenInfo(std::unique_ptr Info) + : TargetCodeGenInfo(std::move(Info)) {} + + // Returns LLVM target extension type "dx.Layout" or "spv.Layout" + // for given structure type and layout data. The first number in + // the Layout is the size followed by offsets for each struct element. + virtual llvm::Type *getHLSLLayoutType(CodeGenModule &CGM, +llvm::StructType *LayoutStructTy, +SmallVector Layout) const { +return nullptr; hekota wrote: This method is/will be implemented by the derived classes `DirectXTargetCodeGenInfo` and `CommonSPIRTargetCodeGenInfo`. The default implementation should return `nullptr`, the same as the default implementation of `getHLSLType` on the `TargetCodeGenInfo` class. `nullptr` means "I don't know who to convert this type". https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Constant buffers codegen (PR #124886)
@@ -0,0 +1,49 @@ +; ModuleID = 'C:\llvm-project\clang\test\CodeGenHLSL\cbuffer_and_namespaces.hlsl' hekota wrote: This file should not be here at all ;). https://github.com/llvm/llvm-project/pull/124886 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][NFC] Use builtin method builder to create default resource constructor (PR #131384)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/131384 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][NFC] Use method builder to create default resource constructor (PR #131384)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/131384 Updates the `BuiltinTypeMethodBuilder` to support creating constructors and use it to create the default resource constructor. This enables us to have a shared code for implementing both builtin methods and constructors and will come in handy when we add more constructors in the future. >From 47b41c88a60a7f376070b9ff779ec955eebf523a Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Wed, 12 Mar 2025 17:20:51 -0700 Subject: [PATCH 1/2] [HLSL] Create default resource constructor with BuiltinTypeMethodBuilder --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 126 ++ 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index db0ed3434d837..a52c6a49264c8 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -89,21 +89,24 @@ struct TemplateParameterListBuilder { // statement (unless the last statement is already a ReturnStmt). struct BuiltinTypeMethodBuilder { private: - struct MethodParam { + struct Param { const IdentifierInfo &NameII; QualType Ty; HLSLParamModifierAttr::Spelling Modifier; -MethodParam(const IdentifierInfo &NameII, QualType Ty, -HLSLParamModifierAttr::Spelling Modifier) +Param(const IdentifierInfo &NameII, QualType Ty, + HLSLParamModifierAttr::Spelling Modifier) : NameII(NameII), Ty(Ty), Modifier(Modifier) {} }; BuiltinTypeDeclBuilder &DeclBuilder; - DeclarationNameInfo NameInfo; + DeclarationName Name; QualType ReturnTy; + // method or constructor declaration (CXXConstructorDecl derives from + // CXXMethodDecl) CXXMethodDecl *Method; bool IsConst; - llvm::SmallVector Params; + bool IsConstructor; + llvm::SmallVector Params; llvm::SmallVector StmtsList; // Argument placeholders, inspired by std::placeholder. These are the indices @@ -122,12 +125,14 @@ struct BuiltinTypeMethodBuilder { friend BuiltinTypeDeclBuilder; BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, - QualType ReturnTy, bool IsConst = false) - : DeclBuilder(DB), NameInfo(DeclarationNameInfo(Name, SourceLocation())), -ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) {} - - BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef Name, - QualType ReturnTy, bool IsConst = false); + QualType ReturnTy, bool IsConst = false, + bool IsConstructor = false) + : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr), +IsConst(IsConst), IsConstructor(IsConstructor) {} + + BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, + QualType ReturnTy, bool IsConst = false, + bool IsConstructor = false); BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other) = delete; ~BuiltinTypeMethodBuilder() { finalizeMethod(); } @@ -148,7 +153,14 @@ struct BuiltinTypeMethodBuilder { Expr *getResourceHandleExpr(); private: - void createMethodDecl(); + void createDecl(); + + // Makes sure the declaration is created; should be called before any + // statement added or when access to 'this' is needed. + void ensureCompleteDecl() { +if (!Method) + createDecl(); + } }; TemplateParameterListBuilder::~TemplateParameterListBuilder() { @@ -323,13 +335,26 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { } BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, - StringRef Name, + StringRef NameStr, QualType ReturnTy, - bool IsConst) -: DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) { - const IdentifierInfo &II = - DB.SemaRef.getASTContext().Idents.get(Name, tok::TokenKind::identifier); - NameInfo = DeclarationNameInfo(DeclarationName(&II), SourceLocation()); + bool IsConst, + bool IsConstructor) +: DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst), + IsConstructor(IsConstructor) { + + assert((!NameStr.empty() || IsConstructor) && "method needs a name"); + assert(((IsConstructor && !IsConst) || !IsConstructor) && + "constructor cannot be const"); + + ASTContext &AST = DB.SemaRef.getASTContext(); + if (IsConstructor) { +Name = AST.DeclarationNames.getCXXConstructorName( +DB.Record->getTypeForDecl()->getCanonicalTypeUnqualified()); + } else { +const IdentifierInfo &II = +
[llvm-branch-commits] [clang] [HLSL][NFC] Use builtin method builder to create default resource constructor (PR #131384)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/131384 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][NFC] Use method builder to create default resource constructor (PR #131384)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/131384 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][NFC] Use method builder to create default resource constructor (PR #131384)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/131384 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] DO NOT MERGE - Resource constructors prototype (PR #132453)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/132453 None >From 47b41c88a60a7f376070b9ff779ec955eebf523a Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Wed, 12 Mar 2025 17:20:51 -0700 Subject: [PATCH 1/3] [HLSL] Create default resource constructor with BuiltinTypeMethodBuilder --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 126 ++ 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index db0ed3434d837..a52c6a49264c8 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -89,21 +89,24 @@ struct TemplateParameterListBuilder { // statement (unless the last statement is already a ReturnStmt). struct BuiltinTypeMethodBuilder { private: - struct MethodParam { + struct Param { const IdentifierInfo &NameII; QualType Ty; HLSLParamModifierAttr::Spelling Modifier; -MethodParam(const IdentifierInfo &NameII, QualType Ty, -HLSLParamModifierAttr::Spelling Modifier) +Param(const IdentifierInfo &NameII, QualType Ty, + HLSLParamModifierAttr::Spelling Modifier) : NameII(NameII), Ty(Ty), Modifier(Modifier) {} }; BuiltinTypeDeclBuilder &DeclBuilder; - DeclarationNameInfo NameInfo; + DeclarationName Name; QualType ReturnTy; + // method or constructor declaration (CXXConstructorDecl derives from + // CXXMethodDecl) CXXMethodDecl *Method; bool IsConst; - llvm::SmallVector Params; + bool IsConstructor; + llvm::SmallVector Params; llvm::SmallVector StmtsList; // Argument placeholders, inspired by std::placeholder. These are the indices @@ -122,12 +125,14 @@ struct BuiltinTypeMethodBuilder { friend BuiltinTypeDeclBuilder; BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, DeclarationName &Name, - QualType ReturnTy, bool IsConst = false) - : DeclBuilder(DB), NameInfo(DeclarationNameInfo(Name, SourceLocation())), -ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) {} - - BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef Name, - QualType ReturnTy, bool IsConst = false); + QualType ReturnTy, bool IsConst = false, + bool IsConstructor = false) + : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr), +IsConst(IsConst), IsConstructor(IsConstructor) {} + + BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, + QualType ReturnTy, bool IsConst = false, + bool IsConstructor = false); BuiltinTypeMethodBuilder(const BuiltinTypeMethodBuilder &Other) = delete; ~BuiltinTypeMethodBuilder() { finalizeMethod(); } @@ -148,7 +153,14 @@ struct BuiltinTypeMethodBuilder { Expr *getResourceHandleExpr(); private: - void createMethodDecl(); + void createDecl(); + + // Makes sure the declaration is created; should be called before any + // statement added or when access to 'this' is needed. + void ensureCompleteDecl() { +if (!Method) + createDecl(); + } }; TemplateParameterListBuilder::~TemplateParameterListBuilder() { @@ -323,13 +335,26 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { } BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, - StringRef Name, + StringRef NameStr, QualType ReturnTy, - bool IsConst) -: DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst) { - const IdentifierInfo &II = - DB.SemaRef.getASTContext().Idents.get(Name, tok::TokenKind::identifier); - NameInfo = DeclarationNameInfo(DeclarationName(&II), SourceLocation()); + bool IsConst, + bool IsConstructor) +: DeclBuilder(DB), ReturnTy(ReturnTy), Method(nullptr), IsConst(IsConst), + IsConstructor(IsConstructor) { + + assert((!NameStr.empty() || IsConstructor) && "method needs a name"); + assert(((IsConstructor && !IsConst) || !IsConstructor) && + "constructor cannot be const"); + + ASTContext &AST = DB.SemaRef.getASTContext(); + if (IsConstructor) { +Name = AST.DeclarationNames.getCXXConstructorName( +DB.Record->getTypeForDecl()->getCanonicalTypeUnqualified()); + } else { +const IdentifierInfo &II = +AST.Idents.get(NameStr, tok::TokenKind::identifier); +Name = DeclarationName(&II); + } } BuiltinTypeMethodBuilder & @@ -342,13 +367,13 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty, return *this; } -void BuiltinTypeMethodBuilder::createMethodDecl(
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
@@ -1529,72 +1529,80 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i); return; } - StringRef SlotNumStr = Slot.substr(1); if (SlotNumStr.getAsInteger(10, SlotNum)) { hekota wrote: Good catch! https://github.com/llvm/llvm-project/pull/135287 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] DO NOT MERGE - Resource constructors prototype (PR #132453)
https://github.com/hekota closed https://github.com/llvm/llvm-project/pull/132453 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/135287 >From 6fb658a603f116f29e635e4802a8d77b896150ff Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Thu, 10 Apr 2025 17:31:57 -0700 Subject: [PATCH 1/4] [HLSL] Allow register annotations to specify only `space` Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. --- clang/include/clang/Basic/Attr.td | 11 ++- clang/lib/CodeGen/CGHLSLRuntime.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 74 +++ .../test/AST/HLSL/resource_binding_attr.hlsl | 4 + .../SemaHLSL/resource_binding_attr_error.hlsl | 4 +- test.ll | 7 ++ 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 test.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd9e686485552..1fe37ad4e2d4d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified unsigned SpaceNumber; public: - void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) { + void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) { RegType = RT; SlotNumber = SlotNum; SpaceNumber = SpaceNum; } + bool isImplicit() const { +return SlotNumber < 0; + } RegisterType getRegisterType() const { +assert(!isImplicit() && "binding does not have register slot"); return RegType; } unsigned getSlotNumber() const { -return SlotNumber; +assert(!isImplicit() && "binding does not have register slot"); +return (unsigned)SlotNumber; } unsigned getSpaceNumber() const { return SpaceNumber; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 450213fcec676..e42bb8e16e80b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { BufDecl->getAttr(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) - if (RBA) + if (RBA && !RBA->isImplicit()) initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), RBA->getSpaceNumber()); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 27959f61f1dc3..73b8c19840026 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i); return; } - StringRef SlotNumStr = Slot.substr(1); if (SlotNumStr.getAsInteger(10, SlotNum)) { - Diag(ArgLoc, diag::err_hlsl_u
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/135287 >From 6fb658a603f116f29e635e4802a8d77b896150ff Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Thu, 10 Apr 2025 17:31:57 -0700 Subject: [PATCH 1/5] [HLSL] Allow register annotations to specify only `space` Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. --- clang/include/clang/Basic/Attr.td | 11 ++- clang/lib/CodeGen/CGHLSLRuntime.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 74 +++ .../test/AST/HLSL/resource_binding_attr.hlsl | 4 + .../SemaHLSL/resource_binding_attr_error.hlsl | 4 +- test.ll | 7 ++ 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 test.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd9e686485552..1fe37ad4e2d4d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified unsigned SpaceNumber; public: - void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) { + void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) { RegType = RT; SlotNumber = SlotNum; SpaceNumber = SpaceNum; } + bool isImplicit() const { +return SlotNumber < 0; + } RegisterType getRegisterType() const { +assert(!isImplicit() && "binding does not have register slot"); return RegType; } unsigned getSlotNumber() const { -return SlotNumber; +assert(!isImplicit() && "binding does not have register slot"); +return (unsigned)SlotNumber; } unsigned getSpaceNumber() const { return SpaceNumber; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 450213fcec676..e42bb8e16e80b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { BufDecl->getAttr(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) - if (RBA) + if (RBA && !RBA->isImplicit()) initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), RBA->getSpaceNumber()); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 27959f61f1dc3..73b8c19840026 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i); return; } - StringRef SlotNumStr = Slot.substr(1); if (SlotNumStr.getAsInteger(10, SlotNum)) { - Diag(ArgLoc, diag::err_hlsl_u
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
@@ -4723,20 +4723,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified hekota wrote: Good catch! DXC actually ignores the register `u4294967295` and uses `u0` instead, but that is a bug. :) We should support the whole `uint32_t` range. https://github.com/llvm/llvm-project/pull/135287 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implementation of DXILResourceImplicitBinding pass (PR #138043)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/138043 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement DXILResourceImplicitBinding pass (PR #138043)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/138043 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Implement DXILResourceImplicitBinding pass (PR #138043)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/138043 >From f58e2d5c079f31d7a4d99d481a569ad4c754c4e7 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Wed, 30 Apr 2025 15:08:04 -0700 Subject: [PATCH 1/2] [HLSL] Implementation of DXILResourceImplicitBinding pass This pass takes advantage of the DXILResourceBinding analysis and assigns register slots to resources that do not have explicit binding. Part 2/2 of #136786 Closes #136786 --- llvm/include/llvm/Analysis/DXILResource.h | 8 + llvm/include/llvm/InitializePasses.h | 1 + llvm/lib/Analysis/Analysis.cpp| 1 + llvm/lib/Analysis/DXILResource.cpp| 53 + llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../DirectX/DXILResourceImplicitBinding.cpp | 182 ++ .../DirectX/DXILResourceImplicitBinding.h | 29 +++ llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXPassRegistry.def| 1 + .../Target/DirectX/DirectXTargetMachine.cpp | 3 + .../CodeGen/DirectX/ImplicitBinding/arrays.ll | 41 .../ImplicitBinding/multiple-spaces.ll| 44 + .../CodeGen/DirectX/ImplicitBinding/simple.ll | 30 +++ .../ImplicitBinding/unbounded-arrays-error.ll | 34 .../ImplicitBinding/unbounded-arrays.ll | 42 llvm/test/CodeGen/DirectX/llc-pipeline.ll | 2 + 16 files changed, 478 insertions(+) create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/simple.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays-error.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays.ll diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 569f5346b9e36..fd34fdfda4c1c 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -632,12 +632,15 @@ class DXILResourceBindingInfo { RegisterSpace(uint32_t Space) : Space(Space) { FreeRanges.emplace_back(0, UINT32_MAX); } +// Size == -1 means unbounded array +bool findAvailableBinding(int32_t Size, uint32_t *RegSlot); }; struct BindingSpaces { dxil::ResourceClass ResClass; llvm::SmallVector Spaces; BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {} +RegisterSpace &getOrInsertSpace(uint32_t Space); }; private: @@ -658,6 +661,7 @@ class DXILResourceBindingInfo { OverlappingBinding(false) {} bool hasImplicitBinding() const { return ImplicitBinding; } + void setHasImplicitBinding(bool Value) { ImplicitBinding = Value; } bool hasOverlappingBinding() const { return OverlappingBinding; } BindingSpaces &getBindingSpaces(dxil::ResourceClass RC) { @@ -673,6 +677,10 @@ class DXILResourceBindingInfo { } } + // Size == -1 means unbounded array + bool findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, +int32_t Size, uint32_t *RegSlot); + friend class DXILResourceBindingAnalysis; friend class DXILResourceBindingWrapperPass; }; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index b84c6d6123d58..71db56d922676 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -85,6 +85,7 @@ void initializeDCELegacyPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &); void initializeDXILResourceBindingWrapperPassPass(PassRegistry &); +void initializeDXILResourceImplicitBindingLegacyPass(PassRegistry &); void initializeDXILResourceTypeWrapperPassPass(PassRegistry &); void initializeDXILResourceWrapperPassPass(PassRegistry &); void initializeDeadMachineInstructionElimPass(PassRegistry &); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 484a456f49f1b..9f5daf32be9a0 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -27,6 +27,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeCallGraphViewerPass(Registry); initializeCycleInfoWrapperPassPass(Registry); initializeDXILMetadataAnalysisWrapperPassPass(Registry); + initializeDXILResourceWrapperPassPass(Registry); initializeDXILResourceBindingWrapperPassPass(Registry); initializeDXILResourceTypeWrapperPassPass(Registry); initializeDXILResourceWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index ce8e250a32ebe..34355c81e77b0 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib
[llvm-branch-commits] [llvm] [HLSL] Implementation of DXILResourceImplicitBinding pass (PR #138043)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/138043 The `DXILResourceImplicitBinding` pass uses the results of `DXILResourceBindingAnalysis` to assigns register slots to resources that do not have explicit binding. It replaces all `llvm.dx.resource.handlefromimplicitbinding` calls with `llvm.dx.resource.handlefrombinding` using the newly assigned binding. If a binding cannot be found for a resource, the pass will raise a diagnostic error. Currently this diagnostic message does not include the resource name, which will be addressed in a separate task (#137868). Part 2/2 of #136786 Closes #136786 >From f58e2d5c079f31d7a4d99d481a569ad4c754c4e7 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Wed, 30 Apr 2025 15:08:04 -0700 Subject: [PATCH] [HLSL] Implementation of DXILResourceImplicitBinding pass This pass takes advantage of the DXILResourceBinding analysis and assigns register slots to resources that do not have explicit binding. Part 2/2 of #136786 Closes #136786 --- llvm/include/llvm/Analysis/DXILResource.h | 8 + llvm/include/llvm/InitializePasses.h | 1 + llvm/lib/Analysis/Analysis.cpp| 1 + llvm/lib/Analysis/DXILResource.cpp| 53 + llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../DirectX/DXILResourceImplicitBinding.cpp | 182 ++ .../DirectX/DXILResourceImplicitBinding.h | 29 +++ llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXPassRegistry.def| 1 + .../Target/DirectX/DirectXTargetMachine.cpp | 3 + .../CodeGen/DirectX/ImplicitBinding/arrays.ll | 41 .../ImplicitBinding/multiple-spaces.ll| 44 + .../CodeGen/DirectX/ImplicitBinding/simple.ll | 30 +++ .../ImplicitBinding/unbounded-arrays-error.ll | 34 .../ImplicitBinding/unbounded-arrays.ll | 42 llvm/test/CodeGen/DirectX/llc-pipeline.ll | 2 + 16 files changed, 478 insertions(+) create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/simple.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays-error.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays.ll diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 569f5346b9e36..fd34fdfda4c1c 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -632,12 +632,15 @@ class DXILResourceBindingInfo { RegisterSpace(uint32_t Space) : Space(Space) { FreeRanges.emplace_back(0, UINT32_MAX); } +// Size == -1 means unbounded array +bool findAvailableBinding(int32_t Size, uint32_t *RegSlot); }; struct BindingSpaces { dxil::ResourceClass ResClass; llvm::SmallVector Spaces; BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {} +RegisterSpace &getOrInsertSpace(uint32_t Space); }; private: @@ -658,6 +661,7 @@ class DXILResourceBindingInfo { OverlappingBinding(false) {} bool hasImplicitBinding() const { return ImplicitBinding; } + void setHasImplicitBinding(bool Value) { ImplicitBinding = Value; } bool hasOverlappingBinding() const { return OverlappingBinding; } BindingSpaces &getBindingSpaces(dxil::ResourceClass RC) { @@ -673,6 +677,10 @@ class DXILResourceBindingInfo { } } + // Size == -1 means unbounded array + bool findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, +int32_t Size, uint32_t *RegSlot); + friend class DXILResourceBindingAnalysis; friend class DXILResourceBindingWrapperPass; }; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index b84c6d6123d58..71db56d922676 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -85,6 +85,7 @@ void initializeDCELegacyPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &); void initializeDXILResourceBindingWrapperPassPass(PassRegistry &); +void initializeDXILResourceImplicitBindingLegacyPass(PassRegistry &); void initializeDXILResourceTypeWrapperPassPass(PassRegistry &); void initializeDXILResourceWrapperPassPass(PassRegistry &); void initializeDeadMachineInstructionElimPass(PassRegistry &); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 484a456f49f1b..9f5daf32be9a0 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -27,6 +27,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
[llvm-branch-commits] [llvm] [HLSL] Implementation of DXILResourceImplicitBinding pass (PR #138043)
@@ -0,0 +1,44 @@ +; RUN: opt -S -dxil-resource-implicit-binding %s | FileCheck %s hekota wrote: I just realized this test is not complete... working on a fix. https://github.com/llvm/llvm-project/pull/138043 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/135287 >From 6fb658a603f116f29e635e4802a8d77b896150ff Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Thu, 10 Apr 2025 17:31:57 -0700 Subject: [PATCH 1/3] [HLSL] Allow register annotations to specify only `space` Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. --- clang/include/clang/Basic/Attr.td | 11 ++- clang/lib/CodeGen/CGHLSLRuntime.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 74 +++ .../test/AST/HLSL/resource_binding_attr.hlsl | 4 + .../SemaHLSL/resource_binding_attr_error.hlsl | 4 +- test.ll | 7 ++ 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 test.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd9e686485552..1fe37ad4e2d4d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified unsigned SpaceNumber; public: - void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) { + void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) { RegType = RT; SlotNumber = SlotNum; SpaceNumber = SpaceNum; } + bool isImplicit() const { +return SlotNumber < 0; + } RegisterType getRegisterType() const { +assert(!isImplicit() && "binding does not have register slot"); return RegType; } unsigned getSlotNumber() const { -return SlotNumber; +assert(!isImplicit() && "binding does not have register slot"); +return (unsigned)SlotNumber; } unsigned getSpaceNumber() const { return SpaceNumber; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 450213fcec676..e42bb8e16e80b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { BufDecl->getAttr(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) - if (RBA) + if (RBA && !RBA->isImplicit()) initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), RBA->getSpaceNumber()); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 27959f61f1dc3..73b8c19840026 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i); return; } - StringRef SlotNumStr = Slot.substr(1); if (SlotNumStr.getAsInteger(10, SlotNum)) { - Diag(ArgLoc, diag::err_hlsl_u
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota ready_for_review https://github.com/llvm/llvm-project/pull/135287 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/135287 >From 6fb658a603f116f29e635e4802a8d77b896150ff Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Thu, 10 Apr 2025 17:31:57 -0700 Subject: [PATCH 1/2] [HLSL] Allow register annotations to specify only `space` Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. --- clang/include/clang/Basic/Attr.td | 11 ++- clang/lib/CodeGen/CGHLSLRuntime.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 74 +++ .../test/AST/HLSL/resource_binding_attr.hlsl | 4 + .../SemaHLSL/resource_binding_attr_error.hlsl | 4 +- test.ll | 7 ++ 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 test.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd9e686485552..1fe37ad4e2d4d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified unsigned SpaceNumber; public: - void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) { + void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) { RegType = RT; SlotNumber = SlotNum; SpaceNumber = SpaceNum; } + bool isImplicit() const { +return SlotNumber < 0; + } RegisterType getRegisterType() const { +assert(!isImplicit() && "binding does not have register slot"); return RegType; } unsigned getSlotNumber() const { -return SlotNumber; +assert(!isImplicit() && "binding does not have register slot"); +return (unsigned)SlotNumber; } unsigned getSpaceNumber() const { return SpaceNumber; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 450213fcec676..e42bb8e16e80b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { BufDecl->getAttr(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) - if (RBA) + if (RBA && !RBA->isImplicit()) initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), RBA->getSpaceNumber()); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 27959f61f1dc3..73b8c19840026 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i); return; } - StringRef SlotNumStr = Slot.substr(1); if (SlotNumStr.getAsInteger(10, SlotNum)) { - Diag(ArgLoc, diag::err_hlsl_u
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/135287 Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. Fixes #133346 Depends on PR #135120 >From 6fb658a603f116f29e635e4802a8d77b896150ff Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Thu, 10 Apr 2025 17:31:57 -0700 Subject: [PATCH] [HLSL] Allow register annotations to specify only `space` Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space. --- clang/include/clang/Basic/Attr.td | 11 ++- clang/lib/CodeGen/CGHLSLRuntime.cpp | 2 +- clang/lib/Sema/SemaHLSL.cpp | 74 +++ .../test/AST/HLSL/resource_binding_attr.hlsl | 4 + .../SemaHLSL/resource_binding_attr_error.hlsl | 4 +- test.ll | 7 ++ 6 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 test.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fd9e686485552..1fe37ad4e2d4d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr { private: RegisterType RegType; - unsigned SlotNumber; + int SlotNumber; // -1 if the register slot was not specified unsigned SpaceNumber; public: - void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) { + void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) { RegType = RT; SlotNumber = SlotNum; SpaceNumber = SpaceNum; } + bool isImplicit() const { +return SlotNumber < 0; + } RegisterType getRegisterType() const { +assert(!isImplicit() && "binding does not have register slot"); return RegType; } unsigned getSlotNumber() const { -return SlotNumber; +assert(!isImplicit() && "binding does not have register slot"); +return (unsigned)SlotNumber; } unsigned getSpaceNumber() const { return SpaceNumber; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 450213fcec676..e42bb8e16e80b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { BufDecl->getAttr(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) - if (RBA) + if (RBA && !RBA->isImplicit()) initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), RBA->getSpaceNumber()); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 27959f61f1dc3..73b8c19840026 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) { diag::err_incomplete_type)) return; } - StringRef Space = "space0"; + StringRef Slot = ""; + StringRef Space = ""; + SourceLocation SlotLoc, SpaceLoc; if (!AL.isArgIdent(0)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Str = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; - SourceLocation SpaceArgLoc; - bool SpecifiedSpace = false; if (AL.getNumArgs() == 2) { -SpecifiedSpace = true; -Slot = Str; +Slot = Loc->Ident->getName(); +SlotLoc = Loc->Loc; + if (!AL.isArgIdent(1)) { Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL << AANT_ArgumentIdentifier; return; } -IdentifierLoc *Loc = AL.getArgAsIdent(1); +Loc = AL.getArgAsIdent(1); Space = Loc->Ident->getName(); -SpaceArgLoc = Loc->Loc; +SpaceLoc = Loc->Loc; } else { -Slot = Str; +StringRef Str = Loc->Ident->getName(); +if (Str.starts_with("space")) { + Space = Str; + SpaceLoc = Loc->Loc; +} else { + Slot = Str; + SlotLoc = Loc->Loc; + Space = "space0"; +} } - RegisterType RegType; - unsigned SlotNum = 0; + RegisterType RegType = RegisterType::SRV; + int SlotNum = -1; unsigned SpaceNum = 0; - // Validate. + // Validate slot if (!Slot.empty()) { if (!convertToRegisterType(Slot, &RegType)) { - Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); + Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1); return; } if (RegType == RegisterType::I) { - Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i); + Diag
[llvm-branch-commits] [llvm] [DirectX] Implement DXILResourceImplicitBinding pass (PR #138043)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/138043 >From f58e2d5c079f31d7a4d99d481a569ad4c754c4e7 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Wed, 30 Apr 2025 15:08:04 -0700 Subject: [PATCH 1/2] [HLSL] Implementation of DXILResourceImplicitBinding pass This pass takes advantage of the DXILResourceBinding analysis and assigns register slots to resources that do not have explicit binding. Part 2/2 of #136786 Closes #136786 --- llvm/include/llvm/Analysis/DXILResource.h | 8 + llvm/include/llvm/InitializePasses.h | 1 + llvm/lib/Analysis/Analysis.cpp| 1 + llvm/lib/Analysis/DXILResource.cpp| 53 + llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../DirectX/DXILResourceImplicitBinding.cpp | 182 ++ .../DirectX/DXILResourceImplicitBinding.h | 29 +++ llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXPassRegistry.def| 1 + .../Target/DirectX/DirectXTargetMachine.cpp | 3 + .../CodeGen/DirectX/ImplicitBinding/arrays.ll | 41 .../ImplicitBinding/multiple-spaces.ll| 44 + .../CodeGen/DirectX/ImplicitBinding/simple.ll | 30 +++ .../ImplicitBinding/unbounded-arrays-error.ll | 34 .../ImplicitBinding/unbounded-arrays.ll | 42 llvm/test/CodeGen/DirectX/llc-pipeline.ll | 2 + 16 files changed, 478 insertions(+) create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp create mode 100644 llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/simple.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays-error.ll create mode 100644 llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays.ll diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 569f5346b9e36..fd34fdfda4c1c 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -632,12 +632,15 @@ class DXILResourceBindingInfo { RegisterSpace(uint32_t Space) : Space(Space) { FreeRanges.emplace_back(0, UINT32_MAX); } +// Size == -1 means unbounded array +bool findAvailableBinding(int32_t Size, uint32_t *RegSlot); }; struct BindingSpaces { dxil::ResourceClass ResClass; llvm::SmallVector Spaces; BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {} +RegisterSpace &getOrInsertSpace(uint32_t Space); }; private: @@ -658,6 +661,7 @@ class DXILResourceBindingInfo { OverlappingBinding(false) {} bool hasImplicitBinding() const { return ImplicitBinding; } + void setHasImplicitBinding(bool Value) { ImplicitBinding = Value; } bool hasOverlappingBinding() const { return OverlappingBinding; } BindingSpaces &getBindingSpaces(dxil::ResourceClass RC) { @@ -673,6 +677,10 @@ class DXILResourceBindingInfo { } } + // Size == -1 means unbounded array + bool findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, +int32_t Size, uint32_t *RegSlot); + friend class DXILResourceBindingAnalysis; friend class DXILResourceBindingWrapperPass; }; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index b84c6d6123d58..71db56d922676 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -85,6 +85,7 @@ void initializeDCELegacyPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &); void initializeDXILResourceBindingWrapperPassPass(PassRegistry &); +void initializeDXILResourceImplicitBindingLegacyPass(PassRegistry &); void initializeDXILResourceTypeWrapperPassPass(PassRegistry &); void initializeDXILResourceWrapperPassPass(PassRegistry &); void initializeDeadMachineInstructionElimPass(PassRegistry &); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 484a456f49f1b..9f5daf32be9a0 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -27,6 +27,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeCallGraphViewerPass(Registry); initializeCycleInfoWrapperPassPass(Registry); initializeDXILMetadataAnalysisWrapperPassPass(Registry); + initializeDXILResourceWrapperPassPass(Registry); initializeDXILResourceBindingWrapperPassPass(Registry); initializeDXILResourceTypeWrapperPassPass(Registry); initializeDXILResourceWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index ce8e250a32ebe..34355c81e77b0 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/135287 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [HLSL] Allow resource annotations to specify only register space (PR #135287)
@@ -163,11 +163,16 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs, SourceLocation SlotLoc = Tok.getLocation(); ArgExprs.push_back(ParseIdentifierLoc()); -// Add numeric_constant for fix-it. -if (SlotStr.size() == 1 && Tok.is(tok::numeric_constant)) +if (SlotStr.size() == 1) { + if (!Tok.is(tok::numeric_constant)) { +Diag(Tok.getLocation(), diag::err_expected) << tok::numeric_constant; +SkipUntil(tok::r_paren, StopAtSemi); // skip through ) hekota wrote: It is for error state recovery. The SkipUntil call tells the parser to move forward until it finds a closing `)` or ';'. After the code returns the parser will resume parsing tokens of the next statement. https://github.com/llvm/llvm-project/pull/135287 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota ready_for_review https://github.com/llvm/llvm-project/pull/125807 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
@@ -286,10 +286,7 @@ void CGHLSLRuntime::emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl, .str( && "layout type does not match the converted element type"); -// there might be resources inside the used defined structs -if (VDTy->isStructureType() && VDTy->isHLSLIntangibleType()) - // FIXME: handle resources in cbuffer structs - llvm_unreachable("resources in cbuffer are not supported yet"); +// FIXME: handle resources in cbuffer user-defined structs hekota wrote: Yes, this is a future work (llvm/wg-hlsl#175). I've removed the `llvm_unreachable` because we use it in existing tests. https://github.com/llvm/llvm-project/pull/125807 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/125807 >From 42bb34f66f0030f55e1055c4ee0b362511b7f45b Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 4 Feb 2025 22:01:49 -0800 Subject: [PATCH 1/5] [HLSL] Implement default constant buffer `$Globals` All variable declarations in the global scope that are not resources, static or empty are implicitly added to implicit constant buffer `$Globals`. Fixes #123801 --- clang/include/clang/AST/Decl.h | 22 +++ clang/include/clang/Sema/SemaHLSL.h | 7 ++- clang/lib/AST/Decl.cpp | 41 - clang/lib/CodeGen/CGHLSLRuntime.cpp | 7 +-- clang/lib/CodeGen/CodeGenModule.cpp | 5 ++ clang/lib/Sema/Sema.cpp | 3 +- clang/lib/Sema/SemaHLSL.cpp | 47 +-- clang/test/AST/HLSL/default_cbuffer.hlsl| 50 clang/test/CodeGenHLSL/basic_types.hlsl | 64 ++--- clang/test/CodeGenHLSL/default_cbuffer.hlsl | 43 ++ 10 files changed, 242 insertions(+), 47 deletions(-) create mode 100644 clang/test/AST/HLSL/default_cbuffer.hlsl create mode 100644 clang/test/CodeGenHLSL/default_cbuffer.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 05e56978977f2..f86ddaf89bd9c 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -5038,6 +5038,11 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { // LayoutStruct - Layout struct for the buffer CXXRecordDecl *LayoutStruct; + // For default (implicit) constant buffer, a lisf of references of global + // decls that belong to the buffer. The decls are already parented by the + // translation unit context. + SmallVector DefaultBufferDecls; + HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); @@ -5047,6 +5052,8 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); + static HLSLBufferDecl *CreateDefaultCBuffer(ASTContext &C, + DeclContext *LexicalParent); static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { @@ -5061,6 +5068,7 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { bool hasPackoffset() const { return HasPackoffset; } const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; } void addLayoutStruct(CXXRecordDecl *LS); + void addDefaultBufferDecl(Decl *D); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -5072,6 +5080,20 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext { return static_cast(const_cast(DC)); } + // Iterator for the buffer decls. Concatenates the list of decls parented + // by this HLSLBufferDecl with the list of default buffer decls. + using buffer_decl_iterator = + llvm::concat_iterator::const_iterator, +decl_iterator>; + using buffer_decl_range = llvm::iterator_range; + + buffer_decl_range buffer_decls() const { +return buffer_decl_range(buffer_decls_begin(), buffer_decls_end()); + } + buffer_decl_iterator buffer_decls_begin() const; + buffer_decl_iterator buffer_decls_end() const; + bool buffer_decls_empty(); + friend class ASTDeclReader; friend class ASTDeclWriter; }; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f4cd11f423a84..b1cc856975532 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -103,13 +103,13 @@ class SemaHLSL : public SemaBase { HLSLParamModifierAttr::Spelling Spelling); void ActOnTopLevelFunction(FunctionDecl *FD); void ActOnVariableDeclarator(VarDecl *VD); + void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU); void CheckEntryPoint(FunctionDecl *FD); void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr); void DiagnoseAttrStageMismatch( const Attr *A, llvm::Triple::EnvironmentType Stage, std::initializer_list AllowedStages); - void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, @@ -159,11 +159,16 @@ class SemaHLSL : public SemaBase { // List of all resource bindings ResourceBindings Bindings; + // default constant buffer $Globals + HLSL
[llvm-branch-commits] [clang] [HLSL] Implement default constant buffer `$Globals` (PR #125807)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/125807 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits