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_MANAGER_H_
     16 #define LIBSPIRV_OPT_PASS_MANAGER_H_
     17 
     18 #include <memory>
     19 #include <vector>
     20 
     21 #include "log.h"
     22 #include "module.h"
     23 #include "pass.h"
     24 
     25 #include "spirv-tools/libspirv.hpp"
     26 
     27 namespace spvtools {
     28 namespace opt {
     29 
     30 // The pass manager, responsible for tracking and running passes.
     31 // Clients should first call AddPass() to add passes and then call Run()
     32 // to run on a module. Passes are executed in the exact order of addition.
     33 class PassManager {
     34  public:
     35   // Constructs a pass manager.
     36   //
     37   // The constructed instance will have an empty message consumer, which just
     38   // ignores all messages from the library. Use SetMessageConsumer() to supply
     39   // one if messages are of concern.
     40   PassManager() : consumer_(nullptr) {}
     41 
     42   // Sets the message consumer to the given |consumer|.
     43   void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); }
     44 
     45   // Adds an externally constructed pass.
     46   void AddPass(std::unique_ptr<Pass> pass);
     47   // Uses the argument |args| to construct a pass instance of type |T|, and adds
     48   // the pass instance to this pass manger. The pass added will use this pass
     49   // manager's message consumer.
     50   template <typename T, typename... Args>
     51   void AddPass(Args&&... args);
     52 
     53   // Returns the number of passes added.
     54   uint32_t NumPasses() const;
     55   // Returns a pointer to the |index|th pass added.
     56   inline Pass* GetPass(uint32_t index) const;
     57 
     58   // Returns the message consumer.
     59   inline const MessageConsumer& consumer() const;
     60 
     61   // Runs all passes on the given |module|. Returns Status::Failure if errors
     62   // occur when processing using one of the registered passes. All passes
     63   // registered after the error-reporting pass will be skipped. Returns the
     64   // corresponding Status::Success if processing is succesful to indicate
     65   // whether changes are made to the module.
     66   Pass::Status Run(ir::Module* module);
     67 
     68  private:
     69   // Consumer for messages.
     70   MessageConsumer consumer_;
     71   // A vector of passes. Order matters.
     72   std::vector<std::unique_ptr<Pass>> passes_;
     73 };
     74 
     75 inline void PassManager::AddPass(std::unique_ptr<Pass> pass) {
     76   passes_.push_back(std::move(pass));
     77 }
     78 
     79 template <typename T, typename... Args>
     80 inline void PassManager::AddPass(Args&&... args) {
     81   passes_.emplace_back(new T(std::forward<Args>(args)...));
     82   passes_.back()->SetMessageConsumer(consumer_);
     83 }
     84 
     85 inline uint32_t PassManager::NumPasses() const {
     86   return static_cast<uint32_t>(passes_.size());
     87 }
     88 
     89 inline Pass* PassManager::GetPass(uint32_t index) const {
     90   SPIRV_ASSERT(consumer_, index < passes_.size(), "index out of bound");
     91   return passes_[index].get();
     92 }
     93 
     94 inline const MessageConsumer& PassManager::consumer() const {
     95   return consumer_;
     96 }
     97 
     98 }  // namespace opt
     99 }  // namespace spvtools
    100 
    101 #endif  // LIBSPIRV_OPT_PASS_MANAGER_H_
    102