Commit 0b77aa5e by Nicolas Capens Committed by Nicolas Capens

Separate Operand store logic from EmitStore()

The new Store() helper function can store Operand instances independent from SPIR-V instructions. This allows reuse of this logic for other instructions that need to store to memory, like Modf and Frexp. Bug: b/153641251 Change-Id: I453bb7cd24ba26b9a23d73568dc3374a52a36073 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43695 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com>
parent 2f4b603e
...@@ -1175,6 +1175,10 @@ private: ...@@ -1175,6 +1175,10 @@ private:
void EvalSpecConstantUnaryOp(InsnIterator insn); void EvalSpecConstantUnaryOp(InsnIterator insn);
void EvalSpecConstantBinaryOp(InsnIterator insn); void EvalSpecConstantBinaryOp(InsnIterator insn);
// Helper for implementing OpStore, which doesn't take an InsnIterator so it
// can also store independent operands.
void Store(Object::ID pointerId, const Operand &value, bool atomic, std::memory_order memoryOrder, EmitState *state) const;
// LoadPhi loads the phi values from the alloca storage and places the // LoadPhi loads the phi values from the alloca storage and places the
// load values into the intermediate with the phi's result id. // load values into the intermediate with the phi's result id.
void LoadPhi(InsnIterator insn, EmitState *state) const; void LoadPhi(InsnIterator insn, EmitState *state) const;
......
...@@ -71,10 +71,6 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta ...@@ -71,10 +71,6 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta
bool atomic = (insn.opcode() == spv::OpAtomicStore); bool atomic = (insn.opcode() == spv::OpAtomicStore);
Object::ID pointerId = insn.word(1); Object::ID pointerId = insn.word(1);
Object::ID objectId = insn.word(atomic ? 4 : 2); Object::ID objectId = insn.word(atomic ? 4 : 2);
auto &object = getObject(objectId);
auto &pointer = getObject(pointerId);
auto &pointerTy = getType(pointer);
auto &elementTy = getType(pointerTy.element);
std::memory_order memoryOrder = std::memory_order_relaxed; std::memory_order memoryOrder = std::memory_order_relaxed;
if(atomic) if(atomic)
...@@ -84,6 +80,19 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta ...@@ -84,6 +80,19 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta
memoryOrder = MemoryOrder(memorySemantics); memoryOrder = MemoryOrder(memorySemantics);
} }
const auto &value = Operand(this, state, objectId);
Store(pointerId, value, atomic, memoryOrder, state);
return EmitResult::Continue;
}
void SpirvShader::Store(Object::ID pointerId, const Operand &value, bool atomic, std::memory_order memoryOrder, EmitState *state) const
{
auto &pointer = getObject(pointerId);
auto &pointerTy = getType(pointer);
auto &elementTy = getType(pointerTy.element);
ASSERT(!atomic || elementTy.opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer." ASSERT(!atomic || elementTy.opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer."
auto ptr = GetPointerToData(pointerId, 0, state); auto ptr = GetPointerToData(pointerId, 0, state);
...@@ -96,28 +105,11 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta ...@@ -96,28 +105,11 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta
mask = mask & state->storesAndAtomicsMask(); mask = mask & state->storesAndAtomicsMask();
} }
if(object.kind == Object::Kind::Constant) VisitMemoryObject(pointerId, [&](const MemoryElement &el) {
{ auto p = ptr + el.offset;
// Constant source data. if(interleavedByLane) { p = InterleaveByLane(p); }
const uint32_t *src = object.constantValue.data(); p.Store(value.Float(el.index), robustness, mask, atomic, memoryOrder);
VisitMemoryObject(pointerId, [&](const MemoryElement &el) { });
auto p = ptr + el.offset;
if(interleavedByLane) { p = InterleaveByLane(p); }
p.Store(SIMD::Int(src[el.index]), robustness, mask, atomic, memoryOrder);
});
}
else
{
// Intermediate source data.
auto &src = state->getIntermediate(objectId);
VisitMemoryObject(pointerId, [&](const MemoryElement &el) {
auto p = ptr + el.offset;
if(interleavedByLane) { p = InterleaveByLane(p); }
p.Store(src.Float(el.index), robustness, mask, atomic, memoryOrder);
});
}
return EmitResult::Continue;
} }
SpirvShader::EmitResult SpirvShader::EmitVariable(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVariable(InsnIterator insn, EmitState *state) const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment