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 3881 for (i = 0; i < nargs; i++) 3882 { 3883 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, 3884 EXPR_LOCATION (*expr_p)); 3885 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i)); 3886 } 3887 3888 gcall *call = gimple_build_call_internal_vec (ifn, vargs); 3889 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p)); 3890 gimplify_seq_add_stmt (pre_p, call); 3891 return GS_ALL_DONE; 3892 } 3893 3894 /* This may be a call to a builtin function. 3895 3896 Builtin function calls may be transformed into different 3897 (and more efficient) builtin function calls under certain 3898 circumstances. Unfortunately, gimplification can muck things 3899 up enough that the builtin expanders are not aware that certain 3900 transformations are still valid. 3901 3902 So we attempt transformation/gimplification of the call before 3903 we gimplify the CALL_EXPR. At this time we do not manage to 3904 transform all calls in the same manner as the expanders do, but 3905 we do transform most of them. */ 3906 fndecl = get_callee_fndecl (*expr_p); 3907 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) 3908 switch (DECL_FUNCTION_CODE (fndecl)) 3909 { 3910 CASE_BUILT_IN_ALLOCA: 3911 /* If the call has been built for a variable-sized object, then we 3912 want to restore the stack level when the enclosing BIND_EXPR is 3913 exited to reclaim the allocated space; otherwise, we precisely 3914 need to do the opposite and preserve the latest stack level. */ 3915 if (CALL_ALLOCA_FOR_VAR_P (*expr_p)) 3916 gimplify_ctxp->save_stack = true; 3917 else 3918 gimplify_ctxp->keep_stack = true; 3919 break; 3920 3921 case BUILT_IN_VA_START: 3922 { 3923 builtin_va_start_p = true; 3924 if (call_expr_nargs (*expr_p) < 2) 3925 { 3926 error ("too few arguments to function %<va_start%>"); 3927 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); 3928 return GS_OK; 3929 } 3930 3931 if (fold_builtin_next_arg (*expr_p, true)) 3932 { 3933 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); 3934 return GS_OK; 3935 } 3936 break; 3937 } 3938 3939 case BUILT_IN_EH_RETURN: 3940 cfun->calls_eh_return = true; 3941 break; 3942 3943 case BUILT_IN_CLEAR_PADDING: 3944 if (call_expr_nargs (*expr_p) == 1) 3945 { 3946 /* Remember the original type of the argument in an internal 3947 dummy second argument, as in GIMPLE pointer conversions are 3948 useless. Also mark this call as not for automatic 3949 initialization in the internal dummy third argument. */ 3950 p = CALL_EXPR_ARG (*expr_p, 0); 3951 *expr_p 3952 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p, 3953 build_zero_cst (TREE_TYPE (p))); 3954 return GS_OK; 3955 } 3956 break; 3957 3958 default: 3959 ; 3960 } 3961 if (fndecl && fndecl_built_in_p (fndecl)) 3962 { 3963 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); 3964 if (new_tree && new_tree != *expr_p) 3965 { 3966 /* There was a transformation of this call which computes the 3967 same value, but in a more efficient way. Return and try 3968 again. */ 3969 *expr_p = new_tree; 3970 return GS_OK; 3971 } 3972 } 3973 3974 /* Remember the original function pointer type. */ 3975 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); 3976 3977 if (flag_openmp 3978 && fndecl 3979 && cfun 3980 && (cfun->curr_properties & PROP_gimple_any) == 0) 3981 { 3982 tree variant = omp_resolve_declare_variant (fndecl); 3983 if (variant != fndecl) 3984 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant); 3985 } 3986 3987 /* There is a sequence point before the call, so any side effects in 3988 the calling expression must occur before the actual call. Force 3989 gimplify_expr to use an internal post queue. */ 3990 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL, 3991 is_gimple_call_addr, fb_rvalue); 3992 3993 if (ret == GS_ERROR) 3994 return GS_ERROR; 3995 3996 nargs = call_expr_nargs (*expr_p); 3997 3998 /* Get argument types for verification. */ 3999 fndecl = get_callee_fndecl (*expr_p); 4000 parms = NULL_TREE; 4001 if (fndecl) 4002 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); 4003 else 4004 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype)); 4005 4006 if (fndecl && DECL_ARGUMENTS (fndecl)) 4007 p = DECL_ARGUMENTS (fndecl); 4008 else if (parms) 4009 p = parms; 4010 else 4011 p = NULL_TREE; 4012 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p)) 4013 ; 4014 4015 /* If the last argument is __builtin_va_arg_pack () and it is not 4016 passed as a named argument, decrease the number of CALL_EXPR 4017 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */ 4018 if (!p 4019 && i < nargs 4020 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR) 4021 { 4022 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1); 4023 tree last_arg_fndecl = get_callee_fndecl (last_arg); 4024 4025 if (last_arg_fndecl 4026 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK)) 4027 { 4028 tree call = *expr_p; 4029 4030 --nargs; 4031 *expr_p = build_call_array_loc (loc, TREE_TYPE (call), 4032 CALL_EXPR_FN (call), 4033 nargs, CALL_EXPR_ARGP (call)); 4034 4035 /* Copy all CALL_EXPR flags, location and block, except 4036 CALL_EXPR_VA_ARG_PACK flag. */ 4037 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call); 4038 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call); 4039 CALL_EXPR_RETURN_SLOT_OPT (*expr_p) 4040 = CALL_EXPR_RETURN_SLOT_OPT (call); 4041 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call); 4042 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call)); 4043 4044 /* Set CALL_EXPR_VA_ARG_PACK. */ 4045 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1; 4046 } 4047 } 4048 4049 /* If the call returns twice then after building the CFG the call 4050 argument computations will no longer dominate the call because 4051 we add an abnormal incoming edge to the call. So do not use SSA 4052 vars there. */ 4053 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE; 4054 4055 /* Gimplify the function arguments. */ 4056 if (nargs > 0) 4057 { 4058 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0); 4059 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs; 4060 PUSH_ARGS_REVERSED ? i-- : i++) 4061 { 4062 enum gimplify_status t; 4063 4064 /* Avoid gimplifying the second argument to va_start, which needs to 4065 be the plain PARM_DECL. */ 4066 if ((i != 1) || !builtin_va_start_p) 4067 { 4068 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, 4069 EXPR_LOCATION (*expr_p), ! returns_twice); 4070 4071 if (t == GS_ERROR) 4072 ret = GS_ERROR; 4073 } 4074 } 4075 } 4076 4077 /* Gimplify the static chain. */ 4078 if (CALL_EXPR_STATIC_CHAIN (*expr_p)) 4079 { 4080 if (fndecl && !DECL_STATIC_CHAIN (fndecl)) 4081 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL; 4082 else 4083 { 4084 enum gimplify_status t; 4085 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p, 4086 EXPR_LOCATION (*expr_p), ! returns_twice); 4087 if (t == GS_ERROR) 4088 ret = GS_ERROR; 4089 } 4090 } 4091 4092 /* Verify the function result. */ 4093 if (want_value && fndecl 4094 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype)))) 4095 { 4096 error_at (loc, "using result of function returning %<void%>"); 4097 ret = GS_ERROR; 4098 } 4099 4100 /* Try this again in case gimplification exposed something. */ 4101 if (ret != GS_ERROR) 4102 { 4103 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); 4104 4105 if (new_tree && new_tree != *expr_p) 4106 { 4107 /* There was a transformation of this call which computes the 4108 same value, but in a more efficient way. Return and try 4109 again. */ 4110 *expr_p = new_tree; 4111 return GS_OK; 4112 } 4113 } 4114 else 4115 { 4116 *expr_p = error_mark_node; 4117 return GS_ERROR; 4118 } 4119 4120 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its 4121 decl. This allows us to eliminate redundant or useless 4122 calls to "const" functions. */ 4123 if (TREE_CODE (*expr_p) == CALL_EXPR) 4124 { 4125 int flags = call_expr_flags (*expr_p); 4126 if (flags & (ECF_CONST | ECF_PURE) 4127 /* An infinite loop is considered a side effect. */ 4128 && !(flags & (ECF_LOOPING_CONST_OR_PURE))) 4129 TREE_SIDE_EFFECTS (*expr_p) = 0; 4130 } 4131 4132 /* If the value is not needed by the caller, emit a new GIMPLE_CALL 4133 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified 4134 form and delegate the creation of a GIMPLE_CALL to 4135 gimplify_modify_expr. This is always possible because when 4136 WANT_VALUE is true, the caller wants the result of this call into 4137 a temporary, which means that we will emit an INIT_EXPR in 4138 internal_get_tmp_var which will then be handled by 4139 gimplify_modify_expr. */ 4140 if (!want_value) 4141 { 4142 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we 4143 have to do is replicate it as a GIMPLE_CALL tuple. */ 4144 gimple_stmt_iterator gsi; 4145 call = gimple_build_call_from_tree (*expr_p, fnptrtype); 4146 notice_special_calls (call); 4147 gimplify_seq_add_stmt (pre_p, call); 4148 gsi = gsi_last (*pre_p); 4149 maybe_fold_stmt (&gsi); 4150 *expr_p = NULL_TREE; 4151 } 4152 else 4153 /* Remember the original function type. */ 4154 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype, 4155 CALL_EXPR_FN (*expr_p)); 4156 4157 return ret; 4158 } 4159 4160 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by 4161 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs. 4162 4163 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the 4164 condition is true or false, respectively. If null, we should generate 4165 our own to skip over the evaluation of this specific expression. 4166 4167 LOCUS is the source location of the COND_EXPR. 4168 4169 The condition_uid is a discriminator tag for condition coverage used to map 4170 conditions to its corresponding full Boolean function. 4171 4172 This function is the tree equivalent of do_jump. 4173 4174 shortcut_cond_r should only be called by shortcut_cond_expr. */ 4175 4176 static tree 4177 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p, 4178 location_t locus, unsigned condition_uid) 4179 { 4180 tree local_label = NULL_TREE; 4181 tree t, expr = NULL; 4182 4183 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to 4184 retain the shortcut semantics. Just insert the gotos here; 4185 shortcut_cond_expr will append the real blocks later. */ 4186 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 4187 { 4188 location_t new_locus; 4189 4190 /* Turn if (a && b) into 4191 4192 if (a); else goto no; 4193 if (b) goto yes; else goto no; 4194 (no:) */ 4195 4196 if (false_label_p == NULL) 4197 false_label_p = &local_label; 4198 4199 /* Keep the original source location on the first 'if'. */ 4200 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus, 4201 condition_uid); 4202 append_to_statement_list (t, &expr); 4203 4204 /* Set the source location of the && on the second 'if'. */ 4205 new_locus = rexpr_location (pred, locus); 4206 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, 4207 new_locus, condition_uid); 4208 append_to_statement_list (t, &expr); 4209 } 4210 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4211 { 4212 location_t new_locus; 4213 4214 /* Turn if (a || b) into 4215 4216 if (a) goto yes; 4217 if (b) goto yes; else goto no; 4218 (yes:) */ 4219 4220 if (true_label_p == NULL) 4221 true_label_p = &local_label; 4222 4223 /* Keep the original source location on the first 'if'. */ 4224 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus, 4225 condition_uid); 4226 append_to_statement_list (t, &expr); 4227 4228 /* Set the source location of the || on the second 'if'. */ 4229 new_locus = rexpr_location (pred, locus); 4230 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, 4231 new_locus, condition_uid); 4232 append_to_statement_list (t, &expr); 4233 } 4234 else if (TREE_CODE (pred) == COND_EXPR 4235 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1))) 4236 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2)))) 4237 { 4238 location_t new_locus; 4239 4240 /* As long as we're messing with gotos, turn if (a ? b : c) into 4241 if (a) 4242 if (b) goto yes; else goto no; 4243 else 4244 if (c) goto yes; else goto no; 4245 4246 Don't do this if one of the arms has void type, which can happen 4247 in C++ when the arm is throw. */ 4248 4249 /* Keep the original source location on the first 'if'. Set the source 4250 location of the ? on the second 'if'. */ 4251 new_locus = rexpr_location (pred, locus); 4252 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0), 4253 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, 4254 false_label_p, locus, condition_uid), 4255 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, 4256 false_label_p, new_locus, 4257 condition_uid)); 4258 SET_EXPR_UID (expr, condition_uid); 4259 } 4260 else 4261 { 4262 expr = build3 (COND_EXPR, void_type_node, pred, 4263 build_and_jump (true_label_p), 4264 build_and_jump (false_label_p)); 4265 SET_EXPR_LOCATION (expr, locus); 4266 SET_EXPR_UID (expr, condition_uid); 4267 } 4268 4269 if (local_label) 4270 { 4271 t = build1 (LABEL_EXPR, void_type_node, local_label); 4272 append_to_statement_list (t, &expr); 4273 } 4274 4275 return expr; 4276 } 4277 4278 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip 4279 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent 4280 statement, if it is the last one. Otherwise, return NULL. */ 4281 4282 static tree 4283 find_goto (tree expr) 4284 { 4285 if (!expr) 4286 return NULL_TREE; 4287 4288 if (TREE_CODE (expr) == GOTO_EXPR) 4289 return expr; 4290 4291 if (TREE_CODE (expr) != STATEMENT_LIST) 4292 return NULL_TREE; 4293 4294 tree_stmt_iterator i = tsi_start (expr); 4295 4296 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT) 4297 tsi_next (&i); 4298 4299 if (!tsi_one_before_end_p (i)) 4300 return NULL_TREE; 4301 4302 return find_goto (tsi_stmt (i)); 4303 } 4304 4305 /* Same as find_goto, except that it returns NULL if the destination 4306 is not a LABEL_DECL. */ 4307 4308 static inline tree 4309 find_goto_label (tree expr) 4310 { 4311 tree dest = find_goto (expr); 4312 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL) 4313 return dest; 4314 return NULL_TREE; 4315 } 4316 4317 4318 /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag 4319 every basic condition with CONDITION_UID. Two basic conditions share the 4320 CONDITION_UID discriminator when they belong to the same predicate, which is 4321 used by the condition coverage. Doing this as an explicit step makes for a 4322 simpler implementation than weaving it into the splitting code as the 4323 splitting code eventually calls the entry point gimplfiy_expr which makes 4324 bookkeeping complicated. */ 4325 static void 4326 tag_shortcut_cond (tree pred, unsigned condition_uid) 4327 { 4328 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR 4329 || TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4330 { 4331 tree fst = TREE_OPERAND (pred, 0); 4332 tree lst = TREE_OPERAND (pred, 1); 4333 4334 if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR 4335 || TREE_CODE (fst) == TRUTH_ORIF_EXPR) 4336 tag_shortcut_cond (fst, condition_uid); 4337 else if (TREE_CODE (fst) == COND_EXPR) 4338 SET_EXPR_UID (fst, condition_uid); 4339 4340 if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR 4341 || TREE_CODE (lst) == TRUTH_ORIF_EXPR) 4342 tag_shortcut_cond (lst, condition_uid); 4343 else if (TREE_CODE (lst) == COND_EXPR) 4344 SET_EXPR_UID (lst, condition_uid); 4345 } 4346 } 4347 4348 /* Given a conditional expression EXPR with short-circuit boolean 4349 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the 4350 predicate apart into the equivalent sequence of conditionals. CONDITION_UID 4351 is a the tag/discriminator for this EXPR - all basic conditions in the 4352 expression will be given the same CONDITION_UID. */ 4353 static tree 4354 shortcut_cond_expr (tree expr, unsigned condition_uid) 4355 { 4356 tree pred = TREE_OPERAND (expr, 0); 4357 tree then_ = TREE_OPERAND (expr, 1); 4358 tree else_ = TREE_OPERAND (expr, 2); 4359 tree true_label, false_label, end_label, t; 4360 tree *true_label_p; 4361 tree *false_label_p; 4362 bool emit_end, emit_false, jump_over_else; 4363 bool then_se = then_ && TREE_SIDE_EFFECTS (then_); 4364 bool else_se = else_ && TREE_SIDE_EFFECTS (else_); 4365 4366 tag_shortcut_cond (pred, condition_uid); 4367 4368 /* First do simple transformations. */ 4369 if (!else_se) 4370 { 4371 /* If there is no 'else', turn 4372 if (a && b) then c 4373 into 4374 if (a) if (b) then c. */ 4375 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) 4376 { 4377 /* Keep the original source location on the first 'if'. */ 4378 location_t locus = EXPR_LOC_OR_LOC (expr, input_location); 4379 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 4380 /* Set the source location of the && on the second 'if'. */ 4381 if (rexpr_has_location (pred)) 4382 SET_EXPR_LOCATION (expr, rexpr_location (pred)); 4383 then_ = shortcut_cond_expr (expr, condition_uid); 4384 then_se = then_ && TREE_SIDE_EFFECTS (then_); 4385 pred = TREE_OPERAND (pred, 0); 4386 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE); 4387 SET_EXPR_LOCATION (expr, locus); 4388 } 4389 } 4390 4391 if (!then_se) 4392 { 4393 /* If there is no 'then', turn 4394 if (a || b); else d 4395 into 4396 if (a); else if (b); else d. */ 4397 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR) 4398 { 4399 /* Keep the original source location on the first 'if'. */ 4400 location_t locus = EXPR_LOC_OR_LOC (expr, input_location); 4401 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); 4402 /* Set the source location of the || on the second 'if'. */ 4403 if (rexpr_has_location (pred)) 4404 SET_EXPR_LOCATION (expr, rexpr_location (pred)); 4405 else_ = shortcut_cond_expr (expr, condition_uid); 4406 else_se = else_ && TREE_SIDE_EFFECTS (else_); 4407 pred = TREE_OPERAND (pred, 0); 4408 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_); 4409 SET_EXPR_LOCATION (expr, locus); 4410 } 4411 } 4412 4413 /* The expr tree should also have the expression id set. */ 4414 SET_EXPR_UID (expr, condition_uid); 4415 4416 /* If we're done, great. */ 4417 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR 4418 && TREE_CODE (pred) != TRUTH_ORIF_EXPR) 4419 return expr; 4420 4421 /* Otherwise we need to mess with gotos. Change 4422 if (a) c; else d; 4423 to 4424 if (a); else goto no; 4425 c; goto end; 4426 no: d; end: 4427 and recursively gimplify the condition. */ 4428 4429 true_label = false_label = end_label = NULL_TREE; 4430 4431 /* If our arms just jump somewhere, hijack those labels so we don't 4432 generate jumps to jumps. */ 4433 4434 if (tree then_goto = find_goto_label (then_)) 4435 { 4436 true_label = GOTO_DESTINATION (then_goto); 4437 then_ = NULL; 4438 then_se = false; 4439 } 4440 4441 if (tree else_goto = find_goto_label (else_)) 4442 { 4443 false_label = GOTO_DESTINATION (else_goto); 4444 else_ = NULL; 4445 else_se = false; 4446 } 4447 4448 /* If we aren't hijacking a label for the 'then' branch, it falls through. */ 4449 if (true_label) 4450 true_label_p = &true_label; 4451 else 4452 true_label_p = NULL; 4453 4454 /* The 'else' branch also needs a label if it contains interesting code. */ 4455 if (false_label || else_se) 4456 false_label_p = &false_label; 4457 else 4458 false_label_p = NULL; 4459 4460 /* If there was nothing else in our arms, just forward the label(s). */ 4461 if (!then_se && !else_se) 4462 return shortcut_cond_r (pred, true_label_p, false_label_p, 4463 EXPR_LOC_OR_LOC (expr, input_location), condition_uid); 4464 4465 /* If our last subexpression already has a terminal label, reuse it. */ 4466 if (else_se) 4467 t = expr_last (else_); 4468 else if (then_se) 4469 t = expr_last (then_); 4470 else 4471 t = NULL; 4472 if (t && TREE_CODE (t) == LABEL_EXPR) 4473 end_label = LABEL_EXPR_LABEL (t); 4474 4475 /* If we don't care about jumping to the 'else' branch, jump to the end 4476 if the condition is false. */ 4477 if (!false_label_p) 4478 false_label_p = &end_label; 4479 4480 /* We only want to emit these labels if we aren't hijacking them. */ 4481 emit_end = (end_label == NULL_TREE); 4482 emit_false = (false_label == NULL_TREE); 4483 4484 /* We only emit the jump over the else clause if we have to--if the 4485 then clause may fall through. Otherwise we can wind up with a 4486 useless jump and a useless label at the end of gimplified code, 4487 which will cause us to think that this conditional as a whole 4488 falls through even if it doesn't. If we then inline a function 4489 which ends with such a condition, that can cause us to issue an 4490 inappropriate warning about control reaching the end of a 4491 non-void function. */ 4492 jump_over_else = block_may_fallthru (then_); 4493 4494 pred = shortcut_cond_r (pred, true_label_p, false_label_p, 4495 EXPR_LOC_OR_LOC (expr, input_location), 4496 condition_uid); 4497 4498 expr = NULL; 4499 append_to_statement_list (pred, &expr); 4500 4501 append_to_statement_list (then_, &expr); 4502 if (else_se) 4503 { 4504 if (jump_over_else) 4505 { 4506 tree last = expr_last (expr); 4507 t = build_and_jump (&end_label); 4508 if (rexpr_has_location (last)) 4509 SET_EXPR_LOCATION (t, rexpr_location (last)); 4510 append_to_statement_list (t, &expr); 4511 } 4512 if (emit_false) 4513 { 4514 t = build1 (LABEL_EXPR, void_type_node, false_label); 4515 append_to_statement_list (t, &expr); 4516 } 4517 append_to_statement_list (else_, &expr); 4518 } 4519 if (emit_end && end_label) 4520 { 4521 t = build1 (LABEL_EXPR, void_type_node, end_label); 4522 append_to_statement_list (t, &expr); 4523 } 4524 4525 return expr; 4526 } 4527 4528 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */ 4529 4530 tree 4531 gimple_boolify (tree expr) 4532 { 4533 tree type = TREE_TYPE (expr); 4534 location_t loc = EXPR_LOCATION (expr); 4535 4536 if (TREE_CODE (expr) == NE_EXPR 4537 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR 4538 && integer_zerop (TREE_OPERAND (expr, 1))) 4539 { 4540 tree call = TREE_OPERAND (expr, 0); 4541 tree fn = get_callee_fndecl (call); 4542 4543 /* For __builtin_expect ((long) (x), y) recurse into x as well 4544 if x is truth_value_p. */ 4545 if (fn 4546 && fndecl_built_in_p (fn, BUILT_IN_EXPECT) 4547 && call_expr_nargs (call) == 2) 4548 { 4549 tree arg = CALL_EXPR_ARG (call, 0); 4550 if (arg) 4551 { 4552 if (TREE_CODE (arg) == NOP_EXPR 4553 && TREE_TYPE (arg) == TREE_TYPE (call)) 4554 arg = TREE_OPERAND (arg, 0); 4555 if (truth_value_p (TREE_CODE (arg))) 4556 { 4557 arg = gimple_boolify (arg); 4558 CALL_EXPR_ARG (call, 0) 4559 = fold_convert_loc (loc, TREE_TYPE (call), arg); 4560 } 4561 } 4562 } 4563 } 4564 4565 switch (TREE_CODE (expr)) 4566 { 4567 case TRUTH_AND_EXPR: 4568 case TRUTH_OR_EXPR: 4569 case TRUTH_XOR_EXPR: 4570 case TRUTH_ANDIF_EXPR: 4571 case TRUTH_ORIF_EXPR: 4572 /* Also boolify the arguments of truth exprs. */ 4573 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); 4574 /* FALLTHRU */ 4575 4576 case TRUTH_NOT_EXPR: 4577 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4578 4579 /* These expressions always produce boolean results. */ 4580 if (TREE_CODE (type) != BOOLEAN_TYPE) 4581 TREE_TYPE (expr) = boolean_type_node; 4582 return expr; 4583 4584 case ANNOTATE_EXPR: 4585 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))) 4586 { 4587 case annot_expr_ivdep_kind: 4588 case annot_expr_unroll_kind: 4589 case annot_expr_no_vector_kind: 4590 case annot_expr_vector_kind: 4591 case annot_expr_parallel_kind: 4592 case annot_expr_maybe_infinite_kind: 4593 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4594 if (TREE_CODE (type) != BOOLEAN_TYPE) 4595 TREE_TYPE (expr) = boolean_type_node; 4596 return expr; 4597 default: 4598 gcc_unreachable (); 4599 } 4600 4601 default: 4602 if (COMPARISON_CLASS_P (expr)) 4603 { 4604 /* These expressions always produce boolean results. */ 4605 if (TREE_CODE (type) != BOOLEAN_TYPE) 4606 TREE_TYPE (expr) = boolean_type_node; 4607 return expr; 4608 } 4609 /* Other expressions that get here must have boolean values, but 4610 might need to be converted to the appropriate mode. */ 4611 if (TREE_CODE (type) == BOOLEAN_TYPE) 4612 return expr; 4613 return fold_convert_loc (loc, boolean_type_node, expr); 4614 } 4615 } 4616 4617 /* Given a conditional expression *EXPR_P without side effects, gimplify 4618 its operands. New statements are inserted to PRE_P. */ 4619 4620 static enum gimplify_status 4621 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p) 4622 { 4623 tree expr = *expr_p, cond; 4624 enum gimplify_status ret, tret; 4625 enum tree_code code; 4626 4627 cond = gimple_boolify (COND_EXPR_COND (expr)); 4628 4629 /* We need to handle && and || specially, as their gimplification 4630 creates pure cond_expr, thus leading to an infinite cycle otherwise. */ 4631 code = TREE_CODE (cond); 4632 if (code == TRUTH_ANDIF_EXPR) 4633 TREE_SET_CODE (cond, TRUTH_AND_EXPR); 4634 else if (code == TRUTH_ORIF_EXPR) 4635 TREE_SET_CODE (cond, TRUTH_OR_EXPR); 4636 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue); 4637 COND_EXPR_COND (*expr_p) = cond; 4638 4639 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL, 4640 is_gimple_val, fb_rvalue); 4641 ret = MIN (ret, tret); 4642 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL, 4643 is_gimple_val, fb_rvalue); 4644 4645 return MIN (ret, tret); 4646 } 4647 4648 /* Return true if evaluating EXPR could trap. 4649 EXPR is GENERIC, while tree_could_trap_p can be called 4650 only on GIMPLE. */ 4651 4652 bool 4653 generic_expr_could_trap_p (tree expr) 4654 { 4655 unsigned i, n; 4656 4657 if (!expr || is_gimple_val (expr)) 4658 return false; 4659 4660 if (!EXPR_P (expr) || tree_could_trap_p (expr)) 4661 return true; 4662 4663 n = TREE_OPERAND_LENGTH (expr); 4664 for (i = 0; i < n; i++) 4665 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i))) 4666 return true; 4667 4668 return false; 4669 } 4670 4671 /* Associate the condition STMT with the discriminator UID. STMTs that are 4672 broken down with ANDIF/ORIF from the same Boolean expression should be given 4673 the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the 4674 { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done. This is used 4675 for condition coverage. */ 4676 static void 4677 gimple_associate_condition_with_expr (struct function *fn, gcond *stmt, 4678 unsigned uid) 4679 { 4680 if (!condition_coverage_flag) 4681 return; 4682 4683 if (!fn->cond_uids) 4684 fn->cond_uids = new hash_map <gcond*, unsigned> (); 4685 4686 fn->cond_uids->put (stmt, uid); 4687 } 4688 4689 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' 4690 into 4691 4692 if (p) if (p) 4693 t1 = a; a; 4694 else or else 4695 t1 = b; b; 4696 t1; 4697 4698 The second form is used when *EXPR_P is of type void. 4699 4700 PRE_P points to the list where side effects that must happen before 4701 *EXPR_P should be stored. */ 4702 4703 static enum gimplify_status 4704 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) 4705 { 4706 tree expr = *expr_p; 4707 tree type = TREE_TYPE (expr); 4708 location_t loc = EXPR_LOCATION (expr); 4709 tree tmp, arm1, arm2; 4710 enum gimplify_status ret; 4711 tree label_true, label_false, label_cont; 4712 bool have_then_clause_p, have_else_clause_p; 4713 gcond *cond_stmt; 4714 enum tree_code pred_code; 4715 gimple_seq seq = NULL; 4716 4717 /* If this COND_EXPR has a value, copy the values into a temporary within 4718 the arms. */ 4719 if (!VOID_TYPE_P (type)) 4720 { 4721 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2); 4722 tree result; 4723 4724 /* If either an rvalue is ok or we do not require an lvalue, create the 4725 temporary. But we cannot do that if the type is addressable. */ 4726 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue)) 4727 && !TREE_ADDRESSABLE (type)) 4728 { 4729 if (gimplify_ctxp->allow_rhs_cond_expr 4730 /* If either branch has side effects or could trap, it can't be 4731 evaluated unconditionally. */ 4732 && !TREE_SIDE_EFFECTS (then_) 4733 && !generic_expr_could_trap_p (then_) 4734 && !TREE_SIDE_EFFECTS (else_) 4735 && !generic_expr_could_trap_p (else_)) 4736 return gimplify_pure_cond_expr (expr_p, pre_p); 4737 4738 tmp = create_tmp_var (type, "iftmp"); 4739 result = tmp; 4740 } 4741 4742 /* Otherwise, only create and copy references to the values. */ 4743 else 4744 { 4745 type = build_pointer_type (type); 4746 4747 if (!VOID_TYPE_P (TREE_TYPE (then_))) 4748 then_ = build_fold_addr_expr_loc (loc, then_); 4749 4750 if (!VOID_TYPE_P (TREE_TYPE (else_))) 4751 else_ = build_fold_addr_expr_loc (loc, else_); 4752 4753 expr 4754 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_); 4755 4756 tmp = create_tmp_var (type, "iftmp"); 4757 result = build_simple_mem_ref_loc (loc, tmp); 4758 } 4759 4760 /* Build the new then clause, `tmp = then_;'. But don't build the 4761 assignment if the value is void; in C++ it can be if it's a throw. */ 4762 if (!VOID_TYPE_P (TREE_TYPE (then_))) 4763 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_); 4764 4765 /* Similarly, build the new else clause, `tmp = else_;'. */ 4766 if (!VOID_TYPE_P (TREE_TYPE (else_))) 4767 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_); 4768 4769 TREE_TYPE (expr) = void_type_node; 4770 recalculate_side_effects (expr); 4771 4772 /* Move the COND_EXPR to the prequeue. */ 4773 gimplify_stmt (&expr, pre_p); 4774 4775 *expr_p = result; 4776 return GS_ALL_DONE; 4777 } 4778 4779 /* Remove any COMPOUND_EXPR so the following cases will be caught. */ 4780 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0)); 4781 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR) 4782 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true); 4783 4784 /* Make sure the condition has BOOLEAN_TYPE. */ 4785 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); 4786 4787 /* Break apart && and || conditions. */ 4788 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR 4789 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR) 4790 { 4791 expr = shortcut_cond_expr (expr, next_cond_uid ()); 4792 4793 if (expr != *expr_p) 4794 { 4795 *expr_p = expr; 4796 4797 /* We can't rely on gimplify_expr to re-gimplify the expanded 4798 form properly, as cleanups might cause the target labels to be 4799 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to 4800 set up a conditional context. */ 4801 gimple_push_condition (); 4802 gimplify_stmt (expr_p, &seq); 4803 gimple_pop_condition (pre_p); 4804 gimple_seq_add_seq (pre_p, seq); 4805 4806 return GS_ALL_DONE; 4807 } 4808 } 4809 4810 /* Now do the normal gimplification. */ 4811 4812 /* Gimplify condition. */ 4813 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, 4814 is_gimple_condexpr_for_cond, fb_rvalue); 4815 if (ret == GS_ERROR) 4816 return GS_ERROR; 4817 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE); 4818 4819 gimple_push_condition (); 4820 4821 have_then_clause_p = have_else_clause_p = false; 4822 label_true = find_goto_label (TREE_OPERAND (expr, 1)); 4823 if (label_true 4824 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl 4825 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR 4826 have different locations, otherwise we end up with incorrect 4827 location information on the branches. */ 4828 && (optimize 4829 || !EXPR_HAS_LOCATION (expr) 4830 || !rexpr_has_location (label_true) 4831 || EXPR_LOCATION (expr) == rexpr_location (label_true))) 4832 { 4833 have_then_clause_p = true; 4834 label_true = GOTO_DESTINATION (label_true); 4835 } 4836 else 4837 label_true = create_artificial_label (UNKNOWN_LOCATION); 4838 label_false = find_goto_label (TREE_OPERAND (expr, 2)); 4839 if (label_false 4840 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl 4841 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR 4842 have different locations, otherwise we end up with incorrect 4843 location information on the branches. */ 4844 && (optimize 4845 || !EXPR_HAS_LOCATION (expr) 4846 || !rexpr_has_location (label_false) 4847 || EXPR_LOCATION (expr) == rexpr_location (label_false))) 4848 { 4849 have_else_clause_p = true; 4850 label_false = GOTO_DESTINATION (label_false); 4851 } 4852 else 4853 label_false = create_artificial_label (UNKNOWN_LOCATION); 4854 4855 unsigned cond_uid = EXPR_COND_UID (expr); 4856 if (cond_uid == 0) 4857 cond_uid = next_cond_uid (); 4858 4859 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1, 4860 &arm2); 4861 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, 4862 label_false); 4863 gimple_set_location (cond_stmt, EXPR_LOCATION (expr)); 4864 gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid); 4865 copy_warning (cond_stmt, COND_EXPR_COND (expr)); 4866 gimplify_seq_add_stmt (&seq, cond_stmt); 4867 gimple_stmt_iterator gsi = gsi_last (seq); 4868 maybe_fold_stmt (&gsi); 4869 4870 label_cont = NULL_TREE; 4871 if (!have_then_clause_p) 4872 { 4873 /* For if (...) {} else { code; } put label_true after 4874 the else block. */ 4875 if (TREE_OPERAND (expr, 1) == NULL_TREE 4876 && !have_else_clause_p 4877 && TREE_OPERAND (expr, 2) != NULL_TREE) 4878 { 4879 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough 4880 handling that label_cont == label_true can be only reached 4881 through fallthrough from { code; }. */ 4882 if (integer_zerop (COND_EXPR_COND (expr))) 4883 UNUSED_LABEL_P (label_true) = 1; 4884 label_cont = label_true; 4885 } 4886 else 4887 { 4888 bool then_side_effects 4889 = (TREE_OPERAND (expr, 1) 4890 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))); 4891 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true)); 4892 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq); 4893 /* For if (...) { code; } else {} or 4894 if (...) { code; } else goto label; or 4895 if (...) { code; return; } else { ... } 4896 label_cont isn't needed. */ 4897 if (!have_else_clause_p 4898 && TREE_OPERAND (expr, 2) != NULL_TREE 4899 && gimple_seq_may_fallthru (seq)) 4900 { 4901 gimple *g; 4902 label_cont = create_artificial_label (UNKNOWN_LOCATION); 4903 4904 /* For if (0) { non-side-effect-code } else { code } 4905 tell -Wimplicit-fallthrough handling that label_cont can 4906 be only reached through fallthrough from { code }. */ 4907 if (integer_zerop (COND_EXPR_COND (expr))) 4908 { 4909 UNUSED_LABEL_P (label_true) = 1; 4910 if (!then_side_effects) 4911 UNUSED_LABEL_P (label_cont) = 1; 4912 } 4913 4914 g = gimple_build_goto (label_cont); 4915 4916 /* GIMPLE_COND's are very low level; they have embedded 4917 gotos. This particular embedded goto should not be marked 4918 with the location of the original COND_EXPR, as it would 4919 correspond to the COND_EXPR's condition, not the ELSE or the 4920 THEN arms. To avoid marking it with the wrong location, flag 4921 it as "no location". */ 4922 gimple_set_do_not_emit_location (g); 4923 4924 gimplify_seq_add_stmt (&seq, g); 4925 } 4926 } 4927 } 4928 if (!have_else_clause_p) 4929 { 4930 /* For if (1) { code } or if (1) { code } else { non-side-effect-code } 4931 tell -Wimplicit-fallthrough handling that label_false can be only 4932 reached through fallthrough from { code }. */ 4933 if (integer_nonzerop (COND_EXPR_COND (expr)) 4934 && (TREE_OPERAND (expr, 2) == NULL_TREE 4935 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))) 4936 UNUSED_LABEL_P (label_false) = 1; 4937 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false)); 4938 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq); 4939 } 4940 if (label_cont) 4941 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont)); 4942 4943 gimple_pop_condition (pre_p); 4944 gimple_seq_add_seq (pre_p, seq); 4945 4946 if (ret == GS_ERROR) 4947 ; /* Do nothing. */ 4948 else if (have_then_clause_p || have_else_clause_p) 4949 ret = GS_ALL_DONE; 4950 else 4951 { 4952 /* Both arms are empty; replace the COND_EXPR with its predicate. */ 4953 expr = TREE_OPERAND (expr, 0); 4954 gimplify_stmt (&expr, pre_p); 4955 } 4956 4957 *expr_p = NULL; 4958 return ret; 4959 } 4960 4961 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression, 4962 to be marked addressable. 4963 4964 We cannot rely on such an expression being directly markable if a temporary 4965 has been created by the gimplification. In this case, we create another 4966 temporary and initialize it with a copy, which will become a store after we 4967 mark it addressable. This can happen if the front-end passed us something 4968 that it could not mark addressable yet, like a Fortran pass-by-reference 4969 parameter (int) floatvar. */ 4970 4971 static void 4972 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p) 4973 { 4974 while (handled_component_p (*expr_p)) 4975 expr_p = &TREE_OPERAND (*expr_p, 0); 4976 4977 /* Do not allow an SSA name as the temporary. */ 4978 if (is_gimple_reg (*expr_p)) 4979 *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true); 4980 } 4981 4982 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 4983 a call to __builtin_memcpy. */ 4984 4985 static enum gimplify_status 4986 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, 4987 gimple_seq *seq_p) 4988 { 4989 tree t, to, to_ptr, from, from_ptr; 4990 gcall *gs; 4991 location_t loc = EXPR_LOCATION (*expr_p); 4992 4993 to = TREE_OPERAND (*expr_p, 0); 4994 from = TREE_OPERAND (*expr_p, 1); 4995 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))) 4996 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from)))); 4997 4998 /* Mark the RHS addressable. Beware that it may not be possible to do so 4999 directly if a temporary has been created by the gimplification. */ 5000 prepare_gimple_addressable (&from, seq_p); 5001 5002 mark_addressable (from); 5003 from_ptr = build_fold_addr_expr_loc (loc, from); 5004 gimplify_arg (&from_ptr, seq_p, loc); 5005 5006 mark_addressable (to); 5007 to_ptr = build_fold_addr_expr_loc (loc, to); 5008 gimplify_arg (&to_ptr, seq_p, loc); 5009 5010 t = builtin_decl_implicit (BUILT_IN_MEMCPY); 5011 5012 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size); 5013 gimple_call_set_alloca_for_var (gs, true); 5014 5015 if (want_value) 5016 { 5017 /* tmp = memcpy() */ 5018 t = create_tmp_var (TREE_TYPE (to_ptr)); 5019 gimple_call_set_lhs (gs, t); 5020 gimplify_seq_add_stmt (seq_p, gs); 5021 5022 *expr_p = build_simple_mem_ref (t); 5023 return GS_ALL_DONE; 5024 } 5025 5026 gimplify_seq_add_stmt (seq_p, gs); 5027 *expr_p = NULL; 5028 return GS_ALL_DONE; 5029 } 5030 5031 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with 5032 a call to __builtin_memset. In this case we know that the RHS is 5033 a CONSTRUCTOR with an empty element list. */ 5034 5035 static enum gimplify_status 5036 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, 5037 gimple_seq *seq_p) 5038 { 5039 tree t, from, to, to_ptr; 5040 gcall *gs; 5041 location_t loc = EXPR_LOCATION (*expr_p); 5042 5043 /* Assert our assumptions, to abort instead of producing wrong code 5044 silently if they are not met. Beware that the RHS CONSTRUCTOR might 5045 not be immediately exposed. */ 5046 from = TREE_OPERAND (*expr_p, 1); 5047 if (TREE_CODE (from) == WITH_SIZE_EXPR) 5048 from = TREE_OPERAND (from, 0); 5049 5050 gcc_assert (TREE_CODE (from) == CONSTRUCTOR 5051 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from))); 5052 5053 /* Now proceed. */ 5054 to = TREE_OPERAND (*expr_p, 0); 5055 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))); 5056 5057 to_ptr = build_fold_addr_expr_loc (loc, to); 5058 gimplify_arg (&to_ptr, seq_p, loc); 5059 t = builtin_decl_implicit (BUILT_IN_MEMSET); 5060 5061 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size); 5062 5063 if (want_value) 5064 { 5065 /* tmp = memset() */ 5066 t = create_tmp_var (TREE_TYPE (to_ptr)); 5067 gimple_call_set_lhs (gs, t); 5068 gimplify_seq_add_stmt (seq_p, gs); 5069 5070 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t); 5071 return GS_ALL_DONE; 5072 } 5073 5074 gimplify_seq_add_stmt (seq_p, gs); 5075 *expr_p = NULL; 5076 return GS_ALL_DONE; 5077 } 5078 5079 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree, 5080 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an 5081 assignment. Return non-null if we detect a potential overlap. */ 5082 5083 struct gimplify_init_ctor_preeval_data 5084 { 5085 /* The base decl of the lhs object. May be NULL, in which case we 5086 have to assume the lhs is indirect. */ 5087 tree lhs_base_decl; 5088 5089 /* The alias set of the lhs object. */ 5090 alias_set_type lhs_alias_set; 5091 }; 5092 5093 static tree 5094 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata) 5095 { 5096 struct gimplify_init_ctor_preeval_data *data 5097 = (struct gimplify_init_ctor_preeval_data *) xdata; 5098 tree t = *tp; 5099 5100 /* If we find the base object, obviously we have overlap. */ 5101 if (data->lhs_base_decl == t) 5102 return t; 5103 5104 /* If the constructor component is indirect, determine if we have a 5105 potential overlap with the lhs. The only bits of information we 5106 have to go on at this point are addressability and alias sets. */ 5107 if ((INDIRECT_REF_P (t) 5108 || TREE_CODE (t) == MEM_REF) 5109 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 5110 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t))) 5111 return t; 5112 5113 /* If the constructor component is a call, determine if it can hide a 5114 potential overlap with the lhs through an INDIRECT_REF like above. 5115 ??? Ugh - this is completely broken. In fact this whole analysis 5116 doesn't look conservative. */ 5117 if (TREE_CODE (t) == CALL_EXPR) 5118 { 5119 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t))); 5120 5121 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type)) 5122 if (POINTER_TYPE_P (TREE_VALUE (type)) 5123 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) 5124 && alias_sets_conflict_p (data->lhs_alias_set, 5125 get_alias_set 5126 (TREE_TYPE (TREE_VALUE (type))))) 5127 return t; 5128 } 5129 5130 if (IS_TYPE_OR_DECL_P (t)) 5131 *walk_subtrees = 0; 5132 return NULL; 5133 } 5134 5135 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR, 5136 force values that overlap with the lhs (as described by *DATA) 5137 into temporaries. */ 5138 5139 static void 5140 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 5141 struct gimplify_init_ctor_preeval_data *data) 5142 { 5143 enum gimplify_status one; 5144 5145 /* If the value is constant, then there's nothing to pre-evaluate. */ 5146 if (TREE_CONSTANT (*expr_p)) 5147 { 5148 /* Ensure it does not have side effects, it might contain a reference to 5149 the object we're initializing. */ 5150 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p)); 5151 return; 5152 } 5153 5154 /* If the type has non-trivial constructors, we can't pre-evaluate. */ 5155 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p))) 5156 return; 5157 5158 /* Recurse for nested constructors. */ 5159 if (TREE_CODE (*expr_p) == CONSTRUCTOR) 5160 { 5161 unsigned HOST_WIDE_INT ix; 5162 constructor_elt *ce; 5163 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p); 5164 5165 FOR_EACH_VEC_SAFE_ELT (v, ix, ce) 5166 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data); 5167 5168 return; 5169 } 5170 5171 /* If this is a variable sized type, we must remember the size. */ 5172 maybe_with_size_expr (expr_p); 5173 5174 /* Gimplify the constructor element to something appropriate for the rhs 5175 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know 5176 the gimplifier will consider this a store to memory. Doing this 5177 gimplification now means that we won't have to deal with complicated 5178 language-specific trees, nor trees like SAVE_EXPR that can induce 5179 exponential search behavior. */ 5180 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue); 5181 if (one == GS_ERROR) 5182 { 5183 *expr_p = NULL; 5184 return; 5185 } 5186 5187 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap 5188 with the lhs, since "a = { .x=a }" doesn't make sense. This will 5189 always be true for all scalars, since is_gimple_mem_rhs insists on a 5190 temporary variable for them. */ 5191 if (DECL_P (*expr_p)) 5192 return; 5193 5194 /* If this is of variable size, we have no choice but to assume it doesn't 5195 overlap since we can't make a temporary for it. */ 5196 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST) 5197 return; 5198 5199 /* Otherwise, we must search for overlap ... */ 5200 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL)) 5201 return; 5202 5203 /* ... and if found, force the value into a temporary. */ 5204 *expr_p = get_formal_tmp_var (*expr_p, pre_p); 5205 } 5206 5207 /* A subroutine of gimplify_init_ctor_eval. Create a loop for 5208 a RANGE_EXPR in a CONSTRUCTOR for an array. 5209 5210 var = lower; 5211 loop_entry: 5212 object[var] = value; 5213 if (var == upper) 5214 goto loop_exit; 5215 var = var + 1; 5216 goto loop_entry; 5217 loop_exit: 5218 5219 We increment var _after_ the loop exit check because we might otherwise 5220 fail if upper == TYPE_MAX_VALUE (type for upper). 5221 5222 Note that we never have to deal with SAVE_EXPRs here, because this has 5223 already been taken care of for us, in gimplify_init_ctor_preeval(). */ 5224 5225 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *, 5226 gimple_seq *, bool); 5227 5228 static void 5229 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper, 5230 tree value, tree array_elt_type, 5231 gimple_seq *pre_p, bool cleared) 5232 { 5233 tree loop_entry_label, loop_exit_label, fall_thru_label; 5234 tree var, var_type, cref, tmp; 5235 5236 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION); 5237 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION); 5238 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION); 5239 5240 /* Create and initialize the index variable. */ 5241 var_type = TREE_TYPE (upper); 5242 var = create_tmp_var (var_type); 5243 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower)); 5244 5245 /* Add the loop entry label. */ 5246 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label)); 5247 5248 /* Build the reference. */ 5249 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 5250 var, NULL_TREE, NULL_TREE); 5251 5252 /* If we are a constructor, just call gimplify_init_ctor_eval to do 5253 the store. Otherwise just assign value to the reference. */ 5254 5255 if (TREE_CODE (value) == CONSTRUCTOR) 5256 /* NB we might have to call ourself recursively through 5257 gimplify_init_ctor_eval if the value is a constructor. */ 5258 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 5259 pre_p, cleared); 5260 else 5261 { 5262 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue) 5263 != GS_ERROR) 5264 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value)); 5265 } 5266 5267 /* We exit the loop when the index var is equal to the upper bound. */ 5268 gimplify_seq_add_stmt (pre_p, 5269 gimple_build_cond (EQ_EXPR, var, upper, 5270 loop_exit_label, fall_thru_label)); 5271 5272 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label)); 5273 5274 /* Otherwise, increment the index var... */ 5275 tmp = build2 (PLUS_EXPR, var_type, var, 5276 fold_convert (var_type, integer_one_node)); 5277 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp)); 5278 5279 /* ...and jump back to the loop entry. */ 5280 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label)); 5281 5282 /* Add the loop exit label. */ 5283 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label)); 5284 } 5285 5286 /* A subroutine of gimplify_init_constructor. Generate individual 5287 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the 5288 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the 5289 CONSTRUCTOR. CLEARED is true if the entire LHS object has been 5290 zeroed first. */ 5291 5292 static void 5293 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts, 5294 gimple_seq *pre_p, bool cleared) 5295 { 5296 tree array_elt_type = NULL; 5297 unsigned HOST_WIDE_INT ix; 5298 tree purpose, value; 5299 5300 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE) 5301 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object))); 5302 5303 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value) 5304 { 5305 tree cref; 5306 5307 /* NULL values are created above for gimplification errors. */ 5308 if (value == NULL) 5309 continue; 5310 5311 if (cleared && initializer_zerop (value)) 5312 continue; 5313 5314 /* ??? Here's to hoping the front end fills in all of the indices, 5315 so we don't have to figure out what's missing ourselves. */ 5316 gcc_assert (purpose); 5317 5318 /* Skip zero-sized fields, unless value has side-effects. This can 5319 happen with calls to functions returning a empty type, which 5320 we shouldn't discard. As a number of downstream passes don't 5321 expect sets of empty type fields, we rely on the gimplification of 5322 the MODIFY_EXPR we make below to drop the assignment statement. */ 5323 if (!TREE_SIDE_EFFECTS (value) 5324 && TREE_CODE (purpose) == FIELD_DECL 5325 && is_empty_type (TREE_TYPE (purpose))) 5326 continue; 5327 5328 /* If we have a RANGE_EXPR, we have to build a loop to assign the 5329 whole range. */ 5330 if (TREE_CODE (purpose) == RANGE_EXPR) 5331 { 5332 tree lower = TREE_OPERAND (purpose, 0); 5333 tree upper = TREE_OPERAND (purpose, 1); 5334 5335 /* If the lower bound is equal to upper, just treat it as if 5336 upper was the index. */ 5337 if (simple_cst_equal (lower, upper)) 5338 purpose = upper; 5339 else 5340 { 5341 gimplify_init_ctor_eval_range (object, lower, upper, value, 5342 array_elt_type, pre_p, cleared); 5343 continue; 5344 } 5345 } 5346 5347 if (array_elt_type) 5348 { 5349 /* Do not use bitsizetype for ARRAY_REF indices. */ 5350 if (TYPE_DOMAIN (TREE_TYPE (object))) 5351 purpose 5352 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))), 5353 purpose); 5354 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), 5355 purpose, NULL_TREE, NULL_TREE); 5356 } 5357 else 5358 { 5359 gcc_assert (TREE_CODE (purpose) == FIELD_DECL); 5360 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose), 5361 unshare_expr (object), purpose, NULL_TREE); 5362 } 5363 5364 if (TREE_CODE (value) == CONSTRUCTOR 5365 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE) 5366 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), 5367 pre_p, cleared); 5368 else 5369 { 5370 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); 5371 gimplify_and_add (init, pre_p); 5372 ggc_free (init); 5373 } 5374 } 5375 } 5376 5377 /* Return the appropriate RHS predicate for this LHS. */ 5378 5379 gimple_predicate 5380 rhs_predicate_for (tree lhs) 5381 { 5382 if (is_gimple_reg (lhs)) 5383 return is_gimple_reg_rhs_or_call; 5384 else 5385 return is_gimple_mem_rhs_or_call; 5386 } 5387 5388 /* Return the initial guess for an appropriate RHS predicate for this LHS, 5389 before the LHS has been gimplified. */ 5390 5391 static gimple_predicate 5392 initial_rhs_predicate_for (tree lhs) 5393 { 5394 if (is_gimple_reg_type (TREE_TYPE (lhs))) 5395 return is_gimple_reg_rhs_or_call; 5396 else 5397 return is_gimple_mem_rhs_or_call; 5398 } 5399 5400 /* Gimplify a C99 compound literal expression. This just means adding 5401 the DECL_EXPR before the current statement and using its anonymous 5402 decl instead. */ 5403 5404 static enum gimplify_status 5405 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p, 5406 bool (*gimple_test_f) (tree), 5407 fallback_t fallback) 5408 { 5409 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p); 5410 tree decl = DECL_EXPR_DECL (decl_s); 5411 tree init = DECL_INITIAL (decl); 5412 /* Mark the decl as addressable if the compound literal 5413 expression is addressable now, otherwise it is marked too late 5414 after we gimplify the initialization expression. */ 5415 if (TREE_ADDRESSABLE (*expr_p)) 5416 TREE_ADDRESSABLE (decl) = 1; 5417 /* Otherwise, if we don't need an lvalue and have a literal directly 5418 substitute it. Check if it matches the gimple predicate, as 5419 otherwise we'd generate a new temporary, and we can as well just 5420 use the decl we already have. */ 5421 else if (!TREE_ADDRESSABLE (decl) 5422 && !TREE_THIS_VOLATILE (decl) 5423 && init 5424 && (fallback & fb_lvalue) == 0 5425 && gimple_test_f (init)) 5426 { 5427 *expr_p = init; 5428 return GS_OK; 5429 } 5430 5431 /* If the decl is not addressable, then it is being used in some 5432 expression or on the right hand side of a statement, and it can 5433 be put into a readonly data section. */ 5434 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0) 5435 TREE_READONLY (decl) = 1; 5436 5437 /* This decl isn't mentioned in the enclosing block, so add it to the 5438 list of temps. FIXME it seems a bit of a kludge to say that 5439 anonymous artificial vars aren't pushed, but everything else is. */ 5440 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl)) 5441 gimple_add_tmp_var (decl); 5442 5443 gimplify_and_add (decl_s, pre_p); 5444 *expr_p = decl; 5445 return GS_OK; 5446 } 5447 5448 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR, 5449 return a new CONSTRUCTOR if something changed. */ 5450 5451 static tree 5452 optimize_compound_literals_in_ctor (tree orig_ctor) 5453 { 5454 tree ctor = orig_ctor; 5455 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor); 5456 unsigned int idx, num = vec_safe_length (elts); 5457 5458 for (idx = 0; idx < num; idx++) 5459 { 5460 tree value = (*elts)[idx].value; 5461 tree newval = value; 5462 if (TREE_CODE (value) == CONSTRUCTOR) 5463 newval = optimize_compound_literals_in_ctor (value); 5464 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR) 5465 { 5466 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value); 5467 tree decl = DECL_EXPR_DECL (decl_s); 5468 tree init = DECL_INITIAL (decl); 5469 5470 if (!TREE_ADDRESSABLE (value) 5471 && !TREE_ADDRESSABLE (decl) 5472 && init 5473 && TREE_CODE (init) == CONSTRUCTOR) 5474 newval = optimize_compound_literals_in_ctor (init); 5475 } 5476 if (newval == value) 5477 continue; 5478 5479 if (ctor == orig_ctor) 5480 { 5481 ctor = copy_node (orig_ctor); 5482 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts); 5483 elts = CONSTRUCTOR_ELTS (ctor); 5484 } 5485 (*elts)[idx].value = newval; 5486 } 5487 return ctor; 5488 } 5489 5490 /* A subroutine of gimplify_modify_expr. Break out elements of a 5491 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs. 5492 5493 Note that we still need to clear any elements that don't have explicit 5494 initializers, so if not all elements are initialized we keep the 5495 original MODIFY_EXPR, we just remove all of the constructor elements. 5496 5497 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return 5498 GS_ERROR if we would have to create a temporary when gimplifying 5499 this constructor. Otherwise, return GS_OK. 5500 5501 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */ 5502 5503 static enum gimplify_status 5504 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 5505 bool want_value, bool notify_temp_creation) 5506 { 5507 tree object, ctor, type; 5508 enum gimplify_status ret; 5509 vec<constructor_elt, va_gc> *elts; 5510 bool cleared = false; 5511 bool is_empty_ctor = false; 5512 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR); 5513 5514 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR); 5515 5516 if (!notify_temp_creation) 5517 { 5518 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 5519 is_gimple_lvalue, fb_lvalue); 5520 if (ret == GS_ERROR) 5521 return ret; 5522 } 5523 5524 object = TREE_OPERAND (*expr_p, 0); 5525 ctor = TREE_OPERAND (*expr_p, 1) 5526 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1)); 5527 type = TREE_TYPE (ctor); 5528 elts = CONSTRUCTOR_ELTS (ctor); 5529 ret = GS_ALL_DONE; 5530 5531 switch (TREE_CODE (type)) 5532 { 5533 case RECORD_TYPE: 5534 case UNION_TYPE: 5535 case QUAL_UNION_TYPE: 5536 case ARRAY_TYPE: 5537 { 5538 /* Use readonly data for initializers of this or smaller size 5539 regardless of the num_nonzero_elements / num_unique_nonzero_elements 5540 ratio. */ 5541 const HOST_WIDE_INT min_unique_size = 64; 5542 /* If num_nonzero_elements / num_unique_nonzero_elements ratio 5543 is smaller than this, use readonly data. */ 5544 const int unique_nonzero_ratio = 8; 5545 /* True if a single access of the object must be ensured. This is the 5546 case if the target is volatile, the type is non-addressable and more 5547 than one field need to be assigned. */ 5548 const bool ensure_single_access 5549 = TREE_THIS_VOLATILE (object) 5550 && !TREE_ADDRESSABLE (type) 5551 && vec_safe_length (elts) > 1; 5552 struct gimplify_init_ctor_preeval_data preeval_data; 5553 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; 5554 HOST_WIDE_INT num_unique_nonzero_elements; 5555 bool complete_p, valid_const_initializer; 5556 5557 /* Aggregate types must lower constructors to initialization of 5558 individual elements. The exception is that a CONSTRUCTOR node 5559 with no elements indicates zero-initialization of the whole. */ 5560 if (vec_safe_is_empty (elts)) 5561 { 5562 if (notify_temp_creation) 5563 return GS_OK; 5564 5565 /* The var will be initialized and so appear on lhs of 5566 assignment, it can't be TREE_READONLY anymore. */ 5567 if (VAR_P (object)) 5568 TREE_READONLY (object) = 0; 5569 5570 is_empty_ctor = true; 5571 break; 5572 } 5573 5574 /* Fetch information about the constructor to direct later processing. 5575 We might want to make static versions of it in various cases, and 5576 can only do so if it known to be a valid constant initializer. */ 5577 valid_const_initializer 5578 = categorize_ctor_elements (ctor, &num_nonzero_elements, 5579 &num_unique_nonzero_elements, 5580 &num_ctor_elements, &complete_p); 5581 5582 /* If a const aggregate variable is being initialized, then it 5583 should never be a lose to promote the variable to be static. */ 5584 if (valid_const_initializer 5585 && num_nonzero_elements > 1 5586 && TREE_READONLY (object) 5587 && VAR_P (object) 5588 && !DECL_REGISTER (object) 5589 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object) 5590 || DECL_MERGEABLE (object)) 5591 /* For ctors that have many repeated nonzero elements 5592 represented through RANGE_EXPRs, prefer initializing 5593 those through runtime loops over copies of large amounts 5594 of data from readonly data section. */ 5595 && (num_unique_nonzero_elements 5596 > num_nonzero_elements / unique_nonzero_ratio 5597 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) 5598 <= (unsigned HOST_WIDE_INT) min_unique_size))) 5599 { 5600 if (notify_temp_creation) 5601 return GS_ERROR; 5602 5603 DECL_INITIAL (object) = ctor; 5604 TREE_STATIC (object) = 1; 5605 if (!DECL_NAME (object) || DECL_NAMELESS (object)) 5606 DECL_NAME (object) = create_tmp_var_name ("C"); 5607 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL); 5608 5609 /* ??? C++ doesn't automatically append a .<number> to the 5610 assembler name, and even when it does, it looks at FE private 5611 data structures to figure out what that number should be, 5612 which are not set for this variable. I suppose this is 5613 important for local statics for inline functions, which aren't 5614 "local" in the object file sense. So in order to get a unique 5615 TU-local symbol, we must invoke the lhd version now. */ 5616 lhd_set_decl_assembler_name (object); 5617 5618 *expr_p = NULL_TREE; 5619 break; 5620 } 5621 5622 /* The var will be initialized and so appear on lhs of 5623 assignment, it can't be TREE_READONLY anymore. */ 5624 if (VAR_P (object) && !notify_temp_creation) 5625 TREE_READONLY (object) = 0; 5626 5627 /* If there are "lots" of initialized elements, even discounting 5628 those that are not address constants (and thus *must* be 5629 computed at runtime), then partition the constructor into 5630 constant and non-constant parts. Block copy the constant 5631 parts in, then generate code for the non-constant parts. */ 5632 /* TODO. There's code in cp/typeck.cc to do this. */ 5633 5634 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0) 5635 /* store_constructor will ignore the clearing of variable-sized 5636 objects. Initializers for such objects must explicitly set 5637 every field that needs to be set. */ 5638 cleared = false; 5639 else if (!complete_p) 5640 /* If the constructor isn't complete, clear the whole object 5641 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it. 5642 5643 ??? This ought not to be needed. For any element not present 5644 in the initializer, we should simply set them to zero. Except 5645 we'd need to *find* the elements that are not present, and that 5646 requires trickery to avoid quadratic compile-time behavior in 5647 large cases or excessive memory use in small cases. */ 5648 cleared = !CONSTRUCTOR_NO_CLEARING (ctor); 5649 else if (num_ctor_elements - num_nonzero_elements 5650 > CLEAR_RATIO (optimize_function_for_speed_p (cfun)) 5651 && num_nonzero_elements < num_ctor_elements / 4) 5652 /* If there are "lots" of zeros, it's more efficient to clear 5653 the memory and then set the nonzero elements. */ 5654 cleared = true; 5655 else if (ensure_single_access && num_nonzero_elements == 0) 5656 /* If a single access to the target must be ensured and all elements 5657 are zero, then it's optimal to clear whatever their number. */ 5658 cleared = true; 5659 else 5660 cleared = false; 5661 5662 /* If there are "lots" of initialized elements, and all of them 5663 are valid address constants, then the entire initializer can 5664 be dropped to memory, and then memcpy'd out. Don't do this 5665 for sparse arrays, though, as it's more efficient to follow 5666 the standard CONSTRUCTOR behavior of memset followed by 5667 individual element initialization. Also don't do this for small 5668 all-zero initializers (which aren't big enough to merit 5669 clearing), and don't try to make bitwise copies of 5670 TREE_ADDRESSABLE types. */ 5671 if (valid_const_initializer 5672 && complete_p 5673 && !(cleared || num_nonzero_elements == 0) 5674 && !TREE_ADDRESSABLE (type)) 5675 { 5676 HOST_WIDE_INT size = int_size_in_bytes (type); 5677 unsigned int align; 5678 5679 /* ??? We can still get unbounded array types, at least 5680 from the C++ front end. This seems wrong, but attempt 5681 to work around it for now. */ 5682 if (size < 0) 5683 { 5684 size = int_size_in_bytes (TREE_TYPE (object)); 5685 if (size >= 0) 5686 TREE_TYPE (ctor) = type = TREE_TYPE (object); 5687 } 5688 5689 /* Find the maximum alignment we can assume for the object. */ 5690 /* ??? Make use of DECL_OFFSET_ALIGN. */ 5691 if (DECL_P (object)) 5692 align = DECL_ALIGN (object); 5693 else 5694 align = TYPE_ALIGN (type); 5695 5696 /* Do a block move either if the size is so small as to make 5697 each individual move a sub-unit move on average, or if it 5698 is so large as to make individual moves inefficient. */ 5699 if (size > 0 5700 && num_nonzero_elements > 1 5701 /* For ctors that have many repeated nonzero elements 5702 represented through RANGE_EXPRs, prefer initializing 5703 those through runtime loops over copies of large amounts 5704 of data from readonly data section. */ 5705 && (num_unique_nonzero_elements 5706 > num_nonzero_elements / unique_nonzero_ratio 5707 || size <= min_unique_size) 5708 && (size < num_nonzero_elements 5709 || !can_move_by_pieces (size, align))) 5710 { 5711 if (notify_temp_creation) 5712 return GS_ERROR; 5713 5714 walk_tree (&ctor, force_labels_r, NULL, NULL); 5715 ctor = tree_output_constant_def (ctor); 5716 if (!useless_type_conversion_p (type, TREE_TYPE (ctor))) 5717 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor); 5718 TREE_OPERAND (*expr_p, 1) = ctor; 5719 5720 /* This is no longer an assignment of a CONSTRUCTOR, but 5721 we still may have processing to do on the LHS. So 5722 pretend we didn't do anything here to let that happen. */ 5723 return GS_UNHANDLED; 5724 } 5725 } 5726 5727 /* If a single access to the target must be ensured and there are 5728 nonzero elements or the zero elements are not assigned en masse, 5729 initialize the target from a temporary. */ 5730 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared)) 5731 { 5732 if (notify_temp_creation) 5733 return GS_ERROR; 5734 5735 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type)); 5736 TREE_OPERAND (*expr_p, 0) = temp; 5737 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), 5738 *expr_p, 5739 build2 (MODIFY_EXPR, void_type_node, 5740 object, temp)); 5741 return GS_OK; 5742 } 5743 5744 if (notify_temp_creation) 5745 return GS_OK; 5746 5747 /* If there are nonzero elements and if needed, pre-evaluate to capture 5748 elements overlapping with the lhs into temporaries. We must do this 5749 before clearing to fetch the values before they are zeroed-out. */ 5750 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR) 5751 { 5752 preeval_data.lhs_base_decl = get_base_address (object); 5753 if (!DECL_P (preeval_data.lhs_base_decl)) 5754 preeval_data.lhs_base_decl = NULL; 5755 preeval_data.lhs_alias_set = get_alias_set (object); 5756 5757 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1), 5758 pre_p, post_p, &preeval_data); 5759 } 5760 5761 bool ctor_has_side_effects_p 5762 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1)); 5763 5764 if (cleared) 5765 { 5766 /* Zap the CONSTRUCTOR element list, which simplifies this case. 5767 Note that we still have to gimplify, in order to handle the 5768 case of variable sized types. Avoid shared tree structures. */ 5769 CONSTRUCTOR_ELTS (ctor) = NULL; 5770 TREE_SIDE_EFFECTS (ctor) = 0; 5771 object = unshare_expr (object); 5772 gimplify_stmt (expr_p, pre_p); 5773 } 5774 5775 /* If we have not block cleared the object, or if there are nonzero 5776 elements in the constructor, or if the constructor has side effects, 5777 add assignments to the individual scalar fields of the object. */ 5778 if (!cleared 5779 || num_nonzero_elements > 0 5780 || ctor_has_side_effects_p) 5781 gimplify_init_ctor_eval (object, elts, pre_p, cleared); 5782 5783 *expr_p = NULL_TREE; 5784 } 5785 break; 5786 5787 case COMPLEX_TYPE: 5788 { 5789 tree r, i; 5790 5791 if (notify_temp_creation) 5792 return GS_OK; 5793 5794 /* Extract the real and imaginary parts out of the ctor. */ 5795 gcc_assert (elts->length () == 2); 5796 r = (*elts)[0].value; 5797 i = (*elts)[1].value; 5798 if (r == NULL || i == NULL) 5799 { 5800 tree zero = build_zero_cst (TREE_TYPE (type)); 5801 if (r == NULL) 5802 r = zero; 5803 if (i == NULL) 5804 i = zero; 5805 } 5806 5807 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to 5808 represent creation of a complex value. */ 5809 if (TREE_CONSTANT (r) && TREE_CONSTANT (i)) 5810 { 5811 ctor = build_complex (type, r, i); 5812 TREE_OPERAND (*expr_p, 1) = ctor; 5813 } 5814 else 5815 { 5816 ctor = build2 (COMPLEX_EXPR, type, r, i); 5817 TREE_OPERAND (*expr_p, 1) = ctor; 5818 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), 5819 pre_p, 5820 post_p, 5821 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)), 5822 fb_rvalue); 5823 } 5824 } 5825 break; 5826 5827 case VECTOR_TYPE: 5828 { 5829 unsigned HOST_WIDE_INT ix; 5830 constructor_elt *ce; 5831 5832 if (notify_temp_creation) 5833 return GS_OK; 5834 5835 /* Vector types use CONSTRUCTOR all the way through gimple 5836 compilation as a general initializer. */ 5837 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce) 5838 { 5839 enum gimplify_status tret; 5840 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val, 5841 fb_rvalue); 5842 if (tret == GS_ERROR) 5843 ret = GS_ERROR; 5844 else if (TREE_STATIC (ctor) 5845 && !initializer_constant_valid_p (ce->value, 5846 TREE_TYPE (ce->value))) 5847 TREE_STATIC (ctor) = 0; 5848 } 5849 recompute_constructor_flags (ctor); 5850 5851 /* Go ahead and simplify constant constructors to VECTOR_CST. */ 5852 if (TREE_CONSTANT (ctor)) 5853 { 5854 bool constant_p = true; 5855 tree value; 5856 5857 /* Even when ctor is constant, it might contain non-*_CST 5858 elements, such as addresses or trapping values like 5859 1.0/0.0 - 1.0/0.0. Such expressions don't belong 5860 in VECTOR_CST nodes. */ 5861 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value) 5862 if (!CONSTANT_CLASS_P (value)) 5863 { 5864 constant_p = false; 5865 break; 5866 } 5867 5868 if (constant_p) 5869 { 5870 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts); 5871 break; 5872 } 5873 } 5874 5875 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0))) 5876 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p); 5877 } 5878 break; 5879 5880 default: 5881 /* So how did we get a CONSTRUCTOR for a scalar type? */ 5882 gcc_unreachable (); 5883 } 5884 5885 if (ret == GS_ERROR) 5886 return GS_ERROR; 5887 /* If we have gimplified both sides of the initializer but have 5888 not emitted an assignment, do so now. */ 5889 if (*expr_p 5890 /* If the type is an empty type, we don't need to emit the 5891 assignment. */ 5892 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) 5893 { 5894 tree lhs = TREE_OPERAND (*expr_p, 0); 5895 tree rhs = TREE_OPERAND (*expr_p, 1); 5896 if (want_value && object == lhs) 5897 lhs = unshare_expr (lhs); 5898 gassign *init = gimple_build_assign (lhs, rhs); 5899 gimplify_seq_add_stmt (pre_p, init); 5900 } 5901 if (want_value) 5902 { 5903 *expr_p = object; 5904 ret = GS_OK; 5905 } 5906 else 5907 { 5908 *expr_p = NULL; 5909 ret = GS_ALL_DONE; 5910 } 5911 5912 /* If the user requests to initialize automatic variables, we 5913 should initialize paddings inside the variable. Add a call to 5914 __builtin_clear_pading (&object, 0, for_auto_init = true) to 5915 initialize paddings of object always to zero regardless of 5916 INIT_TYPE. Note, we will not insert this call if the aggregate 5917 variable has be completely cleared already or it's initialized 5918 with an empty constructor. We cannot insert this call if the 5919 variable is a gimple register since __builtin_clear_padding will take 5920 the address of the variable. As a result, if a long double/_Complex long 5921 double variable will be spilled into stack later, its padding cannot 5922 be cleared with __builtin_clear_padding. We should clear its padding 5923 when it is spilled into memory. */ 5924 if (is_init_expr 5925 && !is_gimple_reg (object) 5926 && clear_padding_type_may_have_padding_p (type) 5927 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor) 5928 || !AGGREGATE_TYPE_P (type)) 5929 && is_var_need_auto_init (object)) 5930 gimple_add_padding_init_for_auto_var (object, false, pre_p); 5931 5932 return ret; 5933 } 5934 5935 /* Given a pointer value OP0, return a simplified version of an 5936 indirection through OP0, or NULL_TREE if no simplification is 5937 possible. This may only be applied to a rhs of an expression. 5938 Note that the resulting type may be different from the type pointed 5939 to in the sense that it is still compatible from the langhooks 5940 point of view. */ 5941 5942 static tree 5943 gimple_fold_indirect_ref_rhs (tree t) 5944 { 5945 return gimple_fold_indirect_ref (t); 5946 } 5947 5948 /* Subroutine of gimplify_modify_expr to do simplifications of 5949 MODIFY_EXPRs based on the code of the RHS. We loop for as long as 5950 something changes. */ 5951 5952 static enum gimplify_status 5953 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, 5954 gimple_seq *pre_p, gimple_seq *post_p, 5955 bool want_value) 5956 { 5957 enum gimplify_status ret = GS_UNHANDLED; 5958 bool changed; 5959 5960 do 5961 { 5962 changed = false; 5963 switch (TREE_CODE (*from_p)) 5964 { 5965 case VAR_DECL: 5966 /* If we're assigning from a read-only variable initialized with 5967 a constructor and not volatile, do the direct assignment from 5968 the constructor, but only if the target is not volatile either 5969 since this latter assignment might end up being done on a per 5970 field basis. However, if the target is volatile and the type 5971 is aggregate and non-addressable, gimplify_init_constructor 5972 knows that it needs to ensure a single access to the target 5973 and it will return GS_OK only in this case. */ 5974 if (TREE_READONLY (*from_p) 5975 && DECL_INITIAL (*from_p) 5976 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR 5977 && !TREE_THIS_VOLATILE (*from_p) 5978 && (!TREE_THIS_VOLATILE (*to_p) 5979 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p)) 5980 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p))))) 5981 { 5982 tree old_from = *from_p; 5983 enum gimplify_status subret; 5984 5985 /* Move the constructor into the RHS. */ 5986 *from_p = unshare_expr (DECL_INITIAL (*from_p)); 5987 5988 /* Let's see if gimplify_init_constructor will need to put 5989 it in memory. */ 5990 subret = gimplify_init_constructor (expr_p, NULL, NULL, 5991 false, true); 5992 if (subret == GS_ERROR) 5993 { 5994 /* If so, revert the change. */ 5995 *from_p = old_from; 5996 } 5997 else 5998 { 5999 ret = GS_OK; 6000 changed = true; 6001 } 6002 } 6003 break; 6004 case INDIRECT_REF: 6005 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p))) 6006 /* If we have code like 6007 6008 *(const A*)(A*)&x 6009 6010 where the type of "x" is a (possibly cv-qualified variant 6011 of "A"), treat the entire expression as identical to "x". 6012 This kind of code arises in C++ when an object is bound 6013 to a const reference, and if "x" is a TARGET_EXPR we want 6014 to take advantage of the optimization below. But not if 6015 the type is TREE_ADDRESSABLE; then C++17 says that the 6016 TARGET_EXPR needs to be a temporary. */ 6017 if (tree t 6018 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0))) 6019 { 6020 bool volatile_p = TREE_THIS_VOLATILE (*from_p); 6021 if (TREE_THIS_VOLATILE (t) != volatile_p) 6022 { 6023 if (DECL_P (t)) 6024 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p), 6025 build_fold_addr_expr (t)); 6026 if (REFERENCE_CLASS_P (t)) 6027 TREE_THIS_VOLATILE (t) = volatile_p; 6028 } 6029 *from_p = t; 6030 ret = GS_OK; 6031 changed = true; 6032 } 6033 break; 6034 6035 case TARGET_EXPR: 6036 { 6037 /* If we are initializing something from a TARGET_EXPR, strip the 6038 TARGET_EXPR and initialize it directly, if possible. This can't 6039 be done if the initializer is void, since that implies that the 6040 temporary is set in some non-trivial way. 6041 6042 ??? What about code that pulls out the temp and uses it 6043 elsewhere? I think that such code never uses the TARGET_EXPR as 6044 an initializer. If I'm wrong, we'll die because the temp won't 6045 have any RTL. In that case, I guess we'll need to replace 6046 references somehow. */ 6047 tree init = TARGET_EXPR_INITIAL (*from_p); 6048 6049 if (init 6050 && (TREE_CODE (*expr_p) != MODIFY_EXPR 6051 || !TARGET_EXPR_NO_ELIDE (*from_p)) 6052 && !VOID_TYPE_P (TREE_TYPE (init))) 6053 { 6054 *from_p = init; 6055 ret = GS_OK; 6056 changed = true; 6057 } 6058 } 6059 break; 6060 6061 case COMPOUND_EXPR: 6062 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be 6063 caught. */ 6064 gimplify_compound_expr (from_p, pre_p, true); 6065 ret = GS_OK; 6066 changed = true; 6067 break; 6068 6069 case CONSTRUCTOR: 6070 /* If we already made some changes, let the front end have a 6071 crack at this before we break it down. */ 6072 if (ret != GS_UNHANDLED) 6073 break; 6074 6075 /* If we're initializing from a CONSTRUCTOR, break this into 6076 individual MODIFY_EXPRs. */ 6077 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value, 6078 false); 6079 return ret; 6080 6081 case COND_EXPR: 6082 /* If we're assigning to a non-register type, push the assignment 6083 down into the branches. This is mandatory for ADDRESSABLE types, 6084 since we cannot generate temporaries for such, but it saves a 6085 copy in other cases as well. */ 6086 if (!is_gimple_reg_type (TREE_TYPE (*from_p))) 6087 { 6088 /* This code should mirror the code in gimplify_cond_expr. */ 6089 enum tree_code code = TREE_CODE (*expr_p); 6090 tree cond = *from_p; 6091 tree result = *to_p; 6092 6093 ret = gimplify_expr (&result, pre_p, post_p, 6094 is_gimple_lvalue, fb_lvalue); 6095 if (ret != GS_ERROR) 6096 ret = GS_OK; 6097 6098 /* If we are going to write RESULT more than once, clear 6099 TREE_READONLY flag, otherwise we might incorrectly promote 6100 the variable to static const and initialize it at compile 6101 time in one of the branches. */ 6102 if (VAR_P (result) 6103 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node 6104 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) 6105 TREE_READONLY (result) = 0; 6106 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node) 6107 TREE_OPERAND (cond, 1) 6108 = build2 (code, void_type_node, result, 6109 TREE_OPERAND (cond, 1)); 6110 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) 6111 TREE_OPERAND (cond, 2) 6112 = build2 (code, void_type_node, unshare_expr (result), 6113 TREE_OPERAND (cond, 2)); 6114 6115 TREE_TYPE (cond) = void_type_node; 6116 recalculate_side_effects (cond); 6117 6118 if (want_value) 6119 { 6120 gimplify_and_add (cond, pre_p); 6121 *expr_p = unshare_expr (result); 6122 } 6123 else 6124 *expr_p = cond; 6125 return ret; 6126 } 6127 break; 6128 6129 case CALL_EXPR: 6130 /* For calls that return in memory, give *to_p as the CALL_EXPR's 6131 return slot so that we don't generate a temporary. */ 6132 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p) 6133 && aggregate_value_p (*from_p, *from_p)) 6134 { 6135 bool use_target; 6136 6137 if (!(rhs_predicate_for (*to_p))(*from_p)) 6138 /* If we need a temporary, *to_p isn't accurate. */ 6139 use_target = false; 6140 /* It's OK to use the return slot directly unless it's an NRV. */ 6141 else if (TREE_CODE (*to_p) == RESULT_DECL 6142 && DECL_NAME (*to_p) == NULL_TREE 6143 && needs_to_live_in_memory (*to_p)) 6144 use_target = true; 6145 else if (is_gimple_reg_type (TREE_TYPE (*to_p)) 6146 || (DECL_P (*to_p) && DECL_REGISTER (*to_p))) 6147 /* Don't force regs into memory. */ 6148 use_target = false; 6149 else if (TREE_CODE (*expr_p) == INIT_EXPR) 6150 /* It's OK to use the target directly if it's being 6151 initialized. */ 6152 use_target = true; 6153 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) 6154 != INTEGER_CST) 6155 /* Always use the target and thus RSO for variable-sized types. 6156 GIMPLE cannot deal with a variable-sized assignment 6157 embedded in a call statement. */ 6158 use_target = true; 6159 else if (TREE_CODE (*to_p) != SSA_NAME 6160 && (!is_gimple_variable (*to_p) 6161 || needs_to_live_in_memory (*to_p))) 6162 /* Don't use the original target if it's already addressable; 6163 if its address escapes, and the called function uses the 6164 NRV optimization, a conforming program could see *to_p 6165 change before the called function returns; see c++/19317. 6166 When optimizing, the return_slot pass marks more functions 6167 as safe after we have escape info. */ 6168 use_target = false; 6169 else 6170 use_target = true; 6171 6172 if (use_target) 6173 { 6174 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1; 6175 mark_addressable (*to_p); 6176 } 6177 } 6178 break; 6179 6180 case WITH_SIZE_EXPR: 6181 /* Likewise for calls that return an aggregate of non-constant size, 6182 since we would not be able to generate a temporary at all. */ 6183 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR) 6184 { 6185 *from_p = TREE_OPERAND (*from_p, 0); 6186 /* We don't change ret in this case because the 6187 WITH_SIZE_EXPR might have been added in 6188 gimplify_modify_expr, so returning GS_OK would lead to an 6189 infinite loop. */ 6190 changed = true; 6191 } 6192 break; 6193 6194 /* If we're initializing from a container, push the initialization 6195 inside it. */ 6196 case CLEANUP_POINT_EXPR: 6197 case BIND_EXPR: 6198 case STATEMENT_LIST: 6199 { 6200 tree wrap = *from_p; 6201 tree t; 6202 6203 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval, 6204 fb_lvalue); 6205 if (ret != GS_ERROR) 6206 ret = GS_OK; 6207 6208 t = voidify_wrapper_expr (wrap, *expr_p); 6209 gcc_assert (t == *expr_p); 6210 6211 if (want_value) 6212 { 6213 gimplify_and_add (wrap, pre_p); 6214 *expr_p = unshare_expr (*to_p); 6215 } 6216 else 6217 *expr_p = wrap; 6218 return GS_OK; 6219 } 6220 6221 case NOP_EXPR: 6222 /* Pull out compound literal expressions from a NOP_EXPR. 6223 Those are created in the C FE to drop qualifiers during 6224 lvalue conversion. */ 6225 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR) 6226 && tree_ssa_useless_type_conversion (*from_p)) 6227 { 6228 *from_p = TREE_OPERAND (*from_p, 0); 6229 ret = GS_OK; 6230 changed = true; 6231 } 6232 break; 6233 6234 case COMPOUND_LITERAL_EXPR: 6235 { 6236 tree complit = TREE_OPERAND (*expr_p, 1); 6237 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit); 6238 tree decl = DECL_EXPR_DECL (decl_s); 6239 tree init = DECL_INITIAL (decl); 6240 6241 /* struct T x = (struct T) { 0, 1, 2 } can be optimized 6242 into struct T x = { 0, 1, 2 } if the address of the 6243 compound literal has never been taken. */ 6244 if (!TREE_ADDRESSABLE (complit) 6245 && !TREE_ADDRESSABLE (decl) 6246 && init) 6247 { 6248 *expr_p = copy_node (*expr_p); 6249 TREE_OPERAND (*expr_p, 1) = init; 6250 return GS_OK; 6251 } 6252 } 6253 6254 default: 6255 break; 6256 } 6257 } 6258 while (changed); 6259 6260 return ret; 6261 } 6262 6263 6264 /* Return true if T looks like a valid GIMPLE statement. */ 6265 6266 static bool 6267 is_gimple_stmt (tree t) 6268 { 6269 const enum tree_code code = TREE_CODE (t); 6270 6271 switch (code) 6272 { 6273 case NOP_EXPR: 6274 /* The only valid NOP_EXPR is the empty statement. */ 6275 return IS_EMPTY_STMT (t); 6276 6277 case BIND_EXPR: 6278 case COND_EXPR: 6279 /* These are only valid if they're void. */ 6280 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t)); 6281 6282 case SWITCH_EXPR: 6283 case GOTO_EXPR: 6284 case RETURN_EXPR: 6285 case LABEL_EXPR: 6286 case CASE_LABEL_EXPR: 6287 case TRY_CATCH_EXPR: 6288 case TRY_FINALLY_EXPR: 6289 case EH_FILTER_EXPR: 6290 case CATCH_EXPR: 6291 case ASM_EXPR: 6292 case STATEMENT_LIST: 6293 case OACC_PARALLEL: 6294 case OACC_KERNELS: 6295 case OACC_SERIAL: 6296 case OACC_DATA: 6297 case OACC_HOST_DATA: 6298 case OACC_DECLARE: 6299 case OACC_UPDATE: 6300 case OACC_ENTER_DATA: 6301 case OACC_EXIT_DATA: 6302 case OACC_CACHE: 6303 case OMP_PARALLEL: 6304 case OMP_FOR: 6305 case OMP_SIMD: 6306 case OMP_DISTRIBUTE: 6307 case OMP_LOOP: 6308 case OACC_LOOP: 6309 case OMP_SCAN: 6310 case OMP_SCOPE: 6311 case OMP_SECTIONS: 6312 case OMP_SECTION: 6313 case OMP_STRUCTURED_BLOCK: 6314 case OMP_SINGLE: 6315 case OMP_MASTER: 6316 case OMP_MASKED: 6317 case OMP_TASKGROUP: 6318 case OMP_ORDERED: 6319 case OMP_CRITICAL: 6320 case OMP_TASK: 6321 case OMP_TARGET: 6322 case OMP_TARGET_DATA: 6323 case OMP_TARGET_UPDATE: 6324 case OMP_TARGET_ENTER_DATA: 6325 case OMP_TARGET_EXIT_DATA: 6326 case OMP_TASKLOOP: 6327 case OMP_TEAMS: 6328 /* These are always void. */ 6329 return true; 6330 6331 case CALL_EXPR: 6332 case MODIFY_EXPR: 6333 case PREDICT_EXPR: 6334 /* These are valid regardless of their type. */ 6335 return true; 6336 6337 default: 6338 return false; 6339 } 6340 } 6341 6342 6343 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is 6344 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register. 6345 6346 IMPORTANT NOTE: This promotion is performed by introducing a load of the 6347 other, unmodified part of the complex object just before the total store. 6348 As a consequence, if the object is still uninitialized, an undefined value 6349 will be loaded into a register, which may result in a spurious exception 6350 if the register is floating-point and the value happens to be a signaling 6351 NaN for example. Then the fully-fledged complex operations lowering pass 6352 followed by a DCE pass are necessary in order to fix things up. */ 6353 6354 static enum gimplify_status 6355 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p, 6356 bool want_value) 6357 { 6358 enum tree_code code, ocode; 6359 tree lhs, rhs, new_rhs, other, realpart, imagpart; 6360 6361 lhs = TREE_OPERAND (*expr_p, 0); 6362 rhs = TREE_OPERAND (*expr_p, 1); 6363 code = TREE_CODE (lhs); 6364 lhs = TREE_OPERAND (lhs, 0); 6365 6366 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; 6367 other = build1 (ocode, TREE_TYPE (rhs), lhs); 6368 suppress_warning (other); 6369 other = get_formal_tmp_var (other, pre_p); 6370 6371 realpart = code == REALPART_EXPR ? rhs : other; 6372 imagpart = code == REALPART_EXPR ? other : rhs; 6373 6374 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart)) 6375 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart); 6376 else 6377 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart); 6378 6379 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs)); 6380 *expr_p = (want_value) ? rhs : NULL_TREE; 6381 6382 return GS_ALL_DONE; 6383 } 6384 6385 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P. 6386 6387 modify_expr 6388 : varname '=' rhs 6389 | '*' ID '=' rhs 6390 6391 PRE_P points to the list where side effects that must happen before 6392 *EXPR_P should be stored. 6393 6394 POST_P points to the list where side effects that must happen after 6395 *EXPR_P should be stored. 6396 6397 WANT_VALUE is nonzero iff we want to use the value of this expression 6398 in another expression. */ 6399 6400 static enum gimplify_status 6401 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 6402 bool want_value) 6403 { 6404 tree *from_p = &TREE_OPERAND (*expr_p, 1); 6405 tree *to_p = &TREE_OPERAND (*expr_p, 0); 6406 enum gimplify_status ret = GS_UNHANDLED; 6407 gimple *assign; 6408 location_t loc = EXPR_LOCATION (*expr_p); 6409 gimple_stmt_iterator gsi; 6410 6411 if (error_operand_p (*from_p) || error_operand_p (*to_p)) 6412 return GS_ERROR; 6413 6414 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR 6415 || TREE_CODE (*expr_p) == INIT_EXPR); 6416 6417 /* Trying to simplify a clobber using normal logic doesn't work, 6418 so handle it here. */ 6419 if (TREE_CLOBBER_P (*from_p)) 6420 { 6421 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 6422 if (ret == GS_ERROR) 6423 return ret; 6424 gcc_assert (!want_value); 6425 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF) 6426 { 6427 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p), 6428 pre_p, post_p); 6429 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr); 6430 } 6431 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p)); 6432 *expr_p = NULL; 6433 return GS_ALL_DONE; 6434 } 6435 6436 /* Convert initialization from an empty variable-size CONSTRUCTOR to 6437 memset. */ 6438 if (TREE_TYPE (*from_p) != error_mark_node 6439 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p)) 6440 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p))) 6441 && TREE_CODE (*from_p) == CONSTRUCTOR 6442 && CONSTRUCTOR_NELTS (*from_p) == 0) 6443 { 6444 maybe_with_size_expr (from_p); 6445 gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR); 6446 return gimplify_modify_expr_to_memset (expr_p, 6447 TREE_OPERAND (*from_p, 1), 6448 want_value, pre_p); 6449 } 6450 6451 /* Insert pointer conversions required by the middle-end that are not 6452 required by the frontend. This fixes middle-end type checking for 6453 for example gcc.dg/redecl-6.c. */ 6454 if (POINTER_TYPE_P (TREE_TYPE (*to_p))) 6455 { 6456 STRIP_USELESS_TYPE_CONVERSION (*from_p); 6457 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p))) 6458 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p); 6459 } 6460 6461 /* See if any simplifications can be done based on what the RHS is. */ 6462 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 6463 want_value); 6464 if (ret != GS_UNHANDLED) 6465 return ret; 6466 6467 /* For empty types only gimplify the left hand side and right hand 6468 side as statements and throw away the assignment. Do this after 6469 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable 6470 types properly. */ 6471 if (is_empty_type (TREE_TYPE (*from_p)) 6472 && !want_value 6473 /* Don't do this for calls that return addressable types, expand_call 6474 relies on those having a lhs. */ 6475 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p)) 6476 && TREE_CODE (*from_p) == CALL_EXPR)) 6477 { 6478 gimplify_stmt (from_p, pre_p); 6479 gimplify_stmt (to_p, pre_p); 6480 *expr_p = NULL_TREE; 6481 return GS_ALL_DONE; 6482 } 6483 6484 /* If the value being copied is of variable width, compute the length 6485 of the copy into a WITH_SIZE_EXPR. Note that we need to do this 6486 before gimplifying any of the operands so that we can resolve any 6487 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses 6488 the size of the expression to be copied, not of the destination, so 6489 that is what we must do here. */ 6490 maybe_with_size_expr (from_p); 6491 6492 /* As a special case, we have to temporarily allow for assignments 6493 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is 6494 a toplevel statement, when gimplifying the GENERIC expression 6495 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple 6496 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>. 6497 6498 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To 6499 prevent gimplify_expr from trying to create a new temporary for 6500 foo's LHS, we tell it that it should only gimplify until it 6501 reaches the CALL_EXPR. On return from gimplify_expr, the newly 6502 created GIMPLE_CALL <foo> will be the last statement in *PRE_P 6503 and all we need to do here is set 'a' to be its LHS. */ 6504 6505 /* Gimplify the RHS first for C++17 and bug 71104. */ 6506 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p); 6507 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue); 6508 if (ret == GS_ERROR) 6509 return ret; 6510 6511 /* Then gimplify the LHS. */ 6512 /* If we gimplified the RHS to a CALL_EXPR and that call may return 6513 twice we have to make sure to gimplify into non-SSA as otherwise 6514 the abnormal edge added later will make those defs not dominate 6515 their uses. 6516 ??? Technically this applies only to the registers used in the 6517 resulting non-register *TO_P. */ 6518 bool saved_into_ssa = gimplify_ctxp->into_ssa; 6519 if (saved_into_ssa 6520 && TREE_CODE (*from_p) == CALL_EXPR 6521 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE) 6522 gimplify_ctxp->into_ssa = false; 6523 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); 6524 gimplify_ctxp->into_ssa = saved_into_ssa; 6525 if (ret == GS_ERROR) 6526 return ret; 6527 6528 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial 6529 guess for the predicate was wrong. */ 6530 gimple_predicate final_pred = rhs_predicate_for (*to_p); 6531 if (final_pred != initial_pred) 6532 { 6533 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue); 6534 if (ret == GS_ERROR) 6535 return ret; 6536 } 6537 6538 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type 6539 size as argument to the call. */ 6540 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) 6541 { 6542 tree call = TREE_OPERAND (*from_p, 0); 6543 tree vlasize = TREE_OPERAND (*from_p, 1); 6544 6545 if (TREE_CODE (call) == CALL_EXPR 6546 && CALL_EXPR_IFN (call) == IFN_VA_ARG) 6547 { 6548 int nargs = call_expr_nargs (call); 6549 tree type = TREE_TYPE (call); 6550 tree ap = CALL_EXPR_ARG (call, 0); 6551 tree tag = CALL_EXPR_ARG (call, 1); 6552 tree aptag = CALL_EXPR_ARG (call, 2); 6553 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call), 6554 IFN_VA_ARG, type, 6555 nargs + 1, ap, tag, 6556 aptag, vlasize); 6557 TREE_OPERAND (*from_p, 0) = newcall; 6558 } 6559 } 6560 6561 /* Now see if the above changed *from_p to something we handle specially. */ 6562 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, 6563 want_value); 6564 if (ret != GS_UNHANDLED) 6565 return ret; 6566 6567 /* If we've got a variable sized assignment between two lvalues (i.e. does 6568 not involve a call), then we can make things a bit more straightforward 6569 by converting the assignment to memcpy or memset. */ 6570 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) 6571 { 6572 tree from = TREE_OPERAND (*from_p, 0); 6573 tree size = TREE_OPERAND (*from_p, 1); 6574 6575 if (TREE_CODE (from) == CONSTRUCTOR) 6576 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p); 6577 else if (is_gimple_addressable (from) 6578 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p))) 6579 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from)))) 6580 { 6581 *from_p = from; 6582 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value, 6583 pre_p); 6584 } 6585 } 6586 6587 /* Transform partial stores to non-addressable complex variables into 6588 total stores. This allows us to use real instead of virtual operands 6589 for these variables, which improves optimization. */ 6590 if ((TREE_CODE (*to_p) == REALPART_EXPR 6591 || TREE_CODE (*to_p) == IMAGPART_EXPR) 6592 && is_gimple_reg (TREE_OPERAND (*to_p, 0))) 6593 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); 6594 6595 /* Try to alleviate the effects of the gimplification creating artificial 6596 temporaries (see for example is_gimple_reg_rhs) on the debug info, but 6597 make sure not to create DECL_DEBUG_EXPR links across functions. */ 6598 if (!gimplify_ctxp->into_ssa 6599 && VAR_P (*from_p) 6600 && DECL_IGNORED_P (*from_p) 6601 && DECL_P (*to_p) 6602 && !DECL_IGNORED_P (*to_p) 6603 && decl_function_context (*to_p) == current_function_decl 6604 && decl_function_context (*from_p) == current_function_decl) 6605 { 6606 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p)) 6607 DECL_NAME (*from_p) 6608 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p))); 6609 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1; 6610 SET_DECL_DEBUG_EXPR (*from_p, *to_p); 6611 } 6612 6613 if (want_value && TREE_THIS_VOLATILE (*to_p)) 6614 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p); 6615 6616 if (TREE_CODE (*from_p) == CALL_EXPR) 6617 { 6618 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL 6619 instead of a GIMPLE_ASSIGN. */ 6620 gcall *call_stmt; 6621 if (CALL_EXPR_FN (*from_p) == NULL_TREE) 6622 { 6623 /* Gimplify internal functions created in the FEs. */ 6624 int nargs = call_expr_nargs (*from_p), i; 6625 enum internal_fn ifn = CALL_EXPR_IFN (*from_p); 6626 auto_vec<tree> vargs (nargs); 6627 6628 for (i = 0; i < nargs; i++) 6629 { 6630 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p, 6631 EXPR_LOCATION (*from_p)); 6632 vargs.quick_push (CALL_EXPR_ARG (*from_p, i)); 6633 } 6634 call_stmt = gimple_build_call_internal_vec (ifn, vargs); 6635 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p)); 6636 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p)); 6637 } 6638 else 6639 { 6640 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p)); 6641 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0); 6642 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p)); 6643 tree fndecl = get_callee_fndecl (*from_p); 6644 if (fndecl 6645 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT) 6646 && call_expr_nargs (*from_p) == 3) 6647 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3, 6648 CALL_EXPR_ARG (*from_p, 0), 6649 CALL_EXPR_ARG (*from_p, 1), 6650 CALL_EXPR_ARG (*from_p, 2)); 6651 else 6652 { 6653 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype); 6654 } 6655 } 6656 notice_special_calls (call_stmt); 6657 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p)) 6658 gimple_call_set_lhs (call_stmt, *to_p); 6659 else if (TREE_CODE (*to_p) == SSA_NAME) 6660 /* The above is somewhat premature, avoid ICEing later for a 6661 SSA name w/o a definition. We may have uses in the GIMPLE IL. 6662 ??? This doesn't make it a default-def. */ 6663 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop (); 6664 6665 assign = call_stmt; 6666 } 6667 else 6668 { 6669 assign = gimple_build_assign (*to_p, *from_p); 6670 gimple_set_location (assign, EXPR_LOCATION (*expr_p)); 6671 if (COMPARISON_CLASS_P (*from_p)) 6672 copy_warning (assign, *from_p); 6673 } 6674 6675 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) 6676 { 6677 /* We should have got an SSA name from the start. */ 6678 gcc_assert (TREE_CODE (*to_p) == SSA_NAME 6679 || ! gimple_in_ssa_p (cfun)); 6680 } 6681 6682 gimplify_seq_add_stmt (pre_p, assign); 6683 gsi = gsi_last (*pre_p); 6684 maybe_fold_stmt (&gsi); 6685 6686 if (want_value) 6687 { 6688 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p); 6689 return GS_OK; 6690 } 6691 else 6692 *expr_p = NULL; 6693 6694 return GS_ALL_DONE; 6695 } 6696 6697 /* Gimplify a comparison between two variable-sized objects. Do this 6698 with a call to BUILT_IN_MEMCMP. */ 6699 6700 static enum gimplify_status 6701 gimplify_variable_sized_compare (tree *expr_p) 6702 { 6703 location_t loc = EXPR_LOCATION (*expr_p); 6704 tree op0 = TREE_OPERAND (*expr_p, 0); 6705 tree op1 = TREE_OPERAND (*expr_p, 1); 6706 tree t, arg, dest, src, expr; 6707 6708 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0)); 6709 arg = unshare_expr (arg); 6710 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0); 6711 src = build_fold_addr_expr_loc (loc, op1); 6712 dest = build_fold_addr_expr_loc (loc, op0); 6713 t = builtin_decl_implicit (BUILT_IN_MEMCMP); 6714 t = build_call_expr_loc (loc, t, 3, dest, src, arg); 6715 6716 expr 6717 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node); 6718 SET_EXPR_LOCATION (expr, loc); 6719 *expr_p = expr; 6720 6721 return GS_OK; 6722 } 6723 6724 /* Gimplify a comparison between two aggregate objects of integral scalar 6725 mode as a comparison between the bitwise equivalent scalar values. */ 6726 6727 static enum gimplify_status 6728 gimplify_scalar_mode_aggregate_compare (tree *expr_p) 6729 { 6730 location_t loc = EXPR_LOCATION (*expr_p); 6731 tree op0 = TREE_OPERAND (*expr_p, 0); 6732 tree op1 = TREE_OPERAND (*expr_p, 1); 6733 6734 tree type = TREE_TYPE (op0); 6735 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1); 6736 6737 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0); 6738 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1); 6739 6740 *expr_p 6741 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1); 6742 6743 return GS_OK; 6744 } 6745 6746 /* Gimplify an expression sequence. This function gimplifies each 6747 expression and rewrites the original expression with the last 6748 expression of the sequence in GIMPLE form. 6749 6750 PRE_P points to the list where the side effects for all the 6751 expressions in the sequence will be emitted. 6752 6753 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */ 6754 6755 static enum gimplify_status 6756 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) 6757 { 6758 tree t = *expr_p; 6759 6760 do 6761 { 6762 tree *sub_p = &TREE_OPERAND (t, 0); 6763 6764 if (TREE_CODE (*sub_p) == COMPOUND_EXPR) 6765 gimplify_compound_expr (sub_p, pre_p, false); 6766 else 6767 gimplify_stmt (sub_p, pre_p); 6768 6769 t = TREE_OPERAND (t, 1); 6770 } 6771 while (TREE_CODE (t) == COMPOUND_EXPR); 6772 6773 *expr_p = t; 6774 if (want_value) 6775 return GS_OK; 6776 else 6777 { 6778 gimplify_stmt (expr_p, pre_p); 6779 return GS_ALL_DONE; 6780 } 6781 } 6782 6783 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to 6784 gimplify. After gimplification, EXPR_P will point to a new temporary 6785 that holds the original value of the SAVE_EXPR node. 6786 6787 PRE_P points to the list where side effects that must happen before 6788 *EXPR_P should be stored. */ 6789 6790 static enum gimplify_status 6791 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6792 { 6793 enum gimplify_status ret = GS_ALL_DONE; 6794 tree val; 6795 6796 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR); 6797 val = TREE_OPERAND (*expr_p, 0); 6798 6799 if (val && TREE_TYPE (val) == error_mark_node) 6800 return GS_ERROR; 6801 6802 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */ 6803 if (!SAVE_EXPR_RESOLVED_P (*expr_p)) 6804 { 6805 /* The operand may be a void-valued expression. It is 6806 being executed only for its side-effects. */ 6807 if (TREE_TYPE (val) == void_type_node) 6808 { 6809 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 6810 is_gimple_stmt, fb_none); 6811 val = NULL; 6812 } 6813 else 6814 /* The temporary may not be an SSA name as later abnormal and EH 6815 control flow may invalidate use/def domination. When in SSA 6816 form then assume there are no such issues and SAVE_EXPRs only 6817 appear via GENERIC foldings. */ 6818 val = get_initialized_tmp_var (val, pre_p, post_p, 6819 gimple_in_ssa_p (cfun)); 6820 6821 TREE_OPERAND (*expr_p, 0) = val; 6822 SAVE_EXPR_RESOLVED_P (*expr_p) = 1; 6823 } 6824 6825 *expr_p = val; 6826 6827 return ret; 6828 } 6829 6830 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P 6831 6832 unary_expr 6833 : ... 6834 | '&' varname 6835 ... 6836 6837 PRE_P points to the list where side effects that must happen before 6838 *EXPR_P should be stored. 6839 6840 POST_P points to the list where side effects that must happen after 6841 *EXPR_P should be stored. */ 6842 6843 static enum gimplify_status 6844 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6845 { 6846 tree expr = *expr_p; 6847 tree op0 = TREE_OPERAND (expr, 0); 6848 enum gimplify_status ret; 6849 location_t loc = EXPR_LOCATION (*expr_p); 6850 6851 switch (TREE_CODE (op0)) 6852 { 6853 case INDIRECT_REF: 6854 do_indirect_ref: 6855 /* Check if we are dealing with an expression of the form '&*ptr'. 6856 While the front end folds away '&*ptr' into 'ptr', these 6857 expressions may be generated internally by the compiler (e.g., 6858 builtins like __builtin_va_end). */ 6859 /* Caution: the silent array decomposition semantics we allow for 6860 ADDR_EXPR means we can't always discard the pair. */ 6861 /* Gimplification of the ADDR_EXPR operand may drop 6862 cv-qualification conversions, so make sure we add them if 6863 needed. */ 6864 { 6865 tree op00 = TREE_OPERAND (op0, 0); 6866 tree t_expr = TREE_TYPE (expr); 6867 tree t_op00 = TREE_TYPE (op00); 6868 6869 if (!useless_type_conversion_p (t_expr, t_op00)) 6870 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00); 6871 *expr_p = op00; 6872 ret = GS_OK; 6873 } 6874 break; 6875 6876 case VIEW_CONVERT_EXPR: 6877 /* Take the address of our operand and then convert it to the type of 6878 this ADDR_EXPR. 6879 6880 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at 6881 all clear. The impact of this transformation is even less clear. */ 6882 6883 /* If the operand is a useless conversion, look through it. Doing so 6884 guarantees that the ADDR_EXPR and its operand will remain of the 6885 same type. */ 6886 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0))) 6887 op0 = TREE_OPERAND (op0, 0); 6888 6889 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr), 6890 build_fold_addr_expr_loc (loc, 6891 TREE_OPERAND (op0, 0))); 6892 ret = GS_OK; 6893 break; 6894 6895 case MEM_REF: 6896 if (integer_zerop (TREE_OPERAND (op0, 1))) 6897 goto do_indirect_ref; 6898 6899 /* fall through */ 6900 6901 default: 6902 /* If we see a call to a declared builtin or see its address 6903 being taken (we can unify those cases here) then we can mark 6904 the builtin for implicit generation by GCC. */ 6905 if (TREE_CODE (op0) == FUNCTION_DECL 6906 && fndecl_built_in_p (op0, BUILT_IN_NORMAL) 6907 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0))) 6908 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true); 6909 6910 /* We use fb_either here because the C frontend sometimes takes 6911 the address of a call that returns a struct; see 6912 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make 6913 the implied temporary explicit. */ 6914 6915 /* Make the operand addressable. */ 6916 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, 6917 is_gimple_addressable, fb_either); 6918 if (ret == GS_ERROR) 6919 break; 6920 6921 /* Then mark it. Beware that it may not be possible to do so directly 6922 if a temporary has been created by the gimplification. */ 6923 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p); 6924 6925 op0 = TREE_OPERAND (expr, 0); 6926 6927 /* For various reasons, the gimplification of the expression 6928 may have made a new INDIRECT_REF. */ 6929 if (INDIRECT_REF_P (op0) 6930 || (TREE_CODE (op0) == MEM_REF 6931 && integer_zerop (TREE_OPERAND (op0, 1)))) 6932 goto do_indirect_ref; 6933 6934 mark_addressable (TREE_OPERAND (expr, 0)); 6935 6936 /* The FEs may end up building ADDR_EXPRs early on a decl with 6937 an incomplete type. Re-build ADDR_EXPRs in canonical form 6938 here. */ 6939 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr)))) 6940 *expr_p = build_fold_addr_expr (op0); 6941 6942 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ 6943 if (TREE_CODE (*expr_p) == ADDR_EXPR) 6944 recompute_tree_invariant_for_addr_expr (*expr_p); 6945 6946 /* If we re-built the ADDR_EXPR add a conversion to the original type 6947 if required. */ 6948 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) 6949 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); 6950 6951 break; 6952 } 6953 6954 return ret; 6955 } 6956 6957 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple 6958 value; output operands should be a gimple lvalue. */ 6959 6960 static enum gimplify_status 6961 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 6962 { 6963 tree expr; 6964 int noutputs; 6965 const char **oconstraints; 6966 int i; 6967 tree link; 6968 const char *constraint; 6969 bool allows_mem, allows_reg, is_inout; 6970 enum gimplify_status ret, tret; 6971 gasm *stmt; 6972 vec<tree, va_gc> *inputs; 6973 vec<tree, va_gc> *outputs; 6974 vec<tree, va_gc> *clobbers; 6975 vec<tree, va_gc> *labels; 6976 tree link_next; 6977 6978 expr = *expr_p; 6979 noutputs = list_length (ASM_OUTPUTS (expr)); 6980 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *)); 6981 6982 inputs = NULL; 6983 outputs = NULL; 6984 clobbers = NULL; 6985 labels = NULL; 6986 6987 ret = GS_ALL_DONE; 6988 link_next = NULL_TREE; 6989 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next) 6990 { 6991 bool ok; 6992 size_t constraint_len; 6993 6994 link_next = TREE_CHAIN (link); 6995 6996 oconstraints[i] 6997 = constraint 6998 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 6999 constraint_len = strlen (constraint); 7000 if (constraint_len == 0) 7001 continue; 7002 7003 ok = parse_output_constraint (&constraint, i, 0, 0, 7004 &allows_mem, &allows_reg, &is_inout); 7005 if (!ok) 7006 { 7007 ret = GS_ERROR; 7008 is_inout = false; 7009 } 7010 7011 /* If we can't make copies, we can only accept memory. 7012 Similarly for VLAs. */ 7013 tree outtype = TREE_TYPE (TREE_VALUE (link)); 7014 if (outtype != error_mark_node 7015 && (TREE_ADDRESSABLE (outtype) 7016 || !COMPLETE_TYPE_P (outtype) 7017 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype)))) 7018 { 7019 if (allows_mem) 7020 allows_reg = 0; 7021 else 7022 { 7023 error ("impossible constraint in %<asm%>"); 7024 error ("non-memory output %d must stay in memory", i); 7025 return GS_ERROR; 7026 } 7027 } 7028 7029 if (!allows_reg && allows_mem) 7030 mark_addressable (TREE_VALUE (link)); 7031 7032 tree orig = TREE_VALUE (link); 7033 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7034 is_inout ? is_gimple_min_lval : is_gimple_lvalue, 7035 fb_lvalue | fb_mayfail); 7036 if (tret == GS_ERROR) 7037 { 7038 if (orig != error_mark_node) 7039 error ("invalid lvalue in %<asm%> output %d", i); 7040 ret = tret; 7041 } 7042 7043 /* If the gimplified operand is a register we do not allow memory. */ 7044 if (allows_reg 7045 && allows_mem 7046 && (is_gimple_reg (TREE_VALUE (link)) 7047 || (handled_component_p (TREE_VALUE (link)) 7048 && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0))))) 7049 allows_mem = 0; 7050 7051 /* If the constraint does not allow memory make sure we gimplify 7052 it to a register if it is not already but its base is. This 7053 happens for complex and vector components. */ 7054 if (!allows_mem) 7055 { 7056 tree op = TREE_VALUE (link); 7057 if (! is_gimple_val (op) 7058 && is_gimple_reg_type (TREE_TYPE (op)) 7059 && is_gimple_reg (get_base_address (op))) 7060 { 7061 tree tem = create_tmp_reg (TREE_TYPE (op)); 7062 tree ass; 7063 if (is_inout) 7064 { 7065 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), 7066 tem, unshare_expr (op)); 7067 gimplify_and_add (ass, pre_p); 7068 } 7069 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem); 7070 gimplify_and_add (ass, post_p); 7071 7072 TREE_VALUE (link) = tem; 7073 tret = GS_OK; 7074 } 7075 } 7076 7077 vec_safe_push (outputs, link); 7078 TREE_CHAIN (link) = NULL_TREE; 7079 7080 if (is_inout) 7081 { 7082 /* An input/output operand. To give the optimizers more 7083 flexibility, split it into separate input and output 7084 operands. */ 7085 tree input; 7086 /* Buffer big enough to format a 32-bit UINT_MAX into. */ 7087 char buf[11]; 7088 7089 /* Turn the in/out constraint into an output constraint. */ 7090 char *p = xstrdup (constraint); 7091 p[0] = '='; 7092 TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link)); 7093 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); 7094 7095 /* And add a matching input constraint. */ 7096 if (allows_reg) 7097 { 7098 sprintf (buf, "%u", i); 7099 7100 /* If there are multiple alternatives in the constraint, 7101 handle each of them individually. Those that allow register 7102 will be replaced with operand number, the others will stay 7103 unchanged. */ 7104 if (strchr (p, ',') != NULL) 7105 { 7106 size_t len = 0, buflen = strlen (buf); 7107 char *beg, *end, *str, *dst; 7108 7109 for (beg = p + 1;;) 7110 { 7111 end = strchr (beg, ','); 7112 if (end == NULL) 7113 end = strchr (beg, '\0'); 7114 if ((size_t) (end - beg) < buflen) 7115 len += buflen + 1; 7116 else 7117 len += end - beg + 1; 7118 if (*end) 7119 beg = end + 1; 7120 else 7121 break; 7122 } 7123 7124 str = (char *) alloca (len); 7125 for (beg = p + 1, dst = str;;) 7126 { 7127 const char *tem; 7128 bool mem_p, reg_p, inout_p; 7129 7130 end = strchr (beg, ','); 7131 if (end) 7132 *end = '\0'; 7133 beg[-1] = '='; 7134 tem = beg - 1; 7135 parse_output_constraint (&tem, i, 0, 0, 7136 &mem_p, ®_p, &inout_p); 7137 if (dst != str) 7138 *dst++ = ','; 7139 if (reg_p) 7140 { 7141 memcpy (dst, buf, buflen); 7142 dst += buflen; 7143 } 7144 else 7145 { 7146 if (end) 7147 len = end - beg; 7148 else 7149 len = strlen (beg); 7150 memcpy (dst, beg, len); 7151 dst += len; 7152 } 7153 if (end) 7154 beg = end + 1; 7155 else 7156 break; 7157 } 7158 *dst = '\0'; 7159 input = build_string (dst - str, str); 7160 } 7161 else 7162 input = build_string (strlen (buf), buf); 7163 } 7164 else 7165 input = build_string (constraint_len - 1, constraint + 1); 7166 7167 free (p); 7168 7169 input = build_tree_list (build_tree_list (NULL_TREE, input), 7170 unshare_expr (TREE_VALUE (link))); 7171 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); 7172 } 7173 } 7174 7175 link_next = NULL_TREE; 7176 for (link = ASM_INPUTS (expr); link; ++i, link = link_next) 7177 { 7178 link_next = TREE_CHAIN (link); 7179 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 7180 parse_input_constraint (&constraint, 0, 0, noutputs, 0, 7181 oconstraints, &allows_mem, &allows_reg); 7182 7183 /* If we can't make copies, we can only accept memory. */ 7184 tree intype = TREE_TYPE (TREE_VALUE (link)); 7185 if (intype != error_mark_node 7186 && (TREE_ADDRESSABLE (intype) 7187 || !COMPLETE_TYPE_P (intype) 7188 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype)))) 7189 { 7190 if (allows_mem) 7191 allows_reg = 0; 7192 else 7193 { 7194 error ("impossible constraint in %<asm%>"); 7195 error ("non-memory input %d must stay in memory", i); 7196 return GS_ERROR; 7197 } 7198 } 7199 7200 /* If the operand is a memory input, it should be an lvalue. */ 7201 if (!allows_reg && allows_mem) 7202 { 7203 tree inputv = TREE_VALUE (link); 7204 STRIP_NOPS (inputv); 7205 if (TREE_CODE (inputv) == PREDECREMENT_EXPR 7206 || TREE_CODE (inputv) == PREINCREMENT_EXPR 7207 || TREE_CODE (inputv) == POSTDECREMENT_EXPR 7208 || TREE_CODE (inputv) == POSTINCREMENT_EXPR 7209 || TREE_CODE (inputv) == MODIFY_EXPR) 7210 TREE_VALUE (link) = error_mark_node; 7211 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7212 is_gimple_lvalue, fb_lvalue | fb_mayfail); 7213 if (tret != GS_ERROR) 7214 { 7215 /* Unlike output operands, memory inputs are not guaranteed 7216 to be lvalues by the FE, and while the expressions are 7217 marked addressable there, if it is e.g. a statement 7218 expression, temporaries in it might not end up being 7219 addressable. They might be already used in the IL and thus 7220 it is too late to make them addressable now though. */ 7221 tree x = TREE_VALUE (link); 7222 while (handled_component_p (x)) 7223 x = TREE_OPERAND (x, 0); 7224 if (TREE_CODE (x) == MEM_REF 7225 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR) 7226 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0); 7227 if ((VAR_P (x) 7228 || TREE_CODE (x) == PARM_DECL 7229 || TREE_CODE (x) == RESULT_DECL) 7230 && !TREE_ADDRESSABLE (x) 7231 && is_gimple_reg (x)) 7232 { 7233 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), 7234 input_location), 0, 7235 "memory input %d is not directly addressable", 7236 i); 7237 prepare_gimple_addressable (&TREE_VALUE (link), pre_p); 7238 } 7239 } 7240 mark_addressable (TREE_VALUE (link)); 7241 if (tret == GS_ERROR) 7242 { 7243 if (inputv != error_mark_node) 7244 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location), 7245 "memory input %d is not directly addressable", i); 7246 ret = tret; 7247 } 7248 } 7249 else 7250 { 7251 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, 7252 is_gimple_asm_val, fb_rvalue); 7253 if (tret == GS_ERROR) 7254 ret = tret; 7255 } 7256 7257 TREE_CHAIN (link) = NULL_TREE; 7258 vec_safe_push (inputs, link); 7259 } 7260 7261 link_next = NULL_TREE; 7262 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next) 7263 { 7264 link_next = TREE_CHAIN (link); 7265 TREE_CHAIN (link) = NULL_TREE; 7266 vec_safe_push (clobbers, link); 7267 } 7268 7269 link_next = NULL_TREE; 7270 for (link = ASM_LABELS (expr); link; ++i, link = link_next) 7271 { 7272 link_next = TREE_CHAIN (link); 7273 TREE_CHAIN (link) = NULL_TREE; 7274 vec_safe_push (labels, link); 7275 } 7276 7277 /* Do not add ASMs with errors to the gimple IL stream. */ 7278 if (ret != GS_ERROR) 7279 { 7280 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)), 7281 inputs, outputs, clobbers, labels); 7282 7283 /* asm is volatile if it was marked by the user as volatile or 7284 there are no outputs or this is an asm goto. */ 7285 gimple_asm_set_volatile (stmt, 7286 ASM_VOLATILE_P (expr) 7287 || noutputs == 0 7288 || labels); 7289 gimple_asm_set_input (stmt, ASM_INPUT_P (expr)); 7290 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr)); 7291 7292 gimplify_seq_add_stmt (pre_p, stmt); 7293 } 7294 7295 return ret; 7296 } 7297 7298 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding 7299 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while 7300 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we 7301 return to this function. 7302 7303 FIXME should we complexify the prequeue handling instead? Or use flags 7304 for all the cleanups and let the optimizer tighten them up? The current 7305 code seems pretty fragile; it will break on a cleanup within any 7306 non-conditional nesting. But any such nesting would be broken, anyway; 7307 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct 7308 and continues out of it. We can do that at the RTL level, though, so 7309 having an optimizer to tighten up try/finally regions would be a Good 7310 Thing. */ 7311 7312 static enum gimplify_status 7313 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p) 7314 { 7315 gimple_stmt_iterator iter; 7316 gimple_seq body_sequence = NULL; 7317 7318 tree temp = voidify_wrapper_expr (*expr_p, NULL); 7319 7320 /* We only care about the number of conditions between the innermost 7321 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and 7322 any cleanups collected outside the CLEANUP_POINT_EXPR. */ 7323 int old_conds = gimplify_ctxp->conditions; 7324 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups; 7325 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr; 7326 gimplify_ctxp->conditions = 0; 7327 gimplify_ctxp->conditional_cleanups = NULL; 7328 gimplify_ctxp->in_cleanup_point_expr = true; 7329 7330 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence); 7331 7332 gimplify_ctxp->conditions = old_conds; 7333 gimplify_ctxp->conditional_cleanups = old_cleanups; 7334 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr; 7335 7336 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); ) 7337 { 7338 gimple *wce = gsi_stmt (iter); 7339 7340 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR) 7341 { 7342 if (gsi_one_before_end_p (iter)) 7343 { 7344 /* Note that gsi_insert_seq_before and gsi_remove do not 7345 scan operands, unlike some other sequence mutators. */ 7346 if (!gimple_wce_cleanup_eh_only (wce)) 7347 gsi_insert_seq_before_without_update (&iter, 7348 gimple_wce_cleanup (wce), 7349 GSI_SAME_STMT); 7350 gsi_remove (&iter, true); 7351 break; 7352 } 7353 else 7354 { 7355 gtry *gtry; 7356 gimple_seq seq; 7357 enum gimple_try_flags kind; 7358 7359 if (gimple_wce_cleanup_eh_only (wce)) 7360 kind = GIMPLE_TRY_CATCH; 7361 else 7362 kind = GIMPLE_TRY_FINALLY; 7363 seq = gsi_split_seq_after (iter); 7364 7365 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind); 7366 /* Do not use gsi_replace here, as it may scan operands. 7367 We want to do a simple structural modification only. */ 7368 gsi_set_stmt (&iter, gtry); 7369 iter = gsi_start (gtry->eval); 7370 } 7371 } 7372 else 7373 gsi_next (&iter); 7374 } 7375 7376 gimplify_seq_add_seq (pre_p, body_sequence); 7377 if (temp) 7378 { 7379 *expr_p = temp; 7380 return GS_OK; 7381 } 7382 else 7383 { 7384 *expr_p = NULL; 7385 return GS_ALL_DONE; 7386 } 7387 } 7388 7389 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP 7390 is the cleanup action required. EH_ONLY is true if the cleanup should 7391 only be executed if an exception is thrown, not on normal exit. 7392 If FORCE_UNCOND is true perform the cleanup unconditionally; this is 7393 only valid for clobbers. */ 7394 7395 static void 7396 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p, 7397 bool force_uncond = false) 7398 { 7399 gimple *wce; 7400 gimple_seq cleanup_stmts = NULL; 7401 7402 /* Errors can result in improperly nested cleanups. Which results in 7403 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */ 7404 if (seen_error ()) 7405 return; 7406 7407 if (gimple_conditional_context ()) 7408 { 7409 /* If we're in a conditional context, this is more complex. We only 7410 want to run the cleanup if we actually ran the initialization that 7411 necessitates it, but we want to run it after the end of the 7412 conditional context. So we wrap the try/finally around the 7413 condition and use a flag to determine whether or not to actually 7414 run the destructor. Thus 7415 7416 test ? f(A()) : 0 7417 7418 becomes (approximately) 7419 7420 flag = 0; 7421 try { 7422 if (test) { A::A(temp); flag = 1; val = f(temp); } 7423 else { val = 0; } 7424 } finally { 7425 if (flag) A::~A(temp); 7426 } 7427 val 7428 */ 7429 if (force_uncond) 7430 { 7431 gimplify_stmt (&cleanup, &cleanup_stmts); 7432 wce = gimple_build_wce (cleanup_stmts); 7433 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce); 7434 } 7435 else 7436 { 7437 tree flag = create_tmp_var (boolean_type_node, "cleanup"); 7438 gassign *ffalse = gimple_build_assign (flag, boolean_false_node); 7439 gassign *ftrue = gimple_build_assign (flag, boolean_true_node); 7440 7441 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL); 7442 gimplify_stmt (&cleanup, &cleanup_stmts); 7443 wce = gimple_build_wce (cleanup_stmts); 7444 gimple_wce_set_cleanup_eh_only (wce, eh_only); 7445 7446 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse); 7447 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce); 7448 gimplify_seq_add_stmt (pre_p, ftrue); 7449 7450 /* Because of this manipulation, and the EH edges that jump 7451 threading cannot redirect, the temporary (VAR) will appear 7452 to be used uninitialized. Don't warn. */ 7453 suppress_warning (var, OPT_Wuninitialized); 7454 } 7455 } 7456 else 7457 { 7458 gimplify_stmt (&cleanup, &cleanup_stmts); 7459 wce = gimple_build_wce (cleanup_stmts); 7460 gimple_wce_set_cleanup_eh_only (wce, eh_only); 7461 gimplify_seq_add_stmt (pre_p, wce); 7462 } 7463 } 7464 7465 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */ 7466 7467 static enum gimplify_status 7468 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 7469 { 7470 tree targ = *expr_p; 7471 tree temp = TARGET_EXPR_SLOT (targ); 7472 tree init = TARGET_EXPR_INITIAL (targ); 7473 enum gimplify_status ret; 7474 7475 bool unpoison_empty_seq = false; 7476 gimple_stmt_iterator unpoison_it; 7477 7478 if (init) 7479 { 7480 gimple_seq init_pre_p = NULL; 7481 7482 /* TARGET_EXPR temps aren't part of the enclosing block, so add it 7483 to the temps list. Handle also variable length TARGET_EXPRs. */ 7484 if (!poly_int_tree_p (DECL_SIZE (temp))) 7485 { 7486 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp))) 7487 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p); 7488 /* FIXME: this is correct only when the size of the type does 7489 not depend on expressions evaluated in init. */ 7490 gimplify_vla_decl (temp, &init_pre_p); 7491 } 7492 else 7493 { 7494 /* Save location where we need to place unpoisoning. It's possible 7495 that a variable will be converted to needs_to_live_in_memory. */ 7496 unpoison_it = gsi_last (*pre_p); 7497 unpoison_empty_seq = gsi_end_p (unpoison_it); 7498 7499 gimple_add_tmp_var (temp); 7500 } 7501 7502 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the 7503 expression is supposed to initialize the slot. */ 7504 if (VOID_TYPE_P (TREE_TYPE (init))) 7505 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt, 7506 fb_none); 7507 else 7508 { 7509 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); 7510 init = init_expr; 7511 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt, 7512 fb_none); 7513 init = NULL; 7514 ggc_free (init_expr); 7515 } 7516 if (ret == GS_ERROR) 7517 { 7518 /* PR c++/28266 Make sure this is expanded only once. */ 7519 TARGET_EXPR_INITIAL (targ) = NULL_TREE; 7520 return GS_ERROR; 7521 } 7522 7523 if (init) 7524 gimplify_and_add (init, &init_pre_p); 7525 7526 /* Add a clobber for the temporary going out of scope, like 7527 gimplify_bind_expr. But only if we did not promote the 7528 temporary to static storage. */ 7529 if (gimplify_ctxp->in_cleanup_point_expr 7530 && !TREE_STATIC (temp) 7531 && needs_to_live_in_memory (temp)) 7532 { 7533 if (flag_stack_reuse == SR_ALL) 7534 { 7535 tree clobber = build_clobber (TREE_TYPE (temp), 7536 CLOBBER_STORAGE_END); 7537 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); 7538 gimple_push_cleanup (temp, clobber, false, pre_p, true); 7539 } 7540 if (asan_poisoned_variables 7541 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT 7542 && !TREE_STATIC (temp) 7543 && dbg_cnt (asan_use_after_scope) 7544 && !gimplify_omp_ctxp) 7545 { 7546 tree asan_cleanup = build_asan_poison_call_expr (temp); 7547 if (asan_cleanup) 7548 { 7549 if (unpoison_empty_seq) 7550 unpoison_it = gsi_start (*pre_p); 7551 7552 asan_poison_variable (temp, false, &unpoison_it, 7553 unpoison_empty_seq); 7554 gimple_push_cleanup (temp, asan_cleanup, false, pre_p); 7555 } 7556 } 7557 } 7558 7559 gimple_seq_add_seq (pre_p, init_pre_p); 7560 7561 /* If needed, push the cleanup for the temp. */ 7562 if (TARGET_EXPR_CLEANUP (targ)) 7563 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), 7564 CLEANUP_EH_ONLY (targ), pre_p); 7565 7566 /* Only expand this once. */ 7567 TREE_OPERAND (targ, 3) = init; 7568 TARGET_EXPR_INITIAL (targ) = NULL_TREE; 7569 } 7570 else 7571 /* We should have expanded this before. */ 7572 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp)); 7573 7574 *expr_p = temp; 7575 return GS_OK; 7576 } 7577 7578 /* Gimplification of expression trees. */ 7579 7580 /* Gimplify an expression which appears at statement context. The 7581 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is 7582 NULL, a new sequence is allocated. 7583 7584 Return true if we actually added a statement to the queue. */ 7585 7586 bool 7587 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p) 7588 { 7589 gimple_seq_node last; 7590 7591 last = gimple_seq_last (*seq_p); 7592 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none); 7593 return last != gimple_seq_last (*seq_p); 7594 } 7595 7596 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels 7597 to CTX. If entries already exist, force them to be some flavor of private. 7598 If there is no enclosing parallel, do nothing. */ 7599 7600 void 7601 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl) 7602 { 7603 splay_tree_node n; 7604 7605 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE) 7606 return; 7607 7608 do 7609 { 7610 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7611 if (n != NULL) 7612 { 7613 if (n->value & GOVD_SHARED) 7614 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN); 7615 else if (n->value & GOVD_MAP) 7616 n->value |= GOVD_MAP_TO_ONLY; 7617 else 7618 return; 7619 } 7620 else if ((ctx->region_type & ORT_TARGET) != 0) 7621 { 7622 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE) 7623 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); 7624 else 7625 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY); 7626 } 7627 else if (ctx->region_type != ORT_WORKSHARE 7628 && ctx->region_type != ORT_TASKGROUP 7629 && ctx->region_type != ORT_SIMD 7630 && ctx->region_type != ORT_ACC 7631 && !(ctx->region_type & ORT_TARGET_DATA)) 7632 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); 7633 7634 ctx = ctx->outer_context; 7635 } 7636 while (ctx); 7637 } 7638 7639 /* Similarly for each of the type sizes of TYPE. */ 7640 7641 static void 7642 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type) 7643 { 7644 if (type == NULL || type == error_mark_node) 7645 return; 7646 type = TYPE_MAIN_VARIANT (type); 7647 7648 if (ctx->privatized_types->add (type)) 7649 return; 7650 7651 switch (TREE_CODE (type)) 7652 { 7653 case INTEGER_TYPE: 7654 case ENUMERAL_TYPE: 7655 case BOOLEAN_TYPE: 7656 case REAL_TYPE: 7657 case FIXED_POINT_TYPE: 7658 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type)); 7659 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type)); 7660 break; 7661 7662 case ARRAY_TYPE: 7663 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 7664 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type)); 7665 break; 7666 7667 case RECORD_TYPE: 7668 case UNION_TYPE: 7669 case QUAL_UNION_TYPE: 7670 { 7671 tree field; 7672 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 7673 if (TREE_CODE (field) == FIELD_DECL) 7674 { 7675 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field)); 7676 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field)); 7677 } 7678 } 7679 break; 7680 7681 case POINTER_TYPE: 7682 case REFERENCE_TYPE: 7683 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type)); 7684 break; 7685 7686 default: 7687 break; 7688 } 7689 7690 omp_firstprivatize_variable (ctx, TYPE_SIZE (type)); 7691 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type)); 7692 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type); 7693 } 7694 7695 /* Add an entry for DECL in the OMP context CTX with FLAGS. */ 7696 7697 static void 7698 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) 7699 { 7700 splay_tree_node n; 7701 unsigned int nflags; 7702 tree t; 7703 7704 if (error_operand_p (decl) || ctx->region_type == ORT_NONE) 7705 return; 7706 7707 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means 7708 there are constructors involved somewhere. Exception is a shared clause, 7709 there is nothing privatized in that case. */ 7710 if ((flags & GOVD_SHARED) == 0 7711 && (TREE_ADDRESSABLE (TREE_TYPE (decl)) 7712 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) 7713 flags |= GOVD_SEEN; 7714 7715 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7716 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 7717 { 7718 /* We shouldn't be re-adding the decl with the same data 7719 sharing class. */ 7720 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0); 7721 nflags = n->value | flags; 7722 /* The only combination of data sharing classes we should see is 7723 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits 7724 reduction variables to be used in data sharing clauses. */ 7725 gcc_assert ((ctx->region_type & ORT_ACC) != 0 7726 || ((nflags & GOVD_DATA_SHARE_CLASS) 7727 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)) 7728 || (flags & GOVD_DATA_SHARE_CLASS) == 0); 7729 n->value = nflags; 7730 return; 7731 } 7732 7733 /* When adding a variable-sized variable, we have to handle all sorts 7734 of additional bits of data: the pointer replacement variable, and 7735 the parameters of the type. */ 7736 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 7737 { 7738 /* Add the pointer replacement variable as PRIVATE if the variable 7739 replacement is private, else FIRSTPRIVATE since we'll need the 7740 address of the original variable either for SHARED, or for the 7741 copy into or out of the context. */ 7742 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP) 7743 { 7744 if (flags & GOVD_MAP) 7745 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT; 7746 else if (flags & GOVD_PRIVATE) 7747 nflags = GOVD_PRIVATE; 7748 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0 7749 && (flags & GOVD_FIRSTPRIVATE)) 7750 || (ctx->region_type == ORT_TARGET_DATA 7751 && (flags & GOVD_DATA_SHARE_CLASS) == 0)) 7752 nflags = GOVD_PRIVATE | GOVD_EXPLICIT; 7753 else 7754 nflags = GOVD_FIRSTPRIVATE; 7755 nflags |= flags & GOVD_SEEN; 7756 t = DECL_VALUE_EXPR (decl); 7757 gcc_assert (INDIRECT_REF_P (t)); 7758 t = TREE_OPERAND (t, 0); 7759 gcc_assert (DECL_P (t)); 7760 omp_add_variable (ctx, t, nflags); 7761 } 7762 7763 /* Add all of the variable and type parameters (which should have 7764 been gimplified to a formal temporary) as FIRSTPRIVATE. */ 7765 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl)); 7766 omp_firstprivatize_variable (ctx, DECL_SIZE (decl)); 7767 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 7768 7769 /* The variable-sized variable itself is never SHARED, only some form 7770 of PRIVATE. The sharing would take place via the pointer variable 7771 which we remapped above. */ 7772 if (flags & GOVD_SHARED) 7773 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE 7774 | (flags & (GOVD_SEEN | GOVD_EXPLICIT)); 7775 7776 /* We're going to make use of the TYPE_SIZE_UNIT at least in the 7777 alloca statement we generate for the variable, so make sure it 7778 is available. This isn't automatically needed for the SHARED 7779 case, since we won't be allocating local storage then. 7780 For local variables TYPE_SIZE_UNIT might not be gimplified yet, 7781 in this case omp_notice_variable will be called later 7782 on when it is gimplified. */ 7783 else if (! (flags & (GOVD_LOCAL | GOVD_MAP)) 7784 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl)))) 7785 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true); 7786 } 7787 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0 7788 && omp_privatize_by_reference (decl)) 7789 { 7790 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); 7791 7792 /* Similar to the direct variable sized case above, we'll need the 7793 size of references being privatized. */ 7794 if ((flags & GOVD_SHARED) == 0) 7795 { 7796 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); 7797 if (t && DECL_P (t)) 7798 omp_notice_variable (ctx, t, true); 7799 } 7800 } 7801 7802 if (n != NULL) 7803 n->value |= flags; 7804 else 7805 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags); 7806 7807 /* For reductions clauses in OpenACC loop directives, by default create a 7808 copy clause on the enclosing parallel construct for carrying back the 7809 results. */ 7810 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION)) 7811 { 7812 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context; 7813 while (outer_ctx) 7814 { 7815 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl); 7816 if (n != NULL) 7817 { 7818 /* Ignore local variables and explicitly declared clauses. */ 7819 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT)) 7820 break; 7821 else if (outer_ctx->region_type == ORT_ACC_KERNELS) 7822 { 7823 /* According to the OpenACC spec, such a reduction variable 7824 should already have a copy map on a kernels construct, 7825 verify that here. */ 7826 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE) 7827 && (n->value & GOVD_MAP)); 7828 } 7829 else if (outer_ctx->region_type == ORT_ACC_PARALLEL) 7830 { 7831 /* Remove firstprivate and make it a copy map. */ 7832 n->value &= ~GOVD_FIRSTPRIVATE; 7833 n->value |= GOVD_MAP; 7834 } 7835 } 7836 else if (outer_ctx->region_type == ORT_ACC_PARALLEL) 7837 { 7838 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl, 7839 GOVD_MAP | GOVD_SEEN); 7840 break; 7841 } 7842 outer_ctx = outer_ctx->outer_context; 7843 } 7844 } 7845 } 7846 7847 /* Notice a threadprivate variable DECL used in OMP context CTX. 7848 This just prints out diagnostics about threadprivate variable uses 7849 in untied tasks. If DECL2 is non-NULL, prevent this warning 7850 on that variable. */ 7851 7852 static bool 7853 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl, 7854 tree decl2) 7855 { 7856 splay_tree_node n; 7857 struct gimplify_omp_ctx *octx; 7858 7859 for (octx = ctx; octx; octx = octx->outer_context) 7860 if ((octx->region_type & ORT_TARGET) != 0 7861 || octx->order_concurrent) 7862 { 7863 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl); 7864 if (n == NULL) 7865 { 7866 if (octx->order_concurrent) 7867 { 7868 error ("threadprivate variable %qE used in a region with" 7869 " %<order(concurrent)%> clause", DECL_NAME (decl)); 7870 inform (octx->location, "enclosing region"); 7871 } 7872 else 7873 { 7874 error ("threadprivate variable %qE used in target region", 7875 DECL_NAME (decl)); 7876 inform (octx->location, "enclosing target region"); 7877 } 7878 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0); 7879 } 7880 if (decl2) 7881 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0); 7882 } 7883 7884 if (ctx->region_type != ORT_UNTIED_TASK) 7885 return false; 7886 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 7887 if (n == NULL) 7888 { 7889 error ("threadprivate variable %qE used in untied task", 7890 DECL_NAME (decl)); 7891 inform (ctx->location, "enclosing task"); 7892 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0); 7893 } 7894 if (decl2) 7895 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0); 7896 return false; 7897 } 7898 7899 /* Return true if global var DECL is device resident. */ 7900 7901 static bool 7902 device_resident_p (tree decl) 7903 { 7904 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl)); 7905 7906 if (!attr) 7907 return false; 7908 7909 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t)) 7910 { 7911 tree c = TREE_VALUE (t); 7912 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT) 7913 return true; 7914 } 7915 7916 return false; 7917 } 7918 7919 /* Return true if DECL has an ACC DECLARE attribute. */ 7920 7921 static bool 7922 is_oacc_declared (tree decl) 7923 { 7924 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl; 7925 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t)); 7926 return declared != NULL_TREE; 7927 } 7928 7929 /* Determine outer default flags for DECL mentioned in an OMP region 7930 but not declared in an enclosing clause. 7931 7932 ??? Some compiler-generated variables (like SAVE_EXPRs) could be 7933 remapped firstprivate instead of shared. To some extent this is 7934 addressed in omp_firstprivatize_type_sizes, but not 7935 effectively. */ 7936 7937 static unsigned 7938 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl, 7939 bool in_code, unsigned flags) 7940 { 7941 enum omp_clause_default_kind default_kind = ctx->default_kind; 7942 enum omp_clause_default_kind kind; 7943 7944 kind = lang_hooks.decls.omp_predetermined_sharing (decl); 7945 if (ctx->region_type & ORT_TASK) 7946 { 7947 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH); 7948 7949 /* The event-handle specified by a detach clause should always be firstprivate, 7950 regardless of the current default. */ 7951 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl) 7952 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 7953 } 7954 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 7955 default_kind = kind; 7956 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl)) 7957 default_kind = OMP_CLAUSE_DEFAULT_SHARED; 7958 /* For C/C++ default({,first}private), variables with static storage duration 7959 declared in a namespace or global scope and referenced in construct 7960 must be explicitly specified, i.e. acts as default(none). */ 7961 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE 7962 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE) 7963 && VAR_P (decl) 7964 && is_global_var (decl) 7965 && (DECL_FILE_SCOPE_P (decl) 7966 || (DECL_CONTEXT (decl) 7967 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)) 7968 && !lang_GNU_Fortran ()) 7969 default_kind = OMP_CLAUSE_DEFAULT_NONE; 7970 7971 switch (default_kind) 7972 { 7973 case OMP_CLAUSE_DEFAULT_NONE: 7974 { 7975 const char *rtype; 7976 7977 if (ctx->region_type & ORT_PARALLEL) 7978 rtype = "parallel"; 7979 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP) 7980 rtype = "taskloop"; 7981 else if (ctx->region_type & ORT_TASK) 7982 rtype = "task"; 7983 else if (ctx->region_type & ORT_TEAMS) 7984 rtype = "teams"; 7985 else 7986 gcc_unreachable (); 7987 7988 error ("%qE not specified in enclosing %qs", 7989 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype); 7990 inform (ctx->location, "enclosing %qs", rtype); 7991 } 7992 /* FALLTHRU */ 7993 case OMP_CLAUSE_DEFAULT_SHARED: 7994 flags |= GOVD_SHARED; 7995 break; 7996 case OMP_CLAUSE_DEFAULT_PRIVATE: 7997 flags |= GOVD_PRIVATE; 7998 break; 7999 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE: 8000 flags |= GOVD_FIRSTPRIVATE; 8001 break; 8002 case OMP_CLAUSE_DEFAULT_UNSPECIFIED: 8003 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */ 8004 gcc_assert ((ctx->region_type & ORT_TASK) != 0); 8005 if (struct gimplify_omp_ctx *octx = ctx->outer_context) 8006 { 8007 omp_notice_variable (octx, decl, in_code); 8008 for (; octx; octx = octx->outer_context) 8009 { 8010 splay_tree_node n2; 8011 8012 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl); 8013 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0 8014 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0)) 8015 continue; 8016 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED) 8017 { 8018 flags |= GOVD_FIRSTPRIVATE; 8019 goto found_outer; 8020 } 8021 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0) 8022 { 8023 flags |= GOVD_SHARED; 8024 goto found_outer; 8025 } 8026 } 8027 } 8028 8029 if (TREE_CODE (decl) == PARM_DECL 8030 || (!is_global_var (decl) 8031 && DECL_CONTEXT (decl) == current_function_decl)) 8032 flags |= GOVD_FIRSTPRIVATE; 8033 else 8034 flags |= GOVD_SHARED; 8035 found_outer: 8036 break; 8037 8038 default: 8039 gcc_unreachable (); 8040 } 8041 8042 return flags; 8043 } 8044 8045 /* Return string name for types of OpenACC constructs from ORT_* values. */ 8046 8047 static const char * 8048 oacc_region_type_name (enum omp_region_type region_type) 8049 { 8050 switch (region_type) 8051 { 8052 case ORT_ACC_DATA: 8053 return "data"; 8054 case ORT_ACC_PARALLEL: 8055 return "parallel"; 8056 case ORT_ACC_KERNELS: 8057 return "kernels"; 8058 case ORT_ACC_SERIAL: 8059 return "serial"; 8060 default: 8061 gcc_unreachable (); 8062 } 8063 } 8064 8065 /* Determine outer default flags for DECL mentioned in an OACC region 8066 but not declared in an enclosing clause. */ 8067 8068 static unsigned 8069 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) 8070 { 8071 struct gimplify_omp_ctx *ctx_default = ctx; 8072 /* If no 'default' clause appears on this compute construct... */ 8073 if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED) 8074 { 8075 /* ..., see if one appears on a lexically containing 'data' 8076 construct. */ 8077 while ((ctx_default = ctx_default->outer_context)) 8078 { 8079 if (ctx_default->region_type == ORT_ACC_DATA 8080 && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED) 8081 break; 8082 } 8083 /* If not, reset. */ 8084 if (!ctx_default) 8085 ctx_default = ctx; 8086 } 8087 8088 bool on_device = false; 8089 bool is_private = false; 8090 bool declared = is_oacc_declared (decl); 8091 tree type = TREE_TYPE (decl); 8092 8093 if (omp_privatize_by_reference (decl)) 8094 type = TREE_TYPE (type); 8095 8096 /* For Fortran COMMON blocks, only used variables in those blocks are 8097 transfered and remapped. The block itself will have a private clause to 8098 avoid transfering the data twice. 8099 The hook evaluates to false by default. For a variable in Fortran's COMMON 8100 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only 8101 the variables in such a COMMON/EQUIVALENCE block shall be privatized not 8102 the whole block. For C++ and Fortran, it can also be true under certain 8103 other conditions, if DECL_HAS_VALUE_EXPR. */ 8104 if (RECORD_OR_UNION_TYPE_P (type)) 8105 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false); 8106 8107 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0 8108 && is_global_var (decl) 8109 && device_resident_p (decl) 8110 && !is_private) 8111 { 8112 on_device = true; 8113 flags |= GOVD_MAP_TO_ONLY; 8114 } 8115 8116 switch (ctx->region_type) 8117 { 8118 case ORT_ACC_KERNELS: 8119 if (is_private) 8120 flags |= GOVD_FIRSTPRIVATE; 8121 else if (AGGREGATE_TYPE_P (type)) 8122 { 8123 /* Aggregates default to 'present_or_copy', or 'present'. */ 8124 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT) 8125 flags |= GOVD_MAP; 8126 else 8127 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT; 8128 } 8129 else 8130 /* Scalars default to 'copy'. */ 8131 flags |= GOVD_MAP | GOVD_MAP_FORCE; 8132 8133 break; 8134 8135 case ORT_ACC_PARALLEL: 8136 case ORT_ACC_SERIAL: 8137 if (is_private) 8138 flags |= GOVD_FIRSTPRIVATE; 8139 else if (on_device || declared) 8140 flags |= GOVD_MAP; 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 'firstprivate'. */ 8151 flags |= GOVD_FIRSTPRIVATE; 8152 8153 break; 8154 8155 default: 8156 gcc_unreachable (); 8157 } 8158 8159 if (DECL_ARTIFICIAL (decl)) 8160 ; /* We can get compiler-generated decls, and should not complain 8161 about them. */ 8162 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE) 8163 { 8164 error ("%qE not specified in enclosing OpenACC %qs construct", 8165 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), 8166 oacc_region_type_name (ctx->region_type)); 8167 if (ctx_default != ctx) 8168 inform (ctx->location, "enclosing OpenACC %qs construct and", 8169 oacc_region_type_name (ctx->region_type)); 8170 inform (ctx_default->location, 8171 "enclosing OpenACC %qs construct with %qs clause", 8172 oacc_region_type_name (ctx_default->region_type), 8173 "default(none)"); 8174 } 8175 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT) 8176 ; /* Handled above. */ 8177 else 8178 gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED); 8179 8180 return flags; 8181 } 8182 8183 /* Record the fact that DECL was used within the OMP context CTX. 8184 IN_CODE is true when real code uses DECL, and false when we should 8185 merely emit default(none) errors. Return true if DECL is going to 8186 be remapped and thus DECL shouldn't be gimplified into its 8187 DECL_VALUE_EXPR (if any). */ 8188 8189 static bool 8190 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) 8191 { 8192 splay_tree_node n; 8193 unsigned flags = in_code ? GOVD_SEEN : 0; 8194 bool ret = false, shared; 8195 8196 if (error_operand_p (decl)) 8197 return false; 8198 8199 if (DECL_ARTIFICIAL (decl)) 8200 { 8201 tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl)); 8202 if (attr) 8203 decl = TREE_VALUE (TREE_VALUE (attr)); 8204 } 8205 8206 if (ctx->region_type == ORT_NONE) 8207 return lang_hooks.decls.omp_disregard_value_expr (decl, false); 8208 8209 if (is_global_var (decl)) 8210 { 8211 /* Threadprivate variables are predetermined. */ 8212 if (DECL_THREAD_LOCAL_P (decl)) 8213 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE); 8214 8215 if (DECL_HAS_VALUE_EXPR_P (decl)) 8216 { 8217 if (ctx->region_type & ORT_ACC) 8218 /* For OpenACC, defer expansion of value to avoid transfering 8219 privatized common block data instead of im-/explicitly transfered 8220 variables which are in common blocks. */ 8221 ; 8222 else 8223 { 8224 tree value = get_base_address (DECL_VALUE_EXPR (decl)); 8225 8226 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) 8227 return omp_notice_threadprivate_variable (ctx, decl, value); 8228 } 8229 } 8230 8231 if (gimplify_omp_ctxp->outer_context == NULL 8232 && VAR_P (decl) 8233 && oacc_get_fn_attrib (current_function_decl)) 8234 { 8235 location_t loc = DECL_SOURCE_LOCATION (decl); 8236 8237 if (lookup_attribute ("omp declare target link", 8238 DECL_ATTRIBUTES (decl))) 8239 { 8240 error_at (loc, 8241 "%qE with %<link%> clause used in %<routine%> function", 8242 DECL_NAME (decl)); 8243 return false; 8244 } 8245 else if (!lookup_attribute ("omp declare target", 8246 DECL_ATTRIBUTES (decl))) 8247 { 8248 error_at (loc, 8249 "%qE requires a %<declare%> directive for use " 8250 "in a %<routine%> function", DECL_NAME (decl)); 8251 return false; 8252 } 8253 } 8254 } 8255 8256 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 8257 if ((ctx->region_type & ORT_TARGET) != 0) 8258 { 8259 if (n == NULL) 8260 { 8261 unsigned nflags = flags; 8262 if ((ctx->region_type & ORT_ACC) == 0) 8263 { 8264 bool is_declare_target = false; 8265 if (is_global_var (decl) 8266 && varpool_node::get_create (decl)->offloadable) 8267 { 8268 struct gimplify_omp_ctx *octx; 8269 for (octx = ctx->outer_context; 8270 octx; octx = octx->outer_context) 8271 { 8272 n = splay_tree_lookup (octx->variables, 8273 (splay_tree_key)decl); 8274 if (n 8275 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED 8276 && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 8277 break; 8278 } 8279 is_declare_target = octx == NULL; 8280 } 8281 if (!is_declare_target) 8282 { 8283 int gdmk; 8284 enum omp_clause_defaultmap_kind kind; 8285 if (lang_hooks.decls.omp_allocatable_p (decl)) 8286 gdmk = GDMK_ALLOCATABLE; 8287 else if (lang_hooks.decls.omp_scalar_target_p (decl)) 8288 gdmk = GDMK_SCALAR_TARGET; 8289 else if (lang_hooks.decls.omp_scalar_p (decl, false)) 8290 gdmk = GDMK_SCALAR; 8291 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 8292 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 8293 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) 8294 == POINTER_TYPE))) 8295 gdmk = GDMK_POINTER; 8296 else 8297 gdmk = GDMK_AGGREGATE; 8298 kind = lang_hooks.decls.omp_predetermined_mapping (decl); 8299 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) 8300 { 8301 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE) 8302 nflags |= GOVD_FIRSTPRIVATE; 8303 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO) 8304 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY; 8305 else 8306 gcc_unreachable (); 8307 } 8308 else if (ctx->defaultmap[gdmk] == 0) 8309 { 8310 tree d = lang_hooks.decls.omp_report_decl (decl); 8311 error ("%qE not specified in enclosing %<target%>", 8312 DECL_NAME (d)); 8313 inform (ctx->location, "enclosing %<target%>"); 8314 } 8315 else if (ctx->defaultmap[gdmk] 8316 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE)) 8317 nflags |= ctx->defaultmap[gdmk]; 8318 else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT) 8319 { 8320 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP); 8321 nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY; 8322 } 8323 else 8324 { 8325 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP); 8326 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP; 8327 } 8328 } 8329 } 8330 8331 struct gimplify_omp_ctx *octx = ctx->outer_context; 8332 if ((ctx->region_type & ORT_ACC) && octx) 8333 { 8334 /* Look in outer OpenACC contexts, to see if there's a 8335 data attribute for this variable. */ 8336 omp_notice_variable (octx, decl, in_code); 8337 8338 for (; octx; octx = octx->outer_context) 8339 { 8340 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET))) 8341 break; 8342 splay_tree_node n2 8343 = splay_tree_lookup (octx->variables, 8344 (splay_tree_key) decl); 8345 if (n2) 8346 { 8347 if (octx->region_type == ORT_ACC_HOST_DATA) 8348 error ("variable %qE declared in enclosing " 8349 "%<host_data%> region", DECL_NAME (decl)); 8350 nflags |= GOVD_MAP; 8351 if (octx->region_type == ORT_ACC_DATA 8352 && (n2->value & GOVD_MAP_0LEN_ARRAY)) 8353 nflags |= GOVD_MAP_0LEN_ARRAY; 8354 goto found_outer; 8355 } 8356 } 8357 } 8358 8359 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY 8360 | GOVD_MAP_ALLOC_ONLY)) == flags) 8361 { 8362 tree type = TREE_TYPE (decl); 8363 8364 if (gimplify_omp_ctxp->target_firstprivatize_array_bases 8365 && omp_privatize_by_reference (decl)) 8366 type = TREE_TYPE (type); 8367 if (!omp_mappable_type (type)) 8368 { 8369 error ("%qD referenced in target region does not have " 8370 "a mappable type", decl); 8371 nflags |= GOVD_MAP | GOVD_EXPLICIT; 8372 } 8373 else 8374 { 8375 if ((ctx->region_type & ORT_ACC) != 0) 8376 nflags = oacc_default_clause (ctx, decl, flags); 8377 else 8378 nflags |= GOVD_MAP; 8379 } 8380 } 8381 found_outer: 8382 omp_add_variable (ctx, decl, nflags); 8383 if (ctx->region_type & ORT_ACC) 8384 /* For OpenACC, as remarked above, defer expansion. */ 8385 shared = false; 8386 else 8387 shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0; 8388 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8389 } 8390 else 8391 { 8392 if (ctx->region_type & ORT_ACC) 8393 /* For OpenACC, as remarked above, defer expansion. */ 8394 shared = false; 8395 else 8396 shared = ((n->value | flags) 8397 & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0; 8398 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8399 /* If nothing changed, there's nothing left to do. */ 8400 if ((n->value & flags) == flags) 8401 return ret; 8402 flags |= n->value; 8403 n->value = flags; 8404 } 8405 goto do_outer; 8406 } 8407 8408 if (n == NULL) 8409 { 8410 if (ctx->region_type == ORT_WORKSHARE 8411 || ctx->region_type == ORT_TASKGROUP 8412 || ctx->region_type == ORT_SIMD 8413 || ctx->region_type == ORT_ACC 8414 || (ctx->region_type & ORT_TARGET_DATA) != 0) 8415 goto do_outer; 8416 8417 flags = omp_default_clause (ctx, decl, in_code, flags); 8418 8419 if ((flags & GOVD_PRIVATE) 8420 && lang_hooks.decls.omp_private_outer_ref (decl)) 8421 flags |= GOVD_PRIVATE_OUTER_REF; 8422 8423 omp_add_variable (ctx, decl, flags); 8424 8425 shared = (flags & GOVD_SHARED) != 0; 8426 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8427 goto do_outer; 8428 } 8429 8430 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd 8431 lb, b or incr expressions, those shouldn't be turned into simd arrays. */ 8432 if (ctx->region_type == ORT_SIMD 8433 && ctx->in_for_exprs 8434 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT)) 8435 == GOVD_PRIVATE)) 8436 flags &= ~GOVD_SEEN; 8437 8438 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0 8439 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN 8440 && DECL_SIZE (decl)) 8441 { 8442 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 8443 { 8444 splay_tree_node n2; 8445 tree t = DECL_VALUE_EXPR (decl); 8446 gcc_assert (INDIRECT_REF_P (t)); 8447 t = TREE_OPERAND (t, 0); 8448 gcc_assert (DECL_P (t)); 8449 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 8450 n2->value |= GOVD_SEEN; 8451 } 8452 else if (omp_privatize_by_reference (decl) 8453 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))) 8454 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))) 8455 != INTEGER_CST)) 8456 { 8457 splay_tree_node n2; 8458 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); 8459 gcc_assert (DECL_P (t)); 8460 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 8461 if (n2) 8462 omp_notice_variable (ctx, t, true); 8463 } 8464 } 8465 8466 if (ctx->region_type & ORT_ACC) 8467 /* For OpenACC, as remarked above, defer expansion. */ 8468 shared = false; 8469 else 8470 shared = ((flags | n->value) & GOVD_SHARED) != 0; 8471 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); 8472 8473 /* If nothing changed, there's nothing left to do. */ 8474 if ((n->value & flags) == flags) 8475 return ret; 8476 flags |= n->value; 8477 n->value = flags; 8478 8479 do_outer: 8480 /* If the variable is private in the current context, then we don't 8481 need to propagate anything to an outer context. */ 8482 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF)) 8483 return ret; 8484 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8485 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8486 return ret; 8487 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE 8488 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8489 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER)) 8490 return ret; 8491 if (ctx->outer_context 8492 && omp_notice_variable (ctx->outer_context, decl, in_code)) 8493 return true; 8494 return ret; 8495 } 8496 8497 /* Verify that DECL is private within CTX. If there's specific information 8498 to the contrary in the innermost scope, generate an error. */ 8499 8500 static bool 8501 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd) 8502 { 8503 splay_tree_node n; 8504 8505 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); 8506 if (n != NULL) 8507 { 8508 if (n->value & GOVD_SHARED) 8509 { 8510 if (ctx == gimplify_omp_ctxp) 8511 { 8512 if (simd) 8513 error ("iteration variable %qE is predetermined linear", 8514 DECL_NAME (decl)); 8515 else 8516 error ("iteration variable %qE should be private", 8517 DECL_NAME (decl)); 8518 n->value = GOVD_PRIVATE; 8519 return true; 8520 } 8521 else 8522 return false; 8523 } 8524 else if ((n->value & GOVD_EXPLICIT) != 0 8525 && (ctx == gimplify_omp_ctxp 8526 || (ctx->region_type == ORT_COMBINED_PARALLEL 8527 && gimplify_omp_ctxp->outer_context == ctx))) 8528 { 8529 if ((n->value & GOVD_FIRSTPRIVATE) != 0) 8530 error ("iteration variable %qE should not be firstprivate", 8531 DECL_NAME (decl)); 8532 else if ((n->value & GOVD_REDUCTION) != 0) 8533 error ("iteration variable %qE should not be reduction", 8534 DECL_NAME (decl)); 8535 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0) 8536 error ("iteration variable %qE should not be linear", 8537 DECL_NAME (decl)); 8538 } 8539 return (ctx == gimplify_omp_ctxp 8540 || (ctx->region_type == ORT_COMBINED_PARALLEL 8541 && gimplify_omp_ctxp->outer_context == ctx)); 8542 } 8543 8544 if (ctx->region_type != ORT_WORKSHARE 8545 && ctx->region_type != ORT_TASKGROUP 8546 && ctx->region_type != ORT_SIMD 8547 && ctx->region_type != ORT_ACC) 8548 return false; 8549 else if (ctx->outer_context) 8550 return omp_is_private (ctx->outer_context, decl, simd); 8551 return false; 8552 } 8553 8554 /* Return true if DECL is private within a parallel region 8555 that binds to the current construct's context or in parallel 8556 region's REDUCTION clause. */ 8557 8558 static bool 8559 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate) 8560 { 8561 splay_tree_node n; 8562 8563 do 8564 { 8565 ctx = ctx->outer_context; 8566 if (ctx == NULL) 8567 { 8568 if (is_global_var (decl)) 8569 return false; 8570 8571 /* References might be private, but might be shared too, 8572 when checking for copyprivate, assume they might be 8573 private, otherwise assume they might be shared. */ 8574 if (copyprivate) 8575 return true; 8576 8577 if (omp_privatize_by_reference (decl)) 8578 return false; 8579 8580 /* Treat C++ privatized non-static data members outside 8581 of the privatization the same. */ 8582 if (omp_member_access_dummy_var (decl)) 8583 return false; 8584 8585 return true; 8586 } 8587 8588 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 8589 8590 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0 8591 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)) 8592 { 8593 if ((ctx->region_type & ORT_TARGET_DATA) != 0 8594 || n == NULL 8595 || (n->value & GOVD_MAP) == 0) 8596 continue; 8597 return false; 8598 } 8599 8600 if (n != NULL) 8601 { 8602 if ((n->value & GOVD_LOCAL) != 0 8603 && omp_member_access_dummy_var (decl)) 8604 return false; 8605 return (n->value & GOVD_SHARED) == 0; 8606 } 8607 8608 if (ctx->region_type == ORT_WORKSHARE 8609 || ctx->region_type == ORT_TASKGROUP 8610 || ctx->region_type == ORT_SIMD 8611 || ctx->region_type == ORT_ACC) 8612 continue; 8613 8614 break; 8615 } 8616 while (1); 8617 return false; 8618 } 8619 8620 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */ 8621 8622 static tree 8623 find_decl_expr (tree *tp, int *walk_subtrees, void *data) 8624 { 8625 tree t = *tp; 8626 8627 /* If this node has been visited, unmark it and keep looking. */ 8628 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data) 8629 return t; 8630 8631 if (IS_TYPE_OR_DECL_P (t)) 8632 *walk_subtrees = 0; 8633 return NULL_TREE; 8634 } 8635 8636 8637 /* Gimplify the affinity clause but effectively ignore it. 8638 Generate: 8639 var = begin; 8640 if ((step > 1) ? var <= end : var > end) 8641 locatator_var_expr; */ 8642 8643 static void 8644 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p) 8645 { 8646 tree last_iter = NULL_TREE; 8647 tree last_bind = NULL_TREE; 8648 tree label = NULL_TREE; 8649 tree *last_body = NULL; 8650 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 8651 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) 8652 { 8653 tree t = OMP_CLAUSE_DECL (c); 8654 if (TREE_CODE (t) == TREE_LIST 8655 && TREE_PURPOSE (t) 8656 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 8657 { 8658 if (TREE_VALUE (t) == null_pointer_node) 8659 continue; 8660 if (TREE_PURPOSE (t) != last_iter) 8661 { 8662 if (last_bind) 8663 { 8664 append_to_statement_list (label, last_body); 8665 gimplify_and_add (last_bind, pre_p); 8666 last_bind = NULL_TREE; 8667 } 8668 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8669 { 8670 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL, 8671 is_gimple_val, fb_rvalue) == GS_ERROR 8672 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL, 8673 is_gimple_val, fb_rvalue) == GS_ERROR 8674 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL, 8675 is_gimple_val, fb_rvalue) == GS_ERROR 8676 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL, 8677 is_gimple_val, fb_rvalue) 8678 == GS_ERROR)) 8679 return; 8680 } 8681 last_iter = TREE_PURPOSE (t); 8682 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5); 8683 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 8684 NULL, block); 8685 last_body = &BIND_EXPR_BODY (last_bind); 8686 tree cond = NULL_TREE; 8687 location_t loc = OMP_CLAUSE_LOCATION (c); 8688 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8689 { 8690 tree var = TREE_VEC_ELT (it, 0); 8691 tree begin = TREE_VEC_ELT (it, 1); 8692 tree end = TREE_VEC_ELT (it, 2); 8693 tree step = TREE_VEC_ELT (it, 3); 8694 loc = DECL_SOURCE_LOCATION (var); 8695 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 8696 var, begin); 8697 append_to_statement_list_force (tem, last_body); 8698 8699 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8700 step, build_zero_cst (TREE_TYPE (step))); 8701 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node, 8702 var, end); 8703 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8704 var, end); 8705 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node, 8706 cond1, cond2, cond3); 8707 if (cond) 8708 cond = fold_build2_loc (loc, TRUTH_AND_EXPR, 8709 boolean_type_node, cond, cond1); 8710 else 8711 cond = cond1; 8712 } 8713 tree cont_label = create_artificial_label (loc); 8714 label = build1 (LABEL_EXPR, void_type_node, cont_label); 8715 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, 8716 void_node, 8717 build_and_jump (&cont_label)); 8718 append_to_statement_list_force (tem, last_body); 8719 } 8720 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR) 8721 { 8722 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0), 8723 last_body); 8724 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1); 8725 } 8726 if (error_operand_p (TREE_VALUE (t))) 8727 return; 8728 append_to_statement_list_force (TREE_VALUE (t), last_body); 8729 TREE_VALUE (t) = null_pointer_node; 8730 } 8731 else 8732 { 8733 if (last_bind) 8734 { 8735 append_to_statement_list (label, last_body); 8736 gimplify_and_add (last_bind, pre_p); 8737 last_bind = NULL_TREE; 8738 } 8739 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 8740 { 8741 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 8742 NULL, is_gimple_val, fb_rvalue); 8743 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 8744 } 8745 if (error_operand_p (OMP_CLAUSE_DECL (c))) 8746 return; 8747 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 8748 is_gimple_lvalue, fb_lvalue) == GS_ERROR) 8749 return; 8750 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p); 8751 } 8752 } 8753 if (last_bind) 8754 { 8755 append_to_statement_list (label, last_body); 8756 gimplify_and_add (last_bind, pre_p); 8757 } 8758 return; 8759 } 8760 8761 /* If *LIST_P contains any OpenMP depend clauses with iterators, 8762 lower all the depend clauses by populating corresponding depend 8763 array. Returns 0 if there are no such depend clauses, or 8764 2 if all depend clauses should be removed, 1 otherwise. */ 8765 8766 static int 8767 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p) 8768 { 8769 tree c; 8770 gimple *g; 8771 size_t n[5] = { 0, 0, 0, 0, 0 }; 8772 bool unused[5]; 8773 tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }; 8774 tree last_iter = NULL_TREE, last_count = NULL_TREE; 8775 size_t i, j; 8776 location_t first_loc = UNKNOWN_LOCATION; 8777 8778 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 8779 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 8780 { 8781 switch (OMP_CLAUSE_DEPEND_KIND (c)) 8782 { 8783 case OMP_CLAUSE_DEPEND_IN: 8784 i = 2; 8785 break; 8786 case OMP_CLAUSE_DEPEND_OUT: 8787 case OMP_CLAUSE_DEPEND_INOUT: 8788 i = 0; 8789 break; 8790 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: 8791 i = 1; 8792 break; 8793 case OMP_CLAUSE_DEPEND_DEPOBJ: 8794 i = 3; 8795 break; 8796 case OMP_CLAUSE_DEPEND_INOUTSET: 8797 i = 4; 8798 break; 8799 default: 8800 gcc_unreachable (); 8801 } 8802 tree t = OMP_CLAUSE_DECL (c); 8803 if (first_loc == UNKNOWN_LOCATION) 8804 first_loc = OMP_CLAUSE_LOCATION (c); 8805 if (TREE_CODE (t) == TREE_LIST 8806 && TREE_PURPOSE (t) 8807 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 8808 { 8809 if (TREE_PURPOSE (t) != last_iter) 8810 { 8811 tree tcnt = size_one_node; 8812 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 8813 { 8814 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL, 8815 is_gimple_val, fb_rvalue) == GS_ERROR 8816 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL, 8817 is_gimple_val, fb_rvalue) == GS_ERROR 8818 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL, 8819 is_gimple_val, fb_rvalue) == GS_ERROR 8820 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL, 8821 is_gimple_val, fb_rvalue) 8822 == GS_ERROR)) 8823 return 2; 8824 tree var = TREE_VEC_ELT (it, 0); 8825 tree begin = TREE_VEC_ELT (it, 1); 8826 tree end = TREE_VEC_ELT (it, 2); 8827 tree step = TREE_VEC_ELT (it, 3); 8828 tree orig_step = TREE_VEC_ELT (it, 4); 8829 tree type = TREE_TYPE (var); 8830 tree stype = TREE_TYPE (step); 8831 location_t loc = DECL_SOURCE_LOCATION (var); 8832 tree endmbegin; 8833 /* Compute count for this iterator as 8834 orig_step > 0 8835 ? (begin < end ? (end - begin + (step - 1)) / step : 0) 8836 : (begin > end ? (end - begin + (step + 1)) / step : 0) 8837 and compute product of those for the entire depend 8838 clause. */ 8839 if (POINTER_TYPE_P (type)) 8840 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR, 8841 stype, end, begin); 8842 else 8843 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type, 8844 end, begin); 8845 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype, 8846 step, 8847 build_int_cst (stype, 1)); 8848 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step, 8849 build_int_cst (stype, 1)); 8850 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype, 8851 unshare_expr (endmbegin), 8852 stepm1); 8853 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, 8854 pos, step); 8855 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype, 8856 endmbegin, stepp1); 8857 if (TYPE_UNSIGNED (stype)) 8858 { 8859 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg); 8860 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step); 8861 } 8862 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, 8863 neg, step); 8864 step = NULL_TREE; 8865 tree cond = fold_build2_loc (loc, LT_EXPR, 8866 boolean_type_node, 8867 begin, end); 8868 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos, 8869 build_int_cst (stype, 0)); 8870 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, 8871 end, begin); 8872 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg, 8873 build_int_cst (stype, 0)); 8874 tree osteptype = TREE_TYPE (orig_step); 8875 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 8876 orig_step, 8877 build_int_cst (osteptype, 0)); 8878 tree cnt = fold_build3_loc (loc, COND_EXPR, stype, 8879 cond, pos, neg); 8880 cnt = fold_convert_loc (loc, sizetype, cnt); 8881 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val, 8882 fb_rvalue) == GS_ERROR) 8883 return 2; 8884 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt); 8885 } 8886 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val, 8887 fb_rvalue) == GS_ERROR) 8888 return 2; 8889 last_iter = TREE_PURPOSE (t); 8890 last_count = tcnt; 8891 } 8892 if (counts[i] == NULL_TREE) 8893 counts[i] = last_count; 8894 else 8895 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c), 8896 PLUS_EXPR, counts[i], last_count); 8897 } 8898 else 8899 n[i]++; 8900 } 8901 for (i = 0; i < 5; i++) 8902 if (counts[i]) 8903 break; 8904 if (i == 5) 8905 return 0; 8906 8907 tree total = size_zero_node; 8908 for (i = 0; i < 5; i++) 8909 { 8910 unused[i] = counts[i] == NULL_TREE && n[i] == 0; 8911 if (counts[i] == NULL_TREE) 8912 counts[i] = size_zero_node; 8913 if (n[i]) 8914 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i])); 8915 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val, 8916 fb_rvalue) == GS_ERROR) 8917 return 2; 8918 total = size_binop (PLUS_EXPR, total, counts[i]); 8919 } 8920 8921 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue) 8922 == GS_ERROR) 8923 return 2; 8924 bool is_old = unused[1] && unused[3] && unused[4]; 8925 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total), 8926 size_int (is_old ? 1 : 4)); 8927 if (!unused[4]) 8928 totalpx = size_binop (PLUS_EXPR, totalpx, 8929 size_binop (MULT_EXPR, counts[4], size_int (2))); 8930 tree type = build_array_type (ptr_type_node, build_index_type (totalpx)); 8931 tree array = create_tmp_var_raw (type); 8932 TREE_ADDRESSABLE (array) = 1; 8933 if (!poly_int_tree_p (totalpx)) 8934 { 8935 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array))) 8936 gimplify_type_sizes (TREE_TYPE (array), pre_p); 8937 if (gimplify_omp_ctxp) 8938 { 8939 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 8940 while (ctx 8941 && (ctx->region_type == ORT_WORKSHARE 8942 || ctx->region_type == ORT_TASKGROUP 8943 || ctx->region_type == ORT_SIMD 8944 || ctx->region_type == ORT_ACC)) 8945 ctx = ctx->outer_context; 8946 if (ctx) 8947 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN); 8948 } 8949 gimplify_vla_decl (array, pre_p); 8950 } 8951 else 8952 gimple_add_tmp_var (array); 8953 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE, 8954 NULL_TREE); 8955 tree tem; 8956 if (!is_old) 8957 { 8958 tem = build2 (MODIFY_EXPR, void_type_node, r, 8959 build_int_cst (ptr_type_node, 0)); 8960 gimplify_and_add (tem, pre_p); 8961 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE, 8962 NULL_TREE); 8963 } 8964 tem = build2 (MODIFY_EXPR, void_type_node, r, 8965 fold_convert (ptr_type_node, total)); 8966 gimplify_and_add (tem, pre_p); 8967 for (i = 1; i < (is_old ? 2 : 4); i++) 8968 { 8969 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old), 8970 NULL_TREE, NULL_TREE); 8971 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]); 8972 gimplify_and_add (tem, pre_p); 8973 } 8974 8975 tree cnts[6]; 8976 for (j = 5; j; j--) 8977 if (!unused[j - 1]) 8978 break; 8979 for (i = 0; i < 5; i++) 8980 { 8981 if (i && (i >= j || unused[i - 1])) 8982 { 8983 cnts[i] = cnts[i - 1]; 8984 continue; 8985 } 8986 cnts[i] = create_tmp_var (sizetype); 8987 if (i == 0) 8988 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5)); 8989 else 8990 { 8991 tree t; 8992 if (is_old) 8993 t = size_binop (PLUS_EXPR, counts[0], size_int (2)); 8994 else 8995 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]); 8996 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue) 8997 == GS_ERROR) 8998 return 2; 8999 g = gimple_build_assign (cnts[i], t); 9000 } 9001 gimple_seq_add_stmt (pre_p, g); 9002 } 9003 if (unused[4]) 9004 cnts[5] = NULL_TREE; 9005 else 9006 { 9007 tree t = size_binop (PLUS_EXPR, total, size_int (5)); 9008 cnts[5] = create_tmp_var (sizetype); 9009 g = gimple_build_assign (cnts[i], t); 9010 gimple_seq_add_stmt (pre_p, g); 9011 } 9012 9013 last_iter = NULL_TREE; 9014 tree last_bind = NULL_TREE; 9015 tree *last_body = NULL; 9016 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) 9017 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 9018 { 9019 switch (OMP_CLAUSE_DEPEND_KIND (c)) 9020 { 9021 case OMP_CLAUSE_DEPEND_IN: 9022 i = 2; 9023 break; 9024 case OMP_CLAUSE_DEPEND_OUT: 9025 case OMP_CLAUSE_DEPEND_INOUT: 9026 i = 0; 9027 break; 9028 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: 9029 i = 1; 9030 break; 9031 case OMP_CLAUSE_DEPEND_DEPOBJ: 9032 i = 3; 9033 break; 9034 case OMP_CLAUSE_DEPEND_INOUTSET: 9035 i = 4; 9036 break; 9037 default: 9038 gcc_unreachable (); 9039 } 9040 tree t = OMP_CLAUSE_DECL (c); 9041 if (TREE_CODE (t) == TREE_LIST 9042 && TREE_PURPOSE (t) 9043 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) 9044 { 9045 if (TREE_PURPOSE (t) != last_iter) 9046 { 9047 if (last_bind) 9048 gimplify_and_add (last_bind, pre_p); 9049 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5); 9050 last_bind = build3 (BIND_EXPR, void_type_node, 9051 BLOCK_VARS (block), NULL, block); 9052 TREE_SIDE_EFFECTS (last_bind) = 1; 9053 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c)); 9054 tree *p = &BIND_EXPR_BODY (last_bind); 9055 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) 9056 { 9057 tree var = TREE_VEC_ELT (it, 0); 9058 tree begin = TREE_VEC_ELT (it, 1); 9059 tree end = TREE_VEC_ELT (it, 2); 9060 tree step = TREE_VEC_ELT (it, 3); 9061 tree orig_step = TREE_VEC_ELT (it, 4); 9062 tree type = TREE_TYPE (var); 9063 location_t loc = DECL_SOURCE_LOCATION (var); 9064 /* Emit: 9065 var = begin; 9066 goto cond_label; 9067 beg_label: 9068 ... 9069 var = var + step; 9070 cond_label: 9071 if (orig_step > 0) { 9072 if (var < end) goto beg_label; 9073 } else { 9074 if (var > end) goto beg_label; 9075 } 9076 for each iterator, with inner iterators added to 9077 the ... above. */ 9078 tree beg_label = create_artificial_label (loc); 9079 tree cond_label = NULL_TREE; 9080 tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 9081 var, begin); 9082 append_to_statement_list_force (tem, p); 9083 tem = build_and_jump (&cond_label); 9084 append_to_statement_list_force (tem, p); 9085 tem = build1 (LABEL_EXPR, void_type_node, beg_label); 9086 append_to_statement_list (tem, p); 9087 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE, 9088 NULL_TREE, NULL_TREE); 9089 TREE_SIDE_EFFECTS (bind) = 1; 9090 SET_EXPR_LOCATION (bind, loc); 9091 append_to_statement_list_force (bind, p); 9092 if (POINTER_TYPE_P (type)) 9093 tem = build2_loc (loc, POINTER_PLUS_EXPR, type, 9094 var, fold_convert_loc (loc, sizetype, 9095 step)); 9096 else 9097 tem = build2_loc (loc, PLUS_EXPR, type, var, step); 9098 tem = build2_loc (loc, MODIFY_EXPR, void_type_node, 9099 var, tem); 9100 append_to_statement_list_force (tem, p); 9101 tem = build1 (LABEL_EXPR, void_type_node, cond_label); 9102 append_to_statement_list (tem, p); 9103 tree cond = fold_build2_loc (loc, LT_EXPR, 9104 boolean_type_node, 9105 var, end); 9106 tree pos 9107 = fold_build3_loc (loc, COND_EXPR, void_type_node, 9108 cond, build_and_jump (&beg_label), 9109 void_node); 9110 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 9111 var, end); 9112 tree neg 9113 = fold_build3_loc (loc, COND_EXPR, void_type_node, 9114 cond, build_and_jump (&beg_label), 9115 void_node); 9116 tree osteptype = TREE_TYPE (orig_step); 9117 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, 9118 orig_step, 9119 build_int_cst (osteptype, 0)); 9120 tem = fold_build3_loc (loc, COND_EXPR, void_type_node, 9121 cond, pos, neg); 9122 append_to_statement_list_force (tem, p); 9123 p = &BIND_EXPR_BODY (bind); 9124 } 9125 last_body = p; 9126 } 9127 last_iter = TREE_PURPOSE (t); 9128 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR) 9129 { 9130 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 9131 0), last_body); 9132 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1); 9133 } 9134 if (error_operand_p (TREE_VALUE (t))) 9135 return 2; 9136 if (TREE_VALUE (t) != null_pointer_node) 9137 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t)); 9138 if (i == 4) 9139 { 9140 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9141 NULL_TREE, NULL_TREE); 9142 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5], 9143 NULL_TREE, NULL_TREE); 9144 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node); 9145 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9146 void_type_node, r, r2); 9147 append_to_statement_list_force (tem, last_body); 9148 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9149 void_type_node, cnts[i], 9150 size_binop (PLUS_EXPR, cnts[i], 9151 size_int (1))); 9152 append_to_statement_list_force (tem, last_body); 9153 i = 5; 9154 } 9155 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9156 NULL_TREE, NULL_TREE); 9157 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9158 void_type_node, r, TREE_VALUE (t)); 9159 append_to_statement_list_force (tem, last_body); 9160 if (i == 5) 9161 { 9162 r = build4 (ARRAY_REF, ptr_type_node, array, 9163 size_binop (PLUS_EXPR, cnts[i], size_int (1)), 9164 NULL_TREE, NULL_TREE); 9165 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET); 9166 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9167 void_type_node, r, tem); 9168 append_to_statement_list_force (tem, last_body); 9169 } 9170 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, 9171 void_type_node, cnts[i], 9172 size_binop (PLUS_EXPR, cnts[i], 9173 size_int (1 + (i == 5)))); 9174 append_to_statement_list_force (tem, last_body); 9175 TREE_VALUE (t) = null_pointer_node; 9176 } 9177 else 9178 { 9179 if (last_bind) 9180 { 9181 gimplify_and_add (last_bind, pre_p); 9182 last_bind = NULL_TREE; 9183 } 9184 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 9185 { 9186 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 9187 NULL, is_gimple_val, fb_rvalue); 9188 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 9189 } 9190 if (error_operand_p (OMP_CLAUSE_DECL (c))) 9191 return 2; 9192 if (OMP_CLAUSE_DECL (c) != null_pointer_node) 9193 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c)); 9194 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 9195 is_gimple_val, fb_rvalue) == GS_ERROR) 9196 return 2; 9197 if (i == 4) 9198 { 9199 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9200 NULL_TREE, NULL_TREE); 9201 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5], 9202 NULL_TREE, NULL_TREE); 9203 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node); 9204 tem = build2 (MODIFY_EXPR, void_type_node, r, r2); 9205 gimplify_and_add (tem, pre_p); 9206 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, 9207 cnts[i], 9208 size_int (1))); 9209 gimple_seq_add_stmt (pre_p, g); 9210 i = 5; 9211 } 9212 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i], 9213 NULL_TREE, NULL_TREE); 9214 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c)); 9215 gimplify_and_add (tem, pre_p); 9216 if (i == 5) 9217 { 9218 r = build4 (ARRAY_REF, ptr_type_node, array, 9219 size_binop (PLUS_EXPR, cnts[i], size_int (1)), 9220 NULL_TREE, NULL_TREE); 9221 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET); 9222 tem = build2 (MODIFY_EXPR, void_type_node, r, tem); 9223 append_to_statement_list_force (tem, last_body); 9224 gimplify_and_add (tem, pre_p); 9225 } 9226 g = gimple_build_assign (cnts[i], 9227 size_binop (PLUS_EXPR, cnts[i], 9228 size_int (1 + (i == 5)))); 9229 gimple_seq_add_stmt (pre_p, g); 9230 } 9231 } 9232 if (last_bind) 9233 gimplify_and_add (last_bind, pre_p); 9234 tree cond = boolean_false_node; 9235 if (is_old) 9236 { 9237 if (!unused[0]) 9238 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0], 9239 size_binop_loc (first_loc, PLUS_EXPR, counts[0], 9240 size_int (2))); 9241 if (!unused[2]) 9242 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond, 9243 build2_loc (first_loc, NE_EXPR, boolean_type_node, 9244 cnts[2], 9245 size_binop_loc (first_loc, PLUS_EXPR, 9246 totalpx, 9247 size_int (1)))); 9248 } 9249 else 9250 { 9251 tree prev = size_int (5); 9252 for (i = 0; i < 5; i++) 9253 { 9254 if (unused[i]) 9255 continue; 9256 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev); 9257 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond, 9258 build2_loc (first_loc, NE_EXPR, boolean_type_node, 9259 cnts[i], unshare_expr (prev))); 9260 } 9261 } 9262 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond, 9263 build_call_expr_loc (first_loc, 9264 builtin_decl_explicit (BUILT_IN_TRAP), 9265 0), void_node); 9266 gimplify_and_add (tem, pre_p); 9267 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND); 9268 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST; 9269 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array); 9270 OMP_CLAUSE_CHAIN (c) = *list_p; 9271 *list_p = c; 9272 return 1; 9273 } 9274 9275 /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor. */ 9276 9277 static bool 9278 omp_map_clause_descriptor_p (tree c) 9279 { 9280 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) 9281 return false; 9282 9283 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET) 9284 return true; 9285 9286 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE 9287 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE) 9288 && OMP_CLAUSE_RELEASE_DESCRIPTOR (c)) 9289 return true; 9290 9291 return false; 9292 } 9293 9294 /* For a set of mappings describing an array section pointed to by a struct 9295 (or derived type, etc.) component, create an "alloc" or "release" node to 9296 insert into a list following a GOMP_MAP_STRUCT node. For some types of 9297 mapping (e.g. Fortran arrays with descriptors), an additional mapping may 9298 be created that is inserted into the list of mapping nodes attached to the 9299 directive being processed -- not part of the sorted list of nodes after 9300 GOMP_MAP_STRUCT. 9301 9302 CODE is the code of the directive being processed. GRP_START and GRP_END 9303 are the first and last of two or three nodes representing this array section 9304 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a 9305 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is 9306 filled with the additional node described above, if needed. 9307 9308 This function does not add the new nodes to any lists itself. It is the 9309 responsibility of the caller to do that. */ 9310 9311 static tree 9312 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end, 9313 tree *extra_node) 9314 { 9315 enum gomp_map_kind mkind 9316 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA) 9317 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 9318 9319 gcc_assert (grp_start != grp_end); 9320 9321 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 9322 OMP_CLAUSE_SET_MAP_KIND (c2, mkind); 9323 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end)); 9324 OMP_CLAUSE_CHAIN (c2) = NULL_TREE; 9325 tree grp_mid = NULL_TREE; 9326 if (OMP_CLAUSE_CHAIN (grp_start) != grp_end) 9327 grp_mid = OMP_CLAUSE_CHAIN (grp_start); 9328 9329 if (grp_mid && omp_map_clause_descriptor_p (grp_mid)) 9330 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid); 9331 else 9332 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node); 9333 9334 if (grp_mid 9335 && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP 9336 && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER) 9337 { 9338 tree c3 9339 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 9340 OMP_CLAUSE_SET_MAP_KIND (c3, mkind); 9341 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid)); 9342 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node); 9343 OMP_CLAUSE_CHAIN (c3) = NULL_TREE; 9344 9345 *extra_node = c3; 9346 } 9347 else 9348 *extra_node = NULL_TREE; 9349 9350 return c2; 9351 } 9352 9353 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object, 9354 and set *BITPOSP and *POFFSETP to the bit offset of the access. 9355 If BASE_REF is non-NULL and the containing object is a reference, set 9356 *BASE_REF to that reference before dereferencing the object. 9357 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or 9358 has array type, else return NULL. */ 9359 9360 static tree 9361 extract_base_bit_offset (tree base, poly_int64 *bitposp, 9362 poly_offset_int *poffsetp, 9363 bool *variable_offset) 9364 { 9365 tree offset; 9366 poly_int64 bitsize, bitpos; 9367 machine_mode mode; 9368 int unsignedp, reversep, volatilep = 0; 9369 poly_offset_int poffset; 9370 9371 STRIP_NOPS (base); 9372 9373 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode, 9374 &unsignedp, &reversep, &volatilep); 9375 9376 STRIP_NOPS (base); 9377 9378 if (offset && poly_int_tree_p (offset)) 9379 { 9380 poffset = wi::to_poly_offset (offset); 9381 *variable_offset = false; 9382 } 9383 else 9384 { 9385 poffset = 0; 9386 *variable_offset = (offset != NULL_TREE); 9387 } 9388 9389 if (maybe_ne (bitpos, 0)) 9390 poffset += bits_to_bytes_round_down (bitpos); 9391 9392 *bitposp = bitpos; 9393 *poffsetp = poffset; 9394 9395 return base; 9396 } 9397 9398 /* Used for topological sorting of mapping groups. UNVISITED means we haven't 9399 started processing the group yet. The TEMPORARY mark is used when we first 9400 encounter a group on a depth-first traversal, and the PERMANENT mark is used 9401 when we have processed all the group's children (i.e. all the base pointers 9402 referred to by the group's mapping nodes, recursively). */ 9403 9404 enum omp_tsort_mark { 9405 UNVISITED, 9406 TEMPORARY, 9407 PERMANENT 9408 }; 9409 9410 /* Hash for trees based on operand_equal_p. Like tree_operand_hash 9411 but ignores side effects in the equality comparisons. */ 9412 9413 struct tree_operand_hash_no_se : tree_operand_hash 9414 { 9415 static inline bool equal (const value_type &, 9416 const compare_type &); 9417 }; 9418 9419 inline bool 9420 tree_operand_hash_no_se::equal (const value_type &t1, 9421 const compare_type &t2) 9422 { 9423 return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS); 9424 } 9425 9426 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map" 9427 clause. */ 9428 9429 struct omp_mapping_group { 9430 tree *grp_start; 9431 tree grp_end; 9432 omp_tsort_mark mark; 9433 /* If we've removed the group but need to reindex, mark the group as 9434 deleted. */ 9435 bool deleted; 9436 /* The group points to an already-created "GOMP_MAP_STRUCT 9437 GOMP_MAP_ATTACH_DETACH" pair. */ 9438 bool reprocess_struct; 9439 /* The group should use "zero-length" allocations for pointers that are not 9440 mapped "to" on the same directive. */ 9441 bool fragile; 9442 struct omp_mapping_group *sibling; 9443 struct omp_mapping_group *next; 9444 }; 9445 9446 DEBUG_FUNCTION void 9447 debug_mapping_group (omp_mapping_group *grp) 9448 { 9449 tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end); 9450 OMP_CLAUSE_CHAIN (grp->grp_end) = NULL; 9451 debug_generic_expr (*grp->grp_start); 9452 OMP_CLAUSE_CHAIN (grp->grp_end) = tmp; 9453 } 9454 9455 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there 9456 isn't one. */ 9457 9458 static tree 9459 omp_get_base_pointer (tree expr) 9460 { 9461 while (TREE_CODE (expr) == ARRAY_REF 9462 || TREE_CODE (expr) == COMPONENT_REF) 9463 expr = TREE_OPERAND (expr, 0); 9464 9465 if (INDIRECT_REF_P (expr) 9466 || (TREE_CODE (expr) == MEM_REF 9467 && integer_zerop (TREE_OPERAND (expr, 1)))) 9468 { 9469 expr = TREE_OPERAND (expr, 0); 9470 while (TREE_CODE (expr) == COMPOUND_EXPR) 9471 expr = TREE_OPERAND (expr, 1); 9472 if (TREE_CODE (expr) == POINTER_PLUS_EXPR) 9473 expr = TREE_OPERAND (expr, 0); 9474 if (TREE_CODE (expr) == SAVE_EXPR) 9475 expr = TREE_OPERAND (expr, 0); 9476 STRIP_NOPS (expr); 9477 return expr; 9478 } 9479 9480 return NULL_TREE; 9481 } 9482 9483 /* An attach or detach operation depends directly on the address being 9484 attached/detached. Return that address, or none if there are no 9485 attachments/detachments. */ 9486 9487 static tree 9488 omp_get_attachment (omp_mapping_group *grp) 9489 { 9490 tree node = *grp->grp_start; 9491 9492 switch (OMP_CLAUSE_MAP_KIND (node)) 9493 { 9494 case GOMP_MAP_TO: 9495 case GOMP_MAP_FROM: 9496 case GOMP_MAP_TOFROM: 9497 case GOMP_MAP_ALWAYS_FROM: 9498 case GOMP_MAP_ALWAYS_TO: 9499 case GOMP_MAP_ALWAYS_TOFROM: 9500 case GOMP_MAP_FORCE_FROM: 9501 case GOMP_MAP_FORCE_TO: 9502 case GOMP_MAP_FORCE_TOFROM: 9503 case GOMP_MAP_FORCE_PRESENT: 9504 case GOMP_MAP_PRESENT_ALLOC: 9505 case GOMP_MAP_PRESENT_FROM: 9506 case GOMP_MAP_PRESENT_TO: 9507 case GOMP_MAP_PRESENT_TOFROM: 9508 case GOMP_MAP_ALWAYS_PRESENT_FROM: 9509 case GOMP_MAP_ALWAYS_PRESENT_TO: 9510 case GOMP_MAP_ALWAYS_PRESENT_TOFROM: 9511 case GOMP_MAP_ALLOC: 9512 case GOMP_MAP_RELEASE: 9513 case GOMP_MAP_DELETE: 9514 case GOMP_MAP_FORCE_ALLOC: 9515 if (node == grp->grp_end) 9516 return NULL_TREE; 9517 9518 node = OMP_CLAUSE_CHAIN (node); 9519 if (node && omp_map_clause_descriptor_p (node)) 9520 { 9521 gcc_assert (node != grp->grp_end); 9522 node = OMP_CLAUSE_CHAIN (node); 9523 } 9524 if (node) 9525 switch (OMP_CLAUSE_MAP_KIND (node)) 9526 { 9527 case GOMP_MAP_POINTER: 9528 case GOMP_MAP_ALWAYS_POINTER: 9529 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9530 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9531 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9532 return NULL_TREE; 9533 9534 case GOMP_MAP_ATTACH_DETACH: 9535 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9536 case GOMP_MAP_DETACH: 9537 return OMP_CLAUSE_DECL (node); 9538 9539 default: 9540 internal_error ("unexpected mapping node"); 9541 } 9542 return error_mark_node; 9543 9544 case GOMP_MAP_TO_PSET: 9545 gcc_assert (node != grp->grp_end); 9546 node = OMP_CLAUSE_CHAIN (node); 9547 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH 9548 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH) 9549 return OMP_CLAUSE_DECL (node); 9550 else 9551 internal_error ("unexpected mapping node"); 9552 return error_mark_node; 9553 9554 case GOMP_MAP_ATTACH: 9555 case GOMP_MAP_DETACH: 9556 node = OMP_CLAUSE_CHAIN (node); 9557 if (!node || *grp->grp_start == grp->grp_end) 9558 return OMP_CLAUSE_DECL (*grp->grp_start); 9559 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9560 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9561 return OMP_CLAUSE_DECL (*grp->grp_start); 9562 else 9563 internal_error ("unexpected mapping node"); 9564 return error_mark_node; 9565 9566 case GOMP_MAP_STRUCT: 9567 case GOMP_MAP_STRUCT_UNORD: 9568 case GOMP_MAP_FORCE_DEVICEPTR: 9569 case GOMP_MAP_DEVICE_RESIDENT: 9570 case GOMP_MAP_LINK: 9571 case GOMP_MAP_IF_PRESENT: 9572 case GOMP_MAP_FIRSTPRIVATE: 9573 case GOMP_MAP_FIRSTPRIVATE_INT: 9574 case GOMP_MAP_USE_DEVICE_PTR: 9575 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9576 return NULL_TREE; 9577 9578 default: 9579 internal_error ("unexpected mapping node"); 9580 } 9581 9582 return error_mark_node; 9583 } 9584 9585 /* Given a pointer START_P to the start of a group of related (e.g. pointer) 9586 mappings, return the chain pointer to the end of that group in the list. */ 9587 9588 static tree * 9589 omp_group_last (tree *start_p) 9590 { 9591 tree c = *start_p, nc, *grp_last_p = start_p; 9592 9593 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP); 9594 9595 nc = OMP_CLAUSE_CHAIN (c); 9596 9597 if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP) 9598 return grp_last_p; 9599 9600 switch (OMP_CLAUSE_MAP_KIND (c)) 9601 { 9602 default: 9603 while (nc 9604 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9605 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9606 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER 9607 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH 9608 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER 9609 || (OMP_CLAUSE_MAP_KIND (nc) 9610 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION) 9611 || (OMP_CLAUSE_MAP_KIND (nc) 9612 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION) 9613 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH 9614 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER 9615 || omp_map_clause_descriptor_p (nc))) 9616 { 9617 tree nc2 = OMP_CLAUSE_CHAIN (nc); 9618 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH) 9619 { 9620 /* In the specific case we're doing "exit data" on an array 9621 slice of a reference-to-pointer struct component, we will see 9622 DETACH followed by ATTACH_DETACH here. We want to treat that 9623 as a single group. In other cases DETACH might represent a 9624 stand-alone "detach" clause, so we don't want to consider 9625 that part of the group. */ 9626 if (nc2 9627 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP 9628 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH) 9629 goto consume_two_nodes; 9630 else 9631 break; 9632 } 9633 if (nc2 9634 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP 9635 && (OMP_CLAUSE_MAP_KIND (nc) 9636 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION) 9637 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH) 9638 { 9639 consume_two_nodes: 9640 grp_last_p = &OMP_CLAUSE_CHAIN (nc); 9641 c = nc2; 9642 nc = OMP_CLAUSE_CHAIN (nc2); 9643 } 9644 else 9645 { 9646 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9647 c = nc; 9648 nc = nc2; 9649 } 9650 } 9651 break; 9652 9653 case GOMP_MAP_ATTACH: 9654 case GOMP_MAP_DETACH: 9655 /* This is a weird artifact of how directives are parsed: bare attach or 9656 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or 9657 FIRSTPRIVATE_REFERENCE node. FIXME. */ 9658 if (nc 9659 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9660 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9661 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER)) 9662 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9663 break; 9664 9665 case GOMP_MAP_TO_PSET: 9666 if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP 9667 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH 9668 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)) 9669 grp_last_p = &OMP_CLAUSE_CHAIN (c); 9670 break; 9671 9672 case GOMP_MAP_STRUCT: 9673 case GOMP_MAP_STRUCT_UNORD: 9674 { 9675 unsigned HOST_WIDE_INT num_mappings 9676 = tree_to_uhwi (OMP_CLAUSE_SIZE (c)); 9677 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER 9678 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 9679 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH) 9680 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p); 9681 for (unsigned i = 0; i < num_mappings; i++) 9682 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p); 9683 } 9684 break; 9685 } 9686 9687 return grp_last_p; 9688 } 9689 9690 /* Walk through LIST_P, and return a list of groups of mappings found (e.g. 9691 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two 9692 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group 9693 if we have more than one such group, else return NULL. */ 9694 9695 static void 9696 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups, 9697 tree gather_sentinel) 9698 { 9699 for (tree *cp = list_p; 9700 *cp && *cp != gather_sentinel; 9701 cp = &OMP_CLAUSE_CHAIN (*cp)) 9702 { 9703 if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP) 9704 continue; 9705 9706 tree *grp_last_p = omp_group_last (cp); 9707 omp_mapping_group grp; 9708 9709 grp.grp_start = cp; 9710 grp.grp_end = *grp_last_p; 9711 grp.mark = UNVISITED; 9712 grp.sibling = NULL; 9713 grp.deleted = false; 9714 grp.reprocess_struct = false; 9715 grp.fragile = false; 9716 grp.next = NULL; 9717 groups->safe_push (grp); 9718 9719 cp = grp_last_p; 9720 } 9721 } 9722 9723 static vec<omp_mapping_group> * 9724 omp_gather_mapping_groups (tree *list_p) 9725 { 9726 vec<omp_mapping_group> *groups = new vec<omp_mapping_group> (); 9727 9728 omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE); 9729 9730 if (groups->length () > 0) 9731 return groups; 9732 else 9733 { 9734 delete groups; 9735 return NULL; 9736 } 9737 } 9738 9739 /* A pointer mapping group GRP may define a block of memory starting at some 9740 base address, and maybe also define a firstprivate pointer or firstprivate 9741 reference that points to that block. The return value is a node containing 9742 the former, and the *FIRSTPRIVATE pointer is set if we have the latter. 9743 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping, 9744 return the number of consecutive chained nodes in CHAINED. */ 9745 9746 static tree 9747 omp_group_base (omp_mapping_group *grp, unsigned int *chained, 9748 tree *firstprivate) 9749 { 9750 tree node = *grp->grp_start; 9751 9752 *firstprivate = NULL_TREE; 9753 *chained = 1; 9754 9755 switch (OMP_CLAUSE_MAP_KIND (node)) 9756 { 9757 case GOMP_MAP_TO: 9758 case GOMP_MAP_FROM: 9759 case GOMP_MAP_TOFROM: 9760 case GOMP_MAP_ALWAYS_FROM: 9761 case GOMP_MAP_ALWAYS_TO: 9762 case GOMP_MAP_ALWAYS_TOFROM: 9763 case GOMP_MAP_FORCE_FROM: 9764 case GOMP_MAP_FORCE_TO: 9765 case GOMP_MAP_FORCE_TOFROM: 9766 case GOMP_MAP_FORCE_PRESENT: 9767 case GOMP_MAP_PRESENT_ALLOC: 9768 case GOMP_MAP_PRESENT_FROM: 9769 case GOMP_MAP_PRESENT_TO: 9770 case GOMP_MAP_PRESENT_TOFROM: 9771 case GOMP_MAP_ALWAYS_PRESENT_FROM: 9772 case GOMP_MAP_ALWAYS_PRESENT_TO: 9773 case GOMP_MAP_ALWAYS_PRESENT_TOFROM: 9774 case GOMP_MAP_ALLOC: 9775 case GOMP_MAP_RELEASE: 9776 case GOMP_MAP_DELETE: 9777 case GOMP_MAP_FORCE_ALLOC: 9778 case GOMP_MAP_IF_PRESENT: 9779 if (node == grp->grp_end) 9780 return node; 9781 9782 node = OMP_CLAUSE_CHAIN (node); 9783 if (!node) 9784 internal_error ("unexpected mapping node"); 9785 if (omp_map_clause_descriptor_p (node)) 9786 { 9787 if (node == grp->grp_end) 9788 return *grp->grp_start; 9789 node = OMP_CLAUSE_CHAIN (node); 9790 } 9791 switch (OMP_CLAUSE_MAP_KIND (node)) 9792 { 9793 case GOMP_MAP_POINTER: 9794 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9795 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9796 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9797 *firstprivate = OMP_CLAUSE_DECL (node); 9798 return *grp->grp_start; 9799 9800 case GOMP_MAP_ALWAYS_POINTER: 9801 case GOMP_MAP_ATTACH_DETACH: 9802 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9803 case GOMP_MAP_DETACH: 9804 return *grp->grp_start; 9805 9806 default: 9807 internal_error ("unexpected mapping node"); 9808 } 9809 return error_mark_node; 9810 9811 case GOMP_MAP_TO_PSET: 9812 gcc_assert (node != grp->grp_end); 9813 node = OMP_CLAUSE_CHAIN (node); 9814 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH 9815 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH) 9816 return NULL_TREE; 9817 else 9818 internal_error ("unexpected mapping node"); 9819 return error_mark_node; 9820 9821 case GOMP_MAP_ATTACH: 9822 case GOMP_MAP_DETACH: 9823 node = OMP_CLAUSE_CHAIN (node); 9824 if (!node || *grp->grp_start == grp->grp_end) 9825 return NULL_TREE; 9826 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9827 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9828 { 9829 /* We're mapping the base pointer itself in a bare attach or detach 9830 node. This is a side effect of how parsing works, and the mapping 9831 will be removed anyway (at least for enter/exit data directives). 9832 We should ignore the mapping here. FIXME. */ 9833 return NULL_TREE; 9834 } 9835 else 9836 internal_error ("unexpected mapping node"); 9837 return error_mark_node; 9838 9839 case GOMP_MAP_STRUCT: 9840 case GOMP_MAP_STRUCT_UNORD: 9841 { 9842 unsigned HOST_WIDE_INT num_mappings 9843 = tree_to_uhwi (OMP_CLAUSE_SIZE (node)); 9844 node = OMP_CLAUSE_CHAIN (node); 9845 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER 9846 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 9847 { 9848 *firstprivate = OMP_CLAUSE_DECL (node); 9849 node = OMP_CLAUSE_CHAIN (node); 9850 } 9851 else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH) 9852 node = OMP_CLAUSE_CHAIN (node); 9853 *chained = num_mappings; 9854 return node; 9855 } 9856 9857 case GOMP_MAP_FORCE_DEVICEPTR: 9858 case GOMP_MAP_DEVICE_RESIDENT: 9859 case GOMP_MAP_LINK: 9860 case GOMP_MAP_FIRSTPRIVATE: 9861 case GOMP_MAP_FIRSTPRIVATE_INT: 9862 case GOMP_MAP_USE_DEVICE_PTR: 9863 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 9864 return NULL_TREE; 9865 9866 case GOMP_MAP_FIRSTPRIVATE_POINTER: 9867 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 9868 case GOMP_MAP_POINTER: 9869 case GOMP_MAP_ALWAYS_POINTER: 9870 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: 9871 /* These shouldn't appear by themselves. */ 9872 if (!seen_error ()) 9873 internal_error ("unexpected pointer mapping node"); 9874 return error_mark_node; 9875 9876 default: 9877 gcc_unreachable (); 9878 } 9879 9880 return error_mark_node; 9881 } 9882 9883 /* Given a vector of omp_mapping_groups, build a hash table so we can look up 9884 nodes by tree_operand_hash_no_se. */ 9885 9886 static void 9887 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se, 9888 omp_mapping_group *> *grpmap, 9889 vec<omp_mapping_group> *groups, 9890 tree reindex_sentinel) 9891 { 9892 omp_mapping_group *grp; 9893 unsigned int i; 9894 bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false; 9895 9896 FOR_EACH_VEC_ELT (*groups, i, grp) 9897 { 9898 if (reindexing && *grp->grp_start == reindex_sentinel) 9899 above_hwm = true; 9900 9901 if (reindexing && !above_hwm) 9902 continue; 9903 9904 if (grp->reprocess_struct) 9905 continue; 9906 9907 tree fpp; 9908 unsigned int chained; 9909 tree node = omp_group_base (grp, &chained, &fpp); 9910 9911 if (node == error_mark_node || (!node && !fpp)) 9912 continue; 9913 9914 for (unsigned j = 0; 9915 node && j < chained; 9916 node = OMP_CLAUSE_CHAIN (node), j++) 9917 { 9918 tree decl = OMP_CLAUSE_DECL (node); 9919 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF, 9920 meaning node-hash lookups don't work. This is a workaround for 9921 that, but ideally we should just create the INDIRECT_REF at 9922 source instead. FIXME. */ 9923 if (TREE_CODE (decl) == MEM_REF 9924 && integer_zerop (TREE_OPERAND (decl, 1))) 9925 decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0)); 9926 9927 omp_mapping_group **prev = grpmap->get (decl); 9928 9929 if (prev && *prev == grp) 9930 /* Empty. */; 9931 else if (prev) 9932 { 9933 /* Mapping the same thing twice is normally diagnosed as an error, 9934 but can happen under some circumstances, e.g. in pr99928-16.c, 9935 the directive: 9936 9937 #pragma omp target simd reduction(+:a[:3]) \ 9938 map(always, tofrom: a[:6]) 9939 ... 9940 9941 will result in two "a[0]" mappings (of different sizes). */ 9942 9943 grp->sibling = (*prev)->sibling; 9944 (*prev)->sibling = grp; 9945 } 9946 else 9947 grpmap->put (decl, grp); 9948 } 9949 9950 if (!fpp) 9951 continue; 9952 9953 omp_mapping_group **prev = grpmap->get (fpp); 9954 if (prev && *prev != grp) 9955 { 9956 grp->sibling = (*prev)->sibling; 9957 (*prev)->sibling = grp; 9958 } 9959 else 9960 grpmap->put (fpp, grp); 9961 } 9962 } 9963 9964 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> * 9965 omp_index_mapping_groups (vec<omp_mapping_group> *groups) 9966 { 9967 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap 9968 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>; 9969 9970 omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE); 9971 9972 return grpmap; 9973 } 9974 9975 /* Rebuild group map from partially-processed clause list (during 9976 omp_build_struct_sibling_lists). We have already processed nodes up until 9977 a high-water mark (HWM). This is a bit tricky because the list is being 9978 reordered as it is scanned, but we know: 9979 9980 1. The list after HWM has not been touched yet, so we can reindex it safely. 9981 9982 2. The list before and including HWM has been altered, but remains 9983 well-formed throughout the sibling-list building operation. 9984 9985 so, we can do the reindex operation in two parts, on the processed and 9986 then the unprocessed halves of the list. */ 9987 9988 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> * 9989 omp_reindex_mapping_groups (tree *list_p, 9990 vec<omp_mapping_group> *groups, 9991 vec<omp_mapping_group> *processed_groups, 9992 tree sentinel) 9993 { 9994 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap 9995 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>; 9996 9997 processed_groups->truncate (0); 9998 9999 omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel); 10000 omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE); 10001 if (sentinel) 10002 omp_index_mapping_groups_1 (grpmap, groups, sentinel); 10003 10004 return grpmap; 10005 } 10006 10007 /* Find the immediately-containing struct for a component ref (etc.) 10008 expression EXPR. */ 10009 10010 static tree 10011 omp_containing_struct (tree expr) 10012 { 10013 tree expr0 = expr; 10014 10015 STRIP_NOPS (expr); 10016 10017 /* Note: don't strip NOPs unless we're also stripping off array refs or a 10018 component ref. */ 10019 if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF) 10020 return expr0; 10021 10022 while (TREE_CODE (expr) == ARRAY_REF) 10023 expr = TREE_OPERAND (expr, 0); 10024 10025 if (TREE_CODE (expr) == COMPONENT_REF) 10026 expr = TREE_OPERAND (expr, 0); 10027 10028 return expr; 10029 } 10030 10031 /* Return TRUE if DECL describes a component that is part of a whole structure 10032 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group 10033 that maps that structure, if present. */ 10034 10035 static bool 10036 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se, 10037 omp_mapping_group *> *grpmap, 10038 tree decl, 10039 omp_mapping_group **mapped_by_group) 10040 { 10041 tree wsdecl = NULL_TREE; 10042 10043 *mapped_by_group = NULL; 10044 10045 while (true) 10046 { 10047 wsdecl = omp_containing_struct (decl); 10048 if (wsdecl == decl) 10049 break; 10050 omp_mapping_group **wholestruct = grpmap->get (wsdecl); 10051 if (!wholestruct 10052 && TREE_CODE (wsdecl) == MEM_REF 10053 && integer_zerop (TREE_OPERAND (wsdecl, 1))) 10054 { 10055 tree deref = TREE_OPERAND (wsdecl, 0); 10056 deref = build_fold_indirect_ref (deref); 10057 wholestruct = grpmap->get (deref); 10058 } 10059 if (wholestruct) 10060 { 10061 *mapped_by_group = *wholestruct; 10062 return true; 10063 } 10064 decl = wsdecl; 10065 } 10066 10067 return false; 10068 } 10069 10070 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or 10071 FALSE on error. */ 10072 10073 static bool 10074 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist, 10075 vec<omp_mapping_group> *groups, 10076 hash_map<tree_operand_hash_no_se, 10077 omp_mapping_group *> *grpmap, 10078 omp_mapping_group *grp) 10079 { 10080 if (grp->mark == PERMANENT) 10081 return true; 10082 if (grp->mark == TEMPORARY) 10083 { 10084 fprintf (stderr, "when processing group:\n"); 10085 debug_mapping_group (grp); 10086 internal_error ("base pointer cycle detected"); 10087 return false; 10088 } 10089 grp->mark = TEMPORARY; 10090 10091 tree attaches_to = omp_get_attachment (grp); 10092 10093 if (attaches_to) 10094 { 10095 omp_mapping_group **basep = grpmap->get (attaches_to); 10096 10097 if (basep && *basep != grp) 10098 { 10099 for (omp_mapping_group *w = *basep; w; w = w->sibling) 10100 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w)) 10101 return false; 10102 } 10103 } 10104 10105 tree decl = OMP_CLAUSE_DECL (*grp->grp_start); 10106 10107 while (decl) 10108 { 10109 tree base = omp_get_base_pointer (decl); 10110 10111 if (!base) 10112 break; 10113 10114 omp_mapping_group **innerp = grpmap->get (base); 10115 omp_mapping_group *wholestruct; 10116 10117 /* We should treat whole-structure mappings as if all (pointer, in this 10118 case) members are mapped as individual list items. Check if we have 10119 such a whole-structure mapping, if we don't have an explicit reference 10120 to the pointer member itself. */ 10121 if (!innerp 10122 && TREE_CODE (base) == COMPONENT_REF 10123 && omp_mapped_by_containing_struct (grpmap, base, &wholestruct)) 10124 innerp = &wholestruct; 10125 10126 if (innerp && *innerp != grp) 10127 { 10128 for (omp_mapping_group *w = *innerp; w; w = w->sibling) 10129 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w)) 10130 return false; 10131 break; 10132 } 10133 10134 decl = base; 10135 } 10136 10137 grp->mark = PERMANENT; 10138 10139 /* Emit grp to output list. */ 10140 10141 **outlist = grp; 10142 *outlist = &grp->next; 10143 10144 return true; 10145 } 10146 10147 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come 10148 before mappings that use those pointers. This is an implementation of the 10149 depth-first search algorithm, described e.g. at: 10150 10151 https://en.wikipedia.org/wiki/Topological_sorting 10152 */ 10153 10154 static omp_mapping_group * 10155 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups, 10156 hash_map<tree_operand_hash_no_se, omp_mapping_group *> 10157 *grpmap, 10158 bool enter_exit_data) 10159 { 10160 omp_mapping_group *grp, *outlist = NULL, **cursor; 10161 unsigned int i; 10162 bool saw_runtime_implicit = false; 10163 10164 cursor = &outlist; 10165 10166 FOR_EACH_VEC_ELT (*groups, i, grp) 10167 { 10168 if (grp->mark != PERMANENT) 10169 { 10170 if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start)) 10171 { 10172 saw_runtime_implicit = true; 10173 continue; 10174 } 10175 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp)) 10176 return NULL; 10177 } 10178 } 10179 10180 if (!saw_runtime_implicit) 10181 return outlist; 10182 10183 FOR_EACH_VEC_ELT (*groups, i, grp) 10184 { 10185 if (grp->mark != PERMANENT 10186 && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start)) 10187 { 10188 /* Clear the flag for enter/exit data because it is currently 10189 meaningless for those operations in libgomp. */ 10190 if (enter_exit_data) 10191 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0; 10192 10193 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp)) 10194 return NULL; 10195 } 10196 } 10197 10198 return outlist; 10199 } 10200 10201 /* Split INLIST into three parts: 10202 10203 - "present" alloc/to/from groups 10204 - other to/from groups 10205 - other alloc/release/delete groups 10206 10207 These sub-lists are then concatenated together to form the final list. 10208 Each sub-list retains the order of the original list. 10209 Note that ATTACH nodes are later moved to the end of the list in 10210 gimplify_adjust_omp_clauses, for target regions. */ 10211 10212 static omp_mapping_group * 10213 omp_segregate_mapping_groups (omp_mapping_group *inlist) 10214 { 10215 omp_mapping_group *ard_groups = NULL, *tf_groups = NULL; 10216 omp_mapping_group *p_groups = NULL; 10217 omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups; 10218 omp_mapping_group **p_tail = &p_groups; 10219 10220 for (omp_mapping_group *w = inlist; w;) 10221 { 10222 tree c = *w->grp_start; 10223 omp_mapping_group *next = w->next; 10224 10225 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP); 10226 10227 switch (OMP_CLAUSE_MAP_KIND (c)) 10228 { 10229 case GOMP_MAP_ALLOC: 10230 case GOMP_MAP_RELEASE: 10231 case GOMP_MAP_DELETE: 10232 *ard_tail = w; 10233 w->next = NULL; 10234 ard_tail = &w->next; 10235 break; 10236 10237 /* These map types are all semantically identical, so are moved into a 10238 single group. They will each be changed into GOMP_MAP_FORCE_PRESENT 10239 in gimplify_adjust_omp_clauses. */ 10240 case GOMP_MAP_PRESENT_ALLOC: 10241 case GOMP_MAP_PRESENT_FROM: 10242 case GOMP_MAP_PRESENT_TO: 10243 case GOMP_MAP_PRESENT_TOFROM: 10244 *p_tail = w; 10245 w->next = NULL; 10246 p_tail = &w->next; 10247 break; 10248 10249 default: 10250 *tf_tail = w; 10251 w->next = NULL; 10252 tf_tail = &w->next; 10253 } 10254 10255 w = next; 10256 } 10257 10258 /* Now splice the lists together... */ 10259 *tf_tail = ard_groups; 10260 *p_tail = tf_groups; 10261 10262 return p_groups; 10263 } 10264 10265 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder 10266 those groups based on the output list of omp_tsort_mapping_groups -- 10267 singly-linked, threaded through each element's NEXT pointer starting at 10268 HEAD. Each list element appears exactly once in that linked list. 10269 10270 Each element of GROUPS may correspond to one or several mapping nodes. 10271 Node groups are kept together, and in the reordered list, the positions of 10272 the original groups are reused for the positions of the reordered list. 10273 Hence if we have e.g. 10274 10275 {to ptr ptr} firstprivate {tofrom ptr} ... 10276 ^ ^ ^ 10277 first group non-"map" second group 10278 10279 and say the second group contains a base pointer for the first so must be 10280 moved before it, the resulting list will contain: 10281 10282 {tofrom ptr} firstprivate {to ptr ptr} ... 10283 ^ prev. second group ^ prev. first group 10284 */ 10285 10286 static tree * 10287 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups, 10288 omp_mapping_group *head, 10289 tree *list_p) 10290 { 10291 omp_mapping_group *grp; 10292 unsigned int i; 10293 unsigned numgroups = groups->length (); 10294 auto_vec<tree> old_heads (numgroups); 10295 auto_vec<tree *> old_headps (numgroups); 10296 auto_vec<tree> new_heads (numgroups); 10297 auto_vec<tree> old_succs (numgroups); 10298 bool map_at_start = (list_p == (*groups)[0].grp_start); 10299 10300 tree *new_grp_tail = NULL; 10301 10302 /* Stash the start & end nodes of each mapping group before we start 10303 modifying the list. */ 10304 FOR_EACH_VEC_ELT (*groups, i, grp) 10305 { 10306 old_headps.quick_push (grp->grp_start); 10307 old_heads.quick_push (*grp->grp_start); 10308 old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end)); 10309 } 10310 10311 /* And similarly, the heads of the groups in the order we want to rearrange 10312 the list to. */ 10313 for (omp_mapping_group *w = head; w; w = w->next) 10314 new_heads.quick_push (*w->grp_start); 10315 10316 FOR_EACH_VEC_ELT (*groups, i, grp) 10317 { 10318 gcc_assert (head); 10319 10320 if (new_grp_tail && old_succs[i - 1] == old_heads[i]) 10321 { 10322 /* a {b c d} {e f g} h i j (original) 10323 --> 10324 a {k l m} {e f g} h i j (inserted new group on last iter) 10325 --> 10326 a {k l m} {n o p} h i j (this time, chain last group to new one) 10327 ^new_grp_tail 10328 */ 10329 *new_grp_tail = new_heads[i]; 10330 } 10331 else if (new_grp_tail) 10332 { 10333 /* a {b c d} e {f g h} i j k (original) 10334 --> 10335 a {l m n} e {f g h} i j k (gap after last iter's group) 10336 --> 10337 a {l m n} e {o p q} h i j (chain last group to old successor) 10338 ^new_grp_tail 10339 */ 10340 *new_grp_tail = old_succs[i - 1]; 10341 *old_headps[i] = new_heads[i]; 10342 } 10343 else 10344 { 10345 /* The first inserted group -- point to new group, and leave end 10346 open. 10347 a {b c d} e f 10348 --> 10349 a {g h i... 10350 */ 10351 *grp->grp_start = new_heads[i]; 10352 } 10353 10354 new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end); 10355 10356 head = head->next; 10357 } 10358 10359 if (new_grp_tail) 10360 *new_grp_tail = old_succs[numgroups - 1]; 10361 10362 gcc_assert (!head); 10363 10364 return map_at_start ? (*groups)[0].grp_start : list_p; 10365 } 10366 10367 /* DECL is supposed to have lastprivate semantics in the outer contexts 10368 of combined/composite constructs, starting with OCTX. 10369 Add needed lastprivate, shared or map clause if no data sharing or 10370 mapping clause are present. IMPLICIT_P is true if it is an implicit 10371 clause (IV on simd), in which case the lastprivate will not be 10372 copied to some constructs. */ 10373 10374 static void 10375 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx, 10376 tree decl, bool implicit_p) 10377 { 10378 struct gimplify_omp_ctx *orig_octx = octx; 10379 for (; octx; octx = octx->outer_context) 10380 { 10381 if ((octx->region_type == ORT_COMBINED_PARALLEL 10382 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS) 10383 && splay_tree_lookup (octx->variables, 10384 (splay_tree_key) decl) == NULL) 10385 { 10386 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN); 10387 continue; 10388 } 10389 if ((octx->region_type & ORT_TASK) != 0 10390 && octx->combined_loop 10391 && splay_tree_lookup (octx->variables, 10392 (splay_tree_key) decl) == NULL) 10393 { 10394 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10395 continue; 10396 } 10397 if (implicit_p 10398 && octx->region_type == ORT_WORKSHARE 10399 && octx->combined_loop 10400 && splay_tree_lookup (octx->variables, 10401 (splay_tree_key) decl) == NULL 10402 && octx->outer_context 10403 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL 10404 && splay_tree_lookup (octx->outer_context->variables, 10405 (splay_tree_key) decl) == NULL) 10406 { 10407 octx = octx->outer_context; 10408 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10409 continue; 10410 } 10411 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC) 10412 && octx->combined_loop 10413 && splay_tree_lookup (octx->variables, 10414 (splay_tree_key) decl) == NULL 10415 && !omp_check_private (octx, decl, false)) 10416 { 10417 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN); 10418 continue; 10419 } 10420 if (octx->region_type == ORT_COMBINED_TARGET) 10421 { 10422 splay_tree_node n = splay_tree_lookup (octx->variables, 10423 (splay_tree_key) decl); 10424 if (n == NULL) 10425 { 10426 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN); 10427 octx = octx->outer_context; 10428 } 10429 else if (!implicit_p 10430 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT)) 10431 { 10432 n->value &= ~(GOVD_FIRSTPRIVATE 10433 | GOVD_FIRSTPRIVATE_IMPLICIT 10434 | GOVD_EXPLICIT); 10435 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN); 10436 octx = octx->outer_context; 10437 } 10438 } 10439 break; 10440 } 10441 if (octx && (implicit_p || octx != orig_octx)) 10442 omp_notice_variable (octx, decl, true); 10443 } 10444 10445 /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also 10446 a "FIRSTPRIVATE" mapping. Return the one that isn't firstprivate, etc. */ 10447 10448 static omp_mapping_group * 10449 omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se, 10450 omp_mapping_group *> *grpmap, 10451 tree decl, bool allow_deleted = false) 10452 { 10453 omp_mapping_group **to_group_p = grpmap->get (decl); 10454 10455 if (!to_group_p) 10456 return NULL; 10457 10458 omp_mapping_group *to_group = *to_group_p; 10459 10460 for (; to_group; to_group = to_group->sibling) 10461 { 10462 tree grp_end = to_group->grp_end; 10463 switch (OMP_CLAUSE_MAP_KIND (grp_end)) 10464 { 10465 case GOMP_MAP_FIRSTPRIVATE_POINTER: 10466 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 10467 break; 10468 10469 default: 10470 if (allow_deleted || !to_group->deleted) 10471 return to_group; 10472 } 10473 } 10474 10475 return NULL; 10476 } 10477 10478 /* Return TRUE if the directive (whose clauses are described by the hash table 10479 of mapping groups, GRPMAP) maps DECL explicitly. If TO_SPECIFICALLY is 10480 true, only count TO mappings. If ALLOW_DELETED is true, ignore the 10481 "deleted" flag for groups. If CONTAINED_IN_STRUCT is true, also return 10482 TRUE if DECL is mapped as a member of a whole-struct mapping. */ 10483 10484 static bool 10485 omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se, 10486 omp_mapping_group *> *grpmap, 10487 tree decl, omp_mapping_group **base_group, 10488 bool to_specifically, bool allow_deleted, 10489 bool contained_in_struct) 10490 { 10491 omp_mapping_group *decl_group 10492 = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted); 10493 10494 *base_group = NULL; 10495 10496 if (decl_group) 10497 { 10498 tree grp_first = *decl_group->grp_start; 10499 /* We might be called during omp_build_struct_sibling_lists, when 10500 GOMP_MAP_STRUCT might have been inserted at the start of the group. 10501 Skip over that, and also possibly the node after it. */ 10502 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT 10503 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD) 10504 { 10505 grp_first = OMP_CLAUSE_CHAIN (grp_first); 10506 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER 10507 || (OMP_CLAUSE_MAP_KIND (grp_first) 10508 == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 10509 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH) 10510 grp_first = OMP_CLAUSE_CHAIN (grp_first); 10511 } 10512 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10513 if (!to_specifically 10514 || GOMP_MAP_COPY_TO_P (first_kind) 10515 || first_kind == GOMP_MAP_ALLOC) 10516 { 10517 *base_group = decl_group; 10518 return true; 10519 } 10520 } 10521 10522 if (contained_in_struct 10523 && omp_mapped_by_containing_struct (grpmap, decl, base_group)) 10524 return true; 10525 10526 return false; 10527 } 10528 10529 /* If we have mappings INNER and OUTER, where INNER is a component access and 10530 OUTER is a mapping of the whole containing struct, check that the mappings 10531 are compatible. We'll be deleting the inner mapping, so we need to make 10532 sure the outer mapping does (at least) the same transfers to/from the device 10533 as the inner mapping. */ 10534 10535 bool 10536 omp_check_mapping_compatibility (location_t loc, 10537 omp_mapping_group *outer, 10538 omp_mapping_group *inner) 10539 { 10540 tree first_outer = *outer->grp_start, first_inner = *inner->grp_start; 10541 10542 gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP); 10543 gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP); 10544 10545 enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer); 10546 enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner); 10547 10548 if (outer_kind == inner_kind) 10549 return true; 10550 10551 switch (outer_kind) 10552 { 10553 case GOMP_MAP_ALWAYS_TO: 10554 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10555 || inner_kind == GOMP_MAP_ALLOC 10556 || inner_kind == GOMP_MAP_TO) 10557 return true; 10558 break; 10559 10560 case GOMP_MAP_ALWAYS_FROM: 10561 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10562 || inner_kind == GOMP_MAP_RELEASE 10563 || inner_kind == GOMP_MAP_FROM) 10564 return true; 10565 break; 10566 10567 case GOMP_MAP_TO: 10568 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10569 || inner_kind == GOMP_MAP_ALLOC) 10570 return true; 10571 break; 10572 10573 case GOMP_MAP_FROM: 10574 if (inner_kind == GOMP_MAP_RELEASE 10575 || inner_kind == GOMP_MAP_FORCE_PRESENT) 10576 return true; 10577 break; 10578 10579 case GOMP_MAP_ALWAYS_TOFROM: 10580 case GOMP_MAP_TOFROM: 10581 if (inner_kind == GOMP_MAP_FORCE_PRESENT 10582 || inner_kind == GOMP_MAP_ALLOC 10583 || inner_kind == GOMP_MAP_TO 10584 || inner_kind == GOMP_MAP_FROM 10585 || inner_kind == GOMP_MAP_TOFROM) 10586 return true; 10587 break; 10588 10589 default: 10590 ; 10591 } 10592 10593 error_at (loc, "data movement for component %qE is not compatible with " 10594 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner), 10595 OMP_CLAUSE_DECL (first_outer)); 10596 10597 return false; 10598 } 10599 10600 /* This function handles several cases where clauses on a mapping directive 10601 can interact with each other. 10602 10603 If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer 10604 on the same directive, change the mapping of the first node to 10605 ATTACH_DETACH. We should have detected that this will happen already in 10606 c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl 10607 as addressable. (If we didn't, bail out.) 10608 10609 If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're 10610 mapping the base pointer also, we may need to change the mapping type to 10611 ATTACH_DETACH and synthesize an alloc node for the reference itself. 10612 10613 If we have an ATTACH_DETACH node, this is an array section with a pointer 10614 base. If we're mapping the base on the same directive too, we can drop its 10615 mapping. However, if we have a reference to pointer, make other appropriate 10616 adjustments to the mapping nodes instead. 10617 10618 If we have an ATTACH_DETACH node with a Fortran pointer-set (array 10619 descriptor) mapping for a derived-type component, and we're also mapping the 10620 whole of the derived-type variable on another clause, the pointer-set 10621 mapping is removed. 10622 10623 If we have a component access but we're also mapping the whole of the 10624 containing struct, drop the former access. 10625 10626 If the expression is a component access, and we're also mapping a base 10627 pointer used in that component access in the same expression, change the 10628 mapping type of the latter to ALLOC (ready for processing by 10629 omp_build_struct_sibling_lists). */ 10630 10631 void 10632 omp_resolve_clause_dependencies (enum tree_code code, 10633 vec<omp_mapping_group> *groups, 10634 hash_map<tree_operand_hash_no_se, 10635 omp_mapping_group *> *grpmap) 10636 { 10637 int i; 10638 omp_mapping_group *grp; 10639 bool repair_chain = false; 10640 10641 FOR_EACH_VEC_ELT (*groups, i, grp) 10642 { 10643 tree grp_end = grp->grp_end; 10644 tree decl = OMP_CLAUSE_DECL (grp_end); 10645 10646 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP); 10647 10648 switch (OMP_CLAUSE_MAP_KIND (grp_end)) 10649 { 10650 case GOMP_MAP_FIRSTPRIVATE_POINTER: 10651 { 10652 omp_mapping_group *to_group 10653 = omp_get_nonfirstprivate_group (grpmap, decl); 10654 10655 if (!to_group || to_group == grp) 10656 continue; 10657 10658 tree grp_first = *to_group->grp_start; 10659 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10660 10661 if ((GOMP_MAP_COPY_TO_P (first_kind) 10662 || first_kind == GOMP_MAP_ALLOC) 10663 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end) 10664 != GOMP_MAP_FIRSTPRIVATE_POINTER)) 10665 { 10666 gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end))); 10667 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH); 10668 } 10669 } 10670 break; 10671 10672 case GOMP_MAP_FIRSTPRIVATE_REFERENCE: 10673 { 10674 tree ptr = build_fold_indirect_ref (decl); 10675 10676 omp_mapping_group *to_group 10677 = omp_get_nonfirstprivate_group (grpmap, ptr); 10678 10679 if (!to_group || to_group == grp) 10680 continue; 10681 10682 tree grp_first = *to_group->grp_start; 10683 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first); 10684 10685 if (GOMP_MAP_COPY_TO_P (first_kind) 10686 || first_kind == GOMP_MAP_ALLOC) 10687 { 10688 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH); 10689 OMP_CLAUSE_DECL (grp_end) = ptr; 10690 if ((OMP_CLAUSE_CHAIN (*to_group->grp_start) 10691 == to_group->grp_end) 10692 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end) 10693 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 10694 { 10695 gcc_assert (TREE_ADDRESSABLE 10696 (OMP_CLAUSE_DECL (to_group->grp_end))); 10697 OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end, 10698 GOMP_MAP_ATTACH_DETACH); 10699 10700 location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end); 10701 tree alloc 10702 = build_omp_clause (loc, OMP_CLAUSE_MAP); 10703 OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC); 10704 tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL 10705 (to_group->grp_end)); 10706 tree char_ptr_type = build_pointer_type (char_type_node); 10707 OMP_CLAUSE_DECL (alloc) 10708 = build2 (MEM_REF, char_type_node, 10709 tmp, 10710 build_int_cst (char_ptr_type, 0)); 10711 OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp)); 10712 10713 OMP_CLAUSE_CHAIN (alloc) 10714 = OMP_CLAUSE_CHAIN (*to_group->grp_start); 10715 OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc; 10716 } 10717 } 10718 } 10719 break; 10720 10721 case GOMP_MAP_ATTACH_DETACH: 10722 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: 10723 { 10724 tree base_ptr, referenced_ptr_node = NULL_TREE; 10725 10726 while (TREE_CODE (decl) == ARRAY_REF) 10727 decl = TREE_OPERAND (decl, 0); 10728 10729 if (TREE_CODE (decl) == INDIRECT_REF) 10730 decl = TREE_OPERAND (decl, 0); 10731 10732 /* Only component accesses. */ 10733 if (DECL_P (decl)) 10734 continue; 10735 10736 /* We want the pointer itself when checking if the base pointer is 10737 mapped elsewhere in the same directive -- if we have a 10738 reference to the pointer, don't use that. */ 10739 10740 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 10741 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE) 10742 { 10743 referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start); 10744 base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node); 10745 } 10746 else 10747 base_ptr = decl; 10748 10749 gomp_map_kind zlas_kind 10750 = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA) 10751 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION; 10752 10753 if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE) 10754 { 10755 /* If we map the base TO, and we're doing an attachment, we can 10756 skip the TO mapping altogether and create an ALLOC mapping 10757 instead, since the attachment will overwrite the device 10758 pointer in that location immediately anyway. Otherwise, 10759 change our mapping to 10760 GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the 10761 attachment target has not been copied to the device already 10762 by some earlier directive. */ 10763 10764 bool base_mapped_to = false; 10765 10766 omp_mapping_group *base_group; 10767 10768 if (omp_directive_maps_explicitly (grpmap, base_ptr, 10769 &base_group, false, true, 10770 false)) 10771 { 10772 if (referenced_ptr_node) 10773 { 10774 base_mapped_to = true; 10775 if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end) 10776 == GOMP_MAP_ATTACH_DETACH) 10777 && (OMP_CLAUSE_CHAIN (*base_group->grp_start) 10778 == base_group->grp_end)) 10779 { 10780 OMP_CLAUSE_CHAIN (*base_group->grp_start) 10781 = OMP_CLAUSE_CHAIN (base_group->grp_end); 10782 base_group->grp_end = *base_group->grp_start; 10783 repair_chain = true; 10784 } 10785 } 10786 else 10787 { 10788 base_group->deleted = true; 10789 OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1; 10790 } 10791 } 10792 10793 /* We're dealing with a reference to a pointer, and we are 10794 attaching both the reference and the pointer. We know the 10795 reference itself is on the target, because we are going to 10796 create an ALLOC node for it in accumulate_sibling_list. The 10797 pointer might be on the target already or it might not, but 10798 if it isn't then it's not an error, so use 10799 GOMP_MAP_ATTACH_ZLAS for it. */ 10800 if (!base_mapped_to && referenced_ptr_node) 10801 OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind); 10802 10803 omp_mapping_group *struct_group; 10804 tree desc; 10805 if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start)) 10806 && omp_map_clause_descriptor_p (desc) 10807 && omp_mapped_by_containing_struct (grpmap, decl, 10808 &struct_group)) 10809 /* If we have a pointer set but we're mapping (or unmapping) 10810 the whole of the containing struct, we can remove the 10811 pointer set mapping. */ 10812 OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc); 10813 } 10814 else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE 10815 && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr))) 10816 == ARRAY_TYPE) 10817 && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION 10818 (*grp->grp_start)) 10819 OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind); 10820 } 10821 break; 10822 10823 case GOMP_MAP_ATTACH: 10824 /* Ignore standalone attach here. */ 10825 break; 10826 10827 default: 10828 { 10829 omp_mapping_group *struct_group; 10830 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group) 10831 && *grp->grp_start == grp_end) 10832 { 10833 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end), 10834 struct_group, grp); 10835 /* Remove the whole of this mapping -- redundant. */ 10836 grp->deleted = true; 10837 } 10838 10839 tree base = decl; 10840 while ((base = omp_get_base_pointer (base))) 10841 { 10842 omp_mapping_group *base_group; 10843 10844 if (omp_directive_maps_explicitly (grpmap, base, &base_group, 10845 true, true, false)) 10846 { 10847 tree grp_first = *base_group->grp_start; 10848 OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC); 10849 } 10850 } 10851 } 10852 } 10853 } 10854 10855 if (repair_chain) 10856 { 10857 /* Group start pointers may have become detached from the 10858 OMP_CLAUSE_CHAIN of previous groups if elements were removed from the 10859 end of those groups. Fix that now. */ 10860 tree *new_next = NULL; 10861 FOR_EACH_VEC_ELT (*groups, i, grp) 10862 { 10863 if (new_next) 10864 grp->grp_start = new_next; 10865 10866 new_next = &OMP_CLAUSE_CHAIN (grp->grp_end); 10867 } 10868 } 10869 } 10870 10871 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only 10872 clause dependencies we handle for now are struct element mappings and 10873 whole-struct mappings on the same directive, and duplicate clause 10874 detection. */ 10875 10876 void 10877 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups, 10878 hash_map<tree_operand_hash_no_se, 10879 omp_mapping_group *> *grpmap) 10880 { 10881 int i; 10882 omp_mapping_group *grp; 10883 hash_set<tree_operand_hash> *seen_components = NULL; 10884 hash_set<tree_operand_hash> *shown_error = NULL; 10885 10886 FOR_EACH_VEC_ELT (*groups, i, grp) 10887 { 10888 tree grp_end = grp->grp_end; 10889 tree decl = OMP_CLAUSE_DECL (grp_end); 10890 10891 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP); 10892 10893 if (DECL_P (grp_end)) 10894 continue; 10895 10896 tree c = OMP_CLAUSE_DECL (*grp->grp_start); 10897 while (TREE_CODE (c) == ARRAY_REF) 10898 c = TREE_OPERAND (c, 0); 10899 if (TREE_CODE (c) != COMPONENT_REF) 10900 continue; 10901 if (!seen_components) 10902 seen_components = new hash_set<tree_operand_hash> (); 10903 if (!shown_error) 10904 shown_error = new hash_set<tree_operand_hash> (); 10905 if (seen_components->contains (c) 10906 && !shown_error->contains (c)) 10907 { 10908 error_at (OMP_CLAUSE_LOCATION (grp_end), 10909 "%qE appears more than once in map clauses", 10910 OMP_CLAUSE_DECL (grp_end)); 10911 shown_error->add (c); 10912 } 10913 else 10914 seen_components->add (c); 10915 10916 omp_mapping_group *struct_group; 10917 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group) 10918 && *grp->grp_start == grp_end) 10919 { 10920 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end), 10921 struct_group, grp); 10922 /* Remove the whole of this mapping -- redundant. */ 10923 grp->deleted = true; 10924 } 10925 } 10926 10927 if (seen_components) 10928 delete seen_components; 10929 if (shown_error) 10930 delete shown_error; 10931 } 10932 10933 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain 10934 is linked to the previous node pointed to by INSERT_AT. */ 10935 10936 static tree * 10937 omp_siblist_insert_node_after (tree newnode, tree *insert_at) 10938 { 10939 OMP_CLAUSE_CHAIN (newnode) = *insert_at; 10940 *insert_at = newnode; 10941 return &OMP_CLAUSE_CHAIN (newnode); 10942 } 10943 10944 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is 10945 pointed to by chain MOVE_AFTER instead. */ 10946 10947 static void 10948 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after) 10949 { 10950 gcc_assert (node == *old_pos); 10951 *old_pos = OMP_CLAUSE_CHAIN (node); 10952 OMP_CLAUSE_CHAIN (node) = *move_after; 10953 *move_after = node; 10954 } 10955 10956 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to 10957 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no 10958 new nodes are prepended to the list before splicing into the new position. 10959 Return the position we should continue scanning the list at, or NULL to 10960 stay where we were. */ 10961 10962 static tree * 10963 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node, 10964 tree *move_after) 10965 { 10966 if (first_ptr == move_after) 10967 return NULL; 10968 10969 tree tmp = *first_ptr; 10970 *first_ptr = OMP_CLAUSE_CHAIN (last_node); 10971 OMP_CLAUSE_CHAIN (last_node) = *move_after; 10972 *move_after = tmp; 10973 10974 return first_ptr; 10975 } 10976 10977 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and 10978 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain 10979 pointer MOVE_AFTER. 10980 10981 The latter list was previously part of the OMP clause list, and the former 10982 (prepended) part is comprised of new nodes. 10983 10984 We start with a list of nodes starting with a struct mapping node. We 10985 rearrange the list so that new nodes starting from FIRST_NEW and whose last 10986 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by 10987 the group of mapping nodes we are currently processing (from the chain 10988 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain 10989 we should continue processing from, or NULL to stay where we were. 10990 10991 The transformation (in the case where MOVE_AFTER and FIRST_PTR are 10992 different) is worked through below. Here we are processing LAST_NODE, and 10993 FIRST_PTR points at the preceding mapping clause: 10994 10995 #. mapping node chain 10996 --------------------------------------------------- 10997 A. struct_node [->B] 10998 B. comp_1 [->C] 10999 C. comp_2 [->D (move_after)] 11000 D. map_to_3 [->E] 11001 E. attach_3 [->F (first_ptr)] 11002 F. map_to_4 [->G (continue_at)] 11003 G. attach_4 (last_node) [->H] 11004 H. ... 11005 11006 *last_new_tail = *first_ptr; 11007 11008 I. new_node (first_new) [->F (last_new_tail)] 11009 11010 *first_ptr = OMP_CLAUSE_CHAIN (last_node) 11011 11012 #. mapping node chain 11013 ---------------------------------------------------- 11014 A. struct_node [->B] 11015 B. comp_1 [->C] 11016 C. comp_2 [->D (move_after)] 11017 D. map_to_3 [->E] 11018 E. attach_3 [->H (first_ptr)] 11019 F. map_to_4 [->G (continue_at)] 11020 G. attach_4 (last_node) [->H] 11021 H. ... 11022 11023 I. new_node (first_new) [->F (last_new_tail)] 11024 11025 OMP_CLAUSE_CHAIN (last_node) = *move_after; 11026 11027 #. mapping node chain 11028 --------------------------------------------------- 11029 A. struct_node [->B] 11030 B. comp_1 [->C] 11031 C. comp_2 [->D (move_after)] 11032 D. map_to_3 [->E] 11033 E. attach_3 [->H (continue_at)] 11034 F. map_to_4 [->G] 11035 G. attach_4 (last_node) [->D] 11036 H. ... 11037 11038 I. new_node (first_new) [->F (last_new_tail)] 11039 11040 *move_after = first_new; 11041 11042 #. mapping node chain 11043 --------------------------------------------------- 11044 A. struct_node [->B] 11045 B. comp_1 [->C] 11046 C. comp_2 [->I (move_after)] 11047 D. map_to_3 [->E] 11048 E. attach_3 [->H (continue_at)] 11049 F. map_to_4 [->G] 11050 G. attach_4 (last_node) [->D] 11051 H. ... 11052 I. new_node (first_new) [->F (last_new_tail)] 11053 11054 or, in order: 11055 11056 #. mapping node chain 11057 --------------------------------------------------- 11058 A. struct_node [->B] 11059 B. comp_1 [->C] 11060 C. comp_2 [->I (move_after)] 11061 I. new_node (first_new) [->F (last_new_tail)] 11062 F. map_to_4 [->G] 11063 G. attach_4 (last_node) [->D] 11064 D. map_to_3 [->E] 11065 E. attach_3 [->H (continue_at)] 11066 H. ... 11067 */ 11068 11069 static tree * 11070 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail, 11071 tree *first_ptr, tree last_node, 11072 tree *move_after) 11073 { 11074 tree *continue_at = NULL; 11075 *last_new_tail = *first_ptr; 11076 if (first_ptr == move_after) 11077 *move_after = first_new; 11078 else 11079 { 11080 *first_ptr = OMP_CLAUSE_CHAIN (last_node); 11081 continue_at = first_ptr; 11082 OMP_CLAUSE_CHAIN (last_node) = *move_after; 11083 *move_after = first_new; 11084 } 11085 return continue_at; 11086 } 11087 11088 static omp_addr_token * 11089 omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens) 11090 { 11091 using namespace omp_addr_tokenizer; 11092 int idx = addr_tokens.length () - 1; 11093 gcc_assert (idx >= 0); 11094 if (addr_tokens[idx]->type != ACCESS_METHOD) 11095 return addr_tokens[idx]; 11096 while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD) 11097 idx--; 11098 return addr_tokens[idx]; 11099 } 11100 11101 /* Mapping struct members causes an additional set of nodes to be created, 11102 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the 11103 number of members being mapped, in order of ascending position (address or 11104 bitwise). 11105 11106 We scan through the list of mapping clauses, calling this function for each 11107 struct member mapping we find, and build up the list of mappings after the 11108 initial GOMP_MAP_STRUCT node. For pointer members, these will be 11109 newly-created ALLOC nodes. For non-pointer members, the existing mapping is 11110 moved into place in the sorted list. 11111 11112 struct { 11113 int *a; 11114 int *b; 11115 int c; 11116 int *d; 11117 }; 11118 11119 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c, 11120 struct.d[0:n]) 11121 11122 GOMP_MAP_STRUCT (4) 11123 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs] 11124 GOMP_MAP_ALLOC (struct.a) 11125 GOMP_MAP_ALLOC (struct.b) 11126 GOMP_MAP_TO (struct.c) 11127 GOMP_MAP_ALLOC (struct.d) 11128 ... 11129 11130 In the case where we are mapping references to pointers, or in Fortran if 11131 we are mapping an array with a descriptor, additional nodes may be created 11132 after the struct node list also. 11133 11134 The return code is either a pointer to the next node to process (if the 11135 list has been rearranged), else NULL to continue with the next node in the 11136 original list. */ 11137 11138 static tree * 11139 omp_accumulate_sibling_list (enum omp_region_type region_type, 11140 enum tree_code code, 11141 hash_map<tree_operand_hash, tree> 11142 *&struct_map_to_clause, 11143 hash_map<tree_operand_hash_no_se, 11144 omp_mapping_group *> *group_map, 11145 tree *grp_start_p, tree grp_end, 11146 vec<omp_addr_token *> &addr_tokens, tree **inner, 11147 bool *fragile_p, bool reprocessing_struct, 11148 tree **added_tail) 11149 { 11150 using namespace omp_addr_tokenizer; 11151 poly_offset_int coffset; 11152 poly_int64 cbitpos; 11153 tree ocd = OMP_CLAUSE_DECL (grp_end); 11154 bool openmp = !(region_type & ORT_ACC); 11155 bool target = (region_type & ORT_TARGET) != 0; 11156 tree *continue_at = NULL; 11157 11158 while (TREE_CODE (ocd) == ARRAY_REF) 11159 ocd = TREE_OPERAND (ocd, 0); 11160 11161 if (*fragile_p) 11162 { 11163 omp_mapping_group *to_group 11164 = omp_get_nonfirstprivate_group (group_map, ocd, true); 11165 11166 if (to_group) 11167 return NULL; 11168 } 11169 11170 omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens); 11171 if (last_token->type == ACCESS_METHOD) 11172 { 11173 switch (last_token->u.access_kind) 11174 { 11175 case ACCESS_REF: 11176 case ACCESS_REF_TO_POINTER: 11177 case ACCESS_REF_TO_POINTER_OFFSET: 11178 case ACCESS_INDEXED_REF_TO_ARRAY: 11179 /* We may see either a bare reference or a dereferenced 11180 "convert_from_reference"-like one here. Handle either way. */ 11181 if (TREE_CODE (ocd) == INDIRECT_REF) 11182 ocd = TREE_OPERAND (ocd, 0); 11183 gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE); 11184 break; 11185 11186 default: 11187 ; 11188 } 11189 } 11190 11191 bool variable_offset; 11192 tree base 11193 = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset); 11194 11195 int base_token; 11196 for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--) 11197 { 11198 if (addr_tokens[base_token]->type == ARRAY_BASE 11199 || addr_tokens[base_token]->type == STRUCTURE_BASE) 11200 break; 11201 } 11202 11203 /* The two expressions in the assertion below aren't quite the same: if we 11204 have 'struct_base_decl access_indexed_array' for something like 11205 "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr 11206 will be "myvar[2]" -- the actual base of the structure. 11207 The former interpretation leads to a strange situation where we get 11208 struct(myvar) alloc(myvar[2].ptr1) 11209 That is, the array of structures is kind of treated as one big structure 11210 for the purposes of gathering sibling lists, etc. */ 11211 /* gcc_assert (base == addr_tokens[base_token]->expr); */ 11212 11213 bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end) 11214 == GOMP_MAP_ATTACH_DETACH) 11215 || (OMP_CLAUSE_MAP_KIND (grp_end) 11216 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)); 11217 bool has_descriptor = false; 11218 if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 11219 { 11220 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p); 11221 if (grp_mid && omp_map_clause_descriptor_p (grp_mid)) 11222 has_descriptor = true; 11223 } 11224 11225 if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL) 11226 { 11227 enum gomp_map_kind str_kind = GOMP_MAP_STRUCT; 11228 11229 if (struct_map_to_clause == NULL) 11230 struct_map_to_clause = new hash_map<tree_operand_hash, tree>; 11231 11232 if (variable_offset) 11233 str_kind = GOMP_MAP_STRUCT_UNORD; 11234 11235 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP); 11236 11237 OMP_CLAUSE_SET_MAP_KIND (l, str_kind); 11238 OMP_CLAUSE_DECL (l) = unshare_expr (base); 11239 OMP_CLAUSE_SIZE (l) = size_int (1); 11240 11241 struct_map_to_clause->put (base, l); 11242 11243 /* On first iterating through the clause list, we insert the struct node 11244 just before the component access node that triggers the initial 11245 omp_accumulate_sibling_list call for a particular sibling list (and 11246 it then forms the first entry in that list). When reprocessing 11247 struct bases that are themselves component accesses, we insert the 11248 struct node on an off-side list to avoid inserting the new 11249 GOMP_MAP_STRUCT into the middle of the old one. */ 11250 tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p; 11251 11252 if (has_descriptor) 11253 { 11254 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p); 11255 if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA) 11256 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE); 11257 tree sc = *insert_node_pos; 11258 OMP_CLAUSE_CHAIN (l) = desc; 11259 OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc); 11260 OMP_CLAUSE_CHAIN (desc) = sc; 11261 *insert_node_pos = l; 11262 } 11263 else if (attach_detach) 11264 { 11265 tree extra_node; 11266 tree alloc_node 11267 = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end, 11268 &extra_node); 11269 tree *tail; 11270 OMP_CLAUSE_CHAIN (l) = alloc_node; 11271 11272 if (extra_node) 11273 { 11274 OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos; 11275 OMP_CLAUSE_CHAIN (alloc_node) = extra_node; 11276 tail = &OMP_CLAUSE_CHAIN (extra_node); 11277 } 11278 else 11279 { 11280 OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos; 11281 tail = &OMP_CLAUSE_CHAIN (alloc_node); 11282 } 11283 11284 /* For OpenMP semantics, we don't want to implicitly allocate 11285 space for the pointer here for non-compute regions (e.g. "enter 11286 data"). A FRAGILE_P node is only being created so that 11287 omp-low.cc is able to rewrite the struct properly. 11288 For references (to pointers), we want to actually allocate the 11289 space for the reference itself in the sorted list following the 11290 struct node. 11291 For pointers, we want to allocate space if we had an explicit 11292 mapping of the attachment point, but not otherwise. */ 11293 if (*fragile_p 11294 || (openmp 11295 && !target 11296 && attach_detach 11297 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE 11298 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end))) 11299 { 11300 if (!lang_GNU_Fortran ()) 11301 /* In Fortran, pointers are dereferenced automatically, but may 11302 be unassociated. So we still want to allocate space for the 11303 pointer (as the base for an attach operation that should be 11304 present in the same directive's clause list also). */ 11305 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node; 11306 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1; 11307 } 11308 11309 *insert_node_pos = l; 11310 11311 if (reprocessing_struct) 11312 { 11313 /* When reprocessing a struct node group used as the base of a 11314 subcomponent access, if we have a reference-to-pointer base, 11315 we will see: 11316 struct(**ptr) attach(*ptr) 11317 whereas for a non-reprocess-struct group, we see, e.g.: 11318 tofrom(**ptr) attach(*ptr) attach(ptr) 11319 and we create the "alloc" for the second "attach", i.e. 11320 for the reference itself. When reprocessing a struct group we 11321 thus change the pointer attachment into a reference attachment 11322 by stripping the indirection. (The attachment of the 11323 referenced pointer must happen elsewhere, either on the same 11324 directive, or otherwise.) */ 11325 tree adecl = OMP_CLAUSE_DECL (alloc_node); 11326 11327 if ((TREE_CODE (adecl) == INDIRECT_REF 11328 || (TREE_CODE (adecl) == MEM_REF 11329 && integer_zerop (TREE_OPERAND (adecl, 1)))) 11330 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0))) 11331 == REFERENCE_TYPE) 11332 && (TREE_CODE (TREE_TYPE (TREE_TYPE 11333 (TREE_OPERAND (adecl, 0)))) == POINTER_TYPE)) 11334 OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0); 11335 11336 *added_tail = tail; 11337 } 11338 } 11339 else 11340 { 11341 gcc_assert (*grp_start_p == grp_end); 11342 if (reprocessing_struct) 11343 { 11344 /* If we don't have an attach/detach node, this is a 11345 "target data" directive or similar, not an offload region. 11346 Synthesize an "alloc" node using just the initiating 11347 GOMP_MAP_STRUCT decl. */ 11348 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA 11349 || code == OACC_EXIT_DATA) 11350 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 11351 tree alloc_node 11352 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11353 OMP_CLAUSE_MAP); 11354 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k); 11355 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr); 11356 OMP_CLAUSE_SIZE (alloc_node) 11357 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node))); 11358 11359 OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l); 11360 OMP_CLAUSE_CHAIN (l) = alloc_node; 11361 *insert_node_pos = l; 11362 *added_tail = &OMP_CLAUSE_CHAIN (alloc_node); 11363 } 11364 else 11365 grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos); 11366 } 11367 11368 unsigned last_access = base_token + 1; 11369 11370 while (last_access + 1 < addr_tokens.length () 11371 && addr_tokens[last_access + 1]->type == ACCESS_METHOD) 11372 last_access++; 11373 11374 if ((region_type & ORT_TARGET) 11375 && addr_tokens[base_token + 1]->type == ACCESS_METHOD) 11376 { 11377 bool base_ref = false; 11378 access_method_kinds access_kind 11379 = addr_tokens[last_access]->u.access_kind; 11380 11381 switch (access_kind) 11382 { 11383 case ACCESS_DIRECT: 11384 case ACCESS_INDEXED_ARRAY: 11385 return NULL; 11386 11387 case ACCESS_REF: 11388 case ACCESS_REF_TO_POINTER: 11389 case ACCESS_REF_TO_POINTER_OFFSET: 11390 case ACCESS_INDEXED_REF_TO_ARRAY: 11391 base_ref = true; 11392 break; 11393 11394 default: 11395 ; 11396 } 11397 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11398 OMP_CLAUSE_MAP); 11399 enum gomp_map_kind mkind; 11400 omp_mapping_group *decl_group; 11401 tree use_base; 11402 switch (access_kind) 11403 { 11404 case ACCESS_POINTER: 11405 case ACCESS_POINTER_OFFSET: 11406 use_base = addr_tokens[last_access]->expr; 11407 break; 11408 case ACCESS_REF_TO_POINTER: 11409 case ACCESS_REF_TO_POINTER_OFFSET: 11410 use_base 11411 = build_fold_indirect_ref (addr_tokens[last_access]->expr); 11412 break; 11413 default: 11414 use_base = addr_tokens[base_token]->expr; 11415 } 11416 bool mapped_to_p 11417 = omp_directive_maps_explicitly (group_map, use_base, &decl_group, 11418 true, false, true); 11419 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11420 && DECL_P (addr_tokens[last_access]->expr) 11421 && !mapped_to_p) 11422 mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE 11423 : GOMP_MAP_FIRSTPRIVATE_POINTER; 11424 else 11425 mkind = GOMP_MAP_ATTACH_DETACH; 11426 11427 OMP_CLAUSE_SET_MAP_KIND (c2, mkind); 11428 /* If we have a reference to pointer base, we want to attach the 11429 pointer here, not the reference. The reference attachment happens 11430 elsewhere. */ 11431 bool ref_to_ptr 11432 = (access_kind == ACCESS_REF_TO_POINTER 11433 || access_kind == ACCESS_REF_TO_POINTER_OFFSET); 11434 tree sdecl = addr_tokens[last_access]->expr; 11435 tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl) 11436 : sdecl; 11437 /* For the FIRSTPRIVATE_REFERENCE after the struct node, we 11438 want to use the reference itself for the decl, but we 11439 still want to use the pointer to calculate the bias. */ 11440 OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH) 11441 ? sdecl_ptr : sdecl; 11442 sdecl = sdecl_ptr; 11443 tree baddr = build_fold_addr_expr (base); 11444 baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end), 11445 ptrdiff_type_node, baddr); 11446 tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end), 11447 ptrdiff_type_node, sdecl); 11448 OMP_CLAUSE_SIZE (c2) 11449 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR, 11450 ptrdiff_type_node, baddr, decladdr); 11451 /* Insert after struct node. */ 11452 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l); 11453 OMP_CLAUSE_CHAIN (l) = c2; 11454 11455 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11456 && (addr_tokens[base_token]->u.structure_base_kind 11457 == BASE_COMPONENT_EXPR) 11458 && mkind == GOMP_MAP_ATTACH_DETACH 11459 && addr_tokens[last_access]->u.access_kind != ACCESS_REF) 11460 { 11461 *inner = insert_node_pos; 11462 if (openmp) 11463 *fragile_p = true; 11464 return NULL; 11465 } 11466 } 11467 11468 if (addr_tokens[base_token]->type == STRUCTURE_BASE 11469 && (addr_tokens[base_token]->u.structure_base_kind 11470 == BASE_COMPONENT_EXPR) 11471 && addr_tokens[last_access]->u.access_kind == ACCESS_REF) 11472 *inner = insert_node_pos; 11473 11474 return NULL; 11475 } 11476 else if (struct_map_to_clause) 11477 { 11478 tree *osc = struct_map_to_clause->get (base); 11479 tree *sc = NULL, *scp = NULL; 11480 bool unordered = false; 11481 11482 if (osc && OMP_CLAUSE_MAP_KIND (*osc) == GOMP_MAP_STRUCT_UNORD) 11483 unordered = true; 11484 11485 unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc)); 11486 sc = &OMP_CLAUSE_CHAIN (*osc); 11487 /* The struct mapping might be immediately followed by a 11488 FIRSTPRIVATE_POINTER, FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH -- 11489 if it's an indirect access or a reference, or if the structure base 11490 is not a decl. The FIRSTPRIVATE_* nodes are removed in omp-low.cc 11491 after they have been processed there, and ATTACH_DETACH nodes are 11492 recomputed and moved out of the GOMP_MAP_STRUCT construct once 11493 sibling list building is complete. */ 11494 if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER 11495 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE 11496 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH) 11497 sc = &OMP_CLAUSE_CHAIN (*sc); 11498 for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc)) 11499 if (attach_detach && sc == grp_start_p) 11500 break; 11501 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF 11502 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF 11503 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF) 11504 break; 11505 else 11506 { 11507 tree sc_decl = OMP_CLAUSE_DECL (*sc); 11508 poly_offset_int offset; 11509 poly_int64 bitpos; 11510 11511 if (TREE_CODE (sc_decl) == ARRAY_REF) 11512 { 11513 while (TREE_CODE (sc_decl) == ARRAY_REF) 11514 sc_decl = TREE_OPERAND (sc_decl, 0); 11515 if (TREE_CODE (sc_decl) != COMPONENT_REF 11516 || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE) 11517 break; 11518 } 11519 else if (INDIRECT_REF_P (sc_decl) 11520 && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF 11521 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0))) 11522 == REFERENCE_TYPE)) 11523 sc_decl = TREE_OPERAND (sc_decl, 0); 11524 11525 bool variable_offset2; 11526 tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset, 11527 &variable_offset2); 11528 if (!base2 || !operand_equal_p (base2, base, 0)) 11529 break; 11530 if (scp) 11531 continue; 11532 if (variable_offset2) 11533 { 11534 OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD); 11535 unordered = true; 11536 break; 11537 } 11538 else if ((region_type & ORT_ACC) != 0) 11539 { 11540 /* For OpenACC, allow (ignore) duplicate struct accesses in 11541 the middle of a mapping clause, e.g. "mystruct->foo" in: 11542 copy(mystruct->foo->bar) copy(mystruct->foo->qux). */ 11543 if (reprocessing_struct 11544 && known_eq (coffset, offset) 11545 && known_eq (cbitpos, bitpos)) 11546 return NULL; 11547 } 11548 else if (known_eq (coffset, offset) 11549 && known_eq (cbitpos, bitpos)) 11550 { 11551 /* Having two struct members at the same offset doesn't work, 11552 so make sure we don't. (We're allowed to ignore this. 11553 Should we report the error?) */ 11554 /*error_at (OMP_CLAUSE_LOCATION (grp_end), 11555 "duplicate struct member %qE in map clauses", 11556 OMP_CLAUSE_DECL (grp_end));*/ 11557 return NULL; 11558 } 11559 if (maybe_lt (coffset, offset) 11560 || (known_eq (coffset, offset) 11561 && maybe_lt (cbitpos, bitpos))) 11562 { 11563 if (attach_detach) 11564 scp = sc; 11565 else 11566 break; 11567 } 11568 } 11569 11570 /* If this is an unordered struct, just insert the new element at the 11571 end of the list. */ 11572 if (unordered) 11573 { 11574 for (; i < elems; i++) 11575 sc = &OMP_CLAUSE_CHAIN (*sc); 11576 scp = NULL; 11577 } 11578 11579 OMP_CLAUSE_SIZE (*osc) 11580 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node); 11581 11582 if (reprocessing_struct) 11583 { 11584 /* If we're reprocessing a struct node, we don't want to do most of 11585 the list manipulation below. We only need to handle the (pointer 11586 or reference) attach/detach case. */ 11587 tree extra_node, alloc_node; 11588 if (has_descriptor) 11589 gcc_unreachable (); 11590 else if (attach_detach) 11591 alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p, 11592 grp_end, &extra_node); 11593 else 11594 { 11595 /* If we don't have an attach/detach node, this is a 11596 "target data" directive or similar, not an offload region. 11597 Synthesize an "alloc" node using just the initiating 11598 GOMP_MAP_STRUCT decl. */ 11599 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA 11600 || code == OACC_EXIT_DATA) 11601 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC; 11602 alloc_node 11603 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), 11604 OMP_CLAUSE_MAP); 11605 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k); 11606 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr); 11607 OMP_CLAUSE_SIZE (alloc_node) 11608 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node))); 11609 } 11610 11611 if (scp) 11612 omp_siblist_insert_node_after (alloc_node, scp); 11613 else 11614 { 11615 tree *new_end = omp_siblist_insert_node_after (alloc_node, sc); 11616 if (sc == *added_tail) 11617 *added_tail = new_end; 11618 } 11619 11620 return NULL; 11621 } 11622 11623 if (has_descriptor) 11624 { 11625 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p); 11626 if (code == OMP_TARGET_EXIT_DATA 11627 || code == OACC_EXIT_DATA) 11628 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE); 11629 omp_siblist_move_node_after (desc, 11630 &OMP_CLAUSE_CHAIN (*grp_start_p), 11631 scp ? scp : sc); 11632 } 11633 else if (attach_detach) 11634 { 11635 tree cl = NULL_TREE, extra_node; 11636 tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p, 11637 grp_end, &extra_node); 11638 tree *tail_chain = NULL; 11639 11640 if (*fragile_p 11641 || (openmp 11642 && !target 11643 && attach_detach 11644 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE 11645 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end))) 11646 { 11647 if (!lang_GNU_Fortran ()) 11648 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node; 11649 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1; 11650 } 11651 11652 /* Here, we have: 11653 11654 grp_end : the last (or only) node in this group. 11655 grp_start_p : pointer to the first node in a pointer mapping group 11656 up to and including GRP_END. 11657 sc : pointer to the chain for the end of the struct component 11658 list. 11659 scp : pointer to the chain for the sorted position at which we 11660 should insert in the middle of the struct component list 11661 (else NULL to insert at end). 11662 alloc_node : the "alloc" node for the structure (pointer-type) 11663 component. We insert at SCP (if present), else SC 11664 (the end of the struct component list). 11665 extra_node : a newly-synthesized node for an additional indirect 11666 pointer mapping or a Fortran pointer set, if needed. 11667 cl : first node to prepend before grp_start_p. 11668 tail_chain : pointer to chain of last prepended node. 11669 11670 The general idea is we move the nodes for this struct mapping 11671 together: the alloc node goes into the sorted list directly after 11672 the struct mapping, and any extra nodes (together with the nodes 11673 mapping arrays pointed to by struct components) get moved after 11674 that list. When SCP is NULL, we insert the nodes at SC, i.e. at 11675 the end of the struct component mapping list. It's important that 11676 the alloc_node comes first in that case because it's part of the 11677 sorted component mapping list (but subsequent nodes are not!). */ 11678 11679 if (scp) 11680 omp_siblist_insert_node_after (alloc_node, scp); 11681 11682 /* Make [cl,tail_chain] a list of the alloc node (if we haven't 11683 already inserted it) and the extra_node (if it is present). The 11684 list can be empty if we added alloc_node above and there is no 11685 extra node. */ 11686 if (scp && extra_node) 11687 { 11688 cl = extra_node; 11689 tail_chain = &OMP_CLAUSE_CHAIN (extra_node); 11690 } 11691 else if (extra_node) 11692 { 11693 OMP_CLAUSE_CHAIN (alloc_node) = extra_node; 11694 cl = alloc_node; 11695 tail_chain = &OMP_CLAUSE_CHAIN (extra_node); 11696 } 11697 else if (!scp) 11698 { 11699 cl = alloc_node; 11700 tail_chain = &OMP_CLAUSE_CHAIN (alloc_node); 11701 } 11702 11703 continue_at 11704 = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain, 11705 grp_start_p, grp_end, 11706 sc) 11707 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc); 11708 } 11709 else if (*sc != grp_end) 11710 { 11711 gcc_assert (*grp_start_p == grp_end); 11712 11713 /* We are moving the current node back to a previous struct node: 11714 the node that used to point to the current node will now point to 11715 the next node. */ 11716 continue_at = grp_start_p; 11717 /* In the non-pointer case, the mapping clause itself is moved into 11718 the correct position in the struct component list, which in this 11719 case is just SC. */ 11720 omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc); 11721 } 11722 } 11723 return continue_at; 11724 } 11725 11726 /* Scan through GROUPS, and create sorted structure sibling lists without 11727 gimplifying. */ 11728 11729 static bool 11730 omp_build_struct_sibling_lists (enum tree_code code, 11731 enum omp_region_type region_type, 11732 vec<omp_mapping_group> *groups, 11733 hash_map<tree_operand_hash_no_se, 11734 omp_mapping_group *> **grpmap, 11735 tree *list_p) 11736 { 11737 using namespace omp_addr_tokenizer; 11738 unsigned i; 11739 omp_mapping_group *grp; 11740 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL; 11741 bool success = true; 11742 tree *new_next = NULL; 11743 tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end); 11744 tree added_nodes = NULL_TREE; 11745 tree *added_tail = &added_nodes; 11746 auto_vec<omp_mapping_group> pre_hwm_groups; 11747 11748 FOR_EACH_VEC_ELT (*groups, i, grp) 11749 { 11750 tree c = grp->grp_end; 11751 tree decl = OMP_CLAUSE_DECL (c); 11752 tree grp_end = grp->grp_end; 11753 auto_vec<omp_addr_token *> addr_tokens; 11754 tree sentinel = OMP_CLAUSE_CHAIN (grp_end); 11755 11756 if (new_next && !grp->reprocess_struct) 11757 grp->grp_start = new_next; 11758 11759 new_next = NULL; 11760 11761 tree *grp_start_p = grp->grp_start; 11762 11763 if (DECL_P (decl)) 11764 continue; 11765 11766 /* Skip groups we marked for deletion in 11767 {omp,oacc}_resolve_clause_dependencies. */ 11768 if (grp->deleted) 11769 continue; 11770 11771 if (OMP_CLAUSE_CHAIN (*grp_start_p) 11772 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 11773 { 11774 /* Don't process an array descriptor that isn't inside a derived type 11775 as a struct (the GOMP_MAP_POINTER following will have the form 11776 "var.data", but such mappings are handled specially). */ 11777 tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p); 11778 if (omp_map_clause_descriptor_p (grpmid) 11779 && DECL_P (OMP_CLAUSE_DECL (grpmid))) 11780 continue; 11781 } 11782 11783 tree expr = decl; 11784 11785 while (TREE_CODE (expr) == ARRAY_REF) 11786 expr = TREE_OPERAND (expr, 0); 11787 11788 if (!omp_parse_expr (addr_tokens, expr)) 11789 continue; 11790 11791 omp_addr_token *last_token 11792 = omp_first_chained_access_token (addr_tokens); 11793 11794 /* A mapping of a reference to a pointer member that doesn't specify an 11795 array section, etc., like this: 11796 *mystruct.ref_to_ptr 11797 should not be processed by the struct sibling-list handling code -- 11798 it just transfers the referenced pointer. 11799 11800 In contrast, the quite similar-looking construct: 11801 *mystruct.ptr 11802 which is equivalent to e.g. 11803 mystruct.ptr[0] 11804 *does* trigger sibling-list processing. 11805 11806 An exception for the former case is for "fragile" groups where the 11807 reference itself is not handled otherwise; this is subject to special 11808 handling in omp_accumulate_sibling_list also. */ 11809 11810 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 11811 && last_token->type == ACCESS_METHOD 11812 && last_token->u.access_kind == ACCESS_REF 11813 && !grp->fragile) 11814 continue; 11815 11816 tree d = decl; 11817 if (TREE_CODE (d) == ARRAY_REF) 11818 { 11819 while (TREE_CODE (d) == ARRAY_REF) 11820 d = TREE_OPERAND (d, 0); 11821 if (TREE_CODE (d) == COMPONENT_REF 11822 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 11823 decl = d; 11824 } 11825 if (d == decl 11826 && INDIRECT_REF_P (decl) 11827 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 11828 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 11829 == REFERENCE_TYPE) 11830 && (OMP_CLAUSE_MAP_KIND (c) 11831 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 11832 decl = TREE_OPERAND (decl, 0); 11833 11834 STRIP_NOPS (decl); 11835 11836 if (TREE_CODE (decl) != COMPONENT_REF) 11837 continue; 11838 11839 /* If we're mapping the whole struct in another node, skip adding this 11840 node to a sibling list. */ 11841 omp_mapping_group *wholestruct; 11842 if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c), 11843 &wholestruct)) 11844 continue; 11845 11846 if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET 11847 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH 11848 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH 11849 && code != OACC_UPDATE 11850 && code != OMP_TARGET_UPDATE) 11851 { 11852 if (error_operand_p (decl)) 11853 { 11854 success = false; 11855 goto error_out; 11856 } 11857 11858 tree stype = TREE_TYPE (decl); 11859 if (TREE_CODE (stype) == REFERENCE_TYPE) 11860 stype = TREE_TYPE (stype); 11861 if (TYPE_SIZE_UNIT (stype) == NULL 11862 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST) 11863 { 11864 error_at (OMP_CLAUSE_LOCATION (c), 11865 "mapping field %qE of variable length " 11866 "structure", OMP_CLAUSE_DECL (c)); 11867 success = false; 11868 goto error_out; 11869 } 11870 11871 tree *inner = NULL; 11872 bool fragile_p = grp->fragile; 11873 11874 new_next 11875 = omp_accumulate_sibling_list (region_type, code, 11876 struct_map_to_clause, *grpmap, 11877 grp_start_p, grp_end, addr_tokens, 11878 &inner, &fragile_p, 11879 grp->reprocess_struct, &added_tail); 11880 11881 if (inner) 11882 { 11883 omp_mapping_group newgrp; 11884 newgrp.grp_start = inner; 11885 if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner)) 11886 == GOMP_MAP_ATTACH_DETACH) 11887 newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner); 11888 else 11889 newgrp.grp_end = *inner; 11890 newgrp.mark = UNVISITED; 11891 newgrp.sibling = NULL; 11892 newgrp.deleted = false; 11893 newgrp.reprocess_struct = true; 11894 newgrp.fragile = fragile_p; 11895 newgrp.next = NULL; 11896 groups->safe_push (newgrp); 11897 11898 /* !!! Growing GROUPS might invalidate the pointers in the group 11899 map. Rebuild it here. This is a bit inefficient, but 11900 shouldn't happen very often. */ 11901 delete (*grpmap); 11902 *grpmap 11903 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups, 11904 sentinel); 11905 } 11906 } 11907 } 11908 11909 /* Delete groups marked for deletion above. At this point the order of the 11910 groups may no longer correspond to the order of the underlying list, 11911 which complicates this a little. First clear out OMP_CLAUSE_DECL for 11912 deleted nodes... */ 11913 11914 FOR_EACH_VEC_ELT (*groups, i, grp) 11915 if (grp->deleted) 11916 for (tree d = *grp->grp_start; 11917 d != OMP_CLAUSE_CHAIN (grp->grp_end); 11918 d = OMP_CLAUSE_CHAIN (d)) 11919 OMP_CLAUSE_DECL (d) = NULL_TREE; 11920 11921 /* ...then sweep through the list removing the now-empty nodes. */ 11922 11923 tail = list_p; 11924 while (*tail) 11925 { 11926 if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP 11927 && OMP_CLAUSE_DECL (*tail) == NULL_TREE) 11928 *tail = OMP_CLAUSE_CHAIN (*tail); 11929 else 11930 tail = &OMP_CLAUSE_CHAIN (*tail); 11931 } 11932 11933 /* Tack on the struct nodes added during nested struct reprocessing. */ 11934 if (added_nodes) 11935 { 11936 *tail = added_nodes; 11937 tail = added_tail; 11938 } 11939 11940 /* Now we have finished building the struct sibling lists, reprocess 11941 newly-added "attach" nodes: we need the address of the first 11942 mapped element of each struct sibling list for the bias of the attach 11943 operation -- not necessarily the base address of the whole struct. */ 11944 if (struct_map_to_clause) 11945 for (hash_map<tree_operand_hash, tree>::iterator iter 11946 = struct_map_to_clause->begin (); 11947 iter != struct_map_to_clause->end (); 11948 ++iter) 11949 { 11950 tree struct_node = (*iter).second; 11951 gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP); 11952 tree attach = OMP_CLAUSE_CHAIN (struct_node); 11953 11954 if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP 11955 || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH) 11956 continue; 11957 11958 OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH); 11959 11960 /* Sanity check: the standalone attach node will not work if we have 11961 an "enter data" operation (because for those, variables need to be 11962 mapped separately and attach nodes must be grouped together with the 11963 base they attach to). We should only have created the 11964 ATTACH_DETACH node after GOMP_MAP_STRUCT for a target region, so 11965 this should never be true. */ 11966 gcc_assert ((region_type & ORT_TARGET) != 0); 11967 11968 /* This is the first sorted node in the struct sibling list. Use it 11969 to recalculate the correct bias to use. 11970 (&first_node - attach_decl). 11971 For GOMP_MAP_STRUCT_UNORD, we need e.g. the 11972 min(min(min(first,second),third),fourth) element, because the 11973 elements aren't in any particular order. */ 11974 tree lowest_addr; 11975 if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD) 11976 { 11977 tree first_node = OMP_CLAUSE_CHAIN (attach); 11978 unsigned HOST_WIDE_INT num_mappings 11979 = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node)); 11980 lowest_addr = OMP_CLAUSE_DECL (first_node); 11981 lowest_addr = build_fold_addr_expr (lowest_addr); 11982 lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr); 11983 tree next_node = OMP_CLAUSE_CHAIN (first_node); 11984 while (num_mappings > 1) 11985 { 11986 tree tmp = OMP_CLAUSE_DECL (next_node); 11987 tmp = build_fold_addr_expr (tmp); 11988 tmp = fold_convert (pointer_sized_int_node, tmp); 11989 lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node, 11990 lowest_addr, tmp); 11991 next_node = OMP_CLAUSE_CHAIN (next_node); 11992 num_mappings--; 11993 } 11994 lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr); 11995 } 11996 else 11997 { 11998 tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach)); 11999 first_node = build_fold_addr_expr (first_node); 12000 lowest_addr = fold_convert (ptrdiff_type_node, first_node); 12001 } 12002 tree attach_decl = OMP_CLAUSE_DECL (attach); 12003 attach_decl = fold_convert (ptrdiff_type_node, attach_decl); 12004 OMP_CLAUSE_SIZE (attach) 12005 = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr, 12006 attach_decl); 12007 12008 /* Remove GOMP_MAP_ATTACH node from after struct node. */ 12009 OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach); 12010 /* ...and re-insert it at the end of our clause list. */ 12011 *tail = attach; 12012 OMP_CLAUSE_CHAIN (attach) = NULL_TREE; 12013 tail = &OMP_CLAUSE_CHAIN (attach); 12014 } 12015 12016 error_out: 12017 if (struct_map_to_clause) 12018 delete struct_map_to_clause; 12019 12020 return success; 12021 } 12022 12023 /* Scan the OMP clauses in *LIST_P, installing mappings into a new 12024 and previous omp contexts. */ 12025 12026 static void 12027 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, 12028 enum omp_region_type region_type, 12029 enum tree_code code) 12030 { 12031 using namespace omp_addr_tokenizer; 12032 struct gimplify_omp_ctx *ctx, *outer_ctx; 12033 tree c; 12034 tree *orig_list_p = list_p; 12035 int handled_depend_iterators = -1; 12036 int nowait = -1; 12037 12038 ctx = new_omp_context (region_type); 12039 ctx->code = code; 12040 outer_ctx = ctx->outer_context; 12041 if (code == OMP_TARGET) 12042 { 12043 if (!lang_GNU_Fortran ()) 12044 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY; 12045 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE; 12046 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran () 12047 ? GOVD_MAP : GOVD_FIRSTPRIVATE); 12048 } 12049 if (!lang_GNU_Fortran ()) 12050 switch (code) 12051 { 12052 case OMP_TARGET: 12053 case OMP_TARGET_DATA: 12054 case OMP_TARGET_ENTER_DATA: 12055 case OMP_TARGET_EXIT_DATA: 12056 case OACC_DECLARE: 12057 case OACC_HOST_DATA: 12058 case OACC_PARALLEL: 12059 case OACC_KERNELS: 12060 ctx->target_firstprivatize_array_bases = true; 12061 default: 12062 break; 12063 } 12064 12065 vec<omp_mapping_group> *groups = NULL; 12066 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL; 12067 unsigned grpnum = 0; 12068 tree *grp_start_p = NULL, grp_end = NULL_TREE; 12069 12070 if (code == OMP_TARGET 12071 || code == OMP_TARGET_DATA 12072 || code == OMP_TARGET_ENTER_DATA 12073 || code == OMP_TARGET_EXIT_DATA 12074 || code == OACC_DATA 12075 || code == OACC_KERNELS 12076 || code == OACC_PARALLEL 12077 || code == OACC_SERIAL 12078 || code == OACC_ENTER_DATA 12079 || code == OACC_EXIT_DATA 12080 || code == OACC_UPDATE 12081 || code == OACC_DECLARE) 12082 { 12083 groups = omp_gather_mapping_groups (list_p); 12084 12085 if (groups) 12086 grpmap = omp_index_mapping_groups (groups); 12087 } 12088 12089 while ((c = *list_p) != NULL) 12090 { 12091 bool remove = false; 12092 bool notice_outer = true; 12093 bool map_descriptor; 12094 const char *check_non_private = NULL; 12095 unsigned int flags; 12096 tree decl; 12097 auto_vec<omp_addr_token *, 10> addr_tokens; 12098 12099 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end)) 12100 { 12101 grp_start_p = NULL; 12102 grp_end = NULL_TREE; 12103 } 12104 12105 switch (OMP_CLAUSE_CODE (c)) 12106 { 12107 case OMP_CLAUSE_PRIVATE: 12108 flags = GOVD_PRIVATE | GOVD_EXPLICIT; 12109 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c))) 12110 { 12111 flags |= GOVD_PRIVATE_OUTER_REF; 12112 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1; 12113 } 12114 else 12115 notice_outer = false; 12116 goto do_add; 12117 case OMP_CLAUSE_SHARED: 12118 flags = GOVD_SHARED | GOVD_EXPLICIT; 12119 goto do_add; 12120 case OMP_CLAUSE_FIRSTPRIVATE: 12121 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; 12122 check_non_private = "firstprivate"; 12123 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) 12124 { 12125 gcc_assert (code == OMP_TARGET); 12126 flags |= GOVD_FIRSTPRIVATE_IMPLICIT; 12127 } 12128 goto do_add; 12129 case OMP_CLAUSE_LASTPRIVATE: 12130 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 12131 switch (code) 12132 { 12133 case OMP_DISTRIBUTE: 12134 error_at (OMP_CLAUSE_LOCATION (c), 12135 "conditional %<lastprivate%> clause on " 12136 "%qs construct", "distribute"); 12137 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12138 break; 12139 case OMP_TASKLOOP: 12140 error_at (OMP_CLAUSE_LOCATION (c), 12141 "conditional %<lastprivate%> clause on " 12142 "%qs construct", "taskloop"); 12143 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12144 break; 12145 default: 12146 break; 12147 } 12148 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT; 12149 if (code != OMP_LOOP) 12150 check_non_private = "lastprivate"; 12151 decl = OMP_CLAUSE_DECL (c); 12152 if (error_operand_p (decl)) 12153 goto do_add; 12154 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) 12155 && !lang_hooks.decls.omp_scalar_p (decl, true)) 12156 { 12157 error_at (OMP_CLAUSE_LOCATION (c), 12158 "non-scalar variable %qD in conditional " 12159 "%<lastprivate%> clause", decl); 12160 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; 12161 } 12162 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 12163 flags |= GOVD_LASTPRIVATE_CONDITIONAL; 12164 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl, 12165 false); 12166 goto do_add; 12167 case OMP_CLAUSE_REDUCTION: 12168 if (OMP_CLAUSE_REDUCTION_TASK (c)) 12169 { 12170 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE) 12171 { 12172 if (nowait == -1) 12173 nowait = omp_find_clause (*list_p, 12174 OMP_CLAUSE_NOWAIT) != NULL_TREE; 12175 if (nowait 12176 && (outer_ctx == NULL 12177 || outer_ctx->region_type != ORT_COMBINED_PARALLEL)) 12178 { 12179 error_at (OMP_CLAUSE_LOCATION (c), 12180 "%<task%> reduction modifier on a construct " 12181 "with a %<nowait%> clause"); 12182 OMP_CLAUSE_REDUCTION_TASK (c) = 0; 12183 } 12184 } 12185 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL) 12186 { 12187 error_at (OMP_CLAUSE_LOCATION (c), 12188 "invalid %<task%> reduction modifier on construct " 12189 "other than %<parallel%>, %qs, %<sections%> or " 12190 "%<scope%>", lang_GNU_Fortran () ? "do" : "for"); 12191 OMP_CLAUSE_REDUCTION_TASK (c) = 0; 12192 } 12193 } 12194 if (OMP_CLAUSE_REDUCTION_INSCAN (c)) 12195 switch (code) 12196 { 12197 case OMP_SECTIONS: 12198 error_at (OMP_CLAUSE_LOCATION (c), 12199 "%<inscan%> %<reduction%> clause on " 12200 "%qs construct", "sections"); 12201 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12202 break; 12203 case OMP_PARALLEL: 12204 error_at (OMP_CLAUSE_LOCATION (c), 12205 "%<inscan%> %<reduction%> clause on " 12206 "%qs construct", "parallel"); 12207 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12208 break; 12209 case OMP_TEAMS: 12210 error_at (OMP_CLAUSE_LOCATION (c), 12211 "%<inscan%> %<reduction%> clause on " 12212 "%qs construct", "teams"); 12213 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12214 break; 12215 case OMP_TASKLOOP: 12216 error_at (OMP_CLAUSE_LOCATION (c), 12217 "%<inscan%> %<reduction%> clause on " 12218 "%qs construct", "taskloop"); 12219 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12220 break; 12221 case OMP_SCOPE: 12222 error_at (OMP_CLAUSE_LOCATION (c), 12223 "%<inscan%> %<reduction%> clause on " 12224 "%qs construct", "scope"); 12225 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; 12226 break; 12227 default: 12228 break; 12229 } 12230 /* FALLTHRU */ 12231 case OMP_CLAUSE_IN_REDUCTION: 12232 case OMP_CLAUSE_TASK_REDUCTION: 12233 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; 12234 /* OpenACC permits reductions on private variables. */ 12235 if (!(region_type & ORT_ACC) 12236 /* taskgroup is actually not a worksharing region. */ 12237 && code != OMP_TASKGROUP) 12238 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)]; 12239 decl = OMP_CLAUSE_DECL (c); 12240 if (TREE_CODE (decl) == MEM_REF) 12241 { 12242 tree type = TREE_TYPE (decl); 12243 bool saved_into_ssa = gimplify_ctxp->into_ssa; 12244 gimplify_ctxp->into_ssa = false; 12245 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p, 12246 NULL, is_gimple_val, fb_rvalue, false) 12247 == GS_ERROR) 12248 { 12249 gimplify_ctxp->into_ssa = saved_into_ssa; 12250 remove = true; 12251 break; 12252 } 12253 gimplify_ctxp->into_ssa = saved_into_ssa; 12254 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 12255 if (DECL_P (v)) 12256 { 12257 omp_firstprivatize_variable (ctx, v); 12258 omp_notice_variable (ctx, v, true); 12259 } 12260 decl = TREE_OPERAND (decl, 0); 12261 if (TREE_CODE (decl) == POINTER_PLUS_EXPR) 12262 { 12263 gimplify_ctxp->into_ssa = false; 12264 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p, 12265 NULL, is_gimple_val, fb_rvalue, false) 12266 == GS_ERROR) 12267 { 12268 gimplify_ctxp->into_ssa = saved_into_ssa; 12269 remove = true; 12270 break; 12271 } 12272 gimplify_ctxp->into_ssa = saved_into_ssa; 12273 v = TREE_OPERAND (decl, 1); 12274 if (DECL_P (v)) 12275 { 12276 omp_firstprivatize_variable (ctx, v); 12277 omp_notice_variable (ctx, v, true); 12278 } 12279 decl = TREE_OPERAND (decl, 0); 12280 } 12281 if (TREE_CODE (decl) == ADDR_EXPR 12282 || TREE_CODE (decl) == INDIRECT_REF) 12283 decl = TREE_OPERAND (decl, 0); 12284 } 12285 goto do_add_decl; 12286 case OMP_CLAUSE_LINEAR: 12287 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL, 12288 is_gimple_val, fb_rvalue) == GS_ERROR) 12289 { 12290 remove = true; 12291 break; 12292 } 12293 else 12294 { 12295 if (code == OMP_SIMD 12296 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 12297 { 12298 struct gimplify_omp_ctx *octx = outer_ctx; 12299 if (octx 12300 && octx->region_type == ORT_WORKSHARE 12301 && octx->combined_loop 12302 && !octx->distribute) 12303 { 12304 if (octx->outer_context 12305 && (octx->outer_context->region_type 12306 == ORT_COMBINED_PARALLEL)) 12307 octx = octx->outer_context->outer_context; 12308 else 12309 octx = octx->outer_context; 12310 } 12311 if (octx 12312 && octx->region_type == ORT_WORKSHARE 12313 && octx->combined_loop 12314 && octx->distribute) 12315 { 12316 error_at (OMP_CLAUSE_LOCATION (c), 12317 "%<linear%> clause for variable other than " 12318 "loop iterator specified on construct " 12319 "combined with %<distribute%>"); 12320 remove = true; 12321 break; 12322 } 12323 } 12324 /* For combined #pragma omp parallel for simd, need to put 12325 lastprivate and perhaps firstprivate too on the 12326 parallel. Similarly for #pragma omp for simd. */ 12327 struct gimplify_omp_ctx *octx = outer_ctx; 12328 bool taskloop_seen = false; 12329 decl = NULL_TREE; 12330 do 12331 { 12332 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12333 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12334 break; 12335 decl = OMP_CLAUSE_DECL (c); 12336 if (error_operand_p (decl)) 12337 { 12338 decl = NULL_TREE; 12339 break; 12340 } 12341 flags = GOVD_SEEN; 12342 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 12343 flags |= GOVD_FIRSTPRIVATE; 12344 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12345 flags |= GOVD_LASTPRIVATE; 12346 if (octx 12347 && octx->region_type == ORT_WORKSHARE 12348 && octx->combined_loop) 12349 { 12350 if (octx->outer_context 12351 && (octx->outer_context->region_type 12352 == ORT_COMBINED_PARALLEL)) 12353 octx = octx->outer_context; 12354 else if (omp_check_private (octx, decl, false)) 12355 break; 12356 } 12357 else if (octx 12358 && (octx->region_type & ORT_TASK) != 0 12359 && octx->combined_loop) 12360 taskloop_seen = true; 12361 else if (octx 12362 && octx->region_type == ORT_COMBINED_PARALLEL 12363 && ((ctx->region_type == ORT_WORKSHARE 12364 && octx == outer_ctx) 12365 || taskloop_seen)) 12366 flags = GOVD_SEEN | GOVD_SHARED; 12367 else if (octx 12368 && ((octx->region_type & ORT_COMBINED_TEAMS) 12369 == ORT_COMBINED_TEAMS)) 12370 flags = GOVD_SEEN | GOVD_SHARED; 12371 else if (octx 12372 && octx->region_type == ORT_COMBINED_TARGET) 12373 { 12374 if (flags & GOVD_LASTPRIVATE) 12375 flags = GOVD_SEEN | GOVD_MAP; 12376 } 12377 else 12378 break; 12379 splay_tree_node on 12380 = splay_tree_lookup (octx->variables, 12381 (splay_tree_key) decl); 12382 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0) 12383 { 12384 octx = NULL; 12385 break; 12386 } 12387 omp_add_variable (octx, decl, flags); 12388 if (octx->outer_context == NULL) 12389 break; 12390 octx = octx->outer_context; 12391 } 12392 while (1); 12393 if (octx 12394 && decl 12395 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12396 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))) 12397 omp_notice_variable (octx, decl, true); 12398 } 12399 flags = GOVD_LINEAR | GOVD_EXPLICIT; 12400 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c) 12401 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 12402 { 12403 notice_outer = false; 12404 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 12405 } 12406 goto do_add; 12407 12408 case OMP_CLAUSE_MAP: 12409 if (!grp_start_p) 12410 { 12411 grp_start_p = list_p; 12412 grp_end = (*groups)[grpnum].grp_end; 12413 grpnum++; 12414 } 12415 decl = OMP_CLAUSE_DECL (c); 12416 12417 if (error_operand_p (decl)) 12418 { 12419 remove = true; 12420 break; 12421 } 12422 12423 if (!omp_parse_expr (addr_tokens, decl)) 12424 { 12425 remove = true; 12426 break; 12427 } 12428 12429 if (remove) 12430 break; 12431 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC)) 12432 { 12433 struct gimplify_omp_ctx *octx; 12434 for (octx = outer_ctx; octx; octx = octx->outer_context) 12435 { 12436 if (octx->region_type != ORT_ACC_HOST_DATA) 12437 break; 12438 splay_tree_node n2 12439 = splay_tree_lookup (octx->variables, 12440 (splay_tree_key) decl); 12441 if (n2) 12442 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE " 12443 "declared in enclosing %<host_data%> region", 12444 DECL_NAME (decl)); 12445 } 12446 } 12447 12448 map_descriptor = false; 12449 12450 /* This condition checks if we're mapping an array descriptor that 12451 isn't inside a derived type -- these have special handling, and 12452 are not handled as structs in omp_build_struct_sibling_lists. 12453 See that function for further details. */ 12454 if (*grp_start_p != grp_end 12455 && OMP_CLAUSE_CHAIN (*grp_start_p) 12456 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) 12457 { 12458 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p); 12459 if (omp_map_clause_descriptor_p (grp_mid) 12460 && DECL_P (OMP_CLAUSE_DECL (grp_mid))) 12461 map_descriptor = true; 12462 } 12463 else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP 12464 && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE 12465 || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE) 12466 && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end)) 12467 map_descriptor = true; 12468 12469 /* Adding the decl for a struct access: we haven't created 12470 GOMP_MAP_STRUCT nodes yet, so this statement needs to predict 12471 whether they will be created in gimplify_adjust_omp_clauses. 12472 NOTE: Technically we should probably look through DECL_VALUE_EXPR 12473 here because something that looks like a DECL_P may actually be a 12474 struct access, e.g. variables in a lambda closure 12475 (__closure->__foo) or class members (this->foo). Currently in both 12476 those cases we map the whole of the containing object (directly in 12477 the C++ FE) though, so struct nodes are not created. */ 12478 if (c == grp_end 12479 && addr_tokens[0]->type == STRUCTURE_BASE 12480 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12481 && !map_descriptor) 12482 { 12483 gcc_assert (addr_tokens[1]->type == ACCESS_METHOD); 12484 /* If we got to this struct via a chain of pointers, maybe we 12485 want to map it implicitly instead. */ 12486 if (omp_access_chain_p (addr_tokens, 1)) 12487 break; 12488 omp_mapping_group *wholestruct; 12489 if (!(region_type & ORT_ACC) 12490 && omp_mapped_by_containing_struct (grpmap, 12491 OMP_CLAUSE_DECL (c), 12492 &wholestruct)) 12493 break; 12494 decl = addr_tokens[1]->expr; 12495 if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl)) 12496 break; 12497 /* Standalone attach or detach clauses for a struct element 12498 should not inhibit implicit mapping of the whole struct. */ 12499 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 12500 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH) 12501 break; 12502 flags = GOVD_MAP | GOVD_EXPLICIT; 12503 12504 gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT 12505 || TREE_ADDRESSABLE (decl)); 12506 goto do_add_decl; 12507 } 12508 12509 if (!DECL_P (decl)) 12510 { 12511 tree d = decl, *pd; 12512 if (TREE_CODE (d) == ARRAY_REF) 12513 { 12514 while (TREE_CODE (d) == ARRAY_REF) 12515 d = TREE_OPERAND (d, 0); 12516 if (TREE_CODE (d) == COMPONENT_REF 12517 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 12518 decl = d; 12519 } 12520 pd = &OMP_CLAUSE_DECL (c); 12521 if (d == decl 12522 && TREE_CODE (decl) == INDIRECT_REF 12523 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 12524 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 12525 == REFERENCE_TYPE) 12526 && (OMP_CLAUSE_MAP_KIND (c) 12527 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 12528 { 12529 pd = &TREE_OPERAND (decl, 0); 12530 decl = TREE_OPERAND (decl, 0); 12531 } 12532 12533 if (addr_tokens[0]->type == STRUCTURE_BASE 12534 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12535 && addr_tokens[1]->type == ACCESS_METHOD 12536 && (addr_tokens[1]->u.access_kind == ACCESS_POINTER 12537 || (addr_tokens[1]->u.access_kind 12538 == ACCESS_POINTER_OFFSET)) 12539 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))) 12540 { 12541 tree base = addr_tokens[1]->expr; 12542 splay_tree_node n 12543 = splay_tree_lookup (ctx->variables, 12544 (splay_tree_key) base); 12545 n->value |= GOVD_SEEN; 12546 } 12547 12548 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c)) 12549 { 12550 /* Don't gimplify *pd fully at this point, as the base 12551 will need to be adjusted during omp lowering. */ 12552 auto_vec<tree, 10> expr_stack; 12553 tree *p = pd; 12554 while (handled_component_p (*p) 12555 || TREE_CODE (*p) == INDIRECT_REF 12556 || TREE_CODE (*p) == ADDR_EXPR 12557 || TREE_CODE (*p) == MEM_REF 12558 || TREE_CODE (*p) == NON_LVALUE_EXPR) 12559 { 12560 expr_stack.safe_push (*p); 12561 p = &TREE_OPERAND (*p, 0); 12562 } 12563 for (int i = expr_stack.length () - 1; i >= 0; i--) 12564 { 12565 tree t = expr_stack[i]; 12566 if (TREE_CODE (t) == ARRAY_REF 12567 || TREE_CODE (t) == ARRAY_RANGE_REF) 12568 { 12569 if (TREE_OPERAND (t, 2) == NULL_TREE) 12570 { 12571 tree low = unshare_expr (array_ref_low_bound (t)); 12572 if (!is_gimple_min_invariant (low)) 12573 { 12574 TREE_OPERAND (t, 2) = low; 12575 if (gimplify_expr (&TREE_OPERAND (t, 2), 12576 pre_p, NULL, 12577 is_gimple_reg, 12578 fb_rvalue) == GS_ERROR) 12579 remove = true; 12580 } 12581 } 12582 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p, 12583 NULL, is_gimple_reg, 12584 fb_rvalue) == GS_ERROR) 12585 remove = true; 12586 if (TREE_OPERAND (t, 3) == NULL_TREE) 12587 { 12588 tree elmt_size = array_ref_element_size (t); 12589 if (!is_gimple_min_invariant (elmt_size)) 12590 { 12591 elmt_size = unshare_expr (elmt_size); 12592 tree elmt_type 12593 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 12594 0))); 12595 tree factor 12596 = size_int (TYPE_ALIGN_UNIT (elmt_type)); 12597 elmt_size 12598 = size_binop (EXACT_DIV_EXPR, elmt_size, 12599 factor); 12600 TREE_OPERAND (t, 3) = elmt_size; 12601 if (gimplify_expr (&TREE_OPERAND (t, 3), 12602 pre_p, NULL, 12603 is_gimple_reg, 12604 fb_rvalue) == GS_ERROR) 12605 remove = true; 12606 } 12607 } 12608 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p, 12609 NULL, is_gimple_reg, 12610 fb_rvalue) == GS_ERROR) 12611 remove = true; 12612 } 12613 else if (TREE_CODE (t) == COMPONENT_REF) 12614 { 12615 if (TREE_OPERAND (t, 2) == NULL_TREE) 12616 { 12617 tree offset = component_ref_field_offset (t); 12618 if (!is_gimple_min_invariant (offset)) 12619 { 12620 offset = unshare_expr (offset); 12621 tree field = TREE_OPERAND (t, 1); 12622 tree factor 12623 = size_int (DECL_OFFSET_ALIGN (field) 12624 / BITS_PER_UNIT); 12625 offset = size_binop (EXACT_DIV_EXPR, offset, 12626 factor); 12627 TREE_OPERAND (t, 2) = offset; 12628 if (gimplify_expr (&TREE_OPERAND (t, 2), 12629 pre_p, NULL, 12630 is_gimple_reg, 12631 fb_rvalue) == GS_ERROR) 12632 remove = true; 12633 } 12634 } 12635 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p, 12636 NULL, is_gimple_reg, 12637 fb_rvalue) == GS_ERROR) 12638 remove = true; 12639 } 12640 } 12641 for (; expr_stack.length () > 0; ) 12642 { 12643 tree t = expr_stack.pop (); 12644 12645 if (TREE_CODE (t) == ARRAY_REF 12646 || TREE_CODE (t) == ARRAY_RANGE_REF) 12647 { 12648 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)) 12649 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p, 12650 NULL, is_gimple_val, 12651 fb_rvalue) == GS_ERROR) 12652 remove = true; 12653 } 12654 } 12655 } 12656 break; 12657 } 12658 12659 if ((code == OMP_TARGET 12660 || code == OMP_TARGET_DATA 12661 || code == OMP_TARGET_ENTER_DATA 12662 || code == OMP_TARGET_EXIT_DATA) 12663 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 12664 { 12665 /* If we have attach/detach but the decl we have is a pointer to 12666 pointer, we're probably mapping the "base level" array 12667 implicitly. Make sure we don't add the decl as if we mapped 12668 it explicitly. That is, 12669 12670 int **arr; 12671 [...] 12672 #pragma omp target map(arr[a][b:c]) 12673 12674 should *not* map "arr" explicitly. That way we get a 12675 zero-length "alloc" mapping for it, and assuming it's been 12676 mapped by some previous directive, etc., things work as they 12677 should. */ 12678 12679 tree basetype = TREE_TYPE (addr_tokens[0]->expr); 12680 12681 if (TREE_CODE (basetype) == REFERENCE_TYPE) 12682 basetype = TREE_TYPE (basetype); 12683 12684 if (code == OMP_TARGET 12685 && addr_tokens[0]->type == ARRAY_BASE 12686 && addr_tokens[0]->u.structure_base_kind == BASE_DECL 12687 && TREE_CODE (basetype) == POINTER_TYPE 12688 && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE) 12689 break; 12690 } 12691 12692 flags = GOVD_MAP | GOVD_EXPLICIT; 12693 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO 12694 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM 12695 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO 12696 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM) 12697 flags |= GOVD_MAP_ALWAYS_TO; 12698 12699 goto do_add; 12700 12701 case OMP_CLAUSE_AFFINITY: 12702 gimplify_omp_affinity (list_p, pre_p); 12703 remove = true; 12704 break; 12705 case OMP_CLAUSE_DOACROSS: 12706 if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK) 12707 { 12708 tree deps = OMP_CLAUSE_DECL (c); 12709 while (deps && TREE_CODE (deps) == TREE_LIST) 12710 { 12711 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR 12712 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1))) 12713 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1), 12714 pre_p, NULL, is_gimple_val, fb_rvalue); 12715 deps = TREE_CHAIN (deps); 12716 } 12717 } 12718 else 12719 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c) 12720 == OMP_CLAUSE_DOACROSS_SOURCE); 12721 break; 12722 case OMP_CLAUSE_DEPEND: 12723 if (handled_depend_iterators == -1) 12724 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p); 12725 if (handled_depend_iterators) 12726 { 12727 if (handled_depend_iterators == 2) 12728 remove = true; 12729 break; 12730 } 12731 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) 12732 { 12733 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, 12734 NULL, is_gimple_val, fb_rvalue); 12735 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); 12736 } 12737 if (error_operand_p (OMP_CLAUSE_DECL (c))) 12738 { 12739 remove = true; 12740 break; 12741 } 12742 if (OMP_CLAUSE_DECL (c) != null_pointer_node) 12743 { 12744 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c)); 12745 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 12746 is_gimple_val, fb_rvalue) == GS_ERROR) 12747 { 12748 remove = true; 12749 break; 12750 } 12751 } 12752 if (code == OMP_TASK) 12753 ctx->has_depend = true; 12754 break; 12755 12756 case OMP_CLAUSE_TO: 12757 case OMP_CLAUSE_FROM: 12758 case OMP_CLAUSE__CACHE_: 12759 decl = OMP_CLAUSE_DECL (c); 12760 if (error_operand_p (decl)) 12761 { 12762 remove = true; 12763 break; 12764 } 12765 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 12766 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) 12767 : TYPE_SIZE_UNIT (TREE_TYPE (decl)); 12768 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, 12769 NULL, is_gimple_val, fb_rvalue) == GS_ERROR) 12770 { 12771 remove = true; 12772 break; 12773 } 12774 if (!DECL_P (decl)) 12775 { 12776 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, 12777 NULL, is_gimple_lvalue, fb_lvalue) 12778 == GS_ERROR) 12779 { 12780 remove = true; 12781 break; 12782 } 12783 break; 12784 } 12785 goto do_notice; 12786 12787 case OMP_CLAUSE_USE_DEVICE_PTR: 12788 case OMP_CLAUSE_USE_DEVICE_ADDR: 12789 flags = GOVD_EXPLICIT; 12790 goto do_add; 12791 12792 case OMP_CLAUSE_HAS_DEVICE_ADDR: 12793 decl = OMP_CLAUSE_DECL (c); 12794 while (TREE_CODE (decl) == INDIRECT_REF 12795 || TREE_CODE (decl) == ARRAY_REF) 12796 decl = TREE_OPERAND (decl, 0); 12797 flags = GOVD_EXPLICIT; 12798 goto do_add_decl; 12799 12800 case OMP_CLAUSE_IS_DEVICE_PTR: 12801 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; 12802 goto do_add; 12803 12804 do_add: 12805 decl = OMP_CLAUSE_DECL (c); 12806 do_add_decl: 12807 if (error_operand_p (decl)) 12808 { 12809 remove = true; 12810 break; 12811 } 12812 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0) 12813 { 12814 tree t = omp_member_access_dummy_var (decl); 12815 if (t) 12816 { 12817 tree v = DECL_VALUE_EXPR (decl); 12818 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1)); 12819 if (outer_ctx) 12820 omp_notice_variable (outer_ctx, t, true); 12821 } 12822 } 12823 if (code == OACC_DATA 12824 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP 12825 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) 12826 flags |= GOVD_MAP_0LEN_ARRAY; 12827 omp_add_variable (ctx, decl, flags); 12828 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12829 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION 12830 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) 12831 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) 12832 { 12833 struct gimplify_omp_ctx *pctx 12834 = code == OMP_TARGET ? outer_ctx : ctx; 12835 if (pctx) 12836 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 12837 GOVD_LOCAL | GOVD_SEEN); 12838 if (pctx 12839 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) 12840 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c), 12841 find_decl_expr, 12842 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 12843 NULL) == NULL_TREE) 12844 omp_add_variable (pctx, 12845 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 12846 GOVD_LOCAL | GOVD_SEEN); 12847 gimplify_omp_ctxp = pctx; 12848 push_gimplify_context (); 12849 12850 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL; 12851 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL; 12852 12853 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), 12854 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)); 12855 pop_gimplify_context 12856 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))); 12857 push_gimplify_context (); 12858 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), 12859 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)); 12860 pop_gimplify_context 12861 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c))); 12862 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE; 12863 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE; 12864 12865 gimplify_omp_ctxp = outer_ctx; 12866 } 12867 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 12868 && OMP_CLAUSE_LASTPRIVATE_STMT (c)) 12869 { 12870 gimplify_omp_ctxp = ctx; 12871 push_gimplify_context (); 12872 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR) 12873 { 12874 tree bind = build3 (BIND_EXPR, void_type_node, NULL, 12875 NULL, NULL); 12876 TREE_SIDE_EFFECTS (bind) = 1; 12877 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c); 12878 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind; 12879 } 12880 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c), 12881 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); 12882 pop_gimplify_context 12883 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))); 12884 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE; 12885 12886 gimplify_omp_ctxp = outer_ctx; 12887 } 12888 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 12889 && OMP_CLAUSE_LINEAR_STMT (c)) 12890 { 12891 gimplify_omp_ctxp = ctx; 12892 push_gimplify_context (); 12893 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR) 12894 { 12895 tree bind = build3 (BIND_EXPR, void_type_node, NULL, 12896 NULL, NULL); 12897 TREE_SIDE_EFFECTS (bind) = 1; 12898 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c); 12899 OMP_CLAUSE_LINEAR_STMT (c) = bind; 12900 } 12901 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c), 12902 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)); 12903 pop_gimplify_context 12904 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))); 12905 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE; 12906 12907 gimplify_omp_ctxp = outer_ctx; 12908 } 12909 if (notice_outer) 12910 goto do_notice; 12911 break; 12912 12913 case OMP_CLAUSE_COPYIN: 12914 case OMP_CLAUSE_COPYPRIVATE: 12915 decl = OMP_CLAUSE_DECL (c); 12916 if (error_operand_p (decl)) 12917 { 12918 remove = true; 12919 break; 12920 } 12921 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE 12922 && !remove 12923 && !omp_check_private (ctx, decl, true)) 12924 { 12925 remove = true; 12926 if (is_global_var (decl)) 12927 { 12928 if (DECL_THREAD_LOCAL_P (decl)) 12929 remove = false; 12930 else if (DECL_HAS_VALUE_EXPR_P (decl)) 12931 { 12932 tree value = get_base_address (DECL_VALUE_EXPR (decl)); 12933 12934 if (value 12935 && DECL_P (value) 12936 && DECL_THREAD_LOCAL_P (value)) 12937 remove = false; 12938 } 12939 } 12940 if (remove) 12941 error_at (OMP_CLAUSE_LOCATION (c), 12942 "copyprivate variable %qE is not threadprivate" 12943 " or private in outer context", DECL_NAME (decl)); 12944 } 12945 do_notice: 12946 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12947 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE 12948 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) 12949 && outer_ctx 12950 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP 12951 || (region_type == ORT_WORKSHARE 12952 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12953 && (OMP_CLAUSE_REDUCTION_INSCAN (c) 12954 || code == OMP_LOOP))) 12955 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL 12956 || (code == OMP_LOOP 12957 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12958 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS) 12959 == ORT_COMBINED_TEAMS)))) 12960 { 12961 splay_tree_node on 12962 = splay_tree_lookup (outer_ctx->variables, 12963 (splay_tree_key)decl); 12964 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0) 12965 { 12966 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION 12967 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF 12968 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 12969 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 12970 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) 12971 == POINTER_TYPE)))) 12972 omp_firstprivatize_variable (outer_ctx, decl); 12973 else 12974 { 12975 omp_add_variable (outer_ctx, decl, 12976 GOVD_SEEN | GOVD_SHARED); 12977 if (outer_ctx->outer_context) 12978 omp_notice_variable (outer_ctx->outer_context, decl, 12979 true); 12980 } 12981 } 12982 } 12983 if (outer_ctx) 12984 omp_notice_variable (outer_ctx, decl, true); 12985 if (check_non_private 12986 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE) 12987 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION 12988 || decl == OMP_CLAUSE_DECL (c) 12989 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF 12990 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0)) 12991 == ADDR_EXPR 12992 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0)) 12993 == POINTER_PLUS_EXPR 12994 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND 12995 (OMP_CLAUSE_DECL (c), 0), 0)) 12996 == ADDR_EXPR))))) 12997 && omp_check_private (ctx, decl, false)) 12998 { 12999 error ("%s variable %qE is private in outer context", 13000 check_non_private, DECL_NAME (decl)); 13001 remove = true; 13002 } 13003 break; 13004 13005 case OMP_CLAUSE_DETACH: 13006 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN; 13007 goto do_add; 13008 13009 case OMP_CLAUSE_IF: 13010 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK 13011 && OMP_CLAUSE_IF_MODIFIER (c) != code) 13012 { 13013 const char *p[2]; 13014 for (int i = 0; i < 2; i++) 13015 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code) 13016 { 13017 case VOID_CST: p[i] = "cancel"; break; 13018 case OMP_PARALLEL: p[i] = "parallel"; break; 13019 case OMP_SIMD: p[i] = "simd"; break; 13020 case OMP_TASK: p[i] = "task"; break; 13021 case OMP_TASKLOOP: p[i] = "taskloop"; break; 13022 case OMP_TARGET_DATA: p[i] = "target data"; break; 13023 case OMP_TARGET: p[i] = "target"; break; 13024 case OMP_TARGET_UPDATE: p[i] = "target update"; break; 13025 case OMP_TARGET_ENTER_DATA: 13026 p[i] = "target enter data"; break; 13027 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break; 13028 default: gcc_unreachable (); 13029 } 13030 error_at (OMP_CLAUSE_LOCATION (c), 13031 "expected %qs %<if%> clause modifier rather than %qs", 13032 p[0], p[1]); 13033 remove = true; 13034 } 13035 /* Fall through. */ 13036 13037 case OMP_CLAUSE_SELF: 13038 case OMP_CLAUSE_FINAL: 13039 OMP_CLAUSE_OPERAND (c, 0) 13040 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); 13041 /* Fall through. */ 13042 13043 case OMP_CLAUSE_NUM_TEAMS: 13044 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS 13045 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 13046 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) 13047 { 13048 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) 13049 { 13050 remove = true; 13051 break; 13052 } 13053 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 13054 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c), 13055 pre_p, NULL, true); 13056 } 13057 /* Fall through. */ 13058 13059 case OMP_CLAUSE_SCHEDULE: 13060 case OMP_CLAUSE_NUM_THREADS: 13061 case OMP_CLAUSE_THREAD_LIMIT: 13062 case OMP_CLAUSE_DIST_SCHEDULE: 13063 case OMP_CLAUSE_DEVICE: 13064 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE 13065 && OMP_CLAUSE_DEVICE_ANCESTOR (c)) 13066 { 13067 if (code != OMP_TARGET) 13068 { 13069 error_at (OMP_CLAUSE_LOCATION (c), 13070 "%<device%> clause with %<ancestor%> is only " 13071 "allowed on %<target%> construct"); 13072 remove = true; 13073 break; 13074 } 13075 13076 tree clauses = *orig_list_p; 13077 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses)) 13078 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE 13079 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE 13080 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE 13081 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP 13082 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP 13083 ) 13084 { 13085 error_at (OMP_CLAUSE_LOCATION (c), 13086 "with %<ancestor%>, only the %<device%>, " 13087 "%<firstprivate%>, %<private%>, %<defaultmap%>, " 13088 "and %<map%> clauses may appear on the " 13089 "construct"); 13090 remove = true; 13091 break; 13092 } 13093 } 13094 /* Fall through. */ 13095 13096 case OMP_CLAUSE_PRIORITY: 13097 case OMP_CLAUSE_GRAINSIZE: 13098 case OMP_CLAUSE_NUM_TASKS: 13099 case OMP_CLAUSE_FILTER: 13100 case OMP_CLAUSE_HINT: 13101 case OMP_CLAUSE_ASYNC: 13102 case OMP_CLAUSE_WAIT: 13103 case OMP_CLAUSE_NUM_GANGS: 13104 case OMP_CLAUSE_NUM_WORKERS: 13105 case OMP_CLAUSE_VECTOR_LENGTH: 13106 case OMP_CLAUSE_WORKER: 13107 case OMP_CLAUSE_VECTOR: 13108 if (OMP_CLAUSE_OPERAND (c, 0) 13109 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0))) 13110 { 13111 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0))) 13112 { 13113 remove = true; 13114 break; 13115 } 13116 /* All these clauses care about value, not a particular decl, 13117 so try to force it into a SSA_NAME or fresh temporary. */ 13118 OMP_CLAUSE_OPERAND (c, 0) 13119 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0), 13120 pre_p, NULL, true); 13121 } 13122 break; 13123 13124 case OMP_CLAUSE_GANG: 13125 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, 13126 is_gimple_val, fb_rvalue) == GS_ERROR) 13127 remove = true; 13128 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL, 13129 is_gimple_val, fb_rvalue) == GS_ERROR) 13130 remove = true; 13131 break; 13132 13133 case OMP_CLAUSE_NOWAIT: 13134 nowait = 1; 13135 break; 13136 13137 case OMP_CLAUSE_ORDERED: 13138 case OMP_CLAUSE_UNTIED: 13139 case OMP_CLAUSE_COLLAPSE: 13140 case OMP_CLAUSE_TILE: 13141 case OMP_CLAUSE_AUTO: 13142 case OMP_CLAUSE_SEQ: 13143 case OMP_CLAUSE_INDEPENDENT: 13144 case OMP_CLAUSE_MERGEABLE: 13145 case OMP_CLAUSE_PROC_BIND: 13146 case OMP_CLAUSE_SAFELEN: 13147 case OMP_CLAUSE_SIMDLEN: 13148 case OMP_CLAUSE_NOGROUP: 13149 case OMP_CLAUSE_THREADS: 13150 case OMP_CLAUSE_SIMD: 13151 case OMP_CLAUSE_BIND: 13152 case OMP_CLAUSE_IF_PRESENT: 13153 case OMP_CLAUSE_FINALIZE: 13154 break; 13155 13156 case OMP_CLAUSE_ORDER: 13157 ctx->order_concurrent = true; 13158 break; 13159 13160 case OMP_CLAUSE_DEFAULTMAP: 13161 enum gimplify_defaultmap_kind gdmkmin, gdmkmax; 13162 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)) 13163 { 13164 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: 13165 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL: 13166 gdmkmin = GDMK_SCALAR; 13167 gdmkmax = GDMK_POINTER; 13168 break; 13169 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: 13170 gdmkmin = GDMK_SCALAR; 13171 gdmkmax = GDMK_SCALAR_TARGET; 13172 break; 13173 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: 13174 gdmkmin = gdmkmax = GDMK_AGGREGATE; 13175 break; 13176 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE: 13177 gdmkmin = gdmkmax = GDMK_ALLOCATABLE; 13178 break; 13179 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: 13180 gdmkmin = gdmkmax = GDMK_POINTER; 13181 break; 13182 default: 13183 gcc_unreachable (); 13184 } 13185 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++) 13186 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c)) 13187 { 13188 case OMP_CLAUSE_DEFAULTMAP_ALLOC: 13189 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY; 13190 break; 13191 case OMP_CLAUSE_DEFAULTMAP_TO: 13192 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY; 13193 break; 13194 case OMP_CLAUSE_DEFAULTMAP_FROM: 13195 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY; 13196 break; 13197 case OMP_CLAUSE_DEFAULTMAP_TOFROM: 13198 ctx->defaultmap[gdmk] = GOVD_MAP; 13199 break; 13200 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE: 13201 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE; 13202 break; 13203 case OMP_CLAUSE_DEFAULTMAP_NONE: 13204 ctx->defaultmap[gdmk] = 0; 13205 break; 13206 case OMP_CLAUSE_DEFAULTMAP_PRESENT: 13207 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT; 13208 break; 13209 case OMP_CLAUSE_DEFAULTMAP_DEFAULT: 13210 switch (gdmk) 13211 { 13212 case GDMK_SCALAR: 13213 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE; 13214 break; 13215 case GDMK_SCALAR_TARGET: 13216 ctx->defaultmap[gdmk] = (lang_GNU_Fortran () 13217 ? GOVD_MAP : GOVD_FIRSTPRIVATE); 13218 break; 13219 case GDMK_AGGREGATE: 13220 case GDMK_ALLOCATABLE: 13221 ctx->defaultmap[gdmk] = GOVD_MAP; 13222 break; 13223 case GDMK_POINTER: 13224 ctx->defaultmap[gdmk] = GOVD_MAP; 13225 if (!lang_GNU_Fortran ()) 13226 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY; 13227 break; 13228 default: 13229 gcc_unreachable (); 13230 } 13231 break; 13232 default: 13233 gcc_unreachable (); 13234 } 13235 break; 13236 13237 case OMP_CLAUSE_ALIGNED: 13238 decl = OMP_CLAUSE_DECL (c); 13239 if (error_operand_p (decl)) 13240 { 13241 remove = true; 13242 break; 13243 } 13244 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL, 13245 is_gimple_val, fb_rvalue) == GS_ERROR) 13246 { 13247 remove = true; 13248 break; 13249 } 13250 if (!is_global_var (decl) 13251 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) 13252 omp_add_variable (ctx, decl, GOVD_ALIGNED); 13253 break; 13254 13255 case OMP_CLAUSE_NONTEMPORAL: 13256 decl = OMP_CLAUSE_DECL (c); 13257 if (error_operand_p (decl)) 13258 { 13259 remove = true; 13260 break; 13261 } 13262 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL); 13263 break; 13264 13265 case OMP_CLAUSE_ALLOCATE: 13266 decl = OMP_CLAUSE_DECL (c); 13267 if (error_operand_p (decl)) 13268 { 13269 remove = true; 13270 break; 13271 } 13272 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL, 13273 is_gimple_val, fb_rvalue) == GS_ERROR) 13274 { 13275 remove = true; 13276 break; 13277 } 13278 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE 13279 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) 13280 == INTEGER_CST)) 13281 ; 13282 else if (code == OMP_TASKLOOP 13283 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))) 13284 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 13285 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 13286 pre_p, NULL, false); 13287 break; 13288 13289 case OMP_CLAUSE_DEFAULT: 13290 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c); 13291 break; 13292 13293 case OMP_CLAUSE_INCLUSIVE: 13294 case OMP_CLAUSE_EXCLUSIVE: 13295 decl = OMP_CLAUSE_DECL (c); 13296 { 13297 splay_tree_node n = splay_tree_lookup (outer_ctx->variables, 13298 (splay_tree_key) decl); 13299 if (n == NULL || (n->value & GOVD_REDUCTION) == 0) 13300 { 13301 error_at (OMP_CLAUSE_LOCATION (c), 13302 "%qD specified in %qs clause but not in %<inscan%> " 13303 "%<reduction%> clause on the containing construct", 13304 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); 13305 remove = true; 13306 } 13307 else 13308 { 13309 n->value |= GOVD_REDUCTION_INSCAN; 13310 if (outer_ctx->region_type == ORT_SIMD 13311 && outer_ctx->outer_context 13312 && outer_ctx->outer_context->region_type == ORT_WORKSHARE) 13313 { 13314 n = splay_tree_lookup (outer_ctx->outer_context->variables, 13315 (splay_tree_key) decl); 13316 if (n && (n->value & GOVD_REDUCTION) != 0) 13317 n->value |= GOVD_REDUCTION_INSCAN; 13318 } 13319 } 13320 } 13321 break; 13322 13323 case OMP_CLAUSE_NOHOST: 13324 default: 13325 gcc_unreachable (); 13326 } 13327 13328 if (code == OACC_DATA 13329 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP 13330 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 13331 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 13332 remove = true; 13333 if (remove) 13334 *list_p = OMP_CLAUSE_CHAIN (c); 13335 else 13336 list_p = &OMP_CLAUSE_CHAIN (c); 13337 } 13338 13339 if (groups) 13340 { 13341 delete grpmap; 13342 delete groups; 13343 } 13344 13345 ctx->clauses = *orig_list_p; 13346 gimplify_omp_ctxp = ctx; 13347 } 13348 13349 /* Return true if DECL is a candidate for shared to firstprivate 13350 optimization. We only consider non-addressable scalars, not 13351 too big, and not references. */ 13352 13353 static bool 13354 omp_shared_to_firstprivate_optimizable_decl_p (tree decl) 13355 { 13356 if (TREE_ADDRESSABLE (decl)) 13357 return false; 13358 tree type = TREE_TYPE (decl); 13359 if (!is_gimple_reg_type (type) 13360 || TREE_CODE (type) == REFERENCE_TYPE 13361 || TREE_ADDRESSABLE (type)) 13362 return false; 13363 /* Don't optimize too large decls, as each thread/task will have 13364 its own. */ 13365 HOST_WIDE_INT len = int_size_in_bytes (type); 13366 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT) 13367 return false; 13368 if (omp_privatize_by_reference (decl)) 13369 return false; 13370 return true; 13371 } 13372 13373 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*. 13374 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as 13375 GOVD_WRITTEN in outer contexts. */ 13376 13377 static void 13378 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl) 13379 { 13380 for (; ctx; ctx = ctx->outer_context) 13381 { 13382 splay_tree_node n = splay_tree_lookup (ctx->variables, 13383 (splay_tree_key) decl); 13384 if (n == NULL) 13385 continue; 13386 else if (n->value & GOVD_SHARED) 13387 { 13388 n->value |= GOVD_WRITTEN; 13389 return; 13390 } 13391 else if (n->value & GOVD_DATA_SHARE_CLASS) 13392 return; 13393 } 13394 } 13395 13396 /* Helper callback for walk_gimple_seq to discover possible stores 13397 to omp_shared_to_firstprivate_optimizable_decl_p decls and set 13398 GOVD_WRITTEN if they are GOVD_SHARED in some outer context 13399 for those. */ 13400 13401 static tree 13402 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data) 13403 { 13404 struct walk_stmt_info *wi = (struct walk_stmt_info *) data; 13405 13406 *walk_subtrees = 0; 13407 if (!wi->is_lhs) 13408 return NULL_TREE; 13409 13410 tree op = *tp; 13411 do 13412 { 13413 if (handled_component_p (op)) 13414 op = TREE_OPERAND (op, 0); 13415 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF) 13416 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR) 13417 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0); 13418 else 13419 break; 13420 } 13421 while (1); 13422 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op)) 13423 return NULL_TREE; 13424 13425 omp_mark_stores (gimplify_omp_ctxp, op); 13426 return NULL_TREE; 13427 } 13428 13429 /* Helper callback for walk_gimple_seq to discover possible stores 13430 to omp_shared_to_firstprivate_optimizable_decl_p decls and set 13431 GOVD_WRITTEN if they are GOVD_SHARED in some outer context 13432 for those. */ 13433 13434 static tree 13435 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p, 13436 bool *handled_ops_p, 13437 struct walk_stmt_info *wi) 13438 { 13439 gimple *stmt = gsi_stmt (*gsi_p); 13440 switch (gimple_code (stmt)) 13441 { 13442 /* Don't recurse on OpenMP constructs for which 13443 gimplify_adjust_omp_clauses already handled the bodies, 13444 except handle gimple_omp_for_pre_body. */ 13445 case GIMPLE_OMP_FOR: 13446 *handled_ops_p = true; 13447 if (gimple_omp_for_pre_body (stmt)) 13448 walk_gimple_seq (gimple_omp_for_pre_body (stmt), 13449 omp_find_stores_stmt, omp_find_stores_op, wi); 13450 break; 13451 case GIMPLE_OMP_PARALLEL: 13452 case GIMPLE_OMP_TASK: 13453 case GIMPLE_OMP_SECTIONS: 13454 case GIMPLE_OMP_SINGLE: 13455 case GIMPLE_OMP_SCOPE: 13456 case GIMPLE_OMP_TARGET: 13457 case GIMPLE_OMP_TEAMS: 13458 case GIMPLE_OMP_CRITICAL: 13459 *handled_ops_p = true; 13460 break; 13461 default: 13462 break; 13463 } 13464 return NULL_TREE; 13465 } 13466 13467 struct gimplify_adjust_omp_clauses_data 13468 { 13469 tree *list_p; 13470 gimple_seq *pre_p; 13471 }; 13472 13473 /* For all variables that were not actually used within the context, 13474 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */ 13475 13476 static int 13477 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) 13478 { 13479 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p; 13480 gimple_seq *pre_p 13481 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p; 13482 tree decl = (tree) n->key; 13483 unsigned flags = n->value; 13484 enum omp_clause_code code; 13485 tree clause; 13486 bool private_debug; 13487 13488 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL 13489 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0) 13490 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN; 13491 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL)) 13492 return 0; 13493 if ((flags & GOVD_SEEN) == 0) 13494 return 0; 13495 if (flags & GOVD_DEBUG_PRIVATE) 13496 { 13497 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED); 13498 private_debug = true; 13499 } 13500 else if (flags & GOVD_MAP) 13501 private_debug = false; 13502 else 13503 private_debug 13504 = lang_hooks.decls.omp_private_debug_clause (decl, 13505 !!(flags & GOVD_SHARED)); 13506 if (private_debug) 13507 code = OMP_CLAUSE_PRIVATE; 13508 else if (flags & GOVD_MAP) 13509 { 13510 code = OMP_CLAUSE_MAP; 13511 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0 13512 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl)))) 13513 { 13514 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl); 13515 return 0; 13516 } 13517 if (VAR_P (decl) 13518 && DECL_IN_CONSTANT_POOL (decl) 13519 && !lookup_attribute ("omp declare target", 13520 DECL_ATTRIBUTES (decl))) 13521 { 13522 tree id = get_identifier ("omp declare target"); 13523 DECL_ATTRIBUTES (decl) 13524 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); 13525 varpool_node *node = varpool_node::get (decl); 13526 if (node) 13527 { 13528 node->offloadable = 1; 13529 if (ENABLE_OFFLOADING) 13530 g->have_offload = true; 13531 } 13532 } 13533 } 13534 else if (flags & GOVD_SHARED) 13535 { 13536 if (is_global_var (decl)) 13537 { 13538 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; 13539 while (ctx != NULL) 13540 { 13541 splay_tree_node on 13542 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13543 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE 13544 | GOVD_PRIVATE | GOVD_REDUCTION 13545 | GOVD_LINEAR | GOVD_MAP)) != 0) 13546 break; 13547 ctx = ctx->outer_context; 13548 } 13549 if (ctx == NULL) 13550 return 0; 13551 } 13552 code = OMP_CLAUSE_SHARED; 13553 /* Don't optimize shared into firstprivate for read-only vars 13554 on tasks with depend clause, we shouldn't try to copy them 13555 until the dependencies are satisfied. */ 13556 if (gimplify_omp_ctxp->has_depend) 13557 flags |= GOVD_WRITTEN; 13558 } 13559 else if (flags & GOVD_PRIVATE) 13560 code = OMP_CLAUSE_PRIVATE; 13561 else if (flags & GOVD_FIRSTPRIVATE) 13562 { 13563 code = OMP_CLAUSE_FIRSTPRIVATE; 13564 if ((gimplify_omp_ctxp->region_type & ORT_TARGET) 13565 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0 13566 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl)))) 13567 { 13568 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on " 13569 "%<target%> construct", decl); 13570 return 0; 13571 } 13572 } 13573 else if (flags & GOVD_LASTPRIVATE) 13574 code = OMP_CLAUSE_LASTPRIVATE; 13575 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL)) 13576 return 0; 13577 else if (flags & GOVD_CONDTEMP) 13578 { 13579 code = OMP_CLAUSE__CONDTEMP_; 13580 gimple_add_tmp_var (decl); 13581 } 13582 else 13583 gcc_unreachable (); 13584 13585 if (((flags & GOVD_LASTPRIVATE) 13586 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN))) 13587 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13588 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 13589 13590 tree chain = *list_p; 13591 clause = build_omp_clause (input_location, code); 13592 OMP_CLAUSE_DECL (clause) = decl; 13593 OMP_CLAUSE_CHAIN (clause) = chain; 13594 if (private_debug) 13595 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1; 13596 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF)) 13597 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1; 13598 else if (code == OMP_CLAUSE_SHARED 13599 && (flags & GOVD_WRITTEN) == 0 13600 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13601 OMP_CLAUSE_SHARED_READONLY (clause) = 1; 13602 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0) 13603 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1; 13604 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0) 13605 { 13606 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP); 13607 OMP_CLAUSE_DECL (nc) = decl; 13608 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 13609 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE) 13610 OMP_CLAUSE_DECL (clause) 13611 = build_fold_indirect_ref_loc (input_location, decl); 13612 OMP_CLAUSE_DECL (clause) 13613 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause), 13614 build_int_cst (build_pointer_type (char_type_node), 0)); 13615 OMP_CLAUSE_SIZE (clause) = size_zero_node; 13616 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13617 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC); 13618 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1; 13619 tree dtype = TREE_TYPE (decl); 13620 if (TREE_CODE (dtype) == REFERENCE_TYPE) 13621 dtype = TREE_TYPE (dtype); 13622 /* FIRSTPRIVATE_POINTER doesn't work well if we have a 13623 multiply-indirected pointer. If we have a reference to a pointer to 13624 a pointer, it's possible that this should really be 13625 GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the 13626 moment, so stick with this. (See PR113279 and testcases 13627 baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice). */ 13628 if (TREE_CODE (dtype) == POINTER_TYPE 13629 && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE) 13630 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 13631 else 13632 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER); 13633 OMP_CLAUSE_CHAIN (nc) = chain; 13634 OMP_CLAUSE_CHAIN (clause) = nc; 13635 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13636 gimplify_omp_ctxp = ctx->outer_context; 13637 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0), 13638 pre_p, NULL, is_gimple_val, fb_rvalue); 13639 gimplify_omp_ctxp = ctx; 13640 } 13641 else if (code == OMP_CLAUSE_MAP) 13642 { 13643 int kind; 13644 /* Not all combinations of these GOVD_MAP flags are actually valid. */ 13645 switch (flags & (GOVD_MAP_TO_ONLY 13646 | GOVD_MAP_FORCE 13647 | GOVD_MAP_FORCE_PRESENT 13648 | GOVD_MAP_ALLOC_ONLY 13649 | GOVD_MAP_FROM_ONLY)) 13650 { 13651 case 0: 13652 kind = GOMP_MAP_TOFROM; 13653 break; 13654 case GOVD_MAP_FORCE: 13655 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE; 13656 break; 13657 case GOVD_MAP_TO_ONLY: 13658 kind = GOMP_MAP_TO; 13659 break; 13660 case GOVD_MAP_FROM_ONLY: 13661 kind = GOMP_MAP_FROM; 13662 break; 13663 case GOVD_MAP_ALLOC_ONLY: 13664 kind = GOMP_MAP_ALLOC; 13665 break; 13666 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE: 13667 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE; 13668 break; 13669 case GOVD_MAP_FORCE_PRESENT: 13670 kind = GOMP_MAP_FORCE_PRESENT; 13671 break; 13672 case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY: 13673 kind = GOMP_MAP_FORCE_PRESENT; 13674 break; 13675 default: 13676 gcc_unreachable (); 13677 } 13678 OMP_CLAUSE_SET_MAP_KIND (clause, kind); 13679 /* Setting of the implicit flag for the runtime is currently disabled for 13680 OpenACC. */ 13681 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0) 13682 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1; 13683 if (DECL_SIZE (decl) 13684 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 13685 { 13686 tree decl2 = DECL_VALUE_EXPR (decl); 13687 gcc_assert (INDIRECT_REF_P (decl2)); 13688 decl2 = TREE_OPERAND (decl2, 0); 13689 gcc_assert (DECL_P (decl2)); 13690 tree mem = build_simple_mem_ref (decl2); 13691 OMP_CLAUSE_DECL (clause) = mem; 13692 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 13693 if (gimplify_omp_ctxp->outer_context) 13694 { 13695 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; 13696 omp_notice_variable (ctx, decl2, true); 13697 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true); 13698 } 13699 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause), 13700 OMP_CLAUSE_MAP); 13701 OMP_CLAUSE_DECL (nc) = decl; 13702 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13703 if (gimplify_omp_ctxp->target_firstprivatize_array_bases) 13704 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER); 13705 else 13706 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 13707 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause); 13708 OMP_CLAUSE_CHAIN (clause) = nc; 13709 } 13710 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases 13711 && omp_privatize_by_reference (decl)) 13712 { 13713 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl); 13714 OMP_CLAUSE_SIZE (clause) 13715 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))); 13716 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13717 gimplify_omp_ctxp = ctx->outer_context; 13718 gimplify_expr (&OMP_CLAUSE_SIZE (clause), 13719 pre_p, NULL, is_gimple_val, fb_rvalue); 13720 gimplify_omp_ctxp = ctx; 13721 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause), 13722 OMP_CLAUSE_MAP); 13723 OMP_CLAUSE_DECL (nc) = decl; 13724 OMP_CLAUSE_SIZE (nc) = size_zero_node; 13725 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE); 13726 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause); 13727 OMP_CLAUSE_CHAIN (clause) = nc; 13728 } 13729 else 13730 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl); 13731 } 13732 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0) 13733 { 13734 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE); 13735 OMP_CLAUSE_DECL (nc) = decl; 13736 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1; 13737 OMP_CLAUSE_CHAIN (nc) = chain; 13738 OMP_CLAUSE_CHAIN (clause) = nc; 13739 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13740 gimplify_omp_ctxp = ctx->outer_context; 13741 lang_hooks.decls.omp_finish_clause (nc, pre_p, 13742 (ctx->region_type & ORT_ACC) != 0); 13743 gimplify_omp_ctxp = ctx; 13744 } 13745 *list_p = clause; 13746 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13747 gimplify_omp_ctxp = ctx->outer_context; 13748 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE 13749 in simd. Those are only added for the local vars inside of simd body 13750 and they don't need to be e.g. default constructible. */ 13751 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD) 13752 lang_hooks.decls.omp_finish_clause (clause, pre_p, 13753 (ctx->region_type & ORT_ACC) != 0); 13754 if (gimplify_omp_ctxp) 13755 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause)) 13756 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP 13757 && DECL_P (OMP_CLAUSE_SIZE (clause))) 13758 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause), 13759 true); 13760 gimplify_omp_ctxp = ctx; 13761 return 0; 13762 } 13763 13764 static void 13765 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, 13766 enum tree_code code) 13767 { 13768 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 13769 tree *orig_list_p = list_p; 13770 tree c, decl; 13771 bool has_inscan_reductions = false; 13772 13773 if (body) 13774 { 13775 struct gimplify_omp_ctx *octx; 13776 for (octx = ctx; octx; octx = octx->outer_context) 13777 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0) 13778 break; 13779 if (octx) 13780 { 13781 struct walk_stmt_info wi; 13782 memset (&wi, 0, sizeof (wi)); 13783 walk_gimple_seq (body, omp_find_stores_stmt, 13784 omp_find_stores_op, &wi); 13785 } 13786 } 13787 13788 if (ctx->add_safelen1) 13789 { 13790 /* If there are VLAs in the body of simd loop, prevent 13791 vectorization. */ 13792 gcc_assert (ctx->region_type == ORT_SIMD); 13793 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN); 13794 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node; 13795 OMP_CLAUSE_CHAIN (c) = *list_p; 13796 *list_p = c; 13797 list_p = &OMP_CLAUSE_CHAIN (c); 13798 } 13799 13800 if (ctx->region_type == ORT_WORKSHARE 13801 && ctx->outer_context 13802 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL) 13803 { 13804 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c)) 13805 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 13806 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 13807 { 13808 decl = OMP_CLAUSE_DECL (c); 13809 splay_tree_node n 13810 = splay_tree_lookup (ctx->outer_context->variables, 13811 (splay_tree_key) decl); 13812 gcc_checking_assert (!splay_tree_lookup (ctx->variables, 13813 (splay_tree_key) decl)); 13814 omp_add_variable (ctx, decl, n->value); 13815 tree c2 = copy_node (c); 13816 OMP_CLAUSE_CHAIN (c2) = *list_p; 13817 *list_p = c2; 13818 if ((n->value & GOVD_FIRSTPRIVATE) == 0) 13819 continue; 13820 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 13821 OMP_CLAUSE_FIRSTPRIVATE); 13822 OMP_CLAUSE_DECL (c2) = decl; 13823 OMP_CLAUSE_CHAIN (c2) = *list_p; 13824 *list_p = c2; 13825 } 13826 } 13827 13828 if (code == OMP_TARGET 13829 || code == OMP_TARGET_DATA 13830 || code == OMP_TARGET_ENTER_DATA 13831 || code == OMP_TARGET_EXIT_DATA) 13832 { 13833 vec<omp_mapping_group> *groups; 13834 groups = omp_gather_mapping_groups (list_p); 13835 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL; 13836 13837 if (groups) 13838 { 13839 grpmap = omp_index_mapping_groups (groups); 13840 13841 omp_resolve_clause_dependencies (code, groups, grpmap); 13842 omp_build_struct_sibling_lists (code, ctx->region_type, groups, 13843 &grpmap, list_p); 13844 13845 omp_mapping_group *outlist = NULL; 13846 13847 delete grpmap; 13848 delete groups; 13849 13850 /* Rebuild now we have struct sibling lists. */ 13851 groups = omp_gather_mapping_groups (list_p); 13852 grpmap = omp_index_mapping_groups (groups); 13853 13854 bool enter_exit = (code == OMP_TARGET_ENTER_DATA 13855 || code == OMP_TARGET_EXIT_DATA); 13856 13857 outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit); 13858 outlist = omp_segregate_mapping_groups (outlist); 13859 list_p = omp_reorder_mapping_groups (groups, outlist, list_p); 13860 13861 delete grpmap; 13862 delete groups; 13863 } 13864 } 13865 else if (ctx->region_type & ORT_ACC) 13866 { 13867 vec<omp_mapping_group> *groups; 13868 groups = omp_gather_mapping_groups (list_p); 13869 if (groups) 13870 { 13871 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap; 13872 grpmap = omp_index_mapping_groups (groups); 13873 13874 oacc_resolve_clause_dependencies (groups, grpmap); 13875 omp_build_struct_sibling_lists (code, ctx->region_type, groups, 13876 &grpmap, list_p); 13877 13878 delete groups; 13879 delete grpmap; 13880 } 13881 } 13882 13883 tree attach_list = NULL_TREE; 13884 tree *attach_tail = &attach_list; 13885 13886 tree *grp_start_p = NULL, grp_end = NULL_TREE; 13887 13888 while ((c = *list_p) != NULL) 13889 { 13890 splay_tree_node n; 13891 bool remove = false; 13892 bool move_attach = false; 13893 13894 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end)) 13895 grp_end = NULL_TREE; 13896 13897 switch (OMP_CLAUSE_CODE (c)) 13898 { 13899 case OMP_CLAUSE_FIRSTPRIVATE: 13900 if ((ctx->region_type & ORT_TARGET) 13901 && (ctx->region_type & ORT_ACC) == 0 13902 && TYPE_ATOMIC (strip_array_types 13903 (TREE_TYPE (OMP_CLAUSE_DECL (c))))) 13904 { 13905 error_at (OMP_CLAUSE_LOCATION (c), 13906 "%<_Atomic%> %qD in %<firstprivate%> clause on " 13907 "%<target%> construct", OMP_CLAUSE_DECL (c)); 13908 remove = true; 13909 break; 13910 } 13911 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) 13912 { 13913 decl = OMP_CLAUSE_DECL (c); 13914 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13915 if ((n->value & GOVD_MAP) != 0) 13916 { 13917 remove = true; 13918 break; 13919 } 13920 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0; 13921 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0; 13922 } 13923 /* FALLTHRU */ 13924 case OMP_CLAUSE_PRIVATE: 13925 case OMP_CLAUSE_SHARED: 13926 case OMP_CLAUSE_LINEAR: 13927 decl = OMP_CLAUSE_DECL (c); 13928 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13929 remove = !(n->value & GOVD_SEEN); 13930 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0 13931 && code == OMP_PARALLEL 13932 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) 13933 remove = true; 13934 if (! remove) 13935 { 13936 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED; 13937 if ((n->value & GOVD_DEBUG_PRIVATE) 13938 || lang_hooks.decls.omp_private_debug_clause (decl, shared)) 13939 { 13940 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0 13941 || ((n->value & GOVD_DATA_SHARE_CLASS) 13942 == GOVD_SHARED)); 13943 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE); 13944 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1; 13945 } 13946 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13947 && ctx->has_depend 13948 && DECL_P (decl)) 13949 n->value |= GOVD_WRITTEN; 13950 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13951 && (n->value & GOVD_WRITTEN) == 0 13952 && DECL_P (decl) 13953 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13954 OMP_CLAUSE_SHARED_READONLY (c) = 1; 13955 else if (DECL_P (decl) 13956 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 13957 && (n->value & GOVD_WRITTEN) != 0) 13958 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 13959 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))) 13960 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13961 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 13962 } 13963 else 13964 n->value &= ~GOVD_EXPLICIT; 13965 break; 13966 13967 case OMP_CLAUSE_LASTPRIVATE: 13968 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to 13969 accurately reflect the presence of a FIRSTPRIVATE clause. */ 13970 decl = OMP_CLAUSE_DECL (c); 13971 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13972 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) 13973 = (n->value & GOVD_FIRSTPRIVATE) != 0; 13974 if (code == OMP_DISTRIBUTE 13975 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)) 13976 { 13977 remove = true; 13978 error_at (OMP_CLAUSE_LOCATION (c), 13979 "same variable used in %<firstprivate%> and " 13980 "%<lastprivate%> clauses on %<distribute%> " 13981 "construct"); 13982 } 13983 if (!remove 13984 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 13985 && DECL_P (decl) 13986 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 13987 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 13988 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL) 13989 remove = true; 13990 break; 13991 13992 case OMP_CLAUSE_ALIGNED: 13993 decl = OMP_CLAUSE_DECL (c); 13994 if (!is_global_var (decl)) 13995 { 13996 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 13997 remove = n == NULL || !(n->value & GOVD_SEEN); 13998 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) 13999 { 14000 struct gimplify_omp_ctx *octx; 14001 if (n != NULL 14002 && (n->value & (GOVD_DATA_SHARE_CLASS 14003 & ~GOVD_FIRSTPRIVATE))) 14004 remove = true; 14005 else 14006 for (octx = ctx->outer_context; octx; 14007 octx = octx->outer_context) 14008 { 14009 n = splay_tree_lookup (octx->variables, 14010 (splay_tree_key) decl); 14011 if (n == NULL) 14012 continue; 14013 if (n->value & GOVD_LOCAL) 14014 break; 14015 /* We have to avoid assigning a shared variable 14016 to itself when trying to add 14017 __builtin_assume_aligned. */ 14018 if (n->value & GOVD_SHARED) 14019 { 14020 remove = true; 14021 break; 14022 } 14023 } 14024 } 14025 } 14026 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 14027 { 14028 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14029 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 14030 remove = true; 14031 } 14032 break; 14033 14034 case OMP_CLAUSE_HAS_DEVICE_ADDR: 14035 decl = OMP_CLAUSE_DECL (c); 14036 while (INDIRECT_REF_P (decl) 14037 || TREE_CODE (decl) == ARRAY_REF) 14038 decl = TREE_OPERAND (decl, 0); 14039 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14040 remove = n == NULL || !(n->value & GOVD_SEEN); 14041 break; 14042 14043 case OMP_CLAUSE_IS_DEVICE_PTR: 14044 case OMP_CLAUSE_NONTEMPORAL: 14045 decl = OMP_CLAUSE_DECL (c); 14046 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14047 remove = n == NULL || !(n->value & GOVD_SEEN); 14048 break; 14049 14050 case OMP_CLAUSE_MAP: 14051 decl = OMP_CLAUSE_DECL (c); 14052 if (!grp_end) 14053 { 14054 grp_start_p = list_p; 14055 grp_end = *omp_group_last (grp_start_p); 14056 } 14057 switch (OMP_CLAUSE_MAP_KIND (c)) 14058 { 14059 case GOMP_MAP_PRESENT_ALLOC: 14060 case GOMP_MAP_PRESENT_TO: 14061 case GOMP_MAP_PRESENT_FROM: 14062 case GOMP_MAP_PRESENT_TOFROM: 14063 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT); 14064 break; 14065 default: 14066 break; 14067 } 14068 switch (code) 14069 { 14070 case OACC_DATA: 14071 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) 14072 break; 14073 /* Fallthrough. */ 14074 case OACC_HOST_DATA: 14075 case OACC_ENTER_DATA: 14076 case OACC_EXIT_DATA: 14077 case OMP_TARGET_DATA: 14078 case OMP_TARGET_ENTER_DATA: 14079 case OMP_TARGET_EXIT_DATA: 14080 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 14081 || (OMP_CLAUSE_MAP_KIND (c) 14082 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 14083 /* For target {,enter ,exit }data only the array slice is 14084 mapped, but not the pointer to it. */ 14085 remove = true; 14086 if (code == OMP_TARGET_EXIT_DATA 14087 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER 14088 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)) 14089 remove = true; 14090 break; 14091 case OMP_TARGET: 14092 break; 14093 default: 14094 break; 14095 } 14096 if (remove) 14097 break; 14098 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14099 { 14100 /* Sanity check: attach/detach map kinds use the size as a bias, 14101 and it's never right to use the decl size for such 14102 mappings. */ 14103 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH 14104 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH 14105 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH 14106 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH 14107 && (OMP_CLAUSE_MAP_KIND (c) 14108 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)); 14109 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) 14110 : TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14111 } 14112 gimplify_omp_ctxp = ctx->outer_context; 14113 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL, 14114 is_gimple_val, fb_rvalue) == GS_ERROR) 14115 { 14116 gimplify_omp_ctxp = ctx; 14117 remove = true; 14118 break; 14119 } 14120 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER 14121 || (OMP_CLAUSE_MAP_KIND (c) 14122 == GOMP_MAP_FIRSTPRIVATE_REFERENCE) 14123 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14124 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST) 14125 { 14126 OMP_CLAUSE_SIZE (c) 14127 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL, 14128 false); 14129 if ((ctx->region_type & ORT_TARGET) != 0) 14130 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c), 14131 GOVD_FIRSTPRIVATE | GOVD_SEEN); 14132 } 14133 gimplify_omp_ctxp = ctx; 14134 /* Data clauses associated with reductions must be 14135 compatible with present_or_copy. Warn and adjust the clause 14136 if that is not the case. */ 14137 if (ctx->region_type == ORT_ACC_PARALLEL 14138 || ctx->region_type == ORT_ACC_SERIAL) 14139 { 14140 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0); 14141 n = NULL; 14142 14143 if (DECL_P (t)) 14144 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t); 14145 14146 if (n && (n->value & GOVD_REDUCTION)) 14147 { 14148 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c); 14149 14150 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1; 14151 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM 14152 && kind != GOMP_MAP_FORCE_PRESENT 14153 && kind != GOMP_MAP_POINTER) 14154 { 14155 warning_at (OMP_CLAUSE_LOCATION (c), 0, 14156 "incompatible data clause with reduction " 14157 "on %qE; promoting to %<present_or_copy%>", 14158 DECL_NAME (t)); 14159 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM); 14160 } 14161 } 14162 } 14163 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT 14164 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD) 14165 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)) 14166 { 14167 remove = true; 14168 break; 14169 } 14170 /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or 14171 a variable captured in a lambda closure), look through that now 14172 before the DECL_P check below. (A code other than COMPONENT_REF, 14173 i.e. INDIRECT_REF, will be a VLA/variable-length array 14174 section. A global var may be a variable in a common block. We 14175 don't want to do this here for either of those.) */ 14176 if ((ctx->region_type & ORT_ACC) == 0 14177 && DECL_P (decl) 14178 && !is_global_var (decl) 14179 && DECL_HAS_VALUE_EXPR_P (decl) 14180 && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF) 14181 decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl); 14182 if (TREE_CODE (decl) == TARGET_EXPR) 14183 { 14184 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, 14185 is_gimple_lvalue, fb_lvalue) == GS_ERROR) 14186 remove = true; 14187 } 14188 else if (!DECL_P (decl)) 14189 { 14190 if ((ctx->region_type & ORT_TARGET) != 0 14191 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) 14192 { 14193 if (INDIRECT_REF_P (decl) 14194 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 14195 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 14196 == REFERENCE_TYPE)) 14197 decl = TREE_OPERAND (decl, 0); 14198 if (TREE_CODE (decl) == COMPONENT_REF) 14199 { 14200 while (TREE_CODE (decl) == COMPONENT_REF) 14201 decl = TREE_OPERAND (decl, 0); 14202 if (DECL_P (decl)) 14203 { 14204 n = splay_tree_lookup (ctx->variables, 14205 (splay_tree_key) decl); 14206 if (!(n->value & GOVD_SEEN)) 14207 remove = true; 14208 } 14209 } 14210 } 14211 14212 tree d = decl, *pd; 14213 if (TREE_CODE (d) == ARRAY_REF) 14214 { 14215 while (TREE_CODE (d) == ARRAY_REF) 14216 d = TREE_OPERAND (d, 0); 14217 if (TREE_CODE (d) == COMPONENT_REF 14218 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE) 14219 decl = d; 14220 } 14221 pd = &OMP_CLAUSE_DECL (c); 14222 if (d == decl 14223 && TREE_CODE (decl) == INDIRECT_REF 14224 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF 14225 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0))) 14226 == REFERENCE_TYPE) 14227 && (OMP_CLAUSE_MAP_KIND (c) 14228 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)) 14229 { 14230 pd = &TREE_OPERAND (decl, 0); 14231 decl = TREE_OPERAND (decl, 0); 14232 } 14233 14234 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14235 switch (code) 14236 { 14237 case OACC_ENTER_DATA: 14238 case OACC_EXIT_DATA: 14239 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 14240 == ARRAY_TYPE) 14241 remove = true; 14242 else if (code == OACC_ENTER_DATA) 14243 goto change_to_attach; 14244 /* Fallthrough. */ 14245 case OMP_TARGET_EXIT_DATA: 14246 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH); 14247 break; 14248 case OACC_UPDATE: 14249 /* An "attach/detach" operation on an update directive 14250 should behave as a GOMP_MAP_ALWAYS_POINTER. Note that 14251 both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER 14252 kinds depend on the previous mapping (for non-TARGET 14253 regions). */ 14254 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER); 14255 break; 14256 default: 14257 change_to_attach: 14258 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH); 14259 if ((ctx->region_type & ORT_TARGET) != 0) 14260 move_attach = true; 14261 } 14262 else if ((ctx->region_type & ORT_TARGET) != 0 14263 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 14264 || (OMP_CLAUSE_MAP_KIND (c) 14265 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))) 14266 move_attach = true; 14267 14268 /* If we have e.g. map(struct: *var), don't gimplify the 14269 argument since omp-low.cc wants to see the decl itself. */ 14270 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT) 14271 break; 14272 14273 /* We've already partly gimplified this in 14274 gimplify_scan_omp_clauses. Don't do any more. */ 14275 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c)) 14276 break; 14277 14278 gimplify_omp_ctxp = ctx->outer_context; 14279 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, 14280 fb_lvalue) == GS_ERROR) 14281 remove = true; 14282 gimplify_omp_ctxp = ctx; 14283 break; 14284 } 14285 14286 if ((code == OMP_TARGET 14287 || code == OMP_TARGET_DATA 14288 || code == OMP_TARGET_ENTER_DATA 14289 || code == OMP_TARGET_EXIT_DATA) 14290 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14291 { 14292 bool firstprivatize = false; 14293 14294 for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx; 14295 octx = octx->outer_context) 14296 { 14297 splay_tree_node n 14298 = splay_tree_lookup (octx->variables, 14299 (splay_tree_key) OMP_CLAUSE_DECL (c)); 14300 /* If this is contained in an outer OpenMP region as a 14301 firstprivate value, remove the attach/detach. */ 14302 if (n && (n->value & GOVD_FIRSTPRIVATE)) 14303 { 14304 firstprivatize = true; 14305 break; 14306 } 14307 } 14308 14309 enum gomp_map_kind map_kind; 14310 if (firstprivatize) 14311 map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER; 14312 else if (code == OMP_TARGET_EXIT_DATA) 14313 map_kind = GOMP_MAP_DETACH; 14314 else 14315 map_kind = GOMP_MAP_ATTACH; 14316 OMP_CLAUSE_SET_MAP_KIND (c, map_kind); 14317 } 14318 else if ((ctx->region_type & ORT_ACC) != 0 14319 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH) 14320 { 14321 enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA 14322 ? GOMP_MAP_DETACH 14323 : GOMP_MAP_ATTACH); 14324 OMP_CLAUSE_SET_MAP_KIND (c, map_kind); 14325 } 14326 14327 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14328 if ((ctx->region_type & ORT_TARGET) != 0 14329 && !(n->value & GOVD_SEEN) 14330 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0 14331 && (!is_global_var (decl) 14332 || !lookup_attribute ("omp declare target link", 14333 DECL_ATTRIBUTES (decl)))) 14334 { 14335 remove = true; 14336 /* For struct element mapping, if struct is never referenced 14337 in target block and none of the mapping has always modifier, 14338 remove all the struct element mappings, which immediately 14339 follow the GOMP_MAP_STRUCT map clause. */ 14340 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT 14341 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD) 14342 { 14343 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c)); 14344 while (cnt--) 14345 OMP_CLAUSE_CHAIN (c) 14346 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c)); 14347 } 14348 } 14349 else if (DECL_SIZE (decl) 14350 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST 14351 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER 14352 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER 14353 && (OMP_CLAUSE_MAP_KIND (c) 14354 != GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 14355 { 14356 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because 14357 for these, TREE_CODE (DECL_SIZE (decl)) will always be 14358 INTEGER_CST. */ 14359 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR); 14360 14361 tree decl2 = DECL_VALUE_EXPR (decl); 14362 gcc_assert (INDIRECT_REF_P (decl2)); 14363 decl2 = TREE_OPERAND (decl2, 0); 14364 gcc_assert (DECL_P (decl2)); 14365 tree mem = build_simple_mem_ref (decl2); 14366 OMP_CLAUSE_DECL (c) = mem; 14367 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14368 if (ctx->outer_context) 14369 { 14370 omp_notice_variable (ctx->outer_context, decl2, true); 14371 omp_notice_variable (ctx->outer_context, 14372 OMP_CLAUSE_SIZE (c), true); 14373 } 14374 if (((ctx->region_type & ORT_TARGET) != 0 14375 || !ctx->target_firstprivatize_array_bases) 14376 && ((n->value & GOVD_SEEN) == 0 14377 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0)) 14378 { 14379 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 14380 OMP_CLAUSE_MAP); 14381 OMP_CLAUSE_DECL (nc) = decl; 14382 OMP_CLAUSE_SIZE (nc) = size_zero_node; 14383 if (ctx->target_firstprivatize_array_bases) 14384 OMP_CLAUSE_SET_MAP_KIND (nc, 14385 GOMP_MAP_FIRSTPRIVATE_POINTER); 14386 else 14387 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER); 14388 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c); 14389 OMP_CLAUSE_CHAIN (c) = nc; 14390 c = nc; 14391 } 14392 } 14393 else 14394 { 14395 if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14396 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); 14397 gcc_assert ((n->value & GOVD_SEEN) == 0 14398 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) 14399 == 0)); 14400 } 14401 14402 /* If we have a target region, we can push all the attaches to the 14403 end of the list (we may have standalone "attach" operations 14404 synthesized for GOMP_MAP_STRUCT nodes that must be processed after 14405 the attachment point AND the pointed-to block have been mapped). 14406 If we have something else, e.g. "enter data", we need to keep 14407 "attach" nodes together with the previous node they attach to so 14408 that separate "exit data" operations work properly (see 14409 libgomp/target.c). */ 14410 if ((ctx->region_type & ORT_TARGET) != 0 14411 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH 14412 || (OMP_CLAUSE_MAP_KIND (c) 14413 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))) 14414 move_attach = true; 14415 14416 break; 14417 14418 case OMP_CLAUSE_TO: 14419 case OMP_CLAUSE_FROM: 14420 case OMP_CLAUSE__CACHE_: 14421 decl = OMP_CLAUSE_DECL (c); 14422 if (!DECL_P (decl)) 14423 break; 14424 if (DECL_SIZE (decl) 14425 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) 14426 { 14427 tree decl2 = DECL_VALUE_EXPR (decl); 14428 gcc_assert (INDIRECT_REF_P (decl2)); 14429 decl2 = TREE_OPERAND (decl2, 0); 14430 gcc_assert (DECL_P (decl2)); 14431 tree mem = build_simple_mem_ref (decl2); 14432 OMP_CLAUSE_DECL (c) = mem; 14433 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl)); 14434 if (ctx->outer_context) 14435 { 14436 omp_notice_variable (ctx->outer_context, decl2, true); 14437 omp_notice_variable (ctx->outer_context, 14438 OMP_CLAUSE_SIZE (c), true); 14439 } 14440 } 14441 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE) 14442 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); 14443 break; 14444 14445 case OMP_CLAUSE_REDUCTION: 14446 if (OMP_CLAUSE_REDUCTION_INSCAN (c)) 14447 { 14448 decl = OMP_CLAUSE_DECL (c); 14449 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14450 if ((n->value & GOVD_REDUCTION_INSCAN) == 0) 14451 { 14452 remove = true; 14453 error_at (OMP_CLAUSE_LOCATION (c), 14454 "%qD specified in %<inscan%> %<reduction%> clause " 14455 "but not in %<scan%> directive clause", decl); 14456 break; 14457 } 14458 has_inscan_reductions = true; 14459 } 14460 /* FALLTHRU */ 14461 case OMP_CLAUSE_IN_REDUCTION: 14462 case OMP_CLAUSE_TASK_REDUCTION: 14463 decl = OMP_CLAUSE_DECL (c); 14464 /* OpenACC reductions need a present_or_copy data clause. 14465 Add one if necessary. Emit error when the reduction is private. */ 14466 if (ctx->region_type == ORT_ACC_PARALLEL 14467 || ctx->region_type == ORT_ACC_SERIAL) 14468 { 14469 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14470 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) 14471 { 14472 remove = true; 14473 error_at (OMP_CLAUSE_LOCATION (c), "invalid private " 14474 "reduction on %qE", DECL_NAME (decl)); 14475 } 14476 else if ((n->value & GOVD_MAP) == 0) 14477 { 14478 tree next = OMP_CLAUSE_CHAIN (c); 14479 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP); 14480 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM); 14481 OMP_CLAUSE_DECL (nc) = decl; 14482 OMP_CLAUSE_CHAIN (c) = nc; 14483 lang_hooks.decls.omp_finish_clause (nc, pre_p, 14484 (ctx->region_type 14485 & ORT_ACC) != 0); 14486 while (1) 14487 { 14488 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1; 14489 if (OMP_CLAUSE_CHAIN (nc) == NULL) 14490 break; 14491 nc = OMP_CLAUSE_CHAIN (nc); 14492 } 14493 OMP_CLAUSE_CHAIN (nc) = next; 14494 n->value |= GOVD_MAP; 14495 } 14496 } 14497 if (DECL_P (decl) 14498 && omp_shared_to_firstprivate_optimizable_decl_p (decl)) 14499 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); 14500 break; 14501 14502 case OMP_CLAUSE_ALLOCATE: 14503 decl = OMP_CLAUSE_DECL (c); 14504 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); 14505 if (n != NULL && !(n->value & GOVD_SEEN)) 14506 { 14507 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR)) 14508 != 0 14509 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0) 14510 remove = true; 14511 } 14512 if (!remove 14513 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 14514 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST 14515 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0 14516 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK 14517 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)) 14518 { 14519 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); 14520 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator); 14521 if (n == NULL) 14522 { 14523 enum omp_clause_default_kind default_kind 14524 = ctx->default_kind; 14525 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 14526 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 14527 true); 14528 ctx->default_kind = default_kind; 14529 } 14530 else 14531 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), 14532 true); 14533 } 14534 break; 14535 14536 case OMP_CLAUSE_COPYIN: 14537 case OMP_CLAUSE_COPYPRIVATE: 14538 case OMP_CLAUSE_IF: 14539 case OMP_CLAUSE_SELF: 14540 case OMP_CLAUSE_NUM_THREADS: 14541 case OMP_CLAUSE_NUM_TEAMS: 14542 case OMP_CLAUSE_THREAD_LIMIT: 14543 case OMP_CLAUSE_DIST_SCHEDULE: 14544 case OMP_CLAUSE_DEVICE: 14545 case OMP_CLAUSE_SCHEDULE: 14546 case OMP_CLAUSE_NOWAIT: 14547 case OMP_CLAUSE_ORDERED: 14548 case OMP_CLAUSE_DEFAULT: 14549 case OMP_CLAUSE_UNTIED: 14550 case OMP_CLAUSE_COLLAPSE: 14551 case OMP_CLAUSE_FINAL: 14552 case OMP_CLAUSE_MERGEABLE: 14553 case OMP_CLAUSE_PROC_BIND: 14554 case OMP_CLAUSE_SAFELEN: 14555 case OMP_CLAUSE_SIMDLEN: 14556 case OMP_CLAUSE_DEPEND: 14557 case OMP_CLAUSE_DOACROSS: 14558 case OMP_CLAUSE_PRIORITY: 14559 case OMP_CLAUSE_GRAINSIZE: 14560 case OMP_CLAUSE_NUM_TASKS: 14561 case OMP_CLAUSE_NOGROUP: 14562 case OMP_CLAUSE_THREADS: 14563 case OMP_CLAUSE_SIMD: 14564 case OMP_CLAUSE_FILTER: 14565 case OMP_CLAUSE_HINT: 14566 case OMP_CLAUSE_DEFAULTMAP: 14567 case OMP_CLAUSE_ORDER: 14568 case OMP_CLAUSE_BIND: 14569 case OMP_CLAUSE_DETACH: 14570 case OMP_CLAUSE_USE_DEVICE_PTR: 14571 case OMP_CLAUSE_USE_DEVICE_ADDR: 14572 case OMP_CLAUSE_ASYNC: 14573 case OMP_CLAUSE_WAIT: 14574 case OMP_CLAUSE_INDEPENDENT: 14575 case OMP_CLAUSE_NUM_GANGS: 14576 case OMP_CLAUSE_NUM_WORKERS: 14577 case OMP_CLAUSE_VECTOR_LENGTH: 14578 case OMP_CLAUSE_GANG: 14579 case OMP_CLAUSE_WORKER: 14580 case OMP_CLAUSE_VECTOR: 14581 case OMP_CLAUSE_AUTO: 14582 case OMP_CLAUSE_SEQ: 14583 case OMP_CLAUSE_TILE: 14584 case OMP_CLAUSE_IF_PRESENT: 14585 case OMP_CLAUSE_FINALIZE: 14586 case OMP_CLAUSE_INCLUSIVE: 14587 case OMP_CLAUSE_EXCLUSIVE: 14588 break; 14589 14590 case OMP_CLAUSE_NOHOST: 14591 default: 14592 gcc_unreachable (); 14593 } 14594 14595 if (remove) 14596 *list_p = OMP_CLAUSE_CHAIN (c); 14597 else if (move_attach) 14598 { 14599 /* Remove attach node from here, separate out into its own list. */ 14600 *attach_tail = c; 14601 *list_p = OMP_CLAUSE_CHAIN (c); 14602 OMP_CLAUSE_CHAIN (c) = NULL_TREE; 14603 attach_tail = &OMP_CLAUSE_CHAIN (c); 14604 } 14605 else 14606 list_p = &OMP_CLAUSE_CHAIN (c); 14607 } 14608 14609 /* Splice attach nodes at the end of the list. */ 14610 if (attach_list) 14611 { 14612 *list_p = attach_list; 14613 list_p = attach_tail; 14614 } 14615 14616 /* Add in any implicit data sharing. */ 14617 struct gimplify_adjust_omp_clauses_data data; 14618 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0) 14619 { 14620 /* OpenMP. Implicit clauses are added at the start of the clause list, 14621 but after any non-map clauses. */ 14622 tree *implicit_add_list_p = orig_list_p; 14623 while (*implicit_add_list_p 14624 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP) 14625 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p); 14626 data.list_p = implicit_add_list_p; 14627 } 14628 else 14629 /* OpenACC. */ 14630 data.list_p = list_p; 14631 data.pre_p = pre_p; 14632 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data); 14633 14634 if (has_inscan_reductions) 14635 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c)) 14636 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 14637 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c)) 14638 { 14639 error_at (OMP_CLAUSE_LOCATION (c), 14640 "%<inscan%> %<reduction%> clause used together with " 14641 "%<linear%> clause for a variable other than loop " 14642 "iterator"); 14643 break; 14644 } 14645 14646 gimplify_omp_ctxp = ctx->outer_context; 14647 delete_omp_context (ctx); 14648 } 14649 14650 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context, 14651 -1 if unknown yet (simd is involved, won't be known until vectorization) 14652 and 1 if they do. If SCORES is non-NULL, it should point to an array 14653 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions 14654 of the CONSTRUCTS (position -1 if it will never match) followed by 14655 number of constructs in the OpenMP context construct trait. If the 14656 score depends on whether it will be in a declare simd clone or not, 14657 the function returns 2 and there will be two sets of the scores, the first 14658 one for the case that it is not in a declare simd clone, the other 14659 that it is in a declare simd clone. */ 14660 14661 int 14662 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs, 14663 int *scores) 14664 { 14665 int matched = 0, cnt = 0; 14666 bool simd_seen = false; 14667 bool target_seen = false; 14668 int declare_simd_cnt = -1; 14669 auto_vec<enum tree_code, 16> codes; 14670 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;) 14671 { 14672 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL) 14673 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC)) 14674 == ORT_TARGET && ctx->code == OMP_TARGET) 14675 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS) 14676 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR) 14677 || (ctx->region_type == ORT_SIMD 14678 && ctx->code == OMP_SIMD 14679 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND))) 14680 { 14681 ++cnt; 14682 if (scores) 14683 codes.safe_push (ctx->code); 14684 else if (matched < nconstructs && ctx->code == constructs[matched]) 14685 { 14686 if (ctx->code == OMP_SIMD) 14687 { 14688 if (matched) 14689 return 0; 14690 simd_seen = true; 14691 } 14692 ++matched; 14693 } 14694 if (ctx->code == OMP_TARGET) 14695 { 14696 if (scores == NULL) 14697 return matched < nconstructs ? 0 : simd_seen ? -1 : 1; 14698 target_seen = true; 14699 break; 14700 } 14701 } 14702 else if (ctx->region_type == ORT_WORKSHARE 14703 && ctx->code == OMP_LOOP 14704 && ctx->outer_context 14705 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL 14706 && ctx->outer_context->outer_context 14707 && ctx->outer_context->outer_context->code == OMP_LOOP 14708 && ctx->outer_context->outer_context->distribute) 14709 ctx = ctx->outer_context->outer_context; 14710 ctx = ctx->outer_context; 14711 } 14712 if (!target_seen 14713 && lookup_attribute ("omp declare simd", 14714 DECL_ATTRIBUTES (current_function_decl))) 14715 { 14716 /* Declare simd is a maybe case, it is supposed to be added only to the 14717 omp-simd-clone.cc added clones and not to the base function. */ 14718 declare_simd_cnt = cnt++; 14719 if (scores) 14720 codes.safe_push (OMP_SIMD); 14721 else if (cnt == 0 14722 && constructs[0] == OMP_SIMD) 14723 { 14724 gcc_assert (matched == 0); 14725 simd_seen = true; 14726 if (++matched == nconstructs) 14727 return -1; 14728 } 14729 } 14730 if (tree attr = lookup_attribute ("omp declare variant variant", 14731 DECL_ATTRIBUTES (current_function_decl))) 14732 { 14733 tree selectors = TREE_VALUE (attr); 14734 int variant_nconstructs = list_length (selectors); 14735 enum tree_code *variant_constructs = NULL; 14736 if (!target_seen && variant_nconstructs) 14737 { 14738 variant_constructs 14739 = (enum tree_code *) alloca (variant_nconstructs 14740 * sizeof (enum tree_code)); 14741 omp_construct_traits_to_codes (selectors, variant_nconstructs, 14742 variant_constructs); 14743 } 14744 for (int i = 0; i < variant_nconstructs; i++) 14745 { 14746 ++cnt; 14747 if (scores) 14748 codes.safe_push (variant_constructs[i]); 14749 else if (matched < nconstructs 14750 && variant_constructs[i] == constructs[matched]) 14751 { 14752 if (variant_constructs[i] == OMP_SIMD) 14753 { 14754 if (matched) 14755 return 0; 14756 simd_seen = true; 14757 } 14758 ++matched; 14759 } 14760 } 14761 } 14762 if (!target_seen 14763 && lookup_attribute ("omp declare target block", 14764 DECL_ATTRIBUTES (current_function_decl))) 14765 { 14766 if (scores) 14767 codes.safe_push (OMP_TARGET); 14768 else if (matched < nconstructs && constructs[matched] == OMP_TARGET) 14769 ++matched; 14770 } 14771 if (scores) 14772 { 14773 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++) 14774 { 14775 int j = codes.length () - 1; 14776 for (int i = nconstructs - 1; i >= 0; i--) 14777 { 14778 while (j >= 0 14779 && (pass != 0 || declare_simd_cnt != j) 14780 && constructs[i] != codes[j]) 14781 --j; 14782 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt) 14783 *scores++ = j - 1; 14784 else 14785 *scores++ = j; 14786 } 14787 *scores++ = ((pass == 0 && declare_simd_cnt != -1) 14788 ? codes.length () - 1 : codes.length ()); 14789 } 14790 return declare_simd_cnt == -1 ? 1 : 2; 14791 } 14792 if (matched == nconstructs) 14793 return simd_seen ? -1 : 1; 14794 return 0; 14795 } 14796 14797 /* Gimplify OACC_CACHE. */ 14798 14799 static void 14800 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p) 14801 { 14802 tree expr = *expr_p; 14803 14804 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC, 14805 OACC_CACHE); 14806 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr), 14807 OACC_CACHE); 14808 14809 /* TODO: Do something sensible with this information. */ 14810 14811 *expr_p = NULL_TREE; 14812 } 14813 14814 /* Helper function of gimplify_oacc_declare. The helper's purpose is to, 14815 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit' 14816 kind. The entry kind will replace the one in CLAUSE, while the exit 14817 kind will be used in a new omp_clause and returned to the caller. */ 14818 14819 static tree 14820 gimplify_oacc_declare_1 (tree clause) 14821 { 14822 HOST_WIDE_INT kind, new_op; 14823 bool ret = false; 14824 tree c = NULL; 14825 14826 kind = OMP_CLAUSE_MAP_KIND (clause); 14827 14828 switch (kind) 14829 { 14830 case GOMP_MAP_ALLOC: 14831 new_op = GOMP_MAP_RELEASE; 14832 ret = true; 14833 break; 14834 14835 case GOMP_MAP_FROM: 14836 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC); 14837 new_op = GOMP_MAP_FROM; 14838 ret = true; 14839 break; 14840 14841 case GOMP_MAP_TOFROM: 14842 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO); 14843 new_op = GOMP_MAP_FROM; 14844 ret = true; 14845 break; 14846 14847 case GOMP_MAP_DEVICE_RESIDENT: 14848 case GOMP_MAP_FORCE_DEVICEPTR: 14849 case GOMP_MAP_FORCE_PRESENT: 14850 case GOMP_MAP_LINK: 14851 case GOMP_MAP_POINTER: 14852 case GOMP_MAP_TO: 14853 break; 14854 14855 default: 14856 gcc_unreachable (); 14857 break; 14858 } 14859 14860 if (ret) 14861 { 14862 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP); 14863 OMP_CLAUSE_SET_MAP_KIND (c, new_op); 14864 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause); 14865 } 14866 14867 return c; 14868 } 14869 14870 /* Gimplify OACC_DECLARE. */ 14871 14872 static void 14873 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p) 14874 { 14875 tree expr = *expr_p; 14876 gomp_target *stmt; 14877 tree clauses, t, decl; 14878 14879 clauses = OACC_DECLARE_CLAUSES (expr); 14880 14881 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE); 14882 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE); 14883 14884 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t)) 14885 { 14886 decl = OMP_CLAUSE_DECL (t); 14887 14888 if (TREE_CODE (decl) == MEM_REF) 14889 decl = TREE_OPERAND (decl, 0); 14890 14891 if (VAR_P (decl) && !is_oacc_declared (decl)) 14892 { 14893 tree attr = get_identifier ("oacc declare target"); 14894 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE, 14895 DECL_ATTRIBUTES (decl)); 14896 } 14897 14898 if (VAR_P (decl) 14899 && !is_global_var (decl) 14900 && DECL_CONTEXT (decl) == current_function_decl) 14901 { 14902 tree c = gimplify_oacc_declare_1 (t); 14903 if (c) 14904 { 14905 if (oacc_declare_returns == NULL) 14906 oacc_declare_returns = new hash_map<tree, tree>; 14907 14908 oacc_declare_returns->put (decl, c); 14909 } 14910 } 14911 14912 if (gimplify_omp_ctxp) 14913 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN); 14914 } 14915 14916 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE, 14917 clauses); 14918 14919 gimplify_seq_add_stmt (pre_p, stmt); 14920 14921 *expr_p = NULL_TREE; 14922 } 14923 14924 /* Gimplify the contents of an OMP_PARALLEL statement. This involves 14925 gimplification of the body, as well as scanning the body for used 14926 variables. We need to do this scan now, because variable-sized 14927 decls will be decomposed during gimplification. */ 14928 14929 static void 14930 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p) 14931 { 14932 tree expr = *expr_p; 14933 gimple *g; 14934 gimple_seq body = NULL; 14935 14936 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, 14937 OMP_PARALLEL_COMBINED (expr) 14938 ? ORT_COMBINED_PARALLEL 14939 : ORT_PARALLEL, OMP_PARALLEL); 14940 14941 push_gimplify_context (); 14942 14943 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body); 14944 if (gimple_code (g) == GIMPLE_BIND) 14945 pop_gimplify_context (g); 14946 else 14947 pop_gimplify_context (NULL); 14948 14949 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr), 14950 OMP_PARALLEL); 14951 14952 g = gimple_build_omp_parallel (body, 14953 OMP_PARALLEL_CLAUSES (expr), 14954 NULL_TREE, NULL_TREE); 14955 if (OMP_PARALLEL_COMBINED (expr)) 14956 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED); 14957 gimplify_seq_add_stmt (pre_p, g); 14958 *expr_p = NULL_TREE; 14959 } 14960 14961 /* Gimplify the contents of an OMP_TASK statement. This involves 14962 gimplification of the body, as well as scanning the body for used 14963 variables. We need to do this scan now, because variable-sized 14964 decls will be decomposed during gimplification. */ 14965 14966 static void 14967 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p) 14968 { 14969 tree expr = *expr_p; 14970 gimple *g; 14971 gimple_seq body = NULL; 14972 bool nowait = false; 14973 bool has_depend = false; 14974 14975 if (OMP_TASK_BODY (expr) == NULL_TREE) 14976 { 14977 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 14978 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) 14979 { 14980 has_depend = true; 14981 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET) 14982 { 14983 error_at (OMP_CLAUSE_LOCATION (c), 14984 "%<mutexinoutset%> kind in %<depend%> clause on a " 14985 "%<taskwait%> construct"); 14986 break; 14987 } 14988 } 14989 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT) 14990 nowait = true; 14991 if (nowait && !has_depend) 14992 { 14993 error_at (EXPR_LOCATION (expr), 14994 "%<taskwait%> construct with %<nowait%> clause but no " 14995 "%<depend%> clauses"); 14996 *expr_p = NULL_TREE; 14997 return; 14998 } 14999 } 15000 15001 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, 15002 omp_find_clause (OMP_TASK_CLAUSES (expr), 15003 OMP_CLAUSE_UNTIED) 15004 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK); 15005 15006 if (OMP_TASK_BODY (expr)) 15007 { 15008 push_gimplify_context (); 15009 15010 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body); 15011 if (gimple_code (g) == GIMPLE_BIND) 15012 pop_gimplify_context (g); 15013 else 15014 pop_gimplify_context (NULL); 15015 } 15016 15017 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr), 15018 OMP_TASK); 15019 15020 g = gimple_build_omp_task (body, 15021 OMP_TASK_CLAUSES (expr), 15022 NULL_TREE, NULL_TREE, 15023 NULL_TREE, NULL_TREE, NULL_TREE); 15024 if (OMP_TASK_BODY (expr) == NULL_TREE) 15025 gimple_omp_task_set_taskwait_p (g, true); 15026 gimplify_seq_add_stmt (pre_p, g); 15027 *expr_p = NULL_TREE; 15028 } 15029 15030 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant, 15031 force it into a temporary initialized in PRE_P and add firstprivate clause 15032 to ORIG_FOR_STMT. */ 15033 15034 static void 15035 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p, 15036 tree orig_for_stmt) 15037 { 15038 if (*tp == NULL || is_gimple_constant (*tp)) 15039 return; 15040 15041 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false); 15042 /* Reference to pointer conversion is considered useless, 15043 but is significant for firstprivate clause. Force it 15044 here. */ 15045 if (type 15046 && TREE_CODE (type) == POINTER_TYPE 15047 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE) 15048 { 15049 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type)); 15050 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp); 15051 gimplify_and_add (m, pre_p); 15052 *tp = v; 15053 } 15054 15055 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); 15056 OMP_CLAUSE_DECL (c) = *tp; 15057 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt); 15058 OMP_FOR_CLAUSES (orig_for_stmt) = c; 15059 } 15060 15061 /* Helper function of gimplify_omp_for, find OMP_ORDERED with 15062 null OMP_ORDERED_BODY inside of OMP_FOR's body. */ 15063 15064 static tree 15065 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *) 15066 { 15067 switch (TREE_CODE (*tp)) 15068 { 15069 case OMP_ORDERED: 15070 if (OMP_ORDERED_BODY (*tp) == NULL_TREE) 15071 return *tp; 15072 break; 15073 case OMP_SIMD: 15074 case OMP_PARALLEL: 15075 case OMP_TARGET: 15076 *walk_subtrees = 0; 15077 break; 15078 default: 15079 break; 15080 } 15081 return NULL_TREE; 15082 } 15083 15084 /* Gimplify the gross structure of an OMP_FOR statement. */ 15085 15086 static enum gimplify_status 15087 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) 15088 { 15089 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t; 15090 enum gimplify_status ret = GS_ALL_DONE; 15091 enum gimplify_status tret; 15092 gomp_for *gfor; 15093 gimple_seq for_body, for_pre_body; 15094 int i; 15095 bitmap has_decl_expr = NULL; 15096 enum omp_region_type ort = ORT_WORKSHARE; 15097 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP; 15098 15099 orig_for_stmt = for_stmt = *expr_p; 15100 15101 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND) 15102 != NULL_TREE); 15103 if (OMP_FOR_INIT (for_stmt) == NULL_TREE) 15104 { 15105 tree *data[4] = { NULL, NULL, NULL, NULL }; 15106 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP); 15107 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt), 15108 find_combined_omp_for, data, NULL); 15109 if (inner_for_stmt == NULL_TREE) 15110 { 15111 gcc_assert (seen_error ()); 15112 *expr_p = NULL_TREE; 15113 return GS_ERROR; 15114 } 15115 if (data[2] && OMP_FOR_PRE_BODY (*data[2])) 15116 { 15117 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]), 15118 &OMP_FOR_PRE_BODY (for_stmt)); 15119 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE; 15120 } 15121 if (OMP_FOR_PRE_BODY (inner_for_stmt)) 15122 { 15123 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt), 15124 &OMP_FOR_PRE_BODY (for_stmt)); 15125 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE; 15126 } 15127 15128 if (data[0]) 15129 { 15130 /* We have some statements or variable declarations in between 15131 the composite construct directives. Move them around the 15132 inner_for_stmt. */ 15133 data[0] = expr_p; 15134 for (i = 0; i < 3; i++) 15135 if (data[i]) 15136 { 15137 tree t = *data[i]; 15138 if (i < 2 && data[i + 1] == &OMP_BODY (t)) 15139 data[i + 1] = data[i]; 15140 *data[i] = OMP_BODY (t); 15141 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE, 15142 NULL_TREE, make_node (BLOCK)); 15143 OMP_BODY (t) = body; 15144 append_to_statement_list_force (inner_for_stmt, 15145 &BIND_EXPR_BODY (body)); 15146 *data[3] = t; 15147 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body))); 15148 gcc_assert (*data[3] == inner_for_stmt); 15149 } 15150 return GS_OK; 15151 } 15152 15153 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++) 15154 if (!loop_p 15155 && OMP_FOR_ORIG_DECLS (inner_for_stmt) 15156 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15157 i)) == TREE_LIST 15158 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15159 i))) 15160 { 15161 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i); 15162 /* Class iterators aren't allowed on OMP_SIMD, so the only 15163 case we need to solve is distribute parallel for. They are 15164 allowed on the loop construct, but that is already handled 15165 in gimplify_omp_loop. */ 15166 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR 15167 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE 15168 && data[1]); 15169 tree orig_decl = TREE_PURPOSE (orig); 15170 tree last = TREE_VALUE (orig); 15171 tree *pc; 15172 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt); 15173 *pc; pc = &OMP_CLAUSE_CHAIN (*pc)) 15174 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE 15175 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE) 15176 && OMP_CLAUSE_DECL (*pc) == orig_decl) 15177 break; 15178 if (*pc == NULL_TREE) 15179 { 15180 tree *spc; 15181 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]); 15182 *spc; spc = &OMP_CLAUSE_CHAIN (*spc)) 15183 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE 15184 && OMP_CLAUSE_DECL (*spc) == orig_decl) 15185 break; 15186 if (*spc) 15187 { 15188 tree c = *spc; 15189 *spc = OMP_CLAUSE_CHAIN (c); 15190 OMP_CLAUSE_CHAIN (c) = NULL_TREE; 15191 *pc = c; 15192 } 15193 } 15194 if (*pc == NULL_TREE) 15195 ; 15196 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE) 15197 { 15198 /* private clause will appear only on inner_for_stmt. 15199 Change it into firstprivate, and add private clause 15200 on for_stmt. */ 15201 tree c = copy_node (*pc); 15202 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15203 OMP_FOR_CLAUSES (for_stmt) = c; 15204 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE; 15205 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc); 15206 } 15207 else 15208 { 15209 /* lastprivate clause will appear on both inner_for_stmt 15210 and for_stmt. Add firstprivate clause to 15211 inner_for_stmt. */ 15212 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc), 15213 OMP_CLAUSE_FIRSTPRIVATE); 15214 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc); 15215 OMP_CLAUSE_CHAIN (c) = *pc; 15216 *pc = c; 15217 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc); 15218 } 15219 tree c = build_omp_clause (UNKNOWN_LOCATION, 15220 OMP_CLAUSE_FIRSTPRIVATE); 15221 OMP_CLAUSE_DECL (c) = last; 15222 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15223 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15224 c = build_omp_clause (UNKNOWN_LOCATION, 15225 *pc ? OMP_CLAUSE_SHARED 15226 : OMP_CLAUSE_FIRSTPRIVATE); 15227 OMP_CLAUSE_DECL (c) = orig_decl; 15228 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15229 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15230 } 15231 /* Similarly, take care of C++ range for temporaries, those should 15232 be firstprivate on OMP_PARALLEL if any. */ 15233 if (data[1]) 15234 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++) 15235 if (OMP_FOR_ORIG_DECLS (inner_for_stmt) 15236 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15237 i)) == TREE_LIST 15238 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), 15239 i))) 15240 { 15241 tree orig 15242 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i); 15243 tree v = TREE_CHAIN (orig); 15244 tree c = build_omp_clause (UNKNOWN_LOCATION, 15245 OMP_CLAUSE_FIRSTPRIVATE); 15246 /* First add firstprivate clause for the __for_end artificial 15247 decl. */ 15248 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1); 15249 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 15250 == REFERENCE_TYPE) 15251 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1; 15252 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15253 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15254 if (TREE_VEC_ELT (v, 0)) 15255 { 15256 /* And now the same for __for_range artificial decl if it 15257 exists. */ 15258 c = build_omp_clause (UNKNOWN_LOCATION, 15259 OMP_CLAUSE_FIRSTPRIVATE); 15260 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0); 15261 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) 15262 == REFERENCE_TYPE) 15263 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1; 15264 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]); 15265 OMP_PARALLEL_CLAUSES (*data[1]) = c; 15266 } 15267 } 15268 } 15269 15270 switch (TREE_CODE (for_stmt)) 15271 { 15272 case OMP_FOR: 15273 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)) 15274 { 15275 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15276 OMP_CLAUSE_SCHEDULE)) 15277 error_at (EXPR_LOCATION (for_stmt), 15278 "%qs clause may not appear on non-rectangular %qs", 15279 "schedule", lang_GNU_Fortran () ? "do" : "for"); 15280 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED)) 15281 error_at (EXPR_LOCATION (for_stmt), 15282 "%qs clause may not appear on non-rectangular %qs", 15283 "ordered", lang_GNU_Fortran () ? "do" : "for"); 15284 } 15285 break; 15286 case OMP_DISTRIBUTE: 15287 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt) 15288 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15289 OMP_CLAUSE_DIST_SCHEDULE)) 15290 error_at (EXPR_LOCATION (for_stmt), 15291 "%qs clause may not appear on non-rectangular %qs", 15292 "dist_schedule", "distribute"); 15293 break; 15294 case OACC_LOOP: 15295 ort = ORT_ACC; 15296 break; 15297 case OMP_TASKLOOP: 15298 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)) 15299 { 15300 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15301 OMP_CLAUSE_GRAINSIZE)) 15302 error_at (EXPR_LOCATION (for_stmt), 15303 "%qs clause may not appear on non-rectangular %qs", 15304 "grainsize", "taskloop"); 15305 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15306 OMP_CLAUSE_NUM_TASKS)) 15307 error_at (EXPR_LOCATION (for_stmt), 15308 "%qs clause may not appear on non-rectangular %qs", 15309 "num_tasks", "taskloop"); 15310 } 15311 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED)) 15312 ort = ORT_UNTIED_TASKLOOP; 15313 else 15314 ort = ORT_TASKLOOP; 15315 break; 15316 case OMP_SIMD: 15317 ort = ORT_SIMD; 15318 break; 15319 default: 15320 gcc_unreachable (); 15321 } 15322 15323 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear 15324 clause for the IV. */ 15325 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1) 15326 { 15327 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0); 15328 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15329 decl = TREE_OPERAND (t, 0); 15330 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c)) 15331 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 15332 && OMP_CLAUSE_DECL (c) == decl) 15333 { 15334 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1; 15335 break; 15336 } 15337 } 15338 15339 if (TREE_CODE (for_stmt) != OMP_TASKLOOP) 15340 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort, 15341 loop_p && TREE_CODE (for_stmt) != OMP_SIMD 15342 ? OMP_LOOP : TREE_CODE (for_stmt)); 15343 15344 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE) 15345 gimplify_omp_ctxp->distribute = true; 15346 15347 /* Handle OMP_FOR_INIT. */ 15348 for_pre_body = NULL; 15349 if ((ort == ORT_SIMD 15350 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD)) 15351 && OMP_FOR_PRE_BODY (for_stmt)) 15352 { 15353 has_decl_expr = BITMAP_ALLOC (NULL); 15354 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR 15355 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))) 15356 { 15357 t = OMP_FOR_PRE_BODY (for_stmt); 15358 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t))); 15359 } 15360 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST) 15361 { 15362 tree_stmt_iterator si; 15363 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si); 15364 tsi_next (&si)) 15365 { 15366 t = tsi_stmt (si); 15367 if (TREE_CODE (t) == DECL_EXPR 15368 && VAR_P (DECL_EXPR_DECL (t))) 15369 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t))); 15370 } 15371 } 15372 } 15373 if (OMP_FOR_PRE_BODY (for_stmt)) 15374 { 15375 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp) 15376 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body); 15377 else 15378 { 15379 struct gimplify_omp_ctx ctx; 15380 memset (&ctx, 0, sizeof (ctx)); 15381 ctx.region_type = ORT_NONE; 15382 gimplify_omp_ctxp = &ctx; 15383 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body); 15384 gimplify_omp_ctxp = NULL; 15385 } 15386 } 15387 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE; 15388 15389 if (OMP_FOR_INIT (for_stmt) == NULL_TREE) 15390 for_stmt = inner_for_stmt; 15391 15392 /* For taskloop, need to gimplify the start, end and step before the 15393 taskloop, outside of the taskloop omp context. */ 15394 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 15395 { 15396 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15397 { 15398 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15399 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body) 15400 ? pre_p : &for_pre_body); 15401 tree type = TREE_TYPE (TREE_OPERAND (t, 0)); 15402 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15403 { 15404 tree v = TREE_OPERAND (t, 1); 15405 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1), 15406 for_pre_p, orig_for_stmt); 15407 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2), 15408 for_pre_p, orig_for_stmt); 15409 } 15410 else 15411 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p, 15412 orig_for_stmt); 15413 15414 /* Handle OMP_FOR_COND. */ 15415 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 15416 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15417 { 15418 tree v = TREE_OPERAND (t, 1); 15419 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1), 15420 for_pre_p, orig_for_stmt); 15421 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2), 15422 for_pre_p, orig_for_stmt); 15423 } 15424 else 15425 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p, 15426 orig_for_stmt); 15427 15428 /* Handle OMP_FOR_INCR. */ 15429 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15430 if (TREE_CODE (t) == MODIFY_EXPR) 15431 { 15432 decl = TREE_OPERAND (t, 0); 15433 t = TREE_OPERAND (t, 1); 15434 tree *tp = &TREE_OPERAND (t, 1); 15435 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl) 15436 tp = &TREE_OPERAND (t, 0); 15437 15438 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p, 15439 orig_for_stmt); 15440 } 15441 } 15442 15443 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort, 15444 OMP_TASKLOOP); 15445 } 15446 15447 if (orig_for_stmt != for_stmt) 15448 gimplify_omp_ctxp->combined_loop = true; 15449 15450 for_body = NULL; 15451 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15452 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt))); 15453 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15454 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt))); 15455 15456 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED); 15457 bool is_doacross = false; 15458 if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt), 15459 find_standalone_omp_ordered, NULL)) 15460 { 15461 OMP_CLAUSE_ORDERED_DOACROSS (c) = 1; 15462 is_doacross = true; 15463 int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); 15464 gimplify_omp_ctxp->loop_iter_var.create (len * 2); 15465 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; ) 15466 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) 15467 { 15468 error_at (OMP_CLAUSE_LOCATION (*pc), 15469 "%<linear%> clause may not be specified together " 15470 "with %<ordered%> clause if stand-alone %<ordered%> " 15471 "construct is nested in it"); 15472 *pc = OMP_CLAUSE_CHAIN (*pc); 15473 } 15474 else 15475 pc = &OMP_CLAUSE_CHAIN (*pc); 15476 } 15477 int collapse = 1, tile = 0; 15478 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE); 15479 if (c) 15480 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c)); 15481 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE); 15482 if (c) 15483 tile = list_length (OMP_CLAUSE_TILE_LIST (c)); 15484 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE); 15485 hash_set<tree> *allocate_uids = NULL; 15486 if (c) 15487 { 15488 allocate_uids = new hash_set<tree>; 15489 for (; c; c = OMP_CLAUSE_CHAIN (c)) 15490 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE) 15491 allocate_uids->add (OMP_CLAUSE_DECL (c)); 15492 } 15493 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15494 { 15495 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15496 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15497 decl = TREE_OPERAND (t, 0); 15498 gcc_assert (DECL_P (decl)); 15499 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)) 15500 || POINTER_TYPE_P (TREE_TYPE (decl))); 15501 if (is_doacross) 15502 { 15503 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt)) 15504 { 15505 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15506 if (TREE_CODE (orig_decl) == TREE_LIST) 15507 { 15508 orig_decl = TREE_PURPOSE (orig_decl); 15509 if (!orig_decl) 15510 orig_decl = decl; 15511 } 15512 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl); 15513 } 15514 else 15515 gimplify_omp_ctxp->loop_iter_var.quick_push (decl); 15516 gimplify_omp_ctxp->loop_iter_var.quick_push (decl); 15517 } 15518 15519 if (for_stmt == orig_for_stmt) 15520 { 15521 tree orig_decl = decl; 15522 if (OMP_FOR_ORIG_DECLS (for_stmt)) 15523 { 15524 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15525 if (TREE_CODE (orig_decl) == TREE_LIST) 15526 { 15527 orig_decl = TREE_PURPOSE (orig_decl); 15528 if (!orig_decl) 15529 orig_decl = decl; 15530 } 15531 } 15532 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl)) 15533 error_at (EXPR_LOCATION (for_stmt), 15534 "threadprivate iteration variable %qD", orig_decl); 15535 } 15536 15537 /* Make sure the iteration variable is private. */ 15538 tree c = NULL_TREE; 15539 tree c2 = NULL_TREE; 15540 if (orig_for_stmt != for_stmt) 15541 { 15542 /* Preserve this information until we gimplify the inner simd. */ 15543 if (has_decl_expr 15544 && bitmap_bit_p (has_decl_expr, DECL_UID (decl))) 15545 TREE_PRIVATE (t) = 1; 15546 } 15547 else if (ort == ORT_SIMD) 15548 { 15549 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables, 15550 (splay_tree_key) decl); 15551 omp_is_private (gimplify_omp_ctxp, decl, 15552 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) 15553 != 1)); 15554 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0) 15555 { 15556 omp_notice_variable (gimplify_omp_ctxp, decl, true); 15557 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL) 15558 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15559 OMP_CLAUSE_LASTPRIVATE); 15560 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3), 15561 OMP_CLAUSE_LASTPRIVATE)) 15562 if (OMP_CLAUSE_DECL (c3) == decl) 15563 { 15564 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp, 15565 "conditional %<lastprivate%> on loop " 15566 "iterator %qD ignored", decl); 15567 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0; 15568 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL; 15569 } 15570 } 15571 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p) 15572 { 15573 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); 15574 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1; 15575 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN; 15576 if ((has_decl_expr 15577 && bitmap_bit_p (has_decl_expr, DECL_UID (decl))) 15578 || TREE_PRIVATE (t)) 15579 { 15580 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15581 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15582 } 15583 struct gimplify_omp_ctx *outer 15584 = gimplify_omp_ctxp->outer_context; 15585 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 15586 { 15587 if (outer->region_type == ORT_WORKSHARE 15588 && outer->combined_loop) 15589 { 15590 n = splay_tree_lookup (outer->variables, 15591 (splay_tree_key)decl); 15592 if (n != NULL && (n->value & GOVD_LOCAL) != 0) 15593 { 15594 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15595 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15596 } 15597 else 15598 { 15599 struct gimplify_omp_ctx *octx = outer->outer_context; 15600 if (octx 15601 && octx->region_type == ORT_COMBINED_PARALLEL 15602 && octx->outer_context 15603 && (octx->outer_context->region_type 15604 == ORT_WORKSHARE) 15605 && octx->outer_context->combined_loop) 15606 { 15607 octx = octx->outer_context; 15608 n = splay_tree_lookup (octx->variables, 15609 (splay_tree_key)decl); 15610 if (n != NULL && (n->value & GOVD_LOCAL) != 0) 15611 { 15612 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1; 15613 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER; 15614 } 15615 } 15616 } 15617 } 15618 } 15619 15620 OMP_CLAUSE_DECL (c) = decl; 15621 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15622 OMP_FOR_CLAUSES (for_stmt) = c; 15623 omp_add_variable (gimplify_omp_ctxp, decl, flags); 15624 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)) 15625 omp_lastprivate_for_combined_outer_constructs (outer, decl, 15626 true); 15627 } 15628 else 15629 { 15630 bool lastprivate 15631 = (!has_decl_expr 15632 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl))); 15633 if (TREE_PRIVATE (t)) 15634 lastprivate = false; 15635 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt)) 15636 { 15637 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 15638 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt)) 15639 lastprivate = false; 15640 } 15641 15642 struct gimplify_omp_ctx *outer 15643 = gimplify_omp_ctxp->outer_context; 15644 if (outer && lastprivate) 15645 omp_lastprivate_for_combined_outer_constructs (outer, decl, 15646 true); 15647 15648 c = build_omp_clause (input_location, 15649 lastprivate ? OMP_CLAUSE_LASTPRIVATE 15650 : OMP_CLAUSE_PRIVATE); 15651 OMP_CLAUSE_DECL (c) = decl; 15652 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt); 15653 OMP_FOR_CLAUSES (for_stmt) = c; 15654 omp_add_variable (gimplify_omp_ctxp, decl, 15655 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE) 15656 | GOVD_EXPLICIT | GOVD_SEEN); 15657 c = NULL_TREE; 15658 } 15659 } 15660 else if (omp_is_private (gimplify_omp_ctxp, decl, 0)) 15661 { 15662 omp_notice_variable (gimplify_omp_ctxp, decl, true); 15663 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables, 15664 (splay_tree_key) decl); 15665 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL)) 15666 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), 15667 OMP_CLAUSE_LASTPRIVATE); 15668 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3), 15669 OMP_CLAUSE_LASTPRIVATE)) 15670 if (OMP_CLAUSE_DECL (c3) == decl) 15671 { 15672 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp, 15673 "conditional %<lastprivate%> on loop " 15674 "iterator %qD ignored", decl); 15675 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0; 15676 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL; 15677 } 15678 } 15679 else 15680 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN); 15681 15682 /* If DECL is not a gimple register, create a temporary variable to act 15683 as an iteration counter. This is valid, since DECL cannot be 15684 modified in the body of the loop. Similarly for any iteration vars 15685 in simd with collapse > 1 where the iterator vars must be 15686 lastprivate. And similarly for vars mentioned in allocate clauses. */ 15687 if (orig_for_stmt != for_stmt) 15688 var = decl; 15689 else if (!is_gimple_reg (decl) 15690 || (ort == ORT_SIMD 15691 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1) 15692 || (allocate_uids && allocate_uids->contains (decl))) 15693 { 15694 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 15695 /* Make sure omp_add_variable is not called on it prematurely. 15696 We call it ourselves a few lines later. */ 15697 gimplify_omp_ctxp = NULL; 15698 var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); 15699 gimplify_omp_ctxp = ctx; 15700 TREE_OPERAND (t, 0) = var; 15701 15702 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var)); 15703 15704 if (ort == ORT_SIMD 15705 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1) 15706 { 15707 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); 15708 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1; 15709 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1; 15710 OMP_CLAUSE_DECL (c2) = var; 15711 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt); 15712 OMP_FOR_CLAUSES (for_stmt) = c2; 15713 omp_add_variable (gimplify_omp_ctxp, var, 15714 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN); 15715 if (c == NULL_TREE) 15716 { 15717 c = c2; 15718 c2 = NULL_TREE; 15719 } 15720 } 15721 else 15722 omp_add_variable (gimplify_omp_ctxp, var, 15723 GOVD_PRIVATE | GOVD_SEEN); 15724 } 15725 else 15726 var = decl; 15727 15728 gimplify_omp_ctxp->in_for_exprs = true; 15729 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15730 { 15731 tree lb = TREE_OPERAND (t, 1); 15732 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL, 15733 is_gimple_val, fb_rvalue, false); 15734 ret = MIN (ret, tret); 15735 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL, 15736 is_gimple_val, fb_rvalue, false); 15737 } 15738 else 15739 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15740 is_gimple_val, fb_rvalue, false); 15741 gimplify_omp_ctxp->in_for_exprs = false; 15742 ret = MIN (ret, tret); 15743 if (ret == GS_ERROR) 15744 return ret; 15745 15746 /* Handle OMP_FOR_COND. */ 15747 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 15748 gcc_assert (COMPARISON_CLASS_P (t)); 15749 gcc_assert (TREE_OPERAND (t, 0) == decl); 15750 15751 gimplify_omp_ctxp->in_for_exprs = true; 15752 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) 15753 { 15754 tree ub = TREE_OPERAND (t, 1); 15755 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL, 15756 is_gimple_val, fb_rvalue, false); 15757 ret = MIN (ret, tret); 15758 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL, 15759 is_gimple_val, fb_rvalue, false); 15760 } 15761 else 15762 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15763 is_gimple_val, fb_rvalue, false); 15764 gimplify_omp_ctxp->in_for_exprs = false; 15765 ret = MIN (ret, tret); 15766 15767 /* Handle OMP_FOR_INCR. */ 15768 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15769 switch (TREE_CODE (t)) 15770 { 15771 case PREINCREMENT_EXPR: 15772 case POSTINCREMENT_EXPR: 15773 { 15774 tree decl = TREE_OPERAND (t, 0); 15775 /* c_omp_for_incr_canonicalize_ptr() should have been 15776 called to massage things appropriately. */ 15777 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl))); 15778 15779 if (orig_for_stmt != for_stmt) 15780 break; 15781 t = build_int_cst (TREE_TYPE (decl), 1); 15782 if (c) 15783 OMP_CLAUSE_LINEAR_STEP (c) = t; 15784 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); 15785 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); 15786 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; 15787 break; 15788 } 15789 15790 case PREDECREMENT_EXPR: 15791 case POSTDECREMENT_EXPR: 15792 /* c_omp_for_incr_canonicalize_ptr() should have been 15793 called to massage things appropriately. */ 15794 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl))); 15795 if (orig_for_stmt != for_stmt) 15796 break; 15797 t = build_int_cst (TREE_TYPE (decl), -1); 15798 if (c) 15799 OMP_CLAUSE_LINEAR_STEP (c) = t; 15800 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); 15801 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); 15802 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; 15803 break; 15804 15805 case MODIFY_EXPR: 15806 gcc_assert (TREE_OPERAND (t, 0) == decl); 15807 TREE_OPERAND (t, 0) = var; 15808 15809 t = TREE_OPERAND (t, 1); 15810 switch (TREE_CODE (t)) 15811 { 15812 case PLUS_EXPR: 15813 if (TREE_OPERAND (t, 1) == decl) 15814 { 15815 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0); 15816 TREE_OPERAND (t, 0) = var; 15817 break; 15818 } 15819 15820 /* Fallthru. */ 15821 case MINUS_EXPR: 15822 case POINTER_PLUS_EXPR: 15823 gcc_assert (TREE_OPERAND (t, 0) == decl); 15824 TREE_OPERAND (t, 0) = var; 15825 break; 15826 default: 15827 gcc_unreachable (); 15828 } 15829 15830 gimplify_omp_ctxp->in_for_exprs = true; 15831 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, 15832 is_gimple_val, fb_rvalue, false); 15833 ret = MIN (ret, tret); 15834 if (c) 15835 { 15836 tree step = TREE_OPERAND (t, 1); 15837 tree stept = TREE_TYPE (decl); 15838 if (POINTER_TYPE_P (stept)) 15839 stept = sizetype; 15840 step = fold_convert (stept, step); 15841 if (TREE_CODE (t) == MINUS_EXPR) 15842 step = fold_build1 (NEGATE_EXPR, stept, step); 15843 OMP_CLAUSE_LINEAR_STEP (c) = step; 15844 if (step != TREE_OPERAND (t, 1)) 15845 { 15846 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), 15847 &for_pre_body, NULL, 15848 is_gimple_val, fb_rvalue, false); 15849 ret = MIN (ret, tret); 15850 } 15851 } 15852 gimplify_omp_ctxp->in_for_exprs = false; 15853 break; 15854 15855 default: 15856 gcc_unreachable (); 15857 } 15858 15859 if (c2) 15860 { 15861 gcc_assert (c); 15862 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c); 15863 } 15864 15865 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt) 15866 { 15867 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c)) 15868 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 15869 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL) 15870 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR 15871 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c) 15872 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL)) 15873 && OMP_CLAUSE_DECL (c) == decl) 15874 { 15875 if (is_doacross && (collapse == 1 || i >= collapse)) 15876 t = var; 15877 else 15878 { 15879 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15880 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15881 gcc_assert (TREE_OPERAND (t, 0) == var); 15882 t = TREE_OPERAND (t, 1); 15883 gcc_assert (TREE_CODE (t) == PLUS_EXPR 15884 || TREE_CODE (t) == MINUS_EXPR 15885 || TREE_CODE (t) == POINTER_PLUS_EXPR); 15886 gcc_assert (TREE_OPERAND (t, 0) == var); 15887 t = build2 (TREE_CODE (t), TREE_TYPE (decl), 15888 is_doacross ? var : decl, 15889 TREE_OPERAND (t, 1)); 15890 } 15891 gimple_seq *seq; 15892 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) 15893 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c); 15894 else 15895 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c); 15896 push_gimplify_context (); 15897 gimplify_assign (decl, t, seq); 15898 gimple *bind = NULL; 15899 if (gimplify_ctxp->temps) 15900 { 15901 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE); 15902 *seq = NULL; 15903 gimplify_seq_add_stmt (seq, bind); 15904 } 15905 pop_gimplify_context (bind); 15906 } 15907 } 15908 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl) 15909 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) 15910 { 15911 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); 15912 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15913 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15914 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15915 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15916 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); 15917 gcc_assert (COMPARISON_CLASS_P (t)); 15918 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15919 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15920 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15921 } 15922 } 15923 15924 BITMAP_FREE (has_decl_expr); 15925 delete allocate_uids; 15926 15927 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP 15928 || (loop_p && orig_for_stmt == for_stmt)) 15929 { 15930 push_gimplify_context (); 15931 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR) 15932 { 15933 OMP_FOR_BODY (orig_for_stmt) 15934 = build3 (BIND_EXPR, void_type_node, NULL, 15935 OMP_FOR_BODY (orig_for_stmt), NULL); 15936 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1; 15937 } 15938 } 15939 15940 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt), 15941 &for_body); 15942 15943 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP 15944 || (loop_p && orig_for_stmt == for_stmt)) 15945 { 15946 if (gimple_code (g) == GIMPLE_BIND) 15947 pop_gimplify_context (g); 15948 else 15949 pop_gimplify_context (NULL); 15950 } 15951 15952 if (orig_for_stmt != for_stmt) 15953 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 15954 { 15955 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 15956 decl = TREE_OPERAND (t, 0); 15957 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 15958 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 15959 gimplify_omp_ctxp = ctx->outer_context; 15960 var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); 15961 gimplify_omp_ctxp = ctx; 15962 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN); 15963 TREE_OPERAND (t, 0) = var; 15964 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 15965 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 15966 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var; 15967 if (OMP_FOR_NON_RECTANGULAR (for_stmt)) 15968 for (int j = i + 1; 15969 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) 15970 { 15971 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); 15972 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 15973 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15974 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15975 { 15976 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 15977 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15978 } 15979 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); 15980 gcc_assert (COMPARISON_CLASS_P (t)); 15981 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC 15982 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) 15983 { 15984 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); 15985 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; 15986 } 15987 } 15988 } 15989 15990 gimplify_adjust_omp_clauses (pre_p, for_body, 15991 &OMP_FOR_CLAUSES (orig_for_stmt), 15992 TREE_CODE (orig_for_stmt)); 15993 15994 int kind; 15995 switch (TREE_CODE (orig_for_stmt)) 15996 { 15997 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break; 15998 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break; 15999 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break; 16000 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break; 16001 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break; 16002 default: 16003 gcc_unreachable (); 16004 } 16005 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD) 16006 { 16007 gimplify_seq_add_seq (pre_p, for_pre_body); 16008 for_pre_body = NULL; 16009 } 16010 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt), 16011 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), 16012 for_pre_body); 16013 if (orig_for_stmt != for_stmt) 16014 gimple_omp_for_set_combined_p (gfor, true); 16015 if (gimplify_omp_ctxp 16016 && (gimplify_omp_ctxp->combined_loop 16017 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL 16018 && gimplify_omp_ctxp->outer_context 16019 && gimplify_omp_ctxp->outer_context->combined_loop))) 16020 { 16021 gimple_omp_for_set_combined_into_p (gfor, true); 16022 if (gimplify_omp_ctxp->combined_loop) 16023 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD); 16024 else 16025 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR); 16026 } 16027 16028 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16029 { 16030 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 16031 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0)); 16032 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1)); 16033 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); 16034 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t)); 16035 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1)); 16036 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); 16037 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1)); 16038 } 16039 16040 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop 16041 constructs with GIMPLE_OMP_TASK sandwiched in between them. 16042 The outer taskloop stands for computing the number of iterations, 16043 counts for collapsed loops and holding taskloop specific clauses. 16044 The task construct stands for the effect of data sharing on the 16045 explicit task it creates and the inner taskloop stands for expansion 16046 of the static loop inside of the explicit task construct. */ 16047 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) 16048 { 16049 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor); 16050 tree task_clauses = NULL_TREE; 16051 tree c = *gfor_clauses_ptr; 16052 tree *gtask_clauses_ptr = &task_clauses; 16053 tree outer_for_clauses = NULL_TREE; 16054 tree *gforo_clauses_ptr = &outer_for_clauses; 16055 bitmap lastprivate_uids = NULL; 16056 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE)) 16057 { 16058 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE); 16059 if (c) 16060 { 16061 lastprivate_uids = BITMAP_ALLOC (NULL); 16062 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c), 16063 OMP_CLAUSE_LASTPRIVATE)) 16064 bitmap_set_bit (lastprivate_uids, 16065 DECL_UID (OMP_CLAUSE_DECL (c))); 16066 } 16067 c = *gfor_clauses_ptr; 16068 } 16069 for (; c; c = OMP_CLAUSE_CHAIN (c)) 16070 switch (OMP_CLAUSE_CODE (c)) 16071 { 16072 /* These clauses are allowed on task, move them there. */ 16073 case OMP_CLAUSE_SHARED: 16074 case OMP_CLAUSE_FIRSTPRIVATE: 16075 case OMP_CLAUSE_DEFAULT: 16076 case OMP_CLAUSE_IF: 16077 case OMP_CLAUSE_UNTIED: 16078 case OMP_CLAUSE_FINAL: 16079 case OMP_CLAUSE_MERGEABLE: 16080 case OMP_CLAUSE_PRIORITY: 16081 case OMP_CLAUSE_REDUCTION: 16082 case OMP_CLAUSE_IN_REDUCTION: 16083 *gtask_clauses_ptr = c; 16084 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16085 break; 16086 case OMP_CLAUSE_PRIVATE: 16087 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c)) 16088 { 16089 /* We want private on outer for and firstprivate 16090 on task. */ 16091 *gtask_clauses_ptr 16092 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16093 OMP_CLAUSE_FIRSTPRIVATE); 16094 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16095 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL, 16096 openacc); 16097 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16098 *gforo_clauses_ptr = c; 16099 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16100 } 16101 else 16102 { 16103 *gtask_clauses_ptr = c; 16104 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16105 } 16106 break; 16107 /* These clauses go into outer taskloop clauses. */ 16108 case OMP_CLAUSE_GRAINSIZE: 16109 case OMP_CLAUSE_NUM_TASKS: 16110 case OMP_CLAUSE_NOGROUP: 16111 *gforo_clauses_ptr = c; 16112 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16113 break; 16114 /* Collapse clause we duplicate on both taskloops. */ 16115 case OMP_CLAUSE_COLLAPSE: 16116 *gfor_clauses_ptr = c; 16117 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16118 *gforo_clauses_ptr = copy_node (c); 16119 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr); 16120 break; 16121 /* For lastprivate, keep the clause on inner taskloop, and add 16122 a shared clause on task. If the same decl is also firstprivate, 16123 add also firstprivate clause on the inner taskloop. */ 16124 case OMP_CLAUSE_LASTPRIVATE: 16125 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) 16126 { 16127 /* For taskloop C++ lastprivate IVs, we want: 16128 1) private on outer taskloop 16129 2) firstprivate and shared on task 16130 3) lastprivate on inner taskloop */ 16131 *gtask_clauses_ptr 16132 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16133 OMP_CLAUSE_FIRSTPRIVATE); 16134 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16135 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL, 16136 openacc); 16137 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16138 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1; 16139 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16140 OMP_CLAUSE_PRIVATE); 16141 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c); 16142 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1; 16143 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c); 16144 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr); 16145 } 16146 *gfor_clauses_ptr = c; 16147 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16148 *gtask_clauses_ptr 16149 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED); 16150 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); 16151 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)) 16152 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1; 16153 gtask_clauses_ptr 16154 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16155 break; 16156 /* Allocate clause we duplicate on task and inner taskloop 16157 if the decl is lastprivate, otherwise just put on task. */ 16158 case OMP_CLAUSE_ALLOCATE: 16159 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) 16160 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))) 16161 { 16162 /* Additionally, put firstprivate clause on task 16163 for the allocator if it is not constant. */ 16164 *gtask_clauses_ptr 16165 = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16166 OMP_CLAUSE_FIRSTPRIVATE); 16167 OMP_CLAUSE_DECL (*gtask_clauses_ptr) 16168 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); 16169 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16170 } 16171 if (lastprivate_uids 16172 && bitmap_bit_p (lastprivate_uids, 16173 DECL_UID (OMP_CLAUSE_DECL (c)))) 16174 { 16175 *gfor_clauses_ptr = c; 16176 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16177 *gtask_clauses_ptr = copy_node (c); 16178 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); 16179 } 16180 else 16181 { 16182 *gtask_clauses_ptr = c; 16183 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); 16184 } 16185 break; 16186 default: 16187 gcc_unreachable (); 16188 } 16189 *gfor_clauses_ptr = NULL_TREE; 16190 *gtask_clauses_ptr = NULL_TREE; 16191 *gforo_clauses_ptr = NULL_TREE; 16192 BITMAP_FREE (lastprivate_uids); 16193 gimple_set_location (gfor, input_location); 16194 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE); 16195 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE, 16196 NULL_TREE, NULL_TREE, NULL_TREE); 16197 gimple_set_location (g, input_location); 16198 gimple_omp_task_set_taskloop_p (g, true); 16199 g = gimple_build_bind (NULL_TREE, g, NULL_TREE); 16200 gomp_for *gforo 16201 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses, 16202 gimple_omp_for_collapse (gfor), 16203 gimple_omp_for_pre_body (gfor)); 16204 gimple_omp_for_set_pre_body (gfor, NULL); 16205 gimple_omp_for_set_combined_p (gforo, true); 16206 gimple_omp_for_set_combined_into_p (gfor, true); 16207 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++) 16208 { 16209 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i)); 16210 tree v = create_tmp_var (type); 16211 gimple_omp_for_set_index (gforo, i, v); 16212 t = unshare_expr (gimple_omp_for_initial (gfor, i)); 16213 gimple_omp_for_set_initial (gforo, i, t); 16214 gimple_omp_for_set_cond (gforo, i, 16215 gimple_omp_for_cond (gfor, i)); 16216 t = unshare_expr (gimple_omp_for_final (gfor, i)); 16217 gimple_omp_for_set_final (gforo, i, t); 16218 t = unshare_expr (gimple_omp_for_incr (gfor, i)); 16219 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i)); 16220 TREE_OPERAND (t, 0) = v; 16221 gimple_omp_for_set_incr (gforo, i, t); 16222 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); 16223 OMP_CLAUSE_DECL (t) = v; 16224 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo); 16225 gimple_omp_for_set_clauses (gforo, t); 16226 if (OMP_FOR_NON_RECTANGULAR (for_stmt)) 16227 { 16228 tree *p1 = NULL, *p2 = NULL; 16229 t = gimple_omp_for_initial (gforo, i); 16230 if (TREE_CODE (t) == TREE_VEC) 16231 p1 = &TREE_VEC_ELT (t, 0); 16232 t = gimple_omp_for_final (gforo, i); 16233 if (TREE_CODE (t) == TREE_VEC) 16234 { 16235 if (p1) 16236 p2 = &TREE_VEC_ELT (t, 0); 16237 else 16238 p1 = &TREE_VEC_ELT (t, 0); 16239 } 16240 if (p1) 16241 { 16242 int j; 16243 for (j = 0; j < i; j++) 16244 if (*p1 == gimple_omp_for_index (gfor, j)) 16245 { 16246 *p1 = gimple_omp_for_index (gforo, j); 16247 if (p2) 16248 *p2 = *p1; 16249 break; 16250 } 16251 gcc_assert (j < i); 16252 } 16253 } 16254 } 16255 gimplify_seq_add_stmt (pre_p, gforo); 16256 } 16257 else 16258 gimplify_seq_add_stmt (pre_p, gfor); 16259 16260 if (TREE_CODE (orig_for_stmt) == OMP_FOR) 16261 { 16262 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; 16263 unsigned lastprivate_conditional = 0; 16264 while (ctx 16265 && (ctx->region_type == ORT_TARGET_DATA 16266 || ctx->region_type == ORT_TASKGROUP)) 16267 ctx = ctx->outer_context; 16268 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0) 16269 for (tree c = gimple_omp_for_clauses (gfor); 16270 c; c = OMP_CLAUSE_CHAIN (c)) 16271 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 16272 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 16273 ++lastprivate_conditional; 16274 if (lastprivate_conditional) 16275 { 16276 struct omp_for_data fd; 16277 omp_extract_for_data (gfor, &fd, NULL); 16278 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type), 16279 lastprivate_conditional); 16280 tree var = create_tmp_var_raw (type); 16281 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_); 16282 OMP_CLAUSE_DECL (c) = var; 16283 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor); 16284 gimple_omp_for_set_clauses (gfor, c); 16285 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN); 16286 } 16287 } 16288 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD) 16289 { 16290 unsigned lastprivate_conditional = 0; 16291 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c)) 16292 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE 16293 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) 16294 ++lastprivate_conditional; 16295 if (lastprivate_conditional) 16296 { 16297 struct omp_for_data fd; 16298 omp_extract_for_data (gfor, &fd, NULL); 16299 tree type = unsigned_type_for (fd.iter_type); 16300 while (lastprivate_conditional--) 16301 { 16302 tree c = build_omp_clause (UNKNOWN_LOCATION, 16303 OMP_CLAUSE__CONDTEMP_); 16304 OMP_CLAUSE_DECL (c) = create_tmp_var (type); 16305 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor); 16306 gimple_omp_for_set_clauses (gfor, c); 16307 } 16308 } 16309 } 16310 16311 if (ret != GS_ALL_DONE) 16312 return GS_ERROR; 16313 *expr_p = NULL_TREE; 16314 return GS_ALL_DONE; 16315 } 16316 16317 /* Helper for gimplify_omp_loop, called through walk_tree. */ 16318 16319 static tree 16320 note_no_context_vars (tree *tp, int *, void *data) 16321 { 16322 if (VAR_P (*tp) 16323 && DECL_CONTEXT (*tp) == NULL_TREE 16324 && !is_global_var (*tp)) 16325 { 16326 vec<tree> *d = (vec<tree> *) data; 16327 d->safe_push (*tp); 16328 DECL_CONTEXT (*tp) = current_function_decl; 16329 } 16330 return NULL_TREE; 16331 } 16332 16333 /* Gimplify the gross structure of an OMP_LOOP statement. */ 16334 16335 static enum gimplify_status 16336 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p) 16337 { 16338 tree for_stmt = *expr_p; 16339 tree clauses = OMP_FOR_CLAUSES (for_stmt); 16340 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp; 16341 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD; 16342 int i; 16343 16344 /* If order is not present, the behavior is as if order(concurrent) 16345 appeared. */ 16346 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER); 16347 if (order == NULL_TREE) 16348 { 16349 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER); 16350 OMP_CLAUSE_CHAIN (order) = clauses; 16351 OMP_FOR_CLAUSES (for_stmt) = clauses = order; 16352 } 16353 16354 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND); 16355 if (bind == NULL_TREE) 16356 { 16357 if (!flag_openmp) /* flag_openmp_simd */ 16358 ; 16359 else if (octx && (octx->region_type & ORT_TEAMS) != 0) 16360 kind = OMP_CLAUSE_BIND_TEAMS; 16361 else if (octx && (octx->region_type & ORT_PARALLEL) != 0) 16362 kind = OMP_CLAUSE_BIND_PARALLEL; 16363 else 16364 { 16365 for (; octx; octx = octx->outer_context) 16366 { 16367 if ((octx->region_type & ORT_ACC) != 0 16368 || octx->region_type == ORT_NONE 16369 || octx->region_type == ORT_IMPLICIT_TARGET) 16370 continue; 16371 break; 16372 } 16373 if (octx == NULL && !in_omp_construct) 16374 error_at (EXPR_LOCATION (for_stmt), 16375 "%<bind%> clause not specified on a %<loop%> " 16376 "construct not nested inside another OpenMP construct"); 16377 } 16378 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND); 16379 OMP_CLAUSE_CHAIN (bind) = clauses; 16380 OMP_CLAUSE_BIND_KIND (bind) = kind; 16381 OMP_FOR_CLAUSES (for_stmt) = bind; 16382 } 16383 else 16384 switch (OMP_CLAUSE_BIND_KIND (bind)) 16385 { 16386 case OMP_CLAUSE_BIND_THREAD: 16387 break; 16388 case OMP_CLAUSE_BIND_PARALLEL: 16389 if (!flag_openmp) /* flag_openmp_simd */ 16390 { 16391 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16392 break; 16393 } 16394 for (; octx; octx = octx->outer_context) 16395 if (octx->region_type == ORT_SIMD 16396 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE) 16397 { 16398 error_at (EXPR_LOCATION (for_stmt), 16399 "%<bind(parallel)%> on a %<loop%> construct nested " 16400 "inside %<simd%> construct"); 16401 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16402 break; 16403 } 16404 kind = OMP_CLAUSE_BIND_PARALLEL; 16405 break; 16406 case OMP_CLAUSE_BIND_TEAMS: 16407 if (!flag_openmp) /* flag_openmp_simd */ 16408 { 16409 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16410 break; 16411 } 16412 if ((octx 16413 && octx->region_type != ORT_IMPLICIT_TARGET 16414 && octx->region_type != ORT_NONE 16415 && (octx->region_type & ORT_TEAMS) == 0) 16416 || in_omp_construct) 16417 { 16418 error_at (EXPR_LOCATION (for_stmt), 16419 "%<bind(teams)%> on a %<loop%> region not strictly " 16420 "nested inside of a %<teams%> region"); 16421 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD; 16422 break; 16423 } 16424 kind = OMP_CLAUSE_BIND_TEAMS; 16425 break; 16426 default: 16427 gcc_unreachable (); 16428 } 16429 16430 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; ) 16431 switch (OMP_CLAUSE_CODE (*pc)) 16432 { 16433 case OMP_CLAUSE_REDUCTION: 16434 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc)) 16435 { 16436 error_at (OMP_CLAUSE_LOCATION (*pc), 16437 "%<inscan%> %<reduction%> clause on " 16438 "%qs construct", "loop"); 16439 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0; 16440 } 16441 if (OMP_CLAUSE_REDUCTION_TASK (*pc)) 16442 { 16443 error_at (OMP_CLAUSE_LOCATION (*pc), 16444 "invalid %<task%> reduction modifier on construct " 16445 "other than %<parallel%>, %qs or %<sections%>", 16446 lang_GNU_Fortran () ? "do" : "for"); 16447 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0; 16448 } 16449 pc = &OMP_CLAUSE_CHAIN (*pc); 16450 break; 16451 case OMP_CLAUSE_LASTPRIVATE: 16452 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16453 { 16454 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); 16455 gcc_assert (TREE_CODE (t) == MODIFY_EXPR); 16456 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0)) 16457 break; 16458 if (OMP_FOR_ORIG_DECLS (for_stmt) 16459 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), 16460 i)) == TREE_LIST 16461 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), 16462 i))) 16463 { 16464 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 16465 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig)) 16466 break; 16467 } 16468 } 16469 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))) 16470 { 16471 error_at (OMP_CLAUSE_LOCATION (*pc), 16472 "%<lastprivate%> clause on a %<loop%> construct refers " 16473 "to a variable %qD which is not the loop iterator", 16474 OMP_CLAUSE_DECL (*pc)); 16475 *pc = OMP_CLAUSE_CHAIN (*pc); 16476 break; 16477 } 16478 pc = &OMP_CLAUSE_CHAIN (*pc); 16479 break; 16480 default: 16481 pc = &OMP_CLAUSE_CHAIN (*pc); 16482 break; 16483 } 16484 16485 TREE_SET_CODE (for_stmt, OMP_SIMD); 16486 16487 int last; 16488 switch (kind) 16489 { 16490 case OMP_CLAUSE_BIND_THREAD: last = 0; break; 16491 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break; 16492 case OMP_CLAUSE_BIND_TEAMS: last = 2; break; 16493 } 16494 for (int pass = 1; pass <= last; pass++) 16495 { 16496 if (pass == 2) 16497 { 16498 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, 16499 make_node (BLOCK)); 16500 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind)); 16501 *expr_p = make_node (OMP_PARALLEL); 16502 TREE_TYPE (*expr_p) = void_type_node; 16503 OMP_PARALLEL_BODY (*expr_p) = bind; 16504 OMP_PARALLEL_COMBINED (*expr_p) = 1; 16505 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt)); 16506 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p); 16507 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) 16508 if (OMP_FOR_ORIG_DECLS (for_stmt) 16509 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i)) 16510 == TREE_LIST)) 16511 { 16512 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); 16513 if (TREE_PURPOSE (elt) && TREE_VALUE (elt)) 16514 { 16515 *pc = build_omp_clause (UNKNOWN_LOCATION, 16516 OMP_CLAUSE_FIRSTPRIVATE); 16517 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt); 16518 pc = &OMP_CLAUSE_CHAIN (*pc); 16519 } 16520 } 16521 } 16522 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR); 16523 tree *pc = &OMP_FOR_CLAUSES (t); 16524 TREE_TYPE (t) = void_type_node; 16525 OMP_FOR_BODY (t) = *expr_p; 16526 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt)); 16527 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c)) 16528 switch (OMP_CLAUSE_CODE (c)) 16529 { 16530 case OMP_CLAUSE_BIND: 16531 case OMP_CLAUSE_ORDER: 16532 case OMP_CLAUSE_COLLAPSE: 16533 *pc = copy_node (c); 16534 pc = &OMP_CLAUSE_CHAIN (*pc); 16535 break; 16536 case OMP_CLAUSE_PRIVATE: 16537 case OMP_CLAUSE_FIRSTPRIVATE: 16538 /* Only needed on innermost. */ 16539 break; 16540 case OMP_CLAUSE_LASTPRIVATE: 16541 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last) 16542 { 16543 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 16544 OMP_CLAUSE_FIRSTPRIVATE); 16545 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c); 16546 lang_hooks.decls.omp_finish_clause (*pc, NULL, false); 16547 pc = &OMP_CLAUSE_CHAIN (*pc); 16548 } 16549 *pc = copy_node (c); 16550 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE; 16551 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c)); 16552 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) 16553 { 16554 if (pass != last) 16555 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1; 16556 else 16557 lang_hooks.decls.omp_finish_clause (*pc, NULL, false); 16558 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0; 16559 } 16560 pc = &OMP_CLAUSE_CHAIN (*pc); 16561 break; 16562 case OMP_CLAUSE_REDUCTION: 16563 *pc = copy_node (c); 16564 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c)); 16565 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c)); 16566 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)) 16567 { 16568 auto_vec<tree> no_context_vars; 16569 int walk_subtrees = 0; 16570 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 16571 &walk_subtrees, &no_context_vars); 16572 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)) 16573 note_no_context_vars (&p, &walk_subtrees, &no_context_vars); 16574 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c), 16575 note_no_context_vars, 16576 &no_context_vars); 16577 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c), 16578 note_no_context_vars, 16579 &no_context_vars); 16580 16581 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc) 16582 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)); 16583 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)) 16584 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc) 16585 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)); 16586 16587 hash_map<tree, tree> decl_map; 16588 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c)); 16589 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), 16590 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)); 16591 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)) 16592 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c), 16593 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)); 16594 16595 copy_body_data id; 16596 memset (&id, 0, sizeof (id)); 16597 id.src_fn = current_function_decl; 16598 id.dst_fn = current_function_decl; 16599 id.src_cfun = cfun; 16600 id.decl_map = &decl_map; 16601 id.copy_decl = copy_decl_no_change; 16602 id.transform_call_graph_edges = CB_CGE_DUPLICATE; 16603 id.transform_new_cfg = true; 16604 id.transform_return_to_modify = false; 16605 id.eh_lp_nr = 0; 16606 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r, 16607 &id, NULL); 16608 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r, 16609 &id, NULL); 16610 16611 for (tree d : no_context_vars) 16612 { 16613 DECL_CONTEXT (d) = NULL_TREE; 16614 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE; 16615 } 16616 } 16617 else 16618 { 16619 OMP_CLAUSE_REDUCTION_INIT (*pc) 16620 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c)); 16621 OMP_CLAUSE_REDUCTION_MERGE (*pc) 16622 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c)); 16623 } 16624 pc = &OMP_CLAUSE_CHAIN (*pc); 16625 break; 16626 default: 16627 gcc_unreachable (); 16628 } 16629 *pc = NULL_TREE; 16630 *expr_p = t; 16631 } 16632 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none); 16633 } 16634 16635 16636 /* Helper function of optimize_target_teams, find OMP_TEAMS inside 16637 of OMP_TARGET's body. */ 16638 16639 static tree 16640 find_omp_teams (tree *tp, int *walk_subtrees, void *) 16641 { 16642 *walk_subtrees = 0; 16643 switch (TREE_CODE (*tp)) 16644 { 16645 case OMP_TEAMS: 16646 return *tp; 16647 case BIND_EXPR: 16648 case STATEMENT_LIST: 16649 *walk_subtrees = 1; 16650 break; 16651 default: 16652 break; 16653 } 16654 return NULL_TREE; 16655 } 16656 16657 /* Helper function of optimize_target_teams, determine if the expression 16658 can be computed safely before the target construct on the host. */ 16659 16660 static tree 16661 computable_teams_clause (tree *tp, int *walk_subtrees, void *) 16662 { 16663 splay_tree_node n; 16664 16665 if (TYPE_P (*tp)) 16666 { 16667 *walk_subtrees = 0; 16668 return NULL_TREE; 16669 } 16670 switch (TREE_CODE (*tp)) 16671 { 16672 case VAR_DECL: 16673 case PARM_DECL: 16674 case RESULT_DECL: 16675 *walk_subtrees = 0; 16676 if (error_operand_p (*tp) 16677 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp)) 16678 || DECL_HAS_VALUE_EXPR_P (*tp) 16679 || DECL_THREAD_LOCAL_P (*tp) 16680 || TREE_SIDE_EFFECTS (*tp) 16681 || TREE_THIS_VOLATILE (*tp)) 16682 return *tp; 16683 if (is_global_var (*tp) 16684 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp)) 16685 || lookup_attribute ("omp declare target link", 16686 DECL_ATTRIBUTES (*tp)))) 16687 return *tp; 16688 if (VAR_P (*tp) 16689 && !DECL_SEEN_IN_BIND_EXPR_P (*tp) 16690 && !is_global_var (*tp) 16691 && decl_function_context (*tp) == current_function_decl) 16692 return *tp; 16693 n = splay_tree_lookup (gimplify_omp_ctxp->variables, 16694 (splay_tree_key) *tp); 16695 if (n == NULL) 16696 { 16697 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE) 16698 return NULL_TREE; 16699 return *tp; 16700 } 16701 else if (n->value & GOVD_LOCAL) 16702 return *tp; 16703 else if (n->value & GOVD_FIRSTPRIVATE) 16704 return NULL_TREE; 16705 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO)) 16706 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO)) 16707 return NULL_TREE; 16708 return *tp; 16709 case INTEGER_CST: 16710 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp))) 16711 return *tp; 16712 return NULL_TREE; 16713 case TARGET_EXPR: 16714 if (TARGET_EXPR_INITIAL (*tp) 16715 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL) 16716 return *tp; 16717 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp), 16718 walk_subtrees, NULL); 16719 /* Allow some reasonable subset of integral arithmetics. */ 16720 case PLUS_EXPR: 16721 case MINUS_EXPR: 16722 case MULT_EXPR: 16723 case TRUNC_DIV_EXPR: 16724 case CEIL_DIV_EXPR: 16725 case FLOOR_DIV_EXPR: 16726 case ROUND_DIV_EXPR: 16727 case TRUNC_MOD_EXPR: 16728 case CEIL_MOD_EXPR: 16729 case FLOOR_MOD_EXPR: 16730 case ROUND_MOD_EXPR: 16731 case RDIV_EXPR: 16732 case EXACT_DIV_EXPR: 16733 case MIN_EXPR: 16734 case MAX_EXPR: 16735 case LSHIFT_EXPR: 16736 case RSHIFT_EXPR: 16737 case BIT_IOR_EXPR: 16738 case BIT_XOR_EXPR: 16739 case BIT_AND_EXPR: 16740 case NEGATE_EXPR: 16741 case ABS_EXPR: 16742 case BIT_NOT_EXPR: 16743 case NON_LVALUE_EXPR: 16744 CASE_CONVERT: 16745 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp))) 16746 return *tp; 16747 return NULL_TREE; 16748 /* And disallow anything else, except for comparisons. */ 16749 default: 16750 if (COMPARISON_CLASS_P (*tp)) 16751 return NULL_TREE; 16752 return *tp; 16753 } 16754 } 16755 16756 /* Try to determine if the num_teams and/or thread_limit expressions 16757 can have their values determined already before entering the 16758 target construct. 16759 INTEGER_CSTs trivially are, 16760 integral decls that are firstprivate (explicitly or implicitly) 16761 or explicitly map(always, to:) or map(always, tofrom:) on the target 16762 region too, and expressions involving simple arithmetics on those 16763 too, function calls are not ok, dereferencing something neither etc. 16764 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of 16765 EXPR based on what we find: 16766 0 stands for clause not specified at all, use implementation default 16767 -1 stands for value that can't be determined easily before entering 16768 the target construct. 16769 -2 means that no explicit teams construct was specified 16770 If teams construct is not present at all, use 1 for num_teams 16771 and 0 for thread_limit (only one team is involved, and the thread 16772 limit is implementation defined. */ 16773 16774 static void 16775 optimize_target_teams (tree target, gimple_seq *pre_p) 16776 { 16777 tree body = OMP_BODY (target); 16778 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL); 16779 tree num_teams_lower = NULL_TREE; 16780 tree num_teams_upper = integer_zero_node; 16781 tree thread_limit = integer_zero_node; 16782 location_t num_teams_loc = EXPR_LOCATION (target); 16783 location_t thread_limit_loc = EXPR_LOCATION (target); 16784 tree c, *p, expr; 16785 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp; 16786 16787 if (teams == NULL_TREE) 16788 num_teams_upper = build_int_cst (integer_type_node, -2); 16789 else 16790 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c)) 16791 { 16792 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS) 16793 { 16794 p = &num_teams_upper; 16795 num_teams_loc = OMP_CLAUSE_LOCATION (c); 16796 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)) 16797 { 16798 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c); 16799 if (TREE_CODE (expr) == INTEGER_CST) 16800 num_teams_lower = expr; 16801 else if (walk_tree (&expr, computable_teams_clause, 16802 NULL, NULL)) 16803 num_teams_lower = integer_minus_one_node; 16804 else 16805 { 16806 num_teams_lower = expr; 16807 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context; 16808 if (gimplify_expr (&num_teams_lower, pre_p, NULL, 16809 is_gimple_val, fb_rvalue, false) 16810 == GS_ERROR) 16811 { 16812 gimplify_omp_ctxp = target_ctx; 16813 num_teams_lower = integer_minus_one_node; 16814 } 16815 else 16816 { 16817 gimplify_omp_ctxp = target_ctx; 16818 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR) 16819 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) 16820 = num_teams_lower; 16821 } 16822 } 16823 } 16824 } 16825 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) 16826 { 16827 p = &thread_limit; 16828 thread_limit_loc = OMP_CLAUSE_LOCATION (c); 16829 } 16830 else 16831 continue; 16832 expr = OMP_CLAUSE_OPERAND (c, 0); 16833 if (TREE_CODE (expr) == INTEGER_CST) 16834 { 16835 *p = expr; 16836 continue; 16837 } 16838 if (walk_tree (&expr, computable_teams_clause, NULL, NULL)) 16839 { 16840 *p = integer_minus_one_node; 16841 continue; 16842 } 16843 *p = expr; 16844 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context; 16845 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false) 16846 == GS_ERROR) 16847 { 16848 gimplify_omp_ctxp = target_ctx; 16849 *p = integer_minus_one_node; 16850 continue; 16851 } 16852 gimplify_omp_ctxp = target_ctx; 16853 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR) 16854 OMP_CLAUSE_OPERAND (c, 0) = *p; 16855 } 16856 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT)) 16857 { 16858 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT); 16859 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit; 16860 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); 16861 OMP_TARGET_CLAUSES (target) = c; 16862 } 16863 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); 16864 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper; 16865 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower; 16866 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); 16867 OMP_TARGET_CLAUSES (target) = c; 16868 } 16869 16870 /* Gimplify the gross structure of several OMP constructs. */ 16871 16872 static void 16873 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) 16874 { 16875 tree expr = *expr_p; 16876 gimple *stmt; 16877 gimple_seq body = NULL; 16878 enum omp_region_type ort; 16879 16880 switch (TREE_CODE (expr)) 16881 { 16882 case OMP_SECTIONS: 16883 case OMP_SINGLE: 16884 ort = ORT_WORKSHARE; 16885 break; 16886 case OMP_SCOPE: 16887 ort = ORT_TASKGROUP; 16888 break; 16889 case OMP_TARGET: 16890 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET; 16891 break; 16892 case OACC_KERNELS: 16893 ort = ORT_ACC_KERNELS; 16894 break; 16895 case OACC_PARALLEL: 16896 ort = ORT_ACC_PARALLEL; 16897 break; 16898 case OACC_SERIAL: 16899 ort = ORT_ACC_SERIAL; 16900 break; 16901 case OACC_DATA: 16902 ort = ORT_ACC_DATA; 16903 break; 16904 case OMP_TARGET_DATA: 16905 ort = ORT_TARGET_DATA; 16906 break; 16907 case OMP_TEAMS: 16908 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS; 16909 if (gimplify_omp_ctxp == NULL 16910 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET) 16911 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS); 16912 break; 16913 case OACC_HOST_DATA: 16914 ort = ORT_ACC_HOST_DATA; 16915 break; 16916 default: 16917 gcc_unreachable (); 16918 } 16919 16920 bool save_in_omp_construct = in_omp_construct; 16921 if ((ort & ORT_ACC) == 0) 16922 in_omp_construct = false; 16923 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort, 16924 TREE_CODE (expr)); 16925 if (TREE_CODE (expr) == OMP_TARGET) 16926 optimize_target_teams (expr, pre_p); 16927 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0 16928 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) 16929 { 16930 push_gimplify_context (); 16931 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body); 16932 if (gimple_code (g) == GIMPLE_BIND) 16933 pop_gimplify_context (g); 16934 else 16935 pop_gimplify_context (NULL); 16936 if ((ort & ORT_TARGET_DATA) != 0) 16937 { 16938 enum built_in_function end_ix; 16939 switch (TREE_CODE (expr)) 16940 { 16941 case OACC_DATA: 16942 case OACC_HOST_DATA: 16943 end_ix = BUILT_IN_GOACC_DATA_END; 16944 break; 16945 case OMP_TARGET_DATA: 16946 end_ix = BUILT_IN_GOMP_TARGET_END_DATA; 16947 break; 16948 default: 16949 gcc_unreachable (); 16950 } 16951 tree fn = builtin_decl_explicit (end_ix); 16952 g = gimple_build_call (fn, 0); 16953 gimple_seq cleanup = NULL; 16954 gimple_seq_add_stmt (&cleanup, g); 16955 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY); 16956 body = NULL; 16957 gimple_seq_add_stmt (&body, g); 16958 } 16959 } 16960 else 16961 gimplify_and_add (OMP_BODY (expr), &body); 16962 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr), 16963 TREE_CODE (expr)); 16964 in_omp_construct = save_in_omp_construct; 16965 16966 switch (TREE_CODE (expr)) 16967 { 16968 case OACC_DATA: 16969 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA, 16970 OMP_CLAUSES (expr)); 16971 break; 16972 case OACC_HOST_DATA: 16973 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT)) 16974 { 16975 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 16976 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR) 16977 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1; 16978 } 16979 16980 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA, 16981 OMP_CLAUSES (expr)); 16982 break; 16983 case OACC_KERNELS: 16984 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS, 16985 OMP_CLAUSES (expr)); 16986 break; 16987 case OACC_PARALLEL: 16988 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL, 16989 OMP_CLAUSES (expr)); 16990 break; 16991 case OACC_SERIAL: 16992 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL, 16993 OMP_CLAUSES (expr)); 16994 break; 16995 case OMP_SECTIONS: 16996 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr)); 16997 break; 16998 case OMP_SINGLE: 16999 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr)); 17000 break; 17001 case OMP_SCOPE: 17002 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr)); 17003 break; 17004 case OMP_TARGET: 17005 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION, 17006 OMP_CLAUSES (expr)); 17007 break; 17008 case OMP_TARGET_DATA: 17009 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed 17010 to be evaluated before the use_device_{ptr,addr} clauses if they 17011 refer to the same variables. */ 17012 { 17013 tree use_device_clauses; 17014 tree *pc, *uc = &use_device_clauses; 17015 for (pc = &OMP_CLAUSES (expr); *pc; ) 17016 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR 17017 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR) 17018 { 17019 *uc = *pc; 17020 *pc = OMP_CLAUSE_CHAIN (*pc); 17021 uc = &OMP_CLAUSE_CHAIN (*uc); 17022 } 17023 else 17024 pc = &OMP_CLAUSE_CHAIN (*pc); 17025 *uc = NULL_TREE; 17026 *pc = use_device_clauses; 17027 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA, 17028 OMP_CLAUSES (expr)); 17029 } 17030 break; 17031 case OMP_TEAMS: 17032 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr)); 17033 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) 17034 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true); 17035 break; 17036 default: 17037 gcc_unreachable (); 17038 } 17039 17040 gimplify_seq_add_stmt (pre_p, stmt); 17041 *expr_p = NULL_TREE; 17042 } 17043 17044 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP 17045 target update constructs. */ 17046 17047 static void 17048 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) 17049 { 17050 tree expr = *expr_p; 17051 int kind; 17052 gomp_target *stmt; 17053 enum omp_region_type ort = ORT_WORKSHARE; 17054 17055 switch (TREE_CODE (expr)) 17056 { 17057 case OACC_ENTER_DATA: 17058 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA; 17059 ort = ORT_ACC; 17060 break; 17061 case OACC_EXIT_DATA: 17062 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA; 17063 ort = ORT_ACC; 17064 break; 17065 case OACC_UPDATE: 17066 kind = GF_OMP_TARGET_KIND_OACC_UPDATE; 17067 ort = ORT_ACC; 17068 break; 17069 case OMP_TARGET_UPDATE: 17070 kind = GF_OMP_TARGET_KIND_UPDATE; 17071 break; 17072 case OMP_TARGET_ENTER_DATA: 17073 kind = GF_OMP_TARGET_KIND_ENTER_DATA; 17074 break; 17075 case OMP_TARGET_EXIT_DATA: 17076 kind = GF_OMP_TARGET_KIND_EXIT_DATA; 17077 break; 17078 default: 17079 gcc_unreachable (); 17080 } 17081 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p, 17082 ort, TREE_CODE (expr)); 17083 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr), 17084 TREE_CODE (expr)); 17085 if (TREE_CODE (expr) == OACC_UPDATE 17086 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr), 17087 OMP_CLAUSE_IF_PRESENT)) 17088 { 17089 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present 17090 clause. */ 17091 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17092 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP) 17093 switch (OMP_CLAUSE_MAP_KIND (c)) 17094 { 17095 case GOMP_MAP_FORCE_TO: 17096 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO); 17097 break; 17098 case GOMP_MAP_FORCE_FROM: 17099 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM); 17100 break; 17101 default: 17102 break; 17103 } 17104 } 17105 else if (TREE_CODE (expr) == OACC_EXIT_DATA 17106 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr), 17107 OMP_CLAUSE_FINALIZE)) 17108 { 17109 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize" 17110 semantics. */ 17111 bool have_clause = false; 17112 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17113 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP) 17114 switch (OMP_CLAUSE_MAP_KIND (c)) 17115 { 17116 case GOMP_MAP_FROM: 17117 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM); 17118 have_clause = true; 17119 break; 17120 case GOMP_MAP_RELEASE: 17121 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE); 17122 have_clause = true; 17123 break; 17124 case GOMP_MAP_TO_PSET: 17125 /* Fortran arrays with descriptors must map that descriptor when 17126 doing standalone "attach" operations (in OpenACC). In that 17127 case GOMP_MAP_TO_PSET appears by itself with no preceding 17128 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */ 17129 break; 17130 case GOMP_MAP_POINTER: 17131 /* TODO PR92929: we may see these here, but they'll always follow 17132 one of the clauses above, and will be handled by libgomp as 17133 one group, so no handling required here. */ 17134 gcc_assert (have_clause); 17135 break; 17136 case GOMP_MAP_DETACH: 17137 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH); 17138 have_clause = false; 17139 break; 17140 case GOMP_MAP_STRUCT: 17141 case GOMP_MAP_STRUCT_UNORD: 17142 have_clause = false; 17143 break; 17144 default: 17145 gcc_unreachable (); 17146 } 17147 } 17148 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr)); 17149 17150 gimplify_seq_add_stmt (pre_p, stmt); 17151 *expr_p = NULL_TREE; 17152 } 17153 17154 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have 17155 stabilized the lhs of the atomic operation as *ADDR. Return true if 17156 EXPR is this stabilized form. */ 17157 17158 static bool 17159 goa_lhs_expr_p (tree expr, tree addr) 17160 { 17161 /* Also include casts to other type variants. The C front end is fond 17162 of adding these for e.g. volatile variables. This is like 17163 STRIP_TYPE_NOPS but includes the main variant lookup. */ 17164 STRIP_USELESS_TYPE_CONVERSION (expr); 17165 17166 if (INDIRECT_REF_P (expr)) 17167 { 17168 expr = TREE_OPERAND (expr, 0); 17169 while (expr != addr 17170 && (CONVERT_EXPR_P (expr) 17171 || TREE_CODE (expr) == NON_LVALUE_EXPR) 17172 && TREE_CODE (expr) == TREE_CODE (addr) 17173 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr))) 17174 { 17175 expr = TREE_OPERAND (expr, 0); 17176 addr = TREE_OPERAND (addr, 0); 17177 } 17178 if (expr == addr) 17179 return true; 17180 return (TREE_CODE (addr) == ADDR_EXPR 17181 && TREE_CODE (expr) == ADDR_EXPR 17182 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0)); 17183 } 17184 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0)) 17185 return true; 17186 return false; 17187 } 17188 17189 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an 17190 expression does not involve the lhs, evaluate it into a temporary. 17191 Return 1 if the lhs appeared as a subexpression, 0 if it did not, 17192 or -1 if an error was encountered. */ 17193 17194 static int 17195 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr, 17196 tree lhs_var, tree &target_expr, bool rhs, int depth) 17197 { 17198 tree expr = *expr_p; 17199 int saw_lhs = 0; 17200 17201 if (goa_lhs_expr_p (expr, lhs_addr)) 17202 { 17203 if (pre_p) 17204 *expr_p = lhs_var; 17205 return 1; 17206 } 17207 if (is_gimple_val (expr)) 17208 return 0; 17209 17210 /* Maximum depth of lhs in expression is for the 17211 __builtin_clear_padding (...), __builtin_clear_padding (...), 17212 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */ 17213 if (++depth > 7) 17214 goto finish; 17215 17216 switch (TREE_CODE_CLASS (TREE_CODE (expr))) 17217 { 17218 case tcc_binary: 17219 case tcc_comparison: 17220 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr, 17221 lhs_var, target_expr, true, depth); 17222 /* FALLTHRU */ 17223 case tcc_unary: 17224 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr, 17225 lhs_var, target_expr, true, depth); 17226 break; 17227 case tcc_expression: 17228 switch (TREE_CODE (expr)) 17229 { 17230 case TRUTH_ANDIF_EXPR: 17231 case TRUTH_ORIF_EXPR: 17232 case TRUTH_AND_EXPR: 17233 case TRUTH_OR_EXPR: 17234 case TRUTH_XOR_EXPR: 17235 case BIT_INSERT_EXPR: 17236 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17237 lhs_addr, lhs_var, target_expr, true, 17238 depth); 17239 /* FALLTHRU */ 17240 case TRUTH_NOT_EXPR: 17241 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17242 lhs_addr, lhs_var, target_expr, true, 17243 depth); 17244 break; 17245 case MODIFY_EXPR: 17246 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var, 17247 target_expr, true, depth)) 17248 break; 17249 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17250 lhs_addr, lhs_var, target_expr, true, 17251 depth); 17252 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17253 lhs_addr, lhs_var, target_expr, false, 17254 depth); 17255 break; 17256 /* FALLTHRU */ 17257 case ADDR_EXPR: 17258 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var, 17259 target_expr, true, depth)) 17260 break; 17261 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17262 lhs_addr, lhs_var, target_expr, false, 17263 depth); 17264 break; 17265 case COMPOUND_EXPR: 17266 /* Break out any preevaluations from cp_build_modify_expr. */ 17267 for (; TREE_CODE (expr) == COMPOUND_EXPR; 17268 expr = TREE_OPERAND (expr, 1)) 17269 { 17270 /* Special-case __builtin_clear_padding call before 17271 __builtin_memcmp. */ 17272 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR) 17273 { 17274 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0)); 17275 if (fndecl 17276 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING) 17277 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))) 17278 && (!pre_p 17279 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, 17280 lhs_addr, lhs_var, 17281 target_expr, true, depth))) 17282 { 17283 if (pre_p) 17284 *expr_p = expr; 17285 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0), 17286 pre_p, lhs_addr, lhs_var, 17287 target_expr, true, depth); 17288 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), 17289 pre_p, lhs_addr, lhs_var, 17290 target_expr, rhs, depth); 17291 return saw_lhs; 17292 } 17293 } 17294 17295 if (pre_p) 17296 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p); 17297 } 17298 if (!pre_p) 17299 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var, 17300 target_expr, rhs, depth); 17301 *expr_p = expr; 17302 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var, 17303 target_expr, rhs, depth); 17304 case COND_EXPR: 17305 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr, 17306 lhs_var, target_expr, true, depth)) 17307 break; 17308 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17309 lhs_addr, lhs_var, target_expr, true, 17310 depth); 17311 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, 17312 lhs_addr, lhs_var, target_expr, true, 17313 depth); 17314 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p, 17315 lhs_addr, lhs_var, target_expr, true, 17316 depth); 17317 break; 17318 case TARGET_EXPR: 17319 if (TARGET_EXPR_INITIAL (expr)) 17320 { 17321 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, 17322 lhs_var, target_expr, true, 17323 depth)) 17324 break; 17325 if (expr == target_expr) 17326 saw_lhs = 1; 17327 else 17328 { 17329 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr), 17330 pre_p, lhs_addr, lhs_var, 17331 target_expr, true, depth); 17332 if (saw_lhs && target_expr == NULL_TREE && pre_p) 17333 target_expr = expr; 17334 } 17335 } 17336 break; 17337 default: 17338 break; 17339 } 17340 break; 17341 case tcc_reference: 17342 if (TREE_CODE (expr) == BIT_FIELD_REF 17343 || TREE_CODE (expr) == VIEW_CONVERT_EXPR) 17344 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, 17345 lhs_addr, lhs_var, target_expr, true, 17346 depth); 17347 break; 17348 case tcc_vl_exp: 17349 if (TREE_CODE (expr) == CALL_EXPR) 17350 { 17351 if (tree fndecl = get_callee_fndecl (expr)) 17352 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING, 17353 BUILT_IN_MEMCMP)) 17354 { 17355 int nargs = call_expr_nargs (expr); 17356 for (int i = 0; i < nargs; i++) 17357 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i), 17358 pre_p, lhs_addr, lhs_var, 17359 target_expr, true, depth); 17360 } 17361 } 17362 break; 17363 default: 17364 break; 17365 } 17366 17367 finish: 17368 if (saw_lhs == 0 && pre_p) 17369 { 17370 enum gimplify_status gs; 17371 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr))) 17372 { 17373 gimplify_stmt (&expr, pre_p); 17374 return saw_lhs; 17375 } 17376 else if (rhs) 17377 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue); 17378 else 17379 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue); 17380 if (gs != GS_ALL_DONE) 17381 saw_lhs = -1; 17382 } 17383 17384 return saw_lhs; 17385 } 17386 17387 /* Gimplify an OMP_ATOMIC statement. */ 17388 17389 static enum gimplify_status 17390 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p) 17391 { 17392 tree addr = TREE_OPERAND (*expr_p, 0); 17393 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ 17394 ? NULL : TREE_OPERAND (*expr_p, 1); 17395 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr))); 17396 tree tmp_load; 17397 gomp_atomic_load *loadstmt; 17398 gomp_atomic_store *storestmt; 17399 tree target_expr = NULL_TREE; 17400 17401 tmp_load = create_tmp_reg (type); 17402 if (rhs 17403 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr, 17404 true, 0) < 0) 17405 return GS_ERROR; 17406 17407 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue) 17408 != GS_ALL_DONE) 17409 return GS_ERROR; 17410 17411 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr, 17412 OMP_ATOMIC_MEMORY_ORDER (*expr_p)); 17413 gimplify_seq_add_stmt (pre_p, loadstmt); 17414 if (rhs) 17415 { 17416 /* BIT_INSERT_EXPR is not valid for non-integral bitfield 17417 representatives. Use BIT_FIELD_REF on the lhs instead. */ 17418 tree rhsarg = rhs; 17419 if (TREE_CODE (rhs) == COND_EXPR) 17420 rhsarg = TREE_OPERAND (rhs, 1); 17421 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR 17422 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load))) 17423 { 17424 tree bitpos = TREE_OPERAND (rhsarg, 2); 17425 tree op1 = TREE_OPERAND (rhsarg, 1); 17426 tree bitsize; 17427 tree tmp_store = tmp_load; 17428 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD) 17429 tmp_store = get_initialized_tmp_var (tmp_load, pre_p); 17430 if (INTEGRAL_TYPE_P (TREE_TYPE (op1))) 17431 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1))); 17432 else 17433 bitsize = TYPE_SIZE (TREE_TYPE (op1)); 17434 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load); 17435 tree t = build2_loc (EXPR_LOCATION (rhsarg), 17436 MODIFY_EXPR, void_type_node, 17437 build3_loc (EXPR_LOCATION (rhsarg), 17438 BIT_FIELD_REF, TREE_TYPE (op1), 17439 tmp_store, bitsize, bitpos), op1); 17440 if (TREE_CODE (rhs) == COND_EXPR) 17441 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node, 17442 TREE_OPERAND (rhs, 0), t, void_node); 17443 gimplify_and_add (t, pre_p); 17444 rhs = tmp_store; 17445 } 17446 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr; 17447 if (TREE_CODE (rhs) == COND_EXPR) 17448 gimplify_ctxp->allow_rhs_cond_expr = true; 17449 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL, 17450 is_gimple_val, fb_rvalue); 17451 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr; 17452 if (gs != GS_ALL_DONE) 17453 return GS_ERROR; 17454 } 17455 17456 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ) 17457 rhs = tmp_load; 17458 storestmt 17459 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p)); 17460 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p)) 17461 { 17462 gimple_omp_atomic_set_weak (loadstmt); 17463 gimple_omp_atomic_set_weak (storestmt); 17464 } 17465 gimplify_seq_add_stmt (pre_p, storestmt); 17466 switch (TREE_CODE (*expr_p)) 17467 { 17468 case OMP_ATOMIC_READ: 17469 case OMP_ATOMIC_CAPTURE_OLD: 17470 *expr_p = tmp_load; 17471 gimple_omp_atomic_set_need_value (loadstmt); 17472 break; 17473 case OMP_ATOMIC_CAPTURE_NEW: 17474 *expr_p = rhs; 17475 gimple_omp_atomic_set_need_value (storestmt); 17476 break; 17477 default: 17478 *expr_p = NULL; 17479 break; 17480 } 17481 17482 return GS_ALL_DONE; 17483 } 17484 17485 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the 17486 body, and adding some EH bits. */ 17487 17488 static enum gimplify_status 17489 gimplify_transaction (tree *expr_p, gimple_seq *pre_p) 17490 { 17491 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr); 17492 gimple *body_stmt; 17493 gtransaction *trans_stmt; 17494 gimple_seq body = NULL; 17495 int subcode = 0; 17496 17497 /* Wrap the transaction body in a BIND_EXPR so we have a context 17498 where to put decls for OMP. */ 17499 if (TREE_CODE (tbody) != BIND_EXPR) 17500 { 17501 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL); 17502 TREE_SIDE_EFFECTS (bind) = 1; 17503 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody)); 17504 TRANSACTION_EXPR_BODY (expr) = bind; 17505 } 17506 17507 push_gimplify_context (); 17508 temp = voidify_wrapper_expr (*expr_p, NULL); 17509 17510 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body); 17511 pop_gimplify_context (body_stmt); 17512 17513 trans_stmt = gimple_build_transaction (body); 17514 if (TRANSACTION_EXPR_OUTER (expr)) 17515 subcode = GTMA_IS_OUTER; 17516 else if (TRANSACTION_EXPR_RELAXED (expr)) 17517 subcode = GTMA_IS_RELAXED; 17518 gimple_transaction_set_subcode (trans_stmt, subcode); 17519 17520 gimplify_seq_add_stmt (pre_p, trans_stmt); 17521 17522 if (temp) 17523 { 17524 *expr_p = temp; 17525 return GS_OK; 17526 } 17527 17528 *expr_p = NULL_TREE; 17529 return GS_ALL_DONE; 17530 } 17531 17532 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY 17533 is the OMP_BODY of the original EXPR (which has already been 17534 gimplified so it's not present in the EXPR). 17535 17536 Return the gimplified GIMPLE_OMP_ORDERED tuple. */ 17537 17538 static gimple * 17539 gimplify_omp_ordered (tree expr, gimple_seq body) 17540 { 17541 tree c, decls; 17542 int failures = 0; 17543 unsigned int i; 17544 tree source_c = NULL_TREE; 17545 tree sink_c = NULL_TREE; 17546 17547 if (gimplify_omp_ctxp) 17548 { 17549 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) 17550 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17551 && gimplify_omp_ctxp->loop_iter_var.is_empty ()) 17552 { 17553 error_at (OMP_CLAUSE_LOCATION (c), 17554 "%<ordered%> construct with %qs clause must be " 17555 "closely nested inside a loop with %<ordered%> clause", 17556 OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross"); 17557 failures++; 17558 } 17559 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17560 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK) 17561 { 17562 bool fail = false; 17563 sink_c = c; 17564 if (OMP_CLAUSE_DECL (c) == NULL_TREE) 17565 continue; /* omp_cur_iteration - 1 */ 17566 for (decls = OMP_CLAUSE_DECL (c), i = 0; 17567 decls && TREE_CODE (decls) == TREE_LIST; 17568 decls = TREE_CHAIN (decls), ++i) 17569 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2) 17570 continue; 17571 else if (TREE_VALUE (decls) 17572 != gimplify_omp_ctxp->loop_iter_var[2 * i]) 17573 { 17574 error_at (OMP_CLAUSE_LOCATION (c), 17575 "variable %qE is not an iteration " 17576 "of outermost loop %d, expected %qE", 17577 TREE_VALUE (decls), i + 1, 17578 gimplify_omp_ctxp->loop_iter_var[2 * i]); 17579 fail = true; 17580 failures++; 17581 } 17582 else 17583 TREE_VALUE (decls) 17584 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1]; 17585 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2) 17586 { 17587 error_at (OMP_CLAUSE_LOCATION (c), 17588 "number of variables in %qs clause with " 17589 "%<sink%> modifier does not match number of " 17590 "iteration variables", 17591 OMP_CLAUSE_DOACROSS_DEPEND (c) 17592 ? "depend" : "doacross"); 17593 failures++; 17594 } 17595 } 17596 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS 17597 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE) 17598 { 17599 if (source_c) 17600 { 17601 error_at (OMP_CLAUSE_LOCATION (c), 17602 "more than one %qs clause with %<source%> " 17603 "modifier on an %<ordered%> construct", 17604 OMP_CLAUSE_DOACROSS_DEPEND (source_c) 17605 ? "depend" : "doacross"); 17606 failures++; 17607 } 17608 else 17609 source_c = c; 17610 } 17611 } 17612 if (source_c && sink_c) 17613 { 17614 error_at (OMP_CLAUSE_LOCATION (source_c), 17615 "%qs clause with %<source%> modifier specified " 17616 "together with %qs clauses with %<sink%> modifier " 17617 "on the same construct", 17618 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross", 17619 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross"); 17620 failures++; 17621 } 17622 17623 if (failures) 17624 return gimple_build_nop (); 17625 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr)); 17626 } 17627 17628 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the 17629 expression produces a value to be used as an operand inside a GIMPLE 17630 statement, the value will be stored back in *EXPR_P. This value will 17631 be a tree of class tcc_declaration, tcc_constant, tcc_reference or 17632 an SSA_NAME. The corresponding sequence of GIMPLE statements is 17633 emitted in PRE_P and POST_P. 17634 17635 Additionally, this process may overwrite parts of the input 17636 expression during gimplification. Ideally, it should be 17637 possible to do non-destructive gimplification. 17638 17639 EXPR_P points to the GENERIC expression to convert to GIMPLE. If 17640 the expression needs to evaluate to a value to be used as 17641 an operand in a GIMPLE statement, this value will be stored in 17642 *EXPR_P on exit. This happens when the caller specifies one 17643 of fb_lvalue or fb_rvalue fallback flags. 17644 17645 PRE_P will contain the sequence of GIMPLE statements corresponding 17646 to the evaluation of EXPR and all the side-effects that must 17647 be executed before the main expression. On exit, the last 17648 statement of PRE_P is the core statement being gimplified. For 17649 instance, when gimplifying 'if (++a)' the last statement in 17650 PRE_P will be 'if (t.1)' where t.1 is the result of 17651 pre-incrementing 'a'. 17652 17653 POST_P will contain the sequence of GIMPLE statements corresponding 17654 to the evaluation of all the side-effects that must be executed 17655 after the main expression. If this is NULL, the post 17656 side-effects are stored at the end of PRE_P. 17657 17658 The reason why the output is split in two is to handle post 17659 side-effects explicitly. In some cases, an expression may have 17660 inner and outer post side-effects which need to be emitted in 17661 an order different from the one given by the recursive 17662 traversal. For instance, for the expression (*p--)++ the post 17663 side-effects of '--' must actually occur *after* the post 17664 side-effects of '++'. However, gimplification will first visit 17665 the inner expression, so if a separate POST sequence was not 17666 used, the resulting sequence would be: 17667 17668 1 t.1 = *p 17669 2 p = p - 1 17670 3 t.2 = t.1 + 1 17671 4 *p = t.2 17672 17673 However, the post-decrement operation in line #2 must not be 17674 evaluated until after the store to *p at line #4, so the 17675 correct sequence should be: 17676 17677 1 t.1 = *p 17678 2 t.2 = t.1 + 1 17679 3 *p = t.2 17680 4 p = p - 1 17681 17682 So, by specifying a separate post queue, it is possible 17683 to emit the post side-effects in the correct order. 17684 If POST_P is NULL, an internal queue will be used. Before 17685 returning to the caller, the sequence POST_P is appended to 17686 the main output sequence PRE_P. 17687 17688 GIMPLE_TEST_F points to a function that takes a tree T and 17689 returns nonzero if T is in the GIMPLE form requested by the 17690 caller. The GIMPLE predicates are in gimple.cc. 17691 17692 FALLBACK tells the function what sort of a temporary we want if 17693 gimplification cannot produce an expression that complies with 17694 GIMPLE_TEST_F. 17695 17696 fb_none means that no temporary should be generated 17697 fb_rvalue means that an rvalue is OK to generate 17698 fb_lvalue means that an lvalue is OK to generate 17699 fb_either means that either is OK, but an lvalue is preferable. 17700 fb_mayfail means that gimplification may fail (in which case 17701 GS_ERROR will be returned) 17702 17703 The return value is either GS_ERROR or GS_ALL_DONE, since this 17704 function iterates until EXPR is completely gimplified or an error 17705 occurs. */ 17706 17707 enum gimplify_status 17708 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 17709 bool (*gimple_test_f) (tree), fallback_t fallback) 17710 { 17711 tree tmp; 17712 gimple_seq internal_pre = NULL; 17713 gimple_seq internal_post = NULL; 17714 tree save_expr; 17715 bool is_statement; 17716 location_t saved_location; 17717 enum gimplify_status ret; 17718 gimple_stmt_iterator pre_last_gsi, post_last_gsi; 17719 tree label; 17720 17721 save_expr = *expr_p; 17722 if (save_expr == NULL_TREE) 17723 return GS_ALL_DONE; 17724 17725 /* If we are gimplifying a top-level statement, PRE_P must be valid. */ 17726 is_statement = gimple_test_f == is_gimple_stmt; 17727 if (is_statement) 17728 gcc_assert (pre_p); 17729 17730 /* Consistency checks. */ 17731 if (gimple_test_f == is_gimple_reg) 17732 gcc_assert (fallback & (fb_rvalue | fb_lvalue)); 17733 else if (gimple_test_f == is_gimple_val 17734 || gimple_test_f == is_gimple_call_addr 17735 || gimple_test_f == is_gimple_condexpr_for_cond 17736 || gimple_test_f == is_gimple_mem_rhs 17737 || gimple_test_f == is_gimple_mem_rhs_or_call 17738 || gimple_test_f == is_gimple_reg_rhs 17739 || gimple_test_f == is_gimple_reg_rhs_or_call 17740 || gimple_test_f == is_gimple_asm_val 17741 || gimple_test_f == is_gimple_mem_ref_addr) 17742 gcc_assert (fallback & fb_rvalue); 17743 else if (gimple_test_f == is_gimple_min_lval 17744 || gimple_test_f == is_gimple_lvalue) 17745 gcc_assert (fallback & fb_lvalue); 17746 else if (gimple_test_f == is_gimple_addressable) 17747 gcc_assert (fallback & fb_either); 17748 else if (gimple_test_f == is_gimple_stmt) 17749 gcc_assert (fallback == fb_none); 17750 else 17751 { 17752 /* We should have recognized the GIMPLE_TEST_F predicate to 17753 know what kind of fallback to use in case a temporary is 17754 needed to hold the value or address of *EXPR_P. */ 17755 gcc_unreachable (); 17756 } 17757 17758 /* We used to check the predicate here and return immediately if it 17759 succeeds. This is wrong; the design is for gimplification to be 17760 idempotent, and for the predicates to only test for valid forms, not 17761 whether they are fully simplified. */ 17762 if (pre_p == NULL) 17763 pre_p = &internal_pre; 17764 17765 if (post_p == NULL) 17766 post_p = &internal_post; 17767 17768 /* Remember the last statements added to PRE_P and POST_P. Every 17769 new statement added by the gimplification helpers needs to be 17770 annotated with location information. To centralize the 17771 responsibility, we remember the last statement that had been 17772 added to both queues before gimplifying *EXPR_P. If 17773 gimplification produces new statements in PRE_P and POST_P, those 17774 statements will be annotated with the same location information 17775 as *EXPR_P. */ 17776 pre_last_gsi = gsi_last (*pre_p); 17777 post_last_gsi = gsi_last (*post_p); 17778 17779 saved_location = input_location; 17780 if (save_expr != error_mark_node 17781 && EXPR_HAS_LOCATION (*expr_p)) 17782 input_location = EXPR_LOCATION (*expr_p); 17783 17784 /* Loop over the specific gimplifiers until the toplevel node 17785 remains the same. */ 17786 do 17787 { 17788 /* Strip away as many useless type conversions as possible 17789 at the toplevel. */ 17790 STRIP_USELESS_TYPE_CONVERSION (*expr_p); 17791 17792 /* Remember the expr. */ 17793 save_expr = *expr_p; 17794 17795 /* Die, die, die, my darling. */ 17796 if (error_operand_p (save_expr)) 17797 { 17798 ret = GS_ERROR; 17799 break; 17800 } 17801 17802 /* Do any language-specific gimplification. */ 17803 ret = ((enum gimplify_status) 17804 lang_hooks.gimplify_expr (expr_p, pre_p, post_p)); 17805 if (ret == GS_OK) 17806 { 17807 if (*expr_p == NULL_TREE) 17808 break; 17809 if (*expr_p != save_expr) 17810 continue; 17811 } 17812 else if (ret != GS_UNHANDLED) 17813 break; 17814 17815 /* Make sure that all the cases set 'ret' appropriately. */ 17816 ret = GS_UNHANDLED; 17817 switch (TREE_CODE (*expr_p)) 17818 { 17819 /* First deal with the special cases. */ 17820 17821 case POSTINCREMENT_EXPR: 17822 case POSTDECREMENT_EXPR: 17823 case PREINCREMENT_EXPR: 17824 case PREDECREMENT_EXPR: 17825 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p, 17826 fallback != fb_none, 17827 TREE_TYPE (*expr_p)); 17828 break; 17829 17830 case VIEW_CONVERT_EXPR: 17831 if ((fallback & fb_rvalue) 17832 && is_gimple_reg_type (TREE_TYPE (*expr_p)) 17833 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) 17834 { 17835 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 17836 post_p, is_gimple_val, fb_rvalue); 17837 recalculate_side_effects (*expr_p); 17838 break; 17839 } 17840 /* Fallthru. */ 17841 17842 case ARRAY_REF: 17843 case ARRAY_RANGE_REF: 17844 case REALPART_EXPR: 17845 case IMAGPART_EXPR: 17846 case COMPONENT_REF: 17847 ret = gimplify_compound_lval (expr_p, pre_p, post_p, 17848 fallback ? fallback : fb_rvalue); 17849 break; 17850 17851 case COND_EXPR: 17852 ret = gimplify_cond_expr (expr_p, pre_p, fallback); 17853 17854 /* C99 code may assign to an array in a structure value of a 17855 conditional expression, and this has undefined behavior 17856 only on execution, so create a temporary if an lvalue is 17857 required. */ 17858 if (fallback == fb_lvalue) 17859 { 17860 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 17861 mark_addressable (*expr_p); 17862 ret = GS_OK; 17863 } 17864 break; 17865 17866 case CALL_EXPR: 17867 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); 17868 17869 /* C99 code may assign to an array in a structure returned 17870 from a function, and this has undefined behavior only on 17871 execution, so create a temporary if an lvalue is 17872 required. */ 17873 if (fallback == fb_lvalue) 17874 { 17875 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 17876 mark_addressable (*expr_p); 17877 ret = GS_OK; 17878 } 17879 break; 17880 17881 case TREE_LIST: 17882 gcc_unreachable (); 17883 17884 case OMP_ARRAY_SECTION: 17885 gcc_unreachable (); 17886 17887 case COMPOUND_EXPR: 17888 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); 17889 break; 17890 17891 case COMPOUND_LITERAL_EXPR: 17892 ret = gimplify_compound_literal_expr (expr_p, pre_p, 17893 gimple_test_f, fallback); 17894 break; 17895 17896 case MODIFY_EXPR: 17897 case INIT_EXPR: 17898 ret = gimplify_modify_expr (expr_p, pre_p, post_p, 17899 fallback != fb_none); 17900 break; 17901 17902 case TRUTH_ANDIF_EXPR: 17903 case TRUTH_ORIF_EXPR: 17904 { 17905 /* Preserve the original type of the expression and the 17906 source location of the outer expression. */ 17907 tree org_type = TREE_TYPE (*expr_p); 17908 *expr_p = gimple_boolify (*expr_p); 17909 *expr_p = build3_loc (input_location, COND_EXPR, 17910 org_type, *expr_p, 17911 fold_convert_loc 17912 (input_location, 17913 org_type, boolean_true_node), 17914 fold_convert_loc 17915 (input_location, 17916 org_type, boolean_false_node)); 17917 ret = GS_OK; 17918 break; 17919 } 17920 17921 case TRUTH_NOT_EXPR: 17922 { 17923 tree type = TREE_TYPE (*expr_p); 17924 /* The parsers are careful to generate TRUTH_NOT_EXPR 17925 only with operands that are always zero or one. 17926 We do not fold here but handle the only interesting case 17927 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */ 17928 *expr_p = gimple_boolify (*expr_p); 17929 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1) 17930 *expr_p = build1_loc (input_location, BIT_NOT_EXPR, 17931 TREE_TYPE (*expr_p), 17932 TREE_OPERAND (*expr_p, 0)); 17933 else 17934 *expr_p = build2_loc (input_location, BIT_XOR_EXPR, 17935 TREE_TYPE (*expr_p), 17936 TREE_OPERAND (*expr_p, 0), 17937 build_int_cst (TREE_TYPE (*expr_p), 1)); 17938 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p))) 17939 *expr_p = fold_convert_loc (input_location, type, *expr_p); 17940 ret = GS_OK; 17941 break; 17942 } 17943 17944 case ADDR_EXPR: 17945 ret = gimplify_addr_expr (expr_p, pre_p, post_p); 17946 break; 17947 17948 case ANNOTATE_EXPR: 17949 { 17950 tree cond = TREE_OPERAND (*expr_p, 0); 17951 tree kind = TREE_OPERAND (*expr_p, 1); 17952 tree data = TREE_OPERAND (*expr_p, 2); 17953 tree type = TREE_TYPE (cond); 17954 if (!INTEGRAL_TYPE_P (type)) 17955 { 17956 *expr_p = cond; 17957 ret = GS_OK; 17958 break; 17959 } 17960 tree tmp = create_tmp_var (type); 17961 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); 17962 gcall *call 17963 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data); 17964 gimple_call_set_lhs (call, tmp); 17965 gimplify_seq_add_stmt (pre_p, call); 17966 *expr_p = tmp; 17967 ret = GS_ALL_DONE; 17968 break; 17969 } 17970 17971 case VA_ARG_EXPR: 17972 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p); 17973 break; 17974 17975 CASE_CONVERT: 17976 if (IS_EMPTY_STMT (*expr_p)) 17977 { 17978 ret = GS_ALL_DONE; 17979 break; 17980 } 17981 17982 if (VOID_TYPE_P (TREE_TYPE (*expr_p)) 17983 || fallback == fb_none) 17984 { 17985 /* Just strip a conversion to void (or in void context) and 17986 try again. */ 17987 *expr_p = TREE_OPERAND (*expr_p, 0); 17988 ret = GS_OK; 17989 break; 17990 } 17991 17992 ret = gimplify_conversion (expr_p); 17993 if (ret == GS_ERROR) 17994 break; 17995 if (*expr_p != save_expr) 17996 break; 17997 /* FALLTHRU */ 17998 17999 case FIX_TRUNC_EXPR: 18000 /* unary_expr: ... | '(' cast ')' val | ... */ 18001 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18002 is_gimple_val, fb_rvalue); 18003 recalculate_side_effects (*expr_p); 18004 break; 18005 18006 case INDIRECT_REF: 18007 { 18008 bool volatilep = TREE_THIS_VOLATILE (*expr_p); 18009 bool notrap = TREE_THIS_NOTRAP (*expr_p); 18010 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0)); 18011 18012 *expr_p = fold_indirect_ref_loc (input_location, *expr_p); 18013 if (*expr_p != save_expr) 18014 { 18015 ret = GS_OK; 18016 break; 18017 } 18018 18019 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18020 is_gimple_reg, fb_rvalue); 18021 if (ret == GS_ERROR) 18022 break; 18023 18024 recalculate_side_effects (*expr_p); 18025 *expr_p = fold_build2_loc (input_location, MEM_REF, 18026 TREE_TYPE (*expr_p), 18027 TREE_OPERAND (*expr_p, 0), 18028 build_int_cst (saved_ptr_type, 0)); 18029 TREE_THIS_VOLATILE (*expr_p) = volatilep; 18030 TREE_THIS_NOTRAP (*expr_p) = notrap; 18031 ret = GS_OK; 18032 break; 18033 } 18034 18035 /* We arrive here through the various re-gimplifcation paths. */ 18036 case MEM_REF: 18037 /* First try re-folding the whole thing. */ 18038 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p), 18039 TREE_OPERAND (*expr_p, 0), 18040 TREE_OPERAND (*expr_p, 1)); 18041 if (tmp) 18042 { 18043 REF_REVERSE_STORAGE_ORDER (tmp) 18044 = REF_REVERSE_STORAGE_ORDER (*expr_p); 18045 *expr_p = tmp; 18046 recalculate_side_effects (*expr_p); 18047 ret = GS_OK; 18048 break; 18049 } 18050 /* Avoid re-gimplifying the address operand if it is already 18051 in suitable form. Re-gimplifying would mark the address 18052 operand addressable. Always gimplify when not in SSA form 18053 as we still may have to gimplify decls with value-exprs. */ 18054 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun) 18055 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0))) 18056 { 18057 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18058 is_gimple_mem_ref_addr, fb_rvalue); 18059 if (ret == GS_ERROR) 18060 break; 18061 } 18062 recalculate_side_effects (*expr_p); 18063 ret = GS_ALL_DONE; 18064 break; 18065 18066 /* Constants need not be gimplified. */ 18067 case INTEGER_CST: 18068 case REAL_CST: 18069 case FIXED_CST: 18070 case STRING_CST: 18071 case COMPLEX_CST: 18072 case VECTOR_CST: 18073 /* Drop the overflow flag on constants, we do not want 18074 that in the GIMPLE IL. */ 18075 if (TREE_OVERFLOW_P (*expr_p)) 18076 *expr_p = drop_tree_overflow (*expr_p); 18077 ret = GS_ALL_DONE; 18078 break; 18079 18080 case CONST_DECL: 18081 /* If we require an lvalue, such as for ADDR_EXPR, retain the 18082 CONST_DECL node. Otherwise the decl is replaceable by its 18083 value. */ 18084 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */ 18085 if (fallback & fb_lvalue) 18086 ret = GS_ALL_DONE; 18087 else 18088 { 18089 *expr_p = DECL_INITIAL (*expr_p); 18090 ret = GS_OK; 18091 } 18092 break; 18093 18094 case DECL_EXPR: 18095 ret = gimplify_decl_expr (expr_p, pre_p); 18096 break; 18097 18098 case BIND_EXPR: 18099 ret = gimplify_bind_expr (expr_p, pre_p); 18100 break; 18101 18102 case LOOP_EXPR: 18103 ret = gimplify_loop_expr (expr_p, pre_p); 18104 break; 18105 18106 case SWITCH_EXPR: 18107 ret = gimplify_switch_expr (expr_p, pre_p); 18108 break; 18109 18110 case EXIT_EXPR: 18111 ret = gimplify_exit_expr (expr_p); 18112 break; 18113 18114 case GOTO_EXPR: 18115 /* If the target is not LABEL, then it is a computed jump 18116 and the target needs to be gimplified. */ 18117 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL) 18118 { 18119 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p, 18120 NULL, is_gimple_val, fb_rvalue); 18121 if (ret == GS_ERROR) 18122 break; 18123 } 18124 gimplify_seq_add_stmt (pre_p, 18125 gimple_build_goto (GOTO_DESTINATION (*expr_p))); 18126 ret = GS_ALL_DONE; 18127 break; 18128 18129 case PREDICT_EXPR: 18130 gimplify_seq_add_stmt (pre_p, 18131 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p), 18132 PREDICT_EXPR_OUTCOME (*expr_p))); 18133 ret = GS_ALL_DONE; 18134 break; 18135 18136 case LABEL_EXPR: 18137 ret = gimplify_label_expr (expr_p, pre_p); 18138 label = LABEL_EXPR_LABEL (*expr_p); 18139 gcc_assert (decl_function_context (label) == current_function_decl); 18140 18141 /* If the label is used in a goto statement, or address of the label 18142 is taken, we need to unpoison all variables that were seen so far. 18143 Doing so would prevent us from reporting a false positives. */ 18144 if (asan_poisoned_variables 18145 && asan_used_labels != NULL 18146 && asan_used_labels->contains (label) 18147 && !gimplify_omp_ctxp) 18148 asan_poison_variables (asan_poisoned_variables, false, pre_p); 18149 break; 18150 18151 case CASE_LABEL_EXPR: 18152 ret = gimplify_case_label_expr (expr_p, pre_p); 18153 18154 if (gimplify_ctxp->live_switch_vars) 18155 asan_poison_variables (gimplify_ctxp->live_switch_vars, false, 18156 pre_p); 18157 break; 18158 18159 case RETURN_EXPR: 18160 ret = gimplify_return_expr (*expr_p, pre_p); 18161 break; 18162 18163 case CONSTRUCTOR: 18164 /* Don't reduce this in place; let gimplify_init_constructor work its 18165 magic. Buf if we're just elaborating this for side effects, just 18166 gimplify any element that has side-effects. */ 18167 if (fallback == fb_none) 18168 { 18169 unsigned HOST_WIDE_INT ix; 18170 tree val; 18171 tree temp = NULL_TREE; 18172 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val) 18173 if (TREE_SIDE_EFFECTS (val)) 18174 append_to_statement_list (val, &temp); 18175 18176 *expr_p = temp; 18177 ret = temp ? GS_OK : GS_ALL_DONE; 18178 } 18179 /* C99 code may assign to an array in a constructed 18180 structure or union, and this has undefined behavior only 18181 on execution, so create a temporary if an lvalue is 18182 required. */ 18183 else if (fallback == fb_lvalue) 18184 { 18185 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false); 18186 mark_addressable (*expr_p); 18187 ret = GS_OK; 18188 } 18189 else 18190 ret = GS_ALL_DONE; 18191 break; 18192 18193 /* The following are special cases that are not handled by the 18194 original GIMPLE grammar. */ 18195 18196 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and 18197 eliminated. */ 18198 case SAVE_EXPR: 18199 ret = gimplify_save_expr (expr_p, pre_p, post_p); 18200 break; 18201 18202 case BIT_FIELD_REF: 18203 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18204 post_p, is_gimple_lvalue, fb_either); 18205 recalculate_side_effects (*expr_p); 18206 break; 18207 18208 case TARGET_MEM_REF: 18209 { 18210 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE; 18211 18212 if (TMR_BASE (*expr_p)) 18213 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p, 18214 post_p, is_gimple_mem_ref_addr, fb_either); 18215 if (TMR_INDEX (*expr_p)) 18216 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p, 18217 post_p, is_gimple_val, fb_rvalue); 18218 if (TMR_INDEX2 (*expr_p)) 18219 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p, 18220 post_p, is_gimple_val, fb_rvalue); 18221 /* TMR_STEP and TMR_OFFSET are always integer constants. */ 18222 ret = MIN (r0, r1); 18223 } 18224 break; 18225 18226 case NON_LVALUE_EXPR: 18227 /* This should have been stripped above. */ 18228 gcc_unreachable (); 18229 18230 case ASM_EXPR: 18231 ret = gimplify_asm_expr (expr_p, pre_p, post_p); 18232 break; 18233 18234 case TRY_FINALLY_EXPR: 18235 case TRY_CATCH_EXPR: 18236 { 18237 gimple_seq eval, cleanup; 18238 gtry *try_; 18239 18240 /* Calls to destructors are generated automatically in FINALLY/CATCH 18241 block. They should have location as UNKNOWN_LOCATION. However, 18242 gimplify_call_expr will reset these call stmts to input_location 18243 if it finds stmt's location is unknown. To prevent resetting for 18244 destructors, we set the input_location to unknown. 18245 Note that this only affects the destructor calls in FINALLY/CATCH 18246 block, and will automatically reset to its original value by the 18247 end of gimplify_expr. */ 18248 input_location = UNKNOWN_LOCATION; 18249 eval = cleanup = NULL; 18250 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval); 18251 bool save_in_handler_expr = gimplify_ctxp->in_handler_expr; 18252 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR 18253 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR) 18254 { 18255 gimple_seq n = NULL, e = NULL; 18256 gimplify_ctxp->in_handler_expr = true; 18257 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1), 18258 0), &n); 18259 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1), 18260 1), &e); 18261 if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e)) 18262 { 18263 geh_else *stmt = gimple_build_eh_else (n, e); 18264 gimple_seq_add_stmt (&cleanup, stmt); 18265 } 18266 } 18267 else 18268 { 18269 gimplify_ctxp->in_handler_expr = true; 18270 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup); 18271 } 18272 gimplify_ctxp->in_handler_expr = save_in_handler_expr; 18273 /* Don't create bogus GIMPLE_TRY with empty cleanup. */ 18274 if (gimple_seq_empty_p (cleanup)) 18275 { 18276 gimple_seq_add_seq (pre_p, eval); 18277 ret = GS_ALL_DONE; 18278 break; 18279 } 18280 try_ = gimple_build_try (eval, cleanup, 18281 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR 18282 ? GIMPLE_TRY_FINALLY 18283 : GIMPLE_TRY_CATCH); 18284 if (EXPR_HAS_LOCATION (save_expr)) 18285 gimple_set_location (try_, EXPR_LOCATION (save_expr)); 18286 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION) 18287 gimple_set_location (try_, saved_location); 18288 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR) 18289 gimple_try_set_catch_is_cleanup (try_, 18290 TRY_CATCH_IS_CLEANUP (*expr_p)); 18291 gimplify_seq_add_stmt (pre_p, try_); 18292 ret = GS_ALL_DONE; 18293 break; 18294 } 18295 18296 case CLEANUP_POINT_EXPR: 18297 ret = gimplify_cleanup_point_expr (expr_p, pre_p); 18298 break; 18299 18300 case TARGET_EXPR: 18301 ret = gimplify_target_expr (expr_p, pre_p, post_p); 18302 break; 18303 18304 case CATCH_EXPR: 18305 { 18306 gimple *c; 18307 gimple_seq handler = NULL; 18308 gimplify_and_add (CATCH_BODY (*expr_p), &handler); 18309 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler); 18310 gimplify_seq_add_stmt (pre_p, c); 18311 ret = GS_ALL_DONE; 18312 break; 18313 } 18314 18315 case EH_FILTER_EXPR: 18316 { 18317 gimple *ehf; 18318 gimple_seq failure = NULL; 18319 18320 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure); 18321 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure); 18322 copy_warning (ehf, *expr_p); 18323 gimplify_seq_add_stmt (pre_p, ehf); 18324 ret = GS_ALL_DONE; 18325 break; 18326 } 18327 18328 case OBJ_TYPE_REF: 18329 { 18330 enum gimplify_status r0, r1; 18331 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, 18332 post_p, is_gimple_val, fb_rvalue); 18333 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, 18334 post_p, is_gimple_val, fb_rvalue); 18335 TREE_SIDE_EFFECTS (*expr_p) = 0; 18336 ret = MIN (r0, r1); 18337 } 18338 break; 18339 18340 case LABEL_DECL: 18341 /* We get here when taking the address of a label. We mark 18342 the label as "forced"; meaning it can never be removed and 18343 it is a potential target for any computed goto. */ 18344 FORCED_LABEL (*expr_p) = 1; 18345 ret = GS_ALL_DONE; 18346 break; 18347 18348 case STATEMENT_LIST: 18349 ret = gimplify_statement_list (expr_p, pre_p); 18350 break; 18351 18352 case WITH_SIZE_EXPR: 18353 { 18354 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18355 post_p == &internal_post ? NULL : post_p, 18356 gimple_test_f, fallback); 18357 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 18358 is_gimple_val, fb_rvalue); 18359 ret = GS_ALL_DONE; 18360 } 18361 break; 18362 18363 case VAR_DECL: 18364 case PARM_DECL: 18365 ret = gimplify_var_or_parm_decl (expr_p); 18366 break; 18367 18368 case RESULT_DECL: 18369 /* When within an OMP context, notice uses of variables. */ 18370 if (gimplify_omp_ctxp) 18371 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true); 18372 /* Handlers can refer to the function result; if that has been 18373 moved, we need to track it. */ 18374 if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp) 18375 *expr_p = gimplify_ctxp->return_temp; 18376 ret = GS_ALL_DONE; 18377 break; 18378 18379 case DEBUG_EXPR_DECL: 18380 gcc_unreachable (); 18381 18382 case DEBUG_BEGIN_STMT: 18383 gimplify_seq_add_stmt (pre_p, 18384 gimple_build_debug_begin_stmt 18385 (TREE_BLOCK (*expr_p), 18386 EXPR_LOCATION (*expr_p))); 18387 ret = GS_ALL_DONE; 18388 *expr_p = NULL; 18389 break; 18390 18391 case SSA_NAME: 18392 /* Allow callbacks into the gimplifier during optimization. */ 18393 ret = GS_ALL_DONE; 18394 break; 18395 18396 case OMP_PARALLEL: 18397 gimplify_omp_parallel (expr_p, pre_p); 18398 ret = GS_ALL_DONE; 18399 break; 18400 18401 case OMP_TASK: 18402 gimplify_omp_task (expr_p, pre_p); 18403 ret = GS_ALL_DONE; 18404 break; 18405 18406 case OMP_SIMD: 18407 { 18408 /* Temporarily disable into_ssa, as scan_omp_simd 18409 which calls copy_gimple_seq_and_replace_locals can't deal 18410 with SSA_NAMEs defined outside of the body properly. */ 18411 bool saved_into_ssa = gimplify_ctxp->into_ssa; 18412 gimplify_ctxp->into_ssa = false; 18413 ret = gimplify_omp_for (expr_p, pre_p); 18414 gimplify_ctxp->into_ssa = saved_into_ssa; 18415 break; 18416 } 18417 18418 case OMP_FOR: 18419 case OMP_DISTRIBUTE: 18420 case OMP_TASKLOOP: 18421 case OACC_LOOP: 18422 ret = gimplify_omp_for (expr_p, pre_p); 18423 break; 18424 18425 case OMP_LOOP: 18426 ret = gimplify_omp_loop (expr_p, pre_p); 18427 break; 18428 18429 case OACC_CACHE: 18430 gimplify_oacc_cache (expr_p, pre_p); 18431 ret = GS_ALL_DONE; 18432 break; 18433 18434 case OACC_DECLARE: 18435 gimplify_oacc_declare (expr_p, pre_p); 18436 ret = GS_ALL_DONE; 18437 break; 18438 18439 case OACC_HOST_DATA: 18440 case OACC_DATA: 18441 case OACC_KERNELS: 18442 case OACC_PARALLEL: 18443 case OACC_SERIAL: 18444 case OMP_SCOPE: 18445 case OMP_SECTIONS: 18446 case OMP_SINGLE: 18447 case OMP_TARGET: 18448 case OMP_TARGET_DATA: 18449 case OMP_TEAMS: 18450 gimplify_omp_workshare (expr_p, pre_p); 18451 ret = GS_ALL_DONE; 18452 break; 18453 18454 case OACC_ENTER_DATA: 18455 case OACC_EXIT_DATA: 18456 case OACC_UPDATE: 18457 case OMP_TARGET_UPDATE: 18458 case OMP_TARGET_ENTER_DATA: 18459 case OMP_TARGET_EXIT_DATA: 18460 gimplify_omp_target_update (expr_p, pre_p); 18461 ret = GS_ALL_DONE; 18462 break; 18463 18464 case OMP_SECTION: 18465 case OMP_STRUCTURED_BLOCK: 18466 case OMP_MASTER: 18467 case OMP_MASKED: 18468 case OMP_ORDERED: 18469 case OMP_CRITICAL: 18470 case OMP_SCAN: 18471 { 18472 gimple_seq body = NULL; 18473 gimple *g; 18474 bool saved_in_omp_construct = in_omp_construct; 18475 18476 in_omp_construct = true; 18477 gimplify_and_add (OMP_BODY (*expr_p), &body); 18478 in_omp_construct = saved_in_omp_construct; 18479 switch (TREE_CODE (*expr_p)) 18480 { 18481 case OMP_SECTION: 18482 g = gimple_build_omp_section (body); 18483 break; 18484 case OMP_STRUCTURED_BLOCK: 18485 g = gimple_build_omp_structured_block (body); 18486 break; 18487 case OMP_MASTER: 18488 g = gimple_build_omp_master (body); 18489 break; 18490 case OMP_ORDERED: 18491 g = gimplify_omp_ordered (*expr_p, body); 18492 if (OMP_BODY (*expr_p) == NULL_TREE 18493 && gimple_code (g) == GIMPLE_OMP_ORDERED) 18494 gimple_omp_ordered_standalone (g); 18495 break; 18496 case OMP_MASKED: 18497 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p), 18498 pre_p, ORT_WORKSHARE, OMP_MASKED); 18499 gimplify_adjust_omp_clauses (pre_p, body, 18500 &OMP_MASKED_CLAUSES (*expr_p), 18501 OMP_MASKED); 18502 g = gimple_build_omp_masked (body, 18503 OMP_MASKED_CLAUSES (*expr_p)); 18504 break; 18505 case OMP_CRITICAL: 18506 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p), 18507 pre_p, ORT_WORKSHARE, OMP_CRITICAL); 18508 gimplify_adjust_omp_clauses (pre_p, body, 18509 &OMP_CRITICAL_CLAUSES (*expr_p), 18510 OMP_CRITICAL); 18511 g = gimple_build_omp_critical (body, 18512 OMP_CRITICAL_NAME (*expr_p), 18513 OMP_CRITICAL_CLAUSES (*expr_p)); 18514 break; 18515 case OMP_SCAN: 18516 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p), 18517 pre_p, ORT_WORKSHARE, OMP_SCAN); 18518 gimplify_adjust_omp_clauses (pre_p, body, 18519 &OMP_SCAN_CLAUSES (*expr_p), 18520 OMP_SCAN); 18521 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p)); 18522 break; 18523 default: 18524 gcc_unreachable (); 18525 } 18526 gimplify_seq_add_stmt (pre_p, g); 18527 ret = GS_ALL_DONE; 18528 break; 18529 } 18530 18531 case OMP_TASKGROUP: 18532 { 18533 gimple_seq body = NULL; 18534 18535 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p); 18536 bool saved_in_omp_construct = in_omp_construct; 18537 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP, 18538 OMP_TASKGROUP); 18539 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP); 18540 18541 in_omp_construct = true; 18542 gimplify_and_add (OMP_BODY (*expr_p), &body); 18543 in_omp_construct = saved_in_omp_construct; 18544 gimple_seq cleanup = NULL; 18545 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END); 18546 gimple *g = gimple_build_call (fn, 0); 18547 gimple_seq_add_stmt (&cleanup, g); 18548 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY); 18549 body = NULL; 18550 gimple_seq_add_stmt (&body, g); 18551 g = gimple_build_omp_taskgroup (body, *pclauses); 18552 gimplify_seq_add_stmt (pre_p, g); 18553 ret = GS_ALL_DONE; 18554 break; 18555 } 18556 18557 case OMP_ATOMIC: 18558 case OMP_ATOMIC_READ: 18559 case OMP_ATOMIC_CAPTURE_OLD: 18560 case OMP_ATOMIC_CAPTURE_NEW: 18561 ret = gimplify_omp_atomic (expr_p, pre_p); 18562 break; 18563 18564 case TRANSACTION_EXPR: 18565 ret = gimplify_transaction (expr_p, pre_p); 18566 break; 18567 18568 case TRUTH_AND_EXPR: 18569 case TRUTH_OR_EXPR: 18570 case TRUTH_XOR_EXPR: 18571 { 18572 tree orig_type = TREE_TYPE (*expr_p); 18573 tree new_type, xop0, xop1; 18574 *expr_p = gimple_boolify (*expr_p); 18575 new_type = TREE_TYPE (*expr_p); 18576 if (!useless_type_conversion_p (orig_type, new_type)) 18577 { 18578 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p); 18579 ret = GS_OK; 18580 break; 18581 } 18582 18583 /* Boolified binary truth expressions are semantically equivalent 18584 to bitwise binary expressions. Canonicalize them to the 18585 bitwise variant. */ 18586 switch (TREE_CODE (*expr_p)) 18587 { 18588 case TRUTH_AND_EXPR: 18589 TREE_SET_CODE (*expr_p, BIT_AND_EXPR); 18590 break; 18591 case TRUTH_OR_EXPR: 18592 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR); 18593 break; 18594 case TRUTH_XOR_EXPR: 18595 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR); 18596 break; 18597 default: 18598 break; 18599 } 18600 /* Now make sure that operands have compatible type to 18601 expression's new_type. */ 18602 xop0 = TREE_OPERAND (*expr_p, 0); 18603 xop1 = TREE_OPERAND (*expr_p, 1); 18604 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0))) 18605 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location, 18606 new_type, 18607 xop0); 18608 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1))) 18609 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location, 18610 new_type, 18611 xop1); 18612 /* Continue classified as tcc_binary. */ 18613 goto expr_2; 18614 } 18615 18616 case VEC_COND_EXPR: 18617 goto expr_3; 18618 18619 case VEC_PERM_EXPR: 18620 /* Classified as tcc_expression. */ 18621 goto expr_3; 18622 18623 case BIT_INSERT_EXPR: 18624 /* Argument 3 is a constant. */ 18625 goto expr_2; 18626 18627 case POINTER_PLUS_EXPR: 18628 { 18629 enum gimplify_status r0, r1; 18630 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18631 post_p, is_gimple_val, fb_rvalue); 18632 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18633 post_p, is_gimple_val, fb_rvalue); 18634 recalculate_side_effects (*expr_p); 18635 ret = MIN (r0, r1); 18636 break; 18637 } 18638 18639 default: 18640 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p))) 18641 { 18642 case tcc_comparison: 18643 /* Handle comparison of objects of non scalar mode aggregates 18644 with a call to memcmp. It would be nice to only have to do 18645 this for variable-sized objects, but then we'd have to allow 18646 the same nest of reference nodes we allow for MODIFY_EXPR and 18647 that's too complex. 18648 18649 Compare scalar mode aggregates as scalar mode values. Using 18650 memcmp for them would be very inefficient at best, and is 18651 plain wrong if bitfields are involved. */ 18652 if (error_operand_p (TREE_OPERAND (*expr_p, 1))) 18653 ret = GS_ERROR; 18654 else 18655 { 18656 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); 18657 18658 /* Vector comparisons need no boolification. */ 18659 if (TREE_CODE (type) == VECTOR_TYPE) 18660 goto expr_2; 18661 else if (!AGGREGATE_TYPE_P (type)) 18662 { 18663 tree org_type = TREE_TYPE (*expr_p); 18664 *expr_p = gimple_boolify (*expr_p); 18665 if (!useless_type_conversion_p (org_type, 18666 TREE_TYPE (*expr_p))) 18667 { 18668 *expr_p = fold_convert_loc (input_location, 18669 org_type, *expr_p); 18670 ret = GS_OK; 18671 } 18672 else 18673 goto expr_2; 18674 } 18675 else if (TYPE_MODE (type) != BLKmode) 18676 ret = gimplify_scalar_mode_aggregate_compare (expr_p); 18677 else 18678 ret = gimplify_variable_sized_compare (expr_p); 18679 } 18680 break; 18681 18682 /* If *EXPR_P does not need to be special-cased, handle it 18683 according to its class. */ 18684 case tcc_unary: 18685 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18686 post_p, is_gimple_val, fb_rvalue); 18687 break; 18688 18689 case tcc_binary: 18690 expr_2: 18691 { 18692 enum gimplify_status r0, r1; 18693 18694 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18695 post_p, is_gimple_val, fb_rvalue); 18696 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18697 post_p, is_gimple_val, fb_rvalue); 18698 18699 ret = MIN (r0, r1); 18700 break; 18701 } 18702 18703 expr_3: 18704 { 18705 enum gimplify_status r0, r1, r2; 18706 18707 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, 18708 post_p, is_gimple_val, fb_rvalue); 18709 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, 18710 post_p, is_gimple_val, fb_rvalue); 18711 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, 18712 post_p, is_gimple_val, fb_rvalue); 18713 18714 ret = MIN (MIN (r0, r1), r2); 18715 break; 18716 } 18717 18718 case tcc_declaration: 18719 case tcc_constant: 18720 ret = GS_ALL_DONE; 18721 goto dont_recalculate; 18722 18723 default: 18724 gcc_unreachable (); 18725 } 18726 18727 recalculate_side_effects (*expr_p); 18728 18729 dont_recalculate: 18730 break; 18731 } 18732 18733 gcc_assert (*expr_p || ret != GS_OK); 18734 } 18735 while (ret == GS_OK); 18736 18737 /* If we encountered an error_mark somewhere nested inside, either 18738 stub out the statement or propagate the error back out. */ 18739 if (ret == GS_ERROR) 18740 { 18741 if (is_statement) 18742 *expr_p = NULL; 18743 goto out; 18744 } 18745 18746 /* This was only valid as a return value from the langhook, which 18747 we handled. Make sure it doesn't escape from any other context. */ 18748 gcc_assert (ret != GS_UNHANDLED); 18749 18750 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p)) 18751 { 18752 /* We aren't looking for a value, and we don't have a valid 18753 statement. If it doesn't have side-effects, throw it away. 18754 We can also get here with code such as "*&&L;", where L is 18755 a LABEL_DECL that is marked as FORCED_LABEL. */ 18756 if (TREE_CODE (*expr_p) == LABEL_DECL 18757 || !TREE_SIDE_EFFECTS (*expr_p)) 18758 *expr_p = NULL; 18759 else if (!TREE_THIS_VOLATILE (*expr_p)) 18760 { 18761 /* This is probably a _REF that contains something nested that 18762 has side effects. Recurse through the operands to find it. */ 18763 enum tree_code code = TREE_CODE (*expr_p); 18764 18765 switch (code) 18766 { 18767 case COMPONENT_REF: 18768 case REALPART_EXPR: 18769 case IMAGPART_EXPR: 18770 case VIEW_CONVERT_EXPR: 18771 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18772 gimple_test_f, fallback); 18773 break; 18774 18775 case ARRAY_REF: 18776 case ARRAY_RANGE_REF: 18777 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 18778 gimple_test_f, fallback); 18779 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, 18780 gimple_test_f, fallback); 18781 break; 18782 18783 default: 18784 /* Anything else with side-effects must be converted to 18785 a valid statement before we get here. */ 18786 gcc_unreachable (); 18787 } 18788 18789 *expr_p = NULL; 18790 } 18791 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)) 18792 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode 18793 && !is_empty_type (TREE_TYPE (*expr_p))) 18794 { 18795 /* Historically, the compiler has treated a bare reference 18796 to a non-BLKmode volatile lvalue as forcing a load. */ 18797 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p)); 18798 18799 /* Normally, we do not want to create a temporary for a 18800 TREE_ADDRESSABLE type because such a type should not be 18801 copied by bitwise-assignment. However, we make an 18802 exception here, as all we are doing here is ensuring that 18803 we read the bytes that make up the type. We use 18804 create_tmp_var_raw because create_tmp_var will abort when 18805 given a TREE_ADDRESSABLE type. */ 18806 tree tmp = create_tmp_var_raw (type, "vol"); 18807 gimple_add_tmp_var (tmp); 18808 gimplify_assign (tmp, *expr_p, pre_p); 18809 *expr_p = NULL; 18810 } 18811 else 18812 /* We can't do anything useful with a volatile reference to 18813 an incomplete type, so just throw it away. Likewise for 18814 a BLKmode type, since any implicit inner load should 18815 already have been turned into an explicit one by the 18816 gimplification process. */ 18817 *expr_p = NULL; 18818 } 18819 18820 /* If we are gimplifying at the statement level, we're done. Tack 18821 everything together and return. */ 18822 if (fallback == fb_none || is_statement) 18823 { 18824 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear 18825 it out for GC to reclaim it. */ 18826 *expr_p = NULL_TREE; 18827 18828 if (!gimple_seq_empty_p (internal_pre) 18829 || !gimple_seq_empty_p (internal_post)) 18830 { 18831 gimplify_seq_add_seq (&internal_pre, internal_post); 18832 gimplify_seq_add_seq (pre_p, internal_pre); 18833 } 18834 18835 /* The result of gimplifying *EXPR_P is going to be the last few 18836 statements in *PRE_P and *POST_P. Add location information 18837 to all the statements that were added by the gimplification 18838 helpers. */ 18839 if (!gimple_seq_empty_p (*pre_p)) 18840 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location); 18841 18842 if (!gimple_seq_empty_p (*post_p)) 18843 annotate_all_with_location_after (*post_p, post_last_gsi, 18844 input_location); 18845 18846 goto out; 18847 } 18848 18849 #ifdef ENABLE_GIMPLE_CHECKING 18850 if (*expr_p) 18851 { 18852 enum tree_code code = TREE_CODE (*expr_p); 18853 /* These expressions should already be in gimple IR form. */ 18854 gcc_assert (code != MODIFY_EXPR 18855 && code != ASM_EXPR 18856 && code != BIND_EXPR 18857 && code != CATCH_EXPR 18858 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr) 18859 && code != EH_FILTER_EXPR 18860 && code != GOTO_EXPR 18861 && code != LABEL_EXPR 18862 && code != LOOP_EXPR 18863 && code != SWITCH_EXPR 18864 && code != TRY_FINALLY_EXPR 18865 && code != EH_ELSE_EXPR 18866 && code != OACC_PARALLEL 18867 && code != OACC_KERNELS 18868 && code != OACC_SERIAL 18869 && code != OACC_DATA 18870 && code != OACC_HOST_DATA 18871 && code != OACC_DECLARE 18872 && code != OACC_UPDATE 18873 && code != OACC_ENTER_DATA 18874 && code != OACC_EXIT_DATA 18875 && code != OACC_CACHE 18876 && code != OMP_CRITICAL 18877 && code != OMP_FOR 18878 && code != OACC_LOOP 18879 && code != OMP_MASTER 18880 && code != OMP_MASKED 18881 && code != OMP_TASKGROUP 18882 && code != OMP_ORDERED 18883 && code != OMP_PARALLEL 18884 && code != OMP_SCAN 18885 && code != OMP_SECTIONS 18886 && code != OMP_SECTION 18887 && code != OMP_STRUCTURED_BLOCK 18888 && code != OMP_SINGLE 18889 && code != OMP_SCOPE); 18890 } 18891 #endif 18892 18893 /* Otherwise we're gimplifying a subexpression, so the resulting 18894 value is interesting. If it's a valid operand that matches 18895 GIMPLE_TEST_F, we're done. Unless we are handling some 18896 post-effects internally; if that's the case, we need to copy into 18897 a temporary before adding the post-effects to POST_P. */ 18898 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p)) 18899 goto out; 18900 18901 /* Otherwise, we need to create a new temporary for the gimplified 18902 expression. */ 18903 18904 /* We can't return an lvalue if we have an internal postqueue. The 18905 object the lvalue refers to would (probably) be modified by the 18906 postqueue; we need to copy the value out first, which means an 18907 rvalue. */ 18908 if ((fallback & fb_lvalue) 18909 && gimple_seq_empty_p (internal_post) 18910 && is_gimple_addressable (*expr_p)) 18911 { 18912 /* An lvalue will do. Take the address of the expression, store it 18913 in a temporary, and replace the expression with an INDIRECT_REF of 18914 that temporary. */ 18915 tree ref_alias_type = reference_alias_ptr_type (*expr_p); 18916 unsigned int ref_align = get_object_alignment (*expr_p); 18917 tree ref_type = TREE_TYPE (*expr_p); 18918 tmp = build_fold_addr_expr_loc (input_location, *expr_p); 18919 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); 18920 if (TYPE_ALIGN (ref_type) != ref_align) 18921 ref_type = build_aligned_type (ref_type, ref_align); 18922 *expr_p = build2 (MEM_REF, ref_type, 18923 tmp, build_zero_cst (ref_alias_type)); 18924 } 18925 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p)) 18926 { 18927 /* An rvalue will do. Assign the gimplified expression into a 18928 new temporary TMP and replace the original expression with 18929 TMP. First, make sure that the expression has a type so that 18930 it can be assigned into a temporary. */ 18931 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p))); 18932 *expr_p = get_formal_tmp_var (*expr_p, pre_p); 18933 } 18934 else 18935 { 18936 #ifdef ENABLE_GIMPLE_CHECKING 18937 if (!(fallback & fb_mayfail)) 18938 { 18939 fprintf (stderr, "gimplification failed:\n"); 18940 print_generic_expr (stderr, *expr_p); 18941 debug_tree (*expr_p); 18942 internal_error ("gimplification failed"); 18943 } 18944 #endif 18945 gcc_assert (fallback & fb_mayfail); 18946 18947 /* If this is an asm statement, and the user asked for the 18948 impossible, don't die. Fail and let gimplify_asm_expr 18949 issue an error. */ 18950 ret = GS_ERROR; 18951 goto out; 18952 } 18953 18954 /* Make sure the temporary matches our predicate. */ 18955 gcc_assert ((*gimple_test_f) (*expr_p)); 18956 18957 if (!gimple_seq_empty_p (internal_post)) 18958 { 18959 annotate_all_with_location (internal_post, input_location); 18960 gimplify_seq_add_seq (pre_p, internal_post); 18961 } 18962 18963 out: 18964 input_location = saved_location; 18965 return ret; 18966 } 18967 18968 /* Like gimplify_expr but make sure the gimplified result is not itself 18969 a SSA name (but a decl if it were). Temporaries required by 18970 evaluating *EXPR_P may be still SSA names. */ 18971 18972 static enum gimplify_status 18973 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 18974 bool (*gimple_test_f) (tree), fallback_t fallback, 18975 bool allow_ssa) 18976 { 18977 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p, 18978 gimple_test_f, fallback); 18979 if (! allow_ssa 18980 && TREE_CODE (*expr_p) == SSA_NAME) 18981 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false); 18982 return ret; 18983 } 18984 18985 /* Look through TYPE for variable-sized objects and gimplify each such 18986 size that we find. Add to LIST_P any statements generated. */ 18987 18988 void 18989 gimplify_type_sizes (tree type, gimple_seq *list_p) 18990 { 18991 if (type == NULL || type == error_mark_node) 18992 return; 18993 18994 const bool ignored_p 18995 = TYPE_NAME (type) 18996 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 18997 && DECL_IGNORED_P (TYPE_NAME (type)); 18998 tree t; 18999 19000 /* We first do the main variant, then copy into any other variants. */ 19001 type = TYPE_MAIN_VARIANT (type); 19002 19003 /* Avoid infinite recursion. */ 19004 if (TYPE_SIZES_GIMPLIFIED (type)) 19005 return; 19006 19007 TYPE_SIZES_GIMPLIFIED (type) = 1; 19008 19009 switch (TREE_CODE (type)) 19010 { 19011 case INTEGER_TYPE: 19012 case ENUMERAL_TYPE: 19013 case BOOLEAN_TYPE: 19014 case REAL_TYPE: 19015 case FIXED_POINT_TYPE: 19016 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p); 19017 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p); 19018 19019 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 19020 { 19021 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); 19022 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); 19023 } 19024 break; 19025 19026 case ARRAY_TYPE: 19027 /* These types may not have declarations, so handle them here. */ 19028 gimplify_type_sizes (TREE_TYPE (type), list_p); 19029 gimplify_type_sizes (TYPE_DOMAIN (type), list_p); 19030 /* Ensure VLA bounds aren't removed, for -O0 they should be variables 19031 with assigned stack slots, for -O1+ -g they should be tracked 19032 by VTA. */ 19033 if (!ignored_p 19034 && TYPE_DOMAIN (type) 19035 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type))) 19036 { 19037 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); 19038 if (t && VAR_P (t) && DECL_ARTIFICIAL (t)) 19039 DECL_IGNORED_P (t) = 0; 19040 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 19041 if (t && VAR_P (t) && DECL_ARTIFICIAL (t)) 19042 DECL_IGNORED_P (t) = 0; 19043 } 19044 break; 19045 19046 case RECORD_TYPE: 19047 case UNION_TYPE: 19048 case QUAL_UNION_TYPE: 19049 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 19050 if (TREE_CODE (field) == FIELD_DECL) 19051 { 19052 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); 19053 /* Likewise, ensure variable offsets aren't removed. */ 19054 if (!ignored_p 19055 && (t = DECL_FIELD_OFFSET (field)) 19056 && VAR_P (t) 19057 && DECL_ARTIFICIAL (t)) 19058 DECL_IGNORED_P (t) = 0; 19059 gimplify_one_sizepos (&DECL_SIZE (field), list_p); 19060 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p); 19061 gimplify_type_sizes (TREE_TYPE (field), list_p); 19062 } 19063 break; 19064 19065 case POINTER_TYPE: 19066 case REFERENCE_TYPE: 19067 /* We used to recurse on the pointed-to type here, which turned out to 19068 be incorrect because its definition might refer to variables not 19069 yet initialized at this point if a forward declaration is involved. 19070 19071 It was actually useful for anonymous pointed-to types to ensure 19072 that the sizes evaluation dominates every possible later use of the 19073 values. Restricting to such types here would be safe since there 19074 is no possible forward declaration around, but would introduce an 19075 undesirable middle-end semantic to anonymity. We then defer to 19076 front-ends the responsibility of ensuring that the sizes are 19077 evaluated both early and late enough, e.g. by attaching artificial 19078 type declarations to the tree. */ 19079 break; 19080 19081 default: 19082 break; 19083 } 19084 19085 gimplify_one_sizepos (&TYPE_SIZE (type), list_p); 19086 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p); 19087 19088 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 19089 { 19090 TYPE_SIZE (t) = TYPE_SIZE (type); 19091 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type); 19092 TYPE_SIZES_GIMPLIFIED (t) = 1; 19093 } 19094 } 19095 19096 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P, 19097 a size or position, has had all of its SAVE_EXPRs evaluated. 19098 We add any required statements to *STMT_P. */ 19099 19100 void 19101 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p) 19102 { 19103 tree expr = *expr_p; 19104 19105 /* We don't do anything if the value isn't there, is constant, or contains 19106 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already 19107 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier 19108 will want to replace it with a new variable, but that will cause problems 19109 if this type is from outside the function. It's OK to have that here. */ 19110 if (expr == NULL_TREE 19111 || is_gimple_constant (expr) 19112 || VAR_P (expr) 19113 || CONTAINS_PLACEHOLDER_P (expr)) 19114 return; 19115 19116 *expr_p = unshare_expr (expr); 19117 19118 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed 19119 if the def vanishes. */ 19120 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false); 19121 19122 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the 19123 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls 19124 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */ 19125 if (is_gimple_constant (*expr_p)) 19126 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false); 19127 } 19128 19129 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node 19130 containing the sequence of corresponding GIMPLE statements. If DO_PARMS 19131 is true, also gimplify the parameters. */ 19132 19133 gbind * 19134 gimplify_body (tree fndecl, bool do_parms) 19135 { 19136 location_t saved_location = input_location; 19137 gimple_seq parm_stmts, parm_cleanup = NULL, seq; 19138 gimple *outer_stmt; 19139 gbind *outer_bind; 19140 19141 timevar_push (TV_TREE_GIMPLIFY); 19142 19143 init_tree_ssa (cfun); 19144 19145 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during 19146 gimplification. */ 19147 default_rtl_profile (); 19148 19149 gcc_assert (gimplify_ctxp == NULL); 19150 push_gimplify_context (true); 19151 19152 if (flag_openacc || flag_openmp) 19153 { 19154 gcc_assert (gimplify_omp_ctxp == NULL); 19155 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl))) 19156 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET); 19157 } 19158 19159 /* Unshare most shared trees in the body and in that of any nested functions. 19160 It would seem we don't have to do this for nested functions because 19161 they are supposed to be output and then the outer function gimplified 19162 first, but the g++ front end doesn't always do it that way. */ 19163 unshare_body (fndecl); 19164 unvisit_body (fndecl); 19165 19166 /* Make sure input_location isn't set to something weird. */ 19167 input_location = DECL_SOURCE_LOCATION (fndecl); 19168 19169 /* Resolve callee-copies. This has to be done before processing 19170 the body so that DECL_VALUE_EXPR gets processed correctly. */ 19171 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL; 19172 19173 /* Gimplify the function's body. */ 19174 seq = NULL; 19175 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq); 19176 outer_stmt = gimple_seq_first_nondebug_stmt (seq); 19177 if (!outer_stmt) 19178 { 19179 outer_stmt = gimple_build_nop (); 19180 gimplify_seq_add_stmt (&seq, outer_stmt); 19181 } 19182 19183 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is 19184 not the case, wrap everything in a GIMPLE_BIND to make it so. */ 19185 if (gimple_code (outer_stmt) == GIMPLE_BIND 19186 && (gimple_seq_first_nondebug_stmt (seq) 19187 == gimple_seq_last_nondebug_stmt (seq))) 19188 { 19189 outer_bind = as_a <gbind *> (outer_stmt); 19190 if (gimple_seq_first_stmt (seq) != outer_stmt 19191 || gimple_seq_last_stmt (seq) != outer_stmt) 19192 { 19193 /* If there are debug stmts before or after outer_stmt, move them 19194 inside of outer_bind body. */ 19195 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq); 19196 gimple_seq second_seq = NULL; 19197 if (gimple_seq_first_stmt (seq) != outer_stmt 19198 && gimple_seq_last_stmt (seq) != outer_stmt) 19199 { 19200 second_seq = gsi_split_seq_after (gsi); 19201 gsi_remove (&gsi, false); 19202 } 19203 else if (gimple_seq_first_stmt (seq) != outer_stmt) 19204 gsi_remove (&gsi, false); 19205 else 19206 { 19207 gsi_remove (&gsi, false); 19208 second_seq = seq; 19209 seq = NULL; 19210 } 19211 gimple_seq_add_seq_without_update (&seq, 19212 gimple_bind_body (outer_bind)); 19213 gimple_seq_add_seq_without_update (&seq, second_seq); 19214 gimple_bind_set_body (outer_bind, seq); 19215 } 19216 } 19217 else 19218 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL); 19219 19220 DECL_SAVED_TREE (fndecl) = NULL_TREE; 19221 19222 /* If we had callee-copies statements, insert them at the beginning 19223 of the function and clear DECL_VALUE_EXPR_P on the parameters. */ 19224 if (!gimple_seq_empty_p (parm_stmts)) 19225 { 19226 tree parm; 19227 19228 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind)); 19229 if (parm_cleanup) 19230 { 19231 gtry *g = gimple_build_try (parm_stmts, parm_cleanup, 19232 GIMPLE_TRY_FINALLY); 19233 parm_stmts = NULL; 19234 gimple_seq_add_stmt (&parm_stmts, g); 19235 } 19236 gimple_bind_set_body (outer_bind, parm_stmts); 19237 19238 for (parm = DECL_ARGUMENTS (current_function_decl); 19239 parm; parm = DECL_CHAIN (parm)) 19240 if (DECL_HAS_VALUE_EXPR_P (parm)) 19241 { 19242 DECL_HAS_VALUE_EXPR_P (parm) = 0; 19243 DECL_IGNORED_P (parm) = 0; 19244 } 19245 } 19246 19247 if ((flag_openacc || flag_openmp || flag_openmp_simd) 19248 && gimplify_omp_ctxp) 19249 { 19250 delete_omp_context (gimplify_omp_ctxp); 19251 gimplify_omp_ctxp = NULL; 19252 } 19253 19254 pop_gimplify_context (outer_bind); 19255 gcc_assert (gimplify_ctxp == NULL); 19256 19257 if (flag_checking && !seen_error ()) 19258 verify_gimple_in_seq (gimple_bind_body (outer_bind)); 19259 19260 timevar_pop (TV_TREE_GIMPLIFY); 19261 input_location = saved_location; 19262 19263 return outer_bind; 19264 } 19265 19266 typedef char *char_p; /* For DEF_VEC_P. */ 19267 19268 /* Return whether we should exclude FNDECL from instrumentation. */ 19269 19270 static bool 19271 flag_instrument_functions_exclude_p (tree fndecl) 19272 { 19273 vec<char_p> *v; 19274 19275 v = (vec<char_p> *) flag_instrument_functions_exclude_functions; 19276 if (v && v->length () > 0) 19277 { 19278 const char *name; 19279 int i; 19280 char *s; 19281 19282 name = lang_hooks.decl_printable_name (fndecl, 1); 19283 FOR_EACH_VEC_ELT (*v, i, s) 19284 if (strstr (name, s) != NULL) 19285 return true; 19286 } 19287 19288 v = (vec<char_p> *) flag_instrument_functions_exclude_files; 19289 if (v && v->length () > 0) 19290 { 19291 const char *name; 19292 int i; 19293 char *s; 19294 19295 name = DECL_SOURCE_FILE (fndecl); 19296 FOR_EACH_VEC_ELT (*v, i, s) 19297 if (strstr (name, s) != NULL) 19298 return true; 19299 } 19300 19301 return false; 19302 } 19303 19304 /* Build a call to the instrumentation function FNCODE and add it to SEQ. 19305 If COND_VAR is not NULL, it is a boolean variable guarding the call to 19306 the instrumentation function. IF STMT is not NULL, it is a statement 19307 to be executed just before the call to the instrumentation function. */ 19308 19309 static void 19310 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode, 19311 tree cond_var, gimple *stmt) 19312 { 19313 /* The instrumentation hooks aren't going to call the instrumented 19314 function and the address they receive is expected to be matchable 19315 against symbol addresses. Make sure we don't create a trampoline, 19316 in case the current function is nested. */ 19317 tree this_fn_addr = build_fold_addr_expr (current_function_decl); 19318 TREE_NO_TRAMPOLINE (this_fn_addr) = 1; 19319 19320 tree label_true, label_false; 19321 if (cond_var) 19322 { 19323 label_true = create_artificial_label (UNKNOWN_LOCATION); 19324 label_false = create_artificial_label (UNKNOWN_LOCATION); 19325 gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node, 19326 label_true, label_false); 19327 gimplify_seq_add_stmt (seq, cond); 19328 gimplify_seq_add_stmt (seq, gimple_build_label (label_true)); 19329 gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL, 19330 NOT_TAKEN)); 19331 } 19332 19333 if (stmt) 19334 gimplify_seq_add_stmt (seq, stmt); 19335 19336 tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); 19337 gcall *call = gimple_build_call (x, 1, integer_zero_node); 19338 tree tmp_var = create_tmp_var (ptr_type_node, "return_addr"); 19339 gimple_call_set_lhs (call, tmp_var); 19340 gimplify_seq_add_stmt (seq, call); 19341 x = builtin_decl_implicit (fncode); 19342 call = gimple_build_call (x, 2, this_fn_addr, tmp_var); 19343 gimplify_seq_add_stmt (seq, call); 19344 19345 if (cond_var) 19346 gimplify_seq_add_stmt (seq, gimple_build_label (label_false)); 19347 } 19348 19349 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL 19350 node for the function we want to gimplify. 19351 19352 Return the sequence of GIMPLE statements corresponding to the body 19353 of FNDECL. */ 19354 19355 void 19356 gimplify_function_tree (tree fndecl) 19357 { 19358 gimple_seq seq; 19359 gbind *bind; 19360 19361 gcc_assert (!gimple_body (fndecl)); 19362 19363 if (DECL_STRUCT_FUNCTION (fndecl)) 19364 push_cfun (DECL_STRUCT_FUNCTION (fndecl)); 19365 else 19366 push_struct_function (fndecl); 19367 19368 reset_cond_uid (); 19369 19370 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr 19371 if necessary. */ 19372 cfun->curr_properties |= PROP_gimple_lva; 19373 19374 if (asan_sanitize_use_after_scope ()) 19375 asan_poisoned_variables = new hash_set<tree> (); 19376 bind = gimplify_body (fndecl, true); 19377 if (asan_poisoned_variables) 19378 { 19379 delete asan_poisoned_variables; 19380 asan_poisoned_variables = NULL; 19381 } 19382 19383 /* The tree body of the function is no longer needed, replace it 19384 with the new GIMPLE body. */ 19385 seq = NULL; 19386 gimple_seq_add_stmt (&seq, bind); 19387 gimple_set_body (fndecl, seq); 19388 19389 /* If we're instrumenting function entry/exit, then prepend the call to 19390 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to 19391 catch the exit hook. */ 19392 /* ??? Add some way to ignore exceptions for this TFE. */ 19393 if (flag_instrument_function_entry_exit 19394 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) 19395 /* Do not instrument extern inline functions. */ 19396 && !(DECL_DECLARED_INLINE_P (fndecl) 19397 && DECL_EXTERNAL (fndecl) 19398 && DECL_DISREGARD_INLINE_LIMITS (fndecl)) 19399 && !flag_instrument_functions_exclude_p (fndecl)) 19400 { 19401 gimple_seq body = NULL, cleanup = NULL; 19402 gassign *assign; 19403 tree cond_var; 19404 19405 /* If -finstrument-functions-once is specified, generate: 19406 19407 static volatile bool C.0 = false; 19408 bool tmp_called; 19409 19410 tmp_called = C.0; 19411 if (!tmp_called) 19412 { 19413 C.0 = true; 19414 [call profiling enter function] 19415 } 19416 19417 without specific protection for data races. */ 19418 if (flag_instrument_function_entry_exit > 1) 19419 { 19420 tree first_var 19421 = build_decl (DECL_SOURCE_LOCATION (current_function_decl), 19422 VAR_DECL, 19423 create_tmp_var_name ("C"), 19424 boolean_type_node); 19425 DECL_ARTIFICIAL (first_var) = 1; 19426 DECL_IGNORED_P (first_var) = 1; 19427 TREE_STATIC (first_var) = 1; 19428 TREE_THIS_VOLATILE (first_var) = 1; 19429 TREE_USED (first_var) = 1; 19430 DECL_INITIAL (first_var) = boolean_false_node; 19431 varpool_node::add (first_var); 19432 19433 cond_var = create_tmp_var (boolean_type_node, "tmp_called"); 19434 assign = gimple_build_assign (cond_var, first_var); 19435 gimplify_seq_add_stmt (&body, assign); 19436 19437 assign = gimple_build_assign (first_var, boolean_true_node); 19438 } 19439 19440 else 19441 { 19442 cond_var = NULL_TREE; 19443 assign = NULL; 19444 } 19445 19446 build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER, 19447 cond_var, assign); 19448 19449 /* If -finstrument-functions-once is specified, generate: 19450 19451 if (!tmp_called) 19452 [call profiling exit function] 19453 19454 without specific protection for data races. */ 19455 build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT, 19456 cond_var, NULL); 19457 19458 gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY); 19459 gimplify_seq_add_stmt (&body, tf); 19460 gbind *new_bind = gimple_build_bind (NULL, body, NULL); 19461 19462 /* Replace the current function body with the body 19463 wrapped in the try/finally TF. */ 19464 seq = NULL; 19465 gimple_seq_add_stmt (&seq, new_bind); 19466 gimple_set_body (fndecl, seq); 19467 bind = new_bind; 19468 } 19469 19470 if (sanitize_flags_p (SANITIZE_THREAD) 19471 && param_tsan_instrument_func_entry_exit) 19472 { 19473 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0); 19474 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY); 19475 gbind *new_bind = gimple_build_bind (NULL, tf, NULL); 19476 /* Replace the current function body with the body 19477 wrapped in the try/finally TF. */ 19478 seq = NULL; 19479 gimple_seq_add_stmt (&seq, new_bind); 19480 gimple_set_body (fndecl, seq); 19481 } 19482 19483 DECL_SAVED_TREE (fndecl) = NULL_TREE; 19484 cfun->curr_properties |= PROP_gimple_any; 19485 19486 pop_cfun (); 19487 19488 dump_function (TDI_gimple, fndecl); 19489 } 19490 19491 /* Return a dummy expression of type TYPE in order to keep going after an 19492 error. */ 19493 19494 static tree 19495 dummy_object (tree type) 19496 { 19497 tree t = build_int_cst (build_pointer_type (type), 0); 19498 return build2 (MEM_REF, type, t, t); 19499 } 19500 19501 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a 19502 builtin function, but a very special sort of operator. */ 19503 19504 enum gimplify_status 19505 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, 19506 gimple_seq *post_p ATTRIBUTE_UNUSED) 19507 { 19508 tree promoted_type, have_va_type; 19509 tree valist = TREE_OPERAND (*expr_p, 0); 19510 tree type = TREE_TYPE (*expr_p); 19511 tree t, tag, aptag; 19512 location_t loc = EXPR_LOCATION (*expr_p); 19513 19514 /* Verify that valist is of the proper type. */ 19515 have_va_type = TREE_TYPE (valist); 19516 if (have_va_type == error_mark_node) 19517 return GS_ERROR; 19518 have_va_type = targetm.canonical_va_list_type (have_va_type); 19519 if (have_va_type == NULL_TREE 19520 && POINTER_TYPE_P (TREE_TYPE (valist))) 19521 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */ 19522 have_va_type 19523 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist))); 19524 gcc_assert (have_va_type != NULL_TREE); 19525 19526 /* Generate a diagnostic for requesting data of a type that cannot 19527 be passed through `...' due to type promotion at the call site. */ 19528 if ((promoted_type = lang_hooks.types.type_promotes_to (type)) 19529 != type) 19530 { 19531 static bool gave_help; 19532 bool warned; 19533 /* Use the expansion point to handle cases such as passing bool (defined 19534 in a system header) through `...'. */ 19535 location_t xloc 19536 = expansion_point_location_if_in_system_header (loc); 19537 19538 /* Unfortunately, this is merely undefined, rather than a constraint 19539 violation, so we cannot make this an error. If this call is never 19540 executed, the program is still strictly conforming. */ 19541 auto_diagnostic_group d; 19542 warned = warning_at (xloc, 0, 19543 "%qT is promoted to %qT when passed through %<...%>", 19544 type, promoted_type); 19545 if (!gave_help && warned) 19546 { 19547 gave_help = true; 19548 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)", 19549 promoted_type, type); 19550 } 19551 19552 /* We can, however, treat "undefined" any way we please. 19553 Call abort to encourage the user to fix the program. */ 19554 if (warned) 19555 inform (xloc, "if this code is reached, the program will abort"); 19556 /* Before the abort, allow the evaluation of the va_list 19557 expression to exit or longjmp. */ 19558 gimplify_and_add (valist, pre_p); 19559 t = build_call_expr_loc (loc, 19560 builtin_decl_implicit (BUILT_IN_TRAP), 0); 19561 gimplify_and_add (t, pre_p); 19562 19563 /* This is dead code, but go ahead and finish so that the 19564 mode of the result comes out right. */ 19565 *expr_p = dummy_object (type); 19566 return GS_ALL_DONE; 19567 } 19568 19569 tag = build_int_cst (build_pointer_type (type), 0); 19570 aptag = build_int_cst (TREE_TYPE (valist), 0); 19571 19572 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3, 19573 valist, tag, aptag); 19574 19575 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG 19576 needs to be expanded. */ 19577 cfun->curr_properties &= ~PROP_gimple_lva; 19578 19579 return GS_OK; 19580 } 19581 19582 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P. 19583 19584 DST/SRC are the destination and source respectively. You can pass 19585 ungimplified trees in DST or SRC, in which case they will be 19586 converted to a gimple operand if necessary. 19587 19588 This function returns the newly created GIMPLE_ASSIGN tuple. */ 19589 19590 gimple * 19591 gimplify_assign (tree dst, tree src, gimple_seq *seq_p) 19592 { 19593 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 19594 gimplify_and_add (t, seq_p); 19595 ggc_free (t); 19596 return gimple_seq_last_stmt (*seq_p); 19597 } 19598 19599 inline hashval_t 19600 gimplify_hasher::hash (const elt_t *p) 19601 { 19602 tree t = p->val; 19603 return iterative_hash_expr (t, 0); 19604 } 19605 19606 inline bool 19607 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2) 19608 { 19609 tree t1 = p1->val; 19610 tree t2 = p2->val; 19611 enum tree_code code = TREE_CODE (t1); 19612 19613 if (TREE_CODE (t2) != code 19614 || TREE_TYPE (t1) != TREE_TYPE (t2)) 19615 return false; 19616 19617 if (!operand_equal_p (t1, t2, 0)) 19618 return false; 19619 19620 /* Only allow them to compare equal if they also hash equal; otherwise 19621 results are nondeterminate, and we fail bootstrap comparison. */ 19622 gcc_checking_assert (hash (p1) == hash (p2)); 19623 19624 return true; 19625 } 19626