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