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 #ifdef USE_PCH
00041 #include "lno_pch.h"
00042 #endif // USE_PCH
00043 #pragma hdrstop
00044
00045 #ifdef _KEEP_RCS_ID
00046
00047 static char *rcs_id = "$Source: be/lno/SCCS/s.ff_utils.cxx $ $Revision: 1.17 $";
00048 #endif
00049
00050 #include <sys/types.h>
00051 #include "wn.h"
00052 #include "opcode.h"
00053 #include "lwn_util.h"
00054 #include "lnopt_main.h"
00055 #include "wn_map.h"
00056 #include "dep_graph.h"
00057 #include "fission.h"
00058 #include "ff_utils.h"
00059 #include "scalar_expand.h"
00060 #include "lnoutils.h"
00061 #include "opt_du.h"
00062 #include "reduc.h"
00063 #include "name.h"
00064 #include "access_vector.h"
00065 #include "inner_fission.h"
00066 #include "lego_util.h"
00067 #include "lego_opts.h"
00068 #include "wn_simp.h"
00069
00070 #define ESTIMATED_SIZE 100 // used to initialize hash table, etc.
00071
00072 static MEM_POOL FF_default_pool;
00073 static BOOL mem_pool_initialized=FALSE;
00074
00075 static UINT64 ref_counter=0;
00076
00077 static void Update_Loop_Info (WN* wn,
00078 SYMBOL* ref_symbol,
00079 SYMBOL* new_symbol);
00080
00081
00082 ARRAY_DIRECTED_GRAPH16* Statement_Dependence_Graph;
00083
00084 static BOOL Is_Reduction_In_Prallel_Region(WN* scalar_ref)
00085 {
00086 WN* wn=scalar_ref;
00087 while (wn) {
00088 WN* mp_region=Get_MP_Region(wn);
00089 if (!mp_region)
00090 return FALSE;
00091 WN* pragmas=WN_region_pragmas(mp_region);
00092 WN* next_wn=WN_first(pragmas);
00093 while (next_wn) {
00094 if (WN_opcode(next_wn)==OPC_PRAGMA)
00095 if ((WN_PRAGMA_ID)WN_pragma(next_wn)==WN_PRAGMA_REDUCTION) {
00096 if (WN_st(scalar_ref)==WN_st(next_wn))
00097 return TRUE;
00098 }
00099 next_wn=WN_next(next_wn);
00100 }
00101 wn=LWN_Get_Parent(mp_region);
00102 }
00103 return FALSE;
00104 }
00105
00106 #ifdef KEY
00107 static BOOL Is_Shared_Or_Reduction_In_Prallel_Region(WN* scalar_ref)
00108 {
00109 WN* wn=scalar_ref;
00110 while (wn) {
00111 WN* mp_region=Get_MP_Region(wn);
00112 if (!mp_region)
00113 return FALSE;
00114 WN* pragmas=WN_region_pragmas(mp_region);
00115 WN* next_wn=WN_first(pragmas);
00116 while (next_wn) {
00117 if (WN_opcode(next_wn)==OPC_PRAGMA)
00118 if ((WN_PRAGMA_ID)WN_pragma(next_wn)==WN_PRAGMA_SHARED ||
00119 (WN_PRAGMA_ID)WN_pragma(next_wn)==WN_PRAGMA_REDUCTION) {
00120 if (WN_st(scalar_ref)==WN_st(next_wn))
00121 return TRUE;
00122 }
00123 next_wn=WN_next(next_wn);
00124 }
00125 wn=LWN_Get_Parent(mp_region);
00126 }
00127 return FALSE;
00128 }
00129 #endif
00130 extern BOOL Edge_Is_Reduction_Dependence(
00131 EINDEX16 edge,
00132 ARRAY_DIRECTED_GRAPH16 *dg,
00133 REDUCTION_MANAGER *Red_Mgr)
00134 {
00135 BOOL is_reduction_dependence=FALSE;
00136
00137 if (Red_Mgr) {
00138 WN* source=dg->Get_Wn(dg->Get_Source(edge));
00139 REDUCTION_TYPE red_type= Red_Mgr->Which_Reduction(source);
00140 if (red_type!=RED_NONE) {
00141 WN* sink=dg->Get_Wn(dg->Get_Sink(edge));
00142 if (red_type==Red_Mgr->Which_Reduction(sink))
00143 is_reduction_dependence=TRUE;
00144 }
00145 }
00146
00147 return is_reduction_dependence;
00148 }
00149
00150
00151
00152
00153 static EINDEX16 Add_Stmt_Dependence(WN* stmt1, WN* stmt2, UINT stmt_level,
00154 ARRAY_DIRECTED_GRAPH16 *sdg)
00155 {
00156
00157 WN* parent_loop=LWN_Get_Parent(LWN_Get_Parent(stmt1));
00158
00159
00160 if (WN_opcode(parent_loop)!=OPC_DO_LOOP) {
00161 Is_True(WN_opcode(parent_loop)==OPC_FUNC_ENTRY,
00162 ("Parent is not loop or func_entry."));
00163 return 0;
00164 }
00165
00166
00167 if (Do_Loop_Is_Good(parent_loop)==FALSE || Do_Loop_Has_Gotos(parent_loop))
00168 return 0;
00169
00170 VINDEX16 source_vertex=sdg->Get_Vertex(stmt1);
00171 VINDEX16 sink_vertex=sdg->Get_Vertex(stmt2);
00172
00173
00174 if (source_vertex==0 || sink_vertex==0)
00175 return 0;
00176
00177 EINDEX16 stmt_e = sdg->Get_Edge(source_vertex,sink_vertex);
00178 if (stmt_e) {
00179
00180 UINT8 old_level = sdg->Level(stmt_e);
00181 if (stmt_level > old_level)
00182 sdg->Set_Level(stmt_e,stmt_level);
00183 } else {
00184
00185 stmt_e = sdg->Add_Edge(sdg->Get_Vertex(stmt1),
00186 sdg->Get_Vertex(stmt2), stmt_level);
00187 if (stmt_e==0) {
00188 sdg->Delete_Vertex(source_vertex);
00189 sdg->Delete_Vertex(sink_vertex);
00190 }
00191 }
00192 return stmt_e;
00193 }
00194
00195
00196
00197 extern UINT Get_Stmt_For_Stmt_Dep_Graph(
00198 WN* source_wn, WN* sink_wn,
00199 WN** source_stmt_out, WN** sink_stmt_out) {
00200
00201 FmtAssert (WN_opcode(source_wn)!=OPC_FUNC_ENTRY &&
00202 WN_opcode(sink_wn)!=OPC_FUNC_ENTRY,
00203 ("FUNC_ENTRY wn passed to Get_Stmt_For_Stmt_Dep_Graph().\n"));
00204
00205 FmtAssert (WN_opcode(LWN_Get_Parent(source_wn))!=OPC_FUNC_ENTRY &&
00206 WN_opcode(LWN_Get_Parent(sink_wn))!=OPC_FUNC_ENTRY,
00207 ("BLOCK wn of a FUNC_ENTRY passed to Get_Stmt_For_Stmt_Dep_Graph().\n"));
00208
00209
00210 WN* source_stmt = 0;
00211 for (source_stmt=source_wn;
00212 WN_opcode(LWN_Get_Parent(source_stmt))!=OPC_BLOCK;
00213 source_stmt = LWN_Get_Parent(source_stmt));
00214
00215
00216 WN* source_parent = 0;
00217 for (source_parent=LWN_Get_Parent(LWN_Get_Parent(source_stmt));
00218 WN_opcode(source_parent)!=OPC_DO_LOOP &&
00219 WN_opcode(source_parent)!=OPC_FUNC_ENTRY;
00220 source_stmt = source_parent,
00221 source_parent=LWN_Get_Parent(LWN_Get_Parent(source_stmt)));
00222
00223 WN* sink_stmt = 0;
00224 for (sink_stmt=sink_wn;
00225 WN_opcode(LWN_Get_Parent(sink_stmt))!=OPC_BLOCK;
00226 sink_stmt = LWN_Get_Parent(sink_stmt));
00227
00228
00229 WN* sink_parent = 0;
00230 for (sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt));
00231 WN_opcode(sink_parent)!=OPC_DO_LOOP &&
00232 WN_opcode(sink_parent)!=OPC_FUNC_ENTRY;
00233 sink_stmt = sink_parent,
00234 sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt)));
00235
00236 mUINT32 source_level;
00237 mUINT32 sink_level;
00238
00239 if (WN_opcode(source_parent)==OPC_DO_LOOP)
00240 source_level = Do_Loop_Depth(source_parent)+1;
00241 else
00242 source_level = 0;
00243
00244 if (WN_opcode(sink_parent)==OPC_DO_LOOP)
00245 sink_level = Do_Loop_Depth(sink_parent)+1;
00246 else
00247 sink_level = 0;
00248
00249 while (source_level>sink_level) {
00250 do {
00251 source_stmt = LWN_Get_Parent(source_stmt);
00252 } while (WN_opcode(source_stmt) != OPC_DO_LOOP);
00253 source_level--;
00254 }
00255 if (source_level>0)
00256 while (WN_opcode(source_parent=
00257 LWN_Get_Parent(LWN_Get_Parent(source_stmt))) != OPC_DO_LOOP)
00258 source_stmt=source_parent;
00259 else
00260 while (WN_opcode(source_parent=
00261 LWN_Get_Parent(LWN_Get_Parent(source_stmt))) != OPC_FUNC_ENTRY)
00262 source_stmt=source_parent;
00263
00264 while (sink_level>source_level) {
00265 do {
00266 sink_stmt = LWN_Get_Parent(sink_stmt);
00267 } while (WN_opcode(sink_stmt) != OPC_DO_LOOP);
00268 sink_level--;
00269 }
00270 if (sink_level>0)
00271 while (WN_opcode(sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt)))
00272 != OPC_DO_LOOP)
00273 sink_stmt=sink_parent;
00274 else
00275 while (WN_opcode(sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt)))
00276 != OPC_FUNC_ENTRY)
00277 sink_stmt=sink_parent;
00278
00279
00280
00281
00282 INT level=source_level;
00283 while (LWN_Get_Parent(source_stmt) != LWN_Get_Parent(sink_stmt)) {
00284 OPCODE opc;
00285 source_parent=LWN_Get_Parent(LWN_Get_Parent(source_stmt));
00286 do {
00287 source_stmt=source_parent;
00288 source_parent=LWN_Get_Parent(LWN_Get_Parent(source_stmt));
00289 opc=WN_opcode(source_parent);
00290 } while (opc!=OPC_DO_LOOP && opc!=OPC_FUNC_ENTRY);
00291 sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt));
00292 do {
00293 sink_stmt=sink_parent;
00294 sink_parent=LWN_Get_Parent(LWN_Get_Parent(sink_stmt));
00295 opc=WN_opcode(sink_parent);
00296 } while (opc!=OPC_DO_LOOP && opc!=OPC_FUNC_ENTRY);
00297 level--;
00298 }
00299 *source_stmt_out= source_stmt;
00300 *sink_stmt_out= sink_stmt;
00301 return (level);
00302 }
00303
00304
00305 EINDEX16 Array_Edge_To_Level_Edge(EINDEX16 dep_e,
00306 ARRAY_DIRECTED_GRAPH16 *adg, ARRAY_DIRECTED_GRAPH16 *sdg)
00307 {
00308
00309 VINDEX16 dep_source = adg->Get_Source(dep_e);
00310 VINDEX16 dep_sink = adg->Get_Sink(dep_e);
00311 WN* source_wn = adg->Get_Wn(dep_source);
00312 WN* sink_wn = adg->Get_Wn(dep_sink);
00313 WN* source_stmt;
00314 WN* sink_stmt;
00315
00316 UINT level=Get_Stmt_For_Stmt_Dep_Graph(
00317 source_wn,sink_wn,&source_stmt,&sink_stmt);
00318 if (level==0)
00319 return 0;
00320
00321 if (sdg->Get_Vertex(source_stmt)==0)
00322 return 0;
00323
00324 if (sdg->Get_Vertex(sink_stmt)==0)
00325 return 0;
00326
00327 DEPV_ARRAY* depv_array = adg->Depv_Array(dep_e);
00328 UINT8 pos_level = 0;
00329 BOOL has_all_zero = FALSE;
00330 for (INT i=depv_array->Num_Vec()-1; i>=0; i--) {
00331 DEPV* depv = depv_array->Depv(i);
00332 INT j = 0;
00333 while (j<depv_array->Num_Dim() &&
00334 DEP_Direction(DEPV_Dep(depv,j))==DIR_EQ) j++;
00335
00336 UINT8 current_level = j+depv_array->Num_Unused_Dim();
00337
00338
00339 if (current_level>pos_level)
00340 pos_level = current_level;
00341 if (j==depv_array->Num_Dim())
00342 has_all_zero = TRUE;
00343 }
00344
00345 EINDEX16 stmt_e=Add_Stmt_Dependence(source_stmt,sink_stmt,pos_level,sdg);
00346
00347 if (stmt_e && has_all_zero)
00348 sdg->Set_Level_Property(stmt_e,HAS_ALL_ZERO);
00349
00350 return stmt_e;
00351
00352 }
00353
00354
00355
00356
00357 extern INT Map_Stmt_To_Level_Graph(WN* wn, ARRAY_DIRECTED_GRAPH16 *sdg) {
00358
00359 OPCODE opcode = WN_opcode(wn);
00360 if (OPCODE_is_expression(opcode))
00361 return 1;
00362 if (opcode==OPC_LABEL || opcode==OPC_RETURN || opcode==OPC_GOTO
00363 #ifdef KEY
00364 || opcode==OPC_GOTO_OUTER_BLOCK
00365 #endif
00366 )
00367 return 1;
00368
00369 VINDEX16 v=sdg->Get_Vertex(wn);
00370 if (!v)
00371 v=sdg->Add_Vertex(wn);
00372 if (!v)
00373 return 0;
00374
00375 if (opcode==OPC_PRAGMA || opcode==OPC_XPRAGMA) {
00376 return 1;
00377 } else if (opcode==OPC_DO_LOOP) {
00378 wn=WN_do_body(wn);
00379
00380 for (WN* stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
00381 if (!Map_Stmt_To_Level_Graph(stmt,sdg))
00382 return 0;
00383 }
00384 } else if (opcode==OPC_REGION) {
00385 wn=WN_region_body(wn);
00386
00387 for (WN* stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
00388 if (!Map_Stmt_To_Level_Graph(stmt,sdg))
00389 return 0;
00390 }
00391 } else if (opcode==OPC_DO_WHILE || opcode==OPC_WHILE_DO) {
00392 wn=WN_while_body(wn);
00393
00394 for (WN* stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
00395 if (!Map_Stmt_To_Level_Graph(stmt,sdg))
00396 return 0;
00397 }
00398 } else if (opcode==OPC_IF) {
00399 WN* then_body=WN_then(wn);
00400
00401 WN* stmt = 0;
00402 for (stmt = WN_first(then_body); stmt; stmt = WN_next(stmt)) {
00403 if (!Map_Stmt_To_Level_Graph(stmt,sdg))
00404 return 0;
00405 }
00406 WN* else_body=WN_else(wn);
00407
00408 for (stmt = WN_first(else_body); stmt; stmt = WN_next(stmt)) {
00409 if (!Map_Stmt_To_Level_Graph(stmt,sdg))
00410 return 0;
00411 }
00412 }
00413 return 1;
00414 }
00415
00416
00417 static DOLOOP_STACK *Copy_Doloop_Stack(DOLOOP_STACK *orig,MEM_POOL *pool)
00418 {
00419 DOLOOP_STACK *copy = CXX_NEW(DOLOOP_STACK(pool),pool);
00420 INT elements = orig->Elements();
00421 for (INT i=0; i<elements; i++) {
00422 copy->Push(orig->Bottom_nth(i));
00423 }
00424 return(copy);
00425 }
00426
00427 extern void toplogical_reordering(WN* in_loop, UINT depth,
00428 ARRAY_DIRECTED_GRAPH16* adg) {
00429
00430 if (!Do_Loop_Is_Good(in_loop) || Do_Loop_Has_Calls(in_loop) ||
00431 Do_Loop_Has_Gotos(in_loop)) {
00432 Is_True(0, ("Bad loop passed to toplogical_reordering().\n"));
00433 return;
00434 }
00435
00436 if (!mem_pool_initialized) {
00437 MEM_POOL_Initialize(&FF_default_pool,"FF_default_pool",FALSE);
00438 mem_pool_initialized=TRUE;
00439 }
00440
00441 MEM_POOL_Push(&FF_default_pool);
00442
00443
00444 {
00445 WN* stmt;
00446
00447 FF_STMT_NODE *stmt_node_p;
00448 DYN_ARRAY<FF_STMT_LIST> loop(&FF_default_pool);
00449
00450 WN_MAP sdm=WN_MAP_Create(&FF_default_pool);
00451 ARRAY_DIRECTED_GRAPH16* sdg=Build_Statement_Dependence_Graph(
00452 in_loop, red_manager, adg, sdm, &FF_default_pool);
00453 Statement_Dependence_Graph = sdg;
00454 if (sdg==NULL) {
00455 DevWarn("Statement dependence graph problem");
00456 WN_MAP_Delete(sdm);
00457 MEM_POOL_Pop(&FF_default_pool);
00458 return;
00459 }
00460 Form_Loops(in_loop,OPT_FLAG_STMT_REORDERING,depth, NULL, NULL, sdg, loop,
00461 &FF_default_pool);
00462
00463 for (INT i=1; i<=loop.Lastidx(); i++) {
00464
00465 WN* loop_body = WN_do_body(in_loop);
00466 while(stmt_node_p = loop[i].Remove_Headnode()) {
00467 stmt = stmt_node_p->Get_Stmt();
00468 stmt = LWN_Extract_From_Block(stmt);
00469 LWN_Insert_Block_Before(loop_body,NULL,stmt);
00470 }
00471
00472 }
00473 Statement_Dependence_Graph = NULL;
00474 CXX_DELETE(sdg,&FF_default_pool);
00475 WN_MAP_Delete(sdm);
00476 }
00477
00478 MEM_POOL_Pop(&FF_default_pool);
00479
00480 }
00481
00482 static INT rename_counter=0;
00483
00484
00485
00486
00487
00488 static void Rename_Update_MP_Region(WN *region, WN *scalar_ref,
00489 ST* new_st,WN_OFFSET new_offset, WN *loop,
00490 BOOL is_outermost_region)
00491 {
00492
00493 WN *tmp = WN_last(WN_region_pragmas(region));
00494 ST *old_st = WN_st(scalar_ref);
00495 WN_OFFSET old_offset = WN_offset(scalar_ref);
00496 BOOL done = FALSE;
00497 BOOL found_it = FALSE;
00498 BOOL no_need = FALSE;
00499
00500
00501
00502 while (!done) {
00503 FmtAssert(tmp != NULL,
00504 ("Rename_Update_MP_Region: Found null pointer"));
00505 if (WN_opcode(tmp) == OPC_PRAGMA || WN_opcode(tmp) == OPC_XPRAGMA) {
00506 if ((WN_pragma(tmp) == WN_PRAGMA_COPYIN) ||
00507 (WN_pragma(tmp) == WN_PRAGMA_LOCAL) ||
00508 (WN_pragma(tmp) == WN_PRAGMA_LASTLOCAL) ||
00509 (WN_pragma(tmp) == WN_PRAGMA_FIRSTPRIVATE) ||
00510 (WN_pragma(tmp) == WN_PRAGMA_SHARED) ||
00511 (WN_pragma(tmp) == WN_PRAGMA_REDUCTION)) {
00512 if ((new_st == WN_st(tmp)) &&
00513 (new_offset == WN_pragma_arg1(tmp))) {
00514 done = TRUE;
00515 found_it = TRUE;
00516 } else if ((old_st == WN_st(tmp)) &&
00517 (old_offset == WN_pragma_arg1(tmp))) {
00518 WN *new_pragma = WN_CreatePragma((WN_PRAGMA_ID) WN_pragma(tmp),
00519 new_st, (INT32) new_offset, WN_pragma_arg2(tmp));
00520 WN_Set_Linenum(new_pragma,WN_Get_Linenum(tmp));
00521 LWN_Insert_Block_After(LWN_Get_Parent(tmp),tmp,new_pragma);
00522 done = TRUE;
00523 found_it = TRUE;
00524 }
00525 } else if (WN_pragma(tmp) == WN_PRAGMA_MASTER_BEGIN) {
00526 no_need = TRUE;
00527 }
00528 }
00529 if (!done) tmp = WN_prev(tmp);
00530 if (!tmp) done = TRUE;
00531 }
00532
00533
00534 if (no_need) return;
00535
00536
00537
00538
00539
00540 if (!found_it && is_outermost_region) {
00541 if (loop && (WN_st(WN_index(loop)) == old_st) &&
00542 (WN_offset(WN_index(loop)) == old_offset)) {
00543 return;
00544 }
00545 if (ST_class(old_st) != CLASS_PREG) {
00546 WN *new_pragma = WN_CreatePragma(WN_PRAGMA_SHARED,
00547 new_st, (INT32) new_offset, 0);
00548 WN_Set_Linenum(new_pragma,WN_Get_Linenum(region));
00549 LWN_Insert_Block_After(WN_region_pragmas(region),
00550 WN_last(WN_region_pragmas(region))
00551 ,new_pragma);
00552 }
00553 }
00554 }
00555
00556
00557 static BOOL Outer_Mp_Region(WN *region)
00558 {
00559 WN *wn = LWN_Get_Parent(region);
00560 while (wn) {
00561 if (Is_Mp_Region(wn)) return FALSE;
00562 wn = LWN_Get_Parent(wn);
00563 }
00564 return TRUE;
00565 }
00566
00567
00568
00569 static void Rename_Update_MP(WN *scalar_ref,ST* new_st,
00570 WN_OFFSET new_offset)
00571 {
00572 WN *region = LWN_Get_Parent(scalar_ref);
00573 while (region) {
00574 if (Is_Mp_Region(region)) {
00575 Rename_Update_MP_Region(region,scalar_ref,new_st,new_offset,NULL,
00576 Outer_Mp_Region(region));
00577 } else if ((WN_opcode(region) == OPC_DO_LOOP) && Do_Loop_Is_Mp(region)) {
00578 WN *loop = region;
00579 region = LWN_Get_Parent(LWN_Get_Parent(region));
00580 #ifdef KEY
00581 if (PU_cxx_lang(Get_Current_PU()) && Is_Eh_Or_Try_Region(region))
00582 region = LWN_Get_Parent(LWN_Get_Parent(region));
00583 #endif
00584 Rename_Update_MP_Region(region,scalar_ref,new_st,new_offset,loop,
00585 Outer_Mp_Region(region));
00586 }
00587 region = LWN_Get_Parent(region);
00588 }
00589 }
00590
00591
00592 extern BOOL scalar_rename(WN* ref, HASH_TABLE<WN*,INT>* checked) {
00593
00594 if (Get_Trace(TP_LNOPT, TT_LNO_NORENAME))
00595 return FALSE;
00596
00597 INT can_rename=TRUE;
00598 SYMBOL ref_symbol(ref);
00599
00600
00601
00602
00603 STACK<WN*>* equivalence_class=
00604 Scalar_Equivalence_Class(ref,Du_Mgr,&LNO_local_pool);
00605
00606 if (equivalence_class==NULL)
00607 return FALSE;
00608
00609 TYPE_ID desc_type = WN_desc(equivalence_class->Top_nth(0));
00610 if (desc_type == MTYPE_M) {
00611 can_rename = FALSE;
00612 }
00613
00614
00615
00616
00617
00618 INT i;
00619 for (i=0; can_rename && i<equivalence_class->Elements(); i++) {
00620
00621 WN* scalar_ref=equivalence_class->Top_nth(i);
00622 if (OPCODE_has_sym(WN_opcode(scalar_ref))) {
00623 SYMBOL temp_symbol(scalar_ref);
00624 OPERATOR opr=WN_operator(scalar_ref);
00625 if ((opr!=OPR_STID && opr!=OPR_LDID) || (ref_symbol!=temp_symbol))
00626 can_rename= FALSE;
00627 else if (TY_is_volatile(WN_ty(scalar_ref)))
00628 can_rename = FALSE;
00629 else if (WN_desc(scalar_ref)!=desc_type)
00630 can_rename = FALSE;
00631 #ifndef KEY
00632 else if (Is_Reduction_In_Prallel_Region(scalar_ref))
00633 can_rename = FALSE;
00634 #else
00635
00636
00637 else if (Contains_MP &&
00638 Is_Shared_Or_Reduction_In_Prallel_Region(scalar_ref))
00639 can_rename = FALSE;
00640
00641 else if ((opr == OPR_STID) && WN_desc(scalar_ref) == MTYPE_BS)
00642 can_rename = FALSE;
00643
00644
00645 else if ((opr == OPR_STID) && MTYPE_is_complex(WN_desc(scalar_ref)))
00646 can_rename = FALSE;
00647 #endif
00648 } else
00649 can_rename= FALSE;
00650 }
00651 if (can_rename) {
00652
00653 SYMBOL new_symbol=Create_Preg_Symbol(ref_symbol.Name(), ref_symbol.Type);
00654 if (LNO_Verbose) {
00655 fprintf(stdout, " Renaming %s\n", ref_symbol.Name());
00656 fprintf(TFile, " Renaming %s\n", ref_symbol.Name());
00657 }
00658 for (i=0; i<equivalence_class->Elements(); i++) {
00659 WN* scalar_ref=equivalence_class->Top_nth(i);
00660 if (Contains_MP) {
00661 Rename_Update_MP(scalar_ref,new_symbol.St(),new_symbol.WN_Offset());
00662 }
00663
00664 OPCODE scalar_op = WN_opcode(scalar_ref);
00665 TYPE_ID desc = OPCODE_desc(scalar_op);
00666
00667 if (WN_operator(scalar_ref)==OPR_STID) {
00668
00669 WN* parent=LWN_Get_Parent(scalar_ref);
00670 if (WN_opcode(parent)==OPC_DO_LOOP && WN_start(parent)==scalar_ref) {
00671 WN_st_idx(WN_index(parent))=ST_st_idx(new_symbol.St());
00672 WN_offset(WN_index(parent))=new_symbol.WN_Offset();
00673 Update_Loop_Info (parent, &ref_symbol, &new_symbol);
00674 }
00675
00676
00677
00678
00679 OPCODE kid_opcode = WN_opcode(WN_kid0(scalar_ref));
00680 if (desc != Promote_Type(desc)) {
00681
00682 if ((WN_opcode(LWN_Get_Parent(scalar_ref)) != OPC_DO_LOOP) ||
00683 (scalar_ref != WN_step(LWN_Get_Parent(scalar_ref)))) {
00684 INT Size = MTYPE_bit_size(desc);
00685 TYPE_ID cvtl_desc=OPCODE_rtype(kid_opcode);
00686 cvtl_desc=Mtype_TransferSign(desc,cvtl_desc);
00687 OPCODE cvtl_o = OPCODE_make_op(OPR_CVTL,cvtl_desc,MTYPE_V);
00688 BOOL simp_state_save = WN_Simplifier_Enable(FALSE);
00689 WN *cvtl = LWN_CreateExp1(cvtl_o,WN_kid0(scalar_ref));
00690 WN_cvtl_bits(cvtl) = Size;
00691 WN_Simplifier_Enable(simp_state_save);
00692 WN_set_ty(scalar_ref,Be_Type_Tbl(Promote_Type(desc)));
00693 WN_kid0(scalar_ref) = cvtl;
00694 LWN_Set_Parent(cvtl,scalar_ref);
00695 }
00696 } else if (MTYPE_bit_size(desc) <
00697 MTYPE_bit_size(OPCODE_rtype(kid_opcode))) {
00698 if ((WN_opcode(LWN_Get_Parent(scalar_ref)) != OPC_DO_LOOP) ||
00699 (scalar_ref != WN_step(LWN_Get_Parent(scalar_ref)))) {
00700 OPCODE cvt_o=OPCODE_make_op(OPR_CVT,desc,OPCODE_rtype(kid_opcode));
00701 WN *cvt = LWN_CreateExp1(cvt_o,WN_kid0(scalar_ref));
00702 WN_kid0(scalar_ref) = cvt;
00703 LWN_Set_Parent(cvt,scalar_ref);
00704 }
00705 }
00706 }
00707 WN_st_idx(scalar_ref)=ST_st_idx(new_symbol.St());
00708 WN_offset(scalar_ref)=new_symbol.WN_Offset();
00709
00710 #ifdef KEY
00711
00712 if (WN_operator(scalar_ref) == OPR_LDID &&
00713 MTYPE_bit_size(desc) == 32 &&
00714 MTYPE_bit_size(WN_rtype(scalar_ref)) == 64) {
00715
00716
00717 OPCODE cvt_o=OPCODE_make_op(OPR_CVT,WN_rtype(scalar_ref), desc);
00718 WN* parent = LWN_Get_Parent(scalar_ref);
00719 INT kid;
00720 for (kid = 0; kid < WN_kid_count(parent); kid ++)
00721 if (WN_kid(parent, kid) == scalar_ref)
00722 break;
00723 WN *cvt = LWN_CreateExp1(cvt_o,scalar_ref);
00724 LWN_Set_Parent(cvt,parent);
00725 WN_kid(parent, kid) = cvt;
00726 WN_set_rtype(scalar_ref, desc);
00727 }
00728 else
00729 #endif
00730 WN_set_opcode(scalar_ref,OPCODE_make_op(
00731 OPCODE_operator(scalar_op),
00732 OPCODE_rtype(scalar_op),
00733 Promote_Type(OPCODE_desc(scalar_op))));
00734 WN_set_ty(scalar_ref,Be_Type_Tbl(Promote_Type(desc)));
00735 WN_set_field_id(scalar_ref, 0);
00736
00737 if (Alias_Mgr) {
00738 Create_alias(Alias_Mgr,scalar_ref);
00739 }
00740 if (checked)
00741 checked->Enter(scalar_ref,1);
00742 }
00743
00744 equivalence_class->Free();
00745 return TRUE;
00746 } else {
00747
00748 if (checked)
00749 for (i=0; i<equivalence_class->Elements(); i++) {
00750 WN* scalar_ref=equivalence_class->Top_nth(i);
00751 checked->Enter(scalar_ref,1);
00752 }
00753
00754 equivalence_class->Free();
00755 return FALSE;
00756 }
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 static void Update_Loop_Info (WN* wn,
00766 SYMBOL* ref_symbol,
00767 SYMBOL* new_symbol) {
00768 DO_LOOP_INFO* dli;
00769 LEGO_INFO* li;
00770 MP_INFO* mpi;
00771
00772 switch (WN_operator(wn)) {
00773 case OPR_DO_LOOP:
00774 {
00775 dli = Get_Do_Loop_Info (wn);
00776 li = dli->Lego_Info;
00777 mpi = dli->Mp_Info;
00778 if (li) {
00779 SYMBOL* old_sym = li->Pid_Sym0();
00780 if (old_sym && (*old_sym == *(ref_symbol))) {
00781 *old_sym = *new_symbol;
00782 }
00783 else {
00784 old_sym = li->Pid_Sym1();
00785 if (old_sym && (*old_sym == *(ref_symbol))) {
00786 *old_sym = *new_symbol;
00787 }
00788 }
00789 }
00790 if (mpi) {
00791 SYMBOL* old_sym = mpi->Pid_Sym0();
00792 if (old_sym && (*old_sym == *(ref_symbol))) {
00793 *old_sym = *new_symbol;
00794 }
00795 else {
00796 old_sym = mpi->Pid_Sym1();
00797 if (old_sym && (*old_sym == *(ref_symbol))) {
00798 *old_sym = *new_symbol;
00799 }
00800 }
00801 }
00802 Update_Loop_Info (WN_do_body(wn), ref_symbol, new_symbol);
00803 break;
00804 }
00805 case OPR_BLOCK:
00806 {
00807 wn = WN_first(wn);
00808 while (wn) {
00809 Update_Loop_Info (wn, ref_symbol, new_symbol);
00810 wn = WN_next(wn);
00811 }
00812 break;
00813 }
00814 default:
00815 {
00816 for (INT i=0; i<WN_kid_count(wn); i++)
00817 Update_Loop_Info (WN_kid(wn, i), ref_symbol, new_symbol);
00818 break;
00819 }
00820 }
00821 }
00822
00823
00824
00825 extern BOOL Scalar_Variable_Renaming(WN* root) {
00826
00827 if (Get_Trace(TP_LNOPT, TT_LNO_NORENAME))
00828 return FALSE;
00829
00830 if (!mem_pool_initialized) {
00831 MEM_POOL_Initialize(&FF_default_pool,"FF_default_pool",FALSE);
00832 mem_pool_initialized=TRUE;
00833 }
00834
00835 BOOL renamed=FALSE;
00836
00837 MEM_POOL_Push(&FF_default_pool);
00838
00839 {
00840
00841
00842
00843
00844 HASH_TABLE<WN*,INT> checked(ESTIMATED_SIZE, &FF_default_pool);
00845
00846 DYN_ARRAY<WN*> wns(&FF_default_pool);
00847
00848
00849 REF_LIST_STACK *writes = CXX_NEW(REF_LIST_STACK(&FF_default_pool),
00850 &FF_default_pool);
00851 REF_LIST_STACK *reads = CXX_NEW(REF_LIST_STACK(&FF_default_pool),
00852 &FF_default_pool);
00853 SCALAR_STACK *scalar_writes = CXX_NEW(SCALAR_STACK(&FF_default_pool),
00854 &FF_default_pool);
00855 SCALAR_STACK *scalar_reads = CXX_NEW(SCALAR_STACK(&FF_default_pool),
00856 &FF_default_pool);
00857 SCALAR_REF_STACK *params =
00858 CXX_NEW(SCALAR_REF_STACK(&FF_default_pool), &FF_default_pool);
00859 DOLOOP_STACK *stack=CXX_NEW(DOLOOP_STACK(&FF_default_pool),
00860 &FF_default_pool);
00861 Build_Doloop_Stack(root, stack);
00862 Init_Ref_Stmt_Counter();
00863 New_Gather_References(root,writes,reads,stack,
00864 scalar_writes,scalar_reads,params,&FF_default_pool,
00865 Gather_Scalar_Refs);
00866
00867
00868
00869 for (INT sj=0; sj<scalar_writes->Elements(); sj++) {
00870 SCALAR_NODE *sjnode = scalar_writes->Bottom_nth(sj);
00871 for (INT sjj=0; sjj<sjnode->Elements(); sjj++) {
00872 WN* ref=sjnode->Bottom_nth(sjj)->Wn;
00873 if (WN_operator(ref)==OPR_STID && !checked.Find(ref)) {
00874 INT i;
00875 for (i=wns.Lastidx(); i>=0; i--) {
00876 SYMBOL symbol1(wns[i]);
00877 SYMBOL symbol2(ref);
00878 if (symbol1==symbol2) {
00879 if (scalar_rename(ref,&checked))
00880 renamed=TRUE;
00881 else if (scalar_rename(wns[i],&checked)) {
00882 wns[i]=ref;
00883 renamed=TRUE;
00884 }
00885 break;
00886 }
00887 }
00888
00889 if (i== -1) {
00890 i=wns.Newidx();
00891 wns[i]=ref;
00892 STACK<WN*>* equivalence_class=
00893 Scalar_Equivalence_Class(ref,Du_Mgr,&FF_default_pool);
00894
00895 if (equivalence_class!=NULL)
00896 for (INT i=0; i<equivalence_class->Elements(); i++) {
00897 WN* scalar_ref=equivalence_class->Top_nth(i);
00898 checked.Enter(scalar_ref,1);
00899 }
00900 }
00901 }
00902 }
00903 }
00904 }
00905
00906 MEM_POOL_Pop(&FF_default_pool);
00907 return renamed;
00908
00909 }
00910
00911
00912
00913
00914 extern void Fission_DU_Update(DU_MANAGER* Du_Mgr, REDUCTION_MANAGER* Red_Mgr,
00915 WN** wn_starts, WN** wn_ends, WN** wn_steps,
00916 UINT total_loops, WN** loops, BOOL index_DU_to_first)
00917 {
00918
00919 MEM_POOL_Push(&LNO_local_pool);
00920
00921 UINT depth=Do_Loop_Depth(loops[0]);
00922
00923
00924
00925 Unrolled_DU_Update(wn_starts, total_loops, depth, TRUE, FALSE);
00926 Unrolled_DU_Update(wn_ends, total_loops, depth, TRUE, FALSE);
00927 Unrolled_DU_Update(wn_steps, total_loops, depth, TRUE, FALSE);
00928
00929
00930
00931
00932
00933 WN* parent=LWN_Get_Parent(loops[0]);
00934 WN* old_loop_index_def=WN_start(loops[0]);
00935 USE_LIST *use_list=Du_Mgr->Du_Get_Use(old_loop_index_def);
00936 USE_LIST_ITER u_iter(use_list);
00937 for (DU_NODE *use_node=(DU_NODE *)u_iter.First();
00938 !u_iter.Is_Empty(); ) {
00939 WN* use=use_node->Wn();
00940 use_node=(DU_NODE *)u_iter.Next();
00941 WN* new_loop=use;
00942 while (WN_opcode(new_loop)!=OPC_DO_LOOP ||
00943 Do_Loop_Depth(new_loop)>depth)
00944 if (WN_opcode(new_loop)==OPC_FUNC_ENTRY)
00945 break;
00946 else
00947 new_loop=LWN_Get_Parent(new_loop);
00948
00949 BOOL inside_loop=TRUE;
00950 if (WN_opcode(new_loop)==OPC_FUNC_ENTRY ||
00951 Do_Loop_Depth(new_loop)<depth){
00952
00953
00954 new_loop=loops[(index_DU_to_first)? 0: total_loops-1];
00955 inside_loop=FALSE;
00956 }
00957 else {
00958 INT j= -1;
00959 for (INT i=0; i<total_loops; i++) {
00960 if (new_loop==loops[i]) {
00961 j=i;
00962 break;
00963 }
00964 }
00965 if (j== -1){
00966 new_loop=loops[(index_DU_to_first)? 0: total_loops-1];
00967 inside_loop=FALSE;
00968 }
00969 }
00970 if (new_loop!=loops[0]) {
00971 Du_Mgr->Delete_Def_Use(WN_start(loops[0]),use);
00972 Du_Mgr->Delete_Def_Use(WN_step(loops[0]),use);
00973 Du_Mgr->Add_Def_Use(WN_start(new_loop),use);
00974 Du_Mgr->Add_Def_Use(WN_step(new_loop),use);
00975 if (inside_loop) Du_Mgr->Ud_Get_Def(use)->Set_loop_stmt(new_loop);
00976 }
00977 }
00978
00979
00980
00981 for (INT i=0; i<total_loops; i++) {
00982
00983
00984 REF_LIST_STACK *writes = CXX_NEW(REF_LIST_STACK(&LNO_local_pool),
00985 &LNO_local_pool);
00986 REF_LIST_STACK *reads = CXX_NEW(REF_LIST_STACK(&LNO_local_pool),
00987 &LNO_local_pool);
00988
00989 SCALAR_STACK *scalar_writes = CXX_NEW(SCALAR_STACK(&LNO_local_pool),
00990 &LNO_local_pool);
00991 SCALAR_STACK *scalar_reads = CXX_NEW(SCALAR_STACK(&LNO_local_pool),
00992 &LNO_local_pool);
00993 SCALAR_REF_STACK *params =
00994 CXX_NEW(SCALAR_REF_STACK(&LNO_local_pool), &LNO_local_pool);
00995
00996 DOLOOP_STACK *stack=CXX_NEW(DOLOOP_STACK(&LNO_local_pool),
00997 &LNO_local_pool);
00998 Build_Doloop_Stack(loops[i], stack);
00999
01000
01001 Init_Ref_Stmt_Counter();
01002 New_Gather_References(WN_do_body(loops[i]),writes,reads,stack,
01003 scalar_writes,scalar_reads,params,&LNO_local_pool,
01004 Gather_Scalar_Refs);
01005
01006 for (INT si=0; si<scalar_reads->Elements(); si++) {
01007 SCALAR_NODE* sinode=scalar_reads->Bottom_nth(si);
01008 WN* use=sinode->Bottom_nth(0)->Wn;
01009 REDUCTION_TYPE red_type;
01010 if (Red_Mgr)
01011 red_type=Red_Mgr->Which_Reduction(use);
01012 else
01013 red_type=RED_NONE;
01014
01015 STACK<WN*> write_stack(&LNO_local_pool);
01016
01017 for (INT sj=0; sj<sinode->Elements(); sj++) {
01018 use=sinode->Bottom_nth(sj)->Wn;
01019
01020 if (red_type!=RED_NONE) {
01021 if (red_type!=Red_Mgr->Which_Reduction(use)) {
01022 red_type=RED_NONE;
01023 } else {
01024 WN *def = LWN_Get_Parent(use);
01025 while (!OPCODE_is_store(WN_opcode(def))) {
01026 FmtAssert(def,("Can't find store of reduction \n"));
01027 def=LWN_Get_Parent(def);
01028 }
01029 write_stack.Push(def);
01030 }
01031 }
01032
01033 DEF_LIST* def_list=Du_Mgr->Ud_Get_Def(use);
01034 if (def_list->Loop_stmt()==loops[0])
01035 def_list->Set_loop_stmt(loops[i]);
01036 }
01037 if (red_type!=RED_NONE)
01038 for (INT rsj=0; rsj<write_stack.Elements(); rsj++) {
01039 WN* write=write_stack.Bottom_nth(rsj);
01040 for (INT sk=0; sk<sinode->Elements(); sk++) {
01041 WN* read=sinode->Bottom_nth(sk)->Wn;
01042
01043 Du_Mgr->Du_Add_Use(write,read);
01044 Du_Mgr->Ud_Add_Def(read,write);
01045 }
01046 }
01047 }
01048 }
01049
01050 MEM_POOL_Pop(&LNO_local_pool);
01051
01052 }
01053
01054
01055
01056
01057
01058
01059
01060 extern INT Lexical_Order(WN* wn1, WN* wn2)
01061 {
01062 WN* stmt1;
01063 WN* stmt2;
01064
01065
01066
01067 Get_Stmt_For_Stmt_Dep_Graph(wn1,wn2,&stmt1,&stmt2);
01068
01069 if (stmt1==stmt2)
01070 return 0;
01071
01072
01073 do {
01074 stmt1=WN_next(stmt1);
01075 if (stmt1==stmt2)
01076 return -1;
01077 } while (stmt1);
01078
01079 return 1;
01080
01081 }
01082
01083
01084
01085
01086 extern WN* Find_SCF_Inside(WN* parent_wn, OPCODE opc) {
01087 WN* wn=LWN_Get_Next_SCF_Node(parent_wn);
01088 while (wn && Wn_Is_Inside(wn,parent_wn) && WN_opcode(wn)!=opc)
01089 wn=LWN_Get_Next_SCF_Node(wn);
01090
01091 if (!wn || !Wn_Is_Inside(wn,parent_wn))
01092 return (WN*)NULL;
01093 else
01094 return wn;
01095 }
01096
01097 extern void FF_Mark_Inner_Loop_Info(WN* loop) {
01098
01099 DO_LOOP_INFO* dli=Get_Do_Loop_Info(loop);
01100 WN* innerloop=Find_SCF_Inside(loop,OPC_DO_LOOP);
01101 if (innerloop)
01102 dli->Is_Inner=FALSE;
01103 else
01104 dli->Is_Inner=TRUE;
01105 return;
01106 }
01107
01108
01109 static UINT32 Gather_Ref_Stmt_Counter=0;
01110
01111 extern void Init_Ref_Stmt_Counter() {
01112 Gather_Ref_Stmt_Counter=0;
01113 }
01114
01115
01116
01117
01118
01119
01120 extern INT32 New_Gather_References(WN *wn, REF_LIST_STACK *writes,
01121 REF_LIST_STACK *reads, DOLOOP_STACK *stack,
01122 SCALAR_STACK *scalar_writes, SCALAR_STACK *scalar_reads,
01123 SCALAR_REF_STACK* params, MEM_POOL *pool,
01124 INT mode)
01125 {
01126 INT32 array_ref_count=0;
01127 WN *kid;
01128
01129 if (OPCODE_is_stmt(WN_opcode(wn)))
01130 Gather_Ref_Stmt_Counter++;
01131
01132 if (WN_opcode(wn) == OPC_BLOCK) {
01133 kid = WN_first (wn);
01134 while (kid) {
01135 INT32 count=
01136 New_Gather_References(kid,writes,reads,stack,scalar_writes,
01137 scalar_reads,params,pool,mode);
01138 if (count == -1)
01139 return -1;
01140 array_ref_count+= count;
01141 kid = WN_next(kid);
01142 }
01143 return array_ref_count;
01144 }
01145
01146 if (WN_opcode(wn) == OPC_DO_LOOP) {
01147 stack->Push(wn);
01148 } else if (OPCODE_is_load(WN_opcode(wn))) {
01149 if (WN_kid_count(wn) == 1) {
01150 if (mode & Gather_Array_Refs) {
01151 array_ref_count++;
01152 DOLOOP_STACK *s = Copy_Doloop_Stack(stack,&LNO_local_pool);
01153 WN *addr = WN_kid0(wn);
01154 if (WN_operator(addr) == OPR_ADD) {
01155 if (WN_operator(WN_kid0(addr)) == OPR_ARRAY) {
01156 addr = WN_kid0(addr);
01157 } else {
01158 addr = WN_kid1(addr);
01159 }
01160 }
01161 if (WN_operator(addr) != OPR_ARRAY)
01162 return -1;
01163 WN *base = WN_array_base(addr);
01164 ST *st_base=Get_ST_Base(base);
01165 INT i;
01166 for (i=0;i<reads->Elements()&&
01167 !(reads->Bottom_nth(i)->ST_Base==st_base); i++);
01168 if (i==reads->Elements()) {
01169 reads->Push(CXX_NEW(REFERENCE_LIST(st_base, wn),pool));
01170 }
01171 reads->Bottom_nth(i)->Append(CXX_NEW(REFERENCE_NODE(wn,s,
01172 Gather_Ref_Stmt_Counter), pool));
01173 }
01174 } else if (WN_operator(wn) == OPR_LDID) {
01175 if (mode & Gather_Scalar_Refs)
01176
01177
01178 scalar_reads->Add_Scalar(wn,Gather_Ref_Stmt_Counter);
01179 }
01180 } else if (OPCODE_is_store(WN_opcode(wn))) {
01181 if (WN_kid_count(wn) == 2) {
01182 if (mode & Gather_Array_Refs) {
01183 array_ref_count++;
01184 DOLOOP_STACK *s = Copy_Doloop_Stack(stack,&LNO_local_pool);
01185 WN *addr = WN_kid1(wn);
01186 if (WN_operator(addr) == OPR_ADD) {
01187 if (WN_operator(WN_kid0(addr)) == OPR_ARRAY) {
01188 addr = WN_kid0(addr);
01189 } else {
01190 addr = WN_kid1(addr);
01191 }
01192 }
01193 if (WN_operator(addr) != OPR_ARRAY)
01194 return -1;
01195 WN *base = WN_array_base(addr);
01196 ST *st_base=Get_ST_Base(base);
01197 INT i;
01198 for (i=0;i<writes->Elements() &&
01199 !(writes->Bottom_nth(i)->ST_Base==st_base); i++);
01200 if (i==writes->Elements()) {
01201 writes->Push(CXX_NEW(REFERENCE_LIST(st_base,
01202 wn),pool));
01203 }
01204 writes->Bottom_nth(i)->Append(CXX_NEW(REFERENCE_NODE(wn,s,
01205 Gather_Ref_Stmt_Counter), pool));
01206 }
01207 } else if (WN_operator(wn) == OPR_STID) {
01208 if (mode & Gather_Scalar_Refs)
01209 scalar_writes->Add_Scalar(wn,Gather_Ref_Stmt_Counter);
01210 }
01211 } else if (WN_operator(wn)==OPR_PARM) {
01212 if (WN_Parm_By_Reference(wn) && (mode & Gather_Params)) {
01213 SCALAR_REF scalar_ref(wn,Gather_Ref_Stmt_Counter);
01214 params->Push(scalar_ref);
01215 }
01216 }
01217
01218 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
01219 kid = WN_kid(wn,kidno);
01220 INT32 count=
01221 New_Gather_References(kid,writes,reads,stack,
01222 scalar_writes,scalar_reads,params,pool,mode);
01223 if (count == -1)
01224 return -1;
01225 array_ref_count+= count;
01226 }
01227
01228 if (WN_opcode(wn) == OPC_DO_LOOP) {
01229 stack->Pop();
01230 }
01231 return array_ref_count;
01232 }
01233
01234 static BOOL Generate_Pragma_Dependence_For_Statement_Dependence_Graph(
01235 WN* wn,
01236 WN* parent_loop,
01237 ARRAY_DIRECTED_GRAPH16* sdg
01238 )
01239 {
01240 OPCODE opcode=WN_opcode(wn);
01241
01242 if (opcode == OPC_BLOCK) {
01243 WN* kid = WN_first (wn);
01244 while (kid) {
01245 if (Generate_Pragma_Dependence_For_Statement_Dependence_Graph(
01246 kid,parent_loop,sdg)==0)
01247 return 0;
01248 kid = WN_next(kid);
01249 }
01250 return 1;
01251 } else if (opcode==OPC_PRAGMA || opcode==OPC_XPRAGMA) {
01252
01253 VINDEX16 v=sdg->Get_Vertex(wn);
01254 VINDEX16 v1;
01255 UINT level = Do_Loop_Depth(parent_loop)+1;
01256 #if 0
01257
01258 WN* before=wn;
01259 v1=0;
01260 do {
01261 before=WN_prev(before);
01262 if (before)
01263 v1=sdg->Get_Vertex(before);
01264 } while (before && !v1);
01265 if (v1) {
01266 EINDEX16 e;
01267 if (!(e=sdg->Get_Edge(v1,v))) {
01268 e=sdg->Add_Edge(v1,v,level);
01269 if (!e)
01270 return 0;
01271 }
01272 sdg->Set_Level_Property(e,HAS_ALL_ZERO);
01273 if (!(e=sdg->Get_Edge(v,v1))) {
01274 e=sdg->Add_Edge(v,v1,level);
01275 if (!e)
01276 return 0;
01277 }
01278 }
01279 #endif
01280 WN* after=wn;
01281 v1=0;
01282 do {
01283 after=WN_next(after);
01284 if (after)
01285 v1=sdg->Get_Vertex(after);
01286 } while (after && !v1);
01287 if (v1) {
01288 EINDEX16 e;
01289 if (!(e=sdg->Get_Edge(v,v1))) {
01290 e=sdg->Add_Edge(v,v1,level);
01291 if (!e)
01292 return 0;
01293 }
01294 sdg->Set_Level_Property(e,HAS_ALL_ZERO);
01295 if (!(e=sdg->Get_Edge(v1,v))) {
01296 e=sdg->Add_Edge(v1,v,level);
01297 if (!e)
01298 return 0;
01299 }
01300 }
01301 return 1;
01302 } else {
01303 if (WN_opcode(wn)==OPC_DO_LOOP)
01304 parent_loop=wn;
01305 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
01306 WN* kid = WN_kid(wn,kidno);
01307 if (Generate_Pragma_Dependence_For_Statement_Dependence_Graph(
01308 kid,parent_loop,sdg)==0)
01309 return 0;
01310 }
01311 return 1;
01312 }
01313 }
01314
01315 extern BOOL Generate_Scalar_Dependence_For_Statement_Dependence_Graph(
01316 WN* in_loop,
01317 SCALAR_STACK *scalar_reads,
01318 SCALAR_STACK *scalar_writes,
01319 SCALAR_REF_STACK *params,
01320 ARRAY_DIRECTED_GRAPH16* sdg,
01321 REDUCTION_MANAGER* Red_Mgr,
01322 BIT_VECTOR *Expandable_Scalar_Set,
01323 BINARY_TREE<NAME2BIT> *mapping_dictionary
01324
01325
01326 )
01327 {
01328
01329
01330 UINT32 stmt_level=Do_Loop_Depth(in_loop);
01331
01332 INT si;
01333 for (si=0; si<scalar_writes->Elements(); si++) {
01334
01335 SCALAR_NODE *sinode = scalar_writes->Bottom_nth(si);
01336 WN *scalar_write = sinode->Bottom_nth(0)->Wn;
01337
01338 for (INT sj=si; sj<scalar_writes->Elements(); sj++) {
01339 SCALAR_NODE *sjnode = scalar_writes->Bottom_nth(sj);
01340 WN *scalar_write1 = sjnode->Bottom_nth(0)->Wn;
01341
01342 if (Aliased(Alias_Mgr,scalar_write,scalar_write1)!=NOT_ALIASED) {
01343
01344
01345 BOOL scalar_expandable=FALSE;
01346
01347 SYMBOL sym(scalar_write);
01348 SYMBOL sym1(scalar_write1);
01349 if (sym==sym1) {
01350 if (mapping_dictionary) {
01351
01352 NAME2BIT temp_map(scalar_write);
01353 const NAME2BIT *name_map=
01354 mapping_dictionary->Find(temp_map)->Get_Data();
01355 if (Expandable_Scalar_Set->Test(name_map->Get_Bit_Position())) {
01356
01357
01358 scalar_expandable=TRUE;
01359 }
01360 }
01361 }
01362
01363 for (INT sii=0; sii<sinode->Elements(); sii++) {
01364 WN* wn=sinode->Bottom_nth(sii)->Wn;
01365 UINT ii_stmt_number=sinode->Bottom_nth(sii)->Statement_Number;
01366 WN* ii_stmt;
01367
01368 REDUCTION_TYPE red_type;
01369 if (Red_Mgr)
01370 red_type=Red_Mgr->Which_Reduction(wn);
01371 else
01372 red_type=RED_NONE;
01373
01374 for (INT sjj=0; sjj<sjnode->Elements(); sjj++) {
01375 WN* wn1=sjnode->Bottom_nth(sjj)->Wn;
01376 if (red_type!=RED_NONE && Red_Mgr->Which_Reduction(wn1)==red_type)
01377 continue;
01378 if (wn==wn1)
01379 continue;
01380 UINT jj_stmt_number=sjnode->Bottom_nth(sjj)->Statement_Number;
01381
01382 WN* jj_stmt;
01383 stmt_level=Get_Stmt_For_Stmt_Dep_Graph(wn,wn1,&ii_stmt,&jj_stmt);
01384
01385 EINDEX16 e1;
01386 EINDEX16 e2=1;
01387 if (ii_stmt_number < jj_stmt_number) {
01388 e1=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01389 if (!scalar_expandable)
01390 e2=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01391 } else {
01392 e1=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01393 if (!scalar_expandable)
01394 e2=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01395 }
01396 if (e1==0 || e2==0) {
01397 return FALSE;
01398 }
01399 if (e1!=0)
01400 sdg->Set_Level_Property(e1, HAS_ALL_ZERO);
01401 }
01402 }
01403 }
01404 }
01405 }
01406
01407 for (si=0; si<scalar_reads->Elements(); si++) {
01408
01409 SCALAR_NODE *sinode = scalar_reads->Bottom_nth(si);
01410 WN *scalar_read = sinode->Bottom_nth(0)->Wn;
01411
01412 for (INT sj=0; sj<scalar_writes->Elements(); sj++) {
01413 SCALAR_NODE *sjnode = scalar_writes->Bottom_nth(sj);
01414 WN *scalar_write = sjnode->Bottom_nth(0)->Wn;
01415
01416 if (Aliased(Alias_Mgr,scalar_read,scalar_write)!=NOT_ALIASED) {
01417
01418 BOOL scalar_expandable=FALSE;
01419
01420 SYMBOL sym(scalar_write);
01421 SYMBOL sym1(scalar_read);
01422 if (sym==sym1) {
01423 if (mapping_dictionary) {
01424
01425 NAME2BIT temp_map(scalar_write);
01426 const NAME2BIT *name_map=
01427 mapping_dictionary->Find(temp_map)->Get_Data();
01428 if (Expandable_Scalar_Set->Test(name_map->Get_Bit_Position())) {
01429
01430
01431 scalar_expandable=TRUE;
01432 }
01433 }
01434 }
01435
01436 for (INT sii=0; sii<sinode->Elements(); sii++) {
01437 WN* wn=sinode->Bottom_nth(sii)->Wn;
01438 UINT ii_stmt_number=sinode->Bottom_nth(sii)->Statement_Number;
01439 WN* ii_stmt;
01440
01441 REDUCTION_TYPE red_type;
01442 if (Red_Mgr)
01443 red_type=Red_Mgr->Which_Reduction(wn);
01444 else
01445 red_type=RED_NONE;
01446
01447 for (INT sjj=0; sjj<sjnode->Elements(); sjj++) {
01448 WN* wn1=sjnode->Bottom_nth(sjj)->Wn;
01449 if (red_type!=RED_NONE && Red_Mgr->Which_Reduction(wn1)==red_type)
01450 continue;
01451 UINT jj_stmt_number=sjnode->Bottom_nth(sjj)->Statement_Number;
01452
01453 WN* jj_stmt;
01454 stmt_level=Get_Stmt_For_Stmt_Dep_Graph(wn,wn1,&ii_stmt,&jj_stmt);
01455
01456 EINDEX16 e1;
01457 EINDEX16 e2=1;
01458 if (ii_stmt_number < jj_stmt_number) {
01459 e1=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01460 if (!scalar_expandable)
01461 e2=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01462 } else {
01463 e1=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01464 if (!scalar_expandable)
01465 e2=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01466 }
01467 if (e1==0 || e2==0) {
01468 return FALSE;
01469 }
01470 if (e1!=0)
01471 sdg->Set_Level_Property(e1, HAS_ALL_ZERO);
01472 }
01473 }
01474 }
01475 }
01476 }
01477
01478 for (si=0; si<params->Elements(); si++) {
01479
01480 SCALAR_REF siref = params->Bottom_nth(si);
01481 WN *param = siref.Wn;
01482 UINT ii_stmt_number=siref.Statement_Number;
01483
01484 WN* tmp=WN_kid0(param);
01485 OPERATOR opr=WN_operator(tmp);
01486
01487 INT sj;
01488 for (sj=0; sj<scalar_writes->Elements(); sj++) {
01489 SCALAR_NODE *sjnode = scalar_writes->Bottom_nth(sj);
01490 WN *scalar_write = sjnode->Bottom_nth(0)->Wn;
01491
01492 if (Aliased(Alias_Mgr,param,scalar_write)!=NOT_ALIASED) {
01493
01494 for (INT sjj=0; sjj<sjnode->Elements(); sjj++) {
01495 WN* wn1=sjnode->Bottom_nth(sjj)->Wn;
01496 UINT jj_stmt_number=sjnode->Bottom_nth(sjj)->Statement_Number;
01497
01498 WN* ii_stmt;
01499 WN* jj_stmt;
01500 stmt_level=
01501 Get_Stmt_For_Stmt_Dep_Graph(param,wn1,&ii_stmt,&jj_stmt);
01502
01503 EINDEX16 e1;
01504 EINDEX16 e2;
01505 if (ii_stmt_number < jj_stmt_number) {
01506 e1=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01507 e2=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01508 } else {
01509 e1=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01510 e2=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01511 }
01512 if (e1==0 || e2==0) {
01513 return FALSE;
01514 }
01515 if (e1!=0)
01516 sdg->Set_Level_Property(e1, HAS_ALL_ZERO);
01517 }
01518 }
01519 }
01520
01521 for (sj=0; sj<scalar_reads->Elements(); sj++) {
01522 SCALAR_NODE *sjnode = scalar_reads->Bottom_nth(sj);
01523 WN *scalar_read = sjnode->Bottom_nth(0)->Wn;
01524
01525 if (Aliased(Alias_Mgr,param,scalar_read)!=NOT_ALIASED) {
01526
01527 for (INT sjj=0; sjj<sjnode->Elements(); sjj++) {
01528 WN* wn1=sjnode->Bottom_nth(sjj)->Wn;
01529 UINT jj_stmt_number=sjnode->Bottom_nth(sjj)->Statement_Number;
01530
01531 WN* ii_stmt;
01532 WN* jj_stmt;
01533 stmt_level=
01534 Get_Stmt_For_Stmt_Dep_Graph(param,wn1,&ii_stmt,&jj_stmt);
01535
01536 EINDEX16 e1;
01537 EINDEX16 e2;
01538 if (ii_stmt_number < jj_stmt_number) {
01539 e1=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01540 e2=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01541 } else {
01542 e1=Add_Stmt_Dependence(jj_stmt, ii_stmt, stmt_level, sdg);
01543 e2=Add_Stmt_Dependence(ii_stmt, jj_stmt, stmt_level, sdg);
01544 }
01545 if (e1==0 || e2==0) {
01546 return FALSE;
01547 }
01548 if (e1!=0)
01549 sdg->Set_Level_Property(e1, HAS_ALL_ZERO);
01550 }
01551 }
01552 }
01553 }
01554 return Generate_Pragma_Dependence_For_Statement_Dependence_Graph(
01555 in_loop,in_loop,sdg);
01556 }
01557
01558 extern BOOL Generate_Array_Dependence_For_Statement_Dependence_Graph(
01559 WN* in_loop,
01560 REF_LIST_STACK *reads,
01561 REF_LIST_STACK *writes,
01562 ARRAY_DIRECTED_GRAPH16* sdg,
01563 REDUCTION_MANAGER* Red_Mgr,
01564 ARRAY_DIRECTED_GRAPH16* adg) {
01565
01566 UINT loop_depth=Do_Loop_Depth(in_loop);
01567
01568 WN* loop_body=WN_do_body(in_loop);
01569 REF_LIST_STACK *ref_list_stack[2];
01570 ref_list_stack[0]=reads;
01571 ref_list_stack[1]=writes;
01572
01573
01574 for (INT ii=0; ii<2; ii++) {
01575
01576 for (INT i=0;i<ref_list_stack[ii]->Elements(); i++) {
01577
01578 REFERENCE_ITER iter(ref_list_stack[ii]->Bottom_nth(i));
01579 for (REFERENCE_NODE *n=iter.First(); !iter.Is_Empty(); n=iter.Next()) {
01580
01581 WN* ref=n->Wn;
01582 VINDEX16 array_v=adg->Get_Vertex(ref);
01583 if (array_v==0) {
01584
01585
01586 WN* stmt=Find_Stmt_Under(ref,loop_body);
01587 VINDEX16 v=sdg->Get_Vertex(stmt);
01588 if (v!=0)
01589 sdg->Delete_Vertex(v);
01590 } else {
01591
01592 WN* stmt=Find_Stmt_Under(ref,loop_body);
01593
01594
01595
01596
01597
01598
01599 EINDEX16 in_edge=adg->Get_In_Edge(array_v);
01600 while (in_edge) {
01601
01602 WN* source_ref=adg->Get_Wn(adg->Get_Source(in_edge));
01603 WN* source_stmt=Find_Stmt_Under(source_ref,loop_body);
01604 if (source_stmt) {
01605 if (!Edge_Is_Reduction_Dependence(in_edge,adg,Red_Mgr)) {
01606 EINDEX16 e1=Array_Edge_To_Level_Edge(in_edge, adg, sdg);
01607 if (e1==0)
01608 return FALSE;
01609 else if (sdg->Level(e1)<loop_depth)
01610 sdg->Delete_Edge(e1);
01611 }
01612 }
01613
01614 in_edge = adg->Get_Next_In_Edge(in_edge);
01615 }
01616 EINDEX16 out_edge=adg->Get_Out_Edge(array_v);
01617 while (out_edge) {
01618
01619 WN* sink_ref=adg->Get_Wn(adg->Get_Sink(out_edge));
01620 WN* sink_stmt=Find_Stmt_Under(sink_ref,loop_body);
01621 if (sink_stmt) {
01622 if (!Edge_Is_Reduction_Dependence(out_edge,adg,Red_Mgr)) {
01623 EINDEX16 e1=Array_Edge_To_Level_Edge(out_edge, adg, sdg);
01624 if (e1==0)
01625 return FALSE;
01626 else if (sdg->Level(e1)<loop_depth)
01627 sdg->Delete_Edge(e1);
01628 }
01629 }
01630
01631 out_edge = adg->Get_Next_Out_Edge(out_edge);
01632 }
01633 }
01634 }
01635 }
01636 }
01637 return TRUE;
01638 }
01639
01640 #ifdef KEY
01641 static BOOL Loop_Has_Asm (WN* loop)
01642 {
01643 LWN_ITER* itr = LWN_WALK_TreeIter(WN_do_body(loop));
01644 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
01645 WN* node = itr->wn;
01646 if (WN_operator(node) == OPR_ASM_STMT)
01647 return TRUE;
01648 }
01649 return FALSE;
01650 }
01651 #endif
01652
01653 extern ARRAY_DIRECTED_GRAPH16* Build_Statement_Dependence_Graph(
01654 WN* in_loop,
01655 REDUCTION_MANAGER* Red_Mgr,
01656 ARRAY_DIRECTED_GRAPH16* adg,
01657 WN_MAP sdm,
01658 MEM_POOL* pool)
01659 {
01660 #ifdef KEY //bug 14121: statement dependence graph will be incorrect
01661
01662 if(Loop_Has_Asm(in_loop))
01663 return NULL;
01664 #endif
01665
01666 MEM_POOL_Push(&LNO_local_pool);
01667 ARRAY_DIRECTED_GRAPH16 *sdg;
01668
01669 {
01670
01671 REF_LIST_STACK *writes = CXX_NEW(REF_LIST_STACK(&LNO_local_pool),
01672 &LNO_local_pool);
01673 REF_LIST_STACK *reads = CXX_NEW(REF_LIST_STACK(&LNO_local_pool),
01674 &LNO_local_pool);
01675
01676 SCALAR_STACK *scalar_writes = CXX_NEW(SCALAR_STACK(&LNO_local_pool),
01677 &LNO_local_pool);
01678 SCALAR_STACK *scalar_reads = CXX_NEW(SCALAR_STACK(&LNO_local_pool),
01679 &LNO_local_pool);
01680 SCALAR_REF_STACK *params = CXX_NEW(SCALAR_REF_STACK(&LNO_local_pool),
01681 &LNO_local_pool);
01682
01683 DOLOOP_STACK *stack=CXX_NEW(DOLOOP_STACK(&LNO_local_pool),
01684 &LNO_local_pool);
01685 Build_Doloop_Stack(in_loop, stack);
01686
01687
01688 WN* loop_body=WN_do_body(in_loop);
01689 Init_Ref_Stmt_Counter();
01690 INT32 status=0;
01691 for (WN* wn=WN_first(loop_body); wn && status!= -1; wn=WN_next(wn)) {
01692 status=New_Gather_References(
01693 wn,writes,reads,stack,scalar_writes,scalar_reads,
01694 params,&LNO_local_pool);
01695 }
01696 if (status == -1) {
01697 DevWarn("Aborted from New_Gather_References");
01698 MEM_POOL_Pop(&LNO_local_pool);
01699 return NULL;
01700 }
01701
01702 sdg = CXX_NEW(ARRAY_DIRECTED_GRAPH16(100,500,sdm,LEVEL_ARRAY_GRAPH), pool);
01703
01704 for (WN* stmt = WN_first(loop_body); stmt; stmt = WN_next(stmt)) {
01705 if (!Map_Stmt_To_Level_Graph(stmt,sdg)) {
01706 DevWarn("Statement dependence graph problem");
01707 MEM_POOL_Pop(&LNO_local_pool);
01708 return NULL;
01709 }
01710 }
01711
01712 if (!Generate_Scalar_Dependence_For_Statement_Dependence_Graph(
01713 in_loop, scalar_reads, scalar_writes, params, sdg, Red_Mgr)) {
01714 CXX_DELETE(sdg,pool);
01715 sdg=NULL;
01716 } else if (!Generate_Array_Dependence_For_Statement_Dependence_Graph(
01717 in_loop, reads, writes, sdg, Red_Mgr, adg)) {
01718 CXX_DELETE(sdg,pool);
01719 sdg=NULL;
01720 }
01721 }
01722
01723 MEM_POOL_Pop(&LNO_local_pool);
01724 return sdg;
01725
01726 }
01727
01728