comparison gcc/c-omp.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* This file contains routines to construct GNU OpenMP constructs, 1 /* This file contains routines to construct GNU OpenMP constructs,
2 called from parsing in the C and C++ front ends. 2 called from parsing in the C and C++ front ends.
3 3
4 Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. 4 Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by Richard Henderson <rth@redhat.com>, 5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>. 6 Diego Novillo <dnovillo@redhat.com>.
33 #include "bitmap.h" 33 #include "bitmap.h"
34 #include "langhooks.h" 34 #include "langhooks.h"
35 35
36 36
37 /* Complete a #pragma omp master construct. STMT is the structured-block 37 /* Complete a #pragma omp master construct. STMT is the structured-block
38 that follows the pragma. */ 38 that follows the pragma. LOC is the l*/
39 39
40 tree 40 tree
41 c_finish_omp_master (tree stmt) 41 c_finish_omp_master (location_t loc, tree stmt)
42 { 42 {
43 return add_stmt (build1 (OMP_MASTER, void_type_node, stmt)); 43 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
44 SET_EXPR_LOCATION (t, loc);
45 return t;
44 } 46 }
45 47
46 /* Complete a #pragma omp critical construct. STMT is the structured-block 48 /* Complete a #pragma omp critical construct. STMT is the structured-block
47 that follows the pragma, NAME is the identifier in the pragma, or null 49 that follows the pragma, NAME is the identifier in the pragma, or null
48 if it was omitted. */ 50 if it was omitted. LOC is the location of the #pragma. */
49 51
50 tree 52 tree
51 c_finish_omp_critical (tree body, tree name) 53 c_finish_omp_critical (location_t loc, tree body, tree name)
52 { 54 {
53 tree stmt = make_node (OMP_CRITICAL); 55 tree stmt = make_node (OMP_CRITICAL);
54 TREE_TYPE (stmt) = void_type_node; 56 TREE_TYPE (stmt) = void_type_node;
55 OMP_CRITICAL_BODY (stmt) = body; 57 OMP_CRITICAL_BODY (stmt) = body;
56 OMP_CRITICAL_NAME (stmt) = name; 58 OMP_CRITICAL_NAME (stmt) = name;
59 SET_EXPR_LOCATION (stmt, loc);
57 return add_stmt (stmt); 60 return add_stmt (stmt);
58 } 61 }
59 62
60 /* Complete a #pragma omp ordered construct. STMT is the structured-block 63 /* Complete a #pragma omp ordered construct. STMT is the structured-block
61 that follows the pragma. */ 64 that follows the pragma. LOC is the location of the #pragma. */
62 65
63 tree 66 tree
64 c_finish_omp_ordered (tree stmt) 67 c_finish_omp_ordered (location_t loc, tree stmt)
65 { 68 {
66 return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt)); 69 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
67 } 70 SET_EXPR_LOCATION (t, loc);
68 71 return add_stmt (t);
69 72 }
70 /* Complete a #pragma omp barrier construct. */ 73
74
75 /* Complete a #pragma omp barrier construct. LOC is the location of
76 the #pragma. */
71 77
72 void 78 void
73 c_finish_omp_barrier (void) 79 c_finish_omp_barrier (location_t loc)
74 { 80 {
75 tree x; 81 tree x;
76 82
77 x = built_in_decls[BUILT_IN_GOMP_BARRIER]; 83 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
78 x = build_call_expr (x, 0); 84 x = build_call_expr_loc (loc, x, 0);
79 add_stmt (x); 85 add_stmt (x);
80 } 86 }
81 87
82 88
83 /* Complete a #pragma omp taskwait construct. */ 89 /* Complete a #pragma omp taskwait construct. LOC is the location of the
90 pragma. */
84 91
85 void 92 void
86 c_finish_omp_taskwait (void) 93 c_finish_omp_taskwait (location_t loc)
87 { 94 {
88 tree x; 95 tree x;
89 96
90 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT]; 97 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
91 x = build_call_expr (x, 0); 98 x = build_call_expr_loc (loc, x, 0);
92 add_stmt (x); 99 add_stmt (x);
93 } 100 }
94 101
95 102
96 /* Complete a #pragma omp atomic construct. The expression to be 103 /* Complete a #pragma omp atomic construct. The expression to be
97 implemented atomically is LHS code= RHS. The value returned is 104 implemented atomically is LHS code= RHS. LOC is the location of
98 either error_mark_node (if the construct was erroneous) or an 105 the atomic statement. The value returned is either error_mark_node
99 OMP_ATOMIC node which should be added to the current statement tree 106 (if the construct was erroneous) or an OMP_ATOMIC node which should
100 with add_stmt. */ 107 be added to the current statement tree with add_stmt.*/
101 108
102 tree 109 tree
103 c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) 110 c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
104 { 111 {
105 tree x, type, addr; 112 tree x, type, addr;
106 113
107 if (lhs == error_mark_node || rhs == error_mark_node) 114 if (lhs == error_mark_node || rhs == error_mark_node)
108 return error_mark_node; 115 return error_mark_node;
114 type = TREE_TYPE (lhs); 121 type = TREE_TYPE (lhs);
115 if (!INTEGRAL_TYPE_P (type) 122 if (!INTEGRAL_TYPE_P (type)
116 && !POINTER_TYPE_P (type) 123 && !POINTER_TYPE_P (type)
117 && !SCALAR_FLOAT_TYPE_P (type)) 124 && !SCALAR_FLOAT_TYPE_P (type))
118 { 125 {
119 error ("invalid expression type for %<#pragma omp atomic%>"); 126 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
120 return error_mark_node; 127 return error_mark_node;
121 } 128 }
122 129
123 /* ??? Validate that rhs does not overlap lhs. */ 130 /* ??? Validate that rhs does not overlap lhs. */
124 131
125 /* Take and save the address of the lhs. From then on we'll reference it 132 /* Take and save the address of the lhs. From then on we'll reference it
126 via indirection. */ 133 via indirection. */
127 addr = build_unary_op (input_location, ADDR_EXPR, lhs, 0); 134 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
128 if (addr == error_mark_node) 135 if (addr == error_mark_node)
129 return error_mark_node; 136 return error_mark_node;
130 addr = save_expr (addr); 137 addr = save_expr (addr);
131 if (TREE_CODE (addr) != SAVE_EXPR 138 if (TREE_CODE (addr) != SAVE_EXPR
132 && (TREE_CODE (addr) != ADDR_EXPR 139 && (TREE_CODE (addr) != ADDR_EXPR
133 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL)) 140 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
134 { 141 {
135 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize 142 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
136 it even after unsharing function body. */ 143 it even after unsharing function body. */
137 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL); 144 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
145 DECL_CONTEXT (var) = current_function_decl;
138 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL); 146 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
139 } 147 }
140 lhs = build_indirect_ref (input_location, addr, NULL); 148 lhs = build_indirect_ref (loc, addr, RO_NULL);
141 149
142 /* There are lots of warnings, errors, and conversions that need to happen 150 /* There are lots of warnings, errors, and conversions that need to happen
143 in the course of interpreting a statement. Use the normal mechanisms 151 in the course of interpreting a statement. Use the normal mechanisms
144 to do this, and then take it apart again. */ 152 to do this, and then take it apart again. */
145 x = build_modify_expr (input_location, lhs, code, rhs); 153 x = build_modify_expr (input_location, lhs, NULL_TREE, code,
154 input_location, rhs, NULL_TREE);
146 if (x == error_mark_node) 155 if (x == error_mark_node)
147 return error_mark_node; 156 return error_mark_node;
148 gcc_assert (TREE_CODE (x) == MODIFY_EXPR); 157 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
149 rhs = TREE_OPERAND (x, 1); 158 rhs = TREE_OPERAND (x, 1);
150 159
151 /* Punt the actual generation of atomic operations to common code. */ 160 /* Punt the actual generation of atomic operations to common code. */
152 return build2 (OMP_ATOMIC, void_type_node, addr, rhs); 161 x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
153 } 162 SET_EXPR_LOCATION (x, loc);
154 163 return x;
155 164 }
156 /* Complete a #pragma omp flush construct. We don't do anything with the 165
157 variable list that the syntax allows. */ 166
167 /* Complete a #pragma omp flush construct. We don't do anything with
168 the variable list that the syntax allows. LOC is the location of
169 the #pragma. */
158 170
159 void 171 void
160 c_finish_omp_flush (void) 172 c_finish_omp_flush (location_t loc)
161 { 173 {
162 tree x; 174 tree x;
163 175
164 x = built_in_decls[BUILT_IN_SYNCHRONIZE]; 176 x = built_in_decls[BUILT_IN_SYNCHRONIZE];
165 x = build_call_expr (x, 0); 177 x = build_call_expr_loc (loc, x, 0);
166 add_stmt (x); 178 add_stmt (x);
167 } 179 }
168 180
169 181
170 /* Check and canonicalize #pragma omp for increment expression. 182 /* Check and canonicalize #pragma omp for increment expression.
171 Helper function for c_finish_omp_for. */ 183 Helper function for c_finish_omp_for. */
172 184
173 static tree 185 static tree
174 check_omp_for_incr_expr (tree exp, tree decl) 186 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
175 { 187 {
176 tree t; 188 tree t;
177 189
178 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp)) 190 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
179 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl))) 191 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
183 return build_int_cst (TREE_TYPE (exp), 0); 195 return build_int_cst (TREE_TYPE (exp), 0);
184 196
185 switch (TREE_CODE (exp)) 197 switch (TREE_CODE (exp))
186 { 198 {
187 CASE_CONVERT: 199 CASE_CONVERT:
188 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl); 200 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
189 if (t != error_mark_node) 201 if (t != error_mark_node)
190 return fold_convert (TREE_TYPE (exp), t); 202 return fold_convert_loc (loc, TREE_TYPE (exp), t);
191 break; 203 break;
192 case MINUS_EXPR: 204 case MINUS_EXPR:
193 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl); 205 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
194 if (t != error_mark_node) 206 if (t != error_mark_node)
195 return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); 207 return fold_build2_loc (loc, MINUS_EXPR,
208 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
196 break; 209 break;
197 case PLUS_EXPR: 210 case PLUS_EXPR:
198 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl); 211 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
199 if (t != error_mark_node) 212 if (t != error_mark_node)
200 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); 213 return fold_build2_loc (loc, PLUS_EXPR,
201 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl); 214 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
215 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
202 if (t != error_mark_node) 216 if (t != error_mark_node)
203 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t); 217 return fold_build2_loc (loc, PLUS_EXPR,
218 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
204 break; 219 break;
205 default: 220 default:
206 break; 221 break;
207 } 222 }
208 223
258 error_at (elocus, "%qE is not initialized", decl); 273 error_at (elocus, "%qE is not initialized", decl);
259 init = integer_zero_node; 274 init = integer_zero_node;
260 fail = true; 275 fail = true;
261 } 276 }
262 277
263 init = build_modify_expr (elocus, decl, NOP_EXPR, init); 278 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
279 /* FIXME diagnostics: This should
280 be the location of the INIT. */
281 elocus,
282 init,
283 NULL_TREE);
264 } 284 }
265 gcc_assert (TREE_CODE (init) == MODIFY_EXPR); 285 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
266 gcc_assert (TREE_OPERAND (init, 0) == decl); 286 gcc_assert (TREE_OPERAND (init, 0) == decl);
267 287
268 if (cond == NULL_TREE) 288 if (cond == NULL_TREE)
301 if (TREE_CODE (op0) == NOP_EXPR 321 if (TREE_CODE (op0) == NOP_EXPR
302 && decl == TREE_OPERAND (op0, 0)) 322 && decl == TREE_OPERAND (op0, 0))
303 { 323 {
304 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0); 324 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
305 TREE_OPERAND (cond, 1) 325 TREE_OPERAND (cond, 1)
306 = fold_build1 (NOP_EXPR, TREE_TYPE (decl), 326 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
307 TREE_OPERAND (cond, 1)); 327 TREE_OPERAND (cond, 1));
308 } 328 }
309 else if (TREE_CODE (op1) == NOP_EXPR 329 else if (TREE_CODE (op1) == NOP_EXPR
310 && decl == TREE_OPERAND (op1, 0)) 330 && decl == TREE_OPERAND (op1, 0))
311 { 331 {
312 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0); 332 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
313 TREE_OPERAND (cond, 0) 333 TREE_OPERAND (cond, 0)
314 = fold_build1 (NOP_EXPR, TREE_TYPE (decl), 334 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
315 TREE_OPERAND (cond, 0)); 335 TREE_OPERAND (cond, 0));
316 } 336 }
317 337
318 if (decl == TREE_OPERAND (cond, 0)) 338 if (decl == TREE_OPERAND (cond, 0))
319 cond_ok = true; 339 cond_ok = true;
375 395
376 incr_ok = true; 396 incr_ok = true;
377 if (POINTER_TYPE_P (TREE_TYPE (decl)) 397 if (POINTER_TYPE_P (TREE_TYPE (decl))
378 && TREE_OPERAND (incr, 1)) 398 && TREE_OPERAND (incr, 1))
379 { 399 {
380 tree t = fold_convert (sizetype, TREE_OPERAND (incr, 1)); 400 tree t = fold_convert_loc (elocus,
401 sizetype, TREE_OPERAND (incr, 1));
381 402
382 if (TREE_CODE (incr) == POSTDECREMENT_EXPR 403 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
383 || TREE_CODE (incr) == PREDECREMENT_EXPR) 404 || TREE_CODE (incr) == PREDECREMENT_EXPR)
384 t = fold_build1 (NEGATE_EXPR, sizetype, t); 405 t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
385 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (decl), decl, t); 406 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (decl), decl, t);
386 incr = build2 (MODIFY_EXPR, void_type_node, decl, t); 407 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
387 } 408 }
388 break; 409 break;
389 410
401 == POINTER_PLUS_EXPR)) 422 == POINTER_PLUS_EXPR))
402 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl) 423 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
403 incr_ok = true; 424 incr_ok = true;
404 else 425 else
405 { 426 {
406 tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), 427 tree t = check_omp_for_incr_expr (elocus,
428 TREE_OPERAND (incr, 1),
407 decl); 429 decl);
408 if (t != error_mark_node) 430 if (t != error_mark_node)
409 { 431 {
410 incr_ok = true; 432 incr_ok = true;
411 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t); 433 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
445 return add_stmt (t); 467 return add_stmt (t);
446 } 468 }
447 } 469 }
448 470
449 471
450 /* Divide CLAUSES into two lists: those that apply to a parallel construct, 472 /* Divide CLAUSES into two lists: those that apply to a parallel
451 and those that apply to a work-sharing construct. Place the results in 473 construct, and those that apply to a work-sharing construct. Place
452 *PAR_CLAUSES and *WS_CLAUSES respectively. In addition, add a nowait 474 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
453 clause to the work-sharing list. */ 475 addition, add a nowait clause to the work-sharing list. LOC is the
476 location of the OMP_PARALLEL*. */
454 477
455 void 478 void
456 c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses) 479 c_split_parallel_clauses (location_t loc, tree clauses,
480 tree *par_clauses, tree *ws_clauses)
457 { 481 {
458 tree next; 482 tree next;
459 483
460 *par_clauses = NULL; 484 *par_clauses = NULL;
461 *ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT); 485 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
462 486
463 for (; clauses ; clauses = next) 487 for (; clauses ; clauses = next)
464 { 488 {
465 next = OMP_CLAUSE_CHAIN (clauses); 489 next = OMP_CLAUSE_CHAIN (clauses);
466 490