00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include "system.h"
00027 #include "coretypes.h"
00028 #include "tm.h"
00029 #include "tree.h"
00030 #include "function.h"
00031 #include "c-common.h"
00032 #include "toplev.h"
00033 #include "tree-gimple.h"
00034 #include "bitmap.h"
00035 #include "langhooks.h"
00036
00037
00038
00039
00040
00041 tree
00042 c_finish_omp_master (tree stmt)
00043 {
00044 return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
00045 }
00046
00047
00048
00049
00050
00051 tree
00052 c_finish_omp_critical (tree body, tree name)
00053 {
00054 tree stmt = make_node (OMP_CRITICAL);
00055 TREE_TYPE (stmt) = void_type_node;
00056 OMP_CRITICAL_BODY (stmt) = body;
00057 OMP_CRITICAL_NAME (stmt) = name;
00058 return add_stmt (stmt);
00059 }
00060
00061
00062
00063
00064 tree
00065 c_finish_omp_ordered (tree stmt)
00066 {
00067 return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
00068 }
00069
00070
00071
00072
00073 void
00074 c_finish_omp_barrier (void)
00075 {
00076 tree x;
00077
00078 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
00079 x = build_function_call_expr (x, NULL);
00080 add_stmt (x);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 tree
00091 c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
00092 {
00093 tree x, type, addr;
00094
00095 if (lhs == error_mark_node || rhs == error_mark_node)
00096 return error_mark_node;
00097
00098
00099
00100
00101
00102 type = TREE_TYPE (lhs);
00103 if (!INTEGRAL_TYPE_P (type)
00104 && !POINTER_TYPE_P (type)
00105 && !SCALAR_FLOAT_TYPE_P (type))
00106 {
00107 error ("invalid expression type for %<#pragma omp atomic%>");
00108 return error_mark_node;
00109 }
00110
00111
00112
00113
00114
00115 addr = build_unary_op (ADDR_EXPR, lhs, 0);
00116 if (addr == error_mark_node)
00117 return error_mark_node;
00118 addr = save_expr (addr);
00119 if (TREE_CODE (addr) != SAVE_EXPR
00120 && (TREE_CODE (addr) != ADDR_EXPR
00121 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
00122 {
00123
00124
00125 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
00126 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
00127 }
00128 lhs = build_indirect_ref (addr, NULL);
00129
00130
00131
00132
00133 x = build_modify_expr (lhs, code, rhs);
00134 if (x == error_mark_node)
00135 return error_mark_node;
00136 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
00137 rhs = TREE_OPERAND (x, 1);
00138
00139
00140 return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
00141 }
00142
00143
00144
00145
00146
00147 void
00148 c_finish_omp_flush (void)
00149 {
00150 tree x;
00151
00152 x = built_in_decls[BUILT_IN_SYNCHRONIZE];
00153 x = build_function_call_expr (x, NULL);
00154 add_stmt (x);
00155 }
00156
00157
00158
00159
00160
00161 static tree
00162 check_omp_for_incr_expr (tree exp, tree decl)
00163 {
00164 tree t;
00165
00166 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
00167 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
00168 return error_mark_node;
00169
00170 if (exp == decl)
00171 return build_int_cst (TREE_TYPE (exp), 0);
00172
00173 switch (TREE_CODE (exp))
00174 {
00175 case NOP_EXPR:
00176 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
00177 if (t != error_mark_node)
00178 return fold_convert (TREE_TYPE (exp), t);
00179 break;
00180 case MINUS_EXPR:
00181 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
00182 if (t != error_mark_node)
00183 return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
00184 break;
00185 case PLUS_EXPR:
00186 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
00187 if (t != error_mark_node)
00188 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
00189 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
00190 if (t != error_mark_node)
00191 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
00192 break;
00193 default:
00194 break;
00195 }
00196
00197 return error_mark_node;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 tree
00207 c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
00208 tree incr, tree body, tree pre_body)
00209 {
00210 location_t elocus = locus;
00211 bool fail = false;
00212
00213 if (EXPR_HAS_LOCATION (init))
00214 elocus = EXPR_LOCATION (init);
00215
00216
00217 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
00218 {
00219 error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
00220 fail = true;
00221 }
00222 if (TYPE_UNSIGNED (TREE_TYPE (decl)))
00223 warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
00224
00225
00226
00227 if (init == decl)
00228 {
00229 elocus = DECL_SOURCE_LOCATION (decl);
00230
00231 init = DECL_INITIAL (decl);
00232 if (init == NULL)
00233 {
00234 error ("%H%qE is not initialized", &elocus, decl);
00235 init = integer_zero_node;
00236 fail = true;
00237 }
00238
00239 init = build_modify_expr (decl, NOP_EXPR, init);
00240 SET_EXPR_LOCATION (init, elocus);
00241 }
00242 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
00243 gcc_assert (TREE_OPERAND (init, 0) == decl);
00244
00245 if (cond == NULL_TREE)
00246 {
00247 error ("%Hmissing controlling predicate", &elocus);
00248 fail = true;
00249 }
00250 else
00251 {
00252 bool cond_ok = false;
00253
00254 if (EXPR_HAS_LOCATION (cond))
00255 elocus = EXPR_LOCATION (cond);
00256
00257 if (TREE_CODE (cond) == LT_EXPR
00258 || TREE_CODE (cond) == LE_EXPR
00259 || TREE_CODE (cond) == GT_EXPR
00260 || TREE_CODE (cond) == GE_EXPR)
00261 {
00262 tree op0 = TREE_OPERAND (cond, 0);
00263 tree op1 = TREE_OPERAND (cond, 1);
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 if (TREE_CODE (op0) == NOP_EXPR
00278 && decl == TREE_OPERAND (op0, 0))
00279 {
00280 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
00281 TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
00282 TREE_OPERAND (cond, 1));
00283 }
00284 else if (TREE_CODE (op1) == NOP_EXPR
00285 && decl == TREE_OPERAND (op1, 0))
00286 {
00287 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
00288 TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
00289 TREE_OPERAND (cond, 0));
00290 }
00291
00292 if (decl == TREE_OPERAND (cond, 0))
00293 cond_ok = true;
00294 else if (decl == TREE_OPERAND (cond, 1))
00295 {
00296 TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
00297 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
00298 TREE_OPERAND (cond, 0) = decl;
00299 cond_ok = true;
00300 }
00301 }
00302
00303 if (!cond_ok)
00304 {
00305 error ("%Hinvalid controlling predicate", &elocus);
00306 fail = true;
00307 }
00308 }
00309
00310 if (incr == NULL_TREE)
00311 {
00312 error ("%Hmissing increment expression", &elocus);
00313 fail = true;
00314 }
00315 else
00316 {
00317 bool incr_ok = false;
00318
00319 if (EXPR_HAS_LOCATION (incr))
00320 elocus = EXPR_LOCATION (incr);
00321
00322
00323
00324 switch (TREE_CODE (incr))
00325 {
00326 case POSTINCREMENT_EXPR:
00327 case PREINCREMENT_EXPR:
00328 case POSTDECREMENT_EXPR:
00329 case PREDECREMENT_EXPR:
00330 incr_ok = (TREE_OPERAND (incr, 0) == decl);
00331 break;
00332
00333 case MODIFY_EXPR:
00334 if (TREE_OPERAND (incr, 0) != decl)
00335 break;
00336 if (TREE_OPERAND (incr, 1) == decl)
00337 break;
00338 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
00339 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
00340 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
00341 incr_ok = true;
00342 else if (TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
00343 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
00344 incr_ok = true;
00345 else
00346 {
00347 tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), decl);
00348 if (t != error_mark_node)
00349 {
00350 incr_ok = true;
00351 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
00352 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
00353 }
00354 }
00355 break;
00356
00357 default:
00358 break;
00359 }
00360 if (!incr_ok)
00361 {
00362 error ("%Hinvalid increment expression", &elocus);
00363 fail = true;
00364 }
00365 }
00366
00367 if (fail)
00368 return NULL;
00369 else
00370 {
00371 tree t = make_node (OMP_FOR);
00372
00373 TREE_TYPE (t) = void_type_node;
00374 OMP_FOR_INIT (t) = init;
00375 OMP_FOR_COND (t) = cond;
00376 OMP_FOR_INCR (t) = incr;
00377 OMP_FOR_BODY (t) = body;
00378 OMP_FOR_PRE_BODY (t) = pre_body;
00379
00380 SET_EXPR_LOCATION (t, locus);
00381 return add_stmt (t);
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 void
00392 c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
00393 {
00394 tree next;
00395
00396 *par_clauses = NULL;
00397 *ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT);
00398
00399 for (; clauses ; clauses = next)
00400 {
00401 next = OMP_CLAUSE_CHAIN (clauses);
00402
00403 switch (OMP_CLAUSE_CODE (clauses))
00404 {
00405 case OMP_CLAUSE_LASTPRIVATE:
00406 #ifdef KEY
00407
00408
00409
00410
00411
00412
00413
00414
00415 if (flag_spin_file && lang_cplus())
00416 {
00417 tree add_clause;
00418 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
00419 *ws_clauses = clauses;
00420
00421 add_clause = build_omp_clause (OMP_CLAUSE_SHARED);
00422 OMP_CLAUSE_DECL (add_clause) = OMP_CLAUSE_DECL (clauses);
00423 OMP_CLAUSE_CHAIN (add_clause) = *par_clauses;
00424 *par_clauses = add_clause;
00425 break;
00426 }
00427 #endif
00428 case OMP_CLAUSE_PRIVATE:
00429 case OMP_CLAUSE_SHARED:
00430 case OMP_CLAUSE_FIRSTPRIVATE:
00431 case OMP_CLAUSE_REDUCTION:
00432 case OMP_CLAUSE_COPYIN:
00433 case OMP_CLAUSE_IF:
00434 case OMP_CLAUSE_NUM_THREADS:
00435 case OMP_CLAUSE_DEFAULT:
00436 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
00437 *par_clauses = clauses;
00438 break;
00439
00440 case OMP_CLAUSE_SCHEDULE:
00441 case OMP_CLAUSE_ORDERED:
00442 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
00443 *ws_clauses = clauses;
00444 break;
00445
00446 default:
00447 gcc_unreachable ();
00448 }
00449 }
00450 }
00451
00452
00453
00454 enum omp_clause_default_kind
00455 c_omp_predetermined_sharing (tree decl)
00456 {
00457
00458
00459 if (TREE_READONLY (decl))
00460 return OMP_CLAUSE_DEFAULT_SHARED;
00461
00462 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
00463 }