Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-dom.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* SSA Dominator optimizations for trees |
145 | 2 Copyright (C) 2001-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Diego Novillo <dnovillo@redhat.com> |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 3, or (at your option) | |
10 any later version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
111 | 24 #include "backend.h" |
0 | 25 #include "tree.h" |
111 | 26 #include "gimple.h" |
27 #include "tree-pass.h" | |
28 #include "ssa.h" | |
29 #include "gimple-pretty-print.h" | |
30 #include "fold-const.h" | |
31 #include "cfganal.h" | |
0 | 32 #include "cfgloop.h" |
111 | 33 #include "gimple-fold.h" |
34 #include "tree-eh.h" | |
35 #include "tree-inline.h" | |
36 #include "gimple-iterator.h" | |
37 #include "tree-cfg.h" | |
38 #include "tree-into-ssa.h" | |
0 | 39 #include "domwalk.h" |
40 #include "tree-ssa-propagate.h" | |
111 | 41 #include "tree-ssa-threadupdate.h" |
42 #include "tree-ssa-scopedtables.h" | |
43 #include "tree-ssa-threadedge.h" | |
44 #include "tree-ssa-dom.h" | |
45 #include "gimplify.h" | |
46 #include "tree-cfgcleanup.h" | |
47 #include "dbgcnt.h" | |
131 | 48 #include "alloc-pool.h" |
49 #include "tree-vrp.h" | |
50 #include "vr-values.h" | |
51 #include "gimple-ssa-evrp-analyze.h" | |
0 | 52 |
53 /* This file implements optimizations on the dominator tree. */ | |
54 | |
111 | 55 /* Structure for recording edge equivalences. |
0 | 56 |
57 Computing and storing the edge equivalences instead of creating | |
58 them on-demand can save significant amounts of time, particularly | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
59 for pathological cases involving switch statements. |
0 | 60 |
61 These structures live for a single iteration of the dominator | |
62 optimizer in the edge's AUX field. At the end of an iteration we | |
111 | 63 free each of these structures. */ |
64 class edge_info | |
65 { | |
66 public: | |
67 typedef std::pair <tree, tree> equiv_pair; | |
68 edge_info (edge); | |
69 ~edge_info (); | |
0 | 70 |
111 | 71 /* Record a simple LHS = RHS equivalence. This may trigger |
72 calls to derive_equivalences. */ | |
73 void record_simple_equiv (tree, tree); | |
74 | |
75 /* If traversing this edge creates simple equivalences, we store | |
76 them as LHS/RHS pairs within this vector. */ | |
77 vec<equiv_pair> simple_equivalences; | |
0 | 78 |
79 /* Traversing an edge may also indicate one or more particular conditions | |
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
|
80 are true or false. */ |
111 | 81 vec<cond_equivalence> cond_equivalences; |
0 | 82 |
111 | 83 private: |
84 /* Derive equivalences by walking the use-def chains. */ | |
85 void derive_equivalences (tree, tree, int); | |
0 | 86 }; |
87 | |
88 /* Track whether or not we have changed the control flow graph. */ | |
89 static bool cfg_altered; | |
90 | |
91 /* Bitmap of blocks that have had EH statements cleaned. We should | |
92 remove their dead edges eventually. */ | |
93 static bitmap need_eh_cleanup; | |
111 | 94 static vec<gimple *> need_noreturn_fixup; |
0 | 95 |
96 /* Statistics for dominator optimizations. */ | |
97 struct opt_stats_d | |
98 { | |
99 long num_stmts; | |
100 long num_exprs_considered; | |
101 long num_re; | |
102 long num_const_prop; | |
103 long num_copy_prop; | |
104 }; | |
105 | |
106 static struct opt_stats_d opt_stats; | |
107 | |
108 /* Local functions. */ | |
111 | 109 static void record_equality (tree, tree, class const_and_copies *); |
0 | 110 static void record_equivalences_from_phis (basic_block); |
111 | 111 static void record_equivalences_from_incoming_edge (basic_block, |
112 class const_and_copies *, | |
113 class avail_exprs_stack *); | |
114 static void eliminate_redundant_computations (gimple_stmt_iterator *, | |
115 class const_and_copies *, | |
116 class avail_exprs_stack *); | |
117 static void record_equivalences_from_stmt (gimple *, int, | |
118 class avail_exprs_stack *); | |
119 static void dump_dominator_optimization_stats (FILE *file, | |
120 hash_table<expr_elt_hasher> *); | |
0 | 121 |
111 | 122 /* Constructor for EDGE_INFO. An EDGE_INFO instance is always |
123 associated with an edge E. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
124 |
111 | 125 edge_info::edge_info (edge e) |
126 { | |
127 /* Free the old one associated with E, if it exists and | |
128 associate our new object with E. */ | |
129 free_dom_edge_info (e); | |
130 e->aux = this; | |
0 | 131 |
111 | 132 /* And initialize the embedded vectors. */ |
133 simple_equivalences = vNULL; | |
134 cond_equivalences = vNULL; | |
135 } | |
0 | 136 |
111 | 137 /* Destructor just needs to release the vectors. */ |
0 | 138 |
111 | 139 edge_info::~edge_info (void) |
140 { | |
141 this->cond_equivalences.release (); | |
142 this->simple_equivalences.release (); | |
0 | 143 } |
144 | |
111 | 145 /* NAME is known to have the value VALUE, which must be a constant. |
0 | 146 |
111 | 147 Walk through its use-def chain to see if there are other equivalences |
148 we might be able to derive. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
149 |
111 | 150 RECURSION_LIMIT controls how far back we recurse through the use-def |
151 chains. */ | |
0 | 152 |
111 | 153 void |
154 edge_info::derive_equivalences (tree name, tree value, int recursion_limit) | |
0 | 155 { |
111 | 156 if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST) |
157 return; | |
0 | 158 |
111 | 159 /* This records the equivalence for the toplevel object. Do |
160 this before checking the recursion limit. */ | |
161 simple_equivalences.safe_push (equiv_pair (name, value)); | |
0 | 162 |
111 | 163 /* Limit how far up the use-def chains we are willing to walk. */ |
164 if (recursion_limit == 0) | |
165 return; | |
0 | 166 |
111 | 167 /* We can walk up the use-def chains to potentially find more |
168 equivalences. */ | |
169 gimple *def_stmt = SSA_NAME_DEF_STMT (name); | |
170 if (is_gimple_assign (def_stmt)) | |
0 | 171 { |
111 | 172 enum tree_code code = gimple_assign_rhs_code (def_stmt); |
173 switch (code) | |
174 { | |
145 | 175 /* If the result of an OR is zero, then its operands are, too. */ |
111 | 176 case BIT_IOR_EXPR: |
177 if (integer_zerop (value)) | |
178 { | |
179 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
180 tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
0 | 181 |
111 | 182 value = build_zero_cst (TREE_TYPE (rhs1)); |
183 derive_equivalences (rhs1, value, recursion_limit - 1); | |
184 value = build_zero_cst (TREE_TYPE (rhs2)); | |
185 derive_equivalences (rhs2, value, recursion_limit - 1); | |
186 } | |
187 break; | |
0 | 188 |
145 | 189 /* If the result of an AND is nonzero, then its operands are, too. */ |
111 | 190 case BIT_AND_EXPR: |
191 if (!integer_zerop (value)) | |
192 { | |
193 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
194 tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
0 | 195 |
111 | 196 /* If either operand has a boolean range, then we |
197 know its value must be one, otherwise we just know it | |
198 is nonzero. The former is clearly useful, I haven't | |
199 seen cases where the latter is helpful yet. */ | |
200 if (TREE_CODE (rhs1) == SSA_NAME) | |
201 { | |
202 if (ssa_name_has_boolean_range (rhs1)) | |
203 { | |
204 value = build_one_cst (TREE_TYPE (rhs1)); | |
205 derive_equivalences (rhs1, value, recursion_limit - 1); | |
206 } | |
207 } | |
208 if (TREE_CODE (rhs2) == SSA_NAME) | |
209 { | |
210 if (ssa_name_has_boolean_range (rhs2)) | |
211 { | |
212 value = build_one_cst (TREE_TYPE (rhs2)); | |
213 derive_equivalences (rhs2, value, recursion_limit - 1); | |
214 } | |
215 } | |
216 } | |
217 break; | |
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
|
218 |
111 | 219 /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was |
220 set via a widening type conversion, then we may be able to record | |
221 additional equivalences. */ | |
222 case NOP_EXPR: | |
223 case CONVERT_EXPR: | |
224 { | |
225 tree rhs = gimple_assign_rhs1 (def_stmt); | |
226 tree rhs_type = TREE_TYPE (rhs); | |
227 if (INTEGRAL_TYPE_P (rhs_type) | |
228 && (TYPE_PRECISION (TREE_TYPE (name)) | |
229 >= TYPE_PRECISION (rhs_type)) | |
230 && int_fits_type_p (value, rhs_type)) | |
231 derive_equivalences (rhs, | |
232 fold_convert (rhs_type, value), | |
233 recursion_limit - 1); | |
234 break; | |
235 } | |
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
|
236 |
111 | 237 /* We can invert the operation of these codes trivially if |
238 one of the RHS operands is a constant to produce a known | |
239 value for the other RHS operand. */ | |
240 case POINTER_PLUS_EXPR: | |
241 case PLUS_EXPR: | |
242 { | |
243 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
244 tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
245 | |
246 /* If either argument is a constant, then we can compute | |
247 a constant value for the nonconstant argument. */ | |
248 if (TREE_CODE (rhs1) == INTEGER_CST | |
249 && TREE_CODE (rhs2) == SSA_NAME) | |
250 derive_equivalences (rhs2, | |
251 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), | |
252 value, rhs1), | |
253 recursion_limit - 1); | |
254 else if (TREE_CODE (rhs2) == INTEGER_CST | |
255 && TREE_CODE (rhs1) == SSA_NAME) | |
256 derive_equivalences (rhs1, | |
257 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), | |
258 value, rhs2), | |
259 recursion_limit - 1); | |
260 break; | |
261 } | |
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
|
262 |
111 | 263 /* If one of the operands is a constant, then we can compute |
264 the value of the other operand. If both operands are | |
265 SSA_NAMEs, then they must be equal if the result is zero. */ | |
266 case MINUS_EXPR: | |
267 { | |
268 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
269 tree rhs2 = gimple_assign_rhs2 (def_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
|
270 |
111 | 271 /* If either argument is a constant, then we can compute |
272 a constant value for the nonconstant argument. */ | |
273 if (TREE_CODE (rhs1) == INTEGER_CST | |
274 && TREE_CODE (rhs2) == SSA_NAME) | |
275 derive_equivalences (rhs2, | |
276 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), | |
277 rhs1, value), | |
278 recursion_limit - 1); | |
279 else if (TREE_CODE (rhs2) == INTEGER_CST | |
280 && TREE_CODE (rhs1) == SSA_NAME) | |
281 derive_equivalences (rhs1, | |
282 fold_binary (PLUS_EXPR, TREE_TYPE (rhs1), | |
283 value, rhs2), | |
284 recursion_limit - 1); | |
285 else if (integer_zerop (value)) | |
286 { | |
287 tree cond = build2 (EQ_EXPR, boolean_type_node, | |
288 gimple_assign_rhs1 (def_stmt), | |
289 gimple_assign_rhs2 (def_stmt)); | |
290 tree inverted = invert_truthvalue (cond); | |
291 record_conditions (&this->cond_equivalences, cond, inverted); | |
292 } | |
293 break; | |
294 } | |
0 | 295 |
111 | 296 case EQ_EXPR: |
297 case NE_EXPR: | |
298 { | |
299 if ((code == EQ_EXPR && integer_onep (value)) | |
300 || (code == NE_EXPR && integer_zerop (value))) | |
301 { | |
302 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
303 tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
304 | |
305 /* If either argument is a constant, then record the | |
306 other argument as being the same as that constant. | |
0 | 307 |
111 | 308 If neither operand is a constant, then we have a |
309 conditional name == name equivalence. */ | |
310 if (TREE_CODE (rhs1) == INTEGER_CST) | |
311 derive_equivalences (rhs2, rhs1, recursion_limit - 1); | |
312 else if (TREE_CODE (rhs2) == INTEGER_CST) | |
313 derive_equivalences (rhs1, rhs2, recursion_limit - 1); | |
314 } | |
315 else | |
316 { | |
317 tree cond = build2 (code, boolean_type_node, | |
318 gimple_assign_rhs1 (def_stmt), | |
319 gimple_assign_rhs2 (def_stmt)); | |
320 tree inverted = invert_truthvalue (cond); | |
321 if (integer_zerop (value)) | |
322 std::swap (cond, inverted); | |
323 record_conditions (&this->cond_equivalences, cond, inverted); | |
324 } | |
325 break; | |
326 } | |
0 | 327 |
111 | 328 /* For BIT_NOT and NEGATE, we can just apply the operation to the |
329 VALUE to get the new equivalence. It will always be a constant | |
330 so we can recurse. */ | |
331 case BIT_NOT_EXPR: | |
332 case NEGATE_EXPR: | |
333 { | |
334 tree rhs = gimple_assign_rhs1 (def_stmt); | |
145 | 335 tree res; |
336 /* If this is a NOT and the operand has a boolean range, then we | |
337 know its value must be zero or one. We are not supposed to | |
338 have a BIT_NOT_EXPR for boolean types with precision > 1 in | |
339 the general case, see e.g. the handling of TRUTH_NOT_EXPR in | |
340 the gimplifier, but it can be generated by match.pd out of | |
341 a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR. Now the handling | |
342 of BIT_AND_EXPR above already forces a specific semantics for | |
343 boolean types with precision > 1 so we must do the same here, | |
344 otherwise we could change the semantics of TRUTH_NOT_EXPR for | |
345 boolean types with precision > 1. */ | |
346 if (code == BIT_NOT_EXPR | |
347 && TREE_CODE (rhs) == SSA_NAME | |
348 && ssa_name_has_boolean_range (rhs)) | |
349 { | |
350 if ((TREE_INT_CST_LOW (value) & 1) == 0) | |
351 res = build_one_cst (TREE_TYPE (rhs)); | |
352 else | |
353 res = build_zero_cst (TREE_TYPE (rhs)); | |
354 } | |
355 else | |
356 res = fold_build1 (code, TREE_TYPE (rhs), value); | |
111 | 357 derive_equivalences (rhs, res, recursion_limit - 1); |
358 break; | |
359 } | |
0 | 360 |
111 | 361 default: |
362 { | |
363 if (TREE_CODE_CLASS (code) == tcc_comparison) | |
364 { | |
365 tree cond = build2 (code, boolean_type_node, | |
366 gimple_assign_rhs1 (def_stmt), | |
367 gimple_assign_rhs2 (def_stmt)); | |
368 tree inverted = invert_truthvalue (cond); | |
369 if (integer_zerop (value)) | |
370 std::swap (cond, inverted); | |
371 record_conditions (&this->cond_equivalences, cond, inverted); | |
372 break; | |
373 } | |
374 break; | |
375 } | |
376 } | |
0 | 377 } |
378 } | |
379 | |
111 | 380 void |
381 edge_info::record_simple_equiv (tree lhs, tree rhs) | |
0 | 382 { |
111 | 383 /* If the RHS is a constant, then we may be able to derive |
384 further equivalences. Else just record the name = name | |
385 equivalence. */ | |
386 if (TREE_CODE (rhs) == INTEGER_CST) | |
387 derive_equivalences (lhs, rhs, 4); | |
388 else | |
389 simple_equivalences.safe_push (equiv_pair (lhs, rhs)); | |
0 | 390 } |
391 | |
111 | 392 /* Free the edge_info data attached to E, if it exists. */ |
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
|
393 |
111 | 394 void |
395 free_dom_edge_info (edge e) | |
396 { | |
145 | 397 class edge_info *edge_info = (class edge_info *)e->aux; |
0 | 398 |
111 | 399 if (edge_info) |
400 delete edge_info; | |
0 | 401 } |
402 | |
403 /* Free all EDGE_INFO structures associated with edges in the CFG. | |
404 If a particular edge can be threaded, copy the redirection | |
405 target from the EDGE_INFO structure into the edge's AUX field | |
406 as required by code to update the CFG and SSA graph for | |
407 jump threading. */ | |
408 | |
409 static void | |
410 free_all_edge_infos (void) | |
411 { | |
412 basic_block bb; | |
413 edge_iterator ei; | |
414 edge e; | |
415 | |
111 | 416 FOR_EACH_BB_FN (bb, cfun) |
0 | 417 { |
418 FOR_EACH_EDGE (e, ei, bb->preds) | |
419 { | |
111 | 420 free_dom_edge_info (e); |
421 e->aux = NULL; | |
0 | 422 } |
423 } | |
424 } | |
425 | |
111 | 426 /* We have finished optimizing BB, record any information implied by |
427 taking a specific outgoing edge from BB. */ | |
428 | |
429 static void | |
430 record_edge_info (basic_block bb) | |
431 { | |
432 gimple_stmt_iterator gsi = gsi_last_bb (bb); | |
433 class edge_info *edge_info; | |
434 | |
435 if (! gsi_end_p (gsi)) | |
436 { | |
437 gimple *stmt = gsi_stmt (gsi); | |
438 location_t loc = gimple_location (stmt); | |
439 | |
440 if (gimple_code (stmt) == GIMPLE_SWITCH) | |
441 { | |
442 gswitch *switch_stmt = as_a <gswitch *> (stmt); | |
443 tree index = gimple_switch_index (switch_stmt); | |
444 | |
445 if (TREE_CODE (index) == SSA_NAME) | |
446 { | |
447 int i; | |
448 int n_labels = gimple_switch_num_labels (switch_stmt); | |
449 tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun)); | |
450 edge e; | |
451 edge_iterator ei; | |
452 | |
453 for (i = 0; i < n_labels; i++) | |
454 { | |
455 tree label = gimple_switch_label (switch_stmt, i); | |
131 | 456 basic_block target_bb |
457 = label_to_block (cfun, CASE_LABEL (label)); | |
111 | 458 if (CASE_HIGH (label) |
459 || !CASE_LOW (label) | |
460 || info[target_bb->index]) | |
461 info[target_bb->index] = error_mark_node; | |
462 else | |
463 info[target_bb->index] = label; | |
464 } | |
465 | |
466 FOR_EACH_EDGE (e, ei, bb->succs) | |
467 { | |
468 basic_block target_bb = e->dest; | |
469 tree label = info[target_bb->index]; | |
470 | |
471 if (label != NULL && label != error_mark_node) | |
472 { | |
473 tree x = fold_convert_loc (loc, TREE_TYPE (index), | |
474 CASE_LOW (label)); | |
475 edge_info = new class edge_info (e); | |
476 edge_info->record_simple_equiv (index, x); | |
477 } | |
478 } | |
479 free (info); | |
480 } | |
481 } | |
482 | |
483 /* A COND_EXPR may create equivalences too. */ | |
484 if (gimple_code (stmt) == GIMPLE_COND) | |
485 { | |
486 edge true_edge; | |
487 edge false_edge; | |
488 | |
489 tree op0 = gimple_cond_lhs (stmt); | |
490 tree op1 = gimple_cond_rhs (stmt); | |
491 enum tree_code code = gimple_cond_code (stmt); | |
492 | |
493 extract_true_false_edges_from_block (bb, &true_edge, &false_edge); | |
494 | |
495 /* Special case comparing booleans against a constant as we | |
496 know the value of OP0 on both arms of the branch. i.e., we | |
497 can record an equivalence for OP0 rather than COND. | |
498 | |
499 However, don't do this if the constant isn't zero or one. | |
500 Such conditionals will get optimized more thoroughly during | |
501 the domwalk. */ | |
502 if ((code == EQ_EXPR || code == NE_EXPR) | |
503 && TREE_CODE (op0) == SSA_NAME | |
504 && ssa_name_has_boolean_range (op0) | |
505 && is_gimple_min_invariant (op1) | |
506 && (integer_zerop (op1) || integer_onep (op1))) | |
507 { | |
508 tree true_val = constant_boolean_node (true, TREE_TYPE (op0)); | |
509 tree false_val = constant_boolean_node (false, TREE_TYPE (op0)); | |
510 | |
511 if (code == EQ_EXPR) | |
512 { | |
513 edge_info = new class edge_info (true_edge); | |
514 edge_info->record_simple_equiv (op0, | |
515 (integer_zerop (op1) | |
516 ? false_val : true_val)); | |
517 edge_info = new class edge_info (false_edge); | |
518 edge_info->record_simple_equiv (op0, | |
519 (integer_zerop (op1) | |
520 ? true_val : false_val)); | |
521 } | |
522 else | |
523 { | |
524 edge_info = new class edge_info (true_edge); | |
525 edge_info->record_simple_equiv (op0, | |
526 (integer_zerop (op1) | |
527 ? true_val : false_val)); | |
528 edge_info = new class edge_info (false_edge); | |
529 edge_info->record_simple_equiv (op0, | |
530 (integer_zerop (op1) | |
531 ? false_val : true_val)); | |
532 } | |
533 } | |
534 /* This can show up in the IL as a result of copy propagation | |
535 it will eventually be canonicalized, but we have to cope | |
536 with this case within the pass. */ | |
537 else if (is_gimple_min_invariant (op0) | |
538 && TREE_CODE (op1) == SSA_NAME) | |
539 { | |
540 tree cond = build2 (code, boolean_type_node, op0, op1); | |
541 tree inverted = invert_truthvalue_loc (loc, cond); | |
542 bool can_infer_simple_equiv | |
543 = !(HONOR_SIGNED_ZEROS (op0) | |
544 && real_zerop (op0)); | |
145 | 545 class edge_info *edge_info; |
111 | 546 |
547 edge_info = new class edge_info (true_edge); | |
548 record_conditions (&edge_info->cond_equivalences, cond, inverted); | |
549 | |
550 if (can_infer_simple_equiv && code == EQ_EXPR) | |
551 edge_info->record_simple_equiv (op1, op0); | |
552 | |
553 edge_info = new class edge_info (false_edge); | |
554 record_conditions (&edge_info->cond_equivalences, inverted, cond); | |
555 | |
556 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR) | |
557 edge_info->record_simple_equiv (op1, op0); | |
558 } | |
559 | |
560 else if (TREE_CODE (op0) == SSA_NAME | |
561 && (TREE_CODE (op1) == SSA_NAME | |
562 || is_gimple_min_invariant (op1))) | |
563 { | |
564 tree cond = build2 (code, boolean_type_node, op0, op1); | |
565 tree inverted = invert_truthvalue_loc (loc, cond); | |
566 bool can_infer_simple_equiv | |
567 = !(HONOR_SIGNED_ZEROS (op1) | |
568 && (TREE_CODE (op1) == SSA_NAME || real_zerop (op1))); | |
145 | 569 class edge_info *edge_info; |
111 | 570 |
571 edge_info = new class edge_info (true_edge); | |
572 record_conditions (&edge_info->cond_equivalences, cond, inverted); | |
573 | |
574 if (can_infer_simple_equiv && code == EQ_EXPR) | |
575 edge_info->record_simple_equiv (op0, op1); | |
576 | |
577 edge_info = new class edge_info (false_edge); | |
578 record_conditions (&edge_info->cond_equivalences, inverted, cond); | |
579 | |
580 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR) | |
581 edge_info->record_simple_equiv (op0, op1); | |
582 } | |
583 } | |
584 } | |
585 } | |
586 | |
587 | |
588 class dom_opt_dom_walker : public dom_walker | |
589 { | |
590 public: | |
591 dom_opt_dom_walker (cdi_direction direction, | |
592 class const_and_copies *const_and_copies, | |
593 class avail_exprs_stack *avail_exprs_stack, | |
594 gcond *dummy_cond) | |
131 | 595 : dom_walker (direction, REACHABLE_BLOCKS), |
111 | 596 m_const_and_copies (const_and_copies), |
597 m_avail_exprs_stack (avail_exprs_stack), | |
145 | 598 evrp_range_analyzer (true), |
111 | 599 m_dummy_cond (dummy_cond) { } |
600 | |
601 virtual edge before_dom_children (basic_block); | |
602 virtual void after_dom_children (basic_block); | |
603 | |
604 private: | |
605 | |
606 /* Unwindable equivalences, both const/copy and expression varieties. */ | |
607 class const_and_copies *m_const_and_copies; | |
608 class avail_exprs_stack *m_avail_exprs_stack; | |
609 | |
131 | 610 /* VRP data. */ |
611 class evrp_range_analyzer evrp_range_analyzer; | |
612 | |
111 | 613 /* Dummy condition to avoid creating lots of throw away statements. */ |
614 gcond *m_dummy_cond; | |
615 | |
616 /* Optimize a single statement within a basic block using the | |
617 various tables mantained by DOM. Returns the taken edge if | |
618 the statement is a conditional with a statically determined | |
619 value. */ | |
145 | 620 edge optimize_stmt (basic_block, gimple_stmt_iterator *, bool *); |
111 | 621 }; |
622 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
623 /* Jump threading, redundancy elimination and const/copy propagation. |
0 | 624 |
625 This pass may expose new symbols that need to be renamed into SSA. For | |
626 every new symbol exposed, its corresponding bit will be set in | |
627 VARS_TO_RENAME. */ | |
628 | |
111 | 629 namespace { |
630 | |
631 const pass_data pass_data_dominator = | |
632 { | |
633 GIMPLE_PASS, /* type */ | |
634 "dom", /* name */ | |
635 OPTGROUP_NONE, /* optinfo_flags */ | |
636 TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ | |
637 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
638 0, /* properties_provided */ | |
639 0, /* properties_destroyed */ | |
640 0, /* todo_flags_start */ | |
641 ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */ | |
642 }; | |
643 | |
644 class pass_dominator : public gimple_opt_pass | |
0 | 645 { |
111 | 646 public: |
647 pass_dominator (gcc::context *ctxt) | |
648 : gimple_opt_pass (pass_data_dominator, ctxt), | |
649 may_peel_loop_headers_p (false) | |
650 {} | |
0 | 651 |
111 | 652 /* opt_pass methods: */ |
653 opt_pass * clone () { return new pass_dominator (m_ctxt); } | |
654 void set_pass_param (unsigned int n, bool param) | |
655 { | |
656 gcc_assert (n == 0); | |
657 may_peel_loop_headers_p = param; | |
658 } | |
659 virtual bool gate (function *) { return flag_tree_dom != 0; } | |
660 virtual unsigned int execute (function *); | |
661 | |
662 private: | |
663 /* This flag is used to prevent loops from being peeled repeatedly in jump | |
664 threading; it will be removed once we preserve loop structures throughout | |
665 the compilation -- we will be able to mark the affected loops directly in | |
666 jump threading, and avoid peeling them next time. */ | |
667 bool may_peel_loop_headers_p; | |
668 }; // class pass_dominator | |
669 | |
670 unsigned int | |
671 pass_dominator::execute (function *fun) | |
672 { | |
0 | 673 memset (&opt_stats, 0, sizeof (opt_stats)); |
674 | |
675 /* Create our hash tables. */ | |
111 | 676 hash_table<expr_elt_hasher> *avail_exprs |
677 = new hash_table<expr_elt_hasher> (1024); | |
678 class avail_exprs_stack *avail_exprs_stack | |
679 = new class avail_exprs_stack (avail_exprs); | |
680 class const_and_copies *const_and_copies = new class const_and_copies (); | |
0 | 681 need_eh_cleanup = BITMAP_ALLOC (NULL); |
111 | 682 need_noreturn_fixup.create (0); |
0 | 683 |
684 calculate_dominance_info (CDI_DOMINATORS); | |
685 cfg_altered = false; | |
686 | |
687 /* We need to know loop structures in order to avoid destroying them | |
688 in jump threading. Note that we still can e.g. thread through loop | |
689 headers to an exit edge, or through loop header to the loop body, assuming | |
111 | 690 that we update the loop info. |
691 | |
692 TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due | |
693 to several overly conservative bail-outs in jump threading, case | |
694 gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is | |
695 missing. We should improve jump threading in future then | |
696 LOOPS_HAVE_PREHEADERS won't be needed here. */ | |
697 loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES); | |
0 | 698 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
699 /* Initialize the value-handle array. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
700 threadedge_initialize_values (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
701 |
0 | 702 /* We need accurate information regarding back edges in the CFG |
703 for jump threading; this may include back edges that are not part of | |
704 a single loop. */ | |
705 mark_dfs_back_edges (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
706 |
111 | 707 /* We want to create the edge info structures before the dominator walk |
708 so that they'll be in place for the jump threader, particularly when | |
709 threading through a join block. | |
710 | |
711 The conditions will be lazily updated with global equivalences as | |
712 we reach them during the dominator walk. */ | |
713 basic_block bb; | |
714 FOR_EACH_BB_FN (bb, fun) | |
715 record_edge_info (bb); | |
716 | |
717 gcond *dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node, | |
718 integer_zero_node, NULL, NULL); | |
719 | |
0 | 720 /* Recursively walk the dominator tree optimizing statements. */ |
111 | 721 dom_opt_dom_walker walker (CDI_DOMINATORS, const_and_copies, |
722 avail_exprs_stack, dummy_cond); | |
723 walker.walk (fun->cfg->x_entry_block_ptr); | |
724 | |
725 /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing | |
726 edge. When found, remove jump threads which contain any outgoing | |
727 edge from the affected block. */ | |
728 if (cfg_altered) | |
729 { | |
730 FOR_EACH_BB_FN (bb, fun) | |
731 { | |
732 edge_iterator ei; | |
733 edge e; | |
734 | |
735 /* First see if there are any edges without EDGE_EXECUTABLE | |
736 set. */ | |
737 bool found = false; | |
738 FOR_EACH_EDGE (e, ei, bb->succs) | |
739 { | |
740 if ((e->flags & EDGE_EXECUTABLE) == 0) | |
741 { | |
742 found = true; | |
743 break; | |
744 } | |
745 } | |
746 | |
747 /* If there were any such edges found, then remove jump threads | |
748 containing any edge leaving BB. */ | |
749 if (found) | |
750 FOR_EACH_EDGE (e, ei, bb->succs) | |
751 remove_jump_threads_including (e); | |
752 } | |
753 } | |
0 | 754 |
755 { | |
756 gimple_stmt_iterator gsi; | |
757 basic_block bb; | |
111 | 758 FOR_EACH_BB_FN (bb, fun) |
759 { | |
760 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
0 | 761 update_stmt_if_modified (gsi_stmt (gsi)); |
762 } | |
763 } | |
764 | |
765 /* If we exposed any new variables, go ahead and put them into | |
766 SSA form now, before we handle jump threading. This simplifies | |
767 interactions between rewriting of _DECL nodes into SSA form | |
768 and rewriting SSA_NAME nodes into SSA form after block | |
769 duplication and CFG manipulation. */ | |
770 update_ssa (TODO_update_ssa); | |
771 | |
772 free_all_edge_infos (); | |
773 | |
774 /* Thread jumps, creating duplicate blocks as needed. */ | |
111 | 775 cfg_altered |= thread_through_all_blocks (may_peel_loop_headers_p); |
0 | 776 |
777 if (cfg_altered) | |
778 free_dominance_info (CDI_DOMINATORS); | |
779 | |
780 /* Removal of statements may make some EH edges dead. Purge | |
781 such edges from the CFG as needed. */ | |
782 if (!bitmap_empty_p (need_eh_cleanup)) | |
783 { | |
784 unsigned i; | |
785 bitmap_iterator bi; | |
786 | |
787 /* Jump threading may have created forwarder blocks from blocks | |
788 needing EH cleanup; the new successor of these blocks, which | |
111 | 789 has inherited from the original block, needs the cleanup. |
790 Don't clear bits in the bitmap, as that can break the bitmap | |
791 iterator. */ | |
0 | 792 EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) |
793 { | |
111 | 794 basic_block bb = BASIC_BLOCK_FOR_FN (fun, i); |
795 if (bb == NULL) | |
796 continue; | |
797 while (single_succ_p (bb) | |
145 | 798 && (single_succ_edge (bb)->flags |
799 & (EDGE_EH|EDGE_DFS_BACK)) == 0) | |
111 | 800 bb = single_succ (bb); |
801 if (bb == EXIT_BLOCK_PTR_FOR_FN (fun)) | |
802 continue; | |
803 if ((unsigned) bb->index != i) | |
804 bitmap_set_bit (need_eh_cleanup, bb->index); | |
0 | 805 } |
806 | |
807 gimple_purge_all_dead_eh_edges (need_eh_cleanup); | |
111 | 808 bitmap_clear (need_eh_cleanup); |
0 | 809 } |
810 | |
111 | 811 /* Fixup stmts that became noreturn calls. This may require splitting |
812 blocks and thus isn't possible during the dominator walk or before | |
813 jump threading finished. Do this in reverse order so we don't | |
814 inadvertedly remove a stmt we want to fixup by visiting a dominating | |
815 now noreturn call first. */ | |
816 while (!need_noreturn_fixup.is_empty ()) | |
817 { | |
818 gimple *stmt = need_noreturn_fixup.pop (); | |
819 if (dump_file && dump_flags & TDF_DETAILS) | |
820 { | |
821 fprintf (dump_file, "Fixing up noreturn call "); | |
822 print_gimple_stmt (dump_file, stmt, 0); | |
823 fprintf (dump_file, "\n"); | |
824 } | |
825 fixup_noreturn_call (stmt); | |
826 } | |
827 | |
828 statistics_counter_event (fun, "Redundant expressions eliminated", | |
0 | 829 opt_stats.num_re); |
111 | 830 statistics_counter_event (fun, "Constants propagated", |
0 | 831 opt_stats.num_const_prop); |
111 | 832 statistics_counter_event (fun, "Copies propagated", |
0 | 833 opt_stats.num_copy_prop); |
834 | |
835 /* Debugging dumps. */ | |
836 if (dump_file && (dump_flags & TDF_STATS)) | |
111 | 837 dump_dominator_optimization_stats (dump_file, avail_exprs); |
0 | 838 |
839 loop_optimizer_finalize (); | |
840 | |
841 /* Delete our main hashtable. */ | |
111 | 842 delete avail_exprs; |
843 avail_exprs = NULL; | |
0 | 844 |
845 /* Free asserted bitmaps and stacks. */ | |
846 BITMAP_FREE (need_eh_cleanup); | |
111 | 847 need_noreturn_fixup.release (); |
848 delete avail_exprs_stack; | |
849 delete const_and_copies; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
850 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
851 /* Free the value-handle array. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
852 threadedge_finalize_values (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
853 |
0 | 854 return 0; |
855 } | |
856 | |
111 | 857 } // anon namespace |
858 | |
859 gimple_opt_pass * | |
860 make_pass_dominator (gcc::context *ctxt) | |
0 | 861 { |
111 | 862 return new pass_dominator (ctxt); |
0 | 863 } |
864 | |
131 | 865 /* A hack until we remove threading from tree-vrp.c and bring the |
866 simplification routine into the dom_opt_dom_walker class. */ | |
867 static class vr_values *x_vr_values; | |
0 | 868 |
869 /* A trivial wrapper so that we can present the generic jump | |
870 threading code with a simple API for simplifying statements. */ | |
871 static tree | |
111 | 872 simplify_stmt_for_jump_threading (gimple *stmt, |
873 gimple *within_stmt ATTRIBUTE_UNUSED, | |
874 class avail_exprs_stack *avail_exprs_stack, | |
875 basic_block bb ATTRIBUTE_UNUSED) | |
0 | 876 { |
131 | 877 /* First query our hash table to see if the the expression is available |
878 there. A non-NULL return value will be either a constant or another | |
879 SSA_NAME. */ | |
880 tree cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, false, true); | |
881 if (cached_lhs) | |
882 return cached_lhs; | |
883 | |
884 /* If the hash table query failed, query VRP information. This is | |
885 essentially the same as tree-vrp's simplification routine. The | |
886 copy in tree-vrp is scheduled for removal in gcc-9. */ | |
887 if (gcond *cond_stmt = dyn_cast <gcond *> (stmt)) | |
888 { | |
889 cached_lhs | |
890 = x_vr_values->vrp_evaluate_conditional (gimple_cond_code (cond_stmt), | |
891 gimple_cond_lhs (cond_stmt), | |
892 gimple_cond_rhs (cond_stmt), | |
893 within_stmt); | |
894 return cached_lhs; | |
895 } | |
896 | |
897 if (gswitch *switch_stmt = dyn_cast <gswitch *> (stmt)) | |
898 { | |
899 tree op = gimple_switch_index (switch_stmt); | |
900 if (TREE_CODE (op) != SSA_NAME) | |
901 return NULL_TREE; | |
902 | |
145 | 903 const value_range_equiv *vr = x_vr_values->get_value_range (op); |
131 | 904 if (vr->undefined_p () |
905 || vr->varying_p () | |
906 || vr->symbolic_p ()) | |
907 return NULL_TREE; | |
908 | |
909 if (vr->kind () == VR_RANGE) | |
910 { | |
911 size_t i, j; | |
912 | |
913 find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j); | |
914 | |
145 | 915 /* Is there only one such label? */ |
131 | 916 if (i == j) |
917 { | |
918 tree label = gimple_switch_label (switch_stmt, i); | |
919 tree singleton; | |
920 | |
145 | 921 /* The i'th label will only be taken if the value range of the |
922 operand is entirely within the bounds of this label. */ | |
131 | 923 if (CASE_HIGH (label) != NULL_TREE |
924 ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0 | |
925 && tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0) | |
926 : (vr->singleton_p (&singleton) | |
927 && tree_int_cst_equal (CASE_LOW (label), singleton))) | |
928 return label; | |
145 | 929 } |
131 | 930 |
145 | 931 /* If there are no such labels, then the default label |
932 will be taken. */ | |
933 if (i > j) | |
934 return gimple_switch_label (switch_stmt, 0); | |
131 | 935 } |
936 | |
937 if (vr->kind () == VR_ANTI_RANGE) | |
938 { | |
939 unsigned n = gimple_switch_num_labels (switch_stmt); | |
940 tree min_label = gimple_switch_label (switch_stmt, 1); | |
941 tree max_label = gimple_switch_label (switch_stmt, n - 1); | |
942 | |
943 /* The default label will be taken only if the anti-range of the | |
944 operand is entirely outside the bounds of all the (non-default) | |
945 case labels. */ | |
946 if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0 | |
947 && (CASE_HIGH (max_label) != NULL_TREE | |
948 ? tree_int_cst_compare (vr->max (), CASE_HIGH (max_label)) >= 0 | |
949 : tree_int_cst_compare (vr->max (), CASE_LOW (max_label)) >= 0)) | |
950 return gimple_switch_label (switch_stmt, 0); | |
951 } | |
952 return NULL_TREE; | |
953 } | |
954 | |
955 if (gassign *assign_stmt = dyn_cast <gassign *> (stmt)) | |
956 { | |
957 tree lhs = gimple_assign_lhs (assign_stmt); | |
958 if (TREE_CODE (lhs) == SSA_NAME | |
959 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) | |
960 || POINTER_TYPE_P (TREE_TYPE (lhs))) | |
961 && stmt_interesting_for_vrp (stmt)) | |
962 { | |
963 edge dummy_e; | |
964 tree dummy_tree; | |
145 | 965 value_range_equiv new_vr; |
131 | 966 x_vr_values->extract_range_from_stmt (stmt, &dummy_e, |
145 | 967 &dummy_tree, &new_vr); |
131 | 968 tree singleton; |
969 if (new_vr.singleton_p (&singleton)) | |
970 return singleton; | |
971 } | |
972 } | |
973 return NULL; | |
111 | 974 } |
975 | |
976 /* Valueize hook for gimple_fold_stmt_to_constant_1. */ | |
977 | |
978 static tree | |
979 dom_valueize (tree t) | |
980 { | |
981 if (TREE_CODE (t) == SSA_NAME) | |
982 { | |
983 tree tem = SSA_NAME_VALUE (t); | |
984 if (tem) | |
985 return tem; | |
986 } | |
987 return t; | |
0 | 988 } |
989 | |
111 | 990 /* We have just found an equivalence for LHS on an edge E. |
991 Look backwards to other uses of LHS and see if we can derive | |
992 additional equivalences that are valid on edge E. */ | |
0 | 993 static void |
111 | 994 back_propagate_equivalences (tree lhs, edge e, |
995 class const_and_copies *const_and_copies) | |
0 | 996 { |
111 | 997 use_operand_p use_p; |
998 imm_use_iterator iter; | |
999 bitmap domby = NULL; | |
1000 basic_block dest = e->dest; | |
1001 | |
1002 /* Iterate over the uses of LHS to see if any dominate E->dest. | |
1003 If so, they may create useful equivalences too. | |
1004 | |
1005 ??? If the code gets re-organized to a worklist to catch more | |
1006 indirect opportunities and it is made to handle PHIs then this | |
1007 should only consider use_stmts in basic-blocks we have already visited. */ | |
1008 FOR_EACH_IMM_USE_FAST (use_p, iter, lhs) | |
1009 { | |
1010 gimple *use_stmt = USE_STMT (use_p); | |
1011 | |
1012 /* Often the use is in DEST, which we trivially know we can't use. | |
1013 This is cheaper than the dominator set tests below. */ | |
1014 if (dest == gimple_bb (use_stmt)) | |
1015 continue; | |
1016 | |
1017 /* Filter out statements that can never produce a useful | |
1018 equivalence. */ | |
1019 tree lhs2 = gimple_get_lhs (use_stmt); | |
1020 if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME) | |
1021 continue; | |
1022 | |
1023 /* Profiling has shown the domination tests here can be fairly | |
1024 expensive. We get significant improvements by building the | |
1025 set of blocks that dominate BB. We can then just test | |
1026 for set membership below. | |
1027 | |
1028 We also initialize the set lazily since often the only uses | |
1029 are going to be in the same block as DEST. */ | |
1030 if (!domby) | |
1031 { | |
1032 domby = BITMAP_ALLOC (NULL); | |
1033 basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest); | |
1034 while (bb) | |
1035 { | |
1036 bitmap_set_bit (domby, bb->index); | |
1037 bb = get_immediate_dominator (CDI_DOMINATORS, bb); | |
1038 } | |
1039 } | |
1040 | |
1041 /* This tests if USE_STMT does not dominate DEST. */ | |
1042 if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index)) | |
1043 continue; | |
1044 | |
1045 /* At this point USE_STMT dominates DEST and may result in a | |
1046 useful equivalence. Try to simplify its RHS to a constant | |
1047 or SSA_NAME. */ | |
1048 tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize, | |
1049 no_follow_ssa_edges); | |
1050 if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res))) | |
1051 record_equality (lhs2, res, const_and_copies); | |
1052 } | |
1053 | |
1054 if (domby) | |
1055 BITMAP_FREE (domby); | |
1056 } | |
0 | 1057 |
111 | 1058 /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied |
1059 by traversing edge E (which are cached in E->aux). | |
1060 | |
1061 Callers are responsible for managing the unwinding markers. */ | |
1062 void | |
1063 record_temporary_equivalences (edge e, | |
1064 class const_and_copies *const_and_copies, | |
1065 class avail_exprs_stack *avail_exprs_stack) | |
1066 { | |
1067 int i; | |
1068 class edge_info *edge_info = (class edge_info *) e->aux; | |
1069 | |
1070 /* If we have info associated with this edge, record it into | |
1071 our equivalence tables. */ | |
1072 if (edge_info) | |
1073 { | |
1074 cond_equivalence *eq; | |
1075 /* If we have 0 = COND or 1 = COND equivalences, record them | |
1076 into our expression hash tables. */ | |
1077 for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) | |
1078 avail_exprs_stack->record_cond (eq); | |
1079 | |
1080 edge_info::equiv_pair *seq; | |
1081 for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i) | |
1082 { | |
1083 tree lhs = seq->first; | |
1084 if (!lhs || TREE_CODE (lhs) != SSA_NAME) | |
1085 continue; | |
1086 | |
1087 /* Record the simple NAME = VALUE equivalence. */ | |
1088 tree rhs = seq->second; | |
1089 | |
1090 /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is | |
1091 cheaper to compute than the other, then set up the equivalence | |
1092 such that we replace the expensive one with the cheap one. | |
1093 | |
1094 If they are the same cost to compute, then do not record | |
1095 anything. */ | |
1096 if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME) | |
1097 { | |
1098 gimple *rhs_def = SSA_NAME_DEF_STMT (rhs); | |
1099 int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights); | |
1100 | |
1101 gimple *lhs_def = SSA_NAME_DEF_STMT (lhs); | |
1102 int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights); | |
1103 | |
1104 if (rhs_cost > lhs_cost) | |
1105 record_equality (rhs, lhs, const_and_copies); | |
1106 else if (rhs_cost < lhs_cost) | |
1107 record_equality (lhs, rhs, const_and_copies); | |
1108 } | |
1109 else | |
1110 record_equality (lhs, rhs, const_and_copies); | |
1111 | |
1112 | |
1113 /* Any equivalence found for LHS may result in additional | |
1114 equivalences for other uses of LHS that we have already | |
1115 processed. */ | |
1116 back_propagate_equivalences (lhs, e, const_and_copies); | |
1117 } | |
1118 } | |
0 | 1119 } |
1120 | |
1121 /* PHI nodes can create equivalences too. | |
1122 | |
1123 Ignoring any alternatives which are the same as the result, if | |
1124 all the alternatives are equal, then the PHI node creates an | |
1125 equivalence. */ | |
1126 | |
1127 static void | |
1128 record_equivalences_from_phis (basic_block bb) | |
1129 { | |
111 | 1130 gphi_iterator gsi; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1131 |
145 | 1132 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) |
0 | 1133 { |
111 | 1134 gphi *phi = gsi.phi (); |
0 | 1135 |
145 | 1136 /* We might eliminate the PHI, so advance GSI now. */ |
1137 gsi_next (&gsi); | |
1138 | |
0 | 1139 tree lhs = gimple_phi_result (phi); |
1140 tree rhs = NULL; | |
1141 size_t i; | |
1142 | |
1143 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
1144 { | |
1145 tree t = gimple_phi_arg_def (phi, i); | |
1146 | |
1147 /* Ignore alternatives which are the same as our LHS. Since | |
1148 LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we | |
1149 can simply compare pointers. */ | |
1150 if (lhs == t) | |
1151 continue; | |
1152 | |
111 | 1153 /* If the associated edge is not marked as executable, then it |
1154 can be ignored. */ | |
1155 if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0) | |
1156 continue; | |
1157 | |
1158 t = dom_valueize (t); | |
1159 | |
131 | 1160 /* If T is an SSA_NAME and its associated edge is a backedge, |
145 | 1161 then quit as we cannot utilize this equivalence. */ |
131 | 1162 if (TREE_CODE (t) == SSA_NAME |
1163 && (gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK)) | |
1164 break; | |
1165 | |
0 | 1166 /* If we have not processed an alternative yet, then set |
1167 RHS to this alternative. */ | |
1168 if (rhs == NULL) | |
1169 rhs = t; | |
1170 /* If we have processed an alternative (stored in RHS), then | |
1171 see if it is equal to this one. If it isn't, then stop | |
1172 the search. */ | |
1173 else if (! operand_equal_for_phi_arg_p (rhs, t)) | |
1174 break; | |
1175 } | |
1176 | |
1177 /* If we had no interesting alternatives, then all the RHS alternatives | |
1178 must have been the same as LHS. */ | |
1179 if (!rhs) | |
1180 rhs = lhs; | |
1181 | |
1182 /* If we managed to iterate through each PHI alternative without | |
1183 breaking out of the loop, then we have a PHI which may create | |
1184 a useful equivalence. We do not need to record unwind data for | |
1185 this, since this is a true assignment and not an equivalence | |
1186 inferred from a comparison. All uses of this ssa name are dominated | |
1187 by this assignment, so unwinding just costs time and space. */ | |
145 | 1188 if (i == gimple_phi_num_args (phi)) |
1189 { | |
1190 if (may_propagate_copy (lhs, rhs)) | |
1191 set_ssa_name_value (lhs, rhs); | |
1192 else if (virtual_operand_p (lhs)) | |
1193 { | |
1194 gimple *use_stmt; | |
1195 imm_use_iterator iter; | |
1196 use_operand_p use_p; | |
1197 /* For virtual operands we have to propagate into all uses as | |
1198 otherwise we will create overlapping life-ranges. */ | |
1199 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs) | |
1200 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
1201 SET_USE (use_p, rhs); | |
1202 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) | |
1203 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1; | |
1204 gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi); | |
1205 remove_phi_node (&tmp_gsi, true); | |
1206 } | |
1207 } | |
0 | 1208 } |
1209 } | |
1210 | |
111 | 1211 /* Record any equivalences created by the incoming edge to BB into |
1212 CONST_AND_COPIES and AVAIL_EXPRS_STACK. If BB has more than one | |
1213 incoming edge, then no equivalence is created. */ | |
0 | 1214 |
1215 static void | |
111 | 1216 record_equivalences_from_incoming_edge (basic_block bb, |
1217 class const_and_copies *const_and_copies, | |
1218 class avail_exprs_stack *avail_exprs_stack) | |
0 | 1219 { |
1220 edge e; | |
1221 basic_block parent; | |
1222 | |
1223 /* If our parent block ended with a control statement, then we may be | |
1224 able to record some equivalences based on which outgoing edge from | |
1225 the parent was followed. */ | |
1226 parent = get_immediate_dominator (CDI_DOMINATORS, bb); | |
1227 | |
131 | 1228 e = single_pred_edge_ignoring_loop_edges (bb, true); |
0 | 1229 |
1230 /* If we had a single incoming edge from our parent block, then enter | |
1231 any data associated with the edge into our tables. */ | |
1232 if (e && e->src == parent) | |
111 | 1233 record_temporary_equivalences (e, const_and_copies, avail_exprs_stack); |
1234 } | |
0 | 1235 |
111 | 1236 /* Dump statistics for the hash table HTAB. */ |
0 | 1237 |
111 | 1238 static void |
1239 htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab) | |
1240 { | |
1241 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", | |
1242 (long) htab.size (), | |
1243 (long) htab.elements (), | |
1244 htab.collisions ()); | |
0 | 1245 } |
1246 | |
1247 /* Dump SSA statistics on FILE. */ | |
1248 | |
111 | 1249 static void |
1250 dump_dominator_optimization_stats (FILE *file, | |
1251 hash_table<expr_elt_hasher> *avail_exprs) | |
0 | 1252 { |
1253 fprintf (file, "Total number of statements: %6ld\n\n", | |
1254 opt_stats.num_stmts); | |
1255 fprintf (file, "Exprs considered for dominator optimizations: %6ld\n", | |
1256 opt_stats.num_exprs_considered); | |
1257 | |
1258 fprintf (file, "\nHash table statistics:\n"); | |
1259 | |
1260 fprintf (file, " avail_exprs: "); | |
111 | 1261 htab_statistics (file, *avail_exprs); |
0 | 1262 } |
1263 | |
1264 | |
1265 /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR. | |
1266 This constrains the cases in which we may treat this as assignment. */ | |
1267 | |
1268 static void | |
111 | 1269 record_equality (tree x, tree y, class const_and_copies *const_and_copies) |
0 | 1270 { |
1271 tree prev_x = NULL, prev_y = NULL; | |
1272 | |
111 | 1273 if (tree_swap_operands_p (x, y)) |
1274 std::swap (x, y); | |
1275 | |
1276 /* Most of the time tree_swap_operands_p does what we want. But there | |
1277 are cases where we know one operand is better for copy propagation than | |
1278 the other. Given no other code cares about ordering of equality | |
1279 comparison operators for that purpose, we just handle the special cases | |
1280 here. */ | |
1281 if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME) | |
1282 { | |
1283 /* If one operand is a single use operand, then make it | |
1284 X. This will preserve its single use properly and if this | |
1285 conditional is eliminated, the computation of X can be | |
1286 eliminated as well. */ | |
1287 if (has_single_use (y) && ! has_single_use (x)) | |
1288 std::swap (x, y); | |
1289 } | |
0 | 1290 if (TREE_CODE (x) == SSA_NAME) |
1291 prev_x = SSA_NAME_VALUE (x); | |
1292 if (TREE_CODE (y) == SSA_NAME) | |
1293 prev_y = SSA_NAME_VALUE (y); | |
1294 | |
1295 /* If one of the previous values is invariant, or invariant in more loops | |
1296 (by depth), then use that. | |
1297 Otherwise it doesn't matter which value we choose, just so | |
1298 long as we canonicalize on one value. */ | |
1299 if (is_gimple_min_invariant (y)) | |
1300 ; | |
111 | 1301 else if (is_gimple_min_invariant (x)) |
0 | 1302 prev_x = x, x = y, y = prev_x, prev_x = prev_y; |
1303 else if (prev_x && is_gimple_min_invariant (prev_x)) | |
1304 x = y, y = prev_x, prev_x = prev_y; | |
1305 else if (prev_y) | |
1306 y = prev_y; | |
1307 | |
1308 /* After the swapping, we must have one SSA_NAME. */ | |
1309 if (TREE_CODE (x) != SSA_NAME) | |
1310 return; | |
1311 | |
1312 /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a | |
1313 variable compared against zero. If we're honoring signed zeros, | |
1314 then we cannot record this value unless we know that the value is | |
1315 nonzero. */ | |
111 | 1316 if (HONOR_SIGNED_ZEROS (x) |
0 | 1317 && (TREE_CODE (y) != REAL_CST |
111 | 1318 || real_equal (&dconst0, &TREE_REAL_CST (y)))) |
0 | 1319 return; |
1320 | |
111 | 1321 const_and_copies->record_const_or_copy (x, y, prev_x); |
0 | 1322 } |
1323 | |
1324 /* Returns true when STMT is a simple iv increment. It detects the | |
1325 following situation: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1326 |
131 | 1327 i_1 = phi (..., i_k) |
1328 [...] | |
1329 i_j = i_{j-1} for each j : 2 <= j <= k-1 | |
1330 [...] | |
1331 i_k = i_{k-1} +/- ... */ | |
0 | 1332 |
111 | 1333 bool |
1334 simple_iv_increment_p (gimple *stmt) | |
0 | 1335 { |
111 | 1336 enum tree_code code; |
0 | 1337 tree lhs, preinc; |
111 | 1338 gimple *phi; |
0 | 1339 size_t i; |
1340 | |
1341 if (gimple_code (stmt) != GIMPLE_ASSIGN) | |
1342 return false; | |
1343 | |
1344 lhs = gimple_assign_lhs (stmt); | |
1345 if (TREE_CODE (lhs) != SSA_NAME) | |
1346 return false; | |
1347 | |
111 | 1348 code = gimple_assign_rhs_code (stmt); |
1349 if (code != PLUS_EXPR | |
1350 && code != MINUS_EXPR | |
1351 && code != POINTER_PLUS_EXPR) | |
0 | 1352 return false; |
1353 | |
1354 preinc = gimple_assign_rhs1 (stmt); | |
1355 if (TREE_CODE (preinc) != SSA_NAME) | |
1356 return false; | |
1357 | |
1358 phi = SSA_NAME_DEF_STMT (preinc); | |
131 | 1359 while (gimple_code (phi) != GIMPLE_PHI) |
1360 { | |
1361 /* Follow trivial copies, but not the DEF used in a back edge, | |
1362 so that we don't prevent coalescing. */ | |
1363 if (!gimple_assign_ssa_name_copy_p (phi)) | |
1364 return false; | |
1365 preinc = gimple_assign_rhs1 (phi); | |
1366 phi = SSA_NAME_DEF_STMT (preinc); | |
1367 } | |
0 | 1368 |
1369 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
1370 if (gimple_phi_arg_def (phi, i) == lhs) | |
1371 return true; | |
1372 | |
1373 return false; | |
1374 } | |
1375 | |
111 | 1376 /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the |
0 | 1377 successors of BB. */ |
1378 | |
1379 static void | |
111 | 1380 cprop_into_successor_phis (basic_block bb, |
1381 class const_and_copies *const_and_copies) | |
0 | 1382 { |
1383 edge e; | |
1384 edge_iterator ei; | |
1385 | |
1386 FOR_EACH_EDGE (e, ei, bb->succs) | |
1387 { | |
1388 int indx; | |
111 | 1389 gphi_iterator gsi; |
0 | 1390 |
1391 /* If this is an abnormal edge, then we do not want to copy propagate | |
1392 into the PHI alternative associated with this edge. */ | |
1393 if (e->flags & EDGE_ABNORMAL) | |
1394 continue; | |
1395 | |
1396 gsi = gsi_start_phis (e->dest); | |
1397 if (gsi_end_p (gsi)) | |
1398 continue; | |
1399 | |
111 | 1400 /* We may have an equivalence associated with this edge. While |
145 | 1401 we cannot propagate it into non-dominated blocks, we can |
111 | 1402 propagate them into PHIs in non-dominated blocks. */ |
1403 | |
1404 /* Push the unwind marker so we can reset the const and copies | |
1405 table back to its original state after processing this edge. */ | |
1406 const_and_copies->push_marker (); | |
1407 | |
1408 /* Extract and record any simple NAME = VALUE equivalences. | |
1409 | |
1410 Don't bother with [01] = COND equivalences, they're not useful | |
1411 here. */ | |
1412 class edge_info *edge_info = (class edge_info *) e->aux; | |
1413 | |
1414 if (edge_info) | |
1415 { | |
1416 edge_info::equiv_pair *seq; | |
1417 for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i) | |
1418 { | |
1419 tree lhs = seq->first; | |
1420 tree rhs = seq->second; | |
1421 | |
1422 if (lhs && TREE_CODE (lhs) == SSA_NAME) | |
1423 const_and_copies->record_const_or_copy (lhs, rhs); | |
1424 } | |
1425 | |
1426 } | |
1427 | |
0 | 1428 indx = e->dest_idx; |
1429 for ( ; !gsi_end_p (gsi); gsi_next (&gsi)) | |
1430 { | |
1431 tree new_val; | |
1432 use_operand_p orig_p; | |
1433 tree orig_val; | |
111 | 1434 gphi *phi = gsi.phi (); |
0 | 1435 |
1436 /* The alternative may be associated with a constant, so verify | |
1437 it is an SSA_NAME before doing anything with it. */ | |
1438 orig_p = gimple_phi_arg_imm_use_ptr (phi, indx); | |
1439 orig_val = get_use_from_ptr (orig_p); | |
1440 if (TREE_CODE (orig_val) != SSA_NAME) | |
1441 continue; | |
1442 | |
1443 /* If we have *ORIG_P in our constant/copy table, then replace | |
1444 ORIG_P with its value in our constant/copy table. */ | |
1445 new_val = SSA_NAME_VALUE (orig_val); | |
1446 if (new_val | |
1447 && new_val != orig_val | |
1448 && may_propagate_copy (orig_val, new_val)) | |
1449 propagate_value (orig_p, new_val); | |
1450 } | |
111 | 1451 |
1452 const_and_copies->pop_to_marker (); | |
0 | 1453 } |
1454 } | |
1455 | |
111 | 1456 edge |
1457 dom_opt_dom_walker::before_dom_children (basic_block bb) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1458 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1459 gimple_stmt_iterator gsi; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1460 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1461 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:
47
diff
changeset
|
1462 fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1463 |
131 | 1464 evrp_range_analyzer.enter (bb); |
1465 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1466 /* Push a marker on the stacks of local information so that we know how |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1467 far to unwind when we finalize this block. */ |
111 | 1468 m_avail_exprs_stack->push_marker (); |
1469 m_const_and_copies->push_marker (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1470 |
111 | 1471 record_equivalences_from_incoming_edge (bb, m_const_and_copies, |
1472 m_avail_exprs_stack); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1473 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1474 /* PHI nodes can create equivalences too. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1475 record_equivalences_from_phis (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1476 |
111 | 1477 /* Create equivalences from redundant PHIs. PHIs are only truly |
1478 redundant when they exist in the same block, so push another | |
1479 marker and unwind right afterwards. */ | |
1480 m_avail_exprs_stack->push_marker (); | |
1481 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
1482 eliminate_redundant_computations (&gsi, m_const_and_copies, | |
1483 m_avail_exprs_stack); | |
1484 m_avail_exprs_stack->pop_to_marker (); | |
1485 | |
1486 edge taken_edge = NULL; | |
145 | 1487 /* Initialize visited flag ahead of us, it has undefined state on |
1488 pass entry. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1489 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
145 | 1490 gimple_set_visited (gsi_stmt (gsi), false); |
1491 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) | |
131 | 1492 { |
145 | 1493 /* Do not optimize a stmt twice, substitution might end up with |
1494 _3 = _3 which is not valid. */ | |
1495 if (gimple_visited_p (gsi_stmt (gsi))) | |
1496 { | |
1497 gsi_next (&gsi); | |
1498 continue; | |
1499 } | |
1500 | |
1501 /* Compute range information and optimize the stmt. */ | |
131 | 1502 evrp_range_analyzer.record_ranges_from_stmt (gsi_stmt (gsi), false); |
145 | 1503 bool removed_p = false; |
1504 taken_edge = this->optimize_stmt (bb, &gsi, &removed_p); | |
1505 if (!removed_p) | |
1506 gimple_set_visited (gsi_stmt (gsi), true); | |
1507 | |
1508 /* Go back and visit stmts inserted by folding after substituting | |
1509 into the stmt at gsi. */ | |
1510 if (gsi_end_p (gsi)) | |
1511 { | |
1512 gcc_checking_assert (removed_p); | |
1513 gsi = gsi_last_bb (bb); | |
1514 while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi))) | |
1515 gsi_prev (&gsi); | |
1516 } | |
1517 else | |
1518 { | |
1519 do | |
1520 { | |
1521 gsi_prev (&gsi); | |
1522 } | |
1523 while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi))); | |
1524 } | |
1525 if (gsi_end_p (gsi)) | |
1526 gsi = gsi_start_bb (bb); | |
1527 else | |
1528 gsi_next (&gsi); | |
131 | 1529 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1530 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1531 /* Now prepare to process dominated blocks. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1532 record_edge_info (bb); |
111 | 1533 cprop_into_successor_phis (bb, m_const_and_copies); |
1534 if (taken_edge && !dbg_cnt (dom_unreachable_edges)) | |
1535 return NULL; | |
1536 | |
1537 return taken_edge; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1538 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1539 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1540 /* We have finished processing the dominator children of BB, perform |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1541 any finalization actions in preparation for leaving this node in |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1542 the dominator tree. */ |
0 | 1543 |
111 | 1544 void |
1545 dom_opt_dom_walker::after_dom_children (basic_block bb) | |
0 | 1546 { |
131 | 1547 x_vr_values = evrp_range_analyzer.get_vr_values (); |
111 | 1548 thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies, |
1549 m_avail_exprs_stack, | |
131 | 1550 &evrp_range_analyzer, |
111 | 1551 simplify_stmt_for_jump_threading); |
131 | 1552 x_vr_values = NULL; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1553 |
111 | 1554 /* These remove expressions local to BB from the tables. */ |
1555 m_avail_exprs_stack->pop_to_marker (); | |
1556 m_const_and_copies->pop_to_marker (); | |
131 | 1557 evrp_range_analyzer.leave (bb); |
0 | 1558 } |
1559 | |
1560 /* Search for redundant computations in STMT. If any are found, then | |
1561 replace them with the variable holding the result of the computation. | |
1562 | |
111 | 1563 If safe, record this expression into AVAIL_EXPRS_STACK and |
1564 CONST_AND_COPIES. */ | |
0 | 1565 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1566 static void |
111 | 1567 eliminate_redundant_computations (gimple_stmt_iterator* gsi, |
1568 class const_and_copies *const_and_copies, | |
1569 class avail_exprs_stack *avail_exprs_stack) | |
0 | 1570 { |
1571 tree expr_type; | |
1572 tree cached_lhs; | |
111 | 1573 tree def; |
0 | 1574 bool insert = true; |
1575 bool assigns_var_p = false; | |
1576 | |
111 | 1577 gimple *stmt = gsi_stmt (*gsi); |
0 | 1578 |
111 | 1579 if (gimple_code (stmt) == GIMPLE_PHI) |
1580 def = gimple_phi_result (stmt); | |
1581 else | |
1582 def = gimple_get_lhs (stmt); | |
0 | 1583 |
145 | 1584 /* Certain expressions on the RHS can be optimized away, but cannot |
0 | 1585 themselves be entered into the hash tables. */ |
1586 if (! def | |
1587 || TREE_CODE (def) != SSA_NAME | |
1588 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1589 || gimple_vdef (stmt) |
0 | 1590 /* Do not record equivalences for increments of ivs. This would create |
1591 overlapping live ranges for a very questionable gain. */ | |
1592 || simple_iv_increment_p (stmt)) | |
1593 insert = false; | |
1594 | |
1595 /* Check if the expression has been computed before. */ | |
111 | 1596 cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true); |
0 | 1597 |
1598 opt_stats.num_exprs_considered++; | |
1599 | |
1600 /* Get the type of the expression we are trying to optimize. */ | |
1601 if (is_gimple_assign (stmt)) | |
1602 { | |
1603 expr_type = TREE_TYPE (gimple_assign_lhs (stmt)); | |
1604 assigns_var_p = true; | |
1605 } | |
1606 else if (gimple_code (stmt) == GIMPLE_COND) | |
1607 expr_type = boolean_type_node; | |
1608 else if (is_gimple_call (stmt)) | |
1609 { | |
1610 gcc_assert (gimple_call_lhs (stmt)); | |
1611 expr_type = TREE_TYPE (gimple_call_lhs (stmt)); | |
1612 assigns_var_p = true; | |
1613 } | |
111 | 1614 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) |
1615 expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt)); | |
1616 else if (gimple_code (stmt) == GIMPLE_PHI) | |
1617 /* We can't propagate into a phi, so the logic below doesn't apply. | |
1618 Instead record an equivalence between the cached LHS and the | |
1619 PHI result of this statement, provided they are in the same block. | |
1620 This should be sufficient to kill the redundant phi. */ | |
1621 { | |
1622 if (def && cached_lhs) | |
1623 const_and_copies->record_const_or_copy (def, cached_lhs); | |
1624 return; | |
1625 } | |
0 | 1626 else |
1627 gcc_unreachable (); | |
1628 | |
1629 if (!cached_lhs) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1630 return; |
0 | 1631 |
1632 /* It is safe to ignore types here since we have already done | |
1633 type checking in the hashing and equality routines. In fact | |
1634 type checking here merely gets in the way of constant | |
1635 propagation. Also, make sure that it is safe to propagate | |
1636 CACHED_LHS into the expression in STMT. */ | |
1637 if ((TREE_CODE (cached_lhs) != SSA_NAME | |
1638 && (assigns_var_p | |
1639 || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))) | |
1640 || may_propagate_copy_into_stmt (stmt, cached_lhs)) | |
1641 { | |
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
|
1642 gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_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
|
1643 || is_gimple_min_invariant (cached_lhs)); |
0 | 1644 |
1645 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1646 { | |
1647 fprintf (dump_file, " Replaced redundant expr '"); | |
1648 print_gimple_expr (dump_file, stmt, 0, dump_flags); | |
1649 fprintf (dump_file, "' with '"); | |
1650 print_generic_expr (dump_file, cached_lhs, dump_flags); | |
1651 fprintf (dump_file, "'\n"); | |
1652 } | |
1653 | |
1654 opt_stats.num_re++; | |
1655 | |
1656 if (assigns_var_p | |
1657 && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))) | |
1658 cached_lhs = fold_convert (expr_type, cached_lhs); | |
1659 | |
1660 propagate_tree_value_into_stmt (gsi, cached_lhs); | |
1661 | |
1662 /* Since it is always necessary to mark the result as modified, | |
1663 perhaps we should move this into propagate_tree_value_into_stmt | |
1664 itself. */ | |
1665 gimple_set_modified (gsi_stmt (*gsi), true); | |
1666 } | |
1667 } | |
1668 | |
1669 /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either | |
1670 the available expressions table or the const_and_copies table. | |
111 | 1671 Detect and record those equivalences into AVAIL_EXPRS_STACK. |
1672 | |
1673 We handle only very simple copy equivalences here. The heavy | |
0 | 1674 lifing is done by eliminate_redundant_computations. */ |
1675 | |
1676 static void | |
111 | 1677 record_equivalences_from_stmt (gimple *stmt, int may_optimize_p, |
1678 class avail_exprs_stack *avail_exprs_stack) | |
0 | 1679 { |
1680 tree lhs; | |
1681 enum tree_code lhs_code; | |
1682 | |
1683 gcc_assert (is_gimple_assign (stmt)); | |
1684 | |
1685 lhs = gimple_assign_lhs (stmt); | |
1686 lhs_code = TREE_CODE (lhs); | |
1687 | |
1688 if (lhs_code == SSA_NAME | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1689 && gimple_assign_single_p (stmt)) |
0 | 1690 { |
1691 tree rhs = gimple_assign_rhs1 (stmt); | |
1692 | |
1693 /* If the RHS of the assignment is a constant or another variable that | |
1694 may be propagated, register it in the CONST_AND_COPIES table. We | |
1695 do not need to record unwind data for this, since this is a true | |
1696 assignment and not an equivalence inferred from a comparison. All | |
1697 uses of this ssa name are dominated by this assignment, so unwinding | |
1698 just costs time and space. */ | |
1699 if (may_optimize_p | |
1700 && (TREE_CODE (rhs) == SSA_NAME | |
1701 || is_gimple_min_invariant (rhs))) | |
111 | 1702 { |
1703 rhs = dom_valueize (rhs); | |
1704 | |
1705 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1706 { | |
1707 fprintf (dump_file, "==== ASGN "); | |
1708 print_generic_expr (dump_file, lhs); | |
1709 fprintf (dump_file, " = "); | |
1710 print_generic_expr (dump_file, rhs); | |
1711 fprintf (dump_file, "\n"); | |
1712 } | |
1713 | |
1714 set_ssa_name_value (lhs, rhs); | |
1715 } | |
1716 } | |
0 | 1717 |
111 | 1718 /* Make sure we can propagate &x + CST. */ |
1719 if (lhs_code == SSA_NAME | |
1720 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR | |
1721 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR | |
1722 && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST) | |
1723 { | |
1724 tree op0 = gimple_assign_rhs1 (stmt); | |
1725 tree op1 = gimple_assign_rhs2 (stmt); | |
1726 tree new_rhs | |
1727 = build_fold_addr_expr (fold_build2 (MEM_REF, | |
1728 TREE_TYPE (TREE_TYPE (op0)), | |
1729 unshare_expr (op0), | |
1730 fold_convert (ptr_type_node, | |
1731 op1))); | |
1732 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1733 { | |
1734 fprintf (dump_file, "==== ASGN "); | |
1735 print_generic_expr (dump_file, lhs); | |
1736 fprintf (dump_file, " = "); | |
1737 print_generic_expr (dump_file, new_rhs); | |
1738 fprintf (dump_file, "\n"); | |
1739 } | |
1740 | |
1741 set_ssa_name_value (lhs, new_rhs); | |
0 | 1742 } |
1743 | |
1744 /* A memory store, even an aliased store, creates a useful | |
1745 equivalence. By exchanging the LHS and RHS, creating suitable | |
1746 vops and recording the result in the available expression table, | |
1747 we may be able to expose more redundant loads. */ | |
1748 if (!gimple_has_volatile_ops (stmt) | |
1749 && gimple_references_memory_p (stmt) | |
1750 && gimple_assign_single_p (stmt) | |
1751 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME | |
1752 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) | |
1753 && !is_gimple_reg (lhs)) | |
1754 { | |
1755 tree rhs = gimple_assign_rhs1 (stmt); | |
111 | 1756 gassign *new_stmt; |
0 | 1757 |
1758 /* Build a new statement with the RHS and LHS exchanged. */ | |
1759 if (TREE_CODE (rhs) == SSA_NAME) | |
1760 { | |
1761 /* NOTE tuples. The call to gimple_build_assign below replaced | |
1762 a call to build_gimple_modify_stmt, which did not set the | |
1763 SSA_NAME_DEF_STMT on the LHS of the assignment. Doing so | |
1764 may cause an SSA validation failure, as the LHS may be a | |
1765 default-initialized name and should have no definition. I'm | |
1766 a bit dubious of this, as the artificial statement that we | |
1767 generate here may in fact be ill-formed, but it is simply | |
1768 used as an internal device in this pass, and never becomes | |
1769 part of the CFG. */ | |
111 | 1770 gimple *defstmt = SSA_NAME_DEF_STMT (rhs); |
0 | 1771 new_stmt = gimple_build_assign (rhs, lhs); |
1772 SSA_NAME_DEF_STMT (rhs) = defstmt; | |
1773 } | |
1774 else | |
1775 new_stmt = gimple_build_assign (rhs, lhs); | |
1776 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1777 gimple_set_vuse (new_stmt, gimple_vdef (stmt)); |
0 | 1778 |
1779 /* Finally enter the statement into the available expression | |
1780 table. */ | |
111 | 1781 avail_exprs_stack->lookup_avail_expr (new_stmt, true, true); |
0 | 1782 } |
1783 } | |
1784 | |
1785 /* Replace *OP_P in STMT with any known equivalent value for *OP_P from | |
1786 CONST_AND_COPIES. */ | |
1787 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1788 static void |
131 | 1789 cprop_operand (gimple *stmt, use_operand_p op_p, vr_values *vr_values) |
0 | 1790 { |
1791 tree val; | |
1792 tree op = USE_FROM_PTR (op_p); | |
1793 | |
1794 /* If the operand has a known constant value or it is known to be a | |
1795 copy of some other variable, use the value or copy stored in | |
1796 CONST_AND_COPIES. */ | |
1797 val = SSA_NAME_VALUE (op); | |
131 | 1798 if (!val) |
1799 val = vr_values->op_with_constant_singleton_value_range (op); | |
1800 | |
0 | 1801 if (val && val != op) |
1802 { | |
1803 /* Do not replace hard register operands in asm statements. */ | |
1804 if (gimple_code (stmt) == GIMPLE_ASM | |
1805 && !may_propagate_copy_into_asm (op)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1806 return; |
0 | 1807 |
1808 /* Certain operands are not allowed to be copy propagated due | |
1809 to their interaction with exception handling and some GCC | |
1810 extensions. */ | |
1811 if (!may_propagate_copy (op, val)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1812 return; |
0 | 1813 |
111 | 1814 /* Do not propagate copies into BIVs. |
1815 See PR23821 and PR62217 for how this can disturb IV and | |
1816 number of iteration analysis. */ | |
1817 if (TREE_CODE (val) != INTEGER_CST) | |
1818 { | |
1819 gimple *def = SSA_NAME_DEF_STMT (op); | |
1820 if (gimple_code (def) == GIMPLE_PHI | |
1821 && gimple_bb (def)->loop_father->header == gimple_bb (def)) | |
1822 return; | |
1823 } | |
0 | 1824 |
1825 /* Dump details. */ | |
1826 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1827 { | |
1828 fprintf (dump_file, " Replaced '"); | |
1829 print_generic_expr (dump_file, op, dump_flags); | |
1830 fprintf (dump_file, "' with %s '", | |
1831 (TREE_CODE (val) != SSA_NAME ? "constant" : "variable")); | |
1832 print_generic_expr (dump_file, val, dump_flags); | |
1833 fprintf (dump_file, "'\n"); | |
1834 } | |
1835 | |
1836 if (TREE_CODE (val) != SSA_NAME) | |
1837 opt_stats.num_const_prop++; | |
1838 else | |
1839 opt_stats.num_copy_prop++; | |
1840 | |
1841 propagate_value (op_p, val); | |
1842 | |
1843 /* And note that we modified this statement. This is now | |
1844 safe, even if we changed virtual operands since we will | |
1845 rescan the statement and rewrite its operands again. */ | |
1846 gimple_set_modified (stmt, true); | |
1847 } | |
1848 } | |
1849 | |
1850 /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1851 known value for that SSA_NAME (or NULL if no value is known). |
0 | 1852 |
1853 Propagate values from CONST_AND_COPIES into the uses, vuses and | |
1854 vdef_ops of STMT. */ | |
1855 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1856 static void |
131 | 1857 cprop_into_stmt (gimple *stmt, vr_values *vr_values) |
0 | 1858 { |
1859 use_operand_p op_p; | |
1860 ssa_op_iter iter; | |
111 | 1861 tree last_copy_propagated_op = NULL; |
0 | 1862 |
111 | 1863 FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE) |
0 | 1864 { |
111 | 1865 tree old_op = USE_FROM_PTR (op_p); |
1866 | |
1867 /* If we have A = B and B = A in the copy propagation tables | |
1868 (due to an equality comparison), avoid substituting B for A | |
1869 then A for B in the trivially discovered cases. This allows | |
1870 optimization of statements were A and B appear as input | |
1871 operands. */ | |
1872 if (old_op != last_copy_propagated_op) | |
1873 { | |
131 | 1874 cprop_operand (stmt, op_p, vr_values); |
111 | 1875 |
1876 tree new_op = USE_FROM_PTR (op_p); | |
1877 if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME) | |
1878 last_copy_propagated_op = new_op; | |
1879 } | |
0 | 1880 } |
1881 } | |
1882 | |
111 | 1883 /* If STMT contains a relational test, try to convert it into an |
1884 equality test if there is only a single value which can ever | |
1885 make the test true. | |
1886 | |
1887 For example, if the expression hash table contains: | |
1888 | |
1889 TRUE = (i <= 1) | |
1890 | |
1891 And we have a test within statement of i >= 1, then we can safely | |
1892 rewrite the test as i == 1 since there only a single value where | |
1893 the test is true. | |
1894 | |
1895 This is similar to code in VRP. */ | |
1896 | |
1897 static void | |
1898 test_for_singularity (gimple *stmt, gcond *dummy_cond, | |
1899 avail_exprs_stack *avail_exprs_stack) | |
1900 { | |
1901 /* We want to support gimple conditionals as well as assignments | |
1902 where the RHS contains a conditional. */ | |
1903 if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND) | |
1904 { | |
1905 enum tree_code code = ERROR_MARK; | |
1906 tree lhs, rhs; | |
1907 | |
1908 /* Extract the condition of interest from both forms we support. */ | |
1909 if (is_gimple_assign (stmt)) | |
1910 { | |
1911 code = gimple_assign_rhs_code (stmt); | |
1912 lhs = gimple_assign_rhs1 (stmt); | |
1913 rhs = gimple_assign_rhs2 (stmt); | |
1914 } | |
1915 else if (gimple_code (stmt) == GIMPLE_COND) | |
1916 { | |
1917 code = gimple_cond_code (as_a <gcond *> (stmt)); | |
1918 lhs = gimple_cond_lhs (as_a <gcond *> (stmt)); | |
1919 rhs = gimple_cond_rhs (as_a <gcond *> (stmt)); | |
1920 } | |
1921 | |
1922 /* We're looking for a relational test using LE/GE. Also note we can | |
1923 canonicalize LT/GT tests against constants into LE/GT tests. */ | |
1924 if (code == LE_EXPR || code == GE_EXPR | |
1925 || ((code == LT_EXPR || code == GT_EXPR) | |
1926 && TREE_CODE (rhs) == INTEGER_CST)) | |
1927 { | |
1928 /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR. */ | |
1929 if (code == LT_EXPR) | |
1930 rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs), | |
1931 rhs, build_int_cst (TREE_TYPE (rhs), 1)); | |
1932 | |
1933 if (code == GT_EXPR) | |
1934 rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs), | |
1935 rhs, build_int_cst (TREE_TYPE (rhs), 1)); | |
1936 | |
1937 /* Determine the code we want to check for in the hash table. */ | |
1938 enum tree_code test_code; | |
1939 if (code == GE_EXPR || code == GT_EXPR) | |
1940 test_code = LE_EXPR; | |
1941 else | |
1942 test_code = GE_EXPR; | |
1943 | |
1944 /* Update the dummy statement so we can query the hash tables. */ | |
1945 gimple_cond_set_code (dummy_cond, test_code); | |
1946 gimple_cond_set_lhs (dummy_cond, lhs); | |
1947 gimple_cond_set_rhs (dummy_cond, rhs); | |
1948 tree cached_lhs | |
1949 = avail_exprs_stack->lookup_avail_expr (dummy_cond, false, false); | |
1950 | |
1951 /* If the lookup returned 1 (true), then the expression we | |
1952 queried was in the hash table. As a result there is only | |
1953 one value that makes the original conditional true. Update | |
1954 STMT accordingly. */ | |
1955 if (cached_lhs && integer_onep (cached_lhs)) | |
1956 { | |
1957 if (is_gimple_assign (stmt)) | |
1958 { | |
1959 gimple_assign_set_rhs_code (stmt, EQ_EXPR); | |
1960 gimple_assign_set_rhs2 (stmt, rhs); | |
1961 gimple_set_modified (stmt, true); | |
1962 } | |
1963 else | |
1964 { | |
1965 gimple_set_modified (stmt, true); | |
1966 gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR); | |
1967 gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs); | |
1968 gimple_set_modified (stmt, true); | |
1969 } | |
1970 } | |
1971 } | |
1972 } | |
1973 } | |
1974 | |
1975 /* Optimize the statement in block BB pointed to by iterator SI. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1976 |
0 | 1977 We try to perform some simplistic global redundancy elimination and |
1978 constant propagation: | |
1979 | |
1980 1- To detect global redundancy, we keep track of expressions that have | |
1981 been computed in this block and its dominators. If we find that the | |
1982 same expression is computed more than once, we eliminate repeated | |
1983 computations by using the target of the first one. | |
1984 | |
1985 2- Constant values and copy assignments. This is used to do very | |
1986 simplistic constant and copy propagation. When a constant or copy | |
1987 assignment is found, we map the value on the RHS of the assignment to | |
111 | 1988 the variable in the LHS in the CONST_AND_COPIES table. |
1989 | |
1990 3- Very simple redundant store elimination is performed. | |
0 | 1991 |
145 | 1992 4- We can simplify a condition to a constant or from a relational |
111 | 1993 condition to an equality condition. */ |
1994 | |
1995 edge | |
145 | 1996 dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si, |
1997 bool *removed_p) | |
0 | 1998 { |
111 | 1999 gimple *stmt, *old_stmt; |
0 | 2000 bool may_optimize_p; |
2001 bool modified_p = false; | |
111 | 2002 bool was_noreturn; |
2003 edge retval = NULL; | |
0 | 2004 |
145 | 2005 old_stmt = stmt = gsi_stmt (*si); |
111 | 2006 was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt); |
0 | 2007 |
2008 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2009 { | |
2010 fprintf (dump_file, "Optimizing statement "); | |
2011 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
2012 } | |
2013 | |
111 | 2014 update_stmt_if_modified (stmt); |
2015 opt_stats.num_stmts++; | |
2016 | |
0 | 2017 /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ |
131 | 2018 cprop_into_stmt (stmt, evrp_range_analyzer.get_vr_values ()); |
0 | 2019 |
2020 /* If the statement has been modified with constant replacements, | |
2021 fold its RHS before checking for redundant computations. */ | |
2022 if (gimple_modified_p (stmt)) | |
2023 { | |
2024 tree rhs = NULL; | |
2025 | |
2026 /* Try to fold the statement making sure that STMT is kept | |
2027 up to date. */ | |
145 | 2028 if (fold_stmt (si)) |
0 | 2029 { |
145 | 2030 stmt = gsi_stmt (*si); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2031 gimple_set_modified (stmt, true); |
0 | 2032 |
2033 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2034 { | |
2035 fprintf (dump_file, " Folded to: "); | |
2036 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
2037 } | |
2038 } | |
2039 | |
2040 /* We only need to consider cases that can yield a gimple operand. */ | |
2041 if (gimple_assign_single_p (stmt)) | |
2042 rhs = gimple_assign_rhs1 (stmt); | |
2043 else if (gimple_code (stmt) == GIMPLE_GOTO) | |
2044 rhs = gimple_goto_dest (stmt); | |
111 | 2045 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) |
0 | 2046 /* This should never be an ADDR_EXPR. */ |
111 | 2047 rhs = gimple_switch_index (swtch_stmt); |
0 | 2048 |
2049 if (rhs && TREE_CODE (rhs) == ADDR_EXPR) | |
2050 recompute_tree_invariant_for_addr_expr (rhs); | |
2051 | |
2052 /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called, | |
2053 even if fold_stmt updated the stmt already and thus cleared | |
2054 gimple_modified_p flag on it. */ | |
2055 modified_p = true; | |
2056 } | |
2057 | |
2058 /* Check for redundant computations. Do this optimization only | |
2059 for assignments that have no volatile ops and conditionals. */ | |
111 | 2060 may_optimize_p = (!gimple_has_side_effects (stmt) |
2061 && (is_gimple_assign (stmt) | |
0 | 2062 || (is_gimple_call (stmt) |
111 | 2063 && gimple_call_lhs (stmt) != NULL_TREE) |
0 | 2064 || gimple_code (stmt) == GIMPLE_COND |
2065 || gimple_code (stmt) == GIMPLE_SWITCH)); | |
2066 | |
2067 if (may_optimize_p) | |
2068 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2069 if (gimple_code (stmt) == GIMPLE_CALL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2070 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2071 /* Resolve __builtin_constant_p. If it hasn't been |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2072 folded to integer_one_node by now, it's fairly |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2073 certain that the value simply isn't constant. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2074 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:
47
diff
changeset
|
2075 if (callee |
131 | 2076 && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2077 { |
145 | 2078 propagate_tree_value_into_stmt (si, integer_zero_node); |
2079 stmt = gsi_stmt (*si); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2080 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2081 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2082 |
111 | 2083 if (gimple_code (stmt) == GIMPLE_COND) |
2084 { | |
2085 tree lhs = gimple_cond_lhs (stmt); | |
2086 tree rhs = gimple_cond_rhs (stmt); | |
2087 | |
2088 /* If the LHS has a range [0..1] and the RHS has a range ~[0..1], | |
2089 then this conditional is computable at compile time. We can just | |
2090 shove either 0 or 1 into the LHS, mark the statement as modified | |
2091 and all the right things will just happen below. | |
2092 | |
2093 Note this would apply to any case where LHS has a range | |
2094 narrower than its type implies and RHS is outside that | |
2095 narrower range. Future work. */ | |
2096 if (TREE_CODE (lhs) == SSA_NAME | |
2097 && ssa_name_has_boolean_range (lhs) | |
2098 && TREE_CODE (rhs) == INTEGER_CST | |
2099 && ! (integer_zerop (rhs) || integer_onep (rhs))) | |
2100 { | |
2101 gimple_cond_set_lhs (as_a <gcond *> (stmt), | |
2102 fold_convert (TREE_TYPE (lhs), | |
2103 integer_zero_node)); | |
2104 gimple_set_modified (stmt, true); | |
2105 } | |
131 | 2106 else if (TREE_CODE (lhs) == SSA_NAME) |
2107 { | |
2108 /* Exploiting EVRP data is not yet fully integrated into DOM | |
2109 but we need to do something for this case to avoid regressing | |
2110 udr4.f90 and new1.C which have unexecutable blocks with | |
2111 undefined behavior that get diagnosed if they're left in the | |
2112 IL because we've attached range information to new | |
2113 SSA_NAMES. */ | |
2114 update_stmt_if_modified (stmt); | |
2115 edge taken_edge = NULL; | |
2116 evrp_range_analyzer.vrp_visit_cond_stmt (as_a <gcond *> (stmt), | |
2117 &taken_edge); | |
2118 if (taken_edge) | |
2119 { | |
2120 if (taken_edge->flags & EDGE_TRUE_VALUE) | |
2121 gimple_cond_make_true (as_a <gcond *> (stmt)); | |
2122 else if (taken_edge->flags & EDGE_FALSE_VALUE) | |
2123 gimple_cond_make_false (as_a <gcond *> (stmt)); | |
2124 else | |
2125 gcc_unreachable (); | |
2126 gimple_set_modified (stmt, true); | |
2127 update_stmt (stmt); | |
2128 cfg_altered = true; | |
2129 return taken_edge; | |
2130 } | |
2131 } | |
111 | 2132 } |
2133 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2134 update_stmt_if_modified (stmt); |
145 | 2135 eliminate_redundant_computations (si, m_const_and_copies, |
111 | 2136 m_avail_exprs_stack); |
145 | 2137 stmt = gsi_stmt (*si); |
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
|
2138 |
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
|
2139 /* Perform simple redundant store elimination. */ |
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
|
2140 if (gimple_assign_single_p (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
|
2141 && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_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
|
2142 { |
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
|
2143 tree lhs = gimple_assign_lhs (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
|
2144 tree rhs = gimple_assign_rhs1 (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
|
2145 tree cached_lhs; |
111 | 2146 gassign *new_stmt; |
2147 rhs = dom_valueize (rhs); | |
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
|
2148 /* Build a new statement with the RHS and LHS exchanged. */ |
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
|
2149 if (TREE_CODE (rhs) == SSA_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
|
2150 { |
111 | 2151 gimple *defstmt = SSA_NAME_DEF_STMT (rhs); |
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
|
2152 new_stmt = gimple_build_assign (rhs, lhs); |
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
|
2153 SSA_NAME_DEF_STMT (rhs) = defstmt; |
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
|
2154 } |
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
|
2155 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
|
2156 new_stmt = gimple_build_assign (rhs, lhs); |
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
|
2157 gimple_set_vuse (new_stmt, gimple_vuse (stmt)); |
111 | 2158 cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false, |
2159 false); | |
2160 if (cached_lhs && operand_equal_p (rhs, cached_lhs, 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
|
2161 { |
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
|
2162 basic_block bb = gimple_bb (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
|
2163 unlink_stmt_vdef (stmt); |
145 | 2164 if (gsi_remove (si, 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
|
2165 { |
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
|
2166 bitmap_set_bit (need_eh_cleanup, bb->index); |
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
|
2167 if (dump_file && (dump_flags & TDF_DETAILS)) |
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
|
2168 fprintf (dump_file, " Flagged to clear EH edges.\n"); |
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
|
2169 } |
111 | 2170 release_defs (stmt); |
145 | 2171 *removed_p = true; |
111 | 2172 return retval; |
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
|
2173 } |
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
|
2174 } |
111 | 2175 |
2176 /* If this statement was not redundant, we may still be able to simplify | |
2177 it, which may in turn allow other part of DOM or other passes to do | |
2178 a better job. */ | |
2179 test_for_singularity (stmt, m_dummy_cond, m_avail_exprs_stack); | |
0 | 2180 } |
2181 | |
2182 /* Record any additional equivalences created by this statement. */ | |
2183 if (is_gimple_assign (stmt)) | |
111 | 2184 record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack); |
0 | 2185 |
111 | 2186 /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may |
2187 know where it goes. */ | |
0 | 2188 if (gimple_modified_p (stmt) || modified_p) |
2189 { | |
2190 tree val = NULL; | |
2191 | |
2192 if (gimple_code (stmt) == GIMPLE_COND) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2193 val = fold_binary_loc (gimple_location (stmt), |
111 | 2194 gimple_cond_code (stmt), boolean_type_node, |
2195 gimple_cond_lhs (stmt), | |
2196 gimple_cond_rhs (stmt)); | |
2197 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) | |
2198 val = gimple_switch_index (swtch_stmt); | |
0 | 2199 |
111 | 2200 if (val && TREE_CODE (val) == INTEGER_CST) |
2201 { | |
2202 retval = find_taken_edge (bb, val); | |
2203 if (retval) | |
2204 { | |
2205 /* Fix the condition to be either true or false. */ | |
2206 if (gimple_code (stmt) == GIMPLE_COND) | |
2207 { | |
2208 if (integer_zerop (val)) | |
2209 gimple_cond_make_false (as_a <gcond *> (stmt)); | |
2210 else if (integer_onep (val)) | |
2211 gimple_cond_make_true (as_a <gcond *> (stmt)); | |
2212 else | |
2213 gcc_unreachable (); | |
2214 | |
2215 gimple_set_modified (stmt, true); | |
2216 } | |
2217 | |
2218 /* Further simplifications may be possible. */ | |
2219 cfg_altered = true; | |
2220 } | |
2221 } | |
2222 | |
2223 update_stmt_if_modified (stmt); | |
0 | 2224 |
2225 /* If we simplified a statement in such a way as to be shown that it | |
2226 cannot trap, update the eh information and the cfg to match. */ | |
2227 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) | |
2228 { | |
2229 bitmap_set_bit (need_eh_cleanup, bb->index); | |
2230 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2231 fprintf (dump_file, " Flagged to clear EH edges.\n"); | |
2232 } | |
2233 | |
111 | 2234 if (!was_noreturn |
2235 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)) | |
2236 need_noreturn_fixup.safe_push (stmt); | |
0 | 2237 } |
111 | 2238 return retval; |
0 | 2239 } |