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_OPTIMIZATIONS_DEOPTIMIZEELIMINATION_H_ 17 #define COMPILER_OPTIMIZER_OPTIMIZATIONS_DEOPTIMIZEELIMINATION_H_ 18 19 #include "compiler_logger.h" 20 #include "optimizer/ir/graph.h" 21 #include "optimizer/pass.h" 22 #include "optimizer/analysis/bounds_analysis.h" 23 #include "optimizer/analysis/loop_analyzer.h" 24 #include "optimizer/ir/graph_visitor.h" 25 26 namespace panda::compiler { 27 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 28 class DeoptimizeElimination : public Optimization, public GraphVisitor { 29 using Optimization::Optimization; 30 31 public: DeoptimizeElimination(Graph * graph)32 explicit DeoptimizeElimination(Graph *graph) 33 : Optimization(graph), 34 blocks_type_(graph->GetLocalAllocator()->Adapter()), 35 deoptimize_must_throw_(graph->GetLocalAllocator()->Adapter()) 36 { 37 } 38 39 NO_MOVE_SEMANTIC(DeoptimizeElimination); 40 NO_COPY_SEMANTIC(DeoptimizeElimination); 41 ~DeoptimizeElimination() override = default; 42 43 bool RunImpl() override; 44 GetPassName()45 const char *GetPassName() const override 46 { 47 return "DeoptimizeElimination"; 48 } 49 50 void InvalidateAnalyses() override; 51 IsEnable()52 bool IsEnable() const override 53 { 54 return options.IsCompilerDeoptimizeElimination(); 55 } 56 57 void ReplaceDeoptimizeIfByUnconditionalDeoptimize(); 58 59 void RemoveSafePoints(); 60 61 /* 62 * By default all blocks have INVALID_TYPE. 63 * GUARD - If block have IsMustDeootimize before runtime call inst(in reverse order) 64 * RUNTIME_CALL - If block have runtime call inst before IsMustDeoptimize(in reverse order) 65 * NOTHING - If block is preccessed, but it doesn't contain GUARD and RUNTIME_CALL 66 */ 67 enum BlockType { INVALID, GUARD, RUNTIME_CALL, NOTHING }; 68 GetBlocksToVisit()69 const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override 70 { 71 return GetGraph()->GetBlocksRPO(); 72 } 73 SetApplied()74 void SetApplied() 75 { 76 is_applied_ = true; 77 } 78 IsApplied()79 bool IsApplied() const 80 { 81 return is_applied_; 82 } 83 HaveCalls()84 bool HaveCalls() 85 { 86 return have_calls_; 87 } 88 89 #include <deoptimize_elimination_call_visitors.inl> 90 static void VisitSaveState(GraphVisitor *v, Inst *inst); 91 static void VisitSaveStateDeoptimize(GraphVisitor *v, Inst *inst); 92 static void VisitDeoptimizeIf(GraphVisitor *v, Inst *inst); 93 void VisitDefault(Inst *inst) override; 94 95 #include "optimizer/ir/visitor.inc" 96 97 private: SetHaveCalls()98 void SetHaveCalls() 99 { 100 have_calls_ = true; 101 } 102 PushNewDeoptimizeIf(Inst * inst)103 void PushNewDeoptimizeIf(Inst *inst) 104 { 105 deoptimize_must_throw_.push_back(inst); 106 } 107 PushNewBlockType(BasicBlock * block,BlockType type)108 void PushNewBlockType(BasicBlock *block, BlockType type) 109 { 110 ASSERT(blocks_type_.find(block) == blocks_type_.end()); 111 blocks_type_.emplace(block, type); 112 } 113 GetBlockType(BasicBlock * block)114 BlockType GetBlockType(BasicBlock *block) 115 { 116 if (blocks_type_.find(block) != blocks_type_.end()) { 117 return blocks_type_.at(block); 118 } 119 return BlockType::INVALID; 120 } 121 122 bool TryToRemoveRedundantSaveState(Inst *inst); 123 bool CanRemoveGuard(Inst *guard); 124 bool CanRemoveGuardRec(BasicBlock *block, Inst *guard, const Marker &mrk, const Marker &remove_mrk); 125 void RemoveGuard(Inst *guard); 126 void RemoveDeoptimizeIf(Inst *inst); 127 bool RequireRegMap(Inst *inst); 128 129 private: 130 bool have_calls_ {false}; 131 bool is_applied_ {false}; 132 ArenaUnorderedMap<BasicBlock *, BlockType> blocks_type_; 133 InstVector deoptimize_must_throw_; 134 }; 135 } // namespace panda::compiler 136 137 #endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_DEOPTIMIZEELIMINATION_H_ 138