diff options
| author | Yong He <yonghe@outlook.com> | 2020-09-04 10:18:44 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-04 10:18:44 -0700 |
| commit | 8f962894fd38edb47d782d303ac9ff87b3a3bb6a (patch) | |
| tree | 449d0d58ca7d90a11759372c9dc82650a565f96a /source/slang/slang-ir-specialize.cpp | |
| parent | 5e10f1b4f0654515af1fcb29e8d1f35e691c8aa3 (diff) | |
Allow mixing unspecialized and specialized existential parameters. (#1533)
* Allow mixing unspecialized and specialized existential parameters.
* Fixes.
Diffstat (limited to 'source/slang/slang-ir-specialize.cpp')
| -rw-r--r-- | source/slang/slang-ir-specialize.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 3acb34c87..75b2beeec 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -611,6 +611,33 @@ struct SpecializationContext return nullptr; } + void maybeInsertGetExistentialValue(IRInst* inst) + { + // If inst has `ExistentialBox` type, we need to make sure + // all uses are through `GetValueFromExistentialBox`. + if (auto existentialBoxType = as<IRExistentialBoxType>(inst->getDataType())) + { + ShortList<IRUse*> usesToReplace; + for (auto use = inst->firstUse; use; use = use->nextUse) + { + if (use->getUser()->op != kIROp_GetValueFromExistentialBox) + usesToReplace.add(use); + } + for (auto use : usesToReplace) + { + auto user = use->getUser(); + IRBuilder builderStorage; + auto builder = &builderStorage; + builder->sharedBuilder = &sharedBuilderStorage; + builder->setInsertBefore(user); + auto getValueInst = builder->emitGetValueFromExistentialBox( + builder->getPtrType(existentialBoxType->getValueType()), inst); + use->set(getValueInst); + addToWorkList(getValueInst); + } + } + } + // All of the machinery for generic specialization // has been defined above, so we will now walk // through the flow of the overall specialization pass. @@ -678,6 +705,10 @@ struct SpecializationContext workListSet.Remove(inst); cleanInsts.Add(inst); + // If inst represents a value of ExistentialBox type, all its uses + // must be through a `GetValueFromExistentialBox` inst. + maybeInsertGetExistentialValue(inst); + // For each instruction we process, we want to perform // a few steps. // @@ -1640,7 +1671,7 @@ struct SpecializationContext if(slotOperandCount <= 1) return; auto concreteType = (IRType*) type->getExistentialArg(0); - auto newVal = builder.getPtrType(kIROp_ExistentialBoxType, concreteType); + auto newVal = builder.getExistentialBoxType(concreteType, baseInterfaceType); addUsersToWorkList(type); type->replaceUsesWith(newVal); |
