diff options
| author | Yong He <yonghe@outlook.com> | 2020-08-18 13:08:45 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-18 13:08:45 -0700 |
| commit | b820f34a1b6336af184458c5b1dfe2273c99f1ff (patch) | |
| tree | ca9986891127cfe07eda18bfbdb5094eef5677cc | |
| parent | 9abcb6ea24dbc7184c3a2ad9f4458f63f8901928 (diff) | |
Support initializing an existential value from a generic value. (#1503)
* Support initializing an existential value from a generic value.
* Remove trailing spaces and clean up debugging code.
21 files changed, 402 insertions, 102 deletions
diff --git a/.gitignore b/.gitignore index 1471d0b6e..0ee4e49e4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.sdf *.ilk *.obj +.clang-format bin/ intermediate/ build.*/ diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp index 26a9fca58..f732ffbe7 100644 --- a/source/slang/slang-ir-any-value-marshalling.cpp +++ b/source/slang/slang-ir-any-value-marshalling.cpp @@ -448,24 +448,18 @@ namespace Slang sharedContext->addToWorkList(sharedContext->module->getModuleInst()); - // Process all instructions and translate all `IRPackAnyValue` and `IRUnpackAnyValue`. while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } diff --git a/source/slang/slang-ir-augment-make-existential.cpp b/source/slang/slang-ir-augment-make-existential.cpp new file mode 100644 index 000000000..18d061276 --- /dev/null +++ b/source/slang/slang-ir-augment-make-existential.cpp @@ -0,0 +1,84 @@ +#include "slang-ir-augment-make-existential.h" +#include "slang-ir-insts.h" +#include "slang-ir.h" + +namespace Slang +{ +struct AugmentMakeExistentialContext +{ + IRModule* module; + + SharedIRBuilder sharedBuilderStorage; + + List<IRInst*> workList; + HashSet<IRInst*> workListSet; + + void addToWorkList(IRInst* inst) + { + if (workListSet.Contains(inst)) + return; + + workList.add(inst); + workListSet.Add(inst); + } + + void processMakeExistential(IRMakeExistential* inst) + { + IRBuilder builderStorage; + auto builder = &builderStorage; + builder->sharedBuilder = &sharedBuilderStorage; + builder->setInsertBefore(inst); + + auto augInst = builder->emitMakeExistentialWithRTTI( + inst->getFullType(), + inst->getWrappedValue(), + inst->getWitnessTable(), + inst->getWrappedValue()->getDataType()); + inst->replaceUsesWith(augInst); + inst->removeAndDeallocate(); + } + + void processInst(IRInst* inst) + { + switch (inst->op) + { + case kIROp_MakeExistential: + processMakeExistential((IRMakeExistential*)inst); + break; + default: + break; + } + } + + void processModule() + { + SharedIRBuilder* sharedBuilder = &sharedBuilderStorage; + sharedBuilder->module = module; + sharedBuilder->session = module->session; + + addToWorkList(module->getModuleInst()); + + while (workList.getCount() != 0) + { + IRInst* inst = workList.getLast(); + + workList.removeLast(); + workListSet.Remove(inst); + + processInst(inst); + + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + addToWorkList(child); + } + } + } +}; + +void augmentMakeExistentialInsts(IRModule* module) +{ + AugmentMakeExistentialContext context; + context.module = module; + context.processModule(); +} +} // namespace Slang diff --git a/source/slang/slang-ir-augment-make-existential.h b/source/slang/slang-ir-augment-make-existential.h new file mode 100644 index 000000000..75f2183b4 --- /dev/null +++ b/source/slang/slang-ir-augment-make-existential.h @@ -0,0 +1,16 @@ +// slang-ir-augment-make-existential.h +#pragma once + +#include "slang-ir.h" + +namespace Slang +{ +struct IRModule; +class DiagnosticSink; + +/// Augment `MakeExistential(v, w)` insts to `MakeExistentialWithRTTI(v, w, t)`, +/// where v is a concrete typed value, w is a witness table, and t is the type of +/// v. +void augmentMakeExistentialInsts(IRModule* module); + +} // namespace Slang diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp index 55e18ebbb..67f376153 100644 --- a/source/slang/slang-ir-generics-lowering-context.cpp +++ b/source/slang/slang-ir-generics-lowering-context.cpp @@ -135,7 +135,8 @@ namespace Slang switch (paramType->op) { case kIROp_WitnessTableType: - // Do not translate witness table type. + case kIROp_ExtractExistentialType: + // Do not translate these types. return (IRType*)paramType; case kIROp_Param: { diff --git a/source/slang/slang-ir-hoist-local-types.cpp b/source/slang/slang-ir-hoist-local-types.cpp new file mode 100644 index 000000000..864daa680 --- /dev/null +++ b/source/slang/slang-ir-hoist-local-types.cpp @@ -0,0 +1,111 @@ +#include "slang-ir-hoist-local-types.h" + +#include "slang-ir-insts.h" +#include "slang-ir.h" + +namespace Slang +{ +struct HoistLocalTypesContext +{ + IRModule* module; + DiagnosticSink* sink; + + SharedIRBuilder sharedBuilderStorage; + + List<IRInst*> workList; + HashSet<IRInst*> workListSet; + + void addToWorkList(IRInst* inst) + { + for (auto ii = inst->getParent(); ii; ii = ii->getParent()) + { + if (as<IRGeneric>(ii)) + return; + } + + if (workListSet.Contains(inst)) + return; + + workList.add(inst); + workListSet.Add(inst); + } + + void processInst(IRInst* inst) + { + auto sharedBuilder = &sharedBuilderStorage; + if (!as<IRType>(inst)) + return; + if (inst->getParent() == module->getModuleInst()) + return; + IRInstKey key = {inst}; + if (auto value = sharedBuilder->globalValueNumberingMap.TryGetValue(key)) + { + inst->replaceUsesWith(*value); + inst->removeAndDeallocate(); + return; + } + IRBuilder builder; + builder.sharedBuilder = sharedBuilder; + builder.setInsertInto(module->getModuleInst()); + bool hoistable = true; + ShortList<IRInst*> mappedOperands; + for (UInt i = 0; i < inst->getOperandCount(); i++) + { + IRInstKey opKey = {inst->getOperand(i)}; + if (auto value = sharedBuilder->globalValueNumberingMap.TryGetValue(opKey)) + { + mappedOperands.add(*value); + } + else + { + hoistable = false; + break; + } + } + if (hoistable) + { + auto newType = builder.getType( + inst->op, mappedOperands.getCount(), mappedOperands.getArrayView().getBuffer()); + inst->transferDecorationsTo(newType); + inst->replaceUsesWith(newType); + inst->removeAndDeallocate(); + } + } + + void processModule() + { + SharedIRBuilder* sharedBuilder = &sharedBuilderStorage; + sharedBuilder->module = module; + sharedBuilder->session = module->session; + + // Deduplicate equivalent types and build numbering map for global types. + sharedBuilder->deduplicateAndRebuildGlobalNumberingMap(); + + addToWorkList(module->getModuleInst()); + + while (workList.getCount() != 0) + { + IRInst* inst = workList.getLast(); + + workList.removeLast(); + workListSet.Remove(inst); + + processInst(inst); + + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + addToWorkList(child); + } + } + } +}; + +void hoistLocalTypes(IRModule* module, DiagnosticSink* sink) +{ + HoistLocalTypesContext context; + context.module = module; + context.sink = sink; + context.processModule(); +} + +} // namespace Slang diff --git a/source/slang/slang-ir-hoist-local-types.h b/source/slang/slang-ir-hoist-local-types.h new file mode 100644 index 000000000..6b742746f --- /dev/null +++ b/source/slang/slang-ir-hoist-local-types.h @@ -0,0 +1,18 @@ +// slang-ir-hoist-local-types.h +#pragma once + +#include "slang-ir.h" + +namespace Slang +{ +struct IRModule; +class DiagnosticSink; + +/// Hoist local types to global scope if possible. +/// Some transformation passes may leave behind local type definitons that +/// can be hoisted to global scope. This pass examines all local type defintions +// and try to hoist them to global scope if the definition is no longer dependent on +// the local context. +void hoistLocalTypes(IRModule* module, DiagnosticSink* sink); + +} // namespace Slang diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index f60f84a9e..05ad07668 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -573,6 +573,10 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) // shows that `C` conforms to `I`. // INST(MakeExistential, makeExistential, 2, 0) +// A `MakeExistentialWithRTTI(v, w, t)` is the same with `MakeExistential`, +// but with the type of `v` being an explict operand. +INST(MakeExistentialWithRTTI, makeExistentialWithRTTI, 3, 0) + // A `wrapExistential(v, T0,w0, T1,w0) : T` instruction is similar to `makeExistential`. // but applies to a value `v` that is of type `BindExistentials(T, T0,w0, ...)`. The diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index a66ca8f7a..65a2dd4a6 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -1590,6 +1590,16 @@ struct IRMakeExistential : IRInst IR_LEAF_ISA(MakeExistential) }; +struct IRMakeExistentialWithRTTI : IRInst +{ + IRInst* getWrappedValue() { return getOperand(0); } + IRInst* getWitnessTable() { return getOperand(1); } + IRInst* getRTTI() { return getOperand(2); } + + + IR_LEAF_ISA(MakeExistentialWithRTTI) +}; + /// Generalizes `IRMakeExistential` by allowing a type with existential sub-fields to be boxed struct IRWrapExistential : IRInst { @@ -1927,6 +1937,12 @@ struct IRBuilder IRInst* value, IRInst* witnessTable); + IRInst* emitMakeExistentialWithRTTI( + IRType* type, + IRInst* value, + IRInst* witnessTable, + IRInst* rtti); + IRInst* emitWrapExistential( IRType* type, IRInst* value, diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index af47a1dfe..4078ad884 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -11,7 +11,7 @@ namespace Slang { SharedGenericsLoweringContext* sharedContext; - void processMakeExistential(IRMakeExistential* inst) + void processMakeExistential(IRMakeExistentialWithRTTI* inst) { IRBuilder builderStorage; auto builder = &builderStorage; @@ -27,17 +27,11 @@ namespace Slang auto rttiType = builder->getPtrType(builder->getRTTIType()); auto tupleType = builder->getTupleType(anyValueType, witnessTableType, rttiType); - IRInst* rttiObject = nullptr; - if (valueType->op != kIROp_AnyValueType) - { - rttiObject = sharedContext->maybeEmitRTTIObject(valueType); - rttiObject = builder->emitGetAddress( - builder->getPtrType(builder->getRTTIType()), - rttiObject); - } - else + IRInst* rttiObject = inst->getRTTI(); + if (auto type = as<IRType>(rttiObject)) { - rttiObject = valueType; + rttiObject = sharedContext->maybeEmitRTTIObject(type); + rttiObject = builder->emitGetAddress(rttiType, rttiObject); } IRInst* packedValue = value; if (valueType->op != kIROp_AnyValueType) @@ -87,7 +81,7 @@ namespace Slang void processInst(IRInst* inst) { - if (auto makeExistential = as<IRMakeExistential>(inst)) + if (auto makeExistential = as<IRMakeExistentialWithRTTI>(inst)) { processMakeExistential(makeExistential); } @@ -119,21 +113,16 @@ namespace Slang while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } } diff --git a/source/slang/slang-ir-lower-generic-call.cpp b/source/slang/slang-ir-lower-generic-call.cpp index 1bc6d6705..90216b915 100644 --- a/source/slang/slang-ir-lower-generic-call.cpp +++ b/source/slang/slang-ir-lower-generic-call.cpp @@ -226,21 +226,16 @@ namespace Slang while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } } diff --git a/source/slang/slang-ir-lower-generic-function.cpp b/source/slang/slang-ir-lower-generic-function.cpp index 360e3cdbb..f9a7e0a24 100644 --- a/source/slang/slang-ir-lower-generic-function.cpp +++ b/source/slang/slang-ir-lower-generic-function.cpp @@ -297,21 +297,16 @@ namespace Slang while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } diff --git a/source/slang/slang-ir-lower-generic-type.cpp b/source/slang/slang-ir-lower-generic-type.cpp index 4ea47a4b2..0b0973274 100644 --- a/source/slang/slang-ir-lower-generic-type.cpp +++ b/source/slang/slang-ir-lower-generic-type.cpp @@ -44,21 +44,16 @@ namespace Slang while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } sharedContext->sharedBuilderStorage.deduplicateAndRebuildGlobalNumberingMap(); diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index b00e36ef1..63e1fdc49 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -2,6 +2,7 @@ #include "slang-ir-lower-generics.h" #include "slang-ir-any-value-marshalling.h" +#include "slang-ir-augment-make-existential.h" #include "slang-ir-generics-lowering-context.h" #include "slang-ir-lower-existential.h" #include "slang-ir-lower-generic-function.h" @@ -21,9 +22,15 @@ namespace Slang sharedContext.module = module; sharedContext.sink = sink; - lowerExistentials(&sharedContext); - if (sink->getErrorCount() != 0) - return; + // Replace all `makeExistential` insts with `makeExistentialWithRTTI` + // before making any other changes. This is necessary because a parameter of + // generic type will be lowered into `AnyValueType`, and after that we can no longer + // access the original generic type parameter from the lowered parameter value. + // This steps ensures that the generic type parameter is available via an + // explicit operand in `makeExistentialWithRTTI`, so that type parameter + // can be translated into an RTTI object during `lower-generic-type`, + // and used to create a tuple representing the existential value. + augmentMakeExistentialInsts(module); lowerGenericFunctions(&sharedContext); if (sink->getErrorCount() != 0) @@ -33,6 +40,10 @@ namespace Slang if (sink->getErrorCount() != 0) return; + lowerExistentials(&sharedContext); + if (sink->getErrorCount() != 0) + return; + lowerGenericCalls(&sharedContext); if (sink->getErrorCount() != 0) return; diff --git a/source/slang/slang-ir-lower-tuple-types.cpp b/source/slang/slang-ir-lower-tuple-types.cpp index cadf77253..d9fd91d3d 100644 --- a/source/slang/slang-ir-lower-tuple-types.cpp +++ b/source/slang/slang-ir-lower-tuple-types.cpp @@ -149,21 +149,16 @@ namespace Slang while (workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (workList.getCount() != 0) - { - IRInst* inst = workList.getLast(); + IRInst* inst = workList.getLast(); - workList.removeLast(); - workListSet.Remove(inst); + workList.removeLast(); + workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + addToWorkList(child); } } diff --git a/source/slang/slang-ir-witness-table-wrapper.cpp b/source/slang/slang-ir-witness-table-wrapper.cpp index 8dda95563..084571642 100644 --- a/source/slang/slang-ir-witness-table-wrapper.cpp +++ b/source/slang/slang-ir-witness-table-wrapper.cpp @@ -211,21 +211,16 @@ namespace Slang while (sharedContext->workList.getCount() != 0) { - // We will then iterate until our work list goes dry. - // - while (sharedContext->workList.getCount() != 0) - { - IRInst* inst = sharedContext->workList.getLast(); + IRInst* inst = sharedContext->workList.getLast(); - sharedContext->workList.removeLast(); - sharedContext->workListSet.Remove(inst); + sharedContext->workList.removeLast(); + sharedContext->workListSet.Remove(inst); - processInst(inst); + processInst(inst); - for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) - { - sharedContext->addToWorkList(child); - } + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + sharedContext->addToWorkList(child); } } } diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 2a1db6310..c5943da3c 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2790,6 +2790,16 @@ namespace Slang return emitIntrinsicInst(type, kIROp_MakeExistential, SLANG_COUNT_OF(args), args); } + IRInst* IRBuilder::emitMakeExistentialWithRTTI( + IRType* type, + IRInst* value, + IRInst* witnessTable, + IRInst* rtti) + { + IRInst* args[] = { value, witnessTable, rtti }; + return emitIntrinsicInst(type, kIROp_MakeExistentialWithRTTI, SLANG_COUNT_OF(args), args); + } + IRInst* IRBuilder::emitWrapExistential( IRType* type, IRInst* value, diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 82e575ef9..563014c5b 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -223,6 +223,7 @@ <ClInclude Include="slang-image-format-defs.h" /> <ClInclude Include="slang-include-system.h" /> <ClInclude Include="slang-ir-any-value-marshalling.h" /> + <ClInclude Include="slang-ir-augment-make-existential.h" /> <ClInclude Include="slang-ir-bind-existentials.h" /> <ClInclude Include="slang-ir-byte-address-legalize.h" /> <ClInclude Include="slang-ir-clone.h" /> @@ -236,6 +237,7 @@ <ClInclude Include="slang-ir-explicit-global-init.h" /> <ClInclude Include="slang-ir-generics-lowering-context.h" /> <ClInclude Include="slang-ir-glsl-legalize.h" /> + <ClInclude Include="slang-ir-hoist-local-types.h" /> <ClInclude Include="slang-ir-inline.h" /> <ClInclude Include="slang-ir-inst-defs.h" /> <ClInclude Include="slang-ir-insts.h" /> @@ -329,6 +331,7 @@ <ClCompile Include="slang-hlsl-intrinsic-set.cpp" /> <ClCompile Include="slang-include-system.cpp" /> <ClCompile Include="slang-ir-any-value-marshalling.cpp" /> + <ClCompile Include="slang-ir-augment-make-existential.cpp" /> <ClCompile Include="slang-ir-bind-existentials.cpp" /> <ClCompile Include="slang-ir-byte-address-legalize.cpp" /> <ClCompile Include="slang-ir-clone.cpp" /> @@ -343,6 +346,7 @@ <ClCompile Include="slang-ir-explicit-global-init.cpp" /> <ClCompile Include="slang-ir-generics-lowering-context.cpp" /> <ClCompile Include="slang-ir-glsl-legalize.cpp" /> + <ClCompile Include="slang-ir-hoist-local-types.cpp" /> <ClCompile Include="slang-ir-inline.cpp" /> <ClCompile Include="slang-ir-layout.cpp" /> <ClCompile Include="slang-ir-legalize-types.cpp" /> @@ -413,4 +417,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project>
\ No newline at end of file +</Project>
\ No newline at end of file diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index 3484a1638..1fff5d01f 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -120,6 +120,9 @@ <ClInclude Include="slang-ir-any-value-marshalling.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-ir-augment-make-existential.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-ir-bind-existentials.h"> <Filter>Header Files</Filter> </ClInclude> @@ -159,6 +162,9 @@ <ClInclude Include="slang-ir-glsl-legalize.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-ir-hoist-local-types.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-ir-inline.h"> <Filter>Header Files</Filter> </ClInclude> @@ -434,6 +440,9 @@ <ClCompile Include="slang-ir-any-value-marshalling.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-ir-augment-make-existential.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-ir-bind-existentials.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -476,6 +485,9 @@ <ClCompile Include="slang-ir-glsl-legalize.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-ir-hoist-local-types.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-ir-inline.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/tests/compute/dynamic-dispatch-9.slang b/tests/compute/dynamic-dispatch-9.slang new file mode 100644 index 000000000..4fb45edc9 --- /dev/null +++ b/tests/compute/dynamic-dispatch-9.slang @@ -0,0 +1,50 @@ +//TEST(compute):COMPARE_COMPUTE:-cpu -xslang -allow-dynamic-code +//DISABLE_TEST(compute):COMPARE_COMPUTE:-cuda -xslang -allow-dynamic-code + +// Test dynamic dispatch code gen for initializing an extential value +// from a generic value. + +[anyValueSize(16)] +interface IInterface +{ + int Compute(int inVal); +}; + +int GenericCompute0(IInterface obj, int inVal) +{ + return obj.Compute(inVal); +} + +int GenericCompute1<T:IInterface>(T obj, int inVal) +{ + IInterface iobj = obj; + return iobj.Compute(inVal) + + GenericCompute0(obj, inVal) - + GenericCompute0(iobj, inVal); +} + + +struct Impl : IInterface +{ + int base; + int Compute(int inVal) { return base + inVal * inVal; } +}; + +int test(int inVal) +{ + Impl obj; + obj.base = 1; + return GenericCompute1(obj, inVal); +} + +//TEST_INPUT:ubuffer(data=[0 1 2 3], stride=4):out,name=outputBuffer +RWStructuredBuffer<int> outputBuffer : register(u0); + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + int inVal = outputBuffer[tid]; + int outVal = test(inVal); + outputBuffer[tid] = outVal; +} diff --git a/tests/compute/dynamic-dispatch-9.slang.expected.txt b/tests/compute/dynamic-dispatch-9.slang.expected.txt new file mode 100644 index 000000000..146ab3c8c --- /dev/null +++ b/tests/compute/dynamic-dispatch-9.slang.expected.txt @@ -0,0 +1,4 @@ +1 +2 +5 +A |
