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/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp | |
| 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/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp')
| -rw-r--r-- | source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp | 96 |
1 files changed, 48 insertions, 48 deletions
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)); + } + }); } }; |
