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 #include "cleanup_empty_blocks.h" 17 #include "optimizer/optimizations/cleanup.h" 18 #include "optimizer/analysis/alias_analysis.h" 19 #include "optimizer/analysis/bounds_analysis.h" 20 #include "optimizer/analysis/dominators_tree.h" 21 #include "optimizer/analysis/linear_order.h" 22 #include "optimizer/analysis/loop_analyzer.h" 23 #include "optimizer/ir/basicblock.h" 24 25 namespace ark::compiler { 26 // Check around for special triangle case CheckSpecialTriangle(BasicBlock * bb)27static bool CheckSpecialTriangle(BasicBlock *bb) 28 { 29 auto succ = bb->GetSuccessor(0); 30 for (auto pred : bb->GetPredsBlocks()) { 31 if (pred->GetSuccessor(0) == succ || 32 (pred->GetSuccsBlocks().size() == MAX_SUCCS_NUM && pred->GetSuccessor(1) == succ)) { 33 return true; 34 } 35 } 36 return false; 37 } 38 TryRemoveEmptyBlock(BasicBlock * bb)39static bool TryRemoveEmptyBlock(BasicBlock *bb) 40 { 41 if (CheckSpecialTriangle(bb)) { 42 return false; 43 } 44 45 bool badLoop = bb->GetLoop()->IsIrreducible(); 46 bb->GetGraph()->RemoveEmptyBlockWithPhis(bb, badLoop); 47 if (badLoop) { 48 bb->GetGraph()->InvalidateAnalysis<LoopAnalyzer>(); 49 bb->GetGraph()->RunPass<LoopAnalyzer>(); 50 } 51 return true; 52 } 53 CleanupEmptyBlocks(Graph * graph)54bool CleanupEmptyBlocks(Graph *graph) 55 { 56 graph->RunPass<DominatorsTree>(); 57 graph->RunPass<LoopAnalyzer>(); 58 59 auto alloc = graph->GetAllocator(); 60 auto emptyBlocks = ArenaVector<BasicBlock *>(alloc->Adapter()); 61 62 for (auto bb : graph->GetVectorBlocks()) { 63 if (!Cleanup::SkipBasicBlock(bb) && bb->IsEmpty()) { 64 emptyBlocks.push_back(bb); 65 } 66 } 67 68 auto modified = false; 69 70 for (auto bb : emptyBlocks) { 71 auto succ = bb->GetSuccessor(0); 72 // Strange infinite loop with only one empty block, or loop pre-header - lets bail out 73 if (succ == bb || succ->GetLoop()->GetPreHeader() == bb) { 74 continue; 75 } 76 77 modified |= TryRemoveEmptyBlock(bb); 78 } 79 if (modified) { 80 graph->InvalidateAnalysis<LinearOrder>(); 81 graph->InvalidateAnalysis<BoundsAnalysis>(); 82 graph->InvalidateAnalysis<compiler::AliasAnalysis>(); 83 } 84 return modified; 85 } 86 } // namespace ark::compiler 87