diff options
| author | Yong He <yonghe@outlook.com> | 2020-11-10 14:55:36 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-10 14:55:36 -0800 |
| commit | 7bcc2b15c8be4aebc6b9b8f05af6db7a451b228b (patch) | |
| tree | 2b89d5deaa9992cdb8c6c1ff72a399a5176be802 /source | |
| parent | 1c4d768bc1b400ab40c10715df98d0b2122bcd66 (diff) | |
Use integer RTTI/witness handles in existential tuples. (#1598)
* Use integer RTTI/witness handles in existential tuples.
* Fix clang error.
* Fix IR serialization to use 16bits for opcode.
* Undo accidental comment change.
* Use variable length encoding for opcode.
* Fix compile error.
* Fixing issues
* Fix code review issues.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-ir-generics-lowering-context.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-ir-generics-lowering-context.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 18 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-existential.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generic-call.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generic-function.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 101 | ||||
| -rw-r--r-- | source/slang/slang-ir-specialize-dispatch.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp | 96 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir.h | 25 |
14 files changed, 203 insertions, 101 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); }; |
