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
00057 #define __STDC_LIMIT_MACROS
00058 #include <stdint.h>
00059 #ifdef USE_PCH
00060 #include "lno_pch.h"
00061 #endif // USE_PCH
00062 #pragma hdrstop
00063
00064 #define snl_nest_CXX "snl_nest.cxx"
00065 const static char *rcs_id = snl_nest_CXX "$Revision: 1.5 $";
00066
00067 #include <sys/types.h>
00068 #include "snl.h"
00069 #include "snl_xbounds.h"
00070
00071 #include "soe.h"
00072 #include "lwn_util.h"
00073 #include "lnopt_main.h"
00074 #include "opt_du.h"
00075
00076
00077
00078
00079
00080
00081
00082 void SNL_BOUNDS_SYMBOL_LIST::Print(FILE *fp) const
00083 {
00084 SNL_BOUNDS_SYMBOL_CONST_ITER iter(this);
00085 for (const SNL_BOUNDS_SYMBOL_NODE *node = iter.First(); !iter.Is_Empty();
00086 node=iter.Next()) {
00087 node->Print(fp);
00088 if (iter.Peek_Next() != NULL)
00089 fprintf(fp, ",");
00090 }
00091 }
00092
00093 void SNL_BOUNDS_SYMBOL_LIST::Init(const SNL_BOUNDS_SYMBOL_LIST *sl)
00094 {
00095 SNL_BOUNDS_SYMBOL_CONST_ITER iter(sl);
00096 for (const SNL_BOUNDS_SYMBOL_NODE *node = iter.First(); !iter.Is_Empty();
00097 node = iter.Next()) {
00098 Append(CXX_NEW(SNL_BOUNDS_SYMBOL_NODE(node), _pool));
00099 }
00100 }
00101
00102 SNL_BOUNDS_SYMBOL_LIST::~SNL_BOUNDS_SYMBOL_LIST()
00103 {
00104 while (!Is_Empty())
00105 CXX_DELETE(Remove_Headnode(), _pool);
00106 }
00107
00108 void SNL_BOUNDS_SYMBOL_NODE::Print(FILE *fp) const
00109 {
00110 Symbol.Print(fp);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 SNL_BOUNDS_INFO::SNL_BOUNDS_INFO(MEM_POOL* mp)
00125 : _pool(mp),
00126 _outermost_depth(0),
00127 _bounds(0,0,0,mp),
00128 _conditionals(0,0,0,mp),
00129 _var_info(mp)
00130 {
00131 }
00132
00133 SNL_BOUNDS_INFO::SNL_BOUNDS_INFO(const SNL_BOUNDS_INFO* bi, MEM_POOL* mp)
00134 : _pool(mp ? mp : bi->_pool),
00135 _outermost_depth(bi->_outermost_depth),
00136 _bounds(&bi->_bounds, mp ? mp : bi->_pool),
00137 _conditionals(&bi->_conditionals, mp ? mp : bi->_pool),
00138 _var_info(mp ? mp : bi->_pool)
00139 {
00140 Is_True(Pool() != &LNO_local_pool,
00141 ("SNL_BOUNDS_INFO cannot use LNO_local_pool"));
00142 _var_info.Init(&bi->_var_info);
00143 }
00144
00145 SNL_BOUNDS_INFO::~SNL_BOUNDS_INFO()
00146 {
00147 }
00148
00149
00150
00151
00152
00153 INT SNL_BOUNDS_INFO::Lookup_Entry(SYMBOL s, WN* alias_wn)
00154 {
00155 SNL_BOUNDS_SYMBOL_ITER iter(&Var_Info());
00156 SNL_BOUNDS_SYMBOL_NODE* n;
00157 INT entry = 0;
00158
00159 for (n = iter.First(); !iter.Is_Empty(); n = iter.Next()) {
00160 if (n->Symbol == s)
00161 return entry;
00162 entry++;
00163 }
00164
00165
00166 _var_info.Append(CXX_NEW(SNL_BOUNDS_SYMBOL_NODE(s, alias_wn), _pool));
00167 _bounds.Add_Vars(1);
00168 _conditionals.Add_Vars(1);
00169 return entry;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 INT SNL_BOUNDS_INFO::Add_Access(ACCESS_VECTOR* av, BOOL is_cond)
00182 {
00183 if (av->Too_Messy || av->Contains_Non_Lin_Symb())
00184 return 0;
00185
00186 INT vsz = (av->Lin_Symb ? av->Lin_Symb->Len() : 0) +
00187 Var_Info().Len() + av->Nest_Depth() + 1;
00188 mINT32* v = CXX_NEW_ARRAY(mINT32, vsz, &LNO_local_pool);
00189
00190 for (INT vszx = 0; vszx < vsz; vszx++)
00191 v[vszx] = 0;
00192
00193
00194
00195 for (INT i = 0; i <= av->Nest_Depth(); i++) {
00196 INT coeff = av->Loop_Coeff(i);
00197 if (coeff) {
00198 INT entry = Lookup_Entry(SYMBOL((ST*)NULL, i, MTYPE_V), NULL);
00199 Is_True(entry < vsz,("Overflow1 in Add_Access\n"));
00200 v[entry] = coeff;
00201 }
00202 }
00203
00204
00205
00206 if (av->Contains_Lin_Symb()) {
00207 INTSYMB_ITER ii(av->Lin_Symb);
00208 for (INTSYMB_NODE* n = ii.First(); !ii.Is_Empty(); n = ii.Next()) {
00209 INT entry = Lookup_Entry(n->Symbol, NULL);
00210 Is_True(entry < vsz,("Overflow2 in Add_Access\n"));
00211 v[entry] = n->Coeff;
00212 }
00213 }
00214
00215 _bounds.Add_Le(v, av->Const_Offset);
00216 if (is_cond)
00217 _conditionals.Add_Le(v, av->Const_Offset);
00218
00219 CXX_DELETE_ARRAY(v, &LNO_local_pool);
00220 return 1;
00221 }
00222
00223 INT SNL_BOUNDS_INFO::Add_Access(ACCESS_ARRAY* aa, BOOL is_cond)
00224 {
00225 INT added_cnt = 0;
00226
00227 for (INT i = 0; i < aa->Num_Vec(); i++)
00228 added_cnt += Add_Access(aa->Dim(i), is_cond);
00229
00230 return added_cnt;
00231 }
00232
00233
00234
00235
00236
00237 void SNL_BOUNDS_INFO::Collect_If_Info(WN* wn, BOOL in_then_part)
00238 {
00239 Is_True(WN_opcode(wn) == OPC_IF,
00240 ("bad opcode %d for Collect_If_Info()", WN_opcode(wn)));
00241
00242 MEM_POOL_Push(&LNO_local_pool);
00243 IF_INFO* ii = Get_If_Info(wn);
00244
00245 if (ii == NULL) {
00246 fprintf(stderr, "Missing IF annotation!");
00247 }
00248 else if (!in_then_part == !ii->Condition_On_Then) {
00249
00250 Add_Access(ii->Condition, FALSE);
00251 }
00252 else {
00253
00254
00255 if (ii->Condition->Num_Vec() == 1) {
00256 ACCESS_VECTOR av(ii->Condition->Dim(0), Pool());
00257 av.Negate_Me();
00258 av.Const_Offset--;
00259 Add_Access(&av, FALSE);
00260 }
00261 }
00262 MEM_POOL_Pop(&LNO_local_pool);
00263 }
00264
00265 void SNL_BOUNDS_INFO::Collect_Do_Info(WN* wn)
00266 {
00267 Is_True(WN_opcode(wn) == OPC_DO_LOOP,
00268 ("bad opcode %d for Collect_Do_Info()", WN_opcode(wn)));
00269
00270 if (Step_Size(wn) != 1)
00271 return;
00272
00273 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
00274 Add_Access(dli->LB, FALSE);
00275 Add_Access(dli->UB, FALSE);
00276 }
00277
00278 void SNL_BOUNDS_INFO::Collect_DoWhile_Info(WN* wn)
00279 {
00280 FmtAssert(WN_opcode(wn) == OPC_DO_WHILE,
00281 ("bad opcode %d for Collect_DoWhile_Info()", WN_opcode(wn)));
00282 }
00283
00284 void SNL_BOUNDS_INFO::Collect_WhileDo_Info(WN* wn)
00285 {
00286 FmtAssert(WN_opcode(wn) == OPC_WHILE_DO,
00287 ("bad opcode %d for Collect_WhileDo_Info()", WN_opcode(wn)));
00288 }
00289
00290
00291
00292
00293 void SNL_BOUNDS_INFO::Collect_Outer_Info(WN* wn)
00294 {
00295 WN* pwn = wn;
00296
00297 for (wn = LWN_Get_Parent(pwn); wn; pwn = wn, wn = LWN_Get_Parent(pwn)) {
00298 switch (WN_opcode(wn)) {
00299 case OPC_IF:
00300 BOOL in_then_part;
00301 if (pwn == WN_then(wn))
00302 in_then_part = TRUE;
00303 else if (pwn == WN_else(wn))
00304 in_then_part = FALSE;
00305 else
00306 FmtAssert(0, ("Bad if/then/else prev condition"));
00307 Collect_If_Info(wn, in_then_part);
00308 break;
00309 case OPC_DO_LOOP:
00310 Collect_Do_Info(wn);
00311 break;
00312 case OPC_DO_WHILE:
00313 Collect_DoWhile_Info(wn);
00314 break;
00315 case OPC_WHILE_DO:
00316 Collect_WhileDo_Info(wn);
00317 break;
00318 }
00319 }
00320 }
00321
00322 void SNL_BOUNDS_INFO::Reset_Varcount_To(INT cols)
00323 {
00324 INT len = _var_info.Len();
00325
00326 Is_True(cols <= len, ("Reset_Varcount_To() len=%d, cols=%d", len, cols));
00327 if (len >= cols)
00328 return;
00329
00330
00331
00332 SNL_BOUNDS_SYMBOL_NODE* prev = NULL;
00333 SNL_BOUNDS_SYMBOL_NODE* node = _var_info.Head();
00334 for (INT cnt = 0; cnt < cols; cnt++) {
00335 prev = node;
00336 node = node->Next();
00337 }
00338
00339 while (node) {
00340 SNL_BOUNDS_SYMBOL_NODE* next = node->Next();
00341 _var_info.Remove(prev, node);
00342 CXX_DELETE(node, Pool());
00343 node = next;
00344 }
00345 }
00346
00347 void SNL_BOUNDS_INFO::Reset_Conditionals_To(INT rows_le, INT rows_eq, INT cols)
00348 {
00349 Reset_Varcount_To(cols);
00350 Conditionals().Reset_To(rows_le, rows_eq, cols);
00351 Bounds().Reset_To(Bounds().Num_Le_Constraints(),
00352 Bounds().Num_Eq_Constraints(),
00353 cols);
00354 }
00355
00356 void SNL_BOUNDS_INFO::Reset_Bounds_To(INT rows_le, INT rows_eq, INT cols)
00357 {
00358 Reset_Varcount_To(cols);
00359 Bounds().Reset_To(rows_le, rows_eq, cols);
00360 Conditionals().Reset_To(Conditionals().Num_Le_Constraints(),
00361 Conditionals().Num_Eq_Constraints(),
00362 cols);
00363 }
00364
00365
00366
00367
00368
00369 void SNL_BOUNDS_INFO::Canonicize(INT nloops, DOLOOP_STACK* stack, INT stk_first)
00370 {
00371 Is_True(stk_first == _outermost_depth, ("Problem in Canonicize"));
00372
00373 SYSTEM_OF_EQUATIONS* soeb = &Bounds();
00374 SYSTEM_OF_EQUATIONS* soec = &Conditionals();
00375
00376 SNL_BOUNDS_SYMBOL_LIST* sl = &Var_Info();
00377 SNL_BOUNDS_SYMBOL_NODE* sld = sl->Head();
00378
00379 for (INT d = 0; d < nloops; d++, sld = sld->Next()) {
00380 SNL_BOUNDS_SYMBOL_NODE* sldd = sld;
00381
00382 for (INT dd = d; sldd; dd++, sldd = sldd->Next()) {
00383 if (sldd->Symbol == SYMBOL((ST*)NULL, _outermost_depth+d, MTYPE_V)) {
00384 if (sld->Symbol != sldd->Symbol) {
00385 SYMBOL tmps = sld->Symbol;
00386 WN* tmpw = sld->Alias_Wn;
00387
00388 sld->Symbol = sldd->Symbol;
00389 sld->Alias_Wn = sldd->Alias_Wn;
00390
00391 sldd->Symbol = tmps;
00392 sldd->Alias_Wn = tmpw;
00393
00394 soeb->Ale().D_Swap_Cols(d,dd);
00395 soeb->Aeq().D_Swap_Cols(d,dd);
00396 soec->Ale().D_Swap_Cols(d,dd);
00397 soec->Aeq().D_Swap_Cols(d,dd);
00398 }
00399 break;
00400 }
00401 }
00402 FmtAssert(sldd, ("Couldn't find loop %d", Outermost_Depth() + d));
00403 }
00404
00405 for (sld = sl->Head(); sld; sld = sld->Next()) {
00406 if (sld->Symbol.St() == NULL) {
00407 WN* doloop = stack->Bottom_nth(sld->Symbol.WN_Offset());
00408 sld->Symbol = SYMBOL(WN_index(doloop));
00409 sld->Symbol.Type = Do_Wtype(doloop);
00410 sld->Alias_Wn = Find_Use_In_Exp(WN_step(doloop), sld->Symbol);
00411 }
00412 else {
00413
00414 WN* wn = stack->Bottom_nth(stk_first+nloops-1);
00415 for ( ; wn; wn = LWN_Get_Parent(wn)) {
00416 if (WN_opcode(wn) == OPC_IF) {
00417 sld->Alias_Wn = Find_Use_In_Exp(WN_if_test(wn), sld->Symbol);
00418 if (sld->Alias_Wn)
00419 break;
00420 }
00421 else if (WN_opcode(wn) == OPC_DO_LOOP) {
00422 sld->Alias_Wn = Find_Use_In_Exp(WN_start(wn), sld->Symbol);
00423 if (sld->Alias_Wn)
00424 break;
00425 sld->Alias_Wn = Find_Use_In_Exp(WN_end(wn), sld->Symbol);
00426 if (sld->Alias_Wn)
00427 break;
00428 sld->Alias_Wn = Find_Use_In_Exp(WN_step(wn), sld->Symbol);
00429 if (sld->Alias_Wn)
00430 break;
00431 }
00432 }
00433 }
00434 FmtAssert(sld->Alias_Wn,
00435 ("Missing alias for %s\n", SYMBOL(sld->Symbol).Name()));
00436 }
00437 }
00438
00439 static void cshift_left(mINT32* row, INT rowsize, INT shft)
00440 {
00441 INT i;
00442
00443 MEM_POOL_Push(&LNO_local_pool);
00444
00445 mINT32* hold = CXX_NEW_ARRAY(mINT32, shft, &LNO_local_pool);
00446
00447 for (i = 0; i < shft; i++)
00448 hold[i] = row[i];
00449 for (i = shft; i < rowsize; i++)
00450 row[i-shft] = row[i];
00451 for (i = 0; i < shft; i++)
00452 row[rowsize-shft+i] = hold[i];
00453
00454 CXX_DELETE_ARRAY(hold, &LNO_local_pool);
00455 MEM_POOL_Pop(&LNO_local_pool);
00456 }
00457
00458 void SNL_BOUNDS_INFO::Exclude_Outer_Loops(INT how_many)
00459 {
00460 _outermost_depth += how_many;
00461
00462
00463
00464
00465 INT cols = _var_info.Len();
00466
00467 IMAT& m1 = _bounds.Aeq();
00468 IMAT& m2 = _bounds.Ale();
00469 IMAT& m3 = _conditionals.Aeq();
00470 IMAT& m4 = _conditionals.Ale();
00471
00472 BOOL m1_valid = m1.Rows() > 0;
00473 BOOL m2_valid = m2.Rows() > 0;
00474 BOOL m3_valid = m3.Rows() > 0;
00475 BOOL m4_valid = m4.Rows() > 0;
00476
00477 FmtAssert((!m1_valid || cols == m1.Cols()) &&
00478 (!m2_valid || cols == m2.Cols()) &&
00479 (!m3_valid || cols == m3.Cols()) &&
00480 (!m4_valid || cols == m4.Cols()),
00481 ("Bad number of cols in Exclude_Outer_Loops"));
00482
00483 for (INT i = 0; i < how_many; i++) {
00484 SNL_BOUNDS_SYMBOL_NODE* n = _var_info.Remove_Headnode();
00485 _var_info.Append(n);
00486
00487
00488 for (INT c = 0; c < cols-1; c++) {
00489 if (m1_valid) m1.D_Swap_Cols(c,c+1);
00490 if (m2_valid) m2.D_Swap_Cols(c,c+1);
00491 if (m3_valid) m3.D_Swap_Cols(c,c+1);
00492 if (m4_valid) m4.D_Swap_Cols(c,c+1);
00493 }
00494 }
00495 }
00496
00497 void SNL_BOUNDS_INFO::Print(FILE* f) const
00498 {
00499 fprintf(f, "Bounds Info: Outermost Depth = %d\n", _outermost_depth);
00500
00501 fprintf(f, "Variables: ");
00502 _var_info.Print(f);
00503
00504 fprintf(f, "\nBounds:\n");
00505 _bounds.Print(f);
00506
00507 fprintf(f, "Conditionals:\n");
00508 _conditionals.Print(f);
00509
00510 fprintf(f, "End of Bounds Info\n");
00511 }
00512