annotate gcc/tree-ssa-sink.c @ 144:8f4e72ab4e11

fix segmentation fault caused by nothing next cur_op to end
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 21:23:56 +0900
parents 84e7813d76e9
children 1830386684a0
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 /* Code sinking for trees
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2001-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Daniel Berlin <dan@dberlin.org>
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"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "gimple.h"
111
kono
parents: 67
diff changeset
27 #include "cfghooks.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 #include "tree-pass.h"
111
kono
parents: 67
diff changeset
29 #include "ssa.h"
kono
parents: 67
diff changeset
30 #include "gimple-pretty-print.h"
kono
parents: 67
diff changeset
31 #include "fold-const.h"
kono
parents: 67
diff changeset
32 #include "stor-layout.h"
kono
parents: 67
diff changeset
33 #include "cfganal.h"
kono
parents: 67
diff changeset
34 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
35 #include "tree-cfg.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 #include "cfgloop.h"
111
kono
parents: 67
diff changeset
37 #include "params.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 /* TODO:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 1. Sinking store only using scalar promotion (IE without moving the RHS):
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 *q = p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 p = p + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 if (something)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 *q = <not p>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 y = *q;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
49
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 should become
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 sinktemp = p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 p = p + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 if (something)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 *q = <not p>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 *q = sinktemp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 y = *q
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 Store copy propagation will take care of the store elimination above.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
61
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 2. Sinking using Partial Dead Code Elimination. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
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 static struct
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
67 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 /* The number of statements sunk down the flowgraph by code sinking. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 int sunk;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
70
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 } sink_stats;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 /* Given a PHI, and one of its arguments (DEF), find the edge for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 that argument and return it. If the argument occurs twice in the PHI node,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 we return NULL. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 static basic_block
111
kono
parents: 67
diff changeset
79 find_bb_for_arg (gphi *phi, tree def)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 bool foundone = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 basic_block result = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 if (PHI_ARG_DEF (phi, i) == def)
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 if (foundone)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 foundone = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 result = gimple_phi_arg_edge (phi, i)->src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 return result;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 /* When the first immediate use is in a statement, then return true if all
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 immediate uses in IMM are in the same statement.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 We could also do the case where the first immediate use is in a phi node,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 and all the other uses are in phis in the same basic block, but this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 requires some expensive checking later (you have to make sure no def/vdef
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 in the statement occurs for multiple edges in the various phi nodes it's
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 used in, so that you only have one place you can sink it to. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 static bool
111
kono
parents: 67
diff changeset
104 all_immediate_uses_same_place (def_operand_p def_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 {
111
kono
parents: 67
diff changeset
106 tree var = DEF_FROM_PTR (def_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 imm_use_iterator imm_iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 use_operand_p use_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
111
kono
parents: 67
diff changeset
110 gimple *firstuse = NULL;
kono
parents: 67
diff changeset
111 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 {
111
kono
parents: 67
diff changeset
113 if (is_gimple_debug (USE_STMT (use_p)))
kono
parents: 67
diff changeset
114 continue;
kono
parents: 67
diff changeset
115 if (firstuse == NULL)
kono
parents: 67
diff changeset
116 firstuse = USE_STMT (use_p);
kono
parents: 67
diff changeset
117 else
kono
parents: 67
diff changeset
118 if (firstuse != USE_STMT (use_p))
kono
parents: 67
diff changeset
119 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 }
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 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 }
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 /* Find the nearest common dominator of all of the immediate uses in IMM. */
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 static basic_block
111
kono
parents: 67
diff changeset
128 nearest_common_dominator_of_uses (def_operand_p def_p, bool *debug_stmts)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
129 {
111
kono
parents: 67
diff changeset
130 tree var = DEF_FROM_PTR (def_p);
kono
parents: 67
diff changeset
131 auto_bitmap blocks;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 basic_block commondom;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 unsigned int j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 bitmap_iterator bi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 imm_use_iterator imm_iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 use_operand_p use_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
111
kono
parents: 67
diff changeset
138 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 {
111
kono
parents: 67
diff changeset
140 gimple *usestmt = USE_STMT (use_p);
kono
parents: 67
diff changeset
141 basic_block useblock;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
111
kono
parents: 67
diff changeset
143 if (gphi *phi = dyn_cast <gphi *> (usestmt))
kono
parents: 67
diff changeset
144 {
kono
parents: 67
diff changeset
145 int idx = PHI_ARG_INDEX_FROM_USE (use_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
111
kono
parents: 67
diff changeset
147 useblock = gimple_phi_arg_edge (phi, idx)->src;
kono
parents: 67
diff changeset
148 }
kono
parents: 67
diff changeset
149 else if (is_gimple_debug (usestmt))
kono
parents: 67
diff changeset
150 {
kono
parents: 67
diff changeset
151 *debug_stmts = true;
kono
parents: 67
diff changeset
152 continue;
kono
parents: 67
diff changeset
153 }
kono
parents: 67
diff changeset
154 else
kono
parents: 67
diff changeset
155 {
kono
parents: 67
diff changeset
156 useblock = gimple_bb (usestmt);
kono
parents: 67
diff changeset
157 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
111
kono
parents: 67
diff changeset
159 /* Short circuit. Nothing dominates the entry block. */
kono
parents: 67
diff changeset
160 if (useblock == ENTRY_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
161 return NULL;
kono
parents: 67
diff changeset
162
kono
parents: 67
diff changeset
163 bitmap_set_bit (blocks, useblock->index);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 }
111
kono
parents: 67
diff changeset
165 commondom = BASIC_BLOCK_FOR_FN (cfun, bitmap_first_set_bit (blocks));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, j, bi)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
167 commondom = nearest_common_dominator (CDI_DOMINATORS, commondom,
111
kono
parents: 67
diff changeset
168 BASIC_BLOCK_FOR_FN (cfun, j));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 return commondom;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
111
kono
parents: 67
diff changeset
172 /* Given EARLY_BB and LATE_BB, two blocks in a path through the dominator
kono
parents: 67
diff changeset
173 tree, return the best basic block between them (inclusive) to place
kono
parents: 67
diff changeset
174 statements.
kono
parents: 67
diff changeset
175
kono
parents: 67
diff changeset
176 We want the most control dependent block in the shallowest loop nest.
kono
parents: 67
diff changeset
177
kono
parents: 67
diff changeset
178 If the resulting block is in a shallower loop nest, then use it. Else
kono
parents: 67
diff changeset
179 only use the resulting block if it has significantly lower execution
kono
parents: 67
diff changeset
180 frequency than EARLY_BB to avoid gratutious statement movement. We
kono
parents: 67
diff changeset
181 consider statements with VOPS more desirable to move.
kono
parents: 67
diff changeset
182
kono
parents: 67
diff changeset
183 This pass would obviously benefit from PDO as it utilizes block
kono
parents: 67
diff changeset
184 frequencies. It would also benefit from recomputing frequencies
kono
parents: 67
diff changeset
185 if profile data is not available since frequencies often get out
kono
parents: 67
diff changeset
186 of sync with reality. */
kono
parents: 67
diff changeset
187
kono
parents: 67
diff changeset
188 static basic_block
kono
parents: 67
diff changeset
189 select_best_block (basic_block early_bb,
kono
parents: 67
diff changeset
190 basic_block late_bb,
kono
parents: 67
diff changeset
191 gimple *stmt)
kono
parents: 67
diff changeset
192 {
kono
parents: 67
diff changeset
193 basic_block best_bb = late_bb;
kono
parents: 67
diff changeset
194 basic_block temp_bb = late_bb;
kono
parents: 67
diff changeset
195 int threshold;
kono
parents: 67
diff changeset
196
kono
parents: 67
diff changeset
197 while (temp_bb != early_bb)
kono
parents: 67
diff changeset
198 {
kono
parents: 67
diff changeset
199 /* If we've moved into a lower loop nest, then that becomes
kono
parents: 67
diff changeset
200 our best block. */
kono
parents: 67
diff changeset
201 if (bb_loop_depth (temp_bb) < bb_loop_depth (best_bb))
kono
parents: 67
diff changeset
202 best_bb = temp_bb;
kono
parents: 67
diff changeset
203
kono
parents: 67
diff changeset
204 /* Walk up the dominator tree, hopefully we'll find a shallower
kono
parents: 67
diff changeset
205 loop nest. */
kono
parents: 67
diff changeset
206 temp_bb = get_immediate_dominator (CDI_DOMINATORS, temp_bb);
kono
parents: 67
diff changeset
207 }
kono
parents: 67
diff changeset
208
kono
parents: 67
diff changeset
209 /* If we found a shallower loop nest, then we always consider that
kono
parents: 67
diff changeset
210 a win. This will always give us the most control dependent block
kono
parents: 67
diff changeset
211 within that loop nest. */
kono
parents: 67
diff changeset
212 if (bb_loop_depth (best_bb) < bb_loop_depth (early_bb))
kono
parents: 67
diff changeset
213 return best_bb;
kono
parents: 67
diff changeset
214
kono
parents: 67
diff changeset
215 /* Get the sinking threshold. If the statement to be moved has memory
kono
parents: 67
diff changeset
216 operands, then increase the threshold by 7% as those are even more
kono
parents: 67
diff changeset
217 profitable to avoid, clamping at 100%. */
kono
parents: 67
diff changeset
218 threshold = PARAM_VALUE (PARAM_SINK_FREQUENCY_THRESHOLD);
kono
parents: 67
diff changeset
219 if (gimple_vuse (stmt) || gimple_vdef (stmt))
kono
parents: 67
diff changeset
220 {
kono
parents: 67
diff changeset
221 threshold += 7;
kono
parents: 67
diff changeset
222 if (threshold > 100)
kono
parents: 67
diff changeset
223 threshold = 100;
kono
parents: 67
diff changeset
224 }
kono
parents: 67
diff changeset
225
kono
parents: 67
diff changeset
226 /* If BEST_BB is at the same nesting level, then require it to have
kono
parents: 67
diff changeset
227 significantly lower execution frequency to avoid gratutious movement. */
kono
parents: 67
diff changeset
228 if (bb_loop_depth (best_bb) == bb_loop_depth (early_bb)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 /* If result of comparsion is unknown, preffer EARLY_BB.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 Thus use !(...>=..) rather than (...<...) */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 && !(best_bb->count.apply_scale (100, 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 > (early_bb->count.apply_scale (threshold, 1))))
111
kono
parents: 67
diff changeset
233 return best_bb;
kono
parents: 67
diff changeset
234
kono
parents: 67
diff changeset
235 /* No better block found, so return EARLY_BB, which happens to be the
kono
parents: 67
diff changeset
236 statement's original block. */
kono
parents: 67
diff changeset
237 return early_bb;
kono
parents: 67
diff changeset
238 }
kono
parents: 67
diff changeset
239
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
240 /* Given a statement (STMT) and the basic block it is currently in (FROMBB),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 determine the location to sink the statement to, if any.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 Returns true if there is such location; in that case, TOGSI points to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 statement before that STMT should be moved. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 static bool
111
kono
parents: 67
diff changeset
246 statement_sink_location (gimple *stmt, basic_block frombb,
kono
parents: 67
diff changeset
247 gimple_stmt_iterator *togsi, bool *zero_uses_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 {
111
kono
parents: 67
diff changeset
249 gimple *use;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 use_operand_p one_use = NULL_USE_OPERAND_P;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 basic_block sinkbb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 use_operand_p use_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 def_operand_p def_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 ssa_op_iter iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 imm_use_iterator imm_iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256
111
kono
parents: 67
diff changeset
257 *zero_uses_p = false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
258
111
kono
parents: 67
diff changeset
259 /* We only can sink assignments and non-looping const/pure calls. */
kono
parents: 67
diff changeset
260 int cf;
kono
parents: 67
diff changeset
261 if (!is_gimple_assign (stmt)
kono
parents: 67
diff changeset
262 && (!is_gimple_call (stmt)
kono
parents: 67
diff changeset
263 || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE))
kono
parents: 67
diff changeset
264 || (cf & ECF_LOOPING_CONST_OR_PURE)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266
111
kono
parents: 67
diff changeset
267 /* We only can sink stmts with a single definition. */
kono
parents: 67
diff changeset
268 def_p = single_ssa_def_operand (stmt, SSA_OP_ALL_DEFS);
kono
parents: 67
diff changeset
269 if (def_p == NULL_DEF_OPERAND_P)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 /* There are a few classes of things we can't or don't move, some because we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 don't have code to handle it, some because it's not profitable and some
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
274 because it's not legal.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
275
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 We can't sink things that may be global stores, at least not without
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 calculating a lot more information, because we may cause it to no longer
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 be seen by an external routine that needs it depending on where it gets
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
279 moved to.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
280
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 We can't sink statements that end basic blocks without splitting the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 incoming edge for the sink location to place it there.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
284 We can't sink statements that have volatile operands.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 We don't want to sink dead code, so anything with 0 immediate uses is not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 sunk.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 Don't sink BLKmode assignments if current function has any local explicit
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 register variables, as BLKmode assignments may involve memcpy or memset
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 calls or, on some targets, inline expansion thereof that sometimes need
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 to use specific hard registers.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 if (stmt_ends_bb_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 || gimple_has_side_effects (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 || (cfun->has_local_explicit_reg_vars
111
kono
parents: 67
diff changeset
298 && TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt))) == BLKmode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 return false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
300
111
kono
parents: 67
diff changeset
301 /* Return if there are no immediate uses of this stmt. */
kono
parents: 67
diff changeset
302 if (has_zero_uses (DEF_FROM_PTR (def_p)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 {
111
kono
parents: 67
diff changeset
304 *zero_uses_p = true;
kono
parents: 67
diff changeset
305 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
307
111
kono
parents: 67
diff changeset
308 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (DEF_FROM_PTR (def_p)))
kono
parents: 67
diff changeset
309 return false;
kono
parents: 67
diff changeset
310
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 tree use = USE_FROM_PTR (use_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
317
111
kono
parents: 67
diff changeset
318 use = NULL;
kono
parents: 67
diff changeset
319
kono
parents: 67
diff changeset
320 /* If stmt is a store the one and only use needs to be the VOP
kono
parents: 67
diff changeset
321 merging PHI node. */
kono
parents: 67
diff changeset
322 if (virtual_operand_p (DEF_FROM_PTR (def_p)))
kono
parents: 67
diff changeset
323 {
kono
parents: 67
diff changeset
324 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
kono
parents: 67
diff changeset
325 {
kono
parents: 67
diff changeset
326 gimple *use_stmt = USE_STMT (use_p);
kono
parents: 67
diff changeset
327
kono
parents: 67
diff changeset
328 /* A killing definition is not a use. */
kono
parents: 67
diff changeset
329 if ((gimple_has_lhs (use_stmt)
kono
parents: 67
diff changeset
330 && operand_equal_p (gimple_get_lhs (stmt),
kono
parents: 67
diff changeset
331 gimple_get_lhs (use_stmt), 0))
kono
parents: 67
diff changeset
332 || stmt_kills_ref_p (use_stmt, gimple_get_lhs (stmt)))
kono
parents: 67
diff changeset
333 {
kono
parents: 67
diff changeset
334 /* If use_stmt is or might be a nop assignment then USE_STMT
kono
parents: 67
diff changeset
335 acts as a use as well as definition. */
kono
parents: 67
diff changeset
336 if (stmt != use_stmt
kono
parents: 67
diff changeset
337 && ref_maybe_used_by_stmt_p (use_stmt,
kono
parents: 67
diff changeset
338 gimple_get_lhs (stmt)))
kono
parents: 67
diff changeset
339 return false;
kono
parents: 67
diff changeset
340 continue;
kono
parents: 67
diff changeset
341 }
kono
parents: 67
diff changeset
342
kono
parents: 67
diff changeset
343 if (gimple_code (use_stmt) != GIMPLE_PHI)
kono
parents: 67
diff changeset
344 return false;
kono
parents: 67
diff changeset
345
kono
parents: 67
diff changeset
346 if (use
kono
parents: 67
diff changeset
347 && use != use_stmt)
kono
parents: 67
diff changeset
348 return false;
kono
parents: 67
diff changeset
349
kono
parents: 67
diff changeset
350 use = use_stmt;
kono
parents: 67
diff changeset
351 }
kono
parents: 67
diff changeset
352 if (!use)
kono
parents: 67
diff changeset
353 return false;
kono
parents: 67
diff changeset
354 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 /* If all the immediate uses are not in the same place, find the nearest
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 common dominator of all the immediate uses. For PHI nodes, we have to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 find the nearest common dominator of all of the predecessor blocks, since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 that is where insertion would have to take place. */
111
kono
parents: 67
diff changeset
359 else if (gimple_vuse (stmt)
kono
parents: 67
diff changeset
360 || !all_immediate_uses_same_place (def_p))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
362 bool debug_stmts = false;
111
kono
parents: 67
diff changeset
363 basic_block commondom = nearest_common_dominator_of_uses (def_p,
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
364 &debug_stmts);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
365
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 if (commondom == frombb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
111
kono
parents: 67
diff changeset
369 /* If this is a load then do not sink past any stores.
kono
parents: 67
diff changeset
370 ??? This is overly simple but cheap. We basically look
kono
parents: 67
diff changeset
371 for an existing load with the same VUSE in the path to one
kono
parents: 67
diff changeset
372 of the sink candidate blocks and we adjust commondom to the
kono
parents: 67
diff changeset
373 nearest to commondom. */
kono
parents: 67
diff changeset
374 if (gimple_vuse (stmt))
kono
parents: 67
diff changeset
375 {
kono
parents: 67
diff changeset
376 /* Do not sink loads from hard registers. */
kono
parents: 67
diff changeset
377 if (gimple_assign_single_p (stmt)
kono
parents: 67
diff changeset
378 && TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
kono
parents: 67
diff changeset
379 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
kono
parents: 67
diff changeset
380 return false;
kono
parents: 67
diff changeset
381
kono
parents: 67
diff changeset
382 imm_use_iterator imm_iter;
kono
parents: 67
diff changeset
383 use_operand_p use_p;
kono
parents: 67
diff changeset
384 basic_block found = NULL;
kono
parents: 67
diff changeset
385 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (stmt))
kono
parents: 67
diff changeset
386 {
kono
parents: 67
diff changeset
387 gimple *use_stmt = USE_STMT (use_p);
kono
parents: 67
diff changeset
388 basic_block bb = gimple_bb (use_stmt);
kono
parents: 67
diff changeset
389 /* For PHI nodes the block we know sth about
kono
parents: 67
diff changeset
390 is the incoming block with the use. */
kono
parents: 67
diff changeset
391 if (gimple_code (use_stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
392 bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
kono
parents: 67
diff changeset
393 /* Any dominator of commondom would be ok with
kono
parents: 67
diff changeset
394 adjusting commondom to that block. */
kono
parents: 67
diff changeset
395 bb = nearest_common_dominator (CDI_DOMINATORS, bb, commondom);
kono
parents: 67
diff changeset
396 if (!found)
kono
parents: 67
diff changeset
397 found = bb;
kono
parents: 67
diff changeset
398 else if (dominated_by_p (CDI_DOMINATORS, bb, found))
kono
parents: 67
diff changeset
399 found = bb;
kono
parents: 67
diff changeset
400 /* If we can't improve, stop. */
kono
parents: 67
diff changeset
401 if (found == commondom)
kono
parents: 67
diff changeset
402 break;
kono
parents: 67
diff changeset
403 }
kono
parents: 67
diff changeset
404 commondom = found;
kono
parents: 67
diff changeset
405 if (commondom == frombb)
kono
parents: 67
diff changeset
406 return false;
kono
parents: 67
diff changeset
407 }
kono
parents: 67
diff changeset
408
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 /* Our common dominator has to be dominated by frombb in order to be a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 trivially safe place to put this statement, since it has multiple
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
411 uses. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 if (!dominated_by_p (CDI_DOMINATORS, commondom, frombb))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 return false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
414
111
kono
parents: 67
diff changeset
415 commondom = select_best_block (frombb, commondom, stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416
111
kono
parents: 67
diff changeset
417 if (commondom == frombb)
kono
parents: 67
diff changeset
418 return false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
419
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 *togsi = gsi_after_labels (commondom);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
421
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 }
111
kono
parents: 67
diff changeset
424 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 {
111
kono
parents: 67
diff changeset
426 FOR_EACH_IMM_USE_FAST (one_use, imm_iter, DEF_FROM_PTR (def_p))
kono
parents: 67
diff changeset
427 {
kono
parents: 67
diff changeset
428 if (is_gimple_debug (USE_STMT (one_use)))
kono
parents: 67
diff changeset
429 continue;
kono
parents: 67
diff changeset
430 break;
kono
parents: 67
diff changeset
431 }
kono
parents: 67
diff changeset
432 use = USE_STMT (one_use);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433
111
kono
parents: 67
diff changeset
434 if (gimple_code (use) != GIMPLE_PHI)
kono
parents: 67
diff changeset
435 {
kono
parents: 67
diff changeset
436 sinkbb = gimple_bb (use);
kono
parents: 67
diff changeset
437 sinkbb = select_best_block (frombb, gimple_bb (use), stmt);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
438
111
kono
parents: 67
diff changeset
439 if (sinkbb == frombb)
kono
parents: 67
diff changeset
440 return false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
441
111
kono
parents: 67
diff changeset
442 *togsi = gsi_for_stmt (use);
kono
parents: 67
diff changeset
443
kono
parents: 67
diff changeset
444 return true;
kono
parents: 67
diff changeset
445 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447
111
kono
parents: 67
diff changeset
448 sinkbb = find_bb_for_arg (as_a <gphi *> (use), DEF_FROM_PTR (def_p));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
111
kono
parents: 67
diff changeset
450 /* This can happen if there are multiple uses in a PHI. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 if (!sinkbb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 return false;
111
kono
parents: 67
diff changeset
453
kono
parents: 67
diff changeset
454 sinkbb = select_best_block (frombb, sinkbb, stmt);
kono
parents: 67
diff changeset
455 if (!sinkbb || sinkbb == frombb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
458 /* If the latch block is empty, don't make it non-empty by sinking
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
459 something into it. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
460 if (sinkbb == frombb->loop_father->latch
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
461 && empty_block_p (sinkbb))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
462 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
463
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 *togsi = gsi_after_labels (sinkbb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 /* Perform code sinking on BB */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 sink_code_in_bb (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 basic_block son;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 bool last = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
479
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 /* If this block doesn't dominate anything, there can't be any place to sink
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 the statements to. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 if (first_dom_son (CDI_DOMINATORS, bb) == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 goto earlyout;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 /* We can't move things across abnormal edges, so don't try. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 if (e->flags & EDGE_ABNORMAL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 goto earlyout;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 {
111
kono
parents: 67
diff changeset
492 gimple *stmt = gsi_stmt (gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 gimple_stmt_iterator togsi;
111
kono
parents: 67
diff changeset
494 bool zero_uses_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495
111
kono
parents: 67
diff changeset
496 if (!statement_sink_location (stmt, bb, &togsi, &zero_uses_p))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 {
111
kono
parents: 67
diff changeset
498 gimple_stmt_iterator saved = gsi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 if (!gsi_end_p (gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 gsi_prev (&gsi);
111
kono
parents: 67
diff changeset
501 /* If we face a dead stmt remove it as it possibly blocks
kono
parents: 67
diff changeset
502 sinking of uses. */
kono
parents: 67
diff changeset
503 if (zero_uses_p
kono
parents: 67
diff changeset
504 && ! gimple_vdef (stmt))
kono
parents: 67
diff changeset
505 {
kono
parents: 67
diff changeset
506 gsi_remove (&saved, true);
kono
parents: 67
diff changeset
507 release_defs (stmt);
kono
parents: 67
diff changeset
508 }
kono
parents: 67
diff changeset
509 else
kono
parents: 67
diff changeset
510 last = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 continue;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
512 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 fprintf (dump_file, "Sinking ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 fprintf (dump_file, " from bb %d to bb %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 bb->index, (gsi_bb (togsi))->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
520
111
kono
parents: 67
diff changeset
521 /* Update virtual operands of statements in the path we
kono
parents: 67
diff changeset
522 do not sink to. */
kono
parents: 67
diff changeset
523 if (gimple_vdef (stmt))
kono
parents: 67
diff changeset
524 {
kono
parents: 67
diff changeset
525 imm_use_iterator iter;
kono
parents: 67
diff changeset
526 use_operand_p use_p;
kono
parents: 67
diff changeset
527 gimple *vuse_stmt;
kono
parents: 67
diff changeset
528
kono
parents: 67
diff changeset
529 FOR_EACH_IMM_USE_STMT (vuse_stmt, iter, gimple_vdef (stmt))
kono
parents: 67
diff changeset
530 if (gimple_code (vuse_stmt) != GIMPLE_PHI)
kono
parents: 67
diff changeset
531 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
kono
parents: 67
diff changeset
532 SET_USE (use_p, gimple_vuse (stmt));
kono
parents: 67
diff changeset
533 }
kono
parents: 67
diff changeset
534
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 /* If this is the end of the basic block, we need to insert at the end
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 of the basic block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 if (gsi_end_p (togsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 gsi_move_to_bb_end (&gsi, gsi_bb (togsi));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 gsi_move_before (&gsi, &togsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 sink_stats.sunk++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 /* If we've just removed the last statement of the BB, the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 gsi_end_p() test below would fail, but gsi_prev() would have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 succeeded, and we want it to succeed. So we keep track of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 whether we're at the last statement and pick up the new last
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 if (last)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 gsi = gsi_last_bb (bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 last = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 if (!gsi_end_p (gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 gsi_prev (&gsi);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
558
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 earlyout:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 son;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 son = next_dom_son (CDI_POST_DOMINATORS, son))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 sink_code_in_bb (son);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
567 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 /* Perform code sinking.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 This moves code down the flowgraph when we know it would be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 profitable to do so, or it wouldn't increase the number of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 executions of the statement.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 IE given
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
575
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 a_1 = b + c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 if (<something>)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 foo (&b, &c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 a_5 = b + c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 a_6 = PHI (a_5, a_1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 USE a_6.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 we'll transform this into:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 if (<something>)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 a_1 = b + c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 foo (&b, &c);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 a_5 = b + c;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 a_6 = PHI (a_5, a_1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 USE a_6.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 Note that this reduces the number of computations of a = b + c to 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 when we take the else edge, instead of 2.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 */
111
kono
parents: 67
diff changeset
605 namespace {
kono
parents: 67
diff changeset
606
kono
parents: 67
diff changeset
607 const pass_data pass_data_sink_code =
kono
parents: 67
diff changeset
608 {
kono
parents: 67
diff changeset
609 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
610 "sink", /* name */
kono
parents: 67
diff changeset
611 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
612 TV_TREE_SINK, /* tv_id */
kono
parents: 67
diff changeset
613 /* PROP_no_crit_edges is ensured by running split_critical_edges in
kono
parents: 67
diff changeset
614 pass_data_sink_code::execute (). */
kono
parents: 67
diff changeset
615 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
616 0, /* properties_provided */
kono
parents: 67
diff changeset
617 0, /* properties_destroyed */
kono
parents: 67
diff changeset
618 0, /* todo_flags_start */
kono
parents: 67
diff changeset
619 TODO_update_ssa, /* todo_flags_finish */
kono
parents: 67
diff changeset
620 };
kono
parents: 67
diff changeset
621
kono
parents: 67
diff changeset
622 class pass_sink_code : public gimple_opt_pass
kono
parents: 67
diff changeset
623 {
kono
parents: 67
diff changeset
624 public:
kono
parents: 67
diff changeset
625 pass_sink_code (gcc::context *ctxt)
kono
parents: 67
diff changeset
626 : gimple_opt_pass (pass_data_sink_code, ctxt)
kono
parents: 67
diff changeset
627 {}
kono
parents: 67
diff changeset
628
kono
parents: 67
diff changeset
629 /* opt_pass methods: */
kono
parents: 67
diff changeset
630 virtual bool gate (function *) { return flag_tree_sink != 0; }
kono
parents: 67
diff changeset
631 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
632
kono
parents: 67
diff changeset
633 }; // class pass_sink_code
kono
parents: 67
diff changeset
634
kono
parents: 67
diff changeset
635 unsigned int
kono
parents: 67
diff changeset
636 pass_sink_code::execute (function *fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 loop_optimizer_init (LOOPS_NORMAL);
111
kono
parents: 67
diff changeset
639 split_critical_edges ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 connect_infinite_loops_to_exit ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 memset (&sink_stats, 0, sizeof (sink_stats));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 calculate_dominance_info (CDI_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 calculate_dominance_info (CDI_POST_DOMINATORS);
111
kono
parents: 67
diff changeset
644 sink_code_in_bb (EXIT_BLOCK_PTR_FOR_FN (fun));
kono
parents: 67
diff changeset
645 statistics_counter_event (fun, "Sunk statements", sink_stats.sunk);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 free_dominance_info (CDI_POST_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 remove_fake_exit_edges ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 loop_optimizer_finalize ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652
111
kono
parents: 67
diff changeset
653 } // anon namespace
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654
111
kono
parents: 67
diff changeset
655 gimple_opt_pass *
kono
parents: 67
diff changeset
656 make_pass_sink_code (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 {
111
kono
parents: 67
diff changeset
658 return new pass_sink_code (ctxt);
kono
parents: 67
diff changeset
659 }