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#include "optimizer/ir/basicblock.h" 17#include "optimizer/ir/graph.h" 18#include "rpo.h" 19 20namespace panda::compiler { 21Rpo::Rpo(Graph *graph) : Analysis(graph), rpo_vector_(graph->GetAllocator()->Adapter()) {} 22 23/** 24 * Depth-first search 25 * `blocks_count` needs for filling `rpo_vector_` in reverse order 26 */ 27void Rpo::DFS(BasicBlock *block, size_t *blocks_count) 28{ 29 ASSERT(block != nullptr); 30 block->SetMarker(marker_); 31 32 for (auto succ_block : block->GetSuccsBlocks()) { 33 if (!succ_block->IsMarked(marker_)) { 34 DFS(succ_block, blocks_count); 35 } 36 } 37 38 ASSERT(blocks_count != nullptr && *blocks_count > 0); 39 rpo_vector_[--(*blocks_count)] = block; 40} 41 42bool Rpo::RunImpl() 43{ 44 size_t blocks_count = GetGraph()->GetAliveBlocksCount(); 45 rpo_vector_.resize(blocks_count); 46 if (blocks_count == 0) { 47 return true; 48 } 49 marker_ = GetGraph()->NewMarker(); 50 ASSERT_PRINT(marker_ != UNDEF_MARKER, "There are no free markers. Please erase unused markers"); 51 DFS(GetGraph()->GetStartBlock(), &blocks_count); 52#ifndef NDEBUG 53 if (blocks_count != 0) { 54 std::cerr << "There are unreachable blocks:\n"; 55 for (auto bb : *GetGraph()) { 56 if (bb != nullptr && !bb->IsMarked(marker_)) { 57 bb->Dump(&std::cerr); 58 } 59 } 60 UNREACHABLE(); 61 } 62#endif // NDEBUG 63 GetGraph()->EraseMarker(marker_); 64 return true; 65} 66} // namespace panda::compiler 67