1 /* 2 * Copyright (c) 2021-2024 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 ark::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 blocksType_(graph->GetLocalAllocator()->Adapter()), 35 deoptimizeMustThrow_(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 g_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 isApplied_ = true; 77 } 78 IsApplied()79 bool IsApplied() const 80 { 81 return isApplied_; 82 } 83 SetLoopDeleted()84 void SetLoopDeleted() 85 { 86 isLoopDeleted_ = true; 87 } 88 IsLoopDeleted()89 bool IsLoopDeleted() const 90 { 91 return isLoopDeleted_; 92 } 93 94 static void VisitDeoptimizeIf(GraphVisitor *v, Inst *inst); 95 96 #include "optimizer/ir/visitor.inc" 97 98 private: PushNewDeoptimizeIf(Inst * inst)99 void PushNewDeoptimizeIf(Inst *inst) 100 { 101 deoptimizeMustThrow_.push_back(inst); 102 } 103 PushNewBlockType(BasicBlock * block,BlockType type)104 void PushNewBlockType(BasicBlock *block, BlockType type) 105 { 106 ASSERT(blocksType_.find(block) == blocksType_.end()); 107 blocksType_.emplace(block, type); 108 } 109 GetBlockType(BasicBlock * block)110 BlockType GetBlockType(BasicBlock *block) 111 { 112 if (blocksType_.find(block) != blocksType_.end()) { 113 return blocksType_.at(block); 114 } 115 return BlockType::INVALID; 116 } 117 118 bool CanRemoveGuard(Inst *guard); 119 bool CanRemoveGuardRec(BasicBlock *block, Inst *guard, const Marker &mrk, const Marker &removeMrk); 120 void RemoveGuard(Inst *guard); 121 void RemoveDeoptimizeIf(Inst *inst); 122 123 private: 124 bool isApplied_ {false}; 125 bool isLoopDeleted_ {false}; 126 ArenaUnorderedMap<BasicBlock *, BlockType> blocksType_; 127 InstVector deoptimizeMustThrow_; 128 }; 129 } // namespace ark::compiler 130 131 #endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_DEOPTIMIZEELIMINATION_H 132