Branch data Line data Source code
1 : : /* Gimple walk support.
2 : :
3 : : Copyright (C) 2007-2024 Free Software Foundation, Inc.
4 : : Contributed by Aldy Hernandez <aldyh@redhat.com>
5 : :
6 : : This file is part of GCC.
7 : :
8 : : GCC is free software; you can redistribute it and/or modify it under
9 : : the terms of the GNU General Public License as published by the Free
10 : : Software Foundation; either version 3, or (at your option) any later
11 : : version.
12 : :
13 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 : : for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with GCC; see the file COPYING3. If not see
20 : : <http://www.gnu.org/licenses/>. */
21 : :
22 : : #include "config.h"
23 : : #include "system.h"
24 : : #include "coretypes.h"
25 : : #include "backend.h"
26 : : #include "tree.h"
27 : : #include "gimple.h"
28 : : #include "gimple-iterator.h"
29 : : #include "gimple-walk.h"
30 : : #include "stmt.h"
31 : :
32 : : /* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
33 : : on each one. WI is as in walk_gimple_stmt.
34 : :
35 : : If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
36 : : value is stored in WI->CALLBACK_RESULT. Also, the statement that
37 : : produced the value is returned if this statement has not been
38 : : removed by a callback (wi->removed_stmt). If the statement has
39 : : been removed, NULL is returned.
40 : :
41 : : Otherwise, all the statements are walked and NULL returned. */
42 : :
43 : : gimple *
44 : 34595991 : walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
45 : : walk_tree_fn callback_op, struct walk_stmt_info *wi)
46 : : {
47 : 34595991 : gimple_stmt_iterator gsi;
48 : :
49 : 258158279 : for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
50 : : {
51 : 190046303 : tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
52 : 190046261 : if (ret)
53 : : {
54 : : /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist
55 : : to hold it. */
56 : 79291 : gcc_assert (wi);
57 : 79291 : wi->callback_result = ret;
58 : :
59 : 79291 : gimple *g;
60 : 79291 : if (!wi->removed_stmt)
61 : 79291 : g = gsi_stmt (gsi);
62 : : else
63 : : {
64 : 0 : g = NULL;
65 : 0 : wi->removed_stmt = false;
66 : : }
67 : 79291 : return g;
68 : : }
69 : :
70 : 189966970 : if (!wi->removed_stmt)
71 : 189963465 : gsi_next (&gsi);
72 : : else
73 : 3505 : wi->removed_stmt = false;
74 : : }
75 : :
76 : 34516658 : if (wi)
77 : 34516658 : wi->callback_result = NULL_TREE;
78 : :
79 : : return NULL;
80 : : }
81 : :
82 : :
83 : : /* Like walk_gimple_seq_mod, but ensure that the head of SEQ isn't
84 : : changed by the callbacks. */
85 : :
86 : : gimple *
87 : 30265066 : walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
88 : : walk_tree_fn callback_op, struct walk_stmt_info *wi)
89 : : {
90 : 30265066 : gimple_seq seq2 = seq;
91 : 30265066 : gimple *ret = walk_gimple_seq_mod (&seq2, callback_stmt, callback_op, wi);
92 : 30265058 : gcc_assert (seq2 == seq);
93 : 30265058 : return ret;
94 : : }
95 : :
96 : :
97 : : /* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */
98 : :
99 : : static tree
100 : 29077560 : walk_gimple_asm (gasm *stmt, walk_tree_fn callback_op,
101 : : struct walk_stmt_info *wi)
102 : : {
103 : 29077560 : tree ret, op;
104 : 29077560 : unsigned noutputs;
105 : 29077560 : const char **oconstraints;
106 : 29077560 : unsigned i, n;
107 : 29077560 : const char *constraint;
108 : 29077560 : bool allows_mem, allows_reg, is_inout;
109 : :
110 : 29077560 : noutputs = gimple_asm_noutputs (stmt);
111 : 29077560 : oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
112 : :
113 : 56989742 : for (i = 0; i < noutputs; i++)
114 : : {
115 : 27912192 : op = gimple_asm_output_op (stmt, i);
116 : 27912192 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
117 : 27912192 : oconstraints[i] = constraint;
118 : 27912192 : if (wi)
119 : : {
120 : 27912100 : if (parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
121 : : &allows_reg, &is_inout))
122 : 27912100 : wi->val_only = (allows_reg || !allows_mem);
123 : : }
124 : 27912100 : if (wi)
125 : 27912100 : wi->is_lhs = true;
126 : 27912192 : ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
127 : 27912192 : if (ret)
128 : 10 : return ret;
129 : : }
130 : :
131 : 29077550 : n = gimple_asm_ninputs (stmt);
132 : 45604173 : for (i = 0; i < n; i++)
133 : : {
134 : 16526629 : op = gimple_asm_input_op (stmt, i);
135 : 16526629 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
136 : :
137 : 16526629 : if (wi)
138 : : {
139 : 16526544 : if (parse_input_constraint (&constraint, 0, 0, noutputs, 0,
140 : : oconstraints, &allows_mem, &allows_reg))
141 : : {
142 : 16526544 : wi->val_only = (allows_reg || !allows_mem);
143 : : /* Although input "m" is not really a LHS, we need a lvalue. */
144 : 16526544 : wi->is_lhs = !wi->val_only;
145 : : }
146 : : }
147 : 16526629 : ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
148 : 16526629 : if (ret)
149 : 6 : return ret;
150 : : }
151 : :
152 : 29077544 : if (wi)
153 : : {
154 : 29077481 : wi->is_lhs = false;
155 : 29077481 : wi->val_only = true;
156 : : }
157 : :
158 : 29077544 : n = gimple_asm_nlabels (stmt);
159 : 29262976 : for (i = 0; i < n; i++)
160 : : {
161 : 185432 : op = gimple_asm_label_op (stmt, i);
162 : 185432 : ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
163 : 185432 : if (ret)
164 : 0 : return ret;
165 : : }
166 : :
167 : : return NULL_TREE;
168 : : }
169 : :
170 : :
171 : : /* Helper function of WALK_GIMPLE_STMT. Walk every tree operand in
172 : : STMT. CALLBACK_OP and WI are as in WALK_GIMPLE_STMT.
173 : :
174 : : CALLBACK_OP is called on each operand of STMT via walk_tree.
175 : : Additional parameters to walk_tree must be stored in WI. For each operand
176 : : OP, walk_tree is called as:
177 : :
178 : : walk_tree (&OP, CALLBACK_OP, WI, WI->PSET)
179 : :
180 : : If CALLBACK_OP returns non-NULL for an operand, the remaining
181 : : operands are not scanned.
182 : :
183 : : The return value is that returned by the last call to walk_tree, or
184 : : NULL_TREE if no CALLBACK_OP is specified. */
185 : :
186 : : tree
187 : 20828784313 : walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
188 : : struct walk_stmt_info *wi)
189 : : {
190 : 20828784313 : hash_set<tree> *pset = (wi) ? wi->pset : NULL;
191 : 20827903965 : unsigned i;
192 : 41656688278 : tree ret = NULL_TREE;
193 : :
194 : 20827903965 : if (wi)
195 : 20827903965 : wi->stmt = stmt;
196 : :
197 : 20828784313 : switch (gimple_code (stmt))
198 : : {
199 : 7805005602 : case GIMPLE_ASSIGN:
200 : : /* Walk the RHS operands. If the LHS is of a non-renamable type or
201 : : is a register variable, we may use a COMPONENT_REF on the RHS. */
202 : 7805005602 : if (wi)
203 : : {
204 : 7804393840 : tree lhs = gimple_assign_lhs (stmt);
205 : 7804393840 : wi->val_only
206 : 15608787680 : = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs))
207 : 13700529883 : || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
208 : : }
209 : :
210 : 17371011534 : for (i = 1; i < gimple_num_ops (stmt); i++)
211 : : {
212 : 9566074554 : ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
213 : : pset);
214 : 9566074554 : if (ret)
215 : 68622 : return ret;
216 : : }
217 : :
218 : : /* Walk the LHS. If the RHS is appropriate for a memory, we
219 : : may use a COMPONENT_REF on the LHS. */
220 : 7804936980 : if (wi)
221 : : {
222 : : /* If the RHS is of a non-renamable type or is a register variable,
223 : : we may use a COMPONENT_REF on the LHS. */
224 : 7804387705 : tree rhs1 = gimple_assign_rhs1 (stmt);
225 : 7804387705 : wi->val_only
226 : 7804387705 : = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
227 : 12058063026 : || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
228 : 7804387705 : wi->is_lhs = true;
229 : : }
230 : :
231 : 7804936980 : ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
232 : 7804936980 : if (ret)
233 : : return ret;
234 : :
235 : 7804911139 : if (wi)
236 : : {
237 : 7804387057 : wi->val_only = true;
238 : 7804387057 : wi->is_lhs = false;
239 : : }
240 : : break;
241 : :
242 : 1789460898 : case GIMPLE_CALL:
243 : 1789460898 : if (wi)
244 : : {
245 : 1789398056 : wi->is_lhs = false;
246 : 1789398056 : wi->val_only = true;
247 : : }
248 : :
249 : 1789460898 : ret = walk_tree (gimple_call_chain_ptr (as_a <gcall *> (stmt)),
250 : : callback_op, wi, pset);
251 : 1789460898 : if (ret)
252 : : return ret;
253 : :
254 : 1789460839 : ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
255 : 1789460839 : if (ret)
256 : : return ret;
257 : :
258 : 5379377905 : for (i = 0; i < gimple_call_num_args (stmt); i++)
259 : : {
260 : 3589921254 : if (wi)
261 : 3589816863 : wi->val_only
262 : 3589816863 : = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
263 : 3589921254 : ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
264 : : pset);
265 : 3589921254 : if (ret)
266 : 4152 : return ret;
267 : : }
268 : :
269 : 1789456651 : if (gimple_call_lhs (stmt))
270 : : {
271 : 719896240 : if (wi)
272 : : {
273 : 719879302 : wi->is_lhs = true;
274 : 719879302 : wi->val_only
275 : 719879302 : = is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
276 : : }
277 : :
278 : 719896240 : ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
279 : 719896240 : if (ret)
280 : : return ret;
281 : : }
282 : :
283 : 1789456342 : if (wi)
284 : : {
285 : 1789396933 : wi->is_lhs = false;
286 : 1789396933 : wi->val_only = true;
287 : : }
288 : : break;
289 : :
290 : 17593 : case GIMPLE_CATCH:
291 : 17593 : ret = walk_tree (gimple_catch_types_ptr (as_a <gcatch *> (stmt)),
292 : : callback_op, wi, pset);
293 : 17593 : if (ret)
294 : : return ret;
295 : : break;
296 : :
297 : 73 : case GIMPLE_EH_FILTER:
298 : 73 : ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
299 : : pset);
300 : 73 : if (ret)
301 : : return ret;
302 : : break;
303 : :
304 : 29077560 : case GIMPLE_ASM:
305 : 29077560 : ret = walk_gimple_asm (as_a <gasm *> (stmt), callback_op, wi);
306 : 29077560 : if (ret)
307 : : return ret;
308 : : break;
309 : :
310 : 195968 : case GIMPLE_OMP_CONTINUE:
311 : 195968 : {
312 : 195968 : gomp_continue *cont_stmt = as_a <gomp_continue *> (stmt);
313 : 195968 : ret = walk_tree (gimple_omp_continue_control_def_ptr (cont_stmt),
314 : : callback_op, wi, pset);
315 : 195968 : if (ret)
316 : : return ret;
317 : :
318 : 195968 : ret = walk_tree (gimple_omp_continue_control_use_ptr (cont_stmt),
319 : : callback_op, wi, pset);
320 : 195968 : if (ret)
321 : : return ret;
322 : : }
323 : : break;
324 : :
325 : 1444 : case GIMPLE_OMP_CRITICAL:
326 : 1444 : {
327 : 1444 : gomp_critical *omp_stmt = as_a <gomp_critical *> (stmt);
328 : 1444 : ret = walk_tree (gimple_omp_critical_name_ptr (omp_stmt),
329 : : callback_op, wi, pset);
330 : 1444 : if (ret)
331 : : return ret;
332 : 1444 : ret = walk_tree (gimple_omp_critical_clauses_ptr (omp_stmt),
333 : : callback_op, wi, pset);
334 : 1444 : if (ret)
335 : : return ret;
336 : : }
337 : : break;
338 : :
339 : 5870 : case GIMPLE_OMP_ORDERED:
340 : 5870 : {
341 : 5870 : gomp_ordered *omp_stmt = as_a <gomp_ordered *> (stmt);
342 : 5870 : ret = walk_tree (gimple_omp_ordered_clauses_ptr (omp_stmt),
343 : : callback_op, wi, pset);
344 : 5870 : if (ret)
345 : : return ret;
346 : : }
347 : : break;
348 : :
349 : 838 : case GIMPLE_OMP_SCAN:
350 : 838 : {
351 : 838 : gomp_scan *scan_stmt = as_a <gomp_scan *> (stmt);
352 : 838 : ret = walk_tree (gimple_omp_scan_clauses_ptr (scan_stmt),
353 : : callback_op, wi, pset);
354 : 838 : if (ret)
355 : : return ret;
356 : : }
357 : : break;
358 : :
359 : 189522 : case GIMPLE_OMP_FOR:
360 : 189522 : ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
361 : : pset);
362 : 189522 : if (ret)
363 : : return ret;
364 : 463911 : for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
365 : : {
366 : 274389 : ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
367 : : wi, pset);
368 : 274389 : if (ret)
369 : 0 : return ret;
370 : 274389 : ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
371 : : wi, pset);
372 : 274389 : if (ret)
373 : 0 : return ret;
374 : 274389 : ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
375 : : wi, pset);
376 : 274389 : if (ret)
377 : 0 : return ret;
378 : 274389 : ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
379 : : wi, pset);
380 : 274389 : if (ret)
381 : 0 : return ret;
382 : : }
383 : : break;
384 : :
385 : 65167 : case GIMPLE_OMP_PARALLEL:
386 : 65167 : {
387 : 65167 : gomp_parallel *omp_par_stmt = as_a <gomp_parallel *> (stmt);
388 : 65167 : ret = walk_tree (gimple_omp_parallel_clauses_ptr (omp_par_stmt),
389 : : callback_op, wi, pset);
390 : 65167 : if (ret)
391 : : return ret;
392 : 65167 : ret = walk_tree (gimple_omp_parallel_child_fn_ptr (omp_par_stmt),
393 : : callback_op, wi, pset);
394 : 65167 : if (ret)
395 : : return ret;
396 : 65167 : ret = walk_tree (gimple_omp_parallel_data_arg_ptr (omp_par_stmt),
397 : : callback_op, wi, pset);
398 : 65167 : if (ret)
399 : : return ret;
400 : : }
401 : : break;
402 : :
403 : 16265 : case GIMPLE_OMP_TASK:
404 : 16265 : ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
405 : : wi, pset);
406 : 16265 : if (ret)
407 : : return ret;
408 : 16265 : ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
409 : : wi, pset);
410 : 16265 : if (ret)
411 : : return ret;
412 : 16265 : ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
413 : : wi, pset);
414 : 16265 : if (ret)
415 : : return ret;
416 : 16265 : ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
417 : : wi, pset);
418 : 16265 : if (ret)
419 : : return ret;
420 : 16265 : ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
421 : : wi, pset);
422 : 16265 : if (ret)
423 : : return ret;
424 : 16265 : ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
425 : : wi, pset);
426 : 16265 : if (ret)
427 : : return ret;
428 : : break;
429 : :
430 : 1774 : case GIMPLE_OMP_SECTIONS:
431 : 1774 : ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
432 : : wi, pset);
433 : 1774 : if (ret)
434 : : return ret;
435 : 1774 : ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
436 : : wi, pset);
437 : 1774 : if (ret)
438 : : return ret;
439 : :
440 : : break;
441 : :
442 : 4814 : case GIMPLE_OMP_SINGLE:
443 : 4814 : ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
444 : : pset);
445 : 4814 : if (ret)
446 : : return ret;
447 : : break;
448 : :
449 : 141924 : case GIMPLE_OMP_TARGET:
450 : 141924 : {
451 : 141924 : gomp_target *omp_stmt = as_a <gomp_target *> (stmt);
452 : 141924 : ret = walk_tree (gimple_omp_target_clauses_ptr (omp_stmt),
453 : : callback_op, wi, pset);
454 : 141924 : if (ret)
455 : : return ret;
456 : 141924 : ret = walk_tree (gimple_omp_target_child_fn_ptr (omp_stmt),
457 : : callback_op, wi, pset);
458 : 141924 : if (ret)
459 : : return ret;
460 : 141924 : ret = walk_tree (gimple_omp_target_data_arg_ptr (omp_stmt),
461 : : callback_op, wi, pset);
462 : 141924 : if (ret)
463 : : return ret;
464 : : }
465 : : break;
466 : :
467 : 34526 : case GIMPLE_OMP_TEAMS:
468 : 34526 : ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
469 : : pset);
470 : 34526 : if (ret)
471 : : return ret;
472 : : break;
473 : :
474 : 50929 : case GIMPLE_OMP_ATOMIC_LOAD:
475 : 50929 : {
476 : 50929 : gomp_atomic_load *omp_stmt = as_a <gomp_atomic_load *> (stmt);
477 : 50929 : ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (omp_stmt),
478 : : callback_op, wi, pset);
479 : 50929 : if (ret)
480 : : return ret;
481 : 50929 : ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (omp_stmt),
482 : : callback_op, wi, pset);
483 : 50929 : if (ret)
484 : : return ret;
485 : : }
486 : : break;
487 : :
488 : 51961 : case GIMPLE_OMP_ATOMIC_STORE:
489 : 51961 : {
490 : 51961 : gomp_atomic_store *omp_stmt = as_a <gomp_atomic_store *> (stmt);
491 : 51961 : ret = walk_tree (gimple_omp_atomic_store_val_ptr (omp_stmt),
492 : : callback_op, wi, pset);
493 : 51961 : if (ret)
494 : : return ret;
495 : : }
496 : : break;
497 : :
498 : 12 : case GIMPLE_ASSUME:
499 : 12 : ret = walk_tree (gimple_assume_guard_ptr (stmt), callback_op, wi, pset);
500 : 12 : if (ret)
501 : : return ret;
502 : : break;
503 : :
504 : 69366 : case GIMPLE_TRANSACTION:
505 : 69366 : {
506 : 69366 : gtransaction *txn = as_a <gtransaction *> (stmt);
507 : :
508 : 69366 : ret = walk_tree (gimple_transaction_label_norm_ptr (txn),
509 : : callback_op, wi, pset);
510 : 69366 : if (ret)
511 : : return ret;
512 : 69366 : ret = walk_tree (gimple_transaction_label_uninst_ptr (txn),
513 : : callback_op, wi, pset);
514 : 69366 : if (ret)
515 : : return ret;
516 : 69366 : ret = walk_tree (gimple_transaction_label_over_ptr (txn),
517 : : callback_op, wi, pset);
518 : 69366 : if (ret)
519 : : return ret;
520 : : }
521 : : break;
522 : :
523 : 397968 : case GIMPLE_OMP_RETURN:
524 : 397968 : ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
525 : : pset);
526 : 397968 : if (ret)
527 : : return ret;
528 : : break;
529 : :
530 : : /* Tuples that do not have operands. */
531 : : case GIMPLE_NOP:
532 : : case GIMPLE_RESX:
533 : : case GIMPLE_PREDICT:
534 : : break;
535 : :
536 : 2243 : case GIMPLE_PHI:
537 : : /* PHIs are not GSS_WITH_OPS so we need to handle them explicitely. */
538 : 2243 : {
539 : 2243 : gphi *phi = as_a <gphi *> (stmt);
540 : 2243 : if (wi)
541 : : {
542 : 2243 : wi->val_only = true;
543 : 2243 : wi->is_lhs = true;
544 : : }
545 : 2243 : ret = walk_tree (gimple_phi_result_ptr (phi), callback_op, wi, pset);
546 : 2243 : if (wi)
547 : 2243 : wi->is_lhs = false;
548 : 2243 : if (ret)
549 : : return ret;
550 : 4805 : for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
551 : : {
552 : 2562 : ret = walk_tree (gimple_phi_arg_def_ptr (phi, i),
553 : : callback_op, wi, pset);
554 : 2562 : if (ret)
555 : 0 : return ret;
556 : : }
557 : : break;
558 : : }
559 : :
560 : 11080553928 : default:
561 : 11080553928 : {
562 : 11080553928 : enum gimple_statement_structure_enum gss;
563 : 11080553928 : gss = gimple_statement_structure (stmt);
564 : 11080553928 : if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
565 : 30714574294 : for (i = 0; i < gimple_num_ops (stmt); i++)
566 : : {
567 : 19639831149 : ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
568 : 19639831149 : if (ret)
569 : 0 : return ret;
570 : : }
571 : : }
572 : : break;
573 : : }
574 : :
575 : : return NULL_TREE;
576 : : }
577 : :
578 : :
579 : : /* Walk the current statement in GSI (optionally using traversal state
580 : : stored in WI). If WI is NULL, no state is kept during traversal.
581 : : The callback CALLBACK_STMT is called. If CALLBACK_STMT indicates
582 : : that it has handled all the operands of the statement, its return
583 : : value is returned. Otherwise, the return value from CALLBACK_STMT
584 : : is discarded and its operands are scanned.
585 : :
586 : : If CALLBACK_STMT is NULL or it didn't handle the operands,
587 : : CALLBACK_OP is called on each operand of the statement via
588 : : walk_gimple_op. If walk_gimple_op returns non-NULL for any
589 : : operand, the remaining operands are not scanned. In this case, the
590 : : return value from CALLBACK_OP is returned.
591 : :
592 : : In any other case, NULL_TREE is returned. */
593 : :
594 : : tree
595 : 192042310 : walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
596 : : walk_tree_fn callback_op, struct walk_stmt_info *wi)
597 : : {
598 : 192042310 : gimple *ret;
599 : 192042310 : tree tree_ret;
600 : 192042310 : gimple *stmt = gsi_stmt (*gsi);
601 : :
602 : 192042310 : if (wi)
603 : : {
604 : 192040466 : wi->gsi = *gsi;
605 : 192040466 : wi->removed_stmt = false;
606 : :
607 : 192040466 : if (wi->want_locations && gimple_has_location (stmt))
608 : 4710542 : input_location = gimple_location (stmt);
609 : : }
610 : :
611 : 192042310 : ret = NULL;
612 : :
613 : : /* Invoke the statement callback. Return if the callback handled
614 : : all of STMT operands by itself. */
615 : 192042310 : if (callback_stmt)
616 : : {
617 : 192005389 : bool handled_ops = false;
618 : 192005389 : tree_ret = callback_stmt (gsi, &handled_ops, wi);
619 : 192005368 : if (handled_ops)
620 : 15440381 : return tree_ret;
621 : :
622 : : /* If CALLBACK_STMT did not handle operands, it should not have
623 : : a value to return. */
624 : 176564987 : gcc_assert (tree_ret == NULL);
625 : :
626 : 176564987 : if (wi && wi->removed_stmt)
627 : : return NULL;
628 : :
629 : : /* Re-read stmt in case the callback changed it. */
630 : 176564987 : stmt = gsi_stmt (*gsi);
631 : : }
632 : :
633 : : /* If CALLBACK_OP is defined, invoke it on every operand of STMT. */
634 : 176601908 : if (callback_op)
635 : : {
636 : 18553617 : tree_ret = walk_gimple_op (stmt, callback_op, wi);
637 : 18553617 : if (tree_ret)
638 : : return tree_ret;
639 : : }
640 : :
641 : : /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */
642 : 176601908 : switch (gimple_code (stmt))
643 : : {
644 : 2138786 : case GIMPLE_BIND:
645 : 2138786 : ret = walk_gimple_seq_mod (gimple_bind_body_ptr (as_a <gbind *> (stmt)),
646 : : callback_stmt, callback_op, wi);
647 : 2138773 : if (ret)
648 : 12117 : return wi->callback_result;
649 : : break;
650 : :
651 : 35236 : case GIMPLE_CATCH:
652 : 35236 : ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (
653 : : as_a <gcatch *> (stmt)),
654 : : callback_stmt, callback_op, wi);
655 : 35236 : if (ret)
656 : 0 : return wi->callback_result;
657 : : break;
658 : :
659 : 163 : case GIMPLE_EH_FILTER:
660 : 163 : ret = walk_gimple_seq_mod (gimple_eh_filter_failure_ptr (stmt), callback_stmt,
661 : : callback_op, wi);
662 : 163 : if (ret)
663 : 0 : return wi->callback_result;
664 : : break;
665 : :
666 : 990 : case GIMPLE_EH_ELSE:
667 : 990 : {
668 : 990 : geh_else *eh_else_stmt = as_a <geh_else *> (stmt);
669 : 990 : ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (eh_else_stmt),
670 : : callback_stmt, callback_op, wi);
671 : 990 : if (ret)
672 : 0 : return wi->callback_result;
673 : 990 : ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (eh_else_stmt),
674 : : callback_stmt, callback_op, wi);
675 : 990 : if (ret)
676 : 0 : return wi->callback_result;
677 : : }
678 : : break;
679 : :
680 : 519860 : case GIMPLE_TRY:
681 : 519860 : ret = walk_gimple_seq_mod (gimple_try_eval_ptr (stmt), callback_stmt, callback_op,
682 : : wi);
683 : 519852 : if (ret)
684 : 210 : return wi->callback_result;
685 : :
686 : 519642 : ret = walk_gimple_seq_mod (gimple_try_cleanup_ptr (stmt), callback_stmt,
687 : : callback_op, wi);
688 : 519642 : if (ret)
689 : 0 : return wi->callback_result;
690 : : break;
691 : :
692 : 8008 : case GIMPLE_OMP_FOR:
693 : 8008 : ret = walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt), callback_stmt,
694 : : callback_op, wi);
695 : 8008 : if (ret)
696 : 0 : return wi->callback_result;
697 : :
698 : : /* FALL THROUGH. */
699 : 26245 : case GIMPLE_OMP_CRITICAL:
700 : 26245 : case GIMPLE_OMP_MASTER:
701 : 26245 : case GIMPLE_OMP_MASKED:
702 : 26245 : case GIMPLE_OMP_TASKGROUP:
703 : 26245 : case GIMPLE_OMP_ORDERED:
704 : 26245 : case GIMPLE_OMP_SCAN:
705 : 26245 : case GIMPLE_OMP_SECTION:
706 : 26245 : case GIMPLE_OMP_STRUCTURED_BLOCK:
707 : 26245 : case GIMPLE_OMP_PARALLEL:
708 : 26245 : case GIMPLE_OMP_TASK:
709 : 26245 : case GIMPLE_OMP_SCOPE:
710 : 26245 : case GIMPLE_OMP_SECTIONS:
711 : 26245 : case GIMPLE_OMP_SINGLE:
712 : 26245 : case GIMPLE_OMP_TARGET:
713 : 26245 : case GIMPLE_OMP_TEAMS:
714 : 26245 : ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
715 : : callback_op, wi);
716 : 26245 : if (ret)
717 : 0 : return wi->callback_result;
718 : : break;
719 : :
720 : 0 : case GIMPLE_WITH_CLEANUP_EXPR:
721 : 0 : ret = walk_gimple_seq_mod (gimple_wce_cleanup_ptr (stmt), callback_stmt,
722 : : callback_op, wi);
723 : 0 : if (ret)
724 : 0 : return wi->callback_result;
725 : : break;
726 : :
727 : 27 : case GIMPLE_ASSUME:
728 : 27 : ret = walk_gimple_seq_mod (gimple_assume_body_ptr (stmt),
729 : : callback_stmt, callback_op, wi);
730 : 27 : if (ret)
731 : 0 : return wi->callback_result;
732 : : break;
733 : :
734 : 757 : case GIMPLE_TRANSACTION:
735 : 757 : ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (
736 : : as_a <gtransaction *> (stmt)),
737 : : callback_stmt, callback_op, wi);
738 : 757 : if (ret)
739 : 4 : return wi->callback_result;
740 : : break;
741 : :
742 : 173879844 : default:
743 : 173879844 : gcc_assert (!gimple_has_substatements (stmt));
744 : : break;
745 : : }
746 : :
747 : : return NULL;
748 : : }
749 : :
750 : : /* From a tree operand OP return the base of a load or store operation
751 : : or NULL_TREE if OP is not a load or a store. */
752 : :
753 : : static tree
754 : 1032375286 : get_base_loadstore (tree op)
755 : : {
756 : 1185947479 : while (handled_component_p (op))
757 : 153572193 : op = TREE_OPERAND (op, 0);
758 : 1032375286 : if (DECL_P (op)
759 : 811834620 : || INDIRECT_REF_P (op)
760 : 811834620 : || TREE_CODE (op) == MEM_REF
761 : 663986792 : || TREE_CODE (op) == TARGET_MEM_REF)
762 : 373790726 : return op;
763 : : return NULL_TREE;
764 : : }
765 : :
766 : :
767 : : /* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and
768 : : VISIT_ADDR if non-NULL on loads, store and address-taken operands
769 : : passing the STMT, the base of the operand, the operand itself containing
770 : : the base and DATA to it. The base will be either a decl, an indirect
771 : : reference (including TARGET_MEM_REF) or the argument of an address
772 : : expression.
773 : : Returns the results of these callbacks or'ed. */
774 : :
775 : : bool
776 : 1923986787 : walk_stmt_load_store_addr_ops (gimple *stmt, void *data,
777 : : walk_stmt_load_store_addr_fn visit_load,
778 : : walk_stmt_load_store_addr_fn visit_store,
779 : : walk_stmt_load_store_addr_fn visit_addr)
780 : : {
781 : 1923986787 : bool ret = false;
782 : 1923986787 : unsigned i;
783 : 1923986787 : if (gimple_assign_single_p (stmt))
784 : : {
785 : 534051506 : tree lhs, rhs, arg;
786 : 534051506 : if (visit_store)
787 : : {
788 : 355997162 : arg = gimple_assign_lhs (stmt);
789 : 355997162 : lhs = get_base_loadstore (arg);
790 : 355997162 : if (lhs)
791 : 176658018 : ret |= visit_store (stmt, lhs, arg, data);
792 : : }
793 : 534051506 : arg = gimple_assign_rhs1 (stmt);
794 : 534051506 : rhs = arg;
795 : 1270343513 : while (handled_component_p (rhs))
796 : 202240501 : rhs = TREE_OPERAND (rhs, 0);
797 : 534051506 : if (visit_addr)
798 : : {
799 : 342844157 : if (TREE_CODE (rhs) == ADDR_EXPR)
800 : 29674622 : ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), arg, data);
801 : 313169535 : else if (TREE_CODE (rhs) == OBJ_TYPE_REF
802 : 313169535 : && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
803 : 1 : ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
804 : : 0), arg, data);
805 : 313169534 : else if (TREE_CODE (rhs) == CONSTRUCTOR)
806 : : {
807 : : unsigned int ix;
808 : : tree val;
809 : :
810 : 36078581 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
811 : 2972079 : if (TREE_CODE (val) == ADDR_EXPR)
812 : 0 : ret |= visit_addr (stmt, TREE_OPERAND (val, 0), arg, data);
813 : 2972079 : else if (TREE_CODE (val) == OBJ_TYPE_REF
814 : 2972079 : && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
815 : 0 : ret |= visit_addr (stmt,
816 : 0 : TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
817 : : 0), arg, data);
818 : : }
819 : : }
820 : 534051506 : if (visit_load)
821 : : {
822 : 355995290 : rhs = get_base_loadstore (rhs);
823 : 355995290 : if (rhs)
824 : 161948974 : ret |= visit_load (stmt, rhs, arg, data);
825 : : }
826 : : }
827 : 1389935281 : else if (visit_addr
828 : 1389935281 : && (is_gimple_assign (stmt)
829 : 653903794 : || gimple_code (stmt) == GIMPLE_COND))
830 : : {
831 : 942789921 : for (i = 0; i < gimple_num_ops (stmt); ++i)
832 : : {
833 : 714613606 : tree op = gimple_op (stmt, i);
834 : 714613606 : if (op == NULL_TREE)
835 : : ;
836 : 562859198 : else if (TREE_CODE (op) == ADDR_EXPR)
837 : 6235801 : ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
838 : : /* COND_EXPR and VCOND_EXPR rhs1 argument is a comparison
839 : : tree with two operands. */
840 : 556623397 : else if (i == 1 && COMPARISON_CLASS_P (op))
841 : : {
842 : 0 : if (TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
843 : 0 : ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 0),
844 : : 0), op, data);
845 : 0 : if (TREE_CODE (TREE_OPERAND (op, 1)) == ADDR_EXPR)
846 : 0 : ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 1),
847 : : 0), op, data);
848 : : }
849 : : }
850 : : }
851 : 1161758966 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
852 : : {
853 : 185711241 : if (visit_store)
854 : : {
855 : 136058043 : tree arg = gimple_call_lhs (call_stmt);
856 : 136058043 : if (arg)
857 : : {
858 : 55570603 : tree lhs = get_base_loadstore (arg);
859 : 55570603 : if (lhs)
860 : 10897848 : ret |= visit_store (stmt, lhs, arg, data);
861 : : }
862 : : }
863 : 185711241 : if (visit_load || visit_addr)
864 : 561838924 : for (i = 0; i < gimple_call_num_args (call_stmt); ++i)
865 : : {
866 : 376435648 : tree arg = gimple_call_arg (call_stmt, i);
867 : 376435648 : if (visit_addr
868 : 216399232 : && TREE_CODE (arg) == ADDR_EXPR)
869 : 63793185 : ret |= visit_addr (stmt, TREE_OPERAND (arg, 0), arg, data);
870 : 312642463 : else if (visit_load)
871 : : {
872 : 243157867 : tree rhs = get_base_loadstore (arg);
873 : 243157867 : if (rhs)
874 : 19403751 : ret |= visit_load (stmt, rhs, arg, data);
875 : : }
876 : : }
877 : 185403276 : if (visit_addr
878 : 108053740 : && gimple_call_chain (call_stmt)
879 : 185959256 : && TREE_CODE (gimple_call_chain (call_stmt)) == ADDR_EXPR)
880 : 227781 : ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (call_stmt), 0),
881 : : gimple_call_chain (call_stmt), data);
882 : 185711241 : if (visit_addr
883 : 108053740 : && gimple_call_return_slot_opt_p (call_stmt)
884 : 4062300 : && gimple_call_lhs (call_stmt) != NULL_TREE
885 : 189703882 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call_stmt))))
886 : 690686 : ret |= visit_addr (stmt, gimple_call_lhs (call_stmt),
887 : : gimple_call_lhs (call_stmt), data);
888 : : }
889 : 976047725 : else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt))
890 : : {
891 : 1975141 : unsigned noutputs;
892 : 1975141 : const char *constraint;
893 : 1975141 : const char **oconstraints;
894 : 1975141 : bool allows_mem, allows_reg, is_inout;
895 : 1975141 : noutputs = gimple_asm_noutputs (asm_stmt);
896 : 1975141 : oconstraints = XALLOCAVEC (const char *, noutputs);
897 : 1975141 : if (visit_store || visit_addr)
898 : 4032888 : for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
899 : : {
900 : 2057747 : tree link = gimple_asm_output_op (asm_stmt, i);
901 : 2057747 : tree op = get_base_loadstore (TREE_VALUE (link));
902 : 2057747 : if (op && visit_store)
903 : 280793 : ret |= visit_store (stmt, op, TREE_VALUE (link), data);
904 : 2057747 : if (visit_addr)
905 : : {
906 : 1400422 : constraint = TREE_STRING_POINTER
907 : : (TREE_VALUE (TREE_PURPOSE (link)));
908 : 1400422 : oconstraints[i] = constraint;
909 : 1400422 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
910 : : &allows_reg, &is_inout);
911 : 1400422 : if (op && !allows_reg && allows_mem)
912 : 77935 : ret |= visit_addr (stmt, op, TREE_VALUE (link), data);
913 : : }
914 : : }
915 : 1975141 : if (visit_load || visit_addr)
916 : 3165297 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
917 : : {
918 : 1191283 : tree link = gimple_asm_input_op (asm_stmt, i);
919 : 1191283 : tree op = TREE_VALUE (link);
920 : 1191283 : if (visit_addr
921 : 845760 : && TREE_CODE (op) == ADDR_EXPR)
922 : 73023 : ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
923 : 1118260 : else if (visit_load || visit_addr)
924 : : {
925 : 1118260 : op = get_base_loadstore (op);
926 : 1118260 : if (op)
927 : : {
928 : 177838 : if (visit_load)
929 : 97800 : ret |= visit_load (stmt, op, TREE_VALUE (link), data);
930 : 177838 : if (visit_addr)
931 : : {
932 : 152001 : constraint = TREE_STRING_POINTER
933 : : (TREE_VALUE (TREE_PURPOSE (link)));
934 : 152001 : parse_input_constraint (&constraint, 0, 0, noutputs,
935 : : 0, oconstraints,
936 : : &allows_mem, &allows_reg);
937 : 152001 : if (!allows_reg && allows_mem)
938 : 83363 : ret |= visit_addr (stmt, op, TREE_VALUE (link),
939 : : data);
940 : : }
941 : : }
942 : : }
943 : : }
944 : : }
945 : 974072584 : else if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
946 : : {
947 : 46408041 : tree op = gimple_return_retval (return_stmt);
948 : 46408041 : if (op)
949 : : {
950 : 25074745 : if (visit_addr
951 : 13824797 : && TREE_CODE (op) == ADDR_EXPR)
952 : 26924 : ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
953 : 25047821 : else if (visit_load)
954 : : {
955 : 18478357 : tree base = get_base_loadstore (op);
956 : 18478357 : if (base)
957 : 4224536 : ret |= visit_load (stmt, base, op, data);
958 : : }
959 : : }
960 : : }
961 : 927664543 : else if (visit_addr
962 : 927664543 : && gimple_code (stmt) == GIMPLE_PHI)
963 : : {
964 : 104826966 : for (i = 0; i < gimple_phi_num_args (stmt); ++i)
965 : : {
966 : 75727401 : tree op = gimple_phi_arg_def (stmt, i);
967 : 75727401 : if (TREE_CODE (op) == ADDR_EXPR)
968 : 613903 : ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
969 : : }
970 : : }
971 : 898564978 : else if (visit_addr
972 : 898564978 : && gimple_code (stmt) == GIMPLE_GOTO)
973 : : {
974 : 5678 : tree op = gimple_goto_dest (stmt);
975 : 5678 : if (TREE_CODE (op) == ADDR_EXPR)
976 : 87 : ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
977 : : }
978 : :
979 : 1923986787 : return ret;
980 : : }
981 : :
982 : : /* Like walk_stmt_load_store_addr_ops but with NULL visit_addr. IPA-CP
983 : : should make a faster clone for this case. */
984 : :
985 : : bool
986 : 774939725 : walk_stmt_load_store_ops (gimple *stmt, void *data,
987 : : walk_stmt_load_store_addr_fn visit_load,
988 : : walk_stmt_load_store_addr_fn visit_store)
989 : : {
990 : 774939725 : return walk_stmt_load_store_addr_ops (stmt, data,
991 : 774939725 : visit_load, visit_store, NULL);
992 : : }
|