aboutsummaryrefslogtreecommitdiff
path: root/source/val
diff options
context:
space:
mode:
authorAndrey Tuganov <andreyt@google.com>2018-01-31 16:29:54 -0500
committerDavid Neto <dneto@google.com>2018-02-05 13:14:55 -0500
commit12e6860d073bfa5a88f7925b58d52450811144a5 (patch)
treea8ba89c1c9b73f2df31464e7b939bd84d0e6ad80 /source/val
parent3ef4bb600f2ac09fda73671617e7793b5891afea (diff)
downloadspirv-tools-12e6860d073bfa5a88f7925b58d52450811144a5.tar.gz
Add barrier instructions validation pass
Diffstat (limited to 'source/val')
-rw-r--r--source/val/function.cpp31
-rw-r--r--source/val/function.h19
2 files changed, 36 insertions, 14 deletions
diff --git a/source/val/function.cpp b/source/val/function.cpp
index f67acc4b..3a5c8e28 100644
--- a/source/val/function.cpp
+++ b/source/val/function.cpp
@@ -349,24 +349,41 @@ int Function::GetBlockDepth(BasicBlock* bb) {
return block_depth_[bb];
}
+void Function::RegisterExecutionModelLimitation(SpvExecutionModel model,
+ const std::string& message) {
+ execution_model_limitations_.push_back(
+ [model, message](SpvExecutionModel in_model, std::string* out_message) {
+ if (model != in_model) {
+ if (out_message) {
+ *out_message = message;
+ }
+ return false;
+ }
+ return true;
+ });
+}
+
bool Function::IsCompatibleWithExecutionModel(SpvExecutionModel model,
std::string* reason) const {
- bool is_compatible = true;
+ bool return_value = true;
std::stringstream ss_reason;
- for (const auto& kv : execution_model_limitations_) {
- if (kv.first != model) {
+ for (const auto& is_compatible : execution_model_limitations_) {
+ std::string message;
+ if (!is_compatible(model, &message)) {
if (!reason) return false;
- is_compatible = false;
- ss_reason << kv.second << "\n";
+ return_value = false;
+ if (!message.empty()) {
+ ss_reason << message << "\n";
+ }
}
}
- if (!is_compatible && reason) {
+ if (!return_value && reason) {
*reason = ss_reason.str();
}
- return is_compatible;
+ return return_value;
}
} // namespace libspirv
diff --git a/source/val/function.h b/source/val/function.h
index f6afb716..1984654f 100644
--- a/source/val/function.h
+++ b/source/val/function.h
@@ -203,11 +203,14 @@ class Function {
void PrintBlocks() const;
/// Registers execution model limitation such as "Feature X is only available
- /// with Execution Model Y". Only the first message per model type is
- /// registered.
+ /// with Execution Model Y".
void RegisterExecutionModelLimitation(SpvExecutionModel model,
- const std::string& message) {
- execution_model_limitations_.emplace(model, message);
+ const std::string& message);
+
+ /// Registers execution model limitation with an |is_compatible| functor.
+ void RegisterExecutionModelLimitation(
+ std::function<bool(SpvExecutionModel, std::string*)> is_compatible) {
+ execution_model_limitations_.push_back(is_compatible);
}
/// Returns true if the given execution model passes the limitations stored in
@@ -338,9 +341,11 @@ class Function {
std::unordered_map<BasicBlock*, int> block_depth_;
/// Stores execution model limitations imposed by instructions used within the
- /// function. The string contains message explaining why the limitation was
- /// imposed.
- std::map<SpvExecutionModel, std::string> execution_model_limitations_;
+ /// function. The functor stored in the list return true if execution model
+ /// is compatible, false otherwise. If the functor returns false, it can also
+ /// optionally fill the string parameter with the reason for incompatibility.
+ std::list<std::function<bool(SpvExecutionModel, std::string*)>>
+ execution_model_limitations_;
/// Stores ids of all functions called from this function.
std::set<uint32_t> function_call_targets_;