1
- // ===- DXILRootSignature.cpp - DXIL Root Signature helper objects
2
- // ---------------===//
1
+ // ===- DXILRootSignature.cpp - DXIL Root Signature helper objects ----===//
3
2
//
4
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
4
// See https://llvm.org/LICENSE.txt for license information.
14
13
#include " DXILRootSignature.h"
15
14
#include " DirectX.h"
16
15
#include " llvm/ADT/StringSwitch.h"
16
+ #include " llvm/ADT/Twine.h"
17
17
#include " llvm/IR/Constants.h"
18
- #include " llvm/IR/Metadata.h"
19
18
#include " llvm/IR/Module.h"
19
+ #include < cstdint>
20
20
21
21
using namespace llvm ;
22
22
using namespace llvm ::dxil;
23
23
24
+ static bool reportError (Twine Message) {
25
+ report_fatal_error (Message, false );
26
+ return true ;
27
+ }
28
+
24
29
static bool parseRootFlags (ModuleRootSignature *MRS, MDNode *RootFlagNode) {
25
30
26
- assert (RootFlagNode->getNumOperands () == 2 &&
27
- " Invalid format for RootFlag Element" );
31
+ if (RootFlagNode->getNumOperands () != 2 )
32
+ return reportError (" Invalid format for RootFlag Element" );
33
+
28
34
auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand (1 ));
29
- auto Value = Flag->getZExtValue ();
35
+ uint32_t Value = Flag->getZExtValue ();
30
36
31
37
// Root Element validation, as specified:
32
38
// https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#validations-during-dxil-generation
33
- assert ((Value & ~0x80000fff ) == 0 && " Invalid flag for RootFlag Element" );
39
+ if ((Value & ~0x80000fff ) != 0 )
40
+ return reportError (" Invalid flag value for RootFlag" );
34
41
35
42
MRS->Flags = Value;
36
43
return false ;
@@ -39,8 +46,8 @@ static bool parseRootFlags(ModuleRootSignature *MRS, MDNode *RootFlagNode) {
39
46
static bool parseRootSignatureElement (ModuleRootSignature *MRS,
40
47
MDNode *Element) {
41
48
MDString *ElementText = cast<MDString>(Element->getOperand (0 ));
42
- assert (ElementText != nullptr &&
43
- " First preoperty of element is not a string " );
49
+ if (ElementText == nullptr )
50
+ return reportError ( " Invalid format for Root Element " );
44
51
45
52
RootSignatureElementKind ElementKind =
46
53
StringSwitch<RootSignatureElementKind>(ElementText->getString ())
@@ -66,7 +73,7 @@ static bool parseRootSignatureElement(ModuleRootSignature *MRS,
66
73
case RootSignatureElementKind::DescriptorTable:
67
74
case RootSignatureElementKind::StaticSampler:
68
75
case RootSignatureElementKind::None:
69
- llvm_unreachable ( " Not Implemented yet " );
76
+ return reportError ( " Invalid Root Element: " + ElementText-> getString () );
70
77
break ;
71
78
}
72
79
@@ -77,49 +84,67 @@ bool ModuleRootSignature::parse(int32_t Version, NamedMDNode *Root) {
77
84
this ->Version = Version;
78
85
bool HasError = false ;
79
86
87
+ /* * Root Signature are specified as following in the metadata:
88
+
89
+ !dx.rootsignatures = !{!2} ; list of function/root signature pairs
90
+ !2 = !{ ptr @main, !3 } ; function, root signature
91
+ !3 = !{ !4, !5, !6, !7 } ; list of root signature elements
92
+
93
+ So for each MDNode inside dx.rootsignatures NamedMDNode
94
+ (the Root parameter of this function), the parsing process needs
95
+ to loop through each of it's operand and process the pairs function
96
+ signature pair.
97
+ */
98
+
80
99
for (unsigned int Sid = 0 ; Sid < Root->getNumOperands (); Sid++) {
81
- // This should be an if, for error handling
82
- MDNode *Node = cast<MDNode>(Root->getOperand (Sid));
100
+ MDNode *Node = dyn_cast<MDNode>(Root->getOperand (Sid));
101
+
102
+ if (Node == nullptr || Node->getNumOperands () != 2 )
103
+ return reportError (" Invalid format for Root Signature Definition. Pairs "
104
+ " of function, root signature expected." );
105
+
106
+ // Get the Root Signature Description from the function signature pair.
107
+ MDNode *RS = dyn_cast<MDNode>(Node->getOperand (1 ).get ());
83
108
84
- // Not sure what use this for...
85
- // Metadata *Func = Node->getOperand(0).get( );
109
+ if (RS == nullptr )
110
+ return reportError ( " Missing Root Signature Metadata node. " );
86
111
87
- MDNode * Elements = cast<MDNode>(Node-> getOperand ( 1 ). get ());
88
- assert (Elements && " Invalid Metadata type on root signature " );
112
+ // Loop through the Root Elements of the root signature.
113
+ for ( unsigned int Eid = 0 ; Eid < RS-> getNumOperands (); Eid++) {
89
114
90
- for ( unsigned int Eid = 0 ; Eid < Elements-> getNumOperands (); Eid++) {
91
- MDNode * Element = cast<MDNode>(Elements-> getOperand (Eid));
92
- assert (Element && " Invalid Metadata type on root element " );
115
+ MDNode *Element = dyn_cast<MDNode>(RS-> getOperand ( Eid));
116
+ if ( Element == nullptr )
117
+ return reportError ( " Missing Root Element Metadata Node. " );
93
118
94
119
HasError = HasError || parseRootSignatureElement (this , Element);
95
120
}
96
121
}
97
122
return HasError;
98
123
}
99
124
100
- AnalysisKey RootSignatureAnalysis::Key;
101
-
102
- ModuleRootSignature RootSignatureAnalysis::run (Module &M,
103
- ModuleAnalysisManager &AM) {
104
- ModuleRootSignature MRSI;
125
+ ModuleRootSignature ModuleRootSignature::analyzeModule (Module &M) {
126
+ ModuleRootSignature MRS;
105
127
106
128
NamedMDNode *RootSignatureNode = M.getNamedMetadata (" dx.rootsignatures" );
107
129
if (RootSignatureNode) {
108
- MRSI.parse (1 , RootSignatureNode);
130
+ if (MRS.parse (1 , RootSignatureNode))
131
+ llvm_unreachable (" Invalid Root Signature Metadata." );
109
132
}
110
133
111
- return MRSI;
134
+ return MRS;
135
+ }
136
+
137
+ AnalysisKey RootSignatureAnalysis::Key;
138
+
139
+ ModuleRootSignature RootSignatureAnalysis::run (Module &M,
140
+ ModuleAnalysisManager &AM) {
141
+ return ModuleRootSignature::analyzeModule (M);
112
142
}
113
143
114
144
// ===----------------------------------------------------------------------===//
115
145
bool RootSignatureAnalysisWrapper::runOnModule (Module &M) {
116
- ModuleRootSignature MRS;
117
146
118
- NamedMDNode *RootSignatureNode = M.getNamedMetadata (" dx.rootsignatures" );
119
- if (RootSignatureNode) {
120
- MRS.parse (1 , RootSignatureNode);
121
- this ->MRS = MRS;
122
- }
147
+ this ->MRS = MRS = ModuleRootSignature::analyzeModule (M);
123
148
124
149
return false ;
125
150
}
0 commit comments