1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees 2 tree representation into the GIMPLE form. 3 Copyright (C) 2002-2024 Free Software Foundation, Inc. 4 Major work done by Sebastian Pop <s.pop (at) laposte.net>, 5 Diego Novillo <dnovillo (at) redhat.com> and Jason Merrill <jason (at) redhat.com>. 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free 11 Software Foundation; either version 3, or (at your option) any later 12 version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "backend.h" 27 #include "target.h" 28 #include "rtl.h" 29 #include "tree.h" 30 #include "memmodel.h" 31 #include "tm_p.h" 32 #include "gimple.h" 33 #include "gimple-predict.h" 34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */ 35 #include "ssa.h" 36 #include "cgraph.h" 37 #include "tree-pretty-print.h" 38 #include "diagnostic-core.h" 39 #include "diagnostic.h" /* For errorcount. */ 40 #include "alias.h" 41 #include "fold-const.h" 42 #include "calls.h" 43 #include "varasm.h" 44 #include "stmt.h" 45 #include "expr.h" 46 #include "gimple-iterator.h" 47 #include "gimple-fold.h" 48 #include "tree-eh.h" 49 #include "gimplify.h" 50 #include "stor-layout.h" 51 #include "print-tree.h" 52 #include "tree-iterator.h" 53 #include "tree-inline.h" 54 #include "langhooks.h" 55 #include "tree-cfg.h" 56 #include "tree-ssa.h" 57 #include "tree-hash-traits.h" 58 #include "omp-general.h" 59 #include "omp-low.h" 60 #include "gimple-low.h" 61 #include "gomp-constants.h" 62 #include "splay-tree.h" 63 #include "gimple-walk.h" 64 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */ 65 #include "builtins.h" 66 #include "stringpool.h" 67 #include "attribs.h" 68 #include "asan.h" 69 #include "dbgcnt.h" 70 #include "omp-offload.h" 71 #include "context.h" 72 #include "tree-nested.h" 73 74 /* Identifier for a basic condition, mapping it to other basic conditions of 75 its Boolean expression. Basic conditions given the same uid (in the same 76 function) are parts of the same ANDIF/ORIF expression. Used for condition 77 coverage. */ 78 static unsigned nextuid = 1; 79 /* Get a fresh identifier for a new condition expression. This is used for 80 condition coverage. */ 81 static unsigned 82 next_cond_uid () 83 { 84 return nextuid++; 85 } 86 /* Reset the condition uid to the value it should have when compiling a new 87 function. 0 is already the default/untouched value, so start at non-zero. 88 A valid and set id should always be > 0. This is used for condition 89 coverage. */ 90 static void 91 reset_cond_uid () 92 { 93 nextuid = 1; 94 } 95 96 /* Hash set of poisoned variables in a bind expr. */ 97 static hash_set<tree> *asan_poisoned_variables = NULL; 98 99 enum gimplify_omp_var_data 100 { 101 GOVD_SEEN = 0x000001, 102 GOVD_EXPLICIT = 0x000002, 103 GOVD_SHARED = 0x000004, 104 GOVD_PRIVATE = 0x000008, 105 GOVD_FIRSTPRIVATE = 0x000010, 106 GOVD_LASTPRIVATE = 0x000020, 107 GOVD_REDUCTION = 0x000040, 108 GOVD_LOCAL = 0x00080, 109 GOVD_MAP = 0x000100, 110 GOVD_DEBUG_PRIVATE = 0x000200, 111 GOVD_PRIVATE_OUTER_REF = 0x000400, 112 GOVD_LINEAR = 0x000800, 113 GOVD_ALIGNED = 0x001000, 114 115 /* Flag for GOVD_MAP: don't copy back. */ 116 GOVD_MAP_TO_ONLY = 0x002000, 117 118 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */ 119 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000, 120 121 GOVD_MAP_0LEN_ARRAY = 0x008000, 122 123 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */ 124 GOVD_MAP_ALWAYS_TO = 0x010000, 125 126 /* Flag for shared vars that are or might be stored to in the region. */ 127 GOVD_WRITTEN = 0x020000, 128 129 /* Flag for GOVD_MAP, if it is a forced mapping. */ 130 GOVD_MAP_FORCE = 0x040000, 131 132 /* Flag for GOVD_MAP: must be present already. */ 133 GOVD_MAP_FORCE_PRESENT = 0x080000, 134 135 /* Flag for GOVD_MAP: only allocate. */ 136 GOVD_MAP_ALLOC_ONLY = 0x100000, 137 138 /* Flag for GOVD_MAP: only copy back. */ 139 GOVD_MAP_FROM_ONLY = 0x200000, 140 141 GOVD_NONTEMPORAL = 0x400000, 142 143 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */ 144 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000, 145 146 GOVD_CONDTEMP = 0x1000000, 147 148 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */ 149 GOVD_REDUCTION_INSCAN = 0x2000000, 150 151 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */ 152 GOVD_FIRSTPRIVATE_IMPLICIT = 0x4000000, 153 154 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE 155 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR 156 | GOVD_LOCAL) 157 }; 158 159 160 enum omp_region_type 161 { 162 ORT_WORKSHARE = 0x00, 163 ORT_TASKGROUP = 0x01, 164 ORT_SIMD = 0x04, 165 166 ORT_PARALLEL = 0x08, 167 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1, 168 169 ORT_TASK = 0x10, 170 ORT_UNTIED_TASK = ORT_TASK | 1, 171 ORT_TASKLOOP = ORT_TASK | 2, 172 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2, 173 174 ORT_TEAMS = 0x20, 175 ORT_COMBINED_TEAMS = ORT_TEAMS | 1, 176 ORT_HOST_TEAMS = ORT_TEAMS | 2, 177 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2, 178 179 /* Data region. */ 180 ORT_TARGET_DATA = 0x40, 181 182 /* Data region with offloading. */ 183 ORT_TARGET = 0x80, 184 ORT_COMBINED_TARGET = ORT_TARGET | 1, 185 ORT_IMPLICIT_TARGET = ORT_TARGET | 2, 186 187 /* OpenACC variants. */ 188 ORT_ACC = 0x100, /* A generic OpenACC region. */ 189 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */ 190 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */ 191 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */ 192 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */ 193 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */ 194 195 /* Dummy OpenMP region, used to disable expansion of 196 DECL_VALUE_EXPRs in taskloop pre body. */ 197 ORT_NONE = 0x200 198 }; 199 200 /* Gimplify hashtable helper. */ 201 202 struct gimplify_hasher : free_ptr_hash <elt_t> 203 { 204 static inline hashval_t hash (const elt_t *); 205 static inline bool equal (const elt_t *, const elt_t *); 206 }; 207 208 struct gimplify_ctx 209 { 210 struct gimplify_ctx *prev_context; 211 212 vec<gbind *> bind_expr_stack; 213 tree temps; 214 gimple_seq conditional_cleanups; 215 tree exit_label; 216 tree return_temp; 217 218 vec<tree> case_labels; 219 hash_set<tree> *live_switch_vars; 220 /* The formal temporary table. Should this be persistent? */ 221 hash_table<gimplify_hasher> *temp_htab; 222 223 int conditions; 224 unsigned into_ssa : 1; 225 unsigned allow_rhs_cond_expr : 1; 226 unsigned in_cleanup_point_expr : 1; 227 unsigned keep_stack : 1; 228 unsigned save_stack : 1; 229 unsigned in_switch_expr : 1; 230 unsigned in_handler_expr : 1; 231 }; 232 233 enum gimplify_defaultmap_kind 234 { 235 GDMK_SCALAR, 236 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */ 237 GDMK_AGGREGATE, 238 GDMK_ALLOCATABLE, 239 GDMK_POINTER 240 }; 241 242 struct gimplify_omp_ctx 243 { 244 struct gimplify_omp_ctx *outer_context; 245 splay_tree variables; 246 hash_set<tree> *privatized_types; 247 tree clauses; 248 /* Iteration variables in an OMP_FOR. */ 249 vec<tree> loop_iter_var; 250 location_t location; 251 enum omp_clause_default_kind default_kind; 252 enum omp_region_type region_type; 253 enum tree_code code; 254 bool combined_loop; 255 bool distribute; 256 bool target_firstprivatize_array_bases; 257 bool add_safelen1; 258 bool order_concurrent; 259 bool has_depend; 260 bool in_for_exprs; 261 int defaultmap[5]; 262 }; 263 264 static struct gimplify_ctx *gimplify_ctxp; 265 static struct gimplify_omp_ctx *gimplify_omp_ctxp; 266 static bool in_omp_construct; 267 268 /* Forward declaration. */ 269 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool); 270 static hash_map<tree, tree> *oacc_declare_returns; 271 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *, 272 bool (*) (tree), fallback_t, bool); 273 static void prepare_gimple_addressable (tree *, gimple_seq *); 274 275 /* Shorter alias name for the above function for use in gimplify.cc 276 only. */ 277 278 static inline void 279 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs) 280 { 281 gimple_seq_add_stmt_without_update (seq_p, gs); 282 } 283 284 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is 285 NULL, a new sequence is allocated. This function is 286 similar to gimple_seq_add_seq, but does not scan the operands. 287 During gimplification, we need to manipulate statement sequences 288 before the def/use vectors have been constructed. */ 289 290 static void 291 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src) 292 { 293 gimple_stmt_iterator si; 294 295 if (src == NULL) 296 return; 297 298 si = gsi_last (*dst_p); 299 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT); 300 } 301 302 303 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing 304 and popping gimplify contexts. */ 305 306 static struct gimplify_ctx *ctx_pool = NULL; 307 308 /* Return a gimplify context struct from the pool. */ 309 310 static inline struct gimplify_ctx * 311 ctx_alloc (void) 312 { 313 struct gimplify_ctx * c = ctx_pool; 314 315 if (c) 316 ctx_pool = c->prev_context; 317 else 318 c = XNEW (struct gimplify_ctx); 319 320 memset (c, '\0', sizeof (*c)); 321 return c; 322 } 323 324 /* Put gimplify context C back into the pool. */ 325 326 static inline void 327 ctx_free (struct gimplify_ctx *c) 328 { 329 c->prev_context = ctx_pool; 330 ctx_pool = c; 331 } 332 333 /* Free allocated ctx stack memory. */ 334 335 void 336 free_gimplify_stack (void) 337 { 338 struct gimplify_ctx *c; 339 340 while ((c = ctx_pool)) 341 { 342 ctx_pool = c->prev_context; 343 free (c); 344 } 345 } 346 347 348 /* Set up a context for the gimplifier. */ 349 350 void 351 push_gimplify_context (bool in_ssa, bool rhs_cond_ok) 352 { 353 struct gimplify_ctx *c = ctx_alloc (); 354 355 c->prev_context = gimplify_ctxp; 356 gimplify_ctxp = c; 357 gimplify_ctxp->into_ssa = in_ssa; 358 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok; 359 } 360 361 /* Tear down a context for the gimplifier. If BODY is non-null, then 362 put the temporaries into the outer BIND_EXPR. Otherwise, put them 363 in the local_decls. 364 365 BODY is not a sequence, but the first tuple in a sequence. */ 366 367 void 368 pop_gimplify_context (gimple *body) 369 { 370 struct gimplify_ctx *c = gimplify_ctxp; 371 372 gcc_assert (c 373 && (!c->bind_expr_stack.exists () 374 || c->bind_expr_stack.is_empty ())); 375 c->bind_expr_stack.release (); 376 gimplify_ctxp = c->prev_context; 377 378 if (body) 379 declare_vars (c->temps, body, false); 380 else 381 record_vars (c->temps); 382 383 delete c->temp_htab; 384 c->temp_htab = NULL; 385 ctx_free (c); 386 } 387 388 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */ 389 390 static void 391 gimple_push_bind_expr (gbind *bind_stmt) 392 { 393 gimplify_ctxp->bind_expr_stack.reserve (8); 394 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt); 395 } 396 397 /* Pop the first element off the stack of bindings. */ 398 399 static void 400 gimple_pop_bind_expr (void) 401 { 402 gimplify_ctxp->bind_expr_stack.pop (); 403 } 404 405 /* Return the first element of the stack of bindings. */ 406 407 gbind * 408 gimple_current_bind_expr (void) 409 { 410 return gimplify_ctxp->bind_expr_stack.last (); 411 } 412 413 /* Return the stack of bindings created during gimplification. */ 414 415 vec<gbind *> 416 gimple_bind_expr_stack (void) 417 { 418 return gimplify_ctxp->bind_expr_stack; 419 } 420 421 /* Return true iff there is a COND_EXPR between us and the innermost 422 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */ 423 424 static bool 425 gimple_conditional_context (void) 426 { 427 return gimplify_ctxp->conditions > 0; 428 } 429 430 /* Note that we've entered a COND_EXPR. */ 431 432 static void 433 gimple_push_condition (void) 434 { 435 #ifdef ENABLE_GIMPLE_CHECKING 436 if (gimplify_ctxp->conditions == 0) 437 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups)); 438 #endif 439 ++(gimplify_ctxp->conditions); 440 } 441 442 /* Note that we've left a COND_EXPR. If we're back at unconditional scope 443 now, add any conditional cleanups we've seen to the prequeue. */ 444 445 static void 446 gimple_pop_condition (gimple_seq *pre_p) 447 { 448 int conds = --(gimplify_ctxp->conditions); 449 450 gcc_assert (conds >= 0); 451 if (conds == 0) 452 { 453 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups); 454 gimplify_ctxp->conditional_cleanups = NULL; 455 } 456 } 457 458 /* A stable comparison routine for use with splay trees and DECLs. */ 459 460 static int 461 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) 462 { 463 tree a = (tree) xa; 464 tree b = (tree) xb; 465 466 return DECL_UID (a) - DECL_UID (b); 467 } 468 469 /* Create a new omp construct that deals with variable remapping. */ 470 471 static struct gimplify_omp_ctx * 472 new_omp_context (enum omp_region_type region_type) 473 { 474 struct gimplify_omp_ctx *c; 475 476 c = XCNEW (struct gimplify_omp_ctx); 477 c->outer_context = gimplify_omp_ctxp; 478 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 479 c->privatized_types = new hash_set<tree>; 480 c->location = input_location; 481 c->region_type = region_type; 482 if ((region_type & ORT_TASK) == 0) 483 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED; 484 else 485 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; 486 c->defaultmap[GDMK_SCALAR] = GOVD_MAP; 487 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP; 488 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP; 489 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP; 490 c->defaultmap[GDMK_POINTER] = GOVD_MAP; 491 492 return c; 493 } 494 495 /* Destroy an omp construct that deals with variable remapping. */ 496 497 static void 498 delete_omp_context (struct gimplify_omp_ctx *c) 499 { 500 splay_tree_delete (c->variables); 501 delete c->privatized_types; 502 c->loop_iter_var.release (); 503 XDELETE (c); 504 } 505 506 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int); 507 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool); 508 509 /* Both gimplify the statement T and append it to *SEQ_P. This function 510 behaves exactly as gimplify_stmt, but you don't have to pass T as a 511 reference. */ 512 513 void 514 gimplify_and_add (tree t, gimple_seq *seq_p) 515 { 516 gimplify_stmt (&t, seq_p); 517 } 518 519 /* Gimplify statement T into sequence *SEQ_P, and return the first 520 tuple in the sequence of generated tuples for this statement. 521 Return NULL if gimplifying T produced no tuples. */ 522 523 static gimple * 524 gimplify_and_return_first (tree t, gimple_seq *seq_p) 525 { 526 gimple_stmt_iterator last = gsi_last (*seq_p); 527 528 gimplify_and_add (t, seq_p); 529 530 if (!gsi_end_p (last)) 531 { 532 gsi_next (&last); 533 return gsi_stmt (last); 534 } 535 else 536 return gimple_seq_first_stmt (*seq_p); 537 } 538 539 /* Returns true iff T is a valid RHS for an assignment to an un-renamed 540 LHS, or for a call argument. */ 541 542 static bool 543 is_gimple_mem_rhs (tree t) 544 { 545 /* If we're dealing with a renamable type, either source or dest must be 546 a renamed variable. */ 547 if (is_gimple_reg_type (TREE_TYPE (t))) 548 return is_gimple_val (t); 549 else 550 return is_gimple_val (t) || is_gimple_lvalue (t); 551 } 552 553 /* Return true if T is a CALL_EXPR or an expression that can be 554 assigned to a temporary. Note that this predicate should only be 555 used during gimplification. See the rationale for this in 556 gimplify_modify_expr. */ 557 558 static bool 559 is_gimple_reg_rhs_or_call (tree t) 560 { 561 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS 562 || TREE_CODE (t) == CALL_EXPR); 563 } 564 565 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that 566 this predicate should only be used during gimplification. See the 567 rationale for this in gimplify_modify_expr. */ 568 569 static bool 570 is_gimple_mem_rhs_or_call (tree t) 571 { 572 /* If we're dealing with a renamable type, either source or dest must be 573 a renamed variable. */ 574 if (is_gimple_reg_type (TREE_TYPE (t))) 575 return is_gimple_val (t); 576 else 577 return (is_gimple_val (t) 578 || is_gimple_lvalue (t) 579 || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0) 580 || TREE_CODE (t) == CALL_EXPR); 581 } 582 583 /* Create a temporary with a name derived from VAL. Subroutine of 584 lookup_tmp_var; nobody else should call this function. */ 585 586 static inline tree 587 create_tmp_from_val (tree val) 588 { 589 /* Drop all qualifiers and address-space information from the value type. */ 590 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val)); 591 tree var = create_tmp_var (type, get_name (val)); 592 return var; 593 } 594 595 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse 596 an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */ 597 598 static tree 599 lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg) 600 { 601 tree ret; 602 603 /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */ 604 gcc_assert (!is_formal || !not_gimple_reg); 605 606 /* If not optimizing, never really reuse a temporary. local-alloc 607 won't allocate any variable that is used in more than one basic 608 block, which means it will go into memory, causing much extra 609 work in reload and final and poorer code generation, outweighing 610 the extra memory allocation here. */ 611 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val)) 612 { 613 ret = create_tmp_from_val (val); 614 DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg; 615 } 616 else 617 { 618 elt_t elt, *elt_p; 619 elt_t **slot; 620 621 elt.val = val; 622 if (!gimplify_ctxp->temp_htab) 623 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000); 624 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT); 625 if (*slot == NULL) 626 { 627 elt_p = XNEW (elt_t); 628 elt_p->val = val; 629 elt_p->temp = ret = create_tmp_from_val (val); 630 *slot = elt_p; 631 } 632 else 633 { 634 elt_p = *slot; 635 ret = elt_p->temp; 636 } 637 } 638 639 return ret; 640 } 641 642 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */ 643 644 static tree 645 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, 646 bool is_formal, bool allow_ssa, bool not_gimple_reg) 647 { 648 tree t, mod; 649 650 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we 651 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */ 652 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call, 653 fb_rvalue); 654 655 if (allow_ssa 656 && gimplify_ctxp->into_ssa 657 && is_gimple_reg_type (TREE_TYPE (val))) 658 { 659 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val))); 660 if (! gimple_in_ssa_p (cfun)) 661 { 662 const char *name = get_name (val); 663 if (name) 664 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name)); 665 } 666 } 667 else 668 t = lookup_tmp_var (val, is_formal, not_gimple_reg); 669 670 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val)); 671 672 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location)); 673 674 /* gimplify_modify_expr might want to reduce this further. */ 675 gimplify_and_add (mod, pre_p); 676 ggc_free (mod); 677 678 /* If we failed to gimplify VAL then we can end up with the temporary 679 SSA name not having a definition. In this case return a decl. */ 680 if (TREE_CODE (t) == SSA_NAME && ! SSA_NAME_DEF_STMT (t)) 681 return lookup_tmp_var (val, is_formal, not_gimple_reg); 682 683 return t; 684 } 685 686 /* Return a formal temporary variable initialized with VAL. PRE_P is as 687 in gimplify_expr. Only use this function if: 688 689 1) The value of the unfactored expression represented by VAL will not 690 change between the initialization and use of the temporary, and 691 2) The temporary will not be otherwise modified. 692 693 For instance, #1 means that this is inappropriate for SAVE_EXPR temps, 694 and #2 means it is inappropriate for && temps. 695 696 For other cases, use get_initialized_tmp_var instead. */ 697 698 tree 699 get_formal_tmp_var (tree val, gimple_seq *pre_p) 700 { 701 return internal_get_tmp_var (val, pre_p, NULL, true, true, false); 702 } 703 704 /* Return a temporary variable initialized with VAL. PRE_P and POST_P 705 are as in gimplify_expr. */ 706 707 tree 708 get_initialized_tmp_var (tree val, gimple_seq *pre_p, 709 gimple_seq *post_p /* = NULL */, 710 bool allow_ssa /* = true */) 711 { 712 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false); 713 } 714 715 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true, 716 generate debug info for them; otherwise don't. */ 717 718 void 719 declare_vars (tree vars, gimple *gs, bool debug_info) 720 { 721 tree last = vars; 722 if (last) 723 { 724 tree temps, block; 725 726 gbind *scope = as_a <gbind *> (gs); 727 728 temps = nreverse (last); 729 730 block = gimple_bind_block (scope); 731 gcc_assert (!block || TREE_CODE (block) == BLOCK); 732 if (!block || !debug_info) 733 { 734 DECL_CHAIN (last) = gimple_bind_vars (scope); 735 gimple_bind_set_vars (scope, temps); 736 } 737 else 738 { 739 /* We need to attach the nodes both to the BIND_EXPR and to its 740 associated BLOCK for debugging purposes. The key point here 741 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR 742 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */ 743 if (BLOCK_VARS (block)) 744 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps); 745 else 746 { 747 gimple_bind_set_vars (scope, 748 chainon (gimple_bind_vars (scope), temps)); 749 BLOCK_VARS (block) = temps; 750 } 751 } 752 } 753 } 754 755 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound 756 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if 757 no such upper bound can be obtained. */ 758 759 static void 760 force_constant_size (tree var) 761 { 762 /* The only attempt we make is by querying the maximum size of objects 763 of the variable's type. */ 764 765 HOST_WIDE_INT max_size; 766 767 gcc_assert (VAR_P (var)); 768 769 max_size = max_int_size_in_bytes (TREE_TYPE (var)); 770 771 gcc_assert (max_size >= 0); 772 773 DECL_SIZE_UNIT (var) 774 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size); 775 DECL_SIZE (var) 776 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT); 777 } 778 779 /* Push the temporary variable TMP into the current binding. */ 780 781 void 782 gimple_add_tmp_var_fn (struct function *fn, tree tmp) 783 { 784 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); 785 786 /* Later processing assumes that the object size is constant, which might 787 not be true at this point. Force the use of a constant upper bound in 788 this case. */ 789 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp))) 790 force_constant_size (tmp); 791 792 DECL_CONTEXT (tmp) = fn->decl; 793 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; 794 795 record_vars_into (tmp, fn->decl); 796 } 797 798 /* Push the temporary variable TMP into the current binding. */ 799 800 void 801 gimple_add_tmp_var (tree tmp) 802 { 803 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); 804 805 /* Later processing assumes that the object size is constant, which might 806 not be true at this point. Force the use of a constant upper bound in 807 this case. */ 808 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp))) 809 force_constant_size (tmp); 810 811 DECL_CONTEXT (tmp) = current_function_decl; 812 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; 813 814 if (gimplify_ctxp) 815 { 816 DECL_CHAIN (tmp) = gimplify_ctxp->temps; 817 gimplify_ctxp->temps = tmp; 818 819 /* Mark temporaries local within the nearest enclosing parallel. */ 820 if (gimplify_omp_ctxp) 821 { 822 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 823 int flag = GOVD_LOCAL | GOVD_SEEN; 824 while (ctx 825 && (ctx->region_type == ORT_WORKSHARE 826 || ctx->region_type == ORT_TASKGROUP 827 || ctx->region_type == ORT_SIMD 828 || ctx->region_type == ORT_ACC)) 829 { 830 if (ctx->region_type == ORT_SIMD 831 && TREE_ADDRESSABLE (tmp) 832 && !TREE_STATIC (tmp)) 833 { 834 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST) 835 ctx->add_safelen1 = true; 836 else if (ctx->in_for_exprs) 837 flag = GOVD_PRIVATE; 838 else 839 flag = GOVD_PRIVATE | GOVD_SEEN; 840 break; 841 } 842 ctx = ctx->outer_context; 843 } 844 if (ctx) 845 omp_add_variable (ctx, tmp, flag); 846 } 847 } 848 else if (cfun) 849 record_vars (tmp); 850 else 851 { 852 gimple_seq body_seq; 853 854 /* This case is for nested functions. We need to expose the locals 855 they create. */ 856 body_seq = gimple_body (current_function_decl); 857 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false); 858 } 859 } 860 861 862 863 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree 865 nodes that are referenced more than once in GENERIC functions. This is 866 necessary because gimplification (translation into GIMPLE) is performed 867 by modifying tree nodes in-place, so gimplication of a shared node in a 868 first context could generate an invalid GIMPLE form in a second context. 869 870 This is achieved with a simple mark/copy/unmark algorithm that walks the 871 GENERIC representation top-down, marks nodes with TREE_VISITED the first 872 time it encounters them, duplicates them if they already have TREE_VISITED 873 set, and finally removes the TREE_VISITED marks it has set. 874 875 The algorithm works only at the function level, i.e. it generates a GENERIC 876 representation of a function with no nodes shared within the function when 877 passed a GENERIC function (except for nodes that are allowed to be shared). 878 879 At the global level, it is also necessary to unshare tree nodes that are 880 referenced in more than one function, for the same aforementioned reason. 881 This requires some cooperation from the front-end. There are 2 strategies: 882 883 1. Manual unsharing. The front-end needs to call unshare_expr on every 884 expression that might end up being shared across functions. 885 886 2. Deep unsharing. This is an extension of regular unsharing. Instead 887 of calling unshare_expr on expressions that might be shared across 888 functions, the front-end pre-marks them with TREE_VISITED. This will 889 ensure that they are unshared on the first reference within functions 890 when the regular unsharing algorithm runs. The counterpart is that 891 this algorithm must look deeper than for manual unsharing, which is 892 specified by LANG_HOOKS_DEEP_UNSHARING. 893 894 If there are only few specific cases of node sharing across functions, it is 895 probably easier for a front-end to unshare the expressions manually. On the 896 contrary, if the expressions generated at the global level are as widespread 897 as expressions generated within functions, deep unsharing is very likely the 898 way to go. */ 899 900 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes. 901 These nodes model computations that must be done once. If we were to 902 unshare something like SAVE_EXPR(i++), the gimplification process would 903 create wrong code. However, if DATA is non-null, it must hold a pointer 904 set that is used to unshare the subtrees of these nodes. */ 905 906 static tree 907 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) 908 { 909 tree t = *tp; 910 enum tree_code code = TREE_CODE (t); 911 912 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but 913 copy their subtrees if we can make sure to do it only once. */ 914 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR) 915 { 916 if (data && !((hash_set<tree> *)data)->add (t)) 917 ; 918 else 919 *walk_subtrees = 0; 920 } 921 922 /* Stop at types, decls, constants like copy_tree_r. */ 923 else if (TREE_CODE_CLASS (code) == tcc_type 924 || TREE_CODE_CLASS (code) == tcc_declaration 925 || TREE_CODE_CLASS (code) == tcc_constant) 926 *walk_subtrees = 0; 927 928 /* Cope with the statement expression extension. */ 929 else if (code == STATEMENT_LIST) 930 ; 931 932 /* Leave the bulk of the work to copy_tree_r itself. */ 933 else 934 copy_tree_r (tp, walk_subtrees, NULL); 935 936 return NULL_TREE; 937 } 938 939 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP. 940 If *TP has been visited already, then *TP is deeply copied by calling 941 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */ 942 943 static tree 944 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) 945 { 946 tree t = *tp; 947 enum tree_code code = TREE_CODE (t); 948 949 /* Skip types, decls, and constants. But we do want to look at their 950 types and the bounds of types. Mark them as visited so we properly 951 unmark their subtrees on the unmark pass. If we've already seen them, 952 don't look down further. */ 953 if (TREE_CODE_CLASS (code) == tcc_type 954 || TREE_CODE_CLASS (code) == tcc_declaration 955 || TREE_CODE_CLASS (code) == tcc_constant) 956 { 957 if (TREE_VISITED (t)) 958 *walk_subtrees = 0; 959 else 960 TREE_VISITED (t) = 1; 961 } 962 963 /* If this node has been visited already, unshare it and don't look 964 any deeper. */ 965 else if (TREE_VISITED (t)) 966 { 967 walk_tree (tp, mostly_copy_tree_r, data, NULL); 968 *walk_subtrees = 0; 969 } 970 971 /* Otherwise, mark the node as visited and keep looking. */ 972 else 973 TREE_VISITED (t) = 1; 974 975 return NULL_TREE; 976 } 977 978 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the 979 copy_if_shared_r callback unmodified. */ 980 981 void 982 copy_if_shared (tree *tp, void *data) 983 { 984 walk_tree (tp, copy_if_shared_r, data, NULL); 985 } 986 987 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of 988 any nested functions. */ 989 990 static void 991 unshare_body (tree fndecl) 992 { 993 struct cgraph_node *cgn = cgraph_node::get (fndecl); 994 /* If the language requires deep unsharing, we need a pointer set to make 995 sure we don't repeatedly unshare subtrees of unshareable nodes. */ 996 hash_set<tree> *visited 997 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL; 998 999 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited); 1000 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited); 1001 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited); 1002 1003 delete visited; 1004 1005 if (cgn) 1006 for (cgn = first_nested_function (cgn); cgn; 1007 cgn = next_nested_function (cgn)) 1008 unshare_body (cgn->decl); 1009 } 1010 1011 /* Callback for walk_tree to unmark the visited trees rooted at *TP. 1012 Subtrees are walked until the first unvisited node is encountered. */ 1013 1014 static tree 1015 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 1016 { 1017 tree t = *tp; 1018 1019 /* If this node has been visited, unmark it and keep looking. */ 1020 if (TREE_VISITED (t)) 1021 TREE_VISITED (t) = 0; 1022 1023 /* Otherwise, don't look any deeper. */ 1024 else 1025 *walk_subtrees = 0; 1026 1027 return NULL_TREE; 1028 } 1029 1030 /* Unmark the visited trees rooted at *TP. */ 1031 1032 static inline void 1033 unmark_visited (tree *tp) 1034 { 1035 walk_tree (tp, unmark_visited_r, NULL, NULL); 1036 } 1037 1038 /* Likewise, but mark all trees as not visited. */ 1039 1040 static void 1041 unvisit_body (tree fndecl) 1042 { 1043 struct cgraph_node *cgn = cgraph_node::get (fndecl); 1044 1045 unmark_visited (&DECL_SAVED_TREE (fndecl)); 1046 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl))); 1047 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl))); 1048 1049 if (cgn) 1050 for (cgn = first_nested_function (cgn); 1051 cgn; cgn = next_nested_function (cgn)) 1052 unvisit_body (cgn->decl); 1053 } 1054 1055 /* Unconditionally make an unshared copy of EXPR. This is used when using 1056 stored expressions which span multiple functions, such as BINFO_VTABLE, 1057 as the normal unsharing process can't tell that they're shared. */ 1058 1059 tree 1060 unshare_expr (tree expr) 1061 { 1062 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); 1063 return expr; 1064 } 1065 1066 /* Worker for unshare_expr_without_location. */ 1067 1068 static tree 1069 prune_expr_location (tree *tp, int *walk_subtrees, void *) 1070 { 1071 if (EXPR_P (*tp)) 1072 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION); 1073 else 1074 *walk_subtrees = 0; 1075 return NULL_TREE; 1076 } 1077 1078 /* Similar to unshare_expr but also prune all expression locations 1079 from EXPR. */ 1080 1081 tree 1082 unshare_expr_without_location (tree expr) 1083 { 1084 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); 1085 if (EXPR_P (expr)) 1086 walk_tree (&expr, prune_expr_location, NULL, NULL); 1087 return expr; 1088 } 1089 1090 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has 1091 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs 1092 comprising at least one DEBUG_BEGIN_STMT followed by exactly one 1093 EXPR is the location of the EXPR. */ 1094 1095 static location_t 1096 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION) 1097 { 1098 if (!expr) 1099 return or_else; 1100 1101 if (EXPR_HAS_LOCATION (expr)) 1102 return EXPR_LOCATION (expr); 1103 1104 if (TREE_CODE (expr) != STATEMENT_LIST) 1105 return or_else; 1106 1107 tree_stmt_iterator i = tsi_start (expr); 1108 1109 bool found = false; 1110 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT) 1111 { 1112 found = true; 1113 tsi_next (&i); 1114 } 1115 1116 if (!found || !tsi_one_before_end_p (i)) 1117 return or_else; 1118 1119 return rexpr_location (tsi_stmt (i), or_else); 1120 } 1121 1122 /* Return TRUE iff EXPR (maybe recursively) has a location; see 1123 rexpr_location for the potential recursion. */ 1124 1125 static inline bool 1126 rexpr_has_location (tree expr) 1127 { 1128 return rexpr_location (expr) != UNKNOWN_LOCATION; 1129 } 1130 1131 1132 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both 1134 contain statements and have a value. Assign its value to a temporary 1135 and give it void_type_node. Return the temporary, or NULL_TREE if 1136 WRAPPER was already void. */ 1137 1138 tree 1139 voidify_wrapper_expr (tree wrapper, tree temp) 1140 { 1141 tree type = TREE_TYPE (wrapper); 1142 if (type && !VOID_TYPE_P (type)) 1143 { 1144 tree *p; 1145 1146 /* Set p to point to the body of the wrapper. Loop until we find 1147 something that isn't a wrapper. */ 1148 for (p = &wrapper; p && *p; ) 1149 { 1150 switch (TREE_CODE (*p)) 1151 { 1152 case BIND_EXPR: 1153 TREE_SIDE_EFFECTS (*p) = 1; 1154 TREE_TYPE (*p) = void_type_node; 1155 /* For a BIND_EXPR, the body is operand 1. */ 1156 p = &BIND_EXPR_BODY (*p); 1157 break; 1158 1159 case CLEANUP_POINT_EXPR: 1160 case TRY_FINALLY_EXPR: 1161 case TRY_CATCH_EXPR: 1162 TREE_SIDE_EFFECTS (*p) = 1; 1163 TREE_TYPE (*p) = void_type_node; 1164 p = &TREE_OPERAND (*p, 0); 1165 break; 1166 1167 case STATEMENT_LIST: 1168 { 1169 tree_stmt_iterator i = tsi_last (*p); 1170 TREE_SIDE_EFFECTS (*p) = 1; 1171 TREE_TYPE (*p) = void_type_node; 1172 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i); 1173 } 1174 break; 1175 1176 case COMPOUND_EXPR: 1177 /* Advance to the last statement. Set all container types to 1178 void. */ 1179 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)) 1180 { 1181 TREE_SIDE_EFFECTS (*p) = 1; 1182 TREE_TYPE (*p) = void_type_node; 1183 } 1184 break; 1185 1186 case TRANSACTION_EXPR: 1187 TREE_SIDE_EFFECTS (*p) = 1; 1188 TREE_TYPE (*p) = void_type_node; 1189 p = &TRANSACTION_EXPR_BODY (*p); 1190 break; 1191 1192 default: 1193 /* Assume that any tree upon which voidify_wrapper_expr is 1194 directly called is a wrapper, and that its body is op0. */ 1195 if (p == &wrapper) 1196 { 1197 TREE_SIDE_EFFECTS (*p) = 1; 1198 TREE_TYPE (*p) = void_type_node; 1199 p = &TREE_OPERAND (*p, 0); 1200 break; 1201 } 1202 goto out; 1203 } 1204 } 1205 1206 out: 1207 if (p == NULL || IS_EMPTY_STMT (*p)) 1208 temp = NULL_TREE; 1209 else if (temp) 1210 { 1211 /* The wrapper is on the RHS of an assignment that we're pushing 1212 down. */ 1213 gcc_assert (TREE_CODE (temp) == INIT_EXPR 1214 || TREE_CODE (temp) == MODIFY_EXPR); 1215 TREE_OPERAND (temp, 1) = *p; 1216 *p = temp; 1217 } 1218 else 1219 { 1220 temp = create_tmp_var (type, "retval"); 1221 *p = build2 (INIT_EXPR, type, temp, *p); 1222 } 1223 1224 return temp; 1225 } 1226 1227 return NULL_TREE; 1228 } 1229 1230 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as 1231 a temporary through which they communicate. */ 1232 1233 static void 1234 build_stack_save_restore (gcall **save, gcall **restore) 1235 { 1236 tree tmp_var; 1237 1238 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0); 1239 tmp_var = create_tmp_var (ptr_type_node, "saved_stack"); 1240 gimple_call_set_lhs (*save, tmp_var); 1241 1242 *restore 1243 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE), 1244 1, tmp_var); 1245 } 1246 1247 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */ 1248 1249 static tree 1250 build_asan_poison_call_expr (tree decl) 1251 { 1252 /* Do not poison variables that have size equal to zero. */ 1253 tree unit_size = DECL_SIZE_UNIT (decl); 1254 if (zerop (unit_size)) 1255 return NULL_TREE; 1256 1257 tree base = build_fold_addr_expr (decl); 1258 1259 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK, 1260 void_type_node, 3, 1261 build_int_cst (integer_type_node, 1262 ASAN_MARK_POISON), 1263 base, unit_size); 1264 } 1265 1266 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending 1267 on POISON flag, shadow memory of a DECL variable. The call will be 1268 put on location identified by IT iterator, where BEFORE flag drives 1269 position where the stmt will be put. */ 1270 1271 static void 1272 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it, 1273 bool before) 1274 { 1275 tree unit_size = DECL_SIZE_UNIT (decl); 1276 tree base = build_fold_addr_expr (decl); 1277 1278 /* Do not poison variables that have size equal to zero. */ 1279 if (zerop (unit_size)) 1280 return; 1281 1282 /* It's necessary to have all stack variables aligned to ASAN granularity 1283 bytes. */ 1284 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ()); 1285 unsigned shadow_granularity 1286 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY; 1287 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity) 1288 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity); 1289 1290 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON; 1291 1292 gimple *g 1293 = gimple_build_call_internal (IFN_ASAN_MARK, 3, 1294 build_int_cst (integer_type_node, flags), 1295 base, unit_size); 1296 1297 if (before) 1298 gsi_insert_before (it, g, GSI_NEW_STMT); 1299 else 1300 gsi_insert_after (it, g, GSI_NEW_STMT); 1301 } 1302 1303 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag 1304 either poisons or unpoisons a DECL. Created statement is appended 1305 to SEQ_P gimple sequence. */ 1306 1307 static void 1308 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p) 1309 { 1310 gimple_stmt_iterator it = gsi_last (*seq_p); 1311 bool before = false; 1312 1313 if (gsi_end_p (it)) 1314 before = true; 1315 1316 asan_poison_variable (decl, poison, &it, before); 1317 } 1318 1319 /* Sort pair of VAR_DECLs A and B by DECL_UID. */ 1320 1321 static int 1322 sort_by_decl_uid (const void *a, const void *b) 1323 { 1324 const tree *t1 = (const tree *)a; 1325 const tree *t2 = (const tree *)b; 1326 1327 int uid1 = DECL_UID (*t1); 1328 int uid2 = DECL_UID (*t2); 1329 1330 if (uid1 < uid2) 1331 return -1; 1332 else if (uid1 > uid2) 1333 return 1; 1334 else 1335 return 0; 1336 } 1337 1338 /* Generate IFN_ASAN_MARK internal call for all VARIABLES 1339 depending on POISON flag. Created statement is appended 1340 to SEQ_P gimple sequence. */ 1341 1342 static void 1343 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p) 1344 { 1345 unsigned c = variables->elements (); 1346 if (c == 0) 1347 return; 1348 1349 auto_vec<tree> sorted_variables (c); 1350 1351 for (hash_set<tree>::iterator it = variables->begin (); 1352 it != variables->end (); ++it) 1353 sorted_variables.safe_push (*it); 1354 1355 sorted_variables.qsort (sort_by_decl_uid); 1356 1357 unsigned i; 1358 tree var; 1359 FOR_EACH_VEC_ELT (sorted_variables, i, var) 1360 { 1361 asan_poison_variable (var, poison, seq_p); 1362 1363 /* Add use_after_scope_memory attribute for the variable in order 1364 to prevent re-written into SSA. */ 1365 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE, 1366 DECL_ATTRIBUTES (var))) 1367 DECL_ATTRIBUTES (var) 1368 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE), 1369 integer_one_node, 1370 DECL_ATTRIBUTES (var)); 1371 } 1372 } 1373 1374 /* Gimplify a BIND_EXPR. Just voidify and recurse. */ 1375 1376 static enum gimplify_status 1377 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) 1378 { 1379 tree bind_expr = *expr_p; 1380 bool old_keep_stack = gimplify_ctxp->keep_stack; 1381 bool old_save_stack = gimplify_ctxp->save_stack; 1382 tree t; 1383 gbind *bind_stmt; 1384 gimple_seq body, cleanup; 1385 gcall *stack_save; 1386 location_t start_locus = 0, end_locus = 0; 1387 tree ret_clauses = NULL; 1388 1389 tree temp = voidify_wrapper_expr (bind_expr, NULL); 1390 1391 /* Mark variables seen in this bind expr. */ 1392 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t)) 1393 { 1394 if (VAR_P (t)) 1395 { 1396 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 1397 tree attr; 1398 1399 if (flag_openmp 1400 && !is_global_var (t) 1401 && DECL_CONTEXT (t) == current_function_decl 1402 && TREE_USED (t) 1403 && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) 1404 != NULL_TREE) 1405 { 1406 gcc_assert (!DECL_HAS_VALUE_EXPR_P (t)); 1407 tree alloc = TREE_PURPOSE (TREE_VALUE (attr)); 1408 tree align = TREE_VALUE (TREE_VALUE (attr)); 1409 /* Allocate directives that appear in a target region must specify 1410 an allocator clause unless a requires directive with the 1411 dynamic_allocators clause is present in the same compilation 1412 unit. */ 1413 bool missing_dyn_alloc = false; 1414 if (alloc == NULL_TREE 1415 && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) 1416 == 0)) 1417 { 1418 /* This comes too early for omp_discover_declare_target..., 1419 but should at least catch the most common cases. */ 1420 missing_dyn_alloc 1421 = cgraph_node::get (current_function_decl)->offloadable; 1422 for (struct gimplify_omp_ctx *ctx2 = ctx; 1423 ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context) 1424 if (ctx2->code == OMP_TARGET) 1425 missing_dyn_alloc = true; 1426 } 1427 if (missing_dyn_alloc) 1428 error_at (DECL_SOURCE_LOCATION (t), 1429 "%<allocate%> directive for %qD inside a target " 1430 "region must specify an %<allocator%> clause", t); 1431 /* Skip for omp_default_mem_alloc (= 1), 1432 unless align is present. */ 1433 else if (!errorcount 1434 && (align != NULL_TREE 1435 || alloc == NULL_TREE 1436 || !integer_onep (alloc))) 1437 { 1438 /* Fortran might already use a pointer type internally; 1439 use that pointer except for type(C_ptr) and type(C_funptr); 1440 note that normal proc pointers are rejected. */ 1441 tree type = TREE_TYPE (t); 1442 tree tmp, v; 1443 if (lang_GNU_Fortran () 1444 && POINTER_TYPE_P (type) 1445 && TREE_TYPE (type) != void_type_node 1446 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE) 1447 { 1448 type = TREE_TYPE (type); 1449 v = t; 1450 } 1451 else 1452 { 1453 tmp = build_pointer_type (type); 1454 v = create_tmp_var (tmp, get_name (t)); 1455 DECL_IGNORED_P (v) = 0; 1456 DECL_ATTRIBUTES (v) 1457 = tree_cons (get_identifier ("omp allocate var"), 1458 build_tree_list (NULL_TREE, t), 1459 remove_attribute ("omp allocate", 1460 DECL_ATTRIBUTES (t))); 1461 tmp = build_fold_indirect_ref (v); 1462 TREE_THIS_NOTRAP (tmp) = 1; 1463 SET_DECL_VALUE_EXPR (t, tmp); 1464 DECL_HAS_VALUE_EXPR_P (t) = 1; 1465 } 1466 tree sz = TYPE_SIZE_UNIT (type); 1467 /* The size to use in Fortran might not match TYPE_SIZE_UNIT; 1468 hence, for some decls, a size variable is saved in the 1469 attributes; use it, if available. */ 1470 if (TREE_CHAIN (TREE_VALUE (attr)) 1471 && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))) 1472 && TREE_PURPOSE ( 1473 TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))) 1474 { 1475 sz = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))); 1476 sz = TREE_PURPOSE (sz); 1477 } 1478 if (alloc == NULL_TREE) 1479 alloc = build_zero_cst (ptr_type_node); 1480 if (align == NULL_TREE) 1481 align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t)); 1482 else 1483 align = build_int_cst (size_type_node, 1484 MAX (tree_to_uhwi (align), 1485 DECL_ALIGN_UNIT (t))); 1486 location_t loc = DECL_SOURCE_LOCATION (t); 1487 tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC); 1488 tmp = build_call_expr_loc (loc, tmp, 3, align, sz, alloc); 1489 tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v, 1490 fold_convert (TREE_TYPE (v), tmp)); 1491 gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE); 1492 /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set 1493 and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t) 1494 is set, using in a condition much further below. */ 1495 gcc_assert (DECL_HAS_VALUE_EXPR_P (t) 1496 || TREE_CHAIN (TREE_VALUE (attr))); 1497 if (TREE_CHAIN (TREE_VALUE (attr))) 1498 { 1499 /* Fortran is special as it does not have properly nest 1500 declarations in blocks. And as there is no 1501 initializer, there is also no expression to look for. 1502 Hence, the FE makes the statement list of the 1503 try-finally block available. We can put the GOMP_alloc 1504 at the top, unless an allocator or size expression 1505 requires to put it afterward; note that the size is 1506 always later in generated code; for strings, no 1507 size expr but still an expr might be available. 1508 As LTO does not handle a statement list, 'sl' has 1509 to be removed; done so by removing the attribute. */ 1510 DECL_ATTRIBUTES (t) 1511 = remove_attribute ("omp allocate", 1512 DECL_ATTRIBUTES (t)); 1513 tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr))); 1514 tree_stmt_iterator e = tsi_start (sl); 1515 tree needle = NULL_TREE; 1516 if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))) 1517 { 1518 needle = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))); 1519 needle = (TREE_VALUE (needle) ? TREE_VALUE (needle) 1520 : sz); 1521 } 1522 else if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))) 1523 needle = sz; 1524 else if (DECL_P (alloc) && DECL_ARTIFICIAL (alloc)) 1525 needle = alloc; 1526 1527 if (needle != NULL_TREE) 1528 { 1529 while (!tsi_end_p (e)) 1530 { 1531 if (*e == needle 1532 || (TREE_CODE (*e) == MODIFY_EXPR 1533 && TREE_OPERAND (*e, 0) == needle)) 1534 break; 1535 ++e; 1536 } 1537 gcc_assert (!tsi_end_p (e)); 1538 } 1539 tsi_link_after (&e, tmp, TSI_SAME_STMT); 1540 1541 /* As the cleanup is in BIND_EXPR_BODY, GOMP_free is added 1542 here; for C/C++ it will be added in the 'cleanup' 1543 section after gimplification. But Fortran already has 1544 a try-finally block. */ 1545 sl = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr))); 1546 e = tsi_last (sl); 1547 tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE); 1548 tmp = build_call_expr_loc (EXPR_LOCATION (*e), tmp, 2, v, 1549 build_zero_cst (ptr_type_node)); 1550 tsi_link_after (&e, tmp, TSI_SAME_STMT); 1551 tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END); 1552 tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v, 1553 fold_convert (TREE_TYPE (v), tmp)); 1554 ++e; 1555 tsi_link_after (&e, tmp, TSI_SAME_STMT); 1556 } 1557 else 1558 { 1559 gcc_assert (TREE_CODE (BIND_EXPR_BODY (bind_expr)) 1560 == STATEMENT_LIST); 1561 tree_stmt_iterator e; 1562 e = tsi_start (BIND_EXPR_BODY (bind_expr)); 1563 while (!tsi_end_p (e)) 1564 { 1565 if ((TREE_CODE (*e) == DECL_EXPR 1566 && TREE_OPERAND (*e, 0) == t) 1567 || (TREE_CODE (*e) == CLEANUP_POINT_EXPR 1568 && (TREE_CODE (TREE_OPERAND (*e, 0)) 1569 == DECL_EXPR) 1570 && (TREE_OPERAND (TREE_OPERAND (*e, 0), 0) 1571 == t))) 1572 break; 1573 ++e; 1574 } 1575 gcc_assert (!tsi_end_p (e)); 1576 tsi_link_before (&e, tmp, TSI_SAME_STMT); 1577 } 1578 } 1579 } 1580 1581 /* Mark variable as local. */ 1582 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)) 1583 { 1584 if (! DECL_SEEN_IN_BIND_EXPR_P (t) 1585 || splay_tree_lookup (ctx->variables, 1586 (splay_tree_key) t) == NULL) 1587 { 1588 int flag = GOVD_LOCAL; 1589 if (ctx->region_type == ORT_SIMD 1590 && TREE_ADDRESSABLE (t) 1591 && !TREE_STATIC (t)) 1592 { 1593 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST) 1594 ctx->add_safelen1 = true; 1595 else 1596 flag = GOVD_PRIVATE; 1597 } 1598 omp_add_variable (ctx, t, flag | GOVD_SEEN); 1599 } 1600 /* Static locals inside of target construct or offloaded 1601 routines need to be "omp declare target". */ 1602 if (TREE_STATIC (t)) 1603 for (; ctx; ctx = ctx->outer_context) 1604 if ((ctx->region_type & ORT_TARGET) != 0) 1605 { 1606 if (!lookup_attribute ("omp declare target", 1607 DECL_ATTRIBUTES (t))) 1608 { 1609 tree id = get_identifier ("omp declare target"); 1610 DECL_ATTRIBUTES (t) 1611 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 1612 varpool_node *node = varpool_node::get (t); 1613 if (node) 1614 { 1615 node->offloadable = 1; 1616 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t)) 1617 { 1618 g->have_offload = true; 1619 if (!in_lto_p) 1620 vec_safe_push (offload_vars, t); 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 } 1627 1628 DECL_SEEN_IN_BIND_EXPR_P (t) = 1; 1629 1630 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) 1631 cfun->has_local_explicit_reg_vars = true; 1632 } 1633 } 1634 1635 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL, 1636 BIND_EXPR_BLOCK (bind_expr)); 1637 gimple_push_bind_expr (bind_stmt); 1638 1639 gimplify_ctxp->keep_stack = false; 1640 gimplify_ctxp->save_stack = false; 1641 1642 /* Gimplify the body into the GIMPLE_BIND tuple's body. */ 1643 body = NULL; 1644 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body); 1645 gimple_bind_set_body (bind_stmt, body); 1646 1647 /* Source location wise, the cleanup code (stack_restore and clobbers) 1648 belongs to the end of the block, so propagate what we have. The 1649 stack_save operation belongs to the beginning of block, which we can 1650 infer from the bind_expr directly if the block has no explicit 1651 assignment. */ 1652 if (BIND_EXPR_BLOCK (bind_expr)) 1653 { 1654 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr)); 1655 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr)); 1656 } 1657 if (start_locus == 0) 1658 start_locus = EXPR_LOCATION (bind_expr); 1659 1660 cleanup = NULL; 1661 stack_save = NULL; 1662 1663 /* Add clobbers for all variables that go out of scope. */ 1664 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t)) 1665 { 1666 if (VAR_P (t) 1667 && !is_global_var (t) 1668 && DECL_CONTEXT (t) == current_function_decl) 1669 { 1670 if (flag_openmp 1671 && DECL_HAS_VALUE_EXPR_P (t) 1672 && TREE_USED (t) 1673 && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) 1674 { 1675 /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which 1676 causes that the GOMP_free call is already added above; 1677 and "omp allocate" is removed from DECL_ATTRIBUTES. */ 1678 tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0); 1679 tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE); 1680 tmp = build_call_expr_loc (end_locus, tmp, 2, v, 1681 build_zero_cst (ptr_type_node)); 1682 gimplify_and_add (tmp, &cleanup); 1683 gimple *clobber_stmt; 1684 tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END); 1685 clobber_stmt = gimple_build_assign (v, tmp); 1686 gimple_set_location (clobber_stmt, end_locus); 1687 gimplify_seq_add_stmt (&cleanup, clobber_stmt); 1688 } 1689 if (!DECL_HARD_REGISTER (t) 1690 && !TREE_THIS_VOLATILE (t) 1691 && !DECL_HAS_VALUE_EXPR_P (t) 1692 /* Only care for variables that have to be in memory. Others 1693 will be rewritten into SSA names, hence moved to the 1694 top-level. */ 1695 && !is_gimple_reg (t) 1696 && flag_stack_reuse != SR_NONE) 1697 { 1698 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_STORAGE_END); 1699 gimple *clobber_stmt; 1700 clobber_stmt = gimple_build_assign (t, clobber); 1701 gimple_set_location (clobber_stmt, end_locus); 1702 gimplify_seq_add_stmt (&cleanup, clobber_stmt); 1703 } 1704 1705 if (flag_openacc && oacc_declare_returns != NULL) 1706 { 1707 tree key = t; 1708 if (DECL_HAS_VALUE_EXPR_P (key)) 1709 { 1710 key = DECL_VALUE_EXPR (key); 1711 if (INDIRECT_REF_P (key)) 1712 key = TREE_OPERAND (key, 0); 1713 } 1714 tree *c = oacc_declare_returns->get (key); 1715 if (c != NULL) 1716 { 1717 if (ret_clauses) 1718 OMP_CLAUSE_CHAIN (*c) = ret_clauses; 1719 1720 ret_clauses = unshare_expr (*c); 1721 1722 oacc_declare_returns->remove (key); 1723 1724 if (oacc_declare_returns->is_empty ()) 1725 { 1726 delete oacc_declare_returns; 1727 oacc_declare_returns = NULL; 1728 } 1729 } 1730 } 1731 } 1732 1733 if (asan_poisoned_variables != NULL 1734 && asan_poisoned_variables->contains (t)) 1735 { 1736 asan_poisoned_variables->remove (t); 1737 asan_poison_variable (t, true, &cleanup); 1738 } 1739 1740 if (gimplify_ctxp->live_switch_vars != NULL 1741 && gimplify_ctxp->live_switch_vars->contains (t)) 1742 gimplify_ctxp->live_switch_vars->remove (t); 1743 } 1744 1745 /* If the code both contains VLAs and calls alloca, then we cannot reclaim 1746 the stack space allocated to the VLAs. */ 1747 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack) 1748 { 1749 gcall *stack_restore; 1750 1751 /* Save stack on entry and restore it on exit. Add a try_finally 1752 block to achieve this. */ 1753 build_stack_save_restore (&stack_save, &stack_restore); 1754 1755 gimple_set_location (stack_save, start_locus); 1756 gimple_set_location (stack_restore, end_locus); 1757 1758 gimplify_seq_add_stmt (&cleanup, stack_restore); 1759 } 1760 1761 if (ret_clauses) 1762 { 1763 gomp_target *stmt; 1764 gimple_stmt_iterator si = gsi_start (cleanup); 1765 1766 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE, 1767 ret_clauses); 1768 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT); 1769 } 1770 1771 if (cleanup) 1772 { 1773 gtry *gs; 1774 gimple_seq new_body; 1775 1776 new_body = NULL; 1777 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup, 1778 GIMPLE_TRY_FINALLY); 1779 1780 if (stack_save) 1781 gimplify_seq_add_stmt (&new_body, stack_save); 1782 gimplify_seq_add_stmt (&new_body, gs); 1783 gimple_bind_set_body (bind_stmt, new_body); 1784 } 1785 1786 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */ 1787 if (!gimplify_ctxp->keep_stack) 1788 gimplify_ctxp->keep_stack = old_keep_stack; 1789 gimplify_ctxp->save_stack = old_save_stack; 1790 1791 gimple_pop_bind_expr (); 1792 1793 gimplify_seq_add_stmt (pre_p, bind_stmt); 1794 1795 if (temp) 1796 { 1797 *expr_p = temp; 1798 return GS_OK; 1799 } 1800 1801 *expr_p = NULL_TREE; 1802 return GS_ALL_DONE; 1803 } 1804 1805 /* Maybe add early return predict statement to PRE_P sequence. */ 1806 1807 static void 1808 maybe_add_early_return_predict_stmt (gimple_seq *pre_p) 1809 { 1810 /* If we are not in a conditional context, add PREDICT statement. */ 1811 if (gimple_conditional_context ()) 1812 { 1813 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN, 1814 NOT_TAKEN); 1815 gimplify_seq_add_stmt (pre_p, predict); 1816 } 1817 } 1818 1819 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a 1820 GIMPLE value, it is assigned to a new temporary and the statement is 1821 re-written to return the temporary. 1822 1823 PRE_P points to the sequence where side effects that must happen before 1824 STMT should be stored. */ 1825 1826 static enum gimplify_status 1827 gimplify_return_expr (tree stmt, gimple_seq *pre_p) 1828 { 1829 greturn *ret; 1830 tree ret_expr = TREE_OPERAND (stmt, 0); 1831 tree result_decl, result; 1832 1833 if (ret_expr == error_mark_node) 1834 return GS_ERROR; 1835 1836 if (!ret_expr 1837 || TREE_CODE (ret_expr) == RESULT_DECL) 1838 { 1839 maybe_add_early_return_predict_stmt (pre_p); 1840 greturn *ret = gimple_build_return (ret_expr); 1841 copy_warning (ret, stmt); 1842 gimplify_seq_add_stmt (pre_p, ret); 1843 return GS_ALL_DONE; 1844 } 1845 1846 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) 1847 result_decl = NULL_TREE; 1848 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR) 1849 { 1850 /* Used in C++ for handling EH cleanup of the return value if a local 1851 cleanup throws. Assume the front-end knows what it's doing. */ 1852 result_decl = DECL_RESULT (current_function_decl); 1853 /* But crash if we end up trying to modify ret_expr below. */ 1854 ret_expr = NULL_TREE; 1855 } 1856 else 1857 { 1858 result_decl = TREE_OPERAND (ret_expr, 0); 1859 1860 /* See through a return by reference. */ 1861 if (INDIRECT_REF_P (result_decl)) 1862 result_decl = TREE_OPERAND (result_decl, 0); 1863 1864 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR 1865 || TREE_CODE (ret_expr) == INIT_EXPR) 1866 && TREE_CODE (result_decl) == RESULT_DECL); 1867 } 1868 1869 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. 1870 Recall that aggregate_value_p is FALSE for any aggregate type that is 1871 returned in registers. If we're returning values in registers, then 1872 we don't want to extend the lifetime of the RESULT_DECL, particularly 1873 across another call. In addition, for those aggregates for which 1874 hard_function_value generates a PARALLEL, we'll die during normal 1875 expansion of structure assignments; there's special code in expand_return 1876 to handle this case that does not exist in expand_expr. */ 1877 if (!result_decl) 1878 result = NULL_TREE; 1879 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl))) 1880 { 1881 if (!poly_int_tree_p (DECL_SIZE (result_decl))) 1882 { 1883 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl))) 1884 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p); 1885 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL 1886 should be effectively allocated by the caller, i.e. all calls to 1887 this function must be subject to the Return Slot Optimization. */ 1888 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p); 1889 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p); 1890 } 1891 result = result_decl; 1892 } 1893 else if (gimplify_ctxp->return_temp) 1894 result = gimplify_ctxp->return_temp; 1895 else 1896 { 1897 result = create_tmp_reg (TREE_TYPE (result_decl)); 1898 1899 /* ??? With complex control flow (usually involving abnormal edges), 1900 we can wind up warning about an uninitialized value for this. Due 1901 to how this variable is constructed and initialized, this is never 1902 true. Give up and never warn. */ 1903 suppress_warning (result, OPT_Wuninitialized); 1904 1905 gimplify_ctxp->return_temp = result; 1906 } 1907 1908 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use. 1909 Then gimplify the whole thing. */ 1910 if (result != result_decl) 1911 TREE_OPERAND (ret_expr, 0) = result; 1912 1913 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p); 1914 1915 maybe_add_early_return_predict_stmt (pre_p); 1916 ret = gimple_build_return (result); 1917 copy_warning (ret, stmt); 1918 gimplify_seq_add_stmt (pre_p, ret); 1919 1920 return GS_ALL_DONE; 1921 } 1922 1923 /* Gimplify a variable-length array DECL. */ 1924 1925 static void 1926 gimplify_vla_decl (tree decl, gimple_seq *seq_p) 1927 { 1928 /* This is a variable-sized decl. Simplify its size and mark it 1929 for deferred expansion. */ 1930 tree t, addr, ptr_type; 1931 1932 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p); 1933 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p); 1934 1935 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */ 1936 if (DECL_HAS_VALUE_EXPR_P (decl)) 1937 return; 1938 1939 /* All occurrences of this decl in final gimplified code will be 1940 replaced by indirection. Setting DECL_VALUE_EXPR does two 1941 things: First, it lets the rest of the gimplifier know what 1942 replacement to use. Second, it lets the debug info know 1943 where to find the value. */ 1944 ptr_type = build_pointer_type (TREE_TYPE (decl)); 1945 addr = create_tmp_var (ptr_type, get_name (decl)); 1946 DECL_IGNORED_P (addr) = 0; 1947 t = build_fold_indirect_ref (addr); 1948 TREE_THIS_NOTRAP (t) = 1; 1949 SET_DECL_VALUE_EXPR (decl, t); 1950 DECL_HAS_VALUE_EXPR_P (decl) = 1; 1951 1952 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl), 1953 max_int_size_in_bytes (TREE_TYPE (decl))); 1954 /* The call has been built for a variable-sized object. */ 1955 CALL_ALLOCA_FOR_VAR_P (t) = 1; 1956 t = fold_convert (ptr_type, t); 1957 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t); 1958 1959 gimplify_and_add (t, seq_p); 1960 1961 /* Record the dynamic allocation associated with DECL if requested. */ 1962 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC) 1963 record_dynamic_alloc (decl); 1964 } 1965 1966 /* A helper function to be called via walk_tree. Mark all labels under *TP 1967 as being forced. To be called for DECL_INITIAL of static variables. */ 1968 1969 static tree 1970 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 1971 { 1972 if (TYPE_P (*tp)) 1973 *walk_subtrees = 0; 1974 if (TREE_CODE (*tp) == LABEL_DECL) 1975 { 1976 FORCED_LABEL (*tp) = 1; 1977 cfun->has_forced_label_in_static = 1; 1978 } 1979 1980 return NULL_TREE; 1981 } 1982 1983 /* Generate an initialization to automatic variable DECL based on INIT_TYPE. 1984 Build a call to internal const function DEFERRED_INIT: 1985 1st argument: SIZE of the DECL; 1986 2nd argument: INIT_TYPE; 1987 3rd argument: NAME of the DECL; 1988 1989 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */ 1990 1991 static void 1992 gimple_add_init_for_auto_var (tree decl, 1993 enum auto_init_type init_type, 1994 gimple_seq *seq_p) 1995 { 1996 gcc_assert (auto_var_p (decl)); 1997 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED); 1998 location_t loc = EXPR_LOCATION (decl); 1999 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 2000 2001 tree init_type_node 2002 = build_int_cst (integer_type_node, (int) init_type); 2003 2004 tree decl_name = NULL_TREE; 2005 if (DECL_NAME (decl)) 2006 2007 decl_name = build_string_literal (DECL_NAME (decl)); 2008 2009 else 2010 { 2011 char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3]; 2012 sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl)); 2013 decl_name = build_string_literal (decl_name_anonymous); 2014 } 2015 2016 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT, 2017 TREE_TYPE (decl), 3, 2018 decl_size, init_type_node, 2019 decl_name); 2020 2021 gimplify_assign (decl, call, seq_p); 2022 } 2023 2024 /* Generate padding initialization for automatic vairable DECL. 2025 C guarantees that brace-init with fewer initializers than members 2026 aggregate will initialize the rest of the aggregate as-if it were 2027 static initialization. In turn static initialization guarantees 2028 that padding is initialized to zero. So, we always initialize paddings 2029 to zeroes regardless INIT_TYPE. 2030 To do the padding initialization, we insert a call to 2031 __builtin_clear_padding (&decl, 0, for_auto_init = true). 2032 Note, we add an additional dummy argument for __builtin_clear_padding, 2033 'for_auto_init' to distinguish whether this call is for automatic 2034 variable initialization or not. 2035 */ 2036 static void 2037 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla, 2038 gimple_seq *seq_p) 2039 { 2040 tree addr_of_decl = NULL_TREE; 2041 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING); 2042 2043 if (is_vla) 2044 { 2045 /* The temporary address variable for this vla should be 2046 created in gimplify_vla_decl. */ 2047 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl)); 2048 gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl))); 2049 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0); 2050 } 2051 else 2052 { 2053 mark_addressable (decl); 2054 addr_of_decl = build_fold_addr_expr (decl); 2055 } 2056 2057 gimple *call = gimple_build_call (fn, 2, addr_of_decl, 2058 build_one_cst (TREE_TYPE (addr_of_decl))); 2059 gimplify_seq_add_stmt (seq_p, call); 2060 } 2061 2062 /* Return true if the DECL need to be automaticly initialized by the 2063 compiler. */ 2064 static bool 2065 is_var_need_auto_init (tree decl) 2066 { 2067 if (auto_var_p (decl) 2068 && (TREE_CODE (decl) != VAR_DECL 2069 || !DECL_HARD_REGISTER (decl)) 2070 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) 2071 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) 2072 && !OPAQUE_TYPE_P (TREE_TYPE (decl)) 2073 && !is_empty_type (TREE_TYPE (decl))) 2074 return true; 2075 return false; 2076 } 2077 2078 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation 2079 and initialization explicit. */ 2080 2081 static enum gimplify_status 2082 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) 2083 { 2084 tree stmt = *stmt_p; 2085 tree decl = DECL_EXPR_DECL (stmt); 2086 2087 *stmt_p = NULL_TREE; 2088 2089 if (TREE_TYPE (decl) == error_mark_node) 2090 return GS_ERROR; 2091 2092 if ((TREE_CODE (decl) == TYPE_DECL 2093 || VAR_P (decl)) 2094 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl))) 2095 { 2096 gimplify_type_sizes (TREE_TYPE (decl), seq_p); 2097 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) 2098 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p); 2099 } 2100 2101 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified 2102 in case its size expressions contain problematic nodes like CALL_EXPR. */ 2103 if (TREE_CODE (decl) == TYPE_DECL 2104 && DECL_ORIGINAL_TYPE (decl) 2105 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl))) 2106 { 2107 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p); 2108 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE) 2109 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p); 2110 } 2111 2112 if (VAR_P (decl) && !DECL_EXTERNAL (decl)) 2113 { 2114 tree init = DECL_INITIAL (decl); 2115 bool is_vla = false; 2116 /* Check whether a decl has FE created VALUE_EXPR here BEFORE 2117 gimplify_vla_decl creates VALUE_EXPR for a vla decl. 2118 If the decl has VALUE_EXPR that was created by FE (usually 2119 C++FE), it's a proxy varaible, and FE already initialized 2120 the VALUE_EXPR of it, we should not initialize it anymore. */ 2121 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl); 2122 2123 poly_uint64 size; 2124 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size) 2125 || (!TREE_STATIC (decl) 2126 && flag_stack_check == GENERIC_STACK_CHECK 2127 && maybe_gt (size, 2128 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE))) 2129 { 2130 gimplify_vla_decl (decl, seq_p); 2131 is_vla = true; 2132 } 2133 2134 if (asan_poisoned_variables 2135 && !is_vla 2136 && TREE_ADDRESSABLE (decl) 2137 && !TREE_STATIC (decl) 2138 && !DECL_HAS_VALUE_EXPR_P (decl) 2139 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT 2140 && dbg_cnt (asan_use_after_scope) 2141 && !gimplify_omp_ctxp 2142 /* GNAT introduces temporaries to hold return values of calls in 2143 initializers of variables defined in other units, so the 2144 declaration of the variable is discarded completely. We do not 2145 want to issue poison calls for such dropped variables. */ 2146 && (DECL_SEEN_IN_BIND_EXPR_P (decl) 2147 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE))) 2148 { 2149 asan_poisoned_variables->add (decl); 2150 asan_poison_variable (decl, false, seq_p); 2151 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars) 2152 gimplify_ctxp->live_switch_vars->add (decl); 2153 } 2154 2155 /* Some front ends do not explicitly declare all anonymous 2156 artificial variables. We compensate here by declaring the 2157 variables, though it would be better if the front ends would 2158 explicitly declare them. */ 2159 if (!DECL_SEEN_IN_BIND_EXPR_P (decl) 2160 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE) 2161 gimple_add_tmp_var (decl); 2162 2163 if (init && init != error_mark_node) 2164 { 2165 if (!TREE_STATIC (decl)) 2166 { 2167 DECL_INITIAL (decl) = NULL_TREE; 2168 init = build2 (INIT_EXPR, void_type_node, decl, init); 2169 gimplify_and_add (init, seq_p); 2170 ggc_free (init); 2171 /* Clear TREE_READONLY if we really have an initialization. */ 2172 if (!DECL_INITIAL (decl) 2173 && !omp_privatize_by_reference (decl)) 2174 TREE_READONLY (decl) = 0; 2175 } 2176 else 2177 /* We must still examine initializers for static variables 2178 as they may contain a label address. */ 2179 walk_tree (&init, force_labels_r, NULL, NULL); 2180 } 2181 /* When there is no explicit initializer, if the user requested, 2182 We should insert an artifical initializer for this automatic 2183 variable. */ 2184 else if (is_var_need_auto_init (decl) 2185 && !decl_had_value_expr_p) 2186 { 2187 gimple_add_init_for_auto_var (decl, 2188 flag_auto_var_init, 2189 seq_p); 2190 /* The expanding of a call to the above .DEFERRED_INIT will apply 2191 block initialization to the whole space covered by this variable. 2192 As a result, all the paddings will be initialized to zeroes 2193 for zero initialization and 0xFE byte-repeatable patterns for 2194 pattern initialization. 2195 In order to make the paddings as zeroes for pattern init, We 2196 should add a call to __builtin_clear_padding to clear the 2197 paddings to zero in compatiple with CLANG. 2198 We cannot insert this call if the variable is a gimple register 2199 since __builtin_clear_padding will take the address of the 2200 variable. As a result, if a long double/_Complex long double 2201 variable will spilled into stack later, its padding is 0XFE. */ 2202 if (flag_auto_var_init == AUTO_INIT_PATTERN 2203 && !is_gimple_reg (decl) 2204 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl))) 2205 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p); 2206 } 2207 } 2208 2209 return GS_ALL_DONE; 2210 } 2211 2212 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body 2213 and replacing the LOOP_EXPR with goto, but if the loop contains an 2214 EXIT_EXPR, we need to append a label for it to jump to. */ 2215 2216 static enum gimplify_status 2217 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p) 2218 { 2219 tree saved_label = gimplify_ctxp->exit_label; 2220 tree start_label = create_artificial_label (UNKNOWN_LOCATION); 2221 2222 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label)); 2223 2224 gimplify_ctxp->exit_label = NULL_TREE; 2225 2226 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p); 2227 2228 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label)); 2229 2230 if (gimplify_ctxp->exit_label) 2231 gimplify_seq_add_stmt (pre_p, 2232 gimple_build_label (gimplify_ctxp->exit_label)); 2233 2234 gimplify_ctxp->exit_label = saved_label; 2235 2236 *expr_p = NULL; 2237 return GS_ALL_DONE; 2238 } 2239 2240 /* Gimplify a statement list onto a sequence. These may be created either 2241 by an enlightened front-end, or by shortcut_cond_expr. */ 2242 2243 static enum gimplify_status 2244 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p) 2245 { 2246 tree temp = voidify_wrapper_expr (*expr_p, NULL); 2247 2248 tree_stmt_iterator i = tsi_start (*expr_p); 2249 2250 while (!tsi_end_p (i)) 2251 { 2252 gimplify_stmt (tsi_stmt_ptr (i), pre_p); 2253 tsi_delink (&i); 2254 } 2255 2256 if (temp) 2257 { 2258 *expr_p = temp; 2259 return GS_OK; 2260 } 2261 2262 return GS_ALL_DONE; 2263 } 2264 2265 2266 /* Emit warning for the unreachable statment STMT if needed. 2267 Return the gimple itself when the warning is emitted, otherwise 2268 return NULL. */ 2269 static gimple * 2270 emit_warn_switch_unreachable (gimple *stmt) 2271 { 2272 if (gimple_code (stmt) == GIMPLE_GOTO 2273 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL 2274 && DECL_ARTIFICIAL (gimple_goto_dest (stmt))) 2275 /* Don't warn for compiler-generated gotos. These occur 2276 in Duff's devices, for example. */ 2277 return NULL; 2278 else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED) 2279 && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT)) 2280 || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING) 2281 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))) 2282 || (is_gimple_assign (stmt) 2283 && gimple_assign_single_p (stmt) 2284 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) 2285 && gimple_call_internal_p ( 2286 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)), 2287 IFN_DEFERRED_INIT)))) 2288 /* Don't warn for compiler-generated initializations for 2289 -ftrivial-auto-var-init. 2290 There are 3 cases: 2291 case 1: a call to .DEFERRED_INIT; 2292 case 2: a call to __builtin_clear_padding with the 2nd argument is 2293 present and non-zero; 2294 case 3: a gimple assign store right after the call to .DEFERRED_INIT 2295 that has the LHS of .DEFERRED_INIT as the RHS as following: 2296 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]); 2297 i1 = _1. */ 2298 return NULL; 2299 else 2300 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, 2301 "statement will never be executed"); 2302 return stmt; 2303 } 2304 2305 /* Callback for walk_gimple_seq. */ 2306 2307 static tree 2308 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p, 2309 bool *handled_ops_p, 2310 struct walk_stmt_info *wi) 2311 { 2312 gimple *stmt = gsi_stmt (*gsi_p); 2313 bool unreachable_issued = wi->info != NULL; 2314 2315 *handled_ops_p = true; 2316 switch (gimple_code (stmt)) 2317 { 2318 case GIMPLE_TRY: 2319 /* A compiler-generated cleanup or a user-written try block. 2320 If it's empty, don't dive into it--that would result in 2321 worse location info. */ 2322 if (gimple_try_eval (stmt) == NULL) 2323 { 2324 if (warn_switch_unreachable && !unreachable_issued) 2325 wi->info = emit_warn_switch_unreachable (stmt); 2326 2327 /* Stop when auto var init warning is not on. */ 2328 if (!warn_trivial_auto_var_init) 2329 return integer_zero_node; 2330 } 2331 /* Fall through. */ 2332 case GIMPLE_BIND: 2333 case GIMPLE_CATCH: 2334 case GIMPLE_EH_FILTER: 2335 case GIMPLE_TRANSACTION: 2336 /* Walk the sub-statements. */ 2337 *handled_ops_p = false; 2338 break; 2339 2340 case GIMPLE_DEBUG: 2341 /* Ignore these. We may generate them before declarations that 2342 are never executed. If there's something to warn about, 2343 there will be non-debug stmts too, and we'll catch those. */ 2344 break; 2345 2346 case GIMPLE_LABEL: 2347 /* Stop till the first Label. */ 2348 return integer_zero_node; 2349 case GIMPLE_CALL: 2350 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK)) 2351 { 2352 *handled_ops_p = false; 2353 break; 2354 } 2355 if (warn_trivial_auto_var_init 2356 && flag_auto_var_init > AUTO_INIT_UNINITIALIZED 2357 && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT)) 2358 { 2359 /* Get the variable name from the 3rd argument of call. */ 2360 tree var_name = gimple_call_arg (stmt, 2); 2361 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0); 2362 const char *var_name_str = TREE_STRING_POINTER (var_name); 2363 2364 warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init, 2365 "%qs cannot be initialized with " 2366 "%<-ftrivial-auto-var_init%>", 2367 var_name_str); 2368 break; 2369 } 2370 2371 /* Fall through. */ 2372 default: 2373 /* check the first "real" statement (not a decl/lexical scope/...), issue 2374 warning if needed. */ 2375 if (warn_switch_unreachable && !unreachable_issued) 2376 wi->info = emit_warn_switch_unreachable (stmt); 2377 /* Stop when auto var init warning is not on. */ 2378 if (!warn_trivial_auto_var_init) 2379 return integer_zero_node; 2380 break; 2381 } 2382 return NULL_TREE; 2383 } 2384 2385 2386 /* Possibly warn about unreachable statements between switch's controlling 2387 expression and the first case. Also warn about -ftrivial-auto-var-init 2388 cannot initialize the auto variable under such situation. 2389 SEQ is the body of a switch expression. */ 2390 2391 static void 2392 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq) 2393 { 2394 if ((!warn_switch_unreachable && !warn_trivial_auto_var_init) 2395 /* This warning doesn't play well with Fortran when optimizations 2396 are on. */ 2397 || lang_GNU_Fortran () 2398 || seq == NULL) 2399 return; 2400 2401 struct walk_stmt_info wi; 2402 2403 memset (&wi, 0, sizeof (wi)); 2404 walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi); 2405 } 2406 2407 2408 /* A label entry that pairs label and a location. */ 2409 struct label_entry 2410 { 2411 tree label; 2412 location_t loc; 2413 }; 2414 2415 /* Find LABEL in vector of label entries VEC. */ 2416 2417 static struct label_entry * 2418 find_label_entry (const auto_vec<struct label_entry> *vec, tree label) 2419 { 2420 unsigned int i; 2421 struct label_entry *l; 2422 2423 FOR_EACH_VEC_ELT (*vec, i, l) 2424 if (l->label == label) 2425 return l; 2426 return NULL; 2427 } 2428 2429 /* Return true if LABEL, a LABEL_DECL, represents a case label 2430 in a vector of labels CASES. */ 2431 2432 static bool 2433 case_label_p (const vec<tree> *cases, tree label) 2434 { 2435 unsigned int i; 2436 tree l; 2437 2438 FOR_EACH_VEC_ELT (*cases, i, l) 2439 if (CASE_LABEL (l) == label) 2440 return true; 2441 return false; 2442 } 2443 2444 /* Find the last nondebug statement in a scope STMT. */ 2445 2446 static gimple * 2447 last_stmt_in_scope (gimple *stmt) 2448 { 2449 if (!stmt) 2450 return NULL; 2451 2452 switch (gimple_code (stmt)) 2453 { 2454 case GIMPLE_BIND: 2455 { 2456 gbind *bind = as_a <gbind *> (stmt); 2457 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind)); 2458 return last_stmt_in_scope (stmt); 2459 } 2460 2461 case GIMPLE_TRY: 2462 { 2463 gtry *try_stmt = as_a <gtry *> (stmt); 2464 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt)); 2465 gimple *last_eval = last_stmt_in_scope (stmt); 2466 if (gimple_stmt_may_fallthru (last_eval) 2467 && (last_eval == NULL 2468 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH)) 2469 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY) 2470 { 2471 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt)); 2472 return last_stmt_in_scope (stmt); 2473 } 2474 else 2475 return last_eval; 2476 } 2477 2478 case GIMPLE_DEBUG: 2479 gcc_unreachable (); 2480 2481 default: 2482 return stmt; 2483 } 2484 } 2485 2486 /* Collect labels that may fall through into LABELS and return the statement 2487 preceding another case label, or a user-defined label. Store a location 2488 useful to give warnings at *PREVLOC (usually the location of the returned 2489 statement or of its surrounding scope). */ 2490 2491 static gimple * 2492 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p, 2493 auto_vec <struct label_entry> *labels, 2494 location_t *prevloc) 2495 { 2496 gimple *prev = NULL; 2497 2498 *prevloc = UNKNOWN_LOCATION; 2499 do 2500 { 2501 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND) 2502 { 2503 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr, 2504 which starts on a GIMPLE_SWITCH and ends with a break label. 2505 Handle that as a single statement that can fall through. */ 2506 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p)); 2507 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind)); 2508 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind)); 2509 if (last 2510 && gimple_code (first) == GIMPLE_SWITCH 2511 && gimple_code (last) == GIMPLE_LABEL) 2512 { 2513 tree label = gimple_label_label (as_a <glabel *> (last)); 2514 if (SWITCH_BREAK_LABEL_P (label)) 2515 { 2516 prev = bind; 2517 gsi_next (gsi_p); 2518 continue; 2519 } 2520 } 2521 } 2522 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND 2523 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY) 2524 { 2525 /* Nested scope. Only look at the last statement of 2526 the innermost scope. */ 2527 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p)); 2528 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p)); 2529 if (last) 2530 { 2531 prev = last; 2532 /* It might be a label without a location. Use the 2533 location of the scope then. */ 2534 if (!gimple_has_location (prev)) 2535 *prevloc = bind_loc; 2536 } 2537 gsi_next (gsi_p); 2538 continue; 2539 } 2540 2541 /* Ifs are tricky. */ 2542 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND) 2543 { 2544 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p)); 2545 tree false_lab = gimple_cond_false_label (cond_stmt); 2546 location_t if_loc = gimple_location (cond_stmt); 2547 2548 /* If we have e.g. 2549 if (i > 1) goto <D.2259>; else goto D; 2550 we can't do much with the else-branch. */ 2551 if (!DECL_ARTIFICIAL (false_lab)) 2552 break; 2553 2554 /* Go on until the false label, then one step back. */ 2555 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p)) 2556 { 2557 gimple *stmt = gsi_stmt (*gsi_p); 2558 if (gimple_code (stmt) == GIMPLE_LABEL 2559 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab) 2560 break; 2561 } 2562 2563 /* Not found? Oops. */ 2564 if (gsi_end_p (*gsi_p)) 2565 break; 2566 2567 /* A dead label can't fall through. */ 2568 if (!UNUSED_LABEL_P (false_lab)) 2569 { 2570 struct label_entry l = { false_lab, if_loc }; 2571 labels->safe_push (l); 2572 } 2573 2574 /* Go to the last statement of the then branch. */ 2575 gsi_prev (gsi_p); 2576 2577 /* if (i != 0) goto <D.1759>; else goto <D.1760>; 2578 <D.1759>: 2579 <stmt>; 2580 goto <D.1761>; 2581 <D.1760>: 2582 */ 2583 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO 2584 && !gimple_has_location (gsi_stmt (*gsi_p))) 2585 { 2586 /* Look at the statement before, it might be 2587 attribute fallthrough, in which case don't warn. */ 2588 gsi_prev (gsi_p); 2589 bool fallthru_before_dest 2590 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH); 2591 gsi_next (gsi_p); 2592 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p)); 2593 if (!fallthru_before_dest) 2594 { 2595 struct label_entry l = { goto_dest, if_loc }; 2596 labels->safe_push (l); 2597 } 2598 } 2599 /* This case is about 2600 if (1 != 0) goto <D.2022>; else goto <D.2023>; 2601 <D.2022>: 2602 n = n + 1; // #1 2603 <D.2023>: // #2 2604 <D.1988>: // #3 2605 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling 2606 through to #3. So set PREV to #1. */ 2607 else if (UNUSED_LABEL_P (false_lab)) 2608 prev = gsi_stmt (*gsi_p); 2609 2610 /* And move back. */ 2611 gsi_next (gsi_p); 2612 } 2613 2614 /* Remember the last statement. Skip labels that are of no interest 2615 to us. */ 2616 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL) 2617 { 2618 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p))); 2619 if (find_label_entry (labels, label)) 2620 prev = gsi_stmt (*gsi_p); 2621 } 2622 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK)) 2623 ; 2624 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT) 2625 ; 2626 else if (!is_gimple_debug (gsi_stmt (*gsi_p))) 2627 prev = gsi_stmt (*gsi_p); 2628 gsi_next (gsi_p); 2629 } 2630 while (!gsi_end_p (*gsi_p) 2631 /* Stop if we find a case or a user-defined label. */ 2632 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL 2633 || !gimple_has_location (gsi_stmt (*gsi_p)))); 2634 2635 if (prev && gimple_has_location (prev)) 2636 *prevloc = gimple_location (prev); 2637 return prev; 2638 } 2639 2640 /* Return true if the switch fallthough warning should occur. LABEL is 2641 the label statement that we're falling through to. */ 2642 2643 static bool 2644 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label) 2645 { 2646 gimple_stmt_iterator gsi = *gsi_p; 2647 2648 /* Don't warn if the label is marked with a "falls through" comment. */ 2649 if (FALLTHROUGH_LABEL_P (label)) 2650 return false; 2651 2652 /* Don't warn for non-case labels followed by a statement: 2653 case 0: 2654 foo (); 2655 label: 2656 bar (); 2657 as these are likely intentional. */ 2658 if (!case_label_p (&gimplify_ctxp->case_labels, label)) 2659 { 2660 tree l; 2661 while (!gsi_end_p (gsi) 2662 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL 2663 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)))) 2664 && !case_label_p (&gimplify_ctxp->case_labels, l)) 2665 gsi_next_nondebug (&gsi); 2666 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL) 2667 return false; 2668 } 2669 2670 /* Don't warn for terminated branches, i.e. when the subsequent case labels 2671 immediately breaks. */ 2672 gsi = *gsi_p; 2673 2674 /* Skip all immediately following labels. */ 2675 while (!gsi_end_p (gsi) 2676 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL 2677 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT)) 2678 gsi_next_nondebug (&gsi); 2679 2680 /* { ... something; default:; } */ 2681 if (gsi_end_p (gsi) 2682 /* { ... something; default: break; } or 2683 { ... something; default: goto L; } */ 2684 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO 2685 /* { ... something; default: return; } */ 2686 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN) 2687 return false; 2688 2689 return true; 2690 } 2691 2692 /* Callback for walk_gimple_seq. */ 2693 2694 static tree 2695 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, 2696 struct walk_stmt_info *) 2697 { 2698 gimple *stmt = gsi_stmt (*gsi_p); 2699 2700 *handled_ops_p = true; 2701 switch (gimple_code (stmt)) 2702 { 2703 case GIMPLE_TRY: 2704 case GIMPLE_BIND: 2705 case GIMPLE_CATCH: 2706 case GIMPLE_EH_FILTER: 2707 case GIMPLE_TRANSACTION: 2708 /* Walk the sub-statements. */ 2709 *handled_ops_p = false; 2710 break; 2711 2712 /* Find a sequence of form: 2713 2714 GIMPLE_LABEL 2715 [...] 2716 <may fallthru stmt> 2717 GIMPLE_LABEL 2718 2719 and possibly warn. */ 2720 case GIMPLE_LABEL: 2721 { 2722 /* Found a label. Skip all immediately following labels. */ 2723 while (!gsi_end_p (*gsi_p) 2724 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL) 2725 gsi_next_nondebug (gsi_p); 2726 2727 /* There might be no more statements. */ 2728 if (gsi_end_p (*gsi_p)) 2729 return integer_zero_node; 2730 2731 /* Vector of labels that fall through. */ 2732 auto_vec <struct label_entry> labels; 2733 location_t prevloc; 2734 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc); 2735 2736 /* There might be no more statements. */ 2737 if (gsi_end_p (*gsi_p)) 2738 return integer_zero_node; 2739 2740 gimple *next = gsi_stmt (*gsi_p); 2741 tree label; 2742 /* If what follows is a label, then we may have a fallthrough. */ 2743 if (gimple_code (next) == GIMPLE_LABEL 2744 && gimple_has_location (next) 2745 && (label = gimple_label_label (as_a <glabel *> (next))) 2746 && prev != NULL) 2747 { 2748 struct label_entry *l; 2749 bool warned_p = false; 2750 auto_diagnostic_group d; 2751 if (!should_warn_for_implicit_fallthrough (gsi_p, label)) 2752 /* Quiet. */; 2753 else if (gimple_code (prev) == GIMPLE_LABEL 2754 && (label = gimple_label_label (as_a <glabel *> (prev))) 2755 && (l = find_label_entry (&labels, label))) 2756 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_, 2757 "this statement may fall through"); 2758 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH) 2759 /* Try to be clever and don't warn when the statement 2760 can't actually fall through. */ 2761 && gimple_stmt_may_fallthru (prev) 2762 && prevloc != UNKNOWN_LOCATION) 2763 warned_p = warning_at (prevloc, 2764 OPT_Wimplicit_fallthrough_, 2765 "this statement may fall through"); 2766 if (warned_p) 2767 inform (gimple_location (next), "here"); 2768 2769 /* Mark this label as processed so as to prevent multiple 2770 warnings in nested switches. */ 2771 FALLTHROUGH_LABEL_P (label) = true; 2772 2773 /* So that next warn_implicit_fallthrough_r will start looking for 2774 a new sequence starting with this label. */ 2775 gsi_prev (gsi_p); 2776 } 2777 } 2778 break; 2779 default: 2780 break; 2781 } 2782 return NULL_TREE; 2783 } 2784 2785 /* Warn when a switch case falls through. */ 2786 2787 static void 2788 maybe_warn_implicit_fallthrough (gimple_seq seq) 2789 { 2790 if (!warn_implicit_fallthrough) 2791 return; 2792 2793 /* This warning is meant for C/C++/ObjC/ObjC++ only. */ 2794 if (!(lang_GNU_C () 2795 || lang_GNU_CXX () 2796 || lang_GNU_OBJC ())) 2797 return; 2798 2799 struct walk_stmt_info wi; 2800 memset (&wi, 0, sizeof (wi)); 2801 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi); 2802 } 2803 2804 /* Callback for walk_gimple_seq. */ 2805 2806 static tree 2807 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, 2808 struct walk_stmt_info *wi) 2809 { 2810 gimple *stmt = gsi_stmt (*gsi_p); 2811 2812 *handled_ops_p = true; 2813 switch (gimple_code (stmt)) 2814 { 2815 case GIMPLE_TRY: 2816 case GIMPLE_BIND: 2817 case GIMPLE_CATCH: 2818 case GIMPLE_EH_FILTER: 2819 case GIMPLE_TRANSACTION: 2820 /* Walk the sub-statements. */ 2821 *handled_ops_p = false; 2822 break; 2823 case GIMPLE_CALL: 2824 static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION; 2825 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH)) 2826 { 2827 location_t loc = gimple_location (stmt); 2828 gsi_remove (gsi_p, true); 2829 wi->removed_stmt = true; 2830 2831 /* nothrow flag is added by genericize_c_loop to mark fallthrough 2832 statement at the end of some loop's body. Those should be 2833 always diagnosed, either because they indeed don't precede 2834 a case label or default label, or because the next statement 2835 is not within the same iteration statement. */ 2836 if ((stmt->subcode & GF_CALL_NOTHROW) != 0) 2837 { 2838 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding " 2839 "a case label or default label"); 2840 break; 2841 } 2842 2843 if (gsi_end_p (*gsi_p)) 2844 { 2845 static_cast<location_t *>(wi->info)[0] = BUILTINS_LOCATION; 2846 static_cast<location_t *>(wi->info)[1] = loc; 2847 break; 2848 } 2849 2850 bool found = false; 2851 2852 gimple_stmt_iterator gsi2 = *gsi_p; 2853 stmt = gsi_stmt (gsi2); 2854 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt)) 2855 { 2856 /* Go on until the artificial label. */ 2857 tree goto_dest = gimple_goto_dest (stmt); 2858 for (; !gsi_end_p (gsi2); gsi_next (&gsi2)) 2859 { 2860 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL 2861 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2))) 2862 == goto_dest) 2863 break; 2864 } 2865 2866 /* Not found? Stop. */ 2867 if (gsi_end_p (gsi2)) 2868 break; 2869 2870 /* Look one past it. */ 2871 gsi_next (&gsi2); 2872 } 2873 2874 /* We're looking for a case label or default label here. */ 2875 while (!gsi_end_p (gsi2)) 2876 { 2877 stmt = gsi_stmt (gsi2); 2878 if (gimple_code (stmt) == GIMPLE_LABEL) 2879 { 2880 tree label = gimple_label_label (as_a <glabel *> (stmt)); 2881 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label)) 2882 { 2883 found = true; 2884 break; 2885 } 2886 } 2887 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK)) 2888 ; 2889 else if (!is_gimple_debug (stmt)) 2890 /* Anything else is not expected. */ 2891 break; 2892 gsi_next (&gsi2); 2893 } 2894 if (!found) 2895 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding " 2896 "a case label or default label"); 2897 } 2898 break; 2899 default: 2900 static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION; 2901 break; 2902 } 2903 return NULL_TREE; 2904 } 2905 2906 /* Expand all FALLTHROUGH () calls in SEQ. */ 2907 2908 static void 2909 expand_FALLTHROUGH (gimple_seq *seq_p) 2910 { 2911 struct walk_stmt_info wi; 2912 location_t loc[2]; 2913 memset (&wi, 0, sizeof (wi)); 2914 loc[0] = UNKNOWN_LOCATION; 2915 loc[1] = UNKNOWN_LOCATION; 2916 wi.info = (void *) &loc[0]; 2917 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi); 2918 if (loc[0] != UNKNOWN_LOCATION) 2919 /* We've found [[fallthrough]]; at the end of a switch, which the C++ 2920 standard says is ill-formed; see [dcl.attr.fallthrough]. */ 2921 pedwarn (loc[1], 0, "attribute %<fallthrough%> not preceding " 2922 "a case label or default label"); 2923 } 2924 2925 2926 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can 2928 branch to. */ 2929 2930 static enum gimplify_status 2931 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) 2932 { 2933 tree switch_expr = *expr_p; 2934 gimple_seq switch_body_seq = NULL; 2935 enum gimplify_status ret; 2936 tree index_type = TREE_TYPE (switch_expr); 2937 if (index_type == NULL_TREE) 2938 index_type = TREE_TYPE (SWITCH_COND (switch_expr)); 2939 2940 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val, 2941 fb_rvalue); 2942 if (ret == GS_ERROR || ret == GS_UNHANDLED) 2943 return ret; 2944 2945 if (SWITCH_BODY (switch_expr)) 2946 { 2947 vec<tree> labels; 2948 vec<tree> saved_labels; 2949 hash_set<tree> *saved_live_switch_vars = NULL; 2950 tree default_case = NULL_TREE; 2951 gswitch *switch_stmt; 2952 2953 /* Save old labels, get new ones from body, then restore the old 2954 labels. Save all the things from the switch body to append after. */ 2955 saved_labels = gimplify_ctxp->case_labels; 2956 gimplify_ctxp->case_labels.create (8); 2957 2958 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */ 2959 saved_live_switch_vars = gimplify_ctxp->live_switch_vars; 2960 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr)); 2961 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST) 2962 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4); 2963 else 2964 gimplify_ctxp->live_switch_vars = NULL; 2965 2966 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr; 2967 gimplify_ctxp->in_switch_expr = true; 2968 2969 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq); 2970 2971 gimplify_ctxp->in_switch_expr = old_in_switch_expr; 2972 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq); 2973 maybe_warn_implicit_fallthrough (switch_body_seq); 2974 /* Only do this for the outermost GIMPLE_SWITCH. */ 2975 if (!gimplify_ctxp->in_switch_expr) 2976 expand_FALLTHROUGH (&switch_body_seq); 2977 2978 labels = gimplify_ctxp->case_labels; 2979 gimplify_ctxp->case_labels = saved_labels; 2980 2981 if (gimplify_ctxp->live_switch_vars) 2982 { 2983 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ()); 2984 delete gimplify_ctxp->live_switch_vars; 2985 } 2986 gimplify_ctxp->live_switch_vars = saved_live_switch_vars; 2987 2988 preprocess_case_label_vec_for_gimple (labels, index_type, 2989 &default_case); 2990 2991 bool add_bind = false; 2992 if (!default_case) 2993 { 2994 glabel *new_default; 2995 2996 default_case 2997 = build_case_label (NULL_TREE, NULL_TREE, 2998 create_artificial_label (UNKNOWN_LOCATION)); 2999 if (old_in_switch_expr) 3000 { 3001 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1; 3002 add_bind = true; 3003 } 3004 new_default = gimple_build_label (CASE_LABEL (default_case)); 3005 gimplify_seq_add_stmt (&switch_body_seq, new_default); 3006 } 3007 else if (old_in_switch_expr) 3008 { 3009 gimple *last = gimple_seq_last_stmt (switch_body_seq); 3010 if (last && gimple_code (last) == GIMPLE_LABEL) 3011 { 3012 tree label = gimple_label_label (as_a <glabel *> (last)); 3013 if (SWITCH_BREAK_LABEL_P (label)) 3014 add_bind = true; 3015 } 3016 } 3017 3018 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr), 3019 default_case, labels); 3020 gimple_set_location (switch_stmt, EXPR_LOCATION (switch_expr)); 3021 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq 3022 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL, 3023 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND, 3024 so that we can easily find the start and end of the switch 3025 statement. */ 3026 if (add_bind) 3027 { 3028 gimple_seq bind_body = NULL; 3029 gimplify_seq_add_stmt (&bind_body, switch_stmt); 3030 gimple_seq_add_seq (&bind_body, switch_body_seq); 3031 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE); 3032 gimple_set_location (bind, EXPR_LOCATION (switch_expr)); 3033 gimplify_seq_add_stmt (pre_p, bind); 3034 } 3035 else 3036 { 3037 gimplify_seq_add_stmt (pre_p, switch_stmt); 3038 gimplify_seq_add_seq (pre_p, switch_body_seq); 3039 } 3040 labels.release (); 3041 } 3042 else 3043 gcc_unreachable (); 3044 3045 return GS_ALL_DONE; 3046 } 3047 3048 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */ 3049 3050 static enum gimplify_status 3051 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p) 3052 { 3053 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p)) 3054 == current_function_decl); 3055 3056 tree label = LABEL_EXPR_LABEL (*expr_p); 3057 glabel *label_stmt = gimple_build_label (label); 3058 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p)); 3059 gimplify_seq_add_stmt (pre_p, label_stmt); 3060 3061 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label))) 3062 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL, 3063 NOT_TAKEN)); 3064 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label))) 3065 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL, 3066 TAKEN)); 3067 3068 return GS_ALL_DONE; 3069 } 3070 3071 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */ 3072 3073 static enum gimplify_status 3074 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p) 3075 { 3076 struct gimplify_ctx *ctxp; 3077 glabel *label_stmt; 3078 3079 /* Invalid programs can play Duff's Device type games with, for example, 3080 #pragma omp parallel. At least in the C front end, we don't 3081 detect such invalid branches until after gimplification, in the 3082 diagnose_omp_blocks pass. */ 3083 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context) 3084 if (ctxp->case_labels.exists ()) 3085 break; 3086 3087 tree label = CASE_LABEL (*expr_p); 3088 label_stmt = gimple_build_label (label); 3089 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p)); 3090 ctxp->case_labels.safe_push (*expr_p); 3091 gimplify_seq_add_stmt (pre_p, label_stmt); 3092 3093 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label))) 3094 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL, 3095 NOT_TAKEN)); 3096 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label))) 3097 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL, 3098 TAKEN)); 3099 3100 return GS_ALL_DONE; 3101 } 3102 3103 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first 3104 if necessary. */ 3105 3106 tree 3107 build_and_jump (tree *label_p) 3108 { 3109 if (label_p == NULL) 3110 /* If there's nowhere to jump, just fall through. */ 3111 return NULL_TREE; 3112 3113 if (*label_p == NULL_TREE) 3114 { 3115 tree label = create_artificial_label (UNKNOWN_LOCATION); 3116 *label_p = label; 3117 } 3118 3119 return build1 (GOTO_EXPR, void_type_node, *label_p); 3120 } 3121 3122 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR. 3123 This also involves building a label to jump to and communicating it to 3124 gimplify_loop_expr through gimplify_ctxp->exit_label. */ 3125 3126 static enum gimplify_status 3127 gimplify_exit_expr (tree *expr_p) 3128 { 3129 tree cond = TREE_OPERAND (*expr_p, 0); 3130 tree expr; 3131 3132 expr = build_and_jump (&gimplify_ctxp->exit_label); 3133 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE); 3134 *expr_p = expr; 3135 3136 return GS_OK; 3137 } 3138 3139 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is 3140 different from its canonical type, wrap the whole thing inside a 3141 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical 3142 type. 3143 3144 The canonical type of a COMPONENT_REF is the type of the field being 3145 referenced--unless the field is a bit-field which can be read directly 3146 in a smaller mode, in which case the canonical type is the 3147 sign-appropriate type corresponding to that mode. */ 3148 3149 static void 3150 canonicalize_component_ref (tree *expr_p) 3151 { 3152 tree expr = *expr_p; 3153 tree type; 3154 3155 gcc_assert (TREE_CODE (expr) == COMPONENT_REF); 3156 3157 if (INTEGRAL_TYPE_P (TREE_TYPE (expr))) 3158 type = TREE_TYPE (get_unwidened (expr, NULL_TREE)); 3159 else 3160 type = TREE_TYPE (TREE_OPERAND (expr, 1)); 3161 3162 /* One could argue that all the stuff below is not necessary for 3163 the non-bitfield case and declare it a FE error if type 3164 adjustment would be needed. */ 3165 if (TREE_TYPE (expr) != type) 3166 { 3167 #ifdef ENABLE_TYPES_CHECKING 3168 tree old_type = TREE_TYPE (expr); 3169 #endif 3170 int type_quals; 3171 3172 /* We need to preserve qualifiers and propagate them from 3173 operand 0. */ 3174 type_quals = TYPE_QUALS (type) 3175 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0))); 3176 if (TYPE_QUALS (type) != type_quals) 3177 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals); 3178 3179 /* Set the type of the COMPONENT_REF to the underlying type. */ 3180 TREE_TYPE (expr) = type; 3181 3182 #ifdef ENABLE_TYPES_CHECKING 3183 /* It is now a FE error, if the conversion from the canonical 3184 type to the original expression type is not useless. */ 3185 gcc_assert (useless_type_conversion_p (old_type, type)); 3186 #endif 3187 } 3188 } 3189 3190 /* If a NOP conversion is changing a pointer to array of foo to a pointer 3191 to foo, embed that change in the ADDR_EXPR by converting 3192 T array[U]; 3193 (T *)&array 3194 ==> 3195 &array[L] 3196 where L is the lower bound. For simplicity, only do this for constant 3197 lower bound. 3198 The constraint is that the type of &array[L] is trivially convertible 3199 to T *. */ 3200 3201 static void 3202 canonicalize_addr_expr (tree *expr_p) 3203 { 3204 tree expr = *expr_p; 3205 tree addr_expr = TREE_OPERAND (expr, 0); 3206 tree datype, ddatype, pddatype; 3207 3208 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */ 3209 if (!POINTER_TYPE_P (TREE_TYPE (expr)) 3210 || TREE_CODE (addr_expr) != ADDR_EXPR) 3211 return; 3212 3213 /* The addr_expr type should be a pointer to an array. */ 3214 datype = TREE_TYPE (TREE_TYPE (addr_expr)); 3215 if (TREE_CODE (datype) != ARRAY_TYPE) 3216 return; 3217 3218 /* The pointer to element type shall be trivially convertible to 3219 the expression pointer type. */ 3220 ddatype = TREE_TYPE (datype); 3221 pddatype = build_pointer_type (ddatype); 3222 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)), 3223 pddatype)) 3224 return; 3225 3226 /* The lower bound and element sizes must be constant. */ 3227 if (!TYPE_SIZE_UNIT (ddatype) 3228 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST 3229 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype)) 3230 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST) 3231 return; 3232 3233 /* All checks succeeded. Build a new node to merge the cast. */ 3234 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0), 3235 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), 3236 NULL_TREE, NULL_TREE); 3237 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p); 3238 3239 /* We can have stripped a required restrict qualifier above. */ 3240 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) 3241 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); 3242 } 3243 3244 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions 3245 underneath as appropriate. */ 3246 3247 static enum gimplify_status 3248 gimplify_conversion (tree *expr_p) 3249 { 3250 location_t loc = EXPR_LOCATION (*expr_p); 3251 gcc_assert (CONVERT_EXPR_P (*expr_p)); 3252 3253 /* Then strip away all but the outermost conversion. */ 3254 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0)); 3255 3256 /* And remove the outermost conversion if it's useless. */ 3257 if (tree_ssa_useless_type_conversion (*expr_p)) 3258 *expr_p = TREE_OPERAND (*expr_p, 0); 3259 3260 /* If we still have a conversion at the toplevel, 3261 then canonicalize some constructs. */ 3262 if (CONVERT_EXPR_P (*expr_p)) 3263 { 3264 tree sub = TREE_OPERAND (*expr_p, 0); 3265 3266 /* If a NOP conversion is changing the type of a COMPONENT_REF 3267 expression, then canonicalize its type now in order to expose more 3268 redundant conversions. */ 3269 if (TREE_CODE (sub) == COMPONENT_REF) 3270 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)); 3271 3272 /* If a NOP conversion is changing a pointer to array of foo 3273 to a pointer to foo, embed that change in the ADDR_EXPR. */ 3274 else if (TREE_CODE (sub) == ADDR_EXPR) 3275 canonicalize_addr_expr (expr_p); 3276 } 3277 3278 /* If we have a conversion to a non-register type force the 3279 use of a VIEW_CONVERT_EXPR instead. */ 3280 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p))) 3281 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p), 3282 TREE_OPERAND (*expr_p, 0)); 3283 3284 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */ 3285 if (TREE_CODE (*expr_p) == CONVERT_EXPR) 3286 TREE_SET_CODE (*expr_p, NOP_EXPR); 3287 3288 return GS_OK; 3289 } 3290 3291 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a 3292 DECL_VALUE_EXPR, and it's worth re-examining things. */ 3293 3294 static enum gimplify_status 3295 gimplify_var_or_parm_decl (tree *expr_p) 3296 { 3297 tree decl = *expr_p; 3298 3299 /* ??? If this is a local variable, and it has not been seen in any 3300 outer BIND_EXPR, then it's probably the result of a duplicate 3301 declaration, for which we've already issued an error. It would 3302 be really nice if the front end wouldn't leak these at all. 3303 Currently the only known culprit is C++ destructors, as seen 3304 in g++.old-deja/g++.jason/binding.C. 3305 Another possible culpit are size expressions for variably modified 3306 types which are lost in the FE or not gimplified correctly. */ 3307 if (VAR_P (decl) 3308 && !DECL_SEEN_IN_BIND_EXPR_P (decl) 3309 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl) 3310 && decl_function_context (decl) == current_function_decl) 3311 { 3312 gcc_assert (seen_error ()); 3313 return GS_ERROR; 3314 } 3315 3316 /* When within an OMP context, notice uses of variables. */ 3317 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true)) 3318 return GS_ALL_DONE; 3319 3320 /* If the decl is an alias for another expression, substitute it now. */ 3321 if (DECL_HAS_VALUE_EXPR_P (decl)) 3322 { 3323 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl)); 3324 return GS_OK; 3325 } 3326 3327 return GS_ALL_DONE; 3328 } 3329 3330 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */ 3331 3332 static void 3333 recalculate_side_effects (tree t) 3334 { 3335 enum tree_code code = TREE_CODE (t); 3336 int len = TREE_OPERAND_LENGTH (t); 3337 int i; 3338 3339 switch (TREE_CODE_CLASS (code)) 3340 { 3341 case tcc_expression: 3342 switch (code) 3343 { 3344 case INIT_EXPR: 3345 case MODIFY_EXPR: 3346 case VA_ARG_EXPR: 3347 case PREDECREMENT_EXPR: 3348 case PREINCREMENT_EXPR: 3349 case POSTDECREMENT_EXPR: 3350 case POSTINCREMENT_EXPR: 3351 /* All of these have side-effects, no matter what their 3352 operands are. */ 3353 return; 3354 3355 default: 3356 break; 3357 } 3358 /* Fall through. */ 3359 3360 case tcc_comparison: /* a comparison expression */ 3361 case tcc_unary: /* a unary arithmetic expression */ 3362 case tcc_binary: /* a binary arithmetic expression */ 3363 case tcc_reference: /* a reference */ 3364 case tcc_vl_exp: /* a function call */ 3365 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t); 3366 for (i = 0; i < len; ++i) 3367 { 3368 tree op = TREE_OPERAND (t, i); 3369 if (op && TREE_SIDE_EFFECTS (op)) 3370 TREE_SIDE_EFFECTS (t) = 1; 3371 } 3372 break; 3373 3374 case tcc_constant: 3375 /* No side-effects. */ 3376 return; 3377 3378 default: 3379 if (code == SSA_NAME) 3380 /* No side-effects. */ 3381 return; 3382 gcc_unreachable (); 3383 } 3384 } 3385 3386 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR 3387 node *EXPR_P. 3388 3389 compound_lval 3390 : min_lval '[' val ']' 3391 | min_lval '.' ID 3392 | compound_lval '[' val ']' 3393 | compound_lval '.' ID 3394 3395 This is not part of the original SIMPLE definition, which separates 3396 array and member references, but it seems reasonable to handle them 3397 together. Also, this way we don't run into problems with union 3398 aliasing; gcc requires that for accesses through a union to alias, the 3399 union reference must be explicit, which was not always the case when we 3400 were splitting up array and member refs. 3401 3402 PRE_P points to the sequence where side effects that must happen before 3403 *EXPR_P should be stored. 3404 3405 POST_P points to the sequence where side effects that must happen after 3406 *EXPR_P should be stored. */ 3407 3408 static enum gimplify_status 3409 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 3410 fallback_t fallback) 3411 { 3412 tree *p; 3413 enum gimplify_status ret = GS_ALL_DONE, tret; 3414 int i; 3415 location_t loc = EXPR_LOCATION (*expr_p); 3416 tree expr = *expr_p; 3417 3418 /* Create a stack of the subexpressions so later we can walk them in 3419 order from inner to outer. */ 3420 auto_vec<tree, 10> expr_stack; 3421 3422 /* We can handle anything that get_inner_reference can deal with. */ 3423 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0)) 3424 { 3425 restart: 3426 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */ 3427 if (TREE_CODE (*p) == INDIRECT_REF) 3428 *p = fold_indirect_ref_loc (loc, *p); 3429 3430 if (handled_component_p (*p)) 3431 ; 3432 /* Expand DECL_VALUE_EXPR now. In some cases that may expose 3433 additional COMPONENT_REFs. */ 3434 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL) 3435 && gimplify_var_or_parm_decl (p) == GS_OK) 3436 goto restart; 3437 else 3438 break; 3439 3440 expr_stack.safe_push (*p); 3441 } 3442 3443 gcc_assert (expr_stack.length ()); 3444 3445 /* Now EXPR_STACK is a stack of pointers to all the refs we've 3446 walked through and P points to the innermost expression. 3447 3448 Java requires that we elaborated nodes in source order. That 3449 means we must gimplify the inner expression followed by each of 3450 the indices, in order. But we can't gimplify the inner 3451 expression until we deal with any variable bounds, sizes, or 3452 positions in order to deal with PLACEHOLDER_EXPRs. 3453 3454 The base expression may contain a statement expression that 3455 has declarations used in size expressions, so has to be 3456 gimplified before gimplifying the size expressions. 3457 3458 So we do this in three steps. First we deal with variable 3459 bounds, sizes, and positions, then we gimplify the base and 3460 ensure it is memory if needed, then we deal with the annotations 3461 for any variables in the components and any indices, from left 3462 to right. */ 3463 3464 bool need_non_reg = false; 3465 for (i = expr_stack.length () - 1; i >= 0; i--) 3466 { 3467 tree t = expr_stack[i]; 3468 3469 if (error_operand_p (TREE_OPERAND (t, 0))) 3470 return GS_ERROR; 3471 3472 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) 3473 { 3474 /* Deal with the low bound and element type size and put them into 3475 the ARRAY_REF. If these values are set, they have already been 3476 gimplified. */ 3477 if (TREE_OPERAND (t, 2) == NULL_TREE) 3478 { 3479 tree low = unshare_expr (array_ref_low_bound (t)); 3480 if (!is_gimple_min_invariant (low)) 3481 { 3482 TREE_OPERAND (t, 2) = low; 3483 } 3484 } 3485 3486 if (TREE_OPERAND (t, 3) == NULL_TREE) 3487 { 3488 tree elmt_size = array_ref_element_size (t); 3489 if (!is_gimple_min_invariant (elmt_size)) 3490 { 3491 elmt_size = unshare_expr (elmt_size); 3492 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); 3493 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); 3494 3495 /* Divide the element size by the alignment of the element 3496 type (above). */ 3497 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, 3498 elmt_size, factor); 3499 3500 TREE_OPERAND (t, 3) = elmt_size; 3501 } 3502 } 3503 need_non_reg = true; 3504 } 3505 else if (TREE_CODE (t) == COMPONENT_REF) 3506 { 3507 /* Set the field offset into T and gimplify it. */ 3508 if (TREE_OPERAND (t, 2) == NULL_TREE) 3509 { 3510 tree offset = component_ref_field_offset (t); 3511 if (!is_gimple_min_invariant (offset)) 3512 { 3513 offset = unshare_expr (offset); 3514 tree field = TREE_OPERAND (t, 1); 3515 tree factor 3516 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); 3517 3518 /* Divide the offset by its alignment. */ 3519 offset = size_binop_loc (loc, EXACT_DIV_EXPR, 3520 offset, factor); 3521 3522 TREE_OPERAND (t, 2) = offset; 3523 } 3524 } 3525 need_non_reg = true; 3526 } 3527 else if (!is_gimple_reg_type (TREE_TYPE (t))) 3528 /* When the result of an operation, in particular a VIEW_CONVERT_EXPR 3529 is a non-register type then require the base object to be a 3530 non-register as well. */ 3531 need_non_reg = true; 3532 } 3533 3534 /* Step 2 is to gimplify the base expression. Make sure lvalue is set 3535 so as to match the min_lval predicate. Failure to do so may result 3536 in the creation of large aggregate temporaries. */ 3537 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, 3538 fallback | fb_lvalue); 3539 ret = MIN (ret, tret); 3540 if (ret == GS_ERROR) 3541 return GS_ERROR; 3542 3543 /* Step 2a: if we have component references we do not support on 3544 registers then make sure the base isn't a register. Of course 3545 we can only do so if an rvalue is OK. */ 3546 if (need_non_reg && (fallback & fb_rvalue)) 3547 prepare_gimple_addressable (p, pre_p); 3548 3549 3550 /* Step 3: gimplify size expressions and the indices and operands of 3551 ARRAY_REF. During this loop we also remove any useless conversions. 3552 If we operate on a register also make sure to properly gimplify 3553 to individual operations. */ 3554 3555 bool reg_operations = is_gimple_reg (*p); 3556 for (; expr_stack.length () > 0; ) 3557 { 3558 tree t = expr_stack.pop (); 3559 3560 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) 3561 { 3562 gcc_assert (!reg_operations); 3563 3564 /* Gimplify the low bound and element type size. */ 3565 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, 3566 is_gimple_reg, fb_rvalue); 3567 ret = MIN (ret, tret); 3568 3569 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p, 3570 is_gimple_reg, fb_rvalue); 3571 ret = MIN (ret, tret); 3572 3573 /* Gimplify the dimension. */ 3574 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, 3575 is_gimple_val, fb_rvalue); 3576 ret = MIN (ret, tret); 3577 } 3578 else if (TREE_CODE (t) == COMPONENT_REF) 3579 { 3580 gcc_assert (!reg_operations); 3581 3582 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, 3583 is_gimple_reg, fb_rvalue); 3584 ret = MIN (ret, tret); 3585 } 3586 else if (reg_operations) 3587 { 3588 tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p, 3589 is_gimple_val, fb_rvalue); 3590 ret = MIN (ret, tret); 3591 } 3592 3593 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0)); 3594 3595 /* The innermost expression P may have originally had 3596 TREE_SIDE_EFFECTS set which would have caused all the outer 3597 expressions in *EXPR_P leading to P to also have had 3598 TREE_SIDE_EFFECTS set. */ 3599 recalculate_side_effects (t); 3600 } 3601 3602 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */ 3603 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF) 3604 { 3605 canonicalize_component_ref (expr_p); 3606 } 3607 3608 expr_stack.release (); 3609 3610 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE); 3611 3612 return ret; 3613 } 3614 3615 /* Gimplify the self modifying expression pointed to by EXPR_P 3616 (++, --, +=, -=). 3617 3618 PRE_P points to the list where side effects that must happen before 3619 *EXPR_P should be stored. 3620 3621 POST_P points to the list where side effects that must happen after 3622 *EXPR_P should be stored. 3623 3624 WANT_VALUE is nonzero iff we want to use the value of this expression 3625 in another expression. 3626 3627 ARITH_TYPE is the type the computation should be performed in. */ 3628 3629 enum gimplify_status 3630 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 3631 bool want_value, tree arith_type) 3632 { 3633 enum tree_code code; 3634 tree lhs, lvalue, rhs, t1; 3635 gimple_seq post = NULL, *orig_post_p = post_p; 3636 bool postfix; 3637 enum tree_code arith_code; 3638 enum gimplify_status ret; 3639 location_t loc = EXPR_LOCATION (*expr_p); 3640 3641 code = TREE_CODE (*expr_p); 3642 3643 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR 3644 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); 3645 3646 /* Prefix or postfix? */ 3647 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) 3648 /* Faster to treat as prefix if result is not used. */ 3649 postfix = want_value; 3650 else 3651 postfix = false; 3652 3653 /* For postfix, make sure the inner expression's post side effects 3654 are executed after side effects from this expression. */ 3655 if (postfix) 3656 post_p = &post; 3657 3658 /* Add or subtract? */ 3659 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) 3660 arith_code = PLUS_EXPR; 3661 else 3662 arith_code = MINUS_EXPR; 3663 3664 /* Gimplify the LHS into a GIMPLE lvalue. */ 3665 lvalue = TREE_OPERAND (*expr_p, 0); 3666 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 3667 if (ret == GS_ERROR) 3668 return ret; 3669 3670 /* Extract the operands to the arithmetic operation. */ 3671 lhs = lvalue; 3672 rhs = TREE_OPERAND (*expr_p, 1); 3673 3674 /* For postfix operator, we evaluate the LHS to an rvalue and then use 3675 that as the result value and in the postqueue operation. */ 3676 if (postfix) 3677 { 3678 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); 3679 if (ret == GS_ERROR) 3680 return ret; 3681 3682 lhs = get_initialized_tmp_var (lhs, pre_p); 3683 } 3684 3685 /* For POINTERs increment, use POINTER_PLUS_EXPR. */ 3686 if (POINTER_TYPE_P (TREE_TYPE (lhs))) 3687 { 3688 rhs = convert_to_ptrofftype_loc (loc, rhs); 3689 if (arith_code == MINUS_EXPR) 3690 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs); 3691 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs); 3692 } 3693 else 3694 t1 = fold_convert (TREE_TYPE (*expr_p), 3695 fold_build2 (arith_code, arith_type, 3696 fold_convert (arith_type, lhs), 3697 fold_convert (arith_type, rhs))); 3698 3699 if (postfix) 3700 { 3701 gimplify_assign (lvalue, t1, pre_p); 3702 gimplify_seq_add_seq (orig_post_p, post); 3703 *expr_p = lhs; 3704 return GS_ALL_DONE; 3705 } 3706 else 3707 { 3708 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1); 3709 return GS_OK; 3710 } 3711 } 3712 3713 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */ 3714 3715 static void 3716 maybe_with_size_expr (tree *expr_p) 3717 { 3718 tree expr = *expr_p; 3719 tree type = TREE_TYPE (expr); 3720 tree size; 3721 3722 /* If we've already wrapped this or the type is error_mark_node, we can't do 3723 anything. */ 3724 if (TREE_CODE (expr) == WITH_SIZE_EXPR 3725 || type == error_mark_node) 3726 return; 3727 3728 /* If the size isn't known or is a constant, we have nothing to do. */ 3729 size = TYPE_SIZE_UNIT (type); 3730 if (!size || poly_int_tree_p (size)) 3731 return; 3732 3733 /* Otherwise, make a WITH_SIZE_EXPR. */ 3734 size = unshare_expr (size); 3735 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr); 3736 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size); 3737 } 3738 3739 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P 3740 Store any side-effects in PRE_P. CALL_LOCATION is the location of 3741 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be 3742 gimplified to an SSA name. */ 3743 3744 enum gimplify_status 3745 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location, 3746 bool allow_ssa) 3747 { 3748 bool (*test) (tree); 3749 fallback_t fb; 3750 3751 /* In general, we allow lvalues for function arguments to avoid 3752 extra overhead of copying large aggregates out of even larger 3753 aggregates into temporaries only to copy the temporaries to 3754 the argument list. Make optimizers happy by pulling out to 3755 temporaries those types that fit in registers. */ 3756 if (is_gimple_reg_type (TREE_TYPE (*arg_p))) 3757 test = is_gimple_val, fb = fb_rvalue; 3758 else 3759 { 3760 test = is_gimple_lvalue, fb = fb_either; 3761 /* Also strip a TARGET_EXPR that would force an extra copy. */ 3762 if (TREE_CODE (*arg_p) == TARGET_EXPR) 3763 { 3764 tree init = TARGET_EXPR_INITIAL (*arg_p); 3765 if (init 3766 && !VOID_TYPE_P (TREE_TYPE (init))) 3767 *arg_p = init; 3768 } 3769 } 3770 3771 /* If this is a variable sized type, we must remember the size. */ 3772 maybe_with_size_expr (arg_p); 3773 3774 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */ 3775 /* Make sure arguments have the same location as the function call 3776 itself. */ 3777 protected_set_expr_location (*arg_p, call_location); 3778 3779 /* There is a sequence point before a function call. Side effects in 3780 the argument list must occur before the actual call. So, when 3781 gimplifying arguments, force gimplify_expr to use an internal 3782 post queue which is then appended to the end of PRE_P. */ 3783 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa); 3784 } 3785 3786 /* Don't fold inside offloading or taskreg regions: it can break code by 3787 adding decl references that weren't in the source. We'll do it during 3788 omplower pass instead. */ 3789 3790 static bool 3791 maybe_fold_stmt (gimple_stmt_iterator *gsi) 3792 { 3793 struct gimplify_omp_ctx *ctx; 3794 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context) 3795 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0) 3796 return false; 3797 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) 3798 return false; 3799 /* Delay folding of builtins until the IL is in consistent state 3800 so the diagnostic machinery can do a better job. */ 3801 if (gimple_call_builtin_p (gsi_stmt (*gsi))) 3802 return false; 3803 return fold_stmt (gsi); 3804 } 3805 3806 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P. 3807 WANT_VALUE is true if the result of the call is desired. */ 3808 3809 static enum gimplify_status 3810 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) 3811 { 3812 tree fndecl, parms, p, fnptrtype; 3813 enum gimplify_status ret; 3814 int i, nargs; 3815 gcall *call; 3816 bool builtin_va_start_p = false; 3817 location_t loc = EXPR_LOCATION (*expr_p); 3818 3819 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR); 3820 3821 /* For reliable diagnostics during inlining, it is necessary that 3822 every call_expr be annotated with file and line. */ 3823 if (! EXPR_HAS_LOCATION (*expr_p)) 3824 SET_EXPR_LOCATION (*expr_p, input_location); 3825 3826 /* Gimplify internal functions created in the FEs. */ 3827 if (CALL_EXPR_FN (*expr_p) == NULL_TREE) 3828 { 3829 if (want_value) 3830 return GS_ALL_DONE; 3831 3832 nargs = call_expr_nargs (*expr_p); 3833 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p); 3834 auto_vec<tree> vargs (nargs); 3835 3836 if (ifn == IFN_ASSUME) 3837 { 3838 if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0))) 3839 { 3840 /* If the [[assume (cond)]]; condition is simple 3841 enough and can be evaluated unconditionally 3842 without side-effects, expand it as 3843 if (!cond) __builtin_unreachable (); */ 3844 tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE); 3845 *expr_p = build3 (COND_EXPR, void_type_node, 3846 CALL_EXPR_ARG (*expr_p, 0), void_node, 3847 build_call_expr_loc (EXPR_LOCATION (*expr_p), 3848 fndecl, 0)); 3849 return GS_OK; 3850 } 3851 /* If not optimizing, ignore the assumptions. */ 3852 if (!optimize || seen_error ()) 3853 { 3854 *expr_p = NULL_TREE; 3855 return GS_ALL_DONE; 3856 } 3857 /* Temporarily, until gimple lowering, transform 3858 .ASSUME (cond); 3859 into: 3860 [[assume (guard)]] 3861 { 3862 guard = cond; 3863 } 3864 such that gimple lowering can outline the condition into 3865 a separate function easily. */ 3866 tree guard = create_tmp_var (boolean_type_node); 3867 *expr_p = build2 (MODIFY_EXPR, void_type_node, guard, 3868 gimple_boolify (CALL_EXPR_ARG (*expr_p, 0))); 3869 *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL); 3870 push_gimplify_context (); 3871 gimple_seq body = NULL; 3872 gimple *g = gimplify_and_return_first (*expr_p, &body); 3873 pop_gimplify_context (g); 3874 g = gimple_build_assume (guard, body); 3875 gimple_set_location (g, loc); 3876 gimplify_seq_add_stmt (pre_p, g); 3877 *expr_p = NULL_TREE; 3878 return GS_ALL_DONE; 3879 } 3880 else if (ifn == IFN_UBSAN_BOUNDS 3881 && nargs == 3 3882 && integer_onep (CALL_EXPR_ARG (*expr_p, 0))) 3883 { 3884 /* If first argument is one, add TYPE_MAX_VALUE (TYPE_DOMAIN (t)) 3885 to 3rd argument and change first argument to 0. This is 3886 done by ubsan_instrument_bounds so that we can use the 3887 max value from gimplify_type_sizes here instead of original 3888 expression for VLAs. */ 3889 tree type = TREE_TYPE (CALL_EXPR_ARG (*expr_p, 0)); 3890 CALL_EXPR_ARG (*expr_p, 0) = build_int_cst (type, 0); 3891 gcc_assert (TREE_CODE (type) == POINTER_TYPE); 3892 type = TREE_TYPE (type); 3893 gcc_assert (TREE_CODE (type) == ARRAY_TYPE); 3894 tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 3895 gcc_assert (maxv); 3896 tree arg3 = CALL_EXPR_ARG (*expr_p, 2); 3897 CALL_EXPR_ARG (*expr_p, 2) 3898 = fold_build2 (PLUS_EXPR, TREE_TYPE (arg3), maxv, arg3); 3899 } 3900 3901 for (i = 0; i < nargs; i++) 3902 { 3903 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, 3904 EXPR_LOCATION (*expr_p)); 3905 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i)); 3906 } 3907 3908 gcall *call = gimple_build_call_internal_vec (ifn, vargs); 3909 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p)); 3910 gimplify_seq_add_stmt (pre_p, call); 3911 return GS_ALL_DONE; 3912 } 3913 3914 /* This may be a call to a builtin function. 3915 3916 Builtin function calls may be transformed into different 3917 (and more efficient) builtin function calls under certain 3918 circumstances. Unfortunately, gimplification can muck things 3919 up enough that the builtin expanders are not aware that certain 3920 transformations are still valid. 3921 3922 So we attempt transformation/gimplification of the call before 3923 we gimplify the CALL_EXPR. At this time we do not manage to 3924 transform all calls in the same manner as the expanders do, but 3925 we do transform most of them. */ 3926 fndecl = get_callee_fndecl (*expr_p); 3927 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) 3928 switch (DECL_FUNCTION_CODE (fndecl)) 3929 { 3930 CASE_BUILT_IN_ALLOCA: 3931 /* If the call has been built for a variable-sized object, then we 3932 want to restore the stack level when the enclosing BIND_EXPR is 3933 exited to reclaim the allocated space; otherwise, we precisely 3934 need to do the opposite and preserve the latest stack level. */ 3935 if (CALL_ALLOCA_FOR_VAR_P (*expr_p)) 3936 gimplify_ctxp->save_stack = true; 3937 else 3938 gimplify_ctxp->keep_stack = true; 3939 break; 3940 3941 case BUILT_IN_VA_START: 3942 { 3943 builtin_va_start_p = true; 3944 if (call_expr_nargs (*expr_p) < 2) 3945 { 3946 error ("too few arguments to function %<va_start%>"); 3947 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); 3948 return GS_OK; 3949 } 3950 3951 if (fold_builtin_next_arg (*expr_p, true)) 3952 { 3953 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); 3954 return GS_OK; 3955 } 3956 break; 3957 } 3958 3959 case BUILT_IN_EH_RETURN: 3960 cfun->calls_eh_return = true; 3961 break; 3962 3963 case BUILT_IN_CLEAR_PADDING: 3964 if (call_expr_nargs (*expr_p) == 1) 3965 { 3966 /* Remember the original type of the argument in an internal 3967 dummy second argument, as in GIMPLE pointer conversions are 3968 useless. Also mark this call as not for automatic 3969 initialization in the internal dummy third argument. */ 3970 p = CALL_EXPR_ARG (*expr_p, 0); 3971 *expr_p 3972 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p, 3973 build_zero_cst (TREE_TYPE (p))); 3974 return GS_OK; 3975 } 3976 break; 3977 3978 default: 3979 ; 3980 } 3981 if (fndecl && fndecl_built_in_p (fndecl)) 3982 { 3983 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); 3984 if (new_tree && new_tree != *expr_p) 3985 { 3986 /* There was a transformation of this call which computes the 3987 same value, but in a more efficient way. Return and try 3988 again. */ 3989 *expr_p = new_tree; 3990 return GS_OK; 3991 } 3992 } 3993 3994 /* Remember the original function pointer type. */ 3995 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); 3996 3997 if (flag_openmp 3998 && fndecl 3999 && cfun 4000 && (cfun->curr_properties & PROP_gimple_any) == 0) 4001 { 4002 tree variant = omp_resolve_declare_variant (fndecl); 4003 if (variant != fndecl) 4004 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant); 4005 } 4006 4007 /* There is a sequence point before the call, so any side effects in 4008 the calling expression must occur before the actual call. Force 4009 gimplify_expr to use an internal post queue. */ 4010 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL, 4011 is_gimple_call_addr, fb_rvalue); 4012 4013 if (ret == GS_ERROR) 4014 return GS_ERROR; 4015 4016 nargs = call_expr_nargs (*expr_p); 4017 4018 /* Get argument types for verification. */ 4019 fndecl = get_callee_fndecl (*expr_p); 4020 parms = NULL_TREE; 4021 if (fndecl) 4022 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 4023 else 4024 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype)); 4025 4026 if (fndecl && DECL_ARGUMENTS (fndecl)) 4027 p = DECL_ARGUMENTS (fndecl); 4028 else if (parms) 4029 p = parms; 4030 else 4031 p = NULL_TREE; 4032 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p)) 4033 ; 4034 4035 /* If the last argument is __builtin_va_arg_pack () and it is not 4036 passed as a named argument, decrease the number of CALL_EXPR 4037 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */ 4038 if (!p 4039 && i < nargs 4040 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR) 4041 { 4042 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1); 4043 tree last_arg_fndecl = get_callee_fndecl (last_arg); 4044 4045 if (last_arg_fndecl 4046 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK)) 4047 { 4048 tree call = *expr_p; 4049 4050 --nargs; 4051 *expr_p = build_call_array_loc (loc, TREE_TYPE (call), 4052 CALL_EXPR_FN (call), 4053 nargs, CALL_EXPR_ARGP (call)); 4054 4055 /* Copy all CALL_EXPR flags, location and block, except 4056 CALL_EXPR_VA_ARG_PACK flag. */ 4057 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call); 4058 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call); 4059 CALL_EXPR_RETURN_SLOT_OPT (*expr_p) 4060 = CALL_EXPR_RETURN_SLOT_OPT (call); 4061 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call); 4062 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call)); 4063 4064 /* Set CALL_EXPR_VA_ARG_PACK. */ 4065 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1; 4066 } 4067 } 4068 4069 /* If the call returns twice then after building the CFG the call 4070 argument computations will no longer dominate the call because 4071 we add an abnormal incoming edge to the call. So do not use SSA 4072 vars there. */ 4073 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE; 4074 4075 /* Gimplify the function arguments. */ 4076 if (nargs > 0) 4077 { 4078 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0); 4079 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs; 4080 PUSH_ARGS_REVERSED ? i-- : i++) 4081 { 4082 enum gimplify_status t; 4083 4084 /* Avoid gimplifying the second argument to va_start, which needs to 4085 be the plain PARM_DECL. */ 4086 if ((i != 1) || !builtin_va_start_p) 4087 { 4088 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, 4089 EXPR_LOCATION (*expr_p), ! returns_twice); 4090 4091 if (t == GS_ERROR) 4092 ret = GS_ERROR; 4093 } 4094 } 4095 } 4096 4097 /* Gimplify the static chain. */ 4098 if (CALL_EXPR_STATIC_CHAIN (*expr_p)) 4099 { 4100 if (fndecl && !DECL_STATIC_CHAIN (fndecl)) 4101 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL; 4102 else 4103 { 4104 enum gimplify_status t; 4105 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p, 4106 EXPR_LOCATION (*expr_p), ! returns_twice); 4107 if (t == GS_ERROR) 4108 ret = GS_ERROR; 4109 } 4110 } 4111 4112 /* Verify the function result. */ 4113 if (want_value && fndecl 4114 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype)))) 4115 { 4116 error_at (loc, "using result of function returning %<void%>"); 4117 ret = GS_ERROR; 4118 } 4119 4120 /* Try this again in case gimplification exposed something. */ 4121 if (ret != GS_ERROR) 4122 { 4123 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); 4124 4125 if (new_tree && new_tree != *expr_p) 4126 { 4127 /* There was a transformation of this call which computes the 4128 same value, but in a more efficient way. Return and try 4129 again. */ 4130 *expr_p = new_tree; 4131 return GS_OK; 4132 } 4133 } 4134 else 4135 { 4136 *expr_p = error_mark_node; 4137 return GS_ERROR; 4138 } 4139 4140 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its 4141 decl. This allows us to eliminate redundant or useless 4142 calls to "const" functions. */ 4143 if (TREE_CODE (*expr_p) == CALL_EXPR) 4144 { 4145 int flags = call_expr_flags (*expr_p); 4146 if (flags & (ECF_CONST | ECF_PURE) 4147 /* An infinite loop is considered a side effect. */ 4148 && !(flags & (ECF_LOOPING_CONST_OR_PURE))) 4149 TREE_SIDE_EFFECTS (*expr_p) = 0; 4150 } 4151 4152 /* If the value is not needed by the caller, emit a new GIMPLE_CALL 4153 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified 4154 form and delegate the creation of a GIMPLE_CALL to 4155 gimplify_modify_expr. This is always possible because when 4156 WANT_VALUE is true, the caller wants the result of this call into 4157 a temporary, which means that we will emit an INIT_EXPR in 4158 internal_get_tmp_var which will then be handled by 4159 gimplify_modify_expr. */ 4160 if (!want_value) 4161 { 4162 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we 4163 have to do is replicate it as a GIMPLE_CALL tuple. */ 4164 gimple_stmt_iterator gsi; 4165 call = gimple_build_call_from_tree (*expr_p, fnptrtype); 4166 notice_special_calls (call); 4167 gimplify_seq_add_stmt (pre_p, call); 4168 gsi = gsi_last (*pre_p); 4169 maybe_fold_stmt (&gsi); 4170 *expr_p = NULL_TREE; 4171 } 4172 else 4173 /* Remember the original function type. */ 4174 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype, 4175 CALL_EXPR_FN (*expr_p)); 4176 4177 return ret; 4178 } 4179 4180 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by 4181 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs. 4182 4183 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the 4184 condition is true or false, respectively. If null, we should generate 4185 our own to skip over the evaluation of this specific expression. 4186 4187 LOCUS is the source location of the COND_EXPR. 4188 4189 The condition_uid is a discriminator tag for condition coverage used to map 4190 conditions to its corresponding full Boolean function. 4191 4192 This function is the tree equivalent of do_jump. 4193 4194 shortcut_cond_r should only be called by shortcut_cond_expr. */ 4195 4196 static tree 4197 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p, 4198 location_t locus, unsigned condition_uid) 4199 { 4200 tree local_label = NULL_TREE; 4201 tree t, expr = NULL; 4202 4203 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to 4204 retain the shortcut semantics. Just insert the gotos here; 4205 shortcut_cond_expr will append the real blocks later. */ 4206 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 4207 { 4208 location_t new_locus; 4209 4210 /* Turn if (a && b) into 4211 4212 if (a); else goto no; 4213 if (b) goto yes; else goto no; 4214 (no:) */ 4215 4216 if (false_label_p == NULL) 4217 false_label_p = &local_label; 4218 4219 /* Keep the original source location on the first 'if'. */ 4220 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus, 4221 condition_uid); 4222 append_to_statement_list (t, &expr); 4223 4224 /* Set the source location of the && on the second 'if'. */ 4225 new_locus = rexpr_location (pred, locus); 4226 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, 4227 new_locus, condition_uid); 4228 append_to_statement_list (t, &expr); 4229 } 4230 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4231 { 4232 location_t new_locus; 4233 4234 /* Turn if (a || b) into 4235 4236 if (a) goto yes; 4237 if (b) goto yes; else goto no; 4238 (yes:) */ 4239 4240 if (true_label_p == NULL) 4241 true_label_p = &local_label; 4242 4243 /* Keep the original source location on the first 'if'. */ 4244 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus, 4245 condition_uid); 4246 append_to_statement_list (t, &expr); 4247 4248 /* Set the source location of the || on the second 'if'. */ 4249 new_locus = rexpr_location (pred, locus); 4250 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, 4251 new_locus, condition_uid); 4252 append_to_statement_list (t, &expr); 4253 } 4254 else if (TREE_CODE (pred) == COND_EXPR 4255 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1))) 4256 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2)))) 4257 { 4258 location_t new_locus; 4259 4260 /* As long as we're messing with gotos, turn if (a ? b : c) into 4261 if (a) 4262 if (b) goto yes; else goto no; 4263 else 4264 if (c) goto yes; else goto no; 4265 4266 Don't do this if one of the arms has void type, which can happen 4267 in C++ when the arm is throw. */ 4268 4269 /* Keep the original source location on the first 'if'. Set the source 4270 location of the ? on the second 'if'. */ 4271 new_locus = rexpr_location (pred, locus); 4272 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0), 4273 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, 4274 false_label_p, locus, condition_uid), 4275 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, 4276 false_label_p, new_locus, 4277 condition_uid)); 4278 SET_EXPR_UID (expr, condition_uid); 4279 } 4280 else 4281 { 4282 expr = build3 (COND_EXPR, void_type_node, pred, 4283 build_and_jump (true_label_p), 4284 build_and_jump (false_label_p)); 4285 SET_EXPR_LOCATION (expr, locus); 4286 SET_EXPR_UID (expr, condition_uid); 4287 } 4288 4289 if (local_label) 4290 { 4291 t = build1 (LABEL_EXPR, void_type_node, local_label); 4292 append_to_statement_list (t, &expr); 4293 } 4294 4295 return expr; 4296 } 4297 4298 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip 4299 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent 4300 statement, if it is the last one. Otherwise, return NULL. */ 4301 4302 static tree 4303 find_goto (tree expr) 4304 { 4305 if (!expr) 4306 return NULL_TREE; 4307 4308 if (TREE_CODE (expr) == GOTO_EXPR) 4309 return expr; 4310 4311 if (TREE_CODE (expr) != STATEMENT_LIST) 4312 return NULL_TREE; 4313 4314 tree_stmt_iterator i = tsi_start (expr); 4315 4316 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT) 4317 tsi_next (&i); 4318 4319 if (!tsi_one_before_end_p (i)) 4320 return NULL_TREE; 4321 4322 return find_goto (tsi_stmt (i)); 4323 } 4324 4325 /* Same as find_goto, except that it returns NULL if the destination 4326 is not a LABEL_DECL. */ 4327 4328 static inline tree 4329 find_goto_label (tree expr) 4330 { 4331 tree dest = find_goto (expr); 4332 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL) 4333 return dest; 4334 return NULL_TREE; 4335 } 4336 4337 4338 /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag 4339 every basic condition with CONDITION_UID. Two basic conditions share the 4340 CONDITION_UID discriminator when they belong to the same predicate, which is 4341 used by the condition coverage. Doing this as an explicit step makes for a 4342 simpler implementation than weaving it into the splitting code as the 4343 splitting code eventually calls the entry point gimplfiy_expr which makes 4344 bookkeeping complicated. */ 4345 static void 4346 tag_shortcut_cond (tree pred, unsigned condition_uid) 4347 { 4348 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR 4349 || TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4350 { 4351 tree fst = TREE_OPERAND (pred, 0); 4352 tree lst = TREE_OPERAND (pred, 1); 4353 4354 if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR 4355 || TREE_CODE (fst) == TRUTH_ORIF_EXPR) 4356 tag_shortcut_cond (fst, condition_uid); 4357 else if (TREE_CODE (fst) == COND_EXPR) 4358 SET_EXPR_UID (fst, condition_uid); 4359 4360 if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR 4361 || TREE_CODE (lst) == TRUTH_ORIF_EXPR) 4362 tag_shortcut_cond (lst, condition_uid); 4363 else if (TREE_CODE (lst) == COND_EXPR) 4364 SET_EXPR_UID (lst, condition_uid); 4365 } 4366 } 4367 4368 /* Given a conditional expression EXPR with short-circuit boolean 4369 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the 4370 predicate apart into the equivalent sequence of conditionals. CONDITION_UID 4371 is a the tag/discriminator for this EXPR - all basic conditions in the 4372 expression will be given the same CONDITION_UID. */ 4373 static tree 4374 shortcut_cond_expr (tree expr, unsigned condition_uid) 4375 { 4376 tree pred = TREE_OPERAND (expr, 0); 4377 tree then_ = TREE_OPERAND (expr, 1); 4378 tree else_ = TREE_OPERAND (expr, 2); 4379 tree true_label, false_label, end_label, t; 4380 tree *true_label_p; 4381 tree *false_label_p; 4382 bool emit_end, emit_false, jump_over_else; 4383 bool then_se = then_ && TREE_SIDE_EFFECTS (then_); 4384 bool else_se = else_ && TREE_SIDE_EFFECTS (else_); 4385 4386 tag_shortcut_cond (pred, condition_uid); 4387 4388 /* First do simple transformations. */ 4389 if (!else_se) 4390 { 4391 /* If there is no 'else', turn 4392 if (a && b) then c 4393 into 4394 if (a) if (b) then c. */ 4395 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 4396 { 4397 /* Keep the original source location on the first 'if'. */ 4398 location_t locus = EXPR_LOC_OR_LOC (expr, input_location); 4399 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 4400 /* Set the source location of the && on the second 'if'. */ 4401 if (rexpr_has_location (pred)) 4402 SET_EXPR_LOCATION (expr, rexpr_location (pred)); 4403 then_ = shortcut_cond_expr (expr, condition_uid); 4404 then_se = then_ && TREE_SIDE_EFFECTS (then_); 4405 pred = TREE_OPERAND (pred, 0); 4406 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE); 4407 SET_EXPR_LOCATION (expr, locus); 4408 } 4409 } 4410 4411 if (!then_se) 4412 { 4413 /* If there is no 'then', turn 4414 if (a || b); else d 4415 into 4416 if (a); else if (b); else d. */ 4417 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4418 { 4419 /* Keep the original source location on the first 'if'. */ 4420 location_t locus = EXPR_LOC_OR_LOC (expr, input_location); 4421 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 4422 /* Set the source location of the || on the second 'if'. */ 4423 if (rexpr_has_location (pred)) 4424 SET_EXPR_LOCATION (expr, rexpr_location (pred)); 4425 else_ = shortcut_cond_expr (expr, condition_uid); 4426 else_se = else_ && TREE_SIDE_EFFECTS (else_); 4427 pred = TREE_OPERAND (pred, 0); 4428 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_); 4429 SET_EXPR_LOCATION (expr, locus); 4430 } 4431 } 4432 4433 /* The expr tree should also have the expression id set. */ 4434 SET_EXPR_UID (expr, condition_uid); 4435 4436 /* If we're done, great. */ 4437 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR 4438 && TREE_CODE (pred) != TRUTH_ORIF_EXPR) 4439 return expr; 4440 4441 /* Otherwise we need to mess with gotos. Change 4442 if (a) c; else d; 4443 to 4444 if (a); else goto no; 4445 c; goto end; 4446 no: d; end: 4447 and recursively gimplify the condition. */ 4448 4449 true_label = false_label = end_label = NULL_TREE; 4450 4451 /* If our arms just jump somewhere, hijack those labels so we don't 4452 generate jumps to jumps. */ 4453 4454 if (tree then_goto = find_goto_label (then_)) 4455 { 4456 true_label = GOTO_DESTINATION (then_goto); 4457 then_ = NULL; 4458 then_se = false; 4459 } 4460 4461 if (tree else_goto = find_goto_label (else_)) 4462 { 4463 false_label = GOTO_DESTINATION (else_goto); 4464 else_ = NULL; 4465 else_se = false; 4466 } 4467 4468 /* If we aren't hijacking a label for the 'then' branch, it falls through. */ 4469 if (true_label) 4470 true_label_p = &true_label; 4471 else 4472 true_label_p = NULL; 4473 4474 /* The 'else' branch also needs a label if it contains interesting code. */ 4475 if (false_label || else_se) 4476 false_label_p = &false_label; 4477 else 4478 false_label_p = NULL; 4479 4480 /* If there was nothing else in our arms, just forward the label(s). */ 4481 if (!then_se && !else_se) 4482 return shortcut_cond_r (pred, true_label_p, false_label_p, 4483 EXPR_LOC_OR_LOC (expr, input_location), condition_uid); 4484 4485 /* If our last subexpression already has a terminal label, reuse it. */ 4486 if (else_se) 4487 t = expr_last (else_); 4488 else if (then_se) 4489 t = expr_last (then_); 4490 else 4491 t = NULL; 4492 if (t && TREE_CODE (t) == LABEL_EXPR) 4493 end_label = LABEL_EXPR_LABEL (t); 4494 4495 /* If we don't care about jumping to the 'else' branch, jump to the end 4496 if the condition is false. */ 4497 if (!false_label_p) 4498 false_label_p = &end_label; 4499 4500 /* We only want to emit these labels if we aren't hijacking them. */ 4501 emit_end = (end_label == NULL_TREE); 4502 emit_false = (false_label == NULL_TREE); 4503 4504 /* We only emit the jump over the else clause if we have to--if the 4505 then clause may fall through. Otherwise we can wind up with a 4506 useless jump and a useless label at the end of gimplified code, 4507 which will cause us to think that this conditional as a whole 4508 falls through even if it doesn't. If we then inline a function 4509 which ends with such a condition, that can cause us to issue an 4510 inappropriate warning about control reaching the end of a 4511 non-void function. */ 4512 jump_over_else = block_may_fallthru (then_); 4513 4514 pred = shortcut_cond_r (pred, true_label_p, false_label_p, 4515 EXPR_LOC_OR_LOC (expr, input_location), 4516 condition_uid); 4517 4518 expr = NULL; 4519 append_to_statement_list (pred, &expr); 4520 4521 append_to_statement_list (then_, &expr); 4522 if (else_se) 4523 { 4524 if (jump_over_else) 4525 { 4526 tree last = expr_last (expr); 4527 t = build_and_jump (&end_label); 4528 if (rexpr_has_location (last)) 4529 SET_EXPR_LOCATION (t, rexpr_location (last)); 4530 append_to_statement_list (t, &expr); 4531 } 4532 if (emit_false) 4533 { 4534 t = build1 (LABEL_EXPR, void_type_node, false_label); 4535 append_to_statement_list (t, &expr); 4536 } 4537 append_to_statement_list (else_, &expr); 4538 } 4539 if (emit_end && end_label) 4540 { 4541 t = build1 (LABEL_EXPR, void_type_node, end_label); 4542 append_to_statement_list (t, &expr); 4543 } 4544 4545 return expr; 4546 } 4547 4548 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */ 4549 4550 tree 4551 gimple_boolify (tree expr) 4552 { 4553 tree type = TREE_TYPE (expr); 4554 location_t loc = EXPR_LOCATION (expr); 4555 4556 if (TREE_CODE (expr) == NE_EXPR 4557 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR 4558 && integer_zerop (TREE_OPERAND (expr, 1))) 4559 { 4560 tree call = TREE_OPERAND (expr, 0); 4561 tree fn = get_callee_fndecl (call); 4562 4563 /* For __builtin_expect ((long) (x), y) recurse into x as well 4564 if x is truth_value_p. */ 4565 if (fn 4566 && fndecl_built_in_p (fn, BUILT_IN_EXPECT) 4567 && call_expr_nargs (call) == 2) 4568 { 4569 tree arg = CALL_EXPR_ARG (call, 0); 4570 if (arg) 4571 { 4572 if (TREE_CODE (arg) == NOP_EXPR 4573 && TREE_TYPE (arg) == TREE_TYPE (call)) 4574 arg = TREE_OPERAND (arg, 0); 4575 if (truth_value_p (TREE_CODE (arg))) 4576 { 4577 arg = gimple_boolify (arg); 4578 CALL_EXPR_ARG (call, 0) 4579 = fold_convert_loc (loc, TREE_TYPE (call), arg); 4580 } 4581 } 4582 } 4583 } 4584 4585 switch (TREE_CODE (expr)) 4586 { 4587 case TRUTH_AND_EXPR: 4588 case TRUTH_OR_EXPR: 4589 case TRUTH_XOR_EXPR: 4590 case TRUTH_ANDIF_EXPR: 4591 case TRUTH_ORIF_EXPR: 4592 /* Also boolify the arguments of truth exprs. */ 4593 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); 4594 /* FALLTHRU */ 4595 4596 case TRUTH_NOT_EXPR: 4597 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4598 4599 /* These expressions always produce boolean results. */ 4600 if (TREE_CODE (type) != BOOLEAN_TYPE) 4601 TREE_TYPE (expr) = boolean_type_node; 4602 return expr; 4603 4604 case ANNOTATE_EXPR: 4605 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))) 4606 { 4607 case annot_expr_ivdep_kind: 4608 case annot_expr_unroll_kind: 4609 case annot_expr_no_vector_kind: 4610 case annot_expr_vector_kind: 4611 case annot_expr_parallel_kind: 4612 case annot_expr_maybe_infinite_kind: 4613 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4614 if (TREE_CODE (type) != BOOLEAN_TYPE) 4615 TREE_TYPE (expr) = boolean_type_node; 4616 return expr; 4617 default: 4618 gcc_unreachable (); 4619 } 4620 4621 default: 4622 if (COMPARISON_CLASS_P (expr)) 4623 { 4624 /* These expressions always produce boolean results. */ 4625 if (TREE_CODE (type) != BOOLEAN_TYPE) 4626 TREE_TYPE (expr) = boolean_type_node; 4627 return expr; 4628 } 4629 /* Other expressions that get here must have boolean values, but 4630 might need to be converted to the appropriate mode. */ 4631 if (TREE_CODE (type) == BOOLEAN_TYPE) 4632 return expr; 4633 return fold_convert_loc (loc, boolean_type_node, expr); 4634 } 4635 } 4636 4637 /* Given a conditional expression *EXPR_P without side effects, gimplify 4638 its operands. New statements are inserted to PRE_P. */ 4639 4640 static enum gimplify_status 4641 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p) 4642 { 4643 tree expr = *expr_p, cond; 4644 enum gimplify_status ret, tret; 4645 enum tree_code code; 4646 4647 cond = gimple_boolify (COND_EXPR_COND (expr)); 4648 4649 /* We need to handle && and || specially, as their gimplification 4650 creates pure cond_expr, thus leading to an infinite cycle otherwise. */ 4651 code = TREE_CODE (cond); 4652 if (code == TRUTH_ANDIF_EXPR) 4653 TREE_SET_CODE (cond, TRUTH_AND_EXPR); 4654 else if (code == TRUTH_ORIF_EXPR) 4655 TREE_SET_CODE (cond, TRUTH_OR_EXPR); 4656 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue); 4657 COND_EXPR_COND (*expr_p) = cond; 4658 4659 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL, 4660 is_gimple_val, fb_rvalue); 4661 ret = MIN (ret, tret); 4662 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL, 4663 is_gimple_val, fb_rvalue); 4664 4665 return MIN (ret, tret); 4666 } 4667 4668 /* Return true if evaluating EXPR could trap. 4669 EXPR is GENERIC, while tree_could_trap_p can be called 4670 only on GIMPLE. */ 4671 4672 bool 4673 generic_expr_could_trap_p (tree expr) 4674 { 4675 unsigned i, n; 4676 4677 if (!expr || is_gimple_val (expr)) 4678 return false; 4679 4680 if (!EXPR_P (expr) || tree_could_trap_p (expr)) 4681 return true; 4682 4683 n = TREE_OPERAND_LENGTH (expr); 4684 for (i = 0; i < n; i++) 4685 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i))) 4686 return true; 4687 4688 return false; 4689 } 4690 4691 /* Associate the condition STMT with the discriminator UID. STMTs that are 4692 broken down with ANDIF/ORIF from the same Boolean expression should be given 4693 the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the 4694 { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done. This is used 4695 for condition coverage. */ 4696 static void 4697 gimple_associate_condition_with_expr (struct function *fn, gcond *stmt, 4698 unsigned uid) 4699 { 4700 if (!condition_coverage_flag) 4701 return; 4702 4703 if (!fn->cond_uids) 4704 fn->cond_uids = new hash_map <gcond*, unsigned> (); 4705 4706 fn->cond_uids->put (stmt, uid); 4707 } 4708 4709 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' 4710 into 4711 4712 if (p) if (p) 4713 t1 = a; a; 4714 else or else 4715 t1 = b; b; 4716 t1; 4717 4718 The second form is used when *EXPR_P is of type void. 4719 4720 PRE_P points to the list where side effects that must happen before 4721 *EXPR_P should be stored. */ 4722 4723 static enum gimplify_status 4724 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) 4725 { 4726 tree expr = *expr_p; 4727 tree type = TREE_TYPE (expr); 4728 location_t loc = EXPR_LOCATION (expr); 4729 tree tmp, arm1, arm2; 4730 enum gimplify_status ret; 4731 tree label_true, label_false, label_cont; 4732 bool have_then_clause_p, have_else_clause_p; 4733 gcond *cond_stmt; 4734 enum tree_code pred_code; 4735 gimple_seq seq = NULL; 4736 4737 /* If this COND_EXPR has a value, copy the values into a temporary within 4738 the arms. */ 4739 if (!VOID_TYPE_P (type)) 4740 { 4741 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2); 4742 tree result; 4743 4744 /* If either an rvalue is ok or we do not require an lvalue, create the 4745 temporary. But we cannot do that if the type is addressable. */ 4746 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue)) 4747 && !TREE_ADDRESSABLE (type)) 4748 { 4749 if (gimplify_ctxp->allow_rhs_cond_expr 4750 /* If either branch has side effects or could trap, it can't be 4751 evaluated unconditionally. */ 4752 && !TREE_SIDE_EFFECTS (then_) 4753 && !generic_expr_could_trap_p (then_) 4754 && !TREE_SIDE_EFFECTS (else_) 4755 && !generic_expr_could_trap_p (else_)) 4756 return gimplify_pure_cond_expr (expr_p, pre_p); 4757 4758 tmp = create_tmp_var (type, "iftmp"); 4759 result = tmp; 4760 } 4761 4762 /* Otherwise, only create and copy references to the values. */ 4763 else 4764 { 4765 type = build_pointer_type (type); 4766 4767 if (!VOID_TYPE_P (TREE_TYPE (then_))) 4768 then_ = build_fold_addr_expr_loc (loc, then_); 4769 4770 if (!VOID_TYPE_P (TREE_TYPE (else_))) 4771 else_ = build_fold_addr_expr_loc (loc, else_); 4772 4773 expr 4774 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_); 4775 4776 tmp = create_tmp_var (type, "iftmp"); 4777 result = build_simple_mem_ref_loc (loc, tmp); 4778 } 4779 4780 /* Build the new then clause, `tmp = then_;'. But don't build the 4781 assignment if the value is void; in C++ it can be if it's a throw. */ 4782 if (!VOID_TYPE_P (TREE_TYPE (then_))) 4783 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_); 4784 4785 /* Similarly, build the new else clause, `tmp = else_;'. */ 4786 if (!VOID_TYPE_P (TREE_TYPE (else_))) 4787 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_); 4788 4789 TREE_TYPE (expr) = void_type_node; 4790 recalculate_side_effects (expr); 4791 4792 /* Move the COND_EXPR to the prequeue. */ 4793 gimplify_stmt (&expr, pre_p); 4794 4795 *expr_p = result; 4796 return GS_ALL_DONE; 4797 } 4798 4799 /* Remove any COMPOUND_EXPR so the following cases will be caught. */ 4800 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0)); 4801 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR) 4802 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true); 4803 4804 /* Make sure the condition has BOOLEAN_TYPE. */ 4805 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4806 4807 /* Break apart && and || conditions. */ 4808 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR 4809 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR) 4810 { 4811 expr = shortcut_cond_expr (expr, next_cond_uid ()); 4812 4813 if (expr != *expr_p) 4814 { 4815 *expr_p = expr; 4816 4817 /* We can't rely on gimplify_expr to re-gimplify the expanded 4818 form properly, as cleanups might cause the target labels to be 4819 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to 4820 set up a conditional context. */ 4821 gimple_push_condition (); 4822 gimplify_stmt (expr_p, &seq); 4823 gimple_pop_condition (pre_p); 4824 gimple_seq_add_seq (pre_p, seq); 4825 4826 return GS_ALL_DONE; 4827 } 4828 } 4829 4830 /* Now do the normal gimplification. */ 4831 4832 /* Gimplify condition. */ 4833 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, 4834 is_gimple_condexpr_for_cond, fb_rvalue); 4835 if (ret == GS_ERROR) 4836 return GS_ERROR; 4837 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE); 4838 4839 gimple_push_condition (); 4840 4841 have_then_clause_p = have_else_clause_p = false; 4842 label_true = find_goto_label (TREE_OPERAND (expr, 1)); 4843 if (label_true 4844 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl 4845 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR 4846 have different locations, otherwise we end up with incorrect 4847 location information on the branches. */ 4848 && (optimize 4849 || !EXPR_HAS_LOCATION (expr) 4850 || !rexpr_has_location (label_true) 4851 || EXPR_LOCATION (expr) == rexpr_location (label_true))) 4852 { 4853 have_then_clause_p = true; 4854 label_true = GOTO_DESTINATION (label_true); 4855 } 4856 else 4857 label_true = create_artificial_label (UNKNOWN_LOCATION); 4858 label_false = find_goto_label (TREE_OPERAND (expr, 2)); 4859 if (label_false 4860 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl 4861 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR 4862 have different locations, otherwise we end up with incorrect 4863 location information on the branches. */ 4864 && (optimize 4865 || !EXPR_HAS_LOCATION (expr) 4866 || !rexpr_has_location (label_false) 4867 || EXPR_LOCATION (expr) == rexpr_location (label_false))) 4868 { 4869 have_else_clause_p = true; 4870 label_false = GOTO_DESTINATION (label_false); 4871 } 4872 else 4873 label_false = create_artificial_label (UNKNOWN_LOCATION); 4874 4875 unsigned cond_uid = EXPR_COND_UID (expr); 4876 if (cond_uid == 0) 4877 cond_uid = next_cond_uid (); 4878 4879 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1, 4880 &arm2); 4881 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, 4882 label_false); 4883 gimple_set_location (cond_stmt, EXPR_LOCATION (expr)); 4884 gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid); 4885 copy_warning (cond_stmt, COND_EXPR_COND (expr)); 4886 gimplify_seq_add_stmt (&seq, cond_stmt); 4887 gimple_stmt_iterator gsi = gsi_last (seq); 4888 maybe_fold_stmt (&gsi); 4889 4890 label_cont = NULL_TREE; 4891 if (!have_then_clause_p) 4892 { 4893 /* For if (...) {} else { code; } put label_true after 4894 the else block. */ 4895 if (TREE_OPERAND (expr, 1) == NULL_TREE 4896 && !have_else_clause_p 4897 && TREE_OPERAND (expr, 2) != NULL_TREE) 4898 { 4899 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough 4900 handling that label_cont == label_true can be only reached 4901 through fallthrough from { code; }. */ 4902 if (integer_zerop (COND_EXPR_COND (expr))) 4903 UNUSED_LABEL_P (label_true) = 1; 4904 label_cont = label_true; 4905 } 4906 else 4907 { 4908 bool then_side_effects 4909 = (TREE_OPERAND (expr, 1) 4910 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))); 4911 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true)); 4912 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq); 4913 /* For if (...) { code; } else {} or 4914 if (...) { code; } else goto label; or 4915 if (...) { code; return; } else { ... } 4916 label_cont isn't needed. */ 4917 if (!have_else_clause_p 4918 && TREE_OPERAND (expr, 2) != NULL_TREE 4919 && gimple_seq_may_fallthru (seq)) 4920 { 4921 gimple *g; 4922 label_cont = create_artificial_label (UNKNOWN_LOCATION); 4923 4924 /* For if (0) { non-side-effect-code } else { code } 4925 tell -Wimplicit-fallthrough handling that label_cont can 4926 be only reached through fallthrough from { code }. */ 4927 if (integer_zerop (COND_EXPR_COND (expr))) 4928 { 4929 UNUSED_LABEL_P (label_true) = 1; 4930 if (!then_side_effects) 4931 UNUSED_LABEL_P (label_cont) = 1; 4932 } 4933 4934 g = gimple_build_goto (label_cont); 4935 4936 /* GIMPLE_COND's are very low level; they have embedded 4937 gotos. This particular embedded goto should not be marked 4938 with the location of the original COND_EXPR, as it would 4939 correspond to the COND_EXPR's condition, not the ELSE or the 4940 THEN arms. To avoid marking it with the wrong location, flag 4941 it as "no location". */ 4942 gimple_set_do_not_emit_location (g); 4943 4944 gimplify_seq_add_stmt (&seq, g); 4945 } 4946 } 4947 } 4948 if (!have_else_clause_p) 4949 { 4950 /* For if (1) { code } or if (1) { code } else { non-side-effect-code } 4951 tell -Wimplicit-fallthrough handling that label_false can be only 4952 reached through fallthrough from { code }. */ 4953 if (integer_nonzerop (COND_EXPR_COND (expr)) 4954 && (TREE_OPERAND (expr, 2) == NULL_TREE 4955 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))) 4956 UNUSED_LABEL_P (label_false) = 1; 4957 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false)); 4958 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq); 4959 } 4960 if (label_cont) 4961 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont)); 4962 4963 gimple_pop_condition (pre_p); 4964 gimple_seq_add_seq (pre_p, seq); 4965 4966 if (ret == GS_ERROR) 4967 ; /* Do nothing. */ 4968 else if (have_then_clause_p || have_else_clause_p) 4969 ret = GS_ALL_DONE; 4970 else 4971 { 4972 /* Both arms are empty; replace the COND_EXPR with its predicate. */ 4973 expr = TREE_OPERAND (expr, 0); 4974 gimplify_stmt (&expr, pre_p); 4975 } 4976 4977 *expr_p = NULL; 4978 return ret; 4979 } 4980 4981 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression, 4982 to be marked addressable. 4983 4984 We cannot rely on such an expression being directly markable if a temporary 4985 has been created by the gimplification. In this case, we create another 4986 temporary and initialize it with a copy, which will become a store after we 4987 mark it addressable. This can happen if the front-end passed us something 4988 that it could not mark addressable yet, like a Fortran pass-by-reference 4989 parameter (int) floatvar. */ 4990 4991 static void 4992 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p) 4993 { 4994 while (handled_component_p (*expr_p)) 4995 expr_p = &TREE_OPERAND (*expr_p, 0); 4996 4997 /* Do not allow an SSA name as the temporary. */ 4998 if (is_gimple_reg (*expr_p)) 4999 *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true); 5000 } 5001 5002 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 5003 a call to __builtin_memcpy. */ 5004 5005 static enum gimplify_status 5006 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, 5007 gimple_seq *seq_p) 5008 { 5009 tree t, to, to_ptr, from, from_ptr; 5010 gcall *gs; 5011 location_t loc = EXPR_LOCATION (*expr_p); 5012 5013 to = TREE_OPERAND (*expr_p, 0); 5014 from = TREE_OPERAND (*expr_p, 1); 5015 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))) 5016 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from)))); 5017 5018 /* Mark the RHS addressable. Beware that it may not be possible to do so 5019 directly if a temporary has been created by the gimplification. */ 5020 prepare_gimple_addressable (&from, seq_p); 5021 5022 mark_addressable (from); 5023 from_ptr = build_fold_addr_expr_loc (loc, from); 5024 gimplify_arg (&from_ptr, seq_p, loc); 5025 5026 mark_addressable (to); 5027 to_ptr = build_fold_addr_expr_loc (loc, to); 5028 gimplify_arg (&to_ptr, seq_p, loc); 5029 5030 t = builtin_decl_implicit (BUILT_IN_MEMCPY); 5031 5032 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size); 5033 gimple_call_set_alloca_for_var (gs, true); 5034 5035 if (want_value) 5036 { 5037 /* tmp = memcpy() */ 5038 t = create_tmp_var (TREE_TYPE (to_ptr)); 5039 gimple_call_set_lhs (gs, t); 5040 gimplify_seq_add_stmt (seq_p, gs); 5041 5042 *expr_p = build_simple_mem_ref (t); 5043 return GS_ALL_DONE; 5044 } 5045 5046 gimplify_seq_add_stmt (seq_p, gs); 5047 *expr_p = NULL; 5048 return GS_ALL_DONE; 5049 } 5050 5051 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 5052 a call to __builtin_memset. In this case we know that the RHS is 5053 a CONSTRUCTOR with an empty element list. */ 5054 5055 static enum gimplify_status 5056 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, 5057 gimple_seq *seq_p) 5058 { 5059 tree t, from, to, to_ptr; 5060 gcall *gs; 5061 location_t loc = EXPR_LOCATION (*expr_p); 5062 5063 /* Assert our assumptions, to abort instead of producing wrong code 5064 silently if they are not met. Beware that the RHS CONSTRUCTOR might 5065 not be immediately exposed. */ 5066 from = TREE_OPERAND (*expr_p, 1); 5067 if (TREE_CODE (from) == WITH_SIZE_EXPR) 5068 from = TREE_OPERAND (from, 0); 5069 5070 gcc_assert (TREE_CODE (from) == CONSTRUCTOR 5071 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from))); 5072 5073 /* Now proceed. */ 5074 to = TREE_OPERAND (*expr_p, 0); 5075 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))); 5076 5077 to_ptr = build_fold_addr_expr_loc (loc, to); 5078 gimplify_arg (&to_ptr, seq_p, loc); 5079 t = builtin_decl_implicit (BUILT_IN_MEMSET); 5080 5081 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size); 5082 5083 if (want_value) 5084 { 5085 /* tmp = memset() */ 5086 t = create_tmp_var (TREE_TYPE (to_ptr)); 5087 gimple_call_set_lhs (gs, t); 5088 gimplify_seq_add_stmt (seq_p, gs); 5089 5090 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t); 5091 return GS_ALL_DONE; 5092 } 5093 5094 gimplify_seq_add_stmt (seq_p, gs); 5095 *expr_p = NULL; 5096 return GS_ALL_DONE; 5097 } 5098 5099 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree, 5100 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an 5101 assignment. Return non-null if we detect a potential overlap. */ 5102 5103 struct gimplify_init_ctor_preeval_data 5104 { 5105 /* The base decl of the lhs object. May be NULL, in which case we 5106 have to assume the lhs is indirect. */ 5107 tree lhs_base_decl; 5108 5109 /* The alias set of the lhs object. */ 5110 alias_set_type lhs_alias_set; 5111 }; 5112 5113 static tree 5114 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata) 5115 { 5116 struct gimplify_init_ctor_preeval_data *data 5117 = (struct gimplify_init_ctor_preeval_data *) xdata; 5118 tree t = *tp; 5119 5120 /* If we find the base object, obviously we have overlap. */ 5121 if (data->lhs_base_decl == t) 5122 return t; 5123 5124 /* If the constructor component is indirect, determine if we have a 5125 potential overlap with the lhs. The only bits of information we 5126 have to go on at this point are addressability and alias sets. */ 5127 if ((INDIRECT_REF_P (t) 5128 || TREE_CODE (t) == MEM_REF) 5129 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 5130 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t))) 5131 return t; 5132 5133 /* If the constructor component is a call, determine if it can hide a 5134 potential overlap with the lhs through an INDIRECT_REF like above. 5135 ??? Ugh - this is completely broken. In fact this whole analysis 5136 doesn't look conservative. */ 5137 if (TREE_CODE (t) == CALL_EXPR) 5138 { 5139 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t))); 5140 5141 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type)) 5142 if (POINTER_TYPE_P (TREE_VALUE (type)) 5143 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 5144 && alias_sets_conflict_p (data->lhs_alias_set, 5145 get_alias_set 5146 (TREE_TYPE (TREE_VALUE (type))))) 5147 return t; 5148 } 5149 5150 if (IS_TYPE_OR_DECL_P (t)) 5151 *walk_subtrees = 0; 5152 return NULL; 5153 } 5154 5155 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR, 5156 force values that overlap with the lhs (as described by *DATA) 5157 into temporaries. */ 5158 5159 static void 5160 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 5161 struct gimplify_init_ctor_preeval_data *data) 5162 { 5163 enum gimplify_status one; 5164 5165 /* If the value is constant, then there's nothing to pre-evaluate. */ 5166 if (TREE_CONSTANT (*expr_p)) 5167 { 5168 /* Ensure it does not have side effects, it might contain a reference to 5169 the object we're initializing. */ 5170 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p)); 5171 return; 5172 } 5173 5174 /* If the type has non-trivial constructors, we can't pre-evaluate. */ 5175 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p))) 5176 return; 5177 5178 /* Recurse for nested constructors. */ 5179 if (TREE_CODE (*expr_p) == CONSTRUCTOR) 5180 { 5181 unsigned HOST_WIDE_INT ix; 5182 constructor_elt *ce; 5183 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p); 5184 5185 FOR_EACH_VEC_SAFE_ELT (v, ix, ce) 5186 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data); 5187 5188 return; 5189 } 5190 5191 /* If this is a variable sized type, we must remember the size. */ 5192 maybe_with_size_expr (expr_p); 5193 5194 /* Gimplify the constructor element to something appropriate for the rhs 5195 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know 5196 the gimplifier will consider this a store to memory. Doing this 5197 gimplification now means that we won't have to deal with complicated 5198 language-specific trees, nor trees like SAVE_EXPR that can induce 5199 exponential search behavior. */ 5200 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue); 5201 if (one == GS_ERROR) 5202 { 5203 *expr_p = NULL; 5204 return; 5205 } 5206 5207 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap 5208 with the lhs, since "a = { .x=a }" doesn't make sense. This will 5209 always be true for all scalars, since is_gimple_mem_rhs insists on a 5210 temporary variable for them. */ 5211 if (DECL_P (*expr_p)) 5212 return; 5213 5214 /* If this is of variable size, we have no choice but to assume it doesn't 5215 overlap since we can't make a temporary for it. */ 5216 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST) 5217 return; 5218 5219 /* Otherwise, we must search for overlap ... */ 5220 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL)) 5221 return; 5222 5223 /* ... and if found, force the value into a temporary. */ 5224 *expr_p = get_formal_tmp_var (*expr_p, pre_p); 5225 } 5226 5227 /* A subroutine of gimplify_init_ctor_eval. Create a loop for 5228 a RANGE_EXPR in a CONSTRUCTOR for an array. 5229 5230 var = lower; 5231 loop_entry: 5232 object[var] = value; 5233 if (var == upper) 5234 goto loop_exit; 5235 var = var + 1; 5236 goto loop_entry; 5237 loop_exit: 5238 5239 We increment var _after_ the loop exit check because we might otherwise 5240 fail if upper == TYPE_MAX_VALUE (type for upper). 5241 5242 Note that we never have to deal with SAVE_EXPRs here, because this has 5243 already been taken care of for us, in gimplify_init_ctor_preeval(). */ 5244 5245 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *, 5246 gimple_seq *, bool); 5247 5248 static void 5249 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper, 5250 tree value, tree array_elt_type, 5251 gimple_seq *pre_p, bool cleared) 5252 { 5253 tree loop_entry_label, loop_exit_label, fall_thru_label; 5254 tree var, var_type, cref, tmp; 5255 5256 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION); 5257 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION); 5258 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION); 5259 5260 /* Create and initialize the index variable. */ 5261 var_type = TREE_TYPE (upper); 5262 var = create_tmp_var (var_type); 5263 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower)); 5264 5265 /* Add the loop entry label. */ 5266 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label)); 5267 5268 /* Build the reference. */ 5269 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 5270 var, NULL_TREE, NULL_TREE); 5271 5272 /* If we are a constructor, just call gimplify_init_ctor_eval to do 5273 the store. Otherwise just assign value to the reference. */ 5274 5275 if (TREE_CODE (value) == CONSTRUCTOR) 5276 /* NB we might have to call ourself recursively through 5277 gimplify_init_ctor_eval if the value is a constructor. */ 5278 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 5279 pre_p, cleared); 5280 else 5281 { 5282 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue) 5283 != GS_ERROR) 5284 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value)); 5285 } 5286 5287 /* We exit the loop when the index var is equal to the upper bound. */ 5288 gimplify_seq_add_stmt (pre_p, 5289 gimple_build_cond (EQ_EXPR, var, upper, 5290 loop_exit_label, fall_thru_label)); 5291 5292 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label)); 5293 5294 /* Otherwise, increment the index var... */ 5295 tmp = build2 (PLUS_EXPR, var_type, var, 5296 fold_convert (var_type, integer_one_node)); 5297 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp)); 5298 5299 /* ...and jump back to the loop entry. */ 5300 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label)); 5301 5302 /* Add the loop exit label. */ 5303 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label)); 5304 } 5305 5306 /* A subroutine of gimplify_init_constructor. Generate individual 5307 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the 5308 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the 5309 CONSTRUCTOR. CLEARED is true if the entire LHS object has been 5310 zeroed first. */ 5311 5312 static void 5313 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts, 5314 gimple_seq *pre_p, bool cleared) 5315 { 5316 tree array_elt_type = NULL; 5317 unsigned HOST_WIDE_INT ix; 5318 tree purpose, value; 5319 5320 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE) 5321 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object))); 5322 5323 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value) 5324 { 5325 tree cref; 5326 5327 /* NULL values are created above for gimplification errors. */ 5328 if (value == NULL) 5329 continue; 5330 5331 if (cleared && initializer_zerop (value)) 5332 continue; 5333 5334 /* ??? Here's to hoping the front end fills in all of the indices, 5335 so we don't have to figure out what's missing ourselves. */ 5336 gcc_assert (purpose); 5337 5338 /* Skip zero-sized fields, unless value has side-effects. This can 5339 happen with calls to functions returning a empty type, which 5340 we shouldn't discard. As a number of downstream passes don't 5341 expect sets of empty type fields, we rely on the gimplification of 5342 the MODIFY_EXPR we make below to drop the assignment statement. */ 5343 if (!TREE_SIDE_EFFECTS (value) 5344 && TREE_CODE (purpose) == FIELD_DECL 5345 && is_empty_type (TREE_TYPE (purpose))) 5346 continue; 5347 5348 /* If we have a RANGE_EXPR, we have to build a loop to assign the 5349 whole range. */ 5350 if (TREE_CODE (purpose) == RANGE_EXPR) 5351 { 5352 tree lower = TREE_OPERAND (purpose, 0); 5353 tree upper = TREE_OPERAND (purpose, 1); 5354 5355 /* If the lower bound is equal to upper, just treat it as if 5356 upper was the index. */ 5357 if (simple_cst_equal (lower, upper)) 5358 purpose = upper; 5359 else 5360 { 5361 gimplify_init_ctor_eval_range (object, lower, upper, value, 5362 array_elt_type, pre_p, cleared); 5363 continue; 5364 } 5365 } 5366 5367 if (array_elt_type) 5368 { 5369 /* Do not use bitsizetype for ARRAY_REF indices. */ 5370 if (TYPE_DOMAIN (TREE_TYPE (object))) 5371 purpose 5372 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))), 5373 purpose); 5374 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 5375 purpose, NULL_TREE, NULL_TREE); 5376 } 5377 else 5378 { 5379 gcc_assert (TREE_CODE (purpose) == FIELD_DECL); 5380 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose), 5381 unshare_expr (object), purpose, NULL_TREE); 5382 } 5383 5384 if (TREE_CODE (value) == CONSTRUCTOR 5385 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE) 5386 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 5387 pre_p, cleared); 5388 else 5389 { 5390 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); 5391 gimplify_and_add (init, pre_p); 5392 ggc_free (init); 5393 } 5394 } 5395 } 5396 5397 /* Return the appropriate RHS predicate for this LHS. */ 5398 5399 gimple_predicate 5400 rhs_predicate_for (tree lhs) 5401 { 5402 if (is_gimple_reg (lhs)) 5403 return is_gimple_reg_rhs_or_call; 5404 else 5405 return is_gimple_mem_rhs_or_call; 5406 } 5407 5408 /* Return the initial guess for an appropriate RHS predicate for this LHS, 5409 before the LHS has been gimplified. */ 5410 5411 static gimple_predicate 5412 initial_rhs_predicate_for (tree lhs) 5413 { 5414 if (is_gimple_reg_type (TREE_TYPE (lhs))) 5415 return is_gimple_reg_rhs_or_call; 5416 else 5417 return is_gimple_mem_rhs_or_call; 5418 } 5419 5420 /* Gimplify a C99 compound literal expression. This just means adding 5421 the DECL_EXPR before the current statement and using its anonymous 5422 decl instead. */ 5423 5424 static enum gimplify_status 5425 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p, 5426 bool (*gimple_test_f) (tree), 5427 fallback_t fallback) 5428 { 5429 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p); 5430 tree decl = DECL_EXPR_DECL (decl_s); 5431 tree init = DECL_INITIAL (decl); 5432 /* Mark the decl as addressable if the compound literal 5433 expression is addressable now, otherwise it is marked too late 5434 after we gimplify the initialization expression. */ 5435 if (TREE_ADDRESSABLE (*expr_p)) 5436 TREE_ADDRESSABLE (decl) = 1; 5437 /* Otherwise, if we don't need an lvalue and have a literal directly 5438 substitute it. Check if it matches the gimple predicate, as 5439 otherwise we'd generate a new temporary, and we can as well just 5440 use the decl we already have. */ 5441 else if (!TREE_ADDRESSABLE (decl) 5442 && !TREE_THIS_VOLATILE (decl) 5443 && init 5444 && (fallback & fb_lvalue) == 0 5445 && gimple_test_f (init)) 5446 { 5447 *expr_p = init; 5448 return GS_OK; 5449 } 5450 5451 /* If the decl is not addressable, then it is being used in some 5452 expression or on the right hand side of a statement, and it can 5453 be put into a readonly data section. */ 5454 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0) 5455 TREE_READONLY (decl) = 1; 5456 5457 /* This decl isn't mentioned in the enclosing block, so add it to the 5458 list of temps. FIXME it seems a bit of a kludge to say that 5459 anonymous artificial vars aren't pushed, but everything else is. */ 5460 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl)) 5461 gimple_add_tmp_var (decl); 5462 5463 gimplify_and_add (decl_s, pre_p); 5464 *expr_p = decl; 5465 return GS_OK; 5466 } 5467 5468 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR, 5469 return a new CONSTRUCTOR if something changed. */ 5470 5471 static tree 5472 optimize_compound_literals_in_ctor (tree orig_ctor) 5473 { 5474 tree ctor = orig_ctor; 5475 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor); 5476 unsigned int idx, num = vec_safe_length (elts); 5477 5478 for (idx = 0; idx < num; idx++) 5479 { 5480 tree value = (*elts)[idx].value; 5481 tree newval = value; 5482 if (TREE_CODE (value) == CONSTRUCTOR) 5483 newval = optimize_compound_literals_in_ctor (value); 5484 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR) 5485 { 5486 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value); 5487 tree decl = DECL_EXPR_DECL (decl_s); 5488 tree init = DECL_INITIAL (decl); 5489 5490 if (!TREE_ADDRESSABLE (value) 5491 && !TREE_ADDRESSABLE (decl) 5492 && init 5493 && TREE_CODE (init) == CONSTRUCTOR) 5494 newval = optimize_compound_literals_in_ctor (init); 5495 } 5496 if (newval == value) 5497 continue; 5498 5499 if (ctor == orig_ctor) 5500 { 5501 ctor = copy_node (orig_ctor); 5502 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts); 5503 elts = CONSTRUCTOR_ELTS (ctor); 5504 } 5505 (*elts)[idx].value = newval; 5506 } 5507 return ctor; 5508 } 5509 5510 /* A subroutine of gimplify_modify_expr. Break out elements of a 5511 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs. 5512 5513 Note that we still need to clear any elements that don't have explicit 5514 initializers, so if not all elements are initialized we keep the 5515 original MODIFY_EXPR, we just remove all of the constructor elements. 5516 5517 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return 5518 GS_ERROR if we would have to create a temporary when gimplifying 5519 this constructor. Otherwise, return GS_OK. 5520 5521 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */ 5522 5523 static enum gimplify_status 5524 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 5525 bool want_value, bool notify_temp_creation) 5526 { 5527 tree object, ctor, type; 5528 enum gimplify_status ret; 5529 vec<constructor_elt, va_gc> *elts; 5530 bool cleared = false; 5531 bool is_empty_ctor = false; 5532 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR); 5533 5534 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR); 5535 5536 if (!notify_temp_creation) 5537 { 5538 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5539 is_gimple_lvalue, fb_lvalue); 5540 if (ret == GS_ERROR) 5541 return ret; 5542 } 5543 5544 object = TREE_OPERAND (*expr_p, 0); 5545 ctor = TREE_OPERAND (*expr_p, 1) 5546 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1)); 5547 type = TREE_TYPE (ctor); 5548 elts = CONSTRUCTOR_ELTS (ctor); 5549 ret = GS_ALL_DONE; 5550 5551 switch (TREE_CODE (type)) 5552 { 5553 case RECORD_TYPE: 5554 case UNION_TYPE: 5555 case QUAL_UNION_TYPE: 5556 case ARRAY_TYPE: 5557 { 5558 /* Use readonly data for initializers of this or smaller size 5559 regardless of the num_nonzero_elements / num_unique_nonzero_elements 5560 ratio. */ 5561 const HOST_WIDE_INT min_unique_size = 64; 5562 /* If num_nonzero_elements / num_unique_nonzero_elements ratio 5563 is smaller than this, use readonly data. */ 5564 const int unique_nonzero_ratio = 8; 5565 /* True if a single access of the object must be ensured. This is the 5566 case if the target is volatile, the type is non-addressable and more 5567 than one field need to be assigned. */ 5568 const bool ensure_single_access 5569 = TREE_THIS_VOLATILE (object) 5570 && !TREE_ADDRESSABLE (type) 5571 && vec_safe_length (elts) > 1; 5572 struct gimplify_init_ctor_preeval_data preeval_data; 5573 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; 5574 HOST_WIDE_INT num_unique_nonzero_elements; 5575 bool complete_p, valid_const_initializer; 5576 5577 /* Aggregate types must lower constructors to initialization of 5578 individual elements. The exception is that a CONSTRUCTOR node 5579 with no elements indicates zero-initialization of the whole. */ 5580 if (vec_safe_is_empty (elts)) 5581 { 5582 if (notify_temp_creation) 5583 return GS_OK; 5584 5585 /* The var will be initialized and so appear on lhs of 5586 assignment, it can't be TREE_READONLY anymore. */ 5587 if (VAR_P (object)) 5588 TREE_READONLY (object) = 0; 5589 5590 is_empty_ctor = true; 5591 break; 5592 } 5593 5594 /* Fetch information about the constructor to direct later processing. 5595 We might want to make static versions of it in various cases, and 5596 can only do so if it known to be a valid constant initializer. */ 5597 valid_const_initializer 5598 = categorize_ctor_elements (ctor, &num_nonzero_elements, 5599 &num_unique_nonzero_elements, 5600 &num_ctor_elements, &complete_p); 5601 5602 /* If a const aggregate variable is being initialized, then it 5603 should never be a lose to promote the variable to be static. */ 5604 if (valid_const_initializer 5605 && num_nonzero_elements > 1 5606 && TREE_READONLY (object) 5607 && VAR_P (object) 5608 && !DECL_REGISTER (object) 5609 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object) 5610 || DECL_MERGEABLE (object)) 5611 /* For ctors that have many repeated nonzero elements 5612 represented through RANGE_EXPRs, prefer initializing 5613 those through runtime loops over copies of large amounts 5614 of data from readonly data section. */ 5615 && (num_unique_nonzero_elements 5616 > num_nonzero_elements / unique_nonzero_ratio 5617 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) 5618 <= (unsigned HOST_WIDE_INT) min_unique_size))) 5619 { 5620 if (notify_temp_creation) 5621 return GS_ERROR; 5622 5623 DECL_INITIAL (object) = ctor; 5624 TREE_STATIC (object) = 1; 5625 if (!DECL_NAME (object) || DECL_NAMELESS (object)) 5626 DECL_NAME (object) = create_tmp_var_name ("C"); 5627 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL); 5628 5629 /* ??? C++ doesn't automatically append a .<number> to the 5630 assembler name, and even when it does, it looks at FE private 5631 data structures to figure out what that number should be, 5632 which are not set for this variable. I suppose this is 5633 important for local statics for inline functions, which aren't 5634 "local" in the object file sense. So in order to get a unique 5635 TU-local symbol, we must invoke the lhd version now. */ 5636 lhd_set_decl_assembler_name (object); 5637 5638 *expr_p = NULL_TREE; 5639 break; 5640 } 5641 5642 /* The var will be initialized and so appear on lhs of 5643 assignment, it can't be TREE_READONLY anymore. */ 5644 if (VAR_P (object) && !notify_temp_creation) 5645 TREE_READONLY (object) = 0; 5646 5647 /* If there are "lots" of initialized elements, even discounting 5648 those that are not address constants (and thus *must* be 5649 computed at runtime), then partition the constructor into 5650 constant and non-constant parts. Block copy the constant 5651 parts in, then generate code for the non-constant parts. */ 5652 /* TODO. There's code in cp/typeck.cc to do this. */ 5653 5654 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0) 5655 /* store_constructor will ignore the clearing of variable-sized 5656 objects. Initializers for such objects must explicitly set 5657 every field that needs to be set. */ 5658 cleared = false; 5659 else if (!complete_p) 5660 /* If the constructor isn't complete, clear the whole object 5661 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it. 5662 5663 ??? This ought not to be needed. For any element not present 5664 in the initializer, we should simply set them to zero. Except 5665 we'd need to *find* the elements that are not present, and that 5666 requires trickery to avoid quadratic compile-time behavior in 5667 large cases or excessive memory use in small cases. */ 5668 cleared = !CONSTRUCTOR_NO_CLEARING (ctor); 5669 else if (num_ctor_elements - num_nonzero_elements 5670 > CLEAR_RATIO (optimize_function_for_speed_p (cfun)) 5671 && num_nonzero_elements < num_ctor_elements / 4) 5672 /* If there are "lots" of zeros, it's more efficient to clear 5673 the memory and then set the nonzero elements. */ 5674 cleared = true; 5675 else if (ensure_single_access && num_nonzero_elements == 0) 5676 /* If a single access to the target must be ensured and all elements 5677 are zero, then it's optimal to clear whatever their number. */ 5678 cleared = true; 5679 else 5680 cleared = false; 5681 5682 /* If there are "lots" of initialized elements, and all of them 5683 are valid address constants, then the entire initializer can 5684 be dropped to memory, and then memcpy'd out. Don't do this 5685 for sparse arrays, though, as it's more efficient to follow 5686 the standard CONSTRUCTOR behavior of memset followed by 5687 individual element initialization. Also don't do this for small 5688 all-zero initializers (which aren't big enough to merit 5689 clearing), and don't try to make bitwise copies of 5690 TREE_ADDRESSABLE types. */ 5691 if (valid_const_initializer 5692 && complete_p 5693 && !(cleared || num_nonzero_elements == 0) 5694 && !TREE_ADDRESSABLE (type)) 5695 { 5696 HOST_WIDE_INT size = int_size_in_bytes (type); 5697 unsigned int align; 5698 5699 /* ??? We can still get unbounded array types, at least 5700 from the C++ front end. This seems wrong, but attempt 5701 to work around it for now. */ 5702 if (size < 0) 5703 { 5704 size = int_size_in_bytes (TREE_TYPE (object)); 5705 if (size >= 0) 5706 TREE_TYPE (ctor) = type = TREE_TYPE (object); 5707 } 5708 5709 /* Find the maximum alignment we can assume for the object. */ 5710 /* ??? Make use of DECL_OFFSET_ALIGN. */ 5711 if (DECL_P (object)) 5712 align = DECL_ALIGN (object); 5713 else 5714 align = TYPE_ALIGN (type); 5715 5716 /* Do a block move either if the size is so small as to make 5717 each individual move a sub-unit move on average, or if it 5718 is so large as to make individual moves inefficient. */ 5719 if (size > 0 5720 && num_nonzero_elements > 1 5721 /* For ctors that have many repeated nonzero elements 5722 represented through RANGE_EXPRs, prefer initializing 5723 those through runtime loops over copies of large amounts 5724 of data from readonly data section. */ 5725 && (num_unique_nonzero_elements 5726 > num_nonzero_elements / unique_nonzero_ratio 5727 || size <= min_unique_size) 5728 && (size < num_nonzero_elements 5729 || !can_move_by_pieces (size, align))) 5730 { 5731 if (notify_temp_creation) 5732 return GS_ERROR; 5733 5734 walk_tree (&ctor, force_labels_r, NULL, NULL); 5735 ctor = tree_output_constant_def (ctor); 5736 if (!useless_type_conversion_p (type, TREE_TYPE (ctor))) 5737 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor); 5738 TREE_OPERAND (*expr_p, 1) = ctor; 5739 5740 /* This is no longer an assignment of a CONSTRUCTOR, but 5741 we still may have processing to do on the LHS. So 5742 pretend we didn't do anything here to let that happen. */ 5743 return GS_UNHANDLED; 5744 } 5745 } 5746 5747 /* If a single access to the target must be ensured and there are 5748 nonzero elements or the zero elements are not assigned en masse, 5749 initialize the target from a temporary. */ 5750 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared)) 5751 { 5752 if (notify_temp_creation) 5753 return GS_ERROR; 5754 5755 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type)); 5756 TREE_OPERAND (*expr_p, 0) = temp; 5757 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), 5758 *expr_p, 5759 build2 (MODIFY_EXPR, void_type_node, 5760 object, temp)); 5761 return GS_OK; 5762 } 5763 5764 if (notify_temp_creation) 5765 return GS_OK; 5766 5767 /* If there are nonzero elements and if needed, pre-evaluate to capture 5768 elements overlapping with the lhs into temporaries. We must do this 5769 before clearing to fetch the values before they are zeroed-out. */ 5770 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR) 5771 { 5772 preeval_data.lhs_base_decl = get_base_address (object); 5773 if (!DECL_P (preeval_data.lhs_base_decl)) 5774 preeval_data.lhs_base_decl = NULL; 5775 preeval_data.lhs_alias_set = get_alias_set (object); 5776 5777 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1), 5778 pre_p, post_p, &preeval_data); 5779 } 5780 5781 bool ctor_has_side_effects_p 5782 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1)); 5783 5784 if (cleared) 5785 { 5786 /* Zap the CONSTRUCTOR element list, which simplifies this case. 5787 Note that we still have to gimplify, in order to handle the 5788 case of variable sized types. Avoid shared tree structures. */ 5789 CONSTRUCTOR_ELTS (ctor) = NULL; 5790 TREE_SIDE_EFFECTS (ctor) = 0; 5791 object = unshare_expr (object); 5792 gimplify_stmt (expr_p, pre_p); 5793 } 5794 5795 /* If we have not block cleared the object, or if there are nonzero 5796 elements in the constructor, or if the constructor has side effects, 5797 add assignments to the individual scalar fields of the object. */ 5798 if (!cleared 5799 || num_nonzero_elements > 0 5800 || ctor_has_side_effects_p) 5801 gimplify_init_ctor_eval (object, elts, pre_p, cleared); 5802 5803 *expr_p = NULL_TREE; 5804 } 5805 break; 5806 5807 case COMPLEX_TYPE: 5808 { 5809 tree r, i; 5810 5811 if (notify_temp_creation) 5812 return GS_OK; 5813 5814 /* Extract the real and imaginary parts out of the ctor. */ 5815 gcc_assert (elts->length () == 2); 5816 r = (*elts)[0].value; 5817 i = (*elts)[1].value; 5818 if (r == NULL || i == NULL) 5819 { 5820 tree zero = build_zero_cst (TREE_TYPE (type)); 5821 if (r == NULL) 5822 r = zero; 5823 if (i == NULL) 5824 i = zero; 5825 } 5826 5827 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to 5828 represent creation of a complex value. */ 5829 if (TREE_CONSTANT (r) && TREE_CONSTANT (i)) 5830 { 5831 ctor = build_complex (type, r, i); 5832 TREE_OPERAND (*expr_p, 1) = ctor; 5833 } 5834 else 5835 { 5836 ctor = build2 (COMPLEX_EXPR, type, r, i); 5837 TREE_OPERAND (*expr_p, 1) = ctor; 5838 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), 5839 pre_p, 5840 post_p, 5841 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)), 5842 fb_rvalue); 5843 } 5844 } 5845 break; 5846 5847 case VECTOR_TYPE: 5848 { 5849 unsigned HOST_WIDE_INT ix; 5850 constructor_elt *ce; 5851 5852 if (notify_temp_creation) 5853 return GS_OK; 5854 5855 /* Vector types use CONSTRUCTOR all the way through gimple 5856 compilation as a general initializer. */ 5857 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce) 5858 { 5859 enum gimplify_status tret; 5860 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val, 5861 fb_rvalue); 5862 if (tret == GS_ERROR) 5863 ret = GS_ERROR; 5864 else if (TREE_STATIC (ctor) 5865 && !initializer_constant_valid_p (ce->value, 5866 TREE_TYPE (ce->value))) 5867 TREE_STATIC (ctor) = 0; 5868 } 5869 recompute_constructor_flags (ctor); 5870 5871 /* Go ahead and simplify constant constructors to VECTOR_CST. */ 5872 if (TREE_CONSTANT (ctor)) 5873 { 5874 bool constant_p = true; 5875 tree value; 5876 5877 /* Even when ctor is constant, it might contain non-*_CST 5878 elements, such as addresses or trapping values like 5879 1.0/0.0 - 1.0/0.0. Such expressions don't belong 5880 in VECTOR_CST nodes. */ 5881 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value) 5882 if (!CONSTANT_CLASS_P (value)) 5883 { 5884 constant_p = false; 5885 break; 5886 } 5887 5888 if (constant_p) 5889 { 5890 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts); 5891 break; 5892 } 5893 } 5894 5895 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0))) 5896 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p); 5897 } 5898 break; 5899 5900 default: 5901 /* So how did we get a CONSTRUCTOR for a scalar type? */ 5902 gcc_unreachable (); 5903 } 5904 5905 if (ret == GS_ERROR) 5906 return GS_ERROR; 5907 /* If we have gimplified both sides of the initializer but have 5908 not emitted an assignment, do so now. */ 5909 if (*expr_p 5910 /* If the type is an empty type, we don't need to emit the 5911 assignment. */ 5912 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) 5913 { 5914 tree lhs = TREE_OPERAND (*expr_p, 0); 5915 tree rhs = TREE_OPERAND (*expr_p, 1); 5916 if (want_value && object == lhs) 5917 lhs = unshare_expr (lhs); 5918 gassign *init = gimple_build_assign (lhs, rhs); 5919 gimplify_seq_add_stmt (pre_p, init); 5920 } 5921 if (want_value) 5922 { 5923 *expr_p = object; 5924 ret = GS_OK; 5925 } 5926 else 5927 { 5928 *expr_p = NULL; 5929 ret = GS_ALL_DONE; 5930 } 5931 5932 /* If the user requests to initialize automatic variables, we 5933 should initialize paddings inside the variable. Add a call to 5934 __builtin_clear_pading (&object, 0, for_auto_init = true) to 5935 initialize paddings of object always to zero regardless of 5936 INIT_TYPE. Note, we will not insert this call if the aggregate 5937 variable has be completely cleared already or it's initialized 5938 with an empty constructor. We cannot insert this call if the 5939 variable is a gimple register since __builtin_clear_padding will take 5940 the address of the variable. As a result, if a long double/_Complex long 5941 double variable will be spilled into stack later, its padding cannot 5942 be cleared with __builtin_clear_padding. We should clear its padding 5943 when it is spilled into memory. */ 5944 if (is_init_expr 5945 && !is_gimple_reg (object) 5946 && clear_padding_type_may_have_padding_p (type) 5947 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor) 5948 || !AGGREGATE_TYPE_P (type)) 5949 && is_var_need_auto_init (object)) 5950 gimple_add_padding_init_for_auto_var (object, false, pre_p); 5951 5952 return ret; 5953 } 5954 5955 /* Given a pointer value OP0, return a simplified version of an 5956 indirection through OP0, or NULL_TREE if no simplification is 5957 possible. This may only be applied to a rhs of an expression. 5958 Note that the resulting type may be different from the type pointed 5959 to in the sense that it is still compatible from the langhooks 5960 point of view. */ 5961 5962 static tree 5963 gimple_fold_indirect_ref_rhs (tree t) 5964 { 5965 return gimple_fold_indirect_ref (t); 5966 } 5967 5968 /* Subroutine of gimplify_modify_expr to do simplifications of 5969 MODIFY_EXPRs based on the code of the RHS. We loop for as long as 5970 something changes. */ 5971 5972 static enum gimplify_status 5973 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, 5974 gimple_seq *pre_p, gimple_seq *post_p, 5975 bool want_value) 5976 { 5977 enum gimplify_status ret = GS_UNHANDLED; 5978 bool changed; 5979 5980 do 5981 { 5982 changed = false; 5983 switch (TREE_CODE (*from_p)) 5984 { 5985 case VAR_DECL: 5986 /* If we're assigning from a read-only variable initialized with 5987 a constructor and not volatile, do the direct assignment from 5988 the constructor, but only if the target is not volatile either 5989 since this latter assignment might end up being done on a per 5990 field basis. However, if the target is volatile and the type 5991 is aggregate and non-addressable, gimplify_init_constructor 5992 knows that it needs to ensure a single access to the target 5993 and it will return GS_OK only in this case. */ 5994 if (TREE_READONLY (*from_p) 5995 && DECL_INITIAL (*from_p) 5996 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR 5997 && !TREE_THIS_VOLATILE (*from_p) 5998 && (!TREE_THIS_VOLATILE (*to_p) 5999 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p)) 6000 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p))))) 6001 { 6002 tree old_from = *from_p; 6003 enum gimplify_status subret; 6004 6005 /* Move the constructor into the RHS. */ 6006 *from_p = unshare_expr (DECL_INITIAL (*from_p)); 6007 6008 /* Let's see if gimplify_init_constructor will need to put 6009 it in memory. */ 6010 subret = gimplify_init_constructor (expr_p, NULL, NULL, 6011 false, true); 6012 if (subret == GS_ERROR) 6013 { 6014 /* If so, revert the change. */ 6015 *from_p = old_from; 6016 } 6017 else 6018 { 6019 ret = GS_OK; 6020 changed = true; 6021 } 6022 } 6023 break; 6024 case INDIRECT_REF: 6025 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p))) 6026 /* If we have code like 6027 6028 *(const A*)(A*)&x 6029 6030 where the type of "x" is a (possibly cv-qualified variant 6031 of "A"), treat the entire expression as identical to "x". 6032 This kind of code arises in C++ when an object is bound 6033 to a const reference, and if "x" is a TARGET_EXPR we want 6034 to take advantage of the optimization below. But not if 6035 the type is TREE_ADDRESSABLE; then C++17 says that the 6036 TARGET_EXPR needs to be a temporary. */ 6037 if (tree t 6038 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0))) 6039 { 6040 bool volatile_p = TREE_THIS_VOLATILE (*from_p); 6041 if (TREE_THIS_VOLATILE (t) != volatile_p) 6042 { 6043 if (DECL_P (t)) 6044 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p), 6045 build_fold_addr_expr (t)); 6046 if (REFERENCE_CLASS_P (t)) 6047 TREE_THIS_VOLATILE (t) = volatile_p; 6048 } 6049 *from_p = t; 6050 ret = GS_OK; 6051 changed = true; 6052 } 6053 break; 6054 6055 case TARGET_EXPR: 6056 { 6057 /* If we are initializing something from a TARGET_EXPR, strip the 6058 TARGET_EXPR and initialize it directly, if possible. This can't 6059 be done if the initializer is void, since that implies that the 6060 temporary is set in some non-trivial way. 6061 6062 ??? What about code that pulls out the temp and uses it 6063 elsewhere? I think that such code never uses the TARGET_EXPR as 6064 an initializer. If I'm wrong, we'll die because the temp won't 6065 have any RTL. In that case, I guess we'll need to replace 6066 references somehow. */ 6067 tree init = TARGET_EXPR_INITIAL (*from_p); 6068 6069 if (init 6070 && (TREE_CODE (*expr_p) != MODIFY_EXPR 6071 || !TARGET_EXPR_NO_ELIDE (*from_p)) 6072 && !VOID_TYPE_P (TREE_TYPE (init))) 6073 { 6074 *from_p = init; 6075 ret = GS_OK; 6076 changed = true; 6077 } 6078 } 6079 break; 6080 6081 case COMPOUND_EXPR: 6082 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be 6083 caught. */ 6084 gimplify_compound_expr (from_p, pre_p, true); 6085 ret = GS_OK; 6086 changed = true; 6087 break; 6088 6089 case CONSTRUCTOR: 6090 /* If we already made some changes, let the front end have a 6091 crack at this before we break it down. */ 6092 if (ret != GS_UNHANDLED) 6093 break; 6094 6095 /* If we're initializing from a CONSTRUCTOR, break this into 6096 individual MODIFY_EXPRs. */ 6097 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value, 6098 false); 6099 return ret; 6100 6101 case COND_EXPR: 6102 /* If we're assigning to a non-register type, push the assignment 6103 down into the branches. This is mandatory for ADDRESSABLE types, 6104 since we cannot generate temporaries for such, but it saves a 6105 copy in other cases as well. */ 6106 if (!is_gimple_reg_type (TREE_TYPE (*from_p))) 6107 { 6108 /* This code should mirror the code in gimplify_cond_expr. */ 6109 enum tree_code code = TREE_CODE (*expr_p); 6110 tree cond = *from_p; 6111 tree result = *to_p; 6112 6113 ret = gimplify_expr (&result, pre_p, post_p, 6114 is_gimple_lvalue, fb_lvalue); 6115 if (ret != GS_ERROR) 6116 ret = GS_OK; 6117 6118 /* If we are going to write RESULT more than once, clear 6119 TREE_READONLY flag, otherwise we might incorrectly promote 6120 the variable to static const and initialize it at compile 6121 time in one of the branches. */ 6122 if (VAR_P (result) 6123 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node 6124 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) 6125 TREE_READONLY (result) = 0; 6126 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node) 6127 TREE_OPERAND (cond, 1) 6128 = build2 (code, void_type_node, result, 6129 TREE_OPERAND (cond, 1)); 6130 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) 6131 TREE_OPERAND (cond, 2) 6132 = build2 (code, void_type_node, unshare_expr (result), 6133 TREE_OPERAND (cond, 2)); 6134 6135 TREE_TYPE (cond) = void_type_node; 6136 recalculate_side_effects (cond); 6137 6138 if (want_value) 6139 { 6140 gimplify_and_add (cond, pre_p); 6141 *expr_p = unshare_expr (result); 6142 } 6143 else 6144 *expr_p = cond; 6145 return ret; 6146 } 6147 break; 6148 6149 case CALL_EXPR: 6150 /* For calls that return in memory, give *to_p as the CALL_EXPR's 6151 return slot so that we don't generate a temporary. */ 6152 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p) 6153 && aggregate_value_p (*from_p, *from_p)) 6154 { 6155 bool use_target; 6156 6157 if (!(rhs_predicate_for (*to_p))(*from_p)) 6158 /* If we need a temporary, *to_p isn't accurate. */ 6159 use_target = false; 6160 /* It's OK to use the return slot directly unless it's an NRV. */ 6161 else if (TREE_CODE (*to_p) == RESULT_DECL 6162 && DECL_NAME (*to_p) == NULL_TREE 6163 && needs_to_live_in_memory (*to_p)) 6164 use_target = true; 6165 else if (is_gimple_reg_type (TREE_TYPE (*to_p)) 6166 || (DECL_P (*to_p) && DECL_REGISTER (*to_p))) 6167 /* Don't force regs into memory. */ 6168 use_target = false; 6169 else if (TREE_CODE (*expr_p) == INIT_EXPR) 6170 /* It's OK to use the target directly if it's being 6171 initialized. */ 6172 use_target = true; 6173 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) 6174 != INTEGER_CST) 6175 /* Always use the target and thus RSO for variable-sized types. 6176 GIMPLE cannot deal with a variable-sized assignment 6177 embedded in a call statement. */ 6178 use_target = true; 6179 else if (TREE_CODE (*to_p) != SSA_NAME 6180 && (!is_gimple_variable (*to_p) 6181 || needs_to_live_in_memory (*to_p))) 6182 /* Don't use the original target if it's already addressable; 6183 if its address escapes, and the called function uses the 6184 NRV optimization, a conforming program could see *to_p 6185 change before the called function returns; see c++/19317. 6186 When optimizing, the return_slot pass marks more functions 6187 as safe after we have escape info. */ 6188 use_target = false; 6189 else 6190 use_target = true; 6191 6192 if (use_target) 6193 { 6194 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1; 6195 mark_addressable (*to_p); 6196 } 6197 } 6198 break; 6199 6200 case WITH_SIZE_EXPR: 6201 /* Likewise for calls that return an aggregate of non-constant size, 6202 since we would not be able to generate a temporary at all. */ 6203 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR) 6204 { 6205 *from_p = TREE_OPERAND (*from_p, 0); 6206 /* We don't change ret in this case because the 6207 WITH_SIZE_EXPR might have been added in 6208 gimplify_modify_expr, so returning GS_OK would lead to an 6209 infinite loop. */ 6210 changed = true; 6211 } 6212 break; 6213 6214 /* If we're initializing from a container, push the initialization 6215 inside it. */ 6216 case CLEANUP_POINT_EXPR: 6217 case BIND_EXPR: 6218 case STATEMENT_LIST: 6219 { 6220 tree wrap = *from_p; 6221 tree t; 6222 6223 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval, 6224 fb_lvalue); 6225 if (ret != GS_ERROR) 6226 ret = GS_OK; 6227 6228 t = voidify_wrapper_expr (wrap, *expr_p); 6229 gcc_assert (t == *expr_p); 6230 6231 if (want_value) 6232 { 6233 gimplify_and_add (wrap, pre_p); 6234 *expr_p = unshare_expr (*to_p); 6235 } 6236 else 6237 *expr_p = wrap; 6238 return GS_OK; 6239 } 6240 6241 case NOP_EXPR: 6242 /* Pull out compound literal expressions from a NOP_EXPR. 6243 Those are created in the C FE to drop qualifiers during 6244 lvalue conversion. */ 6245 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR) 6246 && tree_ssa_useless_type_conversion (*from_p)) 6247 { 6248 *from_p = TREE_OPERAND (*from_p, 0); 6249 ret = GS_OK; 6250 changed = true; 6251 } 6252 break; 6253 6254 case COMPOUND_LITERAL_EXPR: 6255 { 6256 tree complit = TREE_OPERAND (*expr_p, 1); 6257 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit); 6258 tree decl = DECL_EXPR_DECL (decl_s); 6259 tree init = DECL_INITIAL (decl); 6260 6261 /* struct T x = (struct T) { 0, 1, 2 } can be optimized 6262 into struct T x = { 0, 1, 2 } if the address of the 6263 compound literal has never been taken. */ 6264 if (!TREE_ADDRESSABLE (complit) 6265 && !TREE_ADDRESSABLE (decl) 6266 && init) 6267 { 6268 *expr_p = copy_node (*expr_p); 6269 TREE_OPERAND (*expr_p, 1) = init; 6270 return GS_OK; 6271 } 6272 } 6273 6274 default: 6275 break; 6276 } 6277 } 6278 while (changed); 6279 6280 return ret; 6281 } 6282 6283 6284 /* Return true if T looks like a valid GIMPLE statement. */ 6285 6286 static bool 6287 is_gimple_stmt (tree t) 6288 { 6289 const enum tree_code code = TREE_CODE (t); 6290 6291 switch (code) 6292 { 6293 case NOP_EXPR: 6294 /* The only valid NOP_EXPR is the empty statement. */ 6295 return IS_EMPTY_STMT (t); 6296 6297 case BIND_EXPR: 6298 case COND_EXPR: 6299 /* These are only valid if they're void. */ 6300 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t)); 6301 6302 case SWITCH_EXPR: 6303 case GOTO_EXPR: 6304 case RETURN_EXPR: 6305 case LABEL_EXPR: 6306 case CASE_LABEL_EXPR: 6307 case TRY_CATCH_EXPR: 6308 case TRY_FINALLY_EXPR: 6309 case EH_FILTER_EXPR: 6310 case CATCH_EXPR: 6311 case ASM_EXPR: 6312 case STATEMENT_LIST: 6313 case OACC_PARALLEL: 6314 case OACC_KERNELS: 6315 case OACC_SERIAL: 6316 case OACC_DATA: 6317 case OACC_HOST_DATA: 6318 case OACC_DECLARE: 6319 case OACC_UPDATE: 6320 case OACC_ENTER_DATA: 6321 case OACC_EXIT_DATA: 6322 case OACC_CACHE: 6323 case OMP_PARALLEL: 6324 case OMP_FOR: 6325 case OMP_SIMD: 6326 case OMP_DISTRIBUTE: 6327 case OMP_LOOP: 6328 case OACC_LOOP: 6329 case OMP_SCAN: 6330 case OMP_SCOPE: 6331 case OMP_SECTIONS: 6332 case OMP_SECTION: 6333 case OMP_STRUCTURED_BLOCK: 6334 case OMP_SINGLE: 6335 case OMP_MASTER: 6336 case OMP_MASKED: 6337 case OMP_TASKGROUP: 6338 case OMP_ORDERED: 6339 case OMP_CRITICAL: 6340 case OMP_TASK: 6341 case OMP_TARGET: 6342 case OMP_TARGET_DATA: 6343 case OMP_TARGET_UPDATE: 6344 case OMP_TARGET_ENTER_DATA: 6345 case OMP_TARGET_EXIT_DATA: 6346 case OMP_TASKLOOP: 6347 case OMP_TEAMS: 6348 /* These are always void. */ 6349 return true; 6350 6351 case CALL_EXPR: 6352 case MODIFY_EXPR: 6353 case PREDICT_EXPR: 6354 /* These are valid regardless of their type. */ 6355 return true; 6356 6357 default: 6358 return false; 6359 } 6360 } 6361 6362 6363 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is 6364 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register. 6365 6366 IMPORTANT NOTE: This promotion is performed by introducing a load of the 6367 other, unmodified part of the complex object just before the total store. 6368 As a consequence, if the object is still uninitialized, an undefined value 6369 will be loaded into a register, which may result in a spurious exception 6370 if the register is floating-point and the value happens to be a signaling 6371 NaN for example. Then the fully-fledged complex operations lowering pass 6372 followed by a DCE pass are necessary in order to fix things up. */ 6373 6374 static enum gimplify_status 6375 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p, 6376 bool want_value) 6377 { 6378 enum tree_code code, ocode; 6379 tree lhs, rhs, new_rhs, other, realpart, imagpart; 6380 6381 lhs = TREE_OPERAND (*expr_p, 0); 6382 rhs = TREE_OPERAND (*expr_p, 1); 6383 code = TREE_CODE (lhs); 6384 lhs = TREE_OPERAND (lhs, 0); 6385 6386 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; 6387 other = build1 (ocode, TREE_TYPE (rhs), lhs); 6388 suppress_warning (other); 6389 other = get_formal_tmp_var (other, pre_p); 6390 6391 realpart = code == REALPART_EXPR ? rhs : other; 6392 imagpart = code == REALPART_EXPR ? other : rhs; 6393 6394 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart)) 6395 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart); 6396 else 6397 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart); 6398 6399 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs)); 6400 *expr_p = (want_value) ? rhs : NULL_TREE; 6401 6402 return GS_ALL_DONE; 6403 } 6404 6405 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P. 6406 6407 modify_expr 6408 : varname '=' rhs 6409 | '*' ID '=' rhs 6410 6411 PRE_P points to the list where side effects that must happen before 6412 *EXPR_P should be stored. 6413 6414 POST_P points to the list where side effects that must happen after 6415 *EXPR_P should be stored. 6416 6417 WANT_VALUE is nonzero iff we want to use the value of this expression 6418 in another expression. */ 6419 6420 static enum gimplify_status 6421 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 6422 bool want_value) 6423 { 6424 tree *from_p = &TREE_OPERAND (*expr_p, 1); 6425 tree *to_p = &TREE_OPERAND (*expr_p, 0); 6426 enum gimplify_status ret = GS_UNHANDLED; 6427 gimple *assign; 6428 location_t loc = EXPR_LOCATION (*expr_p); 6429 gimple_stmt_iterator gsi; 6430 6431 if (error_operand_p (*from_p) || error_operand_p (*to_p)) 6432 return GS_ERROR; 6433 6434 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR 6435 || TREE_CODE (*expr_p) == INIT_EXPR); 6436 6437 /* Trying to simplify a clobber using normal logic doesn't work, 6438 so handle it here. */ 6439 if (TREE_CLOBBER_P (*from_p)) 6440 { 6441 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 6442 if (ret == GS_ERROR) 6443 return ret; 6444 gcc_assert (!want_value); 6445 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF) 6446 { 6447 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p), 6448 pre_p, post_p); 6449 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr); 6450 } 6451 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p)); 6452 *expr_p = NULL; 6453 return GS_ALL_DONE; 6454 } 6455 6456 /* Convert initialization from an empty variable-size CONSTRUCTOR to 6457 memset. */ 6458 if (TREE_TYPE (*from_p) != error_mark_node 6459 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p)) 6460 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p))) 6461 && TREE_CODE (*from_p) == CONSTRUCTOR 6462 && CONSTRUCTOR_NELTS (*from_p) == 0) 6463 { 6464 maybe_with_size_expr (from_p); 6465 gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR); 6466 return gimplify_modify_expr_to_memset (expr_p, 6467 TREE_OPERAND (*from_p, 1), 6468 want_value, pre_p); 6469 } 6470 6471 /* Insert pointer conversions required by the middle-end that are not 6472 required by the frontend. This fixes middle-end type checking for 6473 for example gcc.dg/redecl-6.c. */ 6474 if (POINTER_TYPE_P (TREE_TYPE (*to_p))) 6475 { 6476 STRIP_USELESS_TYPE_CONVERSION (*from_p); 6477 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p))) 6478 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p); 6479 } 6480 6481 /* See if any simplifications can be done based on what the RHS is. */ 6482 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 6483 want_value); 6484 if (ret != GS_UNHANDLED) 6485 return ret; 6486 6487 /* For empty types only gimplify the left hand side and right hand 6488 side as statements and throw away the assignment. Do this after 6489 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable 6490 types properly. */ 6491 if (is_empty_type (TREE_TYPE (*from_p)) 6492 && !want_value 6493 /* Don't do this for calls that return addressable types, expand_call 6494 relies on those having a lhs. */ 6495 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p)) 6496 && TREE_CODE (*from_p) == CALL_EXPR)) 6497 { 6498 gimplify_stmt (from_p, pre_p); 6499 gimplify_stmt (to_p, pre_p); 6500 *expr_p = NULL_TREE; 6501 return GS_ALL_DONE; 6502 } 6503 6504 /* If the value being copied is of variable width, compute the length 6505 of the copy into a WITH_SIZE_EXPR. Note that we need to do this 6506 before gimplifying any of the operands so that we can resolve any 6507 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses 6508 the size of the expression to be copied, not of the destination, so 6509 that is what we must do here. */ 6510 maybe_with_size_expr (from_p); 6511 6512 /* As a special case, we have to temporarily allow for assignments 6513 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is 6514 a toplevel statement, when gimplifying the GENERIC expression 6515 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple 6516 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>. 6517 6518 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To 6519 prevent gimplify_expr from trying to create a new temporary for 6520 foo's LHS, we tell it that it should only gimplify until it 6521 reaches the CALL_EXPR. On return from gimplify_expr, the newly 6522 created GIMPLE_CALL <foo> will be the last statement in *PRE_P 6523 and all we need to do here is set 'a' to be its LHS. */ 6524 6525 /* Gimplify the RHS first for C++17 and bug 71104. */ 6526 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p); 6527 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue); 6528 if (ret == GS_ERROR) 6529 return ret; 6530 6531 /* Then gimplify the LHS. */ 6532 /* If we gimplified the RHS to a CALL_EXPR and that call may return 6533 twice we have to make sure to gimplify into non-SSA as otherwise 6534 the abnormal edge added later will make those defs not dominate 6535 their uses. 6536 ??? Technically this applies only to the registers used in the 6537 resulting non-register *TO_P. */ 6538 bool saved_into_ssa = gimplify_ctxp->into_ssa; 6539 if (saved_into_ssa 6540 && TREE_CODE (*from_p) == CALL_EXPR 6541 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE) 6542 gimplify_ctxp->into_ssa = false; 6543 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 6544 gimplify_ctxp->into_ssa = saved_into_ssa; 6545 if (ret == GS_ERROR) 6546 return ret; 6547 6548 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial 6549 guess for the predicate was wrong. */ 6550 gimple_predicate final_pred = rhs_predicate_for (*to_p); 6551 if (final_pred != initial_pred) 6552 { 6553 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue); 6554 if (ret == GS_ERROR) 6555 return ret; 6556 } 6557 6558 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type 6559 size as argument to the call. */ 6560 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) 6561 { 6562 tree call = TREE_OPERAND (*from_p, 0); 6563 tree vlasize = TREE_OPERAND (*from_p, 1); 6564 6565 if (TREE_CODE (call) == CALL_EXPR 6566 && CALL_EXPR_IFN (call) == IFN_VA_ARG) 6567 { 6568 int nargs = call_expr_nargs (call); 6569 tree type = TREE_TYPE (call); 6570 tree ap = CALL_EXPR_ARG (call, 0); 6571 tree tag = CALL_EXPR_ARG (call, 1); 6572 tree aptag = CALL_EXPR_ARG (call, 2); 6573 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call), 6574 IFN_VA_ARG, type, 6575 nargs + 1, ap, tag, 6576 aptag, vlasize); 6577 TREE_OPERAND (*from_p, 0) = newcall; 6578 } 6579 } 6580 6581 /* Now see if the above changed *from_p to something we handle specially. */ 6582 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 6583 want_value); 6584 if (ret != GS_UNHANDLED) 6585 return ret; 6586 6587 /* If we've got a variable sized assignment between two lvalues (i.e. does 6588 not involve a call), then we can make things a bit more straightforward 6589 by converting the assignment to memcpy or memset. */ 6590 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) 6591 { 6592 tree from = TREE_OPERAND (*from_p, 0); 6593 tree size = TREE_OPERAND (*from_p, 1); 6594 6595 if (TREE_CODE (from) == CONSTRUCTOR) 6596 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p); 6597 else if (is_gimple_addressable (from) 6598 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p))) 6599 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from)))) 6600 { 6601 *from_p = from; 6602 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value, 6603 pre_p); 6604 } 6605 } 6606 6607 /* Transform partial stores to non-addressable complex variables into 6608 total stores. This allows us to use real instead of virtual operands 6609 for these variables, which improves optimization. */ 6610 if ((TREE_CODE (*to_p) == REALPART_EXPR 6611 || TREE_CODE (*to_p) == IMAGPART_EXPR) 6612 && is_gimple_reg (TREE_OPERAND (*to_p, 0))) 6613 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); 6614 6615 /* Try to alleviate the effects of the gimplification creating artificial 6616 temporaries (see for example is_gimple_reg_rhs) on the debug info, but 6617 make sure not to create DECL_DEBUG_EXPR links across functions. */ 6618 if (!gimplify_ctxp->into_ssa 6619 && VAR_P (*from_p) 6620 && DECL_IGNORED_P (*from_p) 6621 && DECL_P (*to_p) 6622 && !DECL_IGNORED_P (*to_p) 6623 && decl_function_context (*to_p) == current_function_decl 6624 && decl_function_context (*from_p) == current_function_decl) 6625 { 6626 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p)) 6627 DECL_NAME (*from_p) 6628 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p))); 6629 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1; 6630 SET_DECL_DEBUG_EXPR (*from_p, *to_p); 6631 } 6632 6633 if (want_value && TREE_THIS_VOLATILE (*to_p)) 6634 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p); 6635 6636 if (TREE_CODE (*from_p) == CALL_EXPR) 6637 { 6638 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL 6639 instead of a GIMPLE_ASSIGN. */ 6640 gcall *call_stmt; 6641 if (CALL_EXPR_FN (*from_p) == NULL_TREE) 6642 { 6643 /* Gimplify internal functions created in the FEs. */ 6644 int nargs = call_expr_nargs (*from_p), i; 6645 enum internal_fn ifn = CALL_EXPR_IFN (*from_p); 6646 auto_vec<tree> vargs (nargs); 6647 6648 for (i = 0; i < nargs; i++) 6649 { 6650 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p, 6651 EXPR_LOCATION (*from_p)); 6652 vargs.quick_push (CALL_EXPR_ARG (*from_p, i)); 6653 } 6654 call_stmt = gimple_build_call_internal_vec (ifn, vargs); 6655 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p)); 6656 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p)); 6657 } 6658 else 6659 { 6660 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p)); 6661 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0); 6662 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p)); 6663 tree fndecl = get_callee_fndecl (*from_p); 6664 if (fndecl 6665 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT) 6666 && call_expr_nargs (*from_p) == 3) 6667 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3, 6668 CALL_EXPR_ARG (*from_p, 0), 6669 CALL_EXPR_ARG (*from_p, 1), 6670 CALL_EXPR_ARG (*from_p, 2)); 6671 else 6672 { 6673 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype); 6674 } 6675 } 6676 notice_special_calls (call_stmt); 6677 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p)) 6678 gimple_call_set_lhs (call_stmt, *to_p); 6679 else if (TREE_CODE (*to_p) == SSA_NAME) 6680 /* The above is somewhat premature, avoid ICEing later for a 6681 SSA name w/o a definition. We may have uses in the GIMPLE IL. 6682 ??? This doesn't make it a default-def. */ 6683 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop (); 6684 6685 assign = call_stmt; 6686 } 6687 else 6688 { 6689 assign = gimple_build_assign (*to_p, *from_p); 6690 gimple_set_location (assign, EXPR_LOCATION (*expr_p)); 6691 if (COMPARISON_CLASS_P (*from_p)) 6692 copy_warning (assign, *from_p); 6693 } 6694 6695 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) 6696 { 6697 /* We should have got an SSA name from the start. */ 6698 gcc_assert (TREE_CODE (*to_p) == SSA_NAME 6699 || ! gimple_in_ssa_p (cfun)); 6700 } 6701 6702 gimplify_seq_add_stmt (pre_p, assign); 6703 gsi = gsi_last (*pre_p); 6704 maybe_fold_stmt (&gsi); 6705 6706 if (want_value) 6707 { 6708 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p); 6709 return GS_OK; 6710 } 6711 else 6712 *expr_p = NULL; 6713 6714 return GS_ALL_DONE; 6715 } 6716 6717 /* Gimplify a comparison between two variable-sized objects. Do this 6718 with a call to BUILT_IN_MEMCMP. */ 6719 6720 static enum gimplify_status 6721 gimplify_variable_sized_compare (tree *expr_p) 6722 { 6723 location_t loc = EXPR_LOCATION (*expr_p); 6724 tree op0 = TREE_OPERAND (*expr_p, 0); 6725 tree op1 = TREE_OPERAND (*expr_p, 1); 6726 tree t, arg, dest, src, expr; 6727 6728 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0)); 6729 arg = unshare_expr (arg); 6730 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0); 6731 src = build_fold_addr_expr_loc (loc, op1); 6732 dest = build_fold_addr_expr_loc (loc, op0); 6733 t = builtin_decl_implicit (BUILT_IN_MEMCMP); 6734 t = build_call_expr_loc (loc, t, 3, dest, src, arg); 6735 6736 expr 6737 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node); 6738 SET_EXPR_LOCATION (expr, loc); 6739 *expr_p = expr; 6740 6741 return GS_OK; 6742 } 6743 6744 /* Gimplify a comparison between two aggregate objects of integral scalar 6745 mode as a comparison between the bitwise equivalent scalar values. */ 6746 6747 static enum gimplify_status 6748 gimplify_scalar_mode_aggregate_compare (tree *expr_p) 6749 { 6750 location_t loc = EXPR_LOCATION (*expr_p); 6751 tree op0 = TREE_OPERAND (*expr_p, 0); 6752 tree op1 = TREE_OPERAND (*expr_p, 1); 6753 6754 tree type = TREE_TYPE (op0); 6755 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1); 6756 6757 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0); 6758 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1); 6759 6760 *expr_p 6761 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1); 6762 6763 return GS_OK; 6764 } 6765 6766 /* Gimplify an expression sequence. This function gimplifies each 6767 expression and rewrites the original expression with the last 6768 expression of the sequence in GIMPLE form. 6769 6770 PRE_P points to the list where the side effects for all the 6771 expressions in the sequence will be emitted. 6772 6773 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */ 6774 6775 static enum gimplify_status 6776 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) 6777 { 6778 tree t = *expr_p; 6779 6780 do 6781 { 6782 tree *sub_p = &TREE_OPERAND (t, 0); 6783 6784 if (TREE_CODE (*sub_p) == COMPOUND_EXPR) 6785 gimplify_compound_expr (sub_p, pre_p, false); 6786 else 6787 gimplify_stmt (sub_p, pre_p); 6788 6789 t = TREE_OPERAND (t, 1); 6790 } 6791 while (TREE_CODE (t) == COMPOUND_EXPR); 6792 6793 *expr_p = t; 6794 if (want_value) 6795 return GS_OK; 6796 else 6797 { 6798 gimplify_stmt (expr_p, pre_p); 6799 return GS_ALL_DONE; 6800 } 6801 } 6802 6803 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to 6804 gimplify. After gimplification, EXPR_P will point to a new temporary 6805 that holds the original value of the SAVE_EXPR node. 6806 6807 PRE_P points to the list where side effects that must happen before 6808 *EXPR_P should be stored. */ 6809 6810 static enum gimplify_status 6811 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6812 { 6813 enum gimplify_status ret = GS_ALL_DONE; 6814 tree val; 6815 6816 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR); 6817 val = TREE_OPERAND (*expr_p, 0); 6818 6819 if (val && TREE_TYPE (val) == error_mark_node) 6820 return GS_ERROR; 6821 6822 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */ 6823 if (!SAVE_EXPR_RESOLVED_P (*expr_p)) 6824 { 6825 /* The operand may be a void-valued expression. It is 6826 being executed only for its side-effects. */ 6827 if (TREE_TYPE (val) == void_type_node) 6828 { 6829 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 6830 is_gimple_stmt, fb_none); 6831 val = NULL; 6832 } 6833 else 6834 /* The temporary may not be an SSA name as later abnormal and EH 6835 control flow may invalidate use/def domination. When in SSA 6836 form then assume there are no such issues and SAVE_EXPRs only 6837 appear via GENERIC foldings. */ 6838 val = get_initialized_tmp_var (val, pre_p, post_p, 6839 gimple_in_ssa_p (cfun)); 6840 6841 TREE_OPERAND (*expr_p, 0) = val; 6842 SAVE_EXPR_RESOLVED_P (*expr_p) = 1; 6843 } 6844 6845 *expr_p = val; 6846 6847 return ret; 6848 } 6849 6850 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P 6851 6852 unary_expr 6853 : ... 6854 | '&' varname 6855 ... 6856 6857 PRE_P points to the list where side effects that must happen before 6858 *EXPR_P should be stored. 6859 6860 POST_P points to the list where side effects that must happen after 6861 *EXPR_P should be stored. */ 6862 6863 static enum gimplify_status 6864 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6865 { 6866 tree expr = *expr_p; 6867 tree op0 = TREE_OPERAND (expr, 0); 6868 enum gimplify_status ret; 6869 location_t loc = EXPR_LOCATION (*expr_p); 6870 6871 switch (TREE_CODE (op0)) 6872 { 6873 case INDIRECT_REF: 6874 do_indirect_ref: 6875 /* Check if we are dealing with an expression of the form '&*ptr'. 6876 While the front end folds away '&*ptr' into 'ptr', these 6877 expressions may be generated internally by the compiler (e.g., 6878 builtins like __builtin_va_end). */ 6879 /* Caution: the silent array decomposition semantics we allow for 6880 ADDR_EXPR means we can't always discard the pair. */ 6881 /* Gimplification of the ADDR_EXPR operand may drop 6882 cv-qualification conversions, so make sure we add them if 6883 needed. */ 6884 { 6885 tree op00 = TREE_OPERAND (op0, 0); 6886 tree t_expr = TREE_TYPE (expr); 6887 tree t_op00 = TREE_TYPE (op00); 6888 6889 if (!useless_type_conversion_p (t_expr, t_op00)) 6890 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00); 6891 *expr_p = op00; 6892 ret = GS_OK; 6893 } 6894 break; 6895 6896 case VIEW_CONVERT_EXPR: 6897 /* Take the address of our operand and then convert it to the type of 6898 this ADDR_EXPR. 6899 6900 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at 6901 all clear. The impact of this transformation is even less clear. */ 6902 6903 /* If the operand is a useless conversion, look through it. Doing so 6904 guarantees that the ADDR_EXPR and its operand will remain of the 6905 same type. */ 6906 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0))) 6907 op0 = TREE_OPERAND (op0, 0); 6908 6909 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr), 6910 build_fold_addr_expr_loc (loc, 6911 TREE_OPERAND (op0, 0))); 6912 ret = GS_OK; 6913 break; 6914 6915 case MEM_REF: 6916 if (integer_zerop (TREE_OPERAND (op0, 1))) 6917 goto do_indirect_ref; 6918 6919 /* fall through */ 6920 6921 default: 6922 /* If we see a call to a declared builtin or see its address 6923 being taken (we can unify those cases here) then we can mark 6924 the builtin for implicit generation by GCC. */ 6925 if (TREE_CODE (op0) == FUNCTION_DECL 6926 && fndecl_built_in_p (op0, BUILT_IN_NORMAL) 6927 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0))) 6928 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true); 6929 6930 /* We use fb_either here because the C frontend sometimes takes 6931 the address of a call that returns a struct; see 6932 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make 6933 the implied temporary explicit. */ 6934 6935 /* Make the operand addressable. */ 6936 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, 6937 is_gimple_addressable, fb_either); 6938 if (ret == GS_ERROR) 6939 break; 6940 6941 /* Then mark it. Beware that it may not be possible to do so directly 6942 if a temporary has been created by the gimplification. */ 6943 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p); 6944 6945 op0 = TREE_OPERAND (expr, 0); 6946 6947 /* For various reasons, the gimplification of the expression 6948 may have made a new INDIRECT_REF. */ 6949 if (INDIRECT_REF_P (op0) 6950 || (TREE_CODE (op0) == MEM_REF 6951 && integer_zerop (TREE_OPERAND (op0, 1)))) 6952 goto do_indirect_ref; 6953 6954 mark_addressable (TREE_OPERAND (expr, 0)); 6955 6956 /* The FEs may end up building ADDR_EXPRs early on a decl with 6957 an incomplete type. Re-build ADDR_EXPRs in canonical form 6958 here. */ 6959 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr)))) 6960 *expr_p = build_fold_addr_expr (op0); 6961 6962 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ 6963 if (TREE_CODE (*expr_p) == ADDR_EXPR) 6964 recompute_tree_invariant_for_addr_expr (*expr_p); 6965 6966 /* If we re-built the ADDR_EXPR add a conversion to the original type 6967 if required. */ 6968 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) 6969 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); 6970 6971 break; 6972 } 6973 6974 return ret; 6975 } 6976 6977 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple 6978 value; output operands should be a gimple lvalue. */ 6979 6980 static enum gimplify_status 6981 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6982 { 6983 tree expr; 6984 int noutputs; 6985 const char **oconstraints; 6986 int i; 6987 tree link; 6988 const char *constraint; 6989 bool allows_mem, allows_reg, is_inout; 6990 enum gimplify_status ret, tret; 6991 gasm *stmt; 6992 vec<tree, va_gc> *inputs; 6993 vec<tree, va_gc> *outputs; 6994 vec<tree, va_gc> *clobbers; 6995 vec<tree, va_gc> *labels; 6996 tree link_next; 6997 6998 expr = *expr_p; 6999 noutputs = list_length (ASM_OUTPUTS (expr)); 7000 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *)); 7001 7002 inputs = NULL; 7003 outputs = NULL; 7004 clobbers = NULL; 7005 labels = NULL; 7006 7007 ret = GS_ALL_DONE; 7008 link_next = NULL_TREE; 7009 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next) 7010 { 7011 bool ok; 7012 size_t constraint_len; 7013 7014 link_next = TREE_CHAIN (link); 7015 7016 oconstraints[i] 7017 = constraint 7018 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 7019 constraint_len = strlen (constraint); 7020 if (constraint_len == 0) 7021 continue; 7022 7023 ok = parse_output_constraint (&constraint, i, 0, 0, 7024 &allows_mem, &allows_reg, &is_inout); 7025 if (!ok) 7026 { 7027 ret = GS_ERROR; 7028 is_inout = false; 7029 } 7030 7031 /* If we can't make copies, we can only accept memory. 7032 Similarly for VLAs. */ 7033 tree outtype = TREE_TYPE (TREE_VALUE (link)); 7034 if (outtype != error_mark_node 7035 && (TREE_ADDRESSABLE (outtype) 7036 || !COMPLETE_TYPE_P (outtype) 7037 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype)))) 7038 { 7039 if (allows_mem) 7040 allows_reg = 0; 7041 else 7042 { 7043 error ("impossible constraint in %<asm%>"); 7044 error ("non-memory output %d must stay in memory", i); 7045 return GS_ERROR; 7046 } 7047 } 7048 7049 if (!allows_reg && allows_mem) 7050 mark_addressable (TREE_VALUE (link)); 7051 7052 tree orig = TREE_VALUE (link); 7053 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7054 is_inout ? is_gimple_min_lval : is_gimple_lvalue, 7055 fb_lvalue | fb_mayfail); 7056 if (tret == GS_ERROR) 7057 { 7058 if (orig != error_mark_node) 7059 error ("invalid lvalue in %<asm%> output %d", i); 7060 ret = tret; 7061 } 7062 7063 /* If the gimplified operand is a register we do not allow memory. */ 7064 if (allows_reg 7065 && allows_mem 7066 && (is_gimple_reg (TREE_VALUE (link)) 7067 || (handled_component_p (TREE_VALUE (link)) 7068 && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0))))) 7069 allows_mem = 0; 7070 7071 /* If the constraint does not allow memory make sure we gimplify 7072 it to a register if it is not already but its base is. This 7073 happens for complex and vector components. */ 7074 if (!allows_mem) 7075 { 7076 tree op = TREE_VALUE (link); 7077 if (! is_gimple_val (op) 7078 && is_gimple_reg_type (TREE_TYPE (op)) 7079 && is_gimple_reg (get_base_address (op))) 7080 { 7081 tree tem = create_tmp_reg (TREE_TYPE (op)); 7082 tree ass; 7083 if (is_inout) 7084 { 7085 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), 7086 tem, unshare_expr (op)); 7087 gimplify_and_add (ass, pre_p); 7088 } 7089 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem); 7090 gimplify_and_add (ass, post_p); 7091 7092 TREE_VALUE (link) = tem; 7093 tret = GS_OK; 7094 } 7095 } 7096 7097 vec_safe_push (outputs, link); 7098 TREE_CHAIN (link) = NULL_TREE; 7099 7100 if (is_inout) 7101 { 7102 /* An input/output operand. To give the optimizers more 7103 flexibility, split it into separate input and output 7104 operands. */ 7105 tree input; 7106 /* Buffer big enough to format a 32-bit UINT_MAX into. */ 7107 char buf[11]; 7108 7109 /* Turn the in/out constraint into an output constraint. */ 7110 char *p = xstrdup (constraint); 7111 p[0] = '='; 7112 TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link)); 7113 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); 7114 7115 /* And add a matching input constraint. */ 7116 if (allows_reg) 7117 { 7118 sprintf (buf, "%u", i); 7119 7120 /* If there are multiple alternatives in the constraint, 7121 handle each of them individually. Those that allow register 7122 will be replaced with operand number, the others will stay 7123 unchanged. */ 7124 if (strchr (p, ',') != NULL) 7125 { 7126 size_t len = 0, buflen = strlen (buf); 7127 char *beg, *end, *str, *dst; 7128 7129 for (beg = p + 1;;) 7130 { 7131 end = strchr (beg, ','); 7132 if (end == NULL) 7133 end = strchr (beg, '\0'); 7134 if ((size_t) (end - beg) < buflen) 7135 len += buflen + 1; 7136 else 7137 len += end - beg + 1; 7138 if (*end) 7139 beg = end + 1; 7140 else 7141 break; 7142 } 7143 7144 str = (char *) alloca (len); 7145 for (beg = p + 1, dst = str;;) 7146 { 7147 const char *tem; 7148 bool mem_p, reg_p, inout_p; 7149 7150 end = strchr (beg, ','); 7151 if (end) 7152 *end = '\0'; 7153 beg[-1] = '='; 7154 tem = beg - 1; 7155 parse_output_constraint (&tem, i, 0, 0, 7156 &mem_p, ®_p, &inout_p); 7157 if (dst != str) 7158 *dst++ = ','; 7159 if (reg_p) 7160 { 7161 memcpy (dst, buf, buflen); 7162 dst += buflen; 7163 } 7164 else 7165 { 7166 if (end) 7167 len = end - beg; 7168 else 7169 len = strlen (beg); 7170 memcpy (dst, beg, len); 7171 dst += len; 7172 } 7173 if (end) 7174 beg = end + 1; 7175 else 7176 break; 7177 } 7178 *dst = '\0'; 7179 input = build_string (dst - str, str); 7180 } 7181 else 7182 input = build_string (strlen (buf), buf); 7183 } 7184 else 7185 input = build_string (constraint_len - 1, constraint + 1); 7186 7187 free (p); 7188 7189 input = build_tree_list (build_tree_list (NULL_TREE, input), 7190 unshare_expr (TREE_VALUE (link))); 7191 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); 7192 } 7193 } 7194 7195 link_next = NULL_TREE; 7196 for (link = ASM_INPUTS (expr); link; ++i, link = link_next) 7197 { 7198 link_next = TREE_CHAIN (link); 7199 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 7200 parse_input_constraint (&constraint, 0, 0, noutputs, 0, 7201 oconstraints, &allows_mem, &allows_reg); 7202 7203 /* If we can't make copies, we can only accept memory. */ 7204 tree intype = TREE_TYPE (TREE_VALUE (link)); 7205 if (intype != error_mark_node 7206 && (TREE_ADDRESSABLE (intype) 7207 || !COMPLETE_TYPE_P (intype) 7208 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype)))) 7209 { 7210 if (allows_mem) 7211 allows_reg = 0; 7212 else 7213 { 7214 error ("impossible constraint in %<asm%>"); 7215 error ("non-memory input %d must stay in memory", i); 7216 return GS_ERROR; 7217 } 7218 } 7219 7220 /* If the operand is a memory input, it should be an lvalue. */ 7221 if (!allows_reg && allows_mem) 7222 { 7223 tree inputv = TREE_VALUE (link); 7224 STRIP_NOPS (inputv); 7225 if (TREE_CODE (inputv) == PREDECREMENT_EXPR 7226 || TREE_CODE (inputv) == PREINCREMENT_EXPR 7227 || TREE_CODE (inputv) == POSTDECREMENT_EXPR 7228 || TREE_CODE (inputv) == POSTINCREMENT_EXPR 7229 || TREE_CODE (inputv) == MODIFY_EXPR) 7230 TREE_VALUE (link) = error_mark_node; 7231 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7232 is_gimple_lvalue, fb_lvalue | fb_mayfail); 7233 if (tret != GS_ERROR) 7234 { 7235 /* Unlike output operands, memory inputs are not guaranteed 7236 to be lvalues by the FE, and while the expressions are 7237 marked addressable there, if it is e.g. a statement 7238 expression, temporaries in it might not end up being 7239 addressable. They might be already used in the IL and thus 7240 it is too late to make them addressable now though. */ 7241 tree x = TREE_VALUE (link); 7242 while (handled_component_p (x)) 7243 x = TREE_OPERAND (x, 0); 7244 if (TREE_CODE (x) == MEM_REF 7245 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR) 7246 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0); 7247 if ((VAR_P (x) 7248 || TREE_CODE (x) == PARM_DECL 7249 || TREE_CODE (x) == RESULT_DECL) 7250 && !TREE_ADDRESSABLE (x) 7251 && is_gimple_reg (x)) 7252 { 7253 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), 7254 input_location), 0, 7255 "memory input %d is not directly addressable", 7256 i); 7257 prepare_gimple_addressable (&TREE_VALUE (link), pre_p); 7258 } 7259 } 7260 mark_addressable (TREE_VALUE (link)); 7261 if (tret == GS_ERROR) 7262 { 7263 if (inputv != error_mark_node) 7264 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location), 7265 "memory input %d is not directly addressable", i); 7266 ret = tret; 7267 } 7268 } 7269 else 7270 { 7271 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7272 is_gimple_asm_val, fb_rvalue); 7273 if (tret == GS_ERROR) 7274 ret = tret; 7275 } 7276 7277 TREE_CHAIN (link) = NULL_TREE; 7278 vec_safe_push (inputs, link); 7279 } 7280 7281 link_next = NULL_TREE; 7282 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next) 7283 { 7284 link_next = TREE_CHAIN (link); 7285 TREE_CHAIN (link) = NULL_TREE; 7286 vec_safe_push (clobbers, link); 7287 } 7288 7289 link_next = NULL_TREE; 7290 for (link = ASM_LABELS (expr); link; ++i, link = link_next) 7291 { 7292 link_next = TREE_CHAIN (link); 7293 TREE_CHAIN (link) = NULL_TREE; 7294 vec_safe_push (labels, link); 7295 } 7296 7297 /* Do not add ASMs with errors to the gimple IL stream. */ 7298 if (ret != GS_ERROR) 7299 { 7300 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)), 7301 inputs, outputs, clobbers, labels); 7302 7303 /* asm is volatile if it was marked by the user as volatile or 7304 there are no outputs or this is an asm goto. */ 7305 gimple_asm_set_volatile (stmt, 7306 ASM_VOLATILE_P (expr) 7307 || noutputs == 0 7308 || labels); 7309 gimple_asm_set_input (stmt, ASM_INPUT_P (expr)); 7310 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr)); 7311 7312 gimplify_seq_add_stmt (pre_p, stmt); 7313 } 7314 7315 return ret; 7316 } 7317 7318 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding 7319 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while 7320 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we 7321 return to this function. 7322 7323 FIXME should we complexify the prequeue handling instead? Or use flags 7324 for all the cleanups and let the optimizer tighten them up? The current 7325 code seems pretty fragile; it will break on a cleanup within any 7326 non-conditional nesting. But any such nesting would be broken, anyway; 7327 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct 7328 and continues out of it. We can do that at the RTL level, though, so 7329 having an optimizer to tighten up try/finally regions would be a Good 7330 Thing. */ 7331 7332 static enum gimplify_status 7333 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p) 7334 { 7335 gimple_stmt_iterator iter; 7336 gimple_seq body_sequence = NULL; 7337 7338 tree temp = voidify_wrapper_expr (*expr_p, NULL); 7339 7340 /* We only care about the number of conditions between the innermost 7341 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and 7342 any cleanups collected outside the CLEANUP_POINT_EXPR. */ 7343 int old_conds = gimplify_ctxp->conditions; 7344 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups; 7345 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr; 7346 gimplify_ctxp->conditions = 0; 7347 gimplify_ctxp->conditional_cleanups = NULL; 7348 gimplify_ctxp->in_cleanup_point_expr = true; 7349 7350 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence); 7351 7352 gimplify_ctxp->conditions = old_conds; 7353 gimplify_ctxp->conditional_cleanups = old_cleanups; 7354 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr; 7355 7356 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); ) 7357 { 7358 gimple *wce = gsi_stmt (iter); 7359 7360 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR) 7361 { 7362 if (gsi_one_before_end_p (iter)) 7363 { 7364 /* Note that gsi_insert_seq_before and gsi_remove do not 7365 scan operands, unlike some other sequence mutators. */ 7366 if (!gimple_wce_cleanup_eh_only (wce)) 7367 gsi_insert_seq_before_without_update (&iter, 7368 gimple_wce_cleanup (wce), 7369 GSI_SAME_STMT); 7370 gsi_remove (&iter, true); 7371 break; 7372 } 7373 else 7374 { 7375 gtry *gtry; 7376 gimple_seq seq; 7377 enum gimple_try_flags kind; 7378 7379 if (gimple_wce_cleanup_eh_only (wce)) 7380 kind = GIMPLE_TRY_CATCH; 7381 else 7382 kind = GIMPLE_TRY_FINALLY; 7383 seq = gsi_split_seq_after (iter); 7384 7385 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind); 7386 /* Do not use gsi_replace here, as it may scan operands. 7387 We want to do a simple structural modification only. */ 7388 gsi_set_stmt (&iter, gtry); 7389 iter = gsi_start (gtry->eval); 7390 } 7391 } 7392 else 7393 gsi_next (&iter); 7394 } 7395 7396 gimplify_seq_add_seq (pre_p, body_sequence); 7397 if (temp) 7398 { 7399 *expr_p = temp; 7400 return GS_OK; 7401 } 7402 else 7403 { 7404 *expr_p = NULL; 7405 return GS_ALL_DONE; 7406 } 7407 } 7408 7409 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP 7410 is the cleanup action required. EH_ONLY is true if the cleanup should 7411 only be executed if an exception is thrown, not on normal exit. 7412 If FORCE_UNCOND is true perform the cleanup unconditionally; this is 7413 only valid for clobbers. */ 7414 7415 static void 7416 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p, 7417 bool force_uncond = false) 7418 { 7419 gimple *wce; 7420 gimple_seq cleanup_stmts = NULL; 7421 7422 /* Errors can result in improperly nested cleanups. Which results in 7423 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */ 7424 if (seen_error ()) 7425 return; 7426 7427 if (gimple_conditional_context ()) 7428 { 7429 /* If we're in a conditional context, this is more complex. We only 7430 want to run the cleanup if we actually ran the initialization that 7431 necessitates it, but we want to run it after the end of the 7432 conditional context. So we wrap the try/finally around the 7433 condition and use a flag to determine whether or not to actually 7434 run the destructor. Thus 7435 7436 test ? f(A()) : 0 7437 7438 becomes (approximately) 7439 7440 flag = 0; 7441 try { 7442 if (test) { A::A(temp); flag = 1; val = f(temp); } 7443 else { val = 0; } 7444 } finally { 7445 if (flag) A::~A(temp); 7446 } 7447 val 7448 */ 7449 if (force_uncond) 7450 { 7451 gimplify_stmt (&cleanup, &cleanup_stmts); 7452 wce = gimple_build_wce (cleanup_stmts); 7453 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce); 7454 } 7455 else 7456 { 7457 tree flag = create_tmp_var (boolean_type_node, "cleanup"); 7458 gassign *ffalse = gimple_build_assign (flag, boolean_false_node); 7459 gassign *ftrue = gimple_build_assign (flag, boolean_true_node); 7460 7461 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL); 7462 gimplify_stmt (&cleanup, &cleanup_stmts); 7463 wce = gimple_build_wce (cleanup_stmts); 7464 gimple_wce_set_cleanup_eh_only (wce, eh_only); 7465 7466 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse); 7467 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce); 7468 gimplify_seq_add_stmt (pre_p, ftrue); 7469 7470 /* Because of this manipulation, and the EH edges that jump 7471 threading cannot redirect, the temporary (VAR) will appear 7472 to be used uninitialized. Don't warn. */ 7473 suppress_warning (var, OPT_Wuninitialized); 7474 } 7475 } 7476 else 7477 { 7478 gimplify_stmt (&cleanup, &cleanup_stmts); 7479 wce = gimple_build_wce (cleanup_stmts); 7480 gimple_wce_set_cleanup_eh_only (wce, eh_only); 7481 gimplify_seq_add_stmt (pre_p, wce); 7482 } 7483 } 7484 7485 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */ 7486 7487 static enum gimplify_status 7488 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 7489 { 7490 tree targ = *expr_p; 7491 tree temp = TARGET_EXPR_SLOT (targ); 7492 tree init = TARGET_EXPR_INITIAL (targ); 7493 enum gimplify_status ret; 7494 7495 bool unpoison_empty_seq = false; 7496 gimple_stmt_iterator unpoison_it; 7497 7498 if (init) 7499 { 7500 gimple_seq init_pre_p = NULL; 7501 7502 /* TARGET_EXPR temps aren't part of the enclosing block, so add it 7503 to the temps list. Handle also variable length TARGET_EXPRs. */ 7504 if (!poly_int_tree_p (DECL_SIZE (temp))) 7505 { 7506 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp))) 7507 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p); 7508 /* FIXME: this is correct only when the size of the type does 7509 not depend on expressions evaluated in init. */ 7510 gimplify_vla_decl (temp, &init_pre_p); 7511 } 7512 else 7513 { 7514 /* Save location where we need to place unpoisoning. It's possible 7515 that a variable will be converted to needs_to_live_in_memory. */ 7516 unpoison_it = gsi_last (*pre_p); 7517 unpoison_empty_seq = gsi_end_p (unpoison_it); 7518 7519 gimple_add_tmp_var (temp); 7520 } 7521 7522 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the 7523 expression is supposed to initialize the slot. */ 7524 if (VOID_TYPE_P (TREE_TYPE (init))) 7525 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt, 7526 fb_none); 7527 else 7528 { 7529 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); 7530 init = init_expr; 7531 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt, 7532 fb_none); 7533 init = NULL; 7534 ggc_free (init_expr); 7535 } 7536 if (ret == GS_ERROR) 7537 { 7538 /* PR c++/28266 Make sure this is expanded only once. */ 7539 TARGET_EXPR_INITIAL (targ) = NULL_TREE; 7540 return GS_ERROR; 7541 } 7542 7543 if (init) 7544 gimplify_and_add (init, &init_pre_p); 7545 7546 /* Add a clobber for the temporary going out of scope, like 7547 gimplify_bind_expr. But only if we did not promote the 7548 temporary to static storage. */ 7549 if (gimplify_ctxp->in_cleanup_point_expr 7550 && !TREE_STATIC (temp) 7551 && needs_to_live_in_memory (temp)) 7552 { 7553 if (flag_stack_reuse == SR_ALL) 7554 { 7555 tree clobber = build_clobber (TREE_TYPE (temp), 7556 CLOBBER_STORAGE_END); 7557 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); 7558 gimple_push_cleanup (temp, clobber, false, pre_p, true); 7559 } 7560 if (asan_poisoned_variables 7561 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT 7562 && !TREE_STATIC (temp) 7563 && dbg_cnt (asan_use_after_scope) 7564 && !gimplify_omp_ctxp) 7565 { 7566 tree asan_cleanup = build_asan_poison_call_expr (temp); 7567 if (asan_cleanup) 7568 { 7569 if (unpoison_empty_seq) 7570 unpoison_it = gsi_start (*pre_p); 7571 7572 asan_poison_variable (temp, false, &unpoison_it, 7573 unpoison_empty_seq); 7574 gimple_push_cleanup (temp, asan_cleanup, false, pre_p); 7575 } 7576 } 7577 } 7578 7579 gimple_seq_add_seq (pre_p, init_pre_p); 7580 7581 /* If needed, push the cleanup for the temp. */ 7582 if (TARGET_EXPR_CLEANUP (targ)) 7583 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), 7584 CLEANUP_EH_ONLY (targ), pre_p); 7585 7586 /* Only expand this once. */ 7587 TREE_OPERAND (targ, 3) = init; 7588 TARGET_EXPR_INITIAL (targ) = NULL_TREE; 7589 } 7590 else 7591 /* We should have expanded this before. */ 7592 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp)); 7593 7594 *expr_p = temp; 7595 return GS_OK; 7596 } 7597 7598 /* Gimplification of expression trees. */ 7599 7600 /* Gimplify an expression which appears at statement context. The 7601 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is 7602 NULL, a new sequence is allocated. 7603 7604 Return true if we actually added a statement to the queue. */ 7605 7606 bool 7607 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p) 7608 { 7609 gimple_seq_node last; 7610 7611 last = gimple_seq_last (*seq_p); 7612 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none); 7613 return last != gimple_seq_last (*seq_p); 7614 } 7615 7616 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels 7617 to CTX. If entries already exist, force them to be some flavor of private. 7618 If there is no enclosing parallel, do nothing. */ 7619 7620 void 7621 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl) 7622 { 7623 splay_tree_node n; 7624 7625 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE) 7626 return; 7627 7628 do 7629 { 7630 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7631 if (n != NULL) 7632 { 7633 if (n->value & GOVD_SHARED) 7634 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN); 7635 else if (n->value & GOVD_MAP) 7636 n->value |= GOVD_MAP_TO_ONLY; 7637 else 7638 return; 7639 } 7640 else if ((ctx->region_type & ORT_TARGET) != 0) 7641 { 7642 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE) 7643 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); 7644 else 7645 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY); 7646 } 7647 else if (ctx->region_type != ORT_WORKSHARE 7648 && ctx->region_type != ORT_TASKGROUP 7649 && ctx->region_type != ORT_SIMD 7650 && ctx->region_type != ORT_ACC 7651 && !(ctx->region_type & ORT_TARGET_DATA)) 7652 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); 7653 7654 ctx = ctx->outer_context; 7655 } 7656 while (ctx); 7657 } 7658 7659 /* Similarly for each of the type sizes of TYPE. */ 7660 7661 static void 7662 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type) 7663 { 7664 if (type == NULL || type == error_mark_node) 7665 return; 7666 type = TYPE_MAIN_VARIANT (type); 7667 7668 if (ctx->privatized_types->add (type)) 7669 return; 7670 7671 switch (TREE_CODE (type)) 7672 { 7673 case INTEGER_TYPE: 7674 case ENUMERAL_TYPE: 7675 case BOOLEAN_TYPE: 7676 case REAL_TYPE: 7677 case FIXED_POINT_TYPE: 7678 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type)); 7679 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type)); 7680 break; 7681 7682 case ARRAY_TYPE: 7683 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 7684 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type)); 7685 break; 7686 7687 case RECORD_TYPE: 7688 case UNION_TYPE: 7689 case QUAL_UNION_TYPE: 7690 { 7691 tree field; 7692 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 7693 if (TREE_CODE (field) == FIELD_DECL) 7694 { 7695 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field)); 7696 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field)); 7697 } 7698 } 7699 break; 7700 7701 case POINTER_TYPE: 7702 case REFERENCE_TYPE: 7703 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 7704 break; 7705 7706 default: 7707 break; 7708 } 7709 7710 omp_firstprivatize_variable (ctx, TYPE_SIZE (type)); 7711 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type)); 7712 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type); 7713 } 7714 7715 /* Add an entry for DECL in the OMP context CTX with FLAGS. */ 7716 7717 static void 7718 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) 7719 { 7720 splay_tree_node n; 7721 unsigned int nflags; 7722 tree t; 7723 7724 if (error_operand_p (decl) || ctx->region_type == ORT_NONE) 7725 return; 7726 7727 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means 7728 there are constructors involved somewhere. Exception is a shared clause, 7729 there is nothing privatized in that case. */ 7730 if ((flags & GOVD_SHARED) == 0 7731 && (TREE_ADDRESSABLE (TREE_TYPE (decl)) 7732 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) 7733 flags |= GOVD_SEEN; 7734 7735 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7736 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 7737 { 7738 /* We shouldn't be re-adding the decl with the same data 7739 sharing class. */ 7740 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0); 7741 nflags = n->value | flags; 7742 /* The only combination of data sharing classes we should see is 7743 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits 7744 reduction variables to be used in data sharing clauses. */ 7745 gcc_assert ((ctx->region_type & ORT_ACC) != 0 7746 || ((nflags & GOVD_DATA_SHARE_CLASS) 7747 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)) 7748 || (flags & GOVD_DATA_SHARE_CLASS) == 0); 7749 n->value = nflags; 7750 return; 7751 } 7752 7753 /* When adding a variable-sized variable, we have to handle all sorts 7754 of additional bits of data: the pointer replacement variable, and 7755 the parameters of the type. */ 7756 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 7757 { 7758 /* Add the pointer replacement variable as PRIVATE if the variable 7759 replacement is private, else FIRSTPRIVATE since we'll need the 7760 address of the original variable either for SHARED, or for the 7761 copy into or out of the context. */ 7762 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP) 7763 { 7764 if (flags & GOVD_MAP) 7765 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT; 7766 else if (flags & GOVD_PRIVATE) 7767 nflags = GOVD_PRIVATE; 7768 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0 7769 && (flags & GOVD_FIRSTPRIVATE)) 7770 || (ctx->region_type == ORT_TARGET_DATA 7771 && (flags & GOVD_DATA_SHARE_CLASS) == 0)) 7772 nflags = GOVD_PRIVATE | GOVD_EXPLICIT; 7773 else 7774 nflags = GOVD_FIRSTPRIVATE; 7775 nflags |= flags & GOVD_SEEN; 7776 t = DECL_VALUE_EXPR (decl); 7777 gcc_assert (INDIRECT_REF_P (t)); 7778 t = TREE_OPERAND (t, 0); 7779 gcc_assert (DECL_P (t)); 7780 omp_add_variable (ctx, t, nflags); 7781 } 7782 7783 /* Add all of the variable and type parameters (which should have 7784 been gimplified to a formal temporary) as FIRSTPRIVATE. */ 7785 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl)); 7786 omp_firstprivatize_variable (ctx, DECL_SIZE (decl)); 7787 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 7788 7789 /* The variable-sized variable itself is never SHARED, only some form 7790 of PRIVATE. The sharing would take place via the pointer variable 7791 which we remapped above. */ 7792 if (flags & GOVD_SHARED) 7793 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE 7794 | (flags & (GOVD_SEEN | GOVD_EXPLICIT)); 7795 7796 /* We're going to make use of the TYPE_SIZE_UNIT at least in the 7797 alloca statement we generate for the variable, so make sure it 7798 is available. This isn't automatically needed for the SHARED 7799 case, since we won't be allocating local storage then. 7800 For local variables TYPE_SIZE_UNIT might not be gimplified yet, 7801 in this case omp_notice_variable will be called later 7802 on when it is gimplified. */ 7803 else if (! (flags & (GOVD_LOCAL | GOVD_MAP)) 7804 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl)))) 7805 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true); 7806 } 7807 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0 7808 && omp_privatize_by_reference (decl)) 7809 { 7810 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 7811 7812 /* Similar to the direct variable sized case above, we'll need the 7813 size of references being privatized. */ 7814 if ((flags & GOVD_SHARED) == 0) 7815 { 7816 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); 7817 if (t && DECL_P (t)) 7818 omp_notice_variable (ctx, t, true); 7819 } 7820 } 7821 7822 if (n != NULL) 7823 n->value |= flags; 7824 else 7825 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags); 7826 7827 /* For reductions clauses in OpenACC loop directives, by default create a 7828 copy clause on the enclosing parallel construct for carrying back the 7829 results. */ 7830 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION)) 7831 { 7832 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context; 7833 while (outer_ctx) 7834 { 7835 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl); 7836 if (n != NULL) 7837 { 7838 /* Ignore local variables and explicitly declared clauses. */ 7839 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT)) 7840 break; 7841 else if (outer_ctx->region_type == ORT_ACC_KERNELS) 7842 { 7843 /* According to the OpenACC spec, such a reduction variable 7844 should already have a copy map on a kernels construct, 7845 verify that here. */ 7846 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE) 7847 && (n->value & GOVD_MAP)); 7848 } 7849 else if (outer_ctx->region_type == ORT_ACC_PARALLEL) 7850 { 7851 /* Remove firstprivate and make it a copy map. */ 7852 n->value &= ~GOVD_FIRSTPRIVATE; 7853 n->value |= GOVD_MAP; 7854 } 7855 } 7856 else if (outer_ctx->region_type == ORT_ACC_PARALLEL) 7857 { 7858 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl, 7859 GOVD_MAP | GOVD_SEEN); 7860 break; 7861 } 7862 outer_ctx = outer_ctx->outer_context; 7863 } 7864 } 7865 } 7866 7867 /* Notice a threadprivate variable DECL used in OMP context CTX. 7868 This just prints out diagnostics about threadprivate variable uses 7869 in untied tasks. If DECL2 is non-NULL, prevent this warning 7870 on that variable. */ 7871 7872 static bool 7873 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl, 7874 tree decl2) 7875 { 7876 splay_tree_node n; 7877 struct gimplify_omp_ctx *octx; 7878 7879 for (octx = ctx; octx; octx = octx->outer_context) 7880 if ((octx->region_type & ORT_TARGET) != 0 7881 || octx->order_concurrent) 7882 { 7883 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl); 7884 if (n == NULL) 7885 { 7886 if (octx->order_concurrent) 7887 { 7888 error ("threadprivate variable %qE used in a region with" 7889 " %<order(concurrent)%> clause", DECL_NAME (decl)); 7890 inform (octx->location, "enclosing region"); 7891 } 7892 else 7893 { 7894 error ("threadprivate variable %qE used in target region", 7895 DECL_NAME (decl)); 7896 inform (octx->location, "enclosing target region"); 7897 } 7898 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0); 7899 } 7900 if (decl2) 7901 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0); 7902 } 7903 7904 if (ctx->region_type != ORT_UNTIED_TASK) 7905 return false; 7906 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7907 if (n == NULL) 7908 { 7909 error ("threadprivate variable %qE used in untied task", 7910 DECL_NAME (decl)); 7911 inform (ctx->location, "enclosing task"); 7912 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0); 7913 } 7914 if (decl2) 7915 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0); 7916 return false; 7917 } 7918 7919 /* Return true if global var DECL is device resident. */ 7920 7921 static bool 7922 device_resident_p (tree decl) 7923 { 7924 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl)); 7925 7926 if (!attr) 7927 return false; 7928 7929 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t)) 7930 { 7931 tree c = TREE_VALUE (t); 7932 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT) 7933 return true; 7934 } 7935 7936 return false; 7937 } 7938 7939 /* Return true if DECL has an ACC DECLARE attribute. */ 7940 7941 static bool 7942 is_oacc_declared (tree decl) 7943 { 7944 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl; 7945 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t)); 7946 return declared != NULL_TREE; 7947 } 7948 7949 /* Determine outer default flags for DECL mentioned in an OMP region 7950 but not declared in an enclosing clause. 7951 7952 ??? Some compiler-generated variables (like SAVE_EXPRs) could be 7953 remapped firstprivate instead of shared. To some extent this is 7954 addressed in omp_firstprivatize_type_sizes, but not 7955 effectively. */ 7956 7957 static unsigned 7958 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl, 7959 bool in_code, unsigned flags) 7960 { 7961 enum omp_clause_default_kind default_kind = ctx->default_kind; 7962 enum omp_clause_default_kind kind; 7963 7964 kind = lang_hooks.decls.omp_predetermined_sharing (decl); 7965 if (ctx->region_type & ORT_TASK) 7966 { 7967 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH); 7968 7969 /* The event-handle specified by a detach clause should always be firstprivate, 7970 regardless of the current default. */ 7971 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl) 7972 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 7973 } 7974 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 7975 default_kind = kind; 7976 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl)) 7977 default_kind = OMP_CLAUSE_DEFAULT_SHARED; 7978 /* For C/C++ default({,first}private), variables with static storage duration 7979 declared in a namespace or global scope and referenced in construct 7980 must be explicitly specified, i.e. acts as default(none). */ 7981 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE 7982 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE) 7983 && VAR_P (decl) 7984 && is_global_var (decl) 7985 && (DECL_FILE_SCOPE_P (decl) 7986 || (DECL_CONTEXT (decl) 7987 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)) 7988 && !lang_GNU_Fortran ()) 7989 default_kind = OMP_CLAUSE_DEFAULT_NONE; 7990 7991 switch (default_kind) 7992 { 7993 case OMP_CLAUSE_DEFAULT_NONE: 7994 { 7995 const char *rtype; 7996 7997 if (ctx->region_type & ORT_PARALLEL) 7998 rtype = "parallel"; 7999 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP) 8000 rtype = "taskloop"; 8001 else if (ctx->region_type & ORT_TASK) 8002 rtype = "task"; 8003 else if (ctx->region_type & ORT_TEAMS) 8004 rtype = "teams"; 8005 else 8006 gcc_unreachable (); 8007 8008 error ("%qE not specified in enclosing %qs", 8009 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype); 8010 inform (ctx->location, "enclosing %qs", rtype); 8011 } 8012 /* FALLTHRU */ 8013 case OMP_CLAUSE_DEFAULT_SHARED: 8014 flags |= GOVD_SHARED; 8015 break; 8016 case OMP_CLAUSE_DEFAULT_PRIVATE: 8017 flags |= GOVD_PRIVATE; 8018 break; 8019 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE: 8020 flags |= GOVD_FIRSTPRIVATE; 8021 break; 8022 case OMP_CLAUSE_DEFAULT_UNSPECIFIED: 8023 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */ 8024 gcc_assert ((ctx->region_type & ORT_TASK) != 0); 8025 if (struct gimplify_omp_ctx *octx = ctx->outer_context) 8026 { 8027 omp_notice_variable (octx, decl, in_code); 8028 for (; octx; octx = octx->outer_context) 8029 { 8030 splay_tree_node n2; 8031 8032 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl); 8033 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0 8034 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0)) 8035 continue; 8036 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED) 8037 { 8038 flags |= GOVD_FIRSTPRIVATE; 8039 goto found_outer; 8040 } 8041 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0) 8042 { 8043 flags |= GOVD_SHARED; 8044 goto found_outer; 8045 } 8046 } 8047 } 8048 8049 if (TREE_CODE (decl) == PARM_DECL 8050 || (!is_global_var (decl) 8051 && DECL_CONTEXT (decl) == current_function_decl)) 8052 flags |= GOVD_FIRSTPRIVATE; 8053 else 8054 flags |= GOVD_SHARED; 8055 found_outer: 8056 break; 8057 8058 default: 8059 gcc_unreachable (); 8060 } 8061 8062 return flags; 8063 } 8064 8065 /* Return string name for types of OpenACC constructs from ORT_* values. */ 8066 8067 static const char * 8068 oacc_region_type_name (enum omp_region_type region_type) 8069 { 8070 switch (region_type) 8071 { 8072 case ORT_ACC_DATA: 8073 return "data"; 8074 case ORT_ACC_PARALLEL: 8075 return "parallel"; 8076 case ORT_ACC_KERNELS: 8077 return "kernels"; 8078 case ORT_ACC_SERIAL: 8079 return "serial"; 8080 default: 8081 gcc_unreachable (); 8082 } 8083 } 8084 8085 /* Determine outer default flags for DECL mentioned in an OACC region 8086 but not declared in an enclosing clause. */ 8087 8088 static unsigned 8089 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) 8090 { 8091 struct gimplify_omp_ctx *ctx_default = ctx; 8092 /* If no 'default' clause appears on this compute construct... */ 8093 if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED) 8094 { 8095 /* ..., see if one appears on a lexically containing 'data' 8096 construct. */ 8097 while ((ctx_default = ctx_default->outer_context)) 8098 { 8099 if (ctx_default->region_type == ORT_ACC_DATA 8100 && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED) 8101 break; 8102 } 8103 /* If not, reset. */ 8104 if (!ctx_default) 8105 ctx_default = ctx; 8106 } 8107 8108 bool on_device = false; 8109 bool is_private = false; 8110 bool declared = is_oacc_declared (decl); 8111 tree type = TREE_TYPE (decl); 8112 8113 if (omp_privatize_by_reference (decl)) 8114 type = TREE_TYPE (type); 8115 8116 /* For Fortran COMMON blocks, only used variables in those blocks are 8117 transfered and remapped. The block itself will have a private clause to 8118 avoid transfering the data twice. 8119 The hook evaluates to false by default. For a variable in Fortran's COMMON 8120 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only 8121 the variables in such a COMMON/EQUIVALENCE block shall be privatized not 8122 the whole block. For C++ and Fortran, it can also be true under certain 8123 other conditions, if DECL_HAS_VALUE_EXPR. */ 8124 if (RECORD_OR_UNION_TYPE_P (type)) 8125 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false); 8126 8127 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0 8128 && is_global_var (decl) 8129 && device_resident_p (decl) 8130 && !is_private) 8131 { 8132 on_device = true; 8133 flags |= GOVD_MAP_TO_ONLY; 8134 } 8135 8136 switch (ctx->region_type) 8137 { 8138 case ORT_ACC_KERNELS: 8139 if (is_private) 8140 flags |= GOVD_FIRSTPRIVATE; 8141 else if (AGGREGATE_TYPE_P (type)) 8142 { 8143 /* Aggregates default to 'present_or_copy', or 'present'. */ 8144 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT) 8145 flags |= GOVD_MAP; 8146 else 8147 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT; 8148 } 8149 else 8150 /* Scalars default to 'copy'. */ 8151 flags |= GOVD_MAP | GOVD_MAP_FORCE; 8152 8153 break; 8154 8155 case ORT_ACC_PARALLEL: 8156 case ORT_ACC_SERIAL: 8157 if (is_private) 8158 flags |= GOVD_FIRSTPRIVATE; 8159 else if (on_device || declared) 8160 flags |= GOVD_MAP; 8161 else if (AGGREGATE_TYPE_P (type)) 8162 { 8163 /* Aggregates default to 'present_or_copy', or 'present'. */ 8164 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT) 8165 flags |= GOVD_MAP; 8166 else 8167 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT; 8168 } 8169 else 8170 /* Scalars default to 'firstprivate'. */ 8171 flags |= GOVD_FIRSTPRIVATE; 8172 8173 break; 8174 8175 default: 8176 gcc_unreachable (); 8177 } 8178 8179 if (DECL_ARTIFICIAL (decl)) 8180 ; /* We can get compiler-generated decls, and should not complain 8181 about them. */ 8182 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE) 8183 { 8184 error ("%qE not specified in enclosing OpenACC %qs construct", 8185 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), 8186 oacc_region_type_name (ctx->region_type)); 8187 if (ctx_default != ctx) 8188 inform (ctx->location, "enclosing OpenACC %qs construct and", 8189 oacc_region_type_name (ctx->region_type)); 8190 inform (ctx_default->location, 8191 "enclosing OpenACC %qs construct with %qs clause", 8192 oacc_region_type_name (ctx_default->region_type), 8193 "default(none)"); 8194 } 8195 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT) 8196 ; /* Handled above. */ 8197 else 8198 gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED); 8199 8200 return flags; 8201 } 8202 8203 /* Record the fact that DECL was used within the OMP context CTX. 8204 IN_CODE is true when real code uses DECL, and false when we should 8205 merely emit default(none) errors. Return true if DECL is going to 8206 be remapped and thus DECL shouldn't be gimplified into its 8207 DECL_VALUE_EXPR (if any). */ 8208 8209 static bool 8210 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) 8211 { 8212 splay_tree_node n; 8213 unsigned flags = in_code ? GOVD_SEEN : 0; 8214 bool ret = false, shared; 8215 8216 if (error_operand_p (decl)) 8217 return false; 8218 8219 if (DECL_ARTIFICIAL (decl)) 8220 { 8221 tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl)); 8222 if (attr) 8223 decl = TREE_VALUE (TREE_VALUE (attr)); 8224 } 8225 8226 if (ctx->region_type == ORT_NONE) 8227 return lang_hooks.decls.omp_disregard_value_expr (decl, false); 8228 8229 if (is_global_var (decl)) 8230 { 8231 /* Threadprivate variables are predetermined. */ 8232 if (DECL_THREAD_LOCAL_P (decl)) 8233 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE); 8234 8235 if (DECL_HAS_VALUE_EXPR_P (decl)) 8236 { 8237 if (ctx->region_type & ORT_ACC) 8238 /* For OpenACC, defer expansion of value to avoid transfering 8239 privatized common block data instead of im-/explicitly transfered 8240 variables which are in common blocks. */ 8241 ; 8242 else 8243 { 8244 tree value = get_base_address (DECL_VALUE_EXPR (decl)); 8245 8246 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) 8247 return omp_notice_threadprivate_variable (ctx, decl, value); 8248 } 8249 } 8250 8251 if (gimplify_omp_ctxp->outer_context == NULL 8252 && VAR_P (decl) 8253 && oacc_get_fn_attrib (current_function_decl)) 8254 { 8255 location_t loc = DECL_SOURCE_LOCATION (decl); 8256 8257 if (lookup_attribute ("omp declare target link", 8258 DECL_ATTRIBUTES (decl))) 8259 { 8260 error_at (loc, 8261 "%qE with %<link%> clause used in %<routine%> function", 8262 DECL_NAME (decl)); 8263 return false; 8264 } 8265 else if (!lookup_attribute ("omp declare target", 8266 DECL_ATTRIBUTES (decl))) 8267 { 8268 error_at (loc, 8269 "%qE requires a %<declare%> directive for use " 8270 "in a %<routine%> function", DECL_NAME (decl)); 8271 return false; 8272 } 8273 } 8274 } 8275 8276 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 8277 if ((ctx->region_type & ORT_TARGET) != 0) 8278 { 8279 if (n == NULL) 8280 { 8281 unsigned nflags = flags; 8282 if ((ctx->region_type & ORT_ACC) == 0) 8283 { 8284 bool is_declare_target = false; 8285 if (is_global_var (decl) 8286 && varpool_node::get_create (decl)->offloadable) 8287 { 8288 struct gimplify_omp_ctx *octx; 8289 for (octx = ctx->outer_context; 8290 octx; octx = octx->outer_context) 8291 { 8292 n = splay_tree_lookup (octx->variables, 8293 (splay_tree_key)decl); 8294 if (n 8295 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED 8296 && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 8297 break; 8298 } 8299 is_declare_target = octx == NULL; 8300 } 8301 if (!is_declare_target) 8302 { 8303 int gdmk; 8304 enum omp_clause_defaultmap_kind kind; 8305 if (lang_hooks.decls.omp_allocatable_p (decl)) 8306 gdmk = GDMK_ALLOCATABLE; 8307 else if (lang_hooks.decls.omp_scalar_target_p (decl)) 8308 gdmk = GDMK_SCALAR_TARGET; 8309 else if (lang_hooks.decls.omp_scalar_p (decl, false)) 8310 gdmk = GDMK_SCALAR; 8311 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 8312 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 8313 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) 8314 == POINTER_TYPE))) 8315 gdmk = GDMK_POINTER; 8316 else 8317 gdmk = GDMK_AGGREGATE; 8318 kind = lang_hooks.decls.omp_predetermined_mapping (decl); 8319 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) 8320 { 8321 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE) 8322 nflags |= GOVD_FIRSTPRIVATE; 8323 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO) 8324 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY; 8325 else 8326 gcc_unreachable (); 8327 } 8328 else if (ctx->defaultmap[gdmk] == 0) 8329 { 8330 tree d = lang_hooks.decls.omp_report_decl (decl); 8331 error ("%qE not specified in enclosing %<target%>", 8332 DECL_NAME (d)); 8333 inform (ctx->location, "enclosing %<target%>"); 8334 } 8335 else if (ctx->defaultmap[gdmk] 8336 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE)) 8337 nflags |= ctx->defaultmap[gdmk]; 8338 else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT) 8339 { 8340 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP); 8341 nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY; 8342 } 8343 else 8344 { 8345 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP); 8346 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP; 8347 } 8348 } 8349 } 8350 8351 struct gimplify_omp_ctx *octx = ctx->outer_context; 8352 if ((ctx->region_type & ORT_ACC) && octx) 8353 { 8354 /* Look in outer OpenACC contexts, to see if there's a 8355 data attribute for this variable. */ 8356 omp_notice_variable (octx, decl, in_code); 8357 8358 for (; octx; octx = octx->outer_context) 8359 { 8360 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET))) 8361 break; 8362 splay_tree_node n2 8363 = splay_tree_lookup (octx->variables, 8364 (splay_tree_key) decl); 8365 if (n2) 8366 { 8367 if (octx->region_type == ORT_ACC_HOST_DATA) 8368 error ("variable %qE declared in enclosing " 8369 "%<host_data%> region", DECL_NAME (decl)); 8370 nflags |= GOVD_MAP; 8371 if (octx->region_type == ORT_ACC_DATA 8372 && (n2->value & GOVD_MAP_0LEN_ARRAY)) 8373 nflags |= GOVD_MAP_0LEN_ARRAY; 8374 goto found_outer; 8375 } 8376 } 8377 } 8378 8379 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY 8380 | GOVD_MAP_ALLOC_ONLY)) == flags) 8381 { 8382 tree type = TREE_TYPE (decl); 8383 8384 if (gimplify_omp_ctxp->target_firstprivatize_array_bases 8385 && omp_privatize_by_reference (decl)) 8386 type = TREE_TYPE (type); 8387 if (!omp_mappable_type (type)) 8388 { 8389 error ("%qD referenced in target region does not have " 8390 "a mappable type", decl); 8391 nflags |= GOVD_MAP | GOVD_EXPLICIT; 8392 } 8393 else 8394 { 8395 if ((ctx->region_type & ORT_ACC) != 0) 8396 nflags = oacc_default_clause (ctx, decl, flags); 8397 else 8398 nflags |= GOVD_MAP; 8399 } 8400 } 8401 found_outer: 8402 omp_add_variable (ctx, decl, nflags); 8403 if (ctx->region_type & ORT_ACC) 8404 /* For OpenACC, as remarked above, defer expansion. */ 8405 shared = false; 8406 else 8407 shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0; 8408 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8409 } 8410 else 8411 { 8412 if (ctx->region_type & ORT_ACC) 8413 /* For OpenACC, as remarked above, defer expansion. */ 8414 shared = false; 8415 else 8416 shared = ((n->value | flags) 8417 & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0; 8418 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8419 /* If nothing changed, there's nothing left to do. */ 8420 if ((n->value & flags) == flags) 8421 return ret; 8422 flags |= n->value; 8423 n->value = flags; 8424 } 8425 goto do_outer; 8426 } 8427 8428 if (n == NULL) 8429 { 8430 if (ctx->region_type == ORT_WORKSHARE 8431 || ctx->region_type == ORT_TASKGROUP 8432 || ctx->region_type == ORT_SIMD 8433 || ctx->region_type == ORT_ACC 8434 || (ctx->region_type & ORT_TARGET_DATA) != 0) 8435 goto do_outer; 8436 8437 flags = omp_default_clause (ctx, decl, in_code, flags); 8438 8439 if ((flags & GOVD_PRIVATE) 8440 && lang_hooks.decls.omp_private_outer_ref (decl)) 8441 flags |= GOVD_PRIVATE_OUTER_REF; 8442 8443 omp_add_variable (ctx, decl, flags); 8444 8445 shared = (flags & GOVD_SHARED) != 0; 8446 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8447 goto do_outer; 8448 } 8449 8450 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd 8451 lb, b or incr expressions, those shouldn't be turned into simd arrays. */ 8452 if (ctx->region_type == ORT_SIMD 8453 && ctx->in_for_exprs 8454 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT)) 8455 == GOVD_PRIVATE)) 8456 flags &= ~GOVD_SEEN; 8457 8458 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0 8459 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN 8460 && DECL_SIZE (decl)) 8461 { 8462 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 8463 { 8464 splay_tree_node n2; 8465 tree t = DECL_VALUE_EXPR (decl); 8466 gcc_assert (INDIRECT_REF_P (t)); 8467 t = TREE_OPERAND (t, 0); 8468 gcc_assert (DECL_P (t)); 8469 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 8470 n2->value |= GOVD_SEEN; 8471 } 8472 else if (omp_privatize_by_reference (decl) 8473 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))) 8474 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))) 8475 != INTEGER_CST)) 8476 { 8477 splay_tree_node n2; 8478 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); 8479 gcc_assert (DECL_P (t)); 8480 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 8481 if (n2) 8482 omp_notice_variable (ctx, t, true); 8483 } 8484 } 8485 8486 if (ctx->region_type & ORT_ACC) 8487 /* For OpenACC, as remarked above, defer expansion. */ 8488 shared = false; 8489 else 8490 shared = ((flags | n->value) & GOVD_SHARED) != 0; 8491 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8492 8493 /* If nothing changed, there's nothing left to do. */ 8494 if ((n->value & flags) == flags) 8495 return ret; 8496 flags |= n->value; 8497 n->value = flags; 8498 8499 do_outer: 8500 /* If the variable is private in the current context, then we don't 8501 need to propagate anything to an outer context. */ 8502 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF)) 8503 return ret; 8504 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8505 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8506 return ret; 8507 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE 8508 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8509 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8510 return ret; 8511 if (ctx->outer_context 8512 && omp_notice_variable (ctx->outer_context, decl, in_code)) 8513 return true; 8514 return ret; 8515 } 8516 8517 /* Verify that DECL is private within CTX. If there's specific information 8518 to the contrary in the innermost scope, generate an error. */ 8519 8520 static bool 8521 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd) 8522 { 8523 splay_tree_node n; 8524 8525 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 8526 if (n != NULL) 8527 { 8528 if (n->value & GOVD_SHARED) 8529 { 8530 if (ctx == gimplify_omp_ctxp) 8531 { 8532 if (simd) 8533 error ("iteration variable %qE is predetermined linear", 8534 DECL_NAME (decl)); 8535 else 8536 error ("iteration variable %qE should be private", 8537 DECL_NAME (decl)); 8538 n->value = GOVD_PRIVATE; 8539 return true; 8540 } 8541 else 8542 return false; 8543 } 8544 else if ((n->value & GOVD_EXPLICIT) != 0 8545 && (ctx == gimplify_omp_ctxp 8546 || (ctx->region_type == ORT_COMBINED_PARALLEL 8547 && gimplify_omp_ctxp->outer_context == ctx))) 8548 { 8549 if ((n->value & GOVD_FIRSTPRIVATE) != 0) 8550 error ("iteration variable %qE should not be firstprivate", 8551 DECL_NAME (decl)); 8552 else if ((n->value & GOVD_REDUCTION) != 0) 8553 error ("iteration variable %qE should not be reduction", 8554 DECL_NAME (decl)); 8555 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0) 8556 error ("iteration variable %qE should not be linear", 8557 DECL_NAME (decl)); 8558 } 8559 return (ctx == gimplify_omp_ctxp 8560 || (ctx->region_type == ORT_COMBINED_PARALLEL 8561 && gimplify_omp_ctxp->outer_context == ctx)); 8562 } 8563 8564 if (ctx->region_type != ORT_WORKSHARE 8565 && ctx->region_type != ORT_TASKGROUP 8566 && ctx->region_type != ORT_SIMD 8567 && ctx->region_type != ORT_ACC) 8568 return false; 8569 else if (ctx->outer_context) 8570 return omp_is_private (ctx->outer_context, decl, simd); 8571 return false; 8572 } 8573 8574 /* Return true if DECL is private within a parallel region 8575 that binds to the current construct's context or in parallel 8576 region's REDUCTION clause. */ 8577 8578 static bool 8579 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate) 8580 { 8581 splay_tree_node n; 8582 8583 do 8584 { 8585 ctx = ctx->outer_context; 8586 if (ctx == NULL) 8587 { 8588 if (is_global_var (decl)) 8589 return false; 8590 8591 /* References might be private, but might be shared too, 8592 when checking for copyprivate, assume they might be 8593 private, otherwise assume they might be shared. */ 8594 if (copyprivate) 8595 return true; 8596 8597 if (omp_privatize_by_reference (decl)) 8598 return false; 8599 8600 /* Treat C++ privatized non-static data members outside 8601 of the privatization the same. */ 8602 if (omp_member_access_dummy_var (decl)) 8603 return false; 8604 8605 return true; 8606 } 8607 8608 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 8609 8610 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0 8611 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)) 8612 { 8613 if ((ctx->region_type & ORT_TARGET_DATA) != 0 8614 || n == NULL 8615 || (n->value & GOVD_MAP) == 0) 8616 continue; 8617 return false; 8618 } 8619 8620 if (n != NULL) 8621 { 8622 if ((n->value & GOVD_LOCAL) != 0 8623 && omp_member_access_dummy_var (decl)) 8624 return false; 8625 return (n->value & GOVD_SHARED) == 0; 8626 } 8627 8628 if (ctx->region_type == ORT_WORKSHARE 8629 || ctx->region_type == ORT_TASKGROUP 8630 || ctx->region_type == ORT_SIMD 8631 || ctx->region_type == ORT_ACC) 8632 continue; 8633 8634 break; 8635 } 8636 while (1); 8637 return false; 8638 } 8639 8640 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */ 8641 8642 static tree 8643 find_decl_expr (tree *tp, int *walk_subtrees, void *data) 8644 { 8645 tree t = *tp; 8646 8647 /* If this node has been visited, unmark it and keep looking. */ 8648 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data) 8649 return t; 8650 8651 if (IS_TYPE_OR_DECL_P (t)) 8652 *walk_subtrees = 0; 8653 return NULL_TREE; 8654 } 8655 8656 8657 /* Gimplify the affinity clause but effectively ignore it. 8658 Generate: 8659 var = begin; 8660 if ((step > 1) ? var <= end : var > end) 8661 locatator_var_expr; */ 8662 8663 static void 8664 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p) 8665 { 8666 tree last_iter = NULL_TREE; 8667 tree last_bind = NULL_TREE; 8668 tree label = NULL_TREE; 8669 tree *last_body = NULL; 8670 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 8671 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) 8672 { 8673 tree t = OMP_CLAUSE_DECL (c); 8674 if (TREE_CODE (t) == TREE_LIST 8675 && TREE_PURPOSE (t) 8676 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 8677 { 8678 if (TREE_VALUE (t) == null_pointer_node) 8679 continue; 8680 if (TREE_PURPOSE (t) != last_iter) 8681 { 8682 if (last_bind) 8683 { 8684 append_to_statement_list (label, last_body); 8685 gimplify_and_add (last_bind, pre_p); 8686 last_bind = NULL_TREE; 8687 } 8688 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8689 { 8690 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL, 8691 is_gimple_val, fb_rvalue) == GS_ERROR 8692 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL, 8693 is_gimple_val, fb_rvalue) == GS_ERROR 8694 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL, 8695 is_gimple_val, fb_rvalue) == GS_ERROR 8696 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL, 8697 is_gimple_val, fb_rvalue) 8698 == GS_ERROR)) 8699 return; 8700 } 8701 last_iter = TREE_PURPOSE (t); 8702 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5); 8703 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 8704 NULL, block); 8705 last_body = &BIND_EXPR_BODY (last_bind); 8706 tree cond = NULL_TREE; 8707 location_t loc = OMP_CLAUSE_LOCATION (c); 8708 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8709 { 8710 tree var = TREE_VEC_ELT (it, 0); 8711 tree begin = TREE_VEC_ELT (it, 1); 8712 tree end = TREE_VEC_ELT (it, 2); 8713 tree step = TREE_VEC_ELT (it, 3); 8714 loc = DECL_SOURCE_LOCATION (var); 8715 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 8716 var, begin); 8717 append_to_statement_list_force (tem, last_body); 8718 8719 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8720 step, build_zero_cst (TREE_TYPE (step))); 8721 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node, 8722 var, end); 8723 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8724 var, end); 8725 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node, 8726 cond1, cond2, cond3); 8727 if (cond) 8728 cond = fold_build2_loc (loc, TRUTH_AND_EXPR, 8729 boolean_type_node, cond, cond1); 8730 else 8731 cond = cond1; 8732 } 8733 tree cont_label = create_artificial_label (loc); 8734 label = build1 (LABEL_EXPR, void_type_node, cont_label); 8735 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, 8736 void_node, 8737 build_and_jump (&cont_label)); 8738 append_to_statement_list_force (tem, last_body); 8739 } 8740 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR) 8741 { 8742 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0), 8743 last_body); 8744 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1); 8745 } 8746 if (error_operand_p (TREE_VALUE (t))) 8747 return; 8748 append_to_statement_list_force (TREE_VALUE (t), last_body); 8749 TREE_VALUE (t) = null_pointer_node; 8750 } 8751 else 8752 { 8753 if (last_bind) 8754 { 8755 append_to_statement_list (label, last_body); 8756 gimplify_and_add (last_bind, pre_p); 8757 last_bind = NULL_TREE; 8758 } 8759 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 8760 { 8761 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 8762 NULL, is_gimple_val, fb_rvalue); 8763 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 8764 } 8765 if (error_operand_p (OMP_CLAUSE_DECL (c))) 8766 return; 8767 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 8768 is_gimple_lvalue, fb_lvalue) == GS_ERROR) 8769 return; 8770 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p); 8771 } 8772 } 8773 if (last_bind) 8774 { 8775 append_to_statement_list (label, last_body); 8776 gimplify_and_add (last_bind, pre_p); 8777 } 8778 return; 8779 } 8780 8781 /* If *LIST_P contains any OpenMP depend clauses with iterators, 8782 lower all the depend clauses by populating corresponding depend 8783 array. Returns 0 if there are no such depend clauses, or 8784 2 if all depend clauses should be removed, 1 otherwise. */ 8785 8786 static int 8787 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p) 8788 { 8789 tree c; 8790 gimple *g; 8791 size_t n[5] = { 0, 0, 0, 0, 0 }; 8792 bool unused[5]; 8793 tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }; 8794 tree last_iter = NULL_TREE, last_count = NULL_TREE; 8795 size_t i, j; 8796 location_t first_loc = UNKNOWN_LOCATION; 8797 8798 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 8799 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 8800 { 8801 switch (OMP_CLAUSE_DEPEND_KIND (c)) 8802 { 8803 case OMP_CLAUSE_DEPEND_IN: 8804 i = 2; 8805 break; 8806 case OMP_CLAUSE_DEPEND_OUT: 8807 case OMP_CLAUSE_DEPEND_INOUT: 8808 i = 0; 8809 break; 8810 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: 8811 i = 1; 8812 break; 8813 case OMP_CLAUSE_DEPEND_DEPOBJ: 8814 i = 3; 8815 break; 8816 case OMP_CLAUSE_DEPEND_INOUTSET: 8817 i = 4; 8818 break; 8819 default: 8820 gcc_unreachable (); 8821 } 8822 tree t = OMP_CLAUSE_DECL (c); 8823 if (first_loc == UNKNOWN_LOCATION) 8824 first_loc = OMP_CLAUSE_LOCATION (c); 8825 if (TREE_CODE (t) == TREE_LIST 8826 && TREE_PURPOSE (t) 8827 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 8828 { 8829 if (TREE_PURPOSE (t) != last_iter) 8830 { 8831 tree tcnt = size_one_node; 8832 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8833 { 8834 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL, 8835 is_gimple_val, fb_rvalue) == GS_ERROR 8836 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL, 8837 is_gimple_val, fb_rvalue) == GS_ERROR 8838 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL, 8839 is_gimple_val, fb_rvalue) == GS_ERROR 8840 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL, 8841 is_gimple_val, fb_rvalue) 8842 == GS_ERROR)) 8843 return 2; 8844 tree var = TREE_VEC_ELT (it, 0); 8845 tree begin = TREE_VEC_ELT (it, 1); 8846 tree end = TREE_VEC_ELT (it, 2); 8847 tree step = TREE_VEC_ELT (it, 3); 8848 tree orig_step = TREE_VEC_ELT (it, 4); 8849 tree type = TREE_TYPE (var); 8850 tree stype = TREE_TYPE (step); 8851 location_t loc = DECL_SOURCE_LOCATION (var); 8852 tree endmbegin; 8853 /* Compute count for this iterator as 8854 orig_step > 0 8855 ? (begin < end ? (end - begin + (step - 1)) / step : 0) 8856 : (begin > end ? (end - begin + (step + 1)) / step : 0) 8857 and compute product of those for the entire depend 8858 clause. */ 8859 if (POINTER_TYPE_P (type)) 8860 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR, 8861 stype, end, begin); 8862 else 8863 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type, 8864 end, begin); 8865 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype, 8866 step, 8867 build_int_cst (stype, 1)); 8868 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step, 8869 build_int_cst (stype, 1)); 8870 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype, 8871 unshare_expr (endmbegin), 8872 stepm1); 8873 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, 8874 pos, step); 8875 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype, 8876 endmbegin, stepp1); 8877 if (TYPE_UNSIGNED (stype)) 8878 { 8879 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg); 8880 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step); 8881 } 8882 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, 8883 neg, step); 8884 step = NULL_TREE; 8885 tree cond = fold_build2_loc (loc, LT_EXPR, 8886 boolean_type_node, 8887 begin, end); 8888 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos, 8889 build_int_cst (stype, 0)); 8890 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, 8891 end, begin); 8892 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg, 8893 build_int_cst (stype, 0)); 8894 tree osteptype = TREE_TYPE (orig_step); 8895 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8896 orig_step, 8897 build_int_cst (osteptype, 0)); 8898 tree cnt = fold_build3_loc (loc, COND_EXPR, stype, 8899 cond, pos, neg); 8900 cnt = fold_convert_loc (loc, sizetype, cnt); 8901 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val, 8902 fb_rvalue) == GS_ERROR) 8903 return 2; 8904 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt); 8905 } 8906 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val, 8907 fb_rvalue) == GS_ERROR) 8908 return 2; 8909 last_iter = TREE_PURPOSE (t); 8910 last_count = tcnt; 8911 } 8912 if (counts[i] == NULL_TREE) 8913 counts[i] = last_count; 8914 else 8915 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c), 8916 PLUS_EXPR, counts[i], last_count); 8917 } 8918 else 8919 n[i]++; 8920 } 8921 for (i = 0; i < 5; i++) 8922 if (counts[i]) 8923 break; 8924 if (i == 5) 8925 return 0; 8926 8927 tree total = size_zero_node; 8928 for (i = 0; i < 5; i++) 8929 { 8930 unused[i] = counts[i] == NULL_TREE && n[i] == 0; 8931 if (counts[i] == NULL_TREE) 8932 counts[i] = size_zero_node; 8933 if (n[i]) 8934 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i])); 8935 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val, 8936 fb_rvalue) == GS_ERROR) 8937 return 2; 8938 total = size_binop (PLUS_EXPR, total, counts[i]); 8939 } 8940 8941 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue) 8942 == GS_ERROR) 8943 return 2; 8944 bool is_old = unused[1] && unused[3] && unused[4]; 8945 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total), 8946 size_int (is_old ? 1 : 4)); 8947 if (!unused[4]) 8948 totalpx = size_binop (PLUS_EXPR, totalpx, 8949 size_binop (MULT_EXPR, counts[4], size_int (2))); 8950 tree type = build_array_type (ptr_type_node, build_index_type (totalpx)); 8951 tree array = create_tmp_var_raw (type); 8952 TREE_ADDRESSABLE (array) = 1; 8953 if (!poly_int_tree_p (totalpx)) 8954 { 8955 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array))) 8956 gimplify_type_sizes (TREE_TYPE (array), pre_p); 8957 if (gimplify_omp_ctxp) 8958 { 8959 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 8960 while (ctx 8961 && (ctx->region_type == ORT_WORKSHARE 8962 || ctx->region_type == ORT_TASKGROUP 8963 || ctx->region_type == ORT_SIMD 8964 || ctx->region_type == ORT_ACC)) 8965 ctx = ctx->outer_context; 8966 if (ctx) 8967 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN); 8968 } 8969 gimplify_vla_decl (array, pre_p); 8970 } 8971 else 8972 gimple_add_tmp_var (array); 8973 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE, 8974 NULL_TREE); 8975 tree tem; 8976 if (!is_old) 8977 { 8978 tem = build2 (MODIFY_EXPR, void_type_node, r, 8979 build_int_cst (ptr_type_node, 0)); 8980 gimplify_and_add (tem, pre_p); 8981 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE, 8982 NULL_TREE); 8983 } 8984 tem = build2 (MODIFY_EXPR, void_type_node, r, 8985 fold_convert (ptr_type_node, total)); 8986 gimplify_and_add (tem, pre_p); 8987 for (i = 1; i < (is_old ? 2 : 4); i++) 8988 { 8989 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old), 8990 NULL_TREE, NULL_TREE); 8991 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]); 8992 gimplify_and_add (tem, pre_p); 8993 } 8994 8995 tree cnts[6]; 8996 for (j = 5; j; j--) 8997 if (!unused[j - 1]) 8998 break; 8999 for (i = 0; i < 5; i++) 9000 { 9001 if (i && (i >= j || unused[i - 1])) 9002 { 9003 cnts[i] = cnts[i - 1]; 9004 continue; 9005 } 9006 cnts[i] = create_tmp_var (sizetype); 9007 if (i == 0) 9008 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5)); 9009 else 9010 { 9011 tree t; 9012 if (is_old) 9013 t = size_binop (PLUS_EXPR, counts[0], size_int (2)); 9014 else 9015 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]); 9016 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue) 9017 == GS_ERROR) 9018 return 2; 9019 g = gimple_build_assign (cnts[i], t); 9020 } 9021 gimple_seq_add_stmt (pre_p, g); 9022 } 9023 if (unused[4]) 9024 cnts[5] = NULL_TREE; 9025 else 9026 { 9027 tree t = size_binop (PLUS_EXPR, total, size_int (5)); 9028 cnts[5] = create_tmp_var (sizetype); 9029 g = gimple_build_assign (cnts[i], t); 9030 gimple_seq_add_stmt (pre_p, g); 9031 } 9032 9033 last_iter = NULL_TREE; 9034 tree last_bind = NULL_TREE; 9035 tree *last_body = NULL; 9036 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 9037 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 9038 { 9039 switch (OMP_CLAUSE_DEPEND_KIND (c)) 9040 { 9041 case OMP_CLAUSE_DEPEND_IN: 9042 i = 2; 9043 break; 9044 case OMP_CLAUSE_DEPEND_OUT: 9045 case OMP_CLAUSE_DEPEND_INOUT: 9046 i = 0; 9047 break; 9048 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: 9049 i = 1; 9050 break; 9051 case OMP_CLAUSE_DEPEND_DEPOBJ: 9052 i = 3; 9053 break; 9054 case OMP_CLAUSE_DEPEND_INOUTSET: 9055 i = 4; 9056 break; 9057 default: 9058 gcc_unreachable (); 9059 } 9060 tree t = OMP_CLAUSE_DECL (c); 9061 if (TREE_CODE (t) == TREE_LIST 9062 && TREE_PURPOSE (t) 9063 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 9064 { 9065 if (TREE_PURPOSE (t) != last_iter) 9066 { 9067 if (last_bind) 9068 gimplify_and_add (last_bind, pre_p); 9069 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5); 9070 last_bind = build3 (BIND_EXPR, void_type_node, 9071 BLOCK_VARS (block), NULL, block); 9072 TREE_SIDE_EFFECTS (last_bind) = 1; 9073 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c)); 9074 tree *p = &BIND_EXPR_BODY (last_bind); 9075 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 9076 { 9077 tree var = TREE_VEC_ELT (it, 0); 9078 tree begin = TREE_VEC_ELT (it, 1); 9079 tree end = TREE_VEC_ELT (it, 2); 9080 tree step = TREE_VEC_ELT (it, 3); 9081 tree orig_step = TREE_VEC_ELT (it, 4); 9082 tree type = TREE_TYPE (var); 9083 location_t loc = DECL_SOURCE_LOCATION (var); 9084 /* Emit: 9085 var = begin; 9086 goto cond_label; 9087 beg_label: 9088 ... 9089 var = var + step; 9090 cond_label: 9091 if (orig_step > 0) { 9092 if (var < end) goto beg_label; 9093 } else { 9094 if (var > end) goto beg_label; 9095 } 9096 for each iterator, with inner iterators added to 9097 the ... above. */ 9098 tree beg_label = create_artificial_label (loc); 9099 tree cond_label = NULL_TREE; 9100 tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 9101 var, begin); 9102 append_to_statement_list_force (tem, p); 9103 tem = build_and_jump (&cond_label); 9104 append_to_statement_list_force (tem, p); 9105 tem = build1 (LABEL_EXPR, void_type_node, beg_label); 9106 append_to_statement_list (tem, p); 9107 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE, 9108 NULL_TREE, NULL_TREE); 9109 TREE_SIDE_EFFECTS (bind) = 1; 9110 SET_EXPR_LOCATION (bind, loc); 9111 append_to_statement_list_force (bind, p); 9112 if (POINTER_TYPE_P (type)) 9113 tem = build2_loc (loc, POINTER_PLUS_EXPR, type, 9114 var, fold_convert_loc (loc, sizetype, 9115 step)); 9116 else 9117 tem = build2_loc (loc, PLUS_EXPR, type, var, step); 9118 tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 9119 var, tem); 9120 append_to_statement_list_force (tem, p); 9121 tem = build1 (LABEL_EXPR, void_type_node, cond_label); 9122 append_to_statement_list (tem, p); 9123 tree cond = fold_build2_loc (loc, LT_EXPR, 9124 boolean_type_node, 9125 var, end); 9126 tree pos 9127 = fold_build3_loc (loc, COND_EXPR, void_type_node, 9128 cond, build_and_jump (&beg_label), 9129 void_node); 9130 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 9131 var, end); 9132 tree neg 9133 = fold_build3_loc (loc, COND_EXPR, void_type_node, 9134 cond, build_and_jump (&beg_label), 9135 void_node); 9136 tree osteptype = TREE_TYPE (orig_step); 9137 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 9138 orig_step, 9139 build_int_cst (osteptype, 0)); 9140 tem = fold_build3_loc (loc, COND_EXPR, void_type_node, 9141 cond, pos, neg); 9142 append_to_statement_list_force (tem, p); 9143 p = &BIND_EXPR_BODY (bind); 9144 } 9145 last_body = p; 9146 } 9147 last_iter = TREE_PURPOSE (t); 9148 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR) 9149 { 9150 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 9151 0), last_body); 9152 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1); 9153 } 9154 if (error_operand_p (TREE_VALUE (t))) 9155 return 2; 9156 if (TREE_VALUE (t) != null_pointer_node) 9157 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t)); 9158 if (i == 4) 9159 { 9160 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9161 NULL_TREE, NULL_TREE); 9162 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5], 9163 NULL_TREE, NULL_TREE); 9164 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node); 9165 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9166 void_type_node, r, r2); 9167 append_to_statement_list_force (tem, last_body); 9168 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9169 void_type_node, cnts[i], 9170 size_binop (PLUS_EXPR, cnts[i], 9171 size_int (1))); 9172 append_to_statement_list_force (tem, last_body); 9173 i = 5; 9174 } 9175 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9176 NULL_TREE, NULL_TREE); 9177 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9178 void_type_node, r, TREE_VALUE (t)); 9179 append_to_statement_list_force (tem, last_body); 9180 if (i == 5) 9181 { 9182 r = build4 (ARRAY_REF, ptr_type_node, array, 9183 size_binop (PLUS_EXPR, cnts[i], size_int (1)), 9184 NULL_TREE, NULL_TREE); 9185 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET); 9186 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9187 void_type_node, r, tem); 9188 append_to_statement_list_force (tem, last_body); 9189 } 9190 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9191 void_type_node, cnts[i], 9192 size_binop (PLUS_EXPR, cnts[i], 9193 size_int (1 + (i == 5)))); 9194 append_to_statement_list_force (tem, last_body); 9195 TREE_VALUE (t) = null_pointer_node; 9196 } 9197 else 9198 { 9199 if (last_bind) 9200 { 9201 gimplify_and_add (last_bind, pre_p); 9202 last_bind = NULL_TREE; 9203 } 9204 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 9205 { 9206 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 9207 NULL, is_gimple_val, fb_rvalue); 9208 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 9209 } 9210 if (error_operand_p (OMP_CLAUSE_DECL (c))) 9211 return 2; 9212 if (OMP_CLAUSE_DECL (c) != null_pointer_node) 9213 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c)); 9214 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 9215 is_gimple_val, fb_rvalue) == GS_ERROR) 9216 return 2; 9217 if (i == 4) 9218 { 9219 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9220 NULL_TREE, NULL_TREE); 9221 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5], 9222 NULL_TREE, NULL_TREE); 9223 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node); 9224 tem = build2 (MODIFY_EXPR, void_type_node, r, r2); 9225 gimplify_and_add (tem, pre_p); 9226 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, 9227 cnts[i], 9228 size_int (1))); 9229 gimple_seq_add_stmt (pre_p, g); 9230 i = 5; 9231 } 9232 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9233 NULL_TREE, NULL_TREE); 9234 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c)); 9235 gimplify_and_add (tem, pre_p); 9236 if (i == 5) 9237 { 9238 r = build4 (ARRAY_REF, ptr_type_node, array, 9239 size_binop (PLUS_EXPR, cnts[i], size_int (1)), 9240 NULL_TREE, NULL_TREE); 9241 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET); 9242 tem = build2 (MODIFY_EXPR, void_type_node, r, tem); 9243 append_to_statement_list_force (tem, last_body); 9244 gimplify_and_add (tem, pre_p); 9245 } 9246 g = gimple_build_assign (cnts[i], 9247 size_binop (PLUS_EXPR, cnts[i], 9248 size_int (1 + (i == 5)))); 9249 gimple_seq_add_stmt (pre_p, g); 9250 } 9251 } 9252 if (last_bind) 9253 gimplify_and_add (last_bind, pre_p); 9254 tree cond = boolean_false_node; 9255 if (is_old) 9256 { 9257 if (!unused[0]) 9258 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0], 9259 size_binop_loc (first_loc, PLUS_EXPR, counts[0], 9260 size_int (2))); 9261 if (!unused[2]) 9262 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond, 9263 build2_loc (first_loc, NE_EXPR, boolean_type_node, 9264 cnts[2], 9265 size_binop_loc (first_loc, PLUS_EXPR, 9266 totalpx, 9267 size_int (1)))); 9268 } 9269 else 9270 { 9271 tree prev = size_int (5); 9272 for (i = 0; i < 5; i++) 9273 { 9274 if (unused[i]) 9275 continue; 9276 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev); 9277 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond, 9278 build2_loc (first_loc, NE_EXPR, boolean_type_node, 9279 cnts[i], unshare_expr (prev))); 9280 } 9281 } 9282 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond, 9283 build_call_expr_loc (first_loc, 9284 builtin_decl_explicit (BUILT_IN_TRAP), 9285 0), void_node); 9286 gimplify_and_add (tem, pre_p); 9287 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND); 9288 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST; 9289 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array); 9290 OMP_CLAUSE_CHAIN (c) = *list_p; 9291 *list_p = c; 9292 return 1; 9293 } 9294 9295 /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor. */ 9296 9297 static bool 9298 omp_map_clause_descriptor_p (tree c) 9299 { 9300 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) 9301 return false; 9302 9303 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET) 9304 return true; 9305 9306 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE 9307 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE) 9308 && OMP_CLAUSE_RELEASE_DESCRIPTOR (c)) 9309 return true; 9310 9311 return false; 9312 } 9313 9314 /* For a set of mappings describing an array section pointed to by a struct 9315 (or derived type, etc.) component, create an "alloc" or "release" node to 9316 insert into a list following a GOMP_MAP_STRUCT node. For some types of 9317 mapping (e.g. Fortran arrays with descriptors), an additional mapping may 9318 be created that is inserted into the list of mapping nodes attached to the 9319 directive being processed -- not part of the sorted list of nodes after 9320 GOMP_MAP_STRUCT. 9321 9322 CODE is the code of the directive being processed. GRP_START and GRP_END 9323 are the first and last of two or three nodes representing this array section 9324 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a 9325 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is 9326 filled with the additional node described above, if needed. 9327 9328 This function does not add the new nodes to any lists itself. It is the 9329 responsibility of the caller to do that. */ 9330 9331 static tree 9332 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end, 9333 tree *extra_node) 9334 { 9335 enum gomp_map_kind mkind 9336 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA) 9337 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 9338 9339 gcc_assert (grp_start != grp_end); 9340 9341 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 9342 OMP_CLAUSE_SET_MAP_KIND (c2, mkind); 9343 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end)); 9344 OMP_CLAUSE_CHAIN (c2) = NULL_TREE; 9345 tree grp_mid = NULL_TREE; 9346 if (OMP_CLAUSE_CHAIN (grp_start) != grp_end) 9347 grp_mid = OMP_CLAUSE_CHAIN (grp_start); 9348 9349 if (grp_mid && omp_map_clause_descriptor_p (grp_mid)) 9350 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid); 9351 else 9352 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node); 9353 9354 if (grp_mid 9355 && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP 9356 && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER) 9357 { 9358 tree c3 9359 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 9360 OMP_CLAUSE_SET_MAP_KIND (c3, mkind); 9361 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid)); 9362 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node); 9363 OMP_CLAUSE_CHAIN (c3) = NULL_TREE; 9364 9365 *extra_node = c3; 9366 } 9367 else 9368 *extra_node = NULL_TREE; 9369 9370 return c2; 9371 } 9372 9373 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object, 9374 and set *BITPOSP and *POFFSETP to the bit offset of the access. 9375 If BASE_REF is non-NULL and the containing object is a reference, set 9376 *BASE_REF to that reference before dereferencing the object. 9377 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or 9378 has array type, else return NULL. */ 9379 9380 static tree 9381 extract_base_bit_offset (tree base, poly_int64 *bitposp, 9382 poly_offset_int *poffsetp, 9383 bool *variable_offset) 9384 { 9385 tree offset; 9386 poly_int64 bitsize, bitpos; 9387 machine_mode mode; 9388 int unsignedp, reversep, volatilep = 0; 9389 poly_offset_int poffset; 9390 9391 STRIP_NOPS (base); 9392 9393 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode, 9394 &unsignedp, &reversep, &volatilep); 9395 9396 STRIP_NOPS (base); 9397 9398 if (offset && poly_int_tree_p (offset)) 9399 { 9400 poffset = wi::to_poly_offset (offset); 9401 *variable_offset = false; 9402 } 9403 else 9404 { 9405 poffset = 0; 9406 *variable_offset = (offset != NULL_TREE); 9407 } 9408 9409 if (maybe_ne (bitpos, 0)) 9410 poffset += bits_to_bytes_round_down (bitpos); 9411 9412 *bitposp = bitpos; 9413 *poffsetp = poffset; 9414 9415 return base; 9416 } 9417 9418 /* Used for topological sorting of mapping groups. UNVISITED means we haven't 9419 started processing the group yet. The TEMPORARY mark is used when we first 9420 encounter a group on a depth-first traversal, and the PERMANENT mark is used 9421 when we have processed all the group's children (i.e. all the base pointers 9422 referred to by the group's mapping nodes, recursively). */ 9423 9424 enum omp_tsort_mark { 9425 UNVISITED, 9426 TEMPORARY, 9427 PERMANENT 9428 }; 9429 9430 /* Hash for trees based on operand_equal_p. Like tree_operand_hash 9431 but ignores side effects in the equality comparisons. */ 9432 9433 struct tree_operand_hash_no_se : tree_operand_hash 9434 { 9435 static inline bool equal (const value_type &, 9436 const compare_type &); 9437 }; 9438 9439 inline bool 9440 tree_operand_hash_no_se::equal (const value_type &t1, 9441 const compare_type &t2) 9442 { 9443 return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS); 9444 } 9445 9446 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map" 9447 clause. */ 9448 9449 struct omp_mapping_group { 9450 tree *grp_start; 9451 tree grp_end; 9452 omp_tsort_mark mark; 9453 /* If we've removed the group but need to reindex, mark the group as 9454 deleted. */ 9455 bool deleted; 9456 /* The group points to an already-created "GOMP_MAP_STRUCT 9457 GOMP_MAP_ATTACH_DETACH" pair. */ 9458 bool reprocess_struct; 9459 /* The group should use "zero-length" allocations for pointers that are not 9460 mapped "to" on the same directive. */ 9461 bool fragile; 9462 struct omp_mapping_group *sibling; 9463 struct omp_mapping_group *next; 9464 }; 9465 9466 DEBUG_FUNCTION void 9467 debug_mapping_group (omp_mapping_group *grp) 9468 { 9469 tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end); 9470 OMP_CLAUSE_CHAIN (grp->grp_end) = NULL; 9471 debug_generic_expr (*grp->grp_start); 9472 OMP_CLAUSE_CHAIN (grp->grp_end) = tmp; 9473 } 9474 9475 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there 9476 isn't one. */ 9477 9478 static tree 9479 omp_get_base_pointer (tree expr) 9480 { 9481 while (TREE_CODE (expr) == ARRAY_REF 9482 || TREE_CODE (expr) == COMPONENT_REF) 9483 expr = TREE_OPERAND (expr, 0); 9484 9485 if (INDIRECT_REF_P (expr) 9486 || (TREE_CODE (expr) == MEM_REF 9487 && integer_zerop (TREE_OPERAND (expr, 1)))) 9488 { 9489 expr = TREE_OPERAND (expr, 0); 9490 while (TREE_CODE (expr) == COMPOUND_EXPR) 9491 expr = TREE_OPERAND (expr, 1); 9492 if (TREE_CODE (expr) == POINTER_PLUS_EXPR) 9493 expr = TREE_OPERAND (expr, 0); 9494 if (TREE_CODE (expr) == SAVE_EXPR) 9495 expr = TREE_OPERAND (expr, 0); 9496 STRIP_NOPS (expr); 9497 return expr; 9498 } 9499 9500 return NULL_TREE; 9501 } 9502 9503 /* An attach or detach operation depends directly on the address being 9504 attached/detached. Return that address, or none if there are no 9505 attachments/detachments. */ 9506 9507 static tree 9508 omp_get_attachment (omp_mapping_group *grp) 9509 { 9510 tree node = *grp->grp_start; 9511 9512 switch (OMP_CLAUSE_MAP_KIND (node)) 9513 { 9514 case GOMP_MAP_TO: 9515 case GOMP_MAP_FROM: 9516 case GOMP_MAP_TOFROM: 9517 case GOMP_MAP_ALWAYS_FROM: 9518 case GOMP_MAP_ALWAYS_TO: 9519 case GOMP_MAP_ALWAYS_TOFROM: 9520 case GOMP_MAP_FORCE_FROM: 9521 case GOMP_MAP_FORCE_TO: 9522 case GOMP_MAP_FORCE_TOFROM: 9523 case GOMP_MAP_FORCE_PRESENT: 9524 case GOMP_MAP_PRESENT_ALLOC: 9525 case GOMP_MAP_PRESENT_FROM: 9526 case GOMP_MAP_PRESENT_TO: 9527 case GOMP_MAP_PRESENT_TOFROM: 9528 case GOMP_MAP_ALWAYS_PRESENT_FROM: 9529 case GOMP_MAP_ALWAYS_PRESENT_TO: 9530 case GOMP_MAP_ALWAYS_PRESENT_TOFROM: 9531 case GOMP_MAP_ALLOC: 9532 case GOMP_MAP_RELEASE: 9533 case GOMP_MAP_DELETE: 9534 case GOMP_MAP_FORCE_ALLOC: 9535 if (node == grp->grp_end) 9536 return NULL_TREE; 9537 9538 node = OMP_CLAUSE_CHAIN (node); 9539 if (node && omp_map_clause_descriptor_p (node)) 9540 { 9541 gcc_assert (node != grp->grp_end); 9542 node = OMP_CLAUSE_CHAIN (node); 9543 } 9544 if (node) 9545 switch (OMP_CLAUSE_MAP_KIND (node)) 9546 { 9547 case GOMP_MAP_POINTER: 9548 case GOMP_MAP_ALWAYS_POINTER: 9549 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9550 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9551 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9552 return NULL_TREE; 9553 9554 case GOMP_MAP_ATTACH_DETACH: 9555 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9556 case GOMP_MAP_DETACH: 9557 return OMP_CLAUSE_DECL (node); 9558 9559 default: 9560 internal_error ("unexpected mapping node"); 9561 } 9562 return error_mark_node; 9563 9564 case GOMP_MAP_TO_PSET: 9565 gcc_assert (node != grp->grp_end); 9566 node = OMP_CLAUSE_CHAIN (node); 9567 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH 9568 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH) 9569 return OMP_CLAUSE_DECL (node); 9570 else 9571 internal_error ("unexpected mapping node"); 9572 return error_mark_node; 9573 9574 case GOMP_MAP_ATTACH: 9575 case GOMP_MAP_DETACH: 9576 node = OMP_CLAUSE_CHAIN (node); 9577 if (!node || *grp->grp_start == grp->grp_end) 9578 return OMP_CLAUSE_DECL (*grp->grp_start); 9579 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9580 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9581 return OMP_CLAUSE_DECL (*grp->grp_start); 9582 else 9583 internal_error ("unexpected mapping node"); 9584 return error_mark_node; 9585 9586 case GOMP_MAP_STRUCT: 9587 case GOMP_MAP_STRUCT_UNORD: 9588 case GOMP_MAP_FORCE_DEVICEPTR: 9589 case GOMP_MAP_DEVICE_RESIDENT: 9590 case GOMP_MAP_LINK: 9591 case GOMP_MAP_IF_PRESENT: 9592 case GOMP_MAP_FIRSTPRIVATE: 9593 case GOMP_MAP_FIRSTPRIVATE_INT: 9594 case GOMP_MAP_USE_DEVICE_PTR: 9595 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9596 return NULL_TREE; 9597 9598 default: 9599 internal_error ("unexpected mapping node"); 9600 } 9601 9602 return error_mark_node; 9603 } 9604 9605 /* Given a pointer START_P to the start of a group of related (e.g. pointer) 9606 mappings, return the chain pointer to the end of that group in the list. */ 9607 9608 static tree * 9609 omp_group_last (tree *start_p) 9610 { 9611 tree c = *start_p, nc, *grp_last_p = start_p; 9612 9613 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP); 9614 9615 nc = OMP_CLAUSE_CHAIN (c); 9616 9617 if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP) 9618 return grp_last_p; 9619 9620 switch (OMP_CLAUSE_MAP_KIND (c)) 9621 { 9622 default: 9623 while (nc 9624 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9625 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9626 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER 9627 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH 9628 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER 9629 || (OMP_CLAUSE_MAP_KIND (nc) 9630 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION) 9631 || (OMP_CLAUSE_MAP_KIND (nc) 9632 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION) 9633 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH 9634 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER 9635 || omp_map_clause_descriptor_p (nc))) 9636 { 9637 tree nc2 = OMP_CLAUSE_CHAIN (nc); 9638 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH) 9639 { 9640 /* In the specific case we're doing "exit data" on an array 9641 slice of a reference-to-pointer struct component, we will see 9642 DETACH followed by ATTACH_DETACH here. We want to treat that 9643 as a single group. In other cases DETACH might represent a 9644 stand-alone "detach" clause, so we don't want to consider 9645 that part of the group. */ 9646 if (nc2 9647 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP 9648 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH) 9649 goto consume_two_nodes; 9650 else 9651 break; 9652 } 9653 if (nc2 9654 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP 9655 && (OMP_CLAUSE_MAP_KIND (nc) 9656 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION) 9657 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH) 9658 { 9659 consume_two_nodes: 9660 grp_last_p = &OMP_CLAUSE_CHAIN (nc); 9661 c = nc2; 9662 nc = OMP_CLAUSE_CHAIN (nc2); 9663 } 9664 else 9665 { 9666 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9667 c = nc; 9668 nc = nc2; 9669 } 9670 } 9671 break; 9672 9673 case GOMP_MAP_ATTACH: 9674 case GOMP_MAP_DETACH: 9675 /* This is a weird artifact of how directives are parsed: bare attach or 9676 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or 9677 FIRSTPRIVATE_REFERENCE node. FIXME. */ 9678 if (nc 9679 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9680 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9681 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER)) 9682 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9683 break; 9684 9685 case GOMP_MAP_TO_PSET: 9686 if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9687 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH 9688 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)) 9689 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9690 break; 9691 9692 case GOMP_MAP_STRUCT: 9693 case GOMP_MAP_STRUCT_UNORD: 9694 { 9695 unsigned HOST_WIDE_INT num_mappings 9696 = tree_to_uhwi (OMP_CLAUSE_SIZE (c)); 9697 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER 9698 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9699 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH) 9700 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p); 9701 for (unsigned i = 0; i < num_mappings; i++) 9702 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p); 9703 } 9704 break; 9705 } 9706 9707 return grp_last_p; 9708 } 9709 9710 /* Walk through LIST_P, and return a list of groups of mappings found (e.g. 9711 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two 9712 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group 9713 if we have more than one such group, else return NULL. */ 9714 9715 static void 9716 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups, 9717 tree gather_sentinel) 9718 { 9719 for (tree *cp = list_p; 9720 *cp && *cp != gather_sentinel; 9721 cp = &OMP_CLAUSE_CHAIN (*cp)) 9722 { 9723 if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP) 9724 continue; 9725 9726 tree *grp_last_p = omp_group_last (cp); 9727 omp_mapping_group grp; 9728 9729 grp.grp_start = cp; 9730 grp.grp_end = *grp_last_p; 9731 grp.mark = UNVISITED; 9732 grp.sibling = NULL; 9733 grp.deleted = false; 9734 grp.reprocess_struct = false; 9735 grp.fragile = false; 9736 grp.next = NULL; 9737 groups->safe_push (grp); 9738 9739 cp = grp_last_p; 9740 } 9741 } 9742 9743 static vec<omp_mapping_group> * 9744 omp_gather_mapping_groups (tree *list_p) 9745 { 9746 vec<omp_mapping_group> *groups = new vec<omp_mapping_group> (); 9747 9748 omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE); 9749 9750 if (groups->length () > 0) 9751 return groups; 9752 else 9753 { 9754 delete groups; 9755 return NULL; 9756 } 9757 } 9758 9759 /* A pointer mapping group GRP may define a block of memory starting at some 9760 base address, and maybe also define a firstprivate pointer or firstprivate 9761 reference that points to that block. The return value is a node containing 9762 the former, and the *FIRSTPRIVATE pointer is set if we have the latter. 9763 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping, 9764 return the number of consecutive chained nodes in CHAINED. */ 9765 9766 static tree 9767 omp_group_base (omp_mapping_group *grp, unsigned int *chained, 9768 tree *firstprivate) 9769 { 9770 tree node = *grp->grp_start; 9771 9772 *firstprivate = NULL_TREE; 9773 *chained = 1; 9774 9775 switch (OMP_CLAUSE_MAP_KIND (node)) 9776 { 9777 case GOMP_MAP_TO: 9778 case GOMP_MAP_FROM: 9779 case GOMP_MAP_TOFROM: 9780 case GOMP_MAP_ALWAYS_FROM: 9781 case GOMP_MAP_ALWAYS_TO: 9782 case GOMP_MAP_ALWAYS_TOFROM: 9783 case GOMP_MAP_FORCE_FROM: 9784 case GOMP_MAP_FORCE_TO: 9785 case GOMP_MAP_FORCE_TOFROM: 9786 case GOMP_MAP_FORCE_PRESENT: 9787 case GOMP_MAP_PRESENT_ALLOC: 9788 case GOMP_MAP_PRESENT_FROM: 9789 case GOMP_MAP_PRESENT_TO: 9790 case GOMP_MAP_PRESENT_TOFROM: 9791 case GOMP_MAP_ALWAYS_PRESENT_FROM: 9792 case GOMP_MAP_ALWAYS_PRESENT_TO: 9793 case GOMP_MAP_ALWAYS_PRESENT_TOFROM: 9794 case GOMP_MAP_ALLOC: 9795 case GOMP_MAP_RELEASE: 9796 case GOMP_MAP_DELETE: 9797 case GOMP_MAP_FORCE_ALLOC: 9798 case GOMP_MAP_IF_PRESENT: 9799 if (node == grp->grp_end) 9800 return node; 9801 9802 node = OMP_CLAUSE_CHAIN (node); 9803 if (!node) 9804 internal_error ("unexpected mapping node"); 9805 if (omp_map_clause_descriptor_p (node)) 9806 { 9807 if (node == grp->grp_end) 9808 return *grp->grp_start; 9809 node = OMP_CLAUSE_CHAIN (node); 9810 } 9811 switch (OMP_CLAUSE_MAP_KIND (node)) 9812 { 9813 case GOMP_MAP_POINTER: 9814 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9815 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9816 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9817 *firstprivate = OMP_CLAUSE_DECL (node); 9818 return *grp->grp_start; 9819 9820 case GOMP_MAP_ALWAYS_POINTER: 9821 case GOMP_MAP_ATTACH_DETACH: 9822 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9823 case GOMP_MAP_DETACH: 9824 return *grp->grp_start; 9825 9826 default: 9827 internal_error ("unexpected mapping node"); 9828 } 9829 return error_mark_node; 9830 9831 case GOMP_MAP_TO_PSET: 9832 gcc_assert (node != grp->grp_end); 9833 node = OMP_CLAUSE_CHAIN (node); 9834 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH 9835 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH) 9836 return NULL_TREE; 9837 else 9838 internal_error ("unexpected mapping node"); 9839 return error_mark_node; 9840 9841 case GOMP_MAP_ATTACH: 9842 case GOMP_MAP_DETACH: 9843 node = OMP_CLAUSE_CHAIN (node); 9844 if (!node || *grp->grp_start == grp->grp_end) 9845 return NULL_TREE; 9846 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9847 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9848 { 9849 /* We're mapping the base pointer itself in a bare attach or detach 9850 node. This is a side effect of how parsing works, and the mapping 9851 will be removed anyway (at least for enter/exit data directives). 9852 We should ignore the mapping here. FIXME. */ 9853 return NULL_TREE; 9854 } 9855 else 9856 internal_error ("unexpected mapping node"); 9857 return error_mark_node; 9858 9859 case GOMP_MAP_STRUCT: 9860 case GOMP_MAP_STRUCT_UNORD: 9861 { 9862 unsigned HOST_WIDE_INT num_mappings 9863 = tree_to_uhwi (OMP_CLAUSE_SIZE (node)); 9864 node = OMP_CLAUSE_CHAIN (node); 9865 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9866 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9867 { 9868 *firstprivate = OMP_CLAUSE_DECL (node); 9869 node = OMP_CLAUSE_CHAIN (node); 9870 } 9871 else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH) 9872 node = OMP_CLAUSE_CHAIN (node); 9873 *chained = num_mappings; 9874 return node; 9875 } 9876 9877 case GOMP_MAP_FORCE_DEVICEPTR: 9878 case GOMP_MAP_DEVICE_RESIDENT: 9879 case GOMP_MAP_LINK: 9880 case GOMP_MAP_FIRSTPRIVATE: 9881 case GOMP_MAP_FIRSTPRIVATE_INT: 9882 case GOMP_MAP_USE_DEVICE_PTR: 9883 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9884 return NULL_TREE; 9885 9886 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9887 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9888 case GOMP_MAP_POINTER: 9889 case GOMP_MAP_ALWAYS_POINTER: 9890 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9891 /* These shouldn't appear by themselves. */ 9892 if (!seen_error ()) 9893 internal_error ("unexpected pointer mapping node"); 9894 return error_mark_node; 9895 9896 default: 9897 gcc_unreachable (); 9898 } 9899 9900 return error_mark_node; 9901 } 9902 9903 /* Given a vector of omp_mapping_groups, build a hash table so we can look up 9904 nodes by tree_operand_hash_no_se. */ 9905 9906 static void 9907 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se, 9908 omp_mapping_group *> *grpmap, 9909 vec<omp_mapping_group> *groups, 9910 tree reindex_sentinel) 9911 { 9912 omp_mapping_group *grp; 9913 unsigned int i; 9914 bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false; 9915 9916 FOR_EACH_VEC_ELT (*groups, i, grp) 9917 { 9918 if (reindexing && *grp->grp_start == reindex_sentinel) 9919 above_hwm = true; 9920 9921 if (reindexing && !above_hwm) 9922 continue; 9923 9924 if (grp->reprocess_struct) 9925 continue; 9926 9927 tree fpp; 9928 unsigned int chained; 9929 tree node = omp_group_base (grp, &chained, &fpp); 9930 9931 if (node == error_mark_node || (!node && !fpp)) 9932 continue; 9933 9934 for (unsigned j = 0; 9935 node && j < chained; 9936 node = OMP_CLAUSE_CHAIN (node), j++) 9937 { 9938 tree decl = OMP_CLAUSE_DECL (node); 9939 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF, 9940 meaning node-hash lookups don't work. This is a workaround for 9941 that, but ideally we should just create the INDIRECT_REF at 9942 source instead. FIXME. */ 9943 if (TREE_CODE (decl) == MEM_REF 9944 && integer_zerop (TREE_OPERAND (decl, 1))) 9945 decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0)); 9946 9947 omp_mapping_group **prev = grpmap->get (decl); 9948 9949 if (prev && *prev == grp) 9950 /* Empty. */; 9951 else if (prev) 9952 { 9953 /* Mapping the same thing twice is normally diagnosed as an error, 9954 but can happen under some circumstances, e.g. in pr99928-16.c, 9955 the directive: 9956 9957 #pragma omp target simd reduction(+:a[:3]) \ 9958 map(always, tofrom: a[:6]) 9959 ... 9960 9961 will result in two "a[0]" mappings (of different sizes). */ 9962 9963 grp->sibling = (*prev)->sibling; 9964 (*prev)->sibling = grp; 9965 } 9966 else 9967 grpmap->put (decl, grp); 9968 } 9969 9970 if (!fpp) 9971 continue; 9972 9973 omp_mapping_group **prev = grpmap->get (fpp); 9974 if (prev && *prev != grp) 9975 { 9976 grp->sibling = (*prev)->sibling; 9977 (*prev)->sibling = grp; 9978 } 9979 else 9980 grpmap->put (fpp, grp); 9981 } 9982 } 9983 9984 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> * 9985 omp_index_mapping_groups (vec<omp_mapping_group> *groups) 9986 { 9987 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap 9988 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>; 9989 9990 omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE); 9991 9992 return grpmap; 9993 } 9994 9995 /* Rebuild group map from partially-processed clause list (during 9996 omp_build_struct_sibling_lists). We have already processed nodes up until 9997 a high-water mark (HWM). This is a bit tricky because the list is being 9998 reordered as it is scanned, but we know: 9999 10000 1. The list after HWM has not been touched yet, so we can reindex it safely. 10001 10002 2. The list before and including HWM has been altered, but remains 10003 well-formed throughout the sibling-list building operation. 10004 10005 so, we can do the reindex operation in two parts, on the processed and 10006 then the unprocessed halves of the list. */ 10007 10008 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> * 10009 omp_reindex_mapping_groups (tree *list_p, 10010 vec<omp_mapping_group> *groups, 10011 vec<omp_mapping_group> *processed_groups, 10012 tree sentinel) 10013 { 10014 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap 10015 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>; 10016 10017 processed_groups->truncate (0); 10018 10019 omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel); 10020 omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE); 10021 if (sentinel) 10022 omp_index_mapping_groups_1 (grpmap, groups, sentinel); 10023 10024 return grpmap; 10025 } 10026 10027 /* Find the immediately-containing struct for a component ref (etc.) 10028 expression EXPR. */ 10029 10030 static tree 10031 omp_containing_struct (tree expr) 10032 { 10033 tree expr0 = expr; 10034 10035 STRIP_NOPS (expr); 10036 10037 /* Note: don't strip NOPs unless we're also stripping off array refs or a 10038 component ref. */ 10039 if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF) 10040 return expr0; 10041 10042 while (TREE_CODE (expr) == ARRAY_REF) 10043 expr = TREE_OPERAND (expr, 0); 10044 10045 if (TREE_CODE (expr) == COMPONENT_REF) 10046 expr = TREE_OPERAND (expr, 0); 10047 10048 return expr; 10049 } 10050 10051 /* Return TRUE if DECL describes a component that is part of a whole structure 10052 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group 10053 that maps that structure, if present. */ 10054 10055 static bool 10056 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se, 10057 omp_mapping_group *> *grpmap, 10058 tree decl, 10059 omp_mapping_group **mapped_by_group) 10060 { 10061 tree wsdecl = NULL_TREE; 10062 10063 *mapped_by_group = NULL; 10064 10065 while (true) 10066 { 10067 wsdecl = omp_containing_struct (decl); 10068 if (wsdecl == decl) 10069 break; 10070 omp_mapping_group **wholestruct = grpmap->get (wsdecl); 10071 if (!wholestruct 10072 && TREE_CODE (wsdecl) == MEM_REF 10073 && integer_zerop (TREE_OPERAND (wsdecl, 1))) 10074 { 10075 tree deref = TREE_OPERAND (wsdecl, 0); 10076 deref = build_fold_indirect_ref (deref); 10077 wholestruct = grpmap->get (deref); 10078 } 10079 if (wholestruct) 10080 { 10081 *mapped_by_group = *wholestruct; 10082 return true; 10083 } 10084 decl = wsdecl; 10085 } 10086 10087 return false; 10088 } 10089 10090 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or 10091 FALSE on error. */ 10092 10093 static bool 10094 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist, 10095 vec<omp_mapping_group> *groups, 10096 hash_map<tree_operand_hash_no_se, 10097 omp_mapping_group *> *grpmap, 10098 omp_mapping_group *grp) 10099 { 10100 if (grp->mark == PERMANENT) 10101 return true; 10102 if (grp->mark == TEMPORARY) 10103 { 10104 fprintf (stderr, "when processing group:\n"); 10105 debug_mapping_group (grp); 10106 internal_error ("base pointer cycle detected"); 10107 return false; 10108 } 10109 grp->mark = TEMPORARY; 10110 10111 tree attaches_to = omp_get_attachment (grp); 10112 10113 if (attaches_to) 10114 { 10115 omp_mapping_group **basep = grpmap->get (attaches_to); 10116 10117 if (basep && *basep != grp) 10118 { 10119 for (omp_mapping_group *w = *basep; w; w = w->sibling) 10120 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w)) 10121 return false; 10122 } 10123 } 10124 10125 tree decl = OMP_CLAUSE_DECL (*grp->grp_start); 10126 10127 while (decl) 10128 { 10129 tree base = omp_get_base_pointer (decl); 10130 10131 if (!base) 10132 break; 10133 10134 omp_mapping_group **innerp = grpmap->get (base); 10135 omp_mapping_group *wholestruct; 10136 10137 /* We should treat whole-structure mappings as if all (pointer, in this 10138 case) members are mapped as individual list items. Check if we have 10139 such a whole-structure mapping, if we don't have an explicit reference 10140 to the pointer member itself. */ 10141 if (!innerp 10142 && TREE_CODE (base) == COMPONENT_REF 10143 && omp_mapped_by_containing_struct (grpmap, base, &wholestruct)) 10144 innerp = &wholestruct; 10145 10146 if (innerp && *innerp != grp) 10147 { 10148 for (omp_mapping_group *w = *innerp; w; w = w->sibling) 10149 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w)) 10150 return false; 10151 break; 10152 } 10153 10154 decl = base; 10155 } 10156 10157 grp->mark = PERMANENT; 10158 10159 /* Emit grp to output list. */ 10160 10161 **outlist = grp; 10162 *outlist = &grp->next; 10163 10164 return true; 10165 } 10166 10167 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come 10168 before mappings that use those pointers. This is an implementation of the 10169 depth-first search algorithm, described e.g. at: 10170 10171 https://en.wikipedia.org/wiki/Topological_sorting 10172 */ 10173 10174 static omp_mapping_group * 10175 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups, 10176 hash_map<tree_operand_hash_no_se, omp_mapping_group *> 10177 *grpmap, 10178 bool enter_exit_data) 10179 { 10180 omp_mapping_group *grp, *outlist = NULL, **cursor; 10181 unsigned int i; 10182 bool saw_runtime_implicit = false; 10183 10184 cursor = &outlist; 10185 10186 FOR_EACH_VEC_ELT (*groups, i, grp) 10187 { 10188 if (grp->mark != PERMANENT) 10189 { 10190 if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start)) 10191 { 10192 saw_runtime_implicit = true; 10193 continue; 10194 } 10195 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp)) 10196 return NULL; 10197 } 10198 } 10199 10200 if (!saw_runtime_implicit) 10201 return outlist; 10202 10203 FOR_EACH_VEC_ELT (*groups, i, grp) 10204 { 10205 if (grp->mark != PERMANENT 10206 && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start)) 10207 { 10208 /* Clear the flag for enter/exit data because it is currently 10209 meaningless for those operations in libgomp. */ 10210 if (enter_exit_data) 10211 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0; 10212 10213 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp)) 10214 return NULL; 10215 } 10216 } 10217 10218 return outlist; 10219 } 10220 10221 /* Split INLIST into three parts: 10222 10223 - "present" alloc/to/from groups 10224 - other to/from groups 10225 - other alloc/release/delete groups 10226 10227 These sub-lists are then concatenated together to form the final list. 10228 Each sub-list retains the order of the original list. 10229 Note that ATTACH nodes are later moved to the end of the list in 10230 gimplify_adjust_omp_clauses, for target regions. */ 10231 10232 static omp_mapping_group * 10233 omp_segregate_mapping_groups (omp_mapping_group *inlist) 10234 { 10235 omp_mapping_group *ard_groups = NULL, *tf_groups = NULL; 10236 omp_mapping_group *p_groups = NULL; 10237 omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups; 10238 omp_mapping_group **p_tail = &p_groups; 10239 10240 for (omp_mapping_group *w = inlist; w;) 10241 { 10242 tree c = *w->grp_start; 10243 omp_mapping_group *next = w->next; 10244 10245 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP); 10246 10247 switch (OMP_CLAUSE_MAP_KIND (c)) 10248 { 10249 case GOMP_MAP_ALLOC: 10250 case GOMP_MAP_RELEASE: 10251 case GOMP_MAP_DELETE: 10252 *ard_tail = w; 10253 w->next = NULL; 10254 ard_tail = &w->next; 10255 break; 10256 10257 /* These map types are all semantically identical, so are moved into a 10258 single group. They will each be changed into GOMP_MAP_FORCE_PRESENT 10259 in gimplify_adjust_omp_clauses. */ 10260 case GOMP_MAP_PRESENT_ALLOC: 10261 case GOMP_MAP_PRESENT_FROM: 10262 case GOMP_MAP_PRESENT_TO: 10263 case GOMP_MAP_PRESENT_TOFROM: 10264 *p_tail = w; 10265 w->next = NULL; 10266 p_tail = &w->next; 10267 break; 10268 10269 default: 10270 *tf_tail = w; 10271 w->next = NULL; 10272 tf_tail = &w->next; 10273 } 10274 10275 w = next; 10276 } 10277 10278 /* Now splice the lists together... */ 10279 *tf_tail = ard_groups; 10280 *p_tail = tf_groups; 10281 10282 return p_groups; 10283 } 10284 10285 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder 10286 those groups based on the output list of omp_tsort_mapping_groups -- 10287 singly-linked, threaded through each element's NEXT pointer starting at 10288 HEAD. Each list element appears exactly once in that linked list. 10289 10290 Each element of GROUPS may correspond to one or several mapping nodes. 10291 Node groups are kept together, and in the reordered list, the positions of 10292 the original groups are reused for the positions of the reordered list. 10293 Hence if we have e.g. 10294 10295 {to ptr ptr} firstprivate {tofrom ptr} ... 10296 ^ ^ ^ 10297 first group non-"map" second group 10298 10299 and say the second group contains a base pointer for the first so must be 10300 moved before it, the resulting list will contain: 10301 10302 {tofrom ptr} firstprivate {to ptr ptr} ... 10303 ^ prev. second group ^ prev. first group 10304 */ 10305 10306 static tree * 10307 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups, 10308 omp_mapping_group *head, 10309 tree *list_p) 10310 { 10311 omp_mapping_group *grp; 10312 unsigned int i; 10313 unsigned numgroups = groups->length (); 10314 auto_vec<tree> old_heads (numgroups); 10315 auto_vec<tree *> old_headps (numgroups); 10316 auto_vec<tree> new_heads (numgroups); 10317 auto_vec<tree> old_succs (numgroups); 10318 bool map_at_start = (list_p == (*groups)[0].grp_start); 10319 10320 tree *new_grp_tail = NULL; 10321 10322 /* Stash the start & end nodes of each mapping group before we start 10323 modifying the list. */ 10324 FOR_EACH_VEC_ELT (*groups, i, grp) 10325 { 10326 old_headps.quick_push (grp->grp_start); 10327 old_heads.quick_push (*grp->grp_start); 10328 old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end)); 10329 } 10330 10331 /* And similarly, the heads of the groups in the order we want to rearrange 10332 the list to. */ 10333 for (omp_mapping_group *w = head; w; w = w->next) 10334 new_heads.quick_push (*w->grp_start); 10335 10336 FOR_EACH_VEC_ELT (*groups, i, grp) 10337 { 10338 gcc_assert (head); 10339 10340 if (new_grp_tail && old_succs[i - 1] == old_heads[i]) 10341 { 10342 /* a {b c d} {e f g} h i j (original) 10343 --> 10344 a {k l m} {e f g} h i j (inserted new group on last iter) 10345 --> 10346 a {k l m} {n o p} h i j (this time, chain last group to new one) 10347 ^new_grp_tail 10348 */ 10349 *new_grp_tail = new_heads[i]; 10350 } 10351 else if (new_grp_tail) 10352 { 10353 /* a {b c d} e {f g h} i j k (original) 10354 --> 10355 a {l m n} e {f g h} i j k (gap after last iter's group) 10356 --> 10357 a {l m n} e {o p q} h i j (chain last group to old successor) 10358 ^new_grp_tail 10359 */ 10360 *new_grp_tail = old_succs[i - 1]; 10361 *old_headps[i] = new_heads[i]; 10362 } 10363 else 10364 { 10365 /* The first inserted group -- point to new group, and leave end 10366 open. 10367 a {b c d} e f 10368 --> 10369 a {g h i... 10370 */ 10371 *grp->grp_start = new_heads[i]; 10372 } 10373 10374 new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end); 10375 10376 head = head->next; 10377 } 10378 10379 if (new_grp_tail) 10380 *new_grp_tail = old_succs[numgroups - 1]; 10381 10382 gcc_assert (!head); 10383 10384 return map_at_start ? (*groups)[0].grp_start : list_p; 10385 } 10386 10387 /* DECL is supposed to have lastprivate semantics in the outer contexts 10388 of combined/composite constructs, starting with OCTX. 10389 Add needed lastprivate, shared or map clause if no data sharing or 10390 mapping clause are present. IMPLICIT_P is true if it is an implicit 10391 clause (IV on simd), in which case the lastprivate will not be 10392 copied to some constructs. */ 10393 10394 static void 10395 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx, 10396 tree decl, bool implicit_p) 10397 { 10398 struct gimplify_omp_ctx *orig_octx = octx; 10399 for (; octx; octx = octx->outer_context) 10400 { 10401 if ((octx->region_type == ORT_COMBINED_PARALLEL 10402 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS) 10403 && splay_tree_lookup (octx->variables, 10404 (splay_tree_key) decl) == NULL) 10405 { 10406 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN); 10407 continue; 10408 } 10409 if ((octx->region_type & ORT_TASK) != 0 10410 && octx->combined_loop 10411 && splay_tree_lookup (octx->variables, 10412 (splay_tree_key) decl) == NULL) 10413 { 10414 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10415 continue; 10416 } 10417 if (implicit_p 10418 && octx->region_type == ORT_WORKSHARE 10419 && octx->combined_loop 10420 && splay_tree_lookup (octx->variables, 10421 (splay_tree_key) decl) == NULL 10422 && octx->outer_context 10423 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL 10424 && splay_tree_lookup (octx->outer_context->variables, 10425 (splay_tree_key) decl) == NULL) 10426 { 10427 octx = octx->outer_context; 10428 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10429 continue; 10430 } 10431 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC) 10432 && octx->combined_loop 10433 && splay_tree_lookup (octx->variables, 10434 (splay_tree_key) decl) == NULL 10435 && !omp_check_private (octx, decl, false)) 10436 { 10437 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10438 continue; 10439 } 10440 if (octx->region_type == ORT_COMBINED_TARGET) 10441 { 10442 splay_tree_node n = splay_tree_lookup (octx->variables, 10443 (splay_tree_key) decl); 10444 if (n == NULL) 10445 { 10446 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN); 10447 octx = octx->outer_context; 10448 } 10449 else if (!implicit_p 10450 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT)) 10451 { 10452 n->value &= ~(GOVD_FIRSTPRIVATE 10453 | GOVD_FIRSTPRIVATE_IMPLICIT 10454 | GOVD_EXPLICIT); 10455 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN); 10456 octx = octx->outer_context; 10457 } 10458 } 10459 break; 10460 } 10461 if (octx && (implicit_p || octx != orig_octx)) 10462 omp_notice_variable (octx, decl, true); 10463 } 10464 10465 /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also 10466 a "FIRSTPRIVATE" mapping. Return the one that isn't firstprivate, etc. */ 10467 10468 static omp_mapping_group * 10469 omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se, 10470 omp_mapping_group *> *grpmap, 10471 tree decl, bool allow_deleted = false) 10472 { 10473 omp_mapping_group **to_group_p = grpmap->get (decl); 10474 10475 if (!to_group_p) 10476 return NULL; 10477 10478 omp_mapping_group *to_group = *to_group_p; 10479 10480 for (; to_group; to_group = to_group->sibling) 10481 { 10482 tree grp_end = to_group->grp_end; 10483 switch (OMP_CLAUSE_MAP_KIND (grp_end)) 10484 { 10485 case GOMP_MAP_FIRSTPRIVATE_POINTER: 10486 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 10487 break; 10488 10489 default: 10490 if (allow_deleted || !to_group->deleted) 10491 return to_group; 10492 } 10493 } 10494 10495 return NULL; 10496 } 10497 10498 /* Return TRUE if the directive (whose clauses are described by the hash table 10499 of mapping groups, GRPMAP) maps DECL explicitly. If TO_SPECIFICALLY is 10500 true, only count TO mappings. If ALLOW_DELETED is true, ignore the 10501 "deleted" flag for groups. If CONTAINED_IN_STRUCT is true, also return 10502 TRUE if DECL is mapped as a member of a whole-struct mapping. */ 10503 10504 static bool 10505 omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se, 10506 omp_mapping_group *> *grpmap, 10507 tree decl, omp_mapping_group **base_group, 10508 bool to_specifically, bool allow_deleted, 10509 bool contained_in_struct) 10510 { 10511 omp_mapping_group *decl_group 10512 = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted); 10513 10514 *base_group = NULL; 10515 10516 if (decl_group) 10517 { 10518 tree grp_first = *decl_group->grp_start; 10519 /* We might be called during omp_build_struct_sibling_lists, when 10520 GOMP_MAP_STRUCT might have been inserted at the start of the group. 10521 Skip over that, and also possibly the node after it. */ 10522 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT 10523 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD) 10524 { 10525 grp_first = OMP_CLAUSE_CHAIN (grp_first); 10526 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER 10527 || (OMP_CLAUSE_MAP_KIND (grp_first) 10528 == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 10529 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH) 10530 grp_first = OMP_CLAUSE_CHAIN (grp_first); 10531 } 10532 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10533 if (!to_specifically 10534 || GOMP_MAP_COPY_TO_P (first_kind) 10535 || first_kind == GOMP_MAP_ALLOC) 10536 { 10537 *base_group = decl_group; 10538 return true; 10539 } 10540 } 10541 10542 if (contained_in_struct 10543 && omp_mapped_by_containing_struct (grpmap, decl, base_group)) 10544 return true; 10545 10546 return false; 10547 } 10548 10549 /* If we have mappings INNER and OUTER, where INNER is a component access and 10550 OUTER is a mapping of the whole containing struct, check that the mappings 10551 are compatible. We'll be deleting the inner mapping, so we need to make 10552 sure the outer mapping does (at least) the same transfers to/from the device 10553 as the inner mapping. */ 10554 10555 bool 10556 omp_check_mapping_compatibility (location_t loc, 10557 omp_mapping_group *outer, 10558 omp_mapping_group *inner) 10559 { 10560 tree first_outer = *outer->grp_start, first_inner = *inner->grp_start; 10561 10562 gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP); 10563 gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP); 10564 10565 enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer); 10566 enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner); 10567 10568 if (outer_kind == inner_kind) 10569 return true; 10570 10571 switch (outer_kind) 10572 { 10573 case GOMP_MAP_ALWAYS_TO: 10574 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10575 || inner_kind == GOMP_MAP_ALLOC 10576 || inner_kind == GOMP_MAP_TO) 10577 return true; 10578 break; 10579 10580 case GOMP_MAP_ALWAYS_FROM: 10581 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10582 || inner_kind == GOMP_MAP_RELEASE 10583 || inner_kind == GOMP_MAP_FROM) 10584 return true; 10585 break; 10586 10587 case GOMP_MAP_TO: 10588 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10589 || inner_kind == GOMP_MAP_ALLOC) 10590 return true; 10591 break; 10592 10593 case GOMP_MAP_FROM: 10594 if (inner_kind == GOMP_MAP_RELEASE 10595 || inner_kind == GOMP_MAP_FORCE_PRESENT) 10596 return true; 10597 break; 10598 10599 case GOMP_MAP_ALWAYS_TOFROM: 10600 case GOMP_MAP_TOFROM: 10601 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10602 || inner_kind == GOMP_MAP_ALLOC 10603 || inner_kind == GOMP_MAP_TO 10604 || inner_kind == GOMP_MAP_FROM 10605 || inner_kind == GOMP_MAP_TOFROM) 10606 return true; 10607 break; 10608 10609 default: 10610 ; 10611 } 10612 10613 error_at (loc, "data movement for component %qE is not compatible with " 10614 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner), 10615 OMP_CLAUSE_DECL (first_outer)); 10616 10617 return false; 10618 } 10619 10620 /* This function handles several cases where clauses on a mapping directive 10621 can interact with each other. 10622 10623 If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer 10624 on the same directive, change the mapping of the first node to 10625 ATTACH_DETACH. We should have detected that this will happen already in 10626 c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl 10627 as addressable. (If we didn't, bail out.) 10628 10629 If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're 10630 mapping the base pointer also, we may need to change the mapping type to 10631 ATTACH_DETACH and synthesize an alloc node for the reference itself. 10632 10633 If we have an ATTACH_DETACH node, this is an array section with a pointer 10634 base. If we're mapping the base on the same directive too, we can drop its 10635 mapping. However, if we have a reference to pointer, make other appropriate 10636 adjustments to the mapping nodes instead. 10637 10638 If we have an ATTACH_DETACH node with a Fortran pointer-set (array 10639 descriptor) mapping for a derived-type component, and we're also mapping the 10640 whole of the derived-type variable on another clause, the pointer-set 10641 mapping is removed. 10642 10643 If we have a component access but we're also mapping the whole of the 10644 containing struct, drop the former access. 10645 10646 If the expression is a component access, and we're also mapping a base 10647 pointer used in that component access in the same expression, change the 10648 mapping type of the latter to ALLOC (ready for processing by 10649 omp_build_struct_sibling_lists). */ 10650 10651 void 10652 omp_resolve_clause_dependencies (enum tree_code code, 10653 vec<omp_mapping_group> *groups, 10654 hash_map<tree_operand_hash_no_se, 10655 omp_mapping_group *> *grpmap) 10656 { 10657 int i; 10658 omp_mapping_group *grp; 10659 bool repair_chain = false; 10660 10661 FOR_EACH_VEC_ELT (*groups, i, grp) 10662 { 10663 tree grp_end = grp->grp_end; 10664 tree decl = OMP_CLAUSE_DECL (grp_end); 10665 10666 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP); 10667 10668 switch (OMP_CLAUSE_MAP_KIND (grp_end)) 10669 { 10670 case GOMP_MAP_FIRSTPRIVATE_POINTER: 10671 { 10672 omp_mapping_group *to_group 10673 = omp_get_nonfirstprivate_group (grpmap, decl); 10674 10675 if (!to_group || to_group == grp) 10676 continue; 10677 10678 tree grp_first = *to_group->grp_start; 10679 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10680 10681 if ((GOMP_MAP_COPY_TO_P (first_kind) 10682 || first_kind == GOMP_MAP_ALLOC) 10683 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end) 10684 != GOMP_MAP_FIRSTPRIVATE_POINTER)) 10685 { 10686 gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end))); 10687 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH); 10688 } 10689 } 10690 break; 10691 10692 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 10693 { 10694 tree ptr = build_fold_indirect_ref (decl); 10695 10696 omp_mapping_group *to_group 10697 = omp_get_nonfirstprivate_group (grpmap, ptr); 10698 10699 if (!to_group || to_group == grp) 10700 continue; 10701 10702 tree grp_first = *to_group->grp_start; 10703 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10704 10705 if (GOMP_MAP_COPY_TO_P (first_kind) 10706 || first_kind == GOMP_MAP_ALLOC) 10707 { 10708 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH); 10709 OMP_CLAUSE_DECL (grp_end) = ptr; 10710 if ((OMP_CLAUSE_CHAIN (*to_group->grp_start) 10711 == to_group->grp_end) 10712 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end) 10713 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 10714 { 10715 gcc_assert (TREE_ADDRESSABLE 10716 (OMP_CLAUSE_DECL (to_group->grp_end))); 10717 OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end, 10718 GOMP_MAP_ATTACH_DETACH); 10719 10720 location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end); 10721 tree alloc 10722 = build_omp_clause (loc, OMP_CLAUSE_MAP); 10723 OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC); 10724 tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL 10725 (to_group->grp_end)); 10726 tree char_ptr_type = build_pointer_type (char_type_node); 10727 OMP_CLAUSE_DECL (alloc) 10728 = build2 (MEM_REF, char_type_node, 10729 tmp, 10730 build_int_cst (char_ptr_type, 0)); 10731 OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp)); 10732 10733 OMP_CLAUSE_CHAIN (alloc) 10734 = OMP_CLAUSE_CHAIN (*to_group->grp_start); 10735 OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc; 10736 } 10737 } 10738 } 10739 break; 10740 10741 case GOMP_MAP_ATTACH_DETACH: 10742 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 10743 { 10744 tree base_ptr, referenced_ptr_node = NULL_TREE; 10745 10746 while (TREE_CODE (decl) == ARRAY_REF) 10747 decl = TREE_OPERAND (decl, 0); 10748 10749 if (TREE_CODE (decl) == INDIRECT_REF) 10750 decl = TREE_OPERAND (decl, 0); 10751 10752 /* Only component accesses. */ 10753 if (DECL_P (decl)) 10754 continue; 10755 10756 /* We want the pointer itself when checking if the base pointer is 10757 mapped elsewhere in the same directive -- if we have a 10758 reference to the pointer, don't use that. */ 10759 10760 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 10761 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE) 10762 { 10763 referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start); 10764 base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node); 10765 } 10766 else 10767 base_ptr = decl; 10768 10769 gomp_map_kind zlas_kind 10770 = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA) 10771 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION; 10772 10773 if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE) 10774 { 10775 /* If we map the base TO, and we're doing an attachment, we can 10776 skip the TO mapping altogether and create an ALLOC mapping 10777 instead, since the attachment will overwrite the device 10778 pointer in that location immediately anyway. Otherwise, 10779 change our mapping to 10780 GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the 10781 attachment target has not been copied to the device already 10782 by some earlier directive. */ 10783 10784 bool base_mapped_to = false; 10785 10786 omp_mapping_group *base_group; 10787 10788 if (omp_directive_maps_explicitly (grpmap, base_ptr, 10789 &base_group, false, true, 10790 false)) 10791 { 10792 if (referenced_ptr_node) 10793 { 10794 base_mapped_to = true; 10795 if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end) 10796 == GOMP_MAP_ATTACH_DETACH) 10797 && (OMP_CLAUSE_CHAIN (*base_group->grp_start) 10798 == base_group->grp_end)) 10799 { 10800 OMP_CLAUSE_CHAIN (*base_group->grp_start) 10801 = OMP_CLAUSE_CHAIN (base_group->grp_end); 10802 base_group->grp_end = *base_group->grp_start; 10803 repair_chain = true; 10804 } 10805 } 10806 else 10807 { 10808 base_group->deleted = true; 10809 OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1; 10810 } 10811 } 10812 10813 /* We're dealing with a reference to a pointer, and we are 10814 attaching both the reference and the pointer. We know the 10815 reference itself is on the target, because we are going to 10816 create an ALLOC node for it in accumulate_sibling_list. The 10817 pointer might be on the target already or it might not, but 10818 if it isn't then it's not an error, so use 10819 GOMP_MAP_ATTACH_ZLAS for it. */ 10820 if (!base_mapped_to && referenced_ptr_node) 10821 OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind); 10822 10823 omp_mapping_group *struct_group; 10824 tree desc; 10825 if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start)) 10826 && omp_map_clause_descriptor_p (desc) 10827 && omp_mapped_by_containing_struct (grpmap, decl, 10828 &struct_group)) 10829 /* If we have a pointer set but we're mapping (or unmapping) 10830 the whole of the containing struct, we can remove the 10831 pointer set mapping. */ 10832 OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc); 10833 } 10834 else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE 10835 && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr))) 10836 == ARRAY_TYPE) 10837 && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION 10838 (*grp->grp_start)) 10839 OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind); 10840 } 10841 break; 10842 10843 case GOMP_MAP_ATTACH: 10844 /* Ignore standalone attach here. */ 10845 break; 10846 10847 default: 10848 { 10849 omp_mapping_group *struct_group; 10850 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group) 10851 && *grp->grp_start == grp_end) 10852 { 10853 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end), 10854 struct_group, grp); 10855 /* Remove the whole of this mapping -- redundant. */ 10856 grp->deleted = true; 10857 } 10858 10859 tree base = decl; 10860 while ((base = omp_get_base_pointer (base))) 10861 { 10862 omp_mapping_group *base_group; 10863 10864 if (omp_directive_maps_explicitly (grpmap, base, &base_group, 10865 true, true, false)) 10866 { 10867 tree grp_first = *base_group->grp_start; 10868 OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC); 10869 } 10870 } 10871 } 10872 } 10873 } 10874 10875 if (repair_chain) 10876 { 10877 /* Group start pointers may have become detached from the 10878 OMP_CLAUSE_CHAIN of previous groups if elements were removed from the 10879 end of those groups. Fix that now. */ 10880 tree *new_next = NULL; 10881 FOR_EACH_VEC_ELT (*groups, i, grp) 10882 { 10883 if (new_next) 10884 grp->grp_start = new_next; 10885 10886 new_next = &OMP_CLAUSE_CHAIN (grp->grp_end); 10887 } 10888 } 10889 } 10890 10891 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only 10892 clause dependencies we handle for now are struct element mappings and 10893 whole-struct mappings on the same directive, and duplicate clause 10894 detection. */ 10895 10896 void 10897 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups, 10898 hash_map<tree_operand_hash_no_se, 10899 omp_mapping_group *> *grpmap) 10900 { 10901 int i; 10902 omp_mapping_group *grp; 10903 hash_set<tree_operand_hash> *seen_components = NULL; 10904 hash_set<tree_operand_hash> *shown_error = NULL; 10905 10906 FOR_EACH_VEC_ELT (*groups, i, grp) 10907 { 10908 tree grp_end = grp->grp_end; 10909 tree decl = OMP_CLAUSE_DECL (grp_end); 10910 10911 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP); 10912 10913 if (DECL_P (grp_end)) 10914 continue; 10915 10916 tree c = OMP_CLAUSE_DECL (*grp->grp_start); 10917 while (TREE_CODE (c) == ARRAY_REF) 10918 c = TREE_OPERAND (c, 0); 10919 if (TREE_CODE (c) != COMPONENT_REF) 10920 continue; 10921 if (!seen_components) 10922 seen_components = new hash_set<tree_operand_hash> (); 10923 if (!shown_error) 10924 shown_error = new hash_set<tree_operand_hash> (); 10925 if (seen_components->contains (c) 10926 && !shown_error->contains (c)) 10927 { 10928 error_at (OMP_CLAUSE_LOCATION (grp_end), 10929 "%qE appears more than once in map clauses", 10930 OMP_CLAUSE_DECL (grp_end)); 10931 shown_error->add (c); 10932 } 10933 else 10934 seen_components->add (c); 10935 10936 omp_mapping_group *struct_group; 10937 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group) 10938 && *grp->grp_start == grp_end) 10939 { 10940 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end), 10941 struct_group, grp); 10942 /* Remove the whole of this mapping -- redundant. */ 10943 grp->deleted = true; 10944 } 10945 } 10946 10947 if (seen_components) 10948 delete seen_components; 10949 if (shown_error) 10950 delete shown_error; 10951 } 10952 10953 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain 10954 is linked to the previous node pointed to by INSERT_AT. */ 10955 10956 static tree * 10957 omp_siblist_insert_node_after (tree newnode, tree *insert_at) 10958 { 10959 OMP_CLAUSE_CHAIN (newnode) = *insert_at; 10960 *insert_at = newnode; 10961 return &OMP_CLAUSE_CHAIN (newnode); 10962 } 10963 10964 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is 10965 pointed to by chain MOVE_AFTER instead. */ 10966 10967 static void 10968 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after) 10969 { 10970 gcc_assert (node == *old_pos); 10971 *old_pos = OMP_CLAUSE_CHAIN (node); 10972 OMP_CLAUSE_CHAIN (node) = *move_after; 10973 *move_after = node; 10974 } 10975 10976 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to 10977 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no 10978 new nodes are prepended to the list before splicing into the new position. 10979 Return the position we should continue scanning the list at, or NULL to 10980 stay where we were. */ 10981 10982 static tree * 10983 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node, 10984 tree *move_after) 10985 { 10986 if (first_ptr == move_after) 10987 return NULL; 10988 10989 tree tmp = *first_ptr; 10990 *first_ptr = OMP_CLAUSE_CHAIN (last_node); 10991 OMP_CLAUSE_CHAIN (last_node) = *move_after; 10992 *move_after = tmp; 10993 10994 return first_ptr; 10995 } 10996 10997 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and 10998 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain 10999 pointer MOVE_AFTER. 11000 11001 The latter list was previously part of the OMP clause list, and the former 11002 (prepended) part is comprised of new nodes. 11003 11004 We start with a list of nodes starting with a struct mapping node. We 11005 rearrange the list so that new nodes starting from FIRST_NEW and whose last 11006 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by 11007 the group of mapping nodes we are currently processing (from the chain 11008 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain 11009 we should continue processing from, or NULL to stay where we were. 11010 11011 The transformation (in the case where MOVE_AFTER and FIRST_PTR are 11012 different) is worked through below. Here we are processing LAST_NODE, and 11013 FIRST_PTR points at the preceding mapping clause: 11014 11015 #. mapping node chain 11016 --------------------------------------------------- 11017 A. struct_node [->B] 11018 B. comp_1 [->C] 11019 C. comp_2 [->D (move_after)] 11020 D. map_to_3 [->E] 11021 E. attach_3 [->F (first_ptr)] 11022 F. map_to_4 [->G (continue_at)] 11023 G. attach_4 (last_node) [->H] 11024 H. ... 11025 11026 *last_new_tail = *first_ptr; 11027 11028 I. new_node (first_new) [->F (last_new_tail)] 11029 11030 *first_ptr = OMP_CLAUSE_CHAIN (last_node) 11031 11032 #. mapping node chain 11033 ---------------------------------------------------- 11034 A. struct_node [->B] 11035 B. comp_1 [->C] 11036 C. comp_2 [->D (move_after)] 11037 D. map_to_3 [->E] 11038 E. attach_3 [->H (first_ptr)] 11039 F. map_to_4 [->G (continue_at)] 11040 G. attach_4 (last_node) [->H] 11041 H. ... 11042 11043 I. new_node (first_new) [->F (last_new_tail)] 11044 11045 OMP_CLAUSE_CHAIN (last_node) = *move_after; 11046 11047 #. mapping node chain 11048 --------------------------------------------------- 11049 A. struct_node [->B] 11050 B. comp_1 [->C] 11051 C. comp_2 [->D (move_after)] 11052 D. map_to_3 [->E] 11053 E. attach_3 [->H (continue_at)] 11054 F. map_to_4 [->G] 11055 G. attach_4 (last_node) [->D] 11056 H. ... 11057 11058 I. new_node (first_new) [->F (last_new_tail)] 11059 11060 *move_after = first_new; 11061 11062 #. mapping node chain 11063 --------------------------------------------------- 11064 A. struct_node [->B] 11065 B. comp_1 [->C] 11066 C. comp_2 [->I (move_after)] 11067 D. map_to_3 [->E] 11068 E. attach_3 [->H (continue_at)] 11069 F. map_to_4 [->G] 11070 G. attach_4 (last_node) [->D] 11071 H. ... 11072 I. new_node (first_new) [->F (last_new_tail)] 11073 11074 or, in order: 11075 11076 #. mapping node chain 11077 --------------------------------------------------- 11078 A. struct_node [->B] 11079 B. comp_1 [->C] 11080 C. comp_2 [->I (move_after)] 11081 I. new_node (first_new) [->F (last_new_tail)] 11082 F. map_to_4 [->G] 11083 G. attach_4 (last_node) [->D] 11084 D. map_to_3 [->E] 11085 E. attach_3 [->H (continue_at)] 11086 H. ... 11087 */ 11088 11089 static tree * 11090 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail, 11091 tree *first_ptr, tree last_node, 11092 tree *move_after) 11093 { 11094 tree *continue_at = NULL; 11095 *last_new_tail = *first_ptr; 11096 if (first_ptr == move_after) 11097 *move_after = first_new; 11098 else 11099 { 11100 *first_ptr = OMP_CLAUSE_CHAIN (last_node); 11101 continue_at = first_ptr; 11102 OMP_CLAUSE_CHAIN (last_node) = *move_after; 11103 *move_after = first_new; 11104 } 11105 return continue_at; 11106 } 11107 11108 static omp_addr_token * 11109 omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens) 11110 { 11111 using namespace omp_addr_tokenizer; 11112 int idx = addr_tokens.length () - 1; 11113 gcc_assert (idx >= 0); 11114 if (addr_tokens[idx]->type != ACCESS_METHOD) 11115 return addr_tokens[idx]; 11116 while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD) 11117 idx--; 11118 return addr_tokens[idx]; 11119 } 11120 11121 /* Mapping struct members causes an additional set of nodes to be created, 11122 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the 11123 number of members being mapped, in order of ascending position (address or 11124 bitwise). 11125 11126 We scan through the list of mapping clauses, calling this function for each 11127 struct member mapping we find, and build up the list of mappings after the 11128 initial GOMP_MAP_STRUCT node. For pointer members, these will be 11129 newly-created ALLOC nodes. For non-pointer members, the existing mapping is 11130 moved into place in the sorted list. 11131 11132 struct { 11133 int *a; 11134 int *b; 11135 int c; 11136 int *d; 11137 }; 11138 11139 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c, 11140 struct.d[0:n]) 11141 11142 GOMP_MAP_STRUCT (4) 11143 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs] 11144 GOMP_MAP_ALLOC (struct.a) 11145 GOMP_MAP_ALLOC (struct.b) 11146 GOMP_MAP_TO (struct.c) 11147 GOMP_MAP_ALLOC (struct.d) 11148 ... 11149 11150 In the case where we are mapping references to pointers, or in Fortran if 11151 we are mapping an array with a descriptor, additional nodes may be created 11152 after the struct node list also. 11153 11154 The return code is either a pointer to the next node to process (if the 11155 list has been rearranged), else NULL to continue with the next node in the 11156 original list. */ 11157 11158 static tree * 11159 omp_accumulate_sibling_list (enum omp_region_type region_type, 11160 enum tree_code code, 11161 hash_map<tree_operand_hash, tree> 11162 *&struct_map_to_clause, 11163 hash_map<tree_operand_hash_no_se, 11164 omp_mapping_group *> *group_map, 11165 tree *grp_start_p, tree grp_end, 11166 vec<omp_addr_token *> &addr_tokens, tree **inner, 11167 bool *fragile_p, bool reprocessing_struct, 11168 tree **added_tail) 11169 { 11170 using namespace omp_addr_tokenizer; 11171 poly_offset_int coffset; 11172 poly_int64 cbitpos; 11173 tree ocd = OMP_CLAUSE_DECL (grp_end); 11174 bool openmp = !(region_type & ORT_ACC); 11175 bool target = (region_type & ORT_TARGET) != 0; 11176 tree *continue_at = NULL; 11177 11178 while (TREE_CODE (ocd) == ARRAY_REF) 11179 ocd = TREE_OPERAND (ocd, 0); 11180 11181 if (*fragile_p) 11182 { 11183 omp_mapping_group *to_group 11184 = omp_get_nonfirstprivate_group (group_map, ocd, true); 11185 11186 if (to_group) 11187 return NULL; 11188 } 11189 11190 omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens); 11191 if (last_token->type == ACCESS_METHOD) 11192 { 11193 switch (last_token->u.access_kind) 11194 { 11195 case ACCESS_REF: 11196 case ACCESS_REF_TO_POINTER: 11197 case ACCESS_REF_TO_POINTER_OFFSET: 11198 case ACCESS_INDEXED_REF_TO_ARRAY: 11199 /* We may see either a bare reference or a dereferenced 11200 "convert_from_reference"-like one here. Handle either way. */ 11201 if (TREE_CODE (ocd) == INDIRECT_REF) 11202 ocd = TREE_OPERAND (ocd, 0); 11203 gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE); 11204 break; 11205 11206 default: 11207 ; 11208 } 11209 } 11210 11211 bool variable_offset; 11212 tree base 11213 = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset); 11214 11215 int base_token; 11216 for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--) 11217 { 11218 if (addr_tokens[base_token]->type == ARRAY_BASE 11219 || addr_tokens[base_token]->type == STRUCTURE_BASE) 11220 break; 11221 } 11222 11223 /* The two expressions in the assertion below aren't quite the same: if we 11224 have 'struct_base_decl access_indexed_array' for something like 11225 "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr 11226 will be "myvar[2]" -- the actual base of the structure. 11227 The former interpretation leads to a strange situation where we get 11228 struct(myvar) alloc(myvar[2].ptr1) 11229 That is, the array of structures is kind of treated as one big structure 11230 for the purposes of gathering sibling lists, etc. */ 11231 /* gcc_assert (base == addr_tokens[base_token]->expr); */ 11232 11233 bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end) 11234 == GOMP_MAP_ATTACH_DETACH) 11235 || (OMP_CLAUSE_MAP_KIND (grp_end) 11236 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)); 11237 bool has_descriptor = false; 11238 if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 11239 { 11240 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p); 11241 if (grp_mid && omp_map_clause_descriptor_p (grp_mid)) 11242 has_descriptor = true; 11243 } 11244 11245 if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL) 11246 { 11247 enum gomp_map_kind str_kind = GOMP_MAP_STRUCT; 11248 11249 if (struct_map_to_clause == NULL) 11250 struct_map_to_clause = new hash_map<tree_operand_hash, tree>; 11251 11252 if (variable_offset) 11253 str_kind = GOMP_MAP_STRUCT_UNORD; 11254 11255 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 11256 11257 OMP_CLAUSE_SET_MAP_KIND (l, str_kind); 11258 OMP_CLAUSE_DECL (l) = unshare_expr (base); 11259 OMP_CLAUSE_SIZE (l) = size_int (1); 11260 11261 struct_map_to_clause->put (base, l); 11262 11263 /* On first iterating through the clause list, we insert the struct node 11264 just before the component access node that triggers the initial 11265 omp_accumulate_sibling_list call for a particular sibling list (and 11266 it then forms the first entry in that list). When reprocessing 11267 struct bases that are themselves component accesses, we insert the 11268 struct node on an off-side list to avoid inserting the new 11269 GOMP_MAP_STRUCT into the middle of the old one. */ 11270 tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p; 11271 11272 if (has_descriptor) 11273 { 11274 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p); 11275 if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA) 11276 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE); 11277 tree sc = *insert_node_pos; 11278 OMP_CLAUSE_CHAIN (l) = desc; 11279 OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc); 11280 OMP_CLAUSE_CHAIN (desc) = sc; 11281 *insert_node_pos = l; 11282 } 11283 else if (attach_detach) 11284 { 11285 tree extra_node; 11286 tree alloc_node 11287 = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end, 11288 &extra_node); 11289 tree *tail; 11290 OMP_CLAUSE_CHAIN (l) = alloc_node; 11291 11292 if (extra_node) 11293 { 11294 OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos; 11295 OMP_CLAUSE_CHAIN (alloc_node) = extra_node; 11296 tail = &OMP_CLAUSE_CHAIN (extra_node); 11297 } 11298 else 11299 { 11300 OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos; 11301 tail = &OMP_CLAUSE_CHAIN (alloc_node); 11302 } 11303 11304 /* For OpenMP semantics, we don't want to implicitly allocate 11305 space for the pointer here for non-compute regions (e.g. "enter 11306 data"). A FRAGILE_P node is only being created so that 11307 omp-low.cc is able to rewrite the struct properly. 11308 For references (to pointers), we want to actually allocate the 11309 space for the reference itself in the sorted list following the 11310 struct node. 11311 For pointers, we want to allocate space if we had an explicit 11312 mapping of the attachment point, but not otherwise. */ 11313 if (*fragile_p 11314 || (openmp 11315 && !target 11316 && attach_detach 11317 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE 11318 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end))) 11319 { 11320 if (!lang_GNU_Fortran ()) 11321 /* In Fortran, pointers are dereferenced automatically, but may 11322 be unassociated. So we still want to allocate space for the 11323 pointer (as the base for an attach operation that should be 11324 present in the same directive's clause list also). */ 11325 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node; 11326 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1; 11327 } 11328 11329 *insert_node_pos = l; 11330 11331 if (reprocessing_struct) 11332 { 11333 /* When reprocessing a struct node group used as the base of a 11334 subcomponent access, if we have a reference-to-pointer base, 11335 we will see: 11336 struct(**ptr) attach(*ptr) 11337 whereas for a non-reprocess-struct group, we see, e.g.: 11338 tofrom(**ptr) attach(*ptr) attach(ptr) 11339 and we create the "alloc" for the second "attach", i.e. 11340 for the reference itself. When reprocessing a struct group we 11341 thus change the pointer attachment into a reference attachment 11342 by stripping the indirection. (The attachment of the 11343 referenced pointer must happen elsewhere, either on the same 11344 directive, or otherwise.) */ 11345 tree adecl = OMP_CLAUSE_DECL (alloc_node); 11346 11347 if ((TREE_CODE (adecl) == INDIRECT_REF 11348 || (TREE_CODE (adecl) == MEM_REF 11349 && integer_zerop (TREE_OPERAND (adecl, 1)))) 11350 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0))) 11351 == REFERENCE_TYPE) 11352 && (TREE_CODE (TREE_TYPE (TREE_TYPE 11353 (TREE_OPERAND (adecl, 0)))) == POINTER_TYPE)) 11354 OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0); 11355 11356 *added_tail = tail; 11357 } 11358 } 11359 else 11360 { 11361 gcc_assert (*grp_start_p == grp_end); 11362 if (reprocessing_struct) 11363 { 11364 /* If we don't have an attach/detach node, this is a 11365 "target data" directive or similar, not an offload region. 11366 Synthesize an "alloc" node using just the initiating 11367 GOMP_MAP_STRUCT decl. */ 11368 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA 11369 || code == OACC_EXIT_DATA) 11370 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 11371 tree alloc_node 11372 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11373 OMP_CLAUSE_MAP); 11374 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k); 11375 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr); 11376 OMP_CLAUSE_SIZE (alloc_node) 11377 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node))); 11378 11379 OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l); 11380 OMP_CLAUSE_CHAIN (l) = alloc_node; 11381 *insert_node_pos = l; 11382 *added_tail = &OMP_CLAUSE_CHAIN (alloc_node); 11383 } 11384 else 11385 grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos); 11386 } 11387 11388 unsigned last_access = base_token + 1; 11389 11390 while (last_access + 1 < addr_tokens.length () 11391 && addr_tokens[last_access + 1]->type == ACCESS_METHOD) 11392 last_access++; 11393 11394 if ((region_type & ORT_TARGET) 11395 && addr_tokens[base_token + 1]->type == ACCESS_METHOD) 11396 { 11397 bool base_ref = false; 11398 access_method_kinds access_kind 11399 = addr_tokens[last_access]->u.access_kind; 11400 11401 switch (access_kind) 11402 { 11403 case ACCESS_DIRECT: 11404 case ACCESS_INDEXED_ARRAY: 11405 return NULL; 11406 11407 case ACCESS_REF: 11408 case ACCESS_REF_TO_POINTER: 11409 case ACCESS_REF_TO_POINTER_OFFSET: 11410 case ACCESS_INDEXED_REF_TO_ARRAY: 11411 base_ref = true; 11412 break; 11413 11414 default: 11415 ; 11416 } 11417 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11418 OMP_CLAUSE_MAP); 11419 enum gomp_map_kind mkind; 11420 omp_mapping_group *decl_group; 11421 tree use_base; 11422 switch (access_kind) 11423 { 11424 case ACCESS_POINTER: 11425 case ACCESS_POINTER_OFFSET: 11426 use_base = addr_tokens[last_access]->expr; 11427 break; 11428 case ACCESS_REF_TO_POINTER: 11429 case ACCESS_REF_TO_POINTER_OFFSET: 11430 use_base 11431 = build_fold_indirect_ref (addr_tokens[last_access]->expr); 11432 break; 11433 default: 11434 use_base = addr_tokens[base_token]->expr; 11435 } 11436 bool mapped_to_p 11437 = omp_directive_maps_explicitly (group_map, use_base, &decl_group, 11438 true, false, true); 11439 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11440 && DECL_P (addr_tokens[last_access]->expr) 11441 && !mapped_to_p) 11442 mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE 11443 : GOMP_MAP_FIRSTPRIVATE_POINTER; 11444 else 11445 mkind = GOMP_MAP_ATTACH_DETACH; 11446 11447 OMP_CLAUSE_SET_MAP_KIND (c2, mkind); 11448 /* If we have a reference to pointer base, we want to attach the 11449 pointer here, not the reference. The reference attachment happens 11450 elsewhere. */ 11451 bool ref_to_ptr 11452 = (access_kind == ACCESS_REF_TO_POINTER 11453 || access_kind == ACCESS_REF_TO_POINTER_OFFSET); 11454 tree sdecl = addr_tokens[last_access]->expr; 11455 tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl) 11456 : sdecl; 11457 /* For the FIRSTPRIVATE_REFERENCE after the struct node, we 11458 want to use the reference itself for the decl, but we 11459 still want to use the pointer to calculate the bias. */ 11460 OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH) 11461 ? sdecl_ptr : sdecl; 11462 sdecl = sdecl_ptr; 11463 tree baddr = build_fold_addr_expr (base); 11464 baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end), 11465 ptrdiff_type_node, baddr); 11466 tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end), 11467 ptrdiff_type_node, sdecl); 11468 OMP_CLAUSE_SIZE (c2) 11469 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR, 11470 ptrdiff_type_node, baddr, decladdr); 11471 /* Insert after struct node. */ 11472 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l); 11473 OMP_CLAUSE_CHAIN (l) = c2; 11474 11475 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11476 && (addr_tokens[base_token]->u.structure_base_kind 11477 == BASE_COMPONENT_EXPR) 11478 && mkind == GOMP_MAP_ATTACH_DETACH 11479 && addr_tokens[last_access]->u.access_kind != ACCESS_REF) 11480 { 11481 *inner = insert_node_pos; 11482 if (openmp) 11483 *fragile_p = true; 11484 return NULL; 11485 } 11486 } 11487 11488 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11489 && (addr_tokens[base_token]->u.structure_base_kind 11490 == BASE_COMPONENT_EXPR) 11491 && addr_tokens[last_access]->u.access_kind == ACCESS_REF) 11492 *inner = insert_node_pos; 11493 11494 return NULL; 11495 } 11496 else if (struct_map_to_clause) 11497 { 11498 tree *osc = struct_map_to_clause->get (base); 11499 tree *sc = NULL, *scp = NULL; 11500 bool unordered = false; 11501 11502 if (osc && OMP_CLAUSE_MAP_KIND (*osc) == GOMP_MAP_STRUCT_UNORD) 11503 unordered = true; 11504 11505 unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc)); 11506 sc = &OMP_CLAUSE_CHAIN (*osc); 11507 /* The struct mapping might be immediately followed by a 11508 FIRSTPRIVATE_POINTER, FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH -- 11509 if it's an indirect access or a reference, or if the structure base 11510 is not a decl. The FIRSTPRIVATE_* nodes are removed in omp-low.cc 11511 after they have been processed there, and ATTACH_DETACH nodes are 11512 recomputed and moved out of the GOMP_MAP_STRUCT construct once 11513 sibling list building is complete. */ 11514 if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER 11515 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 11516 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH) 11517 sc = &OMP_CLAUSE_CHAIN (*sc); 11518 for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc)) 11519 if (attach_detach && sc == grp_start_p) 11520 break; 11521 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF 11522 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF 11523 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF) 11524 break; 11525 else 11526 { 11527 tree sc_decl = OMP_CLAUSE_DECL (*sc); 11528 poly_offset_int offset; 11529 poly_int64 bitpos; 11530 11531 if (TREE_CODE (sc_decl) == ARRAY_REF) 11532 { 11533 while (TREE_CODE (sc_decl) == ARRAY_REF) 11534 sc_decl = TREE_OPERAND (sc_decl, 0); 11535 if (TREE_CODE (sc_decl) != COMPONENT_REF 11536 || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE) 11537 break; 11538 } 11539 else if (INDIRECT_REF_P (sc_decl) 11540 && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF 11541 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0))) 11542 == REFERENCE_TYPE)) 11543 sc_decl = TREE_OPERAND (sc_decl, 0); 11544 11545 bool variable_offset2; 11546 tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset, 11547 &variable_offset2); 11548 if (!base2 || !operand_equal_p (base2, base, 0)) 11549 break; 11550 if (scp) 11551 continue; 11552 if (variable_offset2) 11553 { 11554 OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD); 11555 unordered = true; 11556 break; 11557 } 11558 else if ((region_type & ORT_ACC) != 0) 11559 { 11560 /* For OpenACC, allow (ignore) duplicate struct accesses in 11561 the middle of a mapping clause, e.g. "mystruct->foo" in: 11562 copy(mystruct->foo->bar) copy(mystruct->foo->qux). */ 11563 if (reprocessing_struct 11564 && known_eq (coffset, offset) 11565 && known_eq (cbitpos, bitpos)) 11566 return NULL; 11567 } 11568 else if (known_eq (coffset, offset) 11569 && known_eq (cbitpos, bitpos)) 11570 { 11571 /* Having two struct members at the same offset doesn't work, 11572 so make sure we don't. (We're allowed to ignore this. 11573 Should we report the error?) */ 11574 /*error_at (OMP_CLAUSE_LOCATION (grp_end), 11575 "duplicate struct member %qE in map clauses", 11576 OMP_CLAUSE_DECL (grp_end));*/ 11577 return NULL; 11578 } 11579 if (maybe_lt (coffset, offset) 11580 || (known_eq (coffset, offset) 11581 && maybe_lt (cbitpos, bitpos))) 11582 { 11583 if (attach_detach) 11584 scp = sc; 11585 else 11586 break; 11587 } 11588 } 11589 11590 /* If this is an unordered struct, just insert the new element at the 11591 end of the list. */ 11592 if (unordered) 11593 { 11594 for (; i < elems; i++) 11595 sc = &OMP_CLAUSE_CHAIN (*sc); 11596 scp = NULL; 11597 } 11598 11599 OMP_CLAUSE_SIZE (*osc) 11600 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node); 11601 11602 if (reprocessing_struct) 11603 { 11604 /* If we're reprocessing a struct node, we don't want to do most of 11605 the list manipulation below. We only need to handle the (pointer 11606 or reference) attach/detach case. */ 11607 tree extra_node, alloc_node; 11608 if (has_descriptor) 11609 gcc_unreachable (); 11610 else if (attach_detach) 11611 alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p, 11612 grp_end, &extra_node); 11613 else 11614 { 11615 /* If we don't have an attach/detach node, this is a 11616 "target data" directive or similar, not an offload region. 11617 Synthesize an "alloc" node using just the initiating 11618 GOMP_MAP_STRUCT decl. */ 11619 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA 11620 || code == OACC_EXIT_DATA) 11621 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 11622 alloc_node 11623 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11624 OMP_CLAUSE_MAP); 11625 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k); 11626 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr); 11627 OMP_CLAUSE_SIZE (alloc_node) 11628 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node))); 11629 } 11630 11631 if (scp) 11632 omp_siblist_insert_node_after (alloc_node, scp); 11633 else 11634 { 11635 tree *new_end = omp_siblist_insert_node_after (alloc_node, sc); 11636 if (sc == *added_tail) 11637 *added_tail = new_end; 11638 } 11639 11640 return NULL; 11641 } 11642 11643 if (has_descriptor) 11644 { 11645 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p); 11646 if (code == OMP_TARGET_EXIT_DATA 11647 || code == OACC_EXIT_DATA) 11648 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE); 11649 omp_siblist_move_node_after (desc, 11650 &OMP_CLAUSE_CHAIN (*grp_start_p), 11651 scp ? scp : sc); 11652 } 11653 else if (attach_detach) 11654 { 11655 tree cl = NULL_TREE, extra_node; 11656 tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p, 11657 grp_end, &extra_node); 11658 tree *tail_chain = NULL; 11659 11660 if (*fragile_p 11661 || (openmp 11662 && !target 11663 && attach_detach 11664 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE 11665 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end))) 11666 { 11667 if (!lang_GNU_Fortran ()) 11668 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node; 11669 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1; 11670 } 11671 11672 /* Here, we have: 11673 11674 grp_end : the last (or only) node in this group. 11675 grp_start_p : pointer to the first node in a pointer mapping group 11676 up to and including GRP_END. 11677 sc : pointer to the chain for the end of the struct component 11678 list. 11679 scp : pointer to the chain for the sorted position at which we 11680 should insert in the middle of the struct component list 11681 (else NULL to insert at end). 11682 alloc_node : the "alloc" node for the structure (pointer-type) 11683 component. We insert at SCP (if present), else SC 11684 (the end of the struct component list). 11685 extra_node : a newly-synthesized node for an additional indirect 11686 pointer mapping or a Fortran pointer set, if needed. 11687 cl : first node to prepend before grp_start_p. 11688 tail_chain : pointer to chain of last prepended node. 11689 11690 The general idea is we move the nodes for this struct mapping 11691 together: the alloc node goes into the sorted list directly after 11692 the struct mapping, and any extra nodes (together with the nodes 11693 mapping arrays pointed to by struct components) get moved after 11694 that list. When SCP is NULL, we insert the nodes at SC, i.e. at 11695 the end of the struct component mapping list. It's important that 11696 the alloc_node comes first in that case because it's part of the 11697 sorted component mapping list (but subsequent nodes are not!). */ 11698 11699 if (scp) 11700 omp_siblist_insert_node_after (alloc_node, scp); 11701 11702 /* Make [cl,tail_chain] a list of the alloc node (if we haven't 11703 already inserted it) and the extra_node (if it is present). The 11704 list can be empty if we added alloc_node above and there is no 11705 extra node. */ 11706 if (scp && extra_node) 11707 { 11708 cl = extra_node; 11709 tail_chain = &OMP_CLAUSE_CHAIN (extra_node); 11710 } 11711 else if (extra_node) 11712 { 11713 OMP_CLAUSE_CHAIN (alloc_node) = extra_node; 11714 cl = alloc_node; 11715 tail_chain = &OMP_CLAUSE_CHAIN (extra_node); 11716 } 11717 else if (!scp) 11718 { 11719 cl = alloc_node; 11720 tail_chain = &OMP_CLAUSE_CHAIN (alloc_node); 11721 } 11722 11723 continue_at 11724 = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain, 11725 grp_start_p, grp_end, 11726 sc) 11727 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc); 11728 } 11729 else if (*sc != grp_end) 11730 { 11731 gcc_assert (*grp_start_p == grp_end); 11732 11733 /* We are moving the current node back to a previous struct node: 11734 the node that used to point to the current node will now point to 11735 the next node. */ 11736 continue_at = grp_start_p; 11737 /* In the non-pointer case, the mapping clause itself is moved into 11738 the correct position in the struct component list, which in this 11739 case is just SC. */ 11740 omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc); 11741 } 11742 } 11743 return continue_at; 11744 } 11745 11746 /* Scan through GROUPS, and create sorted structure sibling lists without 11747 gimplifying. */ 11748 11749 static bool 11750 omp_build_struct_sibling_lists (enum tree_code code, 11751 enum omp_region_type region_type, 11752 vec<omp_mapping_group> *groups, 11753 hash_map<tree_operand_hash_no_se, 11754 omp_mapping_group *> **grpmap, 11755 tree *list_p) 11756 { 11757 using namespace omp_addr_tokenizer; 11758 unsigned i; 11759 omp_mapping_group *grp; 11760 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL; 11761 bool success = true; 11762 tree *new_next = NULL; 11763 tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end); 11764 tree added_nodes = NULL_TREE; 11765 tree *added_tail = &added_nodes; 11766 auto_vec<omp_mapping_group> pre_hwm_groups; 11767 11768 FOR_EACH_VEC_ELT (*groups, i, grp) 11769 { 11770 tree c = grp->grp_end; 11771 tree decl = OMP_CLAUSE_DECL (c); 11772 tree grp_end = grp->grp_end; 11773 auto_vec<omp_addr_token *> addr_tokens; 11774 tree sentinel = OMP_CLAUSE_CHAIN (grp_end); 11775 11776 if (new_next && !grp->reprocess_struct) 11777 grp->grp_start = new_next; 11778 11779 new_next = NULL; 11780 11781 tree *grp_start_p = grp->grp_start; 11782 11783 if (DECL_P (decl)) 11784 continue; 11785 11786 /* Skip groups we marked for deletion in 11787 {omp,oacc}_resolve_clause_dependencies. */ 11788 if (grp->deleted) 11789 continue; 11790 11791 if (OMP_CLAUSE_CHAIN (*grp_start_p) 11792 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 11793 { 11794 /* Don't process an array descriptor that isn't inside a derived type 11795 as a struct (the GOMP_MAP_POINTER following will have the form 11796 "var.data", but such mappings are handled specially). */ 11797 tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p); 11798 if (omp_map_clause_descriptor_p (grpmid) 11799 && DECL_P (OMP_CLAUSE_DECL (grpmid))) 11800 continue; 11801 } 11802 11803 tree expr = decl; 11804 11805 while (TREE_CODE (expr) == ARRAY_REF) 11806 expr = TREE_OPERAND (expr, 0); 11807 11808 if (!omp_parse_expr (addr_tokens, expr)) 11809 continue; 11810 11811 omp_addr_token *last_token 11812 = omp_first_chained_access_token (addr_tokens); 11813 11814 /* A mapping of a reference to a pointer member that doesn't specify an 11815 array section, etc., like this: 11816 *mystruct.ref_to_ptr 11817 should not be processed by the struct sibling-list handling code -- 11818 it just transfers the referenced pointer. 11819 11820 In contrast, the quite similar-looking construct: 11821 *mystruct.ptr 11822 which is equivalent to e.g. 11823 mystruct.ptr[0] 11824 *does* trigger sibling-list processing. 11825 11826 An exception for the former case is for "fragile" groups where the 11827 reference itself is not handled otherwise; this is subject to special 11828 handling in omp_accumulate_sibling_list also. */ 11829 11830 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 11831 && last_token->type == ACCESS_METHOD 11832 && last_token->u.access_kind == ACCESS_REF 11833 && !grp->fragile) 11834 continue; 11835 11836 tree d = decl; 11837 if (TREE_CODE (d) == ARRAY_REF) 11838 { 11839 while (TREE_CODE (d) == ARRAY_REF) 11840 d = TREE_OPERAND (d, 0); 11841 if (TREE_CODE (d) == COMPONENT_REF 11842 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 11843 decl = d; 11844 } 11845 if (d == decl 11846 && INDIRECT_REF_P (decl) 11847 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 11848 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 11849 == REFERENCE_TYPE) 11850 && (OMP_CLAUSE_MAP_KIND (c) 11851 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 11852 decl = TREE_OPERAND (decl, 0); 11853 11854 STRIP_NOPS (decl); 11855 11856 if (TREE_CODE (decl) != COMPONENT_REF) 11857 continue; 11858 11859 /* If we're mapping the whole struct in another node, skip adding this 11860 node to a sibling list. */ 11861 omp_mapping_group *wholestruct; 11862 if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c), 11863 &wholestruct)) 11864 continue; 11865 11866 if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET 11867 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH 11868 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH 11869 && code != OACC_UPDATE 11870 && code != OMP_TARGET_UPDATE) 11871 { 11872 if (error_operand_p (decl)) 11873 { 11874 success = false; 11875 goto error_out; 11876 } 11877 11878 tree stype = TREE_TYPE (decl); 11879 if (TREE_CODE (stype) == REFERENCE_TYPE) 11880 stype = TREE_TYPE (stype); 11881 if (TYPE_SIZE_UNIT (stype) == NULL 11882 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST) 11883 { 11884 error_at (OMP_CLAUSE_LOCATION (c), 11885 "mapping field %qE of variable length " 11886 "structure", OMP_CLAUSE_DECL (c)); 11887 success = false; 11888 goto error_out; 11889 } 11890 11891 tree *inner = NULL; 11892 bool fragile_p = grp->fragile; 11893 11894 new_next 11895 = omp_accumulate_sibling_list (region_type, code, 11896 struct_map_to_clause, *grpmap, 11897 grp_start_p, grp_end, addr_tokens, 11898 &inner, &fragile_p, 11899 grp->reprocess_struct, &added_tail); 11900 11901 if (inner) 11902 { 11903 omp_mapping_group newgrp; 11904 newgrp.grp_start = inner; 11905 if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner)) 11906 == GOMP_MAP_ATTACH_DETACH) 11907 newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner); 11908 else 11909 newgrp.grp_end = *inner; 11910 newgrp.mark = UNVISITED; 11911 newgrp.sibling = NULL; 11912 newgrp.deleted = false; 11913 newgrp.reprocess_struct = true; 11914 newgrp.fragile = fragile_p; 11915 newgrp.next = NULL; 11916 groups->safe_push (newgrp); 11917 11918 /* !!! Growing GROUPS might invalidate the pointers in the group 11919 map. Rebuild it here. This is a bit inefficient, but 11920 shouldn't happen very often. */ 11921 delete (*grpmap); 11922 *grpmap 11923 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups, 11924 sentinel); 11925 } 11926 } 11927 } 11928 11929 /* Delete groups marked for deletion above. At this point the order of the 11930 groups may no longer correspond to the order of the underlying list, 11931 which complicates this a little. First clear out OMP_CLAUSE_DECL for 11932 deleted nodes... */ 11933 11934 FOR_EACH_VEC_ELT (*groups, i, grp) 11935 if (grp->deleted) 11936 for (tree d = *grp->grp_start; 11937 d != OMP_CLAUSE_CHAIN (grp->grp_end); 11938 d = OMP_CLAUSE_CHAIN (d)) 11939 OMP_CLAUSE_DECL (d) = NULL_TREE; 11940 11941 /* ...then sweep through the list removing the now-empty nodes. */ 11942 11943 tail = list_p; 11944 while (*tail) 11945 { 11946 if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP 11947 && OMP_CLAUSE_DECL (*tail) == NULL_TREE) 11948 *tail = OMP_CLAUSE_CHAIN (*tail); 11949 else 11950 tail = &OMP_CLAUSE_CHAIN (*tail); 11951 } 11952 11953 /* Tack on the struct nodes added during nested struct reprocessing. */ 11954 if (added_nodes) 11955 { 11956 *tail = added_nodes; 11957 tail = added_tail; 11958 } 11959 11960 /* Now we have finished building the struct sibling lists, reprocess 11961 newly-added "attach" nodes: we need the address of the first 11962 mapped element of each struct sibling list for the bias of the attach 11963 operation -- not necessarily the base address of the whole struct. */ 11964 if (struct_map_to_clause) 11965 for (hash_map<tree_operand_hash, tree>::iterator iter 11966 = struct_map_to_clause->begin (); 11967 iter != struct_map_to_clause->end (); 11968 ++iter) 11969 { 11970 tree struct_node = (*iter).second; 11971 gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP); 11972 tree attach = OMP_CLAUSE_CHAIN (struct_node); 11973 11974 if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP 11975 || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH) 11976 continue; 11977 11978 OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH); 11979 11980 /* Sanity check: the standalone attach node will not work if we have 11981 an "enter data" operation (because for those, variables need to be 11982 mapped separately and attach nodes must be grouped together with the 11983 base they attach to). We should only have created the 11984 ATTACH_DETACH node after GOMP_MAP_STRUCT for a target region, so 11985 this should never be true. */ 11986 gcc_assert ((region_type & ORT_TARGET) != 0); 11987 11988 /* This is the first sorted node in the struct sibling list. Use it 11989 to recalculate the correct bias to use. 11990 (&first_node - attach_decl). 11991 For GOMP_MAP_STRUCT_UNORD, we need e.g. the 11992 min(min(min(first,second),third),fourth) element, because the 11993 elements aren't in any particular order. */ 11994 tree lowest_addr; 11995 if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD) 11996 { 11997 tree first_node = OMP_CLAUSE_CHAIN (attach); 11998 unsigned HOST_WIDE_INT num_mappings 11999 = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node)); 12000 lowest_addr = OMP_CLAUSE_DECL (first_node); 12001 lowest_addr = build_fold_addr_expr (lowest_addr); 12002 lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr); 12003 tree next_node = OMP_CLAUSE_CHAIN (first_node); 12004 while (num_mappings > 1) 12005 { 12006 tree tmp = OMP_CLAUSE_DECL (next_node); 12007 tmp = build_fold_addr_expr (tmp); 12008 tmp = fold_convert (pointer_sized_int_node, tmp); 12009 lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node, 12010 lowest_addr, tmp); 12011 next_node = OMP_CLAUSE_CHAIN (next_node); 12012 num_mappings--; 12013 } 12014 lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr); 12015 } 12016 else 12017 { 12018 tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach)); 12019 first_node = build_fold_addr_expr (first_node); 12020 lowest_addr = fold_convert (ptrdiff_type_node, first_node); 12021 } 12022 tree attach_decl = OMP_CLAUSE_DECL (attach); 12023 attach_decl = fold_convert (ptrdiff_type_node, attach_decl); 12024 OMP_CLAUSE_SIZE (attach) 12025 = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr, 12026 attach_decl); 12027 12028 /* Remove GOMP_MAP_ATTACH node from after struct node. */ 12029 OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach); 12030 /* ...and re-insert it at the end of our clause list. */ 12031 *tail = attach; 12032 OMP_CLAUSE_CHAIN (attach) = NULL_TREE; 12033 tail = &OMP_CLAUSE_CHAIN (attach); 12034 } 12035 12036 error_out: 12037 if (struct_map_to_clause) 12038 delete struct_map_to_clause; 12039 12040 return success; 12041 } 12042 12043 /* Scan the OMP clauses in *LIST_P, installing mappings into a new 12044 and previous omp contexts. */ 12045 12046 static void 12047 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, 12048 enum omp_region_type region_type, 12049 enum tree_code code) 12050 { 12051 using namespace omp_addr_tokenizer; 12052 struct gimplify_omp_ctx *ctx, *outer_ctx; 12053 tree c; 12054 tree *orig_list_p = list_p; 12055 int handled_depend_iterators = -1; 12056 int nowait = -1; 12057 12058 ctx = new_omp_context (region_type); 12059 ctx->code = code; 12060 outer_ctx = ctx->outer_context; 12061 if (code == OMP_TARGET) 12062 { 12063 if (!lang_GNU_Fortran ()) 12064 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY; 12065 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE; 12066 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran () 12067 ? GOVD_MAP : GOVD_FIRSTPRIVATE); 12068 } 12069 if (!lang_GNU_Fortran ()) 12070 switch (code) 12071 { 12072 case OMP_TARGET: 12073 case OMP_TARGET_DATA: 12074 case OMP_TARGET_ENTER_DATA: 12075 case OMP_TARGET_EXIT_DATA: 12076 case OACC_DECLARE: 12077 case OACC_HOST_DATA: 12078 case OACC_PARALLEL: 12079 case OACC_KERNELS: 12080 ctx->target_firstprivatize_array_bases = true; 12081 default: 12082 break; 12083 } 12084 12085 vec<omp_mapping_group> *groups = NULL; 12086 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL; 12087 unsigned grpnum = 0; 12088 tree *grp_start_p = NULL, grp_end = NULL_TREE; 12089 12090 if (code == OMP_TARGET 12091 || code == OMP_TARGET_DATA 12092 || code == OMP_TARGET_ENTER_DATA 12093 || code == OMP_TARGET_EXIT_DATA 12094 || code == OACC_DATA 12095 || code == OACC_KERNELS 12096 || code == OACC_PARALLEL 12097 || code == OACC_SERIAL 12098 || code == OACC_ENTER_DATA 12099 || code == OACC_EXIT_DATA 12100 || code == OACC_UPDATE 12101 || code == OACC_DECLARE) 12102 { 12103 groups = omp_gather_mapping_groups (list_p); 12104 12105 if (groups) 12106 grpmap = omp_index_mapping_groups (groups); 12107 } 12108 12109 while ((c = *list_p) != NULL) 12110 { 12111 bool remove = false; 12112 bool notice_outer = true; 12113 bool map_descriptor; 12114 const char *check_non_private = NULL; 12115 unsigned int flags; 12116 tree decl; 12117 auto_vec<omp_addr_token *, 10> addr_tokens; 12118 12119 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end)) 12120 { 12121 grp_start_p = NULL; 12122 grp_end = NULL_TREE; 12123 } 12124 12125 switch (OMP_CLAUSE_CODE (c)) 12126 { 12127 case OMP_CLAUSE_PRIVATE: 12128 flags = GOVD_PRIVATE | GOVD_EXPLICIT; 12129 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c))) 12130 { 12131 flags |= GOVD_PRIVATE_OUTER_REF; 12132 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1; 12133 } 12134 else 12135 notice_outer = false; 12136 goto do_add; 12137 case OMP_CLAUSE_SHARED: 12138 flags = GOVD_SHARED | GOVD_EXPLICIT; 12139 goto do_add; 12140 case OMP_CLAUSE_FIRSTPRIVATE: 12141 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; 12142 check_non_private = "firstprivate"; 12143 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) 12144 { 12145 gcc_assert (code == OMP_TARGET); 12146 flags |= GOVD_FIRSTPRIVATE_IMPLICIT; 12147 } 12148 goto do_add; 12149 case OMP_CLAUSE_LASTPRIVATE: 12150 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 12151 switch (code) 12152 { 12153 case OMP_DISTRIBUTE: 12154 error_at (OMP_CLAUSE_LOCATION (c), 12155 "conditional %<lastprivate%> clause on " 12156 "%qs construct", "distribute"); 12157 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12158 break; 12159 case OMP_TASKLOOP: 12160 error_at (OMP_CLAUSE_LOCATION (c), 12161 "conditional %<lastprivate%> clause on " 12162 "%qs construct", "taskloop"); 12163 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12164 break; 12165 default: 12166 break; 12167 } 12168 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT; 12169 if (code != OMP_LOOP) 12170 check_non_private = "lastprivate"; 12171 decl = OMP_CLAUSE_DECL (c); 12172 if (error_operand_p (decl)) 12173 goto do_add; 12174 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) 12175 && !lang_hooks.decls.omp_scalar_p (decl, true)) 12176 { 12177 error_at (OMP_CLAUSE_LOCATION (c), 12178 "non-scalar variable %qD in conditional " 12179 "%<lastprivate%> clause", decl); 12180 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12181 } 12182 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 12183 flags |= GOVD_LASTPRIVATE_CONDITIONAL; 12184 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl, 12185 false); 12186 goto do_add; 12187 case OMP_CLAUSE_REDUCTION: 12188 if (OMP_CLAUSE_REDUCTION_TASK (c)) 12189 { 12190 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE) 12191 { 12192 if (nowait == -1) 12193 nowait = omp_find_clause (*list_p, 12194 OMP_CLAUSE_NOWAIT) != NULL_TREE; 12195 if (nowait 12196 && (outer_ctx == NULL 12197 || outer_ctx->region_type != ORT_COMBINED_PARALLEL)) 12198 { 12199 error_at (OMP_CLAUSE_LOCATION (c), 12200 "%<task%> reduction modifier on a construct " 12201 "with a %<nowait%> clause"); 12202 OMP_CLAUSE_REDUCTION_TASK (c) = 0; 12203 } 12204 } 12205 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL) 12206 { 12207 error_at (OMP_CLAUSE_LOCATION (c), 12208 "invalid %<task%> reduction modifier on construct " 12209 "other than %<parallel%>, %qs, %<sections%> or " 12210 "%<scope%>", lang_GNU_Fortran () ? "do" : "for"); 12211 OMP_CLAUSE_REDUCTION_TASK (c) = 0; 12212 } 12213 } 12214 if (OMP_CLAUSE_REDUCTION_INSCAN (c)) 12215 switch (code) 12216 { 12217 case OMP_SECTIONS: 12218 error_at (OMP_CLAUSE_LOCATION (c), 12219 "%<inscan%> %<reduction%> clause on " 12220 "%qs construct", "sections"); 12221 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12222 break; 12223 case OMP_PARALLEL: 12224 error_at (OMP_CLAUSE_LOCATION (c), 12225 "%<inscan%> %<reduction%> clause on " 12226 "%qs construct", "parallel"); 12227 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12228 break; 12229 case OMP_TEAMS: 12230 error_at (OMP_CLAUSE_LOCATION (c), 12231 "%<inscan%> %<reduction%> clause on " 12232 "%qs construct", "teams"); 12233 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12234 break; 12235 case OMP_TASKLOOP: 12236 error_at (OMP_CLAUSE_LOCATION (c), 12237 "%<inscan%> %<reduction%> clause on " 12238 "%qs construct", "taskloop"); 12239 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12240 break; 12241 case OMP_SCOPE: 12242 error_at (OMP_CLAUSE_LOCATION (c), 12243 "%<inscan%> %<reduction%> clause on " 12244 "%qs construct", "scope"); 12245 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12246 break; 12247 default: 12248 break; 12249 } 12250 /* FALLTHRU */ 12251 case OMP_CLAUSE_IN_REDUCTION: 12252 case OMP_CLAUSE_TASK_REDUCTION: 12253 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; 12254 /* OpenACC permits reductions on private variables. */ 12255 if (!(region_type & ORT_ACC) 12256 /* taskgroup is actually not a worksharing region. */ 12257 && code != OMP_TASKGROUP) 12258 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)]; 12259 decl = OMP_CLAUSE_DECL (c); 12260 if (TREE_CODE (decl) == MEM_REF) 12261 { 12262 tree type = TREE_TYPE (decl); 12263 bool saved_into_ssa = gimplify_ctxp->into_ssa; 12264 gimplify_ctxp->into_ssa = false; 12265 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p, 12266 NULL, is_gimple_val, fb_rvalue, false) 12267 == GS_ERROR) 12268 { 12269 gimplify_ctxp->into_ssa = saved_into_ssa; 12270 remove = true; 12271 break; 12272 } 12273 gimplify_ctxp->into_ssa = saved_into_ssa; 12274 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 12275 if (DECL_P (v)) 12276 { 12277 omp_firstprivatize_variable (ctx, v); 12278 omp_notice_variable (ctx, v, true); 12279 } 12280 decl = TREE_OPERAND (decl, 0); 12281 if (TREE_CODE (decl) == POINTER_PLUS_EXPR) 12282 { 12283 gimplify_ctxp->into_ssa = false; 12284 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p, 12285 NULL, is_gimple_val, fb_rvalue, false) 12286 == GS_ERROR) 12287 { 12288 gimplify_ctxp->into_ssa = saved_into_ssa; 12289 remove = true; 12290 break; 12291 } 12292 gimplify_ctxp->into_ssa = saved_into_ssa; 12293 v = TREE_OPERAND (decl, 1); 12294 if (DECL_P (v)) 12295 { 12296 omp_firstprivatize_variable (ctx, v); 12297 omp_notice_variable (ctx, v, true); 12298 } 12299 decl = TREE_OPERAND (decl, 0); 12300 } 12301 if (TREE_CODE (decl) == ADDR_EXPR 12302 || TREE_CODE (decl) == INDIRECT_REF) 12303 decl = TREE_OPERAND (decl, 0); 12304 } 12305 goto do_add_decl; 12306 case OMP_CLAUSE_LINEAR: 12307 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL, 12308 is_gimple_val, fb_rvalue) == GS_ERROR) 12309 { 12310 remove = true; 12311 break; 12312 } 12313 else 12314 { 12315 if (code == OMP_SIMD 12316 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 12317 { 12318 struct gimplify_omp_ctx *octx = outer_ctx; 12319 if (octx 12320 && octx->region_type == ORT_WORKSHARE 12321 && octx->combined_loop 12322 && !octx->distribute) 12323 { 12324 if (octx->outer_context 12325 && (octx->outer_context->region_type 12326 == ORT_COMBINED_PARALLEL)) 12327 octx = octx->outer_context->outer_context; 12328 else 12329 octx = octx->outer_context; 12330 } 12331 if (octx 12332 && octx->region_type == ORT_WORKSHARE 12333 && octx->combined_loop 12334 && octx->distribute) 12335 { 12336 error_at (OMP_CLAUSE_LOCATION (c), 12337 "%<linear%> clause for variable other than " 12338 "loop iterator specified on construct " 12339 "combined with %<distribute%>"); 12340 remove = true; 12341 break; 12342 } 12343 } 12344 /* For combined #pragma omp parallel for simd, need to put 12345 lastprivate and perhaps firstprivate too on the 12346 parallel. Similarly for #pragma omp for simd. */ 12347 struct gimplify_omp_ctx *octx = outer_ctx; 12348 bool taskloop_seen = false; 12349 decl = NULL_TREE; 12350 do 12351 { 12352 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12353 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12354 break; 12355 decl = OMP_CLAUSE_DECL (c); 12356 if (error_operand_p (decl)) 12357 { 12358 decl = NULL_TREE; 12359 break; 12360 } 12361 flags = GOVD_SEEN; 12362 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 12363 flags |= GOVD_FIRSTPRIVATE; 12364 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12365 flags |= GOVD_LASTPRIVATE; 12366 if (octx 12367 && octx->region_type == ORT_WORKSHARE 12368 && octx->combined_loop) 12369 { 12370 if (octx->outer_context 12371 && (octx->outer_context->region_type 12372 == ORT_COMBINED_PARALLEL)) 12373 octx = octx->outer_context; 12374 else if (omp_check_private (octx, decl, false)) 12375 break; 12376 } 12377 else if (octx 12378 && (octx->region_type & ORT_TASK) != 0 12379 && octx->combined_loop) 12380 taskloop_seen = true; 12381 else if (octx 12382 && octx->region_type == ORT_COMBINED_PARALLEL 12383 && ((ctx->region_type == ORT_WORKSHARE 12384 && octx == outer_ctx) 12385 || taskloop_seen)) 12386 flags = GOVD_SEEN | GOVD_SHARED; 12387 else if (octx 12388 && ((octx->region_type & ORT_COMBINED_TEAMS) 12389 == ORT_COMBINED_TEAMS)) 12390 flags = GOVD_SEEN | GOVD_SHARED; 12391 else if (octx 12392 && octx->region_type == ORT_COMBINED_TARGET) 12393 { 12394 if (flags & GOVD_LASTPRIVATE) 12395 flags = GOVD_SEEN | GOVD_MAP; 12396 } 12397 else 12398 break; 12399 splay_tree_node on 12400 = splay_tree_lookup (octx->variables, 12401 (splay_tree_key) decl); 12402 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0) 12403 { 12404 octx = NULL; 12405 break; 12406 } 12407 omp_add_variable (octx, decl, flags); 12408 if (octx->outer_context == NULL) 12409 break; 12410 octx = octx->outer_context; 12411 } 12412 while (1); 12413 if (octx 12414 && decl 12415 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12416 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))) 12417 omp_notice_variable (octx, decl, true); 12418 } 12419 flags = GOVD_LINEAR | GOVD_EXPLICIT; 12420 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12421 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12422 { 12423 notice_outer = false; 12424 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 12425 } 12426 goto do_add; 12427 12428 case OMP_CLAUSE_MAP: 12429 if (!grp_start_p) 12430 { 12431 grp_start_p = list_p; 12432 grp_end = (*groups)[grpnum].grp_end; 12433 grpnum++; 12434 } 12435 decl = OMP_CLAUSE_DECL (c); 12436 12437 if (error_operand_p (decl)) 12438 { 12439 remove = true; 12440 break; 12441 } 12442 12443 if (!omp_parse_expr (addr_tokens, decl)) 12444 { 12445 remove = true; 12446 break; 12447 } 12448 12449 if (remove) 12450 break; 12451 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC)) 12452 { 12453 struct gimplify_omp_ctx *octx; 12454 for (octx = outer_ctx; octx; octx = octx->outer_context) 12455 { 12456 if (octx->region_type != ORT_ACC_HOST_DATA) 12457 break; 12458 splay_tree_node n2 12459 = splay_tree_lookup (octx->variables, 12460 (splay_tree_key) decl); 12461 if (n2) 12462 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE " 12463 "declared in enclosing %<host_data%> region", 12464 DECL_NAME (decl)); 12465 } 12466 } 12467 12468 map_descriptor = false; 12469 12470 /* This condition checks if we're mapping an array descriptor that 12471 isn't inside a derived type -- these have special handling, and 12472 are not handled as structs in omp_build_struct_sibling_lists. 12473 See that function for further details. */ 12474 if (*grp_start_p != grp_end 12475 && OMP_CLAUSE_CHAIN (*grp_start_p) 12476 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 12477 { 12478 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p); 12479 if (omp_map_clause_descriptor_p (grp_mid) 12480 && DECL_P (OMP_CLAUSE_DECL (grp_mid))) 12481 map_descriptor = true; 12482 } 12483 else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP 12484 && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE 12485 || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE) 12486 && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end)) 12487 map_descriptor = true; 12488 12489 /* Adding the decl for a struct access: we haven't created 12490 GOMP_MAP_STRUCT nodes yet, so this statement needs to predict 12491 whether they will be created in gimplify_adjust_omp_clauses. 12492 NOTE: Technically we should probably look through DECL_VALUE_EXPR 12493 here because something that looks like a DECL_P may actually be a 12494 struct access, e.g. variables in a lambda closure 12495 (__closure->__foo) or class members (this->foo). Currently in both 12496 those cases we map the whole of the containing object (directly in 12497 the C++ FE) though, so struct nodes are not created. */ 12498 if (c == grp_end 12499 && addr_tokens[0]->type == STRUCTURE_BASE 12500 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12501 && !map_descriptor) 12502 { 12503 gcc_assert (addr_tokens[1]->type == ACCESS_METHOD); 12504 /* If we got to this struct via a chain of pointers, maybe we 12505 want to map it implicitly instead. */ 12506 if (omp_access_chain_p (addr_tokens, 1)) 12507 break; 12508 omp_mapping_group *wholestruct; 12509 if (!(region_type & ORT_ACC) 12510 && omp_mapped_by_containing_struct (grpmap, 12511 OMP_CLAUSE_DECL (c), 12512 &wholestruct)) 12513 break; 12514 decl = addr_tokens[1]->expr; 12515 if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl)) 12516 break; 12517 /* Standalone attach or detach clauses for a struct element 12518 should not inhibit implicit mapping of the whole struct. */ 12519 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 12520 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH) 12521 break; 12522 flags = GOVD_MAP | GOVD_EXPLICIT; 12523 12524 gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT 12525 || TREE_ADDRESSABLE (decl)); 12526 goto do_add_decl; 12527 } 12528 12529 if (!DECL_P (decl)) 12530 { 12531 tree d = decl, *pd; 12532 if (TREE_CODE (d) == ARRAY_REF) 12533 { 12534 while (TREE_CODE (d) == ARRAY_REF) 12535 d = TREE_OPERAND (d, 0); 12536 if (TREE_CODE (d) == COMPONENT_REF 12537 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 12538 decl = d; 12539 } 12540 pd = &OMP_CLAUSE_DECL (c); 12541 if (d == decl 12542 && TREE_CODE (decl) == INDIRECT_REF 12543 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 12544 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 12545 == REFERENCE_TYPE) 12546 && (OMP_CLAUSE_MAP_KIND (c) 12547 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 12548 { 12549 pd = &TREE_OPERAND (decl, 0); 12550 decl = TREE_OPERAND (decl, 0); 12551 } 12552 12553 if (addr_tokens[0]->type == STRUCTURE_BASE 12554 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12555 && addr_tokens[1]->type == ACCESS_METHOD 12556 && (addr_tokens[1]->u.access_kind == ACCESS_POINTER 12557 || (addr_tokens[1]->u.access_kind 12558 == ACCESS_POINTER_OFFSET)) 12559 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))) 12560 { 12561 tree base = addr_tokens[1]->expr; 12562 splay_tree_node n 12563 = splay_tree_lookup (ctx->variables, 12564 (splay_tree_key) base); 12565 n->value |= GOVD_SEEN; 12566 } 12567 12568 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c)) 12569 { 12570 /* Don't gimplify *pd fully at this point, as the base 12571 will need to be adjusted during omp lowering. */ 12572 auto_vec<tree, 10> expr_stack; 12573 tree *p = pd; 12574 while (handled_component_p (*p) 12575 || TREE_CODE (*p) == INDIRECT_REF 12576 || TREE_CODE (*p) == ADDR_EXPR 12577 || TREE_CODE (*p) == MEM_REF 12578 || TREE_CODE (*p) == NON_LVALUE_EXPR) 12579 { 12580 expr_stack.safe_push (*p); 12581 p = &TREE_OPERAND (*p, 0); 12582 } 12583 for (int i = expr_stack.length () - 1; i >= 0; i--) 12584 { 12585 tree t = expr_stack[i]; 12586 if (TREE_CODE (t) == ARRAY_REF 12587 || TREE_CODE (t) == ARRAY_RANGE_REF) 12588 { 12589 if (TREE_OPERAND (t, 2) == NULL_TREE) 12590 { 12591 tree low = unshare_expr (array_ref_low_bound (t)); 12592 if (!is_gimple_min_invariant (low)) 12593 { 12594 TREE_OPERAND (t, 2) = low; 12595 if (gimplify_expr (&TREE_OPERAND (t, 2), 12596 pre_p, NULL, 12597 is_gimple_reg, 12598 fb_rvalue) == GS_ERROR) 12599 remove = true; 12600 } 12601 } 12602 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p, 12603 NULL, is_gimple_reg, 12604 fb_rvalue) == GS_ERROR) 12605 remove = true; 12606 if (TREE_OPERAND (t, 3) == NULL_TREE) 12607 { 12608 tree elmt_size = array_ref_element_size (t); 12609 if (!is_gimple_min_invariant (elmt_size)) 12610 { 12611 elmt_size = unshare_expr (elmt_size); 12612 tree elmt_type 12613 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 12614 0))); 12615 tree factor 12616 = size_int (TYPE_ALIGN_UNIT (elmt_type)); 12617 elmt_size 12618 = size_binop (EXACT_DIV_EXPR, elmt_size, 12619 factor); 12620 TREE_OPERAND (t, 3) = elmt_size; 12621 if (gimplify_expr (&TREE_OPERAND (t, 3), 12622 pre_p, NULL, 12623 is_gimple_reg, 12624 fb_rvalue) == GS_ERROR) 12625 remove = true; 12626 } 12627 } 12628 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p, 12629 NULL, is_gimple_reg, 12630 fb_rvalue) == GS_ERROR) 12631 remove = true; 12632 } 12633 else if (TREE_CODE (t) == COMPONENT_REF) 12634 { 12635 if (TREE_OPERAND (t, 2) == NULL_TREE) 12636 { 12637 tree offset = component_ref_field_offset (t); 12638 if (!is_gimple_min_invariant (offset)) 12639 { 12640 offset = unshare_expr (offset); 12641 tree field = TREE_OPERAND (t, 1); 12642 tree factor 12643 = size_int (DECL_OFFSET_ALIGN (field) 12644 / BITS_PER_UNIT); 12645 offset = size_binop (EXACT_DIV_EXPR, offset, 12646 factor); 12647 TREE_OPERAND (t, 2) = offset; 12648 if (gimplify_expr (&TREE_OPERAND (t, 2), 12649 pre_p, NULL, 12650 is_gimple_reg, 12651 fb_rvalue) == GS_ERROR) 12652 remove = true; 12653 } 12654 } 12655 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p, 12656 NULL, is_gimple_reg, 12657 fb_rvalue) == GS_ERROR) 12658 remove = true; 12659 } 12660 } 12661 for (; expr_stack.length () > 0; ) 12662 { 12663 tree t = expr_stack.pop (); 12664 12665 if (TREE_CODE (t) == ARRAY_REF 12666 || TREE_CODE (t) == ARRAY_RANGE_REF) 12667 { 12668 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)) 12669 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p, 12670 NULL, is_gimple_val, 12671 fb_rvalue) == GS_ERROR) 12672 remove = true; 12673 } 12674 } 12675 } 12676 break; 12677 } 12678 12679 if ((code == OMP_TARGET 12680 || code == OMP_TARGET_DATA 12681 || code == OMP_TARGET_ENTER_DATA 12682 || code == OMP_TARGET_EXIT_DATA) 12683 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 12684 { 12685 /* If we have attach/detach but the decl we have is a pointer to 12686 pointer, we're probably mapping the "base level" array 12687 implicitly. Make sure we don't add the decl as if we mapped 12688 it explicitly. That is, 12689 12690 int **arr; 12691 [...] 12692 #pragma omp target map(arr[a][b:c]) 12693 12694 should *not* map "arr" explicitly. That way we get a 12695 zero-length "alloc" mapping for it, and assuming it's been 12696 mapped by some previous directive, etc., things work as they 12697 should. */ 12698 12699 tree basetype = TREE_TYPE (addr_tokens[0]->expr); 12700 12701 if (TREE_CODE (basetype) == REFERENCE_TYPE) 12702 basetype = TREE_TYPE (basetype); 12703 12704 if (code == OMP_TARGET 12705 && addr_tokens[0]->type == ARRAY_BASE 12706 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12707 && TREE_CODE (basetype) == POINTER_TYPE 12708 && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE) 12709 break; 12710 } 12711 12712 flags = GOVD_MAP | GOVD_EXPLICIT; 12713 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO 12714 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM 12715 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO 12716 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM) 12717 flags |= GOVD_MAP_ALWAYS_TO; 12718 12719 goto do_add; 12720 12721 case OMP_CLAUSE_AFFINITY: 12722 gimplify_omp_affinity (list_p, pre_p); 12723 remove = true; 12724 break; 12725 case OMP_CLAUSE_DOACROSS: 12726 if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK) 12727 { 12728 tree deps = OMP_CLAUSE_DECL (c); 12729 while (deps && TREE_CODE (deps) == TREE_LIST) 12730 { 12731 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR 12732 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1))) 12733 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1), 12734 pre_p, NULL, is_gimple_val, fb_rvalue); 12735 deps = TREE_CHAIN (deps); 12736 } 12737 } 12738 else 12739 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c) 12740 == OMP_CLAUSE_DOACROSS_SOURCE); 12741 break; 12742 case OMP_CLAUSE_DEPEND: 12743 if (handled_depend_iterators == -1) 12744 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p); 12745 if (handled_depend_iterators) 12746 { 12747 if (handled_depend_iterators == 2) 12748 remove = true; 12749 break; 12750 } 12751 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 12752 { 12753 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 12754 NULL, is_gimple_val, fb_rvalue); 12755 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 12756 } 12757 if (error_operand_p (OMP_CLAUSE_DECL (c))) 12758 { 12759 remove = true; 12760 break; 12761 } 12762 if (OMP_CLAUSE_DECL (c) != null_pointer_node) 12763 { 12764 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c)); 12765 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 12766 is_gimple_val, fb_rvalue) == GS_ERROR) 12767 { 12768 remove = true; 12769 break; 12770 } 12771 } 12772 if (code == OMP_TASK) 12773 ctx->has_depend = true; 12774 break; 12775 12776 case OMP_CLAUSE_TO: 12777 case OMP_CLAUSE_FROM: 12778 case OMP_CLAUSE__CACHE_: 12779 decl = OMP_CLAUSE_DECL (c); 12780 if (error_operand_p (decl)) 12781 { 12782 remove = true; 12783 break; 12784 } 12785 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 12786 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) 12787 : TYPE_SIZE_UNIT (TREE_TYPE (decl)); 12788 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, 12789 NULL, is_gimple_val, fb_rvalue) == GS_ERROR) 12790 { 12791 remove = true; 12792 break; 12793 } 12794 if (!DECL_P (decl)) 12795 { 12796 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, 12797 NULL, is_gimple_lvalue, fb_lvalue) 12798 == GS_ERROR) 12799 { 12800 remove = true; 12801 break; 12802 } 12803 break; 12804 } 12805 goto do_notice; 12806 12807 case OMP_CLAUSE_USE_DEVICE_PTR: 12808 case OMP_CLAUSE_USE_DEVICE_ADDR: 12809 flags = GOVD_EXPLICIT; 12810 goto do_add; 12811 12812 case OMP_CLAUSE_HAS_DEVICE_ADDR: 12813 decl = OMP_CLAUSE_DECL (c); 12814 while (TREE_CODE (decl) == INDIRECT_REF 12815 || TREE_CODE (decl) == ARRAY_REF) 12816 decl = TREE_OPERAND (decl, 0); 12817 flags = GOVD_EXPLICIT; 12818 goto do_add_decl; 12819 12820 case OMP_CLAUSE_IS_DEVICE_PTR: 12821 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; 12822 goto do_add; 12823 12824 do_add: 12825 decl = OMP_CLAUSE_DECL (c); 12826 do_add_decl: 12827 if (error_operand_p (decl)) 12828 { 12829 remove = true; 12830 break; 12831 } 12832 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0) 12833 { 12834 tree t = omp_member_access_dummy_var (decl); 12835 if (t) 12836 { 12837 tree v = DECL_VALUE_EXPR (decl); 12838 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1)); 12839 if (outer_ctx) 12840 omp_notice_variable (outer_ctx, t, true); 12841 } 12842 } 12843 if (code == OACC_DATA 12844 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP 12845 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) 12846 flags |= GOVD_MAP_0LEN_ARRAY; 12847 omp_add_variable (ctx, decl, flags); 12848 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12849 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION 12850 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) 12851 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) 12852 { 12853 struct gimplify_omp_ctx *pctx 12854 = code == OMP_TARGET ? outer_ctx : ctx; 12855 if (pctx) 12856 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 12857 GOVD_LOCAL | GOVD_SEEN); 12858 if (pctx 12859 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) 12860 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c), 12861 find_decl_expr, 12862 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 12863 NULL) == NULL_TREE) 12864 omp_add_variable (pctx, 12865 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 12866 GOVD_LOCAL | GOVD_SEEN); 12867 gimplify_omp_ctxp = pctx; 12868 push_gimplify_context (); 12869 12870 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL; 12871 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL; 12872 12873 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), 12874 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)); 12875 pop_gimplify_context 12876 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))); 12877 push_gimplify_context (); 12878 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), 12879 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)); 12880 pop_gimplify_context 12881 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c))); 12882 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE; 12883 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE; 12884 12885 gimplify_omp_ctxp = outer_ctx; 12886 } 12887 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 12888 && OMP_CLAUSE_LASTPRIVATE_STMT (c)) 12889 { 12890 gimplify_omp_ctxp = ctx; 12891 push_gimplify_context (); 12892 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR) 12893 { 12894 tree bind = build3 (BIND_EXPR, void_type_node, NULL, 12895 NULL, NULL); 12896 TREE_SIDE_EFFECTS (bind) = 1; 12897 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c); 12898 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind; 12899 } 12900 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c), 12901 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); 12902 pop_gimplify_context 12903 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))); 12904 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE; 12905 12906 gimplify_omp_ctxp = outer_ctx; 12907 } 12908 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 12909 && OMP_CLAUSE_LINEAR_STMT (c)) 12910 { 12911 gimplify_omp_ctxp = ctx; 12912 push_gimplify_context (); 12913 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR) 12914 { 12915 tree bind = build3 (BIND_EXPR, void_type_node, NULL, 12916 NULL, NULL); 12917 TREE_SIDE_EFFECTS (bind) = 1; 12918 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c); 12919 OMP_CLAUSE_LINEAR_STMT (c) = bind; 12920 } 12921 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c), 12922 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)); 12923 pop_gimplify_context 12924 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))); 12925 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE; 12926 12927 gimplify_omp_ctxp = outer_ctx; 12928 } 12929 if (notice_outer) 12930 goto do_notice; 12931 break; 12932 12933 case OMP_CLAUSE_COPYIN: 12934 case OMP_CLAUSE_COPYPRIVATE: 12935 decl = OMP_CLAUSE_DECL (c); 12936 if (error_operand_p (decl)) 12937 { 12938 remove = true; 12939 break; 12940 } 12941 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE 12942 && !remove 12943 && !omp_check_private (ctx, decl, true)) 12944 { 12945 remove = true; 12946 if (is_global_var (decl)) 12947 { 12948 if (DECL_THREAD_LOCAL_P (decl)) 12949 remove = false; 12950 else if (DECL_HAS_VALUE_EXPR_P (decl)) 12951 { 12952 tree value = get_base_address (DECL_VALUE_EXPR (decl)); 12953 12954 if (value 12955 && DECL_P (value) 12956 && DECL_THREAD_LOCAL_P (value)) 12957 remove = false; 12958 } 12959 } 12960 if (remove) 12961 error_at (OMP_CLAUSE_LOCATION (c), 12962 "copyprivate variable %qE is not threadprivate" 12963 " or private in outer context", DECL_NAME (decl)); 12964 } 12965 do_notice: 12966 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12967 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE 12968 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) 12969 && outer_ctx 12970 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP 12971 || (region_type == ORT_WORKSHARE 12972 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12973 && (OMP_CLAUSE_REDUCTION_INSCAN (c) 12974 || code == OMP_LOOP))) 12975 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL 12976 || (code == OMP_LOOP 12977 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12978 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS) 12979 == ORT_COMBINED_TEAMS)))) 12980 { 12981 splay_tree_node on 12982 = splay_tree_lookup (outer_ctx->variables, 12983 (splay_tree_key)decl); 12984 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0) 12985 { 12986 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12987 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF 12988 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 12989 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 12990 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) 12991 == POINTER_TYPE)))) 12992 omp_firstprivatize_variable (outer_ctx, decl); 12993 else 12994 { 12995 omp_add_variable (outer_ctx, decl, 12996 GOVD_SEEN | GOVD_SHARED); 12997 if (outer_ctx->outer_context) 12998 omp_notice_variable (outer_ctx->outer_context, decl, 12999 true); 13000 } 13001 } 13002 } 13003 if (outer_ctx) 13004 omp_notice_variable (outer_ctx, decl, true); 13005 if (check_non_private 13006 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE) 13007 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION 13008 || decl == OMP_CLAUSE_DECL (c) 13009 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF 13010 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0)) 13011 == ADDR_EXPR 13012 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0)) 13013 == POINTER_PLUS_EXPR 13014 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND 13015 (OMP_CLAUSE_DECL (c), 0), 0)) 13016 == ADDR_EXPR))))) 13017 && omp_check_private (ctx, decl, false)) 13018 { 13019 error ("%s variable %qE is private in outer context", 13020 check_non_private, DECL_NAME (decl)); 13021 remove = true; 13022 } 13023 break; 13024 13025 case OMP_CLAUSE_DETACH: 13026 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN; 13027 goto do_add; 13028 13029 case OMP_CLAUSE_IF: 13030 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK 13031 && OMP_CLAUSE_IF_MODIFIER (c) != code) 13032 { 13033 const char *p[2]; 13034 for (int i = 0; i < 2; i++) 13035 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code) 13036 { 13037 case VOID_CST: p[i] = "cancel"; break; 13038 case OMP_PARALLEL: p[i] = "parallel"; break; 13039 case OMP_SIMD: p[i] = "simd"; break; 13040 case OMP_TASK: p[i] = "task"; break; 13041 case OMP_TASKLOOP: p[i] = "taskloop"; break; 13042 case OMP_TARGET_DATA: p[i] = "target data"; break; 13043 case OMP_TARGET: p[i] = "target"; break; 13044 case OMP_TARGET_UPDATE: p[i] = "target update"; break; 13045 case OMP_TARGET_ENTER_DATA: 13046 p[i] = "target enter data"; break; 13047 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break; 13048 default: gcc_unreachable (); 13049 } 13050 error_at (OMP_CLAUSE_LOCATION (c), 13051 "expected %qs %<if%> clause modifier rather than %qs", 13052 p[0], p[1]); 13053 remove = true; 13054 } 13055 /* Fall through. */ 13056 13057 case OMP_CLAUSE_SELF: 13058 case OMP_CLAUSE_FINAL: 13059 OMP_CLAUSE_OPERAND (c, 0) 13060 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); 13061 /* Fall through. */ 13062 13063 case OMP_CLAUSE_NUM_TEAMS: 13064 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS 13065 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 13066 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) 13067 { 13068 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) 13069 { 13070 remove = true; 13071 break; 13072 } 13073 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 13074 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c), 13075 pre_p, NULL, true); 13076 } 13077 /* Fall through. */ 13078 13079 case OMP_CLAUSE_SCHEDULE: 13080 case OMP_CLAUSE_NUM_THREADS: 13081 case OMP_CLAUSE_THREAD_LIMIT: 13082 case OMP_CLAUSE_DIST_SCHEDULE: 13083 case OMP_CLAUSE_DEVICE: 13084 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE 13085 && OMP_CLAUSE_DEVICE_ANCESTOR (c)) 13086 { 13087 if (code != OMP_TARGET) 13088 { 13089 error_at (OMP_CLAUSE_LOCATION (c), 13090 "%<device%> clause with %<ancestor%> is only " 13091 "allowed on %<target%> construct"); 13092 remove = true; 13093 break; 13094 } 13095 13096 tree clauses = *orig_list_p; 13097 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses)) 13098 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE 13099 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE 13100 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE 13101 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP 13102 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP 13103 ) 13104 { 13105 error_at (OMP_CLAUSE_LOCATION (c), 13106 "with %<ancestor%>, only the %<device%>, " 13107 "%<firstprivate%>, %<private%>, %<defaultmap%>, " 13108 "and %<map%> clauses may appear on the " 13109 "construct"); 13110 remove = true; 13111 break; 13112 } 13113 } 13114 /* Fall through. */ 13115 13116 case OMP_CLAUSE_PRIORITY: 13117 case OMP_CLAUSE_GRAINSIZE: 13118 case OMP_CLAUSE_NUM_TASKS: 13119 case OMP_CLAUSE_FILTER: 13120 case OMP_CLAUSE_HINT: 13121 case OMP_CLAUSE_ASYNC: 13122 case OMP_CLAUSE_WAIT: 13123 case OMP_CLAUSE_NUM_GANGS: 13124 case OMP_CLAUSE_NUM_WORKERS: 13125 case OMP_CLAUSE_VECTOR_LENGTH: 13126 case OMP_CLAUSE_WORKER: 13127 case OMP_CLAUSE_VECTOR: 13128 if (OMP_CLAUSE_OPERAND (c, 0) 13129 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0))) 13130 { 13131 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0))) 13132 { 13133 remove = true; 13134 break; 13135 } 13136 /* All these clauses care about value, not a particular decl, 13137 so try to force it into a SSA_NAME or fresh temporary. */ 13138 OMP_CLAUSE_OPERAND (c, 0) 13139 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0), 13140 pre_p, NULL, true); 13141 } 13142 break; 13143 13144 case OMP_CLAUSE_GANG: 13145 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, 13146 is_gimple_val, fb_rvalue) == GS_ERROR) 13147 remove = true; 13148 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL, 13149 is_gimple_val, fb_rvalue) == GS_ERROR) 13150 remove = true; 13151 break; 13152 13153 case OMP_CLAUSE_NOWAIT: 13154 nowait = 1; 13155 break; 13156 13157 case OMP_CLAUSE_ORDERED: 13158 case OMP_CLAUSE_UNTIED: 13159 case OMP_CLAUSE_COLLAPSE: 13160 case OMP_CLAUSE_TILE: 13161 case OMP_CLAUSE_AUTO: 13162 case OMP_CLAUSE_SEQ: 13163 case OMP_CLAUSE_INDEPENDENT: 13164 case OMP_CLAUSE_MERGEABLE: 13165 case OMP_CLAUSE_PROC_BIND: 13166 case OMP_CLAUSE_SAFELEN: 13167 case OMP_CLAUSE_SIMDLEN: 13168 case OMP_CLAUSE_NOGROUP: 13169 case OMP_CLAUSE_THREADS: 13170 case OMP_CLAUSE_SIMD: 13171 case OMP_CLAUSE_BIND: 13172 case OMP_CLAUSE_IF_PRESENT: 13173 case OMP_CLAUSE_FINALIZE: 13174 break; 13175 13176 case OMP_CLAUSE_ORDER: 13177 ctx->order_concurrent = true; 13178 break; 13179 13180 case OMP_CLAUSE_DEFAULTMAP: 13181 enum gimplify_defaultmap_kind gdmkmin, gdmkmax; 13182 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)) 13183 { 13184 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: 13185 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL: 13186 gdmkmin = GDMK_SCALAR; 13187 gdmkmax = GDMK_POINTER; 13188 break; 13189 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: 13190 gdmkmin = GDMK_SCALAR; 13191 gdmkmax = GDMK_SCALAR_TARGET; 13192 break; 13193 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: 13194 gdmkmin = gdmkmax = GDMK_AGGREGATE; 13195 break; 13196 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE: 13197 gdmkmin = gdmkmax = GDMK_ALLOCATABLE; 13198 break; 13199 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: 13200 gdmkmin = gdmkmax = GDMK_POINTER; 13201 break; 13202 default: 13203 gcc_unreachable (); 13204 } 13205 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++) 13206 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c)) 13207 { 13208 case OMP_CLAUSE_DEFAULTMAP_ALLOC: 13209 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY; 13210 break; 13211 case OMP_CLAUSE_DEFAULTMAP_TO: 13212 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY; 13213 break; 13214 case OMP_CLAUSE_DEFAULTMAP_FROM: 13215 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY; 13216 break; 13217 case OMP_CLAUSE_DEFAULTMAP_TOFROM: 13218 ctx->defaultmap[gdmk] = GOVD_MAP; 13219 break; 13220 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE: 13221 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE; 13222 break; 13223 case OMP_CLAUSE_DEFAULTMAP_NONE: 13224 ctx->defaultmap[gdmk] = 0; 13225 break; 13226 case OMP_CLAUSE_DEFAULTMAP_PRESENT: 13227 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT; 13228 break; 13229 case OMP_CLAUSE_DEFAULTMAP_DEFAULT: 13230 switch (gdmk) 13231 { 13232 case GDMK_SCALAR: 13233 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE; 13234 break; 13235 case GDMK_SCALAR_TARGET: 13236 ctx->defaultmap[gdmk] = (lang_GNU_Fortran () 13237 ? GOVD_MAP : GOVD_FIRSTPRIVATE); 13238 break; 13239 case GDMK_AGGREGATE: 13240 case GDMK_ALLOCATABLE: 13241 ctx->defaultmap[gdmk] = GOVD_MAP; 13242 break; 13243 case GDMK_POINTER: 13244 ctx->defaultmap[gdmk] = GOVD_MAP; 13245 if (!lang_GNU_Fortran ()) 13246 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY; 13247 break; 13248 default: 13249 gcc_unreachable (); 13250 } 13251 break; 13252 default: 13253 gcc_unreachable (); 13254 } 13255 break; 13256 13257 case OMP_CLAUSE_ALIGNED: 13258 decl = OMP_CLAUSE_DECL (c); 13259 if (error_operand_p (decl)) 13260 { 13261 remove = true; 13262 break; 13263 } 13264 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL, 13265 is_gimple_val, fb_rvalue) == GS_ERROR) 13266 { 13267 remove = true; 13268 break; 13269 } 13270 if (!is_global_var (decl) 13271 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) 13272 omp_add_variable (ctx, decl, GOVD_ALIGNED); 13273 break; 13274 13275 case OMP_CLAUSE_NONTEMPORAL: 13276 decl = OMP_CLAUSE_DECL (c); 13277 if (error_operand_p (decl)) 13278 { 13279 remove = true; 13280 break; 13281 } 13282 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL); 13283 break; 13284 13285 case OMP_CLAUSE_ALLOCATE: 13286 decl = OMP_CLAUSE_DECL (c); 13287 if (error_operand_p (decl)) 13288 { 13289 remove = true; 13290 break; 13291 } 13292 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL, 13293 is_gimple_val, fb_rvalue) == GS_ERROR) 13294 { 13295 remove = true; 13296 break; 13297 } 13298 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE 13299 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) 13300 == INTEGER_CST)) 13301 ; 13302 else if (code == OMP_TASKLOOP 13303 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))) 13304 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 13305 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 13306 pre_p, NULL, false); 13307 break; 13308 13309 case OMP_CLAUSE_DEFAULT: 13310 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c); 13311 break; 13312 13313 case OMP_CLAUSE_INCLUSIVE: 13314 case OMP_CLAUSE_EXCLUSIVE: 13315 decl = OMP_CLAUSE_DECL (c); 13316 { 13317 splay_tree_node n = splay_tree_lookup (outer_ctx->variables, 13318 (splay_tree_key) decl); 13319 if (n == NULL || (n->value & GOVD_REDUCTION) == 0) 13320 { 13321 error_at (OMP_CLAUSE_LOCATION (c), 13322 "%qD specified in %qs clause but not in %<inscan%> " 13323 "%<reduction%> clause on the containing construct", 13324 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); 13325 remove = true; 13326 } 13327 else 13328 { 13329 n->value |= GOVD_REDUCTION_INSCAN; 13330 if (outer_ctx->region_type == ORT_SIMD 13331 && outer_ctx->outer_context 13332 && outer_ctx->outer_context->region_type == ORT_WORKSHARE) 13333 { 13334 n = splay_tree_lookup (outer_ctx->outer_context->variables, 13335 (splay_tree_key) decl); 13336 if (n && (n->value & GOVD_REDUCTION) != 0) 13337 n->value |= GOVD_REDUCTION_INSCAN; 13338 } 13339 } 13340 } 13341 break; 13342 13343 case OMP_CLAUSE_NOHOST: 13344 default: 13345 gcc_unreachable (); 13346 } 13347 13348 if (code == OACC_DATA 13349 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP 13350 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 13351 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 13352 remove = true; 13353 if (remove) 13354 *list_p = OMP_CLAUSE_CHAIN (c); 13355 else 13356 list_p = &OMP_CLAUSE_CHAIN (c); 13357 } 13358 13359 if (groups) 13360 { 13361 delete grpmap; 13362 delete groups; 13363 } 13364 13365 ctx->clauses = *orig_list_p; 13366 gimplify_omp_ctxp = ctx; 13367 } 13368 13369 /* Return true if DECL is a candidate for shared to firstprivate 13370 optimization. We only consider non-addressable scalars, not 13371 too big, and not references. */ 13372 13373 static bool 13374 omp_shared_to_firstprivate_optimizable_decl_p (tree decl) 13375 { 13376 if (TREE_ADDRESSABLE (decl)) 13377 return false; 13378 tree type = TREE_TYPE (decl); 13379 if (!is_gimple_reg_type (type) 13380 || TREE_CODE (type) == REFERENCE_TYPE 13381 || TREE_ADDRESSABLE (type)) 13382 return false; 13383 /* Don't optimize too large decls, as each thread/task will have 13384 its own. */ 13385 HOST_WIDE_INT len = int_size_in_bytes (type); 13386 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT) 13387 return false; 13388 if (omp_privatize_by_reference (decl)) 13389 return false; 13390 return true; 13391 } 13392 13393 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*. 13394 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as 13395 GOVD_WRITTEN in outer contexts. */ 13396 13397 static void 13398 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl) 13399 { 13400 for (; ctx; ctx = ctx->outer_context) 13401 { 13402 splay_tree_node n = splay_tree_lookup (ctx->variables, 13403 (splay_tree_key) decl); 13404 if (n == NULL) 13405 continue; 13406 else if (n->value & GOVD_SHARED) 13407 { 13408 n->value |= GOVD_WRITTEN; 13409 return; 13410 } 13411 else if (n->value & GOVD_DATA_SHARE_CLASS) 13412 return; 13413 } 13414 } 13415 13416 /* Helper callback for walk_gimple_seq to discover possible stores 13417 to omp_shared_to_firstprivate_optimizable_decl_p decls and set 13418 GOVD_WRITTEN if they are GOVD_SHARED in some outer context 13419 for those. */ 13420 13421 static tree 13422 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data) 13423 { 13424 struct walk_stmt_info *wi = (struct walk_stmt_info *) data; 13425 13426 *walk_subtrees = 0; 13427 if (!wi->is_lhs) 13428 return NULL_TREE; 13429 13430 tree op = *tp; 13431 do 13432 { 13433 if (handled_component_p (op)) 13434 op = TREE_OPERAND (op, 0); 13435 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF) 13436 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR) 13437 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0); 13438 else 13439 break; 13440 } 13441 while (1); 13442 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op)) 13443 return NULL_TREE; 13444 13445 omp_mark_stores (gimplify_omp_ctxp, op); 13446 return NULL_TREE; 13447 } 13448 13449 /* Helper callback for walk_gimple_seq to discover possible stores 13450 to omp_shared_to_firstprivate_optimizable_decl_p decls and set 13451 GOVD_WRITTEN if they are GOVD_SHARED in some outer context 13452 for those. */ 13453 13454 static tree 13455 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p, 13456 bool *handled_ops_p, 13457 struct walk_stmt_info *wi) 13458 { 13459 gimple *stmt = gsi_stmt (*gsi_p); 13460 switch (gimple_code (stmt)) 13461 { 13462 /* Don't recurse on OpenMP constructs for which 13463 gimplify_adjust_omp_clauses already handled the bodies, 13464 except handle gimple_omp_for_pre_body. */ 13465 case GIMPLE_OMP_FOR: 13466 *handled_ops_p = true; 13467 if (gimple_omp_for_pre_body (stmt)) 13468 walk_gimple_seq (gimple_omp_for_pre_body (stmt), 13469 omp_find_stores_stmt, omp_find_stores_op, wi); 13470 break; 13471 case GIMPLE_OMP_PARALLEL: 13472 case GIMPLE_OMP_TASK: 13473 case GIMPLE_OMP_SECTIONS: 13474 case GIMPLE_OMP_SINGLE: 13475 case GIMPLE_OMP_SCOPE: 13476 case GIMPLE_OMP_TARGET: 13477 case GIMPLE_OMP_TEAMS: 13478 case GIMPLE_OMP_CRITICAL: 13479 *handled_ops_p = true; 13480 break; 13481 default: 13482 break; 13483 } 13484 return NULL_TREE; 13485 } 13486 13487 struct gimplify_adjust_omp_clauses_data 13488 { 13489 tree *list_p; 13490 gimple_seq *pre_p; 13491 }; 13492 13493 /* For all variables that were not actually used within the context, 13494 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */ 13495 13496 static int 13497 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) 13498 { 13499 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p; 13500 gimple_seq *pre_p 13501 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p; 13502 tree decl = (tree) n->key; 13503 unsigned flags = n->value; 13504 enum omp_clause_code code; 13505 tree clause; 13506 bool private_debug; 13507 13508 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL 13509 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0) 13510 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN; 13511 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL)) 13512 return 0; 13513 if ((flags & GOVD_SEEN) == 0) 13514 return 0; 13515 if (flags & GOVD_DEBUG_PRIVATE) 13516 { 13517 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED); 13518 private_debug = true; 13519 } 13520 else if (flags & GOVD_MAP) 13521 private_debug = false; 13522 else 13523 private_debug 13524 = lang_hooks.decls.omp_private_debug_clause (decl, 13525 !!(flags & GOVD_SHARED)); 13526 if (private_debug) 13527 code = OMP_CLAUSE_PRIVATE; 13528 else if (flags & GOVD_MAP) 13529 { 13530 code = OMP_CLAUSE_MAP; 13531 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0 13532 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl)))) 13533 { 13534 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl); 13535 return 0; 13536 } 13537 if (VAR_P (decl) 13538 && DECL_IN_CONSTANT_POOL (decl) 13539 && !lookup_attribute ("omp declare target", 13540 DECL_ATTRIBUTES (decl))) 13541 { 13542 tree id = get_identifier ("omp declare target"); 13543 DECL_ATTRIBUTES (decl) 13544 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); 13545 varpool_node *node = varpool_node::get (decl); 13546 if (node) 13547 { 13548 node->offloadable = 1; 13549 if (ENABLE_OFFLOADING) 13550 g->have_offload = true; 13551 } 13552 } 13553 } 13554 else if (flags & GOVD_SHARED) 13555 { 13556 if (is_global_var (decl)) 13557 { 13558 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; 13559 while (ctx != NULL) 13560 { 13561 splay_tree_node on 13562 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13563 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE 13564 | GOVD_PRIVATE | GOVD_REDUCTION 13565 | GOVD_LINEAR | GOVD_MAP)) != 0) 13566 break; 13567 ctx = ctx->outer_context; 13568 } 13569 if (ctx == NULL) 13570 return 0; 13571 } 13572 code = OMP_CLAUSE_SHARED; 13573 /* Don't optimize shared into firstprivate for read-only vars 13574 on tasks with depend clause, we shouldn't try to copy them 13575 until the dependencies are satisfied. */ 13576 if (gimplify_omp_ctxp->has_depend) 13577 flags |= GOVD_WRITTEN; 13578 } 13579 else if (flags & GOVD_PRIVATE) 13580 code = OMP_CLAUSE_PRIVATE; 13581 else if (flags & GOVD_FIRSTPRIVATE) 13582 { 13583 code = OMP_CLAUSE_FIRSTPRIVATE; 13584 if ((gimplify_omp_ctxp->region_type & ORT_TARGET) 13585 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0 13586 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl)))) 13587 { 13588 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on " 13589 "%<target%> construct", decl); 13590 return 0; 13591 } 13592 } 13593 else if (flags & GOVD_LASTPRIVATE) 13594 code = OMP_CLAUSE_LASTPRIVATE; 13595 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL)) 13596 return 0; 13597 else if (flags & GOVD_CONDTEMP) 13598 { 13599 code = OMP_CLAUSE__CONDTEMP_; 13600 gimple_add_tmp_var (decl); 13601 } 13602 else 13603 gcc_unreachable (); 13604 13605 if (((flags & GOVD_LASTPRIVATE) 13606 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN))) 13607 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13608 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 13609 13610 tree chain = *list_p; 13611 clause = build_omp_clause (input_location, code); 13612 OMP_CLAUSE_DECL (clause) = decl; 13613 OMP_CLAUSE_CHAIN (clause) = chain; 13614 if (private_debug) 13615 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1; 13616 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF)) 13617 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1; 13618 else if (code == OMP_CLAUSE_SHARED 13619 && (flags & GOVD_WRITTEN) == 0 13620 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13621 OMP_CLAUSE_SHARED_READONLY (clause) = 1; 13622 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0) 13623 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1; 13624 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0) 13625 { 13626 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP); 13627 OMP_CLAUSE_DECL (nc) = decl; 13628 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 13629 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE) 13630 OMP_CLAUSE_DECL (clause) 13631 = build_fold_indirect_ref_loc (input_location, decl); 13632 OMP_CLAUSE_DECL (clause) 13633 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause), 13634 build_int_cst (build_pointer_type (char_type_node), 0)); 13635 OMP_CLAUSE_SIZE (clause) = size_zero_node; 13636 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13637 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC); 13638 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1; 13639 tree dtype = TREE_TYPE (decl); 13640 if (TREE_CODE (dtype) == REFERENCE_TYPE) 13641 dtype = TREE_TYPE (dtype); 13642 /* FIRSTPRIVATE_POINTER doesn't work well if we have a 13643 multiply-indirected pointer. If we have a reference to a pointer to 13644 a pointer, it's possible that this should really be 13645 GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the 13646 moment, so stick with this. (See PR113279 and testcases 13647 baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice). */ 13648 if (TREE_CODE (dtype) == POINTER_TYPE 13649 && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE) 13650 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 13651 else 13652 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER); 13653 OMP_CLAUSE_CHAIN (nc) = chain; 13654 OMP_CLAUSE_CHAIN (clause) = nc; 13655 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13656 gimplify_omp_ctxp = ctx->outer_context; 13657 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0), 13658 pre_p, NULL, is_gimple_val, fb_rvalue); 13659 gimplify_omp_ctxp = ctx; 13660 } 13661 else if (code == OMP_CLAUSE_MAP) 13662 { 13663 int kind; 13664 /* Not all combinations of these GOVD_MAP flags are actually valid. */ 13665 switch (flags & (GOVD_MAP_TO_ONLY 13666 | GOVD_MAP_FORCE 13667 | GOVD_MAP_FORCE_PRESENT 13668 | GOVD_MAP_ALLOC_ONLY 13669 | GOVD_MAP_FROM_ONLY)) 13670 { 13671 case 0: 13672 kind = GOMP_MAP_TOFROM; 13673 break; 13674 case GOVD_MAP_FORCE: 13675 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE; 13676 break; 13677 case GOVD_MAP_TO_ONLY: 13678 kind = GOMP_MAP_TO; 13679 break; 13680 case GOVD_MAP_FROM_ONLY: 13681 kind = GOMP_MAP_FROM; 13682 break; 13683 case GOVD_MAP_ALLOC_ONLY: 13684 kind = GOMP_MAP_ALLOC; 13685 break; 13686 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE: 13687 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE; 13688 break; 13689 case GOVD_MAP_FORCE_PRESENT: 13690 kind = GOMP_MAP_FORCE_PRESENT; 13691 break; 13692 case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY: 13693 kind = GOMP_MAP_FORCE_PRESENT; 13694 break; 13695 default: 13696 gcc_unreachable (); 13697 } 13698 OMP_CLAUSE_SET_MAP_KIND (clause, kind); 13699 /* Setting of the implicit flag for the runtime is currently disabled for 13700 OpenACC. */ 13701 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0) 13702 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1; 13703 if (DECL_SIZE (decl) 13704 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 13705 { 13706 tree decl2 = DECL_VALUE_EXPR (decl); 13707 gcc_assert (INDIRECT_REF_P (decl2)); 13708 decl2 = TREE_OPERAND (decl2, 0); 13709 gcc_assert (DECL_P (decl2)); 13710 tree mem = build_simple_mem_ref (decl2); 13711 OMP_CLAUSE_DECL (clause) = mem; 13712 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 13713 if (gimplify_omp_ctxp->outer_context) 13714 { 13715 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; 13716 omp_notice_variable (ctx, decl2, true); 13717 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true); 13718 } 13719 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause), 13720 OMP_CLAUSE_MAP); 13721 OMP_CLAUSE_DECL (nc) = decl; 13722 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13723 if (gimplify_omp_ctxp->target_firstprivatize_array_bases) 13724 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER); 13725 else 13726 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 13727 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause); 13728 OMP_CLAUSE_CHAIN (clause) = nc; 13729 } 13730 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases 13731 && omp_privatize_by_reference (decl)) 13732 { 13733 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl); 13734 OMP_CLAUSE_SIZE (clause) 13735 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))); 13736 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13737 gimplify_omp_ctxp = ctx->outer_context; 13738 gimplify_expr (&OMP_CLAUSE_SIZE (clause), 13739 pre_p, NULL, is_gimple_val, fb_rvalue); 13740 gimplify_omp_ctxp = ctx; 13741 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause), 13742 OMP_CLAUSE_MAP); 13743 OMP_CLAUSE_DECL (nc) = decl; 13744 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13745 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE); 13746 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause); 13747 OMP_CLAUSE_CHAIN (clause) = nc; 13748 } 13749 else 13750 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl); 13751 } 13752 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0) 13753 { 13754 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE); 13755 OMP_CLAUSE_DECL (nc) = decl; 13756 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1; 13757 OMP_CLAUSE_CHAIN (nc) = chain; 13758 OMP_CLAUSE_CHAIN (clause) = nc; 13759 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13760 gimplify_omp_ctxp = ctx->outer_context; 13761 lang_hooks.decls.omp_finish_clause (nc, pre_p, 13762 (ctx->region_type & ORT_ACC) != 0); 13763 gimplify_omp_ctxp = ctx; 13764 } 13765 *list_p = clause; 13766 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13767 gimplify_omp_ctxp = ctx->outer_context; 13768 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE 13769 in simd. Those are only added for the local vars inside of simd body 13770 and they don't need to be e.g. default constructible. */ 13771 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD) 13772 lang_hooks.decls.omp_finish_clause (clause, pre_p, 13773 (ctx->region_type & ORT_ACC) != 0); 13774 if (gimplify_omp_ctxp) 13775 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause)) 13776 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP 13777 && DECL_P (OMP_CLAUSE_SIZE (clause))) 13778 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause), 13779 true); 13780 gimplify_omp_ctxp = ctx; 13781 return 0; 13782 } 13783 13784 static void 13785 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, 13786 enum tree_code code) 13787 { 13788 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13789 tree *orig_list_p = list_p; 13790 tree c, decl; 13791 bool has_inscan_reductions = false; 13792 13793 if (body) 13794 { 13795 struct gimplify_omp_ctx *octx; 13796 for (octx = ctx; octx; octx = octx->outer_context) 13797 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0) 13798 break; 13799 if (octx) 13800 { 13801 struct walk_stmt_info wi; 13802 memset (&wi, 0, sizeof (wi)); 13803 walk_gimple_seq (body, omp_find_stores_stmt, 13804 omp_find_stores_op, &wi); 13805 } 13806 } 13807 13808 if (ctx->add_safelen1) 13809 { 13810 /* If there are VLAs in the body of simd loop, prevent 13811 vectorization. */ 13812 gcc_assert (ctx->region_type == ORT_SIMD); 13813 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN); 13814 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node; 13815 OMP_CLAUSE_CHAIN (c) = *list_p; 13816 *list_p = c; 13817 list_p = &OMP_CLAUSE_CHAIN (c); 13818 } 13819 13820 if (ctx->region_type == ORT_WORKSHARE 13821 && ctx->outer_context 13822 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL) 13823 { 13824 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c)) 13825 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 13826 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 13827 { 13828 decl = OMP_CLAUSE_DECL (c); 13829 splay_tree_node n 13830 = splay_tree_lookup (ctx->outer_context->variables, 13831 (splay_tree_key) decl); 13832 gcc_checking_assert (!splay_tree_lookup (ctx->variables, 13833 (splay_tree_key) decl)); 13834 omp_add_variable (ctx, decl, n->value); 13835 tree c2 = copy_node (c); 13836 OMP_CLAUSE_CHAIN (c2) = *list_p; 13837 *list_p = c2; 13838 if ((n->value & GOVD_FIRSTPRIVATE) == 0) 13839 continue; 13840 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 13841 OMP_CLAUSE_FIRSTPRIVATE); 13842 OMP_CLAUSE_DECL (c2) = decl; 13843 OMP_CLAUSE_CHAIN (c2) = *list_p; 13844 *list_p = c2; 13845 } 13846 } 13847 13848 if (code == OMP_TARGET 13849 || code == OMP_TARGET_DATA 13850 || code == OMP_TARGET_ENTER_DATA 13851 || code == OMP_TARGET_EXIT_DATA) 13852 { 13853 vec<omp_mapping_group> *groups; 13854 groups = omp_gather_mapping_groups (list_p); 13855 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL; 13856 13857 if (groups) 13858 { 13859 grpmap = omp_index_mapping_groups (groups); 13860 13861 omp_resolve_clause_dependencies (code, groups, grpmap); 13862 omp_build_struct_sibling_lists (code, ctx->region_type, groups, 13863 &grpmap, list_p); 13864 13865 omp_mapping_group *outlist = NULL; 13866 13867 delete grpmap; 13868 delete groups; 13869 13870 /* Rebuild now we have struct sibling lists. */ 13871 groups = omp_gather_mapping_groups (list_p); 13872 grpmap = omp_index_mapping_groups (groups); 13873 13874 bool enter_exit = (code == OMP_TARGET_ENTER_DATA 13875 || code == OMP_TARGET_EXIT_DATA); 13876 13877 outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit); 13878 outlist = omp_segregate_mapping_groups (outlist); 13879 list_p = omp_reorder_mapping_groups (groups, outlist, list_p); 13880 13881 delete grpmap; 13882 delete groups; 13883 } 13884 } 13885 else if (ctx->region_type & ORT_ACC) 13886 { 13887 vec<omp_mapping_group> *groups; 13888 groups = omp_gather_mapping_groups (list_p); 13889 if (groups) 13890 { 13891 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap; 13892 grpmap = omp_index_mapping_groups (groups); 13893 13894 oacc_resolve_clause_dependencies (groups, grpmap); 13895 omp_build_struct_sibling_lists (code, ctx->region_type, groups, 13896 &grpmap, list_p); 13897 13898 delete groups; 13899 delete grpmap; 13900 } 13901 } 13902 13903 tree attach_list = NULL_TREE; 13904 tree *attach_tail = &attach_list; 13905 13906 tree *grp_start_p = NULL, grp_end = NULL_TREE; 13907 13908 while ((c = *list_p) != NULL) 13909 { 13910 splay_tree_node n; 13911 bool remove = false; 13912 bool move_attach = false; 13913 13914 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end)) 13915 grp_end = NULL_TREE; 13916 13917 switch (OMP_CLAUSE_CODE (c)) 13918 { 13919 case OMP_CLAUSE_FIRSTPRIVATE: 13920 if ((ctx->region_type & ORT_TARGET) 13921 && (ctx->region_type & ORT_ACC) == 0 13922 && TYPE_ATOMIC (strip_array_types 13923 (TREE_TYPE (OMP_CLAUSE_DECL (c))))) 13924 { 13925 error_at (OMP_CLAUSE_LOCATION (c), 13926 "%<_Atomic%> %qD in %<firstprivate%> clause on " 13927 "%<target%> construct", OMP_CLAUSE_DECL (c)); 13928 remove = true; 13929 break; 13930 } 13931 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) 13932 { 13933 decl = OMP_CLAUSE_DECL (c); 13934 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13935 if ((n->value & GOVD_MAP) != 0) 13936 { 13937 remove = true; 13938 break; 13939 } 13940 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0; 13941 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0; 13942 } 13943 /* FALLTHRU */ 13944 case OMP_CLAUSE_PRIVATE: 13945 case OMP_CLAUSE_SHARED: 13946 case OMP_CLAUSE_LINEAR: 13947 decl = OMP_CLAUSE_DECL (c); 13948 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13949 remove = !(n->value & GOVD_SEEN); 13950 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0 13951 && code == OMP_PARALLEL 13952 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) 13953 remove = true; 13954 if (! remove) 13955 { 13956 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED; 13957 if ((n->value & GOVD_DEBUG_PRIVATE) 13958 || lang_hooks.decls.omp_private_debug_clause (decl, shared)) 13959 { 13960 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0 13961 || ((n->value & GOVD_DATA_SHARE_CLASS) 13962 == GOVD_SHARED)); 13963 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE); 13964 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1; 13965 } 13966 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13967 && ctx->has_depend 13968 && DECL_P (decl)) 13969 n->value |= GOVD_WRITTEN; 13970 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13971 && (n->value & GOVD_WRITTEN) == 0 13972 && DECL_P (decl) 13973 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13974 OMP_CLAUSE_SHARED_READONLY (c) = 1; 13975 else if (DECL_P (decl) 13976 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13977 && (n->value & GOVD_WRITTEN) != 0) 13978 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 13979 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))) 13980 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13981 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 13982 } 13983 else 13984 n->value &= ~GOVD_EXPLICIT; 13985 break; 13986 13987 case OMP_CLAUSE_LASTPRIVATE: 13988 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to 13989 accurately reflect the presence of a FIRSTPRIVATE clause. */ 13990 decl = OMP_CLAUSE_DECL (c); 13991 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13992 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) 13993 = (n->value & GOVD_FIRSTPRIVATE) != 0; 13994 if (code == OMP_DISTRIBUTE 13995 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)) 13996 { 13997 remove = true; 13998 error_at (OMP_CLAUSE_LOCATION (c), 13999 "same variable used in %<firstprivate%> and " 14000 "%<lastprivate%> clauses on %<distribute%> " 14001 "construct"); 14002 } 14003 if (!remove 14004 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 14005 && DECL_P (decl) 14006 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 14007 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 14008 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL) 14009 remove = true; 14010 break; 14011 14012 case OMP_CLAUSE_ALIGNED: 14013 decl = OMP_CLAUSE_DECL (c); 14014 if (!is_global_var (decl)) 14015 { 14016 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14017 remove = n == NULL || !(n->value & GOVD_SEEN); 14018 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) 14019 { 14020 struct gimplify_omp_ctx *octx; 14021 if (n != NULL 14022 && (n->value & (GOVD_DATA_SHARE_CLASS 14023 & ~GOVD_FIRSTPRIVATE))) 14024 remove = true; 14025 else 14026 for (octx = ctx->outer_context; octx; 14027 octx = octx->outer_context) 14028 { 14029 n = splay_tree_lookup (octx->variables, 14030 (splay_tree_key) decl); 14031 if (n == NULL) 14032 continue; 14033 if (n->value & GOVD_LOCAL) 14034 break; 14035 /* We have to avoid assigning a shared variable 14036 to itself when trying to add 14037 __builtin_assume_aligned. */ 14038 if (n->value & GOVD_SHARED) 14039 { 14040 remove = true; 14041 break; 14042 } 14043 } 14044 } 14045 } 14046 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 14047 { 14048 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14049 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 14050 remove = true; 14051 } 14052 break; 14053 14054 case OMP_CLAUSE_HAS_DEVICE_ADDR: 14055 decl = OMP_CLAUSE_DECL (c); 14056 while (INDIRECT_REF_P (decl) 14057 || TREE_CODE (decl) == ARRAY_REF) 14058 decl = TREE_OPERAND (decl, 0); 14059 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14060 remove = n == NULL || !(n->value & GOVD_SEEN); 14061 break; 14062 14063 case OMP_CLAUSE_IS_DEVICE_PTR: 14064 case OMP_CLAUSE_NONTEMPORAL: 14065 decl = OMP_CLAUSE_DECL (c); 14066 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14067 remove = n == NULL || !(n->value & GOVD_SEEN); 14068 break; 14069 14070 case OMP_CLAUSE_MAP: 14071 decl = OMP_CLAUSE_DECL (c); 14072 if (!grp_end) 14073 { 14074 grp_start_p = list_p; 14075 grp_end = *omp_group_last (grp_start_p); 14076 } 14077 switch (OMP_CLAUSE_MAP_KIND (c)) 14078 { 14079 case GOMP_MAP_PRESENT_ALLOC: 14080 case GOMP_MAP_PRESENT_TO: 14081 case GOMP_MAP_PRESENT_FROM: 14082 case GOMP_MAP_PRESENT_TOFROM: 14083 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT); 14084 break; 14085 default: 14086 break; 14087 } 14088 switch (code) 14089 { 14090 case OACC_DATA: 14091 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) 14092 break; 14093 /* Fallthrough. */ 14094 case OACC_HOST_DATA: 14095 case OACC_ENTER_DATA: 14096 case OACC_EXIT_DATA: 14097 case OMP_TARGET_DATA: 14098 case OMP_TARGET_ENTER_DATA: 14099 case OMP_TARGET_EXIT_DATA: 14100 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 14101 || (OMP_CLAUSE_MAP_KIND (c) 14102 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 14103 /* For target {,enter ,exit }data only the array slice is 14104 mapped, but not the pointer to it. */ 14105 remove = true; 14106 if (code == OMP_TARGET_EXIT_DATA 14107 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER 14108 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)) 14109 remove = true; 14110 break; 14111 case OMP_TARGET: 14112 break; 14113 default: 14114 break; 14115 } 14116 if (remove) 14117 break; 14118 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14119 { 14120 /* Sanity check: attach/detach map kinds use the size as a bias, 14121 and it's never right to use the decl size for such 14122 mappings. */ 14123 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH 14124 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH 14125 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH 14126 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH 14127 && (OMP_CLAUSE_MAP_KIND (c) 14128 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)); 14129 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) 14130 : TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14131 } 14132 gimplify_omp_ctxp = ctx->outer_context; 14133 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL, 14134 is_gimple_val, fb_rvalue) == GS_ERROR) 14135 { 14136 gimplify_omp_ctxp = ctx; 14137 remove = true; 14138 break; 14139 } 14140 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 14141 || (OMP_CLAUSE_MAP_KIND (c) 14142 == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 14143 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14144 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST) 14145 { 14146 OMP_CLAUSE_SIZE (c) 14147 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL, 14148 false); 14149 if ((ctx->region_type & ORT_TARGET) != 0) 14150 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c), 14151 GOVD_FIRSTPRIVATE | GOVD_SEEN); 14152 } 14153 gimplify_omp_ctxp = ctx; 14154 /* Data clauses associated with reductions must be 14155 compatible with present_or_copy. Warn and adjust the clause 14156 if that is not the case. */ 14157 if (ctx->region_type == ORT_ACC_PARALLEL 14158 || ctx->region_type == ORT_ACC_SERIAL) 14159 { 14160 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0); 14161 n = NULL; 14162 14163 if (DECL_P (t)) 14164 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 14165 14166 if (n && (n->value & GOVD_REDUCTION)) 14167 { 14168 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c); 14169 14170 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1; 14171 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM 14172 && kind != GOMP_MAP_FORCE_PRESENT 14173 && kind != GOMP_MAP_POINTER) 14174 { 14175 warning_at (OMP_CLAUSE_LOCATION (c), 0, 14176 "incompatible data clause with reduction " 14177 "on %qE; promoting to %<present_or_copy%>", 14178 DECL_NAME (t)); 14179 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM); 14180 } 14181 } 14182 } 14183 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT 14184 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD) 14185 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)) 14186 { 14187 remove = true; 14188 break; 14189 } 14190 /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or 14191 a variable captured in a lambda closure), look through that now 14192 before the DECL_P check below. (A code other than COMPONENT_REF, 14193 i.e. INDIRECT_REF, will be a VLA/variable-length array 14194 section. A global var may be a variable in a common block. We 14195 don't want to do this here for either of those.) */ 14196 if ((ctx->region_type & ORT_ACC) == 0 14197 && DECL_P (decl) 14198 && !is_global_var (decl) 14199 && DECL_HAS_VALUE_EXPR_P (decl) 14200 && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF) 14201 decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl); 14202 if (TREE_CODE (decl) == TARGET_EXPR) 14203 { 14204 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 14205 is_gimple_lvalue, fb_lvalue) == GS_ERROR) 14206 remove = true; 14207 } 14208 else if (!DECL_P (decl)) 14209 { 14210 if ((ctx->region_type & ORT_TARGET) != 0 14211 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) 14212 { 14213 if (INDIRECT_REF_P (decl) 14214 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 14215 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 14216 == REFERENCE_TYPE)) 14217 decl = TREE_OPERAND (decl, 0); 14218 if (TREE_CODE (decl) == COMPONENT_REF) 14219 { 14220 while (TREE_CODE (decl) == COMPONENT_REF) 14221 decl = TREE_OPERAND (decl, 0); 14222 if (DECL_P (decl)) 14223 { 14224 n = splay_tree_lookup (ctx->variables, 14225 (splay_tree_key) decl); 14226 if (!(n->value & GOVD_SEEN)) 14227 remove = true; 14228 } 14229 } 14230 } 14231 14232 tree d = decl, *pd; 14233 if (TREE_CODE (d) == ARRAY_REF) 14234 { 14235 while (TREE_CODE (d) == ARRAY_REF) 14236 d = TREE_OPERAND (d, 0); 14237 if (TREE_CODE (d) == COMPONENT_REF 14238 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 14239 decl = d; 14240 } 14241 pd = &OMP_CLAUSE_DECL (c); 14242 if (d == decl 14243 && TREE_CODE (decl) == INDIRECT_REF 14244 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 14245 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 14246 == REFERENCE_TYPE) 14247 && (OMP_CLAUSE_MAP_KIND (c) 14248 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 14249 { 14250 pd = &TREE_OPERAND (decl, 0); 14251 decl = TREE_OPERAND (decl, 0); 14252 } 14253 14254 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14255 switch (code) 14256 { 14257 case OACC_ENTER_DATA: 14258 case OACC_EXIT_DATA: 14259 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 14260 == ARRAY_TYPE) 14261 remove = true; 14262 else if (code == OACC_ENTER_DATA) 14263 goto change_to_attach; 14264 /* Fallthrough. */ 14265 case OMP_TARGET_EXIT_DATA: 14266 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH); 14267 break; 14268 case OACC_UPDATE: 14269 /* An "attach/detach" operation on an update directive 14270 should behave as a GOMP_MAP_ALWAYS_POINTER. Note that 14271 both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER 14272 kinds depend on the previous mapping (for non-TARGET 14273 regions). */ 14274 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER); 14275 break; 14276 default: 14277 change_to_attach: 14278 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH); 14279 if ((ctx->region_type & ORT_TARGET) != 0) 14280 move_attach = true; 14281 } 14282 else if ((ctx->region_type & ORT_TARGET) != 0 14283 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 14284 || (OMP_CLAUSE_MAP_KIND (c) 14285 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))) 14286 move_attach = true; 14287 14288 /* If we have e.g. map(struct: *var), don't gimplify the 14289 argument since omp-low.cc wants to see the decl itself. */ 14290 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT) 14291 break; 14292 14293 /* We've already partly gimplified this in 14294 gimplify_scan_omp_clauses. Don't do any more. */ 14295 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c)) 14296 break; 14297 14298 gimplify_omp_ctxp = ctx->outer_context; 14299 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, 14300 fb_lvalue) == GS_ERROR) 14301 remove = true; 14302 gimplify_omp_ctxp = ctx; 14303 break; 14304 } 14305 14306 if ((code == OMP_TARGET 14307 || code == OMP_TARGET_DATA 14308 || code == OMP_TARGET_ENTER_DATA 14309 || code == OMP_TARGET_EXIT_DATA) 14310 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14311 { 14312 bool firstprivatize = false; 14313 14314 for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx; 14315 octx = octx->outer_context) 14316 { 14317 splay_tree_node n 14318 = splay_tree_lookup (octx->variables, 14319 (splay_tree_key) OMP_CLAUSE_DECL (c)); 14320 /* If this is contained in an outer OpenMP region as a 14321 firstprivate value, remove the attach/detach. */ 14322 if (n && (n->value & GOVD_FIRSTPRIVATE)) 14323 { 14324 firstprivatize = true; 14325 break; 14326 } 14327 } 14328 14329 enum gomp_map_kind map_kind; 14330 if (firstprivatize) 14331 map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER; 14332 else if (code == OMP_TARGET_EXIT_DATA) 14333 map_kind = GOMP_MAP_DETACH; 14334 else 14335 map_kind = GOMP_MAP_ATTACH; 14336 OMP_CLAUSE_SET_MAP_KIND (c, map_kind); 14337 } 14338 else if ((ctx->region_type & ORT_ACC) != 0 14339 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14340 { 14341 enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA 14342 ? GOMP_MAP_DETACH 14343 : GOMP_MAP_ATTACH); 14344 OMP_CLAUSE_SET_MAP_KIND (c, map_kind); 14345 } 14346 14347 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14348 if ((ctx->region_type & ORT_TARGET) != 0 14349 && !(n->value & GOVD_SEEN) 14350 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0 14351 && (!is_global_var (decl) 14352 || !lookup_attribute ("omp declare target link", 14353 DECL_ATTRIBUTES (decl)))) 14354 { 14355 remove = true; 14356 /* For struct element mapping, if struct is never referenced 14357 in target block and none of the mapping has always modifier, 14358 remove all the struct element mappings, which immediately 14359 follow the GOMP_MAP_STRUCT map clause. */ 14360 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT 14361 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD) 14362 { 14363 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c)); 14364 while (cnt--) 14365 OMP_CLAUSE_CHAIN (c) 14366 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c)); 14367 } 14368 } 14369 else if (DECL_SIZE (decl) 14370 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST 14371 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER 14372 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER 14373 && (OMP_CLAUSE_MAP_KIND (c) 14374 != GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 14375 { 14376 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because 14377 for these, TREE_CODE (DECL_SIZE (decl)) will always be 14378 INTEGER_CST. */ 14379 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR); 14380 14381 tree decl2 = DECL_VALUE_EXPR (decl); 14382 gcc_assert (INDIRECT_REF_P (decl2)); 14383 decl2 = TREE_OPERAND (decl2, 0); 14384 gcc_assert (DECL_P (decl2)); 14385 tree mem = build_simple_mem_ref (decl2); 14386 OMP_CLAUSE_DECL (c) = mem; 14387 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14388 if (ctx->outer_context) 14389 { 14390 omp_notice_variable (ctx->outer_context, decl2, true); 14391 omp_notice_variable (ctx->outer_context, 14392 OMP_CLAUSE_SIZE (c), true); 14393 } 14394 if (((ctx->region_type & ORT_TARGET) != 0 14395 || !ctx->target_firstprivatize_array_bases) 14396 && ((n->value & GOVD_SEEN) == 0 14397 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0)) 14398 { 14399 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 14400 OMP_CLAUSE_MAP); 14401 OMP_CLAUSE_DECL (nc) = decl; 14402 OMP_CLAUSE_SIZE (nc) = size_zero_node; 14403 if (ctx->target_firstprivatize_array_bases) 14404 OMP_CLAUSE_SET_MAP_KIND (nc, 14405 GOMP_MAP_FIRSTPRIVATE_POINTER); 14406 else 14407 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 14408 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c); 14409 OMP_CLAUSE_CHAIN (c) = nc; 14410 c = nc; 14411 } 14412 } 14413 else 14414 { 14415 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14416 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); 14417 gcc_assert ((n->value & GOVD_SEEN) == 0 14418 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) 14419 == 0)); 14420 } 14421 14422 /* If we have a target region, we can push all the attaches to the 14423 end of the list (we may have standalone "attach" operations 14424 synthesized for GOMP_MAP_STRUCT nodes that must be processed after 14425 the attachment point AND the pointed-to block have been mapped). 14426 If we have something else, e.g. "enter data", we need to keep 14427 "attach" nodes together with the previous node they attach to so 14428 that separate "exit data" operations work properly (see 14429 libgomp/target.c). */ 14430 if ((ctx->region_type & ORT_TARGET) != 0 14431 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 14432 || (OMP_CLAUSE_MAP_KIND (c) 14433 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))) 14434 move_attach = true; 14435 14436 break; 14437 14438 case OMP_CLAUSE_TO: 14439 case OMP_CLAUSE_FROM: 14440 case OMP_CLAUSE__CACHE_: 14441 decl = OMP_CLAUSE_DECL (c); 14442 if (!DECL_P (decl)) 14443 break; 14444 if (DECL_SIZE (decl) 14445 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 14446 { 14447 tree decl2 = DECL_VALUE_EXPR (decl); 14448 gcc_assert (INDIRECT_REF_P (decl2)); 14449 decl2 = TREE_OPERAND (decl2, 0); 14450 gcc_assert (DECL_P (decl2)); 14451 tree mem = build_simple_mem_ref (decl2); 14452 OMP_CLAUSE_DECL (c) = mem; 14453 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14454 if (ctx->outer_context) 14455 { 14456 omp_notice_variable (ctx->outer_context, decl2, true); 14457 omp_notice_variable (ctx->outer_context, 14458 OMP_CLAUSE_SIZE (c), true); 14459 } 14460 } 14461 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14462 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); 14463 break; 14464 14465 case OMP_CLAUSE_REDUCTION: 14466 if (OMP_CLAUSE_REDUCTION_INSCAN (c)) 14467 { 14468 decl = OMP_CLAUSE_DECL (c); 14469 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14470 if ((n->value & GOVD_REDUCTION_INSCAN) == 0) 14471 { 14472 remove = true; 14473 error_at (OMP_CLAUSE_LOCATION (c), 14474 "%qD specified in %<inscan%> %<reduction%> clause " 14475 "but not in %<scan%> directive clause", decl); 14476 break; 14477 } 14478 has_inscan_reductions = true; 14479 } 14480 /* FALLTHRU */ 14481 case OMP_CLAUSE_IN_REDUCTION: 14482 case OMP_CLAUSE_TASK_REDUCTION: 14483 decl = OMP_CLAUSE_DECL (c); 14484 /* OpenACC reductions need a present_or_copy data clause. 14485 Add one if necessary. Emit error when the reduction is private. */ 14486 if (ctx->region_type == ORT_ACC_PARALLEL 14487 || ctx->region_type == ORT_ACC_SERIAL) 14488 { 14489 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14490 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) 14491 { 14492 remove = true; 14493 error_at (OMP_CLAUSE_LOCATION (c), "invalid private " 14494 "reduction on %qE", DECL_NAME (decl)); 14495 } 14496 else if ((n->value & GOVD_MAP) == 0) 14497 { 14498 tree next = OMP_CLAUSE_CHAIN (c); 14499 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP); 14500 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM); 14501 OMP_CLAUSE_DECL (nc) = decl; 14502 OMP_CLAUSE_CHAIN (c) = nc; 14503 lang_hooks.decls.omp_finish_clause (nc, pre_p, 14504 (ctx->region_type 14505 & ORT_ACC) != 0); 14506 while (1) 14507 { 14508 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1; 14509 if (OMP_CLAUSE_CHAIN (nc) == NULL) 14510 break; 14511 nc = OMP_CLAUSE_CHAIN (nc); 14512 } 14513 OMP_CLAUSE_CHAIN (nc) = next; 14514 n->value |= GOVD_MAP; 14515 } 14516 } 14517 if (DECL_P (decl) 14518 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 14519 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 14520 break; 14521 14522 case OMP_CLAUSE_ALLOCATE: 14523 decl = OMP_CLAUSE_DECL (c); 14524 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14525 if (n != NULL && !(n->value & GOVD_SEEN)) 14526 { 14527 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR)) 14528 != 0 14529 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0) 14530 remove = true; 14531 } 14532 if (!remove 14533 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 14534 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST 14535 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0 14536 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK 14537 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)) 14538 { 14539 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); 14540 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator); 14541 if (n == NULL) 14542 { 14543 enum omp_clause_default_kind default_kind 14544 = ctx->default_kind; 14545 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 14546 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 14547 true); 14548 ctx->default_kind = default_kind; 14549 } 14550 else 14551 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 14552 true); 14553 } 14554 break; 14555 14556 case OMP_CLAUSE_COPYIN: 14557 case OMP_CLAUSE_COPYPRIVATE: 14558 case OMP_CLAUSE_IF: 14559 case OMP_CLAUSE_SELF: 14560 case OMP_CLAUSE_NUM_THREADS: 14561 case OMP_CLAUSE_NUM_TEAMS: 14562 case OMP_CLAUSE_THREAD_LIMIT: 14563 case OMP_CLAUSE_DIST_SCHEDULE: 14564 case OMP_CLAUSE_DEVICE: 14565 case OMP_CLAUSE_SCHEDULE: 14566 case OMP_CLAUSE_NOWAIT: 14567 case OMP_CLAUSE_ORDERED: 14568 case OMP_CLAUSE_DEFAULT: 14569 case OMP_CLAUSE_UNTIED: 14570 case OMP_CLAUSE_COLLAPSE: 14571 case OMP_CLAUSE_FINAL: 14572 case OMP_CLAUSE_MERGEABLE: 14573 case OMP_CLAUSE_PROC_BIND: 14574 case OMP_CLAUSE_SAFELEN: 14575 case OMP_CLAUSE_SIMDLEN: 14576 case OMP_CLAUSE_DEPEND: 14577 case OMP_CLAUSE_DOACROSS: 14578 case OMP_CLAUSE_PRIORITY: 14579 case OMP_CLAUSE_GRAINSIZE: 14580 case OMP_CLAUSE_NUM_TASKS: 14581 case OMP_CLAUSE_NOGROUP: 14582 case OMP_CLAUSE_THREADS: 14583 case OMP_CLAUSE_SIMD: 14584 case OMP_CLAUSE_FILTER: 14585 case OMP_CLAUSE_HINT: 14586 case OMP_CLAUSE_DEFAULTMAP: 14587 case OMP_CLAUSE_ORDER: 14588 case OMP_CLAUSE_BIND: 14589 case OMP_CLAUSE_DETACH: 14590 case OMP_CLAUSE_USE_DEVICE_PTR: 14591 case OMP_CLAUSE_USE_DEVICE_ADDR: 14592 case OMP_CLAUSE_ASYNC: 14593 case OMP_CLAUSE_WAIT: 14594 case OMP_CLAUSE_INDEPENDENT: 14595 case OMP_CLAUSE_NUM_GANGS: 14596 case OMP_CLAUSE_NUM_WORKERS: 14597 case OMP_CLAUSE_VECTOR_LENGTH: 14598 case OMP_CLAUSE_GANG: 14599 case OMP_CLAUSE_WORKER: 14600 case OMP_CLAUSE_VECTOR: 14601 case OMP_CLAUSE_AUTO: 14602 case OMP_CLAUSE_SEQ: 14603 case OMP_CLAUSE_TILE: 14604 case OMP_CLAUSE_IF_PRESENT: 14605 case OMP_CLAUSE_FINALIZE: 14606 case OMP_CLAUSE_INCLUSIVE: 14607 case OMP_CLAUSE_EXCLUSIVE: 14608 break; 14609 14610 case OMP_CLAUSE_NOHOST: 14611 default: 14612 gcc_unreachable (); 14613 } 14614 14615 if (remove) 14616 *list_p = OMP_CLAUSE_CHAIN (c); 14617 else if (move_attach) 14618 { 14619 /* Remove attach node from here, separate out into its own list. */ 14620 *attach_tail = c; 14621 *list_p = OMP_CLAUSE_CHAIN (c); 14622 OMP_CLAUSE_CHAIN (c) = NULL_TREE; 14623 attach_tail = &OMP_CLAUSE_CHAIN (c); 14624 } 14625 else 14626 list_p = &OMP_CLAUSE_CHAIN (c); 14627 } 14628 14629 /* Splice attach nodes at the end of the list. */ 14630 if (attach_list) 14631 { 14632 *list_p = attach_list; 14633 list_p = attach_tail; 14634 } 14635 14636 /* Add in any implicit data sharing. */ 14637 struct gimplify_adjust_omp_clauses_data data; 14638 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0) 14639 { 14640 /* OpenMP. Implicit clauses are added at the start of the clause list, 14641 but after any non-map clauses. */ 14642 tree *implicit_add_list_p = orig_list_p; 14643 while (*implicit_add_list_p 14644 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP) 14645 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p); 14646 data.list_p = implicit_add_list_p; 14647 } 14648 else 14649 /* OpenACC. */ 14650 data.list_p = list_p; 14651 data.pre_p = pre_p; 14652 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data); 14653 14654 if (has_inscan_reductions) 14655 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c)) 14656 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 14657 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 14658 { 14659 error_at (OMP_CLAUSE_LOCATION (c), 14660 "%<inscan%> %<reduction%> clause used together with " 14661 "%<linear%> clause for a variable other than loop " 14662 "iterator"); 14663 break; 14664 } 14665 14666 gimplify_omp_ctxp = ctx->outer_context; 14667 delete_omp_context (ctx); 14668 } 14669 14670 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context, 14671 -1 if unknown yet (simd is involved, won't be known until vectorization) 14672 and 1 if they do. If SCORES is non-NULL, it should point to an array 14673 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions 14674 of the CONSTRUCTS (position -1 if it will never match) followed by 14675 number of constructs in the OpenMP context construct trait. If the 14676 score depends on whether it will be in a declare simd clone or not, 14677 the function returns 2 and there will be two sets of the scores, the first 14678 one for the case that it is not in a declare simd clone, the other 14679 that it is in a declare simd clone. */ 14680 14681 int 14682 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs, 14683 int *scores) 14684 { 14685 int matched = 0, cnt = 0; 14686 bool simd_seen = false; 14687 bool target_seen = false; 14688 int declare_simd_cnt = -1; 14689 auto_vec<enum tree_code, 16> codes; 14690 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;) 14691 { 14692 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL) 14693 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC)) 14694 == ORT_TARGET && ctx->code == OMP_TARGET) 14695 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS) 14696 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR) 14697 || (ctx->region_type == ORT_SIMD 14698 && ctx->code == OMP_SIMD 14699 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND))) 14700 { 14701 ++cnt; 14702 if (scores) 14703 codes.safe_push (ctx->code); 14704 else if (matched < nconstructs && ctx->code == constructs[matched]) 14705 { 14706 if (ctx->code == OMP_SIMD) 14707 { 14708 if (matched) 14709 return 0; 14710 simd_seen = true; 14711 } 14712 ++matched; 14713 } 14714 if (ctx->code == OMP_TARGET) 14715 { 14716 if (scores == NULL) 14717 return matched < nconstructs ? 0 : simd_seen ? -1 : 1; 14718 target_seen = true; 14719 break; 14720 } 14721 } 14722 else if (ctx->region_type == ORT_WORKSHARE 14723 && ctx->code == OMP_LOOP 14724 && ctx->outer_context 14725 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL 14726 && ctx->outer_context->outer_context 14727 && ctx->outer_context->outer_context->code == OMP_LOOP 14728 && ctx->outer_context->outer_context->distribute) 14729 ctx = ctx->outer_context->outer_context; 14730 ctx = ctx->outer_context; 14731 } 14732 if (!target_seen 14733 && lookup_attribute ("omp declare simd", 14734 DECL_ATTRIBUTES (current_function_decl))) 14735 { 14736 /* Declare simd is a maybe case, it is supposed to be added only to the 14737 omp-simd-clone.cc added clones and not to the base function. */ 14738 declare_simd_cnt = cnt++; 14739 if (scores) 14740 codes.safe_push (OMP_SIMD); 14741 else if (cnt == 0 14742 && constructs[0] == OMP_SIMD) 14743 { 14744 gcc_assert (matched == 0); 14745 simd_seen = true; 14746 if (++matched == nconstructs) 14747 return -1; 14748 } 14749 } 14750 if (tree attr = lookup_attribute ("omp declare variant variant", 14751 DECL_ATTRIBUTES (current_function_decl))) 14752 { 14753 tree selectors = TREE_VALUE (attr); 14754 int variant_nconstructs = list_length (selectors); 14755 enum tree_code *variant_constructs = NULL; 14756 if (!target_seen && variant_nconstructs) 14757 { 14758 variant_constructs 14759 = (enum tree_code *) alloca (variant_nconstructs 14760 * sizeof (enum tree_code)); 14761 omp_construct_traits_to_codes (selectors, variant_nconstructs, 14762 variant_constructs); 14763 } 14764 for (int i = 0; i < variant_nconstructs; i++) 14765 { 14766 ++cnt; 14767 if (scores) 14768 codes.safe_push (variant_constructs[i]); 14769 else if (matched < nconstructs 14770 && variant_constructs[i] == constructs[matched]) 14771 { 14772 if (variant_constructs[i] == OMP_SIMD) 14773 { 14774 if (matched) 14775 return 0; 14776 simd_seen = true; 14777 } 14778 ++matched; 14779 } 14780 } 14781 } 14782 if (!target_seen 14783 && lookup_attribute ("omp declare target block", 14784 DECL_ATTRIBUTES (current_function_decl))) 14785 { 14786 if (scores) 14787 codes.safe_push (OMP_TARGET); 14788 else if (matched < nconstructs && constructs[matched] == OMP_TARGET) 14789 ++matched; 14790 } 14791 if (scores) 14792 { 14793 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++) 14794 { 14795 int j = codes.length () - 1; 14796 for (int i = nconstructs - 1; i >= 0; i--) 14797 { 14798 while (j >= 0 14799 && (pass != 0 || declare_simd_cnt != j) 14800 && constructs[i] != codes[j]) 14801 --j; 14802 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt) 14803 *scores++ = j - 1; 14804 else 14805 *scores++ = j; 14806 } 14807 *scores++ = ((pass == 0 && declare_simd_cnt != -1) 14808 ? codes.length () - 1 : codes.length ()); 14809 } 14810 return declare_simd_cnt == -1 ? 1 : 2; 14811 } 14812 if (matched == nconstructs) 14813 return simd_seen ? -1 : 1; 14814 return 0; 14815 } 14816 14817 /* Gimplify OACC_CACHE. */ 14818 14819 static void 14820 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p) 14821 { 14822 tree expr = *expr_p; 14823 14824 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC, 14825 OACC_CACHE); 14826 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr), 14827 OACC_CACHE); 14828 14829 /* TODO: Do something sensible with this information. */ 14830 14831 *expr_p = NULL_TREE; 14832 } 14833 14834 /* Helper function of gimplify_oacc_declare. The helper's purpose is to, 14835 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit' 14836 kind. The entry kind will replace the one in CLAUSE, while the exit 14837 kind will be used in a new omp_clause and returned to the caller. */ 14838 14839 static tree 14840 gimplify_oacc_declare_1 (tree clause) 14841 { 14842 HOST_WIDE_INT kind, new_op; 14843 bool ret = false; 14844 tree c = NULL; 14845 14846 kind = OMP_CLAUSE_MAP_KIND (clause); 14847 14848 switch (kind) 14849 { 14850 case GOMP_MAP_ALLOC: 14851 new_op = GOMP_MAP_RELEASE; 14852 ret = true; 14853 break; 14854 14855 case GOMP_MAP_FROM: 14856 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC); 14857 new_op = GOMP_MAP_FROM; 14858 ret = true; 14859 break; 14860 14861 case GOMP_MAP_TOFROM: 14862 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO); 14863 new_op = GOMP_MAP_FROM; 14864 ret = true; 14865 break; 14866 14867 case GOMP_MAP_DEVICE_RESIDENT: 14868 case GOMP_MAP_FORCE_DEVICEPTR: 14869 case GOMP_MAP_FORCE_PRESENT: 14870 case GOMP_MAP_LINK: 14871 case GOMP_MAP_POINTER: 14872 case GOMP_MAP_TO: 14873 break; 14874 14875 default: 14876 gcc_unreachable (); 14877 break; 14878 } 14879 14880 if (ret) 14881 { 14882 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP); 14883 OMP_CLAUSE_SET_MAP_KIND (c, new_op); 14884 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause); 14885 } 14886 14887 return c; 14888 } 14889 14890 /* Gimplify OACC_DECLARE. */ 14891 14892 static void 14893 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p) 14894 { 14895 tree expr = *expr_p; 14896 gomp_target *stmt; 14897 tree clauses, t, decl; 14898 14899 clauses = OACC_DECLARE_CLAUSES (expr); 14900 14901 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE); 14902 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE); 14903 14904 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t)) 14905 { 14906 decl = OMP_CLAUSE_DECL (t); 14907 14908 if (TREE_CODE (decl) == MEM_REF) 14909 decl = TREE_OPERAND (decl, 0); 14910 14911 if (VAR_P (decl) && !is_oacc_declared (decl)) 14912 { 14913 tree attr = get_identifier ("oacc declare target"); 14914 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE, 14915 DECL_ATTRIBUTES (decl)); 14916 } 14917 14918 if (VAR_P (decl) 14919 && !is_global_var (decl) 14920 && DECL_CONTEXT (decl) == current_function_decl) 14921 { 14922 tree c = gimplify_oacc_declare_1 (t); 14923 if (c) 14924 { 14925 if (oacc_declare_returns == NULL) 14926 oacc_declare_returns = new hash_map<tree, tree>; 14927 14928 oacc_declare_returns->put (decl, c); 14929 } 14930 } 14931 14932 if (gimplify_omp_ctxp) 14933 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN); 14934 } 14935 14936 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE, 14937 clauses); 14938 14939 gimplify_seq_add_stmt (pre_p, stmt); 14940 14941 *expr_p = NULL_TREE; 14942 } 14943 14944 /* Gimplify the contents of an OMP_PARALLEL statement. This involves 14945 gimplification of the body, as well as scanning the body for used 14946 variables. We need to do this scan now, because variable-sized 14947 decls will be decomposed during gimplification. */ 14948 14949 static void 14950 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p) 14951 { 14952 tree expr = *expr_p; 14953 gimple *g; 14954 gimple_seq body = NULL; 14955 14956 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, 14957 OMP_PARALLEL_COMBINED (expr) 14958 ? ORT_COMBINED_PARALLEL 14959 : ORT_PARALLEL, OMP_PARALLEL); 14960 14961 push_gimplify_context (); 14962 14963 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body); 14964 if (gimple_code (g) == GIMPLE_BIND) 14965 pop_gimplify_context (g); 14966 else 14967 pop_gimplify_context (NULL); 14968 14969 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr), 14970 OMP_PARALLEL); 14971 14972 g = gimple_build_omp_parallel (body, 14973 OMP_PARALLEL_CLAUSES (expr), 14974 NULL_TREE, NULL_TREE); 14975 if (OMP_PARALLEL_COMBINED (expr)) 14976 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED); 14977 gimplify_seq_add_stmt (pre_p, g); 14978 *expr_p = NULL_TREE; 14979 } 14980 14981 /* Gimplify the contents of an OMP_TASK statement. This involves 14982 gimplification of the body, as well as scanning the body for used 14983 variables. We need to do this scan now, because variable-sized 14984 decls will be decomposed during gimplification. */ 14985 14986 static void 14987 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p) 14988 { 14989 tree expr = *expr_p; 14990 gimple *g; 14991 gimple_seq body = NULL; 14992 bool nowait = false; 14993 bool has_depend = false; 14994 14995 if (OMP_TASK_BODY (expr) == NULL_TREE) 14996 { 14997 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 14998 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 14999 { 15000 has_depend = true; 15001 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET) 15002 { 15003 error_at (OMP_CLAUSE_LOCATION (c), 15004 "%<mutexinoutset%> kind in %<depend%> clause on a " 15005 "%<taskwait%> construct"); 15006 break; 15007 } 15008 } 15009 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT) 15010 nowait = true; 15011 if (nowait && !has_depend) 15012 { 15013 error_at (EXPR_LOCATION (expr), 15014 "%<taskwait%> construct with %<nowait%> clause but no " 15015 "%<depend%> clauses"); 15016 *expr_p = NULL_TREE; 15017 return; 15018 } 15019 } 15020 15021 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, 15022 omp_find_clause (OMP_TASK_CLAUSES (expr), 15023 OMP_CLAUSE_UNTIED) 15024 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK); 15025 15026 if (OMP_TASK_BODY (expr)) 15027 { 15028 push_gimplify_context (); 15029 15030 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body); 15031 if (gimple_code (g) == GIMPLE_BIND) 15032 pop_gimplify_context (g); 15033 else 15034 pop_gimplify_context (NULL); 15035 } 15036 15037 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr), 15038 OMP_TASK); 15039 15040 g = gimple_build_omp_task (body, 15041 OMP_TASK_CLAUSES (expr), 15042 NULL_TREE, NULL_TREE, 15043 NULL_TREE, NULL_TREE, NULL_TREE); 15044 if (OMP_TASK_BODY (expr) == NULL_TREE) 15045 gimple_omp_task_set_taskwait_p (g, true); 15046 gimplify_seq_add_stmt (pre_p, g); 15047 *expr_p = NULL_TREE; 15048 } 15049 15050 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant, 15051 force it into a temporary initialized in PRE_P and add firstprivate clause 15052 to ORIG_FOR_STMT. */ 15053 15054 static void 15055 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p, 15056 tree orig_for_stmt) 15057 { 15058 if (*tp == NULL || is_gimple_constant (*tp)) 15059 return; 15060 15061 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false); 15062 /* Reference to pointer conversion is considered useless, 15063 but is significant for firstprivate clause. Force it 15064 here. */ 15065 if (type 15066 && TREE_CODE (type) == POINTER_TYPE 15067 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE) 15068 { 15069 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type)); 15070 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp); 15071 gimplify_and_add (m, pre_p); 15072 *tp = v; 15073 } 15074 15075 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); 15076 OMP_CLAUSE_DECL (c) = *tp; 15077 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt); 15078 OMP_FOR_CLAUSES (orig_for_stmt) = c; 15079 } 15080 15081 /* Helper function of gimplify_omp_for, find OMP_ORDERED with 15082 null OMP_ORDERED_BODY inside of OMP_FOR's body. */ 15083 15084 static tree 15085 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *) 15086 { 15087 switch (TREE_CODE (*tp)) 15088 { 15089 case OMP_ORDERED: 15090 if (OMP_ORDERED_BODY (*tp) == NULL_TREE) 15091 return *tp; 15092 break; 15093 case OMP_SIMD: 15094 case OMP_PARALLEL: 15095 case OMP_TARGET: 15096 *walk_subtrees = 0; 15097 break; 15098 default: 15099 break; 15100 } 15101 return NULL_TREE; 15102 } 15103 15104 /* Gimplify the gross structure of an OMP_FOR statement. */ 15105 15106 static enum gimplify_status 15107 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) 15108 { 15109 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t; 15110 enum gimplify_status ret = GS_ALL_DONE; 15111 enum gimplify_status tret; 15112 gomp_for *gfor; 15113 gimple_seq for_body, for_pre_body; 15114 int i; 15115 bitmap has_decl_expr = NULL; 15116 enum omp_region_type ort = ORT_WORKSHARE; 15117 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP; 15118 15119 orig_for_stmt = for_stmt = *expr_p; 15120 15121 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND) 15122 != NULL_TREE); 15123 if (OMP_FOR_INIT (for_stmt) == NULL_TREE) 15124 { 15125 tree *data[4] = { NULL, NULL, NULL, NULL }; 15126 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP); 15127 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt), 15128 find_combined_omp_for, data, NULL); 15129 if (inner_for_stmt == NULL_TREE) 15130 { 15131 gcc_assert (seen_error ()); 15132 *expr_p = NULL_TREE; 15133 return GS_ERROR; 15134 } 15135 if (data[2] && OMP_FOR_PRE_BODY (*data[2])) 15136 { 15137 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]), 15138 &OMP_FOR_PRE_BODY (for_stmt)); 15139 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE; 15140 } 15141 if (OMP_FOR_PRE_BODY (inner_for_stmt)) 15142 { 15143 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt), 15144 &OMP_FOR_PRE_BODY (for_stmt)); 15145 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE; 15146 } 15147 15148 if (data[0]) 15149 { 15150 /* We have some statements or variable declarations in between 15151 the composite construct directives. Move them around the 15152 inner_for_stmt. */ 15153 data[0] = expr_p; 15154 for (i = 0; i < 3; i++) 15155 if (data[i]) 15156 { 15157 tree t = *data[i]; 15158 if (i < 2 && data[i + 1] == &OMP_BODY (t)) 15159 data[i + 1] = data[i]; 15160 *data[i] = OMP_BODY (t); 15161 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE, 15162 NULL_TREE, make_node (BLOCK)); 15163 OMP_BODY (t) = body; 15164 append_to_statement_list_force (inner_for_stmt, 15165 &BIND_EXPR_BODY (body)); 15166 *data[3] = t; 15167 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body))); 15168 gcc_assert (*data[3] == inner_for_stmt); 15169 } 15170 return GS_OK; 15171 } 15172 15173 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++) 15174 if (!loop_p 15175 && OMP_FOR_ORIG_DECLS (inner_for_stmt) 15176 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15177 i)) == TREE_LIST 15178 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15179 i))) 15180 { 15181 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i); 15182 /* Class iterators aren't allowed on OMP_SIMD, so the only 15183 case we need to solve is distribute parallel for. They are 15184 allowed on the loop construct, but that is already handled 15185 in gimplify_omp_loop. */ 15186 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR 15187 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE 15188 && data[1]); 15189 tree orig_decl = TREE_PURPOSE (orig); 15190 tree last = TREE_VALUE (orig); 15191 tree *pc; 15192 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt); 15193 *pc; pc = &OMP_CLAUSE_CHAIN (*pc)) 15194 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE 15195 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE) 15196 && OMP_CLAUSE_DECL (*pc) == orig_decl) 15197 break; 15198 if (*pc == NULL_TREE) 15199 { 15200 tree *spc; 15201 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]); 15202 *spc; spc = &OMP_CLAUSE_CHAIN (*spc)) 15203 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE 15204 && OMP_CLAUSE_DECL (*spc) == orig_decl) 15205 break; 15206 if (*spc) 15207 { 15208 tree c = *spc; 15209 *spc = OMP_CLAUSE_CHAIN (c); 15210 OMP_CLAUSE_CHAIN (c) = NULL_TREE; 15211 *pc = c; 15212 } 15213 } 15214 if (*pc == NULL_TREE) 15215 ; 15216 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE) 15217 { 15218 /* private clause will appear only on inner_for_stmt. 15219 Change it into firstprivate, and add private clause 15220 on for_stmt. */ 15221 tree c = copy_node (*pc); 15222 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15223 OMP_FOR_CLAUSES (for_stmt) = c; 15224 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE; 15225 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc); 15226 } 15227 else 15228 { 15229 /* lastprivate clause will appear on both inner_for_stmt 15230 and for_stmt. Add firstprivate clause to 15231 inner_for_stmt. */ 15232 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc), 15233 OMP_CLAUSE_FIRSTPRIVATE); 15234 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc); 15235 OMP_CLAUSE_CHAIN (c) = *pc; 15236 *pc = c; 15237 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc); 15238 } 15239 tree c = build_omp_clause (UNKNOWN_LOCATION, 15240 OMP_CLAUSE_FIRSTPRIVATE); 15241 OMP_CLAUSE_DECL (c) = last; 15242 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15243 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15244 c = build_omp_clause (UNKNOWN_LOCATION, 15245 *pc ? OMP_CLAUSE_SHARED 15246 : OMP_CLAUSE_FIRSTPRIVATE); 15247 OMP_CLAUSE_DECL (c) = orig_decl; 15248 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15249 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15250 } 15251 /* Similarly, take care of C++ range for temporaries, those should 15252 be firstprivate on OMP_PARALLEL if any. */ 15253 if (data[1]) 15254 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++) 15255 if (OMP_FOR_ORIG_DECLS (inner_for_stmt) 15256 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15257 i)) == TREE_LIST 15258 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15259 i))) 15260 { 15261 tree orig 15262 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i); 15263 tree v = TREE_CHAIN (orig); 15264 tree c = build_omp_clause (UNKNOWN_LOCATION, 15265 OMP_CLAUSE_FIRSTPRIVATE); 15266 /* First add firstprivate clause for the __for_end artificial 15267 decl. */ 15268 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1); 15269 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 15270 == REFERENCE_TYPE) 15271 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1; 15272 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15273 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15274 if (TREE_VEC_ELT (v, 0)) 15275 { 15276 /* And now the same for __for_range artificial decl if it 15277 exists. */ 15278 c = build_omp_clause (UNKNOWN_LOCATION, 15279 OMP_CLAUSE_FIRSTPRIVATE); 15280 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0); 15281 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 15282 == REFERENCE_TYPE) 15283 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1; 15284 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15285 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15286 } 15287 } 15288 } 15289 15290 switch (TREE_CODE (for_stmt)) 15291 { 15292 case OMP_FOR: 15293 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)) 15294 { 15295 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15296 OMP_CLAUSE_SCHEDULE)) 15297 error_at (EXPR_LOCATION (for_stmt), 15298 "%qs clause may not appear on non-rectangular %qs", 15299 "schedule", lang_GNU_Fortran () ? "do" : "for"); 15300 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED)) 15301 error_at (EXPR_LOCATION (for_stmt), 15302 "%qs clause may not appear on non-rectangular %qs", 15303 "ordered", lang_GNU_Fortran () ? "do" : "for"); 15304 } 15305 break; 15306 case OMP_DISTRIBUTE: 15307 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt) 15308 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15309 OMP_CLAUSE_DIST_SCHEDULE)) 15310 error_at (EXPR_LOCATION (for_stmt), 15311 "%qs clause may not appear on non-rectangular %qs", 15312 "dist_schedule", "distribute"); 15313 break; 15314 case OACC_LOOP: 15315 ort = ORT_ACC; 15316 break; 15317 case OMP_TASKLOOP: 15318 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)) 15319 { 15320 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15321 OMP_CLAUSE_GRAINSIZE)) 15322 error_at (EXPR_LOCATION (for_stmt), 15323 "%qs clause may not appear on non-rectangular %qs", 15324 "grainsize", "taskloop"); 15325 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15326 OMP_CLAUSE_NUM_TASKS)) 15327 error_at (EXPR_LOCATION (for_stmt), 15328 "%qs clause may not appear on non-rectangular %qs", 15329 "num_tasks", "taskloop"); 15330 } 15331 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED)) 15332 ort = ORT_UNTIED_TASKLOOP; 15333 else 15334 ort = ORT_TASKLOOP; 15335 break; 15336 case OMP_SIMD: 15337 ort = ORT_SIMD; 15338 break; 15339 default: 15340 gcc_unreachable (); 15341 } 15342 15343 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear 15344 clause for the IV. */ 15345 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1) 15346 { 15347 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0); 15348 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15349 decl = TREE_OPERAND (t, 0); 15350 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c)) 15351 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 15352 && OMP_CLAUSE_DECL (c) == decl) 15353 { 15354 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1; 15355 break; 15356 } 15357 } 15358 15359 if (TREE_CODE (for_stmt) != OMP_TASKLOOP) 15360 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort, 15361 loop_p && TREE_CODE (for_stmt) != OMP_SIMD 15362 ? OMP_LOOP : TREE_CODE (for_stmt)); 15363 15364 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE) 15365 gimplify_omp_ctxp->distribute = true; 15366 15367 /* Handle OMP_FOR_INIT. */ 15368 for_pre_body = NULL; 15369 if ((ort == ORT_SIMD 15370 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD)) 15371 && OMP_FOR_PRE_BODY (for_stmt)) 15372 { 15373 has_decl_expr = BITMAP_ALLOC (NULL); 15374 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR 15375 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))) 15376 { 15377 t = OMP_FOR_PRE_BODY (for_stmt); 15378 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t))); 15379 } 15380 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST) 15381 { 15382 tree_stmt_iterator si; 15383 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si); 15384 tsi_next (&si)) 15385 { 15386 t = tsi_stmt (si); 15387 if (TREE_CODE (t) == DECL_EXPR 15388 && VAR_P (DECL_EXPR_DECL (t))) 15389 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t))); 15390 } 15391 } 15392 } 15393 if (OMP_FOR_PRE_BODY (for_stmt)) 15394 { 15395 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp) 15396 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body); 15397 else 15398 { 15399 struct gimplify_omp_ctx ctx; 15400 memset (&ctx, 0, sizeof (ctx)); 15401 ctx.region_type = ORT_NONE; 15402 gimplify_omp_ctxp = &ctx; 15403 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body); 15404 gimplify_omp_ctxp = NULL; 15405 } 15406 } 15407 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE; 15408 15409 if (OMP_FOR_INIT (for_stmt) == NULL_TREE) 15410 for_stmt = inner_for_stmt; 15411 15412 /* For taskloop, need to gimplify the start, end and step before the 15413 taskloop, outside of the taskloop omp context. */ 15414 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 15415 { 15416 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15417 { 15418 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15419 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body) 15420 ? pre_p : &for_pre_body); 15421 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 15422 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15423 { 15424 tree v = TREE_OPERAND (t, 1); 15425 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1), 15426 for_pre_p, orig_for_stmt); 15427 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2), 15428 for_pre_p, orig_for_stmt); 15429 } 15430 else 15431 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p, 15432 orig_for_stmt); 15433 15434 /* Handle OMP_FOR_COND. */ 15435 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 15436 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15437 { 15438 tree v = TREE_OPERAND (t, 1); 15439 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1), 15440 for_pre_p, orig_for_stmt); 15441 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2), 15442 for_pre_p, orig_for_stmt); 15443 } 15444 else 15445 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p, 15446 orig_for_stmt); 15447 15448 /* Handle OMP_FOR_INCR. */ 15449 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15450 if (TREE_CODE (t) == MODIFY_EXPR) 15451 { 15452 decl = TREE_OPERAND (t, 0); 15453 t = TREE_OPERAND (t, 1); 15454 tree *tp = &TREE_OPERAND (t, 1); 15455 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl) 15456 tp = &TREE_OPERAND (t, 0); 15457 15458 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p, 15459 orig_for_stmt); 15460 } 15461 } 15462 15463 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort, 15464 OMP_TASKLOOP); 15465 } 15466 15467 if (orig_for_stmt != for_stmt) 15468 gimplify_omp_ctxp->combined_loop = true; 15469 15470 for_body = NULL; 15471 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15472 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt))); 15473 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15474 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt))); 15475 15476 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED); 15477 bool is_doacross = false; 15478 if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt), 15479 find_standalone_omp_ordered, NULL)) 15480 { 15481 OMP_CLAUSE_ORDERED_DOACROSS (c) = 1; 15482 is_doacross = true; 15483 int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); 15484 gimplify_omp_ctxp->loop_iter_var.create (len * 2); 15485 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; ) 15486 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) 15487 { 15488 error_at (OMP_CLAUSE_LOCATION (*pc), 15489 "%<linear%> clause may not be specified together " 15490 "with %<ordered%> clause if stand-alone %<ordered%> " 15491 "construct is nested in it"); 15492 *pc = OMP_CLAUSE_CHAIN (*pc); 15493 } 15494 else 15495 pc = &OMP_CLAUSE_CHAIN (*pc); 15496 } 15497 int collapse = 1, tile = 0; 15498 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE); 15499 if (c) 15500 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c)); 15501 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE); 15502 if (c) 15503 tile = list_length (OMP_CLAUSE_TILE_LIST (c)); 15504 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE); 15505 hash_set<tree> *allocate_uids = NULL; 15506 if (c) 15507 { 15508 allocate_uids = new hash_set<tree>; 15509 for (; c; c = OMP_CLAUSE_CHAIN (c)) 15510 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE) 15511 allocate_uids->add (OMP_CLAUSE_DECL (c)); 15512 } 15513 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15514 { 15515 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15516 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15517 decl = TREE_OPERAND (t, 0); 15518 gcc_assert (DECL_P (decl)); 15519 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)) 15520 || POINTER_TYPE_P (TREE_TYPE (decl))); 15521 if (is_doacross) 15522 { 15523 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt)) 15524 { 15525 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15526 if (TREE_CODE (orig_decl) == TREE_LIST) 15527 { 15528 orig_decl = TREE_PURPOSE (orig_decl); 15529 if (!orig_decl) 15530 orig_decl = decl; 15531 } 15532 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl); 15533 } 15534 else 15535 gimplify_omp_ctxp->loop_iter_var.quick_push (decl); 15536 gimplify_omp_ctxp->loop_iter_var.quick_push (decl); 15537 } 15538 15539 if (for_stmt == orig_for_stmt) 15540 { 15541 tree orig_decl = decl; 15542 if (OMP_FOR_ORIG_DECLS (for_stmt)) 15543 { 15544 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15545 if (TREE_CODE (orig_decl) == TREE_LIST) 15546 { 15547 orig_decl = TREE_PURPOSE (orig_decl); 15548 if (!orig_decl) 15549 orig_decl = decl; 15550 } 15551 } 15552 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl)) 15553 error_at (EXPR_LOCATION (for_stmt), 15554 "threadprivate iteration variable %qD", orig_decl); 15555 } 15556 15557 /* Make sure the iteration variable is private. */ 15558 tree c = NULL_TREE; 15559 tree c2 = NULL_TREE; 15560 if (orig_for_stmt != for_stmt) 15561 { 15562 /* Preserve this information until we gimplify the inner simd. */ 15563 if (has_decl_expr 15564 && bitmap_bit_p (has_decl_expr, DECL_UID (decl))) 15565 TREE_PRIVATE (t) = 1; 15566 } 15567 else if (ort == ORT_SIMD) 15568 { 15569 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables, 15570 (splay_tree_key) decl); 15571 omp_is_private (gimplify_omp_ctxp, decl, 15572 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15573 != 1)); 15574 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 15575 { 15576 omp_notice_variable (gimplify_omp_ctxp, decl, true); 15577 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL) 15578 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15579 OMP_CLAUSE_LASTPRIVATE); 15580 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3), 15581 OMP_CLAUSE_LASTPRIVATE)) 15582 if (OMP_CLAUSE_DECL (c3) == decl) 15583 { 15584 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp, 15585 "conditional %<lastprivate%> on loop " 15586 "iterator %qD ignored", decl); 15587 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0; 15588 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL; 15589 } 15590 } 15591 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p) 15592 { 15593 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); 15594 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1; 15595 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN; 15596 if ((has_decl_expr 15597 && bitmap_bit_p (has_decl_expr, DECL_UID (decl))) 15598 || TREE_PRIVATE (t)) 15599 { 15600 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15601 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15602 } 15603 struct gimplify_omp_ctx *outer 15604 = gimplify_omp_ctxp->outer_context; 15605 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 15606 { 15607 if (outer->region_type == ORT_WORKSHARE 15608 && outer->combined_loop) 15609 { 15610 n = splay_tree_lookup (outer->variables, 15611 (splay_tree_key)decl); 15612 if (n != NULL && (n->value & GOVD_LOCAL) != 0) 15613 { 15614 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15615 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15616 } 15617 else 15618 { 15619 struct gimplify_omp_ctx *octx = outer->outer_context; 15620 if (octx 15621 && octx->region_type == ORT_COMBINED_PARALLEL 15622 && octx->outer_context 15623 && (octx->outer_context->region_type 15624 == ORT_WORKSHARE) 15625 && octx->outer_context->combined_loop) 15626 { 15627 octx = octx->outer_context; 15628 n = splay_tree_lookup (octx->variables, 15629 (splay_tree_key)decl); 15630 if (n != NULL && (n->value & GOVD_LOCAL) != 0) 15631 { 15632 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15633 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15634 } 15635 } 15636 } 15637 } 15638 } 15639 15640 OMP_CLAUSE_DECL (c) = decl; 15641 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15642 OMP_FOR_CLAUSES (for_stmt) = c; 15643 omp_add_variable (gimplify_omp_ctxp, decl, flags); 15644 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 15645 omp_lastprivate_for_combined_outer_constructs (outer, decl, 15646 true); 15647 } 15648 else 15649 { 15650 bool lastprivate 15651 = (!has_decl_expr 15652 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl))); 15653 if (TREE_PRIVATE (t)) 15654 lastprivate = false; 15655 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt)) 15656 { 15657 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15658 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt)) 15659 lastprivate = false; 15660 } 15661 15662 struct gimplify_omp_ctx *outer 15663 = gimplify_omp_ctxp->outer_context; 15664 if (outer && lastprivate) 15665 omp_lastprivate_for_combined_outer_constructs (outer, decl, 15666 true); 15667 15668 c = build_omp_clause (input_location, 15669 lastprivate ? OMP_CLAUSE_LASTPRIVATE 15670 : OMP_CLAUSE_PRIVATE); 15671 OMP_CLAUSE_DECL (c) = decl; 15672 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15673 OMP_FOR_CLAUSES (for_stmt) = c; 15674 omp_add_variable (gimplify_omp_ctxp, decl, 15675 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE) 15676 | GOVD_EXPLICIT | GOVD_SEEN); 15677 c = NULL_TREE; 15678 } 15679 } 15680 else if (omp_is_private (gimplify_omp_ctxp, decl, 0)) 15681 { 15682 omp_notice_variable (gimplify_omp_ctxp, decl, true); 15683 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables, 15684 (splay_tree_key) decl); 15685 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL)) 15686 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15687 OMP_CLAUSE_LASTPRIVATE); 15688 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3), 15689 OMP_CLAUSE_LASTPRIVATE)) 15690 if (OMP_CLAUSE_DECL (c3) == decl) 15691 { 15692 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp, 15693 "conditional %<lastprivate%> on loop " 15694 "iterator %qD ignored", decl); 15695 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0; 15696 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL; 15697 } 15698 } 15699 else 15700 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN); 15701 15702 /* If DECL is not a gimple register, create a temporary variable to act 15703 as an iteration counter. This is valid, since DECL cannot be 15704 modified in the body of the loop. Similarly for any iteration vars 15705 in simd with collapse > 1 where the iterator vars must be 15706 lastprivate. And similarly for vars mentioned in allocate clauses. */ 15707 if (orig_for_stmt != for_stmt) 15708 var = decl; 15709 else if (!is_gimple_reg (decl) 15710 || (ort == ORT_SIMD 15711 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1) 15712 || (allocate_uids && allocate_uids->contains (decl))) 15713 { 15714 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 15715 /* Make sure omp_add_variable is not called on it prematurely. 15716 We call it ourselves a few lines later. */ 15717 gimplify_omp_ctxp = NULL; 15718 var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); 15719 gimplify_omp_ctxp = ctx; 15720 TREE_OPERAND (t, 0) = var; 15721 15722 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var)); 15723 15724 if (ort == ORT_SIMD 15725 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1) 15726 { 15727 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); 15728 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1; 15729 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1; 15730 OMP_CLAUSE_DECL (c2) = var; 15731 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt); 15732 OMP_FOR_CLAUSES (for_stmt) = c2; 15733 omp_add_variable (gimplify_omp_ctxp, var, 15734 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN); 15735 if (c == NULL_TREE) 15736 { 15737 c = c2; 15738 c2 = NULL_TREE; 15739 } 15740 } 15741 else 15742 omp_add_variable (gimplify_omp_ctxp, var, 15743 GOVD_PRIVATE | GOVD_SEEN); 15744 } 15745 else 15746 var = decl; 15747 15748 gimplify_omp_ctxp->in_for_exprs = true; 15749 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15750 { 15751 tree lb = TREE_OPERAND (t, 1); 15752 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL, 15753 is_gimple_val, fb_rvalue, false); 15754 ret = MIN (ret, tret); 15755 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL, 15756 is_gimple_val, fb_rvalue, false); 15757 } 15758 else 15759 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15760 is_gimple_val, fb_rvalue, false); 15761 gimplify_omp_ctxp->in_for_exprs = false; 15762 ret = MIN (ret, tret); 15763 if (ret == GS_ERROR) 15764 return ret; 15765 15766 /* Handle OMP_FOR_COND. */ 15767 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 15768 gcc_assert (COMPARISON_CLASS_P (t)); 15769 gcc_assert (TREE_OPERAND (t, 0) == decl); 15770 15771 gimplify_omp_ctxp->in_for_exprs = true; 15772 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15773 { 15774 tree ub = TREE_OPERAND (t, 1); 15775 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL, 15776 is_gimple_val, fb_rvalue, false); 15777 ret = MIN (ret, tret); 15778 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL, 15779 is_gimple_val, fb_rvalue, false); 15780 } 15781 else 15782 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15783 is_gimple_val, fb_rvalue, false); 15784 gimplify_omp_ctxp->in_for_exprs = false; 15785 ret = MIN (ret, tret); 15786 15787 /* Handle OMP_FOR_INCR. */ 15788 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15789 switch (TREE_CODE (t)) 15790 { 15791 case PREINCREMENT_EXPR: 15792 case POSTINCREMENT_EXPR: 15793 { 15794 tree decl = TREE_OPERAND (t, 0); 15795 /* c_omp_for_incr_canonicalize_ptr() should have been 15796 called to massage things appropriately. */ 15797 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl))); 15798 15799 if (orig_for_stmt != for_stmt) 15800 break; 15801 t = build_int_cst (TREE_TYPE (decl), 1); 15802 if (c) 15803 OMP_CLAUSE_LINEAR_STEP (c) = t; 15804 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); 15805 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); 15806 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; 15807 break; 15808 } 15809 15810 case PREDECREMENT_EXPR: 15811 case POSTDECREMENT_EXPR: 15812 /* c_omp_for_incr_canonicalize_ptr() should have been 15813 called to massage things appropriately. */ 15814 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl))); 15815 if (orig_for_stmt != for_stmt) 15816 break; 15817 t = build_int_cst (TREE_TYPE (decl), -1); 15818 if (c) 15819 OMP_CLAUSE_LINEAR_STEP (c) = t; 15820 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); 15821 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); 15822 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; 15823 break; 15824 15825 case MODIFY_EXPR: 15826 gcc_assert (TREE_OPERAND (t, 0) == decl); 15827 TREE_OPERAND (t, 0) = var; 15828 15829 t = TREE_OPERAND (t, 1); 15830 switch (TREE_CODE (t)) 15831 { 15832 case PLUS_EXPR: 15833 if (TREE_OPERAND (t, 1) == decl) 15834 { 15835 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0); 15836 TREE_OPERAND (t, 0) = var; 15837 break; 15838 } 15839 15840 /* Fallthru. */ 15841 case MINUS_EXPR: 15842 case POINTER_PLUS_EXPR: 15843 gcc_assert (TREE_OPERAND (t, 0) == decl); 15844 TREE_OPERAND (t, 0) = var; 15845 break; 15846 default: 15847 gcc_unreachable (); 15848 } 15849 15850 gimplify_omp_ctxp->in_for_exprs = true; 15851 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15852 is_gimple_val, fb_rvalue, false); 15853 ret = MIN (ret, tret); 15854 if (c) 15855 { 15856 tree step = TREE_OPERAND (t, 1); 15857 tree stept = TREE_TYPE (decl); 15858 if (POINTER_TYPE_P (stept)) 15859 stept = sizetype; 15860 step = fold_convert (stept, step); 15861 if (TREE_CODE (t) == MINUS_EXPR) 15862 step = fold_build1 (NEGATE_EXPR, stept, step); 15863 OMP_CLAUSE_LINEAR_STEP (c) = step; 15864 if (step != TREE_OPERAND (t, 1)) 15865 { 15866 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), 15867 &for_pre_body, NULL, 15868 is_gimple_val, fb_rvalue, false); 15869 ret = MIN (ret, tret); 15870 } 15871 } 15872 gimplify_omp_ctxp->in_for_exprs = false; 15873 break; 15874 15875 default: 15876 gcc_unreachable (); 15877 } 15878 15879 if (c2) 15880 { 15881 gcc_assert (c); 15882 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c); 15883 } 15884 15885 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt) 15886 { 15887 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c)) 15888 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 15889 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL) 15890 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 15891 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c) 15892 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL)) 15893 && OMP_CLAUSE_DECL (c) == decl) 15894 { 15895 if (is_doacross && (collapse == 1 || i >= collapse)) 15896 t = var; 15897 else 15898 { 15899 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15900 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15901 gcc_assert (TREE_OPERAND (t, 0) == var); 15902 t = TREE_OPERAND (t, 1); 15903 gcc_assert (TREE_CODE (t) == PLUS_EXPR 15904 || TREE_CODE (t) == MINUS_EXPR 15905 || TREE_CODE (t) == POINTER_PLUS_EXPR); 15906 gcc_assert (TREE_OPERAND (t, 0) == var); 15907 t = build2 (TREE_CODE (t), TREE_TYPE (decl), 15908 is_doacross ? var : decl, 15909 TREE_OPERAND (t, 1)); 15910 } 15911 gimple_seq *seq; 15912 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) 15913 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c); 15914 else 15915 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c); 15916 push_gimplify_context (); 15917 gimplify_assign (decl, t, seq); 15918 gimple *bind = NULL; 15919 if (gimplify_ctxp->temps) 15920 { 15921 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE); 15922 *seq = NULL; 15923 gimplify_seq_add_stmt (seq, bind); 15924 } 15925 pop_gimplify_context (bind); 15926 } 15927 } 15928 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl) 15929 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) 15930 { 15931 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); 15932 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15933 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15934 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15935 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15936 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); 15937 gcc_assert (COMPARISON_CLASS_P (t)); 15938 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15939 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15940 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15941 } 15942 } 15943 15944 BITMAP_FREE (has_decl_expr); 15945 delete allocate_uids; 15946 15947 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP 15948 || (loop_p && orig_for_stmt == for_stmt)) 15949 { 15950 push_gimplify_context (); 15951 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR) 15952 { 15953 OMP_FOR_BODY (orig_for_stmt) 15954 = build3 (BIND_EXPR, void_type_node, NULL, 15955 OMP_FOR_BODY (orig_for_stmt), NULL); 15956 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1; 15957 } 15958 } 15959 15960 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt), 15961 &for_body); 15962 15963 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP 15964 || (loop_p && orig_for_stmt == for_stmt)) 15965 { 15966 if (gimple_code (g) == GIMPLE_BIND) 15967 pop_gimplify_context (g); 15968 else 15969 pop_gimplify_context (NULL); 15970 } 15971 15972 if (orig_for_stmt != for_stmt) 15973 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15974 { 15975 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15976 decl = TREE_OPERAND (t, 0); 15977 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 15978 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 15979 gimplify_omp_ctxp = ctx->outer_context; 15980 var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); 15981 gimplify_omp_ctxp = ctx; 15982 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN); 15983 TREE_OPERAND (t, 0) = var; 15984 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15985 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 15986 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var; 15987 if (OMP_FOR_NON_RECTANGULAR (for_stmt)) 15988 for (int j = i + 1; 15989 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) 15990 { 15991 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); 15992 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15993 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15994 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15995 { 15996 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 15997 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15998 } 15999 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); 16000 gcc_assert (COMPARISON_CLASS_P (t)); 16001 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 16002 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 16003 { 16004 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 16005 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 16006 } 16007 } 16008 } 16009 16010 gimplify_adjust_omp_clauses (pre_p, for_body, 16011 &OMP_FOR_CLAUSES (orig_for_stmt), 16012 TREE_CODE (orig_for_stmt)); 16013 16014 int kind; 16015 switch (TREE_CODE (orig_for_stmt)) 16016 { 16017 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break; 16018 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break; 16019 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break; 16020 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break; 16021 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break; 16022 default: 16023 gcc_unreachable (); 16024 } 16025 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD) 16026 { 16027 gimplify_seq_add_seq (pre_p, for_pre_body); 16028 for_pre_body = NULL; 16029 } 16030 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt), 16031 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), 16032 for_pre_body); 16033 if (orig_for_stmt != for_stmt) 16034 gimple_omp_for_set_combined_p (gfor, true); 16035 if (gimplify_omp_ctxp 16036 && (gimplify_omp_ctxp->combined_loop 16037 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL 16038 && gimplify_omp_ctxp->outer_context 16039 && gimplify_omp_ctxp->outer_context->combined_loop))) 16040 { 16041 gimple_omp_for_set_combined_into_p (gfor, true); 16042 if (gimplify_omp_ctxp->combined_loop) 16043 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD); 16044 else 16045 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR); 16046 } 16047 16048 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16049 { 16050 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 16051 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0)); 16052 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1)); 16053 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 16054 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t)); 16055 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1)); 16056 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 16057 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1)); 16058 } 16059 16060 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop 16061 constructs with GIMPLE_OMP_TASK sandwiched in between them. 16062 The outer taskloop stands for computing the number of iterations, 16063 counts for collapsed loops and holding taskloop specific clauses. 16064 The task construct stands for the effect of data sharing on the 16065 explicit task it creates and the inner taskloop stands for expansion 16066 of the static loop inside of the explicit task construct. */ 16067 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 16068 { 16069 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor); 16070 tree task_clauses = NULL_TREE; 16071 tree c = *gfor_clauses_ptr; 16072 tree *gtask_clauses_ptr = &task_clauses; 16073 tree outer_for_clauses = NULL_TREE; 16074 tree *gforo_clauses_ptr = &outer_for_clauses; 16075 bitmap lastprivate_uids = NULL; 16076 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE)) 16077 { 16078 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE); 16079 if (c) 16080 { 16081 lastprivate_uids = BITMAP_ALLOC (NULL); 16082 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c), 16083 OMP_CLAUSE_LASTPRIVATE)) 16084 bitmap_set_bit (lastprivate_uids, 16085 DECL_UID (OMP_CLAUSE_DECL (c))); 16086 } 16087 c = *gfor_clauses_ptr; 16088 } 16089 for (; c; c = OMP_CLAUSE_CHAIN (c)) 16090 switch (OMP_CLAUSE_CODE (c)) 16091 { 16092 /* These clauses are allowed on task, move them there. */ 16093 case OMP_CLAUSE_SHARED: 16094 case OMP_CLAUSE_FIRSTPRIVATE: 16095 case OMP_CLAUSE_DEFAULT: 16096 case OMP_CLAUSE_IF: 16097 case OMP_CLAUSE_UNTIED: 16098 case OMP_CLAUSE_FINAL: 16099 case OMP_CLAUSE_MERGEABLE: 16100 case OMP_CLAUSE_PRIORITY: 16101 case OMP_CLAUSE_REDUCTION: 16102 case OMP_CLAUSE_IN_REDUCTION: 16103 *gtask_clauses_ptr = c; 16104 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16105 break; 16106 case OMP_CLAUSE_PRIVATE: 16107 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c)) 16108 { 16109 /* We want private on outer for and firstprivate 16110 on task. */ 16111 *gtask_clauses_ptr 16112 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16113 OMP_CLAUSE_FIRSTPRIVATE); 16114 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16115 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL, 16116 openacc); 16117 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16118 *gforo_clauses_ptr = c; 16119 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16120 } 16121 else 16122 { 16123 *gtask_clauses_ptr = c; 16124 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16125 } 16126 break; 16127 /* These clauses go into outer taskloop clauses. */ 16128 case OMP_CLAUSE_GRAINSIZE: 16129 case OMP_CLAUSE_NUM_TASKS: 16130 case OMP_CLAUSE_NOGROUP: 16131 *gforo_clauses_ptr = c; 16132 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16133 break; 16134 /* Collapse clause we duplicate on both taskloops. */ 16135 case OMP_CLAUSE_COLLAPSE: 16136 *gfor_clauses_ptr = c; 16137 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16138 *gforo_clauses_ptr = copy_node (c); 16139 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr); 16140 break; 16141 /* For lastprivate, keep the clause on inner taskloop, and add 16142 a shared clause on task. If the same decl is also firstprivate, 16143 add also firstprivate clause on the inner taskloop. */ 16144 case OMP_CLAUSE_LASTPRIVATE: 16145 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) 16146 { 16147 /* For taskloop C++ lastprivate IVs, we want: 16148 1) private on outer taskloop 16149 2) firstprivate and shared on task 16150 3) lastprivate on inner taskloop */ 16151 *gtask_clauses_ptr 16152 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16153 OMP_CLAUSE_FIRSTPRIVATE); 16154 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16155 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL, 16156 openacc); 16157 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16158 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1; 16159 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16160 OMP_CLAUSE_PRIVATE); 16161 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c); 16162 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1; 16163 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c); 16164 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr); 16165 } 16166 *gfor_clauses_ptr = c; 16167 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16168 *gtask_clauses_ptr 16169 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED); 16170 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16171 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)) 16172 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1; 16173 gtask_clauses_ptr 16174 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16175 break; 16176 /* Allocate clause we duplicate on task and inner taskloop 16177 if the decl is lastprivate, otherwise just put on task. */ 16178 case OMP_CLAUSE_ALLOCATE: 16179 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 16180 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))) 16181 { 16182 /* Additionally, put firstprivate clause on task 16183 for the allocator if it is not constant. */ 16184 *gtask_clauses_ptr 16185 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16186 OMP_CLAUSE_FIRSTPRIVATE); 16187 OMP_CLAUSE_DECL (*gtask_clauses_ptr) 16188 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); 16189 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16190 } 16191 if (lastprivate_uids 16192 && bitmap_bit_p (lastprivate_uids, 16193 DECL_UID (OMP_CLAUSE_DECL (c)))) 16194 { 16195 *gfor_clauses_ptr = c; 16196 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16197 *gtask_clauses_ptr = copy_node (c); 16198 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16199 } 16200 else 16201 { 16202 *gtask_clauses_ptr = c; 16203 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16204 } 16205 break; 16206 default: 16207 gcc_unreachable (); 16208 } 16209 *gfor_clauses_ptr = NULL_TREE; 16210 *gtask_clauses_ptr = NULL_TREE; 16211 *gforo_clauses_ptr = NULL_TREE; 16212 BITMAP_FREE (lastprivate_uids); 16213 gimple_set_location (gfor, input_location); 16214 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE); 16215 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE, 16216 NULL_TREE, NULL_TREE, NULL_TREE); 16217 gimple_set_location (g, input_location); 16218 gimple_omp_task_set_taskloop_p (g, true); 16219 g = gimple_build_bind (NULL_TREE, g, NULL_TREE); 16220 gomp_for *gforo 16221 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses, 16222 gimple_omp_for_collapse (gfor), 16223 gimple_omp_for_pre_body (gfor)); 16224 gimple_omp_for_set_pre_body (gfor, NULL); 16225 gimple_omp_for_set_combined_p (gforo, true); 16226 gimple_omp_for_set_combined_into_p (gfor, true); 16227 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++) 16228 { 16229 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i)); 16230 tree v = create_tmp_var (type); 16231 gimple_omp_for_set_index (gforo, i, v); 16232 t = unshare_expr (gimple_omp_for_initial (gfor, i)); 16233 gimple_omp_for_set_initial (gforo, i, t); 16234 gimple_omp_for_set_cond (gforo, i, 16235 gimple_omp_for_cond (gfor, i)); 16236 t = unshare_expr (gimple_omp_for_final (gfor, i)); 16237 gimple_omp_for_set_final (gforo, i, t); 16238 t = unshare_expr (gimple_omp_for_incr (gfor, i)); 16239 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i)); 16240 TREE_OPERAND (t, 0) = v; 16241 gimple_omp_for_set_incr (gforo, i, t); 16242 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); 16243 OMP_CLAUSE_DECL (t) = v; 16244 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo); 16245 gimple_omp_for_set_clauses (gforo, t); 16246 if (OMP_FOR_NON_RECTANGULAR (for_stmt)) 16247 { 16248 tree *p1 = NULL, *p2 = NULL; 16249 t = gimple_omp_for_initial (gforo, i); 16250 if (TREE_CODE (t) == TREE_VEC) 16251 p1 = &TREE_VEC_ELT (t, 0); 16252 t = gimple_omp_for_final (gforo, i); 16253 if (TREE_CODE (t) == TREE_VEC) 16254 { 16255 if (p1) 16256 p2 = &TREE_VEC_ELT (t, 0); 16257 else 16258 p1 = &TREE_VEC_ELT (t, 0); 16259 } 16260 if (p1) 16261 { 16262 int j; 16263 for (j = 0; j < i; j++) 16264 if (*p1 == gimple_omp_for_index (gfor, j)) 16265 { 16266 *p1 = gimple_omp_for_index (gforo, j); 16267 if (p2) 16268 *p2 = *p1; 16269 break; 16270 } 16271 gcc_assert (j < i); 16272 } 16273 } 16274 } 16275 gimplify_seq_add_stmt (pre_p, gforo); 16276 } 16277 else 16278 gimplify_seq_add_stmt (pre_p, gfor); 16279 16280 if (TREE_CODE (orig_for_stmt) == OMP_FOR) 16281 { 16282 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 16283 unsigned lastprivate_conditional = 0; 16284 while (ctx 16285 && (ctx->region_type == ORT_TARGET_DATA 16286 || ctx->region_type == ORT_TASKGROUP)) 16287 ctx = ctx->outer_context; 16288 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0) 16289 for (tree c = gimple_omp_for_clauses (gfor); 16290 c; c = OMP_CLAUSE_CHAIN (c)) 16291 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 16292 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 16293 ++lastprivate_conditional; 16294 if (lastprivate_conditional) 16295 { 16296 struct omp_for_data fd; 16297 omp_extract_for_data (gfor, &fd, NULL); 16298 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type), 16299 lastprivate_conditional); 16300 tree var = create_tmp_var_raw (type); 16301 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_); 16302 OMP_CLAUSE_DECL (c) = var; 16303 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor); 16304 gimple_omp_for_set_clauses (gfor, c); 16305 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN); 16306 } 16307 } 16308 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD) 16309 { 16310 unsigned lastprivate_conditional = 0; 16311 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c)) 16312 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 16313 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 16314 ++lastprivate_conditional; 16315 if (lastprivate_conditional) 16316 { 16317 struct omp_for_data fd; 16318 omp_extract_for_data (gfor, &fd, NULL); 16319 tree type = unsigned_type_for (fd.iter_type); 16320 while (lastprivate_conditional--) 16321 { 16322 tree c = build_omp_clause (UNKNOWN_LOCATION, 16323 OMP_CLAUSE__CONDTEMP_); 16324 OMP_CLAUSE_DECL (c) = create_tmp_var (type); 16325 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor); 16326 gimple_omp_for_set_clauses (gfor, c); 16327 } 16328 } 16329 } 16330 16331 if (ret != GS_ALL_DONE) 16332 return GS_ERROR; 16333 *expr_p = NULL_TREE; 16334 return GS_ALL_DONE; 16335 } 16336 16337 /* Helper for gimplify_omp_loop, called through walk_tree. */ 16338 16339 static tree 16340 note_no_context_vars (tree *tp, int *, void *data) 16341 { 16342 if (VAR_P (*tp) 16343 && DECL_CONTEXT (*tp) == NULL_TREE 16344 && !is_global_var (*tp)) 16345 { 16346 vec<tree> *d = (vec<tree> *) data; 16347 d->safe_push (*tp); 16348 DECL_CONTEXT (*tp) = current_function_decl; 16349 } 16350 return NULL_TREE; 16351 } 16352 16353 /* Gimplify the gross structure of an OMP_LOOP statement. */ 16354 16355 static enum gimplify_status 16356 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p) 16357 { 16358 tree for_stmt = *expr_p; 16359 tree clauses = OMP_FOR_CLAUSES (for_stmt); 16360 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp; 16361 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD; 16362 int i; 16363 16364 /* If order is not present, the behavior is as if order(concurrent) 16365 appeared. */ 16366 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER); 16367 if (order == NULL_TREE) 16368 { 16369 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER); 16370 OMP_CLAUSE_CHAIN (order) = clauses; 16371 OMP_FOR_CLAUSES (for_stmt) = clauses = order; 16372 } 16373 16374 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND); 16375 if (bind == NULL_TREE) 16376 { 16377 if (!flag_openmp) /* flag_openmp_simd */ 16378 ; 16379 else if (octx && (octx->region_type & ORT_TEAMS) != 0) 16380 kind = OMP_CLAUSE_BIND_TEAMS; 16381 else if (octx && (octx->region_type & ORT_PARALLEL) != 0) 16382 kind = OMP_CLAUSE_BIND_PARALLEL; 16383 else 16384 { 16385 for (; octx; octx = octx->outer_context) 16386 { 16387 if ((octx->region_type & ORT_ACC) != 0 16388 || octx->region_type == ORT_NONE 16389 || octx->region_type == ORT_IMPLICIT_TARGET) 16390 continue; 16391 break; 16392 } 16393 if (octx == NULL && !in_omp_construct) 16394 error_at (EXPR_LOCATION (for_stmt), 16395 "%<bind%> clause not specified on a %<loop%> " 16396 "construct not nested inside another OpenMP construct"); 16397 } 16398 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND); 16399 OMP_CLAUSE_CHAIN (bind) = clauses; 16400 OMP_CLAUSE_BIND_KIND (bind) = kind; 16401 OMP_FOR_CLAUSES (for_stmt) = bind; 16402 } 16403 else 16404 switch (OMP_CLAUSE_BIND_KIND (bind)) 16405 { 16406 case OMP_CLAUSE_BIND_THREAD: 16407 break; 16408 case OMP_CLAUSE_BIND_PARALLEL: 16409 if (!flag_openmp) /* flag_openmp_simd */ 16410 { 16411 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16412 break; 16413 } 16414 for (; octx; octx = octx->outer_context) 16415 if (octx->region_type == ORT_SIMD 16416 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE) 16417 { 16418 error_at (EXPR_LOCATION (for_stmt), 16419 "%<bind(parallel)%> on a %<loop%> construct nested " 16420 "inside %<simd%> construct"); 16421 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16422 break; 16423 } 16424 kind = OMP_CLAUSE_BIND_PARALLEL; 16425 break; 16426 case OMP_CLAUSE_BIND_TEAMS: 16427 if (!flag_openmp) /* flag_openmp_simd */ 16428 { 16429 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16430 break; 16431 } 16432 if ((octx 16433 && octx->region_type != ORT_IMPLICIT_TARGET 16434 && octx->region_type != ORT_NONE 16435 && (octx->region_type & ORT_TEAMS) == 0) 16436 || in_omp_construct) 16437 { 16438 error_at (EXPR_LOCATION (for_stmt), 16439 "%<bind(teams)%> on a %<loop%> region not strictly " 16440 "nested inside of a %<teams%> region"); 16441 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16442 break; 16443 } 16444 kind = OMP_CLAUSE_BIND_TEAMS; 16445 break; 16446 default: 16447 gcc_unreachable (); 16448 } 16449 16450 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; ) 16451 switch (OMP_CLAUSE_CODE (*pc)) 16452 { 16453 case OMP_CLAUSE_REDUCTION: 16454 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc)) 16455 { 16456 error_at (OMP_CLAUSE_LOCATION (*pc), 16457 "%<inscan%> %<reduction%> clause on " 16458 "%qs construct", "loop"); 16459 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0; 16460 } 16461 if (OMP_CLAUSE_REDUCTION_TASK (*pc)) 16462 { 16463 error_at (OMP_CLAUSE_LOCATION (*pc), 16464 "invalid %<task%> reduction modifier on construct " 16465 "other than %<parallel%>, %qs or %<sections%>", 16466 lang_GNU_Fortran () ? "do" : "for"); 16467 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0; 16468 } 16469 pc = &OMP_CLAUSE_CHAIN (*pc); 16470 break; 16471 case OMP_CLAUSE_LASTPRIVATE: 16472 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16473 { 16474 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 16475 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 16476 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0)) 16477 break; 16478 if (OMP_FOR_ORIG_DECLS (for_stmt) 16479 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), 16480 i)) == TREE_LIST 16481 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), 16482 i))) 16483 { 16484 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 16485 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig)) 16486 break; 16487 } 16488 } 16489 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))) 16490 { 16491 error_at (OMP_CLAUSE_LOCATION (*pc), 16492 "%<lastprivate%> clause on a %<loop%> construct refers " 16493 "to a variable %qD which is not the loop iterator", 16494 OMP_CLAUSE_DECL (*pc)); 16495 *pc = OMP_CLAUSE_CHAIN (*pc); 16496 break; 16497 } 16498 pc = &OMP_CLAUSE_CHAIN (*pc); 16499 break; 16500 default: 16501 pc = &OMP_CLAUSE_CHAIN (*pc); 16502 break; 16503 } 16504 16505 TREE_SET_CODE (for_stmt, OMP_SIMD); 16506 16507 int last; 16508 switch (kind) 16509 { 16510 case OMP_CLAUSE_BIND_THREAD: last = 0; break; 16511 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break; 16512 case OMP_CLAUSE_BIND_TEAMS: last = 2; break; 16513 } 16514 for (int pass = 1; pass <= last; pass++) 16515 { 16516 if (pass == 2) 16517 { 16518 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, 16519 make_node (BLOCK)); 16520 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind)); 16521 *expr_p = make_node (OMP_PARALLEL); 16522 TREE_TYPE (*expr_p) = void_type_node; 16523 OMP_PARALLEL_BODY (*expr_p) = bind; 16524 OMP_PARALLEL_COMBINED (*expr_p) = 1; 16525 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt)); 16526 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p); 16527 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16528 if (OMP_FOR_ORIG_DECLS (for_stmt) 16529 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i)) 16530 == TREE_LIST)) 16531 { 16532 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 16533 if (TREE_PURPOSE (elt) && TREE_VALUE (elt)) 16534 { 16535 *pc = build_omp_clause (UNKNOWN_LOCATION, 16536 OMP_CLAUSE_FIRSTPRIVATE); 16537 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt); 16538 pc = &OMP_CLAUSE_CHAIN (*pc); 16539 } 16540 } 16541 } 16542 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR); 16543 tree *pc = &OMP_FOR_CLAUSES (t); 16544 TREE_TYPE (t) = void_type_node; 16545 OMP_FOR_BODY (t) = *expr_p; 16546 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt)); 16547 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c)) 16548 switch (OMP_CLAUSE_CODE (c)) 16549 { 16550 case OMP_CLAUSE_BIND: 16551 case OMP_CLAUSE_ORDER: 16552 case OMP_CLAUSE_COLLAPSE: 16553 *pc = copy_node (c); 16554 pc = &OMP_CLAUSE_CHAIN (*pc); 16555 break; 16556 case OMP_CLAUSE_PRIVATE: 16557 case OMP_CLAUSE_FIRSTPRIVATE: 16558 /* Only needed on innermost. */ 16559 break; 16560 case OMP_CLAUSE_LASTPRIVATE: 16561 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last) 16562 { 16563 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16564 OMP_CLAUSE_FIRSTPRIVATE); 16565 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c); 16566 lang_hooks.decls.omp_finish_clause (*pc, NULL, false); 16567 pc = &OMP_CLAUSE_CHAIN (*pc); 16568 } 16569 *pc = copy_node (c); 16570 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE; 16571 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c)); 16572 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) 16573 { 16574 if (pass != last) 16575 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1; 16576 else 16577 lang_hooks.decls.omp_finish_clause (*pc, NULL, false); 16578 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0; 16579 } 16580 pc = &OMP_CLAUSE_CHAIN (*pc); 16581 break; 16582 case OMP_CLAUSE_REDUCTION: 16583 *pc = copy_node (c); 16584 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c)); 16585 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c)); 16586 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)) 16587 { 16588 auto_vec<tree> no_context_vars; 16589 int walk_subtrees = 0; 16590 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 16591 &walk_subtrees, &no_context_vars); 16592 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)) 16593 note_no_context_vars (&p, &walk_subtrees, &no_context_vars); 16594 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c), 16595 note_no_context_vars, 16596 &no_context_vars); 16597 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c), 16598 note_no_context_vars, 16599 &no_context_vars); 16600 16601 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc) 16602 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)); 16603 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)) 16604 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc) 16605 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)); 16606 16607 hash_map<tree, tree> decl_map; 16608 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c)); 16609 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 16610 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)); 16611 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)) 16612 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 16613 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)); 16614 16615 copy_body_data id; 16616 memset (&id, 0, sizeof (id)); 16617 id.src_fn = current_function_decl; 16618 id.dst_fn = current_function_decl; 16619 id.src_cfun = cfun; 16620 id.decl_map = &decl_map; 16621 id.copy_decl = copy_decl_no_change; 16622 id.transform_call_graph_edges = CB_CGE_DUPLICATE; 16623 id.transform_new_cfg = true; 16624 id.transform_return_to_modify = false; 16625 id.eh_lp_nr = 0; 16626 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r, 16627 &id, NULL); 16628 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r, 16629 &id, NULL); 16630 16631 for (tree d : no_context_vars) 16632 { 16633 DECL_CONTEXT (d) = NULL_TREE; 16634 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE; 16635 } 16636 } 16637 else 16638 { 16639 OMP_CLAUSE_REDUCTION_INIT (*pc) 16640 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c)); 16641 OMP_CLAUSE_REDUCTION_MERGE (*pc) 16642 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c)); 16643 } 16644 pc = &OMP_CLAUSE_CHAIN (*pc); 16645 break; 16646 default: 16647 gcc_unreachable (); 16648 } 16649 *pc = NULL_TREE; 16650 *expr_p = t; 16651 } 16652 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none); 16653 } 16654 16655 16656 /* Helper function of optimize_target_teams, find OMP_TEAMS inside 16657 of OMP_TARGET's body. */ 16658 16659 static tree 16660 find_omp_teams (tree *tp, int *walk_subtrees, void *) 16661 { 16662 *walk_subtrees = 0; 16663 switch (TREE_CODE (*tp)) 16664 { 16665 case OMP_TEAMS: 16666 return *tp; 16667 case BIND_EXPR: 16668 case STATEMENT_LIST: 16669 *walk_subtrees = 1; 16670 break; 16671 default: 16672 break; 16673 } 16674 return NULL_TREE; 16675 } 16676 16677 /* Helper function of optimize_target_teams, determine if the expression 16678 can be computed safely before the target construct on the host. */ 16679 16680 static tree 16681 computable_teams_clause (tree *tp, int *walk_subtrees, void *) 16682 { 16683 splay_tree_node n; 16684 16685 if (TYPE_P (*tp)) 16686 { 16687 *walk_subtrees = 0; 16688 return NULL_TREE; 16689 } 16690 switch (TREE_CODE (*tp)) 16691 { 16692 case VAR_DECL: 16693 case PARM_DECL: 16694 case RESULT_DECL: 16695 *walk_subtrees = 0; 16696 if (error_operand_p (*tp) 16697 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp)) 16698 || DECL_HAS_VALUE_EXPR_P (*tp) 16699 || DECL_THREAD_LOCAL_P (*tp) 16700 || TREE_SIDE_EFFECTS (*tp) 16701 || TREE_THIS_VOLATILE (*tp)) 16702 return *tp; 16703 if (is_global_var (*tp) 16704 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp)) 16705 || lookup_attribute ("omp declare target link", 16706 DECL_ATTRIBUTES (*tp)))) 16707 return *tp; 16708 if (VAR_P (*tp) 16709 && !DECL_SEEN_IN_BIND_EXPR_P (*tp) 16710 && !is_global_var (*tp) 16711 && decl_function_context (*tp) == current_function_decl) 16712 return *tp; 16713 n = splay_tree_lookup (gimplify_omp_ctxp->variables, 16714 (splay_tree_key) *tp); 16715 if (n == NULL) 16716 { 16717 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE) 16718 return NULL_TREE; 16719 return *tp; 16720 } 16721 else if (n->value & GOVD_LOCAL) 16722 return *tp; 16723 else if (n->value & GOVD_FIRSTPRIVATE) 16724 return NULL_TREE; 16725 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO)) 16726 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO)) 16727 return NULL_TREE; 16728 return *tp; 16729 case INTEGER_CST: 16730 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp))) 16731 return *tp; 16732 return NULL_TREE; 16733 case TARGET_EXPR: 16734 if (TARGET_EXPR_INITIAL (*tp) 16735 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL) 16736 return *tp; 16737 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp), 16738 walk_subtrees, NULL); 16739 /* Allow some reasonable subset of integral arithmetics. */ 16740 case PLUS_EXPR: 16741 case MINUS_EXPR: 16742 case MULT_EXPR: 16743 case TRUNC_DIV_EXPR: 16744 case CEIL_DIV_EXPR: 16745 case FLOOR_DIV_EXPR: 16746 case ROUND_DIV_EXPR: 16747 case TRUNC_MOD_EXPR: 16748 case CEIL_MOD_EXPR: 16749 case FLOOR_MOD_EXPR: 16750 case ROUND_MOD_EXPR: 16751 case RDIV_EXPR: 16752 case EXACT_DIV_EXPR: 16753 case MIN_EXPR: 16754 case MAX_EXPR: 16755 case LSHIFT_EXPR: 16756 case RSHIFT_EXPR: 16757 case BIT_IOR_EXPR: 16758 case BIT_XOR_EXPR: 16759 case BIT_AND_EXPR: 16760 case NEGATE_EXPR: 16761 case ABS_EXPR: 16762 case BIT_NOT_EXPR: 16763 case NON_LVALUE_EXPR: 16764 CASE_CONVERT: 16765 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp))) 16766 return *tp; 16767 return NULL_TREE; 16768 /* And disallow anything else, except for comparisons. */ 16769 default: 16770 if (COMPARISON_CLASS_P (*tp)) 16771 return NULL_TREE; 16772 return *tp; 16773 } 16774 } 16775 16776 /* Try to determine if the num_teams and/or thread_limit expressions 16777 can have their values determined already before entering the 16778 target construct. 16779 INTEGER_CSTs trivially are, 16780 integral decls that are firstprivate (explicitly or implicitly) 16781 or explicitly map(always, to:) or map(always, tofrom:) on the target 16782 region too, and expressions involving simple arithmetics on those 16783 too, function calls are not ok, dereferencing something neither etc. 16784 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of 16785 EXPR based on what we find: 16786 0 stands for clause not specified at all, use implementation default 16787 -1 stands for value that can't be determined easily before entering 16788 the target construct. 16789 -2 means that no explicit teams construct was specified 16790 If teams construct is not present at all, use 1 for num_teams 16791 and 0 for thread_limit (only one team is involved, and the thread 16792 limit is implementation defined. */ 16793 16794 static void 16795 optimize_target_teams (tree target, gimple_seq *pre_p) 16796 { 16797 tree body = OMP_BODY (target); 16798 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL); 16799 tree num_teams_lower = NULL_TREE; 16800 tree num_teams_upper = integer_zero_node; 16801 tree thread_limit = integer_zero_node; 16802 location_t num_teams_loc = EXPR_LOCATION (target); 16803 location_t thread_limit_loc = EXPR_LOCATION (target); 16804 tree c, *p, expr; 16805 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp; 16806 16807 if (teams == NULL_TREE) 16808 num_teams_upper = build_int_cst (integer_type_node, -2); 16809 else 16810 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c)) 16811 { 16812 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS) 16813 { 16814 p = &num_teams_upper; 16815 num_teams_loc = OMP_CLAUSE_LOCATION (c); 16816 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)) 16817 { 16818 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c); 16819 if (TREE_CODE (expr) == INTEGER_CST) 16820 num_teams_lower = expr; 16821 else if (walk_tree (&expr, computable_teams_clause, 16822 NULL, NULL)) 16823 num_teams_lower = integer_minus_one_node; 16824 else 16825 { 16826 num_teams_lower = expr; 16827 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context; 16828 if (gimplify_expr (&num_teams_lower, pre_p, NULL, 16829 is_gimple_val, fb_rvalue, false) 16830 == GS_ERROR) 16831 { 16832 gimplify_omp_ctxp = target_ctx; 16833 num_teams_lower = integer_minus_one_node; 16834 } 16835 else 16836 { 16837 gimplify_omp_ctxp = target_ctx; 16838 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR) 16839 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 16840 = num_teams_lower; 16841 } 16842 } 16843 } 16844 } 16845 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) 16846 { 16847 p = &thread_limit; 16848 thread_limit_loc = OMP_CLAUSE_LOCATION (c); 16849 } 16850 else 16851 continue; 16852 expr = OMP_CLAUSE_OPERAND (c, 0); 16853 if (TREE_CODE (expr) == INTEGER_CST) 16854 { 16855 *p = expr; 16856 continue; 16857 } 16858 if (walk_tree (&expr, computable_teams_clause, NULL, NULL)) 16859 { 16860 *p = integer_minus_one_node; 16861 continue; 16862 } 16863 *p = expr; 16864 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context; 16865 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false) 16866 == GS_ERROR) 16867 { 16868 gimplify_omp_ctxp = target_ctx; 16869 *p = integer_minus_one_node; 16870 continue; 16871 } 16872 gimplify_omp_ctxp = target_ctx; 16873 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR) 16874 OMP_CLAUSE_OPERAND (c, 0) = *p; 16875 } 16876 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT)) 16877 { 16878 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT); 16879 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit; 16880 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); 16881 OMP_TARGET_CLAUSES (target) = c; 16882 } 16883 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); 16884 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper; 16885 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower; 16886 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); 16887 OMP_TARGET_CLAUSES (target) = c; 16888 } 16889 16890 /* Gimplify the gross structure of several OMP constructs. */ 16891 16892 static void 16893 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) 16894 { 16895 tree expr = *expr_p; 16896 gimple *stmt; 16897 gimple_seq body = NULL; 16898 enum omp_region_type ort; 16899 16900 switch (TREE_CODE (expr)) 16901 { 16902 case OMP_SECTIONS: 16903 case OMP_SINGLE: 16904 ort = ORT_WORKSHARE; 16905 break; 16906 case OMP_SCOPE: 16907 ort = ORT_TASKGROUP; 16908 break; 16909 case OMP_TARGET: 16910 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET; 16911 break; 16912 case OACC_KERNELS: 16913 ort = ORT_ACC_KERNELS; 16914 break; 16915 case OACC_PARALLEL: 16916 ort = ORT_ACC_PARALLEL; 16917 break; 16918 case OACC_SERIAL: 16919 ort = ORT_ACC_SERIAL; 16920 break; 16921 case OACC_DATA: 16922 ort = ORT_ACC_DATA; 16923 break; 16924 case OMP_TARGET_DATA: 16925 ort = ORT_TARGET_DATA; 16926 break; 16927 case OMP_TEAMS: 16928 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS; 16929 if (gimplify_omp_ctxp == NULL 16930 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET) 16931 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS); 16932 break; 16933 case OACC_HOST_DATA: 16934 ort = ORT_ACC_HOST_DATA; 16935 break; 16936 default: 16937 gcc_unreachable (); 16938 } 16939 16940 bool save_in_omp_construct = in_omp_construct; 16941 if ((ort & ORT_ACC) == 0) 16942 in_omp_construct = false; 16943 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort, 16944 TREE_CODE (expr)); 16945 if (TREE_CODE (expr) == OMP_TARGET) 16946 optimize_target_teams (expr, pre_p); 16947 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0 16948 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) 16949 { 16950 push_gimplify_context (); 16951 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body); 16952 if (gimple_code (g) == GIMPLE_BIND) 16953 pop_gimplify_context (g); 16954 else 16955 pop_gimplify_context (NULL); 16956 if ((ort & ORT_TARGET_DATA) != 0) 16957 { 16958 enum built_in_function end_ix; 16959 switch (TREE_CODE (expr)) 16960 { 16961 case OACC_DATA: 16962 case OACC_HOST_DATA: 16963 end_ix = BUILT_IN_GOACC_DATA_END; 16964 break; 16965 case OMP_TARGET_DATA: 16966 end_ix = BUILT_IN_GOMP_TARGET_END_DATA; 16967 break; 16968 default: 16969 gcc_unreachable (); 16970 } 16971 tree fn = builtin_decl_explicit (end_ix); 16972 g = gimple_build_call (fn, 0); 16973 gimple_seq cleanup = NULL; 16974 gimple_seq_add_stmt (&cleanup, g); 16975 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY); 16976 body = NULL; 16977 gimple_seq_add_stmt (&body, g); 16978 } 16979 } 16980 else 16981 gimplify_and_add (OMP_BODY (expr), &body); 16982 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr), 16983 TREE_CODE (expr)); 16984 in_omp_construct = save_in_omp_construct; 16985 16986 switch (TREE_CODE (expr)) 16987 { 16988 case OACC_DATA: 16989 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA, 16990 OMP_CLAUSES (expr)); 16991 break; 16992 case OACC_HOST_DATA: 16993 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT)) 16994 { 16995 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 16996 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR) 16997 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1; 16998 } 16999 17000 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA, 17001 OMP_CLAUSES (expr)); 17002 break; 17003 case OACC_KERNELS: 17004 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS, 17005 OMP_CLAUSES (expr)); 17006 break; 17007 case OACC_PARALLEL: 17008 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL, 17009 OMP_CLAUSES (expr)); 17010 break; 17011 case OACC_SERIAL: 17012 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL, 17013 OMP_CLAUSES (expr)); 17014 break; 17015 case OMP_SECTIONS: 17016 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr)); 17017 break; 17018 case OMP_SINGLE: 17019 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr)); 17020 break; 17021 case OMP_SCOPE: 17022 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr)); 17023 break; 17024 case OMP_TARGET: 17025 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION, 17026 OMP_CLAUSES (expr)); 17027 break; 17028 case OMP_TARGET_DATA: 17029 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed 17030 to be evaluated before the use_device_{ptr,addr} clauses if they 17031 refer to the same variables. */ 17032 { 17033 tree use_device_clauses; 17034 tree *pc, *uc = &use_device_clauses; 17035 for (pc = &OMP_CLAUSES (expr); *pc; ) 17036 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR 17037 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR) 17038 { 17039 *uc = *pc; 17040 *pc = OMP_CLAUSE_CHAIN (*pc); 17041 uc = &OMP_CLAUSE_CHAIN (*uc); 17042 } 17043 else 17044 pc = &OMP_CLAUSE_CHAIN (*pc); 17045 *uc = NULL_TREE; 17046 *pc = use_device_clauses; 17047 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA, 17048 OMP_CLAUSES (expr)); 17049 } 17050 break; 17051 case OMP_TEAMS: 17052 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr)); 17053 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) 17054 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true); 17055 break; 17056 default: 17057 gcc_unreachable (); 17058 } 17059 17060 gimplify_seq_add_stmt (pre_p, stmt); 17061 *expr_p = NULL_TREE; 17062 } 17063 17064 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP 17065 target update constructs. */ 17066 17067 static void 17068 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) 17069 { 17070 tree expr = *expr_p; 17071 int kind; 17072 gomp_target *stmt; 17073 enum omp_region_type ort = ORT_WORKSHARE; 17074 17075 switch (TREE_CODE (expr)) 17076 { 17077 case OACC_ENTER_DATA: 17078 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA; 17079 ort = ORT_ACC; 17080 break; 17081 case OACC_EXIT_DATA: 17082 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA; 17083 ort = ORT_ACC; 17084 break; 17085 case OACC_UPDATE: 17086 kind = GF_OMP_TARGET_KIND_OACC_UPDATE; 17087 ort = ORT_ACC; 17088 break; 17089 case OMP_TARGET_UPDATE: 17090 kind = GF_OMP_TARGET_KIND_UPDATE; 17091 break; 17092 case OMP_TARGET_ENTER_DATA: 17093 kind = GF_OMP_TARGET_KIND_ENTER_DATA; 17094 break; 17095 case OMP_TARGET_EXIT_DATA: 17096 kind = GF_OMP_TARGET_KIND_EXIT_DATA; 17097 break; 17098 default: 17099 gcc_unreachable (); 17100 } 17101 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p, 17102 ort, TREE_CODE (expr)); 17103 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr), 17104 TREE_CODE (expr)); 17105 if (TREE_CODE (expr) == OACC_UPDATE 17106 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr), 17107 OMP_CLAUSE_IF_PRESENT)) 17108 { 17109 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present 17110 clause. */ 17111 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17112 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP) 17113 switch (OMP_CLAUSE_MAP_KIND (c)) 17114 { 17115 case GOMP_MAP_FORCE_TO: 17116 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO); 17117 break; 17118 case GOMP_MAP_FORCE_FROM: 17119 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM); 17120 break; 17121 default: 17122 break; 17123 } 17124 } 17125 else if (TREE_CODE (expr) == OACC_EXIT_DATA 17126 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr), 17127 OMP_CLAUSE_FINALIZE)) 17128 { 17129 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize" 17130 semantics. */ 17131 bool have_clause = false; 17132 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17133 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP) 17134 switch (OMP_CLAUSE_MAP_KIND (c)) 17135 { 17136 case GOMP_MAP_FROM: 17137 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM); 17138 have_clause = true; 17139 break; 17140 case GOMP_MAP_RELEASE: 17141 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE); 17142 have_clause = true; 17143 break; 17144 case GOMP_MAP_TO_PSET: 17145 /* Fortran arrays with descriptors must map that descriptor when 17146 doing standalone "attach" operations (in OpenACC). In that 17147 case GOMP_MAP_TO_PSET appears by itself with no preceding 17148 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */ 17149 break; 17150 case GOMP_MAP_POINTER: 17151 /* TODO PR92929: we may see these here, but they'll always follow 17152 one of the clauses above, and will be handled by libgomp as 17153 one group, so no handling required here. */ 17154 gcc_assert (have_clause); 17155 break; 17156 case GOMP_MAP_DETACH: 17157 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH); 17158 have_clause = false; 17159 break; 17160 case GOMP_MAP_STRUCT: 17161 case GOMP_MAP_STRUCT_UNORD: 17162 have_clause = false; 17163 break; 17164 default: 17165 gcc_unreachable (); 17166 } 17167 } 17168 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr)); 17169 17170 gimplify_seq_add_stmt (pre_p, stmt); 17171 *expr_p = NULL_TREE; 17172 } 17173 17174 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have 17175 stabilized the lhs of the atomic operation as *ADDR. Return true if 17176 EXPR is this stabilized form. */ 17177 17178 static bool 17179 goa_lhs_expr_p (tree expr, tree addr) 17180 { 17181 /* Also include casts to other type variants. The C front end is fond 17182 of adding these for e.g. volatile variables. This is like 17183 STRIP_TYPE_NOPS but includes the main variant lookup. */ 17184 STRIP_USELESS_TYPE_CONVERSION (expr); 17185 17186 if (INDIRECT_REF_P (expr)) 17187 { 17188 expr = TREE_OPERAND (expr, 0); 17189 while (expr != addr 17190 && (CONVERT_EXPR_P (expr) 17191 || TREE_CODE (expr) == NON_LVALUE_EXPR) 17192 && TREE_CODE (expr) == TREE_CODE (addr) 17193 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr))) 17194 { 17195 expr = TREE_OPERAND (expr, 0); 17196 addr = TREE_OPERAND (addr, 0); 17197 } 17198 if (expr == addr) 17199 return true; 17200 return (TREE_CODE (addr) == ADDR_EXPR 17201 && TREE_CODE (expr) == ADDR_EXPR 17202 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0)); 17203 } 17204 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0)) 17205 return true; 17206 return false; 17207 } 17208 17209 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an 17210 expression does not involve the lhs, evaluate it into a temporary. 17211 Return 1 if the lhs appeared as a subexpression, 0 if it did not, 17212 or -1 if an error was encountered. */ 17213 17214 static int 17215 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr, 17216 tree lhs_var, tree &target_expr, bool rhs, int depth) 17217 { 17218 tree expr = *expr_p; 17219 int saw_lhs = 0; 17220 17221 if (goa_lhs_expr_p (expr, lhs_addr)) 17222 { 17223 if (pre_p) 17224 *expr_p = lhs_var; 17225 return 1; 17226 } 17227 if (is_gimple_val (expr)) 17228 return 0; 17229 17230 /* Maximum depth of lhs in expression is for the 17231 __builtin_clear_padding (...), __builtin_clear_padding (...), 17232 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */ 17233 if (++depth > 7) 17234 goto finish; 17235 17236 switch (TREE_CODE_CLASS (TREE_CODE (expr))) 17237 { 17238 case tcc_binary: 17239 case tcc_comparison: 17240 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr, 17241 lhs_var, target_expr, true, depth); 17242 /* FALLTHRU */ 17243 case tcc_unary: 17244 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr, 17245 lhs_var, target_expr, true, depth); 17246 break; 17247 case tcc_expression: 17248 switch (TREE_CODE (expr)) 17249 { 17250 case TRUTH_ANDIF_EXPR: 17251 case TRUTH_ORIF_EXPR: 17252 case TRUTH_AND_EXPR: 17253 case TRUTH_OR_EXPR: 17254 case TRUTH_XOR_EXPR: 17255 case BIT_INSERT_EXPR: 17256 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17257 lhs_addr, lhs_var, target_expr, true, 17258 depth); 17259 /* FALLTHRU */ 17260 case TRUTH_NOT_EXPR: 17261 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17262 lhs_addr, lhs_var, target_expr, true, 17263 depth); 17264 break; 17265 case MODIFY_EXPR: 17266 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var, 17267 target_expr, true, depth)) 17268 break; 17269 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17270 lhs_addr, lhs_var, target_expr, true, 17271 depth); 17272 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17273 lhs_addr, lhs_var, target_expr, false, 17274 depth); 17275 break; 17276 /* FALLTHRU */ 17277 case ADDR_EXPR: 17278 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var, 17279 target_expr, true, depth)) 17280 break; 17281 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17282 lhs_addr, lhs_var, target_expr, false, 17283 depth); 17284 break; 17285 case COMPOUND_EXPR: 17286 /* Break out any preevaluations from cp_build_modify_expr. */ 17287 for (; TREE_CODE (expr) == COMPOUND_EXPR; 17288 expr = TREE_OPERAND (expr, 1)) 17289 { 17290 /* Special-case __builtin_clear_padding call before 17291 __builtin_memcmp. */ 17292 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR) 17293 { 17294 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0)); 17295 if (fndecl 17296 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING) 17297 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))) 17298 && (!pre_p 17299 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, 17300 lhs_addr, lhs_var, 17301 target_expr, true, depth))) 17302 { 17303 if (pre_p) 17304 *expr_p = expr; 17305 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0), 17306 pre_p, lhs_addr, lhs_var, 17307 target_expr, true, depth); 17308 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), 17309 pre_p, lhs_addr, lhs_var, 17310 target_expr, rhs, depth); 17311 return saw_lhs; 17312 } 17313 } 17314 17315 if (pre_p) 17316 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p); 17317 } 17318 if (!pre_p) 17319 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var, 17320 target_expr, rhs, depth); 17321 *expr_p = expr; 17322 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var, 17323 target_expr, rhs, depth); 17324 case COND_EXPR: 17325 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr, 17326 lhs_var, target_expr, true, depth)) 17327 break; 17328 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17329 lhs_addr, lhs_var, target_expr, true, 17330 depth); 17331 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17332 lhs_addr, lhs_var, target_expr, true, 17333 depth); 17334 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p, 17335 lhs_addr, lhs_var, target_expr, true, 17336 depth); 17337 break; 17338 case TARGET_EXPR: 17339 if (TARGET_EXPR_INITIAL (expr)) 17340 { 17341 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, 17342 lhs_var, target_expr, true, 17343 depth)) 17344 break; 17345 if (expr == target_expr) 17346 saw_lhs = 1; 17347 else 17348 { 17349 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr), 17350 pre_p, lhs_addr, lhs_var, 17351 target_expr, true, depth); 17352 if (saw_lhs && target_expr == NULL_TREE && pre_p) 17353 target_expr = expr; 17354 } 17355 } 17356 break; 17357 default: 17358 break; 17359 } 17360 break; 17361 case tcc_reference: 17362 if (TREE_CODE (expr) == BIT_FIELD_REF 17363 || TREE_CODE (expr) == VIEW_CONVERT_EXPR) 17364 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17365 lhs_addr, lhs_var, target_expr, true, 17366 depth); 17367 break; 17368 case tcc_vl_exp: 17369 if (TREE_CODE (expr) == CALL_EXPR) 17370 { 17371 if (tree fndecl = get_callee_fndecl (expr)) 17372 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING, 17373 BUILT_IN_MEMCMP)) 17374 { 17375 int nargs = call_expr_nargs (expr); 17376 for (int i = 0; i < nargs; i++) 17377 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i), 17378 pre_p, lhs_addr, lhs_var, 17379 target_expr, true, depth); 17380 } 17381 } 17382 break; 17383 default: 17384 break; 17385 } 17386 17387 finish: 17388 if (saw_lhs == 0 && pre_p) 17389 { 17390 enum gimplify_status gs; 17391 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr))) 17392 { 17393 gimplify_stmt (&expr, pre_p); 17394 return saw_lhs; 17395 } 17396 else if (rhs) 17397 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue); 17398 else 17399 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue); 17400 if (gs != GS_ALL_DONE) 17401 saw_lhs = -1; 17402 } 17403 17404 return saw_lhs; 17405 } 17406 17407 /* Gimplify an OMP_ATOMIC statement. */ 17408 17409 static enum gimplify_status 17410 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p) 17411 { 17412 tree addr = TREE_OPERAND (*expr_p, 0); 17413 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ 17414 ? NULL : TREE_OPERAND (*expr_p, 1); 17415 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); 17416 tree tmp_load; 17417 gomp_atomic_load *loadstmt; 17418 gomp_atomic_store *storestmt; 17419 tree target_expr = NULL_TREE; 17420 17421 tmp_load = create_tmp_reg (type); 17422 if (rhs 17423 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr, 17424 true, 0) < 0) 17425 return GS_ERROR; 17426 17427 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue) 17428 != GS_ALL_DONE) 17429 return GS_ERROR; 17430 17431 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr, 17432 OMP_ATOMIC_MEMORY_ORDER (*expr_p)); 17433 gimplify_seq_add_stmt (pre_p, loadstmt); 17434 if (rhs) 17435 { 17436 /* BIT_INSERT_EXPR is not valid for non-integral bitfield 17437 representatives. Use BIT_FIELD_REF on the lhs instead. */ 17438 tree rhsarg = rhs; 17439 if (TREE_CODE (rhs) == COND_EXPR) 17440 rhsarg = TREE_OPERAND (rhs, 1); 17441 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR 17442 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load))) 17443 { 17444 tree bitpos = TREE_OPERAND (rhsarg, 2); 17445 tree op1 = TREE_OPERAND (rhsarg, 1); 17446 tree bitsize; 17447 tree tmp_store = tmp_load; 17448 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD) 17449 tmp_store = get_initialized_tmp_var (tmp_load, pre_p); 17450 if (INTEGRAL_TYPE_P (TREE_TYPE (op1))) 17451 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1))); 17452 else 17453 bitsize = TYPE_SIZE (TREE_TYPE (op1)); 17454 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load); 17455 tree t = build2_loc (EXPR_LOCATION (rhsarg), 17456 MODIFY_EXPR, void_type_node, 17457 build3_loc (EXPR_LOCATION (rhsarg), 17458 BIT_FIELD_REF, TREE_TYPE (op1), 17459 tmp_store, bitsize, bitpos), op1); 17460 if (TREE_CODE (rhs) == COND_EXPR) 17461 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node, 17462 TREE_OPERAND (rhs, 0), t, void_node); 17463 gimplify_and_add (t, pre_p); 17464 rhs = tmp_store; 17465 } 17466 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr; 17467 if (TREE_CODE (rhs) == COND_EXPR) 17468 gimplify_ctxp->allow_rhs_cond_expr = true; 17469 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL, 17470 is_gimple_val, fb_rvalue); 17471 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr; 17472 if (gs != GS_ALL_DONE) 17473 return GS_ERROR; 17474 } 17475 17476 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ) 17477 rhs = tmp_load; 17478 storestmt 17479 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p)); 17480 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p)) 17481 { 17482 gimple_omp_atomic_set_weak (loadstmt); 17483 gimple_omp_atomic_set_weak (storestmt); 17484 } 17485 gimplify_seq_add_stmt (pre_p, storestmt); 17486 switch (TREE_CODE (*expr_p)) 17487 { 17488 case OMP_ATOMIC_READ: 17489 case OMP_ATOMIC_CAPTURE_OLD: 17490 *expr_p = tmp_load; 17491 gimple_omp_atomic_set_need_value (loadstmt); 17492 break; 17493 case OMP_ATOMIC_CAPTURE_NEW: 17494 *expr_p = rhs; 17495 gimple_omp_atomic_set_need_value (storestmt); 17496 break; 17497 default: 17498 *expr_p = NULL; 17499 break; 17500 } 17501 17502 return GS_ALL_DONE; 17503 } 17504 17505 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the 17506 body, and adding some EH bits. */ 17507 17508 static enum gimplify_status 17509 gimplify_transaction (tree *expr_p, gimple_seq *pre_p) 17510 { 17511 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr); 17512 gimple *body_stmt; 17513 gtransaction *trans_stmt; 17514 gimple_seq body = NULL; 17515 int subcode = 0; 17516 17517 /* Wrap the transaction body in a BIND_EXPR so we have a context 17518 where to put decls for OMP. */ 17519 if (TREE_CODE (tbody) != BIND_EXPR) 17520 { 17521 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL); 17522 TREE_SIDE_EFFECTS (bind) = 1; 17523 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody)); 17524 TRANSACTION_EXPR_BODY (expr) = bind; 17525 } 17526 17527 push_gimplify_context (); 17528 temp = voidify_wrapper_expr (*expr_p, NULL); 17529 17530 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body); 17531 pop_gimplify_context (body_stmt); 17532 17533 trans_stmt = gimple_build_transaction (body); 17534 if (TRANSACTION_EXPR_OUTER (expr)) 17535 subcode = GTMA_IS_OUTER; 17536 else if (TRANSACTION_EXPR_RELAXED (expr)) 17537 subcode = GTMA_IS_RELAXED; 17538 gimple_transaction_set_subcode (trans_stmt, subcode); 17539 17540 gimplify_seq_add_stmt (pre_p, trans_stmt); 17541 17542 if (temp) 17543 { 17544 *expr_p = temp; 17545 return GS_OK; 17546 } 17547 17548 *expr_p = NULL_TREE; 17549 return GS_ALL_DONE; 17550 } 17551 17552 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY 17553 is the OMP_BODY of the original EXPR (which has already been 17554 gimplified so it's not present in the EXPR). 17555 17556 Return the gimplified GIMPLE_OMP_ORDERED tuple. */ 17557 17558 static gimple * 17559 gimplify_omp_ordered (tree expr, gimple_seq body) 17560 { 17561 tree c, decls; 17562 int failures = 0; 17563 unsigned int i; 17564 tree source_c = NULL_TREE; 17565 tree sink_c = NULL_TREE; 17566 17567 if (gimplify_omp_ctxp) 17568 { 17569 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17570 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17571 && gimplify_omp_ctxp->loop_iter_var.is_empty ()) 17572 { 17573 error_at (OMP_CLAUSE_LOCATION (c), 17574 "%<ordered%> construct with %qs clause must be " 17575 "closely nested inside a loop with %<ordered%> clause", 17576 OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross"); 17577 failures++; 17578 } 17579 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17580 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK) 17581 { 17582 bool fail = false; 17583 sink_c = c; 17584 if (OMP_CLAUSE_DECL (c) == NULL_TREE) 17585 continue; /* omp_cur_iteration - 1 */ 17586 for (decls = OMP_CLAUSE_DECL (c), i = 0; 17587 decls && TREE_CODE (decls) == TREE_LIST; 17588 decls = TREE_CHAIN (decls), ++i) 17589 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2) 17590 continue; 17591 else if (TREE_VALUE (decls) 17592 != gimplify_omp_ctxp->loop_iter_var[2 * i]) 17593 { 17594 error_at (OMP_CLAUSE_LOCATION (c), 17595 "variable %qE is not an iteration " 17596 "of outermost loop %d, expected %qE", 17597 TREE_VALUE (decls), i + 1, 17598 gimplify_omp_ctxp->loop_iter_var[2 * i]); 17599 fail = true; 17600 failures++; 17601 } 17602 else 17603 TREE_VALUE (decls) 17604 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1]; 17605 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2) 17606 { 17607 error_at (OMP_CLAUSE_LOCATION (c), 17608 "number of variables in %qs clause with " 17609 "%<sink%> modifier does not match number of " 17610 "iteration variables", 17611 OMP_CLAUSE_DOACROSS_DEPEND (c) 17612 ? "depend" : "doacross"); 17613 failures++; 17614 } 17615 } 17616 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17617 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE) 17618 { 17619 if (source_c) 17620 { 17621 error_at (OMP_CLAUSE_LOCATION (c), 17622 "more than one %qs clause with %<source%> " 17623 "modifier on an %<ordered%> construct", 17624 OMP_CLAUSE_DOACROSS_DEPEND (source_c) 17625 ? "depend" : "doacross"); 17626 failures++; 17627 } 17628 else 17629 source_c = c; 17630 } 17631 } 17632 if (source_c && sink_c) 17633 { 17634 error_at (OMP_CLAUSE_LOCATION (source_c), 17635 "%qs clause with %<source%> modifier specified " 17636 "together with %qs clauses with %<sink%> modifier " 17637 "on the same construct", 17638 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross", 17639 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross"); 17640 failures++; 17641 } 17642 17643 if (failures) 17644 return gimple_build_nop (); 17645 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr)); 17646 } 17647 17648 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the 17649 expression produces a value to be used as an operand inside a GIMPLE 17650 statement, the value will be stored back in *EXPR_P. This value will 17651 be a tree of class tcc_declaration, tcc_constant, tcc_reference or 17652 an SSA_NAME. The corresponding sequence of GIMPLE statements is 17653 emitted in PRE_P and POST_P. 17654 17655 Additionally, this process may overwrite parts of the input 17656 expression during gimplification. Ideally, it should be 17657 possible to do non-destructive gimplification. 17658 17659 EXPR_P points to the GENERIC expression to convert to GIMPLE. If 17660 the expression needs to evaluate to a value to be used as 17661 an operand in a GIMPLE statement, this value will be stored in 17662 *EXPR_P on exit. This happens when the caller specifies one 17663 of fb_lvalue or fb_rvalue fallback flags. 17664 17665 PRE_P will contain the sequence of GIMPLE statements corresponding 17666 to the evaluation of EXPR and all the side-effects that must 17667 be executed before the main expression. On exit, the last 17668 statement of PRE_P is the core statement being gimplified. For 17669 instance, when gimplifying 'if (++a)' the last statement in 17670 PRE_P will be 'if (t.1)' where t.1 is the result of 17671 pre-incrementing 'a'. 17672 17673 POST_P will contain the sequence of GIMPLE statements corresponding 17674 to the evaluation of all the side-effects that must be executed 17675 after the main expression. If this is NULL, the post 17676 side-effects are stored at the end of PRE_P. 17677 17678 The reason why the output is split in two is to handle post 17679 side-effects explicitly. In some cases, an expression may have 17680 inner and outer post side-effects which need to be emitted in 17681 an order different from the one given by the recursive 17682 traversal. For instance, for the expression (*p--)++ the post 17683 side-effects of '--' must actually occur *after* the post 17684 side-effects of '++'. However, gimplification will first visit 17685 the inner expression, so if a separate POST sequence was not 17686 used, the resulting sequence would be: 17687 17688 1 t.1 = *p 17689 2 p = p - 1 17690 3 t.2 = t.1 + 1 17691 4 *p = t.2 17692 17693 However, the post-decrement operation in line #2 must not be 17694 evaluated until after the store to *p at line #4, so the 17695 correct sequence should be: 17696 17697 1 t.1 = *p 17698 2 t.2 = t.1 + 1 17699 3 *p = t.2 17700 4 p = p - 1 17701 17702 So, by specifying a separate post queue, it is possible 17703 to emit the post side-effects in the correct order. 17704 If POST_P is NULL, an internal queue will be used. Before 17705 returning to the caller, the sequence POST_P is appended to 17706 the main output sequence PRE_P. 17707 17708 GIMPLE_TEST_F points to a function that takes a tree T and 17709 returns nonzero if T is in the GIMPLE form requested by the 17710 caller. The GIMPLE predicates are in gimple.cc. 17711 17712 FALLBACK tells the function what sort of a temporary we want if 17713 gimplification cannot produce an expression that complies with 17714 GIMPLE_TEST_F. 17715 17716 fb_none means that no temporary should be generated 17717 fb_rvalue means that an rvalue is OK to generate 17718 fb_lvalue means that an lvalue is OK to generate 17719 fb_either means that either is OK, but an lvalue is preferable. 17720 fb_mayfail means that gimplification may fail (in which case 17721 GS_ERROR will be returned) 17722 17723 The return value is either GS_ERROR or GS_ALL_DONE, since this 17724 function iterates until EXPR is completely gimplified or an error 17725 occurs. */ 17726 17727 enum gimplify_status 17728 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 17729 bool (*gimple_test_f) (tree), fallback_t fallback) 17730 { 17731 tree tmp; 17732 gimple_seq internal_pre = NULL; 17733 gimple_seq internal_post = NULL; 17734 tree save_expr; 17735 bool is_statement; 17736 location_t saved_location; 17737 enum gimplify_status ret; 17738 gimple_stmt_iterator pre_last_gsi, post_last_gsi; 17739 tree label; 17740 17741 save_expr = *expr_p; 17742 if (save_expr == NULL_TREE) 17743 return GS_ALL_DONE; 17744 17745 /* If we are gimplifying a top-level statement, PRE_P must be valid. */ 17746 is_statement = gimple_test_f == is_gimple_stmt; 17747 if (is_statement) 17748 gcc_assert (pre_p); 17749 17750 /* Consistency checks. */ 17751 if (gimple_test_f == is_gimple_reg) 17752 gcc_assert (fallback & (fb_rvalue | fb_lvalue)); 17753 else if (gimple_test_f == is_gimple_val 17754 || gimple_test_f == is_gimple_call_addr 17755 || gimple_test_f == is_gimple_condexpr_for_cond 17756 || gimple_test_f == is_gimple_mem_rhs 17757 || gimple_test_f == is_gimple_mem_rhs_or_call 17758 || gimple_test_f == is_gimple_reg_rhs 17759 || gimple_test_f == is_gimple_reg_rhs_or_call 17760 || gimple_test_f == is_gimple_asm_val 17761 || gimple_test_f == is_gimple_mem_ref_addr) 17762 gcc_assert (fallback & fb_rvalue); 17763 else if (gimple_test_f == is_gimple_min_lval 17764 || gimple_test_f == is_gimple_lvalue) 17765 gcc_assert (fallback & fb_lvalue); 17766 else if (gimple_test_f == is_gimple_addressable) 17767 gcc_assert (fallback & fb_either); 17768 else if (gimple_test_f == is_gimple_stmt) 17769 gcc_assert (fallback == fb_none); 17770 else 17771 { 17772 /* We should have recognized the GIMPLE_TEST_F predicate to 17773 know what kind of fallback to use in case a temporary is 17774 needed to hold the value or address of *EXPR_P. */ 17775 gcc_unreachable (); 17776 } 17777 17778 /* We used to check the predicate here and return immediately if it 17779 succeeds. This is wrong; the design is for gimplification to be 17780 idempotent, and for the predicates to only test for valid forms, not 17781 whether they are fully simplified. */ 17782 if (pre_p == NULL) 17783 pre_p = &internal_pre; 17784 17785 if (post_p == NULL) 17786 post_p = &internal_post; 17787 17788 /* Remember the last statements added to PRE_P and POST_P. Every 17789 new statement added by the gimplification helpers needs to be 17790 annotated with location information. To centralize the 17791 responsibility, we remember the last statement that had been 17792 added to both queues before gimplifying *EXPR_P. If 17793 gimplification produces new statements in PRE_P and POST_P, those 17794 statements will be annotated with the same location information 17795 as *EXPR_P. */ 17796 pre_last_gsi = gsi_last (*pre_p); 17797 post_last_gsi = gsi_last (*post_p); 17798 17799 saved_location = input_location; 17800 if (save_expr != error_mark_node 17801 && EXPR_HAS_LOCATION (*expr_p)) 17802 input_location = EXPR_LOCATION (*expr_p); 17803 17804 /* Loop over the specific gimplifiers until the toplevel node 17805 remains the same. */ 17806 do 17807 { 17808 /* Strip away as many useless type conversions as possible 17809 at the toplevel. */ 17810 STRIP_USELESS_TYPE_CONVERSION (*expr_p); 17811 17812 /* Remember the expr. */ 17813 save_expr = *expr_p; 17814 17815 /* Die, die, die, my darling. */ 17816 if (error_operand_p (save_expr)) 17817 { 17818 ret = GS_ERROR; 17819 break; 17820 } 17821 17822 /* Do any language-specific gimplification. */ 17823 ret = ((enum gimplify_status) 17824 lang_hooks.gimplify_expr (expr_p, pre_p, post_p)); 17825 if (ret == GS_OK) 17826 { 17827 if (*expr_p == NULL_TREE) 17828 break; 17829 if (*expr_p != save_expr) 17830 continue; 17831 } 17832 else if (ret != GS_UNHANDLED) 17833 break; 17834 17835 /* Make sure that all the cases set 'ret' appropriately. */ 17836 ret = GS_UNHANDLED; 17837 switch (TREE_CODE (*expr_p)) 17838 { 17839 /* First deal with the special cases. */ 17840 17841 case POSTINCREMENT_EXPR: 17842 case POSTDECREMENT_EXPR: 17843 case PREINCREMENT_EXPR: 17844 case PREDECREMENT_EXPR: 17845 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p, 17846 fallback != fb_none, 17847 TREE_TYPE (*expr_p)); 17848 break; 17849 17850 case VIEW_CONVERT_EXPR: 17851 if ((fallback & fb_rvalue) 17852 && is_gimple_reg_type (TREE_TYPE (*expr_p)) 17853 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) 17854 { 17855 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 17856 post_p, is_gimple_val, fb_rvalue); 17857 recalculate_side_effects (*expr_p); 17858 break; 17859 } 17860 /* Fallthru. */ 17861 17862 case ARRAY_REF: 17863 case ARRAY_RANGE_REF: 17864 case REALPART_EXPR: 17865 case IMAGPART_EXPR: 17866 case COMPONENT_REF: 17867 ret = gimplify_compound_lval (expr_p, pre_p, post_p, 17868 fallback ? fallback : fb_rvalue); 17869 break; 17870 17871 case COND_EXPR: 17872 ret = gimplify_cond_expr (expr_p, pre_p, fallback); 17873 17874 /* C99 code may assign to an array in a structure value of a 17875 conditional expression, and this has undefined behavior 17876 only on execution, so create a temporary if an lvalue is 17877 required. */ 17878 if (fallback == fb_lvalue) 17879 { 17880 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 17881 mark_addressable (*expr_p); 17882 ret = GS_OK; 17883 } 17884 break; 17885 17886 case CALL_EXPR: 17887 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); 17888 17889 /* C99 code may assign to an array in a structure returned 17890 from a function, and this has undefined behavior only on 17891 execution, so create a temporary if an lvalue is 17892 required. */ 17893 if (fallback == fb_lvalue) 17894 { 17895 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 17896 mark_addressable (*expr_p); 17897 ret = GS_OK; 17898 } 17899 break; 17900 17901 case TREE_LIST: 17902 gcc_unreachable (); 17903 17904 case OMP_ARRAY_SECTION: 17905 gcc_unreachable (); 17906 17907 case COMPOUND_EXPR: 17908 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); 17909 break; 17910 17911 case COMPOUND_LITERAL_EXPR: 17912 ret = gimplify_compound_literal_expr (expr_p, pre_p, 17913 gimple_test_f, fallback); 17914 break; 17915 17916 case MODIFY_EXPR: 17917 case INIT_EXPR: 17918 ret = gimplify_modify_expr (expr_p, pre_p, post_p, 17919 fallback != fb_none); 17920 break; 17921 17922 case TRUTH_ANDIF_EXPR: 17923 case TRUTH_ORIF_EXPR: 17924 { 17925 /* Preserve the original type of the expression and the 17926 source location of the outer expression. */ 17927 tree org_type = TREE_TYPE (*expr_p); 17928 *expr_p = gimple_boolify (*expr_p); 17929 *expr_p = build3_loc (input_location, COND_EXPR, 17930 org_type, *expr_p, 17931 fold_convert_loc 17932 (input_location, 17933 org_type, boolean_true_node), 17934 fold_convert_loc 17935 (input_location, 17936 org_type, boolean_false_node)); 17937 ret = GS_OK; 17938 break; 17939 } 17940 17941 case TRUTH_NOT_EXPR: 17942 { 17943 tree type = TREE_TYPE (*expr_p); 17944 /* The parsers are careful to generate TRUTH_NOT_EXPR 17945 only with operands that are always zero or one. 17946 We do not fold here but handle the only interesting case 17947 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */ 17948 *expr_p = gimple_boolify (*expr_p); 17949 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1) 17950 *expr_p = build1_loc (input_location, BIT_NOT_EXPR, 17951 TREE_TYPE (*expr_p), 17952 TREE_OPERAND (*expr_p, 0)); 17953 else 17954 *expr_p = build2_loc (input_location, BIT_XOR_EXPR, 17955 TREE_TYPE (*expr_p), 17956 TREE_OPERAND (*expr_p, 0), 17957 build_int_cst (TREE_TYPE (*expr_p), 1)); 17958 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p))) 17959 *expr_p = fold_convert_loc (input_location, type, *expr_p); 17960 ret = GS_OK; 17961 break; 17962 } 17963 17964 case ADDR_EXPR: 17965 ret = gimplify_addr_expr (expr_p, pre_p, post_p); 17966 break; 17967 17968 case ANNOTATE_EXPR: 17969 { 17970 tree cond = TREE_OPERAND (*expr_p, 0); 17971 tree kind = TREE_OPERAND (*expr_p, 1); 17972 tree data = TREE_OPERAND (*expr_p, 2); 17973 tree type = TREE_TYPE (cond); 17974 if (!INTEGRAL_TYPE_P (type)) 17975 { 17976 *expr_p = cond; 17977 ret = GS_OK; 17978 break; 17979 } 17980 tree tmp = create_tmp_var (type); 17981 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); 17982 gcall *call 17983 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data); 17984 gimple_call_set_lhs (call, tmp); 17985 gimplify_seq_add_stmt (pre_p, call); 17986 *expr_p = tmp; 17987 ret = GS_ALL_DONE; 17988 break; 17989 } 17990 17991 case VA_ARG_EXPR: 17992 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p); 17993 break; 17994 17995 CASE_CONVERT: 17996 if (IS_EMPTY_STMT (*expr_p)) 17997 { 17998 ret = GS_ALL_DONE; 17999 break; 18000 } 18001 18002 if (VOID_TYPE_P (TREE_TYPE (*expr_p)) 18003 || fallback == fb_none) 18004 { 18005 /* Just strip a conversion to void (or in void context) and 18006 try again. */ 18007 *expr_p = TREE_OPERAND (*expr_p, 0); 18008 ret = GS_OK; 18009 break; 18010 } 18011 18012 ret = gimplify_conversion (expr_p); 18013 if (ret == GS_ERROR) 18014 break; 18015 if (*expr_p != save_expr) 18016 break; 18017 /* FALLTHRU */ 18018 18019 case FIX_TRUNC_EXPR: 18020 /* unary_expr: ... | '(' cast ')' val | ... */ 18021 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18022 is_gimple_val, fb_rvalue); 18023 recalculate_side_effects (*expr_p); 18024 break; 18025 18026 case INDIRECT_REF: 18027 { 18028 bool volatilep = TREE_THIS_VOLATILE (*expr_p); 18029 bool notrap = TREE_THIS_NOTRAP (*expr_p); 18030 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0)); 18031 18032 *expr_p = fold_indirect_ref_loc (input_location, *expr_p); 18033 if (*expr_p != save_expr) 18034 { 18035 ret = GS_OK; 18036 break; 18037 } 18038 18039 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18040 is_gimple_reg, fb_rvalue); 18041 if (ret == GS_ERROR) 18042 break; 18043 18044 recalculate_side_effects (*expr_p); 18045 *expr_p = fold_build2_loc (input_location, MEM_REF, 18046 TREE_TYPE (*expr_p), 18047 TREE_OPERAND (*expr_p, 0), 18048 build_int_cst (saved_ptr_type, 0)); 18049 TREE_THIS_VOLATILE (*expr_p) = volatilep; 18050 TREE_THIS_NOTRAP (*expr_p) = notrap; 18051 ret = GS_OK; 18052 break; 18053 } 18054 18055 /* We arrive here through the various re-gimplifcation paths. */ 18056 case MEM_REF: 18057 /* First try re-folding the whole thing. */ 18058 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p), 18059 TREE_OPERAND (*expr_p, 0), 18060 TREE_OPERAND (*expr_p, 1)); 18061 if (tmp) 18062 { 18063 REF_REVERSE_STORAGE_ORDER (tmp) 18064 = REF_REVERSE_STORAGE_ORDER (*expr_p); 18065 *expr_p = tmp; 18066 recalculate_side_effects (*expr_p); 18067 ret = GS_OK; 18068 break; 18069 } 18070 /* Avoid re-gimplifying the address operand if it is already 18071 in suitable form. Re-gimplifying would mark the address 18072 operand addressable. Always gimplify when not in SSA form 18073 as we still may have to gimplify decls with value-exprs. */ 18074 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun) 18075 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0))) 18076 { 18077 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18078 is_gimple_mem_ref_addr, fb_rvalue); 18079 if (ret == GS_ERROR) 18080 break; 18081 } 18082 recalculate_side_effects (*expr_p); 18083 ret = GS_ALL_DONE; 18084 break; 18085 18086 /* Constants need not be gimplified. */ 18087 case INTEGER_CST: 18088 case REAL_CST: 18089 case FIXED_CST: 18090 case STRING_CST: 18091 case COMPLEX_CST: 18092 case VECTOR_CST: 18093 /* Drop the overflow flag on constants, we do not want 18094 that in the GIMPLE IL. */ 18095 if (TREE_OVERFLOW_P (*expr_p)) 18096 *expr_p = drop_tree_overflow (*expr_p); 18097 ret = GS_ALL_DONE; 18098 break; 18099 18100 case CONST_DECL: 18101 /* If we require an lvalue, such as for ADDR_EXPR, retain the 18102 CONST_DECL node. Otherwise the decl is replaceable by its 18103 value. */ 18104 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */ 18105 if (fallback & fb_lvalue) 18106 ret = GS_ALL_DONE; 18107 else 18108 { 18109 *expr_p = DECL_INITIAL (*expr_p); 18110 ret = GS_OK; 18111 } 18112 break; 18113 18114 case DECL_EXPR: 18115 ret = gimplify_decl_expr (expr_p, pre_p); 18116 break; 18117 18118 case BIND_EXPR: 18119 ret = gimplify_bind_expr (expr_p, pre_p); 18120 break; 18121 18122 case LOOP_EXPR: 18123 ret = gimplify_loop_expr (expr_p, pre_p); 18124 break; 18125 18126 case SWITCH_EXPR: 18127 ret = gimplify_switch_expr (expr_p, pre_p); 18128 break; 18129 18130 case EXIT_EXPR: 18131 ret = gimplify_exit_expr (expr_p); 18132 break; 18133 18134 case GOTO_EXPR: 18135 /* If the target is not LABEL, then it is a computed jump 18136 and the target needs to be gimplified. */ 18137 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL) 18138 { 18139 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p, 18140 NULL, is_gimple_val, fb_rvalue); 18141 if (ret == GS_ERROR) 18142 break; 18143 } 18144 gimplify_seq_add_stmt (pre_p, 18145 gimple_build_goto (GOTO_DESTINATION (*expr_p))); 18146 ret = GS_ALL_DONE; 18147 break; 18148 18149 case PREDICT_EXPR: 18150 gimplify_seq_add_stmt (pre_p, 18151 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p), 18152 PREDICT_EXPR_OUTCOME (*expr_p))); 18153 ret = GS_ALL_DONE; 18154 break; 18155 18156 case LABEL_EXPR: 18157 ret = gimplify_label_expr (expr_p, pre_p); 18158 label = LABEL_EXPR_LABEL (*expr_p); 18159 gcc_assert (decl_function_context (label) == current_function_decl); 18160 18161 /* If the label is used in a goto statement, or address of the label 18162 is taken, we need to unpoison all variables that were seen so far. 18163 Doing so would prevent us from reporting a false positives. */ 18164 if (asan_poisoned_variables 18165 && asan_used_labels != NULL 18166 && asan_used_labels->contains (label) 18167 && !gimplify_omp_ctxp) 18168 asan_poison_variables (asan_poisoned_variables, false, pre_p); 18169 break; 18170 18171 case CASE_LABEL_EXPR: 18172 ret = gimplify_case_label_expr (expr_p, pre_p); 18173 18174 if (gimplify_ctxp->live_switch_vars) 18175 asan_poison_variables (gimplify_ctxp->live_switch_vars, false, 18176 pre_p); 18177 break; 18178 18179 case RETURN_EXPR: 18180 ret = gimplify_return_expr (*expr_p, pre_p); 18181 break; 18182 18183 case CONSTRUCTOR: 18184 /* Don't reduce this in place; let gimplify_init_constructor work its 18185 magic. Buf if we're just elaborating this for side effects, just 18186 gimplify any element that has side-effects. */ 18187 if (fallback == fb_none) 18188 { 18189 unsigned HOST_WIDE_INT ix; 18190 tree val; 18191 tree temp = NULL_TREE; 18192 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val) 18193 if (TREE_SIDE_EFFECTS (val)) 18194 append_to_statement_list (val, &temp); 18195 18196 *expr_p = temp; 18197 ret = temp ? GS_OK : GS_ALL_DONE; 18198 } 18199 /* C99 code may assign to an array in a constructed 18200 structure or union, and this has undefined behavior only 18201 on execution, so create a temporary if an lvalue is 18202 required. */ 18203 else if (fallback == fb_lvalue) 18204 { 18205 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 18206 mark_addressable (*expr_p); 18207 ret = GS_OK; 18208 } 18209 else 18210 ret = GS_ALL_DONE; 18211 break; 18212 18213 /* The following are special cases that are not handled by the 18214 original GIMPLE grammar. */ 18215 18216 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and 18217 eliminated. */ 18218 case SAVE_EXPR: 18219 ret = gimplify_save_expr (expr_p, pre_p, post_p); 18220 break; 18221 18222 case BIT_FIELD_REF: 18223 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18224 post_p, is_gimple_lvalue, fb_either); 18225 recalculate_side_effects (*expr_p); 18226 break; 18227 18228 case TARGET_MEM_REF: 18229 { 18230 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE; 18231 18232 if (TMR_BASE (*expr_p)) 18233 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p, 18234 post_p, is_gimple_mem_ref_addr, fb_either); 18235 if (TMR_INDEX (*expr_p)) 18236 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p, 18237 post_p, is_gimple_val, fb_rvalue); 18238 if (TMR_INDEX2 (*expr_p)) 18239 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p, 18240 post_p, is_gimple_val, fb_rvalue); 18241 /* TMR_STEP and TMR_OFFSET are always integer constants. */ 18242 ret = MIN (r0, r1); 18243 } 18244 break; 18245 18246 case NON_LVALUE_EXPR: 18247 /* This should have been stripped above. */ 18248 gcc_unreachable (); 18249 18250 case ASM_EXPR: 18251 ret = gimplify_asm_expr (expr_p, pre_p, post_p); 18252 break; 18253 18254 case TRY_FINALLY_EXPR: 18255 case TRY_CATCH_EXPR: 18256 { 18257 gimple_seq eval, cleanup; 18258 gtry *try_; 18259 18260 /* Calls to destructors are generated automatically in FINALLY/CATCH 18261 block. They should have location as UNKNOWN_LOCATION. However, 18262 gimplify_call_expr will reset these call stmts to input_location 18263 if it finds stmt's location is unknown. To prevent resetting for 18264 destructors, we set the input_location to unknown. 18265 Note that this only affects the destructor calls in FINALLY/CATCH 18266 block, and will automatically reset to its original value by the 18267 end of gimplify_expr. */ 18268 input_location = UNKNOWN_LOCATION; 18269 eval = cleanup = NULL; 18270 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval); 18271 bool save_in_handler_expr = gimplify_ctxp->in_handler_expr; 18272 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR 18273 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR) 18274 { 18275 gimple_seq n = NULL, e = NULL; 18276 gimplify_ctxp->in_handler_expr = true; 18277 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1), 18278 0), &n); 18279 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1), 18280 1), &e); 18281 if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e)) 18282 { 18283 geh_else *stmt = gimple_build_eh_else (n, e); 18284 gimple_seq_add_stmt (&cleanup, stmt); 18285 } 18286 } 18287 else 18288 { 18289 gimplify_ctxp->in_handler_expr = true; 18290 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup); 18291 } 18292 gimplify_ctxp->in_handler_expr = save_in_handler_expr; 18293 /* Don't create bogus GIMPLE_TRY with empty cleanup. */ 18294 if (gimple_seq_empty_p (cleanup)) 18295 { 18296 gimple_seq_add_seq (pre_p, eval); 18297 ret = GS_ALL_DONE; 18298 break; 18299 } 18300 try_ = gimple_build_try (eval, cleanup, 18301 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR 18302 ? GIMPLE_TRY_FINALLY 18303 : GIMPLE_TRY_CATCH); 18304 if (EXPR_HAS_LOCATION (save_expr)) 18305 gimple_set_location (try_, EXPR_LOCATION (save_expr)); 18306 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION) 18307 gimple_set_location (try_, saved_location); 18308 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR) 18309 gimple_try_set_catch_is_cleanup (try_, 18310 TRY_CATCH_IS_CLEANUP (*expr_p)); 18311 gimplify_seq_add_stmt (pre_p, try_); 18312 ret = GS_ALL_DONE; 18313 break; 18314 } 18315 18316 case CLEANUP_POINT_EXPR: 18317 ret = gimplify_cleanup_point_expr (expr_p, pre_p); 18318 break; 18319 18320 case TARGET_EXPR: 18321 ret = gimplify_target_expr (expr_p, pre_p, post_p); 18322 break; 18323 18324 case CATCH_EXPR: 18325 { 18326 gimple *c; 18327 gimple_seq handler = NULL; 18328 gimplify_and_add (CATCH_BODY (*expr_p), &handler); 18329 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler); 18330 gimplify_seq_add_stmt (pre_p, c); 18331 ret = GS_ALL_DONE; 18332 break; 18333 } 18334 18335 case EH_FILTER_EXPR: 18336 { 18337 gimple *ehf; 18338 gimple_seq failure = NULL; 18339 18340 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure); 18341 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure); 18342 copy_warning (ehf, *expr_p); 18343 gimplify_seq_add_stmt (pre_p, ehf); 18344 ret = GS_ALL_DONE; 18345 break; 18346 } 18347 18348 case OBJ_TYPE_REF: 18349 { 18350 enum gimplify_status r0, r1; 18351 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, 18352 post_p, is_gimple_val, fb_rvalue); 18353 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, 18354 post_p, is_gimple_val, fb_rvalue); 18355 TREE_SIDE_EFFECTS (*expr_p) = 0; 18356 ret = MIN (r0, r1); 18357 } 18358 break; 18359 18360 case LABEL_DECL: 18361 /* We get here when taking the address of a label. We mark 18362 the label as "forced"; meaning it can never be removed and 18363 it is a potential target for any computed goto. */ 18364 FORCED_LABEL (*expr_p) = 1; 18365 ret = GS_ALL_DONE; 18366 break; 18367 18368 case STATEMENT_LIST: 18369 ret = gimplify_statement_list (expr_p, pre_p); 18370 break; 18371 18372 case WITH_SIZE_EXPR: 18373 { 18374 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18375 post_p == &internal_post ? NULL : post_p, 18376 gimple_test_f, fallback); 18377 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 18378 is_gimple_val, fb_rvalue); 18379 ret = GS_ALL_DONE; 18380 } 18381 break; 18382 18383 case VAR_DECL: 18384 case PARM_DECL: 18385 ret = gimplify_var_or_parm_decl (expr_p); 18386 break; 18387 18388 case RESULT_DECL: 18389 /* When within an OMP context, notice uses of variables. */ 18390 if (gimplify_omp_ctxp) 18391 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true); 18392 /* Handlers can refer to the function result; if that has been 18393 moved, we need to track it. */ 18394 if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp) 18395 *expr_p = gimplify_ctxp->return_temp; 18396 ret = GS_ALL_DONE; 18397 break; 18398 18399 case DEBUG_EXPR_DECL: 18400 gcc_unreachable (); 18401 18402 case DEBUG_BEGIN_STMT: 18403 gimplify_seq_add_stmt (pre_p, 18404 gimple_build_debug_begin_stmt 18405 (TREE_BLOCK (*expr_p), 18406 EXPR_LOCATION (*expr_p))); 18407 ret = GS_ALL_DONE; 18408 *expr_p = NULL; 18409 break; 18410 18411 case SSA_NAME: 18412 /* Allow callbacks into the gimplifier during optimization. */ 18413 ret = GS_ALL_DONE; 18414 break; 18415 18416 case OMP_PARALLEL: 18417 gimplify_omp_parallel (expr_p, pre_p); 18418 ret = GS_ALL_DONE; 18419 break; 18420 18421 case OMP_TASK: 18422 gimplify_omp_task (expr_p, pre_p); 18423 ret = GS_ALL_DONE; 18424 break; 18425 18426 case OMP_SIMD: 18427 { 18428 /* Temporarily disable into_ssa, as scan_omp_simd 18429 which calls copy_gimple_seq_and_replace_locals can't deal 18430 with SSA_NAMEs defined outside of the body properly. */ 18431 bool saved_into_ssa = gimplify_ctxp->into_ssa; 18432 gimplify_ctxp->into_ssa = false; 18433 ret = gimplify_omp_for (expr_p, pre_p); 18434 gimplify_ctxp->into_ssa = saved_into_ssa; 18435 break; 18436 } 18437 18438 case OMP_FOR: 18439 case OMP_DISTRIBUTE: 18440 case OMP_TASKLOOP: 18441 case OACC_LOOP: 18442 ret = gimplify_omp_for (expr_p, pre_p); 18443 break; 18444 18445 case OMP_LOOP: 18446 ret = gimplify_omp_loop (expr_p, pre_p); 18447 break; 18448 18449 case OACC_CACHE: 18450 gimplify_oacc_cache (expr_p, pre_p); 18451 ret = GS_ALL_DONE; 18452 break; 18453 18454 case OACC_DECLARE: 18455 gimplify_oacc_declare (expr_p, pre_p); 18456 ret = GS_ALL_DONE; 18457 break; 18458 18459 case OACC_HOST_DATA: 18460 case OACC_DATA: 18461 case OACC_KERNELS: 18462 case OACC_PARALLEL: 18463 case OACC_SERIAL: 18464 case OMP_SCOPE: 18465 case OMP_SECTIONS: 18466 case OMP_SINGLE: 18467 case OMP_TARGET: 18468 case OMP_TARGET_DATA: 18469 case OMP_TEAMS: 18470 gimplify_omp_workshare (expr_p, pre_p); 18471 ret = GS_ALL_DONE; 18472 break; 18473 18474 case OACC_ENTER_DATA: 18475 case OACC_EXIT_DATA: 18476 case OACC_UPDATE: 18477 case OMP_TARGET_UPDATE: 18478 case OMP_TARGET_ENTER_DATA: 18479 case OMP_TARGET_EXIT_DATA: 18480 gimplify_omp_target_update (expr_p, pre_p); 18481 ret = GS_ALL_DONE; 18482 break; 18483 18484 case OMP_SECTION: 18485 case OMP_STRUCTURED_BLOCK: 18486 case OMP_MASTER: 18487 case OMP_MASKED: 18488 case OMP_ORDERED: 18489 case OMP_CRITICAL: 18490 case OMP_SCAN: 18491 { 18492 gimple_seq body = NULL; 18493 gimple *g; 18494 bool saved_in_omp_construct = in_omp_construct; 18495 18496 in_omp_construct = true; 18497 gimplify_and_add (OMP_BODY (*expr_p), &body); 18498 in_omp_construct = saved_in_omp_construct; 18499 switch (TREE_CODE (*expr_p)) 18500 { 18501 case OMP_SECTION: 18502 g = gimple_build_omp_section (body); 18503 break; 18504 case OMP_STRUCTURED_BLOCK: 18505 g = gimple_build_omp_structured_block (body); 18506 break; 18507 case OMP_MASTER: 18508 g = gimple_build_omp_master (body); 18509 break; 18510 case OMP_ORDERED: 18511 g = gimplify_omp_ordered (*expr_p, body); 18512 if (OMP_BODY (*expr_p) == NULL_TREE 18513 && gimple_code (g) == GIMPLE_OMP_ORDERED) 18514 gimple_omp_ordered_standalone (g); 18515 break; 18516 case OMP_MASKED: 18517 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p), 18518 pre_p, ORT_WORKSHARE, OMP_MASKED); 18519 gimplify_adjust_omp_clauses (pre_p, body, 18520 &OMP_MASKED_CLAUSES (*expr_p), 18521 OMP_MASKED); 18522 g = gimple_build_omp_masked (body, 18523 OMP_MASKED_CLAUSES (*expr_p)); 18524 break; 18525 case OMP_CRITICAL: 18526 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p), 18527 pre_p, ORT_WORKSHARE, OMP_CRITICAL); 18528 gimplify_adjust_omp_clauses (pre_p, body, 18529 &OMP_CRITICAL_CLAUSES (*expr_p), 18530 OMP_CRITICAL); 18531 g = gimple_build_omp_critical (body, 18532 OMP_CRITICAL_NAME (*expr_p), 18533 OMP_CRITICAL_CLAUSES (*expr_p)); 18534 break; 18535 case OMP_SCAN: 18536 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p), 18537 pre_p, ORT_WORKSHARE, OMP_SCAN); 18538 gimplify_adjust_omp_clauses (pre_p, body, 18539 &OMP_SCAN_CLAUSES (*expr_p), 18540 OMP_SCAN); 18541 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p)); 18542 break; 18543 default: 18544 gcc_unreachable (); 18545 } 18546 gimplify_seq_add_stmt (pre_p, g); 18547 ret = GS_ALL_DONE; 18548 break; 18549 } 18550 18551 case OMP_TASKGROUP: 18552 { 18553 gimple_seq body = NULL; 18554 18555 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p); 18556 bool saved_in_omp_construct = in_omp_construct; 18557 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP, 18558 OMP_TASKGROUP); 18559 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP); 18560 18561 in_omp_construct = true; 18562 gimplify_and_add (OMP_BODY (*expr_p), &body); 18563 in_omp_construct = saved_in_omp_construct; 18564 gimple_seq cleanup = NULL; 18565 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END); 18566 gimple *g = gimple_build_call (fn, 0); 18567 gimple_seq_add_stmt (&cleanup, g); 18568 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY); 18569 body = NULL; 18570 gimple_seq_add_stmt (&body, g); 18571 g = gimple_build_omp_taskgroup (body, *pclauses); 18572 gimplify_seq_add_stmt (pre_p, g); 18573 ret = GS_ALL_DONE; 18574 break; 18575 } 18576 18577 case OMP_ATOMIC: 18578 case OMP_ATOMIC_READ: 18579 case OMP_ATOMIC_CAPTURE_OLD: 18580 case OMP_ATOMIC_CAPTURE_NEW: 18581 ret = gimplify_omp_atomic (expr_p, pre_p); 18582 break; 18583 18584 case TRANSACTION_EXPR: 18585 ret = gimplify_transaction (expr_p, pre_p); 18586 break; 18587 18588 case TRUTH_AND_EXPR: 18589 case TRUTH_OR_EXPR: 18590 case TRUTH_XOR_EXPR: 18591 { 18592 tree orig_type = TREE_TYPE (*expr_p); 18593 tree new_type, xop0, xop1; 18594 *expr_p = gimple_boolify (*expr_p); 18595 new_type = TREE_TYPE (*expr_p); 18596 if (!useless_type_conversion_p (orig_type, new_type)) 18597 { 18598 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p); 18599 ret = GS_OK; 18600 break; 18601 } 18602 18603 /* Boolified binary truth expressions are semantically equivalent 18604 to bitwise binary expressions. Canonicalize them to the 18605 bitwise variant. */ 18606 switch (TREE_CODE (*expr_p)) 18607 { 18608 case TRUTH_AND_EXPR: 18609 TREE_SET_CODE (*expr_p, BIT_AND_EXPR); 18610 break; 18611 case TRUTH_OR_EXPR: 18612 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR); 18613 break; 18614 case TRUTH_XOR_EXPR: 18615 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR); 18616 break; 18617 default: 18618 break; 18619 } 18620 /* Now make sure that operands have compatible type to 18621 expression's new_type. */ 18622 xop0 = TREE_OPERAND (*expr_p, 0); 18623 xop1 = TREE_OPERAND (*expr_p, 1); 18624 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0))) 18625 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location, 18626 new_type, 18627 xop0); 18628 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1))) 18629 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location, 18630 new_type, 18631 xop1); 18632 /* Continue classified as tcc_binary. */ 18633 goto expr_2; 18634 } 18635 18636 case VEC_COND_EXPR: 18637 goto expr_3; 18638 18639 case VEC_PERM_EXPR: 18640 /* Classified as tcc_expression. */ 18641 goto expr_3; 18642 18643 case BIT_INSERT_EXPR: 18644 /* Argument 3 is a constant. */ 18645 goto expr_2; 18646 18647 case POINTER_PLUS_EXPR: 18648 { 18649 enum gimplify_status r0, r1; 18650 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18651 post_p, is_gimple_val, fb_rvalue); 18652 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18653 post_p, is_gimple_val, fb_rvalue); 18654 recalculate_side_effects (*expr_p); 18655 ret = MIN (r0, r1); 18656 break; 18657 } 18658 18659 default: 18660 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p))) 18661 { 18662 case tcc_comparison: 18663 /* Handle comparison of objects of non scalar mode aggregates 18664 with a call to memcmp. It would be nice to only have to do 18665 this for variable-sized objects, but then we'd have to allow 18666 the same nest of reference nodes we allow for MODIFY_EXPR and 18667 that's too complex. 18668 18669 Compare scalar mode aggregates as scalar mode values. Using 18670 memcmp for them would be very inefficient at best, and is 18671 plain wrong if bitfields are involved. */ 18672 if (error_operand_p (TREE_OPERAND (*expr_p, 1))) 18673 ret = GS_ERROR; 18674 else 18675 { 18676 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); 18677 18678 /* Vector comparisons need no boolification. */ 18679 if (TREE_CODE (type) == VECTOR_TYPE) 18680 goto expr_2; 18681 else if (!AGGREGATE_TYPE_P (type)) 18682 { 18683 tree org_type = TREE_TYPE (*expr_p); 18684 *expr_p = gimple_boolify (*expr_p); 18685 if (!useless_type_conversion_p (org_type, 18686 TREE_TYPE (*expr_p))) 18687 { 18688 *expr_p = fold_convert_loc (input_location, 18689 org_type, *expr_p); 18690 ret = GS_OK; 18691 } 18692 else 18693 goto expr_2; 18694 } 18695 else if (TYPE_MODE (type) != BLKmode) 18696 ret = gimplify_scalar_mode_aggregate_compare (expr_p); 18697 else 18698 ret = gimplify_variable_sized_compare (expr_p); 18699 } 18700 break; 18701 18702 /* If *EXPR_P does not need to be special-cased, handle it 18703 according to its class. */ 18704 case tcc_unary: 18705 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18706 post_p, is_gimple_val, fb_rvalue); 18707 break; 18708 18709 case tcc_binary: 18710 expr_2: 18711 { 18712 enum gimplify_status r0, r1; 18713 18714 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18715 post_p, is_gimple_val, fb_rvalue); 18716 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18717 post_p, is_gimple_val, fb_rvalue); 18718 18719 ret = MIN (r0, r1); 18720 break; 18721 } 18722 18723 expr_3: 18724 { 18725 enum gimplify_status r0, r1, r2; 18726 18727 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18728 post_p, is_gimple_val, fb_rvalue); 18729 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18730 post_p, is_gimple_val, fb_rvalue); 18731 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, 18732 post_p, is_gimple_val, fb_rvalue); 18733 18734 ret = MIN (MIN (r0, r1), r2); 18735 break; 18736 } 18737 18738 case tcc_declaration: 18739 case tcc_constant: 18740 ret = GS_ALL_DONE; 18741 goto dont_recalculate; 18742 18743 default: 18744 gcc_unreachable (); 18745 } 18746 18747 recalculate_side_effects (*expr_p); 18748 18749 dont_recalculate: 18750 break; 18751 } 18752 18753 gcc_assert (*expr_p || ret != GS_OK); 18754 } 18755 while (ret == GS_OK); 18756 18757 /* If we encountered an error_mark somewhere nested inside, either 18758 stub out the statement or propagate the error back out. */ 18759 if (ret == GS_ERROR) 18760 { 18761 if (is_statement) 18762 *expr_p = NULL; 18763 goto out; 18764 } 18765 18766 /* This was only valid as a return value from the langhook, which 18767 we handled. Make sure it doesn't escape from any other context. */ 18768 gcc_assert (ret != GS_UNHANDLED); 18769 18770 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p)) 18771 { 18772 /* We aren't looking for a value, and we don't have a valid 18773 statement. If it doesn't have side-effects, throw it away. 18774 We can also get here with code such as "*&&L;", where L is 18775 a LABEL_DECL that is marked as FORCED_LABEL. */ 18776 if (TREE_CODE (*expr_p) == LABEL_DECL 18777 || !TREE_SIDE_EFFECTS (*expr_p)) 18778 *expr_p = NULL; 18779 else if (!TREE_THIS_VOLATILE (*expr_p)) 18780 { 18781 /* This is probably a _REF that contains something nested that 18782 has side effects. Recurse through the operands to find it. */ 18783 enum tree_code code = TREE_CODE (*expr_p); 18784 18785 switch (code) 18786 { 18787 case COMPONENT_REF: 18788 case REALPART_EXPR: 18789 case IMAGPART_EXPR: 18790 case VIEW_CONVERT_EXPR: 18791 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18792 gimple_test_f, fallback); 18793 break; 18794 18795 case ARRAY_REF: 18796 case ARRAY_RANGE_REF: 18797 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18798 gimple_test_f, fallback); 18799 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 18800 gimple_test_f, fallback); 18801 break; 18802 18803 default: 18804 /* Anything else with side-effects must be converted to 18805 a valid statement before we get here. */ 18806 gcc_unreachable (); 18807 } 18808 18809 *expr_p = NULL; 18810 } 18811 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)) 18812 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode 18813 && !is_empty_type (TREE_TYPE (*expr_p))) 18814 { 18815 /* Historically, the compiler has treated a bare reference 18816 to a non-BLKmode volatile lvalue as forcing a load. */ 18817 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p)); 18818 18819 /* Normally, we do not want to create a temporary for a 18820 TREE_ADDRESSABLE type because such a type should not be 18821 copied by bitwise-assignment. However, we make an 18822 exception here, as all we are doing here is ensuring that 18823 we read the bytes that make up the type. We use 18824 create_tmp_var_raw because create_tmp_var will abort when 18825 given a TREE_ADDRESSABLE type. */ 18826 tree tmp = create_tmp_var_raw (type, "vol"); 18827 gimple_add_tmp_var (tmp); 18828 gimplify_assign (tmp, *expr_p, pre_p); 18829 *expr_p = NULL; 18830 } 18831 else 18832 /* We can't do anything useful with a volatile reference to 18833 an incomplete type, so just throw it away. Likewise for 18834 a BLKmode type, since any implicit inner load should 18835 already have been turned into an explicit one by the 18836 gimplification process. */ 18837 *expr_p = NULL; 18838 } 18839 18840 /* If we are gimplifying at the statement level, we're done. Tack 18841 everything together and return. */ 18842 if (fallback == fb_none || is_statement) 18843 { 18844 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear 18845 it out for GC to reclaim it. */ 18846 *expr_p = NULL_TREE; 18847 18848 if (!gimple_seq_empty_p (internal_pre) 18849 || !gimple_seq_empty_p (internal_post)) 18850 { 18851 gimplify_seq_add_seq (&internal_pre, internal_post); 18852 gimplify_seq_add_seq (pre_p, internal_pre); 18853 } 18854 18855 /* The result of gimplifying *EXPR_P is going to be the last few 18856 statements in *PRE_P and *POST_P. Add location information 18857 to all the statements that were added by the gimplification 18858 helpers. */ 18859 if (!gimple_seq_empty_p (*pre_p)) 18860 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location); 18861 18862 if (!gimple_seq_empty_p (*post_p)) 18863 annotate_all_with_location_after (*post_p, post_last_gsi, 18864 input_location); 18865 18866 goto out; 18867 } 18868 18869 #ifdef ENABLE_GIMPLE_CHECKING 18870 if (*expr_p) 18871 { 18872 enum tree_code code = TREE_CODE (*expr_p); 18873 /* These expressions should already be in gimple IR form. */ 18874 gcc_assert (code != MODIFY_EXPR 18875 && code != ASM_EXPR 18876 && code != BIND_EXPR 18877 && code != CATCH_EXPR 18878 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr) 18879 && code != EH_FILTER_EXPR 18880 && code != GOTO_EXPR 18881 && code != LABEL_EXPR 18882 && code != LOOP_EXPR 18883 && code != SWITCH_EXPR 18884 && code != TRY_FINALLY_EXPR 18885 && code != EH_ELSE_EXPR 18886 && code != OACC_PARALLEL 18887 && code != OACC_KERNELS 18888 && code != OACC_SERIAL 18889 && code != OACC_DATA 18890 && code != OACC_HOST_DATA 18891 && code != OACC_DECLARE 18892 && code != OACC_UPDATE 18893 && code != OACC_ENTER_DATA 18894 && code != OACC_EXIT_DATA 18895 && code != OACC_CACHE 18896 && code != OMP_CRITICAL 18897 && code != OMP_FOR 18898 && code != OACC_LOOP 18899 && code != OMP_MASTER 18900 && code != OMP_MASKED 18901 && code != OMP_TASKGROUP 18902 && code != OMP_ORDERED 18903 && code != OMP_PARALLEL 18904 && code != OMP_SCAN 18905 && code != OMP_SECTIONS 18906 && code != OMP_SECTION 18907 && code != OMP_STRUCTURED_BLOCK 18908 && code != OMP_SINGLE 18909 && code != OMP_SCOPE); 18910 } 18911 #endif 18912 18913 /* Otherwise we're gimplifying a subexpression, so the resulting 18914 value is interesting. If it's a valid operand that matches 18915 GIMPLE_TEST_F, we're done. Unless we are handling some 18916 post-effects internally; if that's the case, we need to copy into 18917 a temporary before adding the post-effects to POST_P. */ 18918 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p)) 18919 goto out; 18920 18921 /* Otherwise, we need to create a new temporary for the gimplified 18922 expression. */ 18923 18924 /* We can't return an lvalue if we have an internal postqueue. The 18925 object the lvalue refers to would (probably) be modified by the 18926 postqueue; we need to copy the value out first, which means an 18927 rvalue. */ 18928 if ((fallback & fb_lvalue) 18929 && gimple_seq_empty_p (internal_post) 18930 && is_gimple_addressable (*expr_p)) 18931 { 18932 /* An lvalue will do. Take the address of the expression, store it 18933 in a temporary, and replace the expression with an INDIRECT_REF of 18934 that temporary. */ 18935 tree ref_alias_type = reference_alias_ptr_type (*expr_p); 18936 unsigned int ref_align = get_object_alignment (*expr_p); 18937 tree ref_type = TREE_TYPE (*expr_p); 18938 tmp = build_fold_addr_expr_loc (input_location, *expr_p); 18939 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); 18940 if (TYPE_ALIGN (ref_type) != ref_align) 18941 ref_type = build_aligned_type (ref_type, ref_align); 18942 *expr_p = build2 (MEM_REF, ref_type, 18943 tmp, build_zero_cst (ref_alias_type)); 18944 } 18945 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p)) 18946 { 18947 /* An rvalue will do. Assign the gimplified expression into a 18948 new temporary TMP and replace the original expression with 18949 TMP. First, make sure that the expression has a type so that 18950 it can be assigned into a temporary. */ 18951 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p))); 18952 *expr_p = get_formal_tmp_var (*expr_p, pre_p); 18953 } 18954 else 18955 { 18956 #ifdef ENABLE_GIMPLE_CHECKING 18957 if (!(fallback & fb_mayfail)) 18958 { 18959 fprintf (stderr, "gimplification failed:\n"); 18960 print_generic_expr (stderr, *expr_p); 18961 debug_tree (*expr_p); 18962 internal_error ("gimplification failed"); 18963 } 18964 #endif 18965 gcc_assert (fallback & fb_mayfail); 18966 18967 /* If this is an asm statement, and the user asked for the 18968 impossible, don't die. Fail and let gimplify_asm_expr 18969 issue an error. */ 18970 ret = GS_ERROR; 18971 goto out; 18972 } 18973 18974 /* Make sure the temporary matches our predicate. */ 18975 gcc_assert ((*gimple_test_f) (*expr_p)); 18976 18977 if (!gimple_seq_empty_p (internal_post)) 18978 { 18979 annotate_all_with_location (internal_post, input_location); 18980 gimplify_seq_add_seq (pre_p, internal_post); 18981 } 18982 18983 out: 18984 input_location = saved_location; 18985 return ret; 18986 } 18987 18988 /* Like gimplify_expr but make sure the gimplified result is not itself 18989 a SSA name (but a decl if it were). Temporaries required by 18990 evaluating *EXPR_P may be still SSA names. */ 18991 18992 static enum gimplify_status 18993 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 18994 bool (*gimple_test_f) (tree), fallback_t fallback, 18995 bool allow_ssa) 18996 { 18997 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p, 18998 gimple_test_f, fallback); 18999 if (! allow_ssa 19000 && TREE_CODE (*expr_p) == SSA_NAME) 19001 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false); 19002 return ret; 19003 } 19004 19005 /* Look through TYPE for variable-sized objects and gimplify each such 19006 size that we find. Add to LIST_P any statements generated. */ 19007 19008 void 19009 gimplify_type_sizes (tree type, gimple_seq *list_p) 19010 { 19011 if (type == NULL || type == error_mark_node) 19012 return; 19013 19014 const bool ignored_p 19015 = TYPE_NAME (type) 19016 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 19017 && DECL_IGNORED_P (TYPE_NAME (type)); 19018 tree t; 19019 19020 /* We first do the main variant, then copy into any other variants. */ 19021 type = TYPE_MAIN_VARIANT (type); 19022 19023 /* Avoid infinite recursion. */ 19024 if (TYPE_SIZES_GIMPLIFIED (type)) 19025 return; 19026 19027 TYPE_SIZES_GIMPLIFIED (type) = 1; 19028 19029 switch (TREE_CODE (type)) 19030 { 19031 case INTEGER_TYPE: 19032 case ENUMERAL_TYPE: 19033 case BOOLEAN_TYPE: 19034 case REAL_TYPE: 19035 case FIXED_POINT_TYPE: 19036 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p); 19037 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p); 19038 19039 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 19040 { 19041 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); 19042 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); 19043 } 19044 break; 19045 19046 case ARRAY_TYPE: 19047 /* These types may not have declarations, so handle them here. */ 19048 gimplify_type_sizes (TREE_TYPE (type), list_p); 19049 gimplify_type_sizes (TYPE_DOMAIN (type), list_p); 19050 /* Ensure VLA bounds aren't removed, for -O0 they should be variables 19051 with assigned stack slots, for -O1+ -g they should be tracked 19052 by VTA. */ 19053 if (!ignored_p 19054 && TYPE_DOMAIN (type) 19055 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type))) 19056 { 19057 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); 19058 if (t && VAR_P (t) && DECL_ARTIFICIAL (t)) 19059 DECL_IGNORED_P (t) = 0; 19060 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 19061 if (t && VAR_P (t) && DECL_ARTIFICIAL (t)) 19062 DECL_IGNORED_P (t) = 0; 19063 } 19064 break; 19065 19066 case RECORD_TYPE: 19067 case UNION_TYPE: 19068 case QUAL_UNION_TYPE: 19069 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 19070 if (TREE_CODE (field) == FIELD_DECL) 19071 { 19072 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); 19073 /* Likewise, ensure variable offsets aren't removed. */ 19074 if (!ignored_p 19075 && (t = DECL_FIELD_OFFSET (field)) 19076 && VAR_P (t) 19077 && DECL_ARTIFICIAL (t)) 19078 DECL_IGNORED_P (t) = 0; 19079 gimplify_one_sizepos (&DECL_SIZE (field), list_p); 19080 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p); 19081 gimplify_type_sizes (TREE_TYPE (field), list_p); 19082 } 19083 break; 19084 19085 case POINTER_TYPE: 19086 case REFERENCE_TYPE: 19087 /* We used to recurse on the pointed-to type here, which turned out to 19088 be incorrect because its definition might refer to variables not 19089 yet initialized at this point if a forward declaration is involved. 19090 19091 It was actually useful for anonymous pointed-to types to ensure 19092 that the sizes evaluation dominates every possible later use of the 19093 values. Restricting to such types here would be safe since there 19094 is no possible forward declaration around, but would introduce an 19095 undesirable middle-end semantic to anonymity. We then defer to 19096 front-ends the responsibility of ensuring that the sizes are 19097 evaluated both early and late enough, e.g. by attaching artificial 19098 type declarations to the tree. */ 19099 break; 19100 19101 default: 19102 break; 19103 } 19104 19105 gimplify_one_sizepos (&TYPE_SIZE (type), list_p); 19106 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p); 19107 19108 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 19109 { 19110 TYPE_SIZE (t) = TYPE_SIZE (type); 19111 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type); 19112 TYPE_SIZES_GIMPLIFIED (t) = 1; 19113 } 19114 } 19115 19116 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P, 19117 a size or position, has had all of its SAVE_EXPRs evaluated. 19118 We add any required statements to *STMT_P. */ 19119 19120 void 19121 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p) 19122 { 19123 tree expr = *expr_p; 19124 19125 /* We don't do anything if the value isn't there, is constant, or contains 19126 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already 19127 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier 19128 will want to replace it with a new variable, but that will cause problems 19129 if this type is from outside the function. It's OK to have that here. */ 19130 if (expr == NULL_TREE 19131 || is_gimple_constant (expr) 19132 || VAR_P (expr) 19133 || CONTAINS_PLACEHOLDER_P (expr)) 19134 return; 19135 19136 *expr_p = unshare_expr (expr); 19137 19138 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed 19139 if the def vanishes. */ 19140 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false); 19141 19142 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the 19143 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls 19144 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */ 19145 if (is_gimple_constant (*expr_p)) 19146 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false); 19147 } 19148 19149 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node 19150 containing the sequence of corresponding GIMPLE statements. If DO_PARMS 19151 is true, also gimplify the parameters. */ 19152 19153 gbind * 19154 gimplify_body (tree fndecl, bool do_parms) 19155 { 19156 location_t saved_location = input_location; 19157 gimple_seq parm_stmts, parm_cleanup = NULL, seq; 19158 gimple *outer_stmt; 19159 gbind *outer_bind; 19160 19161 timevar_push (TV_TREE_GIMPLIFY); 19162 19163 init_tree_ssa (cfun); 19164 19165 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during 19166 gimplification. */ 19167 default_rtl_profile (); 19168 19169 gcc_assert (gimplify_ctxp == NULL); 19170 push_gimplify_context (true); 19171 19172 if (flag_openacc || flag_openmp) 19173 { 19174 gcc_assert (gimplify_omp_ctxp == NULL); 19175 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl))) 19176 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET); 19177 } 19178 19179 /* Unshare most shared trees in the body and in that of any nested functions. 19180 It would seem we don't have to do this for nested functions because 19181 they are supposed to be output and then the outer function gimplified 19182 first, but the g++ front end doesn't always do it that way. */ 19183 unshare_body (fndecl); 19184 unvisit_body (fndecl); 19185 19186 /* Make sure input_location isn't set to something weird. */ 19187 input_location = DECL_SOURCE_LOCATION (fndecl); 19188 19189 /* Resolve callee-copies. This has to be done before processing 19190 the body so that DECL_VALUE_EXPR gets processed correctly. */ 19191 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL; 19192 19193 /* Gimplify the function's body. */ 19194 seq = NULL; 19195 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq); 19196 outer_stmt = gimple_seq_first_nondebug_stmt (seq); 19197 if (!outer_stmt) 19198 { 19199 outer_stmt = gimple_build_nop (); 19200 gimplify_seq_add_stmt (&seq, outer_stmt); 19201 } 19202 19203 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is 19204 not the case, wrap everything in a GIMPLE_BIND to make it so. */ 19205 if (gimple_code (outer_stmt) == GIMPLE_BIND 19206 && (gimple_seq_first_nondebug_stmt (seq) 19207 == gimple_seq_last_nondebug_stmt (seq))) 19208 { 19209 outer_bind = as_a <gbind *> (outer_stmt); 19210 if (gimple_seq_first_stmt (seq) != outer_stmt 19211 || gimple_seq_last_stmt (seq) != outer_stmt) 19212 { 19213 /* If there are debug stmts before or after outer_stmt, move them 19214 inside of outer_bind body. */ 19215 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq); 19216 gimple_seq second_seq = NULL; 19217 if (gimple_seq_first_stmt (seq) != outer_stmt 19218 && gimple_seq_last_stmt (seq) != outer_stmt) 19219 { 19220 second_seq = gsi_split_seq_after (gsi); 19221 gsi_remove (&gsi, false); 19222 } 19223 else if (gimple_seq_first_stmt (seq) != outer_stmt) 19224 gsi_remove (&gsi, false); 19225 else 19226 { 19227 gsi_remove (&gsi, false); 19228 second_seq = seq; 19229 seq = NULL; 19230 } 19231 gimple_seq_add_seq_without_update (&seq, 19232 gimple_bind_body (outer_bind)); 19233 gimple_seq_add_seq_without_update (&seq, second_seq); 19234 gimple_bind_set_body (outer_bind, seq); 19235 } 19236 } 19237 else 19238 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL); 19239 19240 DECL_SAVED_TREE (fndecl) = NULL_TREE; 19241 19242 /* If we had callee-copies statements, insert them at the beginning 19243 of the function and clear DECL_VALUE_EXPR_P on the parameters. */ 19244 if (!gimple_seq_empty_p (parm_stmts)) 19245 { 19246 tree parm; 19247 19248 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind)); 19249 if (parm_cleanup) 19250 { 19251 gtry *g = gimple_build_try (parm_stmts, parm_cleanup, 19252 GIMPLE_TRY_FINALLY); 19253 parm_stmts = NULL; 19254 gimple_seq_add_stmt (&parm_stmts, g); 19255 } 19256 gimple_bind_set_body (outer_bind, parm_stmts); 19257 19258 for (parm = DECL_ARGUMENTS (current_function_decl); 19259 parm; parm = DECL_CHAIN (parm)) 19260 if (DECL_HAS_VALUE_EXPR_P (parm)) 19261 { 19262 DECL_HAS_VALUE_EXPR_P (parm) = 0; 19263 DECL_IGNORED_P (parm) = 0; 19264 } 19265 } 19266 19267 if ((flag_openacc || flag_openmp || flag_openmp_simd) 19268 && gimplify_omp_ctxp) 19269 { 19270 delete_omp_context (gimplify_omp_ctxp); 19271 gimplify_omp_ctxp = NULL; 19272 } 19273 19274 pop_gimplify_context (outer_bind); 19275 gcc_assert (gimplify_ctxp == NULL); 19276 19277 if (flag_checking && !seen_error ()) 19278 verify_gimple_in_seq (gimple_bind_body (outer_bind)); 19279 19280 timevar_pop (TV_TREE_GIMPLIFY); 19281 input_location = saved_location; 19282 19283 return outer_bind; 19284 } 19285 19286 typedef char *char_p; /* For DEF_VEC_P. */ 19287 19288 /* Return whether we should exclude FNDECL from instrumentation. */ 19289 19290 static bool 19291 flag_instrument_functions_exclude_p (tree fndecl) 19292 { 19293 vec<char_p> *v; 19294 19295 v = (vec<char_p> *) flag_instrument_functions_exclude_functions; 19296 if (v && v->length () > 0) 19297 { 19298 const char *name; 19299 int i; 19300 char *s; 19301 19302 name = lang_hooks.decl_printable_name (fndecl, 1); 19303 FOR_EACH_VEC_ELT (*v, i, s) 19304 if (strstr (name, s) != NULL) 19305 return true; 19306 } 19307 19308 v = (vec<char_p> *) flag_instrument_functions_exclude_files; 19309 if (v && v->length () > 0) 19310 { 19311 const char *name; 19312 int i; 19313 char *s; 19314 19315 name = DECL_SOURCE_FILE (fndecl); 19316 FOR_EACH_VEC_ELT (*v, i, s) 19317 if (strstr (name, s) != NULL) 19318 return true; 19319 } 19320 19321 return false; 19322 } 19323 19324 /* Build a call to the instrumentation function FNCODE and add it to SEQ. 19325 If COND_VAR is not NULL, it is a boolean variable guarding the call to 19326 the instrumentation function. IF STMT is not NULL, it is a statement 19327 to be executed just before the call to the instrumentation function. */ 19328 19329 static void 19330 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode, 19331 tree cond_var, gimple *stmt) 19332 { 19333 /* The instrumentation hooks aren't going to call the instrumented 19334 function and the address they receive is expected to be matchable 19335 against symbol addresses. Make sure we don't create a trampoline, 19336 in case the current function is nested. */ 19337 tree this_fn_addr = build_fold_addr_expr (current_function_decl); 19338 TREE_NO_TRAMPOLINE (this_fn_addr) = 1; 19339 19340 tree label_true, label_false; 19341 if (cond_var) 19342 { 19343 label_true = create_artificial_label (UNKNOWN_LOCATION); 19344 label_false = create_artificial_label (UNKNOWN_LOCATION); 19345 gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node, 19346 label_true, label_false); 19347 gimplify_seq_add_stmt (seq, cond); 19348 gimplify_seq_add_stmt (seq, gimple_build_label (label_true)); 19349 gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL, 19350 NOT_TAKEN)); 19351 } 19352 19353 if (stmt) 19354 gimplify_seq_add_stmt (seq, stmt); 19355 19356 tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); 19357 gcall *call = gimple_build_call (x, 1, integer_zero_node); 19358 tree tmp_var = create_tmp_var (ptr_type_node, "return_addr"); 19359 gimple_call_set_lhs (call, tmp_var); 19360 gimplify_seq_add_stmt (seq, call); 19361 x = builtin_decl_implicit (fncode); 19362 call = gimple_build_call (x, 2, this_fn_addr, tmp_var); 19363 gimplify_seq_add_stmt (seq, call); 19364 19365 if (cond_var) 19366 gimplify_seq_add_stmt (seq, gimple_build_label (label_false)); 19367 } 19368 19369 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL 19370 node for the function we want to gimplify. 19371 19372 Return the sequence of GIMPLE statements corresponding to the body 19373 of FNDECL. */ 19374 19375 void 19376 gimplify_function_tree (tree fndecl) 19377 { 19378 gimple_seq seq; 19379 gbind *bind; 19380 19381 gcc_assert (!gimple_body (fndecl)); 19382 19383 if (DECL_STRUCT_FUNCTION (fndecl)) 19384 push_cfun (DECL_STRUCT_FUNCTION (fndecl)); 19385 else 19386 push_struct_function (fndecl); 19387 19388 reset_cond_uid (); 19389 19390 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr 19391 if necessary. */ 19392 cfun->curr_properties |= PROP_gimple_lva; 19393 19394 if (asan_sanitize_use_after_scope ()) 19395 asan_poisoned_variables = new hash_set<tree> (); 19396 bind = gimplify_body (fndecl, true); 19397 if (asan_poisoned_variables) 19398 { 19399 delete asan_poisoned_variables; 19400 asan_poisoned_variables = NULL; 19401 } 19402 19403 /* The tree body of the function is no longer needed, replace it 19404 with the new GIMPLE body. */ 19405 seq = NULL; 19406 gimple_seq_add_stmt (&seq, bind); 19407 gimple_set_body (fndecl, seq); 19408 19409 /* If we're instrumenting function entry/exit, then prepend the call to 19410 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to 19411 catch the exit hook. */ 19412 /* ??? Add some way to ignore exceptions for this TFE. */ 19413 if (flag_instrument_function_entry_exit 19414 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) 19415 /* Do not instrument extern inline functions. */ 19416 && !(DECL_DECLARED_INLINE_P (fndecl) 19417 && DECL_EXTERNAL (fndecl) 19418 && DECL_DISREGARD_INLINE_LIMITS (fndecl)) 19419 && !flag_instrument_functions_exclude_p (fndecl)) 19420 { 19421 gimple_seq body = NULL, cleanup = NULL; 19422 gassign *assign; 19423 tree cond_var; 19424 19425 /* If -finstrument-functions-once is specified, generate: 19426 19427 static volatile bool C.0 = false; 19428 bool tmp_called; 19429 19430 tmp_called = C.0; 19431 if (!tmp_called) 19432 { 19433 C.0 = true; 19434 [call profiling enter function] 19435 } 19436 19437 without specific protection for data races. */ 19438 if (flag_instrument_function_entry_exit > 1) 19439 { 19440 tree first_var 19441 = build_decl (DECL_SOURCE_LOCATION (current_function_decl), 19442 VAR_DECL, 19443 create_tmp_var_name ("C"), 19444 boolean_type_node); 19445 DECL_ARTIFICIAL (first_var) = 1; 19446 DECL_IGNORED_P (first_var) = 1; 19447 TREE_STATIC (first_var) = 1; 19448 TREE_THIS_VOLATILE (first_var) = 1; 19449 TREE_USED (first_var) = 1; 19450 DECL_INITIAL (first_var) = boolean_false_node; 19451 varpool_node::add (first_var); 19452 19453 cond_var = create_tmp_var (boolean_type_node, "tmp_called"); 19454 assign = gimple_build_assign (cond_var, first_var); 19455 gimplify_seq_add_stmt (&body, assign); 19456 19457 assign = gimple_build_assign (first_var, boolean_true_node); 19458 } 19459 19460 else 19461 { 19462 cond_var = NULL_TREE; 19463 assign = NULL; 19464 } 19465 19466 build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER, 19467 cond_var, assign); 19468 19469 /* If -finstrument-functions-once is specified, generate: 19470 19471 if (!tmp_called) 19472 [call profiling exit function] 19473 19474 without specific protection for data races. */ 19475 build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT, 19476 cond_var, NULL); 19477 19478 gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY); 19479 gimplify_seq_add_stmt (&body, tf); 19480 gbind *new_bind = gimple_build_bind (NULL, body, NULL); 19481 19482 /* Replace the current function body with the body 19483 wrapped in the try/finally TF. */ 19484 seq = NULL; 19485 gimple_seq_add_stmt (&seq, new_bind); 19486 gimple_set_body (fndecl, seq); 19487 bind = new_bind; 19488 } 19489 19490 if (sanitize_flags_p (SANITIZE_THREAD) 19491 && param_tsan_instrument_func_entry_exit) 19492 { 19493 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0); 19494 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY); 19495 gbind *new_bind = gimple_build_bind (NULL, tf, NULL); 19496 /* Replace the current function body with the body 19497 wrapped in the try/finally TF. */ 19498 seq = NULL; 19499 gimple_seq_add_stmt (&seq, new_bind); 19500 gimple_set_body (fndecl, seq); 19501 } 19502 19503 DECL_SAVED_TREE (fndecl) = NULL_TREE; 19504 cfun->curr_properties |= PROP_gimple_any; 19505 19506 pop_cfun (); 19507 19508 dump_function (TDI_gimple, fndecl); 19509 } 19510 19511 /* Return a dummy expression of type TYPE in order to keep going after an 19512 error. */ 19513 19514 static tree 19515 dummy_object (tree type) 19516 { 19517 tree t = build_int_cst (build_pointer_type (type), 0); 19518 return build2 (MEM_REF, type, t, t); 19519 } 19520 19521 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a 19522 builtin function, but a very special sort of operator. */ 19523 19524 enum gimplify_status 19525 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, 19526 gimple_seq *post_p ATTRIBUTE_UNUSED) 19527 { 19528 tree promoted_type, have_va_type; 19529 tree valist = TREE_OPERAND (*expr_p, 0); 19530 tree type = TREE_TYPE (*expr_p); 19531 tree t, tag, aptag; 19532 location_t loc = EXPR_LOCATION (*expr_p); 19533 19534 /* Verify that valist is of the proper type. */ 19535 have_va_type = TREE_TYPE (valist); 19536 if (have_va_type == error_mark_node) 19537 return GS_ERROR; 19538 have_va_type = targetm.canonical_va_list_type (have_va_type); 19539 if (have_va_type == NULL_TREE 19540 && POINTER_TYPE_P (TREE_TYPE (valist))) 19541 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */ 19542 have_va_type 19543 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist))); 19544 gcc_assert (have_va_type != NULL_TREE); 19545 19546 /* Generate a diagnostic for requesting data of a type that cannot 19547 be passed through `...' due to type promotion at the call site. */ 19548 if ((promoted_type = lang_hooks.types.type_promotes_to (type)) 19549 != type) 19550 { 19551 static bool gave_help; 19552 bool warned; 19553 /* Use the expansion point to handle cases such as passing bool (defined 19554 in a system header) through `...'. */ 19555 location_t xloc 19556 = expansion_point_location_if_in_system_header (loc); 19557 19558 /* Unfortunately, this is merely undefined, rather than a constraint 19559 violation, so we cannot make this an error. If this call is never 19560 executed, the program is still strictly conforming. */ 19561 auto_diagnostic_group d; 19562 warned = warning_at (xloc, 0, 19563 "%qT is promoted to %qT when passed through %<...%>", 19564 type, promoted_type); 19565 if (!gave_help && warned) 19566 { 19567 gave_help = true; 19568 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)", 19569 promoted_type, type); 19570 } 19571 19572 /* We can, however, treat "undefined" any way we please. 19573 Call abort to encourage the user to fix the program. */ 19574 if (warned) 19575 inform (xloc, "if this code is reached, the program will abort"); 19576 /* Before the abort, allow the evaluation of the va_list 19577 expression to exit or longjmp. */ 19578 gimplify_and_add (valist, pre_p); 19579 t = build_call_expr_loc (loc, 19580 builtin_decl_implicit (BUILT_IN_TRAP), 0); 19581 gimplify_and_add (t, pre_p); 19582 19583 /* This is dead code, but go ahead and finish so that the 19584 mode of the result comes out right. */ 19585 *expr_p = dummy_object (type); 19586 return GS_ALL_DONE; 19587 } 19588 19589 tag = build_int_cst (build_pointer_type (type), 0); 19590 aptag = build_int_cst (TREE_TYPE (valist), 0); 19591 19592 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3, 19593 valist, tag, aptag); 19594 19595 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG 19596 needs to be expanded. */ 19597 cfun->curr_properties &= ~PROP_gimple_lva; 19598 19599 return GS_OK; 19600 } 19601 19602 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P. 19603 19604 DST/SRC are the destination and source respectively. You can pass 19605 ungimplified trees in DST or SRC, in which case they will be 19606 converted to a gimple operand if necessary. 19607 19608 This function returns the newly created GIMPLE_ASSIGN tuple. */ 19609 19610 gimple * 19611 gimplify_assign (tree dst, tree src, gimple_seq *seq_p) 19612 { 19613 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 19614 gimplify_and_add (t, seq_p); 19615 ggc_free (t); 19616 return gimple_seq_last_stmt (*seq_p); 19617 } 19618 19619 inline hashval_t 19620 gimplify_hasher::hash (const elt_t *p) 19621 { 19622 tree t = p->val; 19623 return iterative_hash_expr (t, 0); 19624 } 19625 19626 inline bool 19627 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2) 19628 { 19629 tree t1 = p1->val; 19630 tree t2 = p2->val; 19631 enum tree_code code = TREE_CODE (t1); 19632 19633 if (TREE_CODE (t2) != code 19634 || TREE_TYPE (t1) != TREE_TYPE (t2)) 19635 return false; 19636 19637 if (!operand_equal_p (t1, t2, 0)) 19638 return false; 19639 19640 /* Only allow them to compare equal if they also hash equal; otherwise 19641 results are nondeterminate, and we fail bootstrap comparison. */ 19642 gcc_checking_assert (hash (p1) == hash (p2)); 19643 19644 return true; 19645 } 19646