Skip to content

Commit d02cb55

Browse files
committed
introduce a MetadataBuilder to handle the construction of nodes
1 parent 671f099 commit d02cb55

File tree

5 files changed

+118
-17
lines changed

5 files changed

+118
-17
lines changed

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,14 @@ void addRootSignature(
124124
llvm::Function *Fn, llvm::Module &M) {
125125
auto &Ctx = M.getContext();
126126

127-
SmallVector<Metadata *> GeneratedMetadata;
128-
for (auto Element : Elements) {
129-
MDNode *ExampleRootElement = MDNode::get(Ctx, {});
130-
GeneratedMetadata.push_back(ExampleRootElement);
131-
}
132-
133-
MDNode *ExampleRootSignature = MDNode::get(Ctx, GeneratedMetadata);
134-
135-
MDNode *ExamplePairing = MDNode::get(Ctx, {ValueAsMetadata::get(Fn),
136-
ExampleRootSignature});
127+
llvm::hlsl::root_signature::MetadataBuilder Builder(Ctx, Elements);
128+
MDNode *RootSignature = Builder.BuildRootSignature();
129+
MDNode *FnPairing = MDNode::get(Ctx, {ValueAsMetadata::get(Fn),
130+
RootSignature});
137131

138132
StringRef RootSignatureValKey = "dx.rootsignatures";
139133
auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey);
140-
RootSignatureValMD->addOperand(ExamplePairing);
134+
RootSignatureValMD->addOperand(FnPairing);
141135
}
142136

143137
} // namespace
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -o - %s | FileCheck %s
22

33
// CHECK-DAG: ![[#EMPTY:]] = !{}
4-
// CHECK-DAG: ![[#SECOND_RS:]] = !{![[#EMPTY]]}
5-
// CHECK-DAG: ![[#SECOND_ENTRY:]] = !{ptr @SecondEntry, ![[#SECOND_RS]]}
6-
// CHECK-DAG: ![[#FIRST_ENTRY:]] = !{ptr @FirstEntry, ![[#EMPTY]]}
7-
// CHECK-DAG: !dx.rootsignatures = !{![[#FIRST_ENTRY]], ![[#SECOND_ENTRY]]}
8-
94
[shader("compute"), RootSignature("")]
105
[numthreads(1,1,1)]
116
void FirstEntry() {}
127

13-
[shader("compute"), RootSignature("DescriptorTable()")]
8+
// CHECK-DAG: ![[#TABLE:]] = !{!"DescriptorTable"}
9+
// CHECK-DAG: ![[#SECOND_RS:]] = !{![[#TABLE]]}
10+
11+
#define SampleDescriptorTable \
12+
"DescriptorTable( " \
13+
")"
14+
[shader("compute"), RootSignature(SampleDescriptorTable)]
1415
[numthreads(1,1,1)]
1516
void SecondEntry() {}
1617

1718
// Sanity test to ensure to root is added for this function
1819
[shader("compute")]
1920
[numthreads(1,1,1)]
2021
void ThirdEntry() {}
22+
23+
// CHECK-DAG: ![[#FIRST_ENTRY:]] = !{ptr @FirstEntry, ![[#EMPTY]]}
24+
// CHECK-DAG: ![[#SECOND_ENTRY:]] = !{ptr @SecondEntry, ![[#SECOND_RS]]}
25+
// CHECK-DAG: !dx.rootsignatures = !{![[#FIRST_ENTRY]], ![[#SECOND_ENTRY]]}

llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@
1414
#ifndef LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H
1515
#define LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H
1616

17+
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/STLForwardCompat.h"
1719
#include "llvm/Support/DXILABI.h"
1820
#include <variant>
1921

2022
namespace llvm {
23+
class LLVMContext;
24+
class MDNode;
25+
class Metadata;
26+
2127
namespace hlsl {
2228
namespace rootsig {
2329

@@ -122,6 +128,24 @@ using RootElement = std::variant<DescriptorTable, DescriptorTableClause>;
122128
using ParamType = std::variant<uint32_t *, DescriptorRangeOffset *,
123129
DescriptorRangeFlags *, ShaderVisibility *>;
124130

131+
class MetadataBuilder {
132+
public:
133+
MetadataBuilder(llvm::LLVMContext &Ctx, ArrayRef<RootElement> Elements)
134+
: Ctx(Ctx), Elements(Elements) {}
135+
136+
// Iterates through the elements and builds the respective nodes
137+
MDNode *BuildRootSignature();
138+
139+
private:
140+
// Define the various builders for the different metadata types
141+
MDNode *BuildDescriptorTable(const DescriptorTable &Table);
142+
MDNode *BuildDescriptorTableClause(const DescriptorTableClause &Clause);
143+
144+
llvm::LLVMContext &Ctx;
145+
ArrayRef<RootElement> Elements;
146+
SmallVector<Metadata *> GeneratedMetadata;
147+
};
148+
125149
} // namespace rootsig
126150
} // namespace hlsl
127151
} // namespace llvm

llvm/lib/Frontend/HLSL/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_llvm_component_library(LLVMFrontendHLSL
22
HLSLResource.cpp
3+
HLSLRootSignature.cpp
34

45
ADDITIONAL_HEADER_DIRS
56
${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===- HLSLRootSignature.cpp - HLSL Root Signature helper objects ----------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file This file contains helpers for working with HLSL Root Signatures.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
14+
#include "llvm/IR/IRBuilder.h"
15+
#include "llvm/IR/Metadata.h"
16+
#include "llvm/IR/Module.h"
17+
18+
namespace llvm {
19+
namespace hlsl {
20+
namespace root_signature {
21+
22+
static MDString *ClauseTypeToName(LLVMContext &Ctx, ClauseType Type) {
23+
StringRef Name;
24+
switch (Type) {
25+
case ClauseType::CBuffer:
26+
Name = "CBV";
27+
break;
28+
case ClauseType::SRV:
29+
Name = "SRV";
30+
break;
31+
case ClauseType::UAV:
32+
Name = "UAV";
33+
break;
34+
case ClauseType::Sampler:
35+
Name = "Sampler";
36+
break;
37+
}
38+
return MDString::get(Ctx, Name);
39+
}
40+
41+
// Helper struct so that we can use the overloaded notation of std::visit
42+
template <class... Ts> struct OverloadBuilds : Ts... {
43+
using Ts::operator()...;
44+
};
45+
template <class... Ts> OverloadBuilds(Ts...) -> OverloadBuilds<Ts...>;
46+
47+
MDNode *MetadataBuilder::BuildRootSignature() {
48+
for (const RootElement &Element : Elements) {
49+
MDNode *ElementMD =
50+
std::visit(
51+
OverloadBuilds{
52+
[&](DescriptorTable Table) -> MDNode * {
53+
return BuildDescriptorTable(Table);
54+
},
55+
[&](DescriptorTableClause Clause) -> MDNode * {
56+
return BuildDescriptorTableClause(Clause);
57+
},
58+
},
59+
Element);
60+
GeneratedMetadata.push_back(ElementMD);
61+
}
62+
63+
return MDNode::get(Ctx, GeneratedMetadata);
64+
}
65+
66+
MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) {
67+
return MDNode::get(Ctx, {MDString::get(Ctx, "DescriptorTable")});
68+
}
69+
70+
MDNode *MetadataBuilder::BuildDescriptorTableClause(const DescriptorTableClause &Clause) {
71+
return MDNode::get(Ctx, {ClauseTypeToName(Ctx, Clause.Type)});
72+
}
73+
74+
} // namespace root_signature
75+
} // namespace hlsl
76+
} // namespace llvm
77+

0 commit comments

Comments
 (0)