diff options
author | Andrey Tuganov <andreyt@google.com> | 2018-01-31 16:29:54 -0500 |
---|---|---|
committer | David Neto <dneto@google.com> | 2018-02-05 13:14:55 -0500 |
commit | 12e6860d073bfa5a88f7925b58d52450811144a5 (patch) | |
tree | a8ba89c1c9b73f2df31464e7b939bd84d0e6ad80 /source/val | |
parent | 3ef4bb600f2ac09fda73671617e7793b5891afea (diff) | |
download | spirv-tools-12e6860d073bfa5a88f7925b58d52450811144a5.tar.gz |
Add barrier instructions validation pass
Diffstat (limited to 'source/val')
-rw-r--r-- | source/val/function.cpp | 31 | ||||
-rw-r--r-- | source/val/function.h | 19 |
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_; |