Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "anl_common.h"
00039 #include "anl_diagnostics.h"
00040 #include "anl_file_mngr.h"
00041 #include "w2cf_translator.h"
00042 #include "anl_varlist.h"
00043 #include "anl_pragma_attribute.h"
00044 #include "anl_func_entry.h"
00045 #include "anl_region_construct.h"
00046
00047 extern ANL_DIAGNOSTICS *Anl_Diag;
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 BOOL
00060 ANL_REGION_CONSTRUCT::Is_ProMpf_Region_Construct(WN *stmt)
00061 {
00062 BOOL predicate = (stmt != NULL && WN_operator(stmt) == OPR_REGION);
00063
00064 if (predicate)
00065 {
00066 WN *pragma = WN_first(WN_region_pragmas(stmt));
00067 predicate = pragma != NULL ;
00068
00069 if (predicate)
00070 {
00071 switch (WN_pragma(pragma))
00072 {
00073 case WN_PRAGMA_PARALLEL_BEGIN:
00074 case WN_PRAGMA_MASTER_BEGIN:
00075 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
00076 case WN_PRAGMA_PSECTION_BEGIN:
00077 case WN_PRAGMA_PARALLEL_SECTIONS:
00078 break;
00079
00080 default:
00081 predicate = FALSE;
00082 break ;
00083 }
00084 }
00085 }
00086 return predicate;
00087 }
00088
00089
00090 BOOL
00091 ANL_REGION_CONSTRUCT::Is_Valid_Dir(ANL_PRAGMA_ATTRIBUTE *dir,
00092 INT32 construct_level)
00093 {
00094 return dir->Is_Region_Construct_Attribute(construct_level);
00095 }
00096
00097
00098
00099
00100
00101 WN *
00102 ANL_REGION_CONSTRUCT::_First_Region_Stmt()
00103 {
00104 WN *base = _region;
00105 ANL_SRCPOS basepos(_region);
00106
00107 while (WN_prev(base) != NULL && ANL_SRCPOS(WN_prev(base)) >= basepos)
00108 base = WN_prev(base);
00109 return base;
00110 }
00111
00112
00113 WN *
00114 ANL_REGION_CONSTRUCT::_Last_Region_Stmt()
00115 {
00116 WN *base = _region;
00117 ANL_SRCPOS basepos(_region);
00118
00119 while (WN_next(base) != NULL && ANL_SRCPOS(WN_next(base)) <= basepos)
00120 base = WN_next(base);
00121 return base;
00122 }
00123
00124
00125 void
00126 ANL_REGION_CONSTRUCT::_Region_Srcpos_Range(ANL_SRCPOS *min, ANL_SRCPOS *max)
00127 {
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 WN *end_stmt = NULL;
00139 WN *first_stmt = _First_Region_Stmt();
00140 WN *last_stmt = _Last_Region_Stmt();
00141 ANL_SRCPOS minpos(first_stmt);
00142 ANL_SRCPOS maxpos(last_stmt);
00143
00144
00145
00146
00147
00148 for (WN *stmt = first_stmt;
00149 stmt != NULL && WN_prev(stmt) != last_stmt;
00150 stmt = WN_next(stmt))
00151 {
00152 Adjust_Srcpos_Range(stmt, &minpos, &maxpos);
00153 }
00154
00155
00156
00157 for (end_stmt = WN_first(WN_region_pragmas(_region));
00158 (end_stmt != NULL &&
00159 WN_pragma(end_stmt) != WN_PRAGMA_PARALLEL_END &&
00160 WN_pragma(end_stmt) != WN_PRAGMA_END_MARKER &&
00161 (WN_pragma(end_stmt) != WN_PRAGMA_NOWAIT ||
00162 _func_entry->Pu_Translator()->Language_is_C()));
00163 end_stmt = WN_next(end_stmt));
00164
00165
00166
00167
00168 if (end_stmt == NULL && WN_next(last_stmt) != NULL)
00169 {
00170
00171
00172 ANL_SRCPOS next_min(WN_next(last_stmt));
00173 ANL_SRCPOS next_max(WN_next(last_stmt));
00174
00175 Adjust_Srcpos_Range(WN_next(last_stmt), &next_min, &next_max);
00176 if (next_min > maxpos)
00177 {
00178 next_min -= 1;
00179 maxpos = next_min;
00180 }
00181 }
00182 Is_True(end_stmt == NULL || maxpos == ANL_SRCPOS(end_stmt),
00183 ("Unexpected maxpos in "
00184 "ANL_LOOP_CONSTRUCT::_Loop_Srcpos_Range"));
00185
00186 *min = minpos;
00187 *max = maxpos;
00188 }
00189
00190
00191 WN *
00192 ANL_REGION_CONSTRUCT::_userEndParallel()
00193 {
00194 WN *directive;
00195 WN *end_directive = NULL;
00196
00197 if (!_func_entry->Pu_Translator()->Language_is_C())
00198 {
00199 for (directive = WN_first(WN_region_pragmas(_region));
00200 end_directive == NULL && directive != NULL;
00201 directive = WN_next(directive))
00202 {
00203 if (WN_pragma(directive) == WN_PRAGMA_PARALLEL_END &&
00204 !WN_pragma_compiler_generated(directive))
00205 end_directive = directive;
00206 else if (WN_pragma(directive) == WN_PRAGMA_NOWAIT)
00207 end_directive = directive;
00208 else if (WN_pragma(directive) == WN_PRAGMA_END_MARKER)
00209 end_directive = directive;
00210 }
00211 }
00212 return end_directive;
00213
00214 }
00215
00216
00217 void
00218 ANL_REGION_CONSTRUCT::_Write_Region_Directive(ANL_CBUF *cbuf)
00219 {
00220 WN *region_end_pragma = _userEndParallel();
00221 WN *region_pragma = WN_first(WN_region_pragmas(_region));
00222 WN *region_clause = WN_next(region_pragma);
00223 ANL_SRCPOS startpos, endpos;
00224 char *p;
00225
00226 _func_entry->Get_Pragma_Srcpos_Range(region_pragma, &startpos, &endpos);
00227
00228
00229
00230 cbuf->Write_String("idir ");
00231 cbuf->Write_Int(_id);
00232 cbuf->Write_Char(' ');
00233 startpos.Write(cbuf);
00234 cbuf->Write_Char('-');
00235 endpos.Write(cbuf);
00236
00237 cbuf->Append_Pragma_Preamble(_is_omp,FALSE);
00238
00239 switch (_region_kind)
00240 {
00241 case ANL_PARALLEL_REGION:
00242 cbuf->Write_String("PARALLEL ");
00243 break;
00244 case ANL_PSECTION_REGION:
00245 if(_is_omp)
00246 p = "SECTIONS ";
00247 else
00248 p = "PSECTIONS ";
00249 cbuf->Write_String(p);
00250 break;
00251 case ANL_SINGLE_PROCESS_REGION:
00252 if (_is_omp)
00253 p = "SINGLE ";
00254 else
00255 p = "SINGLE PROCESS " ;
00256 cbuf->Write_String(p);
00257 break;
00258 case ANL_MASTER_PROCESS_REGION:
00259 cbuf->Write_String("MASTER");
00260 break;
00261 default:
00262 cbuf->Write_String("<WHATREGION??> ");
00263 break;
00264 }
00265
00266
00267
00268 _func_entry->Pu_Translator()->ClauseList_To_String(cbuf, ®ion_clause);
00269 cbuf->Write_String("\n");
00270
00271 if (region_end_pragma)
00272 {
00273
00274
00275 _func_entry->Get_Pragma_Srcpos_Range(region_end_pragma,
00276 &startpos, &endpos);
00277 cbuf->Write_String("edir ");
00278 cbuf->Write_Int(_id);
00279 cbuf->Write_String(" ");
00280 startpos = ANL_SRCPOS(region_end_pragma);
00281 startpos.Write(cbuf);
00282
00283 cbuf->Append_Pragma_Preamble(_is_omp,FALSE);
00284
00285 switch(_region_kind)
00286 {
00287 case ANL_PSECTION_REGION:
00288 if(_is_omp)
00289 p = "END SECTIONS";
00290 else
00291 p = "END PSECTIONS";
00292 cbuf->Write_String(p);
00293 break ;
00294
00295 case ANL_SINGLE_PROCESS_REGION:
00296 if(_is_omp)
00297 p = "END SINGLE";
00298 else
00299 p = "END SINGLE PROCESS";
00300
00301 cbuf->Write_String(p);
00302 break;
00303
00304 case ANL_MASTER_PROCESS_REGION:
00305 cbuf->Write_String("END MASTER");
00306 break;
00307
00308 case ANL_PARALLEL_REGION:
00309 cbuf->Write_String("END PARALLEL");
00310 break;
00311
00312 default:
00313 cbuf->Write_String("<WHAT END PRAGMA>");
00314 break;
00315 }
00316
00317
00318 if (_is_omp &&
00319 WN_pragma(region_end_pragma) == WN_PRAGMA_NOWAIT)
00320 {
00321 cbuf->Write_String(" NOWAIT ");
00322 _is_nowait = TRUE;
00323 }
00324
00325 cbuf->Write_Char('\n');
00326 }
00327 }
00328
00329
00330
00331
00332
00333 ANL_REGION_CONSTRUCT::ANL_REGION_CONSTRUCT(WN *region,
00334 INT32 construct_level,
00335 ANL_FUNC_ENTRY *func_entry,
00336 MEM_POOL *pool):
00337 _region(region),
00338 _construct_level(construct_level),
00339 _func_entry(func_entry),
00340 _pool(pool)
00341 {
00342 WN * pragma;
00343
00344 _region_kind = ANL_UNKNOWN_REGION;
00345 _id = -1;
00346 _is_nowait = FALSE ;
00347 _is_omp = FALSE ;
00348
00349
00350
00351
00352
00353
00354
00355 if (Is_ProMpf_Region_Construct(region))
00356 {
00357 pragma = WN_first(WN_region_pragmas(region));
00358 _is_omp = WN_pragma_omp(pragma);
00359 _id = _func_entry->Next_Construct_Id()->Post_Incr();
00360
00361 func_entry->Set_Construct_Id(region, _id);
00362 func_entry->Set_Construct_Id(pragma, _id);
00363
00364 switch(WN_pragma(pragma))
00365 {
00366 case WN_PRAGMA_PARALLEL_BEGIN:
00367 _region_kind = ANL_PARALLEL_REGION;
00368 break;
00369
00370 case WN_PRAGMA_PARALLEL_SECTIONS:
00371 case WN_PRAGMA_PSECTION_BEGIN:
00372 _region_kind = ANL_PSECTION_REGION;
00373 break;
00374
00375 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
00376 _region_kind = ANL_SINGLE_PROCESS_REGION;
00377 break;
00378
00379 case WN_PRAGMA_MASTER_BEGIN:
00380 _region_kind = ANL_MASTER_PROCESS_REGION;
00381 break;
00382 }
00383 }
00384 }
00385
00386
00387 WN *
00388 ANL_REGION_CONSTRUCT::Next_Stmt()
00389 {
00390 WN *last_stmt = _Last_Region_Stmt();
00391 return WN_next(last_stmt);
00392 }
00393
00394
00395 void
00396 ANL_REGION_CONSTRUCT::Write(ANL_CBUF *cbuf)
00397 {
00398 if (_region_kind != ANL_UNKNOWN_REGION)
00399 {
00400 ANL_CBUF varlist_cbuf(_pool);
00401 ANL_CBUF nested_cbuf(_pool);
00402 ANL_SRCPOS min_srcpos;
00403 ANL_SRCPOS max_srcpos;
00404 ANL_VARLIST varlist(_pool, _func_entry);
00405 WN *first_stmt = _First_Region_Stmt();
00406 WN *last_stmt = _Last_Region_Stmt();
00407 char *p;
00408
00409
00410
00411 _Region_Srcpos_Range(&min_srcpos, &max_srcpos);
00412
00413 cbuf->Append_Pragma_Preamble(_is_omp,TRUE);
00414 switch (_region_kind)
00415 {
00416 case ANL_PARALLEL_REGION:
00417 cbuf->Write_String("pregion ");
00418 cbuf->Write_Int(_id);
00419 cbuf->Write_String(" \"parallel region\"");
00420 break;
00421
00422 case ANL_PSECTION_REGION:
00423 cbuf->Write_String("psections ");
00424 cbuf->Write_Int(_id);
00425 cbuf->Write_String(" \"parallel sections\"");
00426 break;
00427
00428 case ANL_SINGLE_PROCESS_REGION:
00429 if (_is_omp)
00430 p = "single ";
00431 else
00432 p = "single_proc ";
00433 cbuf->Write_String(p);
00434 cbuf->Write_Int(_id);
00435 cbuf->Write_String(" \"single processor section\"");
00436 break;
00437
00438 case ANL_MASTER_PROCESS_REGION:
00439 cbuf->Write_String("master ");
00440 cbuf->Write_Int(_id);
00441 cbuf->Write_String(" \"master processor section\"");
00442 break;
00443
00444 default:
00445 cbuf->Write_String(" <WHATREGION??>");
00446 break;
00447 }
00448 cbuf->Write_String(" range ");
00449 min_srcpos.Write(cbuf);
00450 cbuf->Write_Char('-');
00451 max_srcpos.Write(cbuf);
00452 cbuf->Write_Char('\n');
00453
00454
00455
00456 _Write_Region_Directive(cbuf);
00457
00458
00459
00460
00461 for (WN *stmt = first_stmt;
00462 stmt != NULL && WN_prev(stmt) != last_stmt;
00463 stmt = WN_next(stmt))
00464 {
00465 varlist.Insert_Var_Refs(stmt);
00466 }
00467 varlist.Write(&varlist_cbuf, _id);
00468 varlist_cbuf.Write_Char('\n');
00469
00470
00471
00472 _func_entry->
00473 Emit_Nested_Original_Constructs(&nested_cbuf,
00474 WN_first(WN_region_body(_region)),
00475 WN_last(WN_region_body(_region)));
00476
00477
00478
00479
00480 _func_entry->
00481 Emit_Dir_Entries(cbuf, _id, _construct_level,
00482 &ANL_REGION_CONSTRUCT::Is_Valid_Dir);
00483
00484
00485
00486 if (varlist_cbuf.Size() > 0)
00487 cbuf->Write_String(varlist_cbuf.Chars());
00488 if (nested_cbuf.Size() > 0)
00489 cbuf->Write_String(nested_cbuf.Chars());
00490
00491
00492
00493
00494 cbuf->Append_Pragma_Preamble(_is_omp,TRUE);
00495 switch (_region_kind)
00496 {
00497 case ANL_PARALLEL_REGION:
00498 cbuf->Write_String("end_pregion ");
00499 break;
00500
00501 case ANL_PSECTION_REGION:
00502 cbuf->Write_String("end_psections ");
00503 break ;
00504
00505 case ANL_SINGLE_PROCESS_REGION:
00506 if (_is_omp)
00507 p = "end_single ";
00508 else
00509 p = "end_single_proc ";
00510 cbuf->Write_String(p);
00511 break ;
00512
00513 case ANL_MASTER_PROCESS_REGION:
00514 cbuf->Write_String("end_master ");
00515 break;
00516
00517 default:
00518 cbuf->Write_String("<what_end??> ");
00519 }
00520
00521 if (_is_nowait)
00522 cbuf->Write_String("nowait ");
00523
00524 cbuf->Write_Int(_id);
00525 cbuf->Write_String("\n");
00526 }
00527 }