Refactor validation types into another file
authorUmar Arshad <umar@arrayfire.com>
Mon, 14 Dec 2015 13:21:08 +0000 (08:21 -0500)
committerDavid Neto <dneto@google.com>
Thu, 17 Dec 2015 20:56:58 +0000 (15:56 -0500)
CMakeLists.txt
include/libspirv/libspirv.h
source/validate.cpp
source/validate_types.cpp [new file with mode: 0644]
source/validate_types.h [new file with mode: 0644]
test/ValidateFixtures.cpp
test/ValidateFixtures.h

index a0fc77c..4b74257 100644 (file)
@@ -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})
index 07bbe75..bd5ad5a 100644 (file)
@@ -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;
 
index 4554e01..179d225 100644 (file)
@@ -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:
diff --git a/source/validate_types.cpp b/source/validate_types.cpp
new file mode 100644 (file)
index 0000000..0779b2e
--- /dev/null
@@ -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);
+}
+}
diff --git a/source/validate_types.h b/source/validate_types.h
new file mode 100644 (file)
index 0000000..add6b29
--- /dev/null
@@ -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
index 5fde620..284fefe 100644 (file)
@@ -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>;
 }
index 1978f87..dbd3500 100644 (file)
@@ -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