diff options
Diffstat (limited to 'source/slang/slang-ir-lower-existential.cpp')
| -rw-r--r-- | source/slang/slang-ir-lower-existential.cpp | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/source/slang/slang-ir-lower-existential.cpp b/source/slang/slang-ir-lower-existential.cpp index a87169ac3..9df0e51db 100644 --- a/source/slang/slang-ir-lower-existential.cpp +++ b/source/slang/slang-ir-lower-existential.cpp @@ -83,28 +83,53 @@ namespace Slang processExtractExistentialElement(inst, 0); } - void processGetValueFromExistentialBox(IRGetValueFromExistentialBox* inst) + void processGetValueFromBoundInterface(IRGetValueFromBoundInterface* 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); + + // A value of interface will lower as a tuple, and + // the third element of that tuple represents the + // concrete value that was put into the existential. + // + auto element = extractTupleElement(builder, inst->getOperand(0), 2); + auto elementType = element->getDataType(); + + // There are two cases we expect to see for that + // tuple element. + // + IRInst* replacement = nullptr; + if(as<IRPseudoPtrType>(elementType)) + { + // The first case is when legacy static specialization + // is applied, and the element is a "pseudo-pointer." + // + // Semantically, we should emit a (pseudo-)load from the pseudo-pointer + // to go from `PseudoPtr<T>` to `T`. + // + // TODO: Actually introduce and emit a "psedudo-load" instruction + // here. For right now we are just using the value directly and + // downstream passes seem okay with it, but it isn't really + // type-correct to be doing this. + // + replacement = element; + } + else { - 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(); + // The second case is when the dynamic-dispatch layout is + // being used, and the element is an "any-value." + // + // In this case we need to emit an unpacking operation + // to get from `AnyValue` to `T`. + // + SLANG_ASSERT(as<IRAnyValueType>(elementType)); + replacement = builder->emitUnpackAnyValue(inst->getFullType(), element); } + + inst->replaceUsesWith(replacement); + inst->removeAndDeallocate(); } void processInst(IRInst* inst) @@ -113,9 +138,9 @@ namespace Slang { processMakeExistential(makeExistential); } - else if (auto getExistentialValue = as<IRGetValueFromExistentialBox>(inst)) + else if (auto getValueFromBoundInterface = as<IRGetValueFromBoundInterface>(inst)) { - processGetValueFromExistentialBox(getExistentialValue); + processGetValueFromBoundInterface(getValueFromBoundInterface); } else if (auto extractExistentialVal = as<IRExtractExistentialValue>(inst)) { |
