• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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