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