1*404b540aSrobert /* This file contains routines to construct GNU OpenMP constructs,
2*404b540aSrobert called from parsing in the C and C++ front ends.
3*404b540aSrobert
4*404b540aSrobert Copyright (C) 2005 Free Software Foundation, Inc.
5*404b540aSrobert Contributed by Richard Henderson <rth@redhat.com>,
6*404b540aSrobert Diego Novillo <dnovillo@redhat.com>.
7*404b540aSrobert
8*404b540aSrobert This file is part of GCC.
9*404b540aSrobert
10*404b540aSrobert GCC is free software; you can redistribute it and/or modify it under
11*404b540aSrobert the terms of the GNU General Public License as published by the Free
12*404b540aSrobert Software Foundation; either version 2, or (at your option) any later
13*404b540aSrobert version.
14*404b540aSrobert
15*404b540aSrobert GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16*404b540aSrobert WARRANTY; without even the implied warranty of MERCHANTABILITY or
17*404b540aSrobert FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18*404b540aSrobert for more details.
19*404b540aSrobert
20*404b540aSrobert You should have received a copy of the GNU General Public License
21*404b540aSrobert along with GCC; see the file COPYING. If not, write to the Free
22*404b540aSrobert Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23*404b540aSrobert 02110-1301, USA. */
24*404b540aSrobert
25*404b540aSrobert #include "config.h"
26*404b540aSrobert #include "system.h"
27*404b540aSrobert #include "coretypes.h"
28*404b540aSrobert #include "tm.h"
29*404b540aSrobert #include "tree.h"
30*404b540aSrobert #include "function.h"
31*404b540aSrobert #include "c-common.h"
32*404b540aSrobert #include "toplev.h"
33*404b540aSrobert #include "tree-gimple.h"
34*404b540aSrobert #include "bitmap.h"
35*404b540aSrobert #include "langhooks.h"
36*404b540aSrobert
37*404b540aSrobert
38*404b540aSrobert /* Complete a #pragma omp master construct. STMT is the structured-block
39*404b540aSrobert that follows the pragma. */
40*404b540aSrobert
41*404b540aSrobert tree
c_finish_omp_master(tree stmt)42*404b540aSrobert c_finish_omp_master (tree stmt)
43*404b540aSrobert {
44*404b540aSrobert return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
45*404b540aSrobert }
46*404b540aSrobert
47*404b540aSrobert /* Complete a #pragma omp critical construct. STMT is the structured-block
48*404b540aSrobert that follows the pragma, NAME is the identifier in the pragma, or null
49*404b540aSrobert if it was omitted. */
50*404b540aSrobert
51*404b540aSrobert tree
c_finish_omp_critical(tree body,tree name)52*404b540aSrobert c_finish_omp_critical (tree body, tree name)
53*404b540aSrobert {
54*404b540aSrobert tree stmt = make_node (OMP_CRITICAL);
55*404b540aSrobert TREE_TYPE (stmt) = void_type_node;
56*404b540aSrobert OMP_CRITICAL_BODY (stmt) = body;
57*404b540aSrobert OMP_CRITICAL_NAME (stmt) = name;
58*404b540aSrobert return add_stmt (stmt);
59*404b540aSrobert }
60*404b540aSrobert
61*404b540aSrobert /* Complete a #pragma omp ordered construct. STMT is the structured-block
62*404b540aSrobert that follows the pragma. */
63*404b540aSrobert
64*404b540aSrobert tree
c_finish_omp_ordered(tree stmt)65*404b540aSrobert c_finish_omp_ordered (tree stmt)
66*404b540aSrobert {
67*404b540aSrobert return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
68*404b540aSrobert }
69*404b540aSrobert
70*404b540aSrobert
71*404b540aSrobert /* Complete a #pragma omp barrier construct. */
72*404b540aSrobert
73*404b540aSrobert void
c_finish_omp_barrier(void)74*404b540aSrobert c_finish_omp_barrier (void)
75*404b540aSrobert {
76*404b540aSrobert tree x;
77*404b540aSrobert
78*404b540aSrobert x = built_in_decls[BUILT_IN_GOMP_BARRIER];
79*404b540aSrobert x = build_function_call_expr (x, NULL);
80*404b540aSrobert add_stmt (x);
81*404b540aSrobert }
82*404b540aSrobert
83*404b540aSrobert
84*404b540aSrobert /* Complete a #pragma omp atomic construct. The expression to be
85*404b540aSrobert implemented atomically is LHS code= RHS. The value returned is
86*404b540aSrobert either error_mark_node (if the construct was erroneous) or an
87*404b540aSrobert OMP_ATOMIC node which should be added to the current statement tree
88*404b540aSrobert with add_stmt. */
89*404b540aSrobert
90*404b540aSrobert tree
c_finish_omp_atomic(enum tree_code code,tree lhs,tree rhs)91*404b540aSrobert c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
92*404b540aSrobert {
93*404b540aSrobert tree x, type, addr;
94*404b540aSrobert
95*404b540aSrobert if (lhs == error_mark_node || rhs == error_mark_node)
96*404b540aSrobert return error_mark_node;
97*404b540aSrobert
98*404b540aSrobert /* ??? According to one reading of the OpenMP spec, complex type are
99*404b540aSrobert supported, but there are no atomic stores for any architecture.
100*404b540aSrobert But at least icc 9.0 doesn't support complex types here either.
101*404b540aSrobert And lets not even talk about vector types... */
102*404b540aSrobert type = TREE_TYPE (lhs);
103*404b540aSrobert if (!INTEGRAL_TYPE_P (type)
104*404b540aSrobert && !POINTER_TYPE_P (type)
105*404b540aSrobert && !SCALAR_FLOAT_TYPE_P (type))
106*404b540aSrobert {
107*404b540aSrobert error ("invalid expression type for %<#pragma omp atomic%>");
108*404b540aSrobert return error_mark_node;
109*404b540aSrobert }
110*404b540aSrobert
111*404b540aSrobert /* ??? Validate that rhs does not overlap lhs. */
112*404b540aSrobert
113*404b540aSrobert /* Take and save the address of the lhs. From then on we'll reference it
114*404b540aSrobert via indirection. */
115*404b540aSrobert addr = build_unary_op (ADDR_EXPR, lhs, 0);
116*404b540aSrobert if (addr == error_mark_node)
117*404b540aSrobert return error_mark_node;
118*404b540aSrobert addr = save_expr (addr);
119*404b540aSrobert if (TREE_CODE (addr) != SAVE_EXPR
120*404b540aSrobert && (TREE_CODE (addr) != ADDR_EXPR
121*404b540aSrobert || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
122*404b540aSrobert {
123*404b540aSrobert /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
124*404b540aSrobert it even after unsharing function body. */
125*404b540aSrobert tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
126*404b540aSrobert addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
127*404b540aSrobert }
128*404b540aSrobert lhs = build_indirect_ref (addr, NULL);
129*404b540aSrobert
130*404b540aSrobert /* There are lots of warnings, errors, and conversions that need to happen
131*404b540aSrobert in the course of interpreting a statement. Use the normal mechanisms
132*404b540aSrobert to do this, and then take it apart again. */
133*404b540aSrobert x = build_modify_expr (lhs, code, rhs);
134*404b540aSrobert if (x == error_mark_node)
135*404b540aSrobert return error_mark_node;
136*404b540aSrobert gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
137*404b540aSrobert rhs = TREE_OPERAND (x, 1);
138*404b540aSrobert
139*404b540aSrobert /* Punt the actual generation of atomic operations to common code. */
140*404b540aSrobert return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
141*404b540aSrobert }
142*404b540aSrobert
143*404b540aSrobert
144*404b540aSrobert /* Complete a #pragma omp flush construct. We don't do anything with the
145*404b540aSrobert variable list that the syntax allows. */
146*404b540aSrobert
147*404b540aSrobert void
c_finish_omp_flush(void)148*404b540aSrobert c_finish_omp_flush (void)
149*404b540aSrobert {
150*404b540aSrobert tree x;
151*404b540aSrobert
152*404b540aSrobert x = built_in_decls[BUILT_IN_SYNCHRONIZE];
153*404b540aSrobert x = build_function_call_expr (x, NULL);
154*404b540aSrobert add_stmt (x);
155*404b540aSrobert }
156*404b540aSrobert
157*404b540aSrobert
158*404b540aSrobert /* Check and canonicalize #pragma omp for increment expression.
159*404b540aSrobert Helper function for c_finish_omp_for. */
160*404b540aSrobert
161*404b540aSrobert static tree
check_omp_for_incr_expr(tree exp,tree decl)162*404b540aSrobert check_omp_for_incr_expr (tree exp, tree decl)
163*404b540aSrobert {
164*404b540aSrobert tree t;
165*404b540aSrobert
166*404b540aSrobert if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
167*404b540aSrobert || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
168*404b540aSrobert return error_mark_node;
169*404b540aSrobert
170*404b540aSrobert if (exp == decl)
171*404b540aSrobert return build_int_cst (TREE_TYPE (exp), 0);
172*404b540aSrobert
173*404b540aSrobert switch (TREE_CODE (exp))
174*404b540aSrobert {
175*404b540aSrobert case NOP_EXPR:
176*404b540aSrobert t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
177*404b540aSrobert if (t != error_mark_node)
178*404b540aSrobert return fold_convert (TREE_TYPE (exp), t);
179*404b540aSrobert break;
180*404b540aSrobert case MINUS_EXPR:
181*404b540aSrobert t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
182*404b540aSrobert if (t != error_mark_node)
183*404b540aSrobert return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
184*404b540aSrobert break;
185*404b540aSrobert case PLUS_EXPR:
186*404b540aSrobert t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
187*404b540aSrobert if (t != error_mark_node)
188*404b540aSrobert return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
189*404b540aSrobert t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
190*404b540aSrobert if (t != error_mark_node)
191*404b540aSrobert return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
192*404b540aSrobert break;
193*404b540aSrobert default:
194*404b540aSrobert break;
195*404b540aSrobert }
196*404b540aSrobert
197*404b540aSrobert return error_mark_node;
198*404b540aSrobert }
199*404b540aSrobert
200*404b540aSrobert /* Validate and emit code for the OpenMP directive #pragma omp for.
201*404b540aSrobert INIT, COND, INCR, BODY and PRE_BODY are the five basic elements
202*404b540aSrobert of the loop (initialization expression, controlling predicate, increment
203*404b540aSrobert expression, body of the loop and statements to go before the loop).
204*404b540aSrobert DECL is the iteration variable. */
205*404b540aSrobert
206*404b540aSrobert tree
c_finish_omp_for(location_t locus,tree decl,tree init,tree cond,tree incr,tree body,tree pre_body)207*404b540aSrobert c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
208*404b540aSrobert tree incr, tree body, tree pre_body)
209*404b540aSrobert {
210*404b540aSrobert location_t elocus = locus;
211*404b540aSrobert bool fail = false;
212*404b540aSrobert
213*404b540aSrobert if (EXPR_HAS_LOCATION (init))
214*404b540aSrobert elocus = EXPR_LOCATION (init);
215*404b540aSrobert
216*404b540aSrobert /* Validate the iteration variable. */
217*404b540aSrobert if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
218*404b540aSrobert {
219*404b540aSrobert error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
220*404b540aSrobert fail = true;
221*404b540aSrobert }
222*404b540aSrobert if (TYPE_UNSIGNED (TREE_TYPE (decl)))
223*404b540aSrobert warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
224*404b540aSrobert
225*404b540aSrobert /* In the case of "for (int i = 0...)", init will be a decl. It should
226*404b540aSrobert have a DECL_INITIAL that we can turn into an assignment. */
227*404b540aSrobert if (init == decl)
228*404b540aSrobert {
229*404b540aSrobert elocus = DECL_SOURCE_LOCATION (decl);
230*404b540aSrobert
231*404b540aSrobert init = DECL_INITIAL (decl);
232*404b540aSrobert if (init == NULL)
233*404b540aSrobert {
234*404b540aSrobert error ("%H%qE is not initialized", &elocus, decl);
235*404b540aSrobert init = integer_zero_node;
236*404b540aSrobert fail = true;
237*404b540aSrobert }
238*404b540aSrobert
239*404b540aSrobert init = build_modify_expr (decl, NOP_EXPR, init);
240*404b540aSrobert SET_EXPR_LOCATION (init, elocus);
241*404b540aSrobert }
242*404b540aSrobert gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
243*404b540aSrobert gcc_assert (TREE_OPERAND (init, 0) == decl);
244*404b540aSrobert
245*404b540aSrobert if (cond == NULL_TREE)
246*404b540aSrobert {
247*404b540aSrobert error ("%Hmissing controlling predicate", &elocus);
248*404b540aSrobert fail = true;
249*404b540aSrobert }
250*404b540aSrobert else
251*404b540aSrobert {
252*404b540aSrobert bool cond_ok = false;
253*404b540aSrobert
254*404b540aSrobert if (EXPR_HAS_LOCATION (cond))
255*404b540aSrobert elocus = EXPR_LOCATION (cond);
256*404b540aSrobert
257*404b540aSrobert if (TREE_CODE (cond) == LT_EXPR
258*404b540aSrobert || TREE_CODE (cond) == LE_EXPR
259*404b540aSrobert || TREE_CODE (cond) == GT_EXPR
260*404b540aSrobert || TREE_CODE (cond) == GE_EXPR)
261*404b540aSrobert {
262*404b540aSrobert tree op0 = TREE_OPERAND (cond, 0);
263*404b540aSrobert tree op1 = TREE_OPERAND (cond, 1);
264*404b540aSrobert
265*404b540aSrobert /* 2.5.1. The comparison in the condition is computed in the type
266*404b540aSrobert of DECL, otherwise the behavior is undefined.
267*404b540aSrobert
268*404b540aSrobert For example:
269*404b540aSrobert long n; int i;
270*404b540aSrobert i < n;
271*404b540aSrobert
272*404b540aSrobert according to ISO will be evaluated as:
273*404b540aSrobert (long)i < n;
274*404b540aSrobert
275*404b540aSrobert We want to force:
276*404b540aSrobert i < (int)n; */
277*404b540aSrobert if (TREE_CODE (op0) == NOP_EXPR
278*404b540aSrobert && decl == TREE_OPERAND (op0, 0))
279*404b540aSrobert {
280*404b540aSrobert TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
281*404b540aSrobert TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
282*404b540aSrobert TREE_OPERAND (cond, 1));
283*404b540aSrobert }
284*404b540aSrobert else if (TREE_CODE (op1) == NOP_EXPR
285*404b540aSrobert && decl == TREE_OPERAND (op1, 0))
286*404b540aSrobert {
287*404b540aSrobert TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
288*404b540aSrobert TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
289*404b540aSrobert TREE_OPERAND (cond, 0));
290*404b540aSrobert }
291*404b540aSrobert
292*404b540aSrobert if (decl == TREE_OPERAND (cond, 0))
293*404b540aSrobert cond_ok = true;
294*404b540aSrobert else if (decl == TREE_OPERAND (cond, 1))
295*404b540aSrobert {
296*404b540aSrobert TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
297*404b540aSrobert TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
298*404b540aSrobert TREE_OPERAND (cond, 0) = decl;
299*404b540aSrobert cond_ok = true;
300*404b540aSrobert }
301*404b540aSrobert }
302*404b540aSrobert
303*404b540aSrobert if (!cond_ok)
304*404b540aSrobert {
305*404b540aSrobert error ("%Hinvalid controlling predicate", &elocus);
306*404b540aSrobert fail = true;
307*404b540aSrobert }
308*404b540aSrobert }
309*404b540aSrobert
310*404b540aSrobert if (incr == NULL_TREE)
311*404b540aSrobert {
312*404b540aSrobert error ("%Hmissing increment expression", &elocus);
313*404b540aSrobert fail = true;
314*404b540aSrobert }
315*404b540aSrobert else
316*404b540aSrobert {
317*404b540aSrobert bool incr_ok = false;
318*404b540aSrobert
319*404b540aSrobert if (EXPR_HAS_LOCATION (incr))
320*404b540aSrobert elocus = EXPR_LOCATION (incr);
321*404b540aSrobert
322*404b540aSrobert /* Check all the valid increment expressions: v++, v--, ++v, --v,
323*404b540aSrobert v = v + incr, v = incr + v and v = v - incr. */
324*404b540aSrobert switch (TREE_CODE (incr))
325*404b540aSrobert {
326*404b540aSrobert case POSTINCREMENT_EXPR:
327*404b540aSrobert case PREINCREMENT_EXPR:
328*404b540aSrobert case POSTDECREMENT_EXPR:
329*404b540aSrobert case PREDECREMENT_EXPR:
330*404b540aSrobert incr_ok = (TREE_OPERAND (incr, 0) == decl);
331*404b540aSrobert break;
332*404b540aSrobert
333*404b540aSrobert case MODIFY_EXPR:
334*404b540aSrobert if (TREE_OPERAND (incr, 0) != decl)
335*404b540aSrobert break;
336*404b540aSrobert if (TREE_OPERAND (incr, 1) == decl)
337*404b540aSrobert break;
338*404b540aSrobert if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
339*404b540aSrobert && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
340*404b540aSrobert || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
341*404b540aSrobert incr_ok = true;
342*404b540aSrobert else if (TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
343*404b540aSrobert && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
344*404b540aSrobert incr_ok = true;
345*404b540aSrobert else
346*404b540aSrobert {
347*404b540aSrobert tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), decl);
348*404b540aSrobert if (t != error_mark_node)
349*404b540aSrobert {
350*404b540aSrobert incr_ok = true;
351*404b540aSrobert t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
352*404b540aSrobert incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
353*404b540aSrobert }
354*404b540aSrobert }
355*404b540aSrobert break;
356*404b540aSrobert
357*404b540aSrobert default:
358*404b540aSrobert break;
359*404b540aSrobert }
360*404b540aSrobert if (!incr_ok)
361*404b540aSrobert {
362*404b540aSrobert error ("%Hinvalid increment expression", &elocus);
363*404b540aSrobert fail = true;
364*404b540aSrobert }
365*404b540aSrobert }
366*404b540aSrobert
367*404b540aSrobert if (fail)
368*404b540aSrobert return NULL;
369*404b540aSrobert else
370*404b540aSrobert {
371*404b540aSrobert tree t = make_node (OMP_FOR);
372*404b540aSrobert
373*404b540aSrobert TREE_TYPE (t) = void_type_node;
374*404b540aSrobert OMP_FOR_INIT (t) = init;
375*404b540aSrobert OMP_FOR_COND (t) = cond;
376*404b540aSrobert OMP_FOR_INCR (t) = incr;
377*404b540aSrobert OMP_FOR_BODY (t) = body;
378*404b540aSrobert OMP_FOR_PRE_BODY (t) = pre_body;
379*404b540aSrobert
380*404b540aSrobert SET_EXPR_LOCATION (t, locus);
381*404b540aSrobert return add_stmt (t);
382*404b540aSrobert }
383*404b540aSrobert }
384*404b540aSrobert
385*404b540aSrobert
386*404b540aSrobert /* Divide CLAUSES into two lists: those that apply to a parallel construct,
387*404b540aSrobert and those that apply to a work-sharing construct. Place the results in
388*404b540aSrobert *PAR_CLAUSES and *WS_CLAUSES respectively. In addition, add a nowait
389*404b540aSrobert clause to the work-sharing list. */
390*404b540aSrobert
391*404b540aSrobert void
c_split_parallel_clauses(tree clauses,tree * par_clauses,tree * ws_clauses)392*404b540aSrobert c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
393*404b540aSrobert {
394*404b540aSrobert tree next;
395*404b540aSrobert
396*404b540aSrobert *par_clauses = NULL;
397*404b540aSrobert *ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT);
398*404b540aSrobert
399*404b540aSrobert for (; clauses ; clauses = next)
400*404b540aSrobert {
401*404b540aSrobert next = OMP_CLAUSE_CHAIN (clauses);
402*404b540aSrobert
403*404b540aSrobert switch (OMP_CLAUSE_CODE (clauses))
404*404b540aSrobert {
405*404b540aSrobert case OMP_CLAUSE_PRIVATE:
406*404b540aSrobert case OMP_CLAUSE_SHARED:
407*404b540aSrobert case OMP_CLAUSE_FIRSTPRIVATE:
408*404b540aSrobert case OMP_CLAUSE_LASTPRIVATE:
409*404b540aSrobert case OMP_CLAUSE_REDUCTION:
410*404b540aSrobert case OMP_CLAUSE_COPYIN:
411*404b540aSrobert case OMP_CLAUSE_IF:
412*404b540aSrobert case OMP_CLAUSE_NUM_THREADS:
413*404b540aSrobert case OMP_CLAUSE_DEFAULT:
414*404b540aSrobert OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
415*404b540aSrobert *par_clauses = clauses;
416*404b540aSrobert break;
417*404b540aSrobert
418*404b540aSrobert case OMP_CLAUSE_SCHEDULE:
419*404b540aSrobert case OMP_CLAUSE_ORDERED:
420*404b540aSrobert OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
421*404b540aSrobert *ws_clauses = clauses;
422*404b540aSrobert break;
423*404b540aSrobert
424*404b540aSrobert default:
425*404b540aSrobert gcc_unreachable ();
426*404b540aSrobert }
427*404b540aSrobert }
428*404b540aSrobert }
429*404b540aSrobert
430*404b540aSrobert /* True if OpenMP sharing attribute of DECL is predetermined. */
431*404b540aSrobert
432*404b540aSrobert enum omp_clause_default_kind
c_omp_predetermined_sharing(tree decl)433*404b540aSrobert c_omp_predetermined_sharing (tree decl)
434*404b540aSrobert {
435*404b540aSrobert /* Variables with const-qualified type having no mutable member
436*404b540aSrobert are predetermined shared. */
437*404b540aSrobert if (TREE_READONLY (decl))
438*404b540aSrobert return OMP_CLAUSE_DEFAULT_SHARED;
439*404b540aSrobert
440*404b540aSrobert return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
441*404b540aSrobert }
442