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 #ifdef USE_PCH
00037 #include "lno_pch.h"
00038 #endif // USE_PCH
00039 #pragma hdrstop
00040
00041 #include <sys/types.h>
00042 #include <alloca.h>
00043 #include "pu_info.h"
00044 #include "lwn_util.h"
00045 #include "lnoutils.h"
00046 #include "ara.h"
00047 #include "ara_loop.h"
00048 #include "prompf.h"
00049 #include "anl_driver.h"
00050 #include "lego_util.h"
00051 #include "config.h"
00052 #include "fiz_fuse.h"
00053 #include "debug.h"
00054 #include "glob.h"
00055
00056 #if ! defined(BUILD_OS_DARWIN)
00057 #pragma weak Anl_File_Path
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066 static void Print_Goto_Lines(WN* wn_loop,
00067 FILE *fp,
00068 MEM_POOL* pool)
00069 {
00070 PROMPF_LINES* pl = CXX_NEW(PROMPF_LINES(NULL, pool), pool);
00071 LWN_ITER* itr = LWN_WALK_TreeIter(wn_loop);
00072 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
00073 WN* wn = itr->wn;
00074 OPCODE op = WN_opcode(wn);
00075 if (OPCODE_is_non_scf(op) || op == OPC_DO_WHILE || op == OPC_WHILE_DO
00076 || op == OPC_COMPGOTO) {
00077 WN* wnn = 0;
00078 for (wnn = wn; wnn != NULL; wnn = LWN_Get_Parent(wnn))
00079 if (OPCODE_has_next_prev(WN_opcode(wnn)) && WN_linenum(wnn) != 0)
00080 break;
00081 if (wnn != NULL)
00082 pl->Add_Line(WN_linenum(wnn));
00083 }
00084 }
00085 pl->Print_Compact(fp, FALSE);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 extern void Print_Prompf_Transaction_Log(BOOL after)
00095 {
00096 if (Get_Trace(TP_LNOPT2, TT_LNO_DEBUG_PROMPF))
00097 Prompf_Info->Print(stdout);
00098 const char *path = Anl_File_Path();
00099 FILE *fp_anl = fopen(path, "a");
00100 if (fp_anl == NULL) {
00101 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
00102 exit(1);
00103 }
00104 Prompf_Info->Print_Compact(fp_anl, after ? PTL_POSTLNO : PTL_PRELNO);
00105 fclose(fp_anl);
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115 static BOOL Has_Io(WN* wn_tree, STACK<WN*>* stk_io)
00116 {
00117 BOOL found_io = FALSE;
00118
00119 if (WN_opcode(wn_tree) == OPC_IO) {
00120 stk_io->Push(wn_tree);
00121 found_io = TRUE;
00122 }
00123
00124 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00125 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00126 if (Has_Io(wn, stk_io))
00127 found_io = TRUE;
00128 } else {
00129 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00130 if (Has_Io(WN_kid(wn_tree, i), stk_io))
00131 found_io = TRUE;
00132 }
00133 return found_io;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 static WN* First_Wn_With_Symbol(WN* wn_base)
00143 {
00144 if (OPCODE_has_sym(WN_opcode(wn_base)))
00145 return wn_base;
00146 for (INT i = 0; i < WN_kid_count(wn_base); i++) {
00147 WN* wn_kid_base = First_Wn_With_Symbol(WN_kid(wn_base, i));
00148 if (wn_kid_base != NULL)
00149 return wn_kid_base;
00150 }
00151 return NULL;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 extern WN* WN_Array_Symbol(WN* wn_ref)
00161 {
00162 OPERATOR opr = WN_operator(wn_ref);
00163 if (opr == OPR_LDID || opr == OPR_STID)
00164 return wn_ref;
00165 if (opr == OPR_ISTORE || opr == OPR_ILOAD) {
00166 WN* wn_array = (WN_operator(wn_ref) == OPR_ISTORE) ?
00167 WN_kid1(wn_ref) : WN_kid0(wn_ref);
00168 if (WN_operator(wn_array) == OPR_PARM)
00169 wn_array = WN_kid0(wn_array);
00170 if (WN_operator(wn_array) == OPR_ARRAY) {
00171 WN* wn_base = WN_array_base(wn_array);
00172 return First_Wn_With_Symbol(wn_base);
00173 } else {
00174 return First_Wn_With_Symbol(wn_array);
00175 }
00176 } else {
00177 return First_Wn_With_Symbol(wn_ref);
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 static INT Mp_Lower_Number(WN* wn_loop)
00194 {
00195 INT multiplier = 0;
00196 for (WN* wn = wn_loop; wn != NULL; wn = LWN_Get_Parent(wn)) {
00197 if (WN_opcode(wn) != OPC_REGION)
00198 continue;
00199 WN* wn_first = WN_first(WN_region_pragmas(wn));
00200 if (wn_first != NULL && WN_opcode(wn_first) == OPC_PRAGMA)
00201 multiplier = WN_pragma(wn_first) == WN_PRAGMA_DOACROSS
00202 || WN_pragma(wn_first) == WN_PRAGMA_PARALLEL_DO ? 1
00203 : WN_pragma(wn_first) == WN_PRAGMA_PARALLEL_BEGIN ? -1 : 0;
00204 WN* wnn = 0;
00205 for (wnn = wn_first; wnn != NULL; wnn = WN_next(wnn))
00206 if (WN_opcode(wnn) == OPC_PRAGMA && WN_pragma(wnn) == WN_PRAGMA_MPNUM)
00207 break;
00208 if (wnn != NULL)
00209 return multiplier * WN_pragma_arg1(wnn);
00210 }
00211 return 0;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 extern void Print_Mp_Lowerer_Name(PU_Info* current_pu,
00221 WN* wn_loop,
00222 FILE* fp)
00223 {
00224 INT mp_num = Mp_Lower_Number(wn_loop);
00225 if (mp_num == 0)
00226 return;
00227 char* program_name = ST_name(PU_Info_proc_sym(current_pu));
00228 if (mp_num > 0)
00229 fprintf(fp, "__mpdo_%s%d", program_name, mp_num);
00230 else
00231 fprintf(fp, "__mpregion_%s%d", program_name, -mp_num);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 static void Print_Prompl_Msgs(PU_Info* current_pu,
00243 FILE *fp,
00244 WN* wn_loop,
00245 FIZ_FUSE_INFO* ffi)
00246 {
00247 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00248 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00249
00250
00251 INT i;
00252 for (i = 0; i < ffi->Num_Snl(); i++) {
00253 if (ffi->Get_Type(i) == Invalid || ffi->Get_Type(i) == Non_SNL)
00254 continue;
00255 if (ffi->Get_Wn(i) == wn_loop)
00256 break;
00257 }
00258 if (i < ffi->Num_Snl()) {
00259 fprintf(fp, "\n");
00260 }
00261 if (dli->Last_Value_Peeled) {
00262 fprintf(fp,
00263 "%5d: Created by peeling last iteration of parallel loop.\n",
00264 (INT) WN_linenum(wn_loop));
00265 return;
00266 }
00267 if (Do_Loop_Is_Mp(wn_loop) && !dli->Auto_Parallelized) {
00268 fprintf(fp, "%5d: PARALLEL (Manual) ", (INT) WN_linenum(wn_loop));
00269 Print_Mp_Lowerer_Name(current_pu, wn_loop, fp);
00270 fprintf(fp, "\n");
00271 return;
00272 }
00273 if (dli->ARA_Info == NULL)
00274 return;
00275 if (dli->ARA_Info->Is_Parallel() && dli->Auto_Parallelized) {
00276 if (dli->Is_Doacross)
00277 fprintf(fp, "%5d: PARALLEL (Auto Synchronized) ",
00278 (INT) WN_linenum(wn_loop));
00279 else
00280 fprintf(fp, "%5d: PARALLEL (Auto) ", (INT) WN_linenum(wn_loop));
00281 Print_Mp_Lowerer_Name(current_pu, wn_loop, fp);
00282 fprintf(fp, "\n");
00283 return;
00284 }
00285 INT found_problem = FALSE;
00286 fprintf(fp, "%5d: Not Parallel\n", (INT) WN_linenum(wn_loop));
00287 if (dli->ARA_Info->Is_Parallel()
00288 && dli->ARA_Info->Not_Enough_Parallel_Work()) {
00289 fprintf(fp, " ");
00290 fprintf(fp, "Loop body does not contain enough work.\n");
00291 found_problem = TRUE;
00292 }
00293 if (dli->Inside_Critical_Section) {
00294 fprintf(fp, " ");
00295 fprintf(fp, "Loop is inside CRITICAL section.\n");
00296 found_problem = TRUE;
00297 }
00298 if (dli->Has_Threadprivate) {
00299 fprintf(fp, " ");
00300 fprintf(fp, "Loop has THREAD_PRIVATE variables.\n");
00301 found_problem = TRUE;
00302 }
00303 if (dli->Has_Exits) {
00304 fprintf(fp, " ");
00305 fprintf(fp, "Loop has early exits on ");
00306 Print_Goto_Lines(wn_loop, fp, &LNO_local_pool);
00307 fprintf(fp, "\n");
00308 found_problem = TRUE;
00309 }
00310 if (dli->Pragma_Cannot_Concurrentize) {
00311 fprintf(fp, " ");
00312 fprintf(fp, "Pragma on loop inhibits parallelization.\n");
00313 found_problem = TRUE;
00314 }
00315 if (dli->Serial_Version_of_Concurrent_Loop) {
00316 fprintf(fp, " ");
00317 fprintf(fp, "Loop in serial version of parallel loop.\n");
00318 found_problem = TRUE;
00319 }
00320 if (!Upper_Bound_Standardize(WN_end(wn_loop), TRUE)) {
00321 fprintf(fp, " ");
00322 fprintf(fp, "Loop bounds could not be put in standard form.\n");
00323 found_problem = TRUE;
00324 }
00325 if (Inside_Lego_Tiled_Loop(wn_loop)) {
00326 fprintf(fp, " ");
00327 fprintf(fp, "Loop refers to distributed or reshaped arrays.\n");
00328 found_problem = TRUE;
00329 }
00330 if (dli->ARA_Info->Is_OK_Parallel()
00331 && dli->ARA_Info->Inner_Loop_Is_Suggested_Parallel()) {
00332 fprintf(fp, " ");
00333 fprintf(fp, "Parallelizing innermore loop was deemed more profitable.\n");
00334 found_problem = TRUE;
00335 }
00336 if (Outermore_Parallel_Construct(wn_loop, FALSE)) {
00337 fprintf(fp, " ");
00338 fprintf(fp, "Loop is contained within a parallel construct.\n");
00339 found_problem = TRUE;
00340 }
00341 if (dli->Has_Unsummarized_Calls || !dli->Is_Concurrent_Call) {
00342 for (i = 0; i < dli->ARA_Info->Call_No_Dep_Vars().Elements(); i++) {
00343 char* call_name = dli->ARA_Info->Call_No_Dep_Vars().Bottom_nth(i);
00344 INT ln_call = dli->ARA_Info->Ln_Call_No_Dep_Vars().Bottom_nth(i);
00345 fprintf(fp, " ");
00346 found_problem = TRUE;
00347 if (strlen(call_name) == 0)
00348 fprintf(fp, "Call on line %d.\n", ln_call);
00349 else
00350 fprintf(fp, "Call %s on line %d.\n", call_name, ln_call);
00351 }
00352 }
00353 STACK<WN*> stk_io(&ARA_memory_pool);
00354 if (Has_Io(wn_loop, &stk_io)) {
00355 for (INT i = 0; i < stk_io.Elements(); i++) {
00356 fprintf(fp, " ");
00357 found_problem = TRUE;
00358 INT ln_node = WN_Whirl_Linenum(stk_io.Bottom_nth(i));
00359 fprintf(fp, "Has IO statement on line %d.\n", ln_node);
00360 }
00361 }
00362 if (found_problem) {
00363 return;
00364 }
00365 for (i = 0; i < dli->ARA_Info->Scalar_Vars().Elements(); i++) {
00366 fprintf(fp, " ");
00367 found_problem = TRUE;
00368 fprintf(fp, "Scalar dependence on %s.",
00369 dli->ARA_Info->Scalar_Vars().Bottom_nth(i).Prompf_Name());
00370 fprintf(fp, "\n");
00371 }
00372 for (i = 0; i < dli->ARA_Info->Scalar_Alias().Elements(); i++) {
00373 fprintf(fp, " ");
00374 found_problem = TRUE;
00375 fprintf(fp, "Aliased scalar %s.",
00376 dli->ARA_Info->Scalar_Alias().Bottom_nth(i).Prompf_Name());
00377 fprintf(fp, "\n");
00378 }
00379 for (i = 0; i < dli->ARA_Info->Scalar_No_Final().Elements(); i++) {
00380 fprintf(fp, " ");
00381 found_problem = TRUE;
00382 fprintf(fp, "Scalar %s without unique last value.",
00383 dli->ARA_Info->Scalar_No_Final().Bottom_nth(i).Prompf_Name());
00384 fprintf(fp, "\n");
00385 }
00386 for (i =0; i < dli->ARA_Info->Scalar_Bad_Peel().Elements(); i++) {
00387 fprintf(fp, " ");
00388 found_problem = TRUE;
00389 SYMBOL sym_priv = dli->ARA_Info->Scalar_Bad_Peel().Bottom_nth(i);
00390 INT ln_priv = dli->ARA_Info->Ln_Scalar_Bad_Peel().Bottom_nth(i);
00391 fprintf(fp, "Last iteration may not write value of scalar %s on line %d.",
00392 sym_priv.Prompf_Name(), ln_priv);
00393 fprintf(fp, "\n");
00394 }
00395 for (i = 0; i < dli->ARA_Info->Array_No_Dep_Vars().Elements(); i++) {
00396 fprintf(fp, " ");
00397 found_problem = TRUE;
00398 SYMBOL sym_node = dli->ARA_Info->Array_No_Dep_Vars().Bottom_nth(i);
00399 INT ln_node = dli->ARA_Info->Ln_Array_No_Dep_Vars().Bottom_nth(i);
00400 fprintf(fp, "Array %s without dependence information. ",
00401 sym_node.Prompf_Name());
00402 fprintf(fp, "on line %d.", ln_node);
00403 fprintf(fp, "\n");
00404 }
00405 for (i = 0; i < dli->ARA_Info->Ln_Misc_No_Dep_Vars().Elements(); i++) {
00406 fprintf(fp, " ");
00407 found_problem = TRUE;
00408 INT ln_node = dli->ARA_Info->Ln_Misc_No_Dep_Vars().Bottom_nth(i);
00409 fprintf(fp, "Reference without dependence information ");
00410 fprintf(fp, "on line %d.", ln_node);
00411 fprintf(fp, "\n");
00412 }
00413 for (i = 0; i < dli->ARA_Info->Dep_Vars().Elements(); i++) {
00414 fprintf(fp, " ");
00415 found_problem = TRUE;
00416 SYMBOL sym_source = dli->ARA_Info->Dep_Source().Bottom_nth(i);
00417 SYMBOL sym_sink = dli->ARA_Info->Dep_Sink().Bottom_nth(i);
00418 INT ln_source = dli->ARA_Info->Ln_Dep_Source().Bottom_nth(i);
00419 INT ln_sink = dli->ARA_Info->Ln_Dep_Sink().Bottom_nth(i);
00420 fprintf(fp, "Array dependence from %s on line %d ",
00421 sym_source.Prompf_Name(), ln_source);
00422 fprintf(fp, "to %s on line %d.",
00423 sym_sink.Prompf_Name(), ln_sink);
00424 fprintf(fp, "\n");
00425 }
00426 for (i =0; i < dli->ARA_Info->Dep_Bad_Peel().Elements(); i++) {
00427 fprintf(fp, " ");
00428 found_problem = TRUE;
00429 SYMBOL sym_priv = dli->ARA_Info->Dep_Bad_Peel().Bottom_nth(i);
00430 INT ln_priv = dli->ARA_Info->Ln_Dep_Bad_Peel().Bottom_nth(i);
00431 fprintf(fp, "Last iteration may not write value of array %s on line %d.",
00432 sym_priv.Prompf_Name(), ln_priv);
00433 fprintf(fp, "\n");
00434 }
00435 for (i =0; i < dli->ARA_Info->Partial_Array_Sec().Elements(); i++) {
00436 fprintf(fp, " ");
00437 found_problem = TRUE;
00438 SYMBOL sym_priv = dli->ARA_Info->Partial_Array_Sec().Bottom_nth(i);
00439 fprintf(fp, "Cannot privatize %s. Requires partial array section.",
00440 sym_priv.Prompf_Name());
00441 fprintf(fp, "\n");
00442 }
00443 if (!found_problem && dli->Has_Bad_Mem) {
00444 fprintf(fp, " ");
00445 fprintf(fp, "Indirect reference.");
00446 fprintf(fp, "\n");
00447 found_problem = TRUE;
00448 }
00449 if (!found_problem) {
00450 fprintf(fp, " ");
00451 fprintf(fp, "Reason unknown.");
00452 fprintf(fp, "\n");
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461 static void Print_Prompl_Msgs_Traverse(PU_Info* current_pu,
00462 FILE* fp,
00463 WN* wn_tree,
00464 FIZ_FUSE_INFO* ffi)
00465 {
00466 if (WN_opcode(wn_tree) == OPC_DO_LOOP) {
00467 Print_Prompl_Msgs(current_pu, fp, wn_tree, ffi);
00468 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00469 if (dli->Is_Inner)
00470 return;
00471 }
00472
00473 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00474 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00475 Print_Prompl_Msgs_Traverse(current_pu, fp, wn, ffi);
00476 } else {
00477 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00478 Print_Prompl_Msgs_Traverse(current_pu, fp, WN_kid(wn_tree, i), ffi);
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487 static BOOL opened_lfile = FALSE;
00488
00489 extern void Print_Prompl_Msgs(PU_Info* current_pu,
00490 WN* func_nd)
00491 {
00492 FIZ_FUSE_INFO* ffi=
00493 CXX_NEW(FIZ_FUSE_INFO(&ARA_memory_pool), &ARA_memory_pool);
00494 ffi->Build(func_nd, TRUE);
00495 char* filename = (char *) alloca(strlen(Obj_File_Name) + strlen(".list"));
00496 strcpy(filename, Obj_File_Name);
00497 INT i;
00498 for (i = strlen(Obj_File_Name); i >= 0; i--)
00499 if (filename[i] == '.')
00500 break;
00501 FmtAssert(i >= 0,
00502 ("Print_Prompl_Parallelization_Msgs: could not find '.'"));
00503 strcpy(&filename[i], ".list");
00504 FILE* fp = NULL;
00505 if (!opened_lfile) {
00506 fprintf(stdout,
00507 "The file %s gives the parallelization status of each loop.\n",
00508 filename);
00509 fp = fopen(filename, "w");
00510 opened_lfile = TRUE;
00511 } else {
00512 fp = fopen(filename, "a");
00513 }
00514 if (fp == NULL) {
00515 fprintf(stderr, "Fatal: Unable to open file %s\n", filename);
00516 exit(1);
00517 }
00518 fprintf(fp, "Parallelization Log for Subprogram %s\n",
00519 ST_name(PU_Info_proc_sym(current_pu)));
00520
00521 Print_Prompl_Msgs_Traverse(current_pu, fp, func_nd, ffi);
00522 fprintf(fp, "\n\n");
00523 fclose(fp);
00524 }
00525
00526
00527
00528
00529
00530
00531
00532 static void Print_Prompf_Msgs(FILE *fp,
00533 WN* wn_loop)
00534 {
00535 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00536 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_loop);
00537
00538 if (dli->Last_Value_Peeled) {
00539 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00540 fprintf(fp, "LAST_VALUE_LOOP");
00541 fprintf(fp, "\n");
00542 } else if (Do_Loop_Is_Mp(wn_loop)) {
00543 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00544 fprintf(fp, "PARALLELIZED ");
00545 if (dli->Is_Doacross)
00546 fprintf(fp, "SYNCHRONIZED ");
00547 fprintf(fp, "\n");
00548 } else if (dli->ARA_Info == NULL) {
00549 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00550 fprintf(fp, "NO_AUTO_PARALLEL ");
00551 fprintf(fp, "\n");
00552 } else if (dli->ARA_Info->Is_Parallel()) {
00553 if (dli->ARA_Info->Not_Enough_Parallel_Work()) {
00554 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00555 fprintf(fp, "NOT_ENOUGH_WORK ");
00556 } else {
00557 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00558 fprintf(fp, "PARALLELIZED ");
00559 }
00560 fprintf(fp, "\n");
00561 } else {
00562 BOOL major_problem = FALSE;
00563 FmtAssert(dli != NULL, ("Print_Prompf_Info: missing doloop info"));
00564 if (dli->Inside_Critical_Section) {
00565 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00566 fprintf(fp, "CRITICAL_SECTION ");
00567 fprintf(fp, "\n");
00568 major_problem = TRUE;
00569 }
00570 if (dli->Has_Threadprivate) {
00571 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00572 fprintf(fp, "THREAD_PRIVATE ");
00573 fprintf(fp, "\n");
00574 major_problem = TRUE;
00575 }
00576 if (dli->Has_Gotos) {
00577 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00578 fprintf(fp, "HAS_GOTOS ");
00579 Print_Goto_Lines(wn_loop, fp, &LNO_local_pool);
00580 fprintf(fp, "\n");
00581 major_problem = TRUE;
00582 }
00583 if (dli->Pragma_Cannot_Concurrentize) {
00584 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00585 fprintf(fp, "PRAGMA_SAYS_NO ");
00586 fprintf(fp, "\n");
00587 major_problem = TRUE;
00588 }
00589 if (dli->Serial_Version_of_Concurrent_Loop) {
00590 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00591 fprintf(fp, "SERIAL_VERSION ");
00592 fprintf(fp, "\n");
00593 major_problem = TRUE;
00594 }
00595 if (!Upper_Bound_Standardize(WN_end(wn_loop), TRUE)) {
00596 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00597 fprintf(fp, "TOUGH_UPPER_BOUND ");
00598 fprintf(fp, "\n");
00599 major_problem = TRUE;
00600 }
00601 if (Inside_Lego_Tiled_Loop(wn_loop)) {
00602 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00603 fprintf(fp, "DSM_TILED_LOOP ");
00604 fprintf(fp, "\n");
00605 major_problem = TRUE;
00606 }
00607 if (dli->ARA_Info->Is_OK_Parallel()
00608 && dli->ARA_Info->Inner_Loop_Is_Suggested_Parallel()) {
00609 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00610 fprintf(fp, "WANT_INNER_PARALLEL ");
00611 fprintf(fp, "\n");
00612 major_problem = TRUE;
00613 }
00614 if (Outermore_Parallel_Construct(wn_loop, FALSE)) {
00615 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00616 fprintf(fp, "SERIAL_INSIDE_PARALLEL ");
00617 fprintf(fp, "\n");
00618 major_problem = TRUE;
00619 }
00620 if (dli->Has_Unsummarized_Calls || !dli->Is_Concurrent_Call) {
00621 for (INT i = 0; i < dli->ARA_Info->Call_No_Dep_Vars().Elements(); i++) {
00622 char* call_name = dli->ARA_Info->Call_No_Dep_Vars().Bottom_nth(i);
00623 INT ln_node = dli->ARA_Info->Ln_Call_No_Dep_Vars().Bottom_nth(i);
00624 major_problem = TRUE;
00625 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00626 fprintf(fp, "HAS_CALL ");
00627 if (strlen(call_name) > 0)
00628 fprintf(fp, "highlight \"%s\" ", call_name);
00629 fprintf(fp, "lines %d ", ln_node);
00630 fprintf(fp, "\n");
00631 }
00632 }
00633 STACK<WN*> stk_io(&ARA_memory_pool);
00634 if (Has_Io(wn_loop, &stk_io)) {
00635 for (INT i = 0; i < stk_io.Elements(); i++) {
00636 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00637 fprintf(fp, "HAS_IO ");
00638 fprintf(fp, "lines %d ", WN_Whirl_Linenum(stk_io.Bottom_nth(i)));
00639 fprintf(fp, "\n");
00640 major_problem = TRUE;
00641 }
00642 }
00643 if (!major_problem) {
00644 BOOL found_problem = FALSE;
00645 INT i;
00646 for (i = 0; i < dli->ARA_Info->Scalar_Vars().Elements(); i++) {
00647 found_problem = TRUE;
00648 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00649 fprintf(fp, "SCALAR_DEP ");
00650 fprintf(fp, "highlight \"%s\" ",
00651 dli->ARA_Info->Scalar_Vars().Bottom_nth(i).Prompf_Name());
00652 fprintf(fp, "\n");
00653 }
00654 for (i = 0; i < dli->ARA_Info->Scalar_Alias().Elements(); i++) {
00655 found_problem = TRUE;
00656 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00657 fprintf(fp, "SCALAR_ALIAS ");
00658 fprintf(fp, "highlight \"%s\" ",
00659 dli->ARA_Info->Scalar_Alias().Bottom_nth(i).Prompf_Name());
00660 fprintf(fp, "\n");
00661 }
00662 for (i = 0; i < dli->ARA_Info->Scalar_No_Final().Elements(); i++) {
00663 found_problem = TRUE;
00664 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00665 fprintf(fp, "SCALAR_LAST_VALUE ");
00666 fprintf(fp, "highlight \"%s\" ",
00667 dli->ARA_Info->Scalar_No_Final().Bottom_nth(i).Prompf_Name());
00668 fprintf(fp, "\n");
00669 }
00670 for (i = 0; i < dli->ARA_Info->Array_No_Dep_Vars().Elements(); i++) {
00671 found_problem = TRUE;
00672 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00673 SYMBOL sym_node = dli->ARA_Info->Array_No_Dep_Vars().Bottom_nth(i);
00674 INT ln_node = dli->ARA_Info->Ln_Array_No_Dep_Vars().Bottom_nth(i);
00675 fprintf(fp, "BAD_ARRAY ");
00676 fprintf(fp, "highlight \"%s\" ", sym_node.Prompf_Name());
00677 fprintf(fp, "lines %d ", ln_node);
00678 fprintf(fp, "\n");
00679 }
00680 for (i = 0; i < dli->ARA_Info->Ln_Misc_No_Dep_Vars().Elements(); i++) {
00681 found_problem = TRUE;
00682 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00683 INT ln_node = dli->ARA_Info->Ln_Misc_No_Dep_Vars().Bottom_nth(i);
00684 fprintf(fp, "BAD_REF ");
00685 fprintf(fp, "lines %d ", ln_node);
00686 fprintf(fp, "\n");
00687 }
00688 for (i = 0; i < dli->ARA_Info->Dep_Vars().Elements(); i++) {
00689 found_problem = TRUE;
00690 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00691 fprintf(fp, "ARRAY_DEP ");
00692 SYMBOL sym_source = dli->ARA_Info->Dep_Source().Bottom_nth(i);
00693 SYMBOL sym_sink = dli->ARA_Info->Dep_Sink().Bottom_nth(i);
00694 INT ln_source = dli->ARA_Info->Ln_Dep_Source().Bottom_nth(i);
00695 INT ln_sink = dli->ARA_Info->Ln_Dep_Sink().Bottom_nth(i);
00696 fprintf(fp, "highlight \"%s\" ", sym_source.Prompf_Name());
00697 fprintf(fp, "lines %d ", ln_source);
00698 fprintf(fp, "highlight \"%s\" ", sym_sink.Prompf_Name());
00699 fprintf(fp, "lines %d ", ln_sink);
00700 fprintf(fp, "\n");
00701 }
00702 for (i =0; i < dli->ARA_Info->Scalar_Bad_Peel().Elements(); i++) {
00703 found_problem = TRUE;
00704 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00705 fprintf(fp, "SCALAR_LAST_ITER ");
00706 SYMBOL sym_priv = dli->ARA_Info->Scalar_Bad_Peel().Bottom_nth(i);
00707 INT ln_priv = dli->ARA_Info->Ln_Scalar_Bad_Peel().Bottom_nth(i);
00708 fprintf(fp, "highlight \"%s\" ", sym_priv.Prompf_Name());
00709 fprintf(fp, "lines %d ", ln_priv);
00710 fprintf(fp, "\n");
00711 }
00712 for (i =0; i < dli->ARA_Info->Dep_Bad_Peel().Elements(); i++) {
00713 found_problem = TRUE;
00714 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00715 fprintf(fp, "ARRAY_LAST_ITER ");
00716 SYMBOL sym_priv = dli->ARA_Info->Dep_Bad_Peel().Bottom_nth(i);
00717 INT ln_priv = dli->ARA_Info->Ln_Dep_Bad_Peel().Bottom_nth(i);
00718 fprintf(fp, "highlight \"%s\" ", sym_priv.Prompf_Name());
00719 fprintf(fp, "lines %d ", ln_priv);
00720 fprintf(fp, "\n");
00721 }
00722 for (i =0; i < dli->ARA_Info->Partial_Array_Sec().Elements(); i++) {
00723 found_problem = TRUE;
00724 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00725 fprintf(fp, "PARTIAL_ARRAY_SEC ");
00726 SYMBOL sym_priv = dli->ARA_Info->Partial_Array_Sec().Bottom_nth(i);
00727 fprintf(fp, "highlight \"%s\" ", sym_priv.Prompf_Name());
00728 fprintf(fp, "\n");
00729 }
00730 if (!found_problem && dli->Has_Bad_Mem) {
00731 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00732 fprintf(fp, "INDIRECT_REF ");
00733 fprintf(fp, "\n");
00734 found_problem = TRUE;
00735 }
00736 if (!found_problem) {
00737 fprintf(fp, "tid %d ", WN_MAP32_Get(Prompf_Id_Map, wn_loop));
00738 fprintf(fp, "UNKNOWN ");
00739 fprintf(fp, "\n");
00740 }
00741 }
00742 }
00743 }
00744
00745
00746
00747
00748
00749
00750 static void Print_Prompf_Msgs_Traverse(FILE* fp,
00751 WN* wn_tree)
00752 {
00753 if (WN_opcode(wn_tree) == OPC_DO_LOOP) {
00754 Print_Prompf_Msgs(fp, wn_tree);
00755 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00756 if (dli->Is_Inner)
00757 return;
00758 }
00759
00760 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00761 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00762 Print_Prompf_Msgs_Traverse(fp, wn);
00763 } else {
00764 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00765 Print_Prompf_Msgs_Traverse(fp, WN_kid(wn_tree, i));
00766 }
00767 }
00768
00769
00770
00771
00772
00773
00774 extern void Print_Prompf_Parallelization_Log(WN* func_nd)
00775 {
00776 if (Find_SCF_Inside(func_nd, OPC_DO_LOOP) != NULL) {
00777 const char *path = Anl_File_Path();
00778 FILE *fp_anl = fopen(path, "a");
00779 if (fp_anl == NULL) {
00780 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
00781 exit(1);
00782 }
00783 fprintf(fp_anl, "PARALLELIZATION_LOG_BEGIN\n");
00784 Print_Prompf_Msgs_Traverse(fp_anl, func_nd);
00785 fprintf(fp_anl, "PARALLELIZATION_LOG_END\n\n");
00786 fclose(fp_anl);
00787 }
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797 static INT Lowered_Doacross_Loops(WN* wn_tree,
00798 STACK<WN*>* stk_wn)
00799 {
00800 INT doacross_count = 0;
00801
00802
00803 if (WN_opcode(wn_tree) == OPC_REGION) {
00804 WN* wn_first = WN_first(WN_region_pragmas(wn_tree));
00805 if (wn_first != NULL && WN_opcode(wn_first) == OPC_PRAGMA
00806 && (WN_pragma(wn_first) == WN_PRAGMA_PARALLEL_BEGIN ||
00807 WN_pragma(wn_first) == WN_PRAGMA_PDO_BEGIN)) {
00808 return doacross_count;
00809 }
00810 }
00811
00812 if (WN_opcode(wn_tree) == OPC_DO_LOOP) {
00813 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00814 if (dli->Mp_Info != NULL && dli->Mp_Info->Nest_Index() == 0) {
00815 stk_wn->Push(wn_tree);
00816 doacross_count++;
00817 }
00818 if (dli->Is_Inner)
00819 return doacross_count;
00820 }
00821
00822 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00823 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00824 doacross_count += Lowered_Doacross_Loops(wn, stk_wn);
00825 } else {
00826 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00827 doacross_count += Lowered_Doacross_Loops(WN_kid(wn_tree, i), stk_wn);
00828 }
00829 return doacross_count;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838 static INT Do_Loops(WN* wn_tree,
00839 STACK<WN*>* stk_wn)
00840 {
00841 INT do_count = 0;
00842
00843 if (WN_opcode(wn_tree) == OPC_DO_LOOP) {
00844 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00845 stk_wn->Push(wn_tree);
00846 do_count++;
00847 if (dli->Is_Inner)
00848 return do_count;
00849 }
00850
00851 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00852 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00853 do_count += Do_Loops(wn, stk_wn);
00854 } else {
00855 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00856 do_count += Do_Loops(WN_kid(wn_tree, i), stk_wn);
00857 }
00858 return do_count;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868 static INT Lowered_Parallel_Regions(WN* wn_tree,
00869 STACK<WN*>* stk_wn)
00870 {
00871 INT parallel_region_count = 0;
00872 if (WN_opcode(wn_tree) == OPC_REGION) {
00873 WN* wn_first = WN_first(WN_region_pragmas(wn_tree));
00874 if (wn_first != NULL && WN_opcode(wn_first) == OPC_PRAGMA
00875 && WN_pragma(wn_first) == WN_PRAGMA_PARALLEL_BEGIN) {
00876 stk_wn->Push(wn_tree);
00877 parallel_region_count++;
00878 }
00879 }
00880 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00881 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00882 parallel_region_count += Lowered_Parallel_Regions(wn, stk_wn);
00883 } else {
00884 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00885 parallel_region_count += Lowered_Parallel_Regions(WN_kid(wn_tree, i),
00886 stk_wn);
00887 }
00888 return parallel_region_count;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897 static void Assign_Doacross_Mpnums(STACK<WN*>* stk_wn)
00898 {
00899 INT doacross_count = 0;
00900 for (INT i = 0; i < stk_wn->Elements(); i++) {
00901 WN* wn_loop = stk_wn->Bottom_nth(i);
00902 WN* wn_region = LWN_Get_Parent(LWN_Get_Parent(wn_loop));
00903 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
00904 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPNUM, (ST_IDX) NULL,
00905 ++doacross_count, 0);
00906 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
00907 }
00908 }
00909
00910
00911
00912
00913
00914
00915
00916 static void Assign_Parallel_Region_Mpnums(STACK<WN*>* stk_wn)
00917 {
00918 INT parallel_region_count = 0;
00919 for (INT i = 0; i < stk_wn->Elements(); i++) {
00920 WN* wn_region = stk_wn->Bottom_nth(i);
00921 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
00922 WN* wn_pragma = WN_CreatePragma(WN_PRAGMA_MPNUM, (ST_IDX) NULL,
00923 ++parallel_region_count, 0);
00924 LWN_Insert_Block_Before(WN_region_pragmas(wn_region), NULL, wn_pragma);
00925 }
00926 }
00927
00928
00929
00930
00931
00932
00933
00934
00935 static void Add_Doacross_Comments(PU_Info* current_pu,
00936 STACK<WN*>* stk_wn)
00937 {
00938 INT doacross_count = 0;
00939 for (INT i = 0; i < stk_wn->Elements(); i++) {
00940 WN* wn_loop = stk_wn->Bottom_nth(i);
00941 WN* wn_region = LWN_Get_Parent(LWN_Get_Parent(wn_loop));
00942 WN* wn_place_comment = wn_region;
00943 if (LWN_Get_Parent(wn_region) != NULL) {
00944 WN* wn_if = LWN_Get_Parent(LWN_Get_Parent(wn_region));
00945 if (wn_if != NULL && WN_opcode(wn_if) == OPC_IF
00946 && WN_Is_If_MpVersion(wn_if))
00947 wn_place_comment = wn_if;
00948 }
00949 char* comment = NULL;
00950 WN* wn_first = WN_first(WN_region_pragmas(wn_region));
00951 FmtAssert(WN_opcode(wn_first) == OPC_PRAGMA,
00952 ("Add_Doacross_Comments: Expected a pragma"));
00953 if (WN_pragma(wn_first) == WN_PRAGMA_DOACROSS) {
00954 comment = (char *) alloca(strlen(ST_name(PU_Info_proc_sym(current_pu)))
00955 + strlen("__mpdo_") + 10 +
00956 + strlen("DOACROSS will be converted to SUBROUTINE ") + 1);
00957 sprintf(comment,
00958 "DOACROSS will be converted to SUBROUTINE __mpdo_%s%d",
00959 ST_name(PU_Info_proc_sym(current_pu)), i + 1);
00960 } else if (WN_pragma(wn_first) == WN_PRAGMA_PARALLEL_DO) {
00961 comment = (char *) alloca(strlen(ST_name(PU_Info_proc_sym(current_pu)))
00962 + strlen("__mpdo_") + 10 +
00963 + strlen("PARALLEL DO will be converted to SUBROUTINE ") + 1);
00964 sprintf(comment,
00965 "PARALLEL DO will be converted to SUBROUTINE __mpdo_%s%d",
00966 ST_name(PU_Info_proc_sym(current_pu)), i + 1);
00967 } else {
00968 FmtAssert(FALSE,
00969 ("Add_Doacross_Comments: Expected a DOACROSS or PARALLEL DO"));
00970 }
00971 WN* wn_comment = WN_CreateComment(comment);
00972 LWN_Insert_Block_Before(LWN_Get_Parent(wn_place_comment),
00973 wn_place_comment, wn_comment);
00974 }
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984 static void Add_Parallel_Region_Comments(PU_Info* current_pu,
00985 STACK<WN*>* stk_wn)
00986 {
00987 INT doacross_count = 0;
00988 for (INT i = 0; i < stk_wn->Elements(); i++) {
00989 WN* wn_region = stk_wn->Bottom_nth(i);
00990 WN* wn_place_comment = wn_region;
00991 if (LWN_Get_Parent(wn_region) != NULL) {
00992 WN* wn_if = LWN_Get_Parent(LWN_Get_Parent(wn_region));
00993 if (wn_if != NULL && WN_opcode(wn_if) == OPC_IF
00994 && WN_Is_If_MpVersion(wn_if))
00995 wn_place_comment = wn_if;
00996 }
00997 char* comment =
00998 (char *) alloca(strlen(ST_name(PU_Info_proc_sym(current_pu)))
00999 + strlen("__mpregion_") + 10 +
01000 + strlen("PARALLEL REGION will be converted to SUBROUTINE ") + 1);
01001 sprintf(comment,
01002 "PARALLEL REGION will be converted to SUBROUTINE __mpregion_%s%d",
01003 ST_name(PU_Info_proc_sym(current_pu)), i + 1);
01004 WN* wn_comment = WN_CreateComment(comment);
01005 LWN_Insert_Block_Before(LWN_Get_Parent(wn_place_comment),
01006 wn_place_comment, wn_comment);
01007 }
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017 extern void Print_Prompf_Doacross_Log(PU_Info* current_pu,
01018 WN* func_nd,
01019 BOOL after)
01020 {
01021 STACK<WN*> stk_wn(&PROMPF_pool);
01022 INT count = Lowered_Doacross_Loops(func_nd, &stk_wn);
01023 if (count == 0)
01024 return;
01025 const char *path = Anl_File_Path();
01026 FILE *fp_anl = fopen(path, "a");
01027 if (fp_anl == NULL) {
01028 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
01029 exit(1);
01030 }
01031 if (after)
01032 fprintf(fp_anl, "POST_");
01033 fprintf(fp_anl, "DOACROSS_LOG_BEGIN\n");
01034 for (INT i = 0; i < count; i++) {
01035 WN* wn_loop = stk_wn.Bottom_nth(i);
01036 INT id = WN_MAP32_Get(Prompf_Id_Map, wn_loop);
01037 fprintf(fp_anl, "tid %d \"__mpdo_%s%d\"\n", id,
01038 ST_name(PU_Info_proc_sym(current_pu)), i + 1);
01039 }
01040 if (after)
01041 fprintf(fp_anl, "POST_");
01042 fprintf(fp_anl, "DOACROSS_LOG_END\n\n");
01043 fclose(fp_anl);
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053 extern void Print_Prompf_Parallel_Region_Log(PU_Info* current_pu,
01054 WN* func_nd,
01055 BOOL after)
01056 {
01057 STACK<WN*> stk_wn(&PROMPF_pool);
01058 INT count = Lowered_Parallel_Regions(func_nd, &stk_wn);
01059 if (count == 0)
01060 return;
01061 const char *path = Anl_File_Path();
01062 FILE *fp_anl = fopen(path, "a");
01063 if (fp_anl == NULL) {
01064 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
01065 exit(1);
01066 }
01067 if (after)
01068 fprintf(fp_anl, "POST_");
01069 fprintf(fp_anl, "PARALLEL_REGION_LOG_BEGIN\n");
01070 for (INT i = 0; i < count; i++) {
01071 WN* wn_region = stk_wn.Bottom_nth(i);
01072 INT id = WN_MAP32_Get(Prompf_Id_Map, wn_region);
01073 fprintf(fp_anl, "tid %d \"__mpregion_%s%d\"\n", id,
01074 ST_name(PU_Info_proc_sym(current_pu)), i + 1);
01075 }
01076 if (after)
01077 fprintf(fp_anl, "POST_");
01078 fprintf(fp_anl, "PARALLEL_REGION_LOG_END\n\n");
01079 fclose(fp_anl);
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089 extern void Annotate_For_Mp_Lowering(PU_Info* current_pu,
01090 WN* func_nd)
01091 {
01092 STACK<WN*> stk_wn_loop(&LNO_local_pool);
01093 STACK<WN*> stk_wn_region(&LNO_local_pool);
01094 Lowered_Doacross_Loops(func_nd, &stk_wn_loop);
01095 Lowered_Parallel_Regions(func_nd, &stk_wn_region);
01096 Assign_Doacross_Mpnums(&stk_wn_loop);
01097 Assign_Parallel_Region_Mpnums(&stk_wn_region);
01098 Add_Doacross_Comments(current_pu, &stk_wn_loop);
01099 Add_Parallel_Region_Comments(current_pu, &stk_wn_region);
01100 }
01101
01102
01103
01104
01105
01106
01107
01108
01109 static BOOL Region_Has_Prompf_Construct(WN* wn_region)
01110 {
01111 FmtAssert(WN_opcode(wn_region) == OPC_REGION,
01112 ("Region_Has_Prompf_Construct: Expected an OPC_BLOCK"));
01113 WN* wn_pragma = WN_first(WN_region_pragmas(wn_region));
01114 if (wn_pragma == NULL) return FALSE;
01115 if (WN_opcode(wn_pragma) != OPC_PRAGMA)
01116 return FALSE;
01117 switch (WN_pragma(wn_pragma)) {
01118 case WN_PRAGMA_DOACROSS:
01119 case WN_PRAGMA_PARALLEL_DO:
01120 case WN_PRAGMA_PDO_BEGIN:
01121 case WN_PRAGMA_PARALLEL_BEGIN:
01122 return TRUE;
01123 default:
01124 return FALSE;
01125 }
01126 }
01127
01128
01129
01130
01131
01132
01133
01134 static BOOL Block_Has_Prompf_Construct(WN* wn_block)
01135 {
01136 FmtAssert(WN_opcode(wn_block) == OPC_BLOCK,
01137 ("Block_Has_Prompf_Construct: Expected an OPC_BLOCK"));
01138 WN* wn_first = WN_first(wn_block);
01139 for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) {
01140 if (WN_opcode(wn) == OPC_PRAGMA) {
01141 switch (WN_pragma(wn)) {
01142 case WN_PRAGMA_PSECTION_BEGIN:
01143 case WN_PRAGMA_PSECTION_END:
01144 case WN_PRAGMA_SECTION:
01145 case WN_PRAGMA_BARRIER:
01146 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
01147 case WN_PRAGMA_SINGLE_PROCESS_END:
01148 case WN_PRAGMA_CRITICAL_SECTION_BEGIN:
01149 case WN_PRAGMA_CRITICAL_SECTION_END:
01150 return TRUE;
01151 }
01152 }
01153 }
01154 return FALSE;
01155 }
01156
01157
01158
01159
01160
01161
01162
01163 static INT Prompf_Nest_Depth(WN* wn_ref)
01164 {
01165 INT nest_depth = 0;
01166 for (WN* wn = wn_ref; wn != NULL; wn = LWN_Get_Parent(wn))
01167 if (WN_opcode(wn) == OPC_REGION && Region_Has_Prompf_Construct(wn)
01168 || WN_opcode(wn) == OPC_BLOCK && Block_Has_Prompf_Construct(wn)
01169 || WN_opcode(wn) == OPC_DO_LOOP && !Do_Loop_Is_Mp(wn))
01170 nest_depth++;
01171 return nest_depth;
01172 }
01173
01174
01175
01176
01177
01178
01179
01180
01181 extern void Print_Prompf_Nest_Log(WN* func_nd,
01182 BOOL after)
01183 {
01184 const char *path = Anl_File_Path();
01185 FILE *fp_anl = fopen(path, "a");
01186 if (fp_anl == NULL) {
01187 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
01188 exit(1);
01189 }
01190 if (after)
01191 fprintf(fp_anl, "POST_");
01192 fprintf(fp_anl, "NEST_LOG_BEGIN\n");
01193 LWN_ITER* itr = LWN_WALK_TreeIter(func_nd);
01194 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
01195 WN* wn_ref = itr->wn;
01196 BOOL is_first = FALSE;
01197 WN* wn_region = NULL;
01198 for (WN* wn = wn_ref; wn != NULL; wn = LWN_Get_Parent(wn)) {
01199 if (WN_opcode(wn) == OPC_REGION) {
01200 wn_region = wn;
01201 break;
01202 }
01203 }
01204 PROMPF_ID_TYPE id_type = Prompf_Id_Type(wn_ref, wn_region, &is_first);
01205 if (!is_first)
01206 continue;
01207 if (id_type == MPID_UNKNOWN || id_type == MPID_FUNC_ENTRY)
01208 continue;
01209 INT id = WN_MAP32_Get(Prompf_Id_Map, wn_ref);
01210 INT level = Prompf_Nest_Depth(wn_ref);
01211 fprintf(fp_anl, "tid %d %d\n", id, level);
01212 }
01213 if (after)
01214 fprintf(fp_anl, "POST_");
01215 fprintf(fp_anl, "NEST_LOG_END\n\n");
01216 fclose(fp_anl);
01217 }
01218
01219
01220
01221
01222
01223
01224
01225 extern void Prompf_Assign_New_Ids_Traverse(WN* wn_tree)
01226 {
01227 if (WN_operator(wn_tree) == OPR_DO_LOOP) {
01228 INT map_id = WN_MAP32_Get(Prompf_Id_Map, wn_tree);
01229 if (map_id == 0) {
01230 INT new_map_id = New_Construct_Id();
01231 WN_MAP32_Set(Prompf_Id_Map, wn_tree, new_map_id);
01232 }
01233 }
01234
01235 if (WN_operator(wn_tree) == OPR_BLOCK) {
01236 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
01237 Prompf_Assign_New_Ids_Traverse(wn);
01238 } else {
01239 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
01240 Prompf_Assign_New_Ids_Traverse(WN_kid(wn_tree, i));
01241 }
01242 }
01243
01244
01245
01246
01247
01248
01249
01250 extern void Prompf_Assign_New_Ids(WN* wn_func)
01251 {
01252 Prompf_Assign_New_Ids_Traverse(wn_func);
01253 }
01254
01255
01256
01257
01258
01259
01260
01261
01262 extern void Prompf_Collect_Ids(WN* wn_tree,
01263 STACK<WN*>* st_wn,
01264 STACK<INT>* st_id)
01265 {
01266 INT map_id = WN_MAP32_Get(Prompf_Id_Map, wn_tree);
01267 if (map_id != 0) {
01268 INT i;
01269 for (i = 0; i < st_id->Elements(); i++)
01270 if (st_id->Bottom_nth(i) == map_id)
01271 break;
01272 if (i == st_id->Elements()) {
01273 st_wn->Push(wn_tree);
01274 st_id->Push(map_id);
01275 }
01276 }
01277
01278 if (WN_opcode(wn_tree) == OPC_BLOCK) {
01279 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
01280 Prompf_Collect_Ids(wn, st_wn, st_id);
01281 } else {
01282 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
01283 Prompf_Collect_Ids(WN_kid(wn_tree, i), st_wn, st_id);
01284 }
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294 extern void Print_Prompf_Preopt_Transaction_Log(PROMPF_INFO* prompf_info,
01295 STACK<INT>* st_before_id,
01296 STACK<WN*>* st_after_wn,
01297 MEM_POOL* mem_pool)
01298 {
01299 STACK<INT> st_missing_id(&MEM_local_pool);
01300 STACK<WN*> st_new_wn(&MEM_local_pool);
01301 INT i;
01302 for (i = 0; i < st_before_id->Elements(); i++) {
01303 INT map_id_before = st_before_id->Bottom_nth(i);
01304 INT j;
01305 for (j = 0; j < st_after_wn->Elements(); j++) {
01306 WN* wn_loop_after = st_after_wn->Bottom_nth(j);
01307 INT map_id_after = WN_MAP32_Get(Prompf_Id_Map, wn_loop_after);
01308 if (map_id_before == map_id_after)
01309 break;
01310 }
01311 if (j == st_after_wn->Elements())
01312 st_missing_id.Push(map_id_before);
01313 }
01314 for (i = 0; i < st_after_wn->Elements(); i++) {
01315 WN* wn_loop_after = st_after_wn->Bottom_nth(i);
01316 INT map_id_after = WN_MAP32_Get(Prompf_Id_Map, wn_loop_after);
01317 INT j;
01318 for (j = 0; j < st_before_id->Elements(); j++) {
01319 INT map_id_before = st_before_id->Bottom_nth(j);
01320 if (map_id_before == map_id_after)
01321 break;
01322 }
01323 if (j == st_before_id->Elements())
01324 st_new_wn.Push(wn_loop_after);
01325 }
01326 if (st_missing_id.Elements() == 0 && st_new_wn.Elements() == 0)
01327 return;
01328 for (i = 0; i < st_missing_id.Elements(); i++) {
01329 INT map_id = st_missing_id.Bottom_nth(i);
01330 prompf_info->Elimination(map_id);
01331 }
01332 for (i = 0; i < st_new_wn.Elements(); i++) {
01333 WN* wn_loop = st_new_wn.Bottom_nth(i);
01334 INT map_id = WN_MAP32_Get(Prompf_Id_Map, wn_loop);
01335 PROMPF_LINES* pl = CXX_NEW(PROMPF_LINES(wn_loop, mem_pool), mem_pool);
01336 prompf_info->Preopt_Create(map_id, pl, (char*) WB_Whirl_Symbol(wn_loop));
01337 }
01338 const char *path = Anl_File_Path();
01339 FILE *fp_anl = fopen(path, "a");
01340 if (fp_anl == NULL) {
01341 fprintf(stderr, "Fatal: Unable to open file %s\n", path);
01342 exit(1);
01343 }
01344 prompf_info->Print_Compact(fp_anl, PTL_PREOPT);
01345 fclose(fp_anl);
01346 }
01347