summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-spirv-legalize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-ir-spirv-legalize.cpp')
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp46
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();