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
20 namespace panda::compiler {
Rpo(Graph * graph)21 Rpo::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 */
DFS(BasicBlock * block,size_t * blocks_count)27 void 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
RunImpl()42 bool 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