summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-emit-cpp.cpp16
-rw-r--r--source/slang/slang-emit.cpp16
-rw-r--r--source/slang/slang-ir-generics-lowering-context.cpp7
-rw-r--r--source/slang/slang-ir-generics-lowering-context.h2
-rw-r--r--source/slang/slang-ir-inst-defs.h18
-rw-r--r--source/slang/slang-ir-insts.h1
-rw-r--r--source/slang/slang-ir-lower-existential.cpp7
-rw-r--r--source/slang/slang-ir-lower-generic-call.cpp4
-rw-r--r--source/slang/slang-ir-lower-generic-function.cpp4
-rw-r--r--source/slang/slang-ir-lower-generics.cpp101
-rw-r--r--source/slang/slang-ir-specialize-dispatch.cpp2
-rw-r--r--source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp96
-rw-r--r--source/slang/slang-ir.cpp5
-rw-r--r--source/slang/slang-ir.h25
-rw-r--r--tools/render-test/cpu-compute-util.cpp14
-rw-r--r--tools/render-test/cuda/cuda-compute-util.cpp20
16 files changed, 214 insertions, 124 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index d1250357a..e02ca3007 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -494,6 +494,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
return SLANG_OK;
}
case kIROp_WitnessTableType:
+ case kIROp_WitnessTableIDType:
{
// A witness table typed value translates to a pointer to the
// struct of function pointers corresponding to the interface type.
@@ -532,6 +533,11 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << "TypeInfo";
return SLANG_OK;
}
+ case kIROp_RTTIHandleType:
+ {
+ out << "TypeInfo*";
+ return SLANG_OK;
+ }
default:
{
if (isNominalOp(type->op))
@@ -1652,8 +1658,10 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
m_writer->emit(" = {\n");
m_writer->indent();
auto seqIdDecoration = witnessTable->findDecoration<IRSequentialIDDecoration>();
- SLANG_ASSERT(seqIdDecoration);
- m_writer->emit((UInt)seqIdDecoration->getSequentialID());
+ if (seqIdDecoration)
+ m_writer->emit((UInt)seqIdDecoration->getSequentialID());
+ else
+ m_writer->emit("0");
for (Index i = 0; i < sortedWitnessTableEntries.getCount(); i++)
{
auto entry = sortedWitnessTableEntries[i];
@@ -1669,7 +1677,7 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
m_writer->emit(getName(witnessTableVal));
}
else if (entry->getSatisfyingVal() &&
- isPointerOfType(entry->getSatisfyingVal()->getDataType(), kIROp_RTTIType))
+ entry->getSatisfyingVal()->getDataType()->op == kIROp_RTTIHandleType)
{
m_writer->emit(",\n");
emitInstExpr(entry->getSatisfyingVal(), getInfo(EmitOp::General));
@@ -1731,7 +1739,7 @@ void CPPSourceEmitter::emitInterface(IRInterfaceType* interfaceType)
m_writer->emit(getName(entry->getRequirementKey()));
m_writer->emit(";\n");
}
- else if (isPointerOfType(entry->getRequirementVal(), kIROp_RTTIType))
+ else if (entry->getRequirementVal()->op == kIROp_RTTIHandleType)
{
m_writer->emit("TypeInfo* ");
m_writer->emit(getName(entry->getRequirementKey()));
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index fbddd2910..baa020b6d 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -664,18 +664,10 @@ Result linkAndOptimizeIR(
break;
}
- switch (target)
- {
- case CodeGenTarget::CPPSource:
- case CodeGenTarget::CUDASource:
- break;
- default:
- // For all targets that don't support true dynamic dispatch through
- // witness tables, we need to eliminate witness tables from the IR so
- // that they don't keep symbols live that we don't actually need.
- stripWitnessTables(irModule);
- break;
- }
+ // TODO: our current dynamic dispatch pass will remove all uses of witness tables.
+ // If we are going to support function-pointer based, "real" modular dynamic dispatch,
+ // we will need to disable this pass.
+ stripWitnessTables(irModule);
#if 0
dumpIRIfEnabled(compileRequest, irModule, "AFTER STRIP WITNESS TABLES");
diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp
index bef4dbb0a..4c4224295 100644
--- a/source/slang/slang-ir-generics-lowering-context.cpp
+++ b/source/slang/slang-ir-generics-lowering-context.cpp
@@ -134,13 +134,14 @@ namespace Slang
if (isTypeValue(paramType))
{
- return builder->getPtrType(builder->getRTTIType());
+ return builder->getRTTIHandleType();
}
IRIntegerValue anyValueSize = kInvalidAnyValueSize;
switch (paramType->op)
{
case kIROp_WitnessTableType:
+ case kIROp_WitnessTableIDType:
case kIROp_ExtractExistentialType:
// Do not translate these types.
return (IRType*)paramType;
@@ -174,8 +175,8 @@ namespace Slang
// An existential type translates into a tuple of (AnyValue, WitnessTable, RTTI*)
anyValueSize = getInterfaceAnyValueSize(paramType, paramType->sourceLoc);
auto anyValueType = builder->getAnyValueType(anyValueSize);
- auto witnessTableType = builder->getWitnessTableType((IRType*)paramType);
- auto rttiType = builder->getPtrType(builder->getRTTIType());
+ auto witnessTableType = builder->getWitnessTableIDType((IRType*)paramType);
+ auto rttiType = builder->getRTTIHandleType();
auto tupleType = builder->getTupleType(rttiType, witnessTableType, anyValueType);
return tupleType;
}
diff --git a/source/slang/slang-ir-generics-lowering-context.h b/source/slang/slang-ir-generics-lowering-context.h
index 2e5366561..f9d81e884 100644
--- a/source/slang/slang-ir-generics-lowering-context.h
+++ b/source/slang/slang-ir-generics-lowering-context.h
@@ -21,7 +21,7 @@ namespace Slang
DiagnosticSink* sink;
// RTTI objects for each type used to call a generic function.
- Dictionary<IRInst*, IRInst*> mapTypeToRTTIObject;
+ OrderedDictionary<IRInst*, IRInst*> mapTypeToRTTIObject;
Dictionary<IRInst*, IRInst*> loweredGenericFunctions;
Dictionary<IRInterfaceType*, IRInterfaceType*> loweredInterfaceTypes;
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 004975252..8256646e0 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -178,20 +178,22 @@ INST(InterfaceType, interface, 0, 0)
INST(AssociatedType, associated_type, 0, 0)
INST(ThisType, this_type, 0, 0)
INST(RTTIType, rtti_type, 0, 0)
+INST(RTTIHandleType, rtti_handle_type, 0, 0)
INST(TupleType, tuple_type, 0, 0)
// A TypeType-typed IRValue represents a IRType.
// It is used to represent a type parameter/argument in a generics.
INST(TypeType, type_t, 0, 0)
-// An `IRWitnessTable` has type `WitnessTableType`.
-INST(WitnessTableType, witness_table_t, 1, 0)
-
-// An integer type representing a witness table for targets where
-// witness tables are represented as integer IDs. This type is used
-// during the lower-generics pass while generating dynamic dispatch
-// code and will eventually lower into an uint type.
-INST(WitnessTableIDType, witness_table_id_t, 1, 0)
+/*IRWitnessTableTypeBase*/
+ // An `IRWitnessTable` has type `WitnessTableType`.
+ INST(WitnessTableType, witness_table_t, 1, 0)
+ // An integer type representing a witness table for targets where
+ // witness tables are represented as integer IDs. This type is used
+ // during the lower-generics pass while generating dynamic dispatch
+ // code and will eventually lower into an uint type.
+ INST(WitnessTableIDType, witness_table_id_t, 1, 0)
+INST_RANGE(WitnessTableTypeBase, WitnessTableType, WitnessTableIDType)
INST_RANGE(Type, VoidType, WitnessTableIDType)
/*IRGlobalValueWithCode*/
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 335ab4827..f651920d9 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -1807,6 +1807,7 @@ struct IRBuilder
IRRawPointerType* getRawPointerType();
IRRTTIPointerType* getRTTIPointerType(IRInst* rttiPtr);
IRRTTIType* getRTTIType();
+ IRRTTIHandleType* getRTTIHandleType();
IRAnyValueType* getAnyValueType(IRIntegerValue size);
IRAnyValueType* getAnyValueType(IRInst* size);
IRDynamicType* getDynamicType();
diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp
index 0dce96de2..a87169ac3 100644
--- a/source/slang/slang-ir-lower-existential.cpp
+++ b/source/slang/slang-ir-lower-existential.cpp
@@ -23,12 +23,13 @@ namespace Slang
auto value = inst->getWrappedValue();
auto valueType = sharedContext->lowerType(builder, value->getDataType());
- auto witnessTableType = cast<IRWitnessTableType>(inst->getWitnessTable()->getDataType());
+ auto witnessTableType = cast<IRWitnessTableTypeBase>(inst->getWitnessTable()->getDataType());
auto interfaceType = witnessTableType->getConformanceType();
+ auto witnessTableIdType = builder->getWitnessTableIDType((IRType*)interfaceType);
auto anyValueSize = sharedContext->getInterfaceAnyValueSize(interfaceType, inst->sourceLoc);
auto anyValueType = builder->getAnyValueType(anyValueSize);
- auto rttiType = builder->getPtrType(builder->getRTTIType());
- auto tupleType = builder->getTupleType(rttiType, witnessTableType, anyValueType);
+ auto rttiType = builder->getRTTIHandleType();
+ auto tupleType = builder->getTupleType(rttiType, witnessTableIdType, anyValueType);
IRInst* rttiObject = inst->getRTTI();
if (auto type = as<IRType>(rttiObject))
diff --git a/source/slang/slang-ir-lower-generic-call.cpp b/source/slang/slang-ir-lower-generic-call.cpp
index 369bc712f..644757a89 100644
--- a/source/slang/slang-ir-lower-generic-call.cpp
+++ b/source/slang/slang-ir-lower-generic-call.cpp
@@ -192,7 +192,7 @@ namespace Slang
// Generate RTTI for this type.
auto rttiObject = sharedContext->maybeEmitRTTIObject(arg);
arg = builder->emitGetAddress(
- builder->getPtrType(builder->getRTTIType()),
+ builder->getRTTIHandleType(),
rttiObject);
}
else if (arg->op == kIROp_Specialize)
@@ -281,7 +281,7 @@ namespace Slang
// If we see a call(lookup_interface_method(...), ...), we need to translate
// all occurences of associatedtypes.
auto interfaceType = cast<IRInterfaceType>(
- cast<IRWitnessTableType>(lookupInst->getWitnessTable()->getDataType())
+ cast<IRWitnessTableTypeBase>(lookupInst->getWitnessTable()->getDataType())
->getConformanceType());
if (isBuiltin(interfaceType))
return;
diff --git a/source/slang/slang-ir-lower-generic-function.cpp b/source/slang/slang-ir-lower-generic-function.cpp
index f5bd469ac..75c58a2f4 100644
--- a/source/slang/slang-ir-lower-generic-function.cpp
+++ b/source/slang/slang-ir-lower-generic-function.cpp
@@ -170,7 +170,7 @@ namespace Slang
}
else if (entry->getRequirementVal()->op == kIROp_AssociatedType)
{
- loweredVal = builder.getPtrType(builder.getRTTIType());
+ loweredVal = builder.getRTTIHandleType();
}
else
{
@@ -231,7 +231,7 @@ namespace Slang
// Translate a Type value to an RTTI object pointer.
auto rttiObject = sharedContext->maybeEmitRTTIObject(entry->getSatisfyingVal());
auto rttiObjectPtr = builder->emitGetAddress(
- builder->getPtrType(builder->getRTTIType()),
+ builder->getRTTIHandleType(),
rttiObject);
entry->satisfyingVal.set(rttiObjectPtr);
}
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index 89194e594..0253c4df8 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -16,6 +16,96 @@
namespace Slang
{
+ // Replace all uses of RTTI objects with its sequential ID.
+ void specializeRTTIObjectReferences(SharedGenericsLoweringContext* sharedContext)
+ {
+ uint32_t id = 0;
+ for (auto rtti : sharedContext->mapTypeToRTTIObject)
+ {
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
+ builder.setInsertBefore(rtti.Value);
+ IRUse* nextUse = nullptr;
+ auto idOperand = builder.getIntValue(builder.getUInt64Type(), id);
+ for (auto use = rtti.Value->firstUse; use; use = nextUse)
+ {
+ nextUse = use->nextUse;
+ if (use->getUser()->op == kIROp_getAddr)
+ {
+ use->getUser()->replaceUsesWith(idOperand);
+ }
+ }
+ }
+ }
+
+ // Replace all WitnessTableID type or RTTIHandleType with uint64.
+ void cleanUpRTTIHandleTypes(SharedGenericsLoweringContext* sharedContext)
+ {
+ List<IRInst*> instsToRemove;
+ for (auto inst : sharedContext->module->getGlobalInsts())
+ {
+ switch (inst->op)
+ {
+ case kIROp_WitnessTableIDType:
+ case kIROp_RTTIHandleType:
+ {
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
+ builder.setInsertBefore(inst);
+ inst->replaceUsesWith(builder.getUInt64Type());
+ instsToRemove.add(inst);
+ }
+ break;
+ }
+ }
+ for (auto inst : instsToRemove)
+ inst->removeAndDeallocate();
+ }
+
+ // Remove all interface types from module.
+ void cleanUpInterfaceTypes(SharedGenericsLoweringContext* sharedContext)
+ {
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
+ builder.setInsertInto(sharedContext->module->getModuleInst());
+ auto dummyInterfaceObj = builder.getIntValue(builder.getIntType(), 0);
+ List<IRInst*> interfaceInsts;
+ for (auto inst : sharedContext->module->getGlobalInsts())
+ {
+ if (inst->op == kIROp_InterfaceType)
+ {
+ interfaceInsts.add(inst);
+ }
+ }
+ for (auto inst : interfaceInsts)
+ {
+ inst->replaceUsesWith(dummyInterfaceObj);
+ inst->removeAndDeallocate();
+ }
+ }
+
+ // Turn all references of witness table or RTTI objects into integer IDs, generate
+ // specialized `switch` based dispatch functions based on witness table IDs, and remove
+ // all original witness table, RTTI object and interface definitions from IR module.
+ // With these transformations, the resulting code is compatible with D3D/Vulkan where
+ // no pointers are involved in RTTI / dynamic dispatch logic.
+ void specializeRTTIObjects(SharedGenericsLoweringContext* sharedContext, DiagnosticSink* sink)
+ {
+ specializeDispatchFunctions(sharedContext);
+ if (sink->getErrorCount() != 0)
+ return;
+
+ specializeDynamicAssociatedTypeLookup(sharedContext);
+ if (sink->getErrorCount() != 0)
+ return;
+
+ specializeRTTIObjectReferences(sharedContext);
+
+ cleanUpRTTIHandleTypes(sharedContext);
+
+ cleanUpInterfaceTypes(sharedContext);
+ }
+
void lowerGenerics(
TargetRequest* targetReq,
IRModule* module,
@@ -60,13 +150,10 @@ namespace Slang
if (sink->getErrorCount() != 0)
return;
- specializeDispatchFunctions(&sharedContext);
- if (sink->getErrorCount() != 0)
- return;
-
- specializeDynamicAssociatedTypeLookup(&sharedContext);
- if (sink->getErrorCount() != 0)
- return;
+ // This optional step replaces all uses of witness tables and RTTI objects with
+ // sequential IDs. Without this step, we will emit code that uses function pointers and
+ // real RTTI objects and witness tables.
+ specializeRTTIObjects(&sharedContext, sink);
// We might have generated new temporary variables during lowering.
// An SSA pass can clean up unnecessary load/stores.
diff --git a/source/slang/slang-ir-specialize-dispatch.cpp b/source/slang/slang-ir-specialize-dispatch.cpp
index 98a0ba3b7..ebf3f1909 100644
--- a/source/slang/slang-ir-specialize-dispatch.cpp
+++ b/source/slang/slang-ir-specialize-dispatch.cpp
@@ -12,7 +12,7 @@ IRFunc* specializeDispatchFunction(SharedGenericsLoweringContext* sharedContext,
// Collect all witness tables of `witnessTableType` in current module.
List<IRWitnessTable*> witnessTables = sharedContext->getWitnessTablesFromInterfaceType(
- cast<IRWitnessTableType>(witnessTableType)->getConformanceType());
+ cast<IRWitnessTableTypeBase>(witnessTableType)->getConformanceType());
SLANG_ASSERT(dispatchFunc->getFirstBlock() == dispatchFunc->getLastBlock());
auto block = dispatchFunc->getFirstBlock();
diff --git a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
index c3095eb98..a8d2902f6 100644
--- a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
+++ b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
@@ -91,22 +91,6 @@ struct AssociatedTypeLookupSpecializationContext
return func;
}
- // Retrieves the conformance type from a WitnessTableType or a WitnessTableIDType.
- IRInterfaceType* getInterfaceTypeFromWitnessTableTypes(IRInst* witnessTableType)
- {
- switch (witnessTableType->op)
- {
- case kIROp_WitnessTableType:
- return cast<IRInterfaceType>(
- cast<IRWitnessTableType>(witnessTableType)->getConformanceType());
- case kIROp_WitnessTableIDType:
- return cast<IRInterfaceType>(
- cast<IRWitnessTableIDType>(witnessTableType)->getConformanceType());
- default:
- return nullptr;
- }
- }
-
void processLookupInterfaceMethodInst(IRLookupWitnessMethod* inst)
{
// Ignore lookups for RTTI objects for now, since they are not used anywhere.
@@ -117,7 +101,8 @@ struct AssociatedTypeLookupSpecializationContext
// returns the sequential ID of the resulting witness table, effectively getting rid
// of actual witness table objects in the target code (they all become IDs).
auto witnessTableType = inst->getWitnessTable()->getDataType();
- IRInterfaceType* interfaceType = getInterfaceTypeFromWitnessTableTypes(witnessTableType);
+ IRInterfaceType* interfaceType = cast<IRInterfaceType>(
+ cast<IRWitnessTableTypeBase>(witnessTableType)->getConformanceType());
if (!interfaceType)
return;
auto key = inst->getRequirementKey();
@@ -141,24 +126,6 @@ struct AssociatedTypeLookupSpecializationContext
inst->removeAndDeallocate();
}
- void cleanUpWitnessTableIDType()
- {
- List<IRInst*> instsToRemove;
- for (auto inst : sharedContext->module->getGlobalInsts())
- {
- if (inst->op == kIROp_WitnessTableIDType)
- {
- IRBuilder builder;
- builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
- builder.setInsertBefore(inst);
- inst->replaceUsesWith(builder.getUIntType());
- instsToRemove.add(inst);
- }
- }
- for (auto inst : instsToRemove)
- inst->removeAndDeallocate();
- }
-
void processGetSequentialIDInst(IRGetSequentialID* inst)
{
if (inst->getRTTIOperand()->getDataType()->op == kIROp_WitnessTableIDType)
@@ -168,7 +135,8 @@ struct AssociatedTypeLookupSpecializationContext
}
}
- void processModule()
+ template<typename TFunc>
+ void workOnModule(const TFunc& func)
{
SharedIRBuilder* sharedBuilder = &sharedContext->sharedBuilderStorage;
sharedBuilder->module = sharedContext->module;
@@ -183,6 +151,7 @@ struct AssociatedTypeLookupSpecializationContext
sharedContext->workList.removeLast();
sharedContext->workListSet.Remove(inst);
+ func(inst);
if (inst->op == kIROp_lookup_interface_method)
{
processLookupInterfaceMethodInst(cast<IRLookupWitnessMethod>(inst));
@@ -193,28 +162,59 @@ struct AssociatedTypeLookupSpecializationContext
sharedContext->addToWorkList(child);
}
}
+ }
- // `GetSequentialID(WitnessTableIDOperand)` becomes just `WitnessTableIDOperand`.
- sharedContext->addToWorkList(sharedContext->module->getModuleInst());
- while (sharedContext->workList.getCount() != 0)
+ void processModule()
+ {
+ // Replace all `lookup_interface_method():IRWitnessTable` with call to specialized functions.
+ workOnModule([this](IRInst* inst)
{
- IRInst* inst = sharedContext->workList.getLast();
-
- sharedContext->workList.removeLast();
- sharedContext->workListSet.Remove(inst);
+ if (inst->op == kIROp_lookup_interface_method)
+ {
+ processLookupInterfaceMethodInst(cast<IRLookupWitnessMethod>(inst));
+ }
+ });
- if (inst->op == kIROp_GetSequentialID)
+ // Replace all direct uses of IRWitnessTables with its sequential ID.
+ workOnModule([](IRInst* inst)
+ {
+ if (inst->op == kIROp_WitnessTable)
{
- processGetSequentialIDInst(cast<IRGetSequentialID>(inst));
+ auto seqId = inst->findDecoration<IRSequentialIDDecoration>();
+ SLANG_ASSERT(seqId);
+ inst->replaceUsesWith(seqId->getSequentialIDOperand());
}
+ });
- for (auto child = inst->getLastChild(); child; child = child->getPrevInst())
+ // Replace all `IRWitnessTableType`s with `IRWitnessTableIDType`.
+ for (auto globalInst : sharedContext->module->getGlobalInsts())
+ {
+ if (globalInst->op == kIROp_WitnessTableType)
{
- sharedContext->addToWorkList(child);
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
+ builder.setInsertBefore(globalInst);
+ auto witnessTableIDType = builder.getWitnessTableIDType(
+ (IRType*)cast<IRWitnessTableType>(globalInst)->getConformanceType());
+ IRUse* nextUse = nullptr;
+ for (auto use = globalInst->firstUse; use; use = nextUse)
+ {
+ nextUse = use->nextUse;
+ if (use->getUser()->op == kIROp_WitnessTable)
+ continue;
+ use->set(witnessTableIDType);
+ }
}
}
- cleanUpWitnessTableIDType();
+ // `GetSequentialID(WitnessTableIDOperand)` becomes just `WitnessTableIDOperand`.
+ workOnModule([this](IRInst* inst)
+ {
+ if (inst->op == kIROp_GetSequentialID)
+ {
+ processGetSequentialIDInst(cast<IRGetSequentialID>(inst));
+ }
+ });
}
};
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 5bc289dab..e735edce9 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -2435,6 +2435,11 @@ namespace Slang
return (IRRTTIType*)getType(kIROp_RTTIType);
}
+ IRRTTIHandleType* IRBuilder::getRTTIHandleType()
+ {
+ return (IRRTTIHandleType*)getType(kIROp_RTTIHandleType);
+ }
+
IRAnyValueType* IRBuilder::getAnyValueType(IRIntegerValue size)
{
return (IRAnyValueType*)getType(kIROp_AnyValueType,
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 4e78cbb78..eb95cda1f 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1271,6 +1271,13 @@ struct IRRTTIType : IRType
IR_LEAF_ISA(RTTIType);
};
+ /// Represents a handle to an RTTI object.
+ /// This is lowered as an integer number identifying a type.
+struct IRRTTIHandleType : IRType
+{
+ IR_LEAF_ISA(RTTIHandleType);
+};
+
struct IRAnyValueType : IRType
{
IR_LEAF_ISA(AnyValueType);
@@ -1280,21 +1287,19 @@ struct IRAnyValueType : IRType
}
};
-struct IRWitnessTableType : IRType
+struct IRWitnessTableTypeBase : IRType
+{
+ IRInst* getConformanceType() { return getOperand(0); }
+ IR_PARENT_ISA(WitnessTableTypeBase);
+};
+
+struct IRWitnessTableType : IRWitnessTableTypeBase
{
- IRInst* getConformanceType()
- {
- return getOperand(0);
- }
IR_LEAF_ISA(WitnessTableType);
};
-struct IRWitnessTableIDType : IRType
+struct IRWitnessTableIDType : IRWitnessTableTypeBase
{
- IRInst* getConformanceType()
- {
- return getOperand(0);
- }
IR_LEAF_ISA(WitnessTableIDType);
};
diff --git a/tools/render-test/cpu-compute-util.cpp b/tools/render-test/cpu-compute-util.cpp
index a861dadf3..72e44fb78 100644
--- a/tools/render-test/cpu-compute-util.cpp
+++ b/tools/render-test/cpu-compute-util.cpp
@@ -427,7 +427,7 @@ SlangResult CPUComputeUtil::fillRuntimeHandleInBuffers(
{
for (auto& rtti : entry.rttiEntries)
{
- void* ptrValue = nullptr;
+ uint64_t ptrValue = 0;
switch (rtti.type)
{
case RTTIDataEntryType::RTTIObject:
@@ -439,7 +439,7 @@ SlangResult CPUComputeUtil::fillRuntimeHandleInBuffers(
linkage->getTypeRTTIMangledName(concreteType, outName.writeRef());
if (!outName)
return SLANG_FAIL;
- ptrValue = sharedLib->findSymbolAddressByName((char*)outName->getBufferPointer());
+ ptrValue = (uint64_t)sharedLib->findSymbolAddressByName((char*)outName->getBufferPointer());
}
break;
case RTTIDataEntryType::WitnessTable:
@@ -451,18 +451,14 @@ SlangResult CPUComputeUtil::fillRuntimeHandleInBuffers(
auto interfaceType = reflection->findTypeByName(rtti.interfaceName.getBuffer());
if (!interfaceType)
return SLANG_FAIL;
- ComPtr<ISlangBlob> outName;
- linkage->getTypeConformanceWitnessMangledName(concreteType, interfaceType, outName.writeRef());
- if (!outName)
- return SLANG_FAIL;
- ptrValue = sharedLib->findSymbolAddressByName((char*)outName->getBufferPointer());
+ uint32_t id = -1;
+ linkage->getTypeConformanceWitnessSequentialID(concreteType, interfaceType, &id);
+ ptrValue = id;
break;
}
default:
break;
}
- if (!ptrValue)
- return SLANG_FAIL;
if (rtti.offset >= 0 && rtti.offset + sizeof(ptrValue) <= entry.bufferData.getCount() * sizeof(decltype(entry.bufferData[0])))
{
memcpy(
diff --git a/tools/render-test/cuda/cuda-compute-util.cpp b/tools/render-test/cuda/cuda-compute-util.cpp
index 73ad78f0b..cc84d4a00 100644
--- a/tools/render-test/cuda/cuda-compute-util.cpp
+++ b/tools/render-test/cuda/cuda-compute-util.cpp
@@ -1409,7 +1409,7 @@ static SlangResult _fillRuntimeHandlesInBuffers(
{
for (auto& rtti : entry.rttiEntries)
{
- CUdeviceptr ptrValue = 0;
+ uint64_t ptrValue = 0;
switch (rtti.type)
{
case RTTIDataEntryType::RTTIObject:
@@ -1422,7 +1422,7 @@ static SlangResult _fillRuntimeHandlesInBuffers(
if (!outName)
return SLANG_FAIL;
SLANG_CUDA_RETURN_ON_FAIL(cuModuleGetGlobal(
- &ptrValue,
+ (CUdeviceptr*)&ptrValue,
nullptr,
cudaModule.m_module,
(char*)outName->getBufferPointer()));
@@ -1438,23 +1438,15 @@ static SlangResult _fillRuntimeHandlesInBuffers(
auto interfaceType = reflection->findTypeByName(rtti.interfaceName.getBuffer());
if (!interfaceType)
return SLANG_FAIL;
- ComPtr<ISlangBlob> outName;
- linkage->getTypeConformanceWitnessMangledName(
- concreteType, interfaceType, outName.writeRef());
- if (!outName)
- return SLANG_FAIL;
- SLANG_CUDA_RETURN_ON_FAIL(cuModuleGetGlobal(
- &ptrValue,
- nullptr,
- cudaModule.m_module,
- (char*)outName->getBufferPointer()));
+ uint32_t id = 0xFFFFFFFF;
+ linkage->getTypeConformanceWitnessSequentialID(
+ concreteType, interfaceType, &id);
+ ptrValue = id;
break;
}
default:
break;
}
- if (!ptrValue)
- return SLANG_FAIL;
if (rtti.offset >= 0 &&
rtti.offset + sizeof(ptrValue) <=
entry.bufferData.getCount() * sizeof(decltype(entry.bufferData[0])))