Home | History | Annotate | Download | only in opt
      1 // Copyright (c) 2017 The Khronos Group Inc.
      2 // Copyright (c) 2017 Valve Corporation
      3 // Copyright (c) 2017 LunarG Inc.
      4 //
      5 // Licensed under the Apache License, Version 2.0 (the "License");
      6 // you may not use this file except in compliance with the License.
      7 // You may obtain a copy of the License at
      8 //
      9 //     http://www.apache.org/licenses/LICENSE-2.0
     10 //
     11 // Unless required by applicable law or agreed to in writing, software
     12 // distributed under the License is distributed on an "AS IS" BASIS,
     13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 // See the License for the specific language governing permissions and
     15 // limitations under the License.
     16 
     17 #ifndef LIBSPIRV_OPT_BLOCK_MERGE_PASS_H_
     18 #define LIBSPIRV_OPT_BLOCK_MERGE_PASS_H_
     19 
     20 #include <algorithm>
     21 #include <map>
     22 #include <queue>
     23 #include <unordered_map>
     24 #include <unordered_set>
     25 #include <utility>
     26 
     27 #include "basic_block.h"
     28 #include "def_use_manager.h"
     29 #include "module.h"
     30 #include "pass.h"
     31 
     32 namespace spvtools {
     33 namespace opt {
     34 
     35 // See optimizer.hpp for documentation.
     36 class BlockMergePass : public Pass {
     37  public:
     38   BlockMergePass();
     39   const char* name() const override { return "sroa"; }
     40   Status Process(ir::Module*) override;
     41 
     42  private:
     43   // Return true if |block_ptr| is loop header block
     44   bool IsLoopHeader(ir::BasicBlock* block_ptr);
     45 
     46   // Return true if |labId| has multiple refs. Do not count OpName.
     47   bool HasMultipleRefs(uint32_t labId);
     48 
     49   // Kill any OpName instruction referencing |inst|, then kill |inst|.
     50   void KillInstAndName(ir::Instruction* inst);
     51 
     52   // Search |func| for blocks which have a single Branch to a block
     53   // with no other predecessors. Merge these blocks into a single block.
     54   bool MergeBlocks(ir::Function* func);
     55 
     56   // Initialize extensions whitelist
     57   void InitExtensions();
     58 
     59   // Return true if all extensions in this module are allowed by this pass.
     60   bool AllExtensionsSupported() const;
     61 
     62   void Initialize(ir::Module* module);
     63   Pass::Status ProcessImpl();
     64 
     65   // Module this pass is processing
     66   ir::Module* module_;
     67 
     68   // Def-Uses for the module we are processing
     69   std::unique_ptr<analysis::DefUseManager> def_use_mgr_;
     70 
     71   // Extensions supported by this pass.
     72   std::unordered_set<std::string> extensions_whitelist_;
     73 };
     74 
     75 }  // namespace opt
     76 }  // namespace spvtools
     77 
     78 #endif  // LIBSPIRV_OPT_BLOCK_MERGE_PASS_H_
     79 
     80