1 // Copyright (c) 2016 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef LIBSPIRV_OPT_PASS_H_ 16 #define LIBSPIRV_OPT_PASS_H_ 17 18 #include <algorithm> 19 #include <map> 20 #include <queue> 21 #include <unordered_map> 22 #include <unordered_set> 23 24 #include <utility> 25 26 #include "module.h" 27 #include "spirv-tools/libspirv.hpp" 28 29 namespace spvtools { 30 namespace opt { 31 32 // Abstract class of a pass. All passes should implement this abstract class 33 // and all analysis and transformation is done via the Process() method. 34 class Pass { 35 public: 36 // The status of processing a module using a pass. 37 // 38 // The numbers for the cases are assigned to make sure that Failure & anything 39 // is Failure, SuccessWithChange & any success is SuccessWithChange. 40 enum class Status { 41 Failure = 0x00, 42 SuccessWithChange = 0x10, 43 SuccessWithoutChange = 0x11, 44 }; 45 46 using ProcessFunction = std::function<bool(ir::Function*)>; 47 48 // Constructs a new pass. 49 // 50 // The constructed instance will have an empty message consumer, which just 51 // ignores all messages from the library. Use SetMessageConsumer() to supply 52 // one if messages are of concern. 53 Pass() : consumer_(nullptr) {} 54 55 // Destructs the pass. 56 virtual ~Pass() = default; 57 58 // Returns a descriptive name for this pass. 59 virtual const char* name() const = 0; 60 61 // Sets the message consumer to the given |consumer|. |consumer| which will be 62 // invoked every time there is a message to be communicated to the outside. 63 void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } 64 // Returns the reference to the message consumer for this pass. 65 const MessageConsumer& consumer() const { return consumer_; } 66 67 // Add to |todo| all ids of functions called in |func|. 68 void AddCalls(ir::Function* func, std::queue<uint32_t>* todo); 69 70 // 71 bool ProcessEntryPointCallTree(ProcessFunction& pfn, ir::Module* module); 72 73 // Processes the given |module|. Returns Status::Failure if errors occur when 74 // processing. Returns the corresponding Status::Success if processing is 75 // succesful to indicate whether changes are made to the module. 76 virtual Status Process(ir::Module* module) = 0; 77 78 private: 79 MessageConsumer consumer_; // Message consumer. 80 }; 81 82 } // namespace opt 83 } // namespace spvtools 84 85 #endif // LIBSPIRV_OPT_PASS_H_ 86