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