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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #define __STDC_LIMIT_MACROS
00059 #include <stdint.h>
00060 #ifdef USE_PCH
00061 #include "lno_pch.h"
00062 #endif // USE_PCH
00063 #pragma hdrstop
00064
00065 #include <sys/types.h>
00066 #include <limits.h>
00067 #include "pu_info.h"
00068 #include "defs.h"
00069 #include "config_cache.h"
00070 #include "config_list.h"
00071 #include "config_lno.h"
00072 #include "erbe.h"
00073 #include "glob.h"
00074 #include "wn.h"
00075 #include "timing.h"
00076 #include "wn_simp.h"
00077 #include "ir_reader.h"
00078 #include "lnoptimizer.h"
00079 #include "opt_du.h"
00080 #include "wn_pragmas.h"
00081
00082 #include "lwn_util.h"
00083 #include "lnoutils.h"
00084 #include "dep_graph.h"
00085 #include "fission.h"
00086 #include "fusion.h"
00087 #include "ff_utils.h"
00088 #include "ff_pragmas.h"
00089 #include "fiz_fuse.h"
00090 #include "fis_gthr.h"
00091 #include "inner_fission.h"
00092 #include "snl.h"
00093 #include "prefetch.h"
00094 #include "reduc.h"
00095 #include "soe.h"
00096 #include "cond.h"
00097 #include "lnopt_main.h"
00098 #include "config.h"
00099 #include "be_util.h"
00100 #include "aequiv.h"
00101 #include "sclrze.h"
00102 #include "dead.h"
00103 #include "minvariant.h"
00104 #include "outer.h"
00105 #include "lego.h"
00106 #include "lego_util.h"
00107 #include "lego_opts.h"
00108 #include "cxx_graph.h"
00109 #include "model.h"
00110 #include "forward.h"
00111 #include "debug.h"
00112 #include "cse.h"
00113 #include "stblock.h"
00114 #include "strtab.h"
00115 #include "reverse.h"
00116 #include "tile.h"
00117 #include "permute.h"
00118 #include "lego_skew.h"
00119 #include "array_bounds.h"
00120 #include "small_trips.h"
00121 #include "parallel.h"
00122 #include "ara.h"
00123 #include "doacross.h"
00124 #include "autod.h"
00125 #include "prompf.h"
00126 #include "anl_driver.h"
00127 #include "parids.h"
00128 #include "call_info.h"
00129 #include "ifminmax.h"
00130 #include "shackle.h"
00131 #include "ipa_lno_info.h"
00132 #include "ipa_lno_file.h"
00133 #include "ipa_lno_summary.h"
00134 #include "ipa_section.h"
00135 #include "lnodriver.h"
00136 #include "ipa_lno_read.h"
00137
00138 #pragma weak Prompf_Emit_Whirl_to_Source__GP7pu_infoP2WN
00139 #if ! defined(BUILD_OS_DARWIN)
00140 #pragma weak Anl_File_Path
00141 #endif
00142 #pragma weak Print_file__16PROJECTED_REGIONGP8__file_s
00143 #pragma weak Print_file__14PROJECTED_NODEGP8__file_s
00144
00145 extern WN *Convert_Intrinsic_To_Alloca_Dealloca (WN *wn);
00146 extern void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu,
00147 WN* func_nd);
00148
00149 extern BOOL Phase_123(PU_Info* current_pu, WN* func_nd,
00150 BOOL do_fiz_fuse, BOOL do_phase25,
00151 BOOL do_inner_fission);
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 WN_MAP Parent_Map;
00162
00163
00164
00165
00166
00167 WN_MAP LNO_Info_Map;
00168
00169
00170
00171
00172 WN_MAP Array_Dependence_Map;
00173
00174
00175 WN_MAP Stmt_Dependence_Map;
00176
00177 MEM_POOL LNO_default_pool;
00178 MEM_POOL LNO_local_pool;
00179 static BOOL lno_mempool_initialized = FALSE;
00180 FILE* LNO_Analysis;
00181 BOOL LNO_Tlog=FALSE;
00182
00183 DU_MANAGER *Du_Mgr;
00184 ALIAS_MANAGER *Alias_Mgr;
00185 REDUCTION_MANAGER *red_manager;
00186 ARRAY_DIRECTED_GRAPH16 *Array_Dependence_Graph;
00187 INT snl_debug = 0;
00188 FILE *STDOUT;
00189 BOOL Contains_MP = FALSE;
00190
00191 BOOL LNO_enabled = TRUE;
00192
00193 PERMUTATION_ARRAYS *Permutation_Arrays;
00194
00195 void Eliminate_Zero_Mult(WN *wn, ARRAY_DIRECTED_GRAPH16 *dep_graph);
00196 extern void Pad_Degenerates();
00197 extern void Pad_First_Dim_Degenerates(WN *func_nd);
00198
00199 extern BOOL Build_Array_Dependence_Graph (WN* func_nd);
00200 extern void Build_CG_Dependence_Graph (WN* func_nd);
00201 extern void Build_CG_Dependence_Graph (ARRAY_DIRECTED_GRAPH16*);
00202
00203 WN* Current_Func_Node = NULL;
00204 BOOL LNO_Allow_Delinearize = TRUE;
00205
00206
00207 static INT prompf_dumped = FALSE;
00208
00209
00210
00211
00212
00213
00214 void Prompf_Init()
00215 {
00216 prompf_dumped = FALSE;
00217 if (Run_prompf) {
00218 Prompf_Info->Enable();
00219 Prompf_Info->Mark_Prelno();
00220 } else if (LNO_Prompl) {
00221 MEM_POOL_Initialize(&PROMPF_pool, "PROMPF_pool", FALSE);
00222 MEM_POOL_Push(&PROMPF_pool);
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231 void Prompf_Finish()
00232 {
00233 if (Run_prompf) {
00234 Prompf_Info->Disable();
00235 MEM_POOL_Pop(&PROMPF_pool);
00236 MEM_POOL_Delete(&PROMPF_pool);
00237 Prompf_Info = NULL;
00238 } else if (LNO_Prompl) {
00239 MEM_POOL_Pop(&PROMPF_pool);
00240 MEM_POOL_Delete(&PROMPF_pool);
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 static void Prompf_Dump(PU_Info* current_pu,
00252 WN* func_nd)
00253 {
00254 FILE *fp_anl = NULL;
00255 prompf_dumped = TRUE;
00256 if (Run_prompf) {
00257 #ifdef Is_True_On
00258 Prompf_Info->Check(stdout, func_nd);
00259 #endif
00260 Prompf_Info->Mark_Postlno();
00261 Prompf_Emit_Whirl_to_Source(current_pu, func_nd);
00262 } else if (Run_w2fc_early) {
00263 Prompf_Emit_Whirl_to_Source(current_pu, func_nd);
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 static void Prompf_Post_Dump(PU_Info* current_pu,
00274 WN* func_nd)
00275 {
00276 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
00277 #ifdef Is_True_On
00278 Prompf_Info->Check(stdout, func_nd);
00279 #endif
00280 Print_Prompf_Transaction_Log(TRUE);
00281 Print_Prompf_Doacross_Log(current_pu, func_nd, TRUE);
00282 Print_Prompf_Parallel_Region_Log(current_pu, func_nd, TRUE);
00283 Print_Prompf_Nest_Log(func_nd, TRUE);
00284 }
00285 }
00286
00287 extern void
00288 Unroll_Loop_By_Trip_Count(WN* outerloop, INT u);
00289
00290
00291 static INT64
00292 Num_Iters(WN* loop)
00293 {
00294 INT64 stepsz = Step_Size(loop);
00295 if (stepsz == 0) {
00296 return -1;
00297 }
00298
00299 DO_LOOP_INFO* dli = Get_Do_Loop_Info(loop);
00300 if (dli->LB->Num_Vec() > 1 || dli->UB->Num_Vec() > 1) {
00301 return -1;
00302 }
00303 ACCESS_VECTOR* ub = dli->UB->Dim(0);
00304 ACCESS_VECTOR* lb = dli->LB->Dim(0);
00305
00306 INT64 rval = -1;
00307 MEM_POOL_Push(&LNO_local_pool);
00308 ACCESS_VECTOR* sum = Add(lb, ub, &LNO_local_pool);
00309 if (sum->Is_Const()) {
00310 if (stepsz < 0) {
00311 stepsz = -stepsz;
00312 }
00313 rval = sum->Const_Offset >= 0 ? (sum->Const_Offset + stepsz)/stepsz : 0;
00314 }
00315 MEM_POOL_Pop(&LNO_local_pool);
00316 return rval;
00317 }
00318
00319 #define MAX_INNER_LOOPS 3
00320
00321 static INT
00322 Num_Inner_Loops(WN* loop)
00323 {
00324 INT max_inner_loops = 0;
00325 for (LWN_ITER* itr = LWN_WALK_TreeIter(WN_do_body(loop));
00326 itr;
00327 itr = LWN_WALK_TreeNext(itr)) {
00328 WN* wn = itr->wn;
00329 if (WN_operator(wn) == OPR_DO_LOOP) {
00330 INT num_inner_loops = 1;
00331 while ((wn = LWN_Get_Parent(wn)) != loop) {
00332 if (WN_operator(wn) == OPR_DO_LOOP) {
00333 num_inner_loops++;
00334 }
00335 }
00336 if (num_inner_loops > max_inner_loops) {
00337 max_inner_loops = num_inner_loops;
00338 #ifdef KEY
00339 if (max_inner_loops > MAX_INNER_LOOPS) {
00340 return max_inner_loops;
00341 }
00342 #else
00343 if (max_inner_loops >= MAX_INNER_LOOPS) {
00344 return MAX_INNER_LOOPS;
00345 }
00346
00347 #endif
00348 }
00349 }
00350 }
00351 return max_inner_loops;
00352 }
00353
00354 #ifdef KEY
00355
00356 static
00357 INT64 Loop_Size(WN* wn)
00358 {
00359 OPCODE opcode = WN_opcode(wn);
00360 if (OPCODE_is_leaf(opcode))
00361 return 1;
00362 else if (OPCODE_is_load(opcode))
00363 return 1;
00364 else if (opcode == OPC_BLOCK) {
00365 WN *kid = WN_first(wn);
00366 INT64 count = 0;
00367 while (kid) {
00368 count += Loop_Size(kid);
00369 kid = WN_next(kid);
00370 }
00371 return count;
00372 } else if (opcode == OPC_DO_LOOP) {
00373 INT64 count = Loop_Size(WN_start(wn));
00374 count += Loop_Size(WN_end(wn));
00375 INT64 count1 = Loop_Size(WN_do_body(wn));
00376 count1 += Loop_Size(WN_step(wn));
00377 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
00378 if (dli) {
00379 count1 *= MAX(1,dli->Est_Num_Iterations);
00380 }
00381 return (count+count1);
00382 }
00383
00384 OPERATOR oper = OPCODE_operator(opcode);
00385
00386 INT64 count = 0;
00387 INT kid_cnt = WN_kid_count(wn);
00388
00389 if ((oper == OPR_TRUNC) || (oper == OPR_RND) ||
00390 (oper == OPR_CEIL) || (oper == OPR_FLOOR) || (oper == OPR_INTRINSIC_OP)) {
00391 count++;
00392 } else if ((oper == OPR_REALPART) || (oper == OPR_IMAGPART) ||
00393 (oper == OPR_PARM) || (oper == OPR_PAREN)) {
00394
00395 } else if (OPCODE_is_expression(opcode) && (oper != OPR_CONST)) {
00396 if ((oper == OPR_MAX) || (oper == OPR_MIN) ||
00397 (oper == OPR_ADD) || (oper == OPR_SUB) || (oper == OPR_MPY) ||
00398 (oper == OPR_NEG))
00399 count++;
00400 else if ((oper == OPR_DIV || oper == OPR_SQRT))
00401 count = count + 10;
00402
00403 } else if (OPCODE_is_store(opcode)) {
00404 count++;
00405 kid_cnt = kid_cnt - 1;
00406 } else if ((oper == OPR_CALL) || (oper == OPR_PURE_CALL_OP)) {
00407 count = count + LNO_Full_Unrolling_Loop_Size_Limit;
00408 }
00409
00410 for (INT kidno=0; kidno<kid_cnt; kidno++) {
00411 WN *kid = WN_kid(wn,kidno);
00412 count += Loop_Size(kid);
00413 }
00414
00415 return count;
00416
00417 }
00418
00419 static BOOL Has_Negative_Offset_Preg(WN *tree)
00420 {
00421 if(WN_operator(tree)==OPR_BLOCK){
00422 for(WN *stmt = WN_first(tree); stmt; stmt=WN_next(stmt)){
00423 if(Has_Negative_Offset_Preg(stmt))
00424 return TRUE;
00425 }
00426 return FALSE;
00427 }
00428 if(WN_operator(tree)==OPR_LDID || WN_operator(tree)==OPR_STID){
00429 if (ST_class(WN_st(tree)) == CLASS_PREG &&
00430 WN_offset(tree) < 0) return TRUE;
00431 }
00432 for(INT kidno=0; kidno<WN_kid_count(tree); kidno++){
00433 if(Has_Negative_Offset_Preg(WN_kid(tree,kidno)))
00434 return TRUE;
00435 }
00436 return FALSE;
00437 }
00438 #endif
00439
00440 void
00441 Fully_Unroll_Short_Loops(WN* wn)
00442 {
00443 WN* first;
00444 WN* last;
00445 WN* next;
00446 OPERATOR oper = WN_operator(wn);
00447 if (oper == OPR_BLOCK) {
00448 wn = WN_first(wn);
00449 while (wn) {
00450 next = WN_next(wn);
00451 Fully_Unroll_Short_Loops(wn);
00452 wn = next;
00453 }
00454 return;
00455 }
00456 else if (oper == OPR_DO_LOOP &&
00457 !Do_Loop_Has_Calls(wn) &&
00458 #ifndef KEY
00459 (!Do_Loop_Has_Exits(wn) || Do_Loop_Is_Regular(wn)) &&
00460 !Do_Loop_Has_Conditional(wn) &&
00461 #else
00462 !Do_Loop_Has_Exits(wn) &&
00463 !Do_Loop_Has_Gotos(wn) &&
00464 #endif
00465 !Do_Loop_Has_Gotos(wn) &&
00466 !Do_Loop_Is_Mp(wn) &&
00467 !Is_Nested_Doacross(wn) &&
00468 #ifdef KEY
00469 Num_Inner_Loops(wn) <= MAX_INNER_LOOPS) {
00470
00471 if(Num_Inner_Loops(wn) == MAX_INNER_LOOPS &&
00472 Is_Invariant_Factorization_Beneficial(wn)) {
00473 DO_LOOP_INFO *dli = Get_Do_Loop_Info(wn);
00474 if(dli && dli->Delay_Full_Unroll==FALSE){
00475 dli->Delay_Full_Unroll = TRUE;
00476 return;
00477 }
00478 }
00479 #else
00480 Num_Inner_Loops(wn) < MAX_INNER_LOOPS) {
00481 #endif
00482 INT64 trip_count = Num_Iters(wn);
00483 if (trip_count == 0
00484 #ifdef KEY
00485
00486
00487 && Iterations(wn, &LNO_local_pool) == 0
00488 #endif
00489 ) {
00490 Remove_Zero_Trip_Loop(wn);
00491 return;
00492 }
00493 if (trip_count >= 1 && trip_count <= LNO_Full_Unrolling_Limit) {
00494 if (trip_count > 1) {
00495 #ifdef KEY
00496
00497
00498
00499
00500 if (Loop_Size(wn)*trip_count > LNO_Full_Unrolling_Loop_Size_Limit ||
00501
00502
00503 Has_Negative_Offset_Preg(WN_do_body(wn))){
00504
00505 Fully_Unroll_Short_Loops(WN_do_body(wn));
00506 return;
00507 }
00508 static INT count = 0;
00509 count ++;
00510 if (LNO_Full_Unroll_Skip_Before > count - 1 ||
00511 LNO_Full_Unroll_Skip_After < count - 1 ||
00512 LNO_Full_Unroll_Skip_Equal == count - 1) {
00513 Fully_Unroll_Short_Loops(WN_do_body(wn));
00514 return;
00515 }
00516 if (LNO_Full_Unroll_Outer == FALSE) {
00517 DO_LOOP_INFO *dli = Get_Do_Loop_Info(wn);
00518 WN* parent = LWN_Get_Parent(wn);
00519 while(parent && WN_operator(parent) != OPR_DO_LOOP &&
00520 WN_operator(parent) != OPR_FUNC_ENTRY)
00521 parent = LWN_Get_Parent(parent);
00522 if (!parent || WN_operator(parent) == OPR_FUNC_ENTRY) {
00523 Fully_Unroll_Short_Loops(WN_do_body(wn));
00524 return;
00525 }
00526 }
00527 #endif
00528 Unroll_Loop_By_Trip_Count(wn, trip_count);
00529
00530 }
00531 Remove_Unity_Trip_Loop(wn, TRUE, &first, &last, NULL, Du_Mgr);
00532
00533 wn = first;
00534 while (wn) {
00535 next = WN_next(wn);
00536 Fully_Unroll_Short_Loops(wn);
00537 if (wn == last) {
00538 break;
00539 }
00540 wn = next;
00541 }
00542 return;
00543 }
00544 }
00545 if (OPERATOR_is_scf(oper)) {
00546 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00547 Fully_Unroll_Short_Loops(WN_kid(wn, kidno));
00548 }
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559 extern void Parallel_And_Padding_Phase(PU_Info* current_pu,
00560 WN* func_nd)
00561 {
00562 Mark_Critical_Section_Loops(func_nd);
00563 Mark_Threadprivate_Loops(func_nd);
00564 IPA_LNO_Evaluate_Call_Infos(func_nd);
00565
00566 if (Run_autopar && LNO_Run_AP > 0 &&
00567 !Get_Trace(TP_LNOPT2, TT_LNO_NO_TRANSPOSE) &&
00568 !Get_Trace(TP_LNOPT2, TT_LNO_NO_AUTO_PARALLEL)) {
00569 Mark_Auto_Parallelizable_Loops(func_nd);
00570 Transpose_For_MP(func_nd);
00571 }
00572
00573 if (!Get_Trace(TP_LNOPT2, TT_LNO_NO_PAD) && LNO_Local_Pad_Size != 0) {
00574 Pad_First_Dim_Degenerates(func_nd);
00575
00576 if (LNO_Local_Pad_Size == (UINT32)-1) {
00577 Pad_Degenerates();
00578 }
00579 }
00580
00581 Doacross_Init(func_nd);
00582
00583 Auto_Parallelization(current_pu, func_nd);
00584 if (LNO_Autodist) {
00585 Automatic_Data_Distribute(func_nd);
00586 }
00587 Prompf_Dump(current_pu, func_nd);
00588 Mp_Tile(func_nd);
00589
00590 Doacross_Finish();
00591 IPA_LNO_Unevaluate_Call_Infos(func_nd);
00592
00593 }
00594
00595 BOOL Run_autopar_save;
00596
00597 #ifdef KEY
00598 static BOOL Skip_Simd;
00599 static BOOL Skip_HoistIf;
00600 static BOOL Skip_SVR;
00601 static BOOL Skip_Unswitch;
00602 #endif
00603 extern WN * Lnoptimizer(PU_Info* current_pu,
00604 WN *func_nd , DU_MANAGER *du_mgr,
00605 ALIAS_MANAGER *alias_mgr)
00606 {
00607 extern BOOL Run_lno;
00608 STDOUT = stdout;
00609
00610 MEM_POOL_Initialize(&ARA_memory_pool, "ARA_memory_pool", FALSE);
00611 MEM_POOL_Push(&ARA_memory_pool);
00612
00613 #ifdef KEY
00614 static INT pu_num = 0;
00615
00616 if (pu_num < LNO_Simd_Skip_Before
00617 || pu_num > LNO_Simd_Skip_After
00618 || pu_num == LNO_Simd_Skip_Equal)
00619 Skip_Simd = TRUE;
00620 else
00621 Skip_Simd = FALSE;
00622
00623 if (pu_num < LNO_HoistIf_Skip_Before
00624 || pu_num > LNO_HoistIf_Skip_After
00625 || pu_num == LNO_HoistIf_Skip_Equal)
00626 Skip_HoistIf = TRUE;
00627 else
00628 Skip_HoistIf = FALSE;
00629
00630 if (pu_num < LNO_SVR_Skip_Before
00631 || pu_num > LNO_SVR_Skip_After
00632 || pu_num == LNO_SVR_Skip_Equal)
00633 Skip_SVR = TRUE;
00634 else
00635 Skip_SVR = FALSE;
00636
00637 if (pu_num < LNO_Unswitch_Skip_Before
00638 || pu_num > LNO_Unswitch_Skip_After
00639 || pu_num == LNO_Unswitch_Skip_Equal)
00640 Skip_Unswitch = TRUE;
00641 else
00642 Skip_Unswitch = FALSE;
00643
00644 if (pu_num < LNO_Skip_Before
00645 || pu_num > LNO_Skip_After
00646 || pu_num == LNO_Skip_Equal)
00647 LNO_enabled = FALSE;
00648 else
00649 LNO_enabled = TRUE;
00650
00651 pu_num ++;
00652 #endif
00653
00654
00655 if ( !Du_Built(du_mgr) ) {
00656
00657
00658 Prompf_Init();
00659 if (Run_prompf)
00660 Print_Prompf_Transaction_Log(FALSE);
00661 Prompf_Dump(current_pu, func_nd);
00662 if (LNO_Prompl) {
00663 Print_Prompl_Msgs(current_pu, func_nd);
00664 }
00665 Prompf_Finish();
00666
00667 #ifdef KEY //just cheat the list_option, don't worry
00668
00669
00670 if(List_Enabled){
00671 Init_Prefetch_Options(func_nd);
00672 Mhd.Initialize();
00673 Mhd.Merge_Options(Mhd_Options);
00674 }
00675 #endif
00676
00677 MEM_POOL_Pop(&ARA_memory_pool);
00678 MEM_POOL_Delete(&ARA_memory_pool);
00679 return func_nd;
00680 }
00681
00682 if ((!Run_lno) ||
00683 (LNO_Opt == 0) ||
00684 (Get_Trace(TP_LNOPT, TT_LNO_SKIP_LNO))) {
00685 LNO_enabled = FALSE;
00686 }
00687
00688 Run_autopar_save = Run_autopar;
00689 ROUNDOFF Roundoff_Level_Save = Roundoff_Level;
00690
00691 Du_Mgr = du_mgr;
00692 WN_Register_Delete_Cleanup_Function(LWN_Delete_DU);
00693 VINDEX16 save_graph_capacity = GRAPH16_CAPACITY;
00694 GRAPH16_CAPACITY = LNO_Graph_Capacity;
00695 Current_Func_Node = func_nd;
00696 if (!lno_mempool_initialized) {
00697 MEM_POOL_Initialize(&LNO_default_pool, "LNO_default_pool", FALSE);
00698 MEM_POOL_Initialize(&LNO_local_pool, "LNO_local_pool", FALSE);
00699 MEM_POOL_Initialize(&SNL_local_pool, "SNL_local_pool", FALSE);
00700 lno_mempool_initialized = TRUE;
00701 }
00702
00703 snl_debug = 0;
00704 if (Get_Trace(TP_LNOPT, TT_LNO_SNL_DEBUG2))
00705 snl_debug += 2;
00706 if (Get_Trace(TP_LNOPT, TT_LNO_SNL_DEBUG1))
00707 snl_debug += 1;
00708
00709 LNO_Allow_Nonlinear = !Get_Trace(TP_LNOPT,TT_LNO_SKIP_NONLIN);
00710 LNO_Debug_Delinearization = Get_Trace(TP_LNOPT,TT_LNO_DEBUG_DELIN);
00711
00712 LNO_Allow_Delinearize = TRUE;
00713
00714
00715 LNO_Verbose = Get_Trace(TP_LNOPT, TT_LNO_VERBOSE);
00716
00717 if (LNO_Verbose) {
00718 fprintf(stdout, "Lno processing procedure: %s\n", Cur_PU_Name);
00719 fprintf(TFile, "Lno processing procedure: %s\n", Cur_PU_Name);
00720 }
00721
00722
00723
00724 Init_Prefetch_Options (func_nd);
00725
00726 Mhd.Initialize();
00727 Mhd.Merge_Options(Mhd_Options);
00728 if (snl_debug)
00729 Mhd.Print(TFile);
00730
00731 MEM_POOL_Push(&LNO_local_pool);
00732 MEM_POOL_Push(&SNL_local_pool);
00733 MEM_POOL_Push_Freeze(&LNO_default_pool);
00734
00735 Alias_Mgr = alias_mgr;
00736 red_manager = NULL;
00737 Array_Dependence_Graph = NULL;
00738
00739 Parent_Map = WN_MAP_Create(&LNO_default_pool);
00740 WN_SimpParentMap = Parent_Map;
00741 FmtAssert(Parent_Map != -1,("Ran out of mappings in Lnoptimizer"));
00742 LNO_Info_Map = WN_MAP_Create(&LNO_default_pool);
00743 FmtAssert(LNO_Info_Map != -1,("Ran out of mappings in Lnoptimizer"));
00744 Array_Dependence_Map = WN_MAP_Create(&LNO_default_pool);
00745 FmtAssert(Array_Dependence_Map != -1,("Ran out of mappings in Lnoptimizer"));
00746 Stmt_Dependence_Map = WN_MAP_Create(&LNO_default_pool);
00747 FmtAssert(Stmt_Dependence_Map != -1,("Ran out of mappings in Lnoptimizer"));
00748
00749 Safe_Spec_Map = WN_MAP_Create(&LNO_default_pool);
00750 FmtAssert(Safe_Spec_Map != WN_MAP_UNDEFINED,
00751 ("Ran out of mappings in Lnoptimizer"));
00752
00753
00754 Start_Timer ( T_LNOParentize_CU );
00755 LWN_Parentize (func_nd);
00756 Stop_Timer ( T_LNOParentize_CU );
00757 Prompf_Init();
00758 WB_Set_Sanity_Check_Level(WBC_DU_ONLY);
00759
00760
00761 #ifdef Is_True_On
00762 Du_Sanity_Check(func_nd);
00763 #endif
00764
00765 if (snl_debug) {
00766 fprintf(TFile, "AFTER PREOPT:\n");
00767 Dump_WN(func_nd, TFile, snl_debug);
00768 }
00769
00770 BOOL simp_state_save = WN_Simplifier_Enable(TRUE);
00771 BOOL simp_fold_iload_save = WN_Simp_Fold_ILOAD;
00772 WN_Simp_Fold_ILOAD = FALSE;
00773
00774 #ifdef _NEW_SYMTAB
00775 if (!LNO_Run_Lego_Set) LNO_Run_Lego = PU_mp_needs_lno(Get_Current_PU());
00776 #else
00777 if (!LNO_Run_Lego_Set) LNO_Run_Lego = SYMTAB_mp_needs_lno(Current_Symtab);
00778 #endif
00779
00780 extern BOOL Run_lno;
00781
00782
00783
00784
00785 Is_True (Run_lno || LNO_Run_Lego || LNO_Run_Lego_Set
00786 || Run_autopar && LNO_Run_AP > 0,
00787 ("LNO on PU %s: Run_lno == FALSE, and no distr-arrays\n",
00788 Cur_PU_Name));
00789
00790 if ( List_Cite ) {
00791 LNO_Analysis=Lst_File;
00792 }
00793 if (!Run_lno && !LNO_Run_Lego && !(Run_autopar && LNO_Run_AP > 0))
00794 goto return_point;
00795
00796 {
00797 Permutation_Arrays = CXX_NEW(PERMUTATION_ARRAYS(&LNO_default_pool),
00798 &LNO_default_pool);
00799
00800 if (LNO_Run_Lego && !LNO_enabled) {
00801
00802 Lego_OZero_Driver(current_pu, func_nd);
00803 goto return_point;
00804 }
00805
00806 if (Get_Trace(TP_LNOPT, TT_LNO_SKIP_LNO)) {
00807 goto return_point;
00808 }
00809
00810
00811
00812
00813 BOOL has_do_loops = Mark_Code(func_nd, TRUE, TRUE);
00814
00815
00816 if (!LNO_enabled && !Run_autopar && !Run_lno) {
00817 goto return_point;
00818 }
00819
00820 if (LNO_Run_call_info) {
00821 Call_Info_Walk(func_nd);
00822 Mark_Code(func_nd, FALSE, TRUE);
00823 }
00824
00825
00826 if (LNO_Run_Lego) {
00827 Lego_PU_Init ();
00828 Lego_Read_Pragmas (func_nd);
00829 void Lego_Fix_Local(WN *func_nd);
00830 if (LNO_Run_Lego_Localizer) Lego_Fix_Local(func_nd);
00831 void Lego_Fix_IO(WN *func_nd, BOOL *has_do_loops);
00832 Lego_Fix_IO(func_nd,&has_do_loops);
00833 }
00834
00835
00836
00837 Start_Timer ( T_LNOAccess_CU );
00838 LNO_Build_Access(func_nd, &LNO_default_pool);
00839 Stop_Timer ( T_LNOAccess_CU );
00840 if (LNO_Verbose) {
00841 LNO_Print_Access(TFile,func_nd);
00842 }
00843
00844 if (Run_autopar && LNO_enabled)
00845 IPA_LNO_Map_Calls(func_nd, IPA_LNO_File);
00846
00847 if (!has_do_loops) {
00848 goto return_point;
00849 }
00850
00851 if (LNO_Full_Unrolling_Limit != 0) {
00852 Fully_Unroll_Short_Loops(func_nd);
00853 }
00854
00855 #ifdef KEY
00856 if (LNO_Build_Scalar_Reductions || Roundoff_Level >= ROUNDOFF_ASSOC) {
00857 #else
00858 if (Roundoff_Level >= ROUNDOFF_ASSOC) {
00859 #endif
00860 red_manager = CXX_NEW
00861 (REDUCTION_MANAGER(&LNO_default_pool), &LNO_default_pool);
00862 red_manager->Build(func_nd,TRUE,FALSE);
00863 }
00864
00865
00866
00867 if (Eliminate_Dead_SCF(func_nd,LWN_Delete_Tree)) {
00868 Mark_Code(func_nd, FALSE, TRUE);
00869
00870 }
00871
00872 if (LNO_Opt > 0) {
00873
00874 if (!Get_Trace(TP_LNOPT2, TT_SHACKLE_ONLY) && !LNO_Shackle)
00875 Hoist_Conditionals(func_nd);
00876 }
00877
00878
00879 Start_Timer ( T_LNOBuildDep_CU );
00880
00881
00882
00883 if (Liberal_Ivdep && Cray_Ivdep) {
00884 DevWarn("Both Liberal_Ivdep and Cray_Ivdep set, Liberal_Ivdep ignored");
00885 }
00886
00887 BOOL LNO_skip=FALSE;
00888
00889
00890 if ( Query_Skiplist ( Optimization_Skip_List, Current_PU_Count() ) )
00891 {
00892 if ( Show_Progress ) {
00893 ErrMsg ( EC_Skip_PU, " LNO", Current_PU_Count(), Cur_PU_Name );
00894 }
00895 LNO_skip=TRUE;
00896 }
00897
00898 if ((LNO_Opt == 0 || LNO_skip || !LNO_enabled) && !(Run_autopar && LNO_Run_AP > 0)) {
00899 GRAPH16_CAPACITY = save_graph_capacity;
00900 Build_CG_Dependence_Graph (func_nd);
00901 Stop_Timer ( T_LNOBuildDep_CU );
00902
00903 if (!Get_Trace(TP_LNOPT, TT_LNO_GUARD)) {
00904 Guard_Dos(func_nd);
00905 }
00906 goto return_point;
00907 }
00908 else {
00909 BOOL graph_is_ok = Build_Array_Dependence_Graph (func_nd);
00910 Stop_Timer ( T_LNOBuildDep_CU );
00911 if (!graph_is_ok)
00912 goto return_point;
00913 }
00914
00915 if (!LNO_enabled && (Run_autopar && LNO_Run_AP > 0)) {
00916 LWN_Process_FF_Pragmas(func_nd);
00917 Parallel_And_Padding_Phase(current_pu, func_nd);
00918 goto return_point;
00919 }
00920
00921 LNO_Tlog = Get_Trace ( TP_PTRACE1, TP_PTRACE1_LNO );
00922
00923 Hoist_Varying_Lower_Bounds(func_nd);
00924 If_MinMax(func_nd);
00925 Dead_Store_Eliminate_Arrays(Array_Dependence_Graph);
00926 Array_Substitution(func_nd);
00927 Reverse_Loops(func_nd);
00928
00929 if (Roundoff_Level >= ROUNDOFF_ASSOC) {
00930
00931 red_manager->Build(func_nd,FALSE,TRUE,Array_Dependence_Graph);
00932
00933 if (Eager_Level >= 4) {
00934 Eliminate_Zero_Mult(func_nd, Array_Dependence_Graph);
00935 }
00936 }
00937
00938
00939 if (LNO_Sclrze) {
00940 Scalarize_Arrays(Array_Dependence_Graph,0,1,red_manager);
00941 }
00942
00943
00944
00945
00946 if (Run_autopar && LNO_Run_AP > 0 &&
00947 !Get_Trace(TP_LNOPT2, TT_LNO_NO_TRANSPOSE) &&
00948 !Get_Trace(TP_LNOPT2, TT_LNO_NO_AUTO_PARALLEL)) {
00949 IPA_LNO_Evaluate_Call_Infos(func_nd);
00950 Mark_Auto_Parallelizable_Loops(func_nd);
00951 Transpose_For_MP(func_nd);
00952 IPA_LNO_Unevaluate_Call_Infos(func_nd);
00953 }
00954 #ifdef KEY
00955 if (LNO_Run_Unswitch && !Skip_Unswitch && Loop_Unswitch_SCF(func_nd)) {
00956
00957 Mark_Code(func_nd, FALSE, TRUE);
00958 }
00959 #endif
00960 #ifdef TARG_X8664
00961 if (LNO_Run_Simd > 0)
00962 Mark_Auto_Vectorizable_Loops(func_nd);
00963 #endif
00964
00965
00966 if (!LNO_Ignore_Pragmas) {
00967 Fission_Init();
00968 Fusion_Init();
00969 LWN_Process_FF_Pragmas(func_nd);
00970 }
00971
00972 Canonicalize_Unsigned_Loops(func_nd);
00973
00974 BOOL do_ara = ((Get_Trace(TP_LNOPT2,TT_LNO_RUN_ARA)
00975 || Run_autopar && LNO_Run_AP > 0)
00976 && Get_Trace(TP_LNOPT2, TT_LNO_NO_AUTO_PARALLEL));
00977 if (do_ara)
00978 Perform_ARA_and_Parallelization(current_pu, func_nd);
00979
00980 if (LNO_Run_Lego) {
00981 Lego_Skew_Indices(func_nd);
00982 Lego_Compute_Tile_Peel (func_nd);
00983 }
00984
00985 Lego_Tile(func_nd, FALSE);
00986 if (LNO_Run_Lego) {
00987 if (!Get_Trace(TP_LNOPT2, TT_LEGO_DISABLE_INTERCHANGE))
00988 Lego_Interchange(func_nd);
00989 extern void RR_Map_Setup (WN* func_wn);
00990 RR_Map_Setup(func_nd);
00991 Lego_Peel(func_nd);
00992 }
00993
00994 BOOL early_exit = FALSE;
00995 {
00996 BOOL do_fiz_fuse = !Get_Trace(TP_LNOPT,TT_LNO_SKIP_FIZ_FUSE);
00997 BOOL do_p25 = !Get_Trace(TP_LNOPT,TT_LNO_SKIP_GS);
00998 BOOL do_inner_fission = !Get_Trace(TP_LNOPT,TT_LNO_SKIP_INNER_FISSION);
00999
01000 Fission_Init();
01001 Fusion_Init();
01002
01003 WB_Set_Sanity_Check_Level(WBC_FULL_SNL);
01004
01005 if (!Get_Trace(TP_LNOPT, TT_LNO_NORENAME))
01006 #ifdef KEY
01007 #ifdef TARG_X8664
01008
01009
01010 if (!Skip_SVR && LNO_SVR && (LNO_SVR_Phase1 || Is_Target_32bit()))
01011 #else
01012 if (!Skip_SVR && LNO_SVR && LNO_SVR_Phase1)
01013 #endif
01014 #endif
01015 {
01016 #ifdef KEY
01017
01018
01019 if(red_manager)
01020 red_manager->Erase(func_nd);
01021 #endif
01022 if (Scalar_Variable_Renaming(func_nd))
01023 LNO_Build_Access(func_nd,&LNO_default_pool);
01024 #ifdef KEY
01025
01026 if(red_manager){
01027 red_manager->Build(func_nd, TRUE, FALSE);
01028 if (Roundoff_Level >= ROUNDOFF_ASSOC)
01029 red_manager->Build(func_nd,FALSE,TRUE,Array_Dependence_Graph);
01030 }
01031 #endif
01032 }
01033 early_exit = Phase_123(current_pu, func_nd, do_fiz_fuse, do_p25,
01034 do_inner_fission);
01035
01036 Fission_Finish();
01037 Fusion_Finish();
01038 }
01039 if (early_exit)
01040 goto return_point;
01041
01042
01043
01044 Prefetch_Driver (func_nd, Array_Dependence_Graph);
01045
01046
01047 if (LNO_Sclrze) {
01048 Scalarize_Arrays(Array_Dependence_Graph,1,0,red_manager);
01049 }
01050
01051 if (LNO_Aequiv) {
01052 AEQUIV aequiv(func_nd,Array_Dependence_Graph);
01053 aequiv.Equivalence_Arrays();
01054 }
01055 if (!Get_Trace(TP_LNOPT, TT_LNO_GUARD)) {
01056 Guard_Dos(func_nd);
01057 if (LNO_Minvar) {
01058 Minvariant_Removal(func_nd, Array_Dependence_Graph);
01059 }
01060 }
01061
01062 if (!LNO_Ignore_Pragmas) {
01063 LNO_Insert_Pragmas(func_nd);
01064 }
01065
01066 #ifdef Is_True_On
01067 MP_Sanity_Check_Func(func_nd);
01068 LNO_Check_Graph(Array_Dependence_Graph);
01069 #endif
01070
01071 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2) ||
01072 Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
01073 fprintf(TFile, "%sLNO dependence graph (after transformation)\n%s",
01074 DBar, DBar);
01075 Array_Dependence_Graph->Print(TFile);
01076 }
01077
01078
01079 Build_CG_Dependence_Graph (Array_Dependence_Graph);
01080
01081 if (LNO_Cse && (Roundoff_Level >= ROUNDOFF_ASSOC)) {
01082 Inter_Iteration_Cses(func_nd);
01083 }
01084
01085 #ifdef KEY // bug 10644
01086
01087
01088 if(!Get_Trace(TP_LNOPT, TT_LNO_GUARD) && LNO_Invariant_Factorization
01089 && Roundoff_Level >= ROUNDOFF_ASSOC){
01090 Invariant_Factorization(func_nd);
01091 }
01092 #endif
01093 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2) ||
01094 Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
01095 fprintf(TFile, "%sLNO dep graph for CG, after LNO\n%s", DBar, DBar);
01096 Current_Dep_Graph->Print(TFile);
01097 fprintf(TFile, "%s", DBar);
01098 }
01099
01100 }
01101 return_point:
01102
01103 if (Alloca_Dealloca_On && PU_has_alloca(Get_Current_PU())) {
01104 Convert_Intrinsic_To_Alloca_Dealloca (func_nd);
01105 }
01106
01107 if (!prompf_dumped)
01108 Prompf_Dump(current_pu, func_nd);
01109 Prompf_Post_Dump(current_pu, func_nd);
01110 #ifndef _NEW_SYMTAB
01111 if (LNO_Mem_Sim) {
01112 void Instrument_Mem_Sim (WN *wn);
01113 Instrument_Mem_Sim (func_nd);
01114 }
01115 #endif
01116 Run_autopar = Run_autopar_save;
01117 Roundoff_Level = Roundoff_Level_Save;
01118
01119
01120 if (LNO_Run_Lego) {
01121 Lego_Lower_Pragmas (func_nd);
01122 Lego_PU_Fini ();
01123
01124
01125 }
01126 WN_Simplify_Tree(func_nd);
01127
01128 if (LNO_Analysis)
01129 Lisp_Loops(func_nd, LNO_Analysis);
01130
01131 WB_Set_Sanity_Check_Level(WBC_DISABLE);
01132 WN_Simplifier_Enable(simp_state_save);
01133 WN_Simp_Fold_ILOAD = simp_fold_iload_save;
01134 WN_Remove_Delete_Cleanup_Function(LWN_Delete_LNO_dep_graph);
01135
01136 if (red_manager) CXX_DELETE(red_manager,&LNO_default_pool);
01137 if (Array_Dependence_Graph) {
01138 CXX_DELETE(Array_Dependence_Graph,&LNO_default_pool);
01139 Array_Dependence_Graph = NULL;
01140 }
01141
01142
01143 WN_MAP_Delete(Parent_Map);
01144
01145 WN_SimpParentMap = WN_MAP_UNDEFINED;
01146 WN_MAP_Delete(LNO_Info_Map);
01147 WN_MAP_Delete(Stmt_Dependence_Map);
01148 WN_MAP_Delete(Array_Dependence_Map);
01149 WN_MAP_Delete(Safe_Spec_Map);
01150 Safe_Spec_Map = WN_MAP_UNDEFINED;
01151
01152 MEM_POOL_Pop(&LNO_local_pool);
01153 MEM_POOL_Pop(&SNL_local_pool);
01154 MEM_POOL_Pop_Unfreeze(&LNO_default_pool);
01155
01156 WN_Remove_Delete_Cleanup_Function(LWN_Delete_DU);
01157 GRAPH16_CAPACITY = save_graph_capacity;
01158
01159 if (LNO_Verbose) {
01160 fprintf(stdout, "Lno DONE processing procedure: %s\n", Cur_PU_Name);
01161 fprintf(TFile, "Lno DONE processing procedure: %s\n", Cur_PU_Name);
01162 }
01163 Prompf_Finish();
01164
01165 MEM_POOL_Pop(&ARA_memory_pool);
01166 MEM_POOL_Delete(&ARA_memory_pool);
01167 return func_nd;
01168 }
01169
01170
01171
01172
01173
01174
01175
01176
01177 extern BOOL Build_Array_Dependence_Graph (WN* func_nd) {
01178
01179 Array_Dependence_Graph =
01180 CXX_NEW(ARRAY_DIRECTED_GRAPH16(100,500,Array_Dependence_Map,
01181 DEPV_ARRAY_ARRAY_GRAPH), &LNO_default_pool);
01182 BOOL graph_ok=Array_Dependence_Graph->Build(func_nd,&LNO_default_pool);
01183 WB_Set_Sanity_Check_Level(WBC_DU_AND_ARRAY);
01184 WN_Register_Delete_Cleanup_Function(LWN_Delete_LNO_dep_graph);
01185
01186
01187 if (!graph_ok) return FALSE;
01188 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2) ||
01189 Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
01190 fprintf(TFile, "%sLNO dependence graph (before transformation)\n%s",
01191 DBar, DBar);
01192 Array_Dependence_Graph->Print(TFile);
01193 }
01194 return TRUE;
01195 }
01196
01197
01198
01199
01200
01201
01202 extern void Build_CG_Dependence_Graph (WN* func_nd) {
01203 if (!Current_Dep_Graph) {
01204 Current_Dep_Graph = CXX_NEW(ARRAY_DIRECTED_GRAPH16(100, 500,
01205 WN_MAP_DEPGRAPH, DEP_ARRAY_GRAPH), Malloc_Mem_Pool);
01206 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
01207 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
01208 }
01209
01210 BOOL graph_ok=Current_Dep_Graph->Build(func_nd);
01211 #ifndef KEY
01212 Is_True(graph_ok,("Overflow converting to cg dependence graph"));
01213 #else
01214 #ifdef Is_True_On
01215 if (!graph_ok)
01216 DevWarn("Overflow converting to cg dependence graph");
01217 #endif
01218 #endif
01219 if (!graph_ok) Current_Dep_Graph->Erase_Graph();
01220
01221 if (graph_ok) {
01222 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2) ||
01223 Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
01224 fprintf(TFile, "%sLNO dep graph for CG, after LNO\n%s", DBar, DBar);
01225 Current_Dep_Graph->Print(TFile);
01226 fprintf(TFile, "%s", DBar);
01227 }
01228 }
01229 WN_Register_Delete_Cleanup_Function(LWN_Delete_CG_dep_graph);
01230 }
01231
01232
01233
01234
01235
01236
01237 extern void Build_CG_Dependence_Graph (ARRAY_DIRECTED_GRAPH16*
01238 Array_Dependence_Graph) {
01239
01240 if (!Current_Dep_Graph) {
01241 Current_Dep_Graph = CXX_NEW(ARRAY_DIRECTED_GRAPH16(100, 500,
01242 WN_MAP_DEPGRAPH, DEP_ARRAY_GRAPH), Malloc_Mem_Pool);
01243 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
01244 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
01245 }
01246 BOOL graph_ok=Current_Dep_Graph->Build(Array_Dependence_Graph);
01247 Is_True(graph_ok,("Overflow converting to cg dependence graph"));
01248 if (!graph_ok) Current_Dep_Graph->Erase_Graph();
01249 WN_Register_Delete_Cleanup_Function(LWN_Delete_CG_dep_graph);
01250 }
01251
01252
01253 void EST_REGISTER_USAGE::Set_Est_Regs(
01254 INT fp_est, INT fp_regs_available,
01255 INT int_est, INT int_regs_available,
01256 INT tlb_est, INT tlb_available)
01257 {
01258 _fp_est = fp_est;
01259 _int_est = int_est;
01260 _tlb_est = tlb_est;
01261 _fits = (_fp_est >= 0 && fp_regs_available >= 0 &&
01262 fp_est <= fp_regs_available &&
01263 _int_est >= 0 && int_regs_available >= 0 &&
01264 int_est <= int_regs_available &&
01265 _tlb_est >= 0 && tlb_available >= 0 &&
01266 tlb_est <= tlb_available);
01267 _no_fit = (_fp_est >= 0 && fp_regs_available >= 0 &&
01268 fp_est > fp_regs_available ||
01269 _int_est >= 0 && int_regs_available >= 0 &&
01270 int_est > int_regs_available);
01271 }
01272
01273 void EST_REGISTER_USAGE::Print(FILE* f)
01274 {
01275 fprintf(f, "fp est=%d, int est=%d, tlb est=%d <%s>", _fp_est, _int_est,
01276 _tlb_est,
01277 _fits ? "FITS" : _no_fit ? "NO FIT" : "DON'T KNOW IF FITS");
01278 }
01279
01280 void DO_LOOP_INFO::Print(FILE *fp, INT indentation)
01281 {
01282 char buf[80];
01283 INT i;
01284
01285 for (i = 0; i < indentation && i < 79; i++)
01286 buf[i] = ' ';
01287 buf[i] = '\0';
01288
01289 if (Has_Calls) fprintf(fp,"%sIt has calls \n", buf);
01290 #ifdef KEY //bug 14284
01291 if (Has_Nested_Calls) fprintf(fp,"%sIt has calls to nested functions \n", buf);
01292 #endif
01293 if (Has_Unsummarized_Calls) fprintf(fp,"%sIt has unsummarized calls \n", buf);
01294 if (Has_Unsummarized_Call_Cost)
01295 fprintf(fp,"%sIt has unsummarized call cost \n", buf);
01296 if (Has_Threadprivate)
01297 fprintf(fp,"%sIt has THREADPRIVATE variables \n", buf);
01298 if (Has_Gotos) fprintf(fp,"%sIt has non-DO or non-IF control flow\n", buf);
01299 if (Has_Gotos_This_Level) fprintf(fp,"%sIt has non-DO or non-IF control flow to this level\n", buf);
01300 if (Has_Exits) fprintf(fp,"%sIt has exits\n", buf);
01301 if (Has_Bad_Mem) fprintf(fp,"%sIt has bad memory references \n", buf);
01302 if (Has_Barriers) fprintf(fp,"%sIt has barriers\n", buf);
01303 if (Cannot_Interchange) fprintf(fp,"%sPragma says can't interchange\n", buf);
01304 if (Cannot_Block) fprintf(fp,"%sPragma says can't block\n", buf);
01305 if (Pragma_Cannot_Concurrentize)
01306 fprintf(fp,"%sPragma says can't concurrentize\n", buf);
01307 if (Pragma_Prefer_Concurrentize)
01308 fprintf(fp,"%sPragma says prefer to concurrentize this loop\n", buf);
01309 if (Serial_Version_of_Concurrent_Loop)
01310 fprintf(fp, "%sLoop is in serial version of parallel loop\n", buf);
01311 if (Auto_Parallelized)
01312 fprintf(fp,"%sAuto Parallelized\n", buf);
01313 if (Required_Unroll) fprintf(fp,"%sPragma requires %d unrolls\n", buf,
01314 Required_Unroll);
01315 BOOL required_blks = FALSE;
01316 for (i = 0; i < MHD_MAX_LEVELS; i++)
01317 if (Required_Blocksize[i] >= 0)
01318 required_blks = TRUE;
01319 if (required_blks) {
01320 fprintf(fp,"%sPragma requires blocksizes of", buf);
01321 for (i = 0; i < MHD_MAX_LEVELS; i++)
01322 if (Required_Blocksize[i] >= 0)
01323 fprintf(fp," L%d=%d", i+1, Required_Blocksize[i]);
01324 fprintf(fp,"\n");
01325 }
01326 if (Blockable_Specification)
01327 fprintf(fp,"%sThe %d loops from here in are blockable, says a pragma\n",
01328 buf, Blockable_Specification);
01329 if (Permutation_Spec_Count > 0) {
01330 fprintf(fp,"%sThe permutation requested in a pragma, from here in:", buf);
01331 for (INT i = 0; i < Permutation_Spec_Count; i++)
01332 fprintf(fp," %d",Permutation_Spec_Array[i]);
01333 fprintf(fp,"\n");
01334 }
01335
01336 if (Required_Unroll) fprintf(fp,"%sPragma requires %d unrolls\n", buf,
01337 Required_Unroll);
01338 if (_wind_down_flags) {
01339 fprintf(fp, "%s_wind_down_flags=", buf);
01340 if (_wind_down_flags&CWD) fprintf(fp, "<cache winddown>");
01341 if (_wind_down_flags&RWD) fprintf(fp, "<reg winddown>");
01342 if (_wind_down_flags&ICWD) fprintf(fp, "<in cache winddown>");
01343 if (_wind_down_flags&IRWD) fprintf(fp, "<in reg winddown>");
01344 if (_wind_down_flags&UNIMPORTANT) fprintf(fp, "<generally unimportant>");
01345 fprintf(fp, "\n");
01346 }
01347 if (Est_Register_Usage.Fits() || Est_Register_Usage.Does_Not_Fit() ||
01348 Est_Register_Usage.Est_Fp_Regs() >= 0 ||
01349 Est_Register_Usage.Est_Int_Regs() >= 0) {
01350 fprintf(fp, "%sEst_Register_Usage: ", buf);
01351 Est_Register_Usage.Print(fp);
01352 fprintf(fp, "\n");
01353 }
01354 if (Is_Inner)
01355 fprintf(fp,"%sIs_Inner is %d \n", buf, Is_Inner);
01356 if (Is_Backward)
01357 fprintf(fp,"%sIs_Backward is %d \n", buf, Is_Backward);
01358 if (Is_Outer_Lego_Tile)
01359 fprintf(fp,"%sIs_Outer_Lego_Tile is %d \n", buf, Is_Outer_Lego_Tile);
01360 if (Is_Inner_Lego_Tile)
01361 fprintf(fp,"%sIs_Inner_Lego_Tile is %d \n", buf, Is_Inner_Lego_Tile);
01362 if (Is_Processor_Tile)
01363 fprintf(fp,"%sIs_Processor_Tile is %d \n", buf, Is_Processor_Tile);
01364 if (Suggested_Parallel)
01365 fprintf(fp,"%sSuggested_Parallel is %d \n", buf, Suggested_Parallel);
01366 if (Parallelizable)
01367 fprintf(fp,"%sParallelizable is %d \n", buf, Parallelizable);
01368 #ifdef KEY
01369 if (Vectorizable)
01370 fprintf(fp,"%sVectorizable is %d \n", buf, Vectorizable);
01371 #endif
01372 if (Last_Value_Peeled)
01373 fprintf(fp,"%sLast Value Peeled is %d \n", buf, Last_Value_Peeled);
01374 if (Not_Enough_Parallel_Work)
01375 fprintf(fp,"%sNot_Enough_Parallel_Work is %d \n", buf,
01376 Not_Enough_Parallel_Work);
01377 if (Inside_Critical_Section)
01378 fprintf(fp, "%sInside_Critical_Section is %d \n", buf,
01379 Inside_Critical_Section);
01380 if (Is_Doacross) {
01381 fprintf(fp, "Is_Doacross is 1 \n");
01382 fprintf(fp, "Doacross_Tile_Size is %d \n", Doacross_Tile_Size);
01383 fprintf(fp, "Sync_Distances[0] = %d \n", Sync_Distances[0]);
01384 fprintf(fp, "Sync_Distances[1] = %d \n", Sync_Distances[1]);
01385 }
01386 if (Is_Ivdep) fprintf(fp,"Is_Ivdep is 1 \n");
01387 if (Is_Concurrent_Call) fprintf(fp,"%sIs_Concurrent_Call is 1 \n",buf);
01388 if (Concurrent_Directive) fprintf(fp,"%sConcurrent_Directive is 1 \n",buf);
01389 if (Work_Estimate != 0)
01390 fprintf(fp,"%sWork_Estimate is %g \n", buf, Work_Estimate);
01391 if (Lego_Mp_Key_Lower != 0 || Lego_Mp_Key_Upper != 0)
01392 fprintf(fp,"%sLego_Mp_Tile Key [%d:%d;%d] \n", buf,
01393 Lego_Mp_Key_Lower, Lego_Mp_Key_Upper, Lego_Mp_Key_Depth);
01394 if (Lego_LB_Symbols) {
01395 for (INT i=0; i<Lego_Mp_Key_Upper-Lego_Mp_Key_Lower+1; i++)
01396 Lego_LB_Symbols[i].Print(fp);
01397 }
01398 fprintf(fp,"%sDepth is %d \n", buf, Depth);
01399 if (Lego_Info != NULL) {
01400 fprintf(fp,"%sLego Info is: \n", buf);
01401 Lego_Info->Print(fp);
01402 }
01403 if (Mp_Info != NULL) {
01404 fprintf(fp,"%sMp Info is: \n", buf);
01405 Mp_Info->Print(fp);
01406 }
01407 fprintf(fp,"%sThe lb is ", buf);
01408 if (LB) LB->Print(fp,TRUE);
01409 else fprintf(fp, "<null>\n");
01410 fprintf(fp,"%sThe ub is ", buf);
01411 if (UB) UB->Print(fp,TRUE);
01412 else fprintf(fp, "<null>\n");
01413 fprintf(fp,"%sThe step is ", buf);
01414 if (Step) {
01415 Step->Print(fp);
01416 fprintf(fp,"\n");
01417 }
01418 else
01419 fprintf(fp, "<null>\n");
01420 fprintf(fp,"%sWe estimate this loop has %lld iterations. %s\n",
01421 buf, Est_Num_Iterations, Num_Iterations_Symbolic?"<symbolic>":"");
01422 if (Est_Max_Iterations_Index != -1)
01423 fprintf(fp,"%sThis loop has at most %lld iterations due to array bounds.\n",
01424 buf, Est_Max_Iterations_Index);
01425 if (Is_Inner_Tile)
01426 if (Tile_Size > 0)
01427 fprintf(fp, "%sLoop is an inner tile with tile size of %d.\n",
01428 buf, Tile_Size);
01429 else
01430 fprintf(fp, "%sLoop is an inner tile with unknown tile size.\n",
01431 buf);
01432 if (Is_Outer_Tile)
01433 fprintf(fp, "%sLoop is an outer tile.\n", buf);
01434 if (ARA_Info != NULL)
01435 ARA_Info->WB_Print(fp);
01436 }
01437
01438 static void Fiz_Fuse_Phase(WN* body, FIZ_FUSE_INFO *ffi)
01439 {
01440 FmtAssert(WN_opcode(body) == OPC_BLOCK, ("Bad block to Fiz_Fuse_Phase()"));
01441
01442 WN* next_wn = NULL;
01443 for (WN* wn = WN_first(body); wn; wn = next_wn) {
01444 next_wn = WN_next(wn);
01445 OPCODE opc = WN_opcode(wn);
01446
01447 switch (opc) {
01448 case OPC_DO_LOOP:
01449 if (Do_Loop_Is_Mp(wn)) {
01450 Fiz_Fuse_Phase(WN_do_body(wn),ffi);
01451 } else {
01452 MEM_POOL_Push(&LNO_local_pool);
01453 *ffi += *Fiz_Fuse(wn,ffi,&LNO_default_pool);
01454 MEM_POOL_Pop(&LNO_local_pool);
01455 }
01456 break;
01457 case OPC_REGION:
01458 Fiz_Fuse_Phase(WN_region_body(wn),ffi);
01459 break;
01460 case OPC_IF:
01461 case OPC_DO_WHILE:
01462 case OPC_WHILE_DO:
01463 (void)If_While_Region_Fiz_Fuse(wn, ffi, &LNO_default_pool);
01464 break;
01465 }
01466 }
01467 }
01468
01469
01470
01471 extern BOOL Phase_123(PU_Info* current_pu, WN* func_nd,
01472 BOOL do_fiz_fuse, BOOL do_phase25,
01473 BOOL do_inner_fission)
01474 {
01475 #ifdef Is_True_On
01476 if (LNO_Verbose) {
01477 fprintf(stdout, "Sanity check on 123 entry\n");
01478 fflush(stdout);
01479 }
01480 LWN_Check_Parentize(func_nd);
01481 SNL_Sanity_Check_Func(func_nd);
01482 MP_Sanity_Check_Func(func_nd);
01483 LNO_Check_Graph(Array_Dependence_Graph);
01484 if (LNO_Verbose) {
01485 fprintf(stdout, "Sanity check on 123 entry complete\n");
01486 fflush(stdout);
01487 }
01488 #endif
01489
01490 if (snl_debug >= 3) {
01491 WN* f2 = WN_Simplify_Tree(func_nd);
01492 Is_True(f2 == func_nd, ("Bug in simplification test code"));
01493 LWN_Parentize(func_nd);
01494 }
01495
01496 FIZ_FUSE_INFO *ffi=
01497 CXX_NEW(FIZ_FUSE_INFO(&LNO_default_pool),&LNO_default_pool);
01498
01499 FIZ_FUSE_INFO *new_ffi=
01500 CXX_NEW(FIZ_FUSE_INFO(&LNO_default_pool),&LNO_default_pool);
01501
01502 FIZ_FUSE_INFO *outer_ffi=
01503 CXX_NEW(FIZ_FUSE_INFO(&LNO_default_pool),&LNO_default_pool);
01504
01505 if (do_fiz_fuse) {
01506 Fiz_Fuse_Phase(WN_func_body(func_nd), ffi);
01507
01508 #ifdef Is_True_On
01509 MP_Sanity_Check_Func(func_nd);
01510 LNO_Check_Graph(Array_Dependence_Graph);
01511 #endif
01512
01513 outer_ffi->Build(func_nd);
01514 if (LNO_Test_Dump)
01515 for (INT i = 0; i < outer_ffi->Num_Snl(); i++)
01516 outer_ffi->Print(i,TFile);
01517
01518 #ifdef Is_True_On
01519 outer_ffi->Check();
01520 #endif
01521 if (LNO_Run_Outer && LNO_Fusion!=0)
01522 Outer_Loop_Fusion_Phase(func_nd, outer_ffi);
01523
01524 new_ffi->Build(func_nd);
01525 if (LNO_Test_Dump)
01526 for (INT i = 0; i < new_ffi->Num_Snl(); i++)
01527 new_ffi->Print(i,TFile);
01528
01529 #ifdef Is_True_On
01530 new_ffi->Check();
01531 #endif
01532 }
01533
01534 if (do_fiz_fuse) {
01535
01536 #ifdef Is_True_On
01537 if (LNO_Verbose) {
01538 fprintf(stdout, "Sanity check after fiz_fuse phase\n");
01539 fflush(stdout);
01540 }
01541 LWN_Check_Parentize(func_nd);
01542 SNL_Sanity_Check_Func(func_nd);
01543 MP_Sanity_Check_Func(func_nd);
01544 LNO_Check_Graph(Array_Dependence_Graph);
01545 if (LNO_Verbose) {
01546 fprintf(stdout, "Sanity check after fiz_fuse phase complete\n");
01547 fflush(stdout);
01548 }
01549 #endif
01550 }
01551
01552 Hoist_Messy_Bounds(func_nd);
01553 Finalize_Loops(func_nd);
01554 Parallel_And_Padding_Phase(current_pu, func_nd);
01555
01556 SHACKLE_Phase(func_nd);
01557
01558 SNL_Phase(func_nd);
01559
01560
01561
01562
01563
01564 #ifdef Is_True_On
01565 if (LNO_Verbose) {
01566 fprintf(stdout, "Sanity check after phase 2\n");
01567 fflush(stdout);
01568 }
01569 LWN_Check_Parentize(func_nd);
01570 SNL_Sanity_Check_Func(func_nd);
01571 MP_Sanity_Check_Func(func_nd);
01572 LNO_Check_Graph(Array_Dependence_Graph);
01573 if (LNO_Verbose) {
01574 fprintf(stdout, "Sanity check after phase 2 complete\n");
01575 fflush(stdout);
01576 }
01577 #endif
01578
01579 if (Get_Trace(TP_LNOPT2, TT_SHACKLE_ONLY)
01580 || Get_Trace(TP_LNOPT2, TT_TILE_ONLY))
01581 return TRUE;
01582
01583 if (do_phase25 && LNO_Fission!=0 && LNO_Gather_Scatter!=0) {
01584
01585 if (!Get_Trace(TP_LNOPT, TT_LNO_NORENAME))
01586
01587 #ifdef KEY
01588 if (!Skip_SVR && LNO_SVR)
01589 #endif
01590 if (Scalar_Variable_Renaming(func_nd))
01591 LNO_Build_Access(func_nd,&LNO_default_pool);
01592
01593 Fiss_Gather_Loop(func_nd, Array_Dependence_Graph);
01594
01595 #ifdef Is_True_On
01596 if (LNO_Verbose) {
01597 fprintf(stdout, "Sanity check after phase 2.5\n");
01598 fflush(stdout);
01599 }
01600 LWN_Check_Parentize(func_nd);
01601 SNL_Sanity_Check_Func(func_nd);
01602 MP_Sanity_Check_Func(func_nd);
01603 LNO_Check_Graph(Array_Dependence_Graph);
01604 if (LNO_Verbose) {
01605 fprintf(stdout, "Sanity check after phase 2.5 complete\n");
01606 fflush(stdout);
01607 }
01608 #endif
01609 }
01610
01611 #ifndef KEY
01612 if ((do_inner_fission || LNO_Run_Vintr==TRUE) && LNO_Fission!=0)
01613 #else
01614 if ((do_inner_fission || LNO_Run_Vintr > 0) && LNO_Fission!=0)
01615 #endif
01616 if (!Get_Trace(TP_LNOPT, TT_LNO_NORENAME))
01617
01618 #ifdef KEY
01619 if (!Skip_SVR && LNO_SVR)
01620 #endif
01621 if (Scalar_Variable_Renaming(func_nd))
01622 LNO_Build_Access(func_nd,&LNO_default_pool);
01623
01624 if (do_inner_fission && LNO_Fission!=0) {
01625
01626 void Inner_Fission(WN* func_nd,
01627 ARRAY_DIRECTED_GRAPH16* Array_Dependence_Graph);
01628 Inner_Fission(func_nd,Array_Dependence_Graph);
01629 }
01630
01631 #ifdef TARG_X8664
01632 void Simd_Phase(WN* func_nd);
01633 if (LNO_Run_Simd && LNO_Run_Simd_Set && !Skip_Simd && Is_Target_SSE2())
01634 Simd_Phase(func_nd);
01635 void HoistIf_Phase(WN* func_nd);
01636 if (LNO_Run_hoistif==TRUE && !Skip_HoistIf)
01637 HoistIf_Phase(func_nd);
01638 #endif
01639
01640
01641 #ifdef KEY
01642 #ifdef TARG_MIPS
01643 Array_Substitution(func_nd);
01644 if(red_manager){
01645 red_manager->Erase(func_nd);
01646 red_manager->Build(func_nd, TRUE, FALSE);
01647 if (Roundoff_Level >= ROUNDOFF_ASSOC)
01648 red_manager->Build(func_nd,FALSE,TRUE,Array_Dependence_Graph);
01649 }
01650 #endif
01651 #endif
01652
01653 void Vintrinsic_Fission_Phase(WN* func_nd);
01654 #ifndef KEY
01655 if (LNO_Run_Vintr==TRUE)
01656 #else
01657 if (LNO_Run_Vintr)
01658 #endif
01659 Vintrinsic_Fission_Phase(func_nd);
01660 Finalize_Loops(func_nd);
01661
01662 #ifdef Is_True_On
01663 if (LNO_Verbose) {
01664 fprintf(stdout, "Sanity check after inner_fission phase\n");
01665 fflush(stdout);
01666 }
01667 LWN_Check_Parentize(func_nd);
01668 SNL_Sanity_Check_Func(func_nd);
01669 MP_Sanity_Check_Func(func_nd);
01670 LNO_Check_Graph(Array_Dependence_Graph);
01671 if (LNO_Verbose) {
01672 fprintf(stdout, "Sanity check after inner_fission phase complete\n");
01673 fflush(stdout);
01674 }
01675 #endif
01676 return FALSE;
01677 }
01678
01679 DO_LOOP_INFO::DO_LOOP_INFO(MEM_POOL *pool, ACCESS_ARRAY *lb, ACCESS_ARRAY *ub,
01680 ACCESS_VECTOR *step, BOOL has_calls, BOOL has_nested_calls, BOOL has_unsummarized_calls,
01681 BOOL has_unsummarized_call_cost, BOOL has_gotos, BOOL has_exits,
01682 BOOL has_gotos_this_level,BOOL is_inner) {
01683 _pool = pool;
01684 LB = lb;
01685 UB = ub;
01686 Step = step;
01687 Has_Calls = has_calls;
01688 Has_Nested_Calls = has_nested_calls;
01689 Has_Unsummarized_Calls = has_unsummarized_calls;
01690 Has_Unsummarized_Call_Cost = has_unsummarized_call_cost;
01691 Has_Threadprivate = FALSE;
01692 Has_Gotos = has_gotos;
01693 #ifndef KEY
01694 Has_Conditional = FALSE;
01695 #endif
01696 Has_Gotos_This_Level = has_gotos_this_level;
01697 Has_Exits = has_exits;
01698 Is_Inner = is_inner;
01699 Has_Bad_Mem = FALSE;
01700 Has_Barriers = FALSE;
01701 Is_Ivdep = FALSE;
01702 Is_Concurrent_Call = FALSE;
01703 Concurrent_Directive = FALSE;
01704 No_Fission = FALSE;
01705 No_Fusion = FALSE;
01706 Aggressive_Inner_Fission = FALSE;
01707 _wind_down_flags = 0;
01708 Est_Num_Iterations = -1;
01709 Est_Max_Iterations_Index = -1;
01710 Num_Iterations_Symbolic = TRUE;
01711 Num_Iterations_Profile = FALSE;
01712 Guard = NULL;
01713 Cannot_Interchange = FALSE;
01714 Cannot_Block = FALSE;
01715 Pragma_Cannot_Concurrentize = FALSE;
01716 Pragma_Prefer_Concurrentize = FALSE;
01717 Serial_Version_of_Concurrent_Loop = FALSE;
01718 Auto_Parallelized = FALSE;
01719 Required_Unroll = 0;
01720 for (INT i = 0; i < MHD_MAX_LEVELS; i++)
01721 Required_Blocksize[i] = -1;
01722 Permutation_Spec_Array = NULL;
01723 Permutation_Spec_Count = 0;
01724 Blockable_Specification = 0;
01725 Is_Inner_Tile = FALSE;
01726 Is_Outer_Tile = FALSE;
01727 Tile_Size = 0;
01728 Is_Backward = FALSE;
01729 Is_Outer_Lego_Tile = FALSE;
01730 Is_Inner_Lego_Tile = FALSE;
01731 Is_Processor_Tile = FALSE;
01732 Suggested_Parallel = FALSE;
01733 Is_Doacross = FALSE;
01734 Doacross_Tile_Size = 0;
01735 Sync_Distances[0] = NULL_DIST;
01736 Sync_Distances[0] = NULL_DIST;
01737 Parallelizable = FALSE;
01738 #ifdef KEY
01739 Vectorizable = FALSE;
01740 Delay_Full_Unroll = FALSE;
01741 #endif
01742 Last_Value_Peeled = FALSE;
01743 Not_Enough_Parallel_Work = FALSE;
01744 Inside_Critical_Section = FALSE;
01745 Work_Estimate = 0.0;
01746 Lego_Mp_Key_Lower = 0;
01747 Lego_Mp_Key_Upper = 0;
01748 Lego_Mp_Key_Depth = 0;
01749 Lego_LB_Symbols = NULL;
01750 Lego_Info = NULL;
01751 Mp_Info = NULL;
01752 ARA_Info = NULL;
01753 }
01754
01755
01756
01757
01758
01759
01760
01761 static INT last_value_peeling = FALSE;
01762
01763 extern void Last_Value_Peeling_On()
01764 {
01765 last_value_peeling = TRUE;
01766 }
01767
01768 extern void Last_Value_Peeling_Off()
01769 {
01770 last_value_peeling = FALSE;
01771 }
01772
01773 extern BOOL Last_Value_Peeling()
01774 {
01775 return last_value_peeling;
01776 }
01777
01778 DO_LOOP_INFO::DO_LOOP_INFO(DO_LOOP_INFO *dli, MEM_POOL *pool) {
01779 _pool = pool;
01780 if (dli->LB) LB = CXX_NEW(ACCESS_ARRAY(dli->LB,pool),pool);
01781 if (dli->UB) UB = CXX_NEW(ACCESS_ARRAY(dli->UB,pool),pool);
01782 if (dli->Step) Step = CXX_NEW(ACCESS_VECTOR(dli->Step,pool),pool);
01783 Has_Calls = dli->Has_Calls;
01784 #ifdef KEY //bug 14284
01785 Has_Nested_Calls = dli->Has_Nested_Calls;
01786 #endif
01787 Has_Unsummarized_Calls = dli->Has_Unsummarized_Calls;
01788 Has_Unsummarized_Call_Cost = dli->Has_Unsummarized_Call_Cost;
01789 Has_Threadprivate = dli->Has_Threadprivate;
01790 Has_Gotos = dli->Has_Gotos;
01791 Has_Gotos_This_Level = dli->Has_Gotos_This_Level;
01792 Has_Exits = dli->Has_Exits;
01793 Has_Bad_Mem = dli->Has_Bad_Mem;
01794 Has_Barriers = dli->Has_Barriers;
01795 Is_Inner = dli->Is_Inner;
01796 Is_Ivdep = dli->Is_Ivdep;
01797 Is_Concurrent_Call = dli->Is_Concurrent_Call;
01798 Concurrent_Directive = dli->Concurrent_Directive;
01799 No_Fission = dli->No_Fission;
01800 No_Fusion = dli->No_Fusion;
01801 Aggressive_Inner_Fission = dli->Aggressive_Inner_Fission;
01802 Depth = dli->Depth;
01803 _wind_down_flags = 0;
01804 Est_Num_Iterations = dli->Est_Num_Iterations;
01805 Est_Max_Iterations_Index = dli->Est_Max_Iterations_Index;
01806 Est_Register_Usage = dli->Est_Register_Usage;
01807 Num_Iterations_Symbolic = dli->Num_Iterations_Symbolic;
01808 Num_Iterations_Profile = dli->Num_Iterations_Profile;
01809 Guard = dli->Guard;
01810 Cannot_Interchange = dli->Cannot_Interchange;
01811 Cannot_Block = dli->Cannot_Block;
01812 Pragma_Cannot_Concurrentize = dli->Pragma_Cannot_Concurrentize;
01813 Pragma_Prefer_Concurrentize = dli->Pragma_Prefer_Concurrentize;
01814 Serial_Version_of_Concurrent_Loop = dli->Serial_Version_of_Concurrent_Loop;
01815 Auto_Parallelized = dli->Auto_Parallelized;
01816 Required_Unroll = dli->Required_Unroll;
01817 for (INT i = 0; i < MHD_MAX_LEVELS; i++)
01818 Required_Blocksize[i] = dli->Required_Blocksize[i];
01819 Permutation_Spec_Array = NULL;
01820 Permutation_Spec_Count = dli->Permutation_Spec_Count;
01821 if (Permutation_Spec_Count > 0) {
01822 Permutation_Spec_Array = CXX_NEW_ARRAY(INT, Permutation_Spec_Count,
01823 pool);
01824 for (INT i = 0; i < Permutation_Spec_Count; i++)
01825 Permutation_Spec_Array[i] = dli->Permutation_Spec_Array[i];
01826 }
01827 Blockable_Specification = dli->Blockable_Specification;
01828 Is_Inner_Tile = dli->Is_Inner_Tile;
01829 Is_Outer_Tile = dli->Is_Outer_Tile;
01830 Tile_Size = dli->Tile_Size;
01831 Is_Backward = dli->Is_Backward;
01832 Is_Outer_Lego_Tile = dli->Is_Outer_Lego_Tile;
01833 Is_Inner_Lego_Tile = dli->Is_Inner_Lego_Tile;
01834 Is_Processor_Tile = dli->Is_Processor_Tile;
01835 Suggested_Parallel = dli->Suggested_Parallel;
01836 Is_Doacross = dli->Is_Doacross;
01837 Doacross_Tile_Size = dli->Doacross_Tile_Size;
01838 Sync_Distances[0] = dli->Sync_Distances[0];
01839 Sync_Distances[1] = dli->Sync_Distances[1];
01840 Parallelizable = dli->Parallelizable;
01841 #ifdef KEY
01842 Vectorizable = dli->Vectorizable;
01843 Delay_Full_Unroll = dli->Delay_Full_Unroll;
01844 #endif
01845 Last_Value_Peeled = dli->Last_Value_Peeled;
01846 Not_Enough_Parallel_Work = dli->Not_Enough_Parallel_Work;
01847 Inside_Critical_Section = dli->Inside_Critical_Section;
01848 Work_Estimate= dli->Work_Estimate;
01849 Lego_Mp_Key_Lower = dli->Lego_Mp_Key_Lower;
01850 Lego_Mp_Key_Upper = dli->Lego_Mp_Key_Upper;
01851 Lego_Mp_Key_Depth = dli->Lego_Mp_Key_Depth;
01852 if (dli->Lego_LB_Symbols) {
01853 INT nloops = Lego_Mp_Key_Upper - Lego_Mp_Key_Lower + 1;
01854 Lego_LB_Symbols = CXX_NEW_ARRAY (SYMBOL, nloops, LEGO_pool);
01855 for (INT i=0; i<nloops; i++) {
01856 Lego_LB_Symbols[i] = dli->Lego_LB_Symbols[i];
01857 }
01858 }
01859 else Lego_LB_Symbols = dli->Lego_LB_Symbols;
01860 Lego_Info = NULL;
01861 if (dli->Lego_Info != NULL)
01862 Lego_Info = CXX_NEW(LEGO_INFO(dli->Lego_Info, LEGO_pool), LEGO_pool);
01863 Mp_Info = NULL;
01864 if (dli->Mp_Info != NULL)
01865 Mp_Info = CXX_NEW(MP_INFO(dli->Mp_Info), pool);
01866 ARA_Info = NULL;
01867 if (dli->ARA_Info != NULL) {
01868 if (Last_Value_Peeling())
01869 Last_Value_Peeled = TRUE;
01870 else
01871 DevWarn("No copy constructor for ARA_Info");
01872 }
01873 }
01874
01875 void REGION_INFO::Print(FILE* fp)
01876 {
01877 if (this == NULL) {
01878 fprintf(fp, "<NULL>\n");
01879 return;
01880 }
01881 if (_auto_parallelized)
01882 fprintf(fp, "Auto Parallelized\n");
01883 else
01884 fprintf(fp, "User Created\n");
01885 }
01886
01887 static INT Check_Vertices_Traverse(WN* wn_tree)
01888 {
01889 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
01890 INT error_count = 0;
01891 OPERATOR opr = WN_operator(wn_tree);
01892 if (opr == OPR_ILOAD || opr == OPR_ISTORE) {
01893 if (dg->Get_Vertex(wn_tree) == 0) {
01894 BOOL found_block = FALSE;
01895 WN *wn;
01896 for (wn = wn_tree; wn != NULL; wn = LWN_Get_Parent(wn)) {
01897 if (WN_operator(wn) == OPR_BLOCK)
01898 found_block = TRUE;
01899 if (found_block && WN_operator(wn) == OPR_DO_LOOP)
01900 break;
01901 }
01902 if (Do_Loop_Is_Good(wn)) {
01903 error_count++;
01904 fprintf(stdout, "0x%p missing vertex\n", wn_tree);
01905 }
01906 }
01907 }
01908 if (WN_operator(wn_tree) == OPR_BLOCK) {
01909 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
01910 error_count += Check_Vertices_Traverse(wn);
01911 } else {
01912 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
01913 error_count += Check_Vertices_Traverse(WN_kid(wn_tree, i));
01914 }
01915 return error_count;
01916 }
01917
01918 extern INT cv()
01919 {
01920 return Check_Vertices_Traverse(Current_Func_Node);
01921 }
01922
01923 extern INT cl()
01924 {
01925 INT error_count = 0;
01926 LWN_ITER* itr = LWN_WALK_TreeIter(Current_Func_Node);
01927 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
01928 WN* wn = itr->wn;
01929 DEF_LIST* def_list = Du_Mgr->Ud_Get_Def(wn);
01930 if (def_list == NULL)
01931 continue;
01932 WN* wn_loop = def_list->Loop_stmt();
01933 if (wn_loop == NULL)
01934 continue;
01935 WN *wnn;
01936 for (wnn = wn; wnn != NULL; wnn = LWN_Get_Parent(wnn))
01937 if (WN_operator(wnn) == OPR_DO_LOOP && wnn == wn_loop)
01938 break;
01939 if (wnn == NULL) {
01940 error_count++;
01941 fprintf(stdout, "0x%p bad loop stmt 0x%p\n", wn, wn_loop);
01942 }
01943 }
01944 return error_count;
01945 }