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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #define __STDC_LIMIT_MACROS
00075 #include <stdint.h>
00076 #ifdef USE_PCH
00077 #include "lno_pch.h"
00078 #endif // USE_PCH
00079 #pragma hdrstop
00080
00081 const static char *source_file = __FILE__;
00082 const static char *rcs_id = "$Source: be/lno/SCCS/s.dep.cxx $ $Revision: 1.6 $";
00083
00084 #include <sys/types.h>
00085 #include "pu_info.h"
00086 #include "soe.h"
00087 #include "dep.h"
00088 #include "lnoptimizer.h"
00089 #include "lnopt_main.h"
00090 #include "lwn_util.h"
00091 #include "opt_alias_interface.h"
00092 #include "opt_alias_mgr.h"
00093 #include "opt_du.h"
00094 #include "call_info.h"
00095 #include "ipa_lno_util.h"
00096 #ifdef KEY
00097 #include "wn_simp.h"
00098 #endif
00099
00100 void DEPV_ARRAY::Print(FILE *fp) const
00101 {
00102 for (INT i=0; i<_num_vec; i++) {
00103 DEPV_Print(Depv(i),fp,Num_Dim());
00104 }
00105 fprintf(fp,"\n");
00106 }
00107
00108 extern DEPV_ARRAY *
00109 Create_DEPV_ARRAY(mUINT8 num_vec, mUINT8 num_dim, mUINT8 num_unused_dim,
00110 MEM_POOL *pool)
00111 {
00112
00113 DEPV_ARRAY *result = (DEPV_ARRAY *)
00114 MEM_POOL_Alloc(pool,sizeof(DEPV_ARRAY)+
00115 (num_vec*num_dim-1)*sizeof(DEPV));
00116 FmtAssert(num_dim <= 15,
00117 ("num_dim = %d is too large in Create_DEPV_ARRAY",num_dim));
00118 FmtAssert(num_unused_dim <= 15,
00119 ("num_unused_dim = %d is too large in Create_DEPV_ARRAY",num_unused_dim));
00120 result->_num_vec = num_vec;
00121 result->_dim = (num_unused_dim << 4) | num_dim;
00122 return(result);
00123 }
00124
00125 extern DEPV_ARRAY *Create_DEPV_ARRAY(DEPV_LIST *depv_list, MEM_POOL *pool)
00126 {
00127 MEM_POOL_Push(&LNO_local_pool);
00128
00129 UINT8 num_dim = depv_list->Num_Dim();
00130 UINT8 num_unused_dim = depv_list->Num_Unused_Dim();
00131
00132 UINT num_vec = depv_list->Len();
00133 if (num_vec > UINT8_MAX) {
00134
00135 DEPV *tmp = DEPV_Create(&LNO_local_pool,num_dim);
00136 DEPV_ITER iter(depv_list);
00137 DEPV_NODE *node = iter.First();
00138 for (INT j=0; j<num_dim; j++) {
00139 DEPV_Dep(tmp,j) = DEPV_Dep(node->Depv,j);
00140 }
00141 if (iter.Is_Empty()) {
00142 return(NULL);
00143 }
00144
00145 for (INT i=0; !iter.Is_Empty(); node=iter.Next(), i++) {
00146 DEPV *depv = node->Depv;
00147 for (INT j=0; j<num_dim; j++) {
00148 DEPV_Dep(tmp,j) = DEP_UnionDirection(DEPV_Dep(tmp,j),
00149 DEP_Direction(DEPV_Dep(depv,j)));
00150 }
00151 }
00152
00153 DEPV_LIST *new_depvlist = CXX_NEW(DEPV_LIST(num_dim,num_unused_dim,
00154 &LNO_local_pool),&LNO_local_pool);
00155 new_depvlist->Append(tmp,num_unused_dim);
00156
00157
00158
00159
00160
00161
00162
00163 if (depv_list->Is_Lexpos()) {
00164 DEPV_LIST *pos = CXX_NEW(DEPV_LIST(num_dim,num_unused_dim,
00165 &LNO_local_pool),&LNO_local_pool);
00166 DEPV_LIST *neg = CXX_NEW(DEPV_LIST(num_dim,num_unused_dim,
00167 &LNO_local_pool),&LNO_local_pool);
00168 new_depvlist->Lex_Pos_Decompose(&LNO_local_pool,pos,neg,
00169 depv_list->Contains_All_Equals(),0);
00170
00171 depv_list = pos;
00172 } else {
00173 depv_list = new_depvlist;
00174 }
00175 num_vec = depv_list->Len();
00176 FmtAssert(num_vec <= UINT8_MAX,
00177 ("Impossible overflow in Create_DEPV_ARRAY"));
00178 }
00179
00180 DEPV_ITER iter(depv_list);
00181 DEPV_NODE *node = iter.First();
00182 if (iter.Is_Empty()) {
00183 return(NULL);
00184 }
00185
00186
00187 DEPV_ARRAY *result = Create_DEPV_ARRAY(num_vec,num_dim,num_unused_dim,pool);
00188 for (INT i=0; !iter.Is_Empty(); node=iter.Next(), i++) {
00189 DEPV *list_depv = node->Depv;
00190 DEPV *array_depv = result->Depv(i);
00191 for (INT j=0; j<num_dim; j++) {
00192 DEPV_Dep(array_depv,j) = DEPV_Dep(list_depv,j);
00193 }
00194 }
00195 MEM_POOL_Pop(&LNO_local_pool);
00196 return(result);
00197 }
00198
00199 extern DEPV_ARRAY *Create_DEPV_ARRAY(const DEPV_ARRAY *orig, MEM_POOL *pool)
00200 {
00201 UINT8 num_vec = orig->Num_Vec();
00202 UINT8 num_dim = orig->Num_Dim();
00203 UINT8 num_unused_dim = orig->Num_Unused_Dim();
00204 DEPV_ARRAY *result = Create_DEPV_ARRAY(num_vec,num_dim,num_unused_dim,pool);
00205 for (INT i=0; i<num_vec; i++) {
00206 const DEPV *orig_depv = orig->Depv(i);
00207 DEPV *res_depv = result->Depv(i);
00208 for (INT j=0; j<num_dim; j++) {
00209 DEPV_Dep(res_depv,j) = DEPV_Dep(orig_depv,j);
00210 }
00211 }
00212 return(result);
00213 }
00214
00215 extern void Delete_DEPV_ARRAY(DEPV_ARRAY *array, MEM_POOL *pool)
00216 {
00217 MEM_POOL_FREE(pool,array);
00218 }
00219
00220
00221 DEPV *DEPV_ARRAY::Union(MEM_POOL *pool)
00222 {
00223 DEPV *depv = CXX_NEW_ARRAY(DEPV,Num_Dim(),pool);
00224
00225 for (INT j=0; j<Num_Dim(); j++) {
00226 DEPV_Dep(depv,j) = DEPV_Dep(Depv(0),j);
00227 }
00228
00229
00230 for (INT i=1; i<Num_Vec(); i++) {
00231 DEPV *tmp = Depv(i);
00232 for (INT j=0; j<Num_Dim(); j++) {
00233 if (!DEP_IsDistance(DEPV_Dep(tmp,j)) ||
00234 !DEP_IsDistance(DEPV_Dep(depv,j)) ||
00235 DEP_Distance(DEPV_Dep(depv,j)) != DEP_Distance(DEPV_Dep(tmp,j))) {
00236 DEPV_Dep(depv,j) = DEP_UnionDirection(DEPV_Dep(depv,j),
00237 DEP_Direction(DEPV_Dep(tmp,j)));
00238 }
00239 }
00240 }
00241 return depv;
00242 }
00243
00244
00245 DEPV_ARRAY *DEPV_ARRAY::Shorten(UINT num_dim,MEM_POOL *pool)
00246 {
00247 FmtAssert (num_dim > 0, ("number dimensions should be at least 1."));
00248 if (Num_Dim() <= num_dim) {
00249 return Create_DEPV_ARRAY(this,pool);
00250 }
00251 DEPV_ARRAY *da = Create_DEPV_ARRAY(Num_Vec(),num_dim,Num_Unused_Dim(),pool);
00252 for (INT i=0; i<Num_Vec(); i++) {
00253 DEPV *oldd = Depv(i);
00254 DEPV *newd = da->Depv(i);
00255 for (INT j=0; j<num_dim; j++) {
00256 DEPV_Dep(newd,j) = DEPV_Dep(oldd,j);
00257 }
00258 }
00259 return da;
00260 }
00261
00262
00263
00264 DEP *DEPV_ARRAY::Shorten_To_Dep(MEM_POOL *pool)
00265 {
00266 DEP *dep = NULL;
00267 for (INT i=0; i<Num_Vec(); i++) {
00268 DEPV *depv = Depv(i);
00269 BOOL good_vector = TRUE;
00270 for (INT j=0; j<Num_Dim()-1 && good_vector; j++) {
00271 DIRECTION dir = DEP_Direction(DEPV_Dep(depv,j));
00272 if ((dir != DIR_EQ) && (dir != DIR_POSEQ) && (dir != DIR_NEGEQ) &&
00273 (dir != DIR_STAR)) {
00274 good_vector = FALSE;
00275 }
00276 }
00277 if (good_vector) {
00278 if (!dep) {
00279 dep = CXX_NEW(DEP,pool);
00280 *dep = DEPV_Dep(depv,Num_Dim()-1);
00281 } else {
00282 DEP tmp = DEPV_Dep(depv,Num_Dim()-1);
00283 if (DEP_IsDistance(tmp)) {
00284 if (!DEP_IsDistance(*dep) ||
00285 (DEP_Distance(*dep) != DEP_Distance(tmp))) {
00286 *dep = DEP_UnionDirection(*dep,DEP_Direction(tmp));
00287 }
00288 } else {
00289 *dep = DEP_UnionDirection(*dep,DEP_Direction(tmp));
00290 }
00291 }
00292 }
00293 }
00294 return(dep);
00295 }
00296
00297 INT DEPV_ARRAY::Max_Level() const
00298 {
00299 INT result=0;
00300 INT num_dim = Num_Dim();
00301 for (INT i=0; i<Num_Vec(); i++) {
00302 const DEPV *depv = Depv(i);
00303 INT j=0;
00304 while (j<num_dim && ((DEP_Direction(DEPV_Dep(depv,j))==DIR_EQ) ||
00305 (DEP_Direction(DEPV_Dep(depv,j))==DIR_POSEQ) ||
00306 (DEP_Direction(DEPV_Dep(depv,j))==DIR_NEGEQ) ||
00307 (DEP_Direction(DEPV_Dep(depv,j))==DIR_STAR))) {
00308 j++;
00309 }
00310 INT current_level = j + Num_Unused_Dim();
00311 if (current_level > result) {
00312 result = current_level;
00313 }
00314 }
00315 return result;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 BOOL DEPV_ARRAY::Equal_Through_Depth (INT depth) {
00325 INT num_dim = Num_Dim();
00326 INT num_unused = Num_Unused_Dim();
00327 for (INT i=0; i<Num_Vec(); i++) {
00328 DEPV *depv = Depv(i);
00329 for (INT j=num_unused; j<=depth; j++) {
00330 if (DEP_Direction(DEPV_Dep(depv,j-num_unused)) != DIR_EQ) return FALSE;
00331 }
00332 }
00333 return TRUE;
00334 }
00335
00336 BOOL DEPV_ARRAY::One_Equal_Through_Depth (INT depth) {
00337 INT num_dim = Num_Dim();
00338 INT num_unused = Num_Unused_Dim();
00339 for (INT i=0; i<Num_Vec(); i++) {
00340 DEPV *depv = Depv(i);
00341 INT j;
00342 for (j=num_unused; j<=depth; j++) {
00343 DIRECTION dir = DEP_Direction(DEPV_Dep(depv, j-num_unused));
00344 if (dir == DIR_POS || dir == DIR_NEG || dir == DIR_POSNEG)
00345 break;
00346 }
00347 if (j > depth)
00348 return TRUE;
00349 }
00350 return FALSE;
00351 }
00352
00353 BOOL DEPV_ARRAY::Loop_Carrying_Dependence() {
00354 INT num_dim = Num_Dim();
00355 INT num_unused = Num_Unused_Dim();
00356 INT result = -1;
00357 for (INT i=0; i<Num_Vec(); i++) {
00358 DEPV *depv = Depv(i);
00359 INT j;
00360 for (j=num_unused; j<num_unused+num_dim; j++) {
00361 DIRECTION dir = DEP_Direction(DEPV_Dep(depv, j-num_unused));
00362 if (dir == DIR_POS)
00363 break;
00364 }
00365 if (j == num_unused+num_dim)
00366 continue;
00367 if (j > result)
00368 result = j;
00369 }
00370 return result;
00371 }
00372
00373 BOOL DEPV_ARRAY::Is_Blockable(INT start_depth,
00374 INT stop_depth)
00375 {
00376 INT num_dim = Num_Dim();
00377 INT num_unused = Num_Unused_Dim();
00378 for (INT i = 0; i < Num_Vec(); i++) {
00379 for (INT j = num_unused; j <= stop_depth; j++) {
00380 DIRECTION dir = DEP_Direction(DEPV_Dep(Depv(i), j - num_unused));
00381 if (j < start_depth && dir == DIR_POS)
00382 return TRUE;
00383 if (j >= start_depth && (dir == DIR_NEG || dir == DIR_POSNEG
00384 || dir == DIR_NEGEQ || dir == DIR_STAR))
00385 return FALSE;
00386 }
00387 }
00388 return TRUE;
00389 }
00390
00391 void DEPV_NODE::Print(FILE *fp, mUINT8 num_dim) const
00392 {
00393 DEPV_Print(Depv,fp,num_dim);
00394 }
00395
00396 BOOL DEPV_NODE::Equal(DEPV_NODE *node2, mUINT8 num_dim)
00397 {
00398 DEPV *d1 = Depv;
00399 DEPV *d2 = node2->Depv;
00400 for (INT i=0; i<num_dim; i++) {
00401 if (d1[i] != d2[i]) {
00402 return FALSE;
00403 }
00404 }
00405 return TRUE;
00406 }
00407
00408
00409
00410 DEPV_LIST::DEPV_LIST(WN *ref1, WN *ref2, mUINT8 common_nest, mUINT8 dv_dim,
00411 BOOL use_bounds, MEM_POOL *pool, const DOLOOP_STACK *s1,
00412 const DOLOOP_STACK *s2)
00413 {
00414 DEPV_COMPUTE compute;
00415 _pool = pool;
00416 _dv_dim = dv_dim;
00417 _num_unused_dim = common_nest-dv_dim;
00418 OPCODE opc1 = WN_opcode(ref1);
00419 OPCODE opc2 = WN_opcode(ref2);
00420 if (OPCODE_is_call(opc1) && Get_Call_Info(ref1) != NULL)
00421 Get_Call_Info(ref1)->Evaluate();
00422 if (ref1 != ref2 && OPCODE_is_call(opc2) && Get_Call_Info(ref2) != NULL)
00423 Get_Call_Info(ref2)->Evaluate();
00424 if (OPCODE_is_call(opc1)) {
00425 if (OPCODE_is_call(opc2)) {
00426 ARA_LOOP_INFO *ali1 = Get_Call_Info(ref1)->Call_Ara_Info();
00427 ARA_REF_ST &writes1 = ali1->MAY_DEF();
00428 INT i;
00429 for (i=0; i<writes1.Elements(); i++) {
00430 ARA_REF *write1 = writes1.Bottom_nth(i);
00431 ARA_LOOP_INFO *ali2 = Get_Call_Info(ref2)->Call_Ara_Info();
00432
00433 ARA_REF_ST &writes2 = ali2->MAY_DEF();
00434 INT j;
00435 for (j=0; j<writes2.Elements(); j++) {
00436 ARA_REF *write2 = writes2.Bottom_nth(j);
00437 compute.Compute(this,ref1,write1,ref2,write2,common_nest,dv_dim,use_bounds,pool,s1,s2);
00438 }
00439
00440 ARA_REF_ST &reads2 = ali2->USE();
00441 for (j=0; j<reads2.Elements(); j++) {
00442 ARA_REF *read2 = reads2.Bottom_nth(j);
00443 compute.Compute(this,ref1,write1,ref2,read2,common_nest,dv_dim,use_bounds,pool,s1,s2);
00444 }
00445 }
00446
00447 ARA_REF_ST &reads1 = ali1->USE();
00448 for (i=0; i<reads1.Elements(); i++) {
00449 ARA_REF *read1 = reads1.Bottom_nth(i);
00450 ARA_LOOP_INFO *ali2 = Get_Call_Info(ref2)->Call_Ara_Info();
00451
00452 ARA_REF_ST &writes2 = ali2->MAY_DEF();
00453 for (INT j=0; j<writes2.Elements(); j++) {
00454 ARA_REF *write2 = writes2.Bottom_nth(j);
00455 compute.Compute(this,ref1,read1,ref2,write2,common_nest,dv_dim,use_bounds,pool,s1,s2);
00456 }
00457 }
00458 } else {
00459 ARA_LOOP_INFO *ali = Get_Call_Info(ref1)->Call_Ara_Info();
00460 ARA_REF_ST &writes = ali->MAY_DEF();
00461 for (INT i=0; i<writes.Elements(); i++) {
00462 ARA_REF *write = writes.Bottom_nth(i);
00463 compute.Compute(this,ref1,write,ref2,NULL,common_nest,dv_dim,use_bounds,pool,s1,s2);
00464 }
00465 if (OPCODE_is_store(opc2)) {
00466 ARA_REF_ST &reads = ali->USE();
00467 for (INT i=0; i<reads.Elements(); i++) {
00468 ARA_REF *read = reads.Bottom_nth(i);
00469 compute.Compute(this,ref1,read,ref2,NULL,common_nest,dv_dim,use_bounds,pool,s1,s2);
00470 }
00471 }
00472 }
00473 Remove_Duplicates();
00474 } else if (OPCODE_is_call(opc2)) {
00475 ARA_LOOP_INFO *ali = Get_Call_Info(ref2)->Call_Ara_Info();
00476 ARA_REF_ST &writes = ali->MAY_DEF();
00477 for (INT i=0; i<writes.Elements(); i++) {
00478 ARA_REF *write = writes.Bottom_nth(i);
00479 compute.Compute(this,ref1,NULL,ref2,write,common_nest,dv_dim,use_bounds,pool,s1,s2);
00480 }
00481 if (OPCODE_is_store(opc1)) {
00482 ARA_REF_ST &reads = ali->USE();
00483 for (INT i=0; i<reads.Elements(); i++) {
00484 ARA_REF *read = reads.Bottom_nth(i);
00485 compute.Compute(this,ref1,NULL,ref2,read,common_nest,dv_dim,use_bounds,pool,s1,s2);
00486 }
00487 }
00488 Remove_Duplicates();
00489 } else {
00490 compute.Compute(this,ref1,NULL,ref2,NULL,common_nest,dv_dim,use_bounds,pool,s1,s2);
00491 }
00492 if (OPCODE_is_call(opc1) && Get_Call_Info(ref1) != NULL)
00493 Get_Call_Info(ref1)->Unevaluate();
00494 if (ref1 != ref2 && OPCODE_is_call(opc2) && Get_Call_Info(ref2) != NULL)
00495 Get_Call_Info(ref2)->Unevaluate();
00496 }
00497
00498
00499
00500
00501 void DEPV_LIST::Print(FILE *fp) const
00502 {
00503 DEPV_CONST_ITER iter(this);
00504 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
00505 node=iter.Next()) {
00506 node->Print(fp,Num_Dim());
00507 }
00508 }
00509
00510
00511 void DEPV_LIST::Remove_Duplicates()
00512 {
00513 mUINT8 num_dim = Num_Dim();
00514 DEPV_ITER iter(this);
00515 for (DEPV_NODE *node=iter.First(); node; node = iter.Next()) {
00516
00517 DEPV_ITER iter2(node);
00518 DEPV_NODE *first = iter2.First();
00519 first = iter2.Next();
00520 DEPV_NODE *prev_node = node;
00521 DEPV_NODE *next_node = NULL;
00522 for (DEPV_NODE *node2=first; node2; node2 = next_node) {
00523 next_node = iter2.Next();
00524 if (node->Equal(node2,num_dim)) {
00525 MEM_POOL_Set_Default(_pool);
00526 CXX_DELETE(Remove(prev_node,node2),_pool);
00527 } else {
00528 prev_node = node2;
00529 }
00530 }
00531 }
00532 }
00533
00534
00535 DEPV_LIST::DEPV_LIST(DEPV_ARRAY *array, MEM_POOL *pool)
00536 {
00537 _dv_dim = array->Num_Dim();
00538 _num_unused_dim = array->Num_Unused_Dim();
00539 _pool = pool;
00540 for (INT i=0; i<array->Num_Vec(); i++) {
00541 Append(CXX_NEW(DEPV_NODE(
00542 DEPV_Copy(pool,array->Depv(i),array->Num_Dim())),pool));
00543 }
00544 }
00545
00546
00547
00548 void DEPV_LIST::Append(DEPV *depv, INT num_bad_outer)
00549 {
00550 if (!num_bad_outer) {
00551 if (depv) {
00552 Append(CXX_NEW(DEPV_NODE(DEPV_Copy(_pool,depv,_dv_dim)), _pool));
00553 }
00554 return;
00555 }
00556
00557 for (INT i=0; i<num_bad_outer; i++) {
00558 DEPV *pos = DEPV_Create(_pool,_dv_dim);
00559 DEPV *neg = DEPV_Create(_pool,_dv_dim);
00560 INT j;
00561 for (j=0; j<i; j++) {
00562 DEPV_Dep(pos,j) = DEP_SetDirection(DIR_STAR);
00563 DEPV_Dep(neg,j) = DEP_SetDirection(DIR_STAR);
00564 }
00565 DEPV_Dep(pos,i) = DEP_SetDirection(DIR_POS);
00566 DEPV_Dep(neg,i) = DEP_SetDirection(DIR_NEG);
00567 for (j=i+1; j<_dv_dim; j++) {
00568 DEPV_Dep(pos,j) = DEP_SetDirection(DIR_STAR);
00569 DEPV_Dep(neg,j) = DEP_SetDirection(DIR_STAR);
00570 }
00571 Append(CXX_NEW(DEPV_NODE(pos),_pool));
00572 Append(CXX_NEW(DEPV_NODE(neg),_pool));
00573 }
00574 if (depv) {
00575 DEPV *eq = DEPV_Create(_pool,_dv_dim);
00576 INT j;
00577 for (j=0; j<num_bad_outer; j++) {
00578 DEPV_Dep(eq,j) = DEP_SetDirection(DIR_EQ);
00579 }
00580 for (j=num_bad_outer; j<_dv_dim; j++) {
00581 DEPV_Dep(eq,j) = DEPV_Dep(depv,j-num_bad_outer);
00582 }
00583 Append(CXX_NEW(DEPV_NODE(eq),_pool));
00584 }
00585 }
00586
00587 void DEPV_LIST::Normalize_Step(INT64 *step)
00588 {
00589 BOOL is_indep;
00590 for (INT i=0; i<Num_Dim(); i++) {
00591 if (step[i] != 1) {
00592 DEPV_ITER iter(this);
00593 DEPV_NODE *next_node=NULL;
00594 DEPV_NODE *prev_node = NULL;
00595 for (DEPV_NODE *node = iter.First(); node; node=next_node) {
00596 next_node = iter.Next();
00597 node->Normalize_Step(i,step[i],&is_indep);
00598 if (is_indep) {
00599 MEM_POOL_Set_Default(_pool);
00600 CXX_DELETE(Remove(prev_node,node),_pool);
00601 } else {
00602 prev_node = node;
00603 }
00604 }
00605 }
00606 }
00607 }
00608
00609 void DEPV_NODE::Normalize_Step(INT dim, INT64 step, BOOL *is_indep)
00610 {
00611 *is_indep = FALSE;
00612
00613 if (step == 0) {
00614
00615
00616 DIRECTION dir = DEP_Direction(DEPV_Dep(Depv,dim));
00617 if ((dir == DIR_POS) || (dir == DIR_NEG) || (dir == DIR_POSNEG)){
00618 DEPV_Dep(Depv,dim) = DEP_SetDirection(DIR_POSNEG);
00619 } else if ((dir == DIR_POSEQ) || (dir == DIR_NEGEQ) || (dir == DIR_STAR)) {
00620 DEPV_Dep(Depv,dim) = DEP_SetDirection(DIR_STAR);
00621 } else {
00622 ;
00623 }
00624 return;
00625 }
00626
00627 if (DEP_IsDistance(DEPV_Dep(Depv,dim))) {
00628 INT dist = DEP_Distance(DEPV_Dep(Depv,dim));
00629 if ((dist % step) != 0) {
00630
00631 DIRECTION dir = DEP_Direction(DEPV_Dep(Depv,dim));
00632 if ((dir == DIR_POS) || (dir == DIR_NEG) || (dir == DIR_POSNEG)){
00633 DEPV_Dep(Depv,dim) = DEP_SetDirection(DIR_POSNEG);
00634 } else if ((dir == DIR_POSEQ) || (dir == DIR_NEGEQ) ||
00635 (dir == DIR_STAR)) {
00636 DEPV_Dep(Depv,dim) = DEP_SetDirection(DIR_STAR);
00637 } else {
00638 ;
00639 }
00640 return;
00641 } else {
00642 DEPV_Dep(Depv,dim) = DEP_SetDistance(dist / step);
00643 }
00644 } else if (step > 0) {
00645 return;
00646 } else {
00647 DEPV_Dep(Depv,dim) = DEP_Negate(DEPV_Dep(Depv,dim));
00648 }
00649 }
00650
00651 static INT Max_Level(DEPV_LIST *dl)
00652 {
00653 INT result=0;
00654 INT num_dim = dl->Num_Dim();
00655 DEPV_CONST_ITER iter(dl);
00656 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
00657 node=iter.Next()) {
00658 const DEPV *depv = node->Depv;
00659 INT j=0;
00660 while (j<num_dim && ((DEP_Direction(DEPV_Dep(depv,j))==DIR_EQ) ||
00661 (DEP_Direction(DEPV_Dep(depv,j))==DIR_POSEQ) ||
00662 (DEP_Direction(DEPV_Dep(depv,j))==DIR_NEGEQ) ||
00663 (DEP_Direction(DEPV_Dep(depv,j))==DIR_STAR))) {
00664 j++;
00665 }
00666 INT current_level = j + dl->Num_Unused_Dim();
00667 if (current_level > result) {
00668 result = current_level;
00669 }
00670 }
00671 return result;
00672 }
00673
00674
00675
00676 BOOL DEPV_LIST::Is_Inner_Single_Distance()
00677 {
00678 if (Max_Level(this) < Num_Dim()-1) return FALSE;
00679 BOOL seen_distance = FALSE;
00680 INT dist;
00681 DEPV_CONST_ITER iter(this);
00682 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
00683 node=iter.Next()) {
00684 DEP dep = DEPV_Dep(node->Depv,Num_Dim()-1);
00685 if (!DEP_IsDistance(dep)) {
00686 return FALSE;
00687 } else {
00688 if (seen_distance) {
00689 if (DEP_Distance(dep) != dist) {
00690 return FALSE;
00691 }
00692 } else {
00693 dist = DEP_Distance(dep);
00694 seen_distance = TRUE;
00695 }
00696 }
00697 }
00698 return seen_distance;
00699 }
00700
00701 BOOL DEPV_LIST::Is_Inner_Non_Zero_Single_Distance()
00702 {
00703 if (Max_Level(this) < Num_Dim()-1) return FALSE;
00704 BOOL seen_distance = FALSE;
00705 INT dist;
00706 DEPV_CONST_ITER iter(this);
00707 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
00708 node=iter.Next()) {
00709 DEP dep = DEPV_Dep(node->Depv,Num_Dim()-1);
00710 if (!DEP_IsDistance(dep) || (DEP_Distance(dep) == 0)) {
00711 return FALSE;
00712 } else {
00713 if (seen_distance) {
00714 if (DEP_Distance(dep) != dist) {
00715 return FALSE;
00716 }
00717 } else {
00718 dist = DEP_Distance(dep);
00719 seen_distance = TRUE;
00720 }
00721 }
00722 }
00723 return seen_distance;
00724 }
00725
00726
00727
00728 void DEPV_LIST::Eliminate_Inner_Carried()
00729 {
00730 DEPV_ITER iter(this);
00731 DEPV_NODE *next_node=NULL;
00732 DEPV_NODE *prev_node = NULL;
00733 for (DEPV_NODE *node = iter.First(); node; node=next_node) {
00734 next_node = iter.Next();
00735 BOOL done = FALSE;
00736 INT i;
00737 for (i=0; !done && i<Num_Dim()-1; i++) {
00738 DIRECTION dir = DEP_Direction(DEPV_Dep(node->Depv,i));
00739 if (dir != DIR_EQ) {
00740 done = TRUE;
00741 }
00742 }
00743 if (!done) {
00744 DIRECTION dir = DEP_Direction(DEPV_Dep(node->Depv,Num_Dim()-1));
00745 if ((dir == DIR_POS) || (dir == DIR_NEG) ||
00746 (dir == DIR_POSNEG)) {
00747 MEM_POOL_Set_Default(_pool);
00748 CXX_DELETE(Remove(prev_node,node),_pool);
00749 } else {
00750 DEPV_Dep(node->Depv,i) = DEP_SetDistance(0);
00751 prev_node = node;
00752 }
00753 } else {
00754 prev_node = node;
00755 }
00756 }
00757 }
00758
00759
00760
00761 void DEPV_LIST::Eliminate_Inner_Carried_Or_All_Equals()
00762 {
00763 DEPV_ITER iter(this);
00764 DEPV_NODE *next_node=NULL;
00765 DEPV_NODE *prev_node = NULL;
00766 for (DEPV_NODE *node = iter.First(); node; node=next_node) {
00767 next_node = iter.Next();
00768 BOOL done = FALSE;
00769 for (INT i=0; !done && i<Num_Dim()-1; i++) {
00770 DIRECTION dir = DEP_Direction(DEPV_Dep(node->Depv,i));
00771 if (dir != DIR_EQ) {
00772 done = TRUE;
00773 }
00774 }
00775 if (!done) {
00776 MEM_POOL_Set_Default(_pool);
00777 CXX_DELETE(Remove(prev_node,node),_pool);
00778 } else {
00779 prev_node = node;
00780 }
00781 }
00782 }
00783
00784
00785 void DEPV_LIST::Eliminate_Non_Distance_Carried_By(INT i)
00786 {
00787
00788 DEPV_ITER iter(this);
00789 DEPV_NODE* node = 0;
00790 for (node = iter.First(); node; node=iter.Next()) {
00791 for (INT j=0; j<=i; j++) {
00792 DIRECTION dir = DEP_Direction(DEPV_Dep(node->Depv,j));
00793 if (dir == DIR_POSEQ) {
00794 DEPV *new_depv = DEPV_Copy(_pool,node->Depv,_dv_dim);
00795 DEPV_Dep(new_depv,j) = DEP_SetDirection(DIR_EQ);
00796 DEPV_Dep(node->Depv,j) = DEP_SetDirection(DIR_POS);
00797 Append(CXX_NEW(DEPV_NODE(new_depv),_pool));
00798 } else if (dir == DIR_NEGEQ) {
00799 DEPV *new_depv = DEPV_Copy(_pool,node->Depv,_dv_dim);
00800 DEPV_Dep(new_depv,j) = DEP_SetDirection(DIR_EQ);
00801 DEPV_Dep(node->Depv,j) = DEP_SetDirection(DIR_NEG);
00802 Append(CXX_NEW(DEPV_NODE(new_depv),_pool));
00803 } else if (dir == DIR_POSNEG) {
00804 DEPV *new_depv = DEPV_Copy(_pool,node->Depv,_dv_dim);
00805 DEPV_Dep(new_depv,j) = DEP_SetDirection(DIR_POS);
00806 DEPV_Dep(node->Depv,j) = DEP_SetDirection(DIR_NEG);
00807 Append(CXX_NEW(DEPV_NODE(new_depv),_pool));
00808 } else if (dir == DIR_STAR) {
00809 DEPV *new_depv = DEPV_Copy(_pool,node->Depv,_dv_dim);
00810 DEPV *new_depv2 = DEPV_Copy(_pool,node->Depv,_dv_dim);
00811 DEPV_Dep(new_depv,j) = DEP_SetDirection(DIR_POS);
00812 DEPV_Dep(new_depv2,j) = DEP_SetDirection(DIR_EQ);
00813 DEPV_Dep(node->Depv,j) = DEP_SetDirection(DIR_NEG);
00814 Append(CXX_NEW(DEPV_NODE(new_depv),_pool));
00815 Append(CXX_NEW(DEPV_NODE(new_depv2),_pool));
00816 }
00817 }
00818 }
00819
00820
00821 DEPV_ITER iter2(this);
00822 DEPV_NODE *next_node=NULL;
00823 DEPV_NODE *prev_node = NULL;
00824 for (node = iter2.First(); node; node=next_node) {
00825 next_node = iter2.Next();
00826 BOOL carried_earlier = FALSE;
00827 for (INT j=0; j<i && !carried_earlier; j++) {
00828 DIRECTION dir = DEP_Direction(DEPV_Dep(node->Depv,j));
00829 if (dir != DIR_EQ) {
00830 carried_earlier = TRUE;
00831 }
00832 }
00833 DEP dep = DEPV_Dep(node->Depv,i);
00834 if (!carried_earlier && !DEP_IsDistance(dep) &&
00835 (DEP_Direction(dep) != DIR_EQ)) {
00836 MEM_POOL_Set_Default(_pool);
00837 CXX_DELETE(Remove(prev_node,node),_pool);
00838 } else {
00839 prev_node = node;
00840 }
00841 }
00842 }
00843
00844
00845
00846
00847
00848 DEPV_LIST::~DEPV_LIST()
00849 {
00850 MEM_POOL_Set_Default(_pool);
00851 while (!Is_Empty()) CXX_DELETE(Remove_Headnode(),Default_Mem_Pool);
00852 }
00853
00854
00855 void DEPV_LIST::Lex_Pos_Decompose(MEM_POOL *pool, DEPV_LIST *pos,
00856 DEPV_LIST *neg, BOOL keep_pos_equals, BOOL keep_neg_equals)
00857 {
00858 Is_True(pos->Num_Dim() == Num_Dim(),
00859 ("Bad pos in DEPV_LIST::Lex_Pos_Decompose"));
00860 Is_True(neg->Num_Dim() == Num_Dim(),
00861 ("Bad neg in DEPV_LIST::Lex_Neg_Decompose"));
00862 DEPV_ITER iter(this);
00863 for (DEPV_NODE *node = iter.First(); !iter.Is_Empty();
00864 node=iter.Next()) {
00865 node->Lex_Pos_Decompose(pool,pos,neg,_dv_dim,0,keep_pos_equals,
00866 keep_neg_equals);
00867 }
00868 }
00869
00870 void DEPV_LIST::Blockable_Part(MEM_POOL *pool,
00871 DEPV_LIST* dl_block,
00872 mUINT8 num_unused_dim,
00873 mUINT8 dv_dim,
00874 INT start_depth,
00875 INT stop_depth)
00876 {
00877 DEPV_ITER iter(this);
00878 DEPV_NODE* node = NULL;
00879 for (node = iter.First(); !iter.Is_Empty(); node=iter.Next())
00880 node->Blockable_Part(pool, dl_block, num_unused_dim, dv_dim,
00881 start_depth, stop_depth);
00882 }
00883
00884
00885 DEP DEPV_LIST::Convert_To_Dep()
00886 {
00887 Is_True(Num_Dim() == 1,
00888 ("Num_Dim() is not 1 in DEPV_LIST::Convert_To_Dep"));
00889 DEPV_ITER iter(this);
00890 DEPV_NODE *node = iter.First();
00891 DEP dep = DEPV_Dep(node->Depv,0);
00892 for (node = iter.Next(); !iter.Is_Empty(); node=iter.Next()) {
00893 DEP tmp = DEPV_Dep(node->Depv,0);
00894 if (DEP_IsDistance(tmp)) {
00895 if (!DEP_IsDistance(dep) || (DEP_Distance(dep) != DEP_Distance(tmp))) {
00896 dep = DEP_UnionDirection(dep,DEP_Direction(tmp));
00897 }
00898 } else {
00899 dep = DEP_UnionDirection(dep,DEP_Direction(tmp));
00900 }
00901 }
00902 return(dep);
00903 }
00904
00905 void DEPV_NODE::Blockable_Part(MEM_POOL* pool,
00906 DEPV_LIST* dl_block,
00907 mUINT8 num_unused_dim,
00908 mUINT8 dv_dim,
00909 INT start_depth,
00910 INT stop_depth)
00911 {
00912 if (start_depth > stop_depth) {
00913 DEPV_NODE* dvn = CXX_NEW(DEPV_NODE(DEPV_Copy(pool, Depv, dv_dim)), pool);
00914 dl_block->Append(dvn);
00915 return;
00916 }
00917 INT start_dim = start_depth - num_unused_dim;
00918 DEP orig = DEPV_Dep(Depv, start_dim);
00919 switch (DEP_Direction(DEPV_Dep(Depv, start_dim))) {
00920 case DIR_POS:
00921 case DIR_POSEQ:
00922 case DIR_EQ:
00923 Blockable_Part(pool, dl_block, num_unused_dim, dv_dim, start_depth + 1,
00924 stop_depth);
00925 break;
00926 case DIR_POSNEG:
00927 DEPV_Dep(Depv, start_dim) = DEP_SetDirection(DIR_POS);
00928 Blockable_Part(pool, dl_block, num_unused_dim, dv_dim, start_depth + 1,
00929 stop_depth);
00930 break;
00931 case DIR_NEGEQ:
00932 DEPV_Dep(Depv, start_dim) = DEP_SetDirection(DIR_EQ);
00933 Blockable_Part(pool, dl_block, num_unused_dim, dv_dim, start_depth + 1,
00934 stop_depth);
00935 break;
00936 case DIR_STAR:
00937 DEPV_Dep(Depv, start_dim) = DEP_SetDirection(DIR_POS);
00938 Blockable_Part(pool, dl_block, num_unused_dim, dv_dim, start_depth + 1,
00939 stop_depth);
00940 DEPV_Dep(Depv, start_dim) = DEP_SetDirection(DIR_EQ);
00941 Blockable_Part(pool, dl_block, num_unused_dim, dv_dim, start_depth + 1,
00942 stop_depth);
00943 break;
00944 }
00945 DEPV_Dep(Depv, start_dim) = orig;
00946 }
00947
00948
00949
00950 void DEPV_NODE::Lex_Pos_Decompose(MEM_POOL *pool, DEPV_LIST *pos,
00951 DEPV_LIST *neg, mUINT8 dv_dim,INT first_dim, BOOL keep_pos_equals,
00952 BOOL keep_neg_equals)
00953 {
00954 if (first_dim == dv_dim) {
00955 if (keep_pos_equals) {
00956 pos->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
00957 }
00958 if (keep_neg_equals) {
00959 neg->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
00960 }
00961 return;
00962 }
00963
00964 DEP orig = DEPV_Dep(Depv,first_dim);
00965 if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_POS) {
00966
00967 pos->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
00968
00969 } else if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_NEG) {
00970
00971 DEPV_NODE *n = CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool);
00972 for (INT i=first_dim; i<dv_dim; i++) {
00973 DEPV_Dep(n->Depv,i) = DEP_Negate(DEPV_Dep(Depv,i));
00974 }
00975 neg->Append(n);
00976
00977 } else if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_POSNEG) {
00978
00979 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_POS);
00980 pos->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
00981
00982 DEPV_NODE *n = CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool);
00983 DEPV_Dep(n->Depv,first_dim) = DEP_SetDirection(DIR_POS);
00984 for (INT i=first_dim+1; i<dv_dim; i++) {
00985 DEPV_Dep(n->Depv,i) = DEP_Negate(DEPV_Dep(Depv,i));
00986 }
00987 neg->Append(n);
00988
00989 } else if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_POSEQ) {
00990
00991 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_POS);
00992 pos->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
00993 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_EQ);
00994 Lex_Pos_Decompose(pool,pos,neg,dv_dim,first_dim+1,keep_pos_equals,
00995 keep_neg_equals);
00996
00997 } else if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_NEGEQ) {
00998
00999 DEPV_NODE *n = CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool);
01000 DEPV_Dep(n->Depv,first_dim) = DEP_SetDirection(DIR_POS);
01001 for (INT i=first_dim+1; i<dv_dim; i++) {
01002 DEPV_Dep(n->Depv,i) = DEP_Negate(DEPV_Dep(Depv,i));
01003 }
01004 neg->Append(n);
01005
01006 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_EQ);
01007 Lex_Pos_Decompose(pool,pos,neg,dv_dim,first_dim+1,keep_pos_equals,
01008 keep_neg_equals);
01009
01010 } else if (DEP_Direction(DEPV_Dep(Depv,first_dim)) == DIR_STAR) {
01011
01012 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_POS);
01013 pos->Append(CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool));
01014
01015 DEPV_NODE *n = CXX_NEW(DEPV_NODE(DEPV_Copy(pool,Depv,dv_dim)),pool);
01016 for (INT i=first_dim+1; i<dv_dim; i++) {
01017 DEPV_Dep(n->Depv,i) = DEP_Negate(DEPV_Dep(Depv,i));
01018 }
01019 neg->Append(n);
01020
01021 DEPV_Dep(Depv,first_dim) = DEP_SetDirection(DIR_EQ);
01022 Lex_Pos_Decompose(pool,pos,neg,dv_dim,first_dim+1,keep_pos_equals,
01023 keep_neg_equals);
01024
01025 } else {
01026 Lex_Pos_Decompose(pool,pos,neg,dv_dim,first_dim+1,keep_pos_equals,
01027 keep_neg_equals);
01028 }
01029 DEPV_Dep(Depv,first_dim)=orig;
01030 }
01031
01032
01033
01034 extern DEPV_LIST *Lex_Pos_Compose(MEM_POOL *pool,DEPV_LIST *pos,DEPV_LIST *neg)
01035 {
01036 DEPV_LIST *result=CXX_NEW(DEPV_LIST(pos->Num_Dim(),pos->Num_Unused_Dim(),
01037 pool), pool);
01038 while (!pos->Is_Empty()) {
01039 DEPV_NODE *node = pos->Remove_Headnode();
01040 result->Append(node);
01041 }
01042 while (!neg->Is_Empty()) {
01043 DEPV_NODE *node = neg->Remove_Headnode();
01044 for (INT i=0; i<neg->Num_Dim(); i++) {
01045 DEPV_Dep(node->Depv,i) = DEP_Negate(DEPV_Dep(node->Depv,i));
01046 }
01047 result->Append(node);
01048 }
01049 return result;
01050 }
01051
01052 BOOL Is_Lexpos(DEPV* dv, INT dims)
01053 {
01054 for (INT i = 0; i < dims; i++) {
01055 switch (DEP_Direction(DEPV_Dep(dv,i))) {
01056 case DIR_EQ:
01057 case DIR_POSEQ:
01058 continue;
01059 case DIR_POS:
01060 return TRUE;
01061 case DIR_NEG:
01062 case DIR_NEGEQ:
01063 case DIR_POSNEG:
01064 case DIR_STAR:
01065 return FALSE;
01066 }
01067 }
01068 return TRUE;
01069 }
01070
01071 BOOL DEPV_LIST::Is_Lexpos() const
01072 {
01073 DEPV_CONST_ITER iter(this);
01074 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
01075 node=iter.Next()) {
01076 if (!::Is_Lexpos(node->Depv,_dv_dim)) {
01077 return FALSE;
01078 }
01079 }
01080 return TRUE;
01081 }
01082
01083 BOOL DEPV_LIST::Contains_All_Equals() const
01084 {
01085 DEPV_CONST_ITER iter(this);
01086 for (const DEPV_NODE *node = iter.First(); !iter.Is_Empty();
01087 node=iter.Next()) {
01088 DEPV *depv = node->Depv;
01089 BOOL found_non_eq = FALSE;
01090 for (INT i=0; i<_dv_dim && !found_non_eq; i++) {
01091 switch (DEP_Direction(DEPV_Dep(depv,i))) {
01092 case DIR_EQ:
01093 case DIR_POSEQ:
01094 case DIR_NEGEQ:
01095 case DIR_STAR:
01096 continue;
01097 case DIR_POS:
01098 case DIR_NEG:
01099 case DIR_POSNEG:
01100 found_non_eq = TRUE;
01101 }
01102 }
01103 if (!found_non_eq) return TRUE;
01104 }
01105 return FALSE;
01106 }
01107
01108 static BOOL Is_All_Equals(DEPV *depv, INT dv_dim);
01109 static INT debug;
01110
01111
01112
01113
01114 static INT Find_Enter_Symbol(SYMBOL_STACK *stack, const SYMBOL *symbol)
01115 {
01116 if (!symbol) {
01117 INT i = stack->Elements();
01118 stack->Push(NULL);
01119 return i;
01120 }
01121 INT i;
01122 for (i=0; i<stack->Elements(); i++) {
01123 if (stack->Bottom_nth(i)) {
01124 if (*stack->Bottom_nth(i) == *symbol) return i;
01125 }
01126 }
01127 stack->Push(symbol);
01128 return(i);
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 void DEPV_COMPUTE::Compute(DEPV_LIST *result,WN *ref1, ARA_REF *ara_ref1,
01151 WN *ref2, ARA_REF *ara_ref2,UINT8 common_nest,
01152 mUINT8 dv_dim, BOOL use_bounds, MEM_POOL *pool,
01153 const DOLOOP_STACK *s1, const DOLOOP_STACK *s2)
01154 {
01155 Is_True(dv_dim > 0,
01156 ("Dv_dim = %d is too small in DEPV_COMPUTE::Compute\n",dv_dim));
01157 Is_True(dv_dim <= common_nest,
01158 ("Dv_dim = %d is too large in DEPV_COMPUTE::Compute\n",dv_dim));
01159 Is_True(s1,("s1 is NULL in DEPV_COMPUTE::Compute"));
01160 Is_True(s2,("s2 is NULL in DEPV_COMPUTE::Compute"));
01161 Is_True(pool != &LNO_local_pool,
01162 ("Cannot use LNO_local_pool in DEPV_COMPUTE::Compute"));
01163
01164 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2)) {
01165 debug = 2;
01166 } else if (Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
01167 debug = 1;
01168 } else {
01169 debug = 0;
01170 }
01171 if (debug >= 2) {
01172 fprintf(TFile,"Dependence analysis comparing two array references\n");
01173 }
01174
01175
01176 MEM_POOL_Push(&LNO_local_pool);
01177 _pool = pool;
01178 Set_Step(s1,s2);
01179
01180 DEP_RESULT dr;
01181 SYMBOL_STACK *symbol_stack = CXX_NEW(SYMBOL_STACK(&LNO_local_pool),
01182 &LNO_local_pool);
01183
01184
01185 dr = Base_Test(ref1,ara_ref1,ref2,ara_ref2);
01186 if (dr == DEP_INDEPENDENT) {
01187 if (debug >= 2) {
01188 fprintf(TFile,"Base test proves them independent \n");
01189 }
01190 goto return_point;
01191 } else if (dr == DEP_DEPENDENT) {
01192 result->Append(CXX_NEW(DEPV_NODE(DEPV_CreateStar(pool,dv_dim)),pool));
01193 if (debug >= 2) {
01194 fprintf(TFile,"Base test forces us to assume dependence\n");
01195 }
01196 goto return_point;
01197 }
01198
01199 {
01200 WN *array1=NULL,*array2=NULL;
01201 if (!ara_ref1) {
01202 array1=(OPCODE_is_load(WN_opcode(ref1))?(WN_kid0(ref1)):(WN_kid1(ref1)));
01203 if (WN_operator(array1) == OPR_ADD) {
01204 if (WN_operator(WN_kid0(array1)) == OPR_ARRAY) {
01205 array1 = WN_kid0(array1);
01206 } else {
01207 array1 = WN_kid1(array1);
01208 }
01209 }
01210 }
01211
01212 if (!ara_ref2) {
01213 array2=(OPCODE_is_load(WN_opcode(ref2))?(WN_kid0(ref2)):(WN_kid1(ref2)));
01214 if (WN_operator(array2) == OPR_ADD) {
01215 if (WN_operator(WN_kid0(array2)) == OPR_ARRAY) {
01216 array2 = WN_kid0(array2);
01217 } else {
01218 array2 = WN_kid1(array2);
01219 }
01220 }
01221 }
01222
01223
01224
01225 ACCESS_ARRAY *a1 = NULL;
01226 INT num_vec1,num_vec2;
01227 if (array1) {
01228 a1 = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,array1);
01229 num_vec1 = a1->Num_Vec();
01230 } else {
01231 REGION_ITER iter(&ara_ref1->Image());
01232 num_vec1 = iter.First()->Num_Dim();
01233 }
01234 ACCESS_ARRAY *a2 = NULL;
01235 if (array2) {
01236 a2 = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,array2);
01237 num_vec2 = a2->Num_Vec();
01238 } else {
01239 REGION_ITER iter(&ara_ref2->Image());
01240 num_vec2 = iter.First()->Num_Dim();
01241 }
01242 if (debug >= 2) {
01243 fprintf(TFile,"The two access arrays are \n");
01244 if (a1) a1->Print(TFile); if (a2) a2->Print(TFile);
01245 }
01246
01247 BOOL delin_ok = TRUE;
01248 if (!a1) {
01249 if (a2) {
01250 for (INT i=0; i<num_vec2 && delin_ok ; i++) {
01251 ACCESS_VECTOR *av2 = a2->Dim(i);
01252 if (av2->Delinearized_Symbol) {
01253 delin_ok = FALSE;
01254 }
01255 }
01256 }
01257 } else if (!a2) {
01258 for (INT i=0; i<num_vec1 && delin_ok ; i++) {
01259 ACCESS_VECTOR *av1 = a1->Dim(i);
01260 if (av1->Delinearized_Symbol) {
01261 delin_ok = FALSE;
01262 }
01263 }
01264 } else {
01265 delin_ok = (num_vec1 == num_vec2);
01266 for (INT i=0; i<num_vec1 && delin_ok ; i++) {
01267 ACCESS_VECTOR *av1 = a1->Dim(i);
01268 ACCESS_VECTOR *av2 = a2->Dim(i);
01269 if (av1->Delinearized_Symbol && av2->Delinearized_Symbol) {
01270 if (!(*av1->Delinearized_Symbol == *av2->Delinearized_Symbol)) {
01271 delin_ok = FALSE;
01272 }
01273 } else if (av1->Delinearized_Symbol || av2->Delinearized_Symbol) {
01274 delin_ok = FALSE;
01275 }
01276 }
01277 }
01278 if (!delin_ok) {
01279 result->Append(CXX_NEW(DEPV_NODE( DEPV_CreateStar(pool,dv_dim)),pool));
01280 if (debug >= 2) {
01281 fprintf(TFile,"Dependent due to different delinearizations \n");
01282 }
01283 goto return_point;
01284 }
01285
01286
01287
01288
01289 BOOL *non_trivial_dim = CXX_NEW_ARRAY(BOOL,num_vec1,&LNO_local_pool);
01290
01291 BOOL same_monotonic = FALSE;
01292 if (a1 && a2) {
01293 same_monotonic=Same_Monotonic(array1,array2,a1,a2,common_nest,dv_dim,s1);
01294 }
01295
01296
01297 if (a1 && a2) {
01298 if (Simple_Gcd_Indep(a1,a2,common_nest,dv_dim)) {
01299 if (debug >= 2) {
01300 fprintf(TFile,"Proven independent by Simple_Gcd_Indep \n");
01301 }
01302 goto return_point;
01303 }
01304 }
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314 INT num_bad_outer=INT32_MAX;
01315 if (a1) {
01316 num_bad_outer = a1->Dim(0)->Non_Const_Loops();
01317 for (INT i=1; i<num_vec1; i++) {
01318 num_bad_outer = MIN(num_bad_outer,a1->Dim(i)->Non_Const_Loops());
01319 }
01320 } else {
01321 REGION_ITER iter(&ara_ref1->Image());
01322 const REGION *first = iter.First();
01323 for (const REGION *node=first; !iter.Is_Empty(); node = iter.Next()) {
01324 AXLE_NODE *axle = node->_axle;
01325 CON_PAIR *lo = axle->lo;
01326 FmtAssert(lo != NULL, ("Compute: axle->lo is NULL"));
01327 num_bad_outer = MIN(num_bad_outer,lo->_ac_v->Non_Const_Loops());
01328 CON_PAIR *up = axle->up;
01329 FmtAssert(up != NULL, ("Compute: axle->hi is NULL"));
01330 if (up) {
01331 num_bad_outer = MIN(num_bad_outer,up->_ac_v->Non_Const_Loops());
01332 }
01333 }
01334 }
01335
01336 if (a2) {
01337 num_bad_outer = a2->Dim(0)->Non_Const_Loops();
01338 for (INT i=1; i<num_vec2; i++) {
01339 num_bad_outer = MIN(num_bad_outer,a2->Dim(i)->Non_Const_Loops());
01340 }
01341 } else {
01342 REGION_ITER iter(&ara_ref2->Image());
01343 const REGION *first = iter.First();
01344 for (const REGION *node=first; !iter.Is_Empty(); node = iter.Next()) {
01345 AXLE_NODE *axle = node->_axle;
01346 CON_PAIR *lo = axle->lo;
01347 num_bad_outer = MIN(num_bad_outer,lo->_ac_v->Non_Const_Loops());
01348 CON_PAIR *up = axle->up;
01349 if (up) {
01350 num_bad_outer = MIN(num_bad_outer,up->_ac_v->Non_Const_Loops());
01351 }
01352 }
01353 }
01354
01355
01356 num_bad_outer -= (common_nest-dv_dim);
01357 num_bad_outer = MAX(num_bad_outer,0);
01358
01359 if (num_bad_outer >= dv_dim) {
01360 result->Append(CXX_NEW(DEPV_NODE(
01361 DEPV_CreateStar(pool,dv_dim)),pool));
01362 if (debug >= 2) {
01363 fprintf(TFile,"Shown dependent since no good dimensions\n");
01364 }
01365 goto return_point;
01366 }
01367
01368
01369
01370 BOOL seen_non_trivial = FALSE;
01371 if (a1 && a2) {
01372 dr = Trivial_Test(a1,a2,dv_dim-num_bad_outer,common_nest,non_trivial_dim,
01373 &seen_non_trivial);
01374 } else {
01375 seen_non_trivial = TRUE;
01376 dr = DEP_CONTINUE;
01377 }
01378 if (dr == DEP_INDEPENDENT) {
01379 if (debug >= 2) {
01380 fprintf(TFile,"Proven independent by trivial tests \n");
01381 }
01382 goto return_point;
01383 } else if ((dr == DEP_DEPENDENT) && !same_monotonic) {
01384 result->Append(CXX_NEW(DEPV_NODE(
01385 DEPV_CreateStar(pool,dv_dim)),pool));
01386 if (debug >= 2) {
01387 fprintf(TFile,"Shown dependent by trivial tests \n");
01388 }
01389 goto return_point;
01390 }
01391
01392 if (same_monotonic) {
01393 if (array1 == array2) {
01394 if (debug >= 2) {
01395 fprintf(TFile,"Proven independent by monotonicity tests \n");
01396 }
01397 } else {
01398 result->Append(CXX_NEW(DEPV_NODE(
01399 DEPV_CreateEqual(pool,dv_dim)),pool));
01400 if (debug >= 2) {
01401 fprintf(TFile,"Two equivalent monotonically changing refs, ");
01402 fprintf(TFile,"all equals dependence. n");
01403 }
01404 }
01405 goto return_point;
01406 }
01407
01408
01409
01410 _nd1 = s1->Elements();
01411 _nd2 = s2->Elements();
01412 _first_dv1 = common_nest-(dv_dim-num_bad_outer);
01413
01414 _first_non_com1 = common_nest;
01415 _first_dv2 = _nd1;
01416 _first_non_com2 = _nd1+(dv_dim-num_bad_outer);
01417
01418 _first_symbol = _nd1+_nd2-_first_dv1;
01419 _work_cols = _first_symbol;
01420 _work_le_rows = 0;
01421
01422
01423
01424 _work_eq_rows = 0;
01425 if (seen_non_trivial) {
01426 if (a1 && a2 ) {
01427 if (!Copy_Equals_To_Work(a1,a2,symbol_stack,non_trivial_dim)) {
01428 result->Append(CXX_NEW(DEPV_NODE(
01429 DEPV_CreateStar(pool,dv_dim)),pool));
01430 if (debug >= 2) {
01431 fprintf(TFile,"Assume dependent because of overflow \n");
01432 }
01433 goto return_point;
01434 }
01435 } else {
01436 INT32 first_dummy;
01437 if (!Create_Dummy_Vars(num_vec1,symbol_stack,first_dummy)) {
01438 result->Append(CXX_NEW(DEPV_NODE(
01439 DEPV_CreateStar(pool,dv_dim)),pool));
01440 if (debug >= 2) {
01441 fprintf(TFile,"Assume dependent because of overflow \n");
01442 }
01443 goto return_point;
01444 }
01445
01446 if (!a1 && a2) {
01447 REGION_UN &image1 = ara_ref1->Image();
01448 if (image1.Is_All()) {
01449 result->Append(CXX_NEW(DEPV_NODE(
01450 DEPV_CreateStar(pool,dv_dim)),pool));
01451 if (debug >= 2) {
01452 fprintf(TFile,
01453 "Assume dependent because summary is Too_Messy or All\n");
01454 }
01455 goto return_point;
01456 } else if (!image1.Is_Empty()) {
01457 DEPV_COEFF coeff(CXX_NEW_ARRAY(INT32,num_vec1,&LNO_local_pool),
01458 first_dummy,num_vec1);
01459 if (!Copy_Call_To_Work(image1,symbol_stack,&coeff,TRUE)) {
01460 result->Append(CXX_NEW(DEPV_NODE(
01461 DEPV_CreateStar(pool,dv_dim)),pool));
01462 if (debug >= 2) {
01463 fprintf(TFile,"Assume dependent because of overflow \n");
01464 }
01465 goto return_point;
01466 }
01467 if (!Copy_Call_Ref_To_Work(a2,&coeff,symbol_stack,FALSE)) {
01468 result->Append(CXX_NEW(DEPV_NODE(
01469 DEPV_CreateStar(pool,dv_dim)),pool));
01470 if (debug >= 2) {
01471 fprintf(TFile,"Assume dependent because of overflow \n");
01472 }
01473 goto return_point;
01474 }
01475 }
01476 } else if (!a2 && a1) {
01477 REGION_UN &image2 = ara_ref2->Image();
01478 if (image2.Is_All()) {
01479 result->Append(CXX_NEW(DEPV_NODE(
01480 DEPV_CreateStar(pool,dv_dim)),pool));
01481 if (debug >= 2) {
01482 fprintf(TFile,
01483 "Assume dependent because summary is Too_Messy or All\n");
01484 }
01485 goto return_point;
01486 } else if (!image2.Is_Empty()) {
01487 DEPV_COEFF coeff(CXX_NEW_ARRAY(INT32,num_vec2,&LNO_local_pool),
01488 first_dummy,num_vec2);
01489 if (!Copy_Call_To_Work(image2,symbol_stack,&coeff,FALSE)) {
01490 result->Append(CXX_NEW(DEPV_NODE(
01491 DEPV_CreateStar(pool,dv_dim)),pool));
01492 if (debug >= 2) {
01493 fprintf(TFile,"Assume dependent because of overflow \n");
01494 }
01495 goto return_point;
01496 }
01497 if (!Copy_Call_Ref_To_Work(a1,&coeff,symbol_stack,TRUE)) {
01498 result->Append(CXX_NEW(DEPV_NODE(
01499 DEPV_CreateStar(pool,dv_dim)),pool));
01500 if (debug >= 2) {
01501 fprintf(TFile,"Assume dependent because of overflow \n");
01502 }
01503 goto return_point;
01504 }
01505 }
01506 } else {
01507 REGION_UN &image1 = ara_ref1->Image();
01508 REGION_UN &image2 = ara_ref2->Image();
01509 if (image1.Is_All() || image2.Is_All()) {
01510 result->Append(CXX_NEW(DEPV_NODE(
01511 DEPV_CreateStar(pool,dv_dim)),pool));
01512 if (debug >= 2) {
01513 fprintf(TFile,
01514 "Assume dependent because summary is Too_Messy or All\n");
01515 }
01516 goto return_point;
01517 } else if (!image1.Is_Empty() && !image2.Is_Empty()) {
01518 DEPV_COEFF coeff(CXX_NEW_ARRAY(INT32,num_vec1,&LNO_local_pool),
01519 first_dummy,num_vec1);
01520 if (!Copy_Call_To_Work(image1,symbol_stack,&coeff,TRUE) ||
01521 !Copy_Call_To_Work(image2,symbol_stack,&coeff,FALSE)) {
01522 result->Append(CXX_NEW(DEPV_NODE(
01523 DEPV_CreateStar(pool,dv_dim)),pool));
01524 if (debug >= 2) {
01525 fprintf(TFile,"Assume dependent because of overflow \n");
01526 }
01527 goto return_point;
01528 }
01529 }
01530 }
01531 }
01532 }
01533
01534
01535 if (a1 && a2 && Permutation_Arrays->Elements() &&
01536 (num_vec1 == WN_num_dim(array1))) {
01537 for (INT i=0; i<num_vec1; i++) {
01538 if (a1->Dim(i)->Too_Messy && a2->Dim(i)->Too_Messy) {
01539 ACCESS_ARRAY *perm1=NULL;
01540 ACCESS_ARRAY *perm2=NULL;
01541 if (Same_Permutation(WN_array_index(array1,i),
01542 WN_array_index(array2,i), &perm1,&perm2,
01543 s1->Bottom_nth(common_nest-(dv_dim-num_bad_outer)))) {
01544 if (!perm1->Too_Messy &&
01545 !perm2->Too_Messy && perm1->Num_Vec()==perm2->Num_Vec()) {
01546 BOOL delin_ok = TRUE;
01547 for (INT dl=0; dl<perm1->Num_Vec() && delin_ok ; dl++) {
01548 ACCESS_VECTOR *dl1 = perm1->Dim(dl);
01549 ACCESS_VECTOR *dl2 = perm2->Dim(dl);
01550 if (dl1->Delinearized_Symbol && dl2->Delinearized_Symbol) {
01551 if (!(*dl1->Delinearized_Symbol==*dl2->Delinearized_Symbol)){
01552 delin_ok = FALSE;
01553 }
01554 } else if (dl1->Delinearized_Symbol||dl2->Delinearized_Symbol){
01555 delin_ok = FALSE;
01556 }
01557 }
01558 if (delin_ok) {
01559 BOOL *non_trivial_dim2 =
01560 CXX_NEW_ARRAY(BOOL,perm1->Num_Vec(),&LNO_local_pool);
01561 BOOL this_seen_non_trivial = FALSE;
01562 DEP_RESULT dr = Trivial_Test(perm1,perm2,dv_dim-num_bad_outer,
01563 common_nest, non_trivial_dim2,&this_seen_non_trivial);
01564 if (this_seen_non_trivial) seen_non_trivial = TRUE;
01565 if (dr == DEP_INDEPENDENT) {
01566 if (debug >= 2) {
01567 fprintf(TFile,"Indirection proven independent by trivial tests \n");
01568 }
01569 goto return_point;
01570 } else if (dr != DEP_DEPENDENT) {
01571 if (this_seen_non_trivial) {
01572 if (!Copy_Equals_To_Work(perm1,perm2,symbol_stack,
01573 non_trivial_dim2)) {
01574 result->Append(CXX_NEW(DEPV_NODE(
01575 DEPV_CreateStar(pool,dv_dim)),pool));
01576 if (debug >= 2) {
01577 fprintf(TFile,"Assume dependent because of overflow \n");
01578 }
01579 goto return_point;
01580 }
01581 }
01582 }
01583 }
01584 }
01585 }
01586 }
01587 }
01588 }
01589 if (!seen_non_trivial) {
01590 result->Append(CXX_NEW(DEPV_NODE(
01591 DEPV_CreateStar(pool,dv_dim)),pool));
01592 if (debug >= 2) {
01593 fprintf(TFile,"Shown dependent by trivial tests \n");
01594 }
01595 goto return_point;
01596 }
01597
01598
01599
01600 if (use_bounds) {
01601 if (!Copy_Bounds_To_Work(s1,s2,symbol_stack)) {
01602 result->Append(CXX_NEW(DEPV_NODE(
01603 DEPV_CreateStar(pool,dv_dim)),pool));
01604 if (debug >= 2) {
01605 fprintf(TFile,"Assume dependent because of overflow \n");
01606 }
01607 goto return_point;
01608 }
01609 }
01610
01611
01612
01613 BOOL *is_used = CXX_NEW_ARRAY(BOOL,_work_cols,&LNO_local_pool);
01614 DEPV *init_distance = DEPV_Create(&LNO_local_pool,(dv_dim-num_bad_outer));
01615 dr = Find_Init_Distance_Used(init_distance,is_used,(dv_dim-num_bad_outer));
01616 if (dr == DEP_INDEPENDENT) {
01617 if (debug >= 2) {
01618 fprintf(TFile,"Proved independent finding initial distance\n");
01619 }
01620 result->Append(NULL,num_bad_outer);
01621 goto return_point;
01622 } else if (dr == DEP_DEPENDENT) {
01623 result->Append(CXX_NEW(DEPV_NODE(
01624 DEPV_CreateStar(pool,dv_dim)),pool));
01625 if (debug >= 2) {
01626 fprintf(TFile,"Shown dependent finding initial distance\n");
01627 }
01628 goto return_point;
01629 }
01630
01631
01632 if ((ref1 == ref2) &&
01633 Is_All_Equals(init_distance,dv_dim-num_bad_outer)) {
01634 if (debug >= 2) {
01635 fprintf(TFile,"Shown independent by Is_All_Equals \n");
01636 }
01637 result->Append(NULL,num_bad_outer);
01638 goto return_point;
01639 }
01640
01641 INT num_bounds_used=0;
01642 BOOL *bounds_used=0;
01643 if (use_bounds) {
01644 bounds_used = CXX_NEW_ARRAY(BOOL,_work_le_rows,&LNO_local_pool);
01645 Bounds_Set_Is_Used(is_used,bounds_used,&num_bounds_used);
01646 }
01647
01648 INT num_vars_used;
01649 INT *map_used = CXX_NEW_ARRAY(INT,_work_cols,&LNO_local_pool);
01650
01651 Set_Map_Used(is_used,&num_vars_used,map_used);
01652
01653
01654
01655 SYSTEM_OF_EQUATIONS *soe = CXX_NEW(SYSTEM_OF_EQUATIONS(
01656 MAX_ROWS,MAX_ROWS,num_vars_used,&LNO_local_pool),&LNO_local_pool);
01657 soe->Add_Eq(_work_eq_rows);
01658 if (num_bounds_used > 0) soe->Add_Le(num_bounds_used);
01659 Copy_To_Soe(is_used,bounds_used,map_used,soe);
01660 if (!soe->Is_Consistent()) {
01661 goto return_point;
01662 }
01663
01664
01665 if (use_bounds) {
01666 Compute_Dep_Vectors(soe,is_used,map_used,init_distance,result,
01667 (ref1 == ref2),dv_dim-num_bad_outer,num_bad_outer);
01668
01669
01670 } else {
01671 if (num_bad_outer == 0) {
01672 result->Append(
01673 CXX_NEW(DEPV_NODE(DEPV_Copy(_pool,init_distance,result->_dv_dim)),
01674 _pool));
01675 } else {
01676 result->Append(DEPV_Copy(&LNO_local_pool,init_distance,
01677 dv_dim-num_bad_outer),num_bad_outer);
01678 }
01679 }
01680 result->Normalize_Step(&_step1[common_nest-dv_dim]);
01681 }
01682
01683 return_point:
01684 if (debug >= 2) {
01685 fprintf(TFile,"result is "); result->Print(TFile); fprintf(TFile,"\n");
01686 }
01687 CXX_DELETE_ARRAY(_step1,_pool);
01688 CXX_DELETE_ARRAY(_step2,_pool);
01689 MEM_POOL_Pop(&LNO_local_pool);
01690 }
01691
01692
01693
01694 BOOL DEPV_COMPUTE::Create_Dummy_Vars(INT32 number, SYMBOL_STACK *symbol_stack,
01695 INT32 &result)
01696 {
01697 result = _first_symbol+Find_Enter_Symbol(symbol_stack,NULL);
01698 _work_cols++;
01699 for (INT i=1; i<number; i++) {
01700 Find_Enter_Symbol(symbol_stack,NULL);
01701 _work_cols++;
01702 }
01703 if(_work_cols > MAX_COLS) {
01704 Is_True(0, ("Column Overflow in DEPV_COMPUTE::Create_Dummy_Vars"));
01705 MEM_POOL_Pop(&LNO_local_pool);
01706 return(FALSE);
01707 }
01708 for (INT j=0; j<number; j++) {
01709 INT i;
01710 for (i=0; i<=_work_eq_rows; i++) {
01711 _work_eq[i][_work_cols-j] = 0;
01712 }
01713 for (i=0; i<=_work_le_rows; i++) {
01714 _work_le[i][_work_cols-j] = 0;
01715 }
01716 }
01717 return TRUE;
01718 }
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730 DEP_RESULT DEPV_COMPUTE::Trivial_Test( const ACCESS_ARRAY *a1,
01731 const ACCESS_ARRAY *a2, mUINT8 dv_dim,mUINT16 common_nest,
01732 BOOL *non_trivial_dim, BOOL *seen_non_trivial) const
01733 {
01734 Is_True(a1->Num_Vec() == a2->Num_Vec(),
01735 ("DEPV_COMPUTE::Trivial_Test access_arrays have different numbers of dims"));
01736
01737
01738 for (INT i=0; i<a1->Num_Vec(); i++) {
01739 ACCESS_VECTOR *av1 = a1->Dim(i);
01740 ACCESS_VECTOR *av2 = a2->Dim(i);
01741 non_trivial_dim[i] = FALSE;
01742
01743 if (!av1->Too_Messy && !av2->Too_Messy &&
01744 (av1->Contains_Non_Lin_Symb() == av2->Contains_Non_Lin_Symb())) {
01745 if ( av1->Non_Const_Loops() < (common_nest-dv_dim+1) &&
01746 av2->Non_Const_Loops() < (common_nest-dv_dim+1)) {
01747
01748 if (!av1->Contains_Non_Lin_Symb() ||
01749 (*av1->Non_Lin_Symb == *av2->Non_Lin_Symb)) {
01750 if (!av1->Contains_Lin_Symb() && !av2->Contains_Lin_Symb() &&
01751 !av1->Has_Loop_Coeff() && !av2->Has_Loop_Coeff()) {
01752 if (av1->Const_Offset != av2->Const_Offset) {
01753 return(DEP_INDEPENDENT);
01754 }
01755 } else {
01756 non_trivial_dim[i] = TRUE;
01757 *seen_non_trivial = TRUE;
01758 }
01759 }
01760 }
01761 }
01762 }
01763
01764 return(DEP_CONTINUE);
01765 }
01766
01767
01768
01769
01770
01771 BOOL DEPV_COMPUTE::Same_Monotonic(WN *array1, WN *array2,
01772 const ACCESS_ARRAY *a1, const ACCESS_ARRAY *a2,
01773 mUINT16 common_nest, mUINT16 dv_dim,const DOLOOP_STACK *s1) const
01774 {
01775 if (WN_num_dim(array1) != a1->Num_Vec()) return FALSE;
01776 for (INT i=0; i<a1->Num_Vec(); i++) {
01777 ACCESS_VECTOR *av1 = a1->Dim(i);
01778 ACCESS_VECTOR *av2 = a2->Dim(i);
01779 if (av1->Non_Const_Loops() >= (common_nest-dv_dim+1) ||
01780 av2->Non_Const_Loops() >= (common_nest-dv_dim+1)) {
01781 if (Same_Monotonic(WN_array_index(array1,i),WN_array_index(array2,i),
01782 av1,av2,common_nest,dv_dim,s1)) {
01783 return TRUE;
01784 }
01785 }
01786 }
01787 return FALSE;
01788 }
01789
01790
01791
01792
01793
01794
01795 BOOL DEPV_COMPUTE::Same_Monotonic(WN *array1_index, WN *array2_index,
01796 const ACCESS_VECTOR *av1, const ACCESS_VECTOR *av2,
01797 mUINT16 common_nest, mUINT16 dv_dim,const DOLOOP_STACK *s1) const
01798 {
01799 if (!(*av1 == *av2)) {
01800 return FALSE;
01801 }
01802 if (av1->Too_Messy || av1->Contains_Non_Lin_Symb()) {
01803 return(FALSE);
01804 }
01805 if (av1->Has_Loop_Coeff()) {
01806 for (INT i=0; i<common_nest; i++) {
01807 if (av1->Loop_Coeff(i)) return FALSE;
01808 }
01809 }
01810
01811 BOOL seen_increase = FALSE;
01812 BOOL seen_decrease = FALSE;
01813 if (av1->Lin_Symb) {
01814 INTSYMB_ITER iter(av1->Lin_Symb);
01815
01816 for (INTSYMB_NODE *node=iter.First();!iter.Is_Empty(); node=iter.Next()) {
01817 INT coeff = node->Coeff;
01818
01819
01820
01821
01822 const WN *wn1 = Find_First_Ldid_For_Symbol(array1_index,&node->Symbol);
01823 const WN *wn2 = Find_First_Ldid_For_Symbol(array2_index,&node->Symbol);
01824 if (!wn1 || !wn2) return FALSE;
01825
01826
01827
01828 DEF_LIST *def1 = Du_Mgr->Ud_Get_Def((WN *) wn1);
01829 if (!def1 || def1->Incomplete() || def1->Loop_stmt()) return FALSE;
01830 DEF_LIST_ITER iter1(def1);
01831 DU_NODE *du_node1 = iter1.First();
01832 if (!du_node1 || iter1.Next()) return FALSE;
01833 WN *def_wn1 = du_node1->Wn();
01834
01835 DEF_LIST *def2 = Du_Mgr->Ud_Get_Def((WN *) wn2);
01836 if (!def2 || def2->Incomplete() || def2->Loop_stmt()) return FALSE;
01837 DEF_LIST_ITER iter2(def2);
01838 DU_NODE *du_node2 = iter2.First();
01839 if (!du_node2 || iter2.Next()) return FALSE;
01840 WN *def_wn2 = du_node2->Wn();
01841
01842 if (def_wn1 != def_wn2) return FALSE;
01843
01844
01845 if (LWN_Get_Parent(def_wn1) != WN_do_body(s1->Bottom_nth(common_nest-1))) {
01846 return FALSE;
01847 }
01848
01849 if (WN_operator(def_wn1) != OPR_STID) {
01850 return FALSE;
01851 }
01852 if (!(SYMBOL(def_wn1) == node->Symbol)) return FALSE;
01853
01854 WN *incr = WN_kid0(def_wn1);
01855 OPERATOR incr_oper = WN_operator(incr);
01856 if ((incr_oper != OPR_ADD) && (incr_oper != OPR_SUB)) return FALSE;
01857
01858 WN *kid0 = WN_kid0(incr);
01859 OPERATOR oper0 = WN_operator(kid0);
01860 WN *kid1 = WN_kid1(incr);
01861 OPERATOR oper1 = WN_operator(kid1);
01862 WN *rhs;
01863 if ((oper0 == OPR_INTCONST) && (oper1 == OPR_LDID)) {
01864 if (incr_oper == OPR_SUB) return FALSE;
01865 if (!(SYMBOL(kid1) == node->Symbol)) return FALSE;
01866 if ((WN_const_val(kid0) > 0) == (coeff > 0)) {
01867 seen_increase = TRUE;
01868 } else {
01869 seen_decrease = TRUE;
01870 }
01871 rhs = kid1;
01872 } else if ((oper1 == OPR_INTCONST) && (oper0 == OPR_LDID)) {
01873 if (!(SYMBOL(kid0) == node->Symbol)) return FALSE;
01874 if (incr_oper == OPR_ADD) {
01875 if ((WN_const_val(kid1) > 0) == (coeff > 0)) {
01876 seen_increase = TRUE;
01877 } else {
01878 seen_decrease = TRUE;
01879 }
01880 } else {
01881 if ((WN_const_val(kid1) > 0) == (coeff > 0)) {
01882 seen_decrease = TRUE;
01883 } else {
01884 seen_increase = TRUE;
01885 }
01886 }
01887 rhs = kid0;
01888 } else {
01889 return FALSE;
01890 }
01891
01892
01893 DEF_LIST *incr_defs = Du_Mgr->Ud_Get_Def(rhs);
01894 if (!incr_defs || incr_defs->Incomplete()) return FALSE;
01895 DEF_LIST_ITER incr_iter(incr_defs);
01896 for(DU_NODE *node=incr_iter.First(); !incr_iter.Is_Empty(); node=incr_iter.Next()) {
01897 WN *def = node->Wn();
01898 if ((def != def_wn1) && Is_Descendent(def,s1->Bottom_nth(common_nest-dv_dim))) {
01899 return FALSE;
01900 }
01901 }
01902 }
01903 } else {
01904 return FALSE;
01905 }
01906 if (seen_increase && seen_decrease) {
01907 return FALSE;
01908 }
01909 return TRUE;
01910 }
01911
01912
01913
01914 const WN *DEPV_COMPUTE::Find_First_Ldid_For_Symbol(const WN *wn, const SYMBOL *symb) const
01915 {
01916 if (WN_operator(wn) == OPR_LDID) {
01917 if (SYMBOL(wn) == *symb) {
01918 return wn;
01919 }
01920 }
01921 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
01922 const WN *tmp = Find_First_Ldid_For_Symbol(WN_kid(wn,kidno),symb);
01923 if (tmp) {
01924 return tmp;
01925 }
01926 }
01927 return NULL;
01928 }
01929
01930
01931
01932
01933
01934 BOOL DEPV_COMPUTE::Simple_Gcd_Indep(ACCESS_ARRAY *a1, ACCESS_ARRAY *a2,
01935 INT common_nest, INT dv_dim) const
01936 {
01937 for (INT i=0; i<a1->Num_Vec(); i++) {
01938 ACCESS_VECTOR *av1 = a1->Dim(i);
01939 ACCESS_VECTOR *av2 = a2->Dim(i);
01940 if (av1->Non_Const_Loops() >= (common_nest-dv_dim+1) ||
01941 av2->Non_Const_Loops() >= (common_nest-dv_dim+1)) {
01942 if (Simple_Gcd_Indep(av1,av2)) {
01943 return TRUE;
01944 }
01945 }
01946 }
01947 return FALSE;
01948 }
01949
01950
01951
01952
01953
01954
01955 BOOL DEPV_COMPUTE::Simple_Gcd_Indep(ACCESS_VECTOR *av1,
01956 ACCESS_VECTOR *av2) const
01957 {
01958 if (av1->Too_Messy || av2->Too_Messy || av1->Contains_Non_Lin_Symb() ||
01959 av2->Contains_Non_Lin_Symb()) {
01960 return(FALSE);
01961 }
01962
01963 INT64 c = abs(av2->Const_Offset - av1->Const_Offset);
01964 if (!c) return(FALSE);
01965
01966 BOOL seen_coeff = FALSE;
01967 INT gcd;
01968
01969
01970 if (av1->Has_Loop_Coeff()) {
01971 for (INT i=0; i<av1->Nest_Depth(); i++) {
01972 INT coeff = abs(av1->Loop_Coeff(i));
01973 if (coeff) {
01974 if (coeff == 1) {
01975 return(FALSE);
01976 }
01977 if (!seen_coeff) {
01978 gcd = coeff;
01979 } else {
01980 gcd = Gcd(gcd,coeff);
01981 }
01982 seen_coeff = 1;
01983 }
01984 }
01985 }
01986 if (av2->Has_Loop_Coeff()) {
01987 for (INT i=0; i<av2->Nest_Depth(); i++) {
01988 INT coeff = abs(av2->Loop_Coeff(i));
01989 if (coeff) {
01990 if (coeff == 1) {
01991 return(FALSE);
01992 }
01993 if (!seen_coeff) {
01994 gcd = coeff;
01995 } else {
01996 gcd = Gcd(gcd,coeff);
01997 }
01998 seen_coeff = 1;
01999 }
02000 }
02001 }
02002
02003
02004 if (av1->Lin_Symb) {
02005 INTSYMB_ITER iter(av1->Lin_Symb);
02006 for (INTSYMB_NODE *node=iter.First();!iter.Is_Empty(); node=iter.Next()) {
02007 INT coeff = abs(node->Coeff);
02008 if (coeff) {
02009 if (coeff == 1) {
02010 return(FALSE);
02011 }
02012 if (!seen_coeff) {
02013 gcd = coeff;
02014 } else {
02015 gcd = Gcd(gcd,coeff);
02016 }
02017 seen_coeff = 1;
02018 }
02019 }
02020 }
02021 if (av2->Lin_Symb) {
02022 INTSYMB_ITER iter(av2->Lin_Symb);
02023 for (INTSYMB_NODE *node=iter.First();!iter.Is_Empty(); node=iter.Next()) {
02024 INT coeff = abs(node->Coeff);
02025 if (coeff) {
02026 if (coeff == 1) {
02027 return(FALSE);
02028 }
02029 if (!seen_coeff) {
02030 gcd = coeff;
02031 } else {
02032 gcd = Gcd(gcd,coeff);
02033 }
02034 seen_coeff = 1;
02035 }
02036 }
02037 }
02038 if (!seen_coeff || ((c % gcd) != 0)) return(TRUE);
02039 return(FALSE);
02040 }
02041
02042 static POINTS_TO* Points_To_For_Array_Star(ARA_REF *ara_ref1)
02043 {
02044 ST* st1 = ara_ref1->Array().St();
02045 INT64 offset1 = ara_ref1->Array().ST_Offset();
02046 OPCODE opc_ldid = OPCODE_make_op(OPR_LDID, Pointer_type, Pointer_type);
02047 WN* wn_ldid = WN_CreateLdid(opc_ldid, offset1, st1, ST_type(st1));
02048 TYPE_ID wtype = TY_mtype(TY_AR_etype(TY_pointed(ST_type(st1))));
02049 OPCODE opc_iload = OPCODE_make_op(OPR_ILOAD, Promote_Type(wtype), wtype);
02050 TY_IDX wty = Be_Type_Tbl(wtype);
02051 TY_IDX pty = Make_Pointer_Type(Be_Type_Tbl(wtype));
02052 WN* wn_iload = WN_CreateIload(opc_iload, 0, wty, pty, wn_ldid);
02053 Create_alias(Alias_Mgr, wn_iload);
02054 IDTYPE id = Alias_Mgr->Id(wn_iload);
02055 POINTS_TO* pt = Alias_Mgr->Pt(id);
02056 WN_Delete(wn_ldid);
02057 WN_Delete(wn_iload);
02058 return pt;
02059 }
02060
02061
02062
02063
02064
02065
02066 DEP_RESULT DEPV_COMPUTE::Base_Test(const WN *ref1, ARA_REF *ara_ref1,
02067 const WN *ref2, ARA_REF *ara_ref2)
02068 {
02069
02070 WN *array1,*array2;
02071 ALIAS_RESULT aresult;
02072 POINTS_TO* pt1 = NULL;
02073 if (ara_ref1 != NULL) {
02074 ST* st1 = ara_ref1->Array().St();
02075 if (TY_kind(ST_type(st1)) == KIND_POINTER) {
02076 pt1 = Points_To_For_Array_Star(ara_ref1);
02077 } else {
02078 INT64 offset1 = ara_ref1->Array().ST_Offset();
02079 INT64 size1 = TY_size(ST_type(st1));
02080 pt1 = CXX_NEW(POINTS_TO(st1, offset1, size1), &LNO_local_pool);
02081 }
02082 }
02083 POINTS_TO* pt2 = NULL;
02084 if (ara_ref2 != NULL) {
02085 ST* st2 = ara_ref2->Array().St();
02086 if (TY_kind(ST_type(st2)) == KIND_POINTER) {
02087 pt2 = Points_To_For_Array_Star(ara_ref2);
02088 } else {
02089 INT64 offset2 = ara_ref2->Array().ST_Offset();
02090 INT64 size2 = TY_size(ST_type(st2));
02091 pt2 = CXX_NEW(POINTS_TO(st2, offset2, size2), &LNO_local_pool);
02092 }
02093 }
02094
02095
02096 if (ara_ref1 != NULL && ara_ref2 != NULL) {
02097 ALIAS_RESULT ar = Alias_Mgr->Aliased(pt1, pt2);
02098 if (ar == NOT_ALIASED)
02099 return DEP_INDEPENDENT;
02100 if (ara_ref1->Is_Whole_Array() || ara_ref1->Is_Messy())
02101 return DEP_DEPENDENT;
02102 if (ara_ref2->Is_Whole_Array() || ara_ref2->Is_Messy())
02103 return DEP_DEPENDENT;
02104 if (ara_ref1->Array().St() != ara_ref2->Array().St())
02105 return DEP_DEPENDENT;
02106 if (!Equiv_Dims(ara_ref1, ara_ref2))
02107 return DEP_DEPENDENT;
02108 return DEP_CONTINUE;
02109 }
02110
02111
02112
02113 if (ara_ref1 != NULL || ara_ref2 != NULL) {
02114 POINTS_TO* pt = ara_ref1 != NULL ? pt1 : pt2;
02115 const WN* wn_ref = ara_ref1 == NULL ? ref1 : ref2;
02116 ARA_REF* ara_ref = ara_ref1 != NULL ? ara_ref1 : ara_ref2;
02117 ALIAS_RESULT ar = Alias_Mgr->Aliased(pt, (WN*) wn_ref);
02118 if (ar == NOT_ALIASED)
02119 return DEP_INDEPENDENT;
02120 if (ara_ref->Is_Whole_Array() || ara_ref->Is_Messy())
02121 return DEP_DEPENDENT;
02122 const WN* wn_array = (OPCODE_is_load(WN_opcode(wn_ref)) ?
02123 WN_kid0(wn_ref) : WN_kid1(wn_ref));
02124
02125 if (WN_operator(wn_array) != OPR_ARRAY)
02126 return DEP_DEPENDENT;
02127 WN* wn_base = WN_array_base(wn_array);
02128 OPERATOR opr_base = WN_operator(wn_base);
02129 if (opr_base != OPR_LDA && opr_base != OPR_LDID)
02130 return DEP_DEPENDENT;
02131 SYMBOL sym(wn_base);
02132 if (sym.St() != ara_ref->Array().St())
02133 return DEP_DEPENDENT;
02134 if (!Equiv_Dims(wn_array, ara_ref))
02135 return DEP_DEPENDENT;
02136 return DEP_CONTINUE;
02137 }
02138
02139
02140
02141 FmtAssert(ara_ref1 == NULL && ara_ref2 == NULL,
02142 ("Base_Test: Should be analyze two arrays at this point"));
02143
02144 aresult = Overlapped_base(Alias_Mgr,ref1,ref2);
02145
02146 if (aresult == NOT_ALIASED) {
02147 return DEP_INDEPENDENT;
02148 }
02149 Is_True(OPCODE_is_load(WN_opcode(ref1)) || OPCODE_is_store(WN_opcode(ref1)),
02150 ("Non-load/store for ref1 in DEPV_COMPUTE::Base_Test"));
02151 Is_True(OPCODE_is_load(WN_opcode(ref2)) || OPCODE_is_store(WN_opcode(ref2)),
02152 ("Non-load/store for ref2 in DEPV_COMPUTE::Base_Test"));
02153
02154 INT type_size = MAX(MTYPE_RegisterSize(WN_desc(ref1)),
02155 MTYPE_RegisterSize(WN_desc(ref2)));
02156 WN *const1,*const2;
02157 array1 = (OPCODE_is_load(WN_opcode(ref1)) ? (WN_kid0(ref1)):(WN_kid1(ref1)));
02158 array2 = (OPCODE_is_load(WN_opcode(ref2)) ? (WN_kid0(ref2)):(WN_kid1(ref2)));
02159 if (WN_operator(array1) == OPR_ADD) {
02160 if (WN_operator(array2) != OPR_ADD) {
02161 return DEP_DEPENDENT;
02162 }
02163 if (WN_operator(WN_kid0(array1)) == OPR_ARRAY) {
02164 array1 = WN_kid0(array1);
02165 const1 = WN_kid1(array1);
02166 } else {
02167 array1 = WN_kid1(array1);
02168 const1 = WN_kid0(array1);
02169 }
02170 if (WN_operator(WN_kid0(array2)) == OPR_ARRAY) {
02171 array2 = WN_kid0(array2);
02172 const2 = WN_kid1(array2);
02173 } else {
02174 array2 = WN_kid1(array2);
02175 const2 = WN_kid0(array2);
02176 }
02177 if ((WN_operator(const1) != OPR_INTCONST) ||
02178 (WN_operator(const2) != OPR_INTCONST)) {
02179 return DEP_DEPENDENT;
02180 }
02181 if (WN_element_size(array1) != WN_element_size(array2)) {
02182 return DEP_DEPENDENT;
02183 }
02184 INT diff = abs(WN_const_val(const1) + WN_offset(ref1)
02185 -WN_const_val(const2) - WN_offset(ref2));
02186 if (diff != 0) {
02187 if ((diff >= type_size) && (diff < WN_element_size(array1))) {
02188 return DEP_INDEPENDENT;
02189 } else {
02190 return DEP_DEPENDENT;
02191 }
02192 }
02193 } else if (WN_operator(array2) == OPR_ADD) {
02194 return DEP_DEPENDENT;
02195 } else {
02196 if (WN_element_size(array1) != WN_element_size(array2)) {
02197 return DEP_DEPENDENT;
02198 }
02199 INT diff = abs(WN_offset(ref1) - WN_offset(ref2));
02200 #ifdef KEY
02201
02202
02203
02204 if (((WN_desc(ref1) == MTYPE_M && WN_offset(ref1) == 0 &&
02205 OPCODE_is_store(WN_opcode(ref1))) ||
02206 (WN_desc(ref2) == MTYPE_M && WN_offset(ref2) == 0 &&
02207 OPCODE_is_store(WN_opcode(ref2)))) &&
02208 WN_Simp_Compare_Trees(array1, array2) == 0)
02209 diff = 0;
02210 #endif
02211 if (diff != 0) {
02212 if ((diff >= type_size) && (diff < WN_element_size(array1))) {
02213 return DEP_INDEPENDENT;
02214 } else {
02215 return DEP_DEPENDENT;
02216 }
02217 }
02218 }
02219
02220
02221 WN *base1 = WN_array_base(array1);
02222 WN *base2 = WN_array_base(array2);
02223
02224 OPERATOR ob1 = WN_operator(base1);
02225 OPERATOR ob2 = WN_operator(base2);
02226
02227 if (ob1 != ob2) return (DEP_DEPENDENT);
02228
02229 BOOL different_structure_offsets = FALSE;
02230 if (ob1 == OPR_ADD) {
02231 INT offset1,offset2;
02232 if (WN_operator(WN_kid0(base1)) == OPR_INTCONST) {
02233 offset1 = WN_const_val(WN_kid0(base1));
02234 base1 = WN_kid1(base1);
02235 ob1 = WN_operator(base1);
02236 } else if (WN_operator(WN_kid1(base1)) == OPR_INTCONST) {
02237 offset1 = WN_const_val(WN_kid1(base1));
02238 base1 = WN_kid0(base1);
02239 ob1 = WN_operator(base1);
02240 } else {
02241 return(DEP_DEPENDENT);
02242 }
02243 if (WN_operator(WN_kid0(base2)) == OPR_INTCONST) {
02244 offset2 = WN_const_val(WN_kid0(base2));
02245 base2 = WN_kid1(base2);
02246 ob2 = WN_operator(base2);
02247 } else if (WN_operator(WN_kid1(base2)) == OPR_INTCONST) {
02248 offset2 = WN_const_val(WN_kid1(base2));
02249 base2 = WN_kid0(base2);
02250 ob2 = WN_operator(base2);
02251 } else {
02252 return(DEP_DEPENDENT);
02253 }
02254 different_structure_offsets = (offset1 != offset2);
02255 }
02256 if (ob1 != ob2) {
02257 return (DEP_DEPENDENT);
02258 }
02259 if (ob1 == OPR_LDA) {
02260 if (ST_ofst(WN_st(base1)) != ST_ofst(WN_st(base2)) ||
02261 ST_base(WN_st(base1)) != ST_base(WN_st(base2)) ||
02262 WN_offset(base1) != WN_offset(base2)) {
02263
02264 return(DEP_DEPENDENT);
02265 }
02266 } else if (ob1 == OPR_LDID) {
02267
02268
02269 ALIAS_RESULT result = Aliased(Alias_Mgr, base1, base2);
02270 if (result != SAME_LOCATION) {
02271 WN *def1 = Find_Def(base1);
02272 if (!def1) return (DEP_DEPENDENT);
02273 WN *def2 = Find_Def(base2);
02274 if (!def2) return (DEP_DEPENDENT);
02275 if (def1 != def2) return (DEP_DEPENDENT);
02276 if (WN_operator(def1) != OPR_STID) {
02277 return DEP_DEPENDENT;
02278 }
02279 if (WN_desc(def1) !=
02280 WN_desc(base1)) {
02281 return DEP_DEPENDENT;
02282 }
02283 }
02284 } else {
02285 return (DEP_DEPENDENT);
02286 }
02287
02288 if (different_structure_offsets) return DEP_INDEPENDENT;
02289
02290
02291
02292
02293 if (!Equiv_Dims(array1,array2)) {
02294 return(DEP_DEPENDENT);
02295 }
02296
02297 return(DEP_CONTINUE);
02298 }
02299
02300
02301
02302
02303
02304 WN *DEPV_COMPUTE::Find_Def(WN *wn)
02305 {
02306 DEF_LIST *defs = Du_Mgr->Ud_Get_Def(wn);
02307 if (!defs || defs->Is_Empty()) {
02308 DevWarn("No defs in DEPV_COMPUTE::Find_Def");
02309 return NULL;
02310 }
02311 if (defs->Incomplete()) return NULL;
02312
02313 DEF_LIST_ITER iter(defs);
02314 BOOL seen_non_entry = FALSE;
02315 BOOL seen_one = FALSE;
02316 BOOL seen_mult = FALSE;
02317 WN *def;
02318 for (const DU_NODE *node = iter.First();
02319 !iter.Is_Empty(); node=iter.Next()) {
02320 if (seen_one) seen_mult = TRUE;
02321 def = (WN *) node->Wn();
02322 OPERATOR opr = WN_operator(def);
02323 if (opr == OPR_STID) {
02324 seen_non_entry = TRUE;
02325 } else if ((opr != OPR_FUNC_ENTRY) && (opr != OPR_ALTENTRY)) {
02326 return NULL;
02327 }
02328 if (seen_mult && seen_non_entry) return NULL;
02329 seen_one = TRUE;
02330 }
02331 if (seen_non_entry) {
02332 return def;
02333 }
02334
02335 WN *tmp = wn;
02336 while (LWN_Get_Parent(tmp)) tmp = LWN_Get_Parent(tmp);
02337 Is_True(WN_opcode(tmp) == OPC_FUNC_ENTRY,("Root isn't FUNC_ENTRY"));
02338 return tmp;
02339 }
02340
02341
02342 mUINT16 DEPV_COMPUTE::Common_Nest(const DOLOOP_STACK *s1,
02343 const DOLOOP_STACK *s2) const
02344 {
02345 INT i;
02346 for (i=0; i<MIN(s1->Elements(),s2->Elements()); i++) {
02347 if (s1->Bottom_nth(i) != s2->Bottom_nth(i)) return(i);
02348 }
02349 return(i);
02350 }
02351
02352
02353
02354 BOOL DEPV_COMPUTE::Equiv_Dims(const WN *array1, const WN *array2)
02355 {
02356 if (WN_num_dim(array1) != WN_num_dim(array2)) {
02357 return(FALSE);
02358 }
02359
02360 for (INT i=1; i<WN_num_dim(array1); i++) {
02361 if (!Equiv_Dim(WN_array_dim(array1,i), WN_array_dim(array2,i))) {
02362 return(FALSE);
02363 }
02364 }
02365 return(TRUE);
02366 }
02367
02368 BOOL DEPV_COMPUTE::Equiv_Dims(const WN* wn_array, ARA_REF* ara_ref)
02369 {
02370 if (ara_ref->Is_Whole_Array() || ara_ref->Is_Messy())
02371 return FALSE;
02372 REGION_UN* ru_ref = &ara_ref->Image();
02373 if (ru_ref->Is_Bottom() || ru_ref->Is_All())
02374 return FALSE;
02375 REGION_ITER iter(ru_ref);
02376 INT num_dim = -1;
02377 for (REGION* rg = iter.First(); !iter.Is_Empty(); rg = iter.Next()) {
02378 if (num_dim == -1 && rg->Num_Dim() != -1)
02379 num_dim = rg->Num_Dim();
02380 else if (rg->Num_Dim() != num_dim)
02381 return FALSE;
02382 }
02383 if (WN_num_dim(wn_array) != num_dim)
02384 return FALSE;
02385
02386
02387
02388 return TRUE;
02389 }
02390
02391 BOOL DEPV_COMPUTE::Equiv_Dims(ARA_REF* ara_ref, const WN* wn_array)
02392 {
02393 return Equiv_Dims(wn_array, ara_ref);
02394 }
02395
02396 BOOL DEPV_COMPUTE::Equiv_Dims(ARA_REF* ara_ref1, ARA_REF* ara_ref2)
02397 {
02398 if (ara_ref1->Is_Whole_Array() || ara_ref1->Is_Messy())
02399 return FALSE;
02400 REGION_UN* ru_ref1 = &ara_ref1->Image();
02401 if (ru_ref1->Is_Bottom() || ru_ref1->Is_All())
02402 return FALSE;
02403 REGION_ITER iter1(ru_ref1);
02404 INT num_dim1 = -1;
02405 REGION* rg = 0;
02406 for (rg = iter1.First(); !iter1.Is_Empty(); rg = iter1.Next()) {
02407 if (num_dim1 == -1)
02408 num_dim1 = rg->Num_Dim();
02409 else if (rg->Num_Dim() != num_dim1)
02410 return FALSE;
02411 }
02412 if (ara_ref2->Is_Whole_Array() || ara_ref2->Is_Messy())
02413 return FALSE;
02414 REGION_UN* ru_ref2 = &ara_ref2->Image();
02415 if (ru_ref2->Is_Bottom() || ru_ref2->Is_All())
02416 return FALSE;
02417 INT num_dim2 = -1;
02418 REGION_ITER iter2(ru_ref2);
02419 for (rg = iter2.First(); !iter2.Is_Empty(); rg = iter2.Next()) {
02420 if (num_dim2 == -1)
02421 num_dim2 = rg->Num_Dim();
02422 else if (rg->Num_Dim() != num_dim2)
02423 return FALSE;
02424 }
02425 if (num_dim1 != num_dim2)
02426 return FALSE;
02427 return TRUE;
02428 }
02429
02430 BOOL DEPV_COMPUTE::Equiv_Dim(const WN *exp1, const WN *exp2)
02431 {
02432 if (WN_opcode(exp1) != WN_opcode(exp2)) return(FALSE);
02433 if (WN_kid_count(exp1) != WN_kid_count(exp2)) return(FALSE);
02434 if (OPCODE_is_load(WN_opcode(exp1))) {
02435
02436 OPERATOR oper = WN_operator(exp1);
02437 if (oper == OPR_LDA) {
02438 if (WN_load_offset(exp1) != WN_load_offset(exp2)) return(FALSE);
02439 if (WN_st(exp1) != WN_st(exp2)) return(FALSE);
02440 } else if (oper == OPR_LDID) {
02441
02442
02443
02444 if (WN_load_offset(exp1) == WN_load_offset(exp2) &&
02445 WN_st(exp1) == WN_st(exp2)) {
02446 return TRUE;
02447 }
02448 WN *def1 = Find_Def((WN *)exp1);
02449 if (!def1) return (FALSE);
02450 WN *def2 = Find_Def((WN *)exp2);
02451 if (!def2) return (FALSE);
02452 if (def1 != def2) return (FALSE);
02453
02454 if (WN_opcode(def1) == OPC_FUNC_ENTRY) {
02455 if (ST_ofst(WN_st(exp1)) != ST_ofst(WN_st(exp2)) ||
02456 ST_base(WN_st(exp1)) != ST_base(WN_st(exp2)) ||
02457 WN_offset(exp1) != WN_offset(exp2)) {
02458 return(FALSE);
02459 }
02460 } else {
02461 while (def1) {
02462 if (WN_opcode(def1) == OPC_DO_LOOP) {
02463 return FALSE;
02464 }
02465 def1 = LWN_Get_Parent(def1);
02466 }
02467 }
02468 } else {
02469 return FALSE;
02470 }
02471 } else if (WN_operator(exp1) == OPR_CONST) {
02472 if (WN_st(exp1) != WN_st(exp2)) return(FALSE);
02473 } else if (WN_operator(exp1) == OPR_INTCONST) {
02474 if (WN_const_val(exp1) != WN_const_val(exp2)) return(FALSE);
02475 } else {
02476 for (INT kidno=0; kidno<WN_kid_count(exp1); kidno++) {
02477 if (!Equiv_Dim(WN_kid(exp1,kidno),WN_kid(exp2,kidno))) {
02478 return FALSE;
02479 }
02480 }
02481 }
02482 return(TRUE);
02483 }
02484
02485
02486
02487
02488
02489
02490
02491
02492 BOOL DEPV_COMPUTE::Copy_Equals_To_Work(const ACCESS_ARRAY *a1,
02493 const ACCESS_ARRAY *a2, SYMBOL_STACK *symbol_stack,
02494 const BOOL *non_trivial_dim)
02495 {
02496
02497 INT i = 0;
02498 while (!non_trivial_dim[i]) i++;
02499
02500 if (_first_symbol > MAX_COLS) {
02501 Is_True(0,("Overflow in DEPV_COMPUTE::Copy_Equals_To_Work"));
02502 return FALSE;
02503 }
02504 _work_cols=_first_symbol;
02505
02506 while (i < a1->Num_Vec()) {
02507 if (non_trivial_dim[i]) {
02508 if(_work_eq_rows >= MAX_ROWS) {
02509 Is_True(0,("Row Overflow in DEPV_COMPUTE::Copy_Equals_To_Work"));
02510 return(FALSE);
02511 }
02512 ACCESS_VECTOR *av1 = a1->Dim(i);
02513 ACCESS_VECTOR *av2 = a2->Dim(i);
02514 if (!Copy_Equal_To_Work(av1,av2,symbol_stack)) {
02515 Is_True(0,("Overflow in DEPV_COMPUTE::Copy_Equals_To_Work"));
02516 return(FALSE);
02517 }
02518 }
02519 i++;
02520 }
02521 return(TRUE);
02522 }
02523
02524
02525
02526 BOOL DEPV_COMPUTE::Copy_Equal_To_Work(ACCESS_VECTOR *av1, ACCESS_VECTOR *av2,
02527 SYMBOL_STACK *symbol_stack)
02528 {
02529 if (av1->Too_Messy || av2->Too_Messy) return TRUE;
02530 if(_work_eq_rows >= MAX_ROWS) {
02531 Is_True(0,("Row Overflow in DEPV_COMPUTE::Copy_Equal_To_Work"));
02532 return(FALSE);
02533 }
02534 _work_eq_const[_work_eq_rows] = av1->Const_Offset - av2->Const_Offset;
02535
02536
02537 if (av1->Has_Loop_Coeff()) {
02538 for (INT j=0; j<_nd1; j++) {
02539 _work_eq[_work_eq_rows][j] = -av1->Loop_Coeff(j);
02540 }
02541 } else {
02542 for (INT j=0; j<_nd1; j++) {
02543 _work_eq[_work_eq_rows][j] = 0;
02544 }
02545 }
02546
02547 if (av2->Has_Loop_Coeff()) {
02548 INT j;
02549 for (j=0; j<_first_dv1; j++) {
02550 _work_eq[_work_eq_rows][j] += av2->Loop_Coeff(j);
02551 }
02552 for (j=_nd1; j<_first_symbol; j++) {
02553 _work_eq[_work_eq_rows][j] = +av2->Loop_Coeff(j-_nd1+_first_dv1);
02554 }
02555 } else {
02556 for (INT j=_nd1; j<_first_symbol; j++) {
02557 _work_eq[_work_eq_rows][j] = 0;
02558 }
02559 }
02560
02561
02562 for (INT j=_first_symbol; j<_work_cols; j++) {
02563 _work_eq[_work_eq_rows][j] = 0;
02564 }
02565
02566 if (av1->Contains_Lin_Symb()) {
02567 INTSYMB_ITER iter(av1->Lin_Symb);
02568 for (INTSYMB_NODE *node = iter.First(); !iter.Is_Empty();
02569 node=iter.Next()) {
02570 INT j = Find_Enter_Symbol(symbol_stack,&node->Symbol);
02571 if (j+_first_symbol >= _work_cols) {
02572 _work_cols=j+1+_first_symbol;
02573 if(_work_cols > MAX_COLS) {
02574 Is_True(0, ("Column Overflow in DEPV_COMPUTE::Copy_Equal_To_Work"));
02575 return(FALSE);
02576 }
02577 INT k;
02578 for (k=0; k<=_work_eq_rows; k++) {
02579 _work_eq[k][_work_cols-1] = 0;
02580 }
02581 for (k=0; k<=_work_le_rows; k++) {
02582 _work_le[k][_work_cols-1] = 0;
02583 }
02584 }
02585 _work_eq[_work_eq_rows][j+_first_symbol] -= node->Coeff;
02586 }
02587 }
02588 if (av2->Contains_Lin_Symb()) {
02589 INTSYMB_ITER iter(av2->Lin_Symb);
02590 for (INTSYMB_NODE *node = iter.First(); !iter.Is_Empty();
02591 node=iter.Next()) {
02592 INT j = Find_Enter_Symbol(symbol_stack,&node->Symbol);
02593 if (j+_first_symbol >= _work_cols) {
02594 _work_cols=j+1+_first_symbol;
02595 if(_work_cols > MAX_COLS) {
02596 Is_True(0,("Column Overflow in DEPV_COMPUTE::Copy_Equals_To_Work"));
02597 return(FALSE);
02598 }
02599 INT k;
02600 for (k=0; k<=_work_eq_rows; k++) {
02601 _work_eq[k][_work_cols-1] = 0;
02602 }
02603 for (k=0; k<=_work_le_rows; k++) {
02604 _work_le[k][_work_cols-1] = 0;
02605 }
02606 }
02607 _work_eq[_work_eq_rows][j+_first_symbol] += node->Coeff;
02608 }
02609 }
02610 _work_eq_rows++;
02611 return(TRUE);
02612 }
02613
02614
02615
02616 BOOL DEPV_COMPUTE::Copy_Equal_To_Work(ACCESS_VECTOR *av, DEPV_COEFF *coeff,
02617 SYMBOL_STACK *symbol_stack, BOOL is_first_ref)
02618 {
02619 if (av->Too_Messy) return TRUE;
02620 if(_work_eq_rows >= MAX_ROWS) {
02621 Is_True(0,("Row Overflow in DEPV_COMPUTE::Copy_Equal_To_Work"));
02622 return(FALSE);
02623 }
02624 _work_eq_const[_work_eq_rows] = -av->Const_Offset;
02625
02626 INT j;
02627 for (j=0; j<_work_cols; j++) {
02628 _work_eq[_work_eq_rows][j] = 0;
02629 }
02630
02631
02632 if (is_first_ref) {
02633 if (av->Has_Loop_Coeff()) {
02634 for (INT j=0; j<_nd1; j++) {
02635 _work_eq[_work_eq_rows][j] = av->Loop_Coeff(j);
02636 }
02637 }
02638 } else {
02639 if (av->Has_Loop_Coeff()) {
02640 INT j;
02641 for (j=0; j<_first_dv1; j++) {
02642 _work_eq[_work_eq_rows][j] = av->Loop_Coeff(j);
02643 }
02644 for (j=_nd1; j<_first_symbol; j++) {
02645 _work_eq[_work_eq_rows][j] = +av->Loop_Coeff(j-_nd1+_first_dv1);
02646 }
02647 }
02648 }
02649
02650
02651 if (av->Contains_Lin_Symb()) {
02652 INTSYMB_ITER iter(av->Lin_Symb);
02653 for (INTSYMB_NODE *node = iter.First(); !iter.Is_Empty();
02654 node=iter.Next()) {
02655 INT j = Find_Enter_Symbol(symbol_stack,&node->Symbol);
02656 if (j+_first_symbol >= _work_cols) {
02657 _work_cols=j+1+_first_symbol;
02658 if(_work_cols > MAX_COLS) {
02659 Is_True(0, ("Column Overflow in DEPV_COMPUTE::Copy_Equal_To_Work"));
02660 return(FALSE);
02661 }
02662 INT k;
02663 for (k=0; k<=_work_eq_rows; k++) {
02664 _work_eq[k][_work_cols-1] = 0;
02665 }
02666 for (k=0; k<=_work_le_rows; k++) {
02667 _work_le[k][_work_cols-1] = 0;
02668 }
02669 }
02670 _work_eq[_work_eq_rows][j+_first_symbol] += node->Coeff;
02671 }
02672 }
02673
02674
02675 for (j=0; j<coeff->_num_dim; j++) {
02676 _work_eq[_work_eq_rows][j+coeff->_first_var] = coeff->_coeff[j];
02677 }
02678 _work_eq_rows++;
02679 return(TRUE);
02680 }
02681
02682
02683
02684
02685
02686
02687
02688
02689 BOOL DEPV_COMPUTE::Copy_Call_To_Work(REGION_UN &image,
02690 SYMBOL_STACK *symbol_stack, DEPV_COEFF *coeff, BOOL is_first_ref)
02691 {
02692 REGION_ITER region_iter(&image);
02693 const REGION *first = region_iter.First();
02694 INT num_dim = first->_dim;
02695
02696 for (const REGION *region_node=first; !region_iter.Is_Empty();
02697 region_node = region_iter.Next()) {
02698 if (!region_node->Is_All() && !region_node->Is_Too_Messy() &&
02699 !region_node->Is_Empty()) {
02700 for (INT i=0; i<num_dim; i++) {
02701 AXLE_NODE &axle = region_node->_axle[i];
02702 if (axle.step < 0) {
02703 Is_True(0, ("Negative strides not supported"));
02704 return FALSE;
02705 }
02706 CON_PAIR *lo = axle.lo;
02707 CON_PAIR *up = axle.up;
02708 ACCESS_VECTOR *av_low = lo->Access_Vector();
02709 if (lo->_coeff) {
02710 for (INT c=0; c<num_dim; c++) {
02711 coeff->_coeff[c] = lo->_coeff[c];
02712 }
02713 } else {
02714 for (INT c=0; c<num_dim; c++) {
02715 coeff->_coeff[c] = 0;
02716 }
02717 coeff->_coeff[i] = -1;
02718 }
02719
02720 if (up) {
02721 ACCESS_VECTOR *av_up = up->Access_Vector();
02722 if (axle.step > 1) {
02723 if (!Copy_Stride_To_Work(av_low,coeff,axle.step,
02724 symbol_stack,is_first_ref)) {
02725 return FALSE;
02726 }
02727 }
02728 Copy_Le_To_Work(av_low,coeff,symbol_stack,is_first_ref,FALSE);
02729 if (up->_coeff) {
02730 for (INT c=0; c<num_dim; c++) {
02731 coeff->_coeff[c] = up->_coeff[c];
02732 }
02733 } else {
02734 for (INT c=0; c<num_dim; c++) {
02735 coeff->_coeff[c] = 0;
02736 }
02737 coeff->_coeff[i] = 1;
02738 }
02739 Copy_Le_To_Work(av_up,coeff,symbol_stack,is_first_ref,TRUE);
02740 } else {
02741 Copy_Equal_To_Work(av_low,coeff,symbol_stack,is_first_ref);
02742 }
02743 }
02744 }
02745 }
02746 return TRUE;
02747 }
02748
02749
02750
02751
02752
02753
02754 BOOL DEPV_COMPUTE::Copy_Call_Ref_To_Work(ACCESS_ARRAY *aa,
02755 DEPV_COEFF *coeff, SYMBOL_STACK *symbol_stack, BOOL is_first_ref)
02756 {
02757 INT num_dim = coeff->_num_dim;
02758 for (INT c=0; c<num_dim; c++) {
02759 coeff->_coeff[c] = 0;
02760 }
02761 if (!aa->Too_Messy) {
02762 for (INT i=0; i<coeff->_num_dim; i++) {
02763 ACCESS_VECTOR *av = aa->Dim(i);
02764 coeff->_coeff[i] = -1;
02765 if (!Copy_Equal_To_Work(av,coeff,symbol_stack,is_first_ref)) {
02766 coeff->_coeff[i] = 0;
02767 return FALSE;
02768 }
02769 coeff->_coeff[i] = 0;
02770 }
02771 }
02772 return TRUE;
02773 }
02774
02775
02776 BOOL DEPV_COMPUTE::Copy_Stride_To_Work(ACCESS_VECTOR *av, DEPV_COEFF *coeff,
02777 INT stride, SYMBOL_STACK *symbol_stack, BOOL is_first_ref)
02778 {
02779 INT j = Find_Enter_Symbol(symbol_stack,NULL);
02780 _work_cols=j+1+_first_symbol;
02781 if(_work_cols > MAX_COLS) {
02782 Is_True(0, ("Column Overflow in DEPV_COMPUTE::Copy_Stride_To_Work"));
02783 return(FALSE);
02784 }
02785 INT k;
02786 for (k=0; k<=_work_eq_rows; k++) {
02787 _work_eq[k][_work_cols-1] = 0;
02788 }
02789 for (k=0; k<=_work_le_rows; k++) {
02790 _work_le[k][_work_cols-1] = 0;
02791 }
02792
02793 if (!Copy_Equal_To_Work(av,coeff,symbol_stack,is_first_ref)) {
02794 return(FALSE);
02795 }
02796 _work_eq[_work_eq_rows-1][_work_cols-1] = -stride;
02797 return TRUE;
02798 }
02799
02800
02801
02802
02803 BOOL DEPV_COMPUTE::Copy_Le_To_Work(ACCESS_VECTOR *av, DEPV_COEFF *coeff,
02804 SYMBOL_STACK *symbol_stack, BOOL is_first_ref, BOOL negate_av)
02805 {
02806 if (av->Too_Messy) return TRUE;
02807 if(_work_le_rows >= MAX_ROWS) {
02808 Is_True(0,("Row Overflow in DEPV_COMPUTE::Copy_Le_To_Work"));
02809 return(FALSE);
02810 }
02811 if (negate_av) {
02812 _work_le_const[_work_le_rows] = av->Const_Offset;
02813 } else {
02814 _work_le_const[_work_le_rows] = -av->Const_Offset;
02815 }
02816
02817 INT j;
02818 for (j=0; j<_work_cols; j++) {
02819 _work_le[_work_le_rows][j] = 0;
02820 }
02821
02822
02823 if (is_first_ref) {
02824 if (av->Has_Loop_Coeff()) {
02825 for (INT j=0; j<_nd1; j++) {
02826 if (negate_av) {
02827 _work_le[_work_le_rows][j] = -av->Loop_Coeff(j);
02828 } else {
02829 _work_le[_work_le_rows][j] = av->Loop_Coeff(j);
02830 }
02831 }
02832 }
02833 } else {
02834 if (av->Has_Loop_Coeff()) {
02835 INT j;
02836 for (j=0; j<_first_dv1; j++) {
02837 if (negate_av) {
02838 _work_le[_work_le_rows][j] = -av->Loop_Coeff(j);
02839 } else {
02840 _work_le[_work_le_rows][j] = av->Loop_Coeff(j);
02841 }
02842 }
02843 for (j=_nd1; j<_first_symbol; j++) {
02844 if (negate_av) {
02845 _work_le[_work_le_rows][j] = -av->Loop_Coeff(j-_nd1+_first_dv1);
02846 } else {
02847 _work_le[_work_le_rows][j] = +av->Loop_Coeff(j-_nd1+_first_dv1);
02848 }
02849 }
02850 }
02851 }
02852
02853 if (av->Contains_Lin_Symb()) {
02854 INTSYMB_ITER iter(av->Lin_Symb);
02855 for (INTSYMB_NODE *node = iter.First(); !iter.Is_Empty();
02856 node=iter.Next()) {
02857 INT j = Find_Enter_Symbol(symbol_stack,&node->Symbol);
02858 if (j+_first_symbol >= _work_cols) {
02859 _work_cols=j+1+_first_symbol;
02860 if(_work_cols > MAX_COLS) {
02861 Is_True(0, ("Column Overflow in DEPV_COMPUTE::Copy_Le_To_Work"));
02862 return(FALSE);
02863 }
02864 INT k;
02865 for (k=0; k<=_work_le_rows; k++) {
02866 _work_le[k][_work_cols-1] = 0;
02867 }
02868 for (k=0; k<=_work_le_rows; k++) {
02869 _work_le[k][_work_cols-1] = 0;
02870 }
02871 }
02872 if (negate_av) {
02873 _work_le[_work_le_rows][j+_first_symbol] -= node->Coeff;
02874 } else {
02875 _work_le[_work_le_rows][j+_first_symbol] += node->Coeff;
02876 }
02877 }
02878 }
02879
02880
02881 for (j=0; j<coeff->_num_dim; j++) {
02882 _work_le[_work_le_rows][j+coeff->_first_var] = coeff->_coeff[j];
02883 }
02884 _work_le_rows++;
02885 return(TRUE);
02886 }
02887
02888
02889
02890
02891
02892
02893
02894
02895 BOOL DEPV_COMPUTE::Copy_Bounds_To_Work(const DOLOOP_STACK *s1,
02896 const DOLOOP_STACK *s2, SYMBOL_STACK *symbol_stack)
02897 {
02898
02899
02900
02901
02902
02903 INT first_dv_bound=0;
02904 INT last_dv_bound=-1;
02905
02906
02907 INT i;
02908 for (i=0; i<_first_dv2; i++) {
02909 if (i==_first_dv1) {
02910 first_dv_bound = _work_le_rows;
02911 }
02912
02913 DO_LOOP_INFO *dli = (DO_LOOP_INFO *)
02914 WN_MAP_Get(LNO_Info_Map,s1->Bottom_nth(i));
02915
02916 INT step=_step1[i];
02917
02918
02919 if (step) {
02920 ACCESS_ARRAY *lb,*ub;
02921 lb = dli->LB;
02922 ub = dli->UB;
02923 INT j;
02924 for (j=0; j<lb->Num_Vec(); j++) {
02925 ACCESS_VECTOR *lbv = lb->Dim(j);
02926 if (!lbv->Too_Messy && !lbv->Contains_Non_Lin_Symb() &&
02927 (lbv->Non_Const_Loops() <= _first_dv1)) {
02928 if (!Copy_Bound_To_Work(i,lbv,symbol_stack,TRUE)) return(FALSE);
02929 }
02930 }
02931
02932
02933 for (j=0; j<ub->Num_Vec(); j++) {
02934 ACCESS_VECTOR *ubv = ub->Dim(j);
02935 if (!ubv->Too_Messy && !ubv->Contains_Non_Lin_Symb() &&
02936 (ubv->Non_Const_Loops() <= _first_dv1)) {
02937 if (!Copy_Bound_To_Work(i,ubv,symbol_stack,TRUE)) return(FALSE);
02938 }
02939 }
02940 }
02941
02942 if (i == _first_non_com1-1) {
02943 if (_first_non_com1 > _first_dv1) {
02944 last_dv_bound = _work_le_rows-1;
02945 }
02946 }
02947 }
02948
02949
02950
02951 if (_work_le_rows +(last_dv_bound-first_dv_bound+1) > MAX_ROWS) {
02952 Is_True(0,("Row overflow in DEPV_COMPUTE::Copy_Bounds_To_Work"));
02953 return FALSE;
02954 }
02955 for (i=first_dv_bound; i<= last_dv_bound; i++) {
02956 _work_le_const[_work_le_rows+i-first_dv_bound] = _work_le_const[i];
02957 INT j;
02958 for (j=0; j<_first_dv1; j++) {
02959 _work_le[_work_le_rows+i-first_dv_bound][j] = _work_le[i][j];
02960 }
02961 for (j=_first_dv1; j<_first_dv2; j++) {
02962 _work_le[_work_le_rows+i-first_dv_bound][j] = 0;
02963 }
02964 for (j=_first_dv2; j<_first_symbol; j++) {
02965 _work_le[_work_le_rows+i-first_dv_bound][j] =
02966 _work_le[i][j-_first_dv2+_first_dv1];
02967 }
02968 for (j=_first_symbol; j<_work_cols; j++) {
02969 _work_le[_work_le_rows+i-first_dv_bound][j] = _work_le[i][j];
02970 }
02971 }
02972 _work_le_rows += (last_dv_bound-first_dv_bound+1);
02973
02974
02975 for (i=_first_non_com2; i<_first_symbol; i++) {
02976 DO_LOOP_INFO *dli = (DO_LOOP_INFO *)WN_MAP_Get(
02977 LNO_Info_Map,s2->Bottom_nth(i-_first_non_com2+_first_non_com1));
02978
02979 INT step=_step2[i-_first_non_com2+_first_non_com1];
02980 if (step) {
02981 ACCESS_ARRAY *lb,*ub;
02982 lb = dli->LB;
02983 ub = dli->UB;
02984 INT j;
02985 for (j=0; j<lb->Num_Vec(); j++) {
02986 ACCESS_VECTOR *lbv = lb->Dim(j);
02987 if (!lbv->Too_Messy && !lbv->Contains_Non_Lin_Symb() &&
02988 (lbv->Non_Const_Loops() <= _first_dv1)) {
02989 if (!Copy_Bound_To_Work(i,lbv,symbol_stack,FALSE)) return(FALSE);
02990 }
02991 }
02992
02993 for (j=0; j<ub->Num_Vec(); j++) {
02994 ACCESS_VECTOR *ubv = ub->Dim(j);
02995 if (!ubv->Too_Messy && !ubv->Contains_Non_Lin_Symb() &&
02996 (ubv->Non_Const_Loops() <= _first_dv1)) {
02997 if (!Copy_Bound_To_Work(i,ubv,symbol_stack,FALSE))return(FALSE);
02998 }
02999 }
03000 }
03001 }
03002 return(TRUE);
03003 }
03004
03005
03006
03007
03008
03009
03010
03011
03012 BOOL DEPV_COMPUTE::Copy_Bound_To_Work(INT var_num, ACCESS_VECTOR *bound,
03013 SYMBOL_STACK *symbol_stack, BOOL is_ref1)
03014 {
03015 if (_work_le_rows > MAX_ROWS) {
03016 Is_True(0,("Row overflow in DEPV_COMPUTE::Copy_Bound_To_Work"));
03017 return FALSE;
03018 }
03019
03020
03021 _work_le_const[_work_le_rows] = bound->Const_Offset;
03022
03023
03024 if (is_ref1) {
03025 if (bound->Has_Loop_Coeff()) {
03026 for (INT i=0; i <= var_num; i++) {
03027 _work_le[_work_le_rows][i] = bound->Loop_Coeff(i);
03028 }
03029 } else {
03030 for (INT i=0; i <= var_num; i++) {
03031 _work_le[_work_le_rows][i] = 0;
03032 }
03033 }
03034 for (INT i=var_num+1; i<_work_cols; i++) {
03035 _work_le[_work_le_rows][i] = 0;
03036 }
03037 } else {
03038 if (bound->Has_Loop_Coeff()) {
03039 INT i;
03040 for (i=0; i < _first_dv1; i++) {
03041 _work_le[_work_le_rows][i] = bound->Loop_Coeff(i);
03042 }
03043 for (i=_first_dv1; i<_first_dv2; i++) {
03044 _work_le[_work_le_rows][i] = 0;
03045 }
03046 for (i=_first_dv2; i<=var_num; i++) {
03047 _work_le[_work_le_rows][i]=bound->Loop_Coeff(i-_first_dv2+_first_dv1);
03048 }
03049 for (i=var_num+1; i<_work_cols; i++) {
03050 _work_le[_work_le_rows][i] = 0;
03051 }
03052 } else {
03053 for (INT i=0; i < _work_cols; i++) {
03054 _work_le[_work_le_rows][i] = 0;
03055 }
03056 }
03057 }
03058
03059
03060 if (bound->Contains_Lin_Symb()) {
03061 INTSYMB_ITER iter(bound->Lin_Symb);
03062 for (INTSYMB_NODE *node = iter.First();!iter.Is_Empty();node=iter.Next()) {
03063 INT i = Find_Enter_Symbol(symbol_stack,&node->Symbol);
03064 if (i+_first_symbol >= _work_cols) {
03065 _work_cols=i+1+_first_symbol;
03066 if(_work_cols > MAX_COLS) {
03067 Is_True(0,("Column Overflow in DEPV_COMPUTE::Copy_Bounds_To_Work"));
03068 return(FALSE);
03069 }
03070 INT j;
03071 for (j=0; j<=_work_eq_rows; j++) {
03072 _work_eq[j][_work_cols-1] = 0;
03073 }
03074 for (j=0; j<=_work_le_rows; j++) {
03075 _work_le[j][_work_cols-1] = 0;
03076 }
03077 }
03078 _work_le[_work_le_rows][i+_first_symbol] += node->Coeff;
03079 }
03080 }
03081 _work_le_rows++;
03082 return(TRUE);
03083 }
03084
03085
03086
03087
03088
03089
03090
03091 DEP_RESULT DEPV_COMPUTE::Find_Init_Distance_Used(DEPV *init_distance,
03092 BOOL *is_used, INT dv_dim) const
03093 {
03094 INT i;
03095 for (i=0; i<_work_cols; i++) {
03096 is_used[i] = FALSE;
03097 }
03098
03099 for (i=0; i<dv_dim; i++) {
03100 DEPV_Dep(init_distance,i) = DEP_SetDirection(DIR_STAR);
03101 }
03102
03103
03104 for (i=0; i<_work_eq_rows; i++) {
03105 INT num_vars=0;
03106 INT first_var;
03107 for (INT j=0; j<_work_cols; j++) {
03108 if (_work_eq[i][j] != 0) {
03109 if (num_vars==0) {
03110 first_var=j;
03111 }
03112 num_vars++;
03113 is_used[j] = TRUE;
03114
03115
03116 if ((j >= _first_dv1) && (j < _first_non_com1)) {
03117 is_used[_first_dv2+j-_first_dv1] = TRUE;
03118 } else if ((j >= _first_dv2) && (j < _first_non_com2)) {
03119 is_used[_first_dv1+j-_first_dv2] = TRUE;
03120 }
03121 }
03122 }
03123
03124 if (num_vars == 2) {
03125 if ((first_var >= _first_dv1) && (first_var < _first_non_com1)) {
03126 INT corres_var= _first_dv2 + first_var-_first_dv1;
03127 if (_work_eq[i][first_var] == -_work_eq[i][corres_var]) {
03128 DEP dep;
03129 if (_work_eq[i][first_var] == 1) {
03130 dep = DEP_SetDistance(-_work_eq_const[i]);
03131 } else if (_work_eq[i][first_var] == -1) {
03132 dep = DEP_SetDistance(_work_eq_const[i]);
03133 } else if ((_work_eq_const[i] % _work_eq[i][first_var]) == 0) {
03134 dep = DEP_SetDistance(-_work_eq_const[i]/_work_eq[i][first_var]);
03135 } else {
03136 return(DEP_INDEPENDENT);
03137 }
03138 DEP current_dep = DEPV_Dep(init_distance,first_var-_first_dv1);
03139 if (DEP_Direction(current_dep) == DIR_STAR) {
03140 DEPV_Dep(init_distance,first_var-_first_dv1) = dep;
03141 } else if (DEP_Distance(current_dep) != DEP_Distance(dep)) {
03142 return(DEP_INDEPENDENT);
03143 }
03144 }
03145 }
03146 }
03147 }
03148
03149
03150
03151 for (i=0; i<_work_le_rows; i++) {
03152 for (INT j=0; j<_work_cols; j++) {
03153 if (_work_le[i][j] != 0) {
03154 is_used[j] = TRUE;
03155
03156
03157 if ((j >= _first_dv1) && (j < _first_non_com1)) {
03158 is_used[_first_dv2+j-_first_dv1] = TRUE;
03159 } else if ((j >= _first_dv2) && (j < _first_non_com2)) {
03160 is_used[_first_dv1+j-_first_dv2] = TRUE;
03161 }
03162 }
03163 }
03164 }
03165 return(DEP_CONTINUE);
03166 }
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187 void DEPV_COMPUTE::Bounds_Set_Is_Used(BOOL *is_used,BOOL *bounds_used,
03188 INT *num_bounds_used) const
03189 {
03190 mBOOL *uses_zapped_symbol=CXX_NEW_ARRAY(mBOOL,_work_le_rows,&LNO_local_pool);
03191
03192
03193
03194
03195 INT j;
03196 for (j=_first_symbol; j<_work_cols; j++) {
03197 if (!is_used[j]) {
03198 BOOL seen_pos=FALSE;
03199 BOOL seen_neg = FALSE;
03200 for (INT i=0; i<_work_le_rows; i++) {
03201 if (_work_le[i][j] < 0) {
03202 seen_neg = TRUE;
03203 } else if (_work_le[i][j] > 0) {
03204 seen_pos = TRUE;
03205 }
03206 }
03207 if (seen_pos && seen_neg) {
03208 is_used[j] = TRUE;
03209 }
03210 }
03211 }
03212
03213 INT i;
03214 for (i=0; i<_work_le_rows; i++) {
03215 bounds_used[i] = FALSE;
03216 uses_zapped_symbol[i] = FALSE;
03217 for (INT j=_first_symbol; j<_work_cols; j++) {
03218 if (!is_used[j] && _work_le[i][j]) {
03219 uses_zapped_symbol[i] = TRUE;
03220 break;
03221 }
03222 }
03223 }
03224
03225
03226
03227
03228
03229
03230
03231
03232 for (i=_work_le_rows-1; i>=0; i--) {
03233 if (!uses_zapped_symbol[i]) {
03234
03235 INT j=_first_symbol-1;
03236 while (_work_le[i][j] == 0) j--;
03237 if (is_used[j]) {
03238 for (j=j-1; j>=0;j--) {
03239 if (!is_used[j]) {
03240 if (_work_le[i][j] != 0) {
03241 is_used[j] = TRUE;
03242
03243 if ((j >= _first_dv1) && (j < _first_non_com1)) {
03244 is_used[_first_dv2+j-_first_dv1] = TRUE;
03245 } else if ((j >= _first_dv2) && (j < _first_non_com2)) {
03246 is_used[_first_dv1+j-_first_dv2] = TRUE;
03247 }
03248 }
03249 }
03250 }
03251 }
03252 }
03253 }
03254
03255
03256
03257
03258
03259 *num_bounds_used=0;
03260 for (i=0; i<_work_le_rows; i++) {
03261 if (!uses_zapped_symbol[i]) {
03262 j=_first_symbol-1;
03263 while (_work_le[i][j] == 0) j--;
03264 if (is_used[j]) {
03265 bounds_used[i] = TRUE;
03266 (*num_bounds_used)++;
03267 }
03268 }
03269 }
03270 }
03271
03272
03273
03274
03275
03276
03277 void DEPV_COMPUTE::Set_Map_Used(const BOOL *is_used,INT *num_vars_used,
03278 INT *map_used) const
03279 {
03280 *num_vars_used=0;
03281 for (INT i=0; i<_work_cols; i++) {
03282 if (is_used[i]) {
03283 map_used[i] = (*num_vars_used)++;
03284 }
03285 }
03286 }
03287
03288
03289
03290 void DEPV_COMPUTE::Copy_To_Soe(const BOOL *is_used,const BOOL *bounds_used,
03291 const INT *map_used, SYSTEM_OF_EQUATIONS *soe) const
03292 {
03293
03294 INT64 *Beq = soe->Beq();
03295 for (INT j=0; j<_work_cols; j++) {
03296 if (is_used[j]) {
03297 INT map_col = map_used[j];
03298 for (INT i=0; i<_work_eq_rows; i++) {
03299 soe->Aeq()(i,map_col) = _work_eq[i][j];
03300 }
03301 }
03302 }
03303 INT i;
03304 for (i=0; i<_work_eq_rows; i++) {
03305 Beq[i] = _work_eq_const[i];
03306 }
03307
03308
03309 INT64 *Ble = soe->Ble();
03310 INT i2 = 0;
03311 for (i=0; i<_work_le_rows; i++) {
03312 if (bounds_used[i]) {
03313 Ble[i2] = _work_le_const[i];
03314 for (INT j=0; j<_work_cols; j++) {
03315 if (is_used[j]) {
03316 soe->Ale()(i2,map_used[j]) = _work_le[i][j];
03317 }
03318 }
03319 i2++;
03320 }
03321 }
03322 }
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339 void DEPV_COMPUTE::Compute_Dep_Vectors(SYSTEM_OF_EQUATIONS *soe,
03340 const INT *is_used, const INT *map_used,
03341 DEPV *input_dependence,DEPV_LIST *result,
03342 BOOL same_reference, INT dv_dim,INT num_bad_outer)
03343 {
03344 BOOL same = same_reference;
03345
03346 INT i=First_Star(input_dependence,is_used);
03347 if (i == -1) {
03348 if (num_bad_outer == 0) {
03349 result->Append(
03350 CXX_NEW(DEPV_NODE(DEPV_Copy(_pool,input_dependence,dv_dim)),
03351 _pool));
03352 } else {
03353 result->Append( DEPV_Copy(_pool,input_dependence,dv_dim),
03354 num_bad_outer);
03355 }
03356 return;
03357 }
03358
03359 Add_Direction(soe,i,map_used,DIR_POS);
03360 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_POS);
03361
03362 if (debug >= 2) {
03363 fprintf(TFile,"trying the direction ");
03364 DEPV_Print(input_dependence,TFile,dv_dim);
03365 fprintf(TFile,"\n");
03366 }
03367 if (soe->Is_Consistent()) {
03368 Compute_Dep_Vectors(soe,is_used,map_used,input_dependence,result,same,
03369 dv_dim,num_bad_outer);
03370 }
03371 soe->Remove_Last_Le();
03372 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_STAR);
03373
03374
03375 if (!same || (i != (dv_dim -1)) ||
03376 !Is_All_Equals(input_dependence,dv_dim-1)) {
03377 Add_Direction(soe,i,map_used,DIR_EQ);
03378 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_EQ);
03379
03380 if (debug >= 2) {
03381 fprintf(TFile,"trying the direction ");
03382 DEPV_Print(input_dependence,TFile,dv_dim);
03383 fprintf(TFile,"\n");
03384 }
03385 if (soe->Is_Consistent()) {
03386 Compute_Dep_Vectors(soe,is_used,map_used,input_dependence,result,same,
03387 dv_dim,num_bad_outer);
03388 }
03389 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_STAR);
03390 soe->Remove_Last_Eq();
03391 }
03392
03393 Add_Direction(soe,i,map_used,DIR_NEG);
03394 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_NEG);
03395
03396 if (debug >= 2) {
03397 fprintf(TFile,"trying the direction ");
03398 DEPV_Print(input_dependence,TFile,dv_dim);
03399 fprintf(TFile,"\n");
03400 }
03401 if (soe->Is_Consistent()) {
03402 Compute_Dep_Vectors(soe,is_used,map_used,input_dependence,result,same,
03403 dv_dim,num_bad_outer);
03404 }
03405 soe->Remove_Last_Le();
03406 DEPV_Dep(input_dependence,i) = DEP_SetDirection(DIR_STAR);
03407 }
03408
03409
03410
03411 void DEPV_COMPUTE::Add_Direction(SYSTEM_OF_EQUATIONS *soe, INT i,
03412 const INT *map_used, DIRECTION direction)
03413 {
03414 for (INT j=0; j<soe->Num_Vars(); j++) {
03415 _tmp[j] = 0;
03416 }
03417
03418 if (direction == DIR_EQ) {
03419 _tmp[map_used[_first_dv1+i]] = 1;
03420 _tmp[map_used[_first_dv2+i]] = -1;
03421 soe->Add_Eq(_tmp,0);
03422 } else if (direction == DIR_NEG) {
03423 _tmp[map_used[_first_dv1+i]] = -1;
03424 _tmp[map_used[_first_dv2+i]] = 1;
03425 soe->Add_Le(_tmp,-1);
03426 } else if (direction == DIR_POS) {
03427 _tmp[map_used[_first_dv1+i]] = 1;
03428 _tmp[map_used[_first_dv2+i]] = -1;
03429 soe->Add_Le(_tmp,-1);
03430 } else {
03431 Is_True(0,("Illegal direction in DEPV_COMPUTE::Add_Direction"));
03432 }
03433 }
03434
03435
03436
03437
03438
03439 INT DEPV_COMPUTE::First_Star(const DEPV *vector, const INT *is_used) const
03440 {
03441 for (INT i=_first_dv1; i<_first_non_com1; i++) {
03442 if (is_used[i]) {
03443 if (DEP_Direction(DEPV_Dep(vector,i-_first_dv1)) == DIR_STAR) {
03444 return(i-_first_dv1);
03445 }
03446 }
03447 }
03448 return(-1);
03449 }
03450
03451 void DEPV_COMPUTE::Print(FILE *fp) const
03452 {
03453 fprintf(fp,"_nd1,_nd2, = %d %d \n",_nd1,_nd2);
03454 fprintf(fp,"_first_dv1,_first_non_com1 = %d %d \n",_first_dv1,
03455 _first_non_com1);
03456 fprintf(fp,"_first_dv2,_first_non_com2 = %d %d \n",_first_dv2,
03457 _first_non_com2);
03458 fprintf(fp,"_first_symbol is %d \n",_first_symbol);
03459 fprintf(fp,"work_eq is \n");
03460 INT i;
03461 for (i=0; i<_work_eq_rows; i++) {
03462 for (INT j=0; j<_work_cols; j++) {
03463 fprintf(fp," %d ",_work_eq[i][j]);
03464 }
03465 fprintf(fp," %lld \n",_work_eq_const[i]);
03466 }
03467 fprintf(fp,"work_le is \n");
03468 for (i=0; i<_work_le_rows; i++) {
03469 for (INT j=0; j<_work_cols; j++) {
03470 fprintf(fp," %d ",_work_le[i][j]);
03471 }
03472 fprintf(fp," %lld \n",_work_le_const[i]);
03473 }
03474 }
03475
03476
03477
03478 void DEPV_COMPUTE::Set_Step(const DOLOOP_STACK *s1, const DOLOOP_STACK *s2)
03479 {
03480 _step1 = CXX_NEW_ARRAY(INT64,s1->Elements(),_pool);
03481 _step2 = CXX_NEW_ARRAY(INT64,s2->Elements(),_pool);
03482 INT i;
03483 for (i=0; i<s1->Elements(); i++) {
03484 DO_LOOP_INFO *dli = (DO_LOOP_INFO *)
03485 WN_MAP_Get(LNO_Info_Map,s1->Bottom_nth(i));
03486 ACCESS_VECTOR *step = dli->Step;
03487 if (!step->Is_Const()) {
03488 _step1[i] = 0;
03489 } else {
03490 _step1[i] = step->Const_Offset;
03491 }
03492 }
03493 for (i=0; i<s2->Elements(); i++) {
03494 DO_LOOP_INFO *dli = (DO_LOOP_INFO *)
03495 WN_MAP_Get(LNO_Info_Map,s2->Bottom_nth(i));
03496 ACCESS_VECTOR *step = dli->Step;
03497 if (!step->Is_Const()) {
03498 _step2[i] = 0;
03499 } else {
03500 _step2[i] = step->Const_Offset;
03501 }
03502 }
03503 }
03504
03505
03506
03507 static BOOL Is_All_Equals(DEPV *depv, INT dv_dim)
03508 {
03509 for (INT i=0; i<dv_dim; i++) {
03510 if (DEP_Direction(DEPV_Dep(depv,i)) != DIR_EQ) {
03511 return(FALSE);
03512 }
03513 }
03514 return TRUE;
03515 }
03516
03517
03518
03519 static BOOL Same_Invariant_Expression(WN *wn1, WN *wn2, WN *loop)
03520 {
03521 if (!WN_Equiv (wn1, wn2)) return FALSE;
03522 OPCODE opc = WN_opcode(wn1);
03523 if (OPCODE_is_load(opc)) {
03524 OPERATOR oper = OPCODE_operator(opc);
03525 if (oper != OPR_LDID) return FALSE;
03526 return Is_Loop_Invariant_Use(wn1,loop);
03527 }
03528 for (INT kidno=0; kidno<WN_kid_count(wn1); kidno++) {
03529 if (!Same_Invariant_Expression(WN_kid(wn1,kidno),
03530 WN_kid(wn2,kidno),loop)) {
03531 return FALSE;
03532 }
03533 }
03534 return TRUE;
03535 }
03536
03537 static BOOL Add_Or_Subtract(OPCODE opc)
03538 {
03539 OPERATOR opr = OPCODE_operator(opc);
03540 if ((opr == OPR_ADD) || (opr == OPR_SUB)) {
03541 return TRUE;
03542 }
03543 return FALSE;
03544 }
03545
03546
03547
03548
03549
03550
03551
03552 BOOL DEPV_COMPUTE::Same_Permutation(WN *ref1, WN *ref2, ACCESS_ARRAY **perm1,
03553 ACCESS_ARRAY **perm2, WN *outer_loop)
03554 {
03555 OPCODE opc1 = WN_opcode(ref1);
03556 OPCODE opc2 = WN_opcode(ref2);
03557 if (opc1 != opc2) return FALSE;
03558
03559
03560 if (Add_Or_Subtract(opc1)) {
03561 WN *kid01 = WN_kid0(ref1);
03562 WN *kid02 = WN_kid0(ref2);
03563 WN *kid11 = WN_kid1(ref1);
03564 WN *kid12 = WN_kid1(ref2);
03565 if (Same_Invariant_Expression(kid01,kid02,outer_loop)) {
03566 return Same_Permutation(kid11,kid12,perm1,perm2,outer_loop);
03567 } else if (Same_Invariant_Expression(kid11,kid12,outer_loop)) {
03568 return Same_Permutation(kid01,kid02,perm1,perm2,outer_loop);
03569 } else {
03570 return FALSE;
03571 }
03572 } else if (OPCODE_operator(opc1) == OPR_NEG) {
03573 return Same_Permutation(WN_kid0(ref1),WN_kid0(ref2),perm1,perm2,outer_loop);
03574 }
03575 if (!OPCODE_is_load(opc1) || !WN_kid_count(ref1)) return FALSE;
03576 if (WN_offset(ref1) != WN_offset(ref2)) return FALSE;
03577 WN *array1 = WN_kid0(ref1);
03578 WN *array2 = WN_kid0(ref2);
03579 OPCODE array_opc1 = WN_opcode(array1);
03580 OPCODE array_opc2 = WN_opcode(array2);
03581 if (array_opc1 != array_opc2 || (OPCODE_operator(array_opc1) != OPR_ARRAY)) {
03582 return FALSE;
03583 }
03584 WN *base1 = WN_array_base(array1);
03585 WN *base2 = WN_array_base(array2);
03586 if (WN_offset(base1) != WN_offset(base2)) return FALSE;
03587 if (WN_st(base1) != WN_st(base2)) return FALSE;
03588
03589 if (Base_Test(ref1,NULL,ref2,NULL) != DEP_CONTINUE) return FALSE;
03590
03591
03592 ST *st = WN_st(base1);
03593 for (INT i=0; i<Permutation_Arrays->Elements(); i++) {
03594 if (st == Permutation_Arrays->Bottom_nth(i)._st) {
03595 if (Permutation_Arrays->Bottom_nth(i)._is_good) {
03596 *perm1 = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,array1);
03597 *perm2 = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,array2);
03598 return TRUE;
03599 } else {
03600 return FALSE;
03601 }
03602 }
03603 }
03604 return FALSE;
03605 }
03606
03607 void DEPV_COMPUTE::Print_Work(FILE *fp)
03608 {
03609 fprintf(fp,"work_le,const_le is \n");
03610 INT32 i;
03611 for (i=0; i<_work_le_rows; i++) {
03612 for (INT32 j=0; j<_work_cols; j++) {
03613 fprintf(fp," %d ",_work_le[i][j]);
03614 }
03615 fprintf(fp," %lld \n",_work_le_const[i]);
03616 }
03617 fprintf(fp,"\n");
03618 fprintf(fp,"work_eq, const_eq is \n");
03619 for (i=0; i<_work_eq_rows; i++) {
03620 for (INT32 j=0; j<_work_cols; j++) {
03621 fprintf(fp," %d ",_work_eq[i][j]);
03622 }
03623 fprintf(fp," %lld \n",_work_eq_const[i]);
03624 }
03625 fprintf(fp,"\n");
03626 }
03627
03628
03629
03630
03631
03632
03633
03634 mINT32 DEPV_COMPUTE::_work_eq[MAX_ROWS][MAX_COLS];
03635 mINT32 DEPV_COMPUTE::_tmp[MAX_COLS];
03636 INT64 DEPV_COMPUTE::_work_eq_const[MAX_ROWS];
03637 mINT32 DEPV_COMPUTE::_work_le[MAX_ROWS][MAX_COLS];
03638 INT64 DEPV_COMPUTE::_work_le_const[MAX_ROWS];
03639
03640
03641