Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-propagate.c @ 88:f214c1d5b862
merge 89
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 20 Dec 2011 18:53:46 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Generic SSA value propagation engine. |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
3 Free Software Foundation, Inc. |
0 | 4 Contributed by Diego Novillo <dnovillo@redhat.com> |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 3, or (at your option) any | |
11 later version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
25 #include "tm.h" | |
26 #include "tree.h" | |
27 #include "flags.h" | |
28 #include "tm_p.h" | |
29 #include "basic-block.h" | |
30 #include "output.h" | |
31 #include "function.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
|
32 #include "gimple-pretty-print.h" |
0 | 33 #include "timevar.h" |
34 #include "tree-dump.h" | |
35 #include "tree-flow.h" | |
36 #include "tree-pass.h" | |
37 #include "tree-ssa-propagate.h" | |
38 #include "langhooks.h" | |
39 #include "vec.h" | |
40 #include "value-prof.h" | |
41 #include "gimple.h" | |
42 | |
43 /* This file implements a generic value propagation engine based on | |
44 the same propagation used by the SSA-CCP algorithm [1]. | |
45 | |
46 Propagation is performed by simulating the execution of every | |
47 statement that produces the value being propagated. Simulation | |
48 proceeds as follows: | |
49 | |
50 1- Initially, all edges of the CFG are marked not executable and | |
51 the CFG worklist is seeded with all the statements in the entry | |
52 basic block (block 0). | |
53 | |
54 2- Every statement S is simulated with a call to the call-back | |
55 function SSA_PROP_VISIT_STMT. This evaluation may produce 3 | |
56 results: | |
57 | |
58 SSA_PROP_NOT_INTERESTING: Statement S produces nothing of | |
59 interest and does not affect any of the work lists. | |
60 | |
61 SSA_PROP_VARYING: The value produced by S cannot be determined | |
62 at compile time. Further simulation of S is not required. | |
63 If S is a conditional jump, all the outgoing edges for the | |
64 block are considered executable and added to the work | |
65 list. | |
66 | |
67 SSA_PROP_INTERESTING: S produces a value that can be computed | |
68 at compile time. Its result can be propagated into the | |
69 statements that feed from S. Furthermore, if S is a | |
70 conditional jump, only the edge known to be taken is added | |
71 to the work list. Edges that are known not to execute are | |
72 never simulated. | |
73 | |
74 3- PHI nodes are simulated with a call to SSA_PROP_VISIT_PHI. The | |
75 return value from SSA_PROP_VISIT_PHI has the same semantics as | |
76 described in #2. | |
77 | |
78 4- Three work lists are kept. Statements are only added to these | |
79 lists if they produce one of SSA_PROP_INTERESTING or | |
80 SSA_PROP_VARYING. | |
81 | |
82 CFG_BLOCKS contains the list of blocks to be simulated. | |
83 Blocks are added to this list if their incoming edges are | |
84 found executable. | |
85 | |
86 VARYING_SSA_EDGES contains the list of statements that feed | |
87 from statements that produce an SSA_PROP_VARYING result. | |
88 These are simulated first to speed up processing. | |
89 | |
90 INTERESTING_SSA_EDGES contains the list of statements that | |
91 feed from statements that produce an SSA_PROP_INTERESTING | |
92 result. | |
93 | |
94 5- Simulation terminates when all three work lists are drained. | |
95 | |
96 Before calling ssa_propagate, it is important to clear | |
97 prop_simulate_again_p for all the statements in the program that | |
98 should be simulated. This initialization allows an implementation | |
99 to specify which statements should never be simulated. | |
100 | |
101 It is also important to compute def-use information before calling | |
102 ssa_propagate. | |
103 | |
104 References: | |
105 | |
106 [1] Constant propagation with conditional branches, | |
107 Wegman and Zadeck, ACM TOPLAS 13(2):181-210. | |
108 | |
109 [2] Building an Optimizing Compiler, | |
110 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9. | |
111 | |
112 [3] Advanced Compiler Design and Implementation, | |
113 Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */ | |
114 | |
115 /* Function pointers used to parameterize the propagation engine. */ | |
116 static ssa_prop_visit_stmt_fn ssa_prop_visit_stmt; | |
117 static ssa_prop_visit_phi_fn ssa_prop_visit_phi; | |
118 | |
119 /* Keep track of statements that have been added to one of the SSA | |
120 edges worklists. This flag is used to avoid visiting statements | |
121 unnecessarily when draining an SSA edge worklist. If while | |
122 simulating a basic block, we find a statement with | |
123 STMT_IN_SSA_EDGE_WORKLIST set, we clear it to prevent SSA edge | |
124 processing from visiting it again. | |
125 | |
126 NOTE: users of the propagation engine are not allowed to use | |
127 the GF_PLF_1 flag. */ | |
128 #define STMT_IN_SSA_EDGE_WORKLIST GF_PLF_1 | |
129 | |
130 /* A bitmap to keep track of executable blocks in the CFG. */ | |
131 static sbitmap executable_blocks; | |
132 | |
133 /* Array of control flow edges on the worklist. */ | |
134 static VEC(basic_block,heap) *cfg_blocks; | |
135 | |
136 static unsigned int cfg_blocks_num = 0; | |
137 static int cfg_blocks_tail; | |
138 static int cfg_blocks_head; | |
139 | |
140 static sbitmap bb_in_list; | |
141 | |
142 /* Worklist of SSA edges which will need reexamination as their | |
143 definition has changed. SSA edges are def-use edges in the SSA | |
144 web. For each D-U edge, we store the target statement or PHI node | |
145 U. */ | |
146 static GTY(()) VEC(gimple,gc) *interesting_ssa_edges; | |
147 | |
148 /* Identical to INTERESTING_SSA_EDGES. For performance reasons, the | |
149 list of SSA edges is split into two. One contains all SSA edges | |
150 who need to be reexamined because their lattice value changed to | |
151 varying (this worklist), and the other contains all other SSA edges | |
152 to be reexamined (INTERESTING_SSA_EDGES). | |
153 | |
154 Since most values in the program are VARYING, the ideal situation | |
155 is to move them to that lattice value as quickly as possible. | |
156 Thus, it doesn't make sense to process any other type of lattice | |
157 value until all VARYING values are propagated fully, which is one | |
158 thing using the VARYING worklist achieves. In addition, if we | |
159 don't use a separate worklist for VARYING edges, we end up with | |
160 situations where lattice values move from | |
161 UNDEFINED->INTERESTING->VARYING instead of UNDEFINED->VARYING. */ | |
162 static GTY(()) VEC(gimple,gc) *varying_ssa_edges; | |
163 | |
164 | |
165 /* Return true if the block worklist empty. */ | |
166 | |
167 static inline bool | |
168 cfg_blocks_empty_p (void) | |
169 { | |
170 return (cfg_blocks_num == 0); | |
171 } | |
172 | |
173 | |
174 /* Add a basic block to the worklist. The block must not be already | |
175 in the worklist, and it must not be the ENTRY or EXIT block. */ | |
176 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
177 static void |
0 | 178 cfg_blocks_add (basic_block bb) |
179 { | |
180 bool head = false; | |
181 | |
182 gcc_assert (bb != ENTRY_BLOCK_PTR && bb != EXIT_BLOCK_PTR); | |
183 gcc_assert (!TEST_BIT (bb_in_list, bb->index)); | |
184 | |
185 if (cfg_blocks_empty_p ()) | |
186 { | |
187 cfg_blocks_tail = cfg_blocks_head = 0; | |
188 cfg_blocks_num = 1; | |
189 } | |
190 else | |
191 { | |
192 cfg_blocks_num++; | |
193 if (cfg_blocks_num > VEC_length (basic_block, cfg_blocks)) | |
194 { | |
195 /* We have to grow the array now. Adjust to queue to occupy | |
196 the full space of the original array. We do not need to | |
197 initialize the newly allocated portion of the array | |
198 because we keep track of CFG_BLOCKS_HEAD and | |
199 CFG_BLOCKS_HEAD. */ | |
200 cfg_blocks_tail = VEC_length (basic_block, cfg_blocks); | |
201 cfg_blocks_head = 0; | |
202 VEC_safe_grow (basic_block, heap, cfg_blocks, 2 * cfg_blocks_tail); | |
203 } | |
204 /* Minor optimization: we prefer to see blocks with more | |
205 predecessors later, because there is more of a chance that | |
206 the incoming edges will be executable. */ | |
207 else if (EDGE_COUNT (bb->preds) | |
208 >= EDGE_COUNT (VEC_index (basic_block, cfg_blocks, | |
209 cfg_blocks_head)->preds)) | |
210 cfg_blocks_tail = ((cfg_blocks_tail + 1) | |
211 % VEC_length (basic_block, cfg_blocks)); | |
212 else | |
213 { | |
214 if (cfg_blocks_head == 0) | |
215 cfg_blocks_head = VEC_length (basic_block, cfg_blocks); | |
216 --cfg_blocks_head; | |
217 head = true; | |
218 } | |
219 } | |
220 | |
221 VEC_replace (basic_block, cfg_blocks, | |
222 head ? cfg_blocks_head : cfg_blocks_tail, | |
223 bb); | |
224 SET_BIT (bb_in_list, bb->index); | |
225 } | |
226 | |
227 | |
228 /* Remove a block from the worklist. */ | |
229 | |
230 static basic_block | |
231 cfg_blocks_get (void) | |
232 { | |
233 basic_block bb; | |
234 | |
235 bb = VEC_index (basic_block, cfg_blocks, cfg_blocks_head); | |
236 | |
237 gcc_assert (!cfg_blocks_empty_p ()); | |
238 gcc_assert (bb); | |
239 | |
240 cfg_blocks_head = ((cfg_blocks_head + 1) | |
241 % VEC_length (basic_block, cfg_blocks)); | |
242 --cfg_blocks_num; | |
243 RESET_BIT (bb_in_list, bb->index); | |
244 | |
245 return bb; | |
246 } | |
247 | |
248 | |
249 /* We have just defined a new value for VAR. If IS_VARYING is true, | |
250 add all immediate uses of VAR to VARYING_SSA_EDGES, otherwise add | |
251 them to INTERESTING_SSA_EDGES. */ | |
252 | |
253 static void | |
254 add_ssa_edge (tree var, bool is_varying) | |
255 { | |
256 imm_use_iterator iter; | |
257 use_operand_p use_p; | |
258 | |
259 FOR_EACH_IMM_USE_FAST (use_p, iter, var) | |
260 { | |
261 gimple use_stmt = USE_STMT (use_p); | |
262 | |
263 if (prop_simulate_again_p (use_stmt) | |
264 && !gimple_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST)) | |
265 { | |
266 gimple_set_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST, true); | |
267 if (is_varying) | |
268 VEC_safe_push (gimple, gc, varying_ssa_edges, use_stmt); | |
269 else | |
270 VEC_safe_push (gimple, gc, interesting_ssa_edges, use_stmt); | |
271 } | |
272 } | |
273 } | |
274 | |
275 | |
276 /* Add edge E to the control flow worklist. */ | |
277 | |
278 static void | |
279 add_control_edge (edge e) | |
280 { | |
281 basic_block bb = e->dest; | |
282 if (bb == EXIT_BLOCK_PTR) | |
283 return; | |
284 | |
285 /* If the edge had already been executed, skip it. */ | |
286 if (e->flags & EDGE_EXECUTABLE) | |
287 return; | |
288 | |
289 e->flags |= EDGE_EXECUTABLE; | |
290 | |
291 /* If the block is already in the list, we're done. */ | |
292 if (TEST_BIT (bb_in_list, bb->index)) | |
293 return; | |
294 | |
295 cfg_blocks_add (bb); | |
296 | |
297 if (dump_file && (dump_flags & TDF_DETAILS)) | |
298 fprintf (dump_file, "Adding Destination of edge (%d -> %d) to worklist\n\n", | |
299 e->src->index, e->dest->index); | |
300 } | |
301 | |
302 | |
303 /* Simulate the execution of STMT and update the work lists accordingly. */ | |
304 | |
305 static void | |
306 simulate_stmt (gimple stmt) | |
307 { | |
308 enum ssa_prop_result val = SSA_PROP_NOT_INTERESTING; | |
309 edge taken_edge = NULL; | |
310 tree output_name = NULL_TREE; | |
311 | |
312 /* Don't bother visiting statements that are already | |
313 considered varying by the propagator. */ | |
314 if (!prop_simulate_again_p (stmt)) | |
315 return; | |
316 | |
317 if (gimple_code (stmt) == GIMPLE_PHI) | |
318 { | |
319 val = ssa_prop_visit_phi (stmt); | |
320 output_name = gimple_phi_result (stmt); | |
321 } | |
322 else | |
323 val = ssa_prop_visit_stmt (stmt, &taken_edge, &output_name); | |
324 | |
325 if (val == SSA_PROP_VARYING) | |
326 { | |
327 prop_set_simulate_again (stmt, false); | |
328 | |
329 /* If the statement produced a new varying value, add the SSA | |
330 edges coming out of OUTPUT_NAME. */ | |
331 if (output_name) | |
332 add_ssa_edge (output_name, true); | |
333 | |
334 /* If STMT transfers control out of its basic block, add | |
335 all outgoing edges to the work list. */ | |
336 if (stmt_ends_bb_p (stmt)) | |
337 { | |
338 edge e; | |
339 edge_iterator ei; | |
340 basic_block bb = gimple_bb (stmt); | |
341 FOR_EACH_EDGE (e, ei, bb->succs) | |
342 add_control_edge (e); | |
343 } | |
344 } | |
345 else if (val == SSA_PROP_INTERESTING) | |
346 { | |
347 /* If the statement produced new value, add the SSA edges coming | |
348 out of OUTPUT_NAME. */ | |
349 if (output_name) | |
350 add_ssa_edge (output_name, false); | |
351 | |
352 /* If we know which edge is going to be taken out of this block, | |
353 add it to the CFG work list. */ | |
354 if (taken_edge) | |
355 add_control_edge (taken_edge); | |
356 } | |
357 } | |
358 | |
359 /* Process an SSA edge worklist. WORKLIST is the SSA edge worklist to | |
360 drain. This pops statements off the given WORKLIST and processes | |
361 them until there are no more statements on WORKLIST. | |
362 We take a pointer to WORKLIST because it may be reallocated when an | |
363 SSA edge is added to it in simulate_stmt. */ | |
364 | |
365 static void | |
366 process_ssa_edge_worklist (VEC(gimple,gc) **worklist) | |
367 { | |
368 /* Drain the entire worklist. */ | |
369 while (VEC_length (gimple, *worklist) > 0) | |
370 { | |
371 basic_block bb; | |
372 | |
373 /* Pull the statement to simulate off the worklist. */ | |
374 gimple stmt = VEC_pop (gimple, *worklist); | |
375 | |
376 /* If this statement was already visited by simulate_block, then | |
377 we don't need to visit it again here. */ | |
378 if (!gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST)) | |
379 continue; | |
380 | |
381 /* STMT is no longer in a worklist. */ | |
382 gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false); | |
383 | |
384 if (dump_file && (dump_flags & TDF_DETAILS)) | |
385 { | |
386 fprintf (dump_file, "\nSimulating statement (from ssa_edges): "); | |
387 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
388 } | |
389 | |
390 bb = gimple_bb (stmt); | |
391 | |
392 /* PHI nodes are always visited, regardless of whether or not | |
393 the destination block is executable. Otherwise, visit the | |
394 statement only if its block is marked executable. */ | |
395 if (gimple_code (stmt) == GIMPLE_PHI | |
396 || TEST_BIT (executable_blocks, bb->index)) | |
397 simulate_stmt (stmt); | |
398 } | |
399 } | |
400 | |
401 | |
402 /* Simulate the execution of BLOCK. Evaluate the statement associated | |
403 with each variable reference inside the block. */ | |
404 | |
405 static void | |
406 simulate_block (basic_block block) | |
407 { | |
408 gimple_stmt_iterator gsi; | |
409 | |
410 /* There is nothing to do for the exit block. */ | |
411 if (block == EXIT_BLOCK_PTR) | |
412 return; | |
413 | |
414 if (dump_file && (dump_flags & TDF_DETAILS)) | |
415 fprintf (dump_file, "\nSimulating block %d\n", block->index); | |
416 | |
417 /* Always simulate PHI nodes, even if we have simulated this block | |
418 before. */ | |
419 for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi)) | |
420 simulate_stmt (gsi_stmt (gsi)); | |
421 | |
422 /* If this is the first time we've simulated this block, then we | |
423 must simulate each of its statements. */ | |
424 if (!TEST_BIT (executable_blocks, block->index)) | |
425 { | |
426 gimple_stmt_iterator j; | |
427 unsigned int normal_edge_count; | |
428 edge e, normal_edge; | |
429 edge_iterator ei; | |
430 | |
431 /* Note that we have simulated this block. */ | |
432 SET_BIT (executable_blocks, block->index); | |
433 | |
434 for (j = gsi_start_bb (block); !gsi_end_p (j); gsi_next (&j)) | |
435 { | |
436 gimple stmt = gsi_stmt (j); | |
437 | |
438 /* If this statement is already in the worklist then | |
439 "cancel" it. The reevaluation implied by the worklist | |
440 entry will produce the same value we generate here and | |
441 thus reevaluating it again from the worklist is | |
442 pointless. */ | |
443 if (gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST)) | |
444 gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false); | |
445 | |
446 simulate_stmt (stmt); | |
447 } | |
448 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
449 /* We can not predict when abnormal and EH edges will be executed, so |
0 | 450 once a block is considered executable, we consider any |
451 outgoing abnormal edges as executable. | |
452 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
453 TODO: This is not exactly true. Simplifying statement might |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
454 prove it non-throwing and also computed goto can be handled |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
455 when destination is known. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
456 |
0 | 457 At the same time, if this block has only one successor that is |
458 reached by non-abnormal edges, then add that successor to the | |
459 worklist. */ | |
460 normal_edge_count = 0; | |
461 normal_edge = NULL; | |
462 FOR_EACH_EDGE (e, ei, block->succs) | |
463 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
464 if (e->flags & (EDGE_ABNORMAL | EDGE_EH)) |
0 | 465 add_control_edge (e); |
466 else | |
467 { | |
468 normal_edge_count++; | |
469 normal_edge = e; | |
470 } | |
471 } | |
472 | |
473 if (normal_edge_count == 1) | |
474 add_control_edge (normal_edge); | |
475 } | |
476 } | |
477 | |
478 | |
479 /* Initialize local data structures and work lists. */ | |
480 | |
481 static void | |
482 ssa_prop_init (void) | |
483 { | |
484 edge e; | |
485 edge_iterator ei; | |
486 basic_block bb; | |
487 | |
488 /* Worklists of SSA edges. */ | |
489 interesting_ssa_edges = VEC_alloc (gimple, gc, 20); | |
490 varying_ssa_edges = VEC_alloc (gimple, gc, 20); | |
491 | |
492 executable_blocks = sbitmap_alloc (last_basic_block); | |
493 sbitmap_zero (executable_blocks); | |
494 | |
495 bb_in_list = sbitmap_alloc (last_basic_block); | |
496 sbitmap_zero (bb_in_list); | |
497 | |
498 if (dump_file && (dump_flags & TDF_DETAILS)) | |
499 dump_immediate_uses (dump_file); | |
500 | |
501 cfg_blocks = VEC_alloc (basic_block, heap, 20); | |
502 VEC_safe_grow (basic_block, heap, cfg_blocks, 20); | |
503 | |
504 /* Initially assume that every edge in the CFG is not executable. | |
505 (including the edges coming out of ENTRY_BLOCK_PTR). */ | |
506 FOR_ALL_BB (bb) | |
507 { | |
508 gimple_stmt_iterator si; | |
509 | |
510 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) | |
511 gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 |
0 | 513 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) |
514 gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false); | |
515 | |
516 FOR_EACH_EDGE (e, ei, bb->succs) | |
517 e->flags &= ~EDGE_EXECUTABLE; | |
518 } | |
519 | |
520 /* Seed the algorithm by adding the successors of the entry block to the | |
521 edge worklist. */ | |
522 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) | |
523 add_control_edge (e); | |
524 } | |
525 | |
526 | |
527 /* Free allocated storage. */ | |
528 | |
529 static void | |
530 ssa_prop_fini (void) | |
531 { | |
532 VEC_free (gimple, gc, interesting_ssa_edges); | |
533 VEC_free (gimple, gc, varying_ssa_edges); | |
534 VEC_free (basic_block, heap, cfg_blocks); | |
535 cfg_blocks = NULL; | |
536 sbitmap_free (bb_in_list); | |
537 sbitmap_free (executable_blocks); | |
538 } | |
539 | |
540 | |
541 /* Return true if EXPR is an acceptable right-hand-side for a | |
542 GIMPLE assignment. We validate the entire tree, not just | |
543 the root node, thus catching expressions that embed complex | |
544 operands that are not permitted in GIMPLE. This function | |
545 is needed because the folding routines in fold-const.c | |
546 may return such expressions in some cases, e.g., an array | |
547 access with an embedded index addition. It may make more | |
548 sense to have folding routines that are sensitive to the | |
549 constraints on GIMPLE operands, rather than abandoning any | |
550 any attempt to fold if the usual folding turns out to be too | |
551 aggressive. */ | |
552 | |
553 bool | |
554 valid_gimple_rhs_p (tree expr) | |
555 { | |
556 enum tree_code code = TREE_CODE (expr); | |
557 | |
558 switch (TREE_CODE_CLASS (code)) | |
559 { | |
560 case tcc_declaration: | |
561 if (!is_gimple_variable (expr)) | |
562 return false; | |
563 break; | |
564 | |
565 case tcc_constant: | |
566 /* All constants are ok. */ | |
567 break; | |
568 | |
569 case tcc_binary: | |
570 case tcc_comparison: | |
571 if (!is_gimple_val (TREE_OPERAND (expr, 0)) | |
572 || !is_gimple_val (TREE_OPERAND (expr, 1))) | |
573 return false; | |
574 break; | |
575 | |
576 case tcc_unary: | |
577 if (!is_gimple_val (TREE_OPERAND (expr, 0))) | |
578 return false; | |
579 break; | |
580 | |
581 case tcc_expression: | |
582 switch (code) | |
583 { | |
584 case ADDR_EXPR: | |
585 { | |
586 tree t; | |
587 if (is_gimple_min_invariant (expr)) | |
588 return true; | |
589 t = TREE_OPERAND (expr, 0); | |
590 while (handled_component_p (t)) | |
591 { | |
592 /* ??? More checks needed, see the GIMPLE verifier. */ | |
593 if ((TREE_CODE (t) == ARRAY_REF | |
594 || TREE_CODE (t) == ARRAY_RANGE_REF) | |
595 && !is_gimple_val (TREE_OPERAND (t, 1))) | |
596 return false; | |
597 t = TREE_OPERAND (t, 0); | |
598 } | |
599 if (!is_gimple_id (t)) | |
600 return false; | |
601 } | |
602 break; | |
603 | |
604 case TRUTH_NOT_EXPR: | |
605 if (!is_gimple_val (TREE_OPERAND (expr, 0))) | |
606 return false; | |
607 break; | |
608 | |
609 case TRUTH_AND_EXPR: | |
610 case TRUTH_XOR_EXPR: | |
611 case TRUTH_OR_EXPR: | |
612 if (!is_gimple_val (TREE_OPERAND (expr, 0)) | |
613 || !is_gimple_val (TREE_OPERAND (expr, 1))) | |
614 return false; | |
615 break; | |
616 | |
617 default: | |
618 return false; | |
619 } | |
620 break; | |
621 | |
622 case tcc_vl_exp: | |
623 return false; | |
624 | |
625 case tcc_exceptional: | |
626 if (code != SSA_NAME) | |
627 return false; | |
628 break; | |
629 | |
630 default: | |
631 return false; | |
632 } | |
633 | |
634 return true; | |
635 } | |
636 | |
637 | |
638 /* Return true if EXPR is a CALL_EXPR suitable for representation | |
639 as a single GIMPLE_CALL statement. If the arguments require | |
640 further gimplification, return false. */ | |
641 | |
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
|
642 static bool |
0 | 643 valid_gimple_call_p (tree expr) |
644 { | |
645 unsigned i, nargs; | |
646 | |
647 if (TREE_CODE (expr) != CALL_EXPR) | |
648 return false; | |
649 | |
650 nargs = call_expr_nargs (expr); | |
651 for (i = 0; i < nargs; i++) | |
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
|
652 { |
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
|
653 tree arg = CALL_EXPR_ARG (expr, i); |
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
|
654 if (is_gimple_reg_type (arg)) |
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
|
655 { |
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
|
656 if (!is_gimple_val (arg)) |
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
|
657 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
658 } |
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
|
659 else |
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
|
660 if (!is_gimple_lvalue (arg)) |
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
|
661 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
662 } |
0 | 663 |
664 return true; | |
665 } | |
666 | |
667 | |
668 /* Make SSA names defined by OLD_STMT point to NEW_STMT | |
669 as their defining statement. */ | |
670 | |
671 void | |
672 move_ssa_defining_stmt_for_defs (gimple new_stmt, gimple old_stmt) | |
673 { | |
674 tree var; | |
675 ssa_op_iter iter; | |
676 | |
677 if (gimple_in_ssa_p (cfun)) | |
678 { | |
679 /* Make defined SSA_NAMEs point to the new | |
680 statement as their definition. */ | |
681 FOR_EACH_SSA_TREE_OPERAND (var, old_stmt, iter, SSA_OP_ALL_DEFS) | |
682 { | |
683 if (TREE_CODE (var) == SSA_NAME) | |
684 SSA_NAME_DEF_STMT (var) = new_stmt; | |
685 } | |
686 } | |
687 } | |
688 | |
689 | |
690 /* Update a GIMPLE_CALL statement at iterator *SI_P to reflect the | |
691 value of EXPR, which is expected to be the result of folding the | |
692 call. This can only be done if EXPR is a CALL_EXPR with valid | |
693 GIMPLE operands as arguments, or if it is a suitable RHS expression | |
694 for a GIMPLE_ASSIGN. More complex expressions will require | |
695 gimplification, which will introduce addtional statements. In this | |
696 event, no update is performed, and the function returns false. | |
697 Note that we cannot mutate a GIMPLE_CALL in-place, so we always | |
698 replace the statement at *SI_P with an entirely new statement. | |
699 The new statement need not be a call, e.g., if the original call | |
700 folded to a constant. */ | |
701 | |
702 bool | |
703 update_call_from_tree (gimple_stmt_iterator *si_p, tree expr) | |
704 { | |
705 tree lhs; | |
706 | |
707 gimple stmt = gsi_stmt (*si_p); | |
708 | |
709 gcc_assert (is_gimple_call (stmt)); | |
710 | |
711 lhs = gimple_call_lhs (stmt); | |
712 | |
713 if (valid_gimple_call_p (expr)) | |
714 { | |
715 /* The call has simplified to another call. */ | |
716 tree fn = CALL_EXPR_FN (expr); | |
717 unsigned i; | |
718 unsigned nargs = call_expr_nargs (expr); | |
719 VEC(tree, heap) *args = NULL; | |
720 gimple new_stmt; | |
721 | |
722 if (nargs > 0) | |
723 { | |
724 args = VEC_alloc (tree, heap, nargs); | |
725 VEC_safe_grow (tree, heap, args, nargs); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
726 |
0 | 727 for (i = 0; i < nargs; i++) |
728 VEC_replace (tree, args, i, CALL_EXPR_ARG (expr, i)); | |
729 } | |
730 | |
731 new_stmt = gimple_build_call_vec (fn, args); | |
732 gimple_call_set_lhs (new_stmt, lhs); | |
733 move_ssa_defining_stmt_for_defs (new_stmt, stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
734 gimple_set_vuse (new_stmt, 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
|
735 gimple_set_vdef (new_stmt, gimple_vdef (stmt)); |
0 | 736 gimple_set_location (new_stmt, gimple_location (stmt)); |
737 gsi_replace (si_p, new_stmt, false); | |
738 VEC_free (tree, heap, args); | |
739 | |
740 return true; | |
741 } | |
742 else if (valid_gimple_rhs_p (expr)) | |
743 { | |
744 gimple new_stmt; | |
745 | |
746 /* The call has simplified to an expression | |
747 that cannot be represented as a GIMPLE_CALL. */ | |
748 if (lhs) | |
749 { | |
750 /* A value is expected. | |
751 Introduce a new GIMPLE_ASSIGN statement. */ | |
752 STRIP_USELESS_TYPE_CONVERSION (expr); | |
753 new_stmt = gimple_build_assign (lhs, expr); | |
754 move_ssa_defining_stmt_for_defs (new_stmt, stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
755 gimple_set_vuse (new_stmt, 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
|
756 gimple_set_vdef (new_stmt, gimple_vdef (stmt)); |
0 | 757 } |
758 else if (!TREE_SIDE_EFFECTS (expr)) | |
759 { | |
760 /* No value is expected, and EXPR has no effect. | |
761 Replace it with an empty statement. */ | |
762 new_stmt = gimple_build_nop (); | |
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
|
763 if (gimple_in_ssa_p (cfun)) |
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
|
764 { |
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
|
765 unlink_stmt_vdef (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
|
766 release_defs (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
|
767 } |
0 | 768 } |
769 else | |
770 { | |
771 /* No value is expected, but EXPR has an effect, | |
772 e.g., it could be a reference to a volatile | |
773 variable. Create an assignment statement | |
774 with a dummy (unused) lhs variable. */ | |
775 STRIP_USELESS_TYPE_CONVERSION (expr); | |
776 lhs = create_tmp_var (TREE_TYPE (expr), NULL); | |
777 new_stmt = gimple_build_assign (lhs, expr); | |
778 add_referenced_var (lhs); | |
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
|
779 if (gimple_in_ssa_p (cfun)) |
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
|
780 lhs = make_ssa_name (lhs, new_stmt); |
0 | 781 gimple_assign_set_lhs (new_stmt, lhs); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
782 gimple_set_vuse (new_stmt, 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
|
783 gimple_set_vdef (new_stmt, gimple_vdef (stmt)); |
0 | 784 move_ssa_defining_stmt_for_defs (new_stmt, stmt); |
785 } | |
786 gimple_set_location (new_stmt, gimple_location (stmt)); | |
787 gsi_replace (si_p, new_stmt, false); | |
788 return true; | |
789 } | |
790 else | |
791 /* The call simplified to an expression that is | |
792 not a valid GIMPLE RHS. */ | |
793 return false; | |
794 } | |
795 | |
796 | |
797 /* Entry point to the propagation engine. | |
798 | |
799 VISIT_STMT is called for every statement visited. | |
800 VISIT_PHI is called for every PHI node visited. */ | |
801 | |
802 void | |
803 ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt, | |
804 ssa_prop_visit_phi_fn visit_phi) | |
805 { | |
806 ssa_prop_visit_stmt = visit_stmt; | |
807 ssa_prop_visit_phi = visit_phi; | |
808 | |
809 ssa_prop_init (); | |
810 | |
811 /* Iterate until the worklists are empty. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
812 while (!cfg_blocks_empty_p () |
0 | 813 || VEC_length (gimple, interesting_ssa_edges) > 0 |
814 || VEC_length (gimple, varying_ssa_edges) > 0) | |
815 { | |
816 if (!cfg_blocks_empty_p ()) | |
817 { | |
818 /* Pull the next block to simulate off the worklist. */ | |
819 basic_block dest_block = cfg_blocks_get (); | |
820 simulate_block (dest_block); | |
821 } | |
822 | |
823 /* In order to move things to varying as quickly as | |
824 possible,process the VARYING_SSA_EDGES worklist first. */ | |
825 process_ssa_edge_worklist (&varying_ssa_edges); | |
826 | |
827 /* Now process the INTERESTING_SSA_EDGES worklist. */ | |
828 process_ssa_edge_worklist (&interesting_ssa_edges); | |
829 } | |
830 | |
831 ssa_prop_fini (); | |
832 } | |
833 | |
834 | |
835 /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref' | |
836 is a non-volatile pointer dereference, a structure reference or a | |
837 reference to a single _DECL. Ignore volatile memory references | |
838 because they are not interesting for the optimizers. */ | |
839 | |
840 bool | |
841 stmt_makes_single_store (gimple stmt) | |
842 { | |
843 tree lhs; | |
844 | |
845 if (gimple_code (stmt) != GIMPLE_ASSIGN | |
846 && gimple_code (stmt) != GIMPLE_CALL) | |
847 return false; | |
848 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
849 if (!gimple_vdef (stmt)) |
0 | 850 return false; |
851 | |
852 lhs = gimple_get_lhs (stmt); | |
853 | |
854 /* A call statement may have a null LHS. */ | |
855 if (!lhs) | |
856 return false; | |
857 | |
858 return (!TREE_THIS_VOLATILE (lhs) | |
859 && (DECL_P (lhs) | |
860 || REFERENCE_CLASS_P (lhs))); | |
861 } | |
862 | |
863 | |
864 /* Propagation statistics. */ | |
865 struct prop_stats_d | |
866 { | |
867 long num_const_prop; | |
868 long num_copy_prop; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
869 long num_stmts_folded; |
0 | 870 long num_dce; |
871 }; | |
872 | |
873 static struct prop_stats_d prop_stats; | |
874 | |
875 /* Replace USE references in statement STMT with the values stored in | |
876 PROP_VALUE. Return true if at least one reference was replaced. */ | |
877 | |
878 static bool | |
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
|
879 replace_uses_in (gimple stmt, ssa_prop_get_value_fn get_value) |
0 | 880 { |
881 bool replaced = false; | |
882 use_operand_p use; | |
883 ssa_op_iter iter; | |
884 | |
885 FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE) | |
886 { | |
887 tree tuse = USE_FROM_PTR (use); | |
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
|
888 tree val = (*get_value) (tuse); |
0 | 889 |
890 if (val == tuse || val == NULL_TREE) | |
891 continue; | |
892 | |
893 if (gimple_code (stmt) == GIMPLE_ASM | |
894 && !may_propagate_copy_into_asm (tuse)) | |
895 continue; | |
896 | |
897 if (!may_propagate_copy (tuse, val)) | |
898 continue; | |
899 | |
900 if (TREE_CODE (val) != SSA_NAME) | |
901 prop_stats.num_const_prop++; | |
902 else | |
903 prop_stats.num_copy_prop++; | |
904 | |
905 propagate_value (use, val); | |
906 | |
907 replaced = true; | |
908 } | |
909 | |
910 return replaced; | |
911 } | |
912 | |
913 | |
914 /* Replace propagated values into all the arguments for PHI using the | |
915 values from PROP_VALUE. */ | |
916 | |
917 static void | |
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
|
918 replace_phi_args_in (gimple phi, ssa_prop_get_value_fn get_value) |
0 | 919 { |
920 size_t i; | |
921 bool replaced = false; | |
922 | |
923 if (dump_file && (dump_flags & TDF_DETAILS)) | |
924 { | |
925 fprintf (dump_file, "Folding PHI node: "); | |
926 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
927 } | |
928 | |
929 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
930 { | |
931 tree arg = gimple_phi_arg_def (phi, i); | |
932 | |
933 if (TREE_CODE (arg) == SSA_NAME) | |
934 { | |
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
|
935 tree val = (*get_value) (arg); |
0 | 936 |
937 if (val && val != arg && may_propagate_copy (arg, val)) | |
938 { | |
939 if (TREE_CODE (val) != SSA_NAME) | |
940 prop_stats.num_const_prop++; | |
941 else | |
942 prop_stats.num_copy_prop++; | |
943 | |
944 propagate_value (PHI_ARG_DEF_PTR (phi, i), val); | |
945 replaced = true; | |
946 | |
947 /* If we propagated a copy and this argument flows | |
948 through an abnormal edge, update the replacement | |
949 accordingly. */ | |
950 if (TREE_CODE (val) == SSA_NAME | |
951 && gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL) | |
952 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1; | |
953 } | |
954 } | |
955 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
956 |
0 | 957 if (dump_file && (dump_flags & TDF_DETAILS)) |
958 { | |
959 if (!replaced) | |
960 fprintf (dump_file, "No folding possible\n"); | |
961 else | |
962 { | |
963 fprintf (dump_file, "Folded into: "); | |
964 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
965 fprintf (dump_file, "\n"); | |
966 } | |
967 } | |
968 } | |
969 | |
970 | |
971 /* Perform final substitution and folding of propagated values. | |
972 | |
973 PROP_VALUE[I] contains the single value that should be substituted | |
974 at every use of SSA name N_I. If PROP_VALUE is NULL, no values are | |
975 substituted. | |
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 If FOLD_FN is non-NULL the function will be invoked on all statements |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
978 before propagating values for pass specific simplification. |
0 | 979 |
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
|
980 DO_DCE is true if trivially dead stmts can be removed. |
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
|
981 |
0 | 982 Return TRUE when something changed. */ |
983 | |
984 bool | |
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
|
985 substitute_and_fold (ssa_prop_get_value_fn get_value_fn, |
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
|
986 ssa_prop_fold_stmt_fn fold_fn, |
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
|
987 bool do_dce) |
0 | 988 { |
989 basic_block bb; | |
990 bool something_changed = false; | |
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
|
991 unsigned i; |
0 | 992 |
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
|
993 if (!get_value_fn && !fold_fn) |
0 | 994 return false; |
995 | |
996 if (dump_file && (dump_flags & TDF_DETAILS)) | |
997 fprintf (dump_file, "\nSubstituting values and folding statements\n\n"); | |
998 | |
999 memset (&prop_stats, 0, sizeof (prop_stats)); | |
1000 | |
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
|
1001 /* Substitute lattice values at definition sites. */ |
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
|
1002 if (get_value_fn) |
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
|
1003 for (i = 1; i < num_ssa_names; ++i) |
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
|
1004 { |
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
|
1005 tree name = ssa_name (i); |
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
|
1006 tree val; |
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
|
1007 gimple def_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
|
1008 gimple_stmt_iterator gsi; |
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
|
1009 |
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
|
1010 if (!name |
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
|
1011 || !is_gimple_reg (name)) |
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
|
1012 continue; |
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
|
1013 |
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
|
1014 def_stmt = SSA_NAME_DEF_STMT (name); |
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
|
1015 if (gimple_nop_p (def_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
|
1016 /* Do not substitute ASSERT_EXPR rhs, this will confuse VRP. */ |
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
|
1017 || (gimple_assign_single_p (def_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
|
1018 && gimple_assign_rhs_code (def_stmt) == ASSERT_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
|
1019 || !(val = (*get_value_fn) (name)) |
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
|
1020 || !may_propagate_copy (name, val)) |
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
|
1021 continue; |
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
|
1022 |
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
|
1023 gsi = gsi_for_stmt (def_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
|
1024 if (is_gimple_assign (def_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
|
1025 { |
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
|
1026 gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val), |
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
|
1027 val, NULL_TREE); |
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
|
1028 gcc_assert (gsi_stmt (gsi) == def_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
|
1029 if (maybe_clean_eh_stmt (def_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
|
1030 gimple_purge_dead_eh_edges (gimple_bb (def_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
|
1031 update_stmt (def_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
|
1032 } |
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
|
1033 else if (is_gimple_call (def_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
|
1034 { |
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
|
1035 if (update_call_from_tree (&gsi, val) |
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
|
1036 && maybe_clean_or_replace_eh_stmt (def_stmt, gsi_stmt (gsi))) |
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
|
1037 gimple_purge_dead_eh_edges (gimple_bb (gsi_stmt (gsi))); |
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
|
1038 } |
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
|
1039 else if (gimple_code (def_stmt) == GIMPLE_PHI) |
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
|
1040 { |
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
|
1041 gimple new_stmt = gimple_build_assign (name, val); |
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
|
1042 gimple_stmt_iterator gsi2; |
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
|
1043 SSA_NAME_DEF_STMT (name) = new_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
|
1044 gsi2 = gsi_after_labels (gimple_bb (def_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
|
1045 gsi_insert_before (&gsi2, new_stmt, GSI_SAME_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
|
1046 remove_phi_node (&gsi, false); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1047 } |
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
|
1048 |
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
|
1049 something_changed = 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
|
1050 } |
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
|
1051 |
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
|
1052 /* Propagate into all uses and fold. */ |
0 | 1053 FOR_EACH_BB (bb) |
1054 { | |
1055 gimple_stmt_iterator i; | |
1056 | |
1057 /* Propagate known values into PHI nodes. */ | |
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
|
1058 if (get_value_fn) |
0 | 1059 for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) |
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
|
1060 replace_phi_args_in (gsi_stmt (i), get_value_fn); |
0 | 1061 |
1062 /* Propagate known values into stmts. Do a backward walk to expose | |
1063 more trivially deletable stmts. */ | |
1064 for (i = gsi_last_bb (bb); !gsi_end_p (i);) | |
1065 { | |
1066 bool did_replace; | |
1067 gimple stmt = gsi_stmt (i); | |
1068 gimple old_stmt; | |
1069 enum gimple_code code = gimple_code (stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1070 gimple_stmt_iterator oldi; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1071 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1072 oldi = i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1073 gsi_prev (&i); |
0 | 1074 |
1075 /* Ignore ASSERT_EXPRs. They are used by VRP to generate | |
1076 range information for names and they are discarded | |
1077 afterwards. */ | |
1078 | |
1079 if (code == GIMPLE_ASSIGN | |
1080 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1081 continue; |
0 | 1082 |
1083 /* No point propagating into a stmt whose result is not used, | |
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
|
1084 but instead we might be able to remove a trivially dead 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
|
1085 Don't do this when called from VRP, since the SSA_NAME which |
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
|
1086 is going to be released could be still referenced in VRP |
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
|
1087 ranges. */ |
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
|
1088 if (do_dce |
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
|
1089 && gimple_get_lhs (stmt) |
0 | 1090 && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME |
1091 && has_zero_uses (gimple_get_lhs (stmt)) | |
1092 && !stmt_could_throw_p (stmt) | |
1093 && !gimple_has_side_effects (stmt)) | |
1094 { | |
1095 gimple_stmt_iterator i2; | |
1096 | |
1097 if (dump_file && dump_flags & TDF_DETAILS) | |
1098 { | |
1099 fprintf (dump_file, "Removing dead stmt "); | |
1100 print_gimple_stmt (dump_file, stmt, 0, 0); | |
1101 fprintf (dump_file, "\n"); | |
1102 } | |
1103 prop_stats.num_dce++; | |
1104 i2 = gsi_for_stmt (stmt); | |
1105 gsi_remove (&i2, true); | |
1106 release_defs (stmt); | |
1107 continue; | |
1108 } | |
1109 | |
1110 /* Replace the statement with its folded version and mark it | |
1111 folded. */ | |
1112 did_replace = false; | |
1113 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1114 { | |
1115 fprintf (dump_file, "Folding statement: "); | |
1116 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1117 } | |
1118 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1119 old_stmt = stmt; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1120 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1121 /* Some statements may be simplified using propagator |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1122 specific information. Do this before propagating |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1123 into the stmt to not disturb pass specific information. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1124 if (fold_fn |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1125 && (*fold_fn)(&oldi)) |
0 | 1126 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1127 did_replace = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1128 prop_stats.num_stmts_folded++; |
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
|
1129 stmt = gsi_stmt (oldi); |
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
|
1130 update_stmt (stmt); |
0 | 1131 } |
1132 | |
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
|
1133 /* Replace real uses in the 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
|
1134 if (get_value_fn) |
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
|
1135 did_replace |= replace_uses_in (stmt, get_value_fn); |
0 | 1136 |
1137 /* If we made a replacement, fold the statement. */ | |
1138 if (did_replace) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1139 fold_stmt (&oldi); |
0 | 1140 |
1141 /* Now cleanup. */ | |
1142 if (did_replace) | |
1143 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1144 stmt = gsi_stmt (oldi); |
0 | 1145 |
1146 /* If we cleaned up EH information from the statement, | |
1147 remove EH edges. */ | |
1148 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) | |
1149 gimple_purge_dead_eh_edges (bb); | |
1150 | |
1151 if (is_gimple_assign (stmt) | |
1152 && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) | |
1153 == GIMPLE_SINGLE_RHS)) | |
1154 { | |
1155 tree rhs = gimple_assign_rhs1 (stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1156 |
0 | 1157 if (TREE_CODE (rhs) == ADDR_EXPR) |
1158 recompute_tree_invariant_for_addr_expr (rhs); | |
1159 } | |
1160 | |
1161 /* Determine what needs to be done to update the SSA form. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1162 update_stmt (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1163 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
|
1164 something_changed = true; |
0 | 1165 } |
1166 | |
1167 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1168 { | |
1169 if (did_replace) | |
1170 { | |
1171 fprintf (dump_file, "Folded into: "); | |
1172 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1173 fprintf (dump_file, "\n"); | |
1174 } | |
1175 else | |
1176 fprintf (dump_file, "Not folded\n"); | |
1177 } | |
1178 } | |
1179 } | |
1180 | |
1181 statistics_counter_event (cfun, "Constants propagated", | |
1182 prop_stats.num_const_prop); | |
1183 statistics_counter_event (cfun, "Copies propagated", | |
1184 prop_stats.num_copy_prop); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1185 statistics_counter_event (cfun, "Statements folded", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1186 prop_stats.num_stmts_folded); |
0 | 1187 statistics_counter_event (cfun, "Statements deleted", |
1188 prop_stats.num_dce); | |
1189 return something_changed; | |
1190 } | |
1191 | |
1192 #include "gt-tree-ssa-propagate.h" |