Home | History | Annotate | Download | only in opt
      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