1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 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 16 #ifndef COMPILER_OPTIMIZER_ANALYSIS_LINEAR_ORDER_H 17 #define COMPILER_OPTIMIZER_ANALYSIS_LINEAR_ORDER_H 18 19 #include "optimizer/ir/marker.h" 20 #include "optimizer/pass.h" 21 #include "utils/arena_containers.h" 22 23 namespace panda::compiler { 24 class BasicBlock; 25 class Graph; 26 27 /* 28 * For each `If` block place its false-successor in the next position of the `linear_blocks_` vector: 29 * - inverse type of IfInst if true-successor is placed first; 30 * - marks `If` block with `JumpFlag` (so `Codegen` could insert `jmp`) if there are no `If` successors 31 * placed just after it; 32 */ 33 class LinearOrder : public Analysis { 34 public: 35 explicit LinearOrder(Graph *graph); 36 37 bool RunImpl() override; 38 39 const char *GetPassName() const override 40 { 41 return "BlocksLinearOrder"; 42 } 43 GetBlocks()44 ArenaVector<BasicBlock *> &GetBlocks() 45 { 46 return linear_blocks_; 47 } 48 GetBlocks() const49 const ArenaVector<BasicBlock *> &GetBlocks() const 50 { 51 return linear_blocks_; 52 } 53 54 NO_MOVE_SEMANTIC(LinearOrder); 55 NO_COPY_SEMANTIC(LinearOrder); 56 ~LinearOrder() override = default; 57 58 private: 59 void HandlePrevInstruction(BasicBlock *block, BasicBlock *prev_block); 60 void HandleIfBlock(BasicBlock *if_true_block, BasicBlock *next_block); 61 template <class T> 62 void MakeLinearOrder(const T &blocks); 63 64 private: 65 BasicBlock *LeastLikelySuccessor(const BasicBlock *block); 66 // similar to DFS but move least frequent branch to the end 67 template <bool defer_least_frequent> 68 void DFSAndDeferLeastFrequentBranches(BasicBlock *block, size_t *blocks_count); 69 Marker marker_ {UNDEF_MARKER}; 70 ArenaVector<BasicBlock *> linear_blocks_; 71 ArenaList<BasicBlock *> rpo_blocks_; 72 ArenaVector<BasicBlock *> reordered_blocks_; 73 }; 74 } // namespace panda::compiler 75 76 #endif // COMPILER_OPTIMIZER_ANALYSIS_LINEAR_ORDER_H 77