1 /* This file contains routines to construct GNU OpenMP constructs, 2 called from parsing in the C and C++ front ends. 3 4 Copyright (C) 2005-2013 Free Software Foundation, Inc. 5 Contributed by Richard Henderson <rth@redhat.com>, 6 Diego Novillo <dnovillo@redhat.com>. 7 8 This file is part of GCC. 9 10 GCC is free software; you can redistribute it and/or modify it under 11 the terms of the GNU General Public License as published by the Free 12 Software Foundation; either version 3, or (at your option) any later 13 version. 14 15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with GCC; see the file COPYING3. If not see 22 <http://www.gnu.org/licenses/>. */ 23 24 #include "config.h" 25 #include "system.h" 26 #include "coretypes.h" 27 #include "tree.h" 28 #include "c-common.h" 29 #include "gimple.h" /* For create_tmp_var_raw. */ 30 #include "langhooks.h" 31 32 33 /* Complete a #pragma omp master construct. STMT is the structured-block 34 that follows the pragma. LOC is the l*/ 35 36 tree 37 c_finish_omp_master (location_t loc, tree stmt) 38 { 39 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt)); 40 SET_EXPR_LOCATION (t, loc); 41 return t; 42 } 43 44 /* Complete a #pragma omp critical construct. STMT is the structured-block 45 that follows the pragma, NAME is the identifier in the pragma, or null 46 if it was omitted. LOC is the location of the #pragma. */ 47 48 tree 49 c_finish_omp_critical (location_t loc, tree body, tree name) 50 { 51 tree stmt = make_node (OMP_CRITICAL); 52 TREE_TYPE (stmt) = void_type_node; 53 OMP_CRITICAL_BODY (stmt) = body; 54 OMP_CRITICAL_NAME (stmt) = name; 55 SET_EXPR_LOCATION (stmt, loc); 56 return add_stmt (stmt); 57 } 58 59 /* Complete a #pragma omp ordered construct. STMT is the structured-block 60 that follows the pragma. LOC is the location of the #pragma. */ 61 62 tree 63 c_finish_omp_ordered (location_t loc, tree stmt) 64 { 65 tree t = build1 (OMP_ORDERED, void_type_node, stmt); 66 SET_EXPR_LOCATION (t, loc); 67 return add_stmt (t); 68 } 69 70 71 /* Complete a #pragma omp barrier construct. LOC is the location of 72 the #pragma. */ 73 74 void 75 c_finish_omp_barrier (location_t loc) 76 { 77 tree x; 78 79 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER); 80 x = build_call_expr_loc (loc, x, 0); 81 add_stmt (x); 82 } 83 84 85 /* Complete a #pragma omp taskwait construct. LOC is the location of the 86 pragma. */ 87 88 void 89 c_finish_omp_taskwait (location_t loc) 90 { 91 tree x; 92 93 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); 94 x = build_call_expr_loc (loc, x, 0); 95 add_stmt (x); 96 } 97 98 99 /* Complete a #pragma omp taskyield construct. LOC is the location of the 100 pragma. */ 101 102 void 103 c_finish_omp_taskyield (location_t loc) 104 { 105 tree x; 106 107 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD); 108 x = build_call_expr_loc (loc, x, 0); 109 add_stmt (x); 110 } 111 112 113 /* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC 114 the expression to be implemented atomically is LHS opcode= RHS. 115 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS 116 opcode= RHS with the new or old content of LHS returned. 117 LOC is the location of the atomic statement. The value returned 118 is either error_mark_node (if the construct was erroneous) or an 119 OMP_ATOMIC* node which should be added to the current statement 120 tree with add_stmt. */ 121 122 tree 123 c_finish_omp_atomic (location_t loc, enum tree_code code, 124 enum tree_code opcode, tree lhs, tree rhs, 125 tree v, tree lhs1, tree rhs1) 126 { 127 tree x, type, addr; 128 129 if (lhs == error_mark_node || rhs == error_mark_node 130 || v == error_mark_node || lhs1 == error_mark_node 131 || rhs1 == error_mark_node) 132 return error_mark_node; 133 134 /* ??? According to one reading of the OpenMP spec, complex type are 135 supported, but there are no atomic stores for any architecture. 136 But at least icc 9.0 doesn't support complex types here either. 137 And lets not even talk about vector types... */ 138 type = TREE_TYPE (lhs); 139 if (!INTEGRAL_TYPE_P (type) 140 && !POINTER_TYPE_P (type) 141 && !SCALAR_FLOAT_TYPE_P (type)) 142 { 143 error_at (loc, "invalid expression type for %<#pragma omp atomic%>"); 144 return error_mark_node; 145 } 146 147 /* ??? Validate that rhs does not overlap lhs. */ 148 149 /* Take and save the address of the lhs. From then on we'll reference it 150 via indirection. */ 151 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0); 152 if (addr == error_mark_node) 153 return error_mark_node; 154 addr = save_expr (addr); 155 if (TREE_CODE (addr) != SAVE_EXPR 156 && (TREE_CODE (addr) != ADDR_EXPR 157 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL)) 158 { 159 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize 160 it even after unsharing function body. */ 161 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL); 162 DECL_CONTEXT (var) = current_function_decl; 163 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL); 164 } 165 lhs = build_indirect_ref (loc, addr, RO_NULL); 166 167 if (code == OMP_ATOMIC_READ) 168 { 169 x = build1 (OMP_ATOMIC_READ, type, addr); 170 SET_EXPR_LOCATION (x, loc); 171 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR, 172 loc, x, NULL_TREE); 173 return x; 174 } 175 176 /* There are lots of warnings, errors, and conversions that need to happen 177 in the course of interpreting a statement. Use the normal mechanisms 178 to do this, and then take it apart again. */ 179 x = build_modify_expr (input_location, lhs, NULL_TREE, opcode, 180 input_location, rhs, NULL_TREE); 181 if (x == error_mark_node) 182 return error_mark_node; 183 gcc_assert (TREE_CODE (x) == MODIFY_EXPR); 184 rhs = TREE_OPERAND (x, 1); 185 186 /* Punt the actual generation of atomic operations to common code. */ 187 if (code == OMP_ATOMIC) 188 type = void_type_node; 189 x = build2 (code, type, addr, rhs); 190 SET_EXPR_LOCATION (x, loc); 191 192 /* Generally it is hard to prove lhs1 and lhs are the same memory 193 location, just diagnose different variables. */ 194 if (rhs1 195 && TREE_CODE (rhs1) == VAR_DECL 196 && TREE_CODE (lhs) == VAR_DECL 197 && rhs1 != lhs) 198 { 199 if (code == OMP_ATOMIC) 200 error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory"); 201 else 202 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory"); 203 return error_mark_node; 204 } 205 206 if (code != OMP_ATOMIC) 207 { 208 /* Generally it is hard to prove lhs1 and lhs are the same memory 209 location, just diagnose different variables. */ 210 if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL) 211 { 212 if (lhs1 != lhs) 213 { 214 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory"); 215 return error_mark_node; 216 } 217 } 218 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR, 219 loc, x, NULL_TREE); 220 if (rhs1 && rhs1 != lhs) 221 { 222 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0); 223 if (rhs1addr == error_mark_node) 224 return error_mark_node; 225 x = omit_one_operand_loc (loc, type, x, rhs1addr); 226 } 227 if (lhs1 && lhs1 != lhs) 228 { 229 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0); 230 if (lhs1addr == error_mark_node) 231 return error_mark_node; 232 if (code == OMP_ATOMIC_CAPTURE_OLD) 233 x = omit_one_operand_loc (loc, type, x, lhs1addr); 234 else 235 { 236 x = save_expr (x); 237 x = omit_two_operands_loc (loc, type, x, x, lhs1addr); 238 } 239 } 240 } 241 else if (rhs1 && rhs1 != lhs) 242 { 243 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0); 244 if (rhs1addr == error_mark_node) 245 return error_mark_node; 246 x = omit_one_operand_loc (loc, type, x, rhs1addr); 247 } 248 249 return x; 250 } 251 252 253 /* Complete a #pragma omp flush construct. We don't do anything with 254 the variable list that the syntax allows. LOC is the location of 255 the #pragma. */ 256 257 void 258 c_finish_omp_flush (location_t loc) 259 { 260 tree x; 261 262 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); 263 x = build_call_expr_loc (loc, x, 0); 264 add_stmt (x); 265 } 266 267 268 /* Check and canonicalize #pragma omp for increment expression. 269 Helper function for c_finish_omp_for. */ 270 271 static tree 272 check_omp_for_incr_expr (location_t loc, tree exp, tree decl) 273 { 274 tree t; 275 276 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp)) 277 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl))) 278 return error_mark_node; 279 280 if (exp == decl) 281 return build_int_cst (TREE_TYPE (exp), 0); 282 283 switch (TREE_CODE (exp)) 284 { 285 CASE_CONVERT: 286 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); 287 if (t != error_mark_node) 288 return fold_convert_loc (loc, TREE_TYPE (exp), t); 289 break; 290 case MINUS_EXPR: 291 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); 292 if (t != error_mark_node) 293 return fold_build2_loc (loc, MINUS_EXPR, 294 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); 295 break; 296 case PLUS_EXPR: 297 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); 298 if (t != error_mark_node) 299 return fold_build2_loc (loc, PLUS_EXPR, 300 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); 301 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl); 302 if (t != error_mark_node) 303 return fold_build2_loc (loc, PLUS_EXPR, 304 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t); 305 break; 306 case COMPOUND_EXPR: 307 { 308 /* cp_build_modify_expr forces preevaluation of the RHS to make 309 sure that it is evaluated before the lvalue-rvalue conversion 310 is applied to the LHS. Reconstruct the original expression. */ 311 tree op0 = TREE_OPERAND (exp, 0); 312 if (TREE_CODE (op0) == TARGET_EXPR 313 && !VOID_TYPE_P (TREE_TYPE (op0))) 314 { 315 tree op1 = TREE_OPERAND (exp, 1); 316 tree temp = TARGET_EXPR_SLOT (op0); 317 if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary 318 && TREE_OPERAND (op1, 1) == temp) 319 { 320 op1 = copy_node (op1); 321 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0); 322 return check_omp_for_incr_expr (loc, op1, decl); 323 } 324 } 325 break; 326 } 327 default: 328 break; 329 } 330 331 return error_mark_node; 332 } 333 334 /* Validate and emit code for the OpenMP directive #pragma omp for. 335 DECLV is a vector of iteration variables, for each collapsed loop. 336 INITV, CONDV and INCRV are vectors containing initialization 337 expressions, controlling predicates and increment expressions. 338 BODY is the body of the loop and PRE_BODY statements that go before 339 the loop. */ 340 341 tree 342 c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv, 343 tree incrv, tree body, tree pre_body) 344 { 345 location_t elocus; 346 bool fail = false; 347 int i; 348 349 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv)); 350 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv)); 351 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv)); 352 for (i = 0; i < TREE_VEC_LENGTH (declv); i++) 353 { 354 tree decl = TREE_VEC_ELT (declv, i); 355 tree init = TREE_VEC_ELT (initv, i); 356 tree cond = TREE_VEC_ELT (condv, i); 357 tree incr = TREE_VEC_ELT (incrv, i); 358 359 elocus = locus; 360 if (EXPR_HAS_LOCATION (init)) 361 elocus = EXPR_LOCATION (init); 362 363 /* Validate the iteration variable. */ 364 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)) 365 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE) 366 { 367 error_at (elocus, "invalid type for iteration variable %qE", decl); 368 fail = true; 369 } 370 371 /* In the case of "for (int i = 0...)", init will be a decl. It should 372 have a DECL_INITIAL that we can turn into an assignment. */ 373 if (init == decl) 374 { 375 elocus = DECL_SOURCE_LOCATION (decl); 376 377 init = DECL_INITIAL (decl); 378 if (init == NULL) 379 { 380 error_at (elocus, "%qE is not initialized", decl); 381 init = integer_zero_node; 382 fail = true; 383 } 384 385 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR, 386 /* FIXME diagnostics: This should 387 be the location of the INIT. */ 388 elocus, 389 init, 390 NULL_TREE); 391 } 392 gcc_assert (TREE_CODE (init) == MODIFY_EXPR); 393 gcc_assert (TREE_OPERAND (init, 0) == decl); 394 395 if (cond == NULL_TREE) 396 { 397 error_at (elocus, "missing controlling predicate"); 398 fail = true; 399 } 400 else 401 { 402 bool cond_ok = false; 403 404 if (EXPR_HAS_LOCATION (cond)) 405 elocus = EXPR_LOCATION (cond); 406 407 if (TREE_CODE (cond) == LT_EXPR 408 || TREE_CODE (cond) == LE_EXPR 409 || TREE_CODE (cond) == GT_EXPR 410 || TREE_CODE (cond) == GE_EXPR 411 || TREE_CODE (cond) == NE_EXPR 412 || TREE_CODE (cond) == EQ_EXPR) 413 { 414 tree op0 = TREE_OPERAND (cond, 0); 415 tree op1 = TREE_OPERAND (cond, 1); 416 417 /* 2.5.1. The comparison in the condition is computed in 418 the type of DECL, otherwise the behavior is undefined. 419 420 For example: 421 long n; int i; 422 i < n; 423 424 according to ISO will be evaluated as: 425 (long)i < n; 426 427 We want to force: 428 i < (int)n; */ 429 if (TREE_CODE (op0) == NOP_EXPR 430 && decl == TREE_OPERAND (op0, 0)) 431 { 432 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0); 433 TREE_OPERAND (cond, 1) 434 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl), 435 TREE_OPERAND (cond, 1)); 436 } 437 else if (TREE_CODE (op1) == NOP_EXPR 438 && decl == TREE_OPERAND (op1, 0)) 439 { 440 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0); 441 TREE_OPERAND (cond, 0) 442 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl), 443 TREE_OPERAND (cond, 0)); 444 } 445 446 if (decl == TREE_OPERAND (cond, 0)) 447 cond_ok = true; 448 else if (decl == TREE_OPERAND (cond, 1)) 449 { 450 TREE_SET_CODE (cond, 451 swap_tree_comparison (TREE_CODE (cond))); 452 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0); 453 TREE_OPERAND (cond, 0) = decl; 454 cond_ok = true; 455 } 456 457 if (TREE_CODE (cond) == NE_EXPR 458 || TREE_CODE (cond) == EQ_EXPR) 459 { 460 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))) 461 cond_ok = false; 462 else if (operand_equal_p (TREE_OPERAND (cond, 1), 463 TYPE_MIN_VALUE (TREE_TYPE (decl)), 464 0)) 465 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR 466 ? GT_EXPR : LE_EXPR); 467 else if (operand_equal_p (TREE_OPERAND (cond, 1), 468 TYPE_MAX_VALUE (TREE_TYPE (decl)), 469 0)) 470 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR 471 ? LT_EXPR : GE_EXPR); 472 else 473 cond_ok = false; 474 } 475 } 476 477 if (!cond_ok) 478 { 479 error_at (elocus, "invalid controlling predicate"); 480 fail = true; 481 } 482 } 483 484 if (incr == NULL_TREE) 485 { 486 error_at (elocus, "missing increment expression"); 487 fail = true; 488 } 489 else 490 { 491 bool incr_ok = false; 492 493 if (EXPR_HAS_LOCATION (incr)) 494 elocus = EXPR_LOCATION (incr); 495 496 /* Check all the valid increment expressions: v++, v--, ++v, --v, 497 v = v + incr, v = incr + v and v = v - incr. */ 498 switch (TREE_CODE (incr)) 499 { 500 case POSTINCREMENT_EXPR: 501 case PREINCREMENT_EXPR: 502 case POSTDECREMENT_EXPR: 503 case PREDECREMENT_EXPR: 504 if (TREE_OPERAND (incr, 0) != decl) 505 break; 506 507 incr_ok = true; 508 if (POINTER_TYPE_P (TREE_TYPE (decl)) 509 && TREE_OPERAND (incr, 1)) 510 { 511 tree t = fold_convert_loc (elocus, 512 sizetype, TREE_OPERAND (incr, 1)); 513 514 if (TREE_CODE (incr) == POSTDECREMENT_EXPR 515 || TREE_CODE (incr) == PREDECREMENT_EXPR) 516 t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t); 517 t = fold_build_pointer_plus (decl, t); 518 incr = build2 (MODIFY_EXPR, void_type_node, decl, t); 519 } 520 break; 521 522 case MODIFY_EXPR: 523 if (TREE_OPERAND (incr, 0) != decl) 524 break; 525 if (TREE_OPERAND (incr, 1) == decl) 526 break; 527 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR 528 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl 529 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl)) 530 incr_ok = true; 531 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR 532 || (TREE_CODE (TREE_OPERAND (incr, 1)) 533 == POINTER_PLUS_EXPR)) 534 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl) 535 incr_ok = true; 536 else 537 { 538 tree t = check_omp_for_incr_expr (elocus, 539 TREE_OPERAND (incr, 1), 540 decl); 541 if (t != error_mark_node) 542 { 543 incr_ok = true; 544 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t); 545 incr = build2 (MODIFY_EXPR, void_type_node, decl, t); 546 } 547 } 548 break; 549 550 default: 551 break; 552 } 553 if (!incr_ok) 554 { 555 error_at (elocus, "invalid increment expression"); 556 fail = true; 557 } 558 } 559 560 TREE_VEC_ELT (initv, i) = init; 561 TREE_VEC_ELT (incrv, i) = incr; 562 } 563 564 if (fail) 565 return NULL; 566 else 567 { 568 tree t = make_node (OMP_FOR); 569 570 TREE_TYPE (t) = void_type_node; 571 OMP_FOR_INIT (t) = initv; 572 OMP_FOR_COND (t) = condv; 573 OMP_FOR_INCR (t) = incrv; 574 OMP_FOR_BODY (t) = body; 575 OMP_FOR_PRE_BODY (t) = pre_body; 576 577 SET_EXPR_LOCATION (t, locus); 578 return add_stmt (t); 579 } 580 } 581 582 583 /* Divide CLAUSES into two lists: those that apply to a parallel 584 construct, and those that apply to a work-sharing construct. Place 585 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In 586 addition, add a nowait clause to the work-sharing list. LOC is the 587 location of the OMP_PARALLEL*. */ 588 589 void 590 c_split_parallel_clauses (location_t loc, tree clauses, 591 tree *par_clauses, tree *ws_clauses) 592 { 593 tree next; 594 595 *par_clauses = NULL; 596 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); 597 598 for (; clauses ; clauses = next) 599 { 600 next = OMP_CLAUSE_CHAIN (clauses); 601 602 switch (OMP_CLAUSE_CODE (clauses)) 603 { 604 case OMP_CLAUSE_PRIVATE: 605 case OMP_CLAUSE_SHARED: 606 case OMP_CLAUSE_FIRSTPRIVATE: 607 case OMP_CLAUSE_LASTPRIVATE: 608 case OMP_CLAUSE_REDUCTION: 609 case OMP_CLAUSE_COPYIN: 610 case OMP_CLAUSE_IF: 611 case OMP_CLAUSE_NUM_THREADS: 612 case OMP_CLAUSE_DEFAULT: 613 OMP_CLAUSE_CHAIN (clauses) = *par_clauses; 614 *par_clauses = clauses; 615 break; 616 617 case OMP_CLAUSE_SCHEDULE: 618 case OMP_CLAUSE_ORDERED: 619 case OMP_CLAUSE_COLLAPSE: 620 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses; 621 *ws_clauses = clauses; 622 break; 623 624 default: 625 gcc_unreachable (); 626 } 627 } 628 } 629 630 /* True if OpenMP sharing attribute of DECL is predetermined. */ 631 632 enum omp_clause_default_kind 633 c_omp_predetermined_sharing (tree decl) 634 { 635 /* Variables with const-qualified type having no mutable member 636 are predetermined shared. */ 637 if (TREE_READONLY (decl)) 638 return OMP_CLAUSE_DEFAULT_SHARED; 639 640 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 641 } 642