From 8f962894fd38edb47d782d303ac9ff87b3a3bb6a Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 4 Sep 2020 10:18:44 -0700 Subject: Allow mixing unspecialized and specialized existential parameters. (#1533) * Allow mixing unspecialized and specialized existential parameters. * Fixes. --- source/slang/slang-ir-lower-existential.cpp | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'source/slang/slang-ir-lower-existential.cpp') diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index a6db2b781..0dce96de2 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -7,6 +7,9 @@ namespace Slang { + bool isCPUTarget(TargetRequest* targetReq); + bool isCUDATarget(TargetRequest* targetReq); + struct ExistentialLoweringContext { SharedGenericsLoweringContext* sharedContext; @@ -79,12 +82,40 @@ namespace Slang processExtractExistentialElement(inst, 0); } + void processGetValueFromExistentialBox(IRGetValueFromExistentialBox* inst) + { + // Currently we do not translate on HLSL/GLSL targets, + // since we don't attempt to actually layout the value inside an fixed sized + // existential box for these targets. + if (isCPUTarget(sharedContext->targetReq) || isCUDATarget(sharedContext->targetReq)) + { + IRBuilder builderStorage; + auto builder = &builderStorage; + builder->sharedBuilder = &sharedContext->sharedBuilderStorage; + builder->setInsertBefore(inst); + + auto element = extractTupleElement(builder, inst->getOperand(0), 2); + // TODO: it is not technically sound to use `getAddress` on a temporary value. + // We probably need to develop a mechanism to allow a temporary value to be used + // in the place of a pointer. + auto elementAddr = + builder->emitGetAddress(builder->getPtrType(element->getDataType()), element); + auto reinterpretAddr = builder->emitBitCast(inst->getDataType(), elementAddr); + inst->replaceUsesWith(reinterpretAddr); + inst->removeAndDeallocate(); + } + } + void processInst(IRInst* inst) { if (auto makeExistential = as(inst)) { processMakeExistential(makeExistential); } + else if (auto getExistentialValue = as(inst)) + { + processGetValueFromExistentialBox(getExistentialValue); + } else if (auto extractExistentialVal = as(inst)) { processExtractExistentialValue(extractExistentialVal); -- cgit v1.2.3