annotate gcc/domwalk.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Generic dominator tree walker
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Diego Novillo <dnovillo@redhat.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
kono
parents: 67
diff changeset
25 #include "cfganal.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "domwalk.h"
111
kono
parents: 67
diff changeset
27 #include "dumpfile.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
29 /* This file implements a generic walker for dominator trees.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 To understand the dominator walker one must first have a grasp of dominators,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 immediate dominators and the dominator tree.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 Dominators
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 A block B1 is said to dominate B2 if every path from the entry to B2 must
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 pass through B1. Given the dominance relationship, we can proceed to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 compute immediate dominators. Note it is not important whether or not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 our definition allows a block to dominate itself.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 Immediate Dominators:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 Every block in the CFG has no more than one immediate dominator. The
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 immediate dominator of block BB must dominate BB and must not dominate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 any other dominator of BB and must not be BB itself.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 Dominator tree:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 If we then construct a tree where each node is a basic block and there
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 is an edge from each block's immediate dominator to the block itself, then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 we have a dominator tree.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 [ Note this walker can also walk the post-dominator tree, which is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 defined in a similar manner. i.e., block B1 is said to post-dominate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 block B2 if all paths from B2 to the exit block must pass through
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 B1. ]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 For example, given the CFG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 3 4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 +---------->5 6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 | / \ /
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 | +--->8 7
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 | | / |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 | +--9 11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 | / |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 +--- 10 ---> 12
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
71
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
72
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 We have a dominator tree which looks like
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 / \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 3 4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 / / \ \
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 | | | |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 5 6 7 12
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 | |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 8 11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 9
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 |
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 10
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
90
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
91
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
92
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 The dominator tree is the basis for a number of analysis, transformation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 and optimization algorithms that operate on a semi-global basis.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
95
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 The dominator walker is a generic routine which visits blocks in the CFG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 via a depth first search of the dominator tree. In the example above
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 the dominator walker might visit blocks in the following order
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
100
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 The dominator walker has a number of callbacks to perform actions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 during the walk of the dominator tree. There are two callbacks
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 which walk statements, one before visiting the dominator children,
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
104 one after visiting the dominator children. There is a callback
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 before and after each statement walk callback. In addition, the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 dominator walker manages allocation/deallocation of data structures
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 which are local to each block visited.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
108
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 The dominator walker is meant to provide a generic means to build a pass
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 which can analyze or transform/optimize a function based on walking
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 the dominator tree. One simply fills in the dominator walker data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 structure with the appropriate callbacks and calls the walker.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
113
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 We currently use the dominator walker to prune the set of variables
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 which might need PHI nodes (which can greatly improve compile-time
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 performance in some cases).
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
117
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 We also use the dominator walker to rewrite the function into SSA form
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 which reduces code duplication since the rewriting phase is inherently
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 a walk of the dominator tree.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 And (of course), we use the dominator walker to drive our dominator
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 optimizer, which is a semi-global optimizer.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 TODO:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 Walking statements is based on the block statement iterator abstraction,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 which is currently an abstraction over walking tree statements. Thus
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 the dominator walker is currently only useful for trees. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
111
kono
parents: 67
diff changeset
131 static int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
132 cmp_bb_postorder (const void *a, const void *b, void *data)
111
kono
parents: 67
diff changeset
133 {
kono
parents: 67
diff changeset
134 basic_block bb1 = *(const basic_block *)(a);
kono
parents: 67
diff changeset
135 basic_block bb2 = *(const basic_block *)(b);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
136 int *bb_postorder = (int *)data;
111
kono
parents: 67
diff changeset
137 /* Place higher completion number first (pop off lower number first). */
kono
parents: 67
diff changeset
138 return bb_postorder[bb2->index] - bb_postorder[bb1->index];
kono
parents: 67
diff changeset
139 }
kono
parents: 67
diff changeset
140
kono
parents: 67
diff changeset
141 /* Permute array BBS of N basic blocks in postorder,
kono
parents: 67
diff changeset
142 i.e. by descending number in BB_POSTORDER array. */
kono
parents: 67
diff changeset
143
kono
parents: 67
diff changeset
144 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
145 sort_bbs_postorder (basic_block *bbs, int n, int *bb_postorder)
111
kono
parents: 67
diff changeset
146 {
kono
parents: 67
diff changeset
147 if (__builtin_expect (n == 2, true))
kono
parents: 67
diff changeset
148 {
kono
parents: 67
diff changeset
149 basic_block bb0 = bbs[0], bb1 = bbs[1];
kono
parents: 67
diff changeset
150 if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
kono
parents: 67
diff changeset
151 bbs[0] = bb1, bbs[1] = bb0;
kono
parents: 67
diff changeset
152 }
kono
parents: 67
diff changeset
153 else if (__builtin_expect (n == 3, true))
kono
parents: 67
diff changeset
154 {
kono
parents: 67
diff changeset
155 basic_block bb0 = bbs[0], bb1 = bbs[1], bb2 = bbs[2];
kono
parents: 67
diff changeset
156 if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
kono
parents: 67
diff changeset
157 std::swap (bb0, bb1);
kono
parents: 67
diff changeset
158 if (bb_postorder[bb1->index] < bb_postorder[bb2->index])
kono
parents: 67
diff changeset
159 {
kono
parents: 67
diff changeset
160 std::swap (bb1, bb2);
kono
parents: 67
diff changeset
161 if (bb_postorder[bb0->index] < bb_postorder[bb1->index])
kono
parents: 67
diff changeset
162 std::swap (bb0, bb1);
kono
parents: 67
diff changeset
163 }
kono
parents: 67
diff changeset
164 bbs[0] = bb0, bbs[1] = bb1, bbs[2] = bb2;
kono
parents: 67
diff changeset
165 }
kono
parents: 67
diff changeset
166 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
167 gcc_sort_r (bbs, n, sizeof *bbs, cmp_bb_postorder, bb_postorder);
111
kono
parents: 67
diff changeset
168 }
kono
parents: 67
diff changeset
169
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 /* Set EDGE_EXECUTABLE on every edge within FN's CFG. */
111
kono
parents: 67
diff changeset
171
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 set_all_edges_as_executable (function *fn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 basic_block bb;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 FOR_ALL_BB_FN (bb, fn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 edge_iterator ei;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 edge e;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 FOR_EACH_EDGE (e, ei, bb->succs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 e->flags |= EDGE_EXECUTABLE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185 /* Constructor for a dom walker. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186
111
kono
parents: 67
diff changeset
187 dom_walker::dom_walker (cdi_direction direction,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
188 enum reachability reachability,
111
kono
parents: 67
diff changeset
189 int *bb_index_to_rpo)
kono
parents: 67
diff changeset
190 : m_dom_direction (direction),
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
191 m_reachability (reachability),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
192 m_user_bb_to_rpo (bb_index_to_rpo != NULL),
111
kono
parents: 67
diff changeset
193 m_unreachable_dom (NULL),
kono
parents: 67
diff changeset
194 m_bb_to_rpo (bb_index_to_rpo)
kono
parents: 67
diff changeset
195 {
kono
parents: 67
diff changeset
196 }
kono
parents: 67
diff changeset
197
kono
parents: 67
diff changeset
198 /* Destructor. */
kono
parents: 67
diff changeset
199
kono
parents: 67
diff changeset
200 dom_walker::~dom_walker ()
kono
parents: 67
diff changeset
201 {
kono
parents: 67
diff changeset
202 if (! m_user_bb_to_rpo)
kono
parents: 67
diff changeset
203 free (m_bb_to_rpo);
kono
parents: 67
diff changeset
204 }
kono
parents: 67
diff changeset
205
kono
parents: 67
diff changeset
206 /* Return TRUE if BB is reachable, false otherwise. */
kono
parents: 67
diff changeset
207
kono
parents: 67
diff changeset
208 bool
kono
parents: 67
diff changeset
209 dom_walker::bb_reachable (struct function *fun, basic_block bb)
kono
parents: 67
diff changeset
210 {
kono
parents: 67
diff changeset
211 /* If we're not skipping unreachable blocks, then assume everything
kono
parents: 67
diff changeset
212 is reachable. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
213 if (m_reachability == ALL_BLOCKS)
111
kono
parents: 67
diff changeset
214 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
111
kono
parents: 67
diff changeset
216 /* If any of the predecessor edges that do not come from blocks dominated
kono
parents: 67
diff changeset
217 by us are still marked as possibly executable consider this block
kono
parents: 67
diff changeset
218 reachable. */
kono
parents: 67
diff changeset
219 bool reachable = false;
kono
parents: 67
diff changeset
220 if (!m_unreachable_dom)
kono
parents: 67
diff changeset
221 {
kono
parents: 67
diff changeset
222 reachable = bb == ENTRY_BLOCK_PTR_FOR_FN (fun);
kono
parents: 67
diff changeset
223 edge_iterator ei;
kono
parents: 67
diff changeset
224 edge e;
kono
parents: 67
diff changeset
225 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents: 67
diff changeset
226 if (!dominated_by_p (CDI_DOMINATORS, e->src, bb))
kono
parents: 67
diff changeset
227 reachable |= (e->flags & EDGE_EXECUTABLE);
kono
parents: 67
diff changeset
228 }
kono
parents: 67
diff changeset
229
kono
parents: 67
diff changeset
230 return reachable;
kono
parents: 67
diff changeset
231 }
kono
parents: 67
diff changeset
232
kono
parents: 67
diff changeset
233 /* BB has been determined to be unreachable. Propagate that property
kono
parents: 67
diff changeset
234 to incoming and outgoing edges of BB as appropriate. */
kono
parents: 67
diff changeset
235
kono
parents: 67
diff changeset
236 void
kono
parents: 67
diff changeset
237 dom_walker::propagate_unreachable_to_edges (basic_block bb,
kono
parents: 67
diff changeset
238 FILE *dump_file,
kono
parents: 67
diff changeset
239 dump_flags_t dump_flags)
kono
parents: 67
diff changeset
240 {
kono
parents: 67
diff changeset
241 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
242 fprintf (dump_file, "Marking all outgoing edges of unreachable "
kono
parents: 67
diff changeset
243 "BB %d as not executable\n", bb->index);
kono
parents: 67
diff changeset
244
kono
parents: 67
diff changeset
245 edge_iterator ei;
kono
parents: 67
diff changeset
246 edge e;
kono
parents: 67
diff changeset
247 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
248 e->flags &= ~EDGE_EXECUTABLE;
kono
parents: 67
diff changeset
249
kono
parents: 67
diff changeset
250 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents: 67
diff changeset
251 {
kono
parents: 67
diff changeset
252 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
kono
parents: 67
diff changeset
253 {
kono
parents: 67
diff changeset
254 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
255 fprintf (dump_file, "Marking backedge from BB %d into "
kono
parents: 67
diff changeset
256 "unreachable BB %d as not executable\n",
kono
parents: 67
diff changeset
257 e->src->index, bb->index);
kono
parents: 67
diff changeset
258 e->flags &= ~EDGE_EXECUTABLE;
kono
parents: 67
diff changeset
259 }
kono
parents: 67
diff changeset
260 }
kono
parents: 67
diff changeset
261
kono
parents: 67
diff changeset
262 if (!m_unreachable_dom)
kono
parents: 67
diff changeset
263 m_unreachable_dom = bb;
kono
parents: 67
diff changeset
264 }
kono
parents: 67
diff changeset
265
kono
parents: 67
diff changeset
266 const edge dom_walker::STOP = (edge)-1;
kono
parents: 67
diff changeset
267
kono
parents: 67
diff changeset
268 /* Recursively walk the dominator tree.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 BB is the basic block we are currently visiting. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 void
111
kono
parents: 67
diff changeset
272 dom_walker::walk (basic_block bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
274 /* Compute the basic-block index to RPO mapping lazily. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
275 if (!m_bb_to_rpo
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
276 && m_dom_direction == CDI_DOMINATORS)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
277 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
278 int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
279 int postorder_num = pre_and_rev_post_order_compute (NULL, postorder,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
280 true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
281 m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
282 for (int i = 0; i < postorder_num; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
283 m_bb_to_rpo[postorder[i]] = i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
284 free (postorder);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
285 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
286
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
287 /* Set up edge flags if need be. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
288 if (m_reachability == REACHABLE_BLOCKS)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
289 set_all_edges_as_executable (cfun);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
290
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 basic_block dest;
111
kono
parents: 67
diff changeset
292 basic_block *worklist = XNEWVEC (basic_block,
kono
parents: 67
diff changeset
293 n_basic_blocks_for_fn (cfun) * 2);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 int sp = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 while (true)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 /* Don't worry about unreachable blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 if (EDGE_COUNT (bb->preds) > 0
111
kono
parents: 67
diff changeset
300 || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
kono
parents: 67
diff changeset
301 || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 {
111
kono
parents: 67
diff changeset
303 edge taken_edge = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304
111
kono
parents: 67
diff changeset
305 /* Callback for subclasses to do custom things before we have walked
kono
parents: 67
diff changeset
306 the dominator children, but before we walk statements. */
kono
parents: 67
diff changeset
307 if (this->bb_reachable (cfun, bb))
kono
parents: 67
diff changeset
308 {
kono
parents: 67
diff changeset
309 taken_edge = before_dom_children (bb);
kono
parents: 67
diff changeset
310 if (taken_edge && taken_edge != STOP)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 {
111
kono
parents: 67
diff changeset
312 edge_iterator ei;
kono
parents: 67
diff changeset
313 edge e;
kono
parents: 67
diff changeset
314 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
315 if (e != taken_edge)
kono
parents: 67
diff changeset
316 e->flags &= ~EDGE_EXECUTABLE;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 }
111
kono
parents: 67
diff changeset
319 else
kono
parents: 67
diff changeset
320 propagate_unreachable_to_edges (bb, dump_file, dump_flags);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
321
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 /* Mark the current BB to be popped out of the recursion stack
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 once children are processed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 worklist[sp++] = bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 worklist[sp++] = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326
111
kono
parents: 67
diff changeset
327 /* If the callback returned NONE then we are supposed to
kono
parents: 67
diff changeset
328 stop and not even propagate EDGE_EXECUTABLE further. */
kono
parents: 67
diff changeset
329 if (taken_edge != STOP)
kono
parents: 67
diff changeset
330 {
kono
parents: 67
diff changeset
331 int saved_sp = sp;
kono
parents: 67
diff changeset
332 for (dest = first_dom_son (m_dom_direction, bb);
kono
parents: 67
diff changeset
333 dest; dest = next_dom_son (m_dom_direction, dest))
kono
parents: 67
diff changeset
334 worklist[sp++] = dest;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 /* Sort worklist after RPO order if requested. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 if (sp - saved_sp > 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 && m_dom_direction == CDI_DOMINATORS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 && m_bb_to_rpo)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
339 sort_bbs_postorder (&worklist[saved_sp], sp - saved_sp,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
340 m_bb_to_rpo);
111
kono
parents: 67
diff changeset
341 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
343 /* NULL is used to mark pop operations in the recursion stack. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 while (sp > 0 && !worklist[sp - 1])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 --sp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 bb = worklist[--sp];
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
348
111
kono
parents: 67
diff changeset
349 /* Callback allowing subclasses to do custom things after we have
kono
parents: 67
diff changeset
350 walked dominator children, but before we walk statements. */
kono
parents: 67
diff changeset
351 if (bb_reachable (cfun, bb))
kono
parents: 67
diff changeset
352 after_dom_children (bb);
kono
parents: 67
diff changeset
353 else if (m_unreachable_dom == bb)
kono
parents: 67
diff changeset
354 m_unreachable_dom = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 if (sp)
111
kono
parents: 67
diff changeset
357 bb = worklist[--sp];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 free (worklist);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 }