Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-threadedge.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* SSA Jump Threading | 1 /* SSA Jump Threading |
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2005-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 Contributed by Jeff Law <law@redhat.com> | 3 Contributed by Jeff Law <law@redhat.com> |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
20 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
21 | 20 |
22 #include "config.h" | 21 #include "config.h" |
23 #include "system.h" | 22 #include "system.h" |
24 #include "coretypes.h" | 23 #include "coretypes.h" |
25 #include "tm.h" | 24 #include "backend.h" |
26 #include "tree.h" | 25 #include "tree.h" |
27 #include "flags.h" | 26 #include "gimple.h" |
28 #include "tm_p.h" | 27 #include "predict.h" |
29 #include "basic-block.h" | 28 #include "ssa.h" |
29 #include "fold-const.h" | |
30 #include "cfgloop.h" | 30 #include "cfgloop.h" |
31 #include "output.h" | 31 #include "gimple-iterator.h" |
32 #include "function.h" | 32 #include "tree-cfg.h" |
33 #include "timevar.h" | 33 #include "tree-ssa-threadupdate.h" |
34 #include "tree-dump.h" | |
35 #include "tree-flow.h" | |
36 #include "tree-pass.h" | |
37 #include "tree-ssa-propagate.h" | |
38 #include "langhooks.h" | |
39 #include "params.h" | 34 #include "params.h" |
35 #include "tree-ssa-scopedtables.h" | |
36 #include "tree-ssa-threadedge.h" | |
37 #include "tree-ssa-dom.h" | |
38 #include "gimple-fold.h" | |
39 #include "cfganal.h" | |
40 | 40 |
41 /* To avoid code explosion due to jump threading, we limit the | 41 /* To avoid code explosion due to jump threading, we limit the |
42 number of statements we are going to copy. This variable | 42 number of statements we are going to copy. This variable |
43 holds the number of statements currently seen that we'll have | 43 holds the number of statements currently seen that we'll have |
44 to copy as part of the jump threading process. */ | 44 to copy as part of the jump threading process. */ |
45 static int stmt_count; | 45 static int stmt_count; |
46 | 46 |
47 /* Array to record value-handles per SSA_NAME. */ | 47 /* Array to record value-handles per SSA_NAME. */ |
48 VEC(tree,heap) *ssa_name_values; | 48 vec<tree> ssa_name_values; |
49 | |
50 typedef tree (pfn_simplify) (gimple *, gimple *, | |
51 class avail_exprs_stack *, | |
52 basic_block); | |
49 | 53 |
50 /* Set the value for the SSA name NAME to VALUE. */ | 54 /* Set the value for the SSA name NAME to VALUE. */ |
51 | 55 |
52 void | 56 void |
53 set_ssa_name_value (tree name, tree value) | 57 set_ssa_name_value (tree name, tree value) |
54 { | 58 { |
55 if (SSA_NAME_VERSION (name) >= VEC_length (tree, ssa_name_values)) | 59 if (SSA_NAME_VERSION (name) >= ssa_name_values.length ()) |
56 VEC_safe_grow_cleared (tree, heap, ssa_name_values, | 60 ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1); |
57 SSA_NAME_VERSION (name) + 1); | 61 if (value && TREE_OVERFLOW_P (value)) |
58 VEC_replace (tree, ssa_name_values, SSA_NAME_VERSION (name), value); | 62 value = drop_tree_overflow (value); |
63 ssa_name_values[SSA_NAME_VERSION (name)] = value; | |
59 } | 64 } |
60 | 65 |
61 /* Initialize the per SSA_NAME value-handles array. Returns it. */ | 66 /* Initialize the per SSA_NAME value-handles array. Returns it. */ |
62 void | 67 void |
63 threadedge_initialize_values (void) | 68 threadedge_initialize_values (void) |
64 { | 69 { |
65 gcc_assert (ssa_name_values == NULL); | 70 gcc_assert (!ssa_name_values.exists ()); |
66 ssa_name_values = VEC_alloc(tree, heap, num_ssa_names); | 71 ssa_name_values.create (num_ssa_names); |
67 } | 72 } |
68 | 73 |
69 /* Free the per SSA_NAME value-handle array. */ | 74 /* Free the per SSA_NAME value-handle array. */ |
70 void | 75 void |
71 threadedge_finalize_values (void) | 76 threadedge_finalize_values (void) |
72 { | 77 { |
73 VEC_free(tree, heap, ssa_name_values); | 78 ssa_name_values.release (); |
74 } | 79 } |
75 | 80 |
76 /* Return TRUE if we may be able to thread an incoming edge into | 81 /* Return TRUE if we may be able to thread an incoming edge into |
77 BB to an outgoing edge from BB. Return FALSE otherwise. */ | 82 BB to an outgoing edge from BB. Return FALSE otherwise. */ |
78 | 83 |
79 bool | 84 bool |
80 potentially_threadable_block (basic_block bb) | 85 potentially_threadable_block (basic_block bb) |
81 { | 86 { |
82 gimple_stmt_iterator gsi; | 87 gimple_stmt_iterator gsi; |
88 | |
89 /* Special case. We can get blocks that are forwarders, but are | |
90 not optimized away because they forward from outside a loop | |
91 to the loop header. We want to thread through them as we can | |
92 sometimes thread to the loop exit, which is obviously profitable. | |
93 the interesting case here is when the block has PHIs. */ | |
94 if (gsi_end_p (gsi_start_nondebug_bb (bb)) | |
95 && !gsi_end_p (gsi_start_phis (bb))) | |
96 return true; | |
83 | 97 |
84 /* If BB has a single successor or a single predecessor, then | 98 /* If BB has a single successor or a single predecessor, then |
85 there is no threading opportunity. */ | 99 there is no threading opportunity. */ |
86 if (single_succ_p (bb) || single_pred_p (bb)) | 100 if (single_succ_p (bb) || single_pred_p (bb)) |
87 return false; | 101 return false; |
97 return false; | 111 return false; |
98 | 112 |
99 return true; | 113 return true; |
100 } | 114 } |
101 | 115 |
102 /* Return the LHS of any ASSERT_EXPR where OP appears as the first | |
103 argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates | |
104 BB. If no such ASSERT_EXPR is found, return OP. */ | |
105 | |
106 static tree | |
107 lhs_of_dominating_assert (tree op, basic_block bb, gimple stmt) | |
108 { | |
109 imm_use_iterator imm_iter; | |
110 gimple use_stmt; | |
111 use_operand_p use_p; | |
112 | |
113 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op) | |
114 { | |
115 use_stmt = USE_STMT (use_p); | |
116 if (use_stmt != stmt | |
117 && gimple_assign_single_p (use_stmt) | |
118 && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR | |
119 && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op | |
120 && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt))) | |
121 { | |
122 return gimple_assign_lhs (use_stmt); | |
123 } | |
124 } | |
125 return op; | |
126 } | |
127 | |
128 /* We record temporary equivalences created by PHI nodes or | |
129 statements within the target block. Doing so allows us to | |
130 identify more jump threading opportunities, even in blocks | |
131 with side effects. | |
132 | |
133 We keep track of those temporary equivalences in a stack | |
134 structure so that we can unwind them when we're done processing | |
135 a particular edge. This routine handles unwinding the data | |
136 structures. */ | |
137 | |
138 static void | |
139 remove_temporary_equivalences (VEC(tree, heap) **stack) | |
140 { | |
141 while (VEC_length (tree, *stack) > 0) | |
142 { | |
143 tree prev_value, dest; | |
144 | |
145 dest = VEC_pop (tree, *stack); | |
146 | |
147 /* A NULL value indicates we should stop unwinding, otherwise | |
148 pop off the next entry as they're recorded in pairs. */ | |
149 if (dest == NULL) | |
150 break; | |
151 | |
152 prev_value = VEC_pop (tree, *stack); | |
153 set_ssa_name_value (dest, prev_value); | |
154 } | |
155 } | |
156 | |
157 /* Record a temporary equivalence, saving enough information so that | |
158 we can restore the state of recorded equivalences when we're | |
159 done processing the current edge. */ | |
160 | |
161 static void | |
162 record_temporary_equivalence (tree x, tree y, VEC(tree, heap) **stack) | |
163 { | |
164 tree prev_x = SSA_NAME_VALUE (x); | |
165 | |
166 if (TREE_CODE (y) == SSA_NAME) | |
167 { | |
168 tree tmp = SSA_NAME_VALUE (y); | |
169 y = tmp ? tmp : y; | |
170 } | |
171 | |
172 set_ssa_name_value (x, y); | |
173 VEC_reserve (tree, heap, *stack, 2); | |
174 VEC_quick_push (tree, *stack, prev_x); | |
175 VEC_quick_push (tree, *stack, x); | |
176 } | |
177 | |
178 /* Record temporary equivalences created by PHIs at the target of the | 116 /* Record temporary equivalences created by PHIs at the target of the |
179 edge E. Record unwind information for the equivalences onto STACK. | 117 edge E. Record unwind information for the equivalences onto STACK. |
180 | 118 |
181 If a PHI which prevents threading is encountered, then return FALSE | 119 If a PHI which prevents threading is encountered, then return FALSE |
182 indicating we should not thread this edge, else return TRUE. */ | 120 indicating we should not thread this edge, else return TRUE. |
121 | |
122 If SRC_MAP/DST_MAP exist, then mark the source and destination SSA_NAMEs | |
123 of any equivalences recorded. We use this to make invalidation after | |
124 traversing back edges less painful. */ | |
183 | 125 |
184 static bool | 126 static bool |
185 record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack) | 127 record_temporary_equivalences_from_phis (edge e, const_and_copies *const_and_copies) |
186 { | 128 { |
187 gimple_stmt_iterator gsi; | 129 gphi_iterator gsi; |
188 | 130 |
189 /* Each PHI creates a temporary equivalence, record them. | 131 /* Each PHI creates a temporary equivalence, record them. |
190 These are context sensitive equivalences and will be removed | 132 These are context sensitive equivalences and will be removed |
191 later. */ | 133 later. */ |
192 for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) | 134 for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) |
193 { | 135 { |
194 gimple phi = gsi_stmt (gsi); | 136 gphi *phi = gsi.phi (); |
195 tree src = PHI_ARG_DEF_FROM_EDGE (phi, e); | 137 tree src = PHI_ARG_DEF_FROM_EDGE (phi, e); |
196 tree dst = gimple_phi_result (phi); | 138 tree dst = gimple_phi_result (phi); |
197 | 139 |
198 /* If the desired argument is not the same as this PHI's result | 140 /* If the desired argument is not the same as this PHI's result |
199 and it is set by a PHI in E->dest, then we can not thread | 141 and it is set by a PHI in E->dest, then we can not thread |
204 && gimple_bb (SSA_NAME_DEF_STMT (src)) == e->dest) | 146 && gimple_bb (SSA_NAME_DEF_STMT (src)) == e->dest) |
205 return false; | 147 return false; |
206 | 148 |
207 /* We consider any non-virtual PHI as a statement since it | 149 /* We consider any non-virtual PHI as a statement since it |
208 count result in a constant assignment or copy operation. */ | 150 count result in a constant assignment or copy operation. */ |
209 if (is_gimple_reg (dst)) | 151 if (!virtual_operand_p (dst)) |
210 stmt_count++; | 152 stmt_count++; |
211 | 153 |
212 record_temporary_equivalence (dst, src, stack); | 154 const_and_copies->record_const_or_copy (dst, src); |
213 } | 155 } |
214 return true; | 156 return true; |
215 } | 157 } |
216 | 158 |
217 /* Fold the RHS of an assignment statement and return it as a tree. | 159 /* Valueize hook for gimple_fold_stmt_to_constant_1. */ |
218 May return NULL_TREE if no simplification is possible. */ | |
219 | 160 |
220 static tree | 161 static tree |
221 fold_assignment_stmt (gimple stmt) | 162 threadedge_valueize (tree t) |
222 { | 163 { |
223 enum tree_code subcode = gimple_assign_rhs_code (stmt); | 164 if (TREE_CODE (t) == SSA_NAME) |
224 | 165 { |
225 switch (get_gimple_rhs_class (subcode)) | 166 tree tem = SSA_NAME_VALUE (t); |
226 { | 167 if (tem) |
227 case GIMPLE_SINGLE_RHS: | 168 return tem; |
228 { | 169 } |
229 tree rhs = gimple_assign_rhs1 (stmt); | 170 return t; |
230 | |
231 if (TREE_CODE (rhs) == COND_EXPR) | |
232 { | |
233 /* Sadly, we have to handle conditional assignments specially | |
234 here, because fold expects all the operands of an expression | |
235 to be folded before the expression itself is folded, but we | |
236 can't just substitute the folded condition here. */ | |
237 tree cond = fold (COND_EXPR_COND (rhs)); | |
238 if (cond == boolean_true_node) | |
239 rhs = COND_EXPR_THEN (rhs); | |
240 else if (cond == boolean_false_node) | |
241 rhs = COND_EXPR_ELSE (rhs); | |
242 } | |
243 | |
244 return fold (rhs); | |
245 } | |
246 | |
247 case GIMPLE_UNARY_RHS: | |
248 { | |
249 tree lhs = gimple_assign_lhs (stmt); | |
250 tree op0 = gimple_assign_rhs1 (stmt); | |
251 return fold_unary (subcode, TREE_TYPE (lhs), op0); | |
252 } | |
253 | |
254 case GIMPLE_BINARY_RHS: | |
255 { | |
256 tree lhs = gimple_assign_lhs (stmt); | |
257 tree op0 = gimple_assign_rhs1 (stmt); | |
258 tree op1 = gimple_assign_rhs2 (stmt); | |
259 return fold_binary (subcode, TREE_TYPE (lhs), op0, op1); | |
260 } | |
261 | |
262 case GIMPLE_TERNARY_RHS: | |
263 { | |
264 tree lhs = gimple_assign_lhs (stmt); | |
265 tree op0 = gimple_assign_rhs1 (stmt); | |
266 tree op1 = gimple_assign_rhs2 (stmt); | |
267 tree op2 = gimple_assign_rhs3 (stmt); | |
268 return fold_ternary (subcode, TREE_TYPE (lhs), op0, op1, op2); | |
269 } | |
270 | |
271 default: | |
272 gcc_unreachable (); | |
273 } | |
274 } | 171 } |
275 | 172 |
276 /* Try to simplify each statement in E->dest, ultimately leading to | 173 /* Try to simplify each statement in E->dest, ultimately leading to |
277 a simplification of the COND_EXPR at the end of E->dest. | 174 a simplification of the COND_EXPR at the end of E->dest. |
278 | 175 |
288 If we are able to simplify a statement into the form | 185 If we are able to simplify a statement into the form |
289 SSA_NAME = (SSA_NAME | gimple invariant), then we can record | 186 SSA_NAME = (SSA_NAME | gimple invariant), then we can record |
290 a context sensitive equivalence which may help us simplify | 187 a context sensitive equivalence which may help us simplify |
291 later statements in E->dest. */ | 188 later statements in E->dest. */ |
292 | 189 |
293 static gimple | 190 static gimple * |
294 record_temporary_equivalences_from_stmts_at_dest (edge e, | 191 record_temporary_equivalences_from_stmts_at_dest (edge e, |
295 VEC(tree, heap) **stack, | 192 const_and_copies *const_and_copies, |
296 tree (*simplify) (gimple, | 193 avail_exprs_stack *avail_exprs_stack, |
297 gimple)) | 194 pfn_simplify simplify) |
298 { | 195 { |
299 gimple stmt = NULL; | 196 gimple *stmt = NULL; |
300 gimple_stmt_iterator gsi; | 197 gimple_stmt_iterator gsi; |
301 int max_stmt_count; | 198 int max_stmt_count; |
302 | 199 |
303 max_stmt_count = PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS); | 200 max_stmt_count = PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS); |
304 | 201 |
319 continue; | 216 continue; |
320 | 217 |
321 /* If the statement has volatile operands, then we assume we | 218 /* If the statement has volatile operands, then we assume we |
322 can not thread through this block. This is overly | 219 can not thread through this block. This is overly |
323 conservative in some ways. */ | 220 conservative in some ways. */ |
324 if (gimple_code (stmt) == GIMPLE_ASM && gimple_asm_volatile_p (stmt)) | 221 if (gimple_code (stmt) == GIMPLE_ASM |
222 && gimple_asm_volatile_p (as_a <gasm *> (stmt))) | |
223 return NULL; | |
224 | |
225 /* If the statement is a unique builtin, we can not thread | |
226 through here. */ | |
227 if (gimple_code (stmt) == GIMPLE_CALL | |
228 && gimple_call_internal_p (stmt) | |
229 && gimple_call_internal_unique_p (stmt)) | |
325 return NULL; | 230 return NULL; |
326 | 231 |
327 /* If duplicating this block is going to cause too much code | 232 /* If duplicating this block is going to cause too much code |
328 expansion, then do not thread through this block. */ | 233 expansion, then do not thread through this block. */ |
329 stmt_count++; | 234 stmt_count++; |
388 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR) | 293 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR) |
389 cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); | 294 cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); |
390 else | 295 else |
391 { | 296 { |
392 /* A statement that is not a trivial copy or ASSERT_EXPR. | 297 /* A statement that is not a trivial copy or ASSERT_EXPR. |
393 We're going to temporarily copy propagate the operands | 298 Try to fold the new expression. Inserting the |
394 and see if that allows us to simplify this statement. */ | 299 expression into the hash table is unlikely to help. */ |
395 tree *copy; | 300 /* ??? The DOM callback below can be changed to setting |
396 ssa_op_iter iter; | 301 the mprts_hook around the call to thread_across_edge, |
397 use_operand_p use_p; | 302 avoiding the use substitution. The VRP hook should be |
398 unsigned int num, i = 0; | 303 changed to properly valueize operands itself using |
399 | 304 SSA_NAME_VALUE in addition to its own lattice. */ |
400 num = NUM_SSA_OPERANDS (stmt, (SSA_OP_USE | SSA_OP_VUSE)); | 305 cached_lhs = gimple_fold_stmt_to_constant_1 (stmt, |
401 copy = XCNEWVEC (tree, num); | 306 threadedge_valueize); |
402 | 307 if (NUM_SSA_OPERANDS (stmt, SSA_OP_ALL_USES) != 0 |
403 /* Make a copy of the uses & vuses into USES_COPY, then cprop into | 308 && (!cached_lhs |
404 the operands. */ | 309 || (TREE_CODE (cached_lhs) != SSA_NAME |
405 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE) | 310 && !is_gimple_min_invariant (cached_lhs)))) |
406 { | 311 { |
407 tree tmp = NULL; | 312 /* We're going to temporarily copy propagate the operands |
408 tree use = USE_FROM_PTR (use_p); | 313 and see if that allows us to simplify this statement. */ |
409 | 314 tree *copy; |
410 copy[i++] = use; | 315 ssa_op_iter iter; |
411 if (TREE_CODE (use) == SSA_NAME) | 316 use_operand_p use_p; |
412 tmp = SSA_NAME_VALUE (use); | 317 unsigned int num, i = 0; |
413 if (tmp) | 318 |
414 SET_USE (use_p, tmp); | 319 num = NUM_SSA_OPERANDS (stmt, SSA_OP_ALL_USES); |
320 copy = XALLOCAVEC (tree, num); | |
321 | |
322 /* Make a copy of the uses & vuses into USES_COPY, then cprop into | |
323 the operands. */ | |
324 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) | |
325 { | |
326 tree tmp = NULL; | |
327 tree use = USE_FROM_PTR (use_p); | |
328 | |
329 copy[i++] = use; | |
330 if (TREE_CODE (use) == SSA_NAME) | |
331 tmp = SSA_NAME_VALUE (use); | |
332 if (tmp) | |
333 SET_USE (use_p, tmp); | |
334 } | |
335 | |
336 cached_lhs = (*simplify) (stmt, stmt, avail_exprs_stack, e->src); | |
337 | |
338 /* Restore the statement's original uses/defs. */ | |
339 i = 0; | |
340 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) | |
341 SET_USE (use_p, copy[i++]); | |
415 } | 342 } |
416 | |
417 /* Try to fold/lookup the new expression. Inserting the | |
418 expression into the hash table is unlikely to help. */ | |
419 if (is_gimple_call (stmt)) | |
420 cached_lhs = fold_call_stmt (stmt, false); | |
421 else | |
422 cached_lhs = fold_assignment_stmt (stmt); | |
423 | |
424 if (!cached_lhs | |
425 || (TREE_CODE (cached_lhs) != SSA_NAME | |
426 && !is_gimple_min_invariant (cached_lhs))) | |
427 cached_lhs = (*simplify) (stmt, stmt); | |
428 | |
429 /* Restore the statement's original uses/defs. */ | |
430 i = 0; | |
431 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE) | |
432 SET_USE (use_p, copy[i++]); | |
433 | |
434 free (copy); | |
435 } | 343 } |
436 | 344 |
437 /* Record the context sensitive equivalence if we were able | 345 /* Record the context sensitive equivalence if we were able |
438 to simplify this statement. */ | 346 to simplify this statement. */ |
439 if (cached_lhs | 347 if (cached_lhs |
440 && (TREE_CODE (cached_lhs) == SSA_NAME | 348 && (TREE_CODE (cached_lhs) == SSA_NAME |
441 || is_gimple_min_invariant (cached_lhs))) | 349 || is_gimple_min_invariant (cached_lhs))) |
442 record_temporary_equivalence (gimple_get_lhs (stmt), cached_lhs, stack); | 350 const_and_copies->record_const_or_copy (gimple_get_lhs (stmt), |
351 cached_lhs); | |
443 } | 352 } |
444 return stmt; | 353 return stmt; |
445 } | 354 } |
446 | 355 |
356 static tree simplify_control_stmt_condition_1 (edge, gimple *, | |
357 class avail_exprs_stack *, | |
358 tree, enum tree_code, tree, | |
359 gcond *, pfn_simplify, | |
360 unsigned); | |
361 | |
447 /* Simplify the control statement at the end of the block E->dest. | 362 /* Simplify the control statement at the end of the block E->dest. |
448 | 363 |
449 To avoid allocating memory unnecessarily, a scratch GIMPLE_COND | 364 To avoid allocating memory unnecessarily, a scratch GIMPLE_COND |
450 is available to use/clobber in DUMMY_COND. | 365 is available to use/clobber in DUMMY_COND. |
451 | 366 |
452 Use SIMPLIFY (a pointer to a callback function) to further simplify | 367 Use SIMPLIFY (a pointer to a callback function) to further simplify |
453 a condition using pass specific information. | 368 a condition using pass specific information. |
454 | 369 |
455 Return the simplified condition or NULL if simplification could | 370 Return the simplified condition or NULL if simplification could |
456 not be performed. */ | 371 not be performed. When simplifying a GIMPLE_SWITCH, we may return |
372 the CASE_LABEL_EXPR that will be taken. | |
373 | |
374 The available expression table is referenced via AVAIL_EXPRS_STACK. */ | |
457 | 375 |
458 static tree | 376 static tree |
459 simplify_control_stmt_condition (edge e, | 377 simplify_control_stmt_condition (edge e, |
460 gimple stmt, | 378 gimple *stmt, |
461 gimple dummy_cond, | 379 class avail_exprs_stack *avail_exprs_stack, |
462 tree (*simplify) (gimple, gimple), | 380 gcond *dummy_cond, |
463 bool handle_dominating_asserts) | 381 pfn_simplify simplify) |
464 { | 382 { |
465 tree cond, cached_lhs; | 383 tree cond, cached_lhs; |
466 enum gimple_code code = gimple_code (stmt); | 384 enum gimple_code code = gimple_code (stmt); |
467 | 385 |
468 /* For comparisons, we have to update both operands, then try | 386 /* For comparisons, we have to update both operands, then try |
477 cond_code = gimple_cond_code (stmt); | 395 cond_code = gimple_cond_code (stmt); |
478 | 396 |
479 /* Get the current value of both operands. */ | 397 /* Get the current value of both operands. */ |
480 if (TREE_CODE (op0) == SSA_NAME) | 398 if (TREE_CODE (op0) == SSA_NAME) |
481 { | 399 { |
482 tree tmp = SSA_NAME_VALUE (op0); | 400 for (int i = 0; i < 2; i++) |
483 if (tmp) | 401 { |
484 op0 = tmp; | 402 if (TREE_CODE (op0) == SSA_NAME |
403 && SSA_NAME_VALUE (op0)) | |
404 op0 = SSA_NAME_VALUE (op0); | |
405 else | |
406 break; | |
407 } | |
485 } | 408 } |
486 | 409 |
487 if (TREE_CODE (op1) == SSA_NAME) | 410 if (TREE_CODE (op1) == SSA_NAME) |
488 { | 411 { |
489 tree tmp = SSA_NAME_VALUE (op1); | 412 for (int i = 0; i < 2; i++) |
490 if (tmp) | 413 { |
491 op1 = tmp; | 414 if (TREE_CODE (op1) == SSA_NAME |
415 && SSA_NAME_VALUE (op1)) | |
416 op1 = SSA_NAME_VALUE (op1); | |
417 else | |
418 break; | |
419 } | |
492 } | 420 } |
493 | 421 |
494 if (handle_dominating_asserts) | 422 const unsigned recursion_limit = 4; |
423 | |
424 cached_lhs | |
425 = simplify_control_stmt_condition_1 (e, stmt, avail_exprs_stack, | |
426 op0, cond_code, op1, | |
427 dummy_cond, simplify, | |
428 recursion_limit); | |
429 | |
430 /* If we were testing an integer/pointer against a constant, then | |
431 we can use the FSM code to trace the value of the SSA_NAME. If | |
432 a value is found, then the condition will collapse to a constant. | |
433 | |
434 Return the SSA_NAME we want to trace back rather than the full | |
435 expression and give the FSM threader a chance to find its value. */ | |
436 if (cached_lhs == NULL) | |
495 { | 437 { |
496 /* Now see if the operand was consumed by an ASSERT_EXPR | 438 /* Recover the original operands. They may have been simplified |
497 which dominates E->src. If so, we want to replace the | 439 using context sensitive equivalences. Those context sensitive |
498 operand with the LHS of the ASSERT_EXPR. */ | 440 equivalences may not be valid on paths found by the FSM optimizer. */ |
499 if (TREE_CODE (op0) == SSA_NAME) | 441 tree op0 = gimple_cond_lhs (stmt); |
500 op0 = lhs_of_dominating_assert (op0, e->src, stmt); | 442 tree op1 = gimple_cond_rhs (stmt); |
501 | 443 |
502 if (TREE_CODE (op1) == SSA_NAME) | 444 if ((INTEGRAL_TYPE_P (TREE_TYPE (op0)) |
503 op1 = lhs_of_dominating_assert (op1, e->src, stmt); | 445 || POINTER_TYPE_P (TREE_TYPE (op0))) |
446 && TREE_CODE (op0) == SSA_NAME | |
447 && TREE_CODE (op1) == INTEGER_CST) | |
448 return op0; | |
504 } | 449 } |
505 | 450 |
506 /* We may need to canonicalize the comparison. For | |
507 example, op0 might be a constant while op1 is an | |
508 SSA_NAME. Failure to canonicalize will cause us to | |
509 miss threading opportunities. */ | |
510 if (tree_swap_operands_p (op0, op1, false)) | |
511 { | |
512 tree tmp; | |
513 cond_code = swap_tree_comparison (cond_code); | |
514 tmp = op0; | |
515 op0 = op1; | |
516 op1 = tmp; | |
517 } | |
518 | |
519 /* Stuff the operator and operands into our dummy conditional | |
520 expression. */ | |
521 gimple_cond_set_code (dummy_cond, cond_code); | |
522 gimple_cond_set_lhs (dummy_cond, op0); | |
523 gimple_cond_set_rhs (dummy_cond, op1); | |
524 | |
525 /* We absolutely do not care about any type conversions | |
526 we only care about a zero/nonzero value. */ | |
527 fold_defer_overflow_warnings (); | |
528 | |
529 cached_lhs = fold_binary (cond_code, boolean_type_node, op0, op1); | |
530 if (cached_lhs) | |
531 while (CONVERT_EXPR_P (cached_lhs)) | |
532 cached_lhs = TREE_OPERAND (cached_lhs, 0); | |
533 | |
534 fold_undefer_overflow_warnings ((cached_lhs | |
535 && is_gimple_min_invariant (cached_lhs)), | |
536 stmt, WARN_STRICT_OVERFLOW_CONDITIONAL); | |
537 | |
538 /* If we have not simplified the condition down to an invariant, | |
539 then use the pass specific callback to simplify the condition. */ | |
540 if (!cached_lhs | |
541 || !is_gimple_min_invariant (cached_lhs)) | |
542 cached_lhs = (*simplify) (dummy_cond, stmt); | |
543 | |
544 return cached_lhs; | 451 return cached_lhs; |
545 } | 452 } |
546 | 453 |
547 if (code == GIMPLE_SWITCH) | 454 if (code == GIMPLE_SWITCH) |
548 cond = gimple_switch_index (stmt); | 455 cond = gimple_switch_index (as_a <gswitch *> (stmt)); |
549 else if (code == GIMPLE_GOTO) | 456 else if (code == GIMPLE_GOTO) |
550 cond = gimple_goto_dest (stmt); | 457 cond = gimple_goto_dest (stmt); |
551 else | 458 else |
552 gcc_unreachable (); | 459 gcc_unreachable (); |
553 | 460 |
554 /* We can have conditionals which just test the state of a variable | 461 /* We can have conditionals which just test the state of a variable |
555 rather than use a relational operator. These are simpler to handle. */ | 462 rather than use a relational operator. These are simpler to handle. */ |
556 if (TREE_CODE (cond) == SSA_NAME) | 463 if (TREE_CODE (cond) == SSA_NAME) |
557 { | 464 { |
465 tree original_lhs = cond; | |
558 cached_lhs = cond; | 466 cached_lhs = cond; |
559 | 467 |
560 /* Get the variable's current value from the equivalence chains. | 468 /* Get the variable's current value from the equivalence chains. |
561 | 469 |
562 It is possible to get loops in the SSA_NAME_VALUE chains | 470 It is possible to get loops in the SSA_NAME_VALUE chains |
563 (consider threading the backedge of a loop where we have | 471 (consider threading the backedge of a loop where we have |
564 a loop invariant SSA_NAME used in the condition. */ | 472 a loop invariant SSA_NAME used in the condition). */ |
565 if (cached_lhs | 473 if (cached_lhs) |
566 && TREE_CODE (cached_lhs) == SSA_NAME | 474 { |
567 && SSA_NAME_VALUE (cached_lhs)) | 475 for (int i = 0; i < 2; i++) |
568 cached_lhs = SSA_NAME_VALUE (cached_lhs); | 476 { |
569 | 477 if (TREE_CODE (cached_lhs) == SSA_NAME |
570 /* If we're dominated by a suitable ASSERT_EXPR, then | 478 && SSA_NAME_VALUE (cached_lhs)) |
571 update CACHED_LHS appropriately. */ | 479 cached_lhs = SSA_NAME_VALUE (cached_lhs); |
572 if (handle_dominating_asserts && TREE_CODE (cached_lhs) == SSA_NAME) | 480 else |
573 cached_lhs = lhs_of_dominating_assert (cached_lhs, e->src, stmt); | 481 break; |
482 } | |
483 } | |
574 | 484 |
575 /* If we haven't simplified to an invariant yet, then use the | 485 /* If we haven't simplified to an invariant yet, then use the |
576 pass specific callback to try and simplify it further. */ | 486 pass specific callback to try and simplify it further. */ |
577 if (cached_lhs && ! is_gimple_min_invariant (cached_lhs)) | 487 if (cached_lhs && ! is_gimple_min_invariant (cached_lhs)) |
578 cached_lhs = (*simplify) (stmt, stmt); | 488 { |
489 if (code == GIMPLE_SWITCH) | |
490 { | |
491 /* Replace the index operand of the GIMPLE_SWITCH with any LHS | |
492 we found before handing off to VRP. If simplification is | |
493 possible, the simplified value will be a CASE_LABEL_EXPR of | |
494 the label that is proven to be taken. */ | |
495 gswitch *dummy_switch = as_a<gswitch *> (gimple_copy (stmt)); | |
496 gimple_switch_set_index (dummy_switch, cached_lhs); | |
497 cached_lhs = (*simplify) (dummy_switch, stmt, | |
498 avail_exprs_stack, e->src); | |
499 ggc_free (dummy_switch); | |
500 } | |
501 else | |
502 cached_lhs = (*simplify) (stmt, stmt, avail_exprs_stack, e->src); | |
503 } | |
504 | |
505 /* We couldn't find an invariant. But, callers of this | |
506 function may be able to do something useful with the | |
507 unmodified destination. */ | |
508 if (!cached_lhs) | |
509 cached_lhs = original_lhs; | |
579 } | 510 } |
580 else | 511 else |
581 cached_lhs = NULL; | 512 cached_lhs = NULL; |
582 | 513 |
583 return cached_lhs; | 514 return cached_lhs; |
584 } | 515 } |
585 | 516 |
517 /* Recursive helper for simplify_control_stmt_condition. */ | |
518 | |
519 static tree | |
520 simplify_control_stmt_condition_1 (edge e, | |
521 gimple *stmt, | |
522 class avail_exprs_stack *avail_exprs_stack, | |
523 tree op0, | |
524 enum tree_code cond_code, | |
525 tree op1, | |
526 gcond *dummy_cond, | |
527 pfn_simplify simplify, | |
528 unsigned limit) | |
529 { | |
530 if (limit == 0) | |
531 return NULL_TREE; | |
532 | |
533 /* We may need to canonicalize the comparison. For | |
534 example, op0 might be a constant while op1 is an | |
535 SSA_NAME. Failure to canonicalize will cause us to | |
536 miss threading opportunities. */ | |
537 if (tree_swap_operands_p (op0, op1)) | |
538 { | |
539 cond_code = swap_tree_comparison (cond_code); | |
540 std::swap (op0, op1); | |
541 } | |
542 | |
543 /* If the condition has the form (A & B) CMP 0 or (A | B) CMP 0 then | |
544 recurse into the LHS to see if there is a dominating ASSERT_EXPR | |
545 of A or of B that makes this condition always true or always false | |
546 along the edge E. */ | |
547 if ((cond_code == EQ_EXPR || cond_code == NE_EXPR) | |
548 && TREE_CODE (op0) == SSA_NAME | |
549 && integer_zerop (op1)) | |
550 { | |
551 gimple *def_stmt = SSA_NAME_DEF_STMT (op0); | |
552 if (gimple_code (def_stmt) != GIMPLE_ASSIGN) | |
553 ; | |
554 else if (gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR | |
555 || gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR) | |
556 { | |
557 enum tree_code rhs_code = gimple_assign_rhs_code (def_stmt); | |
558 const tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
559 const tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
560 | |
561 /* Is A != 0 ? */ | |
562 const tree res1 | |
563 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack, | |
564 rhs1, NE_EXPR, op1, | |
565 dummy_cond, simplify, | |
566 limit - 1); | |
567 if (res1 == NULL_TREE) | |
568 ; | |
569 else if (rhs_code == BIT_AND_EXPR && integer_zerop (res1)) | |
570 { | |
571 /* If A == 0 then (A & B) != 0 is always false. */ | |
572 if (cond_code == NE_EXPR) | |
573 return boolean_false_node; | |
574 /* If A == 0 then (A & B) == 0 is always true. */ | |
575 if (cond_code == EQ_EXPR) | |
576 return boolean_true_node; | |
577 } | |
578 else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res1)) | |
579 { | |
580 /* If A != 0 then (A | B) != 0 is always true. */ | |
581 if (cond_code == NE_EXPR) | |
582 return boolean_true_node; | |
583 /* If A != 0 then (A | B) == 0 is always false. */ | |
584 if (cond_code == EQ_EXPR) | |
585 return boolean_false_node; | |
586 } | |
587 | |
588 /* Is B != 0 ? */ | |
589 const tree res2 | |
590 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack, | |
591 rhs2, NE_EXPR, op1, | |
592 dummy_cond, simplify, | |
593 limit - 1); | |
594 if (res2 == NULL_TREE) | |
595 ; | |
596 else if (rhs_code == BIT_AND_EXPR && integer_zerop (res2)) | |
597 { | |
598 /* If B == 0 then (A & B) != 0 is always false. */ | |
599 if (cond_code == NE_EXPR) | |
600 return boolean_false_node; | |
601 /* If B == 0 then (A & B) == 0 is always true. */ | |
602 if (cond_code == EQ_EXPR) | |
603 return boolean_true_node; | |
604 } | |
605 else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res2)) | |
606 { | |
607 /* If B != 0 then (A | B) != 0 is always true. */ | |
608 if (cond_code == NE_EXPR) | |
609 return boolean_true_node; | |
610 /* If B != 0 then (A | B) == 0 is always false. */ | |
611 if (cond_code == EQ_EXPR) | |
612 return boolean_false_node; | |
613 } | |
614 | |
615 if (res1 != NULL_TREE && res2 != NULL_TREE) | |
616 { | |
617 if (rhs_code == BIT_AND_EXPR | |
618 && TYPE_PRECISION (TREE_TYPE (op0)) == 1 | |
619 && integer_nonzerop (res1) | |
620 && integer_nonzerop (res2)) | |
621 { | |
622 /* If A != 0 and B != 0 then (bool)(A & B) != 0 is true. */ | |
623 if (cond_code == NE_EXPR) | |
624 return boolean_true_node; | |
625 /* If A != 0 and B != 0 then (bool)(A & B) == 0 is false. */ | |
626 if (cond_code == EQ_EXPR) | |
627 return boolean_false_node; | |
628 } | |
629 | |
630 if (rhs_code == BIT_IOR_EXPR | |
631 && integer_zerop (res1) | |
632 && integer_zerop (res2)) | |
633 { | |
634 /* If A == 0 and B == 0 then (A | B) != 0 is false. */ | |
635 if (cond_code == NE_EXPR) | |
636 return boolean_false_node; | |
637 /* If A == 0 and B == 0 then (A | B) == 0 is true. */ | |
638 if (cond_code == EQ_EXPR) | |
639 return boolean_true_node; | |
640 } | |
641 } | |
642 } | |
643 /* Handle (A CMP B) CMP 0. */ | |
644 else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) | |
645 == tcc_comparison) | |
646 { | |
647 tree rhs1 = gimple_assign_rhs1 (def_stmt); | |
648 tree rhs2 = gimple_assign_rhs2 (def_stmt); | |
649 | |
650 tree_code new_cond = gimple_assign_rhs_code (def_stmt); | |
651 if (cond_code == EQ_EXPR) | |
652 new_cond = invert_tree_comparison (new_cond, false); | |
653 | |
654 tree res | |
655 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack, | |
656 rhs1, new_cond, rhs2, | |
657 dummy_cond, simplify, | |
658 limit - 1); | |
659 if (res != NULL_TREE && is_gimple_min_invariant (res)) | |
660 return res; | |
661 } | |
662 } | |
663 | |
664 gimple_cond_set_code (dummy_cond, cond_code); | |
665 gimple_cond_set_lhs (dummy_cond, op0); | |
666 gimple_cond_set_rhs (dummy_cond, op1); | |
667 | |
668 /* We absolutely do not care about any type conversions | |
669 we only care about a zero/nonzero value. */ | |
670 fold_defer_overflow_warnings (); | |
671 | |
672 tree res = fold_binary (cond_code, boolean_type_node, op0, op1); | |
673 if (res) | |
674 while (CONVERT_EXPR_P (res)) | |
675 res = TREE_OPERAND (res, 0); | |
676 | |
677 fold_undefer_overflow_warnings ((res && is_gimple_min_invariant (res)), | |
678 stmt, WARN_STRICT_OVERFLOW_CONDITIONAL); | |
679 | |
680 /* If we have not simplified the condition down to an invariant, | |
681 then use the pass specific callback to simplify the condition. */ | |
682 if (!res | |
683 || !is_gimple_min_invariant (res)) | |
684 res = (*simplify) (dummy_cond, stmt, avail_exprs_stack, e->src); | |
685 | |
686 return res; | |
687 } | |
688 | |
689 /* Copy debug stmts from DEST's chain of single predecessors up to | |
690 SRC, so that we don't lose the bindings as PHI nodes are introduced | |
691 when DEST gains new predecessors. */ | |
692 void | |
693 propagate_threaded_block_debug_into (basic_block dest, basic_block src) | |
694 { | |
695 if (!MAY_HAVE_DEBUG_STMTS) | |
696 return; | |
697 | |
698 if (!single_pred_p (dest)) | |
699 return; | |
700 | |
701 gcc_checking_assert (dest != src); | |
702 | |
703 gimple_stmt_iterator gsi = gsi_after_labels (dest); | |
704 int i = 0; | |
705 const int alloc_count = 16; // ?? Should this be a PARAM? | |
706 | |
707 /* Estimate the number of debug vars overridden in the beginning of | |
708 DEST, to tell how many we're going to need to begin with. */ | |
709 for (gimple_stmt_iterator si = gsi; | |
710 i * 4 <= alloc_count * 3 && !gsi_end_p (si); gsi_next (&si)) | |
711 { | |
712 gimple *stmt = gsi_stmt (si); | |
713 if (!is_gimple_debug (stmt)) | |
714 break; | |
715 i++; | |
716 } | |
717 | |
718 auto_vec<tree, alloc_count> fewvars; | |
719 hash_set<tree> *vars = NULL; | |
720 | |
721 /* If we're already starting with 3/4 of alloc_count, go for a | |
722 hash_set, otherwise start with an unordered stack-allocated | |
723 VEC. */ | |
724 if (i * 4 > alloc_count * 3) | |
725 vars = new hash_set<tree>; | |
726 | |
727 /* Now go through the initial debug stmts in DEST again, this time | |
728 actually inserting in VARS or FEWVARS. Don't bother checking for | |
729 duplicates in FEWVARS. */ | |
730 for (gimple_stmt_iterator si = gsi; !gsi_end_p (si); gsi_next (&si)) | |
731 { | |
732 gimple *stmt = gsi_stmt (si); | |
733 if (!is_gimple_debug (stmt)) | |
734 break; | |
735 | |
736 tree var; | |
737 | |
738 if (gimple_debug_bind_p (stmt)) | |
739 var = gimple_debug_bind_get_var (stmt); | |
740 else if (gimple_debug_source_bind_p (stmt)) | |
741 var = gimple_debug_source_bind_get_var (stmt); | |
742 else | |
743 gcc_unreachable (); | |
744 | |
745 if (vars) | |
746 vars->add (var); | |
747 else | |
748 fewvars.quick_push (var); | |
749 } | |
750 | |
751 basic_block bb = dest; | |
752 | |
753 do | |
754 { | |
755 bb = single_pred (bb); | |
756 for (gimple_stmt_iterator si = gsi_last_bb (bb); | |
757 !gsi_end_p (si); gsi_prev (&si)) | |
758 { | |
759 gimple *stmt = gsi_stmt (si); | |
760 if (!is_gimple_debug (stmt)) | |
761 continue; | |
762 | |
763 tree var; | |
764 | |
765 if (gimple_debug_bind_p (stmt)) | |
766 var = gimple_debug_bind_get_var (stmt); | |
767 else if (gimple_debug_source_bind_p (stmt)) | |
768 var = gimple_debug_source_bind_get_var (stmt); | |
769 else | |
770 gcc_unreachable (); | |
771 | |
772 /* Discard debug bind overlaps. ??? Unlike stmts from src, | |
773 copied into a new block that will precede BB, debug bind | |
774 stmts in bypassed BBs may actually be discarded if | |
775 they're overwritten by subsequent debug bind stmts, which | |
776 might be a problem once we introduce stmt frontier notes | |
777 or somesuch. Adding `&& bb == src' to the condition | |
778 below will preserve all potentially relevant debug | |
779 notes. */ | |
780 if (vars && vars->add (var)) | |
781 continue; | |
782 else if (!vars) | |
783 { | |
784 int i = fewvars.length (); | |
785 while (i--) | |
786 if (fewvars[i] == var) | |
787 break; | |
788 if (i >= 0) | |
789 continue; | |
790 | |
791 if (fewvars.length () < (unsigned) alloc_count) | |
792 fewvars.quick_push (var); | |
793 else | |
794 { | |
795 vars = new hash_set<tree>; | |
796 for (i = 0; i < alloc_count; i++) | |
797 vars->add (fewvars[i]); | |
798 fewvars.release (); | |
799 vars->add (var); | |
800 } | |
801 } | |
802 | |
803 stmt = gimple_copy (stmt); | |
804 /* ??? Should we drop the location of the copy to denote | |
805 they're artificial bindings? */ | |
806 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); | |
807 } | |
808 } | |
809 while (bb != src && single_pred_p (bb)); | |
810 | |
811 if (vars) | |
812 delete vars; | |
813 else if (fewvars.exists ()) | |
814 fewvars.release (); | |
815 } | |
816 | |
817 /* See if TAKEN_EDGE->dest is a threadable block with no side effecs (ie, it | |
818 need not be duplicated as part of the CFG/SSA updating process). | |
819 | |
820 If it is threadable, add it to PATH and VISITED and recurse, ultimately | |
821 returning TRUE from the toplevel call. Otherwise do nothing and | |
822 return false. | |
823 | |
824 DUMMY_COND, SIMPLIFY are used to try and simplify the condition at the | |
825 end of TAKEN_EDGE->dest. | |
826 | |
827 The available expression table is referenced via AVAIL_EXPRS_STACK. */ | |
828 | |
829 static bool | |
830 thread_around_empty_blocks (edge taken_edge, | |
831 gcond *dummy_cond, | |
832 class avail_exprs_stack *avail_exprs_stack, | |
833 pfn_simplify simplify, | |
834 bitmap visited, | |
835 vec<jump_thread_edge *> *path) | |
836 { | |
837 basic_block bb = taken_edge->dest; | |
838 gimple_stmt_iterator gsi; | |
839 gimple *stmt; | |
840 tree cond; | |
841 | |
842 /* The key property of these blocks is that they need not be duplicated | |
843 when threading. Thus they can not have visible side effects such | |
844 as PHI nodes. */ | |
845 if (!gsi_end_p (gsi_start_phis (bb))) | |
846 return false; | |
847 | |
848 /* Skip over DEBUG statements at the start of the block. */ | |
849 gsi = gsi_start_nondebug_bb (bb); | |
850 | |
851 /* If the block has no statements, but does have a single successor, then | |
852 it's just a forwarding block and we can thread through it trivially. | |
853 | |
854 However, note that just threading through empty blocks with single | |
855 successors is not inherently profitable. For the jump thread to | |
856 be profitable, we must avoid a runtime conditional. | |
857 | |
858 By taking the return value from the recursive call, we get the | |
859 desired effect of returning TRUE when we found a profitable jump | |
860 threading opportunity and FALSE otherwise. | |
861 | |
862 This is particularly important when this routine is called after | |
863 processing a joiner block. Returning TRUE too aggressively in | |
864 that case results in pointless duplication of the joiner block. */ | |
865 if (gsi_end_p (gsi)) | |
866 { | |
867 if (single_succ_p (bb)) | |
868 { | |
869 taken_edge = single_succ_edge (bb); | |
870 | |
871 if ((taken_edge->flags & EDGE_DFS_BACK) != 0) | |
872 return false; | |
873 | |
874 if (!bitmap_bit_p (visited, taken_edge->dest->index)) | |
875 { | |
876 jump_thread_edge *x | |
877 = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK); | |
878 path->safe_push (x); | |
879 bitmap_set_bit (visited, taken_edge->dest->index); | |
880 return thread_around_empty_blocks (taken_edge, | |
881 dummy_cond, | |
882 avail_exprs_stack, | |
883 simplify, | |
884 visited, | |
885 path); | |
886 } | |
887 } | |
888 | |
889 /* We have a block with no statements, but multiple successors? */ | |
890 return false; | |
891 } | |
892 | |
893 /* The only real statements this block can have are a control | |
894 flow altering statement. Anything else stops the thread. */ | |
895 stmt = gsi_stmt (gsi); | |
896 if (gimple_code (stmt) != GIMPLE_COND | |
897 && gimple_code (stmt) != GIMPLE_GOTO | |
898 && gimple_code (stmt) != GIMPLE_SWITCH) | |
899 return false; | |
900 | |
901 /* Extract and simplify the condition. */ | |
902 cond = simplify_control_stmt_condition (taken_edge, stmt, | |
903 avail_exprs_stack, dummy_cond, | |
904 simplify); | |
905 | |
906 /* If the condition can be statically computed and we have not already | |
907 visited the destination edge, then add the taken edge to our thread | |
908 path. */ | |
909 if (cond != NULL_TREE | |
910 && (is_gimple_min_invariant (cond) | |
911 || TREE_CODE (cond) == CASE_LABEL_EXPR)) | |
912 { | |
913 if (TREE_CODE (cond) == CASE_LABEL_EXPR) | |
914 taken_edge = find_edge (bb, label_to_block (CASE_LABEL (cond))); | |
915 else | |
916 taken_edge = find_taken_edge (bb, cond); | |
917 | |
918 if ((taken_edge->flags & EDGE_DFS_BACK) != 0) | |
919 return false; | |
920 | |
921 if (bitmap_bit_p (visited, taken_edge->dest->index)) | |
922 return false; | |
923 bitmap_set_bit (visited, taken_edge->dest->index); | |
924 | |
925 jump_thread_edge *x | |
926 = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK); | |
927 path->safe_push (x); | |
928 | |
929 thread_around_empty_blocks (taken_edge, | |
930 dummy_cond, | |
931 avail_exprs_stack, | |
932 simplify, | |
933 visited, | |
934 path); | |
935 return true; | |
936 } | |
937 | |
938 return false; | |
939 } | |
940 | |
586 /* We are exiting E->src, see if E->dest ends with a conditional | 941 /* We are exiting E->src, see if E->dest ends with a conditional |
587 jump which has a known value when reached via E. | 942 jump which has a known value when reached via E. |
943 | |
944 E->dest can have arbitrary side effects which, if threading is | |
945 successful, will be maintained. | |
588 | 946 |
589 Special care is necessary if E is a back edge in the CFG as we | 947 Special care is necessary if E is a back edge in the CFG as we |
590 may have already recorded equivalences for E->dest into our | 948 may have already recorded equivalences for E->dest into our |
591 various tables, including the result of the conditional at | 949 various tables, including the result of the conditional at |
592 the end of E->dest. Threading opportunities are severely | 950 the end of E->dest. Threading opportunities are severely |
593 limited in that case to avoid short-circuiting the loop | 951 limited in that case to avoid short-circuiting the loop |
594 incorrectly. | 952 incorrectly. |
595 | 953 |
596 Note it is quite common for the first block inside a loop to | |
597 end with a conditional which is either always true or always | |
598 false when reached via the loop backedge. Thus we do not want | |
599 to blindly disable threading across a loop backedge. | |
600 | |
601 DUMMY_COND is a shared cond_expr used by condition simplification as scratch, | 954 DUMMY_COND is a shared cond_expr used by condition simplification as scratch, |
602 to avoid allocating memory. | 955 to avoid allocating memory. |
603 | 956 |
604 HANDLE_DOMINATING_ASSERTS is true if we should try to replace operands of | |
605 the simplified condition with left-hand sides of ASSERT_EXPRs they are | |
606 used in. | |
607 | |
608 STACK is used to undo temporary equivalences created during the walk of | 957 STACK is used to undo temporary equivalences created during the walk of |
609 E->dest. | 958 E->dest. |
610 | 959 |
611 SIMPLIFY is a pass-specific function used to simplify statements. */ | 960 SIMPLIFY is a pass-specific function used to simplify statements. |
612 | 961 |
613 void | 962 Our caller is responsible for restoring the state of the expression |
614 thread_across_edge (gimple dummy_cond, | 963 and const_and_copies stacks. |
615 edge e, | 964 |
616 bool handle_dominating_asserts, | 965 Positive return value is success. Zero return value is failure, but |
617 VEC(tree, heap) **stack, | 966 the block can still be duplicated as a joiner in a jump thread path, |
618 tree (*simplify) (gimple, gimple)) | 967 negative indicates the block should not be duplicated and thus is not |
968 suitable for a joiner in a jump threading path. */ | |
969 | |
970 static int | |
971 thread_through_normal_block (edge e, | |
972 gcond *dummy_cond, | |
973 const_and_copies *const_and_copies, | |
974 avail_exprs_stack *avail_exprs_stack, | |
975 pfn_simplify simplify, | |
976 vec<jump_thread_edge *> *path, | |
977 bitmap visited) | |
619 { | 978 { |
620 gimple stmt; | 979 /* We want to record any equivalences created by traversing E. */ |
621 | 980 record_temporary_equivalences (e, const_and_copies, avail_exprs_stack); |
622 /* If E is a backedge, then we want to verify that the COND_EXPR, | 981 |
623 SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected | 982 /* PHIs create temporary equivalences. |
624 by any statements in e->dest. If it is affected, then it is not | 983 Note that if we found a PHI that made the block non-threadable, then |
625 safe to thread this edge. */ | 984 we need to bubble that up to our caller in the same manner we do |
626 if (e->flags & EDGE_DFS_BACK) | 985 when we prematurely stop processing statements below. */ |
627 { | 986 if (!record_temporary_equivalences_from_phis (e, const_and_copies)) |
628 ssa_op_iter iter; | 987 return -1; |
629 use_operand_p use_p; | |
630 gimple last = gsi_stmt (gsi_last_bb (e->dest)); | |
631 | |
632 FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE) | |
633 { | |
634 tree use = USE_FROM_PTR (use_p); | |
635 | |
636 if (TREE_CODE (use) == SSA_NAME | |
637 && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI | |
638 && gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest) | |
639 goto fail; | |
640 } | |
641 } | |
642 | |
643 stmt_count = 0; | |
644 | |
645 /* PHIs create temporary equivalences. */ | |
646 if (!record_temporary_equivalences_from_phis (e, stack)) | |
647 goto fail; | |
648 | 988 |
649 /* Now walk each statement recording any context sensitive | 989 /* Now walk each statement recording any context sensitive |
650 temporary equivalences we can detect. */ | 990 temporary equivalences we can detect. */ |
651 stmt = record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify); | 991 gimple *stmt |
992 = record_temporary_equivalences_from_stmts_at_dest (e, const_and_copies, | |
993 avail_exprs_stack, | |
994 simplify); | |
995 | |
996 /* There's two reasons STMT might be null, and distinguishing | |
997 between them is important. | |
998 | |
999 First the block may not have had any statements. For example, it | |
1000 might have some PHIs and unconditionally transfer control elsewhere. | |
1001 Such blocks are suitable for jump threading, particularly as a | |
1002 joiner block. | |
1003 | |
1004 The second reason would be if we did not process all the statements | |
1005 in the block (because there were too many to make duplicating the | |
1006 block profitable. If we did not look at all the statements, then | |
1007 we may not have invalidated everything needing invalidation. Thus | |
1008 we must signal to our caller that this block is not suitable for | |
1009 use as a joiner in a threading path. */ | |
652 if (!stmt) | 1010 if (!stmt) |
653 goto fail; | 1011 { |
1012 /* First case. The statement simply doesn't have any instructions, but | |
1013 does have PHIs. */ | |
1014 if (gsi_end_p (gsi_start_nondebug_bb (e->dest)) | |
1015 && !gsi_end_p (gsi_start_phis (e->dest))) | |
1016 return 0; | |
1017 | |
1018 /* Second case. */ | |
1019 return -1; | |
1020 } | |
654 | 1021 |
655 /* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm | 1022 /* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm |
656 will be taken. */ | 1023 will be taken. */ |
657 if (gimple_code (stmt) == GIMPLE_COND | 1024 if (gimple_code (stmt) == GIMPLE_COND |
658 || gimple_code (stmt) == GIMPLE_GOTO | 1025 || gimple_code (stmt) == GIMPLE_GOTO |
659 || gimple_code (stmt) == GIMPLE_SWITCH) | 1026 || gimple_code (stmt) == GIMPLE_SWITCH) |
660 { | 1027 { |
661 tree cond; | 1028 tree cond; |
662 | 1029 |
663 /* Extract and simplify the condition. */ | 1030 /* Extract and simplify the condition. */ |
664 cond = simplify_control_stmt_condition (e, stmt, dummy_cond, simplify, handle_dominating_asserts); | 1031 cond = simplify_control_stmt_condition (e, stmt, avail_exprs_stack, |
665 | 1032 dummy_cond, simplify); |
666 if (cond && is_gimple_min_invariant (cond)) | 1033 |
1034 if (!cond) | |
1035 return 0; | |
1036 | |
1037 if (is_gimple_min_invariant (cond) | |
1038 || TREE_CODE (cond) == CASE_LABEL_EXPR) | |
667 { | 1039 { |
668 edge taken_edge = find_taken_edge (e->dest, cond); | 1040 edge taken_edge; |
1041 if (TREE_CODE (cond) == CASE_LABEL_EXPR) | |
1042 taken_edge = find_edge (e->dest, | |
1043 label_to_block (CASE_LABEL (cond))); | |
1044 else | |
1045 taken_edge = find_taken_edge (e->dest, cond); | |
1046 | |
669 basic_block dest = (taken_edge ? taken_edge->dest : NULL); | 1047 basic_block dest = (taken_edge ? taken_edge->dest : NULL); |
670 | 1048 |
671 if (dest == e->dest) | 1049 /* DEST could be NULL for a computed jump to an absolute |
672 goto fail; | 1050 address. */ |
673 | 1051 if (dest == NULL |
674 remove_temporary_equivalences (stack); | 1052 || dest == e->dest |
675 register_jump_thread (e, taken_edge); | 1053 || (taken_edge->flags & EDGE_DFS_BACK) != 0 |
1054 || bitmap_bit_p (visited, dest->index)) | |
1055 return 0; | |
1056 | |
1057 /* Only push the EDGE_START_JUMP_THREAD marker if this is | |
1058 first edge on the path. */ | |
1059 if (path->length () == 0) | |
1060 { | |
1061 jump_thread_edge *x | |
1062 = new jump_thread_edge (e, EDGE_START_JUMP_THREAD); | |
1063 path->safe_push (x); | |
1064 } | |
1065 | |
1066 jump_thread_edge *x | |
1067 = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK); | |
1068 path->safe_push (x); | |
1069 | |
1070 /* See if we can thread through DEST as well, this helps capture | |
1071 secondary effects of threading without having to re-run DOM or | |
1072 VRP. | |
1073 | |
1074 We don't want to thread back to a block we have already | |
1075 visited. This may be overly conservative. */ | |
1076 bitmap_set_bit (visited, dest->index); | |
1077 bitmap_set_bit (visited, e->dest->index); | |
1078 thread_around_empty_blocks (taken_edge, | |
1079 dummy_cond, | |
1080 avail_exprs_stack, | |
1081 simplify, | |
1082 visited, | |
1083 path); | |
1084 return 1; | |
676 } | 1085 } |
677 } | 1086 } |
678 | 1087 return 0; |
679 fail: | |
680 remove_temporary_equivalences (stack); | |
681 } | 1088 } |
1089 | |
1090 /* We are exiting E->src, see if E->dest ends with a conditional | |
1091 jump which has a known value when reached via E. | |
1092 | |
1093 DUMMY_COND is a shared cond_expr used by condition simplification as scratch, | |
1094 to avoid allocating memory. | |
1095 | |
1096 CONST_AND_COPIES is used to undo temporary equivalences created during the | |
1097 walk of E->dest. | |
1098 | |
1099 The available expression table is referenced vai AVAIL_EXPRS_STACK. | |
1100 | |
1101 SIMPLIFY is a pass-specific function used to simplify statements. */ | |
1102 | |
1103 static void | |
1104 thread_across_edge (gcond *dummy_cond, | |
1105 edge e, | |
1106 class const_and_copies *const_and_copies, | |
1107 class avail_exprs_stack *avail_exprs_stack, | |
1108 pfn_simplify simplify) | |
1109 { | |
1110 bitmap visited = BITMAP_ALLOC (NULL); | |
1111 | |
1112 const_and_copies->push_marker (); | |
1113 avail_exprs_stack->push_marker (); | |
1114 | |
1115 stmt_count = 0; | |
1116 | |
1117 vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> (); | |
1118 bitmap_clear (visited); | |
1119 bitmap_set_bit (visited, e->src->index); | |
1120 bitmap_set_bit (visited, e->dest->index); | |
1121 | |
1122 int threaded; | |
1123 if ((e->flags & EDGE_DFS_BACK) == 0) | |
1124 threaded = thread_through_normal_block (e, dummy_cond, | |
1125 const_and_copies, | |
1126 avail_exprs_stack, | |
1127 simplify, path, | |
1128 visited); | |
1129 else | |
1130 threaded = 0; | |
1131 | |
1132 if (threaded > 0) | |
1133 { | |
1134 propagate_threaded_block_debug_into (path->last ()->e->dest, | |
1135 e->dest); | |
1136 const_and_copies->pop_to_marker (); | |
1137 avail_exprs_stack->pop_to_marker (); | |
1138 BITMAP_FREE (visited); | |
1139 register_jump_thread (path); | |
1140 return; | |
1141 } | |
1142 else | |
1143 { | |
1144 /* Negative and zero return values indicate no threading was possible, | |
1145 thus there should be no edges on the thread path and no need to walk | |
1146 through the vector entries. */ | |
1147 gcc_assert (path->length () == 0); | |
1148 path->release (); | |
1149 delete path; | |
1150 | |
1151 /* A negative status indicates the target block was deemed too big to | |
1152 duplicate. Just quit now rather than trying to use the block as | |
1153 a joiner in a jump threading path. | |
1154 | |
1155 This prevents unnecessary code growth, but more importantly if we | |
1156 do not look at all the statements in the block, then we may have | |
1157 missed some invalidations if we had traversed a backedge! */ | |
1158 if (threaded < 0) | |
1159 { | |
1160 BITMAP_FREE (visited); | |
1161 const_and_copies->pop_to_marker (); | |
1162 avail_exprs_stack->pop_to_marker (); | |
1163 return; | |
1164 } | |
1165 } | |
1166 | |
1167 /* We were unable to determine what out edge from E->dest is taken. However, | |
1168 we might still be able to thread through successors of E->dest. This | |
1169 often occurs when E->dest is a joiner block which then fans back out | |
1170 based on redundant tests. | |
1171 | |
1172 If so, we'll copy E->dest and redirect the appropriate predecessor to | |
1173 the copy. Within the copy of E->dest, we'll thread one or more edges | |
1174 to points deeper in the CFG. | |
1175 | |
1176 This is a stopgap until we have a more structured approach to path | |
1177 isolation. */ | |
1178 { | |
1179 edge taken_edge; | |
1180 edge_iterator ei; | |
1181 bool found; | |
1182 | |
1183 /* If E->dest has abnormal outgoing edges, then there's no guarantee | |
1184 we can safely redirect any of the edges. Just punt those cases. */ | |
1185 FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) | |
1186 if (taken_edge->flags & EDGE_ABNORMAL) | |
1187 { | |
1188 const_and_copies->pop_to_marker (); | |
1189 avail_exprs_stack->pop_to_marker (); | |
1190 BITMAP_FREE (visited); | |
1191 return; | |
1192 } | |
1193 | |
1194 /* Look at each successor of E->dest to see if we can thread through it. */ | |
1195 FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) | |
1196 { | |
1197 if ((e->flags & EDGE_DFS_BACK) != 0 | |
1198 || (taken_edge->flags & EDGE_DFS_BACK) != 0) | |
1199 continue; | |
1200 | |
1201 /* Push a fresh marker so we can unwind the equivalences created | |
1202 for each of E->dest's successors. */ | |
1203 const_and_copies->push_marker (); | |
1204 avail_exprs_stack->push_marker (); | |
1205 | |
1206 /* Avoid threading to any block we have already visited. */ | |
1207 bitmap_clear (visited); | |
1208 bitmap_set_bit (visited, e->src->index); | |
1209 bitmap_set_bit (visited, e->dest->index); | |
1210 bitmap_set_bit (visited, taken_edge->dest->index); | |
1211 vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> (); | |
1212 | |
1213 /* Record whether or not we were able to thread through a successor | |
1214 of E->dest. */ | |
1215 jump_thread_edge *x = new jump_thread_edge (e, EDGE_START_JUMP_THREAD); | |
1216 path->safe_push (x); | |
1217 | |
1218 x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK); | |
1219 path->safe_push (x); | |
1220 found = false; | |
1221 found = thread_around_empty_blocks (taken_edge, | |
1222 dummy_cond, | |
1223 avail_exprs_stack, | |
1224 simplify, | |
1225 visited, | |
1226 path); | |
1227 | |
1228 if (!found) | |
1229 found = thread_through_normal_block (path->last ()->e, dummy_cond, | |
1230 const_and_copies, | |
1231 avail_exprs_stack, | |
1232 simplify, path, | |
1233 visited) > 0; | |
1234 | |
1235 /* If we were able to thread through a successor of E->dest, then | |
1236 record the jump threading opportunity. */ | |
1237 if (found) | |
1238 { | |
1239 propagate_threaded_block_debug_into (path->last ()->e->dest, | |
1240 taken_edge->dest); | |
1241 register_jump_thread (path); | |
1242 } | |
1243 else | |
1244 delete_jump_thread_path (path); | |
1245 | |
1246 /* And unwind the equivalence table. */ | |
1247 avail_exprs_stack->pop_to_marker (); | |
1248 const_and_copies->pop_to_marker (); | |
1249 } | |
1250 BITMAP_FREE (visited); | |
1251 } | |
1252 | |
1253 const_and_copies->pop_to_marker (); | |
1254 avail_exprs_stack->pop_to_marker (); | |
1255 } | |
1256 | |
1257 /* Examine the outgoing edges from BB and conditionally | |
1258 try to thread them. | |
1259 | |
1260 DUMMY_COND is a shared cond_expr used by condition simplification as scratch, | |
1261 to avoid allocating memory. | |
1262 | |
1263 CONST_AND_COPIES is used to undo temporary equivalences created during the | |
1264 walk of E->dest. | |
1265 | |
1266 The available expression table is referenced vai AVAIL_EXPRS_STACK. | |
1267 | |
1268 SIMPLIFY is a pass-specific function used to simplify statements. */ | |
1269 | |
1270 void | |
1271 thread_outgoing_edges (basic_block bb, gcond *dummy_cond, | |
1272 class const_and_copies *const_and_copies, | |
1273 class avail_exprs_stack *avail_exprs_stack, | |
1274 tree (*simplify) (gimple *, gimple *, | |
1275 class avail_exprs_stack *, | |
1276 basic_block)) | |
1277 { | |
1278 int flags = (EDGE_IGNORE | EDGE_COMPLEX | EDGE_ABNORMAL); | |
1279 gimple *last; | |
1280 | |
1281 /* If we have an outgoing edge to a block with multiple incoming and | |
1282 outgoing edges, then we may be able to thread the edge, i.e., we | |
1283 may be able to statically determine which of the outgoing edges | |
1284 will be traversed when the incoming edge from BB is traversed. */ | |
1285 if (single_succ_p (bb) | |
1286 && (single_succ_edge (bb)->flags & flags) == 0 | |
1287 && potentially_threadable_block (single_succ (bb))) | |
1288 { | |
1289 thread_across_edge (dummy_cond, single_succ_edge (bb), | |
1290 const_and_copies, avail_exprs_stack, | |
1291 simplify); | |
1292 } | |
1293 else if ((last = last_stmt (bb)) | |
1294 && gimple_code (last) == GIMPLE_COND | |
1295 && EDGE_COUNT (bb->succs) == 2 | |
1296 && (EDGE_SUCC (bb, 0)->flags & flags) == 0 | |
1297 && (EDGE_SUCC (bb, 1)->flags & flags) == 0) | |
1298 { | |
1299 edge true_edge, false_edge; | |
1300 | |
1301 extract_true_false_edges_from_block (bb, &true_edge, &false_edge); | |
1302 | |
1303 /* Only try to thread the edge if it reaches a target block with | |
1304 more than one predecessor and more than one successor. */ | |
1305 if (potentially_threadable_block (true_edge->dest)) | |
1306 thread_across_edge (dummy_cond, true_edge, | |
1307 const_and_copies, avail_exprs_stack, simplify); | |
1308 | |
1309 /* Similarly for the ELSE arm. */ | |
1310 if (potentially_threadable_block (false_edge->dest)) | |
1311 thread_across_edge (dummy_cond, false_edge, | |
1312 const_and_copies, avail_exprs_stack, simplify); | |
1313 } | |
1314 } |