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 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #ifdef USE_PCH
00043 #include "lno_pch.h"
00044 #endif // USE_PCH
00045 #pragma hdrstop
00046
00047 #include <sys/types.h>
00048 #include "defs.h"
00049 #include "lnopt_main.h"
00050 #include "mat.h"
00051 #include "cxx_base.h"
00052 #include "access_vector.h"
00053 #include "snl.h"
00054 #include "opt_du.h"
00055 #include "lwn_util.h"
00056 #include "lnoutils.h"
00057 #include "scalar_expand.h"
00058 #include "sxlist.h"
00059 #include "sdlist.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 SD_PNODE::SD_PNODE(const SYMBOL& symbol,
00072 INT innermost_depth,
00073 BOOL above):
00074 _symbol(symbol), _innermost_depth(innermost_depth), _above(above),
00075 _in_closure(SD_HASH_SIZE, &LNO_local_pool)
00076 {
00077 }
00078
00079
00080
00081
00082
00083
00084 void SD_PNODE::Print(FILE* fp) const
00085 {
00086 fprintf(fp, "<%s:[%d]>", _symbol.Name(), _innermost_depth);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 SD_PLIST::~SD_PLIST() {
00100 while (!Is_Empty())
00101 CXX_DELETE(Remove_Head(), _pool);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 const SD_PNODE* SD_PLIST::Find(const SYMBOL& sym) const
00111 {
00112 SD_CONST_PITER i(this);
00113 for (const SD_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00114 if (n->Symbol() == sym)
00115 return n;
00116 return NULL;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125 SD_PNODE* SD_PLIST::Find(const SYMBOL& sym)
00126 {
00127 SD_PITER i(this);
00128 for (SD_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00129 if (n->Symbol() == sym)
00130 return n;
00131 return NULL;
00132 }
00133
00134
00135
00136
00137
00138
00139 void SD_PLIST::Print(FILE* fp) const
00140 {
00141 SD_CONST_PITER i(this);
00142 for (const SD_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00143 n->Print(fp);
00144 fprintf(stdout, "\n");
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 BOOL Is_Above(WN* wn_ref)
00165 {
00166 WN* wnn = NULL;
00167 WN* wn = NULL;
00168 for (wn = wn_ref; wn != NULL; wn = wnn) {
00169 wnn = LWN_Get_Parent(wn);
00170 if (WN_opcode(wn) == OPC_DO_LOOP)
00171 return TRUE;
00172 if (wnn != NULL && WN_opcode(wnn) == OPC_BLOCK)
00173 break;
00174 }
00175 if (wn == NULL)
00176 return TRUE;
00177 WN* wn_first = wn;
00178 for (wn = wn_first; wn != NULL; wn = WN_next(wn))
00179 if (WN_opcode(wn) == OPC_DO_LOOP)
00180 return TRUE;
00181 return FALSE;
00182 }
00183
00184
00185
00186
00187
00188
00189 BOOL SD_INFO::Update(SD_PNODE* sd_ref,
00190 WN* wn)
00191 {
00192 sd_ref->Add_Closure(wn);
00193 INT depth = Loop_Depth(wn);
00194 BOOL above = Is_Above(wn);
00195 if (sd_ref->Innermost_Depth() == depth
00196 && (sd_ref->Above() && !above || !sd_ref->Above() && above)) {
00197 Set_Worst_Case(sd_ref);
00198 return FALSE;
00199 }
00200 if (sd_ref->Innermost_Depth() < depth) {
00201 sd_ref->Set_Innermost_Depth(depth);
00202 sd_ref->Set_Above(above);
00203 }
00204 if (Is_Worst_Case(sd_ref))
00205 return FALSE;
00206 return TRUE;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void SD_INFO::Set_Worst_Case(SD_PNODE* sd_ref)
00216 {
00217 if (sd_ref != NULL) {
00218 sd_ref->Set_Innermost_Depth(_max_inner_depth);
00219 } else {
00220 SD_PITER ii(&Plist);
00221 for (SD_PNODE* sdn = ii.First(); !ii.Is_Empty(); sdn = ii.Next())
00222 sdn->Set_Innermost_Depth(_max_inner_depth);
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 BOOL SD_INFO::Push_Memory_Nodes(WN* wn_orig,
00236 SD_PNODE* sd_ref,
00237 STACK<WN*>* st_closure)
00238 {
00239 if (sd_ref->In_Closure(wn_orig))
00240 return TRUE;
00241 if (!Wn_Is_Inside(wn_orig, _wn_outer))
00242 return TRUE;
00243 WN* wnn = NULL;
00244 for (WN* wn = wn_orig; wn != NULL; wnn = wn, wn = LWN_Get_Parent(wn)) {
00245 OPCODE op = WN_opcode(wn);
00246 if (op == OPC_BLOCK || op == OPC_DO_LOOP)
00247 break;
00248 }
00249 WN* wn_stat = wnn;
00250 if (wn_stat == NULL)
00251 return TRUE;
00252 LWN_ITER* itr = LWN_WALK_TreeIter(wn_stat);
00253 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
00254 WN* wn = itr->wn;
00255 switch (WN_operator(wn)) {
00256 case OPR_STID:
00257 if (!Index_Variable(wn) && !sd_ref->In_Closure(wn)) {
00258 BOOL ok = Register_Stid(wn, sd_ref);
00259 if (ok) {
00260 st_closure->Push(wn);
00261 } else {
00262 st_closure->Clear();
00263 return FALSE;
00264 }
00265 }
00266 break;
00267 case OPR_LDID:
00268 if (!Index_Variable(wn) && !sd_ref->In_Closure(wn)) {
00269 BOOL ok = Register_Ldid(wn, sd_ref);
00270 if (ok) {
00271 st_closure->Push(wn);
00272 } else {
00273 st_closure->Clear();
00274 return FALSE;
00275 }
00276 }
00277 break;
00278 case OPR_ILOAD:
00279 if (!Index_Variable(wn) && !sd_ref->In_Closure(wn)) {
00280 BOOL ok = Register_ILoad(wn, sd_ref);
00281 if (ok) {
00282 st_closure->Push(wn);
00283 } else {
00284 st_closure->Clear();
00285 return FALSE;
00286 }
00287 }
00288 break;
00289 case OPR_ISTORE:
00290 if (!Index_Variable(wn) && !sd_ref->In_Closure(wn)) {
00291 BOOL ok = Register_IStore(wn, sd_ref);
00292 if (ok) {
00293 st_closure->Push(wn);
00294 } else {
00295 st_closure->Clear();
00296 return FALSE;
00297 }
00298 }
00299 break;
00300 case OPR_MLOAD:
00301 case OPR_MSTORE:
00302 case OPR_CALL:
00303 case OPR_ICALL:
00304 case OPR_INTRINSIC_CALL:
00305 case OPR_IO:
00306 Set_Worst_Case(NULL);
00307 st_closure->Clear();
00308 return FALSE;
00309 }
00310 }
00311 return TRUE;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321 BOOL SD_INFO::Register_Ldid(WN* wn_ldid,
00322 SD_PNODE* sd_ref)
00323 {
00324 DU_MANAGER* du = Du_Mgr;
00325 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00326 if (dg->Get_Vertex(wn_ldid) != 0) {
00327 Set_Worst_Case(sd_ref);
00328 return FALSE;
00329 }
00330 DEF_LIST* def_list = du->Ud_Get_Def(wn_ldid);
00331 if (def_list == NULL || def_list->Incomplete()) {
00332 Set_Worst_Case(sd_ref);
00333 return FALSE;
00334 }
00335 if (!Update(sd_ref, wn_ldid))
00336 return FALSE;
00337 return TRUE;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 BOOL SD_INFO::Closure_Ldid(WN* wn_ldid,
00350 SD_PNODE* sd_ref,
00351 STACK<WN*>* st_closure)
00352 {
00353 DU_MANAGER* du = Du_Mgr;
00354 DEF_LIST* def_list = du->Ud_Get_Def(wn_ldid);
00355 DEF_LIST_ITER iter(def_list);
00356 const DU_NODE* node = NULL;
00357 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00358 WN* wn_def = node->Wn();
00359 if (!Push_Memory_Nodes(wn_def, sd_ref, st_closure))
00360 return FALSE;
00361 }
00362 return TRUE;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372 BOOL SD_INFO::Register_Stid(WN* wn_stid,
00373 SD_PNODE* sd_ref)
00374 {
00375 DU_MANAGER* du = Du_Mgr;
00376 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00377 if (dg->Get_Vertex(wn_stid) != 0) {
00378 Set_Worst_Case(sd_ref);
00379 return FALSE;
00380 }
00381 USE_LIST *use_list = du->Du_Get_Use(wn_stid);
00382 if (use_list == NULL || use_list->Incomplete()) {
00383 Set_Worst_Case(sd_ref);
00384 return FALSE;
00385 }
00386 if (!Update(sd_ref, wn_stid))
00387 return FALSE;
00388 return TRUE;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 BOOL SD_INFO::Closure_Stid(WN* wn_stid,
00401 SD_PNODE* sd_ref,
00402 STACK<WN*>* st_closure)
00403 {
00404 DU_MANAGER* du = Du_Mgr;
00405 USE_LIST *use_list = du->Du_Get_Use(wn_stid);
00406 USE_LIST_ITER iter(use_list);
00407 const DU_NODE* node = NULL;
00408 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00409 WN* wn_use = node->Wn();
00410 if (!Push_Memory_Nodes(wn_use, sd_ref, st_closure))
00411 return FALSE;
00412 }
00413 return TRUE;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 BOOL SD_INFO::Register_ILoad(WN* wn_iload,
00424 SD_PNODE* sd_ref)
00425 {
00426 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00427 if (!Update(sd_ref, wn_iload))
00428 return FALSE;
00429 return TRUE;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 BOOL SD_INFO::Closure_ILoad(WN* wn_iload,
00442 SD_PNODE* sd_ref,
00443 STACK<WN*>* st_closure)
00444 {
00445 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00446 EINDEX16 e = 0;
00447 VINDEX16 v_iload = dg->Get_Vertex(wn_iload);
00448 for (e = dg->Get_In_Edge(v_iload); e != 0; e = dg->Get_Next_In_Edge(e)) {
00449 WN* wn_source = dg->Get_Wn(dg->Get_Source(e));
00450 if (!Push_Memory_Nodes(wn_source, sd_ref, st_closure))
00451 return FALSE;
00452 }
00453 return TRUE;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463 BOOL SD_INFO::Register_IStore(WN* wn_istore,
00464 SD_PNODE* sd_ref)
00465 {
00466 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00467 if (!Update(sd_ref, wn_istore))
00468 return FALSE;
00469 return TRUE;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 BOOL SD_INFO::Closure_IStore(WN* wn_istore,
00482 SD_PNODE* sd_ref,
00483 STACK<WN*>* st_closure)
00484 {
00485 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00486 EINDEX16 e = 0;
00487 VINDEX16 v_istore = dg->Get_Vertex(wn_istore);
00488 for (e = dg->Get_Out_Edge(v_istore); e != 0; e = dg->Get_Next_Out_Edge(e)) {
00489 WN* wn_sink = dg->Get_Wn(dg->Get_Sink(e));
00490 if (WN_operator(wn_sink) != OPR_ILOAD)
00491 continue;
00492 if (!Push_Memory_Nodes(wn_sink, sd_ref, st_closure))
00493 return FALSE;
00494 }
00495 return TRUE;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504 void SD_INFO::Closure(WN* wn_ref)
00505 {
00506 DU_MANAGER* du = Du_Mgr;
00507 ARRAY_DIRECTED_GRAPH16* dg = Array_Dependence_Graph;
00508
00509 SYMBOL sym_ref(wn_ref);
00510 SD_PNODE* sd_ref = Find(sym_ref);
00511 FmtAssert(sd_ref != NULL, ("Computing closure on non-entered symbol"));
00512 if (sd_ref->In_Closure(wn_ref) || Is_Worst_Case(sd_ref))
00513 return;
00514
00515 STACK<WN*> st_closure(&LNO_local_pool);
00516 if (!Push_Memory_Nodes(wn_ref, sd_ref, &st_closure))
00517 return;
00518
00519 while (st_closure.Elements() > 0) {
00520 WN* wn = st_closure.Pop();
00521 switch (WN_operator(wn)) {
00522 case OPR_LDID:
00523 if (!Closure_Ldid(wn, sd_ref, &st_closure))
00524 return;
00525 break;
00526 case OPR_STID:
00527 if (!Closure_Stid(wn, sd_ref, &st_closure))
00528 return;
00529 break;
00530 case OPR_ILOAD:
00531 if (!Closure_ILoad(wn, sd_ref, &st_closure))
00532 return;
00533 break;
00534 case OPR_ISTORE:
00535 if (!Closure_IStore(wn, sd_ref, &st_closure))
00536 return;
00537 break;
00538 default:
00539 FmtAssert(TRUE, ("Bad node type on closure stack"));
00540 break;
00541 }
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 void SD_INFO::Handle_Def(WN* wn)
00552 {
00553 SYMBOL sym(wn);
00554 Create(sym, wn);
00555 Closure(wn);
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565 const SD_PNODE* SD_INFO::Find(const SYMBOL& sym) const
00566 {
00567 SD_CONST_PITER i(&Plist);
00568 for (const SD_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00569 if (n->Symbol() == sym)
00570 return n;
00571 return NULL;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581 SD_PNODE* SD_INFO::Find(const SYMBOL& sym)
00582 {
00583 SD_PITER i(&Plist);
00584 for (SD_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00585 if (n->Symbol() == sym)
00586 return n;
00587 return NULL;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597 void SD_INFO::Enter(const SYMBOL& sym,
00598 INT innermost_depth,
00599 BOOL above)
00600 {
00601 Is_True(Find(sym) == NULL,
00602 ("Entering %s twice into SD_INFO", sym.Name()));
00603 SD_PNODE* n = CXX_NEW(SD_PNODE(sym, innermost_depth, above),
00604 Plist.Pool());
00605 Plist.Append(n);
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 void SD_INFO::Create(const SYMBOL& sym,
00617 WN* wn)
00618 {
00619 SD_PNODE* sd_node = Find(sym);
00620 INT innermost_depth = Loop_Depth(wn);
00621 BOOL above = Is_Above(wn);
00622 if (sd_node == NULL) {
00623 sd_node = CXX_NEW(SD_PNODE(sym, innermost_depth, above),
00624 Plist.Pool());
00625 Plist.Append(sd_node);
00626 } else {
00627 Update(sd_node, wn);
00628 }
00629 }
00630
00631
00632
00633
00634
00635
00636 void SD_INFO::Remove(SD_PNODE* sdn)
00637 {
00638 Plist.Remove(sdn);
00639 }
00640
00641
00642
00643
00644
00645
00646 void SD_INFO::Print(FILE* f) const
00647 {
00648 Plist.Print(f);
00649 fprintf(f, "\n");
00650 }
00651
00652
00653
00654
00655
00656
00657
00658 void SD_INFO::Make_Sd_Info(WN* wn_outer,
00659 INT nloops)
00660 {
00661 _wn_outer = wn_outer;
00662 WN* wn_inner = SNL_Get_Inner_Snl_Loop(wn_outer, nloops);
00663 _max_inner_depth = Do_Loop_Depth(wn_inner);
00664 LWN_ITER* itr = LWN_WALK_TreeIter(wn_outer);
00665 for (; itr != NULL; itr = LWN_WALK_TreeNext(itr)) {
00666 WN* wn = itr->wn;
00667 OPERATOR opr = WN_operator(wn);
00668 if (opr == OPR_STID && !Index_Variable(wn))
00669 Handle_Def(wn);
00670 }
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 BOOL SD_INFO::Distribution_Range(INT depth,
00682 SX_INFO* sx_info)
00683 {
00684 INT best_upper_range = -1;
00685 SD_CONST_PITER ii(&Plist);
00686 for (const SD_PNODE* sdn = ii.First(); !ii.Is_Empty(); sdn = ii.Next()) {
00687 const SX_PNODE* sxn = sx_info->Find(sdn->Symbol());
00688 if (sxn != NULL && sxn->Transformable(depth) == SX_PNODE::ILLEGAL) {
00689 if (best_upper_range == -1 || best_upper_range < sdn->Innermost_Depth())
00690 best_upper_range = sdn->Innermost_Depth();
00691 }
00692 }
00693 return best_upper_range;
00694 }