c-omp.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. /* This file contains routines to construct OpenACC and OpenMP constructs,
  2. called from parsing in the C and C++ front ends.
  3. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  4. Contributed by Richard Henderson <rth@redhat.com>,
  5. Diego Novillo <dnovillo@redhat.com>.
  6. This file is part of GCC.
  7. GCC is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 3, or (at your option) any later
  10. version.
  11. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  12. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with GCC; see the file COPYING3. If not see
  17. <http://www.gnu.org/licenses/>. */
  18. #include "config.h"
  19. #include "system.h"
  20. #include "coretypes.h"
  21. #include "tm.h"
  22. #include "hash-set.h"
  23. #include "machmode.h"
  24. #include "vec.h"
  25. #include "double-int.h"
  26. #include "input.h"
  27. #include "alias.h"
  28. #include "symtab.h"
  29. #include "wide-int.h"
  30. #include "inchash.h"
  31. #include "tree.h"
  32. #include "c-common.h"
  33. #include "c-pragma.h"
  34. #include "gimple-expr.h"
  35. #include "langhooks.h"
  36. #include "omp-low.h"
  37. #include "gomp-constants.h"
  38. /* Complete a #pragma oacc wait construct. LOC is the location of
  39. the #pragma. */
  40. tree
  41. c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
  42. {
  43. const int nparms = list_length (parms);
  44. tree stmt, t;
  45. vec<tree, va_gc> *args;
  46. vec_alloc (args, nparms + 2);
  47. stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
  48. if (find_omp_clause (clauses, OMP_CLAUSE_ASYNC))
  49. t = OMP_CLAUSE_ASYNC_EXPR (clauses);
  50. else
  51. t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
  52. args->quick_push (t);
  53. args->quick_push (build_int_cst (integer_type_node, nparms));
  54. for (t = parms; t; t = TREE_CHAIN (t))
  55. {
  56. if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
  57. args->quick_push (build_int_cst (integer_type_node,
  58. TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
  59. else
  60. args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
  61. }
  62. stmt = build_call_expr_loc_vec (loc, stmt, args);
  63. add_stmt (stmt);
  64. vec_free (args);
  65. return stmt;
  66. }
  67. /* Complete a #pragma omp master construct. STMT is the structured-block
  68. that follows the pragma. LOC is the l*/
  69. tree
  70. c_finish_omp_master (location_t loc, tree stmt)
  71. {
  72. tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
  73. SET_EXPR_LOCATION (t, loc);
  74. return t;
  75. }
  76. /* Complete a #pragma omp taskgroup construct. STMT is the structured-block
  77. that follows the pragma. LOC is the l*/
  78. tree
  79. c_finish_omp_taskgroup (location_t loc, tree stmt)
  80. {
  81. tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
  82. SET_EXPR_LOCATION (t, loc);
  83. return t;
  84. }
  85. /* Complete a #pragma omp critical construct. STMT is the structured-block
  86. that follows the pragma, NAME is the identifier in the pragma, or null
  87. if it was omitted. LOC is the location of the #pragma. */
  88. tree
  89. c_finish_omp_critical (location_t loc, tree body, tree name)
  90. {
  91. tree stmt = make_node (OMP_CRITICAL);
  92. TREE_TYPE (stmt) = void_type_node;
  93. OMP_CRITICAL_BODY (stmt) = body;
  94. OMP_CRITICAL_NAME (stmt) = name;
  95. SET_EXPR_LOCATION (stmt, loc);
  96. return add_stmt (stmt);
  97. }
  98. /* Complete a #pragma omp ordered construct. STMT is the structured-block
  99. that follows the pragma. LOC is the location of the #pragma. */
  100. tree
  101. c_finish_omp_ordered (location_t loc, tree stmt)
  102. {
  103. tree t = build1 (OMP_ORDERED, void_type_node, stmt);
  104. SET_EXPR_LOCATION (t, loc);
  105. return add_stmt (t);
  106. }
  107. /* Complete a #pragma omp barrier construct. LOC is the location of
  108. the #pragma. */
  109. void
  110. c_finish_omp_barrier (location_t loc)
  111. {
  112. tree x;
  113. x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
  114. x = build_call_expr_loc (loc, x, 0);
  115. add_stmt (x);
  116. }
  117. /* Complete a #pragma omp taskwait construct. LOC is the location of the
  118. pragma. */
  119. void
  120. c_finish_omp_taskwait (location_t loc)
  121. {
  122. tree x;
  123. x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
  124. x = build_call_expr_loc (loc, x, 0);
  125. add_stmt (x);
  126. }
  127. /* Complete a #pragma omp taskyield construct. LOC is the location of the
  128. pragma. */
  129. void
  130. c_finish_omp_taskyield (location_t loc)
  131. {
  132. tree x;
  133. x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
  134. x = build_call_expr_loc (loc, x, 0);
  135. add_stmt (x);
  136. }
  137. /* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
  138. the expression to be implemented atomically is LHS opcode= RHS.
  139. For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
  140. opcode= RHS with the new or old content of LHS returned.
  141. LOC is the location of the atomic statement. The value returned
  142. is either error_mark_node (if the construct was erroneous) or an
  143. OMP_ATOMIC* node which should be added to the current statement
  144. tree with add_stmt. */
  145. tree
  146. c_finish_omp_atomic (location_t loc, enum tree_code code,
  147. enum tree_code opcode, tree lhs, tree rhs,
  148. tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst)
  149. {
  150. tree x, type, addr, pre = NULL_TREE;
  151. if (lhs == error_mark_node || rhs == error_mark_node
  152. || v == error_mark_node || lhs1 == error_mark_node
  153. || rhs1 == error_mark_node)
  154. return error_mark_node;
  155. /* ??? According to one reading of the OpenMP spec, complex type are
  156. supported, but there are no atomic stores for any architecture.
  157. But at least icc 9.0 doesn't support complex types here either.
  158. And lets not even talk about vector types... */
  159. type = TREE_TYPE (lhs);
  160. if (!INTEGRAL_TYPE_P (type)
  161. && !POINTER_TYPE_P (type)
  162. && !SCALAR_FLOAT_TYPE_P (type))
  163. {
  164. error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
  165. return error_mark_node;
  166. }
  167. if (opcode == RDIV_EXPR)
  168. opcode = TRUNC_DIV_EXPR;
  169. /* ??? Validate that rhs does not overlap lhs. */
  170. /* Take and save the address of the lhs. From then on we'll reference it
  171. via indirection. */
  172. addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
  173. if (addr == error_mark_node)
  174. return error_mark_node;
  175. addr = save_expr (addr);
  176. if (TREE_CODE (addr) != SAVE_EXPR
  177. && (TREE_CODE (addr) != ADDR_EXPR
  178. || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
  179. {
  180. /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
  181. it even after unsharing function body. */
  182. tree var = create_tmp_var_raw (TREE_TYPE (addr));
  183. DECL_CONTEXT (var) = current_function_decl;
  184. addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
  185. }
  186. lhs = build_indirect_ref (loc, addr, RO_NULL);
  187. if (code == OMP_ATOMIC_READ)
  188. {
  189. x = build1 (OMP_ATOMIC_READ, type, addr);
  190. SET_EXPR_LOCATION (x, loc);
  191. OMP_ATOMIC_SEQ_CST (x) = seq_cst;
  192. return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
  193. loc, x, NULL_TREE);
  194. }
  195. /* There are lots of warnings, errors, and conversions that need to happen
  196. in the course of interpreting a statement. Use the normal mechanisms
  197. to do this, and then take it apart again. */
  198. if (swapped)
  199. {
  200. rhs = build_binary_op (loc, opcode, rhs, lhs, 1);
  201. opcode = NOP_EXPR;
  202. }
  203. bool save = in_late_binary_op;
  204. in_late_binary_op = true;
  205. x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE);
  206. in_late_binary_op = save;
  207. if (x == error_mark_node)
  208. return error_mark_node;
  209. if (TREE_CODE (x) == COMPOUND_EXPR)
  210. {
  211. pre = TREE_OPERAND (x, 0);
  212. gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
  213. x = TREE_OPERAND (x, 1);
  214. }
  215. gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
  216. rhs = TREE_OPERAND (x, 1);
  217. /* Punt the actual generation of atomic operations to common code. */
  218. if (code == OMP_ATOMIC)
  219. type = void_type_node;
  220. x = build2 (code, type, addr, rhs);
  221. SET_EXPR_LOCATION (x, loc);
  222. OMP_ATOMIC_SEQ_CST (x) = seq_cst;
  223. /* Generally it is hard to prove lhs1 and lhs are the same memory
  224. location, just diagnose different variables. */
  225. if (rhs1
  226. && TREE_CODE (rhs1) == VAR_DECL
  227. && TREE_CODE (lhs) == VAR_DECL
  228. && rhs1 != lhs)
  229. {
  230. if (code == OMP_ATOMIC)
  231. error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory");
  232. else
  233. error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
  234. return error_mark_node;
  235. }
  236. if (code != OMP_ATOMIC)
  237. {
  238. /* Generally it is hard to prove lhs1 and lhs are the same memory
  239. location, just diagnose different variables. */
  240. if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL)
  241. {
  242. if (lhs1 != lhs)
  243. {
  244. error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
  245. return error_mark_node;
  246. }
  247. }
  248. x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
  249. loc, x, NULL_TREE);
  250. if (rhs1 && rhs1 != lhs)
  251. {
  252. tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
  253. if (rhs1addr == error_mark_node)
  254. return error_mark_node;
  255. x = omit_one_operand_loc (loc, type, x, rhs1addr);
  256. }
  257. if (lhs1 && lhs1 != lhs)
  258. {
  259. tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0);
  260. if (lhs1addr == error_mark_node)
  261. return error_mark_node;
  262. if (code == OMP_ATOMIC_CAPTURE_OLD)
  263. x = omit_one_operand_loc (loc, type, x, lhs1addr);
  264. else
  265. {
  266. x = save_expr (x);
  267. x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
  268. }
  269. }
  270. }
  271. else if (rhs1 && rhs1 != lhs)
  272. {
  273. tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
  274. if (rhs1addr == error_mark_node)
  275. return error_mark_node;
  276. x = omit_one_operand_loc (loc, type, x, rhs1addr);
  277. }
  278. if (pre)
  279. x = omit_one_operand_loc (loc, type, x, pre);
  280. return x;
  281. }
  282. /* Complete a #pragma omp flush construct. We don't do anything with
  283. the variable list that the syntax allows. LOC is the location of
  284. the #pragma. */
  285. void
  286. c_finish_omp_flush (location_t loc)
  287. {
  288. tree x;
  289. x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
  290. x = build_call_expr_loc (loc, x, 0);
  291. add_stmt (x);
  292. }
  293. /* Check and canonicalize OMP_FOR increment expression.
  294. Helper function for c_finish_omp_for. */
  295. static tree
  296. check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
  297. {
  298. tree t;
  299. if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
  300. || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
  301. return error_mark_node;
  302. if (exp == decl)
  303. return build_int_cst (TREE_TYPE (exp), 0);
  304. switch (TREE_CODE (exp))
  305. {
  306. CASE_CONVERT:
  307. t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
  308. if (t != error_mark_node)
  309. return fold_convert_loc (loc, TREE_TYPE (exp), t);
  310. break;
  311. case MINUS_EXPR:
  312. t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
  313. if (t != error_mark_node)
  314. return fold_build2_loc (loc, MINUS_EXPR,
  315. TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
  316. break;
  317. case PLUS_EXPR:
  318. t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
  319. if (t != error_mark_node)
  320. return fold_build2_loc (loc, PLUS_EXPR,
  321. TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
  322. t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
  323. if (t != error_mark_node)
  324. return fold_build2_loc (loc, PLUS_EXPR,
  325. TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
  326. break;
  327. case COMPOUND_EXPR:
  328. {
  329. /* cp_build_modify_expr forces preevaluation of the RHS to make
  330. sure that it is evaluated before the lvalue-rvalue conversion
  331. is applied to the LHS. Reconstruct the original expression. */
  332. tree op0 = TREE_OPERAND (exp, 0);
  333. if (TREE_CODE (op0) == TARGET_EXPR
  334. && !VOID_TYPE_P (TREE_TYPE (op0)))
  335. {
  336. tree op1 = TREE_OPERAND (exp, 1);
  337. tree temp = TARGET_EXPR_SLOT (op0);
  338. if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
  339. && TREE_OPERAND (op1, 1) == temp)
  340. {
  341. op1 = copy_node (op1);
  342. TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
  343. return check_omp_for_incr_expr (loc, op1, decl);
  344. }
  345. }
  346. break;
  347. }
  348. default:
  349. break;
  350. }
  351. return error_mark_node;
  352. }
  353. /* If the OMP_FOR increment expression in INCR is of pointer type,
  354. canonicalize it into an expression handled by gimplify_omp_for()
  355. and return it. DECL is the iteration variable. */
  356. static tree
  357. c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
  358. {
  359. if (POINTER_TYPE_P (TREE_TYPE (decl))
  360. && TREE_OPERAND (incr, 1))
  361. {
  362. tree t = fold_convert_loc (loc,
  363. sizetype, TREE_OPERAND (incr, 1));
  364. if (TREE_CODE (incr) == POSTDECREMENT_EXPR
  365. || TREE_CODE (incr) == PREDECREMENT_EXPR)
  366. t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
  367. t = fold_build_pointer_plus (decl, t);
  368. incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
  369. }
  370. return incr;
  371. }
  372. /* Validate and generate OMP_FOR.
  373. DECLV is a vector of iteration variables, for each collapsed loop.
  374. INITV, CONDV and INCRV are vectors containing initialization
  375. expressions, controlling predicates and increment expressions.
  376. BODY is the body of the loop and PRE_BODY statements that go before
  377. the loop. */
  378. tree
  379. c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
  380. tree initv, tree condv, tree incrv, tree body, tree pre_body)
  381. {
  382. location_t elocus;
  383. bool fail = false;
  384. int i;
  385. if ((code == CILK_SIMD || code == CILK_FOR)
  386. && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
  387. fail = true;
  388. gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
  389. gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
  390. gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
  391. for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
  392. {
  393. tree decl = TREE_VEC_ELT (declv, i);
  394. tree init = TREE_VEC_ELT (initv, i);
  395. tree cond = TREE_VEC_ELT (condv, i);
  396. tree incr = TREE_VEC_ELT (incrv, i);
  397. elocus = locus;
  398. if (EXPR_HAS_LOCATION (init))
  399. elocus = EXPR_LOCATION (init);
  400. /* Validate the iteration variable. */
  401. if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
  402. && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
  403. {
  404. error_at (elocus, "invalid type for iteration variable %qE", decl);
  405. fail = true;
  406. }
  407. /* In the case of "for (int i = 0...)", init will be a decl. It should
  408. have a DECL_INITIAL that we can turn into an assignment. */
  409. if (init == decl)
  410. {
  411. elocus = DECL_SOURCE_LOCATION (decl);
  412. init = DECL_INITIAL (decl);
  413. if (init == NULL)
  414. {
  415. error_at (elocus, "%qE is not initialized", decl);
  416. init = integer_zero_node;
  417. fail = true;
  418. }
  419. init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
  420. /* FIXME diagnostics: This should
  421. be the location of the INIT. */
  422. elocus,
  423. init,
  424. NULL_TREE);
  425. }
  426. if (init != error_mark_node)
  427. {
  428. gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
  429. gcc_assert (TREE_OPERAND (init, 0) == decl);
  430. }
  431. if (cond == NULL_TREE)
  432. {
  433. error_at (elocus, "missing controlling predicate");
  434. fail = true;
  435. }
  436. else
  437. {
  438. bool cond_ok = false;
  439. if (EXPR_HAS_LOCATION (cond))
  440. elocus = EXPR_LOCATION (cond);
  441. if (TREE_CODE (cond) == LT_EXPR
  442. || TREE_CODE (cond) == LE_EXPR
  443. || TREE_CODE (cond) == GT_EXPR
  444. || TREE_CODE (cond) == GE_EXPR
  445. || TREE_CODE (cond) == NE_EXPR
  446. || TREE_CODE (cond) == EQ_EXPR)
  447. {
  448. tree op0 = TREE_OPERAND (cond, 0);
  449. tree op1 = TREE_OPERAND (cond, 1);
  450. /* 2.5.1. The comparison in the condition is computed in
  451. the type of DECL, otherwise the behavior is undefined.
  452. For example:
  453. long n; int i;
  454. i < n;
  455. according to ISO will be evaluated as:
  456. (long)i < n;
  457. We want to force:
  458. i < (int)n; */
  459. if (TREE_CODE (op0) == NOP_EXPR
  460. && decl == TREE_OPERAND (op0, 0))
  461. {
  462. TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
  463. TREE_OPERAND (cond, 1)
  464. = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
  465. TREE_OPERAND (cond, 1));
  466. }
  467. else if (TREE_CODE (op1) == NOP_EXPR
  468. && decl == TREE_OPERAND (op1, 0))
  469. {
  470. TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
  471. TREE_OPERAND (cond, 0)
  472. = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
  473. TREE_OPERAND (cond, 0));
  474. }
  475. if (decl == TREE_OPERAND (cond, 0))
  476. cond_ok = true;
  477. else if (decl == TREE_OPERAND (cond, 1))
  478. {
  479. TREE_SET_CODE (cond,
  480. swap_tree_comparison (TREE_CODE (cond)));
  481. TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
  482. TREE_OPERAND (cond, 0) = decl;
  483. cond_ok = true;
  484. }
  485. if (TREE_CODE (cond) == NE_EXPR
  486. || TREE_CODE (cond) == EQ_EXPR)
  487. {
  488. if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
  489. {
  490. if (code != CILK_SIMD && code != CILK_FOR)
  491. cond_ok = false;
  492. }
  493. else if (operand_equal_p (TREE_OPERAND (cond, 1),
  494. TYPE_MIN_VALUE (TREE_TYPE (decl)),
  495. 0))
  496. TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
  497. ? GT_EXPR : LE_EXPR);
  498. else if (operand_equal_p (TREE_OPERAND (cond, 1),
  499. TYPE_MAX_VALUE (TREE_TYPE (decl)),
  500. 0))
  501. TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
  502. ? LT_EXPR : GE_EXPR);
  503. else if (code != CILK_SIMD && code != CILK_FOR)
  504. cond_ok = false;
  505. }
  506. }
  507. if (!cond_ok)
  508. {
  509. error_at (elocus, "invalid controlling predicate");
  510. fail = true;
  511. }
  512. }
  513. if (incr == NULL_TREE)
  514. {
  515. error_at (elocus, "missing increment expression");
  516. fail = true;
  517. }
  518. else
  519. {
  520. bool incr_ok = false;
  521. if (EXPR_HAS_LOCATION (incr))
  522. elocus = EXPR_LOCATION (incr);
  523. /* Check all the valid increment expressions: v++, v--, ++v, --v,
  524. v = v + incr, v = incr + v and v = v - incr. */
  525. switch (TREE_CODE (incr))
  526. {
  527. case POSTINCREMENT_EXPR:
  528. case PREINCREMENT_EXPR:
  529. case POSTDECREMENT_EXPR:
  530. case PREDECREMENT_EXPR:
  531. if (TREE_OPERAND (incr, 0) != decl)
  532. break;
  533. incr_ok = true;
  534. incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
  535. break;
  536. case COMPOUND_EXPR:
  537. if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
  538. || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
  539. break;
  540. incr = TREE_OPERAND (incr, 1);
  541. /* FALLTHRU */
  542. case MODIFY_EXPR:
  543. if (TREE_OPERAND (incr, 0) != decl)
  544. break;
  545. if (TREE_OPERAND (incr, 1) == decl)
  546. break;
  547. if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
  548. && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
  549. || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
  550. incr_ok = true;
  551. else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
  552. || (TREE_CODE (TREE_OPERAND (incr, 1))
  553. == POINTER_PLUS_EXPR))
  554. && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
  555. incr_ok = true;
  556. else
  557. {
  558. tree t = check_omp_for_incr_expr (elocus,
  559. TREE_OPERAND (incr, 1),
  560. decl);
  561. if (t != error_mark_node)
  562. {
  563. incr_ok = true;
  564. t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
  565. incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
  566. }
  567. }
  568. break;
  569. default:
  570. break;
  571. }
  572. if (!incr_ok)
  573. {
  574. error_at (elocus, "invalid increment expression");
  575. fail = true;
  576. }
  577. }
  578. TREE_VEC_ELT (initv, i) = init;
  579. TREE_VEC_ELT (incrv, i) = incr;
  580. }
  581. if (fail)
  582. return NULL;
  583. else
  584. {
  585. tree t = make_node (code);
  586. TREE_TYPE (t) = void_type_node;
  587. OMP_FOR_INIT (t) = initv;
  588. OMP_FOR_COND (t) = condv;
  589. OMP_FOR_INCR (t) = incrv;
  590. OMP_FOR_BODY (t) = body;
  591. OMP_FOR_PRE_BODY (t) = pre_body;
  592. SET_EXPR_LOCATION (t, locus);
  593. return add_stmt (t);
  594. }
  595. }
  596. /* Right now we have 14 different combined constructs, this
  597. function attempts to split or duplicate clauses for combined
  598. constructs. CODE is the innermost construct in the combined construct,
  599. and MASK allows to determine which constructs are combined together,
  600. as every construct has at least one clause that no other construct
  601. has (except for OMP_SECTIONS, but that can be only combined with parallel).
  602. Combined constructs are:
  603. #pragma omp parallel for
  604. #pragma omp parallel sections
  605. #pragma omp parallel for simd
  606. #pragma omp for simd
  607. #pragma omp distribute simd
  608. #pragma omp distribute parallel for
  609. #pragma omp distribute parallel for simd
  610. #pragma omp teams distribute
  611. #pragma omp teams distribute parallel for
  612. #pragma omp teams distribute parallel for simd
  613. #pragma omp target teams
  614. #pragma omp target teams distribute
  615. #pragma omp target teams distribute parallel for
  616. #pragma omp target teams distribute parallel for simd */
  617. void
  618. c_omp_split_clauses (location_t loc, enum tree_code code,
  619. omp_clause_mask mask, tree clauses, tree *cclauses)
  620. {
  621. tree next, c;
  622. enum c_omp_clause_split s;
  623. int i;
  624. for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
  625. cclauses[i] = NULL;
  626. /* Add implicit nowait clause on
  627. #pragma omp parallel {for,for simd,sections}. */
  628. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
  629. switch (code)
  630. {
  631. case OMP_FOR:
  632. case OMP_SIMD:
  633. cclauses[C_OMP_CLAUSE_SPLIT_FOR]
  634. = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
  635. break;
  636. case OMP_SECTIONS:
  637. cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
  638. = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
  639. break;
  640. default:
  641. break;
  642. }
  643. for (; clauses ; clauses = next)
  644. {
  645. next = OMP_CLAUSE_CHAIN (clauses);
  646. switch (OMP_CLAUSE_CODE (clauses))
  647. {
  648. /* First the clauses that are unique to some constructs. */
  649. case OMP_CLAUSE_DEVICE:
  650. case OMP_CLAUSE_MAP:
  651. s = C_OMP_CLAUSE_SPLIT_TARGET;
  652. break;
  653. case OMP_CLAUSE_NUM_TEAMS:
  654. case OMP_CLAUSE_THREAD_LIMIT:
  655. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  656. break;
  657. case OMP_CLAUSE_DIST_SCHEDULE:
  658. s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
  659. break;
  660. case OMP_CLAUSE_COPYIN:
  661. case OMP_CLAUSE_NUM_THREADS:
  662. case OMP_CLAUSE_PROC_BIND:
  663. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  664. break;
  665. case OMP_CLAUSE_ORDERED:
  666. case OMP_CLAUSE_SCHEDULE:
  667. case OMP_CLAUSE_NOWAIT:
  668. s = C_OMP_CLAUSE_SPLIT_FOR;
  669. break;
  670. case OMP_CLAUSE_SAFELEN:
  671. case OMP_CLAUSE_LINEAR:
  672. case OMP_CLAUSE_ALIGNED:
  673. s = C_OMP_CLAUSE_SPLIT_SIMD;
  674. break;
  675. /* Duplicate this to all of distribute, for and simd. */
  676. case OMP_CLAUSE_COLLAPSE:
  677. if (code == OMP_SIMD)
  678. {
  679. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  680. OMP_CLAUSE_COLLAPSE);
  681. OMP_CLAUSE_COLLAPSE_EXPR (c)
  682. = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
  683. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
  684. cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
  685. }
  686. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
  687. {
  688. if ((mask & (OMP_CLAUSE_MASK_1
  689. << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
  690. {
  691. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  692. OMP_CLAUSE_COLLAPSE);
  693. OMP_CLAUSE_COLLAPSE_EXPR (c)
  694. = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
  695. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
  696. cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
  697. s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
  698. }
  699. else
  700. s = C_OMP_CLAUSE_SPLIT_FOR;
  701. }
  702. else
  703. s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
  704. break;
  705. /* Private clause is supported on all constructs but target,
  706. it is enough to put it on the innermost one. For
  707. #pragma omp {for,sections} put it on parallel though,
  708. as that's what we did for OpenMP 3.1. */
  709. case OMP_CLAUSE_PRIVATE:
  710. switch (code)
  711. {
  712. case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
  713. case OMP_FOR: case OMP_SECTIONS:
  714. case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
  715. case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
  716. case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
  717. default: gcc_unreachable ();
  718. }
  719. break;
  720. /* Firstprivate clause is supported on all constructs but
  721. target and simd. Put it on the outermost of those and
  722. duplicate on parallel. */
  723. case OMP_CLAUSE_FIRSTPRIVATE:
  724. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
  725. != 0)
  726. {
  727. if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
  728. | (OMP_CLAUSE_MASK_1
  729. << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
  730. {
  731. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  732. OMP_CLAUSE_FIRSTPRIVATE);
  733. OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
  734. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
  735. cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
  736. if ((mask & (OMP_CLAUSE_MASK_1
  737. << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
  738. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  739. else
  740. s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
  741. }
  742. else
  743. /* This must be
  744. #pragma omp parallel{, for{, simd}, sections}. */
  745. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  746. }
  747. else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
  748. != 0)
  749. {
  750. /* This must be one of
  751. #pragma omp {,target }teams distribute
  752. #pragma omp target teams
  753. #pragma omp {,target }teams distribute simd. */
  754. gcc_assert (code == OMP_DISTRIBUTE
  755. || code == OMP_TEAMS
  756. || code == OMP_SIMD);
  757. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  758. }
  759. else if ((mask & (OMP_CLAUSE_MASK_1
  760. << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
  761. {
  762. /* This must be #pragma omp distribute simd. */
  763. gcc_assert (code == OMP_SIMD);
  764. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  765. }
  766. else
  767. {
  768. /* This must be #pragma omp for simd. */
  769. gcc_assert (code == OMP_SIMD);
  770. s = C_OMP_CLAUSE_SPLIT_FOR;
  771. }
  772. break;
  773. /* Lastprivate is allowed on for, sections and simd. In
  774. parallel {for{, simd},sections} we actually want to put it on
  775. parallel rather than for or sections. */
  776. case OMP_CLAUSE_LASTPRIVATE:
  777. if (code == OMP_FOR || code == OMP_SECTIONS)
  778. {
  779. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
  780. != 0)
  781. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  782. else
  783. s = C_OMP_CLAUSE_SPLIT_FOR;
  784. break;
  785. }
  786. gcc_assert (code == OMP_SIMD);
  787. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
  788. {
  789. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  790. OMP_CLAUSE_LASTPRIVATE);
  791. OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
  792. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
  793. != 0)
  794. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  795. else
  796. s = C_OMP_CLAUSE_SPLIT_FOR;
  797. OMP_CLAUSE_CHAIN (c) = cclauses[s];
  798. cclauses[s] = c;
  799. }
  800. s = C_OMP_CLAUSE_SPLIT_SIMD;
  801. break;
  802. /* Shared and default clauses are allowed on private and teams. */
  803. case OMP_CLAUSE_SHARED:
  804. case OMP_CLAUSE_DEFAULT:
  805. if (code == OMP_TEAMS)
  806. {
  807. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  808. break;
  809. }
  810. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
  811. != 0)
  812. {
  813. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  814. OMP_CLAUSE_CODE (clauses));
  815. if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
  816. OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
  817. else
  818. OMP_CLAUSE_DEFAULT_KIND (c)
  819. = OMP_CLAUSE_DEFAULT_KIND (clauses);
  820. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
  821. cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
  822. }
  823. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  824. break;
  825. /* Reduction is allowed on simd, for, parallel, sections and teams.
  826. Duplicate it on all of them, but omit on for or sections if
  827. parallel is present. */
  828. case OMP_CLAUSE_REDUCTION:
  829. if (code == OMP_SIMD)
  830. {
  831. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  832. OMP_CLAUSE_REDUCTION);
  833. OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
  834. OMP_CLAUSE_REDUCTION_CODE (c)
  835. = OMP_CLAUSE_REDUCTION_CODE (clauses);
  836. OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
  837. = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
  838. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
  839. cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
  840. }
  841. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
  842. {
  843. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
  844. != 0)
  845. {
  846. c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
  847. OMP_CLAUSE_REDUCTION);
  848. OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
  849. OMP_CLAUSE_REDUCTION_CODE (c)
  850. = OMP_CLAUSE_REDUCTION_CODE (clauses);
  851. OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
  852. = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
  853. OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
  854. cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
  855. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  856. }
  857. else if ((mask & (OMP_CLAUSE_MASK_1
  858. << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
  859. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  860. else
  861. s = C_OMP_CLAUSE_SPLIT_FOR;
  862. }
  863. else if (code == OMP_SECTIONS)
  864. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  865. else
  866. s = C_OMP_CLAUSE_SPLIT_TEAMS;
  867. break;
  868. case OMP_CLAUSE_IF:
  869. /* FIXME: This is currently being discussed. */
  870. if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
  871. != 0)
  872. s = C_OMP_CLAUSE_SPLIT_PARALLEL;
  873. else
  874. s = C_OMP_CLAUSE_SPLIT_TARGET;
  875. break;
  876. default:
  877. gcc_unreachable ();
  878. }
  879. OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
  880. cclauses[s] = clauses;
  881. }
  882. }
  883. /* qsort callback to compare #pragma omp declare simd clauses. */
  884. static int
  885. c_omp_declare_simd_clause_cmp (const void *p, const void *q)
  886. {
  887. tree a = *(const tree *) p;
  888. tree b = *(const tree *) q;
  889. if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
  890. {
  891. if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
  892. return -1;
  893. return 1;
  894. }
  895. if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
  896. && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
  897. && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
  898. {
  899. int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
  900. int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
  901. if (c < d)
  902. return 1;
  903. if (c > d)
  904. return -1;
  905. }
  906. return 0;
  907. }
  908. /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
  909. CLAUSES on FNDECL into argument indexes and sort them. */
  910. tree
  911. c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
  912. {
  913. tree c;
  914. vec<tree> clvec = vNULL;
  915. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  916. {
  917. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
  918. && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
  919. && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
  920. {
  921. tree decl = OMP_CLAUSE_DECL (c);
  922. tree arg;
  923. int idx;
  924. for (arg = parms, idx = 0; arg;
  925. arg = TREE_CHAIN (arg), idx++)
  926. if (arg == decl)
  927. break;
  928. if (arg == NULL_TREE)
  929. {
  930. error_at (OMP_CLAUSE_LOCATION (c),
  931. "%qD is not an function argument", decl);
  932. continue;
  933. }
  934. OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
  935. }
  936. clvec.safe_push (c);
  937. }
  938. if (!clvec.is_empty ())
  939. {
  940. unsigned int len = clvec.length (), i;
  941. clvec.qsort (c_omp_declare_simd_clause_cmp);
  942. clauses = clvec[0];
  943. for (i = 0; i < len; i++)
  944. OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
  945. }
  946. else
  947. clauses = NULL_TREE;
  948. clvec.release ();
  949. return clauses;
  950. }
  951. /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
  952. void
  953. c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
  954. {
  955. tree c;
  956. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  957. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
  958. && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
  959. && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
  960. {
  961. int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
  962. tree arg;
  963. for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
  964. arg = TREE_CHAIN (arg), i++)
  965. if (i == idx)
  966. break;
  967. gcc_assert (arg);
  968. OMP_CLAUSE_DECL (c) = arg;
  969. }
  970. }
  971. /* True if OpenMP sharing attribute of DECL is predetermined. */
  972. enum omp_clause_default_kind
  973. c_omp_predetermined_sharing (tree decl)
  974. {
  975. /* Variables with const-qualified type having no mutable member
  976. are predetermined shared. */
  977. if (TREE_READONLY (decl))
  978. return OMP_CLAUSE_DEFAULT_SHARED;
  979. return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
  980. }