@@ -46,6 +46,48 @@ namespace Slang
46
46
inst->removeAndDeallocate ();
47
47
}
48
48
49
+ // Translates `createExistentialObject` insts, which takes a user defined
50
+ // type id and user defined value and turns into an existential value,
51
+ // into a `makeTuple` inst that makes the tuple representing the lowered
52
+ // existential value.
53
+ void processCreateExistentialObject (IRCreateExistentialObject* inst)
54
+ {
55
+ IRBuilder builderStorage;
56
+ auto builder = &builderStorage;
57
+ builder->sharedBuilder = &sharedContext->sharedBuilderStorage ;
58
+ builder->setInsertBefore (inst);
59
+
60
+ // The result type of this `createExistentialObject` inst should already
61
+ // be lowered into a `TupleType(rttiType, WitnessTableIDType, AnyValueType)`
62
+ // in the previous `lowerGenericType` pass.
63
+ auto tupleType = inst->getDataType ();
64
+ auto witnessTableIdType = cast<IRWitnessTableIDType>(tupleType->getOperand (1 ));
65
+ auto anyValueType = cast<IRAnyValueType>(tupleType->getOperand (2 ));
66
+
67
+ // Create a null value for `rttiObject` for now since it will not be used.
68
+ IRInst* rttiObject = builder->getIntValue (builder->getIntType (), 0 );
69
+
70
+ // Pack the user provided value into `AnyValue`.
71
+ IRInst* packedValue = inst->getValue ();
72
+ if (packedValue->getDataType ()->getOp () != kIROp_AnyValueType )
73
+ packedValue = builder->emitPackAnyValue (anyValueType, packedValue);
74
+
75
+ // Use the user provided `typeID` value as the witness table ID field in the
76
+ // newly constructed tuple.
77
+ // All `WitnessTableID` types are lowered into `uint2`s, so we need to create
78
+ // a `uint2` value from `typeID` to stay consistent with the convention.
79
+ IRInst* vectorArgs[2 ] = {
80
+ inst->getTypeID (), builder->getIntValue (builder->getUIntType (), 0 )};
81
+ auto uint2Type = builder->getVectorType (
82
+ builder->getUIntType (), builder->getIntValue (builder->getIntType (), 2 ));
83
+ IRInst* typeIdValue = builder->emitMakeVector (uint2Type, 2 , vectorArgs);
84
+ typeIdValue = builder->emitBitCast (witnessTableIdType, typeIdValue);
85
+ IRInst* tupleArgs[] = {rttiObject, typeIdValue, packedValue};
86
+ auto tuple = builder->emitMakeTuple (tupleType, 3 , tupleArgs);
87
+ inst->replaceUsesWith (tuple);
88
+ inst->removeAndDeallocate ();
89
+ }
90
+
49
91
IRInst* extractTupleElement (IRBuilder* builder, IRInst* value, UInt index)
50
92
{
51
93
auto tupleType = cast<IRTupleType>(sharedContext->lowerType (builder, value->getDataType ()));
@@ -138,6 +180,10 @@ namespace Slang
138
180
{
139
181
processMakeExistential (makeExistential);
140
182
}
183
+ else if (auto createExistentialObject = as<IRCreateExistentialObject>(inst))
184
+ {
185
+ processCreateExistentialObject (createExistentialObject);
186
+ }
141
187
else if (auto getValueFromBoundInterface = as<IRGetValueFromBoundInterface>(inst))
142
188
{
143
189
processGetValueFromBoundInterface (getValueFromBoundInterface);
0 commit comments