Commit 78cc4f4a by Nicolas Capens Committed by Nicolas Capens

Add helper methods for obtaining type and result ID

For instructions which define objects, the type ID and result ID are always the second and third SPIR-V instruction word, respectively. Bug: b/129000021 Change-Id: I6879251732860b80e1f7780d9078ad7bc9751b4c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43691 Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 9d2fd9c1
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "Vulkan/VkConfig.h" #include "Vulkan/VkConfig.h"
#include "Vulkan/VkDescriptorSet.hpp" #include "Vulkan/VkDescriptorSet.hpp"
#define SPV_ENABLE_UTILITY_CODE
#include <spirv/unified1/spirv.hpp> #include <spirv/unified1/spirv.hpp>
#include <array> #include <array>
...@@ -143,12 +144,22 @@ public: ...@@ -143,12 +144,22 @@ public:
ControlBarrier, ControlBarrier,
}; };
/* Pseudo-iterator over SPIRV instructions, designed to support range-based-for. */ class Type;
class Object;
// Pseudo-iterator over SPIRV instructions, designed to support range-based-for.
class InsnIterator class InsnIterator
{ {
InsnStore::const_iterator iter;
public: public:
InsnIterator(InsnIterator const &other) = default;
InsnIterator() = default;
explicit InsnIterator(InsnStore::const_iterator iter)
: iter{ iter }
{
}
spv::Op opcode() const spv::Op opcode() const
{ {
return static_cast<spv::Op>(*iter & spv::OpCodeMask); return static_cast<spv::Op>(*iter & spv::OpCodeMask);
...@@ -176,6 +187,26 @@ public: ...@@ -176,6 +187,26 @@ public:
return reinterpret_cast<const char *>(wordPointer(n)); return reinterpret_cast<const char *>(wordPointer(n));
} }
bool hasResultAndType() const
{
bool hasResult = false, hasResultType = false;
spv::HasResultAndType(opcode(), &hasResult, &hasResultType);
return hasResultType;
}
SpirvID<Type> resultTypeId() const
{
ASSERT(hasResultAndType());
return word(1);
}
SpirvID<Object> resultId() const
{
ASSERT(hasResultAndType());
return word(2);
}
bool operator==(InsnIterator const &other) const bool operator==(InsnIterator const &other) const
{ {
return iter == other.iter; return iter == other.iter;
...@@ -204,14 +235,8 @@ public: ...@@ -204,14 +235,8 @@ public:
return ret; return ret;
} }
InsnIterator(InsnIterator const &other) = default; private:
InsnStore::const_iterator iter;
InsnIterator() = default;
explicit InsnIterator(InsnStore::const_iterator iter)
: iter{ iter }
{
}
}; };
/* range-based-for interface */ /* range-based-for interface */
...@@ -247,9 +272,11 @@ public: ...@@ -247,9 +272,11 @@ public:
using ID = SpirvID<Object>; using ID = SpirvID<Object>;
spv::Op opcode() const { return definition.opcode(); } spv::Op opcode() const { return definition.opcode(); }
Type::ID typeId() const { return definition.resultTypeId(); }
Object::ID id() const { return definition.resultId(); }
InsnIterator definition; InsnIterator definition;
Type::ID type; Type::ID type; // TODO(b/129000021): Eliminate. Use typeId() instead.
std::unique_ptr<uint32_t[]> constantValue = nullptr; std::unique_ptr<uint32_t[]> constantValue = nullptr;
enum class Kind enum class Kind
...@@ -1006,7 +1033,12 @@ private: ...@@ -1006,7 +1033,12 @@ private:
return SIMD::UInt(constantValue[i]); return SIMD::UInt(constantValue[i]);
} }
SpirvShader::Type::ID const type; SpirvShader::Type::ID const type; // TODO(b/129000021): Eliminate. Use typeId() instead.
Type::ID typeId() const
{
return obj.typeId();
}
}; };
Type const &getType(Type::ID id) const Type const &getType(Type::ID id) const
...@@ -1016,6 +1048,16 @@ private: ...@@ -1016,6 +1048,16 @@ private:
return it->second; return it->second;
} }
Type const &getType(const Object &object) const
{
return getType(object.typeId());
}
Type const &getType(const Operand &operand) const
{
return getType(operand.typeId());
}
Object const &getObject(Object::ID id) const Object const &getObject(Object::ID id) const
{ {
auto it = defs.find(id); auto it = defs.find(id);
...@@ -1167,6 +1209,10 @@ private: ...@@ -1167,6 +1209,10 @@ private:
// etc). // etc).
static bool IsStatement(spv::Op op); static bool IsStatement(spv::Op op);
// HasTypeAndResult() returns true if the given opcode's instruction
// has a result type ID and result ID, i.e. defines an Object.
static bool HasTypeAndResult(spv::Op op);
// Helper as we often need to take dot products as part of doing other things. // Helper as we often need to take dot products as part of doing other things.
SIMD::Float Dot(unsigned numComponents, Operand const &x, Operand const &y) const; SIMD::Float Dot(unsigned numComponents, Operand const &x, Operand const &y) 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