summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2020-11-10 14:55:36 -0800
committerGitHub <noreply@github.com>2020-11-10 14:55:36 -0800
commit7bcc2b15c8be4aebc6b9b8f05af6db7a451b228b (patch)
tree2b89d5deaa9992cdb8c6c1ff72a399a5176be802 /source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
parent1c4d768bc1b400ab40c10715df98d0b2122bcd66 (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.cpp96
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));
+ }
+ });
}
};