• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2018 Valve Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24 
25 #ifndef ACO_DOMINANCE_CPP
26 #define ACO_DOMINANCE_CPP
27 
28 #include "aco_ir.h"
29 
30 /*
31  * Implements the algorithms for computing the dominator tree from
32  * "A Simple, Fast Dominance Algorithm" by Cooper, Harvey, and Kennedy.
33  *
34  * Different from the paper, our CFG allows to compute the dominator tree
35  * in a single pass as it is guaranteed that the dominating predecessors
36  * are processed before the current block.
37  */
38 
39 namespace aco {
40 
41 void
dominator_tree(Program * program)42 dominator_tree(Program* program)
43 {
44    program->blocks[0].logical_idom = 0;
45    program->blocks[0].linear_idom = 0;
46 
47    for (unsigned i = 1; i < program->blocks.size(); i++) {
48       Block& block = program->blocks[i];
49       int new_logical_idom = -1;
50       int new_linear_idom = -1;
51       for (unsigned pred_idx : block.logical_preds) {
52          if ((int)program->blocks[pred_idx].logical_idom == -1)
53             continue;
54 
55          if (new_logical_idom == -1) {
56             new_logical_idom = pred_idx;
57             continue;
58          }
59 
60          while ((int)pred_idx != new_logical_idom) {
61             if ((int)pred_idx > new_logical_idom)
62                pred_idx = program->blocks[pred_idx].logical_idom;
63             if ((int)pred_idx < new_logical_idom)
64                new_logical_idom = program->blocks[new_logical_idom].logical_idom;
65          }
66       }
67 
68       for (unsigned pred_idx : block.linear_preds) {
69          if ((int)program->blocks[pred_idx].linear_idom == -1)
70             continue;
71 
72          if (new_linear_idom == -1) {
73             new_linear_idom = pred_idx;
74             continue;
75          }
76 
77          while ((int)pred_idx != new_linear_idom) {
78             if ((int)pred_idx > new_linear_idom)
79                pred_idx = program->blocks[pred_idx].linear_idom;
80             if ((int)pred_idx < new_linear_idom)
81                new_linear_idom = program->blocks[new_linear_idom].linear_idom;
82          }
83       }
84 
85       block.logical_idom = new_logical_idom;
86       block.linear_idom = new_linear_idom;
87    }
88 }
89 
90 } // namespace aco
91 #endif
92