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 "wn_tree_util.h"
00039 #include "anl_common.h"
00040 #include "anl_diagnostics.h"
00041 #include "anl_file_mngr.h"
00042 #include "w2cf_translator.h"
00043 #include "anl_varlist.h"
00044 #include "anl_pragma_attribute.h"
00045 #include "anl_func_entry.h"
00046 #include "anl_loop_construct.h"
00047
00048 extern ANL_DIAGNOSTICS *Anl_Diag;
00049
00050
00051
00052
00053
00054 #define WN_current_loop_nest(wn) WN_pragma_arg1(wn)
00055 #define WN_max_loop_nest(wn) WN_pragma_arg2(wn)
00056
00057
00058
00059
00060
00061 BOOL
00062 ANL_LOOP_CONSTRUCT::Is_Valid_Dir(ANL_PRAGMA_ATTRIBUTE *dir,
00063 INT32 construct_level)
00064 {
00065 return dir->Is_Loop_Construct_Attribute(construct_level);
00066 }
00067
00068 BOOL
00069 ANL_LOOP_CONSTRUCT::Is_End_Of_Loop_Comment(WN *end_stmt)
00070 {
00071 return (WN_operator(end_stmt) == OPR_COMMENT &&
00072 strcmp(Index_To_Str(WN_GetComment(end_stmt)), "ENDLOOP") == 0);
00073 }
00074
00075 void
00076 ANL_LOOP_CONSTRUCT::Remove_Stmt_In_Block(WN *stmt)
00077 {
00078 WN *block = LWN_Get_Parent(stmt);
00079
00080 while (block != NULL && WN_operator(block) != OPR_BLOCK)
00081 block = LWN_Get_Parent(block);
00082
00083 if (WN_operator(block) == OPR_BLOCK)
00084 {
00085 WN_DELETE_FromBlock(block, stmt);
00086 }
00087 }
00088
00089
00090
00091
00092
00093 WN *
00094 ANL_LOOP_CONSTRUCT::_First_Loop_Stmt()
00095 {
00096 WN *base = (_Is_Parallel_Loop()? _loop_region : _loop);
00097 ANL_SRCPOS basepos(base);
00098
00099 while (WN_prev(base) != NULL && ANL_SRCPOS(WN_prev(base)) >= basepos)
00100 base = WN_prev(base);
00101 return base;
00102 }
00103
00104
00105 WN *
00106 ANL_LOOP_CONSTRUCT::_Last_Loop_Stmt()
00107 {
00108 WN *base = (_Is_Parallel_Loop()? _loop_region : _loop);
00109 ANL_SRCPOS basepos(base);
00110
00111 while (WN_next(base) != NULL && ANL_SRCPOS(WN_next(base)) <= basepos)
00112 base = WN_next(base);
00113 return base;
00114 }
00115
00116
00117 void
00118 ANL_LOOP_CONSTRUCT::_Loop_Srcpos_Range(ANL_SRCPOS *min, ANL_SRCPOS *max)
00119 {
00120
00121
00122
00123
00124 WN *end_stmt = NULL;
00125 WN *end_comment = NULL;
00126 WN *base = (_Is_Parallel_Loop()? _loop_region : _loop);
00127 WN *first_stmt = _First_Loop_Stmt();
00128 WN *last_stmt = _Last_Loop_Stmt();
00129 ANL_SRCPOS minpos(first_stmt);
00130 ANL_SRCPOS maxpos(last_stmt);
00131
00132
00133
00134
00135
00136 for (WN *stmt = first_stmt;
00137 stmt != NULL && WN_prev(stmt) != last_stmt;
00138 stmt = WN_next(stmt))
00139 {
00140 Adjust_Srcpos_Range(stmt, &minpos, &maxpos);
00141 }
00142
00143
00144
00145
00146
00147 if (_Is_Parallel_Loop())
00148 {
00149
00150
00151 for (end_stmt = WN_first(WN_region_pragmas(_loop_region));
00152 (end_stmt != NULL &&
00153 WN_pragma(end_stmt) != WN_PRAGMA_PDO_END &&
00154 WN_pragma(end_stmt) != WN_PRAGMA_END_MARKER &&
00155 (WN_pragma(end_stmt) != WN_PRAGMA_NOWAIT ||
00156 _func_entry->Pu_Translator()->Language_is_C()));
00157 end_stmt = WN_next(end_stmt));
00158 }
00159
00160
00161
00162
00163 if (_Is_Parallel_Loop())
00164 {
00165
00166
00167 for (end_comment = WN_first(WN_region_body(_loop_region));
00168 (end_comment != NULL && WN_operator(end_comment) != OPR_DO_LOOP);
00169 end_comment = WN_next(end_comment));
00170
00171
00172
00173
00174 if (end_comment != NULL)
00175 for (end_comment = WN_first(WN_do_body(end_comment));
00176 (end_comment != NULL && !Is_End_Of_Loop_Comment(end_comment));
00177 end_comment = WN_next(end_comment));
00178 }
00179 else
00180 {
00181 WN *const body = (_loop_kind == ANL_DO_LOOP?
00182 WN_do_body(_loop) : WN_while_body(_loop));
00183
00184
00185
00186
00187 for (end_comment = WN_first(body);
00188 (end_comment != NULL && !Is_End_Of_Loop_Comment(end_comment));
00189 end_comment = WN_next(end_comment));
00190 }
00191 if (end_comment != NULL)
00192 {
00193 if (end_stmt == NULL)
00194 end_stmt = end_comment;
00195 Remove_Stmt_In_Block(end_comment);
00196 }
00197
00198
00199
00200
00201 if (end_stmt == NULL && WN_next(last_stmt) != NULL)
00202 {
00203
00204
00205 ANL_SRCPOS next_min(WN_next(last_stmt));
00206 ANL_SRCPOS next_max(WN_next(last_stmt));
00207
00208 Adjust_Srcpos_Range(WN_next(last_stmt), &next_min, &next_max);
00209 if (next_min > maxpos)
00210 {
00211 next_min -= 1;
00212 maxpos = next_min;
00213 }
00214 }
00215
00216 Is_True(end_stmt == NULL || maxpos == ANL_SRCPOS(end_stmt),
00217 ("Unexpected maxpos (maxpos=[%d,%d,%d],end_stmt_pos=[%d,%d,%d]) in "
00218 "ANL_LOOP_CONSTRUCT::_Loop_Srcpos_Range",
00219 maxpos.Filenum(), maxpos.Linenum(), maxpos.Column(),
00220 ANL_SRCPOS(end_stmt).Filenum(),
00221 ANL_SRCPOS(end_stmt).Linenum(),
00222 ANL_SRCPOS(end_stmt).Column()));
00223
00224 *min = minpos;
00225 *max = maxpos;
00226 }
00227
00228
00229 void
00230 ANL_LOOP_CONSTRUCT::_Write_Loop_Header(ANL_CBUF *cbuf)
00231 {
00232 ANL_SRCPOS min_srcpos;
00233 ANL_SRCPOS max_srcpos;
00234
00235 _Loop_Srcpos_Range(&min_srcpos, &max_srcpos);
00236 switch (_loop_kind)
00237 {
00238 case ANL_WHILE_LOOP:
00239 cbuf->Write_String("owhile ");
00240 cbuf->Write_Int(_id);
00241 if (_func_entry->Pu_Translator()->Language_is_C())
00242 cbuf->Write_String(" \"while ");
00243 else
00244 cbuf->Write_String(" \"do while ");
00245 _func_entry->Pu_Translator()->Expr_To_String(cbuf, WN_while_test(_loop));
00246 break;
00247
00248 case ANL_WHILE_AS_DO_LOOP:
00249 cbuf->Write_String("oloop ");
00250 cbuf->Write_Int(_id);
00251 if (_func_entry->Pu_Translator()->Language_is_C())
00252 cbuf->Write_String(" \"for ");
00253 else
00254 cbuf->Write_String(" \"do ");
00255 _func_entry->Pu_Translator()->
00256 Original_Symname_To_String(cbuf, WN_st(WN_prev(_loop)));
00257 break;
00258
00259 case ANL_DO_LOOP:
00260 case ANL_DOACROSS_LOOP:
00261 case ANL_PARALLELDO_LOOP:
00262 case ANL_PDO_LOOP:
00263 cbuf->Write_String("oloop ");
00264 cbuf->Write_Int(_id);
00265 if (_func_entry->Pu_Translator()->Language_is_C())
00266 cbuf->Write_String(" \"for ");
00267 else
00268 cbuf->Write_String(" \"do ");
00269 _func_entry->Pu_Translator()->
00270 Original_Symname_To_String(cbuf, WN_st(WN_index(_loop)));
00271 break;
00272
00273 default:
00274 break;
00275 }
00276 cbuf->Write_String("\" range ");
00277 min_srcpos.Write(cbuf);
00278 cbuf->Write_Char('-');
00279 max_srcpos.Write(cbuf);
00280 cbuf->Write_Char('\n');
00281 }
00282
00283
00284 void
00285 ANL_LOOP_CONSTRUCT::_Write_Loop_Directive(ANL_CBUF *cbuf)
00286 {
00287 BOOL omp_pragma;
00288 WN *nowait = NULL;
00289 WN *end_pdo = NULL;
00290 WN *region_pragma = WN_first(WN_region_pragmas(_loop_region));
00291 WN *next_clause = WN_next(region_pragma);
00292 ANL_SRCPOS startpos;
00293 ANL_SRCPOS endpos;
00294
00295
00296
00297 _func_entry->Get_Pragma_Srcpos_Range(region_pragma, &startpos, &endpos);
00298
00299
00300
00301 cbuf->Write_String("idir ");
00302 cbuf->Write_Int(_id);
00303 cbuf->Write_Char(' ');
00304 startpos.Write(cbuf);
00305 cbuf->Write_Char('-');
00306 endpos.Write(cbuf);
00307
00308 omp_pragma = WN_pragma_omp(region_pragma);
00309 cbuf->Append_Pragma_Preamble(omp_pragma,FALSE);
00310
00311 switch (_loop_kind)
00312 {
00313 case ANL_DOACROSS_LOOP:
00314 cbuf->Write_String("DOACROSS ");
00315 break;
00316 case ANL_PARALLELDO_LOOP:
00317 cbuf->Write_String("PARALLEL DO ");
00318 break;
00319 case ANL_PDO_LOOP:
00320 if (omp_pragma)
00321 cbuf->Write_String("DO ");
00322 else if (_func_entry->Pu_Translator()->Language_is_C())
00323 cbuf->Write_String("PFOR ");
00324 else
00325 cbuf->Write_String("PDO ");
00326 break;
00327 default:
00328 cbuf->Write_String("<WHATLOOP??> ");
00329 break;
00330 }
00331
00332
00333
00334 if (WN_max_loop_nest(region_pragma) > 1)
00335 {
00336 _func_entry->Pu_Translator()->
00337 Nest_Clauses_To_String(cbuf,
00338 _loop_region,
00339 WN_max_loop_nest(region_pragma));
00340 if ( _func_entry->Pu_Translator()->Is_A_Pragma_Clause(next_clause))
00341 cbuf->Write_String(", ");
00342 }
00343
00344
00345
00346 _func_entry->Pu_Translator()->ClauseList_To_String(cbuf, &next_clause);
00347 cbuf->Write_String("\n");
00348
00349
00350
00351 if (next_clause != NULL &&
00352 !_func_entry->Pu_Translator()->Language_is_C())
00353 {
00354
00355
00356
00357 if (WN_pragma(next_clause) == WN_PRAGMA_PDO_END &&
00358 !WN_pragma_compiler_generated(next_clause))
00359 end_pdo = next_clause;
00360 else if (WN_pragma(next_clause) == WN_PRAGMA_NOWAIT &&
00361 !WN_pragma_compiler_generated(next_clause))
00362 nowait = next_clause;
00363 }
00364 if (nowait != NULL || end_pdo != NULL)
00365 {
00366 if (end_pdo != NULL)
00367 startpos = ANL_SRCPOS(end_pdo);
00368 else
00369 startpos = ANL_SRCPOS(nowait);
00370 cbuf->Write_String("edir ");
00371 cbuf->Write_Int(_id);
00372 cbuf->Write_String(" ");
00373 startpos.Write(cbuf);
00374
00375 cbuf->Append_Pragma_Preamble(omp_pragma,FALSE);
00376 if (WN_pragma_omp(next_clause))
00377 cbuf->Write_String("END DO");
00378 else
00379 cbuf->Write_String("END PDO");
00380 if (nowait)
00381 cbuf->Write_String(" nowait\n");
00382 else
00383 cbuf->Write_Char('\n');
00384 }
00385 }
00386
00387
00388
00389
00390
00391
00392 ANL_LOOP_CONSTRUCT::ANL_LOOP_CONSTRUCT(WN *loop,
00393 INT32 construct_level,
00394 ANL_FUNC_ENTRY *func_entry,
00395 MEM_POOL *pool):
00396 _loop_region(NULL),
00397 _loop(loop),
00398 _construct_level(construct_level),
00399 _func_entry(func_entry),
00400 _pool(pool)
00401 {
00402 WN *parent_region = NULL;
00403 BOOL in_region = FALSE;
00404
00405
00406
00407
00408 if (WN_operator(loop) == OPR_WHILE_DO ||
00409 WN_operator(loop) == OPR_DO_WHILE)
00410 {
00411 if (_func_entry->Pu_Translator()->Whileloop_Looks_Like_Forloop(loop))
00412 _loop_kind = ANL_WHILE_AS_DO_LOOP;
00413 else
00414 _loop_kind = ANL_WHILE_LOOP;
00415 }
00416 else
00417 {
00418 _loop_kind = ANL_DO_LOOP;
00419 parent_region = LWN_Get_Parent(LWN_Get_Parent(loop));
00420 in_region = (WN_operator(parent_region) == OPR_REGION);
00421 }
00422
00423
00424
00425 _id = _func_entry->Next_Construct_Id()->Post_Incr();
00426 func_entry->Set_Construct_Id(loop, _id);
00427
00428
00429
00430 if (in_region)
00431 {
00432 WN *pragma = WN_first(WN_region_pragmas(parent_region));
00433
00434 if (pragma != NULL)
00435 {
00436 if (WN_pragma(pragma) == WN_PRAGMA_DOACROSS &&
00437 WN_current_loop_nest(pragma) == 0)
00438 {
00439 _loop_kind = ANL_DOACROSS_LOOP;
00440 _loop_region = parent_region;
00441 func_entry->Set_Construct_Id(parent_region, _id);
00442 }
00443 else if (WN_pragma(pragma) == WN_PRAGMA_PARALLEL_DO &&
00444 WN_current_loop_nest(pragma) == 0)
00445 {
00446 _loop_kind = ANL_PARALLELDO_LOOP;
00447 _loop_region = parent_region;
00448 func_entry->Set_Construct_Id(parent_region, _id);
00449 }
00450 else if (WN_pragma(pragma) == WN_PRAGMA_PDO_BEGIN &&
00451 WN_current_loop_nest(pragma) == 0)
00452 {
00453 _loop_kind = ANL_PDO_LOOP;
00454 _loop_region = parent_region;
00455 func_entry->Set_Construct_Id(parent_region, _id);
00456 }
00457 }
00458 }
00459 }
00460
00461
00462 WN *
00463 ANL_LOOP_CONSTRUCT::Next_Stmt()
00464 {
00465
00466
00467
00468 return WN_next(_loop);
00469 }
00470
00471
00472 void
00473 ANL_LOOP_CONSTRUCT::Write(ANL_CBUF *cbuf)
00474 {
00475 ANL_CBUF varlist_cbuf(_pool);
00476 ANL_CBUF nested_cbuf(_pool);
00477 ANL_SRCPOS min_srcpos;
00478 ANL_SRCPOS max_srcpos;
00479 ANL_VARLIST varlist(_pool, _func_entry);
00480 WN *first_stmt = _First_Loop_Stmt();
00481 WN *last_stmt = _Last_Loop_Stmt();
00482 WN *body = ((_loop_kind == ANL_WHILE_AS_DO_LOOP ||
00483 _loop_kind == ANL_WHILE_LOOP)?
00484 WN_while_body(_loop) :
00485 WN_do_body(_loop));
00486
00487
00488
00489 _Write_Loop_Header(cbuf);
00490
00491
00492
00493 if (_loop_kind != ANL_WHILE_LOOP)
00494 {
00495 ST *const st = (_loop_kind == ANL_WHILE_AS_DO_LOOP?
00496 WN_st(WN_prev(_loop)) : WN_st(WN_index(_loop)));
00497
00498 cbuf->Write_String("index \"");
00499 _func_entry->Pu_Translator()-> Original_Symname_To_String(cbuf, st);
00500 cbuf->Write_String("\"\n");
00501 }
00502
00503
00504
00505 if (_loop_kind == ANL_DOACROSS_LOOP ||
00506 _loop_kind == ANL_PARALLELDO_LOOP ||
00507 _loop_kind == ANL_PDO_LOOP)
00508 {
00509 _Write_Loop_Directive(cbuf);
00510 }
00511
00512
00513
00514
00515 for (WN *stmt = first_stmt;
00516 stmt != NULL && WN_prev(stmt) != last_stmt;
00517 stmt = WN_next(stmt))
00518 {
00519 varlist.Insert_Var_Refs(stmt);
00520 }
00521 varlist.Write(&varlist_cbuf, _id);
00522 varlist_cbuf.Write_Char('\n');
00523
00524
00525
00526 _func_entry->Emit_Nested_Original_Constructs(&nested_cbuf,
00527 WN_first(body), WN_last(body));
00528
00529
00530
00531
00532 _func_entry->
00533 Emit_Dir_Entries(cbuf, _id, _construct_level,
00534 &ANL_LOOP_CONSTRUCT::Is_Valid_Dir);
00535
00536
00537
00538 if (varlist_cbuf.Size() > 0)
00539 cbuf->Write_String(varlist_cbuf.Chars());
00540 if (nested_cbuf.Size() > 0)
00541 cbuf->Write_String(nested_cbuf.Chars());
00542
00543
00544
00545 if (_loop_kind == ANL_WHILE_LOOP)
00546 cbuf->Write_String("end_owhile ");
00547 else
00548 cbuf->Write_String("end_oloop ");
00549 cbuf->Write_Int(_id);
00550 cbuf->Write_String("\n");
00551 }