diff options
Diffstat (limited to 'source/slang/slang-ir-spirv-legalize.cpp')
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 2c4bd11cc..f795a6559 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -893,18 +893,22 @@ struct SPIRVLegalizationContext : public SourceEmitterBase IRBuilder builder(inst); builder.setInsertBefore(inst); auto funcType = as<IRFuncType>(funcValue->getFullType()); + bool argsChanged = false; for (UInt i = 0; i < inst->getArgCount(); i++) { auto arg = inst->getArg(i); auto paramType = funcType->getParamType(i); - if (as<IRPtrType>(paramType)) + if (auto ptrType = as<IRPtrType>(paramType)) { - // If the parameter has an explicit pointer type, - // then we know the user is using the variable pointer - // capability to pass a true pointer. - // In this case we should not rewrite the call. - newArgs.add(arg); - continue; + if (ptrType->getAddressSpace() == AddressSpace::UserPointer) + { + // If the parameter has an explicit pointer type, + // then we know the user is using the variable pointer + // capability to pass a true pointer. + // In this case we should not rewrite the call. + newArgs.add(arg); + continue; + } } auto ptrType = as<IRPtrTypeBase>(arg->getDataType()); if (!as<IRPtrTypeBase>(arg->getDataType())) @@ -953,13 +957,26 @@ struct SPIRVLegalizationContext : public SourceEmitterBase // If we reach here, we need to allocate a temp var. auto tempVar = builder.emitVar(ptrType->getValueType()); + builder.addDecoration(tempVar, kIROp_DisableCopyEliminationDecoration); auto load = builder.emitLoad(arg); builder.emitStore(tempVar, load); newArgs.add(tempVar); + argsChanged = true; + + // We may need to write the value back to the original pointer argument + // after the call. + // + // If callee doesn't modify the memory location, no need to write back. + if (funcType && funcType->getParamCount() > i && + as<IRConstRefType>(funcType->getParamType(i))) + continue; + // If the buffer location is immutable, don't write back. + if (isPointerToImmutableLocation(root)) + continue; writeBacks.add(WriteBackPair{arg, tempVar}); } SLANG_ASSERT((UInt)newArgs.getCount() == inst->getArgCount()); - if (writeBacks.getCount()) + if (argsChanged) { auto newCall = builder.emitCallInst(inst->getFullType(), inst->getCallee(), newArgs); for (auto wb : writeBacks) @@ -2297,19 +2314,6 @@ struct SPIRVLegalizationContext : public SourceEmitterBase // so we need to update the function types to match that. updateFunctionTypes(); - // Lower all loads/stores from buffer pointers to use correct storage types. - // We didn't do the lowering for buffer pointers because we don't know which pointer - // types are actual storage buffer pointers until we propagated the address space of - // pointers in this pass. In the future we should consider separate out IRAddress as - // the type for IRVar, and use IRPtrType to dedicate pointers in user code, so we can - // safely lower the pointer load stores early together with other buffer types. - BufferElementTypeLoweringOptions bufferElementTypeLoweringOptions; - bufferElementTypeLoweringOptions.lowerBufferPointer = true; - lowerBufferElementTypeToStorageType( - m_sharedContext->m_targetProgram, - m_module, - bufferElementTypeLoweringOptions); - // Look for structs that are both used as fields and marked with Block // decorations, and move the Block decoration to a wrapper struct. legalizeStructBlocks(); |
