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
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 static INT Which_Loop_Inside(WN* ref, DOLOOP_STACK* stack, INT first)
00100 {
00101 INT i;
00102 for (i = first; i >= 0; i--)
00103 if (Wn_Is_Inside(ref, stack->Bottom_nth(i)))
00104 break;
00105 return i;
00106 }
00107
00108
00109
00110
00111
00112
00113 static INT Which_Loop_Inside(WN* ref, DOLOOP_STACK* stack)
00114 {
00115 return Which_Loop_Inside(ref, stack, stack->Elements() - 1);
00116 }
00117
00118
00119
00120
00121
00122
00123 SX_PNODE::SX_PNODE(WN* wn_symbol,
00124 const SYMBOL& symbol,
00125 WN* reduction_carried_by,
00126 INT outer_se_reqd,
00127 INT outer_se_not_reqd,
00128 INT defining_def_depth,
00129 INT lcd_depth,
00130 BOOL finalize):
00131 _wn_symbol(wn_symbol), _symbol(symbol),
00132 _reduction_carried_by(reduction_carried_by),
00133 _outer_se_reqd(outer_se_reqd), _outer_se_not_reqd(outer_se_not_reqd),
00134 _defining_def_depth(defining_def_depth), _finalize(finalize),
00135 _lcd_depth(lcd_depth) {
00136 FmtAssert(_outer_se_reqd <= _outer_se_not_reqd,
00137 ("how can scalar expansion disable transformation? %d %d",
00138 _outer_se_reqd, _outer_se_not_reqd));
00139 }
00140
00141 void SX_PNODE::Print(FILE* fp) const
00142 {
00143 fprintf(fp, "<0x%p %s:se=%d,exdp=%d,nose=%d,lcd=%d",
00144 _wn_symbol, _symbol.Name(), _outer_se_reqd, _defining_def_depth,
00145 _outer_se_not_reqd, _lcd_depth);
00146 if (_reduction_carried_by)
00147 fprintf(fp, ",red_carried_by=%s(0x%p)",
00148 SYMBOL(WN_index(_reduction_carried_by)).Name(), _reduction_carried_by);
00149 fprintf(fp, ">");
00150 }
00151
00152 SX_PNODE::STATUS SX_PNODE::Transformable(INT depth, INT permutation[],
00153 INT nloops) const
00154 {
00155 if (depth >= _outer_se_not_reqd)
00156 return SX_PNODE::SE_NOT_REQD;
00157 if (permutation != NULL) {
00158 INT i;
00159 for (i = _defining_def_depth - depth + 1; i < nloops; i++)
00160 if (permutation[i] != i)
00161 break;
00162 if (i == nloops)
00163 return SX_PNODE::SE_NOT_REQD;
00164 }
00165 if (depth >= _outer_se_reqd)
00166 return SX_PNODE::SE_REQD;
00167 return SX_PNODE::ILLEGAL;
00168 }
00169
00170
00171
00172
00173
00174
00175 SX_PLIST::~SX_PLIST() {
00176 while (!Is_Empty())
00177 CXX_DELETE(Remove_Head(), _pool);
00178 }
00179
00180 void SX_PLIST::Print(FILE* fp) const
00181 {
00182 SX_CONST_PITER i(this);
00183 for (const SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00184 n->Print(fp);
00185 fprintf(stdout, "\n");
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 SX_INFO::SX_INFO(const SX_INFO& pinfo,
00196 WN* wn_orig,
00197 WN* wn_copy,
00198 MEM_POOL* pool) : Plist(pool)
00199 {
00200 HASH_TABLE<WN*,WN*>* ht = Make_Loop_Mapping(wn_orig, wn_copy, pool);
00201 for (WN* wn = LWN_Get_Parent(wn_orig); wn; wn = LWN_Get_Parent(wn))
00202 if (WN_opcode(wn) == OPC_DO_LOOP)
00203 ht->Enter(wn, wn);
00204 SX_CONST_PITER ii(&pinfo.Plist);
00205 for (const SX_PNODE* n = ii.First(); !ii.Is_Empty(); n = ii.Next()) {
00206 WN* red = NULL;
00207 if (n->Reduction_Carried_By()) {
00208 red = ht->Find(n->Reduction_Carried_By());
00209 if (red == NULL && LNO_Verbose) {
00210 fprintf(stdout, "pnode: ");
00211 n->Print(stdout);
00212 fprintf(stdout, " is broken\n");
00213 }
00214 FmtAssert(red, ("Loop 0x%p(%s) had bad pnode reduction",
00215 wn_orig, SYMBOL(WN_index(wn_orig)).Name()));
00216 }
00217 Enter(n->Wn_Symbol(), n->Symbol(), red, n->Outer_Se_Reqd(),
00218 n->Outer_Se_Not_Reqd(),
00219 n->Expansion_Depth(), n->Lcd_Depth(), n->Finalize());
00220 }
00221 }
00222
00223 SX_INFO::SX_INFO(const SX_INFO& pinfo,
00224 WN* wn_orig,
00225 HASH_TABLE<WN*,WN*>* ht,
00226 MEM_POOL* pool) : Plist(pool)
00227 {
00228 for (WN* wn = LWN_Get_Parent(wn_orig); wn; wn = LWN_Get_Parent(wn))
00229 if (WN_opcode(wn) == OPC_DO_LOOP)
00230 ht->Enter(wn, wn);
00231 SX_CONST_PITER ii(&pinfo.Plist);
00232 for (const SX_PNODE* n = ii.First(); !ii.Is_Empty(); n = ii.Next()) {
00233 WN* red = NULL;
00234 if (n->Reduction_Carried_By()) {
00235 red = ht->Find(n->Reduction_Carried_By());
00236 if (red == NULL && LNO_Verbose) {
00237 fprintf(stdout, "pnode: ");
00238 n->Print(stdout);
00239 fprintf(stdout, " is broken\n");
00240 }
00241 FmtAssert(red, ("Loop 0x%p(%s) had bad pnode reduction",
00242 wn_orig, SYMBOL(WN_index(wn_orig)).Name()));
00243 }
00244 Enter(n->Wn_Symbol(), n->Symbol(), red, n->Outer_Se_Reqd(),
00245 n->Outer_Se_Not_Reqd(), n->Expansion_Depth(), n->Finalize(),
00246 n->Lcd_Depth());
00247 }
00248 }
00249
00250 void SX_INFO::Print(FILE* f) const
00251 {
00252 fprintf(f, "SX_INFO: (ftd=%d): ", First_Transformable_Depth());
00253 Plist.Print(f);
00254 fprintf(f, "\n");
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void SX_INFO::Enter(WN* wn_symbol,
00267 const SYMBOL& sym,
00268 WN* wn_rd,
00269 INT se_depth,
00270 INT no_se_depth,
00271 INT defining_def_depth,
00272 INT lcd_depth,
00273 BOOL finalize)
00274 {
00275 Is_True(Find(sym) == NULL,
00276 ("Entering %s twice into SX_INFO", sym.Name()));
00277 SX_PNODE* n = CXX_NEW(SX_PNODE(wn_symbol, sym, wn_rd, se_depth,
00278 no_se_depth, defining_def_depth, lcd_depth, finalize), Plist._pool);
00279 Plist.Append(n);
00280 }
00281
00282
00283
00284
00285
00286
00287 void SX_INFO::Remove(SX_PNODE* n)
00288 {
00289 Plist.Remove(n);
00290 }
00291
00292
00293
00294
00295
00296
00297 SX_PNODE* SX_INFO::Find(const SYMBOL& sym)
00298 {
00299 SX_PITER i(&Plist);
00300 for (SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00301 if (n->Symbol() == sym)
00302 return n;
00303 return NULL;
00304 }
00305
00306
00307
00308
00309
00310
00311 const SX_PNODE* SX_INFO::Find(const SYMBOL& sym) const
00312 {
00313 SX_CONST_PITER i(&Plist);
00314 for (const SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00315 if (n->Symbol() == sym)
00316 return n;
00317 return NULL;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 INT SX_INFO::First_Transformable_Depth(const SX_PNODE** p) const
00330 {
00331 INT ftd = 0;
00332 SX_CONST_PITER i(&Plist);
00333 if (p)
00334 *p = NULL;
00335 for (const SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next()) {
00336 if (ftd < n->_outer_se_reqd) {
00337 ftd = n->_outer_se_reqd;
00338 if (p)
00339 *p = n;
00340 }
00341 }
00342 return ftd;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 static BOOL Index_Variable_Outside_Loop(WN* wn_use,
00355 WN* wn_def,
00356 HASH_TABLE<WN*,BOOL>* loops)
00357 {
00358 WN* wn_parent = LWN_Get_Parent(wn_def);
00359 return wn_parent != NULL && WN_opcode(wn_parent) == OPC_DO_LOOP
00360 && loops->Find(wn_parent) && !Wn_Is_Inside(wn_use, wn_parent);
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 void SX_INFO::Handle_Use(WN* wn_use,
00379 INT depth,
00380 HASH_TABLE<WN*,BOOL>* loops)
00381 {
00382 DEF_LIST* dl = Du_Mgr->Ud_Get_Def(wn_use);
00383 if (dl == NULL) {
00384 DevWarn("missing def list for use (%s) while gathering sx info",
00385 SYMBOL(wn_use).Name());
00386 return;
00387 }
00388 DEF_LIST_ITER iter(dl);
00389 const DU_NODE* node = NULL;
00390 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00391 WN* wn_def = node->Wn();
00392 if (Index_Variable_Outside_Loop(wn_use, wn_def, loops)) {
00393 Enter(wn_use, SYMBOL(wn_use), NULL, depth + 1, depth + 1, 0, -1, FALSE);
00394 if (LNO_Verbose)
00395 fprintf(stdout, "ivar %s used outside loop makes untransformable\n",
00396 (SYMBOL(wn_use)).Name());
00397 SNL_DEBUG1(2, "ivar %s used outside loop makes untransformable\n",
00398 (SYMBOL(wn_use)).Name());
00399 return;
00400 }
00401 }
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 void SX_INFO::Handle_Index_Variable_Def(WN* wn_def,
00418 WN* wn_rep_def,
00419 INT depth)
00420 {
00421 if (wn_rep_def != NULL)
00422 return;
00423 SYMBOL sym(wn_def);
00424 USE_LIST* ul = Du_Mgr->Du_Get_Use(wn_def);
00425 USE_LIST_ITER iter(ul);
00426 const DU_NODE* node = NULL;
00427 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00428 WN* wn_use = node->Wn();
00429 if (!OPCODE_has_sym(WN_opcode(wn_use)) || sym != SYMBOL(wn_use)) {
00430
00431
00432 SX_PNODE* pnode = Find(SYMBOL(wn_def));
00433 if (pnode == NULL) {
00434 Enter(wn_def, SYMBOL(wn_def), NULL, depth + 1, depth + 1, 0, -1, FALSE);
00435 } else {
00436 pnode->_outer_se_reqd = depth + 1;
00437 pnode->_outer_se_not_reqd = depth + 1;
00438 pnode->_reduction_carried_by = NULL;
00439 pnode->_defining_def_depth = 0;
00440 }
00441 const char* name = OPCODE_has_sym(WN_opcode(wn_use))
00442 ? (SYMBOL(wn_use)).Name() : "<NONAME>";
00443 if (LNO_Verbose)
00444 fprintf(stdout, "ivar %s has link to use %s\n", sym.Name(), name);
00445 SNL_DEBUG2(2, "ivar %s has link to use %s\n", sym.Name(), name);
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453
00454
00455 static void Check_Loop_Statement(WN* wn,
00456 WN* wn_loop_stmt)
00457 {
00458 #ifdef Is_True_On
00459 if (wn_loop_stmt == NULL)
00460 return;
00461
00462 WN *parent;
00463 for (parent = wn; parent; parent = LWN_Get_Parent(parent))
00464 if (parent == wn_loop_stmt)
00465 break;
00466 const INT bufsz = 64;
00467 char buf[bufsz];
00468 FmtAssert(parent, ("Bad loop_stmt %s(0x%p) for %s(0x%p)",
00469 SYMBOL(WN_index(wn_loop_stmt)).Name(), wn_loop_stmt,
00470 SYMBOL(wn).Name(buf,bufsz), wn));
00471 #endif
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 BOOL SX_INFO::Analyze_Reduction(WN* wn_def,
00498 INT outer,
00499 STACK<WN*>* equivalence_class,
00500 DOLOOP_STACK* dostack,
00501 WN** wn_non_red_def_ptr,
00502 INT* non_red_depth_ptr,
00503 WN** wn_red_loop_stmt_ptr)
00504 {
00505 REDUCTION_TYPE rt_old = RED_NONE;
00506 BOOL bad = red_manager == NULL ? TRUE : FALSE;
00507 INT non_red_depth = -1;
00508 WN* wn_non_red_def = NULL;
00509 WN* wn_loop_stmt = NULL;
00510 WN* wn_red_loop_stmt = NULL;
00511 if (bad) {
00512 *wn_non_red_def_ptr = wn_non_red_def;
00513 *non_red_depth_ptr = non_red_depth;
00514 *wn_red_loop_stmt_ptr = wn_red_loop_stmt;
00515 return TRUE;
00516 }
00517
00518 INT elts = equivalence_class->Elements();
00519 INT i;
00520 for (i = 0; i < elts; i++) {
00521
00522 WN* wn = equivalence_class->Bottom_nth(i);
00523 OPERATOR opr = WN_operator(wn);
00524 if (opr != OPR_LDID && opr != OPR_STID || SYMBOL(wn_def) != SYMBOL(wn)) {
00525 DevWarn("Bad equivalence class");
00526 break;
00527 }
00528
00529 INT dwn = Which_Loop_Inside(wn, dostack);
00530 if (dwn < outer)
00531 continue;
00532
00533 REDUCTION_TYPE rt_new = red_manager->Which_Reduction(wn);
00534 if (rt_new == RED_NONE) {
00535
00536 if (non_red_depth != -1 && non_red_depth != dwn)
00537 break;
00538 non_red_depth = dwn;
00539 if (opr == OPR_STID) {
00540
00541 if (wn_non_red_def != NULL)
00542 break;
00543 wn_non_red_def = wn;
00544 }
00545 } else {
00546
00547 if (rt_old != RED_NONE && rt_old != rt_new)
00548 break;
00549 rt_old = rt_new;
00550 if (opr == OPR_LDID) {
00551 WN* wn_loop_stmt = Du_Mgr->Ud_Get_Def(wn)->Loop_stmt();
00552 Check_Loop_Statement(wn, wn_loop_stmt);
00553
00554 if (wn_loop_stmt != NULL && red_manager == NULL)
00555 break;
00556 if (wn_red_loop_stmt == NULL)
00557 wn_red_loop_stmt = wn_loop_stmt;
00558
00559 if (wn_red_loop_stmt != wn_loop_stmt)
00560 break;
00561 }
00562 }
00563 }
00564 *wn_non_red_def_ptr = wn_non_red_def;
00565 *non_red_depth_ptr = non_red_depth;
00566 *wn_red_loop_stmt_ptr = wn_red_loop_stmt;
00567 return i < elts;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 void SX_INFO::Handle_Other_Def(WN* wn_def,
00582 WN* wn_rep_def,
00583 INT outer,
00584 INT inner,
00585 INT depth,
00586 DOLOOP_STACK* dostack)
00587 {
00588 WN* wn_outer_loop = dostack->Bottom_nth(outer);
00589 WN* wn_loop = dostack->Bottom_nth(depth);
00590 WN* wn_eq_loop = NULL;
00591 STACK<WN*>* equivalence_class = Scalar_Equivalence_Class(wn_def,
00592 Du_Mgr, &LNO_local_pool, TRUE, &wn_eq_loop);
00593
00594
00595 INT se_reqd = depth + 1;
00596 INT se_not_reqd = depth + 1;
00597 INT defining_def_depth = 0;
00598 WN* wn_red_loop_stmt = NULL;
00599
00600 if (Get_Trace(TP_LNOPT2, TT_LNO_DISABLE_SEFIN)) {
00601 CXX_DELETE(equivalence_class, &LNO_local_pool);
00602 equivalence_class = NULL;
00603 }
00604
00605
00606
00607 if (wn_rep_def != NULL) {
00608 BOOL in_eq_class = FALSE;
00609 if (equivalence_class != NULL) {
00610 INT i;
00611 for (i = 0; i < equivalence_class->Elements(); i++)
00612 if (equivalence_class->Bottom_nth(i) == wn_rep_def)
00613 break;
00614 if (i < equivalence_class->Elements())
00615 in_eq_class = TRUE;
00616 }
00617 SX_PNODE* sxp = Find(SYMBOL(wn_rep_def));
00618 if (!in_eq_class || depth != sxp->_defining_def_depth) {
00619 sxp->_outer_se_reqd = depth + 1;
00620 sxp->_outer_se_not_reqd = depth + 1;
00621 sxp->_defining_def_depth = 0;
00622 sxp->_reduction_carried_by = NULL;
00623 }
00624 CXX_DELETE(equivalence_class, &LNO_local_pool);
00625 return;
00626 }
00627
00628 if (equivalence_class == NULL
00629 || wn_eq_loop != NULL && Do_Loop_Depth(wn_eq_loop) > outer) {
00630
00631 Enter(wn_def, SYMBOL(wn_def), wn_red_loop_stmt, se_reqd, se_not_reqd,
00632 defining_def_depth, -1, FALSE);
00633 return;
00634 }
00635
00636 SE_RESULT se_result = Scalar_Expandable(equivalence_class, wn_def,
00637 wn_loop, Du_Mgr, wn_outer_loop, wn_eq_loop);
00638 INT lcd_depth = -1;
00639 if (se_result == SE_EASY_LCD || se_result == SE_HARD_LCD) {
00640 for (INT i = 0; i < equivalence_class->Elements(); i++) {
00641 WN* wn = equivalence_class->Bottom_nth(i);
00642 if (WN_operator(wn) == OPR_LDID) {
00643 DEF_LIST* def_list = Du_Mgr->Ud_Get_Def(wn);
00644 if (def_list->Loop_stmt() && (lcd_depth == -1
00645 || Do_Loop_Depth(def_list->Loop_stmt()) < lcd_depth))
00646 lcd_depth = Do_Loop_Depth(def_list->Loop_stmt());
00647 }
00648 }
00649 }
00650 if (se_result != SE_NONE) {
00651
00652
00653
00654
00655 se_reqd = outer;
00656 se_not_reqd = depth + 1;
00657 defining_def_depth = depth;
00658 if (depth >= inner || Scalar_Expansion_Not_Necessary(wn_def, Du_Mgr)) {
00659
00660
00661 se_not_reqd = outer;
00662 }
00663 Enter(wn_def, SYMBOL(wn_def), wn_red_loop_stmt, se_reqd, se_not_reqd,
00664 defining_def_depth, lcd_depth, se_result == SE_HARD || se_result
00665 == SE_HARD_LCD);
00666 CXX_DELETE(equivalence_class, &LNO_local_pool);
00667 return;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676 WN* wn_non_red_def = NULL;
00677 INT non_red_depth = -1;
00678 BOOL bad = Analyze_Reduction(wn_def, outer, equivalence_class, dostack,
00679 &wn_non_red_def, &non_red_depth, &wn_red_loop_stmt);
00680 if (bad) {
00681
00682 Enter(wn_def, SYMBOL(wn_def), wn_red_loop_stmt, se_reqd, se_not_reqd,
00683 defining_def_depth, -1, FALSE);
00684 CXX_DELETE(equivalence_class, &LNO_local_pool);
00685 return;
00686 }
00687 if (non_red_depth < outer) {
00688
00689 se_reqd = outer;
00690 se_not_reqd = outer;
00691 } else if (wn_non_red_def) {
00692 se_result = Scalar_Expandable(equivalence_class,
00693 wn_non_red_def, dostack->Bottom_nth(non_red_depth), Du_Mgr,
00694 wn_outer_loop, wn_eq_loop);
00695 if (se_result != SE_NONE) {
00696 se_reqd = outer;
00697 se_not_reqd = non_red_depth + 1;
00698 defining_def_depth = non_red_depth;
00699 }
00700 }
00701 Enter(wn_def, SYMBOL(wn_def), wn_red_loop_stmt, se_reqd, se_not_reqd,
00702 defining_def_depth, lcd_depth, se_result == SE_HARD
00703 || se_result == SE_HARD_LCD);
00704 CXX_DELETE(equivalence_class, &LNO_local_pool);
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 void SX_INFO::Handle_Def(WN* wn_def,
00717 WN* wn_rep_def,
00718 INT outer,
00719 INT inner,
00720 INT depth,
00721 DOLOOP_STACK* dostack)
00722 {
00723 if (WN_opcode(LWN_Get_Parent(wn_def)) == OPC_DO_LOOP) {
00724 Handle_Index_Variable_Def(wn_def, wn_rep_def, depth);
00725 } else {
00726 Handle_Other_Def(wn_def, wn_rep_def, outer, inner, depth, dostack);
00727 }
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 void SX_INFO::Walk(WN* wn,
00743 INT outer,
00744 INT inner,
00745 INT depth,
00746 HASH_TABLE<WN*,BOOL>* loops,
00747 DOLOOP_STACK* dostack)
00748 {
00749 OPCODE opc = WN_opcode(wn);
00750 if (opc == OPC_DO_LOOP) {
00751
00752
00753
00754 if (depth != inner)
00755 return;
00756 }
00757
00758 if (opc == OPC_BLOCK) {
00759 for (WN* wnn = WN_first(wn); wnn; wnn = WN_next(wnn))
00760 Walk(wnn, outer, inner, depth, loops, dostack);
00761 } else {
00762 OPERATOR opr = OPCODE_operator(opc);
00763 if (opr == OPR_STID) {
00764 SX_PNODE* sxp = Find(SYMBOL(wn));
00765 WN* wn_rep_def = sxp != NULL ? sxp->Wn_Symbol() : NULL;
00766 Handle_Def(wn, wn_rep_def, outer, inner, depth, dostack);
00767 } else if (opr == OPR_LDID) {
00768 if (Find(SYMBOL(wn)) == NULL)
00769 Handle_Use(wn, depth, loops);
00770 }
00771 for (INT k = 0; k < WN_kid_count(wn); k++)
00772 Walk(WN_kid(wn, k), outer, inner, depth, loops, dostack);
00773 }
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 void SX_INFO::Make_Sx_Info(WN* wn_outer,
00785 INT nloops,
00786 BOOL ignore_illegal)
00787 {
00788 INT td = 0;
00789 const SX_PNODE* p = NULL;
00790 WN* wn_inner = SNL_Get_Inner_Snl_Loop(wn_outer, nloops);
00791 INT outer = Do_Loop_Depth(wn_outer);
00792 INT inner = Do_Loop_Depth(wn_inner);
00793 DOLOOP_STACK dostack(&LNO_local_pool);
00794 Build_Doloop_Stack(wn_inner, &dostack);
00795 for (INT d = inner; d >= outer; d--) {
00796 WN* wn_body = WN_do_body(dostack.Bottom_nth(d));
00797 HASH_TABLE<WN*,BOOL>* ht = Find_Loops_Within(wn_body, &LNO_local_pool);
00798 Walk(wn_body, outer, inner, d, ht, &dostack);
00799 td = First_Transformable_Depth(&p);
00800 CXX_DELETE(ht, &LNO_local_pool);
00801 if (!ignore_illegal && td >= d)
00802 break;
00803 }
00804
00805 if (td > outer) {
00806 FmtAssert(p != NULL, ("Bug return val of First_Transformable_Depth()"));
00807 SNL_DEBUG3(1, "Loop %s (depth %d) has priv problems from sym %s",
00808 (SYMBOL(WN_index(dostack.Bottom_nth(td-1)))).Name(), td-1,
00809 p->Symbol().Name());
00810 }
00811 }
00812
00813
00814
00815
00816
00817
00818
00819 INT SX_INFO::Lcd_Depth()
00820 {
00821 INT lcd_depth = -1;
00822 SX_CONST_PITER i(&Plist);
00823 for (const SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00824 if (n->Lcd_Depth() >= 0 && (lcd_depth == -1 || n->Lcd_Depth() < lcd_depth))
00825 lcd_depth = n->Lcd_Depth();
00826 return lcd_depth;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835 INT SX_INFO::Must_Finalize()
00836 {
00837 SX_CONST_PITER i(&Plist);
00838 for (const SX_PNODE* n = i.First(); !i.Is_Empty(); n = i.Next())
00839 if (n->Finalize())
00840 return TRUE;
00841 return FALSE;
00842 }
00843
00844
00845
00846
00847
00848
00849 void SX_INFO::Update_Reduction_Loop_Stmts(WN* wn_inner)
00850 {
00851 DOLOOP_STACK loop_stack(&LNO_local_pool);
00852 Build_Doloop_Stack(wn_inner, &loop_stack);
00853 SX_PITER ix(&Plist);
00854 SX_PNODE* nn = NULL;
00855 for (SX_PNODE* n = ix.First(); !ix.Is_Empty(); n = nn) {
00856 nn = ix.Next();
00857 if (n->Reduction_Carried_By() != NULL) {
00858
00859 WN* wn_def = n->Wn_Symbol();
00860 WN* wn_enclosing_loop = Enclosing_Loop(wn_def);
00861 INT i;
00862 for (i = 0; i < loop_stack.Elements(); i++) {
00863 WN* wn_loop = loop_stack.Bottom_nth(i);
00864 if (wn_loop == wn_enclosing_loop)
00865 break;
00866 }
00867 if (i == loop_stack.Elements()) {
00868 Remove(n);
00869 continue;
00870 }
00871 REDUCTION_TYPE rt = red_manager->Which_Reduction(wn_def);
00872 #ifdef KEY // Bug 6288 - if not part of a reduction, continue.
00873 if (rt == RED_NONE)
00874 continue;
00875 #else
00876 FmtAssert(rt != RED_NONE, ("Should be part of a reduction"));
00877 #endif
00878 USE_LIST *use_list = Du_Mgr->Du_Get_Use(wn_def);
00879 FmtAssert(use_list != NULL, ("Expected a use list"));
00880 USE_LIST_ITER iter(use_list);
00881 const DU_NODE* node = NULL;
00882 WN* wn_use = NULL;
00883 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00884 wn_use = node->Wn();
00885 if (!Wn_Is_Inside(wn_use, wn_def))
00886 continue;
00887 REDUCTION_TYPE rt_use = red_manager->Which_Reduction(wn_use);
00888 if (rt_use != RED_NONE)
00889 break;
00890 }
00891 FmtAssert(wn_use != NULL, ("Need to find at least one use"));
00892 WN* wn_loop_stmt = Du_Mgr->Ud_Get_Def(wn_use)->Loop_stmt();
00893 n->Set_Reduction_Carried_By(wn_loop_stmt);
00894 }
00895 }
00896 }
00897