diff options
| author | Yong He <yonghe@outlook.com> | 2020-10-02 09:49:18 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-02 09:49:18 -0700 |
| commit | aadf6002783b88ea79c30a2f908270685b6c3d27 (patch) | |
| tree | 890d60ea78a81b35fa9ad28873bbe25c1fc7f9a4 /source/slang/slang-ir-specialize.cpp | |
| parent | 274c20a5eb133779a9d890ca79120815fb92b04e (diff) | |
Specialize exsitentials parameters in struct fields. (#1565)
* Specialize exsitentials parameters in struct fields.
* Cleanup.
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-specialize.cpp')
| -rw-r--r-- | source/slang/slang-ir-specialize.cpp | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index d364de3fb..ceba4b03c 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -808,6 +808,24 @@ struct SpecializationContext return false; } + /// Used by `maybeSpecailizeBufferLoadCall`, this function returns a new specialized callee that + /// replaces a `specialize(.operator[], oldType)` to `specialize(.operator[], newElementType)`. + IRInst* getNewSpecializedBufferLoadCallee( + IRInst* oldSpecializedCallee, + IRType* newContainerType, + IRType* newElementType) + { + auto oldSpecialize = cast<IRSpecialize>(oldSpecializedCallee); + SLANG_ASSERT(oldSpecialize->getArgCount() == 1); + IRBuilder builder; + builder.sharedBuilder = &sharedBuilderStorage; + builder.setInsertBefore(oldSpecializedCallee); + auto calleeType = builder.getFuncType(1, &newContainerType, newElementType); + auto newSpecialize = builder.emitSpecializeInst( + calleeType, oldSpecialize->getBase(), 1, (IRInst**)&newElementType); + return newSpecialize; + } + /// Transform a buffer load intrinsic call. /// `bufferLoad(wrapExistential(bufferObj, wrapArgs), loadArgs)` should be transformed into /// `wrapExistential(bufferLoad(bufferObj, loadArgs), wragArgs)`. @@ -844,11 +862,18 @@ struct SpecializationContext { slotOperands.add(wrapExistential->getSlotOperand(ii)); } - auto newCall = builder.emitCallInst(elementType, inst->getCallee(), args); + // The old callee should be in the form of `specialize(.operator[], IInterfaceType)`, + // we should update it to be `specialize(.operator[], elementType)`, so the return type + // of the load call is `elementType`. + auto oldCallee = inst->getCallee(); + auto newCallee = getNewSpecializedBufferLoadCallee(inst->getCallee(), sbType, elementType); + auto newCall = builder.emitCallInst(elementType, newCallee, args); auto newWrapExistential = builder.emitWrapExistential( resultType, newCall, slotOperandCount, slotOperands.getBuffer()); inst->replaceUsesWith(newWrapExistential); inst->removeAndDeallocate(); + SLANG_ASSERT(!oldCallee->hasUses()); + oldCallee->removeAndDeallocate(); addUsersToWorkList(newWrapExistential); return true; } @@ -1080,7 +1105,8 @@ struct SpecializationContext // if(as<IRInterfaceType>(type)) return true; - + if (calcExistentialTypeParamSlotCount(type) != 0) + return true; // Eventually we will also want to handle arrays over // existential types, but that will require careful // handling in many places. @@ -1518,6 +1544,11 @@ struct SpecializationContext type = arrayType->getElementType(); goto top; } + else if (auto sbType = as<IRHLSLStructuredBufferTypeBase>(type)) + { + type = sbType->getElementType(); + goto top; + } else if( auto structType = as<IRStructType>(type) ) { UInt count = 0; @@ -1800,6 +1831,11 @@ struct SpecializationContext type = ptrLikeType->getElementType(); goto top; } + else if (auto sbType = as<IRHLSLStructuredBufferTypeBase>(type)) + { + type = sbType->getElementType(); + goto top; + } else if( auto structType = as<IRStructType>(type) ) { UInt count = 0; @@ -1872,15 +1908,15 @@ struct SpecializationContext baseElementType, slotOperandCount, type->getExistentialArgs()); - addToWorkList(wrappedElementType); auto newPtrLikeType = builder.getType( baseType->op, 1, &wrappedElementType); + addUsersToWorkList(type); addToWorkList(newPtrLikeType); + addToWorkList(wrappedElementType); - addUsersToWorkList(type); type->replaceUsesWith(newPtrLikeType); type->removeAndDeallocate(); return; @@ -1911,10 +1947,13 @@ struct SpecializationContext } IRStructType* newStructType = nullptr; + addUsersToWorkList(type); + if( !existentialSpecializedStructs.TryGetValue(key, newStructType) ) { builder.setInsertBefore(baseStructType); newStructType = builder.createStructType(); + addToWorkList(newStructType); auto fieldSlotArgs = type->getExistentialArgs(); @@ -1939,10 +1978,8 @@ struct SpecializationContext } existentialSpecializedStructs.Add(key, newStructType); - addToWorkList(newStructType); } - addUsersToWorkList(type); type->replaceUsesWith(newStructType); type->removeAndDeallocate(); return; |
