mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 12:10:06 +00:00
Refactor validation types into another file
This commit is contained in:
parent
532af9c09c
commit
6d37e3c5f3
@ -115,6 +115,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text_handler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/assembly_grammar.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/binary.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/disassemble.cpp
|
||||
@ -128,6 +129,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text_handler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate_types.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate_id.cpp)
|
||||
|
||||
add_library(${SPIRV_TOOLS} ${SPIRV_SOURCES})
|
||||
|
@ -74,6 +74,7 @@ typedef enum spv_result_t {
|
||||
SPV_ERROR_INVALID_DIAGNOSTIC = -8,
|
||||
SPV_ERROR_INVALID_LOOKUP = -9,
|
||||
SPV_ERROR_INVALID_ID = -10,
|
||||
SPV_ERROR_INVALID_CFG = -11,
|
||||
SPV_FORCE_32_BIT_ENUM(spv_result_t)
|
||||
} spv_result_t;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
|
||||
#include "validate.h"
|
||||
#include "validate_types.h"
|
||||
|
||||
#include "binary.h"
|
||||
#include "diagnostic.h"
|
||||
@ -56,6 +57,7 @@ using std::transform;
|
||||
using std::unordered_set;
|
||||
using std::vector;
|
||||
|
||||
using libspirv::ValidationState_t;
|
||||
|
||||
#define spvCheckReturn(expression) \
|
||||
if (spv_result_t error = (expression)) return error;
|
||||
@ -303,90 +305,6 @@ spv_result_t setHeader(void* user_data, spv_endianness_t endian, uint32_t magic,
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO(umar): Move this class to another file
|
||||
class ValidationState_t {
|
||||
public:
|
||||
ValidationState_t(spv_diagnostic* diag, uint32_t options)
|
||||
: diagnostic_(diag),
|
||||
instruction_counter_(0),
|
||||
validation_flags_(options) {}
|
||||
|
||||
spv_result_t definedIds(uint32_t id) {
|
||||
if (defined_ids_.find(id) == std::end(defined_ids_)) {
|
||||
defined_ids_.insert(id);
|
||||
} else {
|
||||
return diag(SPV_ERROR_INVALID_ID)
|
||||
<< "ID cannot be assigned multiple times";
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t forwardDeclareId(uint32_t id) {
|
||||
unresolved_forward_ids_.insert(id);
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t removeIfForwardDeclared(uint32_t id) {
|
||||
unresolved_forward_ids_.erase(id);
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
void assignNameToId(uint32_t id, string name) { operand_names[id] = name; }
|
||||
|
||||
string getIdName(uint32_t id) {
|
||||
std::stringstream out;
|
||||
out << id;
|
||||
if (operand_names.find(id) != end(operand_names)) {
|
||||
out << "[" << operand_names[id] << "]";
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
size_t unresolvedForwardIdCount() const {
|
||||
return unresolved_forward_ids_.size();
|
||||
}
|
||||
|
||||
vector<uint32_t> unresolvedForwardIds() const {
|
||||
vector<uint32_t> out(begin(unresolved_forward_ids_),
|
||||
end(unresolved_forward_ids_));
|
||||
return out;
|
||||
}
|
||||
|
||||
//
|
||||
bool isDefinedId(uint32_t id) const {
|
||||
return defined_ids_.find(id) != std::end(defined_ids_);
|
||||
}
|
||||
|
||||
bool is_enabled(uint32_t flag) const {
|
||||
return (flag & validation_flags_) == flag;
|
||||
}
|
||||
|
||||
// Increments the instruction count. Used for diagnostic
|
||||
int incrementInstructionCount() { return instruction_counter_++; }
|
||||
|
||||
libspirv::DiagnosticStream diag(spv_result_t error_code) const {
|
||||
return libspirv::DiagnosticStream(
|
||||
{0, 0, static_cast<size_t>(instruction_counter_)}, diagnostic_,
|
||||
error_code);
|
||||
}
|
||||
|
||||
private:
|
||||
spv_diagnostic* diagnostic_;
|
||||
// Tracks the number of instructions evaluated by the validator
|
||||
int instruction_counter_;
|
||||
|
||||
// All IDs which have been defined
|
||||
unordered_set<uint32_t> defined_ids_;
|
||||
|
||||
// IDs which have been forward declared but have not been defined
|
||||
unordered_set<uint32_t> unresolved_forward_ids_;
|
||||
|
||||
// Validation options to determine the passes to execute
|
||||
uint32_t validation_flags_;
|
||||
|
||||
map<uint32_t, string> operand_names;
|
||||
};
|
||||
|
||||
// Performs SSA validation on the IDs of an instruction. The
|
||||
// can_have_forward_declared_ids functor should return true if the
|
||||
// instruction operand's ID can be forward referenced.
|
||||
@ -407,7 +325,7 @@ spv_result_t SsaPass(ValidationState_t& _,
|
||||
switch (type) {
|
||||
case SPV_OPERAND_TYPE_RESULT_ID:
|
||||
_.removeIfForwardDeclared(*operand_ptr);
|
||||
ret = _.definedIds(*operand_ptr);
|
||||
ret = _.defineId(*operand_ptr);
|
||||
break;
|
||||
case SPV_OPERAND_TYPE_ID:
|
||||
case SPV_OPERAND_TYPE_TYPE_ID:
|
||||
|
105
source/validate_types.cpp
Normal file
105
source/validate_types.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2015 The Khronos Group Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and/or associated documentation files (the
|
||||
// "Materials"), to deal in the Materials without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
// permit persons to whom the Materials are furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Materials.
|
||||
//
|
||||
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
|
||||
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
|
||||
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
|
||||
// https://www.khronos.org/registry/
|
||||
//
|
||||
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
|
||||
#include "validate_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::unordered_set;
|
||||
|
||||
namespace libspirv {
|
||||
|
||||
ValidationState_t::ValidationState_t(spv_diagnostic* diag, uint32_t options)
|
||||
: diagnostic_(diag), instruction_counter_(0), validation_flags_(options) {}
|
||||
|
||||
spv_result_t ValidationState_t::defineId(uint32_t id) {
|
||||
if (defined_ids_.find(id) == end(defined_ids_)) {
|
||||
defined_ids_.insert(id);
|
||||
} else {
|
||||
return diag(SPV_ERROR_INVALID_ID) << "ID cannot be assigned multiple times";
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t ValidationState_t::forwardDeclareId(uint32_t id) {
|
||||
unresolved_forward_ids_.insert(id);
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t ValidationState_t::removeIfForwardDeclared(uint32_t id) {
|
||||
unresolved_forward_ids_.erase(id);
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
void ValidationState_t::assignNameToId(uint32_t id, string name) {
|
||||
operand_names_[id] = name;
|
||||
}
|
||||
|
||||
string ValidationState_t::getIdName(uint32_t id) const {
|
||||
std::stringstream out;
|
||||
out << id;
|
||||
if (operand_names_.find(id) != end(operand_names_)) {
|
||||
out << "[" << operand_names_.at(id) << "]";
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
size_t ValidationState_t::unresolvedForwardIdCount() const {
|
||||
return unresolved_forward_ids_.size();
|
||||
}
|
||||
|
||||
vector<uint32_t> ValidationState_t::unresolvedForwardIds() const {
|
||||
vector<uint32_t> out(begin(unresolved_forward_ids_),
|
||||
end(unresolved_forward_ids_));
|
||||
return out;
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidationState_t::isDefinedId(uint32_t id) const {
|
||||
return defined_ids_.find(id) != end(defined_ids_);
|
||||
}
|
||||
|
||||
bool ValidationState_t::is_enabled(spv_validate_options_t flag) const {
|
||||
return (flag & validation_flags_) == flag;
|
||||
}
|
||||
|
||||
// Increments the instruction count. Used for diagnostic
|
||||
int ValidationState_t::incrementInstructionCount() {
|
||||
return instruction_counter_++;
|
||||
}
|
||||
|
||||
libspirv::DiagnosticStream ValidationState_t::diag(
|
||||
spv_result_t error_code) const {
|
||||
return libspirv::DiagnosticStream(
|
||||
{0, 0, static_cast<size_t>(instruction_counter_)}, diagnostic_,
|
||||
error_code);
|
||||
}
|
||||
}
|
98
source/validate_types.h
Normal file
98
source/validate_types.h
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2015 The Khronos Group Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and/or associated documentation files (the
|
||||
// "Materials"), to deal in the Materials without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
// permit persons to whom the Materials are furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Materials.
|
||||
//
|
||||
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
|
||||
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
|
||||
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
|
||||
// https://www.khronos.org/registry/
|
||||
//
|
||||
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
|
||||
#ifndef LIBSPIRV_VALIDATE_TYPES_H_
|
||||
#define LIBSPIRV_VALIDATE_TYPES_H_
|
||||
|
||||
#include "binary.h"
|
||||
#include "diagnostic.h"
|
||||
#include "libspirv/libspirv.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace libspirv {
|
||||
|
||||
class ValidationState_t {
|
||||
public:
|
||||
ValidationState_t(spv_diagnostic* diag, uint32_t options);
|
||||
|
||||
// Defines the \p id for the module
|
||||
spv_result_t defineId(uint32_t id);
|
||||
|
||||
// Forward declares the id in the module
|
||||
spv_result_t forwardDeclareId(uint32_t id);
|
||||
|
||||
// Removes a forward declared ID if it has been defined
|
||||
spv_result_t removeIfForwardDeclared(uint32_t id);
|
||||
|
||||
// Assigns a name to an ID
|
||||
void assignNameToId(uint32_t id, std::string name);
|
||||
|
||||
// Returns a string representation of the ID in the format <id>[Name] where
|
||||
// the <id> is the numeric valid of the id and the Name is a name assigned by
|
||||
// the OpName instruction
|
||||
std::string getIdName(uint32_t id) const;
|
||||
|
||||
// Returns the number of ID which have been forward referenced but not defined
|
||||
size_t unresolvedForwardIdCount() const;
|
||||
|
||||
// Returns a list of unresolved forward ids.
|
||||
std::vector<uint32_t> unresolvedForwardIds() const;
|
||||
|
||||
// Returns true if the id has been defined
|
||||
bool isDefinedId(uint32_t id) const;
|
||||
|
||||
// Returns true if an spv_validate_options_t option is enabled in the
|
||||
// validation instruction
|
||||
bool is_enabled(spv_validate_options_t flag) const;
|
||||
|
||||
// Increments the instruction count. Used for diagnostic
|
||||
int incrementInstructionCount();
|
||||
|
||||
libspirv::DiagnosticStream diag(spv_result_t error_code) const;
|
||||
|
||||
private:
|
||||
spv_diagnostic* diagnostic_;
|
||||
// Tracks the number of instructions evaluated by the validator
|
||||
int instruction_counter_;
|
||||
|
||||
// All IDs which have been defined
|
||||
std::unordered_set<uint32_t> defined_ids_;
|
||||
|
||||
// IDs which have been forward declared but have not been defined
|
||||
std::unordered_set<uint32_t> unresolved_forward_ids_;
|
||||
|
||||
// Validation options to determine the passes to execute
|
||||
uint32_t validation_flags_;
|
||||
|
||||
std::map<uint32_t, std::string> operand_names_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -75,4 +75,6 @@ std::string ValidateBase<T, OPTIONS>::getDiagnosticString() {
|
||||
|
||||
template class spvtest::ValidateBase<std::pair<std::string, bool>,
|
||||
SPV_VALIDATE_SSA_BIT>;
|
||||
template class spvtest::ValidateBase<bool,
|
||||
SPV_VALIDATE_SSA_BIT>;
|
||||
}
|
||||
|
@ -26,6 +26,9 @@
|
||||
|
||||
// Common validation fixtures for unit tests
|
||||
|
||||
#ifndef LIBSPIRV_TEST_VALIDATE_FIXTURES_H_
|
||||
#define LIBSPIRV_TEST_VALIDATE_FIXTURES_H_
|
||||
|
||||
#include "UnitSPIRV.h"
|
||||
|
||||
namespace spvtest {
|
||||
@ -56,3 +59,4 @@ class ValidateBase : public ::testing::Test,
|
||||
static const uint32_t validation_options_ = OPTIONS;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user