xref: /openbsd/gnu/gcc/gcc/c-omp.c (revision 404b540a)
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