10
10
11
11
namespace Slang
12
12
{
13
- // Only attempt to precompile functions:
13
+ // Only attempt to precompile functions and global variables :
14
14
// 1) With function bodies (not just empty decls)
15
15
// 2) Not marked with unsafeForceInlineDecoration
16
16
// 3) Have a simple HLSL data type as the return or parameter type
17
17
static bool attemptPrecompiledExport (IRInst* inst)
18
18
{
19
- if (inst->getOp () != kIROp_Func )
19
+ if (inst->getOp () != kIROp_Func && inst-> getOp () != kIROp_GlobalVar && inst-> getOp () != kIROp_GlobalConstant )
20
20
{
21
21
return false ;
22
22
}
23
23
24
- // Skip functions with no body
25
- bool hasBody = false ;
26
- for (auto child : inst->getChildren ())
24
+ if (inst->getOp () == kIROp_GlobalVar ||
25
+ inst->getOp () == kIROp_GlobalConstant )
27
26
{
28
- if (child->getOp () == kIROp_Block )
27
+ printf (" GlobalVar or GlobalConstant\n " );
28
+ if (inst->findDecoration <IRExportDecoration>())
29
29
{
30
- hasBody = true ;
31
- break ;
30
+ printf ( " Exporting global variable \n " ) ;
31
+ return true ;
32
32
}
33
- }
34
- if (!hasBody)
35
- {
33
+ printf (" Not exporting global variable\n " );
36
34
return false ;
37
35
}
38
-
39
- // Skip functions marked with unsafeForceInlineDecoration
40
- if (inst->findDecoration <IRUnsafeForceInlineEarlyDecoration>())
36
+ else if (inst->getOp () == kIROp_Func )
41
37
{
42
- return false ;
38
+ // Skip functions with no body
39
+ bool hasBody = false ;
40
+ for (auto child : inst->getChildren ())
41
+ {
42
+ if (child->getOp () == kIROp_Block )
43
+ {
44
+ hasBody = true ;
45
+ break ;
46
+ }
47
+ }
48
+ if (!hasBody)
49
+ {
50
+ return false ;
51
+ }
52
+
53
+ // Skip functions marked with unsafeForceInlineDecoration
54
+ if (inst->findDecoration <IRUnsafeForceInlineEarlyDecoration>())
55
+ {
56
+ return false ;
57
+ }
43
58
}
44
59
45
60
// Skip non-simple HLSL data types, filters out generics
@@ -51,6 +66,18 @@ static bool attemptPrecompiledExport(IRInst* inst)
51
66
return true ;
52
67
}
53
68
69
+ static bool needsImport (IRInst* inst)
70
+ {
71
+ if (inst->getOp () == kIROp_GlobalVar || inst->getOp () == kIROp_GlobalConstant )
72
+ {
73
+ if (inst->findDecoration <IRUserExternDecoration>())
74
+ {
75
+ return true ;
76
+ }
77
+ }
78
+ return false ;
79
+ }
80
+
54
81
/*
55
82
* Precompile the module for the given target.
56
83
*
@@ -67,28 +94,28 @@ static bool attemptPrecompiledExport(IRInst* inst)
67
94
* done during target generation in between IR linking+legalization and
68
95
* target source emission.
69
96
*
70
- * Functions which can be rejected up front:
97
+ * Language features which can be rejected up front:
71
98
* - Functions with no body
72
99
* - Functions marked with unsafeForceInlineDecoration
73
100
* - Functions that define or use generics
74
101
*
75
- * The functions not rejected up front are marked with
76
- * DownstreamModuleExportDecoration which indicates functions we're trying to
77
- * export for precompilation, and this also helps to identify the functions
102
+ * The instructions not rejected up front are marked with
103
+ * DownstreamModuleExportDecoration which indicates what we're trying to
104
+ * export for precompilation, and this also helps to identify the instructions
78
105
* in the linked IR which survived the additional pruning.
79
106
*
80
- * Functions that are rejected after linking+legalization (inside
107
+ * Instructions that are rejected after linking+legalization (inside
81
108
* emitPrecompiledDownstreamIR):
82
109
* - (DXIL) Functions that return or take a HLSLStructuredBufferType
83
110
* - (DXIL) Functions that return or take a Matrix type
84
111
*
85
112
* emitPrecompiled* produces the output artifact containing target language
86
- * blob, and as metadata, the list of functions which survived the second
113
+ * blob, and as metadata, the list of instructions which survived the second
87
114
* phase of filtering.
88
115
*
89
- * The original module IR functions matching those are then marked with
116
+ * The original module IR instructions matching those are then marked with
90
117
* "AvailableInDownstreamIRDecoration" to indicate to future
91
- * module users which functions are present in the precompiled blob.
118
+ * module users which instructions are present in the precompiled blob.
92
119
*/
93
120
SLANG_NO_THROW SlangResult SLANG_MCALL
94
121
Module::precompileForTarget (SlangCompileTarget target, slang::IBlob** outDiagnostics)
@@ -107,6 +134,9 @@ Module::precompileForTarget(SlangCompileTarget target, slang::IBlob** outDiagnos
107
134
}
108
135
}
109
136
137
+ if (getEntryPoints ().getCount () != 0 )
138
+ return SLANG_OK;
139
+
110
140
auto module = getIRModule ();
111
141
auto linkage = getLinkage ();
112
142
auto builder = IRBuilder (module);
@@ -160,20 +190,26 @@ Module::precompileForTarget(SlangCompileTarget target, slang::IBlob** outDiagnos
160
190
// the linked result to see which functions survived the pruning and are included in the
161
191
// precompiled blob.
162
192
Dictionary<String, IRInst*> nameToFunction;
163
- bool hasAtLeastOneFunction = false ;
193
+ bool hasAtLeastOneExport = false ;
194
+ bool hasAtLeastOneImport = false ;
164
195
for (auto inst : module->getGlobalInsts ())
165
196
{
166
197
if (attemptPrecompiledExport (inst))
167
198
{
168
- hasAtLeastOneFunction = true ;
199
+ hasAtLeastOneExport = true ;
169
200
builder.addDecoration (inst, kIROp_DownstreamModuleExportDecoration );
170
201
nameToFunction[inst->findDecoration <IRExportDecoration>()->getMangledName ()] = inst;
171
202
}
203
+ if (needsImport (inst))
204
+ {
205
+ hasAtLeastOneImport = true ;
206
+ builder.addDecoration (inst, kIROp_DownstreamModuleImportDecoration );
207
+ }
172
208
}
173
209
174
- // Bail if there are no functions to export. That's not treated as an error
175
- // because it's possible that the module just doesn't have any simple HLSL .
176
- if (!hasAtLeastOneFunction )
210
+ // Bail if there is nothing to import/ export. That's not treated as an error
211
+ // because it's possible that the module just doesn't have any simple code .
212
+ if (!hasAtLeastOneExport && !hasAtLeastOneImport )
177
213
{
178
214
return SLANG_OK;
179
215
}
@@ -201,19 +237,17 @@ Module::precompileForTarget(SlangCompileTarget target, slang::IBlob** outDiagnos
201
237
kIROp_AvailableInDownstreamIRDecoration ,
202
238
builder.getIntValue (builder.getIntType (), (int )targetReq->getTarget ()));
203
239
auto moduleDec = moduleInst->findDecoration <IRDownstreamModuleExportDecoration>();
204
- moduleDec->removeAndDeallocate ();
240
+ if (moduleDec)
241
+ moduleDec->removeAndDeallocate ();
205
242
}
206
243
207
244
// Finally, clean up the transient export decorations left over in the module. These are
208
245
// represent functions that were pruned from the IR after linking, before target generation.
209
246
for (auto moduleInst : module->getGlobalInsts ())
210
247
{
211
- if (moduleInst->getOp () == kIROp_Func )
248
+ if (auto dec = moduleInst->findDecoration <IRDownstreamModuleExportDecoration>() )
212
249
{
213
- if (auto dec = moduleInst->findDecoration <IRDownstreamModuleExportDecoration>())
214
- {
215
- dec->removeAndDeallocate ();
216
- }
250
+ dec->removeAndDeallocate ();
217
251
}
218
252
}
219
253
0 commit comments