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
00026
00027
00028
00029
00030 #include "defs.h"
00031 #include "glob.h"
00032 #include "config.h"
00033 #include "wn.h"
00034 #include "wn_util.h"
00035
00036 extern "C"{
00037 #include "gspin-wgen-interface.h"
00038 }
00039 #include "wgen_misc.h"
00040 #include "wgen_dst.h"
00041 #include "wgen_expr.h"
00042 #include "wgen_stmt.h"
00043 #include "wgen_spin_symbol.h"
00044 #include "omp_types.h"
00045 #include "omp_directive.h"
00046 #include "wgen_omp_directives.h"
00047 #include "wgen_omp_check_stack.h"
00048
00049 #include "stdio.h"
00050 #include "errors.h"
00051 #include "const.h"
00052 #include "erglob.h"
00053
00054 #include <stack>
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 std::stack<WN *> dtor_call_stack;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 std::stack<WN *> local_node_stack;
00079
00080
00081 std::stack<WN *> lastlocal_node_stack;
00082
00083
00084 std::vector<WN *> doloop_side_effects;
00085
00086 BOOL Trace_Omp = FALSE;
00087
00088
00089 void WGEN_Omp_Init (void)
00090 {
00091 WGEN_CS_Init ();
00092 if (getenv ("CFE_OMP_DEBUG") && !strcmp (getenv ("CFE_OMP_DEBUG"), "1"))
00093 Trace_Omp = TRUE;
00094 }
00095
00096
00097 WN * WGEN_region(REGION_KIND kind)
00098 {
00099 WN *body,*pragmas,*exits,*region;
00100
00101 body = WN_CreateBlock ();
00102 pragmas = WN_CreateBlock ();
00103 exits = WN_CreateBlock ();
00104 region = WN_CreateRegion (kind,
00105 body,
00106 pragmas,
00107 exits,
00108 -1,
00109 0);
00110 WGEN_Stmt_Append (region, Get_Srcpos());
00111 WGEN_Stmt_Push (body, wgen_stmk_scope, Get_Srcpos());
00112 WGEN_Stmt_Push (pragmas, wgen_stmk_region_pragmas, Get_Srcpos());
00113
00114 return region;
00115 }
00116
00119
00120 void WGEN_omp_error(CHECK_STMT* cs, bool chkflag, char * msg)
00121 {
00122 char dirname[100];
00123 if(chkflag==false)
00124 return;
00125 switch(cs->kind)
00126 {
00127 case wgen_omp_parallel: sprintf(dirname,"#PRAGMA OMP PARALLEL");
00128 break;
00129 case wgen_omp_for: sprintf(dirname,"#PRAGMA OMP FOR");
00130 break;
00131 case wgen_omp_single: sprintf(dirname,"#PRAGMA OMP SINGLE");
00132 break;
00133 case wgen_omp_sections: sprintf(dirname,"#PRAGMA OMP SECTIONS");
00134 break;
00135 case wgen_omp_parallel_sections: sprintf(dirname,"#1PRAGMA OMP PARRALLEL SECTIONS");
00136 break;
00137 case wgen_omp_parallel_for: sprintf(dirname,"#PRAGMA OMP PARRALLEL FOR");
00138 break;
00139 default: sprintf(dirname,"OTHER DIRECTIVES ");
00140 }
00141
00142 if (msg)
00143 ErrMsg (EC_Bad_Omp, msg);
00144 }
00145
00146 void WGEN_check_private(WN *wn_p, bool chkflag)
00147 {
00148 if(ST_is_const_var(* WN_st(wn_p)))
00149 { fprintf(stderr ,"A variable specified in a private\
00150 clause must not have a const-qualified type \
00151 unless it has a class type with a mutable member.\n");
00152 chkflag=true;
00153 }
00154 if(WN_st(wn_p)->storage_class==SCLASS_FORMAL_REF)
00155 {
00156 fprintf(stderr,"A variable specified in a private\
00157 clause must not have an incomplete type \
00158 or a reference type. \n");
00159 chkflag=true;
00160 }
00161
00162 }
00163 void WGEN_check_firstprivate(WN *wn_fp, bool chkflag)
00164 {
00165 if(WN_st(wn_fp)->storage_class==SCLASS_FORMAL_REF)
00166 {
00167 fprintf(stderr,"A variable specified in a first private\
00168 clause must not have an incomplete type \
00169 or a reference type. \n");
00170 chkflag=true;
00171 }
00172 }
00173 void WGEN_check_lastprivate(WN *wn_lp, bool chkflag)
00174 {
00175 if(ST_is_const_var(* WN_st(wn_lp)))
00176 {
00177 fprintf(stderr," A variable specified in a lastprivate clause must\
00178 not have a const-qualified type \
00179 unless it has a class type with a mutable member.\n");
00180 chkflag=true;
00181 }
00182 if(WN_st(wn_lp)->storage_class==SCLASS_FORMAL_REF)
00183 {
00184 fprintf(stderr,"A variable specified in a lastprivate clause must\
00185 not have an incomplete type \
00186 or a reference type. \n");
00187 chkflag=true;
00188 }
00189
00190 }
00191 void WGEN_check_reduction(WN* wn_r, bool chkflag)
00192 {
00193 if(ST_is_const_var(* WN_st(wn_r)))
00194 {
00195 fprintf(stderr," A variable that is specified in the reduction\
00196 clause must not be const-qualified\n");
00197 chkflag=true;
00198 }
00199 }
00200 #if 0
00201 void WGEN_check_default(WN* wn_d, bool chkflag)
00202 {
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 }
00217
00220 void WGEN_check_parallel ( WN *parallel_wn)
00221 {
00222
00223
00224
00225
00226 bool chkflag=false;
00227 char * msg = NULL;
00228
00229 CHECK_STMT* cs1;
00230 WN* wn1,*wn2;
00231
00232 cs1=WGEN_CS_top();
00233 wn1=cs1->wn_prag;
00234 wn2=WN_first(wn1);
00235
00236 while(wn2!=NULL)
00237 {
00238 if(WN_st(wn2)==NULL)
00239 {
00240 wn2=WN_next(wn2);
00241 continue;
00242 }
00243
00244 if(ST_is_thread_private(* WN_st(wn2)) )
00245 {
00246 if(WN_pragma(wn2)!=WN_PRAGMA_COPYIN&&WN_pragma(wn2)!=WN_PRAGMA_COPYPRIVATE
00247 &&WN_pragma(wn2)!=WN_PRAGMA_MPSCHEDTYPE&&WN_pragma(wn2)!=WN_PRAGMA_IF
00248 &&WN_pragma(wn2)!=WN_PRAGMA_NUMTHREADS)
00249 {
00250 msg = "A threadprivate variable must not appear\
00251 in any clause except the copyin,\
00252 copyprivate, schedule, num_threads,or the if clause.";
00253
00254 chkflag=true;
00255
00256 }
00257 }
00258
00259 if(WN_pragma(wn2)==WN_PRAGMA_LOCAL)
00260 WGEN_check_private(wn2,chkflag);
00261
00262 if(WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
00263 WGEN_check_firstprivate(wn2,chkflag);
00264
00265 if(WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
00266 WGEN_check_reduction(wn2,chkflag);
00267
00268 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
00269 WGEN_check_default(wn2,chkflag);
00270
00271 if(WN_pragma(wn2)==WN_PRAGMA_COPYIN)
00272 {
00273 if (!ST_is_thread_private(* WN_st(wn2)))
00274 {
00275 msg = "A variable that is specified\
00276 in the copyin clause must be a threadprivate variable.";
00277 chkflag=true;
00278 }
00279 }
00280 wn2=WN_next(wn2);
00281 }
00282 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
00283 };
00284 #endif
00285
00286
00287
00288
00289 static BOOL WGEN_is_default_constructor (gs_t fndecl)
00290 {
00291 Is_True (gs_tree_code (fndecl) == GS_FUNCTION_DECL, ("Invalid function decl"));
00292 if (!gs_decl_constructor_p (fndecl)) return FALSE;
00293 if (gs_decl_copy_constructor_p (fndecl)) return FALSE;
00294
00295 gs_t args = gs_function_first_user_parmtype (fndecl);
00296
00297
00298 for (; args; args = gs_tree_chain (args))
00299 if (args != gs_void_list_node() && !gs_tree_purpose (args)) return FALSE;
00300 return TRUE;
00301 }
00302
00303
00304
00305
00306
00307 static BOOL WGEN_maybe_call_default_ctor (gs_t var, WN ** c, WN ** d)
00308 {
00309 gs_t type = gs_tree_type (var);
00310 if (gs_tree_code (type) != GS_RECORD_TYPE || !gs_classtype_non_pod_p (type))
00311 return FALSE;
00312
00313 ST * obj = Get_ST (var);
00314 FmtAssert (gs_type_has_default_constructor (type),
00315 ("private clause on non-pod object %s needs default constructor",
00316 ST_name (obj)));
00317 gs_t found_ctor = NULL;
00318 gs_t found_dtor = NULL;
00319 for (gs_t methods = gs_type_methods (type);
00320 methods;
00321 methods = gs_tree_chain (methods))
00322 {
00323 if (gs_decl_complete_constructor_p (methods) &&
00324 WGEN_is_default_constructor (methods))
00325 {
00326 FmtAssert (!found_ctor,
00327 ("Multiple default constructor candidates for %s",
00328 ST_name (obj)));
00329 found_ctor = methods;
00330 }
00331 if (gs_decl_complete_destructor_p (methods))
00332 {
00333 FmtAssert (!found_dtor, ("Multiple destructor candidates for %s",
00334 ST_name (obj)));
00335 found_dtor = methods;
00336 }
00337 }
00338
00339 FmtAssert (found_ctor && found_dtor,
00340 ("No default ctor/dtor found for non-pod object %s",
00341 ST_name (obj)));
00342
00343 ST * ctor_st = Get_ST (found_ctor);
00344 WN * call_ctor = WN_Call (MTYPE_V, MTYPE_V, 1, ST_st_idx (ctor_st));
00345 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00346 WN_actual (call_ctor, 0) = WN_CreateParm (WN_rtype (lda_obj),
00347 lda_obj,
00348 WN_ty (lda_obj),
00349 WN_PARM_BY_VALUE);
00350 WN_Set_Call_Default_Flags (call_ctor);
00351 *c = call_ctor;
00352
00353
00354 ST * dtor_st = Get_ST (found_dtor);
00355 WN * call_dtor = WN_Call (MTYPE_V, MTYPE_V, 1, ST_st_idx (dtor_st));
00356 WN_actual (call_dtor, 0) = WN_COPY_Tree (WN_kid0 (call_ctor));
00357 WN_Set_Call_Default_Flags (call_dtor);
00358 *d = call_dtor;
00359
00360 return TRUE;
00361 }
00362
00363
00364
00365 static BOOL WGEN_maybe_call_copy_ctor (gs_t var, WN ** c, WN ** d)
00366 {
00367 gs_t type = gs_tree_type (var);
00368 if (gs_tree_code (type) != GS_RECORD_TYPE || !gs_classtype_non_pod_p (type))
00369 return FALSE;
00370
00371 ST * obj = Get_ST (var);
00372 gs_t found_ctor = NULL;
00373 gs_t found_dtor = NULL;
00374 BOOL no_implicit_copy_ctor = !gs_type_has_implicit_copy_constructor(type);
00375 for (gs_t methods = gs_type_methods (type);
00376 methods;
00377 methods = gs_tree_chain (methods))
00378 {
00379 if (no_implicit_copy_ctor &&
00380 gs_decl_complete_constructor_p (methods) &&
00381 gs_decl_copy_constructor_p (methods))
00382 {
00383 FmtAssert (!found_ctor,
00384 ("Multiple copy constructor candidates for %s",
00385 ST_name (obj)));
00386 found_ctor = methods;
00387 }
00388 if (gs_decl_complete_destructor_p (methods))
00389 {
00390 FmtAssert (!found_dtor, ("Multiple destructor candidates for %s",
00391 ST_name (obj)));
00392 found_dtor = methods;
00393 }
00394 }
00395 if (!found_ctor || !found_dtor)
00396 DevWarn ("No copy-ctor/dtor found for non-pod object %s", ST_name (obj));
00397
00398
00399
00400 if (found_ctor)
00401 {
00402 ST * ctor_st = Get_ST (found_ctor);
00403 WN * call_ctor = WN_Call (MTYPE_V, MTYPE_V, 2, ST_st_idx (ctor_st));
00404 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00405 WN_actual (call_ctor, 0) = WN_CreateParm (WN_rtype (lda_obj),
00406 lda_obj,
00407 WN_ty (lda_obj),
00408 WN_PARM_BY_VALUE);
00409 WN_actual (call_ctor, 1) = NULL;
00410 WN_Set_Call_Default_Flags (call_ctor);
00411 *c = call_ctor;
00412 }
00413
00414 if (found_dtor)
00415 {
00416 ST * dtor_st = Get_ST (found_dtor);
00417 WN * call_dtor = WN_Call (MTYPE_V, MTYPE_V, 1, ST_st_idx (dtor_st));
00418 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00419 WN_actual (call_dtor, 0) = WN_CreateParm (WN_rtype (lda_obj),
00420 lda_obj,
00421 WN_ty (lda_obj),
00422 WN_PARM_BY_VALUE);
00423 WN_Set_Call_Default_Flags (call_dtor);
00424 *d = call_dtor;
00425 }
00426
00427 return TRUE;
00428 }
00429
00430 static BOOL WGEN_maybe_call_assignment_opr (gs_t var, WN ** c, WN ** d, WN ** a)
00431 {
00432 gs_t type = gs_tree_type (var);
00433 if (gs_tree_code (type) != GS_RECORD_TYPE || !gs_classtype_non_pod_p (type))
00434 return FALSE;
00435
00436 ST * obj = Get_ST (var);
00437 gs_t found_ctor = NULL;
00438 gs_t found_dtor = NULL;
00439 gs_t found_asn_opr = NULL;
00440
00441 for (gs_t methods = gs_type_methods (type);
00442 methods;
00443 methods = gs_tree_chain (methods))
00444 {
00445 if (gs_decl_complete_constructor_p (methods) &&
00446 WGEN_is_default_constructor (methods))
00447 {
00448 FmtAssert (!found_ctor,
00449 ("Multiple copy constructor candidates for %s",
00450 ST_name (obj)));
00451 found_ctor = methods;
00452 }
00453 if (gs_decl_assignment_operator_p (methods))
00454 {
00455 FmtAssert (!found_asn_opr, ("Multiple assignment operators for %s",
00456 ST_name (obj)));
00457 found_asn_opr = methods;
00458 }
00459 if (gs_decl_complete_destructor_p (methods))
00460 {
00461 FmtAssert (!found_dtor, ("Multiple destructor candidates for %s",
00462 ST_name (obj)));
00463 found_dtor = methods;
00464 }
00465 }
00466 if (!found_ctor || !found_dtor || !found_asn_opr)
00467 DevWarn ("No copy-ctor/dtor found for non-pod object %s", ST_name (obj));
00468
00469
00470 if (found_ctor)
00471 {
00472 ST * ctor_st = Get_ST (found_ctor);
00473 WN * call_ctor = WN_Call (MTYPE_V, MTYPE_V, 1, ST_st_idx (ctor_st));
00474 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00475 WN_actual (call_ctor, 0) = WN_CreateParm (WN_rtype (lda_obj),
00476 lda_obj,
00477 WN_ty (lda_obj),
00478 WN_PARM_BY_VALUE);
00479 WN_Set_Call_Default_Flags (call_ctor);
00480 *c = call_ctor;
00481 }
00482
00483
00484
00485 if (found_asn_opr)
00486 {
00487 ST * asn_opr_st = Get_ST (found_asn_opr);
00488 WN * asn_opr_call = WN_Call (MTYPE_V, MTYPE_V, 2, ST_st_idx (asn_opr_st));
00489 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00490 WN_actual (asn_opr_call, 0) = NULL;
00491 WN_actual (asn_opr_call, 1) = WN_CreateParm (WN_rtype (lda_obj),
00492 lda_obj,
00493 WN_ty (lda_obj),
00494 WN_PARM_BY_VALUE);
00495 WN_Set_Call_Default_Flags (asn_opr_call);
00496 *a = asn_opr_call;
00497 }
00498
00499 if (found_dtor)
00500 {
00501 ST * dtor_st = Get_ST (found_dtor);
00502 WN * call_dtor = WN_Call (MTYPE_V, MTYPE_V, 1, ST_st_idx (dtor_st));
00503 WN * lda_obj = WN_Lda (Pointer_Mtype, 0, obj, 0);
00504 WN_actual (call_dtor, 0) = WN_CreateParm (WN_rtype (lda_obj),
00505 lda_obj,
00506 WN_ty (lda_obj),
00507 WN_PARM_BY_VALUE);
00508 WN_Set_Call_Default_Flags (call_dtor);
00509 *d = call_dtor;
00510 }
00511
00512 return TRUE;
00513 }
00514
00515
00516
00517 static void WGEN_maybe_call_dtors (WN * wn)
00518 {
00519 Is_True (WN_operator (wn) == OPR_BLOCK, ("BLOCK node expected"));
00520 Is_True (dtor_call_stack.empty() ||
00521 WN_operator (dtor_call_stack.top()) == OPR_REGION,
00522 ("REGION node expected"));
00523
00524 if (dtor_call_stack.empty() || WN_region_body (dtor_call_stack.top()) != wn)
00525 return;
00526
00527 dtor_call_stack.pop();
00528 while (!dtor_call_stack.empty() &&
00529 WN_operator (dtor_call_stack.top()) == OPR_CALL)
00530 {
00531 WN_INSERT_BlockLast (wn, dtor_call_stack.top());
00532 dtor_call_stack.pop ();
00533 }
00534 Is_True (dtor_call_stack.empty() ||
00535 WN_operator (dtor_call_stack.top()) == OPR_REGION,
00536 ("REGION node expected"));
00537 }
00538
00539
00540 static void WGEN_localize_var (WN * block, ST * old_st, ST * new_st)
00541 {
00542 if (WN_has_sym (block) && WN_st (block) == old_st)
00543 WN_st_idx (block) = ST_st_idx (new_st);
00544
00545 OPERATOR opr = WN_operator (block);
00546
00547 if (opr == OPR_BLOCK)
00548 {
00549 WN * node = WN_first (block);
00550 while (node)
00551 {
00552 WGEN_localize_var (node, old_st, new_st);
00553 node = WN_next (node);
00554 }
00555 }
00556 else
00557 {
00558
00559
00560
00561
00562
00563
00564
00565
00566 if (WN_operator (block) == OPR_CALL && WN_kid_count (block) == 2 &&
00567 (WN_kid0 (block) == NULL || WN_kid1 (block) == NULL))
00568 {
00569 if (WN_kid0 (block))
00570 {
00571 WN * lda = WN_kid0 (WN_kid0 (block));
00572 if (WN_operator(lda) == OPR_LDA
00573 && WN_st(lda) == old_st)
00574 {
00575 WN_kid1 (block) = WN_COPY_Tree (WN_kid0 (block));
00576 WGEN_localize_var (WN_kid0 (block), old_st, new_st);
00577 }
00578 }
00579 else
00580 {
00581 WN * lda = WN_kid0 (WN_kid1 (block));
00582 if (WN_operator(lda) == OPR_LDA
00583 && WN_st(lda) == old_st)
00584 {
00585 WN_kid0 (block) = WN_COPY_Tree (WN_kid1 (block));
00586 WGEN_localize_var (WN_kid1 (block), old_st, new_st);
00587 }
00588 }
00589 }
00590 else
00591 {
00592 for (int i=0; i<WN_kid_count (block); i++)
00593 WGEN_localize_var (WN_kid (block, i), old_st, new_st);
00594 }
00595 }
00596 }
00597
00598
00599 static void WGEN_maybe_localize_vars (WN * wn)
00600 {
00601 Is_True (WN_operator (wn) == OPR_BLOCK, ("BLOCK node expected"));
00602 Is_True (local_node_stack.empty() ||
00603 WN_operator (local_node_stack.top()) == OPR_REGION,
00604 ("REGION node expected"));
00605
00606 if (local_node_stack.empty() || WN_region_body (local_node_stack.top()) != wn)
00607 return;
00608
00609 wn = local_node_stack.top();
00610 local_node_stack.pop();
00611 while (!local_node_stack.empty() &&
00612 WN_operator (local_node_stack.top()) == OPR_PRAGMA)
00613 {
00614 WN * pragma = local_node_stack.top();
00615 ST * st = WN_st (pragma);
00616
00617 FmtAssert (ST_class (st) != CLASS_PREG, ("NYI"));
00618 TY_IDX ty = ST_type (st);
00619 char * localname = (char *) alloca (strlen (ST_name (st)) +
00620 strlen ("__mplocalfe_") + 1);
00621
00622 sprintf (localname, "__mplocalfe_%s", ST_name (st));
00623 ST * new_st = New_ST (CURRENT_SYMTAB);
00624 ST_Init (new_st, Save_Str (localname), CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, ty);
00625 if (ST_addr_saved(st))
00626 Set_ST_addr_saved(new_st);
00627 if (ST_addr_passed(st))
00628 Set_ST_addr_passed(new_st);
00629
00630 WGEN_localize_var (wn, st, new_st);
00631 local_node_stack.pop();
00632 }
00633 Is_True (local_node_stack.empty() ||
00634 WN_operator (local_node_stack.top()) == OPR_REGION,
00635 ("REGION node expected"));
00636 }
00637
00638
00639
00640
00641
00642 static BOOL WGEN_handle_non_pods (gs_t var, WN * block, gs_omp_clause_code_t p)
00643 {
00644 WN * c = NULL, * d = NULL, * a = NULL;
00645
00646 BOOL constructed = FALSE;
00647 switch (p)
00648 {
00649 case GS_OMP_CLAUSE_PRIVATE:
00650 constructed = WGEN_maybe_call_default_ctor (var, &c, &d);
00651 break;
00652 case GS_OMP_CLAUSE_FIRSTPRIVATE:
00653 constructed = WGEN_maybe_call_copy_ctor (var, &c, &d);
00654 break;
00655 case GS_OMP_CLAUSE_LASTPRIVATE:
00656 constructed = WGEN_maybe_call_assignment_opr (var, &c, &d, &a);
00657 break;
00658 default:
00659 break;
00660 }
00661
00662 if (constructed)
00663 {
00664 ST * st = Get_ST (var);
00665
00666 Set_TY_is_non_pod (ST_type (st));
00667
00668
00669
00670
00671
00672
00673
00674 if (c)
00675 WN_INSERT_BlockFirst (block, c);
00676
00677
00678 if (d)
00679 dtor_call_stack.push (d);
00680 if (a)
00681 lastlocal_node_stack.push (a);
00682 return TRUE;
00683 }
00684 return FALSE;
00685 }
00686
00687 static OPERATOR get_reduction_code (gs_t clause)
00688 {
00689 OPERATOR opr = OPERATOR_UNKNOWN;
00690 Is_True (gs_omp_clause_code(clause) == GS_OMP_CLAUSE_REDUCTION,
00691 ("get_reduction_code: invalid clause type"));
00692
00693 switch (gs_omp_clause_reduction_code(clause))
00694 {
00695 case GS_BIT_AND_EXPR:
00696 opr = OPR_BAND;
00697 break;
00698 case GS_BIT_IOR_EXPR:
00699 opr = OPR_BIOR;
00700 break;
00701 case GS_BIT_XOR_EXPR:
00702 opr = OPR_BXOR;
00703 break;
00704 case GS_PLUS_EXPR:
00705 opr = OPR_ADD;
00706 break;
00707 case GS_MULT_EXPR:
00708 opr = OPR_MPY;
00709 break;
00710 case GS_MINUS_EXPR:
00711 opr = OPR_SUB;
00712 break;
00713 case GS_TRUTH_AND_EXPR:
00714 case GS_TRUTH_ANDIF_EXPR:
00715 opr = OPR_CAND;
00716 break;
00717 case GS_TRUTH_OR_EXPR:
00718 case GS_TRUTH_ORIF_EXPR:
00719 opr = OPR_CIOR;
00720 break;
00721 }
00722
00723 return opr;
00724 }
00725
00726
00727
00728 static void WGEN_process_omp_clause (gs_t clauses, WN * region = 0)
00729 {
00730 ST * st = NULL;
00731 WN * wn = NULL;
00732 BOOL non_pod = FALSE;
00733 switch (gs_omp_clause_code(clauses))
00734 {
00735 case GS_OMP_CLAUSE_PRIVATE:
00736 {
00737 gs_t var = gs_omp_clause_decl(clauses);
00738 WGEN_Set_Cflag(clause_private);
00739 st = Get_ST(var);
00740 wn = WN_CreatePragma(WN_PRAGMA_LOCAL, st, 0, 0);
00741 if (lang_cplus && region && (non_pod = WGEN_handle_non_pods (var,
00742 WN_region_body(region),
00743 GS_OMP_CLAUSE_PRIVATE)))
00744 local_node_stack.push (wn);
00745 }
00746 break;
00747
00748 case GS_OMP_CLAUSE_IF:
00749 wn = WN_CreateXpragma(WN_PRAGMA_IF, (ST_IDX) NULL, 1);
00750 WN_kid0(wn) = WGEN_Expand_Expr (gs_omp_clause_if_expr(clauses));
00751 break;
00752
00753 case GS_OMP_CLAUSE_FIRSTPRIVATE:
00754 {
00755 gs_t var = gs_omp_clause_decl(clauses);
00756 WGEN_Set_Cflag(clause_firstprivate);
00757 st = Get_ST(var);
00758 wn = WN_CreatePragma(WN_PRAGMA_FIRSTPRIVATE, st, 0, 0);
00759 if (lang_cplus && region && (non_pod = WGEN_handle_non_pods (var,
00760 WN_region_body(region),
00761 GS_OMP_CLAUSE_FIRSTPRIVATE)))
00762 local_node_stack.push (wn);
00763 }
00764 break;
00765
00766 case GS_OMP_CLAUSE_LASTPRIVATE:
00767 {
00768 gs_t var = gs_omp_clause_decl(clauses);
00769 WGEN_Set_Cflag(clause_lastprivate);
00770 st = Get_ST(var);
00771 wn = WN_CreatePragma(WN_PRAGMA_LASTLOCAL, st, 0, 0);
00772 if (lang_cplus && region && (non_pod = WGEN_handle_non_pods (var,
00773 WN_region_body(region),
00774 GS_OMP_CLAUSE_LASTPRIVATE)))
00775 local_node_stack.push (wn);
00776 }
00777 break;
00778
00779 case GS_OMP_CLAUSE_SHARED:
00780 WGEN_Set_Cflag(clause_shared);
00781 st = Get_ST(gs_omp_clause_decl(clauses));
00782 wn = WN_CreatePragma(WN_PRAGMA_SHARED, st, 0, 0);
00783 break;
00784
00785 case GS_OMP_CLAUSE_NUM_THREADS:
00786 wn = WN_CreateXpragma(WN_PRAGMA_NUMTHREADS, (ST_IDX) NULL, 1);
00787 WN_kid0(wn) = WGEN_Expand_Expr (gs_omp_clause_num_threads_expr(clauses));
00788 break;
00789
00790 case GS_OMP_CLAUSE_DEFAULT:
00791 {
00792 gs_omp_clause_default_kind_t default_value =
00793 gs_omp_clause_default_kind (clauses);
00794 WN_PRAGMA_DEFAULT_KIND kind = WN_PRAGMA_DEFAULT_UNKNOWN;
00795
00796 switch (default_value)
00797 {
00798 case GS_OMP_CLAUSE_DEFAULT_SHARED:
00799 kind = WN_PRAGMA_DEFAULT_SHARED; break;
00800 case GS_OMP_CLAUSE_DEFAULT_NONE:
00801 kind = WN_PRAGMA_DEFAULT_NONE; break;
00802 case GS_OMP_CLAUSE_DEFAULT_PRIVATE:
00803 kind = WN_PRAGMA_DEFAULT_PRIVATE; break;
00804 }
00805 wn = WN_CreatePragma(WN_PRAGMA_DEFAULT,
00806 (ST_IDX) NULL,
00807 kind,
00808 0);
00809 }
00810 break;
00811
00812 case GS_OMP_CLAUSE_COPYIN:
00813 WGEN_Set_Cflag(clause_copyin);
00814 st = Get_ST(gs_omp_clause_decl(clauses));
00815 wn = WN_CreatePragma(WN_PRAGMA_COPYIN, st, 0, 0);
00816 break;
00817
00818 case GS_OMP_CLAUSE_COPYPRIVATE:
00819 WGEN_Set_Cflag(clause_copyprivate);
00820 st = Get_ST(gs_omp_clause_decl(clauses));
00821 wn = WN_CreatePragma(WN_PRAGMA_COPYPRIVATE, st, 0, 0);
00822 break;
00823
00824 case GS_OMP_CLAUSE_REDUCTION:
00825 {
00826 WGEN_Set_Cflag(clause_reduction);
00827 OPERATOR opr = get_reduction_code(clauses);
00828 st = Get_ST(gs_omp_clause_decl(clauses));
00829 wn = WN_CreatePragma(WN_PRAGMA_REDUCTION, st, 0, opr);
00830 }
00831 break;
00832
00833 case GS_OMP_CLAUSE_NOWAIT:
00834 wn = WN_CreatePragma(WN_PRAGMA_NOWAIT, (ST_IDX)NULL, 0, 0);
00835 break;
00836
00837 case GS_OMP_CLAUSE_ORDERED:
00838 WGEN_Set_Cflag(clause_ordered);
00839 wn = WN_CreatePragma(WN_PRAGMA_ORDERED, (ST_IDX)NULL, 0, 0);
00840 break;
00841
00842 case GS_OMP_CLAUSE_SCHEDULE:
00843 {
00844 WN_PRAGMA_SCHEDTYPE_KIND schedtype_kind;
00845 switch(gs_omp_clause_schedule_kind(clauses)) {
00846 case GS_OMP_CLAUSE_SCHEDULE_STATIC:
00847 schedtype_kind = WN_PRAGMA_SCHEDTYPE_SIMPLE;
00848 break;
00849 case GS_OMP_CLAUSE_SCHEDULE_DYNAMIC:
00850 schedtype_kind = WN_PRAGMA_SCHEDTYPE_DYNAMIC;
00851 break;
00852 case GS_OMP_CLAUSE_SCHEDULE_GUIDED:
00853 schedtype_kind = WN_PRAGMA_SCHEDTYPE_GSS;
00854 break;
00855 case GS_OMP_CLAUSE_SCHEDULE_RUNTIME:
00856 schedtype_kind = WN_PRAGMA_SCHEDTYPE_RUNTIME;
00857 break;
00858 default:
00859 Fail_FmtAssertion ("Invalid OpenMP schedule kind");
00860 }
00861
00862 wn = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE,
00863 (ST_IDX)NULL,
00864 schedtype_kind,
00865 0);
00866 WN_set_pragma_omp(wn);
00867 WGEN_Stmt_Append (wn, Get_Srcpos());
00868
00869 wn = NULL;
00870
00871 gs_t chunk_size = gs_omp_clause_schedule_chunk_expr(clauses);
00872 if (chunk_size)
00873 {
00874 wn = WN_CreateXpragma(WN_PRAGMA_CHUNKSIZE,
00875 (ST_IDX) NULL,
00876 1);
00877 WN * chunk_wn = WGEN_Expand_Expr(chunk_size);
00878 if (lang_cplus && region && WN_has_side_effects(chunk_wn))
00879 {
00880 TY_IDX ty_idx = MTYPE_TO_TY_array[WN_rtype(chunk_wn)];
00881 ST * st = Gen_Temp_Symbol (ty_idx, "__mp_chunk_size");
00882
00883 WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st, TRUE);
00884 WN * stid = WN_Stid (TY_mtype(ty_idx), 0, st, ty_idx, chunk_wn);
00885
00886
00887
00888 WGEN_Stmt_Append(stid, Get_Srcpos());
00889 WN * top = WGEN_Stmt_Top();
00890 stid = WN_EXTRACT_FromBlock(top, WN_last(top));
00891 WN_INSERT_BlockFirst (WN_region_body(region), stid);
00892 chunk_wn = WN_Ldid (TY_mtype(ty_idx), 0, st, ty_idx);
00893 }
00894 WN_kid0(wn) = chunk_wn;
00895 WN_set_pragma_omp(wn);
00896 WGEN_Stmt_Append (wn, Get_Srcpos());
00897
00898 wn = NULL;
00899 }
00900 }
00901 break;
00902
00903 default:
00904 DevWarn ("WGEN_process_omp_clause: unhandled OpenMP clause");
00905 }
00906
00907 if (wn)
00908 {
00909 WN_set_pragma_omp(wn);
00910
00911
00912 if (region && non_pod && WN_region_kind(region) == REGION_KIND_MP)
00913 WN_INSERT_BlockLast(WN_region_pragmas(region), wn);
00914 else
00915 WGEN_Stmt_Append (wn, Get_Srcpos());
00916 }
00917 }
00918
00919 void WGEN_expand_start_parallel (gs_t stmt)
00920 {
00921
00922
00923 WN * region = WGEN_region(REGION_KIND_MP);
00924
00925 WN *wn;
00926
00927 wn = WN_CreatePragma(WN_PRAGMA_PARALLEL_BEGIN,
00928 (ST_IDX) NULL,
00929 0,
00930 0);
00931 WN_set_pragma_omp(wn);
00932 WGEN_Stmt_Append (wn, Get_Srcpos());
00933
00935 SRCPOS srcpos = Get_Srcpos();
00936 WGEN_CS_push(wgen_omp_parallel, SRCPOS_linenum(srcpos),
00937 SRCPOS_filenum(srcpos));
00938 WGEN_Set_Prag(WGEN_Stmt_Top());
00939 WGEN_Set_Region (region);
00940
00941
00943 Set_PU_has_mp (Get_Current_PU ());
00944 Set_FILE_INFO_has_mp (File_info);
00945 Set_PU_uplevel (Get_Current_PU ());
00946
00947 gs_t clauses = gs_omp_parallel_clauses (stmt);
00948
00949 for (; clauses; clauses = gs_omp_clause_chain(clauses))
00950 WGEN_process_omp_clause(clauses, region);
00951
00952 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
00953
00954 if (lang_cplus)
00955 {
00956 if (!dtor_call_stack.empty() &&
00957 WN_operator (dtor_call_stack.top()) == OPR_CALL)
00958 dtor_call_stack.push (region);
00959
00960 if (!local_node_stack.empty() &&
00961 WN_operator (local_node_stack.top()) == OPR_PRAGMA)
00962 local_node_stack.push (region);
00963 }
00964 }
00965
00966 void WGEN_expand_end_parallel ()
00967 {
00968 if (lang_cplus)
00969 {
00970 WN * wn = WGEN_Stmt_Top ();
00971 WGEN_maybe_call_dtors (wn);
00972 WGEN_maybe_localize_vars (wn);
00973 WGEN_maybe_do_eh_cleanups ();
00974 }
00975
00976 WGEN_Stmt_Pop (wgen_stmk_scope);
00977 WGEN_CS_pop (wgen_omp_parallel);
00978 };
00979
00980
00981 #if 0
00984
00985 void WGEN_check_for ( WN *for_wn)
00986 {
00987
00988
00989
00990
00991 bool chkflag=false;
00992
00993 WN* wn1,*wn2,*wn3,*wn4;
00994 CHECK_STMT *cs1,*cs2;
00995 char * msg = NULL;
00996
00997 if (WN_operator(for_wn)!=OPR_BLOCK)
00998 {
00999 fprintf(stderr,"WGEN_check_for can't deal with Non-block item!\n");
01000 chkflag=true;
01001 }
01002 else if (WN_first (for_wn) &&
01003 WN_operator (WN_first (for_wn)) == OPR_DO_LOOP)
01004 {
01005 ST * index_st = WN_st (WN_index (WN_first (for_wn)));
01006 if (ST_is_thread_private (index_st))
01007 {
01008 msg = "A for loop iteration variable may not appear in a threadprivate directive.";
01009 chkflag = true;
01010 }
01011 }
01012
01013
01014 if( WGEN_bind_to_same(wgen_omp_for,wgen_omp_for,wgen_omp_parallel)||
01015 WGEN_bind_to_same(wgen_omp_for,wgen_omp_sections,wgen_omp_parallel)||
01016 WGEN_bind_to_same(wgen_omp_for,wgen_omp_single,wgen_omp_parallel) )
01017 {
01018 msg = "for, sections, and single directives\
01019 that bind to the \
01020 same parallel are not allowed to be nested inside each other.";
01021 chkflag=true;
01022 }
01023
01024
01025
01026 if( WGEN_bind_to_same(wgen_omp_for,wgen_omp_critical,wgen_omp_parallel)||
01027 WGEN_bind_to_same(wgen_omp_for,wgen_omp_ordered,wgen_omp_parallel)||
01028 WGEN_bind_to_same(wgen_omp_for,wgen_omp_master,wgen_omp_parallel) )
01029 {
01030 msg = "for, sections, and single directives\
01031 are not permitted in the dynamic extent of critical, ordered,\
01032 and master regions if the directives\
01033 bind to the same parallel as the regions.";
01034 chkflag=true;
01035 }
01036
01037
01038
01039 cs1=WGEN_CS_Find_Rtn(wgen_omp_parallel);
01040 cs2=WGEN_CS_top();
01041 bool fg1,fg2,fg3,fg4,fg5;
01042 fg1=fg2=fg3=fg4=fg5=false;
01043 if(cs1)
01044 {
01045
01046
01047 fg1=WGEN_Check_Cflag(cs1, clause_reduction);
01048 fg2=WGEN_Check_Cflag(cs1, clause_private);
01049 fg3=WGEN_Check_Cflag(cs2, clause_private);
01050 fg4=WGEN_Check_Cflag(cs2,clause_firstprivate);
01051 fg5=WGEN_Check_Cflag(cs2,clause_lastprivate);
01052
01053 if(fg1&&(fg3||fg4||fg5)||fg2&&(fg4||fg5))
01054 {
01055 wn1=cs1->wn_prag;
01056 wn2=cs2->wn_prag;
01057 wn3=WN_first(wn1);
01058 wn4=WN_first(wn2);
01059 while(wn3!=NULL)
01060 {
01061 if(WN_pragma(wn3)!=WN_PRAGMA_REDUCTION&&
01062 WN_pragma(wn3)!=WN_PRAGMA_LOCAL)
01063 {
01064 wn3=WN_next(wn3);
01065 continue;
01066 }
01067
01068 while(wn4!=NULL)
01069 {
01070 if(WN_pragma(wn4)==WN_PRAGMA_LOCAL&&WN_pragma(wn3)==WN_PRAGMA_REDUCTION
01071 &&WN_st_idx(wn3)==WN_st_idx(wn4))
01072 {
01073 msg = "Variables that appear in the reduction clause of a parallel \
01074 directive cannot be specified in a private clause on a work-sharing \
01075 directive that binds to the parallel construct.";
01076 chkflag=true;
01077 }
01078 if(WN_pragma(wn4)==WN_PRAGMA_FIRSTPRIVATE&&
01079 WN_st_idx(wn3)==WN_st_idx(wn4))
01080 {
01081 msg = "Variables that are private within a parallel region or that appear \
01082 in the reduction clause of a parallel directive cannot be specified in a \
01083 firstprivateclause on for directive that binds to the parallel construct.";
01084 chkflag=true;
01085 }
01086 if(WN_pragma(wn4)==WN_PRAGMA_LASTLOCAL&&
01087 WN_st_idx(wn3)==WN_st_idx(wn4))
01088 {
01089 msg = "Variables that are private within a parallel region or that appear \
01090 in the reduction clause of a parallel directive cannot be specified in a \
01091 lastprivate clause on a for directive that binds to the parallel construct.";
01092 chkflag=true;
01093 }
01094 wn4=WN_next(wn4);
01095 }
01096 wn3=WN_next(wn3);
01097 }
01098
01099 }
01100 }
01101
01102 cs1=WGEN_CS_top();
01103 wn1=cs1->wn_prag;
01104 wn2=WN_first(wn1);
01105 while(wn2!=NULL)
01106 {
01107
01108 if(WN_st(wn2)==NULL)
01109 {
01110 wn2=WN_next(wn2);
01111 continue;
01112 }
01113 if(ST_is_thread_private(* WN_st(wn2)) )
01114 {
01115 if(WN_pragma(wn2)!=WN_PRAGMA_COPYIN&&WN_pragma(wn2)!=WN_PRAGMA_COPYPRIVATE
01116 &&WN_pragma(wn2)!=WN_PRAGMA_MPSCHEDTYPE&&WN_pragma(wn2)!=WN_PRAGMA_IF
01117 &&WN_pragma(wn2)!=WN_PRAGMA_NUMTHREADS)
01118 {
01119 msg = "A threadprivate variable must not appear in any clause except the copyin, \
01120 copyprivate, schedule, num_threads,or the if clause.";
01121 chkflag=true;
01122 }
01123 }
01124
01125
01126 if(WN_pragma(wn2)==WN_PRAGMA_LOCAL)
01127 WGEN_check_private(wn2,chkflag);
01128
01129 if(WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
01130 WGEN_check_firstprivate(wn2,chkflag);
01131
01132 if(WN_pragma(wn2)==WN_PRAGMA_LASTLOCAL)
01133 WGEN_check_lastprivate(wn2,chkflag);
01134
01135 if(WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
01136 WGEN_check_reduction(wn2,chkflag);
01137
01138 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
01139 WGEN_check_default(wn2,chkflag);
01140
01141 wn2=WN_next(wn2);
01142
01143 }
01144 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
01145 return;
01146
01147 };
01148
01149 #endif
01150
01151 static WN * Setup_MP_Enclosing_Region (void);
01152
01153 void WGEN_expand_start_for (gs_t stmt)
01154 {
01155 FmtAssert (lastlocal_node_stack.empty(),
01156 ("Lastlocal non-POD variables from previous region?"));
01157
01158 WN * enclosing_region = NULL;
01159 if (lang_cplus)
01160 {
01161 CHECK_STMT * enclosing = WGEN_CS_top();
01162 if (enclosing)
01163 {
01164 enclosing_region = enclosing->region;
01165
01166 FmtAssert (enclosing_region,
01167 ("NULL enclosing region of SECTIONS clause"));
01168
01169 WN * first_pragma = WN_first(WN_region_pragmas(enclosing_region));
01170 FmtAssert (WN_region_kind(enclosing_region) == REGION_KIND_MP &&
01171 first_pragma &&
01172 WN_pragma(first_pragma) == WN_PRAGMA_PARALLEL_BEGIN,
01173 ("Unexpected parent region of SECTIONS clause"));
01174 }
01175 else
01176 enclosing_region = Setup_MP_Enclosing_Region();
01177 }
01178
01179
01180
01181 WN * region = WGEN_region(REGION_KIND_MP);
01182
01183 WN *wn;
01184
01185 wn = WN_CreatePragma(WN_PRAGMA_PDO_BEGIN,
01186 (ST_IDX) NULL,
01187 0,
01188 0);
01189 WN_set_pragma_omp(wn);
01190 WGEN_Stmt_Append (wn, Get_Srcpos());
01192 SRCPOS srcpos = Get_Srcpos();
01193 WGEN_CS_push(wgen_omp_for,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
01194 WGEN_Set_Prag(WGEN_Stmt_Top());
01195 WGEN_Set_Region (region);
01196
01197
01199 Set_PU_has_mp (Get_Current_PU ());
01200 Set_FILE_INFO_has_mp (File_info);
01201 Set_PU_uplevel (Get_Current_PU ());
01202
01203 gs_t clauses = gs_omp_for_clauses (stmt);
01204
01205 if (lang_cplus)
01206 region = enclosing_region;
01207 for (; clauses; clauses = gs_omp_clause_chain(clauses))
01208 WGEN_process_omp_clause(clauses, region);
01209
01210 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
01211
01212 if (lang_cplus)
01213 {
01214 if (!dtor_call_stack.empty() &&
01215 WN_operator (dtor_call_stack.top()) == OPR_CALL)
01216 dtor_call_stack.push (region);
01217
01218 if (!local_node_stack.empty() &&
01219 WN_operator (local_node_stack.top()) == OPR_PRAGMA)
01220 local_node_stack.push (region);
01221 }
01222 }
01223
01224 void WGEN_expand_end_for ( )
01225 {
01226
01227 WGEN_Stmt_Pop (wgen_stmk_scope);
01228
01229 if (lang_cplus)
01230 {
01231 WN *wn = WGEN_Stmt_Top ();
01232
01233 for (INT i=0; i<doloop_side_effects.size(); i++)
01234 WN_INSERT_BlockFirst (wn, doloop_side_effects[i]);
01235 doloop_side_effects.clear ();
01236
01237
01238
01239
01240 if (!WGEN_CS_enclose())
01241 {
01242 WGEN_maybe_call_dtors (wn);
01243 WGEN_maybe_localize_vars (wn);
01244 WGEN_maybe_do_eh_cleanups ();
01245
01246 WGEN_Stmt_Pop (wgen_stmk_region_body);
01247 }
01248 }
01249 WGEN_CS_pop(wgen_omp_for);
01250 }
01251
01252 #if 0
01253
01256
01257 void WGEN_check_sections ( WN *sections_wn)
01258 {
01259 bool chkflag=false;
01260 char * msg = NULL;
01261
01262
01263 WN* wn1,*wn2,*wn3,*wn4;
01264 CHECK_STMT *cs1,*cs2;
01265
01266
01267
01268
01269
01270
01271
01272 if( WGEN_bind_to_same(wgen_omp_sections,wgen_omp_for,wgen_omp_parallel) ||
01273 WGEN_bind_to_same(wgen_omp_sections,wgen_omp_single,wgen_omp_parallel) )
01274 {
01275 msg = "for, sections, and single directives that bind to the same parallel \
01276 are not allowed to be nested inside each other.";
01277 chkflag=true;
01278 }
01279
01280
01281
01282 if( WGEN_bind_to_same(wgen_omp_sections,wgen_omp_critical,wgen_omp_parallel)||
01283 WGEN_bind_to_same(wgen_omp_sections,wgen_omp_ordered,wgen_omp_parallel)||
01284 WGEN_bind_to_same(wgen_omp_sections,wgen_omp_master,wgen_omp_parallel))
01285
01286 {
01287 msg = "for, sections, and single directives are not permitted in \
01288 the dynamic extent of critical, ordered, and master regions if the directives \
01289 bind to the same parallel as the regions.";
01290 chkflag=true;
01291 }
01292
01293
01294 cs1=WGEN_CS_Find_Rtn(wgen_omp_parallel);
01295 cs2=WGEN_CS_top();
01296 bool fg1,fg2,fg3,fg4,fg5;
01297 fg1=fg2=fg3=fg4=fg5=false;
01298 if(cs1)
01299 {
01300
01301
01302 fg1=WGEN_Check_Cflag(cs1, clause_reduction);
01303 fg2=WGEN_Check_Cflag(cs1, clause_private);
01304 fg3=WGEN_Check_Cflag(cs2, clause_private);
01305 fg4=WGEN_Check_Cflag(cs2,clause_firstprivate);
01306 fg5=WGEN_Check_Cflag(cs2,clause_lastprivate);
01307
01308 if(fg1&&(fg3||fg4||fg5)||fg2&&(fg4||fg5))
01309 {
01310 wn1=cs1->wn_prag;
01311 wn2=cs2->wn_prag;
01312 wn3=WN_first(wn1);
01313 wn4=WN_first(wn2);
01314 while(wn3!=NULL)
01315 {
01316 if(WN_pragma(wn3)!=WN_PRAGMA_REDUCTION&&
01317 WN_pragma(wn3)!=WN_PRAGMA_LOCAL)
01318 {
01319 wn3=WN_next(wn3);
01320 continue;
01321 }
01322 while(wn4!=NULL)
01323 {
01324 if( WN_pragma(wn4)==WN_PRAGMA_LOCAL&&WN_pragma(wn3)==WN_PRAGMA_REDUCTION
01325 &&WN_st_idx(wn3)==WN_st_idx(wn4))
01326 {
01327 msg = "Variables that appear in the reduction clause of a parallel \
01328 directive cannot be specified in a private clause on a work-sharing \
01329 directive that binds to the parallel construct.";
01330 chkflag=true;
01331 }
01332 if(WN_pragma(wn4)==WN_PRAGMA_FIRSTPRIVATE&&
01333 WN_st_idx(wn3)==WN_st_idx(wn4))
01334 {
01335 msg = "Variables that are private within a parallel region or that appear \
01336 in the reduction clause of a parallel directive cannot be specified in a \
01337 firstprivate clause on for directive that binds to the parallel construct.";
01338 chkflag=true;
01339 }
01340 if(WN_pragma(wn4)==WN_PRAGMA_LASTLOCAL&&
01341 WN_st_idx(wn3)==WN_st_idx(wn4))
01342 {
01343 msg = "Variables that are private within a parallel region or that appear \
01344 in the reduction clause of a parallel directive cannot be specified in a \
01345 lastprivate clause on a for directive that binds to the parallel construct.";
01346 chkflag=true;
01347 }
01348 wn4=WN_next(wn4);
01349 }
01350 wn3=WN_next(wn3);
01351 }
01352
01353 }
01354 }
01355 cs1=WGEN_CS_top();
01356 wn1=cs1->wn_prag;
01357 wn2=WN_first(wn1);
01358 while(wn2!=NULL)
01359 {
01360 if(WN_st(wn2)==NULL)
01361 {
01362 wn2=WN_next(wn2);
01363 continue;
01364 }
01365 if(ST_is_thread_private(* WN_st(wn2)) )
01366 {
01367 if(WN_pragma(wn2)!=WN_PRAGMA_COPYIN&&WN_pragma(wn2)!=WN_PRAGMA_COPYPRIVATE
01368 &&WN_pragma(wn2)!=WN_PRAGMA_MPSCHEDTYPE&&WN_pragma(wn2)!=WN_PRAGMA_IF
01369 &&WN_pragma(wn2)!=WN_PRAGMA_NUMTHREADS)
01370 {
01371 msg = "A threadprivate variable must not appear in any clause except the copyin, \
01372 copyprivate, schedule, num_threads,or the if clause.";
01373 chkflag=true;
01374 }
01375 }
01376
01377 if(WN_pragma(wn2)==WN_PRAGMA_LOCAL)
01378 WGEN_check_private(wn2,chkflag);
01379
01380 if(WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
01381 WGEN_check_firstprivate(wn2,chkflag);
01382
01383 if(WN_pragma(wn2)==WN_PRAGMA_LASTLOCAL)
01384 WGEN_check_lastprivate(wn2,chkflag);
01385
01386 if(WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
01387 WGEN_check_reduction(wn2,chkflag);
01388
01389 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
01390 WGEN_check_default(wn2,chkflag);
01391
01392 wn2=WN_next(wn2);
01393
01394 }
01395 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
01396 return;
01397 };
01398
01399 #endif
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static WN *
01410 Setup_MP_Enclosing_Region (void)
01411 {
01412 if (!lang_cplus) return NULL;
01413
01414 WN * region_body = WN_CreateBlock();
01415
01416 INITV_IDX iv;
01417 LABEL_IDX pad = 0;
01418
01419 iv = New_INITV();
01420 INITV_Set_ZERO (Initv_Table[iv], MTYPE_U4, 1);
01421
01422 INITV_IDX initv_label = New_INITV();
01423 INITV_Set_ZERO (Initv_Table[initv_label], MTYPE_U4, 1);
01424 INITV_IDX blk = New_INITV();
01425 INITV_Init_Block (blk, initv_label);
01426
01427 Set_INITV_next (initv_label, iv);
01428
01429 TY_IDX ty = MTYPE_TO_TY_array[MTYPE_U4];
01430 ST * ereg = Gen_Temp_Named_Symbol (ty, "dummy1", CLASS_VAR,
01431 SCLASS_EH_REGION_SUPP);
01432 Set_ST_is_initialized (*ereg);
01433 Set_ST_is_not_used (*ereg);
01434 INITO_IDX ereg_supp = New_INITO (ST_st_idx(ereg), blk);
01435
01436 WN * region = WN_CreateRegion (REGION_KIND_EH, region_body,
01437 WN_CreateBlock(), WN_CreateBlock(), New_Region_Id(), ereg_supp);
01438
01439 WGEN_Stmt_Append (region, Get_Srcpos());
01440 Set_PU_has_region (Get_Current_PU());
01441 Set_PU_has_exc_scopes (Get_Current_PU());
01442
01443 WGEN_Stmt_Push (region_body, wgen_stmk_region_body, Get_Srcpos());
01444
01445 return region;
01446 }
01447
01448 void WGEN_expand_start_sections (gs_t stmt)
01449 {
01450 FmtAssert (lastlocal_node_stack.empty(),
01451 ("Lastlocal non-POD variables from previous region?"));
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 WN * enclosing_region = NULL;
01467 if (lang_cplus)
01468 {
01469 CHECK_STMT * enclosing = WGEN_CS_top();
01470 if (enclosing)
01471 {
01472 enclosing_region = enclosing->region;
01473
01474 FmtAssert (enclosing_region,
01475 ("NULL enclosing region of SECTIONS clause"));
01476
01477 WN * first_pragma = WN_first(WN_region_pragmas(enclosing_region));
01478 FmtAssert (WN_region_kind(enclosing_region) == REGION_KIND_MP &&
01479 first_pragma &&
01480 WN_pragma(first_pragma) == WN_PRAGMA_PARALLEL_BEGIN,
01481 ("Unexpected parent region of SECTIONS clause"));
01482 }
01483 else
01484 enclosing_region = Setup_MP_Enclosing_Region();
01485 }
01486
01487
01488
01489 WN * region = WGEN_region(REGION_KIND_MP);
01490
01491 WN *wn;
01492
01494 SRCPOS srcpos = Get_Srcpos();
01495 WGEN_CS_push(wgen_omp_sections,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
01496 WGEN_Set_Prag(WGEN_Stmt_Top());
01497 WGEN_Set_Region (region);
01499
01500 wn = WN_CreatePragma(WN_PRAGMA_PSECTION_BEGIN,
01501 (ST_IDX) NULL,
01502 0,
01503 0);
01504 WN_set_pragma_omp(wn);
01505 WGEN_Stmt_Append (wn, Get_Srcpos());
01506
01508 Set_PU_has_mp (Get_Current_PU ());
01509 Set_FILE_INFO_has_mp (File_info);
01510 Set_PU_uplevel (Get_Current_PU ());
01511
01512 gs_t clauses = gs_omp_sections_clauses (stmt);
01513
01514 #if 0 // clean up
01515
01516
01517
01518
01519 CHECK_STMT * enclosing = WGEN_CS_enclose();
01520 if (enclosing)
01521 {
01522 region = enclosing->region;
01523
01524 FmtAssert (region, ("NULL enclosing region of SECTIONS clause"));
01525
01526 WN * first_pragma = WN_first(WN_region_pragmas(region));
01527 FmtAssert (WN_region_kind(region) == REGION_KIND_MP &&
01528 first_pragma &&
01529 WN_pragma(first_pragma) == WN_PRAGMA_PARALLEL_BEGIN,
01530 ("Unexpected parent region of SECTIONS clause"));
01531 }
01532 #else
01533 if (lang_cplus)
01534 region = enclosing_region;
01535 #endif
01536
01537 for (; clauses; clauses = gs_omp_clause_chain(clauses))
01538 WGEN_process_omp_clause(clauses, region);
01539
01540 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
01541
01542 if (lang_cplus)
01543 {
01544
01545 if (!dtor_call_stack.empty() &&
01546 WN_operator (dtor_call_stack.top()) == OPR_CALL)
01547 dtor_call_stack.push (region);
01548
01549
01550 if (!local_node_stack.empty() &&
01551 WN_operator (local_node_stack.top()) == OPR_PRAGMA)
01552 local_node_stack.push (region);
01553 }
01554 }
01555
01556
01557 void WGEN_expand_start_section ()
01558 {
01559 WN *wn;
01560
01561 wn = WN_CreatePragma(WN_PRAGMA_SECTION,
01562 (ST_IDX) NULL,
01563 0,
01564 0);
01565 WN_set_pragma_omp(wn);
01566 WGEN_Stmt_Append (wn, Get_Srcpos());
01567
01568 WN * body = WN_CreateBlock ();
01569 WGEN_Stmt_Push (body, wgen_stmk_scope, Get_Srcpos());
01571 SRCPOS srcpos = Get_Srcpos();
01572 WGEN_CS_push(wgen_omp_section,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
01573 }
01574
01575 #if 0
01576 void WGEN_check_section ( )
01577 {
01578 int i;
01579 bool chkflag=false;
01580 char * msg = NULL;
01581
01582 if(WGEN_CS_Find (wgen_omp_sections) >= 0 ||
01583 WGEN_CS_Find (wgen_omp_parallel_sections) >= 0)
01584 return;
01585
01586 msg = "Section directive appeared outside the lexical extent of \
01587 directive sections or directive parallel sections.";
01588 chkflag=true;
01589 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
01590 return;
01591 }
01592 #endif
01593
01594 void WGEN_expand_end_section ( )
01595 {
01596
01597
01598 WN *wn = WGEN_Stmt_Top ();
01599 #if 0
01600
01601 WGEN_check_section();
01602 #endif
01603 WGEN_Stmt_Pop (wgen_stmk_scope);
01604 WGEN_Stmt_Append (wn, Get_Srcpos());
01605
01606 WGEN_CS_pop(wgen_omp_section);
01607 }
01608
01609
01610 static void WGEN_generate_non_pod_lastlocal_finalization (void);
01611
01612 void WGEN_expand_end_sections ( )
01613 {
01614 #if 0
01615
01616 WGEN_check_sections (wn);
01617 #endif
01618 WGEN_generate_non_pod_lastlocal_finalization ();
01619 WGEN_Stmt_Pop (wgen_stmk_scope);
01620
01621
01622
01623 if (lang_cplus && !WGEN_CS_enclose())
01624 {
01625 WN *wn = WGEN_Stmt_Top ();
01626
01627 WGEN_maybe_call_dtors(wn);
01628 WGEN_maybe_localize_vars(wn);
01629 WGEN_maybe_do_eh_cleanups();
01630
01631 WGEN_Stmt_Pop (wgen_stmk_region_body);
01632 }
01633
01634 WGEN_CS_pop(wgen_omp_sections);
01635 }
01636
01637
01638 #if 0
01641
01642 void WGEN_check_single ()
01643 {
01644 bool chkflag=false;
01645 char * msg = NULL;
01646
01647
01648 WN* wn1,*wn2,*wn3,*wn4,*wn5,*wn6;
01649 CHECK_STMT *cs1,*cs2,*cs3;
01650 bool fg1,fg2,fg3,fg4;
01651 int find=-1;
01652
01653
01654
01655
01656
01657
01658
01659 if( WGEN_bind_to_same(wgen_omp_single,wgen_omp_for,wgen_omp_parallel) ||
01660 WGEN_bind_to_same(wgen_omp_single,wgen_omp_sections,wgen_omp_parallel) )
01661 {
01662 msg="for, sections, and single directives that bind to the same\n"
01663 "\tparallel are not allowed to be nested inside each other.";
01664 chkflag=true;
01665 }
01666
01667
01668
01669 if( WGEN_bind_to_same(wgen_omp_single,wgen_omp_critical,wgen_omp_parallel)||
01670 WGEN_bind_to_same(wgen_omp_single,wgen_omp_ordered,wgen_omp_parallel)||
01671 WGEN_bind_to_same(wgen_omp_single,wgen_omp_master,wgen_omp_parallel))
01672
01673 {
01674 msg="for, sections, and single directives are not permitted in\n"
01675 "\tthe dynamic extent of critical, ordered, and master regions\n"
01676 "\tif the directives bind to the same parallel as the regions.";
01677 chkflag=true;
01678 }
01679
01680 fg1=fg2=fg3=fg4=false;
01681
01682 cs1=WGEN_CS_top();
01683 fg1=WGEN_Check_Cflag(cs1, clause_copyprivate);
01684
01685 if(fg1 && (WGEN_CS_Find(wgen_omp_parallel) >= 0))
01686 {
01687 cs2=WGEN_CS_enclose();
01688 cs3=WGEN_CS_Find_Rtn(wgen_omp_parallel);
01689 wn1=cs1->wn_prag;
01690 wn2=cs2->wn_prag;
01691 wn3=WN_first(wn1);
01692 wn4=WN_first(wn2);
01693 wn5=cs3->wn_prag;
01694 wn6=WN_first(wn5);
01695
01696 if((cs2!=NULL)&&(cs2->kind>=wgen_omp_parallel&&cs2->kind<=wgen_omp_parallel_for))
01697 {
01698 while(wn3!=NULL)
01699 {
01700
01701 if(WN_pragma(wn3)!=WN_PRAGMA_COPYPRIVATE)
01702 {
01703 wn3=WN_next(wn3);
01704 continue;
01705 }
01706 if (ST_is_thread_private (WN_st (wn3)))
01707 fg2 = true;
01708 if (!fg2)
01709 while(wn4!=NULL)
01710 {
01711 if(WN_pragma(wn4) == WN_PRAGMA_LOCAL &&
01712 WN_st_idx(wn3) == WN_st_idx(wn4))
01713 {
01714 fg2=true;
01715 break;
01716 }
01717 wn4=WN_next(wn4);
01718 }
01719
01720 if(fg2==false)
01721 {
01722 msg="A single directive with copyprivate clause encountered in\n"
01723 "\tthe dynamic extent of parallel region, but the variables\n"
01724 "\tspecified copyprivate are not threadprivate, or private\n"
01725 "\tin the enclosing context.";
01726 chkflag=true;
01727 }
01728
01729 wn3=WN_next(wn3);
01730 }
01731 }
01732 }
01733
01734 fg1=WGEN_Check_Cflag(cs1, clause_copyprivate);
01735 fg2=WGEN_Check_Cflag(cs1, clause_private);
01736 fg3=WGEN_Check_Cflag(cs1, clause_firstprivate);
01737
01738 if(fg1 && (fg2 || fg3))
01739 {
01740 wn1=cs1->wn_prag;
01741 wn2=wn3=WN_first(wn1);
01742 while(wn2)
01743 {
01744 if(WN_pragma(wn2)==WN_PRAGMA_COPYPRIVATE)
01745 break;
01746 wn2=WN_next(wn2);
01747 }
01748 if(wn2!=NULL)
01749 {
01750 while(wn3)
01751 {
01752 if((WN_pragma(wn3)==WN_PRAGMA_LOCAL||WN_pragma(wn3)==WN_PRAGMA_FIRSTPRIVATE)
01753 &&WN_st(wn2)==WN_st(wn3))
01754 {
01755 msg="A variable that is specified copyprivate cannot appear in\n"
01756 "\tprivate or firstprivate clause in the same single directive.";
01757 chkflag=true;
01758 }
01759 wn3=WN_next(wn3);
01760 }
01761 }
01762 }
01763
01764
01765 cs1=WGEN_CS_Find_Rtn(wgen_omp_parallel);
01766 cs2=WGEN_CS_top();
01767
01768 fg1 = fg2 = fg3 = fg4 = false;
01769 if(cs1)
01770 {
01771 fg1=WGEN_Check_Cflag(cs1, clause_reduction);
01772 fg2=WGEN_Check_Cflag(cs1, clause_private);
01773 fg3=WGEN_Check_Cflag(cs2, clause_private);
01774 fg4=WGEN_Check_Cflag(cs2,clause_firstprivate);
01775
01776 if(fg1 && (fg3 || fg4) || fg2 && fg4)
01777 {
01778 wn1=cs1->wn_prag;
01779 wn2=cs2->wn_prag;
01780 wn3=WN_first(wn1);
01781 wn4=WN_first(wn2);
01782 while(wn3!=NULL)
01783 {
01784 if(WN_pragma(wn3) != WN_PRAGMA_REDUCTION &&
01785 WN_pragma(wn3) != WN_PRAGMA_LOCAL)
01786 {
01787 wn3=WN_next(wn3);
01788 continue;
01789 }
01790 while(wn4!=NULL)
01791 {
01792 if(WN_pragma(wn4) == WN_PRAGMA_LOCAL &&
01793 WN_pragma(wn3) == WN_PRAGMA_REDUCTION &&
01794 WN_st_idx(wn3) == WN_st_idx(wn4))
01795 {
01796 msg="Variables that appear in the reduction clause of a\n"
01797 "\tparallel directive cannot be specified in a private\n"
01798 "\tclause on a work-sharing directive that binds to\n"
01799 "\tthe parallel construct.";
01800 chkflag=true;
01801 }
01802 if(WN_pragma(wn4) == WN_PRAGMA_FIRSTPRIVATE &&
01803 WN_st_idx(wn3) == WN_st_idx(wn4))
01804 {
01805 msg="Variables that are private within a parallel region or\n"
01806 "\tthat appear in the reduction clause of a parallel\n"
01807 "\tdirective cannot be specified in a firstprivate\n"
01808 "\tclause on for directive that binds to the parallel\n"
01809 "\t construct.";
01810 chkflag=true;
01811 }
01812 wn4=WN_next(wn4);
01813 }
01814 wn3=WN_next(wn3);
01815 }
01816 }
01817 }
01818
01819 cs1=WGEN_CS_top();
01820 wn1=cs1->wn_prag;
01821 wn2=WN_first(wn1);
01822
01823 while(wn2!=NULL)
01824 {
01825 if(WN_st(wn2)==NULL)
01826 {
01827 wn2=WN_next(wn2);
01828 continue;
01829 }
01830 if(ST_is_thread_private(* WN_st(wn2)) )
01831 {
01832 if(WN_pragma(wn2) != WN_PRAGMA_COPYIN &&
01833 WN_pragma(wn2) != WN_PRAGMA_COPYPRIVATE &&
01834 WN_pragma(wn2) != WN_PRAGMA_MPSCHEDTYPE &&
01835 WN_pragma(wn2) != WN_PRAGMA_IF &&
01836 WN_pragma(wn2) != WN_PRAGMA_NUMTHREADS)
01837 {
01838 msg="A threadprivate variable must not appear in any clause\n"
01839 "\texcept the copyin, copyprivate, schedule, num_threads,\n"
01840 "\tor the if clause.";
01841 chkflag=true;
01842 }
01843 }
01844
01845 if(WN_pragma(wn2)==WN_PRAGMA_LOCAL)
01846 WGEN_check_private(wn2,chkflag);
01847
01848
01849 if(WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
01850 WGEN_check_firstprivate(wn2,chkflag);
01851
01852
01853 if(WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
01854 WGEN_check_reduction(wn2,chkflag);
01855
01856
01857 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
01858 WGEN_check_default(wn2,chkflag);
01859
01860 wn2=WN_next(wn2);
01861 }
01862
01863 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
01864 return;
01865 }
01866
01867 #endif
01868
01869 void WGEN_expand_start_single (gs_t stmt)
01870 {
01871
01872
01873 WN * region = WGEN_region(REGION_KIND_MP);
01874
01875 WN *wn;
01876
01877 wn = WN_CreatePragma(WN_PRAGMA_SINGLE_PROCESS_BEGIN,
01878 (ST_IDX) NULL, 0, 0);
01879 WN_set_pragma_omp(wn);
01880 WGEN_Stmt_Append (wn, Get_Srcpos());
01882 SRCPOS srcpos = Get_Srcpos();
01883 WGEN_CS_push(wgen_omp_single,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
01884 WGEN_Set_Prag(WGEN_Stmt_Top());
01885 WGEN_Set_Region (region);
01886
01888 Set_PU_has_mp (Get_Current_PU ());
01889 Set_FILE_INFO_has_mp (File_info);
01890 Set_PU_uplevel (Get_Current_PU ());
01891
01892 gs_t clauses = gs_omp_single_clauses (stmt);
01893
01894 for (; clauses; clauses = gs_omp_clause_chain(clauses))
01895 WGEN_process_omp_clause(clauses, region);
01896
01897 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
01898
01899 if (lang_cplus)
01900 {
01901 if (!dtor_call_stack.empty() &&
01902 WN_operator (dtor_call_stack.top()) == OPR_CALL)
01903 dtor_call_stack.push (region);
01904
01905 if (!local_node_stack.empty() &&
01906 WN_operator (local_node_stack.top()) == OPR_PRAGMA)
01907 local_node_stack.push (region);
01908 }
01909 }
01910
01911 void WGEN_expand_end_single ()
01912 {
01913 if (lang_cplus)
01914 {
01915 WN *wn = WGEN_Stmt_Top ();
01916 WGEN_maybe_call_dtors (wn);
01917 WGEN_maybe_localize_vars (wn);
01918 WGEN_maybe_do_eh_cleanups ();
01919 }
01920
01921 WGEN_Stmt_Pop (wgen_stmk_scope);
01922 WGEN_CS_pop(wgen_omp_single);
01923 }
01924
01925 #if 0
01926
01929
01930
01931 void WGEN_check_parallel_for ( WN *parallel_for_wn)
01932 {
01933
01934
01935
01936
01937
01938 bool chkflag=false;
01939
01940
01941 char * msg = NULL;
01942 CHECK_STMT* cs1;
01943 WN* wn1,*wn2,*wn3;
01944 bool fg1,fg2,fg3,fg4;
01945 fg1=fg2=fg3=fg4=false;
01946
01947 if (WN_operator(parallel_for_wn)!=OPR_BLOCK)
01948 {
01949 fprintf(stderr,"WGEN_check_parallel_for can't deal with Non-block item!\n");
01950 chkflag = true;
01951 }
01952 else if (WN_first (parallel_for_wn) &&
01953 WN_operator (WN_first (parallel_for_wn)) == OPR_DO_LOOP)
01954 {
01955 ST * index_st = WN_st (WN_index (WN_first (parallel_for_wn)));
01956 if (ST_is_thread_private (index_st))
01957 {
01958 msg = "Warning: A for loop iteration variable may not appear in a threadprivate directive.";
01959 chkflag = true;
01960 }
01961 }
01962
01963
01964 cs1=WGEN_CS_top();
01965 wn1=cs1->wn_prag;
01966 wn2=wn3=WN_first(wn1);
01967 while(wn2!=NULL)
01968 {
01969 if(WN_st(wn2)==NULL)
01970 {
01971 wn2=WN_next(wn2);
01972 continue;
01973 }
01974
01975 if (WN_pragma(wn2)==WN_PRAGMA_LOCAL)
01976 WGEN_check_private(wn2,chkflag);
01977
01978 if (WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
01979 WGEN_check_firstprivate(wn2,chkflag);
01980
01981 if (WN_pragma(wn2)==WN_PRAGMA_LASTLOCAL)
01982 WGEN_check_lastprivate(wn2,chkflag);
01983
01984 if (WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
01985 WGEN_check_reduction(wn2,chkflag);
01986
01987 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
01988 WGEN_check_default(wn2,chkflag);
01989
01990
01991 if(WN_pragma(wn2) == WN_PRAGMA_COPYIN &&
01992 !ST_is_thread_private(* WN_st(wn2)))
01993 {
01994 msg = "A variable that is specified in the copyin clause \
01995 must be a threadprivate variable.";
01996 chkflag=true;
01997 }
01998
01999 if(ST_is_thread_private(* WN_st(wn2)) )
02000 {
02001 if(WN_pragma(wn2)!=WN_PRAGMA_COPYIN&&WN_pragma(wn2)!=WN_PRAGMA_COPYPRIVATE
02002 &&WN_pragma(wn2)!=WN_PRAGMA_MPSCHEDTYPE&&WN_pragma(wn2)!=WN_PRAGMA_IF
02003 &&WN_pragma(wn2)!=WN_PRAGMA_NUMTHREADS)
02004 {
02005 msg = "A threadprivate variable must not appear in any clause except the copyin, \
02006 copyprivate, schedule, num_threads, or the if clause.";
02007 chkflag=true;
02008 }
02009 }
02010
02011 if(WN_pragma(wn2)!=WN_PRAGMA_REDUCTION&&
02012 WN_pragma(wn2)!=WN_PRAGMA_LOCAL)
02013 {
02014 wn2=WN_next(wn2);
02015 continue;
02016 }
02017 fg1=WGEN_Check_Cflag(cs1, clause_reduction);
02018 fg2=WGEN_Check_Cflag(cs1, clause_private);
02019 fg3=WGEN_Check_Cflag(cs1,clause_firstprivate);
02020 fg4=WGEN_Check_Cflag(cs1,clause_lastprivate);
02021 if(!(fg1&&(fg2||fg3||fg4)||fg2&&(fg3||fg4)))
02022 {
02023 wn2 = WN_next (wn2);
02024 continue;
02025 }
02026 while(wn3!=NULL)
02027 {
02028 if( WN_pragma(wn3)==WN_PRAGMA_LOCAL&&WN_pragma(wn2)==WN_PRAGMA_REDUCTION
02029 &&WN_st(wn3)==WN_st(wn2))
02030 {
02031 msg = "Variables that appear in the reduction clause of a parallel \
02032 directive cannot be specified in a private clause on a work-sharing \
02033 directive that binds to the parallel construct.";
02034 chkflag=true;
02035 }
02036 if( WN_pragma(wn3)==WN_PRAGMA_FIRSTPRIVATE&&
02037 WN_st(wn3)==WN_st(wn2))
02038 {
02039 msg = "Variables that are private within a parallel region or that appear \
02040 in the reduction clause of a parallel directive cannot be specified in a \
02041 firstprivateclause on for directive that binds to the parallel construct.";
02042 chkflag=true;
02043 }
02044 if( WN_pragma(wn3)==WN_PRAGMA_LASTLOCAL&&
02045 WN_st(wn3)==WN_st(wn2))
02046 {
02047 msg = "Variables that are private within a parallel region or that appear \
02048 in the reduction clause of a parallel directive cannot be specified in a \
02049 lastprivate clause on a for directive that binds to the parallel construct.";
02050 chkflag=true;
02051 }
02052 wn3=WN_next(wn3);
02053 }
02054
02055 wn2=WN_next(wn2);
02056 }
02057 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
02058
02059 }
02060
02061 #endif
02062
02063 void WGEN_expand_start_parallel_for (gs_t stmt)
02064 {
02065 Is_True (gs_tree_code(stmt) == GS_OMP_PARALLEL,
02066 ("WGEN_expand_start_parallel_for: unexpected tree code"));
02067
02068
02069 WN * region = WGEN_region(REGION_KIND_MP);
02070
02071 WN *wn;
02072
02073 wn = WN_CreatePragma(WN_PRAGMA_PARALLEL_DO, (ST_IDX) NULL, 0, 0);
02074 WN_set_pragma_omp(wn);
02075 WGEN_Stmt_Append (wn, Get_Srcpos());
02077 SRCPOS srcpos = Get_Srcpos();
02078 WGEN_CS_push (wgen_omp_parallel_for, SRCPOS_linenum(srcpos),
02079 SRCPOS_filenum(srcpos));
02080 WGEN_Set_Prag (WGEN_Stmt_Top());
02081 WGEN_Set_Region (region);
02083 Set_PU_has_mp (Get_Current_PU ());
02084 Set_FILE_INFO_has_mp (File_info);
02085 Set_PU_uplevel (Get_Current_PU ());
02086
02087
02088 gs_t clauses = gs_omp_parallel_clauses (stmt);
02089
02090 for (; clauses; clauses = gs_omp_clause_chain(clauses))
02091 WGEN_process_omp_clause(clauses);
02092
02093
02094 stmt = gs_omp_parallel_body(stmt);
02095 Is_True (gs_tree_code(stmt) == GS_BIND_EXPR,
02096 ("WGEN_expand_start_parallel_for: unexpected scope stmt"));
02097 stmt = gs_bind_expr_body(stmt);
02098 Is_True (gs_tree_code(stmt) == GS_OMP_FOR,
02099 ("WGEN_expand_start_parallel_for: expected FOR pragma"));
02100
02101 clauses = gs_omp_for_clauses (stmt);
02102 for (; clauses; clauses = gs_omp_clause_chain(clauses))
02103 if (gs_omp_clause_code(clauses) != GS_OMP_CLAUSE_NOWAIT)
02104 WGEN_process_omp_clause(clauses);
02105
02106 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
02107 }
02108
02109 void WGEN_expand_end_parallel_for ()
02110 {
02111 WN *wn = WGEN_Stmt_Top ();
02112
02113 WGEN_Stmt_Pop (wgen_stmk_scope);
02114 WGEN_CS_pop(wgen_omp_parallel_for);
02115 }
02116
02117
02120
02121 #if 0
02122
02123 void WGEN_check_parallel_sections ( WN *parallel_sections_wn)
02124 {
02125
02126
02127
02128
02129 bool chkflag=false;
02130 char * msg = NULL;
02131
02132
02133 CHECK_STMT* cs1;
02134 WN* wn1,*wn2,*wn3;
02135 bool fg1,fg2,fg3,fg4;
02136 fg1=fg2=fg3=fg4=false;
02137
02138 cs1=WGEN_CS_top();
02139 wn1=cs1->wn_prag;
02140 wn2=wn3=WN_first(wn1);
02141 while(wn2!=NULL)
02142 {
02143 if(WN_st(wn2)==NULL)
02144 {
02145 wn2=WN_next(wn2);
02146 continue;
02147 }
02148
02149 if(WN_pragma(wn2)==WN_PRAGMA_LOCAL)
02150 WGEN_check_private(wn2,chkflag);
02151
02152 if(WN_pragma(wn2)==WN_PRAGMA_FIRSTPRIVATE)
02153 WGEN_check_firstprivate(wn2,chkflag);
02154
02155 if(WN_pragma(wn2)==WN_PRAGMA_LASTLOCAL)
02156 WGEN_check_lastprivate(wn2,chkflag);
02157
02158 if(WN_pragma(wn2)==WN_PRAGMA_REDUCTION)
02159 WGEN_check_reduction(wn2,chkflag);
02160
02161 if(WN_pragma(wn2)==WN_PRAGMA_DEFAULT)
02162 WGEN_check_default(wn2,chkflag);
02163
02164
02165
02166 if(WN_pragma(wn2)==WN_PRAGMA_COPYIN)
02167 {
02168 if(!ST_is_thread_private(* WN_st(wn2)))
02169 msg = "A variable that is specified in the copyin clause \
02170 must be a threadprivate variable.";
02171 }
02172 if(ST_is_thread_private(* WN_st(wn2)) )
02173 {
02174 if(WN_pragma(wn2)!=WN_PRAGMA_COPYIN&&WN_pragma(wn2)!=WN_PRAGMA_COPYPRIVATE
02175 &&WN_pragma(wn2)!=WN_PRAGMA_MPSCHEDTYPE&&WN_pragma(wn2)!=WN_PRAGMA_IF
02176 &&WN_pragma(wn2)!=WN_PRAGMA_NUMTHREADS)
02177 {
02178 msg = "A threadprivate variable must not appear in any clause except the copyin, \
02179 copyprivate, schedule, num_threads,or the if clause.";
02180 chkflag=true;
02181 }
02182 }
02183
02184 if(WN_pragma(wn2)!=WN_PRAGMA_REDUCTION&&
02185 WN_pragma(wn2)!=WN_PRAGMA_LOCAL)
02186 {
02187 wn2=WN_next(wn2);
02188 continue;
02189 }
02190 fg1=WGEN_Check_Cflag(cs1, clause_reduction);
02191 fg2=WGEN_Check_Cflag(cs1, clause_private);
02192 fg3=WGEN_Check_Cflag(cs1,clause_firstprivate);
02193 fg4=WGEN_Check_Cflag(cs1,clause_lastprivate);
02194 if(!(fg1&&(fg2||fg3||fg4)||fg2&&(fg3||fg4)))
02195 {
02196 wn2 = WN_next (wn2);
02197 continue;
02198 }
02199 while(wn3!=NULL)
02200 {
02201 if( WN_pragma(wn3)==WN_PRAGMA_LOCAL&&WN_pragma(wn2)==WN_PRAGMA_REDUCTION
02202 &&WN_st(wn3)==WN_st(wn2))
02203 {
02204 msg = "Variables that appear in the reduction clause of a parallel \
02205 directive cannot be specified in a private clause on a work-sharing \
02206 directive that binds to the parallel construct.";
02207 chkflag=true;
02208 }
02209 if( WN_pragma(wn3)==WN_PRAGMA_FIRSTPRIVATE&&
02210 WN_st(wn3)==WN_st(wn2))
02211 {
02212 msg = "Variables that are private within a parallel region or that appear \
02213 in the reduction clause of a parallel directive cannot be specified in a \
02214 firstprivateclause on for directive that binds to the parallel construct.";
02215 chkflag=true;
02216 }
02217 if( WN_pragma(wn3)==WN_PRAGMA_LASTLOCAL&&
02218 WN_st(wn3)==WN_st(wn2))
02219 {
02220 msg = "Variables that are private within a parallel region or that appear \
02221 in the reduction clause of a parallel directive cannot be specified in a \
02222 lastprivate clause on a for directive that binds to the parallel construct.";
02223 chkflag=true;
02224 }
02225 wn3=WN_next(wn3);
02226 }
02227
02228 wn2=WN_next(wn2);
02229 }
02230 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
02231 }
02232
02233
02234 #endif
02235
02236 void WGEN_expand_start_parallel_sections (gs_t stmt)
02237 {
02238
02239
02240 WN * region = WGEN_region(REGION_KIND_MP);
02241
02242 WN *wn;
02243
02244 wn = WN_CreatePragma(WN_PRAGMA_PARALLEL_SECTIONS, (ST_IDX) NULL, 0, 0);
02245 WN_set_pragma_omp(wn);
02246 WGEN_Stmt_Append (wn, Get_Srcpos());
02247
02249 SRCPOS srcpos = Get_Srcpos();
02250 WGEN_CS_push (wgen_omp_parallel_sections, SRCPOS_linenum(srcpos),
02251 SRCPOS_filenum(srcpos));
02252 WGEN_Set_Prag (WGEN_Stmt_Top());
02253 WGEN_Set_Region (region);
02254
02256 Set_PU_has_mp (Get_Current_PU ());
02257 Set_FILE_INFO_has_mp (File_info);
02258 Set_PU_uplevel (Get_Current_PU ());
02259
02260
02261 gs_t clauses = gs_omp_parallel_clauses (stmt);
02262
02263 for (; clauses; clauses = gs_omp_clause_chain(clauses))
02264 WGEN_process_omp_clause(clauses);
02265
02266
02267 stmt = gs_omp_parallel_body(stmt);
02268 Is_True (gs_tree_code(stmt) == GS_BIND_EXPR,
02269 ("WGEN_expand_start_parallel_for: unexpected scope stmt"));
02270 stmt = gs_bind_expr_body(stmt);
02271 Is_True (gs_tree_code(stmt) == GS_OMP_SECTIONS,
02272 ("WGEN_expand_start_parallel_for: expected FOR pragma"));
02273
02274 clauses = gs_omp_sections_clauses (stmt);
02275 for (; clauses; clauses = gs_omp_clause_chain(clauses))
02276 if (gs_omp_clause_code(clauses) != GS_OMP_CLAUSE_NOWAIT)
02277 WGEN_process_omp_clause(clauses);
02278
02279 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
02280 }
02281
02282 void WGEN_expand_end_parallel_sections ()
02283 {
02284 WN *wn = WGEN_Stmt_Top ();
02285
02286 WGEN_Stmt_Pop (wgen_stmk_scope);
02287
02288 WGEN_CS_pop(wgen_omp_parallel_sections);
02289 }
02290
02291
02293 void WGEN_check_master()
02294 {
02295
02296
02297
02298 bool chkflag=false;
02299 char * msg = NULL;
02300
02301 if( WGEN_bind_to_same(wgen_omp_master,wgen_omp_for,wgen_omp_parallel)||
02302 WGEN_bind_to_same(wgen_omp_master,wgen_omp_sections,wgen_omp_parallel)||
02303 WGEN_bind_to_same(wgen_omp_master,wgen_omp_single,wgen_omp_parallel))
02304 {
02305 msg = "Master directives are not permitted in the dynamic extent \
02306 of for, sections,and single directives if the master directives bind to \
02307 the same parallel as the work-sharing directives.";
02308 chkflag=true;
02309 }
02310
02311 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
02312 return;
02313
02314
02315 }
02316
02317 void WGEN_expand_start_master ( )
02318 {
02319
02320
02321 WGEN_region(REGION_KIND_MP);
02322 WN *wn;
02323 wn = WN_CreatePragma(WN_PRAGMA_MASTER_BEGIN,
02324 (ST_IDX) NULL,
02325 0,
02326 0);
02327 WN_set_pragma_omp(wn);
02328 WGEN_Stmt_Append (wn, Get_Srcpos());
02330 SRCPOS srcpos = Get_Srcpos();
02331 WGEN_CS_push(wgen_omp_master,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02332
02333
02335 Set_PU_has_mp (Get_Current_PU ());
02336 Set_FILE_INFO_has_mp (File_info);
02337 Set_PU_uplevel (Get_Current_PU ());
02338
02339 WGEN_Stmt_Pop (wgen_stmk_region_pragmas);
02340 }
02341
02342 void WGEN_expand_end_master ()
02343 {
02344 WGEN_Stmt_Pop (wgen_stmk_scope);
02345 WGEN_CS_pop(wgen_omp_master);
02346 };
02347
02348 #if 0
02349
02351 void WGEN_check_critical(char* name)
02352 {
02353 bool chkflag=false;
02354 char * msg = NULL;
02355
02356
02357 if(WGEN_CS_Find_fgname(wgen_omp_critical, name)>-1)
02358 {
02359 msg = "Critical directives with the same name are not \
02360 allowed to be nested inside each other.";
02361 chkflag=true;
02362 }
02363 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
02364 return;
02365
02366 }
02367
02368 #endif
02369
02370 void WGEN_expand_start_critical (ST *region_phrase,char* critical_name)
02371 {
02372 WN *wn;
02373 TCON tcon;
02374
02375
02376 WN * pragma_wn = wn = WN_CreatePragma(WN_PRAGMA_CRITICAL_SECTION_BEGIN,
02377 region_phrase,
02378 0,
02379 0);
02380
02381 WN_set_pragma_omp(wn);
02382 WGEN_Stmt_Append (wn, Get_Srcpos());
02383 wn = WN_CreateBarrier( FALSE, 0 );
02384 WN_set_pragma_omp(wn);
02385 WGEN_Stmt_Append (wn, Get_Srcpos());
02386
02387
02388 WGEN_Stmt_Push (pragma_wn, wgen_stmk_dummy, Get_Srcpos());
02389
02391 SRCPOS srcpos = Get_Srcpos();
02392 WGEN_CS_push(wgen_omp_critical,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02393
02394
02395
02396
02397 #if 0
02398
02399 if (critical_name) WGEN_check_critical(critical_name);
02400 #endif
02401 WGEN_Set_Nameflag(critical_name);
02402
02404 Set_PU_has_mp (Get_Current_PU ());
02405 Set_FILE_INFO_has_mp (File_info);
02406 Set_PU_uplevel (Get_Current_PU ());
02407
02408 WN * body = WN_CreateBlock ();
02409 WGEN_Stmt_Push (body, wgen_stmk_scope, Get_Srcpos());
02410 }
02411
02412 void WGEN_expand_end_critical ( )
02413 {
02414 WN *wn;
02415 ST * st;
02416
02417 WN *wn1 = WGEN_Stmt_Top ();
02418 WGEN_Stmt_Pop (wgen_stmk_scope);
02419
02420 wn = WGEN_Stmt_Top ( );
02421 st = WN_st (wn);
02422
02423
02424 WGEN_Stmt_Pop ( wgen_stmk_dummy );
02425
02426 WGEN_Stmt_Append (wn1, Get_Srcpos());
02427
02428 wn = WN_CreateBarrier( TRUE, 0 );
02429 WN_set_pragma_omp(wn);
02430 WGEN_Stmt_Append (wn, Get_Srcpos());
02431 wn = WN_CreatePragma(WN_PRAGMA_CRITICAL_SECTION_END,
02432 st,
02433 0,
02434 0);
02435 WN_set_pragma_omp(wn);
02436 WGEN_Stmt_Append (wn, Get_Srcpos());
02437
02438 WGEN_CS_pop(wgen_omp_critical);
02439
02440 }
02441
02443
02444 void WGEN_expand_start_atomic ()
02445 {
02446 WN *wn;
02447 wn = WN_CreatePragma(WN_PRAGMA_ATOMIC,
02448 (ST_IDX) NULL,
02449 0,
02450 0);
02451 WN_set_pragma_omp(wn);
02452 WGEN_Stmt_Append (wn, Get_Srcpos());
02453
02454 WN * body = WN_CreateBlock ();
02455 WGEN_Stmt_Push (body, wgen_stmk_scope, Get_Srcpos());
02457 SRCPOS srcpos = Get_Srcpos();
02458 WGEN_CS_push(wgen_omp_atomic,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02459
02461 Set_PU_has_mp (Get_Current_PU ());
02462 Set_FILE_INFO_has_mp (File_info);
02463 Set_PU_uplevel (Get_Current_PU ());
02464 }
02465
02466
02467
02468 static BOOL Direct_Memory(WN *wn1)
02469 {
02470 OPERATOR oper = WN_operator(wn1);
02471 return oper == OPR_LDID || oper == OPR_STID;
02472 }
02473
02474
02475 static BOOL Equiv_Expression(WN *wn1, WN *wn2)
02476 {
02477 if (!WN_Equiv(wn1,wn2)) return FALSE;
02478 for (INT kidno=0; kidno<WN_kid_count(wn1); kidno++) {
02479 if (!Equiv_Expression(WN_kid(wn1,kidno),WN_kid(wn2,kidno))) {
02480 return FALSE;
02481 }
02482 }
02483 return TRUE;
02484 }
02485
02486
02487
02488 static BOOL Same_Location(WN *wn1, WN *wn2)
02489 {
02490 OPCODE opc1 = WN_opcode(wn1);
02491 OPCODE opc2 = WN_opcode(wn2);
02492 if (!OPCODE_is_load(opc1) && !OPCODE_is_store(opc1)) return FALSE;
02493 if (!OPCODE_is_load(opc2) && !OPCODE_is_store(opc2)) return FALSE;
02494 if (WN_offset(wn1) != WN_offset(wn2)) return FALSE;
02495 if (Direct_Memory(wn1)) {
02496 if (!Direct_Memory(wn2)) return FALSE;
02497 return WN_st(wn1) == WN_st(wn2);
02498 }
02499 if (Direct_Memory(wn2)) return FALSE;
02500 WN *addr_kid1, *addr_kid2;
02501 if (OPCODE_is_store(opc1)) {
02502 addr_kid1 = WN_kid1(wn1);
02503 } else {
02504 addr_kid1 = WN_kid0(wn1);
02505 }
02506 if (OPCODE_is_store(opc2)) {
02507 addr_kid2 = WN_kid1(wn2);
02508 } else {
02509 addr_kid2 = WN_kid0(wn2);
02510 }
02511 return Equiv_Expression(addr_kid1,addr_kid2);
02512 }
02513
02514
02515
02516
02517 static WN *Find_Same_Location(WN *loc,WN *wn, WN ** parent, int * kidnum)
02518 {
02519 if (Same_Location(loc,wn)) {
02520 return wn;
02521 } else {
02522
02523 if (WN_operator (wn) == OPR_BLOCK)
02524 return NULL;
02525 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
02526 WN *tmp;
02527 tmp = Find_Same_Location(loc,WN_kid(wn,kidno), parent, kidnum);
02528 if (tmp)
02529 {
02530 if (WN_kid (wn, kidno) == tmp)
02531 {
02532 *kidnum = kidno;
02533 *parent = wn;
02534 }
02535 return tmp;
02536 }
02537 }
02538 return NULL;
02539 }
02540 }
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556 static void format_rhs_atomic_stmt (WN * wn)
02557 {
02558 Is_True (WN_operator (wn) == OPR_BLOCK, ("Expected block"));
02559 Is_True (WN_first (wn) && (WN_first (wn) == WN_last (wn)),
02560 ("Expected 1 stmt in block"));
02561 WN * store = WN_first (wn);
02562 WN * op = WN_kid0 (store);
02563 if (Same_Location (store, WN_kid0 (op)) ||
02564 Same_Location (store, WN_kid1 (op)))
02565 return;
02566
02567 FmtAssert (WN_operator (op) == OPR_ADD || WN_operator (op) == OPR_SUB,
02568 ("Support other operations"));
02569
02570
02571 WN * parent;
02572 int kidno;
02573 WN * find = Find_Same_Location (store, op, &parent, &kidno);
02574 FmtAssert (find, ("Invalid atomic operation stmt"));
02575 Is_True (WN_kid (parent, kidno) == find, ("Operand mismatch"));
02576
02577 WN_kid (parent, kidno) = WN_Intconst (WN_rtype (find), 0);
02578 WN_kid0 (store) = WN_Add (WN_rtype (op), find, op);
02579 }
02580
02581 static WN * check_atomic (WN * block)
02582 {
02583 Is_True (WN_operator(block) == OPR_BLOCK, (""));
02584
02585 if (WN_first(block) == WN_last(block)) return NULL;
02586
02587 return WN_last(block);
02588 }
02589
02590 static void adjust_atomic (WN * stmt)
02591 {
02592 WN * top = WGEN_Stmt_Top();
02593
02594 Is_True (WN_operator(top) == OPR_BLOCK,
02595 ("adjust_atomic: expected BLOCK node"));
02596 Is_True (WN_last(top) == stmt,
02597 ("adjust_atomic: expected atomic operation to be last stmt in blk"));
02598 WN * prev = WN_prev(stmt);
02599
02600 while (prev && (WN_operator(prev) != OPR_PRAGMA ||
02601 WN_pragma(prev) != WN_PRAGMA_ATOMIC))
02602 prev = WN_prev(prev);
02603
02604 Is_True (prev, ("adjust_atomic: did not find ATOMIC pragma"));
02605
02606 prev = WN_EXTRACT_FromBlock (top, prev);
02607 WN_INSERT_BlockBefore (top, stmt, prev);
02608 }
02609
02610 void WGEN_expand_end_atomic ()
02611 {
02612 WN *wn = WGEN_Stmt_Top ();
02613 WN * ptr = check_atomic(wn);
02614 WGEN_Stmt_Pop (wgen_stmk_scope);
02615 #if 0
02616
02617 format_rhs_atomic_stmt (wn);
02618 #endif
02619 WGEN_Stmt_Append (wn, Get_Srcpos());
02620 if (ptr)
02621 adjust_atomic(ptr);
02622 WGEN_CS_pop(wgen_omp_atomic);
02623 }
02624
02625
02626 #if 0
02627
02629 void WGEN_check_ordered()
02630 {
02631
02632
02633
02634 bool chkflag=false;
02635 char * msg = NULL;
02636
02637 if ((WGEN_CS_Find (wgen_omp_for) >=0 &&
02638 WGEN_CS_Find_Cflag(wgen_omp_for,clause_ordered) < 0) ||
02639 (WGEN_CS_Find (wgen_omp_parallel_for) >= 0 &&
02640 WGEN_CS_Find_Cflag(wgen_omp_parallel_for,clause_ordered) < 0))
02641 {
02642 msg = "An ordered directive must not be in the dynamic extent \
02643 of a for directive that does not have the ordered clause specified.";
02644 chkflag=true;
02645 }
02646
02647
02648
02649 if( WGEN_CS_Find(wgen_omp_critical)>WGEN_CS_Find(wgen_omp_parallel)
02650 && WGEN_CS_Find(wgen_omp_parallel)>=0)
02651 {
02652 msg = "Ordered directives are not allowed in the dynamic extent of \
02653 critical regions if the directives bind to the same parallel as the regions.";
02654 chkflag=true;
02655 }
02656 WGEN_omp_error(WGEN_CS_top(), chkflag, msg);
02657 return;
02658
02659 }
02660
02661 #endif
02662
02663 void WGEN_expand_start_ordered (void)
02664 {
02665 WN *wn;
02666 wn = WN_CreatePragma(WN_PRAGMA_ORDERED_BEGIN,
02667 (ST_IDX) NULL,
02668 0,
02669 0);
02670 WN_set_pragma_omp(wn);
02671 WGEN_Stmt_Append (wn, Get_Srcpos());
02672 wn = WN_CreateBarrier( FALSE, 0 );
02673 WN_set_pragma_omp(wn);
02674 WGEN_Stmt_Append (wn, Get_Srcpos());
02675
02677 SRCPOS srcpos = Get_Srcpos();
02678 WGEN_CS_push(wgen_omp_ordered,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02679
02681 Set_PU_has_mp (Get_Current_PU ());
02682 Set_FILE_INFO_has_mp (File_info);
02683 Set_PU_uplevel (Get_Current_PU ());
02684 }
02685
02686 void WGEN_expand_end_ordered (void)
02687 {
02688 WN *wn;
02689 wn = WN_CreateBarrier( TRUE, 0 );
02690 WN_set_pragma_omp(wn);
02691 WGEN_Stmt_Append (wn, Get_Srcpos());
02692 wn = WN_CreatePragma(WN_PRAGMA_ORDERED_END, (ST_IDX) NULL,
02693 0,
02694 0);
02695 WN_set_pragma_omp(wn);
02696 WGEN_Stmt_Append (wn, Get_Srcpos());
02697
02698 WGEN_CS_pop(wgen_omp_ordered);
02699 }
02700
02701
02702 #if 0
02704
02705 void WGEN_check_barrier ( )
02706 {
02707
02708
02709
02710
02711
02712
02713
02714 bool chkflag=false;
02715 char * msg = NULL;
02716
02717 CHECK_STMT* cs = WGEN_CS_top ();
02718 SRCPOS srcpos = Get_Srcpos();
02719 WGEN_Set_LFnum(cs, SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02720
02721
02722 if(WGEN_is_top(wgen_cscf))
02723 {
02724 msg = "A barrier directive appeared as the immediate \
02725 subordinate of a C/C++ control statement if, switch, while, do, for.";
02726 chkflag=true;
02727 }
02728
02729 WN* wn1;
02730 wn1=WGEN_Stmt_Top();
02731 if(WN_operator(wn1)!=OPR_BLOCK)
02732 {
02733 msg = "The smallest statement that contains a barrier directive must be a block (or \
02734 compound-statement).";
02735 chkflag=true;
02736 }
02737
02738
02739
02740 if( WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_for,wgen_omp_parallel)||
02741 WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_ordered,wgen_omp_parallel)||
02742 WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_sections,wgen_omp_parallel)||
02743 WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_single,wgen_omp_parallel)||
02744 WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_master,wgen_omp_parallel)||
02745 WGEN_bind_to_same(wgen_omp_barrier,wgen_omp_critical,wgen_omp_parallel))
02746
02747 {
02748 msg = "Barrier directives are not permitted in the dynamic extent of for, ordered, \
02749 sections, single, master, and critical regions if the directives bind to the \
02750 same parallel as the regions.";
02751 chkflag=true;
02752 }
02753 WGEN_omp_error(cs, chkflag, msg);
02754 return;
02755
02756 };
02757
02758 #endif
02759
02760 void WGEN_expand_barrier ()
02761 {
02762 WN *wn;
02763 wn = WN_CreatePragma(WN_PRAGMA_BARRIER,
02764 (ST_IDX) NULL,
02765 0,
02766 0);
02767 WN_set_pragma_omp(wn);
02768 WGEN_Stmt_Append (wn, Get_Srcpos());
02770 SRCPOS srcpos = Get_Srcpos();
02771 WGEN_CS_push(wgen_omp_barrier,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02772
02773
02774
02776 Set_PU_has_mp (Get_Current_PU ());
02777 Set_FILE_INFO_has_mp (File_info);
02778 Set_PU_uplevel (Get_Current_PU ());
02779
02780 WGEN_CS_pop(wgen_omp_barrier);
02781 }
02782
02783
02784 #if 0
02786
02787 void WGEN_check_flush ( )
02788 {
02789
02790
02791
02792
02793
02794 bool chkflag=false;
02795 char * msg = NULL;
02796
02797 CHECK_STMT* cs = WGEN_CS_top ();
02798 SRCPOS srcpos = Get_Srcpos();
02799 WGEN_Set_LFnum(cs, SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02800
02801
02802 if(WGEN_is_top(wgen_cscf))
02803 {
02804 msg = "A barrier directive appeared as the immediate subordinate of a C/C++ control statement.";
02805 chkflag=true;
02806 }
02807
02808 WN* wn1;
02809 wn1=WGEN_Stmt_Top();
02810 if(WN_operator(wn1)!=OPR_BLOCK)
02811 {
02812 msg = "The smallest statement that contains a barrier directive must be a block (or \
02813 compound-statement).";
02814 chkflag=true;
02815 }
02816 WGEN_omp_error(cs, chkflag, msg);
02817
02818 }
02819
02820 void WGEN_expand_flush (WN_list *flush_variables)
02821 {
02822 WN * sync, * wn1, * wn2;
02823 WN * wn;
02824 ST * st;
02825 WN_list * wn_list;
02826 UINT num =0, i = 0 ;
02827
02828 sync = WN_Create_Intrinsic(OPC_VINTRINSIC_CALL,
02829 INTRN_SYNCHRONIZE,0,NULL);
02830
02831 for (wn_list = flush_variables; wn_list != NULL; wn_list = wn_list->next)
02832 num++;
02833
02834 wn1 = WN_CreateBarrier(TRUE, num);
02835 wn2 = WN_CreateBarrier(FALSE, num);
02836
02837 for (wn_list = flush_variables; wn_list != NULL; wn_list = wn_list->next)
02838 {
02839 wn = wn_list->wn;
02840 st = WN_st(wn);
02841 if (Barrier_Lvalues_On) {
02842 WN_kid(wn1,i) = wn;
02843 WN_kid(wn2,i) = wn;
02844 }
02845 else {
02846 WN_kid(wn1,i) = WN_CreateIdname(0,st);
02847 WN_kid(wn2,i) = WN_CreateIdname(0,st);
02848 }
02849 i++;
02850 }
02851
02852 WGEN_Stmt_Append (wn1, Get_Srcpos());
02853 WGEN_Stmt_Append (sync, Get_Srcpos());
02854 WGEN_Stmt_Append (wn2, Get_Srcpos());
02856 SRCPOS srcpos = Get_Srcpos();
02857 WGEN_CS_push(wgen_omp_flush,SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
02858 WGEN_check_flush();
02859 WGEN_CS_pop(wgen_omp_flush);
02860
02861 }
02862
02864 void WGEN_check_threadprivate(ST_list* threadprivate_variables)
02865 {
02866 bool chkflag=false;
02867
02868
02869 ST* st;
02870 ST_list *st_list;
02871 SYMTAB_IDX si1,si2;
02872
02873 si1=PU_lexical_level(Get_Current_PU());
02874
02875 st_list=threadprivate_variables;
02876 while(st_list!=NULL)
02877 {
02878 st=st_list->st;
02879 if(ST_is_thread_private(* st))
02880 {
02881 si2=ST_level(st);
02882 if(si1!=si2&&ST_storage_class(*st)==SCLASS_PSTATIC)
02883 {
02884 fprintf(stderr,"Warning: A threadprivate directive for static block-scope variables must appear in \
02885 the scope of the variable and not in a nested scope.\n");
02886 chkflag=true;
02887 }
02888 }
02889 st_list=st_list->next;
02890 }
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909 }
02910 #endif
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 static void
02925 WGEN_generate_non_pod_lastlocal_finalization (void)
02926 {
02927 const char * omp_non_pod_lastlocal_var_name = "__omp_non_pod_lastlocal";
02928 static ST * omp_non_pod_lastlocal_var_st = NULL;
02929
02930 if (!lang_cplus) return;
02931
02932 if (lastlocal_node_stack.empty()) return;
02933
02934 WN * then_block = WN_CreateBlock();
02935 WN * else_block = WN_CreateBlock();
02936
02937 if (!omp_non_pod_lastlocal_var_st)
02938 {
02939 omp_non_pod_lastlocal_var_st = New_ST(GLOBAL_SYMTAB);
02940 ST_Init (omp_non_pod_lastlocal_var_st,
02941 Save_Str(omp_non_pod_lastlocal_var_name),
02942 CLASS_VAR, SCLASS_EXTERN, EXPORT_PREEMPTIBLE,
02943 MTYPE_TO_TY_array[MTYPE_I4]);
02944 }
02945
02946 WN * test = WN_NE (MTYPE_I4,
02947 WN_Ldid (MTYPE_I4,
02948 0,
02949 omp_non_pod_lastlocal_var_st,
02950 ST_type(omp_non_pod_lastlocal_var_st)),
02951 WN_Intconst(MTYPE_I4, 0));
02952
02953
02954
02955 WN_INSERT_BlockLast (then_block, WN_CreateBarrier(FALSE, 0));
02956
02957 while (!lastlocal_node_stack.empty())
02958 {
02959 WN * lastlocal = lastlocal_node_stack.top();
02960 lastlocal_node_stack.pop();
02961 WN_INSERT_BlockLast (then_block, lastlocal);
02962 }
02963
02964 WN_INSERT_BlockLast (then_block, WN_CreateBarrier(TRUE, 0));
02965
02966 WN * if_stmt = WN_CreateIf (test, then_block, else_block);
02967
02968 WGEN_Stmt_Append (WN_CreateBarrier(TRUE, 0), Get_Srcpos());
02969 WGEN_Stmt_Append (if_stmt, Get_Srcpos());
02970 WGEN_Stmt_Append (WN_CreateBarrier(FALSE, 0), Get_Srcpos());
02971 }
02972
02974
02975 void WGEN_expand_start_do_loop(WN * index, WN * start, WN * end, WN * step)
02976 {
02977 WN *doloop;
02978
02979 WN * body = WN_CreateBlock ();
02980
02981 doloop = WN_CreateDO(index, start, end, step, body, NULL);
02982 WGEN_Stmt_Append (doloop, Get_Srcpos());
02983
02984 WGEN_Stmt_Push (doloop, wgen_stmk_for_cond, Get_Srcpos());
02985 WGEN_Stmt_Push (body, wgen_stmk_for_body, Get_Srcpos());
02986 }
02987
02988 void WGEN_expand_end_do_loop (void)
02989 {
02990 WGEN_generate_non_pod_lastlocal_finalization ();
02991
02992 WGEN_Stmt_Pop (wgen_stmk_for_body);
02993
02994 WGEN_Stmt_Pop (wgen_stmk_for_cond);
02995 }
02996