@@ -15,6 +15,10 @@ namespace Slang
15
15
InstWorkList workList;
16
16
InstHashSet workListSet;
17
17
18
+ IRGeneric* genericOptionalStructType = nullptr ;
19
+ IRStructKey* valueKey = nullptr ;
20
+ IRStructKey* hasValueKey = nullptr ;
21
+
18
22
OptionalTypeLoweringContext (IRModule* inModule)
19
23
:module(inModule), workList(inModule), workListSet(inModule)
20
24
{}
@@ -24,8 +28,6 @@ namespace Slang
24
28
IRType* optionalType = nullptr ;
25
29
IRType* valueType = nullptr ;
26
30
IRType* loweredType = nullptr ;
27
- IRStructField* valueField = nullptr ;
28
- IRStructField* hasValueField = nullptr ;
29
31
};
30
32
Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> mapLoweredTypeToOptionalTypeInfo;
31
33
Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> loweredOptionalTypes;
@@ -38,6 +40,34 @@ namespace Slang
38
40
return type;
39
41
}
40
42
43
+ IRInst* getOrCreateGenericOptionalStruct ()
44
+ {
45
+ if (genericOptionalStructType)
46
+ return genericOptionalStructType;
47
+ IRBuilder builder (module);
48
+ builder.setInsertInto (module->getModuleInst ());
49
+
50
+ valueKey = builder.createStructKey ();
51
+ builder.addNameHintDecoration (valueKey, UnownedStringSlice (" value" ));
52
+ hasValueKey = builder.createStructKey ();
53
+ builder.addNameHintDecoration (hasValueKey, UnownedStringSlice (" hasValue" ));
54
+
55
+ genericOptionalStructType = builder.emitGeneric ();
56
+ builder.addNameHintDecoration (genericOptionalStructType, UnownedStringSlice (" _slang_Optional" ));
57
+
58
+ builder.setInsertInto (genericOptionalStructType);
59
+ auto block = builder.emitBlock ();
60
+ auto typeParam = builder.emitParam (builder.getTypeKind ());
61
+ auto structType = builder.createStructType ();
62
+ builder.addNameHintDecoration (structType, UnownedStringSlice (" _slang_Optional" ));
63
+ builder.createStructField (structType, valueKey, (IRType*)typeParam);
64
+ builder.createStructField (structType, hasValueKey, builder.getBoolType ());
65
+ builder.setInsertInto (block);
66
+ builder.emitReturn (structType);
67
+ genericOptionalStructType->setFullType (builder.getTypeKind ());
68
+ return genericOptionalStructType;
69
+ }
70
+
41
71
bool typeHasNullValue (IRInst* type)
42
72
{
43
73
switch (type->getOp ())
@@ -78,19 +108,10 @@ namespace Slang
78
108
}
79
109
else
80
110
{
81
- auto structType = builder->createStructType ();
82
- info->loweredType = structType;
83
- builder->addNameHintDecoration (structType, UnownedStringSlice (" OptionalType" ));
84
-
85
- info->valueType = valueType;
86
- auto valueKey = builder->createStructKey ();
87
- builder->addNameHintDecoration (valueKey, UnownedStringSlice (" value" ));
88
- info->valueField = builder->createStructField (structType, valueKey, (IRType*)valueType);
89
-
90
- auto boolType = builder->getBoolType ();
91
- auto hasValueKey = builder->createStructKey ();
92
- builder->addNameHintDecoration (hasValueKey, UnownedStringSlice (" hasValue" ));
93
- info->hasValueField = builder->createStructField (structType, hasValueKey, (IRType*)boolType);
111
+ auto genericType = getOrCreateGenericOptionalStruct ();
112
+ IRInst* args[] = { valueType };
113
+ auto specializedType = builder->emitSpecializeInst (builder->getTypeKind (), genericType, 1 , args);
114
+ info->loweredType = (IRType*)specializedType;
94
115
}
95
116
mapLoweredTypeToOptionalTypeInfo[info->loweredType ] = info;
96
117
loweredOptionalTypes[type] = info;
@@ -100,12 +121,6 @@ namespace Slang
100
121
void addToWorkList (
101
122
IRInst* inst)
102
123
{
103
- for (auto ii = inst->getParent (); ii; ii = ii->getParent ())
104
- {
105
- if (as<IRGeneric>(ii))
106
- return ;
107
- }
108
-
109
124
if (workListSet.contains (inst))
110
125
return ;
111
126
@@ -169,7 +184,7 @@ namespace Slang
169
184
result = builder->emitFieldExtract (
170
185
builder->getBoolType (),
171
186
optionalInst,
172
- loweredOptionalTypeInfo-> hasValueField -> getKey () );
187
+ hasValueKey );
173
188
}
174
189
else
175
190
{
@@ -201,11 +216,10 @@ namespace Slang
201
216
if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType )
202
217
{
203
218
SLANG_ASSERT (loweredOptionalTypeInfo);
204
- SLANG_ASSERT (loweredOptionalTypeInfo->valueField );
205
219
auto getElement = builder->emitFieldExtract (
206
220
loweredOptionalTypeInfo->valueType ,
207
221
base,
208
- loweredOptionalTypeInfo-> valueField -> getKey () );
222
+ valueKey );
209
223
inst->replaceUsesWith (getElement);
210
224
}
211
225
else
@@ -257,7 +271,6 @@ namespace Slang
257
271
while (workList.getCount () != 0 )
258
272
{
259
273
IRInst* inst = workList.getLast ();
260
-
261
274
workList.removeLast ();
262
275
workListSet.remove (inst);
263
276
0 commit comments