Mercurial > hg > CbC > CbC_gcc
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 |