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 #ifdef USE_PCH
00039 #include "lno_pch.h"
00040 #endif // USE_PCH
00041 #pragma hdrstop
00042
00043 #include <math.h>
00044 #include <sys/types.h>
00045 #include <limits.h>
00046 #include "pu_info.h"
00047 #include "lnoutils.h"
00048 #include "lnopt_main.h"
00049 #include "stdlib.h"
00050 #include "fiz_fuse.h"
00051 #include "ara.h"
00052 #include "cross_snl.h"
00053 #include "snl_utils.h"
00054 #include "cross_cache.h"
00055
00056
00057 #define SMALL_CONST 5
00058 #define ESTIMATED_CONST 100
00059 #define ABS(x) (((x) < 0) ? -(x) : (x))
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 INT Get_Range(ACCESS_VECTOR *lo, ACCESS_VECTOR *hi)
00070 {
00071 if (hi == NULL)
00072 return 1;
00073
00074
00075 BOOL indices_same = TRUE;
00076
00077 for (INT i = 0; i < lo->Nest_Depth(); ++i) {
00078 if (lo->Loop_Coeff(i) != hi->Loop_Coeff(i)) {
00079 indices_same = FALSE;
00080 break;
00081 }
00082 }
00083
00084 if (indices_same == FALSE) {
00085
00086 return -1;
00087 }
00088
00089
00090 if (lo->Lin_Symb != NULL && hi->Lin_Symb != NULL) {
00091 if ( *(lo->Lin_Symb) == *(hi->Lin_Symb)) {
00092 return hi->Const_Offset - lo->Const_Offset + 1;
00093 } else {
00094
00095 return ESTIMATED_CONST;
00096 }
00097 } else {
00098
00099 if (lo->Lin_Symb == NULL && hi->Lin_Symb == NULL) {
00100 return hi->Const_Offset - lo->Const_Offset;
00101 } else {
00102 return ESTIMATED_CONST + (hi->Const_Offset - lo->Const_Offset) + 1;
00103 }
00104 }
00105
00106 return -1;
00107
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 BOOL Is_Similar(ACCESS_VECTOR *acv1, ACCESS_VECTOR *acv2)
00123 {
00124 BOOL is_unprojected = FALSE;
00125
00126
00127
00128 INT j;
00129 for (j = 0; j < acv1->Nest_Depth(); ++j) {
00130 if (acv1->Loop_Coeff(j) != 0) {
00131 is_unprojected = TRUE;
00132 if (j >= acv2->Nest_Depth()) {
00133 return FALSE;
00134 }
00135
00136
00137 if (acv1->Loop_Coeff(j) != acv2->Loop_Coeff(j)) {
00138 return FALSE;
00139 }
00140
00141
00142 if (acv1->Lin_Symb != NULL) {
00143 if (acv2->Lin_Symb != NULL) {
00144 if (!(*(acv1->Lin_Symb) == *(acv2->Lin_Symb))) {
00145 return FALSE;
00146 }
00147 } else {
00148 return FALSE;
00149 }
00150 } else {
00151 if (acv2->Lin_Symb != NULL) {
00152 return FALSE;
00153 }
00154 }
00155
00156
00157 if (acv1->Const_Offset != acv2->Const_Offset) {
00158 return FALSE;
00159 }
00160 }
00161 }
00162
00163
00164 for (j = 0; j < acv2->Nest_Depth(); ++j) {
00165 if (acv2->Loop_Coeff(j) != 0) {
00166 is_unprojected = TRUE;
00167
00168 if (j >= acv1->Nest_Depth()) {
00169 return FALSE;
00170 }
00171
00172
00173 if (acv1->Loop_Coeff(j) != acv2->Loop_Coeff(j)) {
00174 return FALSE;
00175 }
00176
00177
00178 if (acv2->Lin_Symb != NULL) {
00179 if (acv1->Lin_Symb != NULL) {
00180 if (!(*(acv2->Lin_Symb) == *(acv1->Lin_Symb))) {
00181 return FALSE;
00182 }
00183 } else {
00184 return FALSE;
00185 }
00186 } else {
00187 if (acv1->Lin_Symb != NULL) {
00188 return FALSE;
00189 }
00190 }
00191
00192
00193 if (acv2->Const_Offset != acv1->Const_Offset) {
00194 return FALSE;
00195 }
00196 }
00197 }
00198
00199
00200 if (! is_unprojected) {
00201 if (acv1->Lin_Symb != NULL) {
00202 if (acv2->Lin_Symb != NULL) {
00203 if (!(*(acv1->Lin_Symb) == *(acv2->Lin_Symb))) {
00204 return FALSE;
00205 }
00206 } else {
00207 return FALSE;
00208 }
00209 } else {
00210 if (acv1->Lin_Symb != NULL) {
00211 return FALSE;
00212 }
00213 }
00214
00215 if (ABS(acv1->Const_Offset - acv2->Const_Offset) > SMALL_CONST) {
00216 return FALSE;
00217 }
00218 }
00219
00220 return TRUE;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 BOOL Is_Equal(ACCESS_VECTOR *acv1, ACCESS_VECTOR *acv2)
00231 {
00232
00233
00234 INT j;
00235 for (j = 0; j < acv1->Nest_Depth(); ++j) {
00236 if (acv1->Loop_Coeff(j) != 0) {
00237 if (j >= acv2->Nest_Depth()) {
00238 return FALSE;
00239 }
00240
00241
00242 if (acv1->Loop_Coeff(j) != acv2->Loop_Coeff(j)) {
00243 return FALSE;
00244 }
00245 }
00246 }
00247
00248
00249 for (j = 0; j < acv2->Nest_Depth(); ++j) {
00250 if (acv2->Loop_Coeff(j) != 0) {
00251
00252 if (j >= acv1->Nest_Depth()) {
00253 return FALSE;
00254 }
00255
00256
00257 if (acv1->Loop_Coeff(j) != acv2->Loop_Coeff(j)) {
00258 return FALSE;
00259 }
00260
00261 }
00262 }
00263
00264
00265 if (acv2->Lin_Symb != NULL) {
00266 if (acv1->Lin_Symb != NULL) {
00267 if (!(*(acv2->Lin_Symb) == *(acv1->Lin_Symb))) {
00268 return FALSE;
00269 }
00270 } else {
00271 return FALSE;
00272 }
00273 } else {
00274 if (acv1->Lin_Symb != NULL) {
00275 return FALSE;
00276 }
00277 }
00278
00279
00280 if (acv2->Const_Offset != acv1->Const_Offset) {
00281 return FALSE;
00282 }
00283
00284 return TRUE;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294 BOOL Are_Independent_Regions(CACHE_REGION *c1, CACHE_REGION *c2, ARA_LOOP_INFO *ara_info)
00295 {
00296 if (c1->Is_Messy() || c2->Is_Messy())
00297 return FALSE;
00298 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00299 return TRUE;
00300 }
00301
00302 REGION *r1 = c1->Get_Region();
00303 REGION *r2 = c2->Get_Region();
00304
00305 REGION *r = Region_Intersect(*r1, *r2, *ara_info);
00306
00307 if (r != NULL) {
00308 CXX_DELETE(r, &ARA_memory_pool);
00309 return FALSE;
00310 } else {
00311 return TRUE;
00312 }
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 BOOL Is_Subset_Region(CACHE_REGION *c1, CACHE_REGION *c2, ARA_LOOP_INFO *ara_info)
00322 {
00323 if (c1->Is_Messy() || c2->Is_Messy())
00324 return FALSE;
00325 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00326 return FALSE;
00327 }
00328
00329 REGION *r1 = c1->Get_Region();
00330 REGION *r2 = c2->Get_Region();
00331
00332 INT res = Region_Compare(*r1, *r2, *ara_info);
00333 if (res == 1 || res == 3) {
00334 return TRUE;
00335 }
00336
00337 return FALSE;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 INT Compare_Cache_Regions(CACHE_REGION *c1, CACHE_REGION *c2, ARA_LOOP_INFO *ara_info)
00352 {
00353 if (c1->Is_Messy() || c2->Is_Messy())
00354 return -1;
00355 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00356 return -1;
00357 }
00358
00359 REGION *r1 = c1->Get_Region();
00360 REGION *r2 = c2->Get_Region();
00361
00362 INT res = Region_Compare(*r1, *r2, *ara_info);
00363 if (res == 1 || res == 3 || res == 2) {
00364 return res;
00365 }
00366
00367 return -1;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 BOOL Are_Similar_Dimensions(CACHE_REGION *c1, CACHE_REGION *c2, INT32* dist, INT ndist)
00380 {
00381 if (c1->Is_Messy() || c2->Is_Messy())
00382 return FALSE;
00383
00384 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00385 return FALSE;
00386 }
00387
00388 REGION *r1 = c1->Get_Region();
00389 REGION *r2 = c2->Get_Region();
00390
00391
00392
00393
00394
00395
00396
00397
00398 if (r1->Num_Dim() != r2->Num_Dim())
00399 return FALSE;
00400
00401 for (INT i = 0; i < ndist; ++i) {
00402 AXLE_NODE *ax1 = &r1->Dim(dist[i]);
00403 AXLE_NODE *ax2 = &r2->Dim(dist[i]);
00404
00405
00406
00407 CON_PAIR *lo1 = ax1->lo;
00408 CON_PAIR *lo2 = ax2->lo;
00409
00410 if (lo1->_coeff != NULL || lo2->_coeff != NULL) {
00411
00412 return FALSE;
00413 }
00414
00415
00416
00417 if (!Is_Similar(lo1->_ac_v, lo2->_ac_v)) {
00418 return FALSE;
00419 }
00420
00421
00422 if (ax2->up != NULL && ax1->up != NULL) {
00423 if (ax2->up->_coeff != NULL || ax1->up->_coeff != NULL) {
00424 return FALSE;
00425 }
00426
00427 if (!Is_Similar(ax2->up->_ac_v, ax1->up->_ac_v)) {
00428 return FALSE;
00429 }
00430 } else if (!(ax2->up == NULL && ax1->up == NULL)) {
00431 return FALSE;
00432 }
00433 }
00434 return TRUE;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 BOOL Are_Similar_Regions(CACHE_REGION *c1, CACHE_REGION *c2)
00444 {
00445
00446 if (c1->Is_Messy() || c2->Is_Messy())
00447 return FALSE;
00448
00449 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00450 return FALSE;
00451 }
00452
00453 REGION *r1 = c1->Get_Region();
00454 REGION *r2 = c2->Get_Region();
00455
00456
00457
00458
00459
00460
00461
00462
00463 if (r1->Num_Dim() != r2->Num_Dim())
00464 return FALSE;
00465
00466 int ndims = r1->Num_Dim();
00467 for (INT i = 0; i < ndims; ++i) {
00468 AXLE_NODE *ax1 = &r1->Dim(i);
00469 AXLE_NODE *ax2 = &r2->Dim(i);
00470
00471
00472
00473 CON_PAIR *lo1 = ax1->lo;
00474 CON_PAIR *lo2 = ax2->lo;
00475
00476 if (lo1->_coeff != NULL || lo2->_coeff != NULL) {
00477
00478 return FALSE;
00479 }
00480
00481
00482
00483 if (!Is_Similar(lo1->_ac_v, lo2->_ac_v)) {
00484 return FALSE;
00485 }
00486
00487
00488 if (ax2->up != NULL && ax1->up != NULL) {
00489 if (ax2->up->_coeff != NULL || ax1->up->_coeff != NULL) {
00490 return FALSE;
00491 }
00492
00493 if (!Is_Similar(ax2->up->_ac_v, ax1->up->_ac_v)) {
00494 return FALSE;
00495 }
00496 } else if (!(ax2->up == NULL && ax1->up == NULL)) {
00497 return FALSE;
00498 }
00499 }
00500 return TRUE;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 CACHE_REGION *Merge_Regions(CACHE_REGION *c1, CACHE_REGION *c2, ARA_LOOP_INFO *ara_info )
00512 {
00513 if (c1->Is_Messy() || c2->Is_Messy())
00514 return NULL;
00515
00516 if (c1->Get_Ref()->Array() != c2->Get_Ref()->Array()) {
00517 return NULL;
00518 }
00519
00520 if (c1->Type() != c2->Type()) {
00521 return NULL;
00522 }
00523
00524 if (c1->Type() == EXCLUSIVE || c1->Type() == REPLICATED) {
00525
00526 REGION *newregion = Region_Union(*(c1->Get_Region()), *(c2->Get_Region()), *ara_info);
00527 if (newregion == NULL) {
00528 return NULL;
00529 } else {
00530
00531 ARA_REF *newref = CXX_NEW (ARA_REF(*c1->Get_Ref()), &LNO_local_pool);
00532
00533
00534 while (!newref->Image().Is_Empty()) {
00535 REGION * tmp = newref->Image().Remove_Headnode();
00536 }
00537 newref->Image().Append(newregion);
00538
00539
00540
00541 CACHE_REGION *newcr = CXX_NEW(CACHE_REGION(c1, newref), &LNO_local_pool);
00542 return newcr;
00543 }
00544 } else {
00545
00546 if (c1->N_Dist() != c2->N_Dist()) {
00547 return NULL;
00548 }
00549
00550 INT* dist1 = c1->Dist();
00551 INT* dist2 = c2->Dist();
00552
00553
00554 INT i;
00555 for (i = 0; i < c1->N_Dist(); ++i) {
00556 INT dim = dist1[i];
00557 BOOL found = FALSE;
00558
00559 for (INT j = 0; j < c2->N_Dist(); ++j) {
00560 if (dist2[j] == dim) {
00561 found = TRUE;
00562 break;
00563 }
00564 }
00565
00566 if (!found) {
00567 return NULL;
00568 }
00569 }
00570
00571
00572
00573 REGION *r1 = c1->Get_Region();
00574 REGION *r2 = c2->Get_Region();
00575
00576 for (i = 0; i < c1->N_Dist(); ++i) {
00577 AXLE_NODE *ax1 = &r1->Dim(dist1[i]);
00578 AXLE_NODE *ax2 = &r2->Dim(dist1[i]);
00579 CON_PAIR *lo1 = ax1->lo;
00580 CON_PAIR *lo2 = ax2->lo;
00581 CON_PAIR *hi1 = ax1->up;
00582 CON_PAIR *hi2 = ax2->up;
00583
00584 if (lo1->_coeff != NULL || lo2->_coeff != NULL
00585 || hi1->_coeff != NULL || hi2->_coeff != NULL) {
00586
00587 return NULL;
00588 }
00589
00590 if (!Is_Equal(lo1->_ac_v, lo2->_ac_v)) {
00591 return NULL;
00592 }
00593
00594
00595 if (hi1 != NULL || hi2 != NULL) {
00596 if (hi1 == NULL || hi2 == NULL) {
00597 return NULL;
00598 }
00599
00600 if (!Is_Equal(hi1->_ac_v, hi2->_ac_v)) {
00601 return NULL;
00602 }
00603 }
00604 }
00605
00606
00607
00608
00609 REGION *newregion = Region_Union(*r1, *r2, *ara_info);
00610 if (newregion == NULL) {
00611 return NULL;
00612 } else {
00613
00614 ARA_REF *newref = CXX_NEW (ARA_REF(*c1->Get_Ref()), &LNO_local_pool);
00615
00616
00617 while (!newref->Image().Is_Empty()) {
00618 REGION * tmp = newref->Image().Remove_Headnode();
00619 }
00620 newref->Image().Append(newregion);
00621
00622
00623 CACHE_REGION *newcr = CXX_NEW(CACHE_REGION(c1, newref), &LNO_local_pool);
00624 return newcr;
00625 }
00626
00627 }
00628
00629 return NULL;
00630
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 CACHE_REGION::CACHE_REGION(ARA_REF_INFO *ref, ARRAY_SNL_INFO *asi, UINT32 parallel_loop)
00647 {
00648 _dist = NULL;
00649 _offsets = NULL;
00650 _ranges = NULL;
00651
00652
00653 if (parallel_loop == 0) {
00654
00655 if (ref->Is_Messy()) {
00656 _is_messy = TRUE;
00657 return;
00658 } else {
00659 _is_messy = FALSE;
00660
00661 _type = EXCLUSIVE;
00662 _reg = ref->Get_Proj_Ref();
00663 _dims = ref->Dim();
00664 _ndist = 0;
00665 return;
00666 }
00667 } else {
00668 if (ref->Is_Messy()) {
00669 _is_messy = TRUE;
00670 return;
00671 }
00672
00673 _reg = ref->Get_Proj_Ref();
00674 _dims = ref->Dim();
00675 _is_messy = FALSE;
00676
00677
00678 WN* snl_root = asi->Get_SNL_Root();
00679 WN* wn_parallel = (parallel_loop != 1) ? SNL_Get_Inner_Snl_Loop(snl_root, parallel_loop) :
00680 snl_root;
00681 ARA_REF *orig_ref = ref->Get_Ref();
00682
00683
00684
00685
00686
00687 REGION_ITER iter(&orig_ref->Image());
00688 REGION *r = iter.First();
00689
00690
00691
00692 _dist = CXX_NEW_ARRAY(INT32, _dims, &LNO_local_pool);
00693 _offsets = CXX_NEW_ARRAY(INT32, _dims, &LNO_local_pool);
00694 _ranges = CXX_NEW_ARRAY(INT32, _dims, &LNO_local_pool);
00695 _ndist = 0;
00696
00697 for (INT i = 0; i < _dims; ++i) {
00698 AXLE_NODE *a = &r->Dim(i);
00699 CON_PAIR *lo = a->lo;
00700 CON_PAIR *up = a->up;
00701 INT step = a->step;
00702
00703 if (lo->_coeff != NULL || (up != NULL && (up->_coeff != NULL || ABS(step) != 1))) {
00704 _is_messy = TRUE;
00705 return;
00706
00707 }
00708
00709 INT loop_start_depth = Do_Loop_Depth(snl_root);
00710 INT loop_var = loop_start_depth + parallel_loop - 1;
00711 ACCESS_VECTOR *acv = lo->_ac_v;
00712
00713 if (acv->Loop_Coeff(loop_var) == 0)
00714 continue;
00715
00716
00717 if (acv->Contains_Lin_Symb() || acv->Contains_Non_Lin_Symb()) {
00718 _is_messy = TRUE;
00719 return;
00720 }
00721
00722
00723
00724 for (INT j = 0; j < asi->Get_Depth(); ++j) {
00725
00726 if (j == parallel_loop - 1)
00727 continue;
00728
00729 if (acv->Loop_Coeff(j+loop_start_depth) != 0) {
00730 _is_messy = TRUE;
00731 return;
00732 }
00733 }
00734
00735
00736
00737
00738 _dist[_ndist] = (acv->Loop_Coeff(loop_var) > 0) ? i : -i;
00739 _offsets[_ndist] = acv->Const_Offset;
00740
00741 if (up == NULL) {
00742 _ranges[_ndist] = 0;
00743 } else {
00744 if (up->_ac_v->Contains_Lin_Symb() || up->_ac_v->Contains_Non_Lin_Symb()) {
00745 _is_messy = TRUE;
00746 return;
00747 }
00748
00749
00750 for (INT k = 0; k <= acv->Nest_Depth(); ++k) {
00751 if (acv->Loop_Coeff(k) != up->_ac_v->Loop_Coeff(k)) {
00752 _is_messy = TRUE;
00753 return;
00754 }
00755 }
00756
00757
00758 _ranges[_ndist] = up->_ac_v->Const_Offset;
00759 }
00760
00761 _ndist++;
00762 }
00763
00764 if (_ndist == 0) {
00765
00766 _type = REPLICATED;
00767 } else if (_ndist == 1) {
00768 _type = DISTRIBUTED;
00769 } else if (_ndist > 1) {
00770
00771 _is_messy = TRUE;
00772 return;
00773 }
00774
00775 return;
00776 }
00777 }
00778
00779
00780 CACHE_REGION::CACHE_REGION(CACHE_REGION *cr)
00781 {
00782 _type = cr->_type;
00783 _reg = cr->_reg;
00784 _dims = cr->_dims;
00785 if (cr->_ndist > 0) {
00786 _dist = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00787 _ranges = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00788 _offsets = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00789 for (INT i = 0; i < _ndist; ++i) {
00790 _dist[i] = cr->_dist[i];
00791 _ranges[i] = cr->_ranges[i];
00792 _offsets[i] = cr->_offsets[i];
00793 }
00794 } else {
00795 _dist = NULL;
00796 _ranges = NULL;
00797 _offsets = NULL;
00798 }
00799
00800 _ndist = cr->_ndist;
00801 _is_messy = cr->_is_messy;
00802 }
00803
00804 CACHE_REGION::CACHE_REGION(CACHE_REGION *cr, ARA_REF *ref)
00805 {
00806 _type = cr->_type;
00807 _reg = ref;
00808 _dims = cr->_dims;
00809 if (cr->_ndist > 0) {
00810 _dist = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00811 _ranges = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00812 _offsets = CXX_NEW_ARRAY(INT32, cr->_ndist, &LNO_local_pool);
00813 for (INT i = 0; i < cr->_ndist; ++i) {
00814 _dist[i] = cr->_dist[i];
00815 _ranges[i] = cr->_ranges[i];
00816 _offsets[i] = cr->_offsets[i];
00817 }
00818 } else {
00819 _dist = NULL;
00820 _ranges = NULL;
00821 _offsets = NULL;
00822 }
00823
00824 _ndist = cr->_ndist;
00825 _is_messy = cr->_is_messy;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 INT32 CACHE_REGION::Region_Size(void)
00835 {
00836 if (_is_messy)
00837 return -1;
00838
00839
00840
00841
00842
00843 REGION *r1 = Get_Region();
00844 INT32 size = 1;
00845
00846 for (INT i = 0; i < r1->Num_Dim(); ++i) {
00847 AXLE_NODE *ax = &r1->Dim(i);
00848 CON_PAIR *lo = ax->lo;
00849 CON_PAIR *hi = ax->up;
00850
00851
00852 if (lo->_coeff != NULL || (hi != NULL && hi->_coeff != NULL)) {
00853 return -1;
00854 }
00855
00856 if (hi != NULL) {
00857
00858 INT range = Get_Range(lo->_ac_v, hi->_ac_v);
00859
00860 if (range == -1)
00861 return -1;
00862 else
00863 size = range * size;
00864 }
00865 }
00866
00867 return size;
00868 }
00869
00870
00871
00872
00873
00874
00875
00876 INT32 CACHE_REGION::Intersect_Region(CACHE_REGION *c, ARA_LOOP_INFO *ara_info)
00877 {
00878 if (this->Is_Messy() || c->Is_Messy()) {
00879 return -1;
00880 }
00881
00882 if (this->Get_Ref()->Array() != c->Get_Ref()->Array()) {
00883 return -1;
00884 }
00885
00886 REGION *r1 = this->Get_Region();
00887 REGION *r2 = c->Get_Region();
00888 REGION *r = Region_Intersect(*r1, *r2, *ara_info);
00889
00890 if (r == NULL) {
00891 return 0;
00892 } else {
00893 INT32 size = 1;
00894
00895 for (INT i = 0; i < r->Num_Dim(); ++i) {
00896 AXLE_NODE *ax = &r->Dim(i);
00897 CON_PAIR *lo = ax->lo;
00898 CON_PAIR *hi = ax->up;
00899
00900
00901 if (lo->_coeff != NULL || (hi != NULL && hi->_coeff != NULL)) {
00902 return -1;
00903 }
00904
00905 if (hi != NULL) {
00906
00907 INT range = Get_Range(lo->_ac_v, hi->_ac_v);
00908
00909 if (range == -1)
00910 return -1;
00911 else
00912 size = range * size;
00913 }
00914 }
00915
00916 return size;
00917 }
00918 }
00919
00920 void CACHE_REGION::Print(FILE *file)
00921 {
00922 fprintf(file, "Type : ");
00923 switch(_type) {
00924 case DISTRIBUTED : fprintf(file, "DISTRIBUTED\n"); break;
00925 case REPLICATED : fprintf(file, "REPLICATED\n"); break;
00926 case EXCLUSIVE : fprintf(file, "EXCLUSIVE\n"); break;
00927 default : fprintf(file, "UNKNOWN\n"); break;
00928 }
00929
00930 fprintf(file, "Messy : %s\n", (_is_messy) ? "TRUE" : "FALSE");
00931
00932 fprintf(file, "Region : ");
00933 _reg->Print(file);
00934
00935 if (_type == DISTRIBUTED) {
00936 fprintf(file, "NDIST : %d\n", _ndist);
00937 for (INT i = 0; i < _ndist; ++i) {
00938 fprintf(file, "dim = %d offset = %d range = %d\n", _dist[i], _offsets[i], _ranges[i]);
00939 }
00940 }
00941 }
00942
00943
00944 CACHE_CONTENTS::CACHE_CONTENTS(CACHE_TYPE type, UINT64 size, INT32 nprocs,
00945 ARA_LOOP_INFO *ara_info ) :
00946 _reg_list()
00947 {
00948 _type = type;
00949 _size = size;
00950 _nprocs = nprocs;
00951 _ara_info = ara_info;
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961 void CACHE_CONTENTS::Add_Region(CACHE_REGION *c, ACCESS_TYPE atype)
00962 {
00963 switch (c->Type()) {
00964 case DISTRIBUTED : {
00965 Add_Region_Distributed(c, atype);
00966 break;
00967 }
00968 case REPLICATED : {
00969 Add_Region_Replicated(c, atype);
00970 break;
00971 }
00972 case EXCLUSIVE : {
00973 Add_Region_Exclusive(c, atype);
00974 break;
00975 }
00976 default : {
00977 FmtAssert(0, ("Uknown cache region type"));
00978 }
00979 }
00980 }
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 void CACHE_CONTENTS::Add_Region_Distributed(CACHE_REGION *c, ACCESS_TYPE atype)
00999 {
01000 BOOL add_region = TRUE;
01001
01002 CACHE_REGION_ITER iter(&_reg_list);
01003 CACHE_REGION * prev = NULL;
01004 CACHE_REGION * curr = iter.First();
01005
01006 while (!iter.Is_Empty()) {
01007 if (!Are_Independent_Regions(c, curr, _ara_info)) {
01008 if (Are_Similar_Regions(c, curr)) {
01009 if (atype != CACHE_READ_ONLY) {
01010 CXX_DELETE(_reg_list.Remove(prev,curr), &LNO_local_pool);
01011 prev = NULL;
01012 iter.Init(&_reg_list);
01013 curr = iter.First();
01014 }
01015 } else {
01016
01017
01018
01019
01020
01021 }
01022 }
01023 prev = curr;
01024 curr = iter.Next();
01025 }
01026
01027 _reg_list.Append(c);
01028 }
01029
01030
01031 void CACHE_CONTENTS::Add_Region_Replicated(CACHE_REGION *c, ACCESS_TYPE atype)
01032 {
01033 BOOL add_region = TRUE;
01034
01035 CACHE_REGION_ITER iter(&_reg_list);
01036 CACHE_REGION * prev = NULL;
01037 CACHE_REGION * curr = iter.First();
01038
01039 while (!iter.Is_Empty()) {
01040 if (!Are_Independent_Regions(c, curr, _ara_info)) {
01041 if (Are_Similar_Regions(c, curr)) {
01042 if (atype != CACHE_READ_ONLY) {
01043 CXX_DELETE(_reg_list.Remove(prev,curr), &LNO_local_pool);
01044 prev = NULL;
01045 iter.Init(&_reg_list);
01046 curr = iter.First();
01047 }
01048 } else {
01049
01050
01051
01052
01053
01054 }
01055 }
01056 prev = curr;
01057 curr = iter.Next();
01058 }
01059
01060 _reg_list.Append(c);
01061 }
01062
01063
01064 void CACHE_CONTENTS::Add_Region_Exclusive(CACHE_REGION *c, ACCESS_TYPE atype)
01065 {
01066 BOOL add_region = TRUE;
01067
01068 CACHE_REGION_ITER iter(&_reg_list);
01069 CACHE_REGION * prev = NULL;
01070 CACHE_REGION * curr = iter.First();
01071
01072 while (!iter.Is_Empty()) {
01073 if (!Are_Independent_Regions(c, curr, _ara_info)) {
01074 if (Are_Similar_Regions(c, curr)) {
01075 if (atype != CACHE_READ_ONLY) {
01076 CXX_DELETE(_reg_list.Remove(prev,curr), &LNO_local_pool);
01077 prev = NULL;
01078 iter.Init(&_reg_list);
01079 curr = iter.First();
01080 }
01081 } else {
01082
01083
01084
01085
01086
01087 }
01088 }
01089 prev = curr;
01090 curr = iter.Next();
01091 }
01092
01093 _reg_list.Append(c);
01094 }
01095
01096
01097
01098
01099
01100 void CACHE_CONTENTS::Compact_Cache(void)
01101 {
01102 CACHE_REGION_ITER iter(&_reg_list);
01103 CACHE_REGION_LIST *crl = CXX_NEW(CACHE_REGION_LIST, &LNO_local_pool);
01104
01105 while (!_reg_list.Is_Empty()) {
01106 CACHE_REGION * curr = _reg_list.Remove_Headnode();
01107
01108 CACHE_REGION_ITER piter(crl);
01109 CACHE_REGION *prev = NULL;
01110 CACHE_REGION *pcur = piter.First();
01111 CACHE_REGION * add_reg = curr;
01112
01113 while (!piter.Is_Empty()) {
01114
01115 if (add_reg->Get_Ref()->Array() != pcur->Get_Ref()->Array() ||
01116 pcur->Type() != add_reg->Type()) {
01117 prev = pcur;
01118 pcur = piter.Next();
01119 continue;
01120 }
01121
01122
01123 CACHE_REGION *newcurr = Merge_Regions(add_reg, pcur, _ara_info);
01124 if (newcurr != NULL) {
01125 crl->Remove(prev, pcur);
01126 add_reg = newcurr;
01127
01128 piter.Init(&_reg_list);
01129 pcur = piter.First();
01130 prev = NULL;
01131 break;
01132 } else {
01133 prev = pcur;
01134 pcur = piter.Next();
01135 }
01136 }
01137
01138 crl->Append(add_reg);
01139 }
01140
01141 _reg_list.Append_List(crl);
01142
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152 INT32 Regions_Distributed_Similarly(CACHE_REGION *c1, CACHE_REGION *c2)
01153 {
01154 if (c1->N_Dist() != c2->N_Dist()) {
01155 return -1;
01156 }
01157
01158 INT32 *dims1 = c1->Dist();
01159 INT32 *dims2 = c2->Dist();
01160 BOOL found = FALSE;
01161 for (INT i = 0; i < c1->N_Dist(); ++i) {
01162 INT32 d = dims1[i];
01163 found = FALSE;
01164
01165 for (INT j = 0; j < c2->N_Dist(); ++j) {
01166 if (dims1[j] == dims2[i]) {
01167 found = TRUE;
01168 break;
01169 }
01170 }
01171 if (!found)
01172 break;
01173 }
01174
01175 if (!found)
01176 return -1;
01177
01178 if (Are_Similar_Dimensions(c1, c2, dims1, c1->N_Dist())) {
01179 return 0;
01180 } else {
01181 return -1;
01182 }
01183 }
01184
01185
01186
01187
01188
01189
01190 BOOL Regions_Distributed_Orthogonally(CACHE_REGION *c1, CACHE_REGION *c2)
01191 {
01192 FmtAssert(c1->N_Dist() == c2->N_Dist(), ("Dimensions dont match"));
01193
01194 INT32 *dims1 = c1->Dist();
01195 INT32 *dims2 = c2->Dist();
01196 BOOL found = FALSE;
01197 for (INT i = 0; i < c1->N_Dist(); ++i) {
01198 INT32 d = dims1[i];
01199 found = FALSE;
01200
01201 for (INT j = 0; j < c2->N_Dist(); ++j) {
01202 if (dims1[j] == dims2[i]) {
01203 found = TRUE;
01204 break;
01205 }
01206 }
01207 if (found)
01208 break;
01209 }
01210
01211 if (found)
01212 return FALSE;
01213 else
01214 return TRUE;
01215 }
01216
01217
01218
01219
01220
01221 INT32 CACHE_CONTENTS::Intersect_Region(CACHE_REGION *c)
01222 {
01223
01224 CACHE_REGION_ITER iter(&_reg_list);
01225 INT csize = c->Region_Size();
01226 INT size = 0;
01227
01228 if (csize == -1) {
01229 return -1;
01230 }
01231
01232 for (CACHE_REGION * curr = iter.First(); !iter.Is_Empty(); curr = iter.Next()) {
01233 if (!Are_Independent_Regions(c, curr, _ara_info)) {
01234 INT comparision = Compare_Cache_Regions(c, curr, _ara_info);
01235 if (comparision == 1 || comparision == 3) {
01236
01237
01238 if (c->Type() == curr->Type()) {
01239 if (c->Type() != DISTRIBUTED) {
01240 size = MAX(size, csize);
01241 continue;
01242 } else {
01243
01244
01245 INT32 offset = Regions_Distributed_Similarly(c, curr);
01246 if (offset >= 0) {
01247 size = MAX(size, csize / _nprocs - offset);
01248 continue;
01249 } else if (Regions_Distributed_Orthogonally(c, curr)) {
01250 size = MAX(size, csize / (_nprocs * _nprocs));
01251 continue;
01252 }
01253 }
01254 } else {
01255
01256 if (c->Type() == EXCLUSIVE) {
01257 if (curr->Type() == REPLICATED) {
01258 size = MAX(size, csize);
01259 continue;
01260 } else if (curr->Type() == DISTRIBUTED) {
01261 size = MAX(size, csize / _nprocs);
01262 continue;
01263 }
01264 } else if (c->Type() == REPLICATED) {
01265 if (curr->Type() == EXCLUSIVE) {
01266 size = MAX(size, 0);
01267 } else if (curr->Type() == DISTRIBUTED) {
01268 if (Are_Similar_Dimensions(c, curr, curr->Dist(), curr->N_Dist()) >= 0) {
01269 size = MAX(size, csize / _nprocs);
01270 continue;
01271 }
01272 }
01273 } else if (c->Type() == DISTRIBUTED) {
01274 if (curr->Type() == EXCLUSIVE) {
01275 size = MAX(size, 0);
01276 continue;
01277 } else if (curr->Type() == REPLICATED) {
01278 size = MAX(size, csize / _nprocs);
01279 continue;
01280 }
01281 }
01282 }
01283 } else if (comparision == 2) {
01284
01285 INT isize = c->Region_Size();
01286
01287 if (c->Type() == curr->Type()) {
01288 if (c->Type() != DISTRIBUTED) {
01289 size = MAX(size, isize);
01290 continue;
01291 } else {
01292
01293
01294 INT32 offset = Regions_Distributed_Similarly(curr, c);
01295 if (offset >= 0) {
01296 size = MAX(size, isize / _nprocs - offset);
01297 continue;
01298 } else if (Regions_Distributed_Orthogonally(curr, c)) {
01299 if (Are_Similar_Dimensions(curr, c, c->Dist(), c->N_Dist()) >= 0) {
01300 size = MAX(size, isize / (_nprocs * _nprocs));
01301 continue;
01302 }
01303 }
01304 }
01305 } else {
01306
01307
01308 if (c->Type() == EXCLUSIVE) {
01309 if (curr->Type() == REPLICATED) {
01310 size = MAX(size, isize);
01311 continue;
01312 } else if (curr->Type() == DISTRIBUTED) {
01313 size = MAX(size, isize / _nprocs);
01314 continue;
01315 }
01316 } else if (c->Type() == REPLICATED) {
01317 if (curr->Type() == EXCLUSIVE) {
01318 size = MAX(size, 0);
01319 continue;
01320 } else if (curr->Type() == DISTRIBUTED) {
01321 size = MAX(size, isize / _nprocs);
01322 continue;
01323 }
01324 } else if (c->Type() == DISTRIBUTED) {
01325 if (curr->Type() == EXCLUSIVE) {
01326 size = MAX(size, 0);
01327 continue;
01328 } else if (curr->Type() == REPLICATED) {
01329 if (Are_Similar_Dimensions(c, curr, c->Dist(), c->N_Dist()) >= 0) {
01330 size = MAX(size, isize / _nprocs);
01331 continue;
01332 }
01333 }
01334 }
01335 }
01336 }
01337
01338 if (Are_Similar_Regions(c, curr)) {
01339
01340
01341 if (c->Type() == curr->Type()) {
01342 if (c->Type() != DISTRIBUTED) {
01343 INT isize = c->Intersect_Region(curr, _ara_info);
01344 size = MAX(size, isize);
01345 } else {
01346
01347 INT32 offset = Regions_Distributed_Similarly(curr, c);
01348 if (offset >= 0) {
01349 size = MAX(size, csize / _nprocs - offset);
01350 continue;
01351 } else if (Regions_Distributed_Orthogonally(curr, c)) {
01352 size = MAX(size, csize / (_nprocs * _nprocs));
01353 continue;
01354 }
01355 }
01356 } else {
01357 if (c->Type() == EXCLUSIVE) {
01358 if (curr->Type() == REPLICATED) {
01359 INT isize = c->Intersect_Region(curr, _ara_info);
01360 size = MAX(size, isize);
01361 continue;
01362 } else if (curr->Type() == DISTRIBUTED) {
01363 if (Are_Similar_Dimensions(c, curr, curr->Dist(), curr->N_Dist())) {
01364 size = MAX(size, csize / _nprocs);
01365 continue;
01366 }
01367 }
01368 } else if (c->Type() == REPLICATED) {
01369 if (curr->Type() == EXCLUSIVE) {
01370 size = MAX(size, 0);
01371 continue;
01372 } else if (curr->Type() == DISTRIBUTED) {
01373 size = MAX(size, csize / _nprocs);
01374 continue;
01375 }
01376 } else if (c->Type() == DISTRIBUTED) {
01377 if (curr->Type() == EXCLUSIVE) {
01378 if (_nprocs >= 1) {
01379 size = MAX(size, 0);
01380 continue;
01381 }
01382 continue;
01383 } else if (curr->Type() == REPLICATED) {
01384 if (_nprocs >= 1) {
01385 size = MAX(size, csize * (_nprocs - 1) / _nprocs);
01386 continue;
01387 } else {
01388 size = MAX(size, csize);
01389 continue;
01390 }
01391 }
01392 }
01393 }
01394 }
01395 }
01396 }
01397
01398 if (c->Type() == DISTRIBUTED) {
01399 return size * _nprocs;
01400 } else {
01401 return size;
01402 }
01403 }
01404
01405
01406 void CACHE_CONTENTS::Print(FILE *file)
01407 {
01408 fprintf(file, "_ara_info = %p\n", _ara_info);
01409 fprintf(file, "CACHE CONTENTS :");
01410 CACHE_REGION_ITER iter(&_reg_list);
01411 INT i = 0;
01412
01413 for (CACHE_REGION *curr = iter.First(); !iter.Is_Empty(); curr = iter.Next()) {
01414 fprintf(file, "\n%d : ", ++i);
01415 curr->Print(file);
01416 }
01417 fprintf(file, "\n-*-\n");
01418 }
01419
01420
01421
01422
01423