Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-dce.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* Dead code elimination pass for the GNU compiler. |
131 | 2 Copyright (C) 2002-2018 Free Software Foundation, Inc. |
0 | 3 Contributed by Ben Elliston <bje@redhat.com> |
4 and Andrew MacLeod <amacleod@redhat.com> | |
5 Adapted to use control dependence by Steven Bosscher, SUSE Labs. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
6 |
0 | 7 This file is part of GCC. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
8 |
0 | 9 GCC is free software; you can redistribute it and/or modify it |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 3, or (at your option) any | |
12 later version. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
13 |
0 | 14 GCC is distributed in the hope that it will be useful, but WITHOUT |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
18 |
0 | 19 You should have received a copy of the GNU General Public License |
20 along with GCC; see the file COPYING3. If not see | |
21 <http://www.gnu.org/licenses/>. */ | |
22 | |
23 /* Dead code elimination. | |
24 | |
25 References: | |
26 | |
27 Building an Optimizing Compiler, | |
28 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9. | |
29 | |
30 Advanced Compiler Design and Implementation, | |
31 Steven Muchnick, Morgan Kaufmann, 1997, Section 18.10. | |
32 | |
33 Dead-code elimination is the removal of statements which have no | |
34 impact on the program's output. "Dead statements" have no impact | |
35 on the program's output, while "necessary statements" may have | |
36 impact on the output. | |
37 | |
38 The algorithm consists of three phases: | |
39 1. Marking as necessary all statements known to be necessary, | |
40 e.g. most function calls, writing a value to memory, etc; | |
41 2. Propagating necessary statements, e.g., the statements | |
42 giving values to operands in necessary statements; and | |
43 3. Removing dead statements. */ | |
44 | |
45 #include "config.h" | |
46 #include "system.h" | |
47 #include "coretypes.h" | |
111 | 48 #include "backend.h" |
49 #include "rtl.h" | |
0 | 50 #include "tree.h" |
111 | 51 #include "gimple.h" |
52 #include "cfghooks.h" | |
53 #include "tree-pass.h" | |
54 #include "ssa.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
55 #include "gimple-pretty-print.h" |
111 | 56 #include "fold-const.h" |
57 #include "calls.h" | |
58 #include "cfganal.h" | |
59 #include "tree-eh.h" | |
60 #include "gimplify.h" | |
61 #include "gimple-iterator.h" | |
62 #include "tree-cfg.h" | |
63 #include "tree-ssa-loop-niter.h" | |
64 #include "tree-into-ssa.h" | |
65 #include "tree-dfa.h" | |
0 | 66 #include "cfgloop.h" |
67 #include "tree-scalar-evolution.h" | |
111 | 68 #include "tree-ssa-propagate.h" |
69 #include "gimple-fold.h" | |
0 | 70 |
71 static struct stmt_stats | |
72 { | |
73 int total; | |
74 int total_phis; | |
75 int removed; | |
76 int removed_phis; | |
77 } stats; | |
78 | |
79 #define STMT_NECESSARY GF_PLF_1 | |
80 | |
111 | 81 static vec<gimple *> worklist; |
0 | 82 |
83 /* Vector indicating an SSA name has already been processed and marked | |
84 as necessary. */ | |
85 static sbitmap processed; | |
86 | |
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
|
87 /* Vector indicating that the last statement of a basic block has already |
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
|
88 been marked as necessary. */ |
0 | 89 static sbitmap last_stmt_necessary; |
90 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
91 /* Vector indicating that BB contains statements that are live. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 static sbitmap bb_contains_live_stmts; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 |
0 | 94 /* Before we can determine whether a control branch is dead, we need to |
95 compute which blocks are control dependent on which edges. | |
96 | |
97 We expect each block to be control dependent on very few edges so we | |
98 use a bitmap for each block recording its edges. An array holds the | |
99 bitmap. The Ith bit in the bitmap is set if that block is dependent | |
100 on the Ith edge. */ | |
111 | 101 static control_dependences *cd; |
0 | 102 |
103 /* Vector indicating that a basic block has already had all the edges | |
104 processed that it is control dependent on. */ | |
105 static sbitmap visited_control_parents; | |
106 | |
107 /* TRUE if this pass alters the CFG (by removing control statements). | |
108 FALSE otherwise. | |
109 | |
110 If this pass alters the CFG, then it will arrange for the dominators | |
111 to be recomputed. */ | |
112 static bool cfg_altered; | |
113 | |
111 | 114 /* When non-NULL holds map from basic block index into the postorder. */ |
115 static int *bb_postorder; | |
0 | 116 |
117 | |
118 /* If STMT is not already marked necessary, mark it, and add it to the | |
119 worklist if ADD_TO_WORKLIST is true. */ | |
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
|
120 |
0 | 121 static inline void |
111 | 122 mark_stmt_necessary (gimple *stmt, bool add_to_worklist) |
0 | 123 { |
124 gcc_assert (stmt); | |
125 | |
126 if (gimple_plf (stmt, STMT_NECESSARY)) | |
127 return; | |
128 | |
129 if (dump_file && (dump_flags & TDF_DETAILS)) | |
130 { | |
131 fprintf (dump_file, "Marking useful stmt: "); | |
132 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
133 fprintf (dump_file, "\n"); | |
134 } | |
135 | |
136 gimple_set_plf (stmt, STMT_NECESSARY, true); | |
137 if (add_to_worklist) | |
111 | 138 worklist.safe_push (stmt); |
139 if (add_to_worklist && bb_contains_live_stmts && !is_gimple_debug (stmt)) | |
140 bitmap_set_bit (bb_contains_live_stmts, gimple_bb (stmt)->index); | |
0 | 141 } |
142 | |
143 | |
144 /* Mark the statement defining operand OP as necessary. */ | |
145 | |
146 static inline void | |
147 mark_operand_necessary (tree op) | |
148 { | |
111 | 149 gimple *stmt; |
0 | 150 int ver; |
151 | |
152 gcc_assert (op); | |
153 | |
154 ver = SSA_NAME_VERSION (op); | |
111 | 155 if (bitmap_bit_p (processed, ver)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
156 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
157 stmt = SSA_NAME_DEF_STMT (op); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
158 gcc_assert (gimple_nop_p (stmt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
159 || gimple_plf (stmt, STMT_NECESSARY)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
160 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
161 } |
111 | 162 bitmap_set_bit (processed, ver); |
0 | 163 |
164 stmt = SSA_NAME_DEF_STMT (op); | |
165 gcc_assert (stmt); | |
166 | |
167 if (gimple_plf (stmt, STMT_NECESSARY) || gimple_nop_p (stmt)) | |
168 return; | |
169 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
170 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
171 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
172 fprintf (dump_file, "marking necessary through "); |
111 | 173 print_generic_expr (dump_file, op); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 fprintf (dump_file, " stmt "); |
111 | 175 print_gimple_stmt (dump_file, stmt, 0); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
176 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
177 |
0 | 178 gimple_set_plf (stmt, STMT_NECESSARY, true); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
179 if (bb_contains_live_stmts) |
111 | 180 bitmap_set_bit (bb_contains_live_stmts, gimple_bb (stmt)->index); |
181 worklist.safe_push (stmt); | |
0 | 182 } |
183 | |
184 | |
185 /* Mark STMT as necessary if it obviously is. Add it to the worklist if | |
186 it can make other statements necessary. | |
187 | |
188 If AGGRESSIVE is false, control statements are conservatively marked as | |
189 necessary. */ | |
190 | |
191 static void | |
111 | 192 mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) |
0 | 193 { |
194 /* With non-call exceptions, we have to assume that all statements could | |
111 | 195 throw. If a statement could throw, it can be deemed necessary. */ |
196 if (cfun->can_throw_non_call_exceptions | |
197 && !cfun->can_delete_dead_exceptions | |
131 | 198 && stmt_could_throw_p (cfun, stmt)) |
0 | 199 { |
200 mark_stmt_necessary (stmt, true); | |
201 return; | |
202 } | |
203 | |
204 /* Statements that are implicitly live. Most function calls, asm | |
205 and return statements are required. Labels and GIMPLE_BIND nodes | |
206 are kept because they are control flow, and we have no way of | |
207 knowing whether they can be removed. DCE can eliminate all the | |
208 other statements in a block, and CFG can then remove the block | |
209 and labels. */ | |
210 switch (gimple_code (stmt)) | |
211 { | |
212 case GIMPLE_PREDICT: | |
213 case GIMPLE_LABEL: | |
214 mark_stmt_necessary (stmt, false); | |
215 return; | |
216 | |
217 case GIMPLE_ASM: | |
218 case GIMPLE_RESX: | |
219 case GIMPLE_RETURN: | |
220 mark_stmt_necessary (stmt, true); | |
221 return; | |
222 | |
223 case GIMPLE_CALL: | |
111 | 224 { |
225 tree callee = gimple_call_fndecl (stmt); | |
226 if (callee != NULL_TREE | |
131 | 227 && fndecl_built_in_p (callee, BUILT_IN_NORMAL)) |
111 | 228 switch (DECL_FUNCTION_CODE (callee)) |
229 { | |
230 case BUILT_IN_MALLOC: | |
231 case BUILT_IN_ALIGNED_ALLOC: | |
232 case BUILT_IN_CALLOC: | |
233 CASE_BUILT_IN_ALLOCA: | |
234 case BUILT_IN_STRDUP: | |
235 case BUILT_IN_STRNDUP: | |
236 return; | |
237 | |
238 default:; | |
239 } | |
240 /* Most, but not all function calls are required. Function calls that | |
241 produce no result and have no side effects (i.e. const pure | |
242 functions) are unnecessary. */ | |
243 if (gimple_has_side_effects (stmt)) | |
244 { | |
245 mark_stmt_necessary (stmt, true); | |
246 return; | |
247 } | |
248 if (!gimple_call_lhs (stmt)) | |
0 | 249 return; |
111 | 250 break; |
251 } | |
0 | 252 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 case GIMPLE_DEBUG: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 /* Debug temps without a value are not useful. ??? If we could |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 easily locate the debug temp bind stmt for a use thereof, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 would could refrain from marking all debug temps here, and |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
257 mark them only if they're used. */ |
131 | 258 if (gimple_debug_nonbind_marker_p (stmt) |
259 || !gimple_debug_bind_p (stmt) | |
111 | 260 || gimple_debug_bind_has_value_p (stmt) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
261 || TREE_CODE (gimple_debug_bind_get_var (stmt)) != DEBUG_EXPR_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
262 mark_stmt_necessary (stmt, false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
263 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
264 |
0 | 265 case GIMPLE_GOTO: |
266 gcc_assert (!simple_goto_p (stmt)); | |
267 mark_stmt_necessary (stmt, true); | |
268 return; | |
269 | |
270 case GIMPLE_COND: | |
271 gcc_assert (EDGE_COUNT (gimple_bb (stmt)->succs) == 2); | |
272 /* Fall through. */ | |
273 | |
274 case GIMPLE_SWITCH: | |
275 if (! aggressive) | |
276 mark_stmt_necessary (stmt, true); | |
277 break; | |
278 | |
111 | 279 case GIMPLE_ASSIGN: |
280 if (gimple_clobber_p (stmt)) | |
281 return; | |
282 break; | |
283 | |
0 | 284 default: |
285 break; | |
286 } | |
287 | |
288 /* If the statement has volatile operands, it needs to be preserved. | |
289 Same for statements that can alter control flow in unpredictable | |
290 ways. */ | |
291 if (gimple_has_volatile_ops (stmt) || is_ctrl_altering_stmt (stmt)) | |
292 { | |
293 mark_stmt_necessary (stmt, true); | |
294 return; | |
295 } | |
296 | |
111 | 297 if (stmt_may_clobber_global_p (stmt)) |
0 | 298 { |
299 mark_stmt_necessary (stmt, true); | |
300 return; | |
301 } | |
302 | |
303 return; | |
304 } | |
305 | |
306 | |
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
|
307 /* Mark the last statement of BB as necessary. */ |
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
|
308 |
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
|
309 static void |
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
|
310 mark_last_stmt_necessary (basic_block bb) |
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
|
311 { |
111 | 312 gimple *stmt = last_stmt (bb); |
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
|
313 |
111 | 314 bitmap_set_bit (last_stmt_necessary, bb->index); |
315 bitmap_set_bit (bb_contains_live_stmts, bb->index); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
316 |
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
|
317 /* We actually mark the statement only if it is a control statement. */ |
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
|
318 if (stmt && is_ctrl_stmt (stmt)) |
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
|
319 mark_stmt_necessary (stmt, true); |
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
|
320 } |
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
|
321 |
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
|
322 |
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
|
323 /* Mark control dependent edges of BB as necessary. We have to do this only |
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
|
324 once for each basic block so we set the appropriate bit after we're done. |
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
|
325 |
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
|
326 When IGNORE_SELF is true, ignore BB in the list of control dependences. */ |
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
|
327 |
0 | 328 static void |
111 | 329 mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self) |
0 | 330 { |
331 bitmap_iterator bi; | |
332 unsigned edge_number; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
333 bool skipped = false; |
0 | 334 |
111 | 335 gcc_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)); |
0 | 336 |
111 | 337 if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
0 | 338 return; |
339 | |
111 | 340 EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index), |
341 0, edge_number, bi) | |
0 | 342 { |
111 | 343 basic_block cd_bb = cd->get_edge_src (edge_number); |
0 | 344 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
345 if (ignore_self && cd_bb == bb) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
346 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
347 skipped = true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
348 continue; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
349 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
350 |
111 | 351 if (!bitmap_bit_p (last_stmt_necessary, cd_bb->index)) |
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
|
352 mark_last_stmt_necessary (cd_bb); |
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
|
353 } |
0 | 354 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
355 if (!skipped) |
111 | 356 bitmap_set_bit (visited_control_parents, bb->index); |
0 | 357 } |
358 | |
359 | |
360 /* Find obviously necessary statements. These are things like most function | |
361 calls, and stores to file level variables. | |
362 | |
363 If EL is NULL, control statements are conservatively marked as | |
364 necessary. Otherwise it contains the list of edges used by control | |
365 dependence analysis. */ | |
366 | |
367 static void | |
111 | 368 find_obviously_necessary_stmts (bool aggressive) |
0 | 369 { |
370 basic_block bb; | |
371 gimple_stmt_iterator gsi; | |
372 edge e; | |
111 | 373 gimple *phi, *stmt; |
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
|
374 int flags; |
0 | 375 |
111 | 376 FOR_EACH_BB_FN (bb, cfun) |
0 | 377 { |
378 /* PHI nodes are never inherently necessary. */ | |
379 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
380 { | |
381 phi = gsi_stmt (gsi); | |
382 gimple_set_plf (phi, STMT_NECESSARY, false); | |
383 } | |
384 | |
385 /* Check all statements in the block. */ | |
386 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
387 { | |
388 stmt = gsi_stmt (gsi); | |
389 gimple_set_plf (stmt, STMT_NECESSARY, false); | |
111 | 390 mark_stmt_if_obviously_necessary (stmt, aggressive); |
0 | 391 } |
392 } | |
393 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
394 /* Pure and const functions are finite and thus have no infinite loops in |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
395 them. */ |
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
|
396 flags = flags_from_decl_or_type (current_function_decl); |
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
|
397 if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
398 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
399 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
400 /* Prevent the empty possibly infinite loops from being removed. */ |
111 | 401 if (aggressive) |
0 | 402 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
403 struct loop *loop; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
404 if (mark_irreducible_loops ()) |
111 | 405 FOR_EACH_BB_FN (bb, cfun) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
406 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
407 edge_iterator ei; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
408 FOR_EACH_EDGE (e, ei, bb->succs) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
409 if ((e->flags & EDGE_DFS_BACK) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
410 && (e->flags & EDGE_IRREDUCIBLE_LOOP)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
412 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 fprintf (dump_file, "Marking back edge of irreducible loop %i->%i\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 e->src->index, e->dest->index); |
111 | 415 mark_control_dependent_edges_necessary (e->dest, false); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
416 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
417 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
418 |
111 | 419 FOR_EACH_LOOP (loop, 0) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
420 if (!finite_loop_p (loop)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
421 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
422 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
423 fprintf (dump_file, "can not prove finiteness of loop %i\n", loop->num); |
111 | 424 mark_control_dependent_edges_necessary (loop->latch, false); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
425 } |
0 | 426 } |
427 } | |
428 | |
429 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
430 /* Return true if REF is based on an aliased base, otherwise false. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
431 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
432 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
433 ref_may_be_aliased (tree ref) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
434 { |
111 | 435 gcc_assert (TREE_CODE (ref) != WITH_SIZE_EXPR); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
436 while (handled_component_p (ref)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
437 ref = TREE_OPERAND (ref, 0); |
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
|
438 if (TREE_CODE (ref) == MEM_REF |
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
|
439 && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR) |
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
|
440 ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
441 return !(DECL_P (ref) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
442 && !may_be_aliased (ref)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
443 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
444 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
445 static bitmap visited = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
446 static unsigned int longest_chain = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
447 static unsigned int total_chain = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
448 static unsigned int nr_walks = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
449 static bool chain_ovfl = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
450 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
451 /* Worker for the walker that marks reaching definitions of REF, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
452 which is based on a non-aliased decl, necessary. It returns |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
453 true whenever the defining statement of the current VDEF is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
454 a kill for REF, as no dominating may-defs are necessary for REF |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
455 anymore. DATA points to the basic-block that contains the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
456 stmt that refers to REF. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
457 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
458 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
459 mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
460 { |
111 | 461 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
462 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
463 /* All stmts we visit are necessary. */ |
111 | 464 if (! gimple_clobber_p (def_stmt)) |
465 mark_operand_necessary (vdef); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
466 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
467 /* If the stmt lhs kills ref, then we can stop walking. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
468 if (gimple_has_lhs (def_stmt) |
111 | 469 && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME |
470 /* The assignment is not necessarily carried out if it can throw | |
471 and we can catch it in the current function where we could inspect | |
472 the previous value. | |
473 ??? We only need to care about the RHS throwing. For aggregate | |
474 assignments or similar calls and non-call exceptions the LHS | |
475 might throw as well. */ | |
131 | 476 && !stmt_can_throw_internal (cfun, def_stmt)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
477 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
478 tree base, lhs = gimple_get_lhs (def_stmt); |
131 | 479 poly_int64 size, offset, max_size; |
111 | 480 bool reverse; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
481 ao_ref_base (ref); |
111 | 482 base |
483 = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
484 /* We can get MEM[symbol: sZ, index: D.8862_1] here, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
485 so base == refd->base does not always hold. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
486 if (base == ref->base) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
487 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
488 /* For a must-alias check we need to be able to constrain |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
489 the accesses properly. */ |
131 | 490 if (known_eq (size, max_size) |
491 && known_subrange_p (ref->offset, ref->max_size, offset, size)) | |
492 return true; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
493 /* Or they need to be exactly the same. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
494 else if (ref->ref |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
495 /* Make sure there is no induction variable involved |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
496 in the references (gcc.c-torture/execute/pr42142.c). |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
497 The simplest way is to check if the kill dominates |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
498 the use. */ |
111 | 499 /* But when both are in the same block we cannot |
500 easily tell whether we came from a backedge | |
501 unless we decide to compute stmt UIDs | |
502 (see PR58246). */ | |
503 && (basic_block) data != gimple_bb (def_stmt) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
504 && dominated_by_p (CDI_DOMINATORS, (basic_block) data, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
505 gimple_bb (def_stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
506 && operand_equal_p (ref->ref, lhs, 0)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
507 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
508 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
509 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
510 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
511 /* Otherwise keep walking. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
514 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
515 static void |
111 | 516 mark_aliased_reaching_defs_necessary (gimple *stmt, tree ref) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
517 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
518 unsigned int chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
519 ao_ref refd; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
520 gcc_assert (!chain_ovfl); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
521 ao_ref_init (&refd, ref); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
522 chain = walk_aliased_vdefs (&refd, gimple_vuse (stmt), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
523 mark_aliased_reaching_defs_necessary_1, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
524 gimple_bb (stmt), NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
525 if (chain > longest_chain) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
526 longest_chain = chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
527 total_chain += chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
528 nr_walks++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
529 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
530 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
531 /* Worker for the walker that marks reaching definitions of REF, which |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
532 is not based on a non-aliased decl. For simplicity we need to end |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
533 up marking all may-defs necessary that are not based on a non-aliased |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
534 decl. The only job of this walker is to skip may-defs based on |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
535 a non-aliased decl. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
536 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
537 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
538 mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
539 tree vdef, void *data ATTRIBUTE_UNUSED) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
540 { |
111 | 541 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
542 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
543 /* We have to skip already visited (and thus necessary) statements |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
544 to make the chaining work after we dropped back to simple mode. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
545 if (chain_ovfl |
111 | 546 && bitmap_bit_p (processed, SSA_NAME_VERSION (vdef))) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
547 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
548 gcc_assert (gimple_nop_p (def_stmt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
549 || gimple_plf (def_stmt, STMT_NECESSARY)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
550 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
551 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
552 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
553 /* We want to skip stores to non-aliased variables. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
554 if (!chain_ovfl |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
555 && gimple_assign_single_p (def_stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
556 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
557 tree lhs = gimple_assign_lhs (def_stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
558 if (!ref_may_be_aliased (lhs)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
559 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
560 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
561 |
111 | 562 /* We want to skip statments that do not constitute stores but have |
563 a virtual definition. */ | |
564 if (is_gimple_call (def_stmt)) | |
565 { | |
566 tree callee = gimple_call_fndecl (def_stmt); | |
567 if (callee != NULL_TREE | |
131 | 568 && fndecl_built_in_p (callee, BUILT_IN_NORMAL)) |
111 | 569 switch (DECL_FUNCTION_CODE (callee)) |
570 { | |
571 case BUILT_IN_MALLOC: | |
572 case BUILT_IN_ALIGNED_ALLOC: | |
573 case BUILT_IN_CALLOC: | |
574 CASE_BUILT_IN_ALLOCA: | |
575 case BUILT_IN_FREE: | |
576 return false; | |
577 | |
578 default:; | |
579 } | |
580 } | |
581 | |
582 if (! gimple_clobber_p (def_stmt)) | |
583 mark_operand_necessary (vdef); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
584 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
585 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
586 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
587 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
588 static void |
111 | 589 mark_all_reaching_defs_necessary (gimple *stmt) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
590 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
591 walk_aliased_vdefs (NULL, gimple_vuse (stmt), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
592 mark_all_reaching_defs_necessary_1, NULL, &visited); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
593 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
594 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
595 /* Return true for PHI nodes with one or identical arguments |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
596 can be removed. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
597 static bool |
111 | 598 degenerate_phi_p (gimple *phi) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
599 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
600 unsigned int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
601 tree op = gimple_phi_arg_def (phi, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
602 for (i = 1; i < gimple_phi_num_args (phi); i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
603 if (gimple_phi_arg_def (phi, i) != op) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
604 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
605 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
606 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
607 |
0 | 608 /* Propagate necessity using the operands of necessary statements. |
609 Process the uses on each statement in the worklist, and add all | |
610 feeding statements which contribute to the calculation of this | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
611 value to the worklist. |
0 | 612 |
613 In conservative mode, EL is NULL. */ | |
614 | |
615 static void | |
111 | 616 propagate_necessity (bool aggressive) |
0 | 617 { |
111 | 618 gimple *stmt; |
0 | 619 |
620 if (dump_file && (dump_flags & TDF_DETAILS)) | |
621 fprintf (dump_file, "\nProcessing worklist:\n"); | |
622 | |
111 | 623 while (worklist.length () > 0) |
0 | 624 { |
625 /* Take STMT from worklist. */ | |
111 | 626 stmt = worklist.pop (); |
0 | 627 |
628 if (dump_file && (dump_flags & TDF_DETAILS)) | |
629 { | |
630 fprintf (dump_file, "processing: "); | |
631 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
632 fprintf (dump_file, "\n"); | |
633 } | |
634 | |
635 if (aggressive) | |
636 { | |
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
|
637 /* Mark the last statement of the basic blocks on which the block |
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
|
638 containing STMT is control dependent, but only if we haven't |
0 | 639 already done so. */ |
640 basic_block bb = gimple_bb (stmt); | |
111 | 641 if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) |
642 && !bitmap_bit_p (visited_control_parents, bb->index)) | |
643 mark_control_dependent_edges_necessary (bb, false); | |
0 | 644 } |
645 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
646 if (gimple_code (stmt) == GIMPLE_PHI |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
647 /* We do not process virtual PHI nodes nor do we track their |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
648 necessity. */ |
111 | 649 && !virtual_operand_p (gimple_phi_result (stmt))) |
0 | 650 { |
651 /* PHI nodes are somewhat special in that each PHI alternative has | |
652 data and control dependencies. All the statements feeding the | |
653 PHI node's arguments are always necessary. In aggressive mode, | |
654 we also consider the control dependent edges leading to the | |
655 predecessor block associated with each PHI alternative as | |
656 necessary. */ | |
111 | 657 gphi *phi = as_a <gphi *> (stmt); |
0 | 658 size_t k; |
659 | |
660 for (k = 0; k < gimple_phi_num_args (stmt); k++) | |
661 { | |
662 tree arg = PHI_ARG_DEF (stmt, k); | |
663 if (TREE_CODE (arg) == SSA_NAME) | |
664 mark_operand_necessary (arg); | |
665 } | |
666 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
667 /* For PHI operands it matters from where the control flow arrives |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
668 to the BB. Consider the following example: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
669 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
670 a=exp1; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
671 b=exp2; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
672 if (test) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
673 ; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
674 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
675 ; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
676 c=PHI(a,b) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
677 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
678 We need to mark control dependence of the empty basic blocks, since they |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
679 contains computation of PHI operands. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
680 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
681 Doing so is too restrictive in the case the predecestor block is in |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
682 the loop. Consider: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
683 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
684 if (b) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
685 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
686 int i; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
687 for (i = 0; i<1000; ++i) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
688 ; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
689 j = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
690 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
691 return j; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
692 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
693 There is PHI for J in the BB containing return statement. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
694 In this case the control dependence of predecestor block (that is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
695 within the empty loop) also contains the block determining number |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
696 of iterations of the block that would prevent removing of empty |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
697 loop in this case. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
698 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
699 This scenario can be avoided by splitting critical edges. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
700 To save the critical edge splitting pass we identify how the control |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
701 dependence would look like if the edge was split. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
702 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
703 Consider the modified CFG created from current CFG by splitting |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
704 edge B->C. In the postdominance tree of modified CFG, C' is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
705 always child of C. There are two cases how chlids of C' can look |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
706 like: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
707 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
708 1) C' is leaf |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
709 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
710 In this case the only basic block C' is control dependent on is B. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
711 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
712 2) C' has single child that is B |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
713 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
714 In this case control dependence of C' is same as control |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
715 dependence of B in original CFG except for block B itself. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
716 (since C' postdominate B in modified CFG) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
717 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
718 Now how to decide what case happens? There are two basic options: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
719 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
720 a) C postdominate B. Then C immediately postdominate B and |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
721 case 2 happens iff there is no other way from B to C except |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
722 the edge B->C. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
723 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
724 There is other way from B to C iff there is succesor of B that |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
725 is not postdominated by B. Testing this condition is somewhat |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
726 expensive, because we need to iterate all succesors of B. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
727 We are safe to assume that this does not happen: we will mark B |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
728 as needed when processing the other path from B to C that is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
729 conrol dependent on B and marking control dependencies of B |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
730 itself is harmless because they will be processed anyway after |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
731 processing control statement in B. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
732 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
733 b) C does not postdominate B. Always case 1 happens since there is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
734 path from C to exit that does not go through B and thus also C'. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
735 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
736 if (aggressive && !degenerate_phi_p (stmt)) |
0 | 737 { |
738 for (k = 0; k < gimple_phi_num_args (stmt); k++) | |
739 { | |
111 | 740 basic_block arg_bb = gimple_phi_arg_edge (phi, k)->src; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
741 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
742 if (gimple_bb (stmt) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
743 != get_immediate_dominator (CDI_POST_DOMINATORS, arg_bb)) |
0 | 744 { |
111 | 745 if (!bitmap_bit_p (last_stmt_necessary, arg_bb->index)) |
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
|
746 mark_last_stmt_necessary (arg_bb); |
0 | 747 } |
111 | 748 else if (arg_bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) |
749 && !bitmap_bit_p (visited_control_parents, | |
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
|
750 arg_bb->index)) |
111 | 751 mark_control_dependent_edges_necessary (arg_bb, true); |
0 | 752 } |
753 } | |
754 } | |
755 else | |
756 { | |
757 /* Propagate through the operands. Examine all the USE, VUSE and | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
758 VDEF operands in this statement. Mark all the statements |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
759 which feed this statement's uses as necessary. */ |
0 | 760 ssa_op_iter iter; |
761 tree use; | |
762 | |
111 | 763 /* If this is a call to free which is directly fed by an |
764 allocation function do not mark that necessary through | |
765 processing the argument. */ | |
766 if (gimple_call_builtin_p (stmt, BUILT_IN_FREE)) | |
767 { | |
768 tree ptr = gimple_call_arg (stmt, 0); | |
769 gimple *def_stmt; | |
770 tree def_callee; | |
771 /* If the pointer we free is defined by an allocation | |
772 function do not add the call to the worklist. */ | |
773 if (TREE_CODE (ptr) == SSA_NAME | |
774 && is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr)) | |
775 && (def_callee = gimple_call_fndecl (def_stmt)) | |
776 && DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL | |
777 && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC | |
778 || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC | |
779 || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) | |
131 | 780 continue; |
111 | 781 } |
782 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
783 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) |
0 | 784 mark_operand_necessary (use); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
785 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
786 use = gimple_vuse (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
787 if (!use) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
788 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
789 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
790 /* If we dropped to simple mode make all immediately |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
791 reachable definitions necessary. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
792 if (chain_ovfl) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
793 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
794 mark_all_reaching_defs_necessary (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
795 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
796 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
797 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
798 /* For statements that may load from memory (have a VUSE) we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
799 have to mark all reaching (may-)definitions as necessary. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
800 We partition this task into two cases: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
801 1) explicit loads based on decls that are not aliased |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
802 2) implicit loads (like calls) and explicit loads not |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
803 based on decls that are not aliased (like indirect |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
804 references or loads from globals) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
805 For 1) we mark all reaching may-defs as necessary, stopping |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
806 at dominating kills. For 2) we want to mark all dominating |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
807 references necessary, but non-aliased ones which we handle |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
808 in 1). By keeping a global visited bitmap for references |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
809 we walk for 2) we avoid quadratic behavior for those. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
810 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
811 if (is_gimple_call (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
812 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
813 tree callee = gimple_call_fndecl (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
814 unsigned i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
815 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
816 /* Calls to functions that are merely acting as barriers |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
817 or that only store to memory do not make any previous |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
818 stores necessary. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
819 if (callee != NULL_TREE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
820 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
821 && (DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET |
111 | 822 || DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET_CHK |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
823 || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC |
111 | 824 || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALIGNED_ALLOC |
825 || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC | |
826 || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE | |
827 || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END | |
828 || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)) | |
829 || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE | |
830 || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE | |
831 || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
832 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
833 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
834 /* Calls implicitly load from memory, their arguments |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
835 in addition may explicitly perform memory loads. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
836 mark_all_reaching_defs_necessary (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
837 for (i = 0; i < gimple_call_num_args (stmt); ++i) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
838 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
839 tree arg = gimple_call_arg (stmt, i); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
840 if (TREE_CODE (arg) == SSA_NAME |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
841 || is_gimple_min_invariant (arg)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
842 continue; |
111 | 843 if (TREE_CODE (arg) == WITH_SIZE_EXPR) |
844 arg = TREE_OPERAND (arg, 0); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
845 if (!ref_may_be_aliased (arg)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
846 mark_aliased_reaching_defs_necessary (stmt, arg); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
847 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
848 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
849 else if (gimple_assign_single_p (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
850 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
851 tree rhs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
852 /* If this is a load mark things necessary. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
853 rhs = gimple_assign_rhs1 (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
854 if (TREE_CODE (rhs) != SSA_NAME |
111 | 855 && !is_gimple_min_invariant (rhs) |
856 && TREE_CODE (rhs) != CONSTRUCTOR) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
857 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
858 if (!ref_may_be_aliased (rhs)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
859 mark_aliased_reaching_defs_necessary (stmt, rhs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
860 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
861 mark_all_reaching_defs_necessary (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
862 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
863 } |
111 | 864 else if (greturn *return_stmt = dyn_cast <greturn *> (stmt)) |
865 { | |
866 tree rhs = gimple_return_retval (return_stmt); | |
867 /* A return statement may perform a load. */ | |
868 if (rhs | |
869 && TREE_CODE (rhs) != SSA_NAME | |
870 && !is_gimple_min_invariant (rhs) | |
871 && TREE_CODE (rhs) != CONSTRUCTOR) | |
872 { | |
873 if (!ref_may_be_aliased (rhs)) | |
874 mark_aliased_reaching_defs_necessary (stmt, rhs); | |
875 else | |
876 mark_all_reaching_defs_necessary (stmt); | |
877 } | |
878 } | |
879 else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
880 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
881 unsigned i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
882 mark_all_reaching_defs_necessary (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
883 /* Inputs may perform loads. */ |
111 | 884 for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
885 { |
111 | 886 tree op = TREE_VALUE (gimple_asm_input_op (asm_stmt, i)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
887 if (TREE_CODE (op) != SSA_NAME |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
888 && !is_gimple_min_invariant (op) |
111 | 889 && TREE_CODE (op) != CONSTRUCTOR |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
890 && !ref_may_be_aliased (op)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
891 mark_aliased_reaching_defs_necessary (stmt, op); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
892 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
893 } |
111 | 894 else if (gimple_code (stmt) == GIMPLE_TRANSACTION) |
895 { | |
896 /* The beginning of a transaction is a memory barrier. */ | |
897 /* ??? If we were really cool, we'd only be a barrier | |
898 for the memories touched within the transaction. */ | |
899 mark_all_reaching_defs_necessary (stmt); | |
900 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
901 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
902 gcc_unreachable (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
903 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
904 /* If we over-used our alias oracle budget drop to simple |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
905 mode. The cost metric allows quadratic behavior |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
906 (number of uses times number of may-defs queries) up to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
907 a constant maximal number of queries and after that falls back to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
908 super-linear complexity. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
909 if (/* Constant but quadratic for small functions. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
910 total_chain > 128 * 128 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
911 /* Linear in the number of may-defs. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
912 && total_chain > 32 * longest_chain |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
913 /* Linear in the number of uses. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
914 && total_chain > nr_walks * 32) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
915 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
916 chain_ovfl = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
917 if (visited) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
918 bitmap_clear (visited); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
919 } |
0 | 920 } |
921 } | |
922 } | |
923 | |
924 /* Remove dead PHI nodes from block BB. */ | |
925 | |
926 static bool | |
927 remove_dead_phis (basic_block bb) | |
928 { | |
929 bool something_changed = false; | |
111 | 930 gphi *phi; |
931 gphi_iterator gsi; | |
0 | 932 |
111 | 933 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);) |
0 | 934 { |
935 stats.total_phis++; | |
111 | 936 phi = gsi.phi (); |
0 | 937 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
938 /* We do not track necessity of virtual PHI nodes. Instead do |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
939 very simple dead PHI removal here. */ |
111 | 940 if (virtual_operand_p (gimple_phi_result (phi))) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
941 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
942 /* Virtual PHI nodes with one or identical arguments |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
943 can be removed. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
944 if (degenerate_phi_p (phi)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
945 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
946 tree vdef = gimple_phi_result (phi); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
947 tree vuse = gimple_phi_arg_def (phi, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
948 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
949 use_operand_p use_p; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
950 imm_use_iterator iter; |
111 | 951 gimple *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
|
952 FOR_EACH_IMM_USE_STMT (use_stmt, iter, vdef) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
953 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
954 SET_USE (use_p, vuse); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
955 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vdef) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
956 && TREE_CODE (vuse) == SSA_NAME) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
957 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
958 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
959 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
960 gimple_set_plf (phi, STMT_NECESSARY, true); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
961 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
962 |
0 | 963 if (!gimple_plf (phi, STMT_NECESSARY)) |
964 { | |
965 something_changed = true; | |
966 if (dump_file && (dump_flags & TDF_DETAILS)) | |
967 { | |
968 fprintf (dump_file, "Deleting : "); | |
969 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
970 fprintf (dump_file, "\n"); | |
971 } | |
972 | |
973 remove_phi_node (&gsi, true); | |
974 stats.removed_phis++; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
975 continue; |
0 | 976 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
977 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
978 gsi_next (&gsi); |
0 | 979 } |
980 return something_changed; | |
981 } | |
982 | |
983 | |
984 /* Remove dead statement pointed to by iterator I. Receives the basic block BB | |
985 containing I so that we don't have to look it up. */ | |
986 | |
987 static void | |
988 remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb) | |
989 { | |
111 | 990 gimple *stmt = gsi_stmt (*i); |
0 | 991 |
992 if (dump_file && (dump_flags & TDF_DETAILS)) | |
993 { | |
994 fprintf (dump_file, "Deleting : "); | |
995 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
996 fprintf (dump_file, "\n"); | |
997 } | |
998 | |
999 stats.removed++; | |
1000 | |
1001 /* If we have determined that a conditional branch statement contributes | |
111 | 1002 nothing to the program, then we not only remove it, but we need to update |
1003 the CFG. We can chose any of edges out of BB as long as we are sure to not | |
1004 close infinite loops. This is done by always choosing the edge closer to | |
1005 exit in inverted_post_order_compute order. */ | |
0 | 1006 if (is_ctrl_stmt (stmt)) |
1007 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1008 edge_iterator ei; |
111 | 1009 edge e = NULL, e2; |
0 | 1010 |
111 | 1011 /* See if there is only one non-abnormal edge. */ |
1012 if (single_succ_p (bb)) | |
1013 e = single_succ_edge (bb); | |
1014 /* Otherwise chose one that is closer to bb with live statement in it. | |
1015 To be able to chose one, we compute inverted post order starting from | |
1016 all BBs with live statements. */ | |
1017 if (!e) | |
1018 { | |
1019 if (!bb_postorder) | |
1020 { | |
1021 auto_vec<int, 20> postorder; | |
1022 inverted_post_order_compute (&postorder, | |
1023 &bb_contains_live_stmts); | |
1024 bb_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun)); | |
1025 for (unsigned int i = 0; i < postorder.length (); ++i) | |
1026 bb_postorder[postorder[i]] = i; | |
1027 } | |
1028 FOR_EACH_EDGE (e2, ei, bb->succs) | |
1029 if (!e || e2->dest == EXIT_BLOCK_PTR_FOR_FN (cfun) | |
1030 || bb_postorder [e->dest->index] | |
1031 < bb_postorder [e2->dest->index]) | |
1032 e = e2; | |
1033 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1034 gcc_assert (e); |
111 | 1035 e->probability = profile_probability::always (); |
0 | 1036 |
1037 /* The edge is no longer associated with a conditional, so it does | |
111 | 1038 not have TRUE/FALSE flags. |
1039 We are also safe to drop EH/ABNORMAL flags and turn them into | |
1040 normal control flow, because we know that all the destinations (including | |
1041 those odd edges) are equivalent for program execution. */ | |
1042 e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_EH | EDGE_ABNORMAL); | |
0 | 1043 |
1044 /* The lone outgoing edge from BB will be a fallthru edge. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1045 e->flags |= EDGE_FALLTHRU; |
0 | 1046 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1047 /* Remove the remaining outgoing edges. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1048 for (ei = ei_start (bb->succs); (e2 = ei_safe_edge (ei)); ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1049 if (e != e2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1050 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1051 cfg_altered = true; |
111 | 1052 /* If we made a BB unconditionally exit a loop or removed |
1053 an entry into an irreducible region, then this transform | |
1054 alters the set of BBs in the loop. Schedule a fixup. */ | |
1055 if (loop_exit_edge_p (bb->loop_father, e) | |
1056 || (e2->dest->flags & BB_IRREDUCIBLE_LOOP)) | |
1057 loops_state_set (LOOPS_NEED_FIXUP); | |
1058 remove_edge (e2); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1059 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1060 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1061 ei_next (&ei); |
0 | 1062 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1063 |
111 | 1064 /* If this is a store into a variable that is being optimized away, |
1065 add a debug bind stmt if possible. */ | |
131 | 1066 if (MAY_HAVE_DEBUG_BIND_STMTS |
111 | 1067 && gimple_assign_single_p (stmt) |
1068 && is_gimple_val (gimple_assign_rhs1 (stmt))) | |
1069 { | |
1070 tree lhs = gimple_assign_lhs (stmt); | |
1071 if ((VAR_P (lhs) || TREE_CODE (lhs) == PARM_DECL) | |
1072 && !DECL_IGNORED_P (lhs) | |
1073 && is_gimple_reg_type (TREE_TYPE (lhs)) | |
1074 && !is_global_var (lhs) | |
1075 && !DECL_HAS_VALUE_EXPR_P (lhs)) | |
1076 { | |
1077 tree rhs = gimple_assign_rhs1 (stmt); | |
1078 gdebug *note | |
1079 = gimple_build_debug_bind (lhs, unshare_expr (rhs), stmt); | |
1080 gsi_insert_after (i, note, GSI_SAME_STMT); | |
1081 } | |
1082 } | |
1083 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1084 unlink_stmt_vdef (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1085 gsi_remove (i, true); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1086 release_defs (stmt); |
0 | 1087 } |
1088 | |
111 | 1089 /* Helper for maybe_optimize_arith_overflow. Find in *TP if there are any |
1090 uses of data (SSA_NAME) other than REALPART_EXPR referencing it. */ | |
1091 | |
1092 static tree | |
1093 find_non_realpart_uses (tree *tp, int *walk_subtrees, void *data) | |
1094 { | |
1095 if (TYPE_P (*tp) || TREE_CODE (*tp) == REALPART_EXPR) | |
1096 *walk_subtrees = 0; | |
1097 if (*tp == (tree) data) | |
1098 return *tp; | |
1099 return NULL_TREE; | |
1100 } | |
1101 | |
1102 /* If the IMAGPART_EXPR of the {ADD,SUB,MUL}_OVERFLOW result is never used, | |
1103 but REALPART_EXPR is, optimize the {ADD,SUB,MUL}_OVERFLOW internal calls | |
1104 into plain unsigned {PLUS,MINUS,MULT}_EXPR, and if needed reset debug | |
1105 uses. */ | |
1106 | |
1107 static void | |
1108 maybe_optimize_arith_overflow (gimple_stmt_iterator *gsi, | |
1109 enum tree_code subcode) | |
1110 { | |
1111 gimple *stmt = gsi_stmt (*gsi); | |
1112 tree lhs = gimple_call_lhs (stmt); | |
1113 | |
1114 if (lhs == NULL || TREE_CODE (lhs) != SSA_NAME) | |
1115 return; | |
1116 | |
1117 imm_use_iterator imm_iter; | |
1118 use_operand_p use_p; | |
1119 bool has_debug_uses = false; | |
1120 bool has_realpart_uses = false; | |
1121 bool has_other_uses = false; | |
1122 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) | |
1123 { | |
1124 gimple *use_stmt = USE_STMT (use_p); | |
1125 if (is_gimple_debug (use_stmt)) | |
1126 has_debug_uses = true; | |
1127 else if (is_gimple_assign (use_stmt) | |
1128 && gimple_assign_rhs_code (use_stmt) == REALPART_EXPR | |
1129 && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == lhs) | |
1130 has_realpart_uses = true; | |
1131 else | |
1132 { | |
1133 has_other_uses = true; | |
1134 break; | |
1135 } | |
1136 } | |
1137 | |
1138 if (!has_realpart_uses || has_other_uses) | |
1139 return; | |
1140 | |
1141 tree arg0 = gimple_call_arg (stmt, 0); | |
1142 tree arg1 = gimple_call_arg (stmt, 1); | |
1143 location_t loc = gimple_location (stmt); | |
1144 tree type = TREE_TYPE (TREE_TYPE (lhs)); | |
1145 tree utype = type; | |
1146 if (!TYPE_UNSIGNED (type)) | |
1147 utype = build_nonstandard_integer_type (TYPE_PRECISION (type), 1); | |
1148 tree result = fold_build2_loc (loc, subcode, utype, | |
1149 fold_convert_loc (loc, utype, arg0), | |
1150 fold_convert_loc (loc, utype, arg1)); | |
1151 result = fold_convert_loc (loc, type, result); | |
1152 | |
1153 if (has_debug_uses) | |
1154 { | |
1155 gimple *use_stmt; | |
1156 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) | |
1157 { | |
1158 if (!gimple_debug_bind_p (use_stmt)) | |
1159 continue; | |
1160 tree v = gimple_debug_bind_get_value (use_stmt); | |
1161 if (walk_tree (&v, find_non_realpart_uses, lhs, NULL)) | |
1162 { | |
1163 gimple_debug_bind_reset_value (use_stmt); | |
1164 update_stmt (use_stmt); | |
1165 } | |
1166 } | |
1167 } | |
1168 | |
1169 if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result)) | |
1170 result = drop_tree_overflow (result); | |
1171 tree overflow = build_zero_cst (type); | |
1172 tree ctype = build_complex_type (type); | |
1173 if (TREE_CODE (result) == INTEGER_CST) | |
1174 result = build_complex (ctype, result, overflow); | |
1175 else | |
1176 result = build2_loc (gimple_location (stmt), COMPLEX_EXPR, | |
1177 ctype, result, overflow); | |
1178 | |
1179 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1180 { | |
1181 fprintf (dump_file, "Transforming call: "); | |
1182 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1183 fprintf (dump_file, "because the overflow result is never used into: "); | |
1184 print_generic_stmt (dump_file, result, TDF_SLIM); | |
1185 fprintf (dump_file, "\n"); | |
1186 } | |
1187 | |
1188 if (!update_call_from_tree (gsi, result)) | |
1189 gimplify_and_update_call_from_tree (gsi, result); | |
1190 } | |
1191 | |
0 | 1192 /* Eliminate unnecessary statements. Any instruction not marked as necessary |
1193 contributes nothing to the program, and can be deleted. */ | |
1194 | |
1195 static bool | |
1196 eliminate_unnecessary_stmts (void) | |
1197 { | |
1198 bool something_changed = false; | |
1199 basic_block bb; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1200 gimple_stmt_iterator gsi, psi; |
111 | 1201 gimple *stmt; |
0 | 1202 tree call; |
111 | 1203 vec<basic_block> h; |
0 | 1204 |
1205 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1206 fprintf (dump_file, "\nEliminating unnecessary statements:\n"); | |
1207 | |
1208 clear_special_calls (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1209 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1210 /* Walking basic blocks and statements in reverse order avoids |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1211 releasing SSA names before any other DEFs that refer to them are |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1212 released. This helps avoid loss of debug information, as we get |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1213 a chance to propagate all RHSs of removed SSAs into debug uses, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1214 rather than only the latest ones. E.g., consider: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1215 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1216 x_3 = y_1 + z_2; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1217 a_5 = x_3 - b_4; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1218 # DEBUG a => a_5 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1219 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1220 If we were to release x_3 before a_5, when we reached a_5 and |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1221 tried to substitute it into the debug stmt, we'd see x_3 there, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1222 but x_3's DEF, type, etc would have already been disconnected. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1223 By going backwards, the debug stmt first changes to: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1224 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1225 # DEBUG a => x_3 - b_4 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1226 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1227 and then to: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1228 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1229 # DEBUG a => y_1 + z_2 - b_4 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1230 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1231 as desired. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1232 gcc_assert (dom_info_available_p (CDI_DOMINATORS)); |
111 | 1233 h = get_all_dominated_blocks (CDI_DOMINATORS, |
1234 single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1235 |
111 | 1236 while (h.length ()) |
0 | 1237 { |
111 | 1238 bb = h.pop (); |
0 | 1239 |
1240 /* Remove dead statements. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1241 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi = psi) |
0 | 1242 { |
1243 stmt = gsi_stmt (gsi); | |
1244 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1245 psi = gsi; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1246 gsi_prev (&psi); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1247 |
0 | 1248 stats.total++; |
1249 | |
111 | 1250 /* We can mark a call to free as not necessary if the |
1251 defining statement of its argument is not necessary | |
1252 (and thus is getting removed). */ | |
1253 if (gimple_plf (stmt, STMT_NECESSARY) | |
1254 && gimple_call_builtin_p (stmt, BUILT_IN_FREE)) | |
1255 { | |
1256 tree ptr = gimple_call_arg (stmt, 0); | |
1257 if (TREE_CODE (ptr) == SSA_NAME) | |
1258 { | |
1259 gimple *def_stmt = SSA_NAME_DEF_STMT (ptr); | |
1260 if (!gimple_nop_p (def_stmt) | |
1261 && !gimple_plf (def_stmt, STMT_NECESSARY)) | |
1262 gimple_set_plf (stmt, STMT_NECESSARY, false); | |
1263 } | |
1264 } | |
1265 | |
0 | 1266 /* If GSI is not necessary then remove it. */ |
1267 if (!gimple_plf (stmt, STMT_NECESSARY)) | |
1268 { | |
111 | 1269 /* Keep clobbers that we can keep live live. */ |
1270 if (gimple_clobber_p (stmt)) | |
1271 { | |
1272 ssa_op_iter iter; | |
1273 use_operand_p use_p; | |
1274 bool dead = false; | |
1275 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) | |
1276 { | |
1277 tree name = USE_FROM_PTR (use_p); | |
1278 if (!SSA_NAME_IS_DEFAULT_DEF (name) | |
1279 && !bitmap_bit_p (processed, SSA_NAME_VERSION (name))) | |
1280 { | |
1281 dead = true; | |
1282 break; | |
1283 } | |
1284 } | |
1285 if (!dead) | |
1286 continue; | |
1287 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1288 if (!is_gimple_debug (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1289 something_changed = true; |
0 | 1290 remove_dead_stmt (&gsi, bb); |
1291 } | |
1292 else if (is_gimple_call (stmt)) | |
1293 { | |
111 | 1294 tree name = gimple_call_lhs (stmt); |
1295 | |
1296 notice_special_calls (as_a <gcall *> (stmt)); | |
0 | 1297 |
111 | 1298 /* When LHS of var = call (); is dead, simplify it into |
1299 call (); saving one operand. */ | |
1300 if (name | |
1301 && TREE_CODE (name) == SSA_NAME | |
1302 && !bitmap_bit_p (processed, SSA_NAME_VERSION (name)) | |
1303 /* Avoid doing so for allocation calls which we | |
1304 did not mark as necessary, it will confuse the | |
1305 special logic we apply to malloc/free pair removal. */ | |
1306 && (!(call = gimple_call_fndecl (stmt)) | |
1307 || DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL | |
1308 || (DECL_FUNCTION_CODE (call) != BUILT_IN_ALIGNED_ALLOC | |
1309 && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC | |
1310 && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC | |
1311 && !ALLOCA_FUNCTION_CODE_P | |
131 | 1312 (DECL_FUNCTION_CODE (call))))) |
111 | 1313 { |
1314 something_changed = true; | |
1315 if (dump_file && (dump_flags & TDF_DETAILS)) | |
0 | 1316 { |
111 | 1317 fprintf (dump_file, "Deleting LHS of call: "); |
1318 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1319 fprintf (dump_file, "\n"); | |
1320 } | |
1321 | |
1322 gimple_call_set_lhs (stmt, NULL_TREE); | |
1323 maybe_clean_or_replace_eh_stmt (stmt, stmt); | |
1324 update_stmt (stmt); | |
1325 release_ssa_name (name); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1326 |
111 | 1327 /* GOMP_SIMD_LANE or ASAN_POISON without lhs is not |
1328 needed. */ | |
1329 if (gimple_call_internal_p (stmt)) | |
1330 switch (gimple_call_internal_fn (stmt)) | |
1331 { | |
1332 case IFN_GOMP_SIMD_LANE: | |
1333 case IFN_ASAN_POISON: | |
1334 remove_dead_stmt (&gsi, bb); | |
1335 break; | |
1336 default: | |
1337 break; | |
1338 } | |
0 | 1339 } |
111 | 1340 else if (gimple_call_internal_p (stmt)) |
1341 switch (gimple_call_internal_fn (stmt)) | |
1342 { | |
1343 case IFN_ADD_OVERFLOW: | |
1344 maybe_optimize_arith_overflow (&gsi, PLUS_EXPR); | |
1345 break; | |
1346 case IFN_SUB_OVERFLOW: | |
1347 maybe_optimize_arith_overflow (&gsi, MINUS_EXPR); | |
1348 break; | |
1349 case IFN_MUL_OVERFLOW: | |
1350 maybe_optimize_arith_overflow (&gsi, MULT_EXPR); | |
1351 break; | |
1352 default: | |
1353 break; | |
1354 } | |
0 | 1355 } |
1356 } | |
1357 } | |
1358 | |
111 | 1359 h.release (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1360 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1361 /* Since we don't track liveness of virtual PHI nodes, it is possible that we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1362 rendered some PHI nodes unreachable while they are still in use. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1363 Mark them for renaming. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1364 if (cfg_altered) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1365 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1366 basic_block prev_bb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1367 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1368 find_unreachable_blocks (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1369 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1370 /* Delete all unreachable basic blocks in reverse dominator order. */ |
111 | 1371 for (bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; |
1372 bb != ENTRY_BLOCK_PTR_FOR_FN (cfun); bb = prev_bb) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1373 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1374 prev_bb = bb->prev_bb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1375 |
111 | 1376 if (!bitmap_bit_p (bb_contains_live_stmts, bb->index) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1377 || !(bb->flags & BB_REACHABLE)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1378 { |
111 | 1379 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); |
1380 gsi_next (&gsi)) | |
1381 if (virtual_operand_p (gimple_phi_result (gsi.phi ()))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1382 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1383 bool found = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1384 imm_use_iterator iter; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1385 |
111 | 1386 FOR_EACH_IMM_USE_STMT (stmt, iter, |
1387 gimple_phi_result (gsi.phi ())) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1388 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1389 if (!(gimple_bb (stmt)->flags & BB_REACHABLE)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1390 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1391 if (gimple_code (stmt) == GIMPLE_PHI |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1392 || gimple_plf (stmt, STMT_NECESSARY)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1393 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1394 found = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1395 BREAK_FROM_IMM_USE_STMT (iter); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1396 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1397 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1398 if (found) |
111 | 1399 mark_virtual_phi_result_for_renaming (gsi.phi ()); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1400 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1401 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1402 if (!(bb->flags & BB_REACHABLE)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1403 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1404 /* Speed up the removal of blocks that don't |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1405 dominate others. Walking backwards, this should |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1406 be the common case. ??? Do we need to recompute |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1407 dominators because of cfg_altered? */ |
131 | 1408 if (!first_dom_son (CDI_DOMINATORS, bb)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1409 delete_basic_block (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1410 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1411 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1412 h = get_all_dominated_blocks (CDI_DOMINATORS, bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1413 |
111 | 1414 while (h.length ()) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1415 { |
111 | 1416 bb = h.pop (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1417 prev_bb = bb->prev_bb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1418 /* Rearrangements to the CFG may have failed |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1419 to update the dominators tree, so that |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1420 formerly-dominated blocks are now |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1421 otherwise reachable. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1422 if (!!(bb->flags & BB_REACHABLE)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1423 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1424 delete_basic_block (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1425 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1426 |
111 | 1427 h.release (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1428 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1429 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1430 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1431 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1432 } |
111 | 1433 FOR_EACH_BB_FN (bb, cfun) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1434 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1435 /* Remove dead PHI nodes. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1436 something_changed |= remove_dead_phis (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1437 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1438 |
111 | 1439 if (bb_postorder) |
1440 free (bb_postorder); | |
1441 bb_postorder = NULL; | |
1442 | |
0 | 1443 return something_changed; |
1444 } | |
1445 | |
1446 | |
1447 /* Print out removed statement statistics. */ | |
1448 | |
1449 static void | |
1450 print_stats (void) | |
1451 { | |
1452 float percg; | |
1453 | |
1454 percg = ((float) stats.removed / (float) stats.total) * 100; | |
1455 fprintf (dump_file, "Removed %d of %d statements (%d%%)\n", | |
1456 stats.removed, stats.total, (int) percg); | |
1457 | |
1458 if (stats.total_phis == 0) | |
1459 percg = 0; | |
1460 else | |
1461 percg = ((float) stats.removed_phis / (float) stats.total_phis) * 100; | |
1462 | |
1463 fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n", | |
1464 stats.removed_phis, stats.total_phis, (int) percg); | |
1465 } | |
1466 | |
1467 /* Initialization for this pass. Set up the used data structures. */ | |
1468 | |
1469 static void | |
1470 tree_dce_init (bool aggressive) | |
1471 { | |
1472 memset ((void *) &stats, 0, sizeof (stats)); | |
1473 | |
1474 if (aggressive) | |
1475 { | |
111 | 1476 last_stmt_necessary = sbitmap_alloc (last_basic_block_for_fn (cfun)); |
1477 bitmap_clear (last_stmt_necessary); | |
1478 bb_contains_live_stmts = sbitmap_alloc (last_basic_block_for_fn (cfun)); | |
1479 bitmap_clear (bb_contains_live_stmts); | |
0 | 1480 } |
1481 | |
1482 processed = sbitmap_alloc (num_ssa_names + 1); | |
111 | 1483 bitmap_clear (processed); |
0 | 1484 |
111 | 1485 worklist.create (64); |
0 | 1486 cfg_altered = false; |
1487 } | |
1488 | |
1489 /* Cleanup after this pass. */ | |
1490 | |
1491 static void | |
1492 tree_dce_done (bool aggressive) | |
1493 { | |
1494 if (aggressive) | |
1495 { | |
111 | 1496 delete cd; |
0 | 1497 sbitmap_free (visited_control_parents); |
1498 sbitmap_free (last_stmt_necessary); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1499 sbitmap_free (bb_contains_live_stmts); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1500 bb_contains_live_stmts = NULL; |
0 | 1501 } |
1502 | |
1503 sbitmap_free (processed); | |
1504 | |
111 | 1505 worklist.release (); |
0 | 1506 } |
1507 | |
1508 /* Main routine to eliminate dead code. | |
1509 | |
1510 AGGRESSIVE controls the aggressiveness of the algorithm. | |
1511 In conservative mode, we ignore control dependence and simply declare | |
1512 all but the most trivially dead branches necessary. This mode is fast. | |
1513 In aggressive mode, control dependences are taken into account, which | |
1514 results in more dead code elimination, but at the cost of some time. | |
1515 | |
1516 FIXME: Aggressive mode before PRE doesn't work currently because | |
1517 the dominance info is not invalidated after DCE1. This is | |
1518 not an issue right now because we only run aggressive DCE | |
1519 as the last tree SSA pass, but keep this in mind when you | |
1520 start experimenting with pass ordering. */ | |
1521 | |
1522 static unsigned int | |
1523 perform_tree_ssa_dce (bool aggressive) | |
1524 { | |
1525 bool something_changed = 0; | |
1526 | |
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
|
1527 calculate_dominance_info (CDI_DOMINATORS); |
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
|
1528 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1529 /* Preheaders are needed for SCEV to work. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1530 Simple lateches and recorded exits improve chances that loop will |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1531 proved to be finite in testcases such as in loop-15.c and loop-24.c */ |
111 | 1532 bool in_loop_pipeline = scev_initialized_p (); |
1533 if (aggressive && ! in_loop_pipeline) | |
1534 { | |
1535 scev_initialize (); | |
1536 loop_optimizer_init (LOOPS_NORMAL | |
1537 | LOOPS_HAVE_RECORDED_EXITS); | |
1538 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1539 |
0 | 1540 tree_dce_init (aggressive); |
1541 | |
1542 if (aggressive) | |
1543 { | |
1544 /* Compute control dependence. */ | |
1545 calculate_dominance_info (CDI_POST_DOMINATORS); | |
111 | 1546 cd = new control_dependences (); |
0 | 1547 |
111 | 1548 visited_control_parents = |
1549 sbitmap_alloc (last_basic_block_for_fn (cfun)); | |
1550 bitmap_clear (visited_control_parents); | |
0 | 1551 |
1552 mark_dfs_back_edges (); | |
1553 } | |
1554 | |
111 | 1555 find_obviously_necessary_stmts (aggressive); |
0 | 1556 |
111 | 1557 if (aggressive && ! in_loop_pipeline) |
1558 { | |
1559 loop_optimizer_finalize (); | |
1560 scev_finalize (); | |
1561 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1562 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1563 longest_chain = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1564 total_chain = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1565 nr_walks = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1566 chain_ovfl = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1567 visited = BITMAP_ALLOC (NULL); |
111 | 1568 propagate_necessity (aggressive); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1569 BITMAP_FREE (visited); |
0 | 1570 |
1571 something_changed |= eliminate_unnecessary_stmts (); | |
1572 something_changed |= cfg_altered; | |
1573 | |
1574 /* We do not update postdominators, so free them unconditionally. */ | |
1575 free_dominance_info (CDI_POST_DOMINATORS); | |
1576 | |
1577 /* If we removed paths in the CFG, then we need to update | |
1578 dominators as well. I haven't investigated the possibility | |
1579 of incrementally updating dominators. */ | |
1580 if (cfg_altered) | |
1581 free_dominance_info (CDI_DOMINATORS); | |
1582 | |
1583 statistics_counter_event (cfun, "Statements deleted", stats.removed); | |
1584 statistics_counter_event (cfun, "PHI nodes deleted", stats.removed_phis); | |
1585 | |
1586 /* Debugging dumps. */ | |
1587 if (dump_file && (dump_flags & (TDF_STATS|TDF_DETAILS))) | |
1588 print_stats (); | |
1589 | |
1590 tree_dce_done (aggressive); | |
1591 | |
1592 if (something_changed) | |
111 | 1593 { |
1594 free_numbers_of_iterations_estimates (cfun); | |
1595 if (in_loop_pipeline) | |
1596 scev_reset (); | |
1597 return TODO_update_ssa | TODO_cleanup_cfg; | |
1598 } | |
1599 return 0; | |
0 | 1600 } |
1601 | |
1602 /* Pass entry points. */ | |
1603 static unsigned int | |
1604 tree_ssa_dce (void) | |
1605 { | |
1606 return perform_tree_ssa_dce (/*aggressive=*/false); | |
1607 } | |
1608 | |
1609 static unsigned int | |
1610 tree_ssa_cd_dce (void) | |
1611 { | |
1612 return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2); | |
1613 } | |
1614 | |
111 | 1615 namespace { |
0 | 1616 |
111 | 1617 const pass_data pass_data_dce = |
0 | 1618 { |
111 | 1619 GIMPLE_PASS, /* type */ |
1620 "dce", /* name */ | |
1621 OPTGROUP_NONE, /* optinfo_flags */ | |
1622 TV_TREE_DCE, /* tv_id */ | |
1623 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
1624 0, /* properties_provided */ | |
1625 0, /* properties_destroyed */ | |
1626 0, /* todo_flags_start */ | |
1627 0, /* todo_flags_finish */ | |
0 | 1628 }; |
1629 | |
111 | 1630 class pass_dce : public gimple_opt_pass |
0 | 1631 { |
111 | 1632 public: |
1633 pass_dce (gcc::context *ctxt) | |
1634 : gimple_opt_pass (pass_data_dce, ctxt) | |
1635 {} | |
1636 | |
1637 /* opt_pass methods: */ | |
1638 opt_pass * clone () { return new pass_dce (m_ctxt); } | |
1639 virtual bool gate (function *) { return flag_tree_dce != 0; } | |
1640 virtual unsigned int execute (function *) { return tree_ssa_dce (); } | |
1641 | |
1642 }; // class pass_dce | |
1643 | |
1644 } // anon namespace | |
1645 | |
1646 gimple_opt_pass * | |
1647 make_pass_dce (gcc::context *ctxt) | |
1648 { | |
1649 return new pass_dce (ctxt); | |
1650 } | |
1651 | |
1652 namespace { | |
1653 | |
1654 const pass_data pass_data_cd_dce = | |
1655 { | |
1656 GIMPLE_PASS, /* type */ | |
1657 "cddce", /* name */ | |
1658 OPTGROUP_NONE, /* optinfo_flags */ | |
1659 TV_TREE_CD_DCE, /* tv_id */ | |
1660 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
1661 0, /* properties_provided */ | |
1662 0, /* properties_destroyed */ | |
1663 0, /* todo_flags_start */ | |
1664 0, /* todo_flags_finish */ | |
0 | 1665 }; |
1666 | |
111 | 1667 class pass_cd_dce : public gimple_opt_pass |
0 | 1668 { |
111 | 1669 public: |
1670 pass_cd_dce (gcc::context *ctxt) | |
1671 : gimple_opt_pass (pass_data_cd_dce, ctxt) | |
1672 {} | |
1673 | |
1674 /* opt_pass methods: */ | |
1675 opt_pass * clone () { return new pass_cd_dce (m_ctxt); } | |
1676 virtual bool gate (function *) { return flag_tree_dce != 0; } | |
1677 virtual unsigned int execute (function *) { return tree_ssa_cd_dce (); } | |
1678 | |
1679 }; // class pass_cd_dce | |
1680 | |
1681 } // anon namespace | |
1682 | |
1683 gimple_opt_pass * | |
1684 make_pass_cd_dce (gcc::context *ctxt) | |
1685 { | |
1686 return new pass_cd_dce (ctxt); | |
1687 } | |
131 | 1688 |
1689 | |
1690 /* A cheap DCE interface. WORKLIST is a list of possibly dead stmts and | |
1691 is consumed by this function. The function has linear complexity in | |
1692 the number of dead stmts with a constant factor like the average SSA | |
1693 use operands number. */ | |
1694 | |
1695 void | |
1696 simple_dce_from_worklist (bitmap worklist) | |
1697 { | |
1698 while (! bitmap_empty_p (worklist)) | |
1699 { | |
1700 /* Pop item. */ | |
1701 unsigned i = bitmap_first_set_bit (worklist); | |
1702 bitmap_clear_bit (worklist, i); | |
1703 | |
1704 tree def = ssa_name (i); | |
1705 /* Removed by somebody else or still in use. */ | |
1706 if (! def || ! has_zero_uses (def)) | |
1707 continue; | |
1708 | |
1709 gimple *t = SSA_NAME_DEF_STMT (def); | |
1710 if (gimple_has_side_effects (t)) | |
1711 continue; | |
1712 | |
1713 /* Add uses to the worklist. */ | |
1714 ssa_op_iter iter; | |
1715 use_operand_p use_p; | |
1716 FOR_EACH_PHI_OR_STMT_USE (use_p, t, iter, SSA_OP_USE) | |
1717 { | |
1718 tree use = USE_FROM_PTR (use_p); | |
1719 if (TREE_CODE (use) == SSA_NAME | |
1720 && ! SSA_NAME_IS_DEFAULT_DEF (use)) | |
1721 bitmap_set_bit (worklist, SSA_NAME_VERSION (use)); | |
1722 } | |
1723 | |
1724 /* Remove stmt. */ | |
1725 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1726 { | |
1727 fprintf (dump_file, "Removing dead stmt:"); | |
1728 print_gimple_stmt (dump_file, t, 0); | |
1729 } | |
1730 gimple_stmt_iterator gsi = gsi_for_stmt (t); | |
1731 if (gimple_code (t) == GIMPLE_PHI) | |
1732 remove_phi_node (&gsi, true); | |
1733 else | |
1734 { | |
1735 gsi_remove (&gsi, true); | |
1736 release_defs (t); | |
1737 } | |
1738 } | |
1739 } |