Home | History | Annotate | Download | only in opt
      1 // Copyright (c) 2018 Google LLC.
      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 SOURCE_OPT_LICM_PASS_H_
     16 #define SOURCE_OPT_LICM_PASS_H_
     17 
     18 #include <queue>
     19 #include <vector>
     20 
     21 #include "source/opt/basic_block.h"
     22 #include "source/opt/instruction.h"
     23 #include "source/opt/loop_descriptor.h"
     24 #include "source/opt/pass.h"
     25 
     26 namespace spvtools {
     27 namespace opt {
     28 
     29 class LICMPass : public Pass {
     30  public:
     31   LICMPass() {}
     32 
     33   const char* name() const override { return "loop-invariant-code-motion"; }
     34   Status Process() override;
     35 
     36  private:
     37   // Searches the IRContext for functions and processes each, moving invariants
     38   // outside loops within the function where possible.
     39   // Returns the status depending on whether or not there was a failure or
     40   // change.
     41   Pass::Status ProcessIRContext();
     42 
     43   // Checks the function for loops, calling ProcessLoop on each one found.
     44   // Returns the status depending on whether or not there was a failure or
     45   // change.
     46   Pass::Status ProcessFunction(Function* f);
     47 
     48   // Checks for invariants in the loop and attempts to move them to the loops
     49   // preheader. Works from inner loop to outer when nested loops are found.
     50   // Returns the status depending on whether or not there was a failure or
     51   // change.
     52   Pass::Status ProcessLoop(Loop* loop, Function* f);
     53 
     54   // Analyses each instruction in |bb|, hoisting invariants to |pre_header_bb|.
     55   // Each child of |bb| wrt to |dom_tree| is pushed to |loop_bbs|
     56   // Returns the status depending on whether or not there was a failure or
     57   // change.
     58   Pass::Status AnalyseAndHoistFromBB(Loop* loop, Function* f, BasicBlock* bb,
     59                                      std::vector<BasicBlock*>* loop_bbs);
     60 
     61   // Returns true if |bb| is immediately contained in |loop|
     62   bool IsImmediatelyContainedInLoop(Loop* loop, Function* f, BasicBlock* bb);
     63 
     64   // Move the instruction to the preheader of |loop|.
     65   // This method will update the instruction to block mapping for the context
     66   bool HoistInstruction(Loop* loop, Instruction* inst);
     67 };
     68 
     69 }  // namespace opt
     70 }  // namespace spvtools
     71 
     72 #endif  // SOURCE_OPT_LICM_PASS_H_
     73