00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #define __STDC_LIMIT_MACROS
00043 #include <stdint.h>
00044 #ifdef USE_PCH
00045 #include "lno_pch.h"
00046 #endif // USE_PCH
00047 #pragma hdrstop
00048
00049 #ifdef _KEEP_RCS_ID
00050
00051 static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/be/lno/SCCS/s.ara_region.cxx $ $Revision: 1.5 $";
00052 #endif
00053
00054 #include <sys/types.h>
00055 #include <limits.h>
00056 #include "pu_info.h"
00057 #include "ara_region.h"
00058 #include "ara_loop.h"
00059 #include "wn_map.h"
00060 #include "lnopt_main.h"
00061 #include "lno_bv.h"
00062 #include "ara_utils.h"
00063 #include "mempool.h"
00064 #include "ipa_lno_util.h"
00065
00066 KERNEL_IMAGE::~KERNEL_IMAGE()
00067 {
00068 if (_region) CXX_DELETE(_region, &ARA_memory_pool);
00069
00070 CXX_DELETE_ARRAY(_is_independent, &ARA_memory_pool);
00071 }
00072
00073 CON_PAIR::CON_PAIR(CON_PAIR* c, INT dim)
00074 {
00075 _ac_v = NULL;
00076 if (c->_ac_v != NULL)
00077 _ac_v = CXX_NEW(ACCESS_VECTOR(c->_ac_v, &ARA_memory_pool),
00078 &ARA_memory_pool);
00079 _coeff = NULL;
00080 if (c->_coeff != NULL) {
00081 _coeff = CXX_NEW_ARRAY(INT, dim, &ARA_memory_pool);
00082 for (INT i = 0; i < dim; i++)
00083 _coeff[i] = c->_coeff[i];
00084 }
00085 }
00086
00087 CON_PAIR::CON_PAIR(const CON_PAIR &a, const INT dim)
00088 {
00089 if (a._ac_v)
00090 _ac_v = CXX_NEW(ACCESS_VECTOR(a._ac_v, &ARA_memory_pool),&ARA_memory_pool);
00091 else
00092 _ac_v = NULL;
00093
00094 if (a._coeff) {
00095 _coeff = CXX_NEW_ARRAY(INT, dim, &ARA_memory_pool);
00096 for (INT i = 0; i < dim; ++i) _coeff[i] = a._coeff[i];
00097 } else
00098 _coeff = NULL;
00099 }
00100
00101 void
00102 CON_PAIR::Print(FILE *fp, INT dim) const
00103 {
00104
00105 if (_coeff != NULL) {
00106 fprintf(fp,"(");
00107 for (INT i = 0; i < dim; ++i)
00108 fprintf(fp," %d ",_coeff[i]);
00109 fprintf(fp,")");
00110 }
00111 if (_ac_v)
00112 _ac_v->Print(fp);
00113
00114 }
00115
00116 void
00117 CON_PAIR::WB_Print(FILE *fp, INT dim) const
00118 {
00119 char bf[MAX_TLOG_CHARS];
00120 WB_Print(bf, dim, 0);
00121 fprintf(fp, "%s", bf);
00122 }
00123
00124 INT
00125 CON_PAIR::WB_Print(char* bf, INT ccount, INT dim) const
00126 {
00127 INT new_ccount = ccount;
00128 if (_coeff != NULL) {
00129 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "(");
00130 for (INT i = 0; i < dim; ++i) {
00131 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, " ");
00132 new_ccount = snprintfd(bf, new_ccount, MAX_TLOG_CHARS, _coeff[i]);
00133 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, " ");
00134 }
00135 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, ")");
00136 }
00137 if (_ac_v)
00138 new_ccount = _ac_v->Print(bf, new_ccount, FALSE, FALSE);
00139 return new_ccount;
00140 }
00141
00142 void
00143 CON_PAIR::Print_Analysis_Info(FILE *fp, INT dim, DOLOOP_STACK &do_stack)
00144 {
00145
00146 if (_coeff != NULL) {
00147 fprintf(fp,"(");
00148 for (INT i = 0; i < dim; ++i)
00149 fprintf(fp," %d ",_coeff[i]);
00150 fprintf(fp,")");
00151 }
00152 if (_ac_v) _ac_v->Print_Analysis_Info(fp, do_stack);
00153
00154 }
00155
00156 BOOL CON_PAIR::Has_Formal_Parameter()
00157 {
00158 return _ac_v->Has_Formal_Parameter();
00159 }
00160
00161 AXLE_NODE::AXLE_NODE(AXLE_NODE* a, INT dim)
00162 {
00163 if (a->lo) {
00164 lo = CXX_NEW(CON_PAIR(a->lo, dim), &ARA_memory_pool);
00165 } else {
00166 lo = NULL;
00167 }
00168
00169 if (a->up) {
00170 up = CXX_NEW(CON_PAIR(a->up, dim), &ARA_memory_pool);
00171 } else {
00172 up = NULL;
00173 }
00174 step = a->step;
00175 }
00176
00177 void
00178 AXLE_NODE::Print(FILE *fp, INT dim) const
00179 {
00180
00181 if (lo) lo->Print(fp, dim);
00182
00183 if (up) {
00184 fprintf(fp," : ");
00185 up->Print(fp, dim);
00186 fprintf(fp," : %d", step);
00187 }
00188
00189 }
00190
00191 void
00192 AXLE_NODE::WB_Print(FILE *fp, INT dim) const
00193 {
00194 char bf[MAX_TLOG_CHARS];
00195 WB_Print(bf, dim, 0);
00196 fprintf(fp, "%s", bf);
00197 }
00198
00199 INT
00200 AXLE_NODE::WB_Print(char* bf, INT ccount, INT dim) const
00201 {
00202 INT new_ccount = ccount;
00203 if (lo)
00204 new_ccount = lo->WB_Print(bf, new_ccount, dim);
00205 if (up) {
00206 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, ":");
00207 new_ccount = up->WB_Print(bf, new_ccount, dim);
00208 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, ":");
00209 new_ccount = snprintfd(bf, new_ccount, MAX_TLOG_CHARS, step);
00210 }
00211 return new_ccount;
00212 }
00213
00214 void
00215 AXLE_NODE::Print_Analysis_Info(FILE *fp, INT dim, INT indent, DOLOOP_STACK &do_stack)
00216 {
00217
00218 print_indent(fp,indent);
00219 fprintf(fp,"(\"");
00220 if (lo) lo->Print_Analysis_Info(fp, dim, do_stack);
00221 fprintf(fp,"\"");
00222
00223 if (up) {
00224 fprintf(fp," \"");
00225 up->Print_Analysis_Info(fp, dim, do_stack);
00226 fprintf(fp,"\" \"%d\"", step);
00227 }
00228 fprintf(fp,")\n");
00229
00230 }
00231
00232 BOOL AXLE_NODE::Has_Formal_Parameter()
00233 {
00234 if (lo->Has_Formal_Parameter())
00235 return TRUE;
00236 if (up->Has_Formal_Parameter())
00237 return TRUE;
00238 return FALSE;
00239 }
00240
00241 void
00242 REGION::Print(FILE *fp) const
00243 {
00244
00245 switch (_type) {
00246 case ARA_TOP:
00247 fprintf(fp,"Top \n");
00248 break;
00249 case ARA_BOTTOM:
00250 fprintf(fp,"Bottom \n");
00251 break;
00252 case ARA_TOO_MESSY:
00253 fprintf(fp,"Unknown \n");
00254 break;
00255 default:
00256 fprintf(fp,"[");
00257 INT i;
00258 for (i = 0; i < _dim-1; ++i) {
00259 _axle[i].Print(fp,_dim);
00260 fprintf(fp,",");
00261 }
00262 _axle[i].Print(fp,_dim);
00263 fprintf(fp,"] \n");
00264 }
00265
00266 }
00267
00268 void
00269 REGION::WB_Print(FILE *fp) const
00270 {
00271 char bf[MAX_TLOG_CHARS];
00272 WB_Print(bf, 0);
00273 fprintf(fp, "%s", bf);
00274 }
00275
00276 INT
00277 REGION::WB_Print(char* bf, INT ccount) const
00278 {
00279 INT new_ccount = ccount;
00280 switch (_type) {
00281 case ARA_TOP:
00282 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "<Top>");
00283 break;
00284 case ARA_BOTTOM:
00285 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "<Bottom>");
00286 break;
00287 case ARA_TOO_MESSY:
00288 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "<Unknown>");
00289 break;
00290 default:
00291 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "[");
00292 INT i;
00293 for (i = 0; i < _dim-1; ++i) {
00294 new_ccount = _axle[i].WB_Print(bf, new_ccount, _dim);
00295 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "][");
00296 }
00297 new_ccount = _axle[i].WB_Print(bf, new_ccount, _dim);
00298 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "]");
00299 }
00300 return new_ccount;
00301 }
00302
00303 void
00304 REGION::Print_Analysis_Info(FILE *fp, INT indent, DOLOOP_STACK &do_stack)
00305 {
00306
00307 switch (_type) {
00308 case ARA_TOP:
00309 print_indent(fp,indent);
00310 fprintf(fp,"(ALL)\n");
00311 break;
00312 case ARA_BOTTOM:
00313 print_indent(fp,indent);
00314 fprintf(fp,"(NULL)\n");
00315 break;
00316 case ARA_TOO_MESSY:
00317 print_indent(fp,indent);
00318 fprintf(fp,"(UNKNOWN)\n");
00319 break;
00320 default:
00321 for (INT i = 0; i < _dim; ++i) {
00322 _axle[i].Print_Analysis_Info(fp,_dim, indent, do_stack);
00323 }
00324 }
00325
00326 }
00327
00328 REGION::REGION(REGION* r) :
00329 _wn_list(&ARA_memory_pool)
00330 {
00331 INT i;
00332 _dim = r->_dim;
00333 _axle = CXX_NEW(AXLE_NODE(r->_axle, _dim), &ARA_memory_pool);
00334 _depth = r->_depth;
00335 _type = r->_type;
00336 _coupled = r->_coupled;
00337 _conditions = NULL;
00338 if (r->_conditions != NULL)
00339 _conditions = CXX_NEW(ACCESS_ARRAY(r->_conditions, &ARA_memory_pool),
00340 &ARA_memory_pool);
00341 FmtAssert(_kernel == NULL,
00342 ("REGION::REGION: Not sure how ro replicate this otherwise"));
00343 _kernel = NULL;
00344 for (i = 0; i < r->_wn_list.Elements(); i++)
00345 _wn_list.Push(r->_wn_list.Bottom_nth(i));
00346 }
00347
00348
00349 REGION::REGION(const REGION &a) :
00350 _wn_list(&ARA_memory_pool)
00351 {
00352
00353 _dim = a._dim;
00354 _type = a._type;
00355 _depth = a._depth;
00356 _coupled = a._coupled;
00357 _conditions = NULL;
00358 _axle = NULL;
00359 if (a._axle) {
00360 _axle = CXX_NEW_ARRAY(AXLE_NODE,_dim,&ARA_memory_pool);
00361 for (INT i = 0; i < _dim; ++i)
00362 _axle[i].Set_Axle(a._axle[i].lo, a._axle[i].up, a._axle[i].step, _dim);
00363 }
00364
00365 if (a._conditions)
00366 _conditions = CXX_NEW(ACCESS_ARRAY(a._conditions,&ARA_memory_pool),
00367 &ARA_memory_pool);
00368 _kernel = a._kernel;
00369 for (INT i = 0; i < a._wn_list.Elements(); ++i)
00370 _wn_list.Push(a._wn_list.Bottom_nth(i));
00371
00372 }
00373
00374 BOOL REGION::Has_Formal_Parameter()
00375 {
00376 for (INT i = 0; i < _dim; i++)
00377 if (_axle[i].Has_Formal_Parameter())
00378 return TRUE;
00379 return FALSE;
00380 }
00381
00382 void
00383 REGION_UN::Print(FILE *fp) const
00384 {
00385
00386 REGION_CONST_ITER iter(this);
00387 fprintf(fp,"{ \n");
00388 for (const REGION* cur = iter.First();
00389 !iter.Is_Empty(); cur = iter.Next())
00390 cur->Print(fp);
00391 fprintf(fp,"\n } \n");
00392
00393 }
00394
00395 void
00396 REGION_UN::WB_Print(FILE *fp) const
00397 {
00398 char bf[MAX_TLOG_CHARS];
00399 WB_Print(bf, 0);
00400 fprintf(fp, "%s", bf);
00401 }
00402
00403 INT
00404 REGION_UN::WB_Print(char* bf, INT ccount) const
00405 {
00406 INT new_ccount = ccount;
00407 REGION_CONST_ITER iter(this);
00408 INT count = 0;
00409 const REGION* cur = 0;
00410 for (cur = iter.First(); !iter.Is_Empty(); cur = iter.Next())
00411 count++;
00412 if (count == 0)
00413 return new_ccount;
00414 if (count > 1)
00415 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "{");
00416 for (cur = iter.First(); !iter.Is_Empty(); cur = iter.Next())
00417 new_ccount = cur->WB_Print(bf, new_ccount);
00418 if (count > 1)
00419 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "} ");
00420 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "\n");
00421 return new_ccount;
00422 }
00423
00424 void
00425 REGION_UN::Print_Analysis_Info(FILE *fp, INT indent, DOLOOP_STACK &do_stack)
00426 {
00427
00428 REGION_ITER iter(this);
00429 for (REGION* cur = iter.First();
00430 !iter.Is_Empty(); cur = iter.Next()) {
00431 print_indent(fp, indent);
00432 fprintf(fp,"(SECTION \n");
00433 cur->Print_Analysis_Info(fp,indent+3,do_stack);
00434 print_indent(fp, indent); fprintf(fp, ")\n");
00435 }
00436
00437 }
00438
00439 BOOL REGION_UN::Has_Formal_Parameter()
00440 {
00441 REGION_ITER riter(this);
00442 for (REGION* rg = riter.First(); !riter.Is_Empty(); rg = riter.Next()) {
00443 if (rg->_type == ARA_TOP || rg->_type == ARA_BOTTOM
00444 || rg->_type == ARA_TOO_MESSY)
00445 continue;
00446 if (rg->Has_Formal_Parameter())
00447 return TRUE;
00448 }
00449 return FALSE;
00450 }
00451
00452 void
00453 AXLE_NODE::Init_To_Access(ACCESS_VECTOR *av)
00454 {
00455 lo = CXX_NEW(CON_PAIR(av), &ARA_memory_pool);
00456 up = NULL;
00457 step = 1;
00458 }
00459
00460 void
00461 AXLE_NODE::Set_Axle(const CON_PAIR *lo_new, const CON_PAIR *up_new,
00462 const INT16 step_new, const INT dim)
00463 {
00464 if (lo) CXX_DELETE(lo,&ARA_memory_pool);
00465 if (up) CXX_DELETE(up,&ARA_memory_pool);
00466 if (lo_new) lo = CXX_NEW(CON_PAIR(*lo_new,dim),&ARA_memory_pool);
00467 if (up_new) up = CXX_NEW(CON_PAIR(*up_new,dim),&ARA_memory_pool);
00468 step = step_new;
00469 }
00470
00471 void
00472 AXLE_NODE::Clear()
00473 {
00474 if (lo) CXX_DELETE(lo,&ARA_memory_pool);
00475 if (up) CXX_DELETE(up,&ARA_memory_pool);
00476 lo = up = NULL;
00477 step = 0;
00478 }
00479
00480
00481
00482
00483 BOOL
00484 Equivalent(const AXLE_NODE &a, const AXLE_NODE &b, const INT dim)
00485 {
00486 return ((a.step == b.step) &&
00487 ((a.lo == NULL && b.lo == NULL) ||
00488 (a.lo != NULL && b.lo != NULL && Equivalent(*a.lo,*b.lo,dim))) &&
00489 ((a.up == NULL && b.up == NULL) ||
00490 (a.up != NULL && b.up != NULL && Equivalent(*a.up,*b.up,dim))));
00491 }
00492
00493
00494
00495
00496
00497 BOOL
00498 Equivalent(const CON_PAIR &a, const CON_PAIR &b, const INT dim)
00499 {
00500
00501 if (a._ac_v) {
00502 if (b._ac_v == NULL)
00503 return FALSE;
00504 else if ( !(*a._ac_v == *b._ac_v) )
00505 return FALSE;
00506 } else if (b._ac_v != NULL)
00507 return FALSE;
00508
00509 if (a._coeff) {
00510 if (b._coeff == NULL)
00511 return FALSE;
00512 else
00513 for (INT i = 0; i < dim; ++i)
00514 if (a._coeff[i]!=b._coeff[i]) return FALSE;
00515 } else if (b._coeff != NULL)
00516 return FALSE;
00517
00518 return TRUE;
00519
00520 }
00521
00522
00523 REGION::REGION(WN* wn, ARA_LOOP_INFO *ara_loop_info):_wn_list(&ARA_memory_pool)
00524 {
00525 Is_True(ara_loop_info,("Must have ARA loop info!\n"));
00526 KERNEL_LIST & kernels = ara_loop_info->Kernels();
00527 INT16 depth = ara_loop_info->Depth()+1;
00528
00529
00530 _type = ARA_TOO_MESSY;
00531 _axle = NULL;
00532 _conditions = NULL;
00533 _kernel = NULL;
00534 _depth = depth;
00535 _dim = WN_num_dim(wn);
00536 _wn_list.Push(wn);
00537
00538 ACCESS_ARRAY *array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map, wn);
00539
00540
00541 if (!array || array->Too_Messy) return;
00542
00543 INT i;
00544 for (i = 0; i < array->Num_Vec(); ++i) {
00545 ACCESS_VECTOR *av = array->Dim(i);
00546 if (av->Too_Messy || av->Contains_Non_Lin_Symb() || av->Delinearized_Symbol) return;
00547 }
00548
00549
00550 _type = ARA_NORMAL;
00551
00552 _axle = CXX_NEW_ARRAY(AXLE_NODE,_dim,&ARA_memory_pool);
00553 for (i = 0; i < array->Num_Vec(); ++i) {
00554 ACCESS_VECTOR *av = array->Dim(i);
00555 _axle[i].Init_To_Access(av);
00556 }
00557
00558
00559 KERNEL_SLIST_ITER iter(&kernels);
00560 for (KERNEL_IMAGE *kern = iter.First(); _kernel==NULL &&
00561 !iter.Is_Empty(); kern = iter.Next()) {
00562
00563 if (kern->Depth() != depth) continue;
00564
00565 ACCESS_ARRAY *cur = kern->Get_Kernel();
00566 if (array->Num_Vec() != cur->Num_Vec()) continue;
00567 BOOL match=TRUE;
00568
00569 for (INT i = 0; i < array->Num_Vec(); ++i) {
00570
00571 ACCESS_VECTOR *av = array->Dim(i);
00572 ACCESS_VECTOR *ker_av = cur->Dim(i);
00573
00574 INT j;
00575 for (j = 0; j < depth; ++j)
00576 if (av->Loop_Coeff(j)!= ker_av->Loop_Coeff(j)) break;
00577
00578 if (j != depth) {
00579 match = FALSE;
00580 break;
00581 }
00582
00583 }
00584
00585 if (match) {
00586 _kernel = kern;
00587 break;
00588 }
00589
00590 }
00591
00592 if (_kernel == NULL) {
00593 _kernel = CXX_NEW(KERNEL_IMAGE(array, ara_loop_info), &ARA_memory_pool);
00594 kernels.Append(_kernel);
00595 }
00596
00597 }
00598
00599
00600
00601 REGION::REGION(WN* wn, ACCESS_ARRAY* array):_wn_list(&ARA_memory_pool)
00602 {
00603 INT16 depth = Do_Loop_Depth(Enclosing_Do_Loop(wn))+1;
00604
00605
00606 _type = ARA_TOO_MESSY;
00607 _axle = NULL;
00608 _conditions = NULL;
00609 _kernel = NULL;
00610 _depth = depth;
00611 _dim = array->Num_Vec();
00612 _wn_list.Push(wn);
00613
00614
00615 if (!array || array->Too_Messy) return;
00616
00617 INT i;
00618 for (i = 0; i < array->Num_Vec(); ++i) {
00619 ACCESS_VECTOR *av = array->Dim(i);
00620 if (av->Too_Messy || av->Contains_Non_Lin_Symb() || av->Delinearized_Symbol) return;
00621 }
00622
00623
00624 _type = ARA_NORMAL;
00625
00626 _axle = CXX_NEW_ARRAY(AXLE_NODE,_dim,&ARA_memory_pool);
00627 for (i = 0; i < array->Num_Vec(); ++i) {
00628 ACCESS_VECTOR *av = array->Dim(i);
00629 _axle[i].Init_To_Access(av);
00630 }
00631
00632 if (_kernel == NULL) {
00633 _kernel = CXX_NEW(KERNEL_IMAGE(array), &ARA_memory_pool);
00634 }
00635
00636 }
00637
00638 INT
00639 Find_Non_Const_Loops(const SYMBOL &x, const ARA_LOOP_INFO &ara_loop_info)
00640 {
00641
00642 const ARA_LOOP_INFO *ara_info = &ara_loop_info;
00643
00644 while (ara_info) {
00645 if (!ara_info->Is_Invariant(x)) return (ara_info->Depth() + 1);
00646 ara_info = ara_info->Parent();
00647 }
00648
00649 return 0;
00650
00651 }
00652
00653 INT Locate_Sym(SYMBOL_LIST *syms, const SYMBOL &x, SYSTEM_OF_EQUATIONS *soe, INT_ST & non_const_loops, const ARA_LOOP_INFO & ara_loop_info)
00654 {
00655
00656 SYMBOL_ITER iter(syms);
00657 INT loc = 0;
00658
00659 for (SYMBOL_NODE *s = iter.First(); !iter.Is_Empty();
00660 ++loc, s = iter.Next())
00661 if (s->Symbol == x) return loc;
00662
00663
00664 syms->Append(CXX_NEW(SYMBOL_NODE(x,FALSE), &LNO_local_pool));
00665 non_const_loops.Push(Find_Non_Const_Loops(x,ara_loop_info));
00666 soe->Add_Vars(1);
00667 return loc;
00668
00669 }
00670
00671 enum ARA_ACT_TYPE
00672 {
00673 ARA_LO_BD, ARA_UP_BD, ARA_EQN
00674 };
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 void
00688 Add_Access(ACCESS_VECTOR *av, const INT32 coeff[],
00689 SYSTEM_OF_EQUATIONS *soes, SYMBOL_LIST *syms,
00690 INT_ST & non_const_loops,
00691 const mUINT16 depth, const INT num_dim,
00692 const INT axle, const ARA_ACT_TYPE act,
00693 const ARA_LOOP_INFO & ara_info,
00694 BOOL ignore_sym = FALSE)
00695 {
00696
00697 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
00698 fprintf(stdout,"Add access vector: \n");
00699 av->Print(stdout);
00700 fprintf(stdout,"\n To SOE: \n");
00701 soes->Print(stdout);
00702 }
00703
00704 Is_True(!av->Too_Messy,("Add_Access: Too messy access vector passed in"));
00705 INT vsz = ((av && av->Lin_Symb && !ignore_sym) ? av->Lin_Symb->Len() : 0) +
00706 syms->Len() + num_dim + depth + 1;
00707
00708 mINT32 *v = CXX_NEW_ARRAY(mINT32, vsz, &LNO_local_pool);
00709
00710 bzero(v, sizeof(mINT32) * vsz);
00711
00712
00713 if (coeff!=NULL)
00714 for (INT i = 0; i < num_dim; ++i)
00715 v[i] = coeff[i];
00716 else if (act == ARA_LO_BD)
00717 v[axle] = -1;
00718 else
00719 v[axle] = 1;
00720
00721
00722 if (av) {
00723
00724 for (INT i = 0; i < depth; ++i) {
00725
00726 #if 0
00727 fprintf(stdout,"%d \n", av->Loop_Coeff(i));
00728 #endif
00729
00730
00731 v[num_dim+i] = av->Loop_Coeff(i);
00732 }
00733
00734
00735 if (av->Contains_Lin_Symb() && !ignore_sym) {
00736 INTSYMB_ITER iter(av->Lin_Symb);
00737 for (INTSYMB_NODE *cur = iter.First();
00738 !iter.Is_Empty(); cur = iter.Next()) {
00739 INT pos = Locate_Sym(syms,cur->Symbol,soes, non_const_loops, ara_info);
00740 v[num_dim+depth+pos] = cur->Coeff;
00741 }
00742 }
00743 }
00744
00745 if (act != ARA_LO_BD) {
00746 for (INT i = num_dim; i < vsz; ++i)
00747 v[i] = -v[i];
00748 }
00749
00750
00751 INT c = av ? av->Const_Offset : 0 ;
00752 if (act == ARA_LO_BD) c = -c;
00753
00754 if (act != ARA_EQN)
00755 soes->Add_Le(v, c);
00756 else
00757 soes->Add_Eq(v, c);
00758
00759 CXX_DELETE_ARRAY(v, &LNO_local_pool);
00760
00761 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
00762 fprintf(stdout,"New SOE is: \n");
00763 soes->Print(stdout);
00764 }
00765
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 void
00781 Add_Bound(ACCESS_VECTOR *av,
00782 SYSTEM_OF_EQUATIONS *soes, SYMBOL_LIST *syms,
00783 INT_ST & non_const_loops,
00784 const mUINT16 depth, const INT num_dim,
00785 const ARA_LOOP_INFO & ara_info)
00786 {
00787
00788 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
00789 fprintf(stdout,"Add access vector: \n");
00790 av->Print(stdout);
00791 fprintf(stdout,"\n To SOE: \n");
00792 soes->Print(stdout);
00793 }
00794
00795 INT vsz = ((av && av->Lin_Symb) ? av->Lin_Symb->Len() : 0) +
00796 syms->Len() + num_dim + depth + 1;
00797
00798 mINT32 *v = CXX_NEW_ARRAY(mINT32, vsz, &LNO_local_pool);
00799
00800 bzero(v, sizeof(mINT32) * vsz);
00801
00802 if (av) {
00803
00804 for (INT i = 0; i < depth; ++i) {
00805
00806 #if 0
00807 fprintf(stdout,"%d \n", av->Loop_Coeff(i));
00808 #endif
00809
00810
00811 v[num_dim+i] = av->Loop_Coeff(i);
00812 }
00813
00814
00815 if (av->Contains_Lin_Symb()) {
00816 INTSYMB_ITER iter(av->Lin_Symb);
00817 for (INTSYMB_NODE *cur = iter.First();
00818 !iter.Is_Empty(); cur = iter.Next()) {
00819 INT pos = Locate_Sym(syms,cur->Symbol,soes, non_const_loops, ara_info);
00820 v[num_dim+depth+pos] = cur->Coeff;
00821 }
00822 }
00823 }
00824
00825
00826 INT c = av ? av->Const_Offset : 0 ;
00827
00828 soes->Add_Le(v, c);
00829
00830 CXX_DELETE_ARRAY(v, &LNO_local_pool);
00831
00832 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
00833 fprintf(stdout,"New SOE is: \n");
00834 soes->Print(stdout);
00835 }
00836
00837 }
00838
00839
00840
00841
00842
00843
00844
00845 void
00846 Add_To_SOE(const REGION &a, const INT pos, SYSTEM_OF_EQUATIONS *soe,
00847 SYMBOL_LIST *syms, INT_ST & non_const_loops,
00848 const BOOL convert_equation, const ARA_LOOP_INFO &ara_info)
00849 {
00850
00851 if (a._axle[pos].up != NULL){
00852 Add_Access(a._axle[pos].lo->_ac_v, a._axle[pos].lo->_coeff, soe, syms,
00853 non_const_loops, a._depth, a._dim, pos, ARA_LO_BD, ara_info);
00854 Add_Access(a._axle[pos].up->_ac_v, a._axle[pos].up->_coeff, soe, syms,
00855 non_const_loops, a._depth, a._dim, pos, ARA_UP_BD, ara_info);
00856 } else {
00857 if (convert_equation) {
00858 Add_Access(a._axle[pos].lo->_ac_v, a._axle[pos].lo->_coeff, soe, syms,
00859 non_const_loops, a._depth, a._dim, pos, ARA_LO_BD, ara_info);
00860 Add_Access(a._axle[pos].lo->_ac_v, a._axle[pos].lo->_coeff, soe, syms,
00861 non_const_loops, a._depth, a._dim, pos, ARA_UP_BD, ara_info);
00862 } else
00863 Add_Access(a._axle[pos].lo->_ac_v, a._axle[pos].lo->_coeff, soe, syms,
00864 non_const_loops, a._depth, a._dim, pos, ARA_EQN, ara_info);
00865 }
00866
00867 }
00868
00869
00870
00871
00872
00873
00874
00875 BOOL
00876 is_equality(const SYSTEM_OF_EQUATIONS *soe, const INT i, const INT j)
00877 {
00878
00879 for (INT k = 0; k < soe->Num_Vars(); ++k)
00880 if ((soe->Work(i,k)+soe->Work(j,k)) != 0) return FALSE;
00881
00882 return (soe->Work_Const(i) + soe->Work_Const(j) == 0);
00883
00884 }
00885
00886 INT
00887 Max_Non_Const_Loop(const SYSTEM_OF_EQUATIONS *soe, const INT i, const INT offset, const INT which_array, const INT_ST & non_const_loops)
00888 {
00889
00890 INT res = 0;
00891 INT k;
00892 switch (which_array) {
00893 case 0:
00894 for (k = 0; k < non_const_loops.Elements(); ++k) {
00895 if (soe->Work(i,offset+k)!=0)
00896 res = MAX(res, non_const_loops.Bottom_nth(k));
00897 }
00898 break;
00899 case 1:
00900 for (k = 0; k < non_const_loops.Elements(); ++k) {
00901 if (soe->Aeq()(i,offset+k)!=0)
00902 res = MAX(res, non_const_loops.Bottom_nth(k));
00903 }
00904 break;
00905 case 2:
00906 for (k = 0; k < non_const_loops.Elements(); ++k) {
00907 if (soe->Ale()(i,offset+k)!=0)
00908 res = MAX(res, non_const_loops.Bottom_nth(k));
00909 }
00910 break;
00911 default:
00912 FmtAssert(0,("Max_Non_Const_Loop: illegal array specification"));
00913 }
00914
00915 return res;
00916
00917 }
00918
00919 void
00920 AXLE_NODE::Set_Axle(const SYSTEM_OF_EQUATIONS *soe,
00921 const INT i, const INT j, const SYMBOL_LIST *syms,
00922 const INT depth, const INT dim,
00923 const INT_ST & non_const_loops,
00924 const INT stride)
00925 {
00926
00927 if (lo) CXX_DELETE(lo,&ARA_memory_pool);
00928 if (up) CXX_DELETE(up,&ARA_memory_pool);
00929
00930 step = stride;
00931
00932
00933 if (is_equality(soe, i, j)) {
00934 up = NULL;
00935 lo = CXX_NEW(CON_PAIR(), &ARA_memory_pool);
00936 lo->_ac_v =
00937 CXX_NEW(ACCESS_VECTOR(soe,i,syms,depth,dim,
00938 Max_Non_Const_Loop(soe,i,dim+depth,0,non_const_loops),
00939 0, TRUE, &ARA_memory_pool),&ARA_memory_pool);
00940
00941 INT k;
00942 for (k = 0; k<dim; ++k)
00943 if (soe->Work(i,k) != 0 && 2*k != i) {
00944 lo->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
00945 for (INT l = 0; l < dim; ++l) lo->_coeff[l] = 0;
00946 break;
00947 }
00948
00949 if (lo->_coeff)
00950 for (k = 0; k<dim; ++k)
00951 lo->_coeff[k] = soe->Work(i,k);
00952
00953 return;
00954 }
00955
00956
00957 lo = CXX_NEW(CON_PAIR(), &ARA_memory_pool);
00958 lo->_ac_v =
00959 CXX_NEW(ACCESS_VECTOR(soe,i,syms,depth,dim,
00960 Max_Non_Const_Loop(soe,i,dim+depth,0,non_const_loops),
00961 0, TRUE ,&ARA_memory_pool),&ARA_memory_pool);
00962
00963 INT k;
00964 for (k = 0; k<dim; ++k)
00965 if (soe->Work(i,k) != 0 && 2*k != i) {
00966 lo->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
00967 for (INT l = 0; l < dim; ++l) lo->_coeff[l] = 0;
00968 break;
00969 }
00970
00971 if (lo->_coeff)
00972 for (k = 0 ; k < dim; ++k)
00973 lo->_coeff[k] = soe->Work(i,k);
00974
00975 up = CXX_NEW(CON_PAIR(), &ARA_memory_pool);
00976 up->_ac_v = CXX_NEW(ACCESS_VECTOR(soe,j,syms,depth,dim,
00977 Max_Non_Const_Loop(soe,j,dim+depth,0,non_const_loops),
00978 0, FALSE ,&ARA_memory_pool),&ARA_memory_pool);
00979 for (k = 0; k<dim; ++k)
00980 if (soe->Work(i,k) != 0 && 2*k != i) {
00981 up->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
00982 for (INT l = 0; l < dim; ++l) up->_coeff[l] = 0;
00983 break;
00984 }
00985
00986 if (up->_coeff)
00987 for (k = 0; k < dim; ++k)
00988 up->_coeff[k] = soe->Work(i,k);
00989
00990 }
00991
00992 void
00993 AXLE_NODE::Set_Axle_Eq(const SYSTEM_OF_EQUATIONS *soe,
00994 const INT i, const INT j, const SYMBOL_LIST *syms,
00995 const INT depth, const INT dim,
00996 const INT_ST & non_const_loops,
00997 const INT stride)
00998 {
00999
01000 step = stride;
01001
01002
01003 if (lo==NULL) lo = CXX_NEW(CON_PAIR(),&ARA_memory_pool);
01004
01005 if (lo->_ac_v) CXX_DELETE(lo->_ac_v, &ARA_memory_pool);
01006 if (lo->_coeff) {
01007 CXX_DELETE_ARRAY(lo->_coeff, &ARA_memory_pool);
01008 lo->_coeff = NULL;
01009 }
01010
01011 if (up) {
01012 CXX_DELETE(up, &ARA_memory_pool);
01013 up = NULL;
01014 }
01015
01016 lo->_ac_v =
01017 CXX_NEW(ACCESS_VECTOR(soe,i,syms,depth,dim,
01018 Max_Non_Const_Loop(soe,i,dim+depth,1,non_const_loops),
01019 TRUE,1,&ARA_memory_pool),&ARA_memory_pool);
01020
01021 INT k;
01022 for (k = 0; k<dim; ++k)
01023 if (soe->Aeq()(i,k) != 0 && k!=j) {
01024 lo->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
01025 for (INT l = 0; l < dim; ++l) lo->_coeff[l] = 0;
01026 break;
01027 }
01028
01029 if (lo->_coeff)
01030 for (k = 0; k < dim; ++k)
01031 lo->_coeff[k] = soe->Aeq()(i,k);
01032
01033 }
01034
01035 void
01036 AXLE_NODE::Set_Axle_Le(const SYSTEM_OF_EQUATIONS *soe,
01037 const INT i, const INT j, const SYMBOL_LIST *syms,
01038 const INT depth, const INT dim,
01039 const INT_ST & non_const_loops,
01040 const INT stride)
01041 {
01042
01043 step = stride;
01044
01045
01046 if (soe->Ale()(i,j)<0) {
01047 if (lo==NULL) lo = CXX_NEW(CON_PAIR(),&ARA_memory_pool);
01048
01049 if (lo->_ac_v) CXX_DELETE(lo->_ac_v, &ARA_memory_pool);
01050 if (lo->_coeff) {
01051 CXX_DELETE_ARRAY(lo->_coeff, &ARA_memory_pool);
01052 lo->_coeff = NULL;
01053 }
01054 lo->_ac_v =
01055 CXX_NEW(ACCESS_VECTOR(soe,i,syms,depth,dim,
01056 Max_Non_Const_Loop(soe,i,dim+depth,2,non_const_loops),
01057 2,TRUE,&ARA_memory_pool),&ARA_memory_pool);
01058
01059 INT k;
01060 for (k = 0; k<dim; ++k)
01061 if (soe->Ale()(i,k) != 0 && k != j) {
01062 lo->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
01063 for (INT l = 0; l < dim; ++l) lo->_coeff[l] = 0;
01064 break;
01065 }
01066
01067 if (lo->_coeff)
01068 for (k = 0; k < dim; ++k)
01069 lo->_coeff[k] = soe->Ale()(i,k);
01070
01071 } else {
01072
01073 if (up==NULL) up = CXX_NEW(CON_PAIR(),&ARA_memory_pool);
01074 if (up->_ac_v) CXX_DELETE(up->_ac_v,&ARA_memory_pool);
01075 if (up->_coeff) {
01076 CXX_DELETE_ARRAY(up->_coeff,&ARA_memory_pool);
01077 up->_coeff = NULL;
01078 }
01079
01080 up->_ac_v =
01081 CXX_NEW(ACCESS_VECTOR(soe,i,syms,depth,dim,
01082 Max_Non_Const_Loop(soe,j,dim+depth,2,non_const_loops),
01083 2,FALSE,&ARA_memory_pool),&ARA_memory_pool);
01084
01085 INT k;
01086 for (k = 0; k<dim; ++k)
01087 if (soe->Ale()(i,k) != 0 && k != j) {
01088 up->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
01089 for (INT l = 0; l < dim; ++l) up->_coeff[l] = 0;
01090 break;
01091 }
01092 if (up->_coeff)
01093 for (k = 0; k < dim; ++k)
01094 up->_coeff[k] = soe->Ale()(i,k);
01095
01096 }
01097
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107 void
01108 REGION::Set_Region(const SYSTEM_OF_EQUATIONS * soe,
01109 const SYMBOL_LIST * syms,
01110 const INT_ST & non_const_loops,
01111 const INT strides[])
01112 {
01113
01114 Is_True(soe, ("Null pointer passed to Set_Region"));
01115
01116 _type = ARA_NORMAL;
01117 if (_axle==NULL) _axle = CXX_NEW_ARRAY(AXLE_NODE,_dim,&ARA_memory_pool);
01118
01119
01120 for (INT i = 0; i < _dim; ++i) {
01121
01122
01123 Is_True(soe->Work(2*i,i) && soe->Work(2*i+1,i),
01124 ("SOE is not in correct order"));
01125
01126 _axle[i].Set_Axle(soe, 2*i, 2*i+1, syms, _depth, _dim,
01127 non_const_loops, strides[i]);
01128 }
01129
01130 }
01131
01132
01133
01134
01135
01136
01137 void
01138 REGION::Set_Region(const SYSTEM_OF_EQUATIONS * soe,
01139 const SYMBOL_LIST * syms,
01140 const INT_ST & non_const_loops,
01141 INT strides[],
01142 const INT pivot_row,
01143 const INT pos,
01144 const INT loop_step,
01145 const INT projected_axle)
01146 {
01147
01148 Is_True(soe, ("Null SOE pointer passed to Set_Region"));
01149
01150 _type = ARA_NORMAL;
01151 if (_axle==NULL) _axle = CXX_NEW_ARRAY(AXLE_NODE,_dim,&ARA_memory_pool);
01152
01153 INT i;
01154 for (i = 0; i < _dim; ++i) _axle[i].Clear();
01155
01156
01157 INT pivot_column = _dim+pos;
01158 INT multiple = - soe->Aeq()(pivot_row,pivot_column);
01159 for (i = 0; i < _dim; ++i) {
01160 if (soe->Aeq()(pivot_row,i)!=0) {
01161 strides[i]=multiple*loop_step;
01162 break;
01163 }
01164 }
01165
01166 MEM_POOL_Push(&LNO_local_pool);
01167 {
01168 BIT_VECTOR *ancestor_lo = CXX_NEW(BIT_VECTOR(_dim,&LNO_local_pool), &LNO_local_pool);
01169
01170 BIT_VECTOR *ancestor_up = CXX_NEW(BIT_VECTOR(_dim,&LNO_local_pool), &LNO_local_pool);
01171
01172
01173 INT k = 0;
01174 for (i = 0; i < soe->Num_Eq_Constraints(); ++i)
01175 if (i!=pivot_row) {
01176 #if Is_True_On
01177 BOOL found = FALSE;
01178 #endif
01179 for (; k < _dim; ++k)
01180 if (k!=projected_axle && soe->Aeq()(i,k)!=0) {
01181 _axle[k].Set_Axle_Eq(soe, i, k, syms, _depth, _dim, non_const_loops, strides[k]);
01182 Is_True(!ancestor_lo->Test(k),("REGION::Set_Region: axle already set"));
01183 ancestor_lo->Set(k);
01184 ancestor_up->Set(k);
01185 #if Is_True_On
01186 found = TRUE;
01187 #endif
01188 break;
01189 }
01190 Is_True(found,("REGION::Set_Region: cannot find an axle to set"));
01191 }
01192
01193 Is_True((_dim-ancestor_lo->Pop_Count())*2 == soe->Num_Le_Constraints(),("REGION:Set_Region: Inequality constraints do not match the number of dimensions"));
01194
01195
01196 BOOL progress = TRUE;
01197 while (progress && ((ancestor_up->Pop_Count() != _dim) ||
01198 (ancestor_lo->Pop_Count() != _dim))) {
01199
01200 progress = FALSE;
01201
01202 for (i = 0; i < soe->Num_Le_Constraints(); ++i) {
01203 INT axle = -1;
01204 for (INT k = 0; k < _dim; ++k)
01205 if (soe->Ale()(i,k)<0 && !ancestor_lo->Test(k) ||
01206 soe->Ale()(i,k)>0 && !ancestor_up->Test(k)) {
01207 if (axle>=0) {
01208 axle = -1;
01209 break;
01210 } else
01211 axle = k;
01212 }
01213
01214 if (axle>=0) {
01215
01216
01217 progress = TRUE;
01218
01219 if (soe->Ale()(i,axle)<0) {
01220 _axle[axle].Set_Axle_Le(soe, i, axle, syms, _depth, _dim, non_const_loops, strides[axle]);
01221 ancestor_lo->Set(axle);
01222 } else {
01223 _axle[axle].Set_Axle_Le(soe, i, axle, syms, _depth, _dim, non_const_loops, strides[axle]);
01224 ancestor_up->Set(axle);
01225 }
01226
01227 }
01228
01229 }
01230
01231 }
01232
01233 if (!progress) {
01234 Set_Too_Messy();
01235 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01236 fprintf(stdout,"REGION::Set_Region: No progress\n");
01237 }
01238 }
01239
01240 CXX_DELETE(ancestor_lo, &LNO_local_pool);
01241 CXX_DELETE(ancestor_up, &LNO_local_pool);
01242 }
01243 MEM_POOL_Pop(&LNO_local_pool);
01244
01245 }
01246
01247
01248
01249
01250
01251
01252
01253 REGION *
01254 Region_Intersect(const REGION &a, const REGION &b, const ARA_LOOP_INFO & ara_info)
01255 {
01256
01257
01258
01259
01260 if ( a._type==ARA_BOTTOM||b._type==ARA_BOTTOM)
01261 return NULL;
01262
01263
01264 if (a._type==ARA_TOP) {
01265 REGION* result = CXX_NEW(REGION(b),&ARA_memory_pool);
01266 for (INT i = 0; i < a._wn_list.Elements(); ++i)
01267 result->_wn_list.Push(a._wn_list.Bottom_nth(i));
01268 return result;
01269 }
01270
01271 if (b._type==ARA_TOP) {
01272 REGION* result = CXX_NEW(REGION(a),&ARA_memory_pool);
01273 for (INT i = 0; i < b._wn_list.Elements(); ++i)
01274 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01275 return result;
01276 }
01277
01278
01279
01280 if (a._dim != b._dim)
01281 return NULL;
01282
01283 Is_True(a._dim==b._dim,("Try to merge arrays with different dimensions"));
01284
01285
01286
01287
01288 INT i;
01289 for (i = 0; i < a._dim; ++i) {
01290 if (a._axle[i].up == NULL && b._axle[i].up == NULL &&
01291 !(Equivalent(*a._axle[i].lo, *b._axle[i].lo, a._dim)))
01292 return NULL;
01293 }
01294
01295
01296 INT depth = MIN(a._depth, b._depth);
01297 INT dim = a._dim;
01298 REGION * result = CXX_NEW(REGION(depth,dim), &ARA_memory_pool);
01299 result->_dim = dim;
01300 result->_depth = depth;
01301 result->_axle = CXX_NEW_ARRAY(AXLE_NODE, result->_dim, &ARA_memory_pool);
01302
01303
01304 for (i = 0; i < a._wn_list.Elements(); ++i)
01305 result->_wn_list.Push(a._wn_list.Bottom_nth(i));
01306 for (i = 0; i < b._wn_list.Elements(); ++i)
01307 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01308
01309 MEM_POOL_Push(&LNO_local_pool);
01310 {
01311
01312 SYSTEM_OF_EQUATIONS *soe = CXX_NEW(SYSTEM_OF_EQUATIONS(0,0,dim+depth,&LNO_local_pool), &LNO_local_pool);
01313
01314 SYMBOL_LIST *syms = CXX_NEW(SYMBOL_LIST, &LNO_local_pool);
01315
01316
01317 INT_ST non_const_loops(&LNO_local_pool);
01318
01319
01320 INT *strides = CXX_NEW_ARRAY(INT, result->_dim, &LNO_local_pool);
01321
01322
01323 for (i = 0; i < dim; ++i) {
01324
01325 if (a._axle[i].up == NULL && b._axle[i].up == NULL) {
01326
01327
01328 ACCESS_VECTOR *av = a._axle[i].lo->_ac_v;
01329 INT32 *coeff = a._axle[i].lo->_coeff;
01330 strides[i] = 1;
01331
01332 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01333 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01334
01335
01336 av = b._axle[i].lo->_ac_v;
01337 coeff = b._axle[i].lo->_coeff;
01338
01339 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01340 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01341
01342 } else if (a._axle[i].up == NULL && b._axle[i].up != NULL) {
01343
01344
01345
01346
01347 ACCESS_VECTOR *av = a._axle[i].lo->_ac_v;
01348 INT32 *coeff = a._axle[i].lo->_coeff;
01349
01350
01351 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01352 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01353
01354 av = b._axle[i].lo->_ac_v;
01355 coeff = b._axle[i].lo->_coeff;
01356 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01357
01358 av = b._axle[i].up->_ac_v;
01359 coeff = b._axle[i].up->_coeff;
01360 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01361
01362 } else if (a._axle[i].up != NULL && b._axle[i].up == NULL) {
01363
01364 ACCESS_VECTOR *av = a._axle[i].lo->_ac_v;
01365 INT32 *coeff = a._axle[i].lo->_coeff;
01366 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01367
01368 av = a._axle[i].up->_ac_v;
01369 coeff = a._axle[i].up->_coeff;
01370 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01371
01372 av = b._axle[i].lo->_ac_v;
01373 coeff = b._axle[i].lo->_coeff;
01374
01375 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01376
01377 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01378
01379 } else {
01380
01381
01382 ACCESS_VECTOR *av = a._axle[i].lo->_ac_v;
01383 INT32 *coeff = a._axle[i].lo->_coeff;
01384 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01385
01386 av = a._axle[i].up->_ac_v;
01387 coeff = a._axle[i].up->_coeff;
01388 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01389
01390 av = b._axle[i].lo->_ac_v;
01391 coeff = b._axle[i].lo->_coeff;
01392 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_LO_BD, ara_info);
01393
01394 av = b._axle[i].up->_ac_v;
01395 coeff = b._axle[i].up->_coeff;
01396 Add_Access(av, coeff, soe, syms, non_const_loops, depth, dim, i, ARA_UP_BD, ara_info);
01397
01398 }
01399
01400
01401 Is_True(a._axle[i].step > 0 && b._axle[i].step > 0, ("Negative stride found"));
01402 strides[i] = a._axle[i].step;
01403
01404 if (a._axle[i].step != b._axle[i].step) {
01405 const IMAT & ale = soe->Ale();
01406 INT row = ale.Rows();
01407 for (INT k = 0; k < ale.Cols(); ++k) {
01408 if (ale(row-1,k) != ale(row-3,k)) {
01409 CXX_DELETE_ARRAY(strides, &LNO_local_pool);
01410 CXX_DELETE(result, &ARA_memory_pool);
01411 CXX_DELETE(syms, &LNO_local_pool);
01412 CXX_DELETE(soe, &LNO_local_pool);
01413 result = NULL;
01414 goto return_point;
01415 }
01416 }
01417
01418 INT64 *ble = soe->Ble();
01419 INT offset1 = -ble[row-1];
01420 INT offset2 = -ble[row-3];
01421 INT diff = abs(offset1-offset2);
01422
01423 strides[i] = MAX(a._axle[i].step,b._axle[i].step);
01424 if (diff == 0) continue;
01425
01426
01427 INT g = Gcd(a._axle[i].step,b._axle[i].step);
01428 if ((diff % g) != 0) {
01429 CXX_DELETE_ARRAY(strides, &LNO_local_pool);
01430 CXX_DELETE(result, &ARA_memory_pool);
01431 CXX_DELETE(syms, &LNO_local_pool);
01432 CXX_DELETE(soe, &LNO_local_pool);
01433 result = NULL;
01434 goto return_point;
01435 }
01436
01437
01438
01439 while (offset1 != offset2) {
01440 if (offset1 < offset2)
01441 offset1 += a._axle[i].step;
01442 else
01443 offset2 += b._axle[i].step;
01444 }
01445
01446
01447
01448 ble[row-3] = -offset1;
01449 soe->Remove_Le_Number(row-1);
01450
01451 }
01452 }
01453
01454
01455 if (soe->Copy_To_Work()) {
01456 INT num_con = soe->Work_Constraints();
01457
01458
01459
01460 soe->Elim_Simple_Redundant();
01461
01462 if (2*soe->Work_Constraints() == num_con) {
01463
01464
01465 if (soe->Is_Consistent_Work()) {
01466
01467
01468 soe->Copy_To_Work();
01469 soe->Elim_Simple_Redundant();
01470 soe->Remove_Last_Le(num_con);
01471 soe->Add_Work_Le();
01472
01473
01474
01475 INT * sort_criteria = CXX_NEW_ARRAY(INT, soe->Num_Le_Constraints(), &LNO_local_pool);
01476 for (INT i = 0; i < soe->Num_Le_Constraints(); ++i) {
01477 BOOL var = -1;
01478 for (INT j = 0; j < a._dim; ++j) {
01479 if (soe->Work(i,j) != 0) {
01480 var = j;
01481 break;
01482 }
01483 }
01484
01485 FmtAssert(var != -1, (("region is not bounded")));
01486 if (soe->Work(i,var) > 0) {
01487 sort_criteria[i] = 2*var+1;
01488 } else {
01489 sort_criteria[i] = 2*var;
01490 }
01491 }
01492 soe->Sort_Le(sort_criteria, FALSE);
01493 soe->Copy_To_Work();
01494
01495
01496
01497 result->Set_Region(soe, syms, non_const_loops, strides);
01498 CXX_DELETE(syms, &LNO_local_pool);
01499 CXX_DELETE_ARRAY(strides, &LNO_local_pool);
01500 CXX_DELETE(soe,&LNO_local_pool);
01501 CXX_DELETE_ARRAY(sort_criteria, &LNO_local_pool);
01502 goto return_point;
01503 }
01504
01505 } else if (soe->Is_Consistent_Work()) {
01506
01507
01508
01509
01510 soe->Copy_To_Work();
01511 soe->Elim_Simple_Redundant();
01512 soe->Remove_Last_Le(num_con);
01513 soe->Add_Work_Le();
01514
01515
01516
01517
01518 BOOL *is_redundant =
01519 CXX_NEW_ARRAY(BOOL, soe->Num_Le_Constraints(), &LNO_local_pool);
01520 soe->Mark_Redundant(is_redundant);
01521
01522 INT limit = soe->Num_Le_Constraints();
01523 for (INT i = 0; i < limit; ++i) {
01524 if (is_redundant[i]) soe->Remove_Le_Number(i);
01525 }
01526
01527
01528 if (soe->Num_Le_Constraints() == num_con) {
01529
01530 soe->Copy_To_Work();
01531
01532
01533 result->Set_Region(soe, syms, non_const_loops, strides);
01534 CXX_DELETE_ARRAY(strides, &LNO_local_pool);
01535 CXX_DELETE(syms, &LNO_local_pool);
01536 CXX_DELETE(soe, &LNO_local_pool);
01537 goto return_point;
01538 }
01539 }
01540 }
01541
01542
01543
01544 CXX_DELETE_ARRAY(strides, &LNO_local_pool);
01545 CXX_DELETE(result, &ARA_memory_pool);
01546 CXX_DELETE(syms, &LNO_local_pool);
01547 CXX_DELETE(soe, &LNO_local_pool);
01548 result = NULL;
01549 goto return_point;
01550 }
01551
01552 return_point:
01553
01554 MEM_POOL_Pop(&LNO_local_pool);
01555 return result;
01556
01557 }
01558
01559 BOOL
01560 REGION::Is_Included(const REGION &a, const ARA_LOOP_INFO &ara_info)
01561 {
01562 INT res = Region_Compare(*this, a, ara_info);
01563 return (res == 2 || res == 3);
01564 }
01565
01566 BOOL
01567 REGION::Contains(WN * array_wn)
01568 {
01569
01570 for (INT i=0; i<_wn_list.Elements(); ++i) {
01571 WN *cur = _wn_list.Bottom_nth(i);
01572 if (array_wn == _wn_list.Bottom_nth(i)) return TRUE;
01573 }
01574 return FALSE;
01575
01576 }
01577
01578
01579
01580
01581
01582
01583
01584
01585 INT
01586 Region_Compare(const REGION &a, const REGION &b, const ARA_LOOP_INFO &ara_info)
01587 {
01588
01589
01590 if (a._type==b._type) {
01591 if (a._type==ARA_TOP || a._type == ARA_BOTTOM)
01592 return 3;
01593 else if (a._type == ARA_TOO_MESSY)
01594 return 0;
01595 }
01596
01597 if (b._type == ARA_TOP) return 1;
01598 if (a._type == ARA_TOP) return 2;
01599 if (a._type == ARA_TOO_MESSY || b._type == ARA_TOO_MESSY) return 0;
01600
01601
01602 if (a._dim != b._dim)
01603 return 0;
01604
01605 #if 0
01606
01607
01608 if (a._kernel!=b._kernel) return 0;
01609 #endif
01610
01611 INT result = 0;
01612
01613
01614
01615 INT i;
01616 for (i = 0; i < a._dim; ++i) {
01617 if (a._axle[i].up == NULL && b._axle[i].up == NULL &&
01618 !(Equivalent(*a._axle[i].lo, *b._axle[i].lo, a._dim)))
01619 return 0;
01620 }
01621
01622 MEM_POOL_Push(&LNO_local_pool);
01623 {
01624
01625 SYSTEM_OF_EQUATIONS *soe = CXX_NEW(SYSTEM_OF_EQUATIONS(0,0,a._dim+a._depth,&LNO_local_pool), &LNO_local_pool);
01626 SYMBOL_LIST *syms = CXX_NEW(SYMBOL_LIST, &LNO_local_pool);
01627 INT_ST non_const_loops(&LNO_local_pool);
01628
01629
01630
01631
01632
01633
01634
01635 for (i = 0; i < a._dim; ++i) {
01636 Add_To_SOE(a, i, soe, syms, non_const_loops, TRUE, ara_info);
01637 Add_To_SOE(b, i, soe, syms, non_const_loops, TRUE, ara_info);
01638 }
01639
01640 if (!soe->Copy_To_Work()) goto return_point;
01641 INT16 * lower = CXX_NEW_ARRAY(INT16, a._dim, &LNO_local_pool);
01642 INT16 * upper = CXX_NEW_ARRAY(INT16, a._dim, &LNO_local_pool);
01643
01644 for (i = 0; i < a._dim; ++i) {
01645 lower[i] = soe->Simple_Redundant(4*i, 4*i+2);
01646 upper[i] = soe->Simple_Redundant(4*i+1, 4*i+3);
01647 }
01648
01649
01650 for (i = 0; i < a._dim; ++i) {
01651 if (lower[i]!=3 || upper[i]!=3)
01652 break;
01653 }
01654
01655 if (i==a._dim) {
01656 result = 3;
01657 goto return_point;
01658 }
01659
01660 BOOL exists_1 = FALSE;
01661 BOOL exists_2 = FALSE;
01662
01663 for (; i < a._dim; ++i) {
01664 exists_1 = (exists_1 || lower[i]==1 || upper[i]==1);
01665 exists_2 = (exists_2 || lower[i]==2 || upper[i]==2);
01666 if (exists_1 && exists_2) {
01667 result = 0;
01668 goto return_point;
01669 }
01670 }
01671
01672
01673
01674 BOOL redundant_1 = FALSE;
01675 BOOL redundant_2 = FALSE;
01676
01677 if (!exists_2) redundant_1 = soe->Prove_Redundant(0, a._dim);
01678 if (redundant_1 && exists_1) {
01679 result = 2;
01680 goto return_point;
01681 }
01682
01683 if (!exists_1) redundant_2 = soe->Prove_Redundant(1, a._dim);
01684 if (redundant_2 && exists_2) {
01685 result = 1;
01686 goto return_point;
01687 }
01688
01689 if (redundant_1 && redundant_2) {
01690 result = 3;
01691 goto return_point;
01692 }
01693
01694 }
01695 return_point: ;
01696
01697 MEM_POOL_Pop(&LNO_local_pool);
01698 return result;
01699
01700 }
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710 REGION *
01711 Region_Union(const REGION &a, const REGION &b, const ARA_LOOP_INFO &ara_info)
01712 {
01713 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01714 fprintf(stdout,"Union two REGIONs \n");
01715 a.Print(stdout);
01716 b.Print(stdout);
01717 }
01718
01719
01720 if (a._type==ARA_TOP) {
01721 REGION* result = CXX_NEW(REGION(a),&ARA_memory_pool);
01722 for (INT i = 0; i < b._wn_list.Elements(); ++i)
01723 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01724 return result;
01725 }
01726
01727 if (b._type==ARA_TOP) {
01728 REGION* result = CXX_NEW(REGION(b),&ARA_memory_pool);
01729 for (INT i = 0; i < a._wn_list.Elements(); ++i)
01730 result->_wn_list.Push(a._wn_list.Bottom_nth(i));
01731 return result;
01732 }
01733
01734 if (a._type==ARA_BOTTOM || b._type==ARA_TOO_MESSY) {
01735 REGION* result = CXX_NEW(REGION(b),&ARA_memory_pool);
01736 for (INT i = 0; i < a._wn_list.Elements(); ++i)
01737 result->_wn_list.Push(a._wn_list.Bottom_nth(i));
01738 return result;
01739 }
01740
01741 if (b._type==ARA_BOTTOM || a._type==ARA_TOO_MESSY) {
01742 REGION* result = CXX_NEW(REGION(a),&ARA_memory_pool);
01743 for (INT i = 0; i < b._wn_list.Elements(); ++i)
01744 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01745 return result;
01746 }
01747
01748
01749
01750 if (a._dim != b._dim)
01751 return NULL;
01752
01753 Is_True(a._dim==b._dim,("Try to merge arrays with different dimensions"));
01754
01755
01756 INT pos = -1;
01757 for (INT i = 0; i < a._dim; ++i)
01758 if (!Equivalent(a._axle[i],b._axle[i],a._dim)) {
01759 if (pos>=0) return NULL;
01760 pos = i;
01761 }
01762
01763 if (pos<0) {
01764 REGION* result = CXX_NEW(REGION(a),&ARA_memory_pool);
01765 for (INT i = 0; i < b._wn_list.Elements(); ++i)
01766 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01767 return result;
01768 }
01769
01770
01771
01772 AXLE_NODE & ax = a._axle[pos];
01773 AXLE_NODE & bx = b._axle[pos];
01774
01775 if (ax.step != bx.step && ax.up != NULL && bx.up != NULL) return NULL;
01776
01777
01778 INT step = MAX(ax.step, bx.step);
01779 REGION * result = NULL;
01780
01781 MEM_POOL_Push(&LNO_local_pool);
01782 {
01783
01784 SYSTEM_OF_EQUATIONS *soe =
01785 CXX_NEW(SYSTEM_OF_EQUATIONS(0,0,a._dim+a._depth,&LNO_local_pool), &LNO_local_pool);
01786 SYMBOL_LIST *syms = CXX_NEW(SYMBOL_LIST, &LNO_local_pool);
01787 INT_ST non_const_loops(&LNO_local_pool);
01788
01789
01790 Add_To_SOE(a, pos, soe, syms, non_const_loops, TRUE, ara_info);
01791 Add_To_SOE(b, pos, soe, syms, non_const_loops, TRUE, ara_info);
01792
01793
01794
01795
01796
01797
01798 INT64 *ble = soe->Ble();
01799 ble[1] += step;
01800 ble[3] += step;
01801
01802
01803
01804 if (soe->Copy_To_Work()) {
01805 BOOL *is_redundant =
01806 CXX_NEW_ARRAY(BOOL, soe->Num_Le_Constraints(), &LNO_local_pool);
01807
01808 INT num_con = soe->Num_Le_Constraints();
01809
01810
01811 num_con -= soe->Mark_Simple_Redundant(is_redundant);
01812
01813 if (num_con > 2) {
01814
01815
01816 num_con -= soe->Mark_New_Redundant(is_redundant);
01817 }
01818
01819
01820
01821 if (num_con == 2) {
01822
01823
01824
01825 if (soe->Is_Consistent() && ax.step == 1) {
01826 if ((!is_redundant[0] && !is_redundant[2]) ||
01827 (!is_redundant[1] && !is_redundant[3])) {
01828 goto return_point;
01829 }
01830
01831 if (is_redundant[0]) {
01832 result = CXX_NEW(REGION(a), &ARA_memory_pool);
01833 result->_axle[pos].Set_Axle(ax.lo, (bx.up) ? bx.up : bx.lo,
01834 step, a._dim);
01835 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01836 fprintf(stdout,"0 is redundant \n");
01837 result->Print(stdout);
01838 }
01839
01840 } else {
01841 result = CXX_NEW(REGION(a), &ARA_memory_pool);
01842 result->_axle[pos].Set_Axle(bx.lo, (ax.up) ? ax.up : ax.lo,
01843 step, a._dim);
01844 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
01845 fprintf(stdout,"1 is redundant \n");
01846 result->Print(stdout);
01847 }
01848 }
01849
01850
01851 for (INT i = 0; i < b._wn_list.Elements(); ++i)
01852 result->_wn_list.Push(b._wn_list.Bottom_nth(i));
01853
01854 goto return_point;
01855 }
01856 }
01857
01858 }
01859 }
01860 return_point:
01861 MEM_POOL_Pop(&LNO_local_pool);
01862
01863 return result;
01864
01865 }
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893 REGION &
01894 REGION::Region_Projection(const INT pos, const ARA_LOOP_INFO & ara_info)
01895 {
01896
01897 if (_type != ARA_NORMAL) return *this;
01898
01899
01900 if (_kernel->Get_Independent_Loops()[pos])
01901 return *this;
01902
01903
01904
01905
01906 if (_kernel->Projected_Level()>pos) {
01907 _kernel->Project(pos, ara_info);
01908 }
01909
01910 if (_kernel->Region() && _kernel->Region()->Is_Too_Messy()) {
01911 this->Set_Too_Messy();
01912 _depth = pos;
01913 return *this;
01914 }
01915
01916
01917
01918 for (INT i = 0; i < _dim; ++i) {
01919 AXLE_NODE & ax = _axle[i];
01920 if ((ax.lo->_ac_v && ax.lo->_ac_v->Loop_Coeff(pos)!=0) ||
01921 (ax.up && ax.up->_ac_v && ax.up->_ac_v->Loop_Coeff(pos)!=0)) {
01922 ax.Set_To_Kernel_Image(_kernel->Region()->Dim(i),_dim, _kernel->Get_Kernel()->Dim(i)->Const_Offset);
01923 }
01924 }
01925 _depth = pos;
01926
01927 return *this;
01928 }
01929
01930
01931
01932
01933
01934
01935 void
01936 AXLE_NODE::Set_To_Kernel_Image(const AXLE_NODE &a, const INT dim, const INT kernel_offset)
01937 {
01938
01939 if (a.up) {
01940 if (!up) {
01941 if (lo)
01942 up = CXX_NEW(CON_PAIR(*lo, dim), &ARA_memory_pool);
01943 else
01944 up = CXX_NEW(CON_PAIR(), &ARA_memory_pool);
01945 }
01946
01947 if (a.up->_ac_v) {
01948
01949 if (!up->_ac_v) {
01950 up->_ac_v = CXX_NEW(ACCESS_VECTOR(a.up->_ac_v,&ARA_memory_pool), &ARA_memory_pool);
01951 } else {
01952
01953 for (INT i = 0; i < up->_ac_v->Nest_Depth(); ++i)
01954 up->_ac_v->Set_Loop_Coeff(i,0);
01955 up->_ac_v->Const_Offset -= kernel_offset;
01956 ACCESS_VECTOR *old_av = up->_ac_v;
01957 #if 0
01958 FmtAssert(old_av->Nest_Depth() == a.up->_ac_v->Nest_Depth(),
01959 ("Access depths do not match"));
01960 #endif
01961 old_av->Set_Nest_Depth(a.up->_ac_v->Nest_Depth());
01962 up->_ac_v = Merge(a.up->_ac_v, old_av, &ARA_memory_pool);
01963 CXX_DELETE(old_av, &ARA_memory_pool);
01964
01965 }
01966
01967 up->_ac_v->Set_Non_Const_Loops(a.up->_ac_v->Non_Const_Loops());
01968
01969 }
01970
01971 if (a.up->_coeff) {
01972
01973 if (!up->_coeff)
01974 up->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
01975
01976 for (INT i = 0; i < dim; ++i)
01977 up->_coeff[i] = a.up->_coeff[i];
01978
01979 }
01980
01981 }
01982
01983 if (a.lo) {
01984
01985 if (!lo) lo = CXX_NEW(CON_PAIR(), &ARA_memory_pool);
01986
01987 if (a.lo->_ac_v) {
01988
01989 if (!lo->_ac_v) {
01990
01991 lo->_ac_v =
01992 CXX_NEW(ACCESS_VECTOR(a.lo->_ac_v,&ARA_memory_pool),&ARA_memory_pool);
01993 } else {
01994
01995 for (INT i = 0; i < lo->_ac_v->Nest_Depth(); ++i)
01996 lo->_ac_v->Set_Loop_Coeff(i,0);
01997 lo->_ac_v->Const_Offset -= kernel_offset;
01998 ACCESS_VECTOR *old_av = lo->_ac_v;
01999 #if 0
02000 FmtAssert(a.lo->_ac_v->Nest_Depth() == old_av->Nest_Depth(),
02001 ("Nest depths of accesses do not match"));
02002 #endif
02003
02004 old_av->Set_Nest_Depth(a.lo->_ac_v->Nest_Depth());
02005 lo->_ac_v = Merge(a.lo->_ac_v, old_av, &ARA_memory_pool);
02006 CXX_DELETE(old_av, &ARA_memory_pool);
02007
02008 }
02009
02010 lo->_ac_v->Set_Non_Const_Loops(a.lo->_ac_v->Non_Const_Loops());
02011
02012 }
02013
02014 if (a.lo->_coeff) {
02015
02016 if (!lo->_coeff)
02017 lo->_coeff = CXX_NEW_ARRAY(INT32, dim, &ARA_memory_pool);
02018
02019 for (INT i = 0; i < dim; ++i)
02020 lo->_coeff[i] = a.lo->_coeff[i];
02021
02022 }
02023
02024 }
02025
02026 }
02027
02028
02029
02030
02031
02032
02033
02034
02035 void
02036 KERNEL_IMAGE::Project(const INT level, const ARA_LOOP_INFO &ara_info)
02037 {
02038
02039 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02040 fprintf(stdout,"enters KERNEL_IMAGE::Project \n");
02041 if (_region) _region->Print(stdout);
02042 }
02043
02044
02045 if (_projected_level <= level) return;
02046 _projected_level = level;
02047
02048 MEM_POOL_Push(&LNO_local_pool);
02049 {
02050
02051 SYSTEM_OF_EQUATIONS *soe =
02052 CXX_NEW(SYSTEM_OF_EQUATIONS(0,0,_kernel->Num_Vec()+_depth,&LNO_local_pool), &LNO_local_pool);
02053 SYMBOL_LIST *syms = CXX_NEW(SYMBOL_LIST, &LNO_local_pool);
02054 INT_ST non_const_loops(&LNO_local_pool);
02055 INT *strides = CXX_NEW_ARRAY(INT, _kernel->Num_Vec(), &LNO_local_pool);
02056 INT *which_axle = CXX_NEW_ARRAY(INT, _kernel->Num_Vec(), &LNO_local_pool);
02057 INT eq_count = 0;
02058
02059
02060 if (_region) {
02061
02062 for (INT i = 0; i < _region->Num_Dim(); ++i) {
02063 Add_To_SOE(*_region, i, soe, syms, non_const_loops, FALSE, ara_info);
02064 strides[i] = _region->_axle[i].step;
02065 if (_region->_axle[i].up == NULL) {
02066 which_axle[eq_count] = i;
02067 eq_count++;
02068 }
02069 }
02070
02071 } else {
02072
02073
02074 for (INT i = 0; i < _kernel->Num_Vec(); ++i) {
02075 Add_Access(_kernel->Dim(i), NULL, soe, syms, non_const_loops,
02076 _depth, _kernel->Num_Vec(), i, ARA_EQN, ara_info, TRUE);
02077 strides[i] = 1;
02078 which_axle[i] = i;
02079 }
02080 _region = CXX_NEW(REGION(_depth,_kernel->Num_Vec()),&ARA_memory_pool);
02081
02082 }
02083
02084
02085
02086 INT pivot_row;
02087 INT step;
02088 DOLOOP_STACK & do_stack = ((ARA_LOOP_INFO &) ara_info).Do_Stack();
02089 for (INT i = do_stack.Elements() - 1; i >= level; --i) {
02090 DO_LOOP_INFO *dli = Get_Do_Loop_Info(do_stack.Bottom_nth(i));
02091 ACCESS_ARRAY *lb = dli->LB;
02092 ACCESS_ARRAY *ub = dli->UB;
02093 step = dli->Step->Const_Offset;
02094
02095 if (lb->Num_Vec()>1 || ub->Num_Vec()>1 || !dli->Step->Is_Const()) {
02096 _region->Set_Too_Messy();
02097
02098 goto return_point;
02099 }
02100
02101 Add_Bound(lb->Dim(0), soe, syms, non_const_loops, _depth, _kernel->Num_Vec(),
02102 ara_info);
02103 Add_Bound(ub->Dim(0), soe, syms, non_const_loops, _depth, _kernel->Num_Vec(),
02104 ara_info);
02105 BOOL is_inconsistent = FALSE;
02106
02107
02108 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02109 fprintf(stdout,"Before base change, the SOE is: \n");
02110 soe->Print(stdout);
02111 }
02112
02113
02114
02115 pivot_row = soe->Change_Base(_kernel->Num_Vec(), i, &LNO_local_pool);
02116
02117 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02118 fprintf(stdout,"After base change, the SOE is: \n");
02119 soe->Print(stdout);
02120 }
02121 if (pivot_row < 0) {
02122 _region->Set_Too_Messy();
02123
02124 goto return_point;
02125 }
02126 }
02127
02128 _region->Set_Region(soe, syms, non_const_loops, strides, pivot_row, level, step, which_axle[pivot_row]);
02129
02130 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG)) {
02131 fprintf(stdout,"exits KERNEL_IMAGE::Project \n");
02132 if (_region) _region->Print(stdout);
02133 }
02134
02135 }
02136
02137 return_point:
02138 MEM_POOL_Pop(&LNO_local_pool);
02139
02140 }
02141
02142 WN *
02143 REGION_UN::Any_Wn()
02144 {
02145
02146 Is_True(!Is_Empty(),("Try to get WN from an empty REGION_UN"));
02147
02148 if (Is_Empty()) return NULL;
02149
02150 REGION *cur = Head();
02151 if (cur->_wn_list.Elements())
02152 return cur->_wn_list.Bottom_nth(0);
02153 else
02154 return NULL;
02155
02156 }
02157
02158 BOOL
02159 REGION_UN::Is_Included(const REGION &a, const ARA_LOOP_INFO &ara_info)
02160 {
02161
02162 REGION_ITER reg_iter(this);
02163 for (REGION *cur = reg_iter.First();
02164 !reg_iter.Is_Empty(); cur= reg_iter.Next())
02165 if (cur->Is_Included(a, ara_info)) return TRUE;
02166
02167 return FALSE;
02168
02169 }
02170
02171 BOOL
02172 REGION_UN::Is_Included(const REGION_UN &a, const ARA_LOOP_INFO &ara_info)
02173 {
02174 REGION_CONST_ITER a_iter(&a);
02175
02176 for (const REGION *a_cur = a_iter.First();
02177 !a_iter.Is_Empty(); a_cur = a_iter.Next()) {
02178 REGION_ITER my_iter(this);
02179 BOOL covered = FALSE;
02180 for (REGION *my_cur = my_iter.First();
02181 !my_iter.Is_Empty(); my_cur = my_iter.Next()) {
02182 if (my_cur->Is_Included(*a_cur, ara_info)) {
02183 covered = TRUE;
02184 break;
02185 }
02186
02187 if (!covered) return FALSE;
02188 }
02189 }
02190
02191 return TRUE;
02192
02193 }
02194
02195 BOOL
02196 REGION_UN::Contains(WN *array_wn)
02197 {
02198
02199 REGION_ITER iter(this);
02200 for (REGION *cur = iter.First(); !iter.Is_Empty(); cur = iter.Next())
02201 if (cur->Contains(array_wn)) return TRUE;
02202
02203 return FALSE;
02204
02205 }
02206
02207
02208
02209
02210
02211
02212
02213 REGION_UN &
02214 REGION_UN::Add_Region(REGION *a, const ARA_LOOP_INFO &ara_info)
02215 {
02216
02217 REGION* add_reg = a;
02218 a = NULL;
02219
02220 REGION_ITER reg_iter(this);
02221 REGION *prev = NULL;
02222 REGION *cur = reg_iter.First();
02223
02224 while (!reg_iter.Is_Empty()) {
02225
02226 REGION *new_reg = Region_Union(*cur, *add_reg, ara_info);
02227 if (new_reg==NULL) {
02228 prev = cur;
02229 cur = reg_iter.Next();
02230 } else {
02231
02232
02233
02234
02235 CXX_DELETE(this->Remove(prev,cur),&ARA_memory_pool);
02236 CXX_DELETE(add_reg,&ARA_memory_pool);
02237 add_reg = new_reg;
02238
02239
02240
02241
02242 reg_iter.Init(this);
02243 cur = reg_iter.First();
02244 prev = NULL;
02245 }
02246
02247 }
02248
02249 this->Append(add_reg);
02250 return *this;
02251
02252 }
02253
02254 REGION_UN *
02255 RegionUN_Intersect(const REGION_UN &a, const REGION_UN &b, ARA_LOOP_INFO &ara_info)
02256 {
02257
02258 REGION_UN* result=CXX_NEW(REGION_UN(),&ARA_memory_pool);
02259 REGION_CONST_ITER a_iter(&a);
02260 REGION_CONST_ITER b_iter(&b);
02261 for (const REGION* a_cur = a_iter.First(); !a_iter.Is_Empty(); a_cur = a_iter.Next())
02262 for (const REGION *b_cur = b_iter.First(); !b_iter.Is_Empty(); b_cur = b_iter.Next()) {
02263 REGION* intersect = Region_Intersect(*a_cur,*b_cur,ara_info);
02264 if (intersect!=NULL) result->Add_Region(intersect, ara_info);
02265 }
02266
02267 return result;
02268
02269 }
02270
02271 REGION_UN *
02272 RegionUN_Union(const REGION_UN &a, const REGION_UN &b, const ARA_LOOP_INFO &ara_info)
02273 {
02274
02275 REGION_UN* result = CXX_NEW(REGION_UN(),&ARA_memory_pool);
02276 REGION_CONST_ITER a_iter(&a);
02277 REGION_CONST_ITER b_iter(&b);
02278
02279 for (const REGION* a_cur=a_iter.First();!a_iter.Is_Empty();a_cur=a_iter.Next())
02280 result->Add_Region(CXX_NEW(REGION(*a_cur),&ARA_memory_pool), ara_info);
02281 for (const REGION* b_cur=b_iter.First();!b_iter.Is_Empty();b_cur=b_iter.Next())
02282 result->Add_Region(CXX_NEW(REGION(*b_cur),&ARA_memory_pool), ara_info);
02283
02284 return result;
02285
02286 }
02287
02288 BOOL
02289 RegionUN_LE(const REGION_UN &a, const REGION_UN &b, const ARA_LOOP_INFO &ara_info)
02290 {
02291
02292 return ((REGION_UN &) b).Is_Included(a, ara_info);
02293
02294 }
02295
02296 BOOL
02297 RegionUN_EQ(const REGION_UN &a, const REGION_UN &b, const ARA_LOOP_INFO &ara_info)
02298 {
02299
02300 return (RegionUN_LE(a,b,ara_info) && RegionUN_LE(b,a,ara_info));
02301
02302 }
02303
02304 REGION_UN &
02305 REGION_UN::RegionUN_Projection(const INT depth, ARA_LOOP_INFO &ara_info)
02306 {
02307
02308 MEM_POOL_Push(&LNO_local_pool);
02309 {
02310 REGION_UN *tmp = CXX_NEW(REGION_UN(),&LNO_local_pool);
02311 REGION *cur;
02312 while (!Is_Empty()) {
02313 cur = Remove_Headnode();
02314 cur->Region_Projection(depth, ara_info);
02315 tmp->Append(cur);
02316 }
02317
02318 while (!tmp->Is_Empty()) {
02319 cur = tmp->Remove_Headnode();
02320 Add_Region(cur, ara_info);
02321 }
02322 }
02323 MEM_POOL_Pop(&LNO_local_pool);
02324
02325 return *this;
02326
02327 }
02328
02329 BOOL
02330 REGION::Is_Loop_Invariant(WN *loop)
02331 {
02332 if (WN_operator(loop) != OPR_DO_LOOP) return FALSE;
02333 INT loopno = Do_Loop_Depth(loop);
02334
02335 if ( _type != ARA_NORMAL ) return TRUE;
02336 for (INT i = 0; i < Num_Dim(); i++) {
02337 AXLE_NODE &ax = Dim(i);
02338 if (ax.lo) {
02339 ACCESS_VECTOR *av = ax.lo->Access_Vector();
02340 if (av->Non_Const_Loops() > loopno) return FALSE;
02341 for (INT j = 0; j <= loopno; ++j) {
02342 if (av->Loop_Coeff(j) != 0) return FALSE;
02343 }
02344 }
02345 if (ax.up) {
02346 ACCESS_VECTOR *av = ax.up->Access_Vector();
02347 if (av->Non_Const_Loops() > loopno) return FALSE;
02348 for (INT j = 0; j <= loopno; ++j) {
02349 if (av->Loop_Coeff(j) != 0) return FALSE;
02350 }
02351 }
02352 }
02353 return TRUE;
02354 }