1 /* file "dvector.cc" */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
13 #define _MODULE_ "libdependence.a"
14 #pragma implementation "dvector.h"
20 #include "dependence.h"
25 // routines to create a distance vector
26 // taking as input two array instructions
29 // a1 and a2 are two memory references which have the same base array
30 // --- possibly NULL or unknown
31 // if a1 and a2 are array accesses, generate the access vectors using
33 // if they are not, try to determine if they are independent, if not
34 // dependence vector is (*)
37 // interface the access vectors to the gcd program and find
38 // the distance vector
40 int Gcd(coeff
, coeff
**);
41 //overload int is_good_symb(access_vector *av1,access_list *symbols);
42 access_list
*unite_unequals(access_list
*a1
, access_list
*a2
);
43 //overload int inline is_good_symb(access_vector *av1);
46 dvlist::dvlist(array_info
*a1
, array_info
*a2
,
47 int minnest
, int valid_dim
, tn_list
* al
, int lexpos
, int flow
)
49 dv_calc(a1
,a2
,minnest
,valid_dim
,al
,flow
);
50 if(lexpos
) make_lexpos();
53 distance_vector::distance_vector(array_info
*a1
, array_info
*a2
,
54 int minnest
, int valid_dim
, tn_list
* al
,int flow
)
56 dvlist
*dvl
=new dvlist(a1
,a2
,minnest
,valid_dim
,al
,flow
);
61 static int dim_is_ok(access_vector
*a
,tn_list
*al
)
65 ass_list_iter
<int> ai(&a
->elts
);
66 while(!ai
.is_empty()) {
67 ass_list_e
<int> *ae
= ai
.step();
68 if(ae
->info
!= NULL
&& !al
->lookup((tree_node
*)ae
->key
))
74 static int wierd_constant_fields_same(access_vector
*av1
,access_vector
*av2
)
76 av_compare_info
ans(av1
,av2
);
77 return ans
.same_paths() && ans
.same_conregs() && ans
.same_memregs();
83 dvlist_iter
iter(this);
84 while(!iter
.is_empty()) {
85 dvlist_e
* de
= iter
.step();
86 if(de
->dv
) delete de
->dv
;
87 remove(iter
.cur_elem());
98 dvlist::dvlist(array_info
*a1
, array_info
*a2
, tn_list
*al
,int lexpos
, int flow
)
101 array_info
*ai1
= new array_info
;
102 array_info
*ai2
= new array_info
;
103 array_info_iter
aii1(a1
);
104 array_info_iter
aii2(a2
);
105 while(!aii1
.is_empty()) {
106 assert(!aii2
.is_empty());
107 access_vector
*av1
= aii1
.step();
108 access_vector
*av2
= aii2
.step();
109 if(dim_is_ok(av1
,al
) && dim_is_ok(av2
,al
)) {
110 // wierd_constant_fields_same(av1,av2)) {
112 ai1
-> append(new access_vector(av1
));
113 ai2
-> append(new access_vector(av2
));
116 dv_calc(ai1
,ai2
,al
->count(),valid_dim
,al
,flow
);
117 if(lexpos
) make_lexpos();
124 distance_vector::distance_vector(array_info
*a1
,array_info
*a2
,
125 tn_list
*al
,int flow
)
128 array_info
*ai1
= new array_info
;
129 array_info
*ai2
= new array_info
;
130 array_info_iter
aii1(a1
);
131 array_info_iter
aii2(a2
);
132 while(!aii1
.is_empty()) {
133 assert(!aii2
.is_empty());
134 access_vector
*av1
= aii1
.step();
135 access_vector
*av2
= aii2
.step();
136 if(dim_is_ok(av1
,al
) && dim_is_ok(av2
,al
) &&
137 wierd_constant_fields_same(av1
,av2
)) {
139 ai1
-> append(new access_vector(av1
));
140 ai2
-> append(new access_vector(av2
));
143 dvlist
*dvl
=new dvlist(ai1
,ai2
,al
->count(),valid_dim
,al
,flow
);
145 delete ai1
; delete ai2
;
148 void dvlist::dv_calc(array_info
*a1
, array_info
*a2
,
149 int minnest
, int valid_dim
, tn_list
* al
,int flow
)
151 //= printf("a1:"); a1->print();
152 //= printf("\na2:"); a2->print();
153 //= printf("\nminnest=%d, valid_dim=%d, flow=%d\n", minnest, valid_dim, flow);
155 tn_list_iter titer(al);
157 while(!titer.is_empty()) {
158 tree_node * tn = titer.step();
159 assert(tn->is_for());
160 printf("%s ", ((tree_for*)tn)->index());
164 array_info_iter
* a1i
, *a2i
;
165 access_vector
* av1
, * av2
;
166 tn_list_iter
* loops
;
167 tn_list_iter
* loops2
;
168 dependency_test
*dt
=new dependency_test();
169 set_dep(); // initialization
171 int *write_used
= new int[minnest
]; // which loops are used by
172 // the write, assume a1 is
175 valid_dim
= elim_bad_symb(a1
, a2
); // dims with bad symbols
176 if (!valid_dim
&& flow
) {
177 dir_array
*da
= new dir_array(minnest
);
178 int *is_used
= new int[2*minnest
];
179 for (int i
=0; i
<minnest
; i
++) {
180 da
->data
[i
].set_direction(d_star
);
184 dir_list
*dl
= new dir_list(da
);
185 dl
->flow_reduce(is_used
);
187 while ((da2
=dl
->pop())) {
188 distance_vector
*dv2
= new distance_vector();
189 for (int s
=0; s
<da2
->size
; s
++) {
190 distance dis
=da2
->data
[s
];
193 push(new dvlist_e(dv2
));
199 access_list
*symbols
= find_symbs(a1
,a2
);
200 int num_symb
= symbols
->count();
203 printf("\nThe two references are \n");
204 a1->print(stdout); printf("\n");
205 a2->print(stdout); printf("\n");
207 // find the bounds from al and shove into L and U
208 integer_matrix
*L
= new integer_matrix();
209 integer_matrix
*U
= new integer_matrix();
210 boolean
*lb_valid
= new boolean
[DD
+1]; // does this bound exist
211 boolean
*ub_valid
= new boolean
[DD
+1];
212 void SetLU(tn_list
*, int, integer_matrix
*, integer_matrix
* ,boolean
* ,
213 boolean
*,access_list
*,int,int flow
=0);
214 SetLU(al
,DD
,L
,U
,lb_valid
,ub_valid
,symbols
,num_symb
,flow
);
216 // throw out constant dimensions
217 a1i
= new array_info_iter(a1
);
218 a2i
= new array_info_iter(a2
);
220 int has_const_dim
= 0;
221 // throw out constant dimensions
222 array_info
*newa1
= new array_info();
223 array_info
*newa2
= new array_info();
224 while(!a1i
->is_empty()) {
225 assert(!a2i
->is_empty());
228 av_compare_info
avc(av1
,av2
);
229 // will subracting the two will create a constant
230 if (av1
->elts
.is_empty() && av2
->elts
.is_empty() &&
231 avc
.same_conregs() && avc
.same_memregs() &&
233 if (av1
->con
!= av2
->con
) {
234 if (minnest
> 0) dt
->const_test
++;
236 //printf("It's independent \n");
246 delete a1i
; delete a2i
;
247 a1
->clear(); a2
->clear();
250 if (valid_dim
== 0) { // set all elements to star
251 if (has_const_dim
&& (minnest
>0)) dt
->const_test
++;
252 distance_vector
*dv
= new distance_vector();
253 for (int i
=0; i
<minnest
; i
++) {
254 distance
*d
= new distance();
255 distance_vector_e
*temp
= new distance_vector_e(*d
);
258 push(new dvlist_e(dv
));
259 //= printf("The result is1 \n"); this->print(stdout); printf("\n");
263 a1i
= new array_info_iter(newa1
);
264 a2i
= new array_info_iter(newa2
);
266 // check which induction variables are actually used and get a count
267 int *loop_used
= new int[2*minnest
+num_symb
];
268 void SetLoopUsed(int *,int ,int,int *, int *, array_info_iter
*,
269 array_info_iter
*,tn_list
*,integer_matrix
*,
270 integer_matrix
*,int,int *);
271 SetLoopUsed(loop_used
,minnest
,valid_dim
,lb_valid
,ub_valid
,
272 a1i
,a2i
,al
,L
,U
,num_symb
,write_used
);
276 for (i
=2*(minnest
-1); i
>=0; i
-=2) {
277 if (loop_used
[i
+num_symb
]) loop1_num
++;
279 for (i
=2*minnest
-1; i
>=0; i
-=2) {
280 if (loop_used
[i
+num_symb
]) loop2_num
++;
282 int num_used
= loop1_num
+ loop2_num
;
284 // throw out unused variables from write_used
285 assert(num_used
%2 == 0);
287 for (i
=0; i
<num_used
/2; i
++) {
288 if (loop_used
[2*i
+num_symb
] || loop_used
[2*i
+num_symb
+1]) {
289 write_used
[i2
++] = write_used
[i
];
292 //= printf("L:\n");L->print();
293 //= printf("U:\n");U->print();
294 //= for(int x=0; x<DD+1; x++)
295 //= printf("(%d %d)", lb_valid[x], ub_valid[x]);
296 // put equations into a coeff A
299 int total_vars
= 2*minnest
+num_symb
;
300 X
->vars
= new int[total_vars
*total_vars
];
301 X
->constant
= new int[total_vars
];
302 A
.n
= num_used
+num_symb
;
304 A
.vars
= new int[A
.n
*A
.m
];
305 A
.constant
= new int[valid_dim
];
307 /* now set the A matrix, eliminating unused variables */
308 a1i
= new array_info_iter(newa1
);
309 a2i
= new array_info_iter(newa2
);
310 for (i
=0; i
<valid_dim
; i
++) {
314 loops
= new tn_list_iter(al
);
315 loops2
= new tn_list_iter(al
);
318 for (j
=num_used
-1; j
>=0; j
--) {
320 while(!loop_used
[k
+num_symb
]) {
321 if ((k
%2) ==0) av1
->val(loops
->step());
322 else av2
->val(loops2
->step());
326 A
.vars
[j2
*valid_dim
+i
] = av1
->val(loops
-> step());
328 A
.vars
[j2
*valid_dim
+i
] = -av2
->val(loops2
-> step());
331 //= printf("%d %d %d---\n", i, j, k); A.print();
333 delete loops
; delete loops2
;
334 A
.constant
[i
] = av1
->con
- av2
->con
;
336 // add in symbolic components
337 access_list_iter
temp_symb(symbols
);
338 for (j
=num_symb
-1; j
>=0; j
--) {
339 assert(!temp_symb
.is_empty());
340 access_list_e
*e
= temp_symb
.step();
341 A
.vars
[j
*valid_dim
+i
] = av1
->conregs
.val(e
->var())-
342 av2
->conregs
.val(e
->var());
343 //= printf("%d %d ---\n", i, j); A.print();
347 //eliminate unused variables for L and U
349 DD
= num_used
+num_symb
;
350 int numlow
= 0; // number of lower bounds
352 for (i
=1; i
<=olddd
; i
++) {
353 if (loop_used
[i
-1]) {
354 numlow
+= lb_valid
[i
];
355 numup
+= ub_valid
[i
];
358 integer_matrix
*L2
= new integer_matrix();
359 integer_matrix
*U2
= new integer_matrix();
360 L2
->init(num_symb
+numlow
+1,DD
+1);
361 U2
->init(num_symb
+numup
+1,DD
+1);
362 int oldlow
,oldup
,newlow
,newup
;
363 //= printf("L:\n");L->print();
364 //= printf("U:\n");U->print();
365 oldlow
= oldup
= newlow
= newup
= 1;
367 for (i
=1; i
<=olddd
; i
++) {
368 if (loop_used
[i
-1]) {
369 lb_valid
[i2
] = lb_valid
[i
]; ub_valid
[i2
] = ub_valid
[i
];
371 for (a
=1; a
<= lb_valid
[i
]; a
++, oldlow
++, newlow
++) {
372 (*L2
)[newlow
][0] = (*L
)[oldlow
][0];
375 for (j
=1; j
<i
; j
++) {
376 if (loop_used
[j
-1]) {
377 (*L2
)[newlow
][j2
] = (*L
)[oldlow
][j
];
382 for (a
=1; a
<= ub_valid
[i
]; a
++, oldup
++, newup
++) {
383 (*U2
)[newup
][0] = (*U
)[oldup
][0];
386 for (j
=1; j
<i
; j
++) {
387 if (loop_used
[j
-1]) {
388 (*U2
)[newup
][j2
] = (*U
)[oldup
][j
];
395 oldlow
+= lb_valid
[i
];
396 oldup
+= ub_valid
[i
];
401 //= printf("L:\n");L->print();
402 //= printf("U:\n");U->print();
405 // check degenerate cases
406 if (minnest
== 0) { // if all constants equal then set to star
407 // else set to independent
408 for (i
=0; i
<valid_dim
; i
++) {
409 if (A
.constant
[i
] != 0) {
415 } else if (Gcd(A
,&X
)) {
416 distance_vector
*dv
= new distance_vector();
417 for (i
=num_used
/2-1; i
>= 0; i
--) { // once for each d_vec dim
418 int i2
= 2*i
+num_symb
;
421 for (int j
=0; j
<X
->n
&& !done
; j
++) {
422 if (X
->vars
[j
*X
->m
+i2
] !=
423 X
->vars
[j
*X
->m
+i2
+1]) {
424 // non constant distance vector
425 d
= new distance(); // star
431 int c
=X
->constant
[i2
+1]-X
->constant
[i2
];
432 d
= new distance(-c
);
434 distance_vector_e
*temp
= new distance_vector_e(*d
);
439 // convert from coefficient structure to integer_matrix needed by exact
442 for (int l
=0; l
<X
->m
; l
++) {
443 assert(l
+1 < (DD
+1));
444 S
[l
+1][0] = X
->constant
[l
];
445 for (int m
=0; m
<X
->n
; m
++) {
446 assert((m
+1) < (DD
+1));
447 S
[l
+1][m
+1]=X
->vars
[m
*X
->m
+ l
];
450 // convert direction vector to dir_array needed by exact
451 dir_array
*da
= new dir_array(num_used
/2);
452 boolean
*const_dist
= new boolean
[num_used
/2];
453 distance_vector_iter
di(dv
);
454 for (i
=0; i
<num_used
/2; i
++) {
457 da
->data
[i
].set_direction(d
.dir());
458 const_dist
[i
] = d
.is_const();
461 exact
*ex
= new exact(&S
,DD
,da
,const_dist
,L
,U
,
462 lb_valid
,ub_valid
,num_symb
,flow
,write_used
);
463 if (ex
->is_indep()) {
464 //= printf("ex makes it independent \n");
468 /* printf("Gcd gave ");
469 dv->print(stdout); printf("\n");
470 printf("The set of direction vectors is\n");
471 ex->directions()->print(stdout);
476 dir_list
*dl
= ex
->directions();
477 if (!indep()) dl
->add_unused(loop_used
+num_symb
,
480 dl
->flow_reduce(loop_used
+num_symb
);
483 distance_vector
*dv2
=
484 new distance_vector();
485 dir_array
*da
= dl
->data
;
487 distance_vector_iter
iter1(dv
);
488 for (int s
=0; s
<da
->size
; s
++) {
490 if (loop_used
[num_symb
+2*s
]) {
491 assert(!iter1
.is_empty());
492 dis
= iter1
.step()->d
;
493 if (!dis
.is_const()) {
501 push(new dvlist_e(dv2
));
507 dv
->add_unused(loop_used
+num_symb
, 2*minnest
);
508 push(new dvlist_e(dv
));
513 delete a1i
; delete a2i
; delete newa1
; delete newa2
;
514 delete loop_used
; delete L
; delete U
;
516 //= printf("The result is2 \n"); this->print(stdout); printf("\n");
520 // collapse a list of direction vectors into 1
521 // by oring in the directions
522 void dvlist::collapse(distance_vector
*output
)
524 if (this->indep()) output
->set_indep();
528 dvlist_iter
iterator(this);
529 for (; !iterator
.is_empty();) {
530 distance_vector
*dv
= iterator
.step()->dv
;
533 distance_vector_iter
iter1(dv
);
534 while(!iter1
.is_empty()) {
535 output
->append(iter1
.step()->d
);
538 distance_vector_iter
iter1(output
);
539 distance_vector_iter
iter2(dv
);
540 while(!iter1
.is_empty()) {
541 assert(!iter2
.is_empty());
542 distance
*d1
= &iter1
.step()->d
;
543 distance
*d2
= &iter2
.step()->d
;
544 if (d1
->is_const() && d2
->is_const()) {
545 assert(d1
->dist()==d2
->dist());
547 direction newd
= direction(d1
->dir()|d2
->dir());
548 d1
->set_direction(newd
);
560 // initialize a distance vector to the same as another
562 distance_vector::distance_vector(distance_vector
* dv
)
568 distance_vector_iter
iterator(dv
);
569 for(; !iterator
.is_empty();) {
570 append(iterator
.step()->d
);
577 // print a distance vector
579 void distance_vector::print(FILE *str
)
582 fprintf(str
,"These vectors are independent \n");
585 distance_vector_iter
iterator(this);
586 for(; !iterator
.is_empty();) {
587 iterator
.step()->d
.print(str
);
597 void dvlist::print(FILE *str
)
600 fprintf(str
,"These vectors are independent \n");
602 dvlist_iter
iterator(this);
603 for(; !iterator
.is_empty();) {
604 iterator
.step()->dv
->print(str
);
611 void distance::print(FILE *str
)
614 fprintf(str
,"%d ",dist());
615 if(dist() > 0) assert(dir() == d_lt
);
616 else if(dist() == 0) assert(dir() == d_eq
);
617 else assert(dir() == d_gt
);
621 case d_lt
: fprintf(str
,"+ "); break; // lt
622 case d_gt
: fprintf(str
,"- "); break; // gt
623 case d_eq
: assert(0);
624 case d_le
: fprintf(str
,"+/0 "); break; // le
625 case d_ge
: fprintf(str
,"0/- "); break; // ge
626 case d_lg
: fprintf(str
,"+/- "); break; // lg
627 case d_star
: fprintf(str
,"* "); break;
634 // is distance vector 0
636 int distance_vector::is_zero()
641 distance_vector_iter
iterator(this);
642 for(; !iterator
.is_empty();) {
643 if (!(iterator
.step() -> is_zero())) {
651 /* turn leading >= into = */
652 void distance_vector::make_pos()
655 distance_vector_e
*dve
;
659 distance_vector_iter
iterator(this);
660 for(; !iterator
.is_empty();) {
661 dve
= iterator
.step();
663 if (d
.dir() == d_lt
) {
666 if (d
.dir() == d_gt
) {
669 if (d
.dir() == d_ge
) {
670 dve
-> d
.set_direction(d_eq
);
672 if (d
.dir() == d_lg
) {
675 if (d
.dir() == d_star
) {
678 if (d
.dir() == d_le
) {
681 /* (d.dir() == d_eq) */
688 // is distance vector positive
690 int distance_vector::is_pos()
697 distance_vector_iter
iterator(this);
698 for(; !iterator
.is_empty();) {
699 d
= iterator
.step() -> d
;
700 if (d
.dir() == d_lt
) {
703 if (d
.dir() == d_gt
) {
706 if (d
.dir() == d_ge
) {
709 if (d
.dir() == d_lg
) {
712 if (d
.dir() == d_star
) {
715 if ((d
.dir() == d_le
) || (d
.dir() == d_eq
));
722 // is distance vector negative
724 int distance_vector::is_neg()
731 distance_vector_iter
iterator(this);
732 for(; !iterator
.is_empty();) {
733 d
= iterator
.step() -> d
;
742 if (d
.dir() == d_star
)
744 if ((d
.dir() == d_ge
) || (d
.dir() == d_eq
));
751 // is distance vector a star
753 int distance_vector::is_star()
760 distance_vector_iter
iterator(this);
761 for(; !iterator
.is_empty();) {
762 d
= iterator
.step() -> d
;
765 if (d
.dir() == d_eq
);
774 // return level of dependence
776 int distance_vector::level()
784 distance_vector_iter
iterator(this);
785 for(i
= 1; !iterator
.is_empty(); i
++) {
786 d
= iterator
.step() -> d
;
787 if (!d
.is_zero() && !d
.is_star())
797 // return number of elements in graph
799 int distance_vector::size()
806 distance_vector_iter
iterator(this);
807 for(i
= 0; !iterator
.is_empty(); i
++) {
816 // return level of dependence
818 distance
*distance_vector::thresh(int level
)
824 distance_vector_iter
iterator(this);
825 for(i
= 1; !iterator
.is_empty(); i
++) {
826 d
= iterator
.step() -> d
;
828 return new distance(&d
);
831 return(new distance(0));
836 // return level of first non-= or * dependence
837 // return 0 if all ='s or *'s
839 int distance_vector::first_not_eq()
845 distance_vector_iter
iterator(this);
846 for(i
= 1; !iterator
.is_empty(); i
++) {
847 d
= iterator
.step() -> d
;
859 // return entry for level
861 distance
distance_vector::entry(int level
)
866 distance_vector_iter
iterator(this);
867 for(i
= 1; !iterator
.is_empty(); i
++) {
868 distance_vector_e
*e
= iterator
.step();
874 return(* new distance());
877 void distance_vector::set_entry(distance dd
,int level
)
882 distance_vector_iter
iterator(this);
883 for(i
= 1; !iterator
.is_empty(); i
++) {
884 distance_vector_e
*e
= iterator
.step();
896 void distance::negate()
904 case d_lt
: set_direction(d_gt
); break;
905 case d_gt
: set_direction(d_lt
); break;
906 case d_le
: set_direction(d_ge
); break;
907 case d_ge
: set_direction(d_le
); break;
914 // negate all the distances
916 void distance_vector::negate()
923 distance_vector_iter
iterator(this);
924 for(; !iterator
.is_empty();) {
925 d
= &(iterator
.step() -> d
);
934 // check which loop variables are actually used by array statements
935 /* a variable is unused if it and its prime is not used either in the */
936 /* expression nor in a triangular loop */
937 // also check which write variables are used, assume a1 is the write
938 void SetLoopUsed(int *loop_used
,int minnest
,int valid_dim
, int *lb_valid
,
939 int *ub_valid
, array_info_iter
*a1i
, array_info_iter
*a2i
,
940 tn_list
*al
,integer_matrix
*L
, integer_matrix
*U
,int num_symb
,
943 access_vector
*av1
, *av2
;
947 for (j
=0; j
<2*minnest
; j
++) loop_used
[j
+num_symb
]=0;
948 for (j
=0; j
<num_symb
; j
++) loop_used
[j
] = 1;
949 for (j
=0; j
<minnest
; j
++) write_used
[j
] = 0;
950 for (int i
=0; i
<valid_dim
; i
++) {
954 tn_list_iter
*loops
= new tn_list_iter(al
);
955 for (j
=2*(minnest
-1); j
>=0; j
-=2) {
956 if (av1
->val(loops
->step()) != 0) {
961 loops
= new tn_list_iter(al
);
962 for (j
=(2*minnest
)-1; j
>=0; j
-=2) {
963 if (av2
->val(loops
->step()) != 0) loop_used
[j
+n
]=1;
968 // check unused ones in case they're used in triangular loops
969 for (j
=1; j
<=2*minnest
; j
++) {
970 if (!loop_used
[j
-1+n
]) {
973 for (int i
=1; i
<=2*minnest
; i
++) {
974 int lbounds
= lb_valid
[i
+n
];
976 for (k
=ltotal
; k
<ltotal
+lbounds
; k
++) {
977 if (lb_valid
[i
+n
] && (*L
)[k
][j
+n
]) {
978 loop_used
[j
-1+n
] = 1;
979 write_used
[(j
-1)/2] = 1;
984 int ubounds
= ub_valid
[i
+n
];
985 for (k
=utotal
; k
<utotal
+ubounds
; k
++) {
986 if (ub_valid
[i
+n
] && (*U
)[k
][j
+n
]) {
987 loop_used
[j
-1+n
] = 1;
988 write_used
[(j
-1)/2] = 1;
996 // check if pair of unused is used
997 for (j
=0; j
<2*minnest
; j
+=2) {
998 if (loop_used
[j
+n
]) loop_used
[j
+1+n
] =1;
999 if (loop_used
[j
+1+n
]) loop_used
[j
+n
] =1;
1006 // use the tree_node_list and symbols to set a matrix of lower and upper bounds
1007 // symbolic variables are placed first
1009 void SetLU(tn_list
*al
, int DD
, integer_matrix
*L
, integer_matrix
*U
,
1011 boolean
*ub_valid
, access_list
*symbols
, int num_symb
,
1014 int is_good_symb(access_vector
*,access_list
*);
1017 // init lb_valid and ub_valid
1019 for (i
=0; i
<=DD
; i
++) {
1020 lb_valid
[i
] = ub_valid
[i
] = 0;
1023 // find out how many bounds there are
1024 tn_list_iter
*loops
= new tn_list_iter(al
);
1025 for (i
= DD
; i
>= 1+num_symb
; i
-=2) { // for each loop
1026 tree_node
*induct
= loops
->step();
1027 assert(induct
->kind() == TREE_FOR
);
1028 dep_for_annote
* df
= (dep_for_annote
*)induct
->peek_annote(k_dep_for_annote
);
1031 if (flow
) assert(df
->lb
->count() <= 1);
1032 array_info_iter
ai(df
->lb
);
1033 while (!ai
.is_empty()) { // for each bound
1034 access_vector
*lb
= ai
.step();
1035 if (is_good_symb(lb
,symbols
)) {
1044 if (flow
) assert(df
->ub
->count() <= 1);
1045 array_info_iter
ai2(df
->ub
);
1046 while (!ai2
.is_empty()) { // for each bound
1047 access_vector
*ub
= ai2
.step();
1048 if (is_good_symb(ub
,symbols
)) {
1055 L
->init(low_bounds
+1,DD
+1);
1056 U
->init(up_bounds
+1,DD
+1);
1058 // set bounds of induction variables
1060 loops
= new tn_list_iter(al
);
1061 int uconstr
= up_bounds
;
1062 int lconstr
= low_bounds
;
1063 for (i
= DD
; i
>=1+num_symb
; i
-=2) { // for each loop
1064 tree_node
*induct
= loops
->step();
1065 dep_for_annote
* df
= (dep_for_annote
*)induct
->peek_annote(k_dep_for_annote
);
1068 array_info_iter
ai(df
->lb
);
1071 while (!ai
.is_empty()) {
1072 access_vector
*lb
= ai
.step();
1073 if (is_good_symb(lb
,symbols
)) {
1075 (*L
)[lconstr
][0] = lb
->con
;
1076 (*L
)[lconstr
-lb_valid
[i
]][0] = lb
->con
;
1077 tn_list_iter
temp(al
);
1078 temp
.set(loops
->glist_iter::peek());
1080 for (j
=i
-2;j
>=1+num_symb
;j
-=2) {
1081 // for each induct element
1082 assert(!temp
.is_empty());
1083 tree_node
*element
= temp
.step();
1085 (*L
)[lconstr
-lb_valid
[i
]][j
-1]
1089 access_list_iter
temp_symb(symbols
);
1090 for (j
=num_symb
; j
>=1; j
--) {
1091 assert(!temp_symb
.is_empty());
1092 access_list_e
*e
= temp_symb
.step();
1094 (*L
)[lconstr
-lb_valid
[i
]][j
] =
1095 lb
->conregs
.val(e
->var());
1101 assert(count
== lb_valid
[i
]);
1102 lconstr
-= lb_valid
[i
];
1103 array_info_iter
ai2(df
->ub
);
1105 while (!ai2
.is_empty()) {
1106 access_vector
*ub
= ai2
.step();
1107 if (is_good_symb(ub
,symbols
)) {
1109 (*U
)[uconstr
][0] = ub
->con
;
1110 (*U
)[uconstr
-ub_valid
[i
]][0] = ub
->con
;
1111 tn_list_iter
temp(al
);
1112 temp
.set(loops
->glist_iter::peek());
1114 for (j
=i
-2;j
>=1+num_symb
;j
-=2) {
1115 assert(!temp
.is_empty());
1116 tree_node
*element
= temp
.step();
1118 (*U
)[uconstr
-ub_valid
[i
]][j
-1]=
1122 access_list_iter
temp_symb(symbols
);
1123 for (j
=num_symb
; j
>=1; j
--) {
1124 assert(!temp_symb
.is_empty());
1125 access_list_e
*e
= temp_symb
.step();
1127 (*U
)[uconstr
-ub_valid
[i
]][j
] =
1128 ub
->conregs
.val(e
->var());
1133 assert(count
== ub_valid
[i
]);
1134 uconstr
-= ub_valid
[i
];
1141 // use the bit vector used to add unused components back into dvector
1142 // if not flow any unused component is a star
1143 void distance_vector::add_unused(boolean
*used
, int n
)
1145 if (indep()) return;
1146 for (int i
=0; i
<n
; i
+=2) {
1149 this->append(*new distance()); // XXX
1151 this->append(this->pop()->d
);
1157 // use the bit vector used to add unused components back into dir_array
1158 // any unused component is a star
1159 void dir_list::add_unused(boolean
*used
, int n
)
1162 dir_list
*temp
= this;
1164 dir_array
*dir
= temp
->data
;
1165 distance
*new_data
= new distance
[n
/2];
1167 for (int i
=0; i
<n
; i
+=2) {
1170 new_data
[i
/2].set_direction(d_star
);
1172 new_data
[i
/2] = dir
->data
[i2
];
1177 dir
->data
= new_data
;
1187 // is this access vector good
1188 // it's bad if memregs or conpaths or mod_this is not nil
1189 inline int is_good_symb(access_vector
*av1
)
1191 return (!av1
->too_messy
&& av1
->memregs
.is_empty() &&
1195 // same as above but can only refer to symbols on list
1196 int is_good_symb(access_vector
*av1
,access_list
*symbols
)
1198 if (!is_good_symb(av1
)) {
1201 access_list
*temp
= new access_list
;
1202 temp
->unite(symbols
,&av1
->conregs
);
1203 int answer
= (temp
->count() == symbols
->count());
1208 // eliminate dimensions which have anything but conregs and induct vars
1209 // and where mod_this is not nil
1210 // return the number of valid dims
1211 int dvlist::elim_bad_symb(array_info
*a1
, array_info
*a2
)
1213 array_info_iter
ai1(a1
);
1214 array_info_iter
ai2(a2
);
1219 while (!ai1
.is_empty() && !ai2
.is_empty()) {
1220 access_vector
*av1
= ai1
.step();
1221 access_vector
*av2
= ai2
.step();
1223 if(is_good_symb(av1
) && is_good_symb(av2
)) {
1225 newa1
.append(new access_vector(av1
));
1226 newa2
.append(new access_vector(av2
));
1229 a1
->clear(); a1
->glist::append(&newa1
);
1230 a2
->clear(); a2
->glist::append(&newa2
);
1231 newa1
.clear(); newa2
.clear();
1235 // return a list of all symbols used in the array_info
1236 // only looks at conregs
1237 access_list
*dvlist::find_symb(array_info
*a
)
1239 access_list
*al
= new access_list();
1240 array_info_iter
*ai
= new array_info_iter(a
);
1241 while (!ai
->is_empty()) {
1242 access_vector
*av
= ai
->step();
1243 al
->unite(&av
->conregs
);
1248 // return a list of all symbols used in either array_info
1249 // disregard case where for the same dimension, both
1250 // sybols have the same value (ie a[n] vrs a[n])
1251 // only looks at conregs
1252 access_list
*dvlist::find_symbs(array_info
*a1
, array_info
*a2
)
1254 access_list
*al
= new access_list();
1255 array_info_iter
ai1(a1
);
1256 array_info_iter
ai2(a2
);
1257 while(!ai1
.is_empty()) {
1258 assert(!ai2
.is_empty());
1259 access_list
*temp
= unite_unequals(&ai1
.step()->conregs
,&ai2
.step()->conregs
);
1264 assert(ai2
.is_empty());
1270 // return the union of two access_lists throwing out elements with the
1272 access_list
*unite_unequals(access_list
*a1
, access_list
*a2
)
1274 access_list
*result
= new access_list();
1276 access_list_iter
ai(a1
);
1277 while (!ai
.is_empty()) {
1278 access_list_e
*e
= ai
.step();
1279 access_list_e
*e2
= a2
->search(e
->var());
1280 if (!e2
|| (e2
->val() != e
->val())) {
1281 result
->enter(e
->var(),e
->val());
1285 access_list_iter
ai2(a2
);
1286 while (!ai2
.is_empty()) {
1287 access_list_e
*e
= ai2
.step();
1288 access_list_e
*e2
= a1
->search(e
->var());
1289 if (!e2
|| (e2
->val() != e
->val())) {
1290 result
->enter(e
->var(),e
->val());
1296 int distance_vector::operator==(distance_vector
&d
)
1298 distance_vector_iter
ti(this),di(&d
);
1299 while(!ti
.is_empty() && !di
.is_empty()) {
1300 if(ti
.step()->d
!= di
.step()->d
)
1303 return ti
.is_empty() && di
.is_empty();
1306 static void insert_dvector(dvlist
*l
,distance_vector
*d
)
1308 // don't insert any duplicates ... pretty dumb
1310 while(!di
.is_empty()) {
1311 if(*di
.step()->dv
== *d
) {
1316 l
->append(new dvlist_e(d
));
1319 static void lexpos_decomp(dvlist
*l
, distance_vector
*d
,
1320 boolean strict_pos
=FALSE
)
1322 assert(d
->ind
== 0);
1323 distance_vector_iter
di(d
);
1325 for(int i
=1; !di
.is_empty(); i
++) {
1326 distance_vector_e
*dd
= di
.step();
1327 switch(dd
->d
.dir()) {
1329 insert_dvector(l
,d
);
1338 distance_vector
*copy1
= new distance_vector(d
);
1339 dd
->d
.set_direction(d_eq
);
1341 ddd
.set_direction(d_lt
);
1342 copy1
->set_entry(ddd
,i
);
1343 insert_dvector(l
,copy1
);
1347 dd
->d
.set_direction(d_eq
);
1350 dd
->d
.set_direction(d_lt
);
1351 insert_dvector(l
,d
);
1358 // if strictly lex. positive, DO NOT include loop independent dependences
1360 insert_dvector(l
,d
);
1364 void dvlist::make_lexpos(boolean strict_pos
)
1366 // make a list of dependence vectors all lexicographically positive.
1367 // actually, makes it lexpos or zero, unless strict_pos is set to TRUE.
1368 // Those who wish can remove blatantly redundant entries from list.
1374 while(!l
.is_empty()) {
1375 dvlist_e
*de
= (dvlist_e
*)l
.pop();
1376 lexpos_decomp(this,de
->dv
,strict_pos
);