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 #define __STDC_LIMIT_MACROS
00062 #include <stdint.h>
00063 #include <sys/types.h>
00064 #include <alloca.h>
00065
00066 #ifdef __MINGW32__
00067 #include <WINDOWS.h>
00068 #endif
00069 #include "defs.h"
00070 #include "cxx_memory.h"
00071 #include "soe.h"
00072 #include "ipa_section.h"
00073 #include "ipa_lno_util.h"
00074 #include "opt_sys.h"
00075
00076 #ifndef IPA_SUMMARY
00077 INT IPA_Ivar_Global_Count;
00078 INT IPA_Ivar_Count;
00079 mINT32
00080 SYSTEM_OF_EQUATIONS::_work_cols;
00081 mINT32
00082 SYSTEM_OF_EQUATIONS::_work_rows_eq;
00083 mINT32
00084 SYSTEM_OF_EQUATIONS::_work_rows;
00085 template <> MEM_POOL*
00086 MAT<int>::_default_pool;
00087 #endif
00088
00089
00090
00091
00092 void
00093 LINEX::Free_terms()
00094 {
00095 _larray.Free_array();
00096 _larray.Resetidx();
00097 }
00098
00099
00100
00101
00102 void
00103 PROJECTED_NODE::Reset_node()
00104 {
00105 LINEX *l;
00106 if (l = Get_upper_linex())
00107 l->Free_terms();
00108 if (l = Get_lower_linex())
00109 l->Free_terms();
00110 if (l = Get_step_linex())
00111 l->Free_terms();
00112 if (l = Get_segment_length_linex())
00113 l->Free_terms();
00114 if (l = Get_segment_stride_linex())
00115 l->Free_terms();
00116
00117 Set_flags(0);
00118 }
00119
00120
00121
00122
00123 void
00124 PROJECTED_NODE::Set_constant_linexs(INT32 upper,
00125 INT32 lower,
00126 INT32 step,
00127 INT32 segment_length,
00128 INT32 segment_stride)
00129 {
00130 MEM_POOL* pool = Mem_Pool();
00131 Set_upper_linex((LINEX*)CXX_NEW(LINEX(pool),pool));
00132 Get_upper_linex()->Set_term(LTKIND_CONST, upper, CONST_DESC,0);
00133 Set_lower_linex((LINEX*)CXX_NEW(LINEX(pool),pool));
00134 Get_lower_linex()->Set_term(LTKIND_CONST, lower, CONST_DESC,0);
00135 Set_step_linex((LINEX*)CXX_NEW(LINEX(pool),pool));
00136 Get_step_linex()->Set_term(LTKIND_CONST, step, CONST_DESC,0);
00137 if (segment_length <= 0) {
00138 Set_segment_length_linex(NULL);
00139 Set_segment_stride_linex(NULL);
00140 } else {
00141 Set_segment_length_linex((LINEX*)CXX_NEW(LINEX(pool),pool));
00142 Get_segment_length_linex()->Set_term(LTKIND_CONST, segment_length,
00143 CONST_DESC,0);
00144 Set_segment_stride_linex((LINEX*)CXX_NEW(LINEX(pool),pool));
00145 Get_segment_stride_linex()->Set_term(LTKIND_CONST, segment_stride,
00146 CONST_DESC,0);
00147 }
00148 Set_flags(0);
00149 }
00150
00151
00152
00153
00154 void
00155 PROJECTED_NODE::Set_constant_two_strided_section(INT32 lower,
00156 INT32 upper,
00157 INT32 step,
00158 INT32 seg_len,
00159 INT32 seg_stride)
00160 {
00161 MEM_POOL* pool = Mem_Pool();
00162 Set_lower_linex(CXX_NEW(LINEX(pool), pool));
00163 Get_lower_linex()->Set_term(LTKIND_CONST, lower, CONST_DESC, 0);
00164
00165 Set_upper_linex(CXX_NEW(LINEX(pool), pool));
00166 Get_upper_linex()->Set_term(LTKIND_CONST, upper, CONST_DESC, 0);
00167
00168 Set_step_linex(CXX_NEW(LINEX(pool), pool));
00169 Get_step_linex()->Set_term(LTKIND_CONST, step, CONST_DESC, 0);
00170
00171 Set_segment_length_linex(CXX_NEW(LINEX(pool), pool));
00172 Get_segment_length_linex()->Set_term(LTKIND_CONST, seg_len, CONST_DESC, 0);
00173
00174 Set_segment_stride_linex(CXX_NEW(LINEX(pool), pool));
00175 Get_segment_stride_linex()->Set_term(LTKIND_CONST, seg_stride, CONST_DESC,0);
00176
00177 Set_flags(0);
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 void PROJECTED_NODE::Fill_Out()
00187 {
00188 LINEX* lx_lower = Get_lower_linex();
00189 LINEX* lx_upper = Get_upper_linex();
00190 LINEX* lx_step = Get_step_linex();
00191 if (lx_upper != NULL && lx_upper->Num_terms() >= 0
00192 && lx_step != NULL && lx_step->Num_terms() >= 0)
00193 return;
00194 Reset_is_unprojected();
00195 if (lx_upper != NULL)
00196 lx_upper->Free_terms();
00197 if (lx_step != NULL)
00198 lx_step->Free_terms();
00199 lx_step->Set_term(LTKIND_CONST, (INT32) 1, CONST_DESC, 0);
00200 for (INT i = 0; i <= lx_lower->Num_terms(); i++)
00201 lx_upper->Set_term(lx_lower->Get_term(i));
00202 }
00203
00204
00205
00206
00207 void
00208 PROJECTED_NODE::Set_linexs(LINEX* low_new,
00209 LINEX* up_new,
00210 LINEX* step_new,
00211 LINEX* segment_length_new,
00212 LINEX* segment_stride_new)
00213 {
00214 Reset_node();
00215
00216 if (low_new)
00217 low_new->Copy(Get_lower_linex());
00218 if (up_new)
00219 up_new->Copy(Get_upper_linex());
00220 if (step_new)
00221 step_new->Copy(Get_step_linex());
00222 if (segment_length_new)
00223
00224 segment_length_new->Copy(Get_segment_length_linex());
00225 if (segment_stride_new)
00226 segment_stride_new->Copy(Get_segment_stride_linex());
00227 }
00228
00229
00230
00231
00232
00233
00234 void
00235 LINEX::Copy(LINEX *to)
00236 {
00237 if (this == to)
00238 return;
00239
00240 for (INT i = 0; i <= Num_terms(); ++i) {
00241 if ((Get_term(i)->Get_coeff() == 0 &&
00242 Get_term(i)->Get_type() == LTKIND_CONST) ||
00243 (Get_term(i)->Get_coeff() != 0))
00244 to->Set_term(Get_term(i));
00245 }
00246 }
00247
00248
00249
00250
00251 void
00252 PROJECTED_NODE::Copy(PROJECTED_NODE* to)
00253 {
00254 MEM_POOL* m = Mem_Pool();
00255 if (this == to)
00256 return;
00257
00258 to->Set_flags(Get_flags());
00259
00260 to->Set_lower_linex(CXX_NEW(LINEX(m), m));
00261 Get_lower_linex()->Copy(to->Get_lower_linex());
00262
00263 to->Set_upper_linex(CXX_NEW(LINEX(m), m));
00264 Get_upper_linex()->Copy(to->Get_upper_linex());
00265
00266 to->Set_step_linex(CXX_NEW(LINEX(m), m));
00267 Get_step_linex()->Copy(to->Get_step_linex());
00268
00269 if (Get_segment_length_linex() != NULL) {
00270 to->Set_segment_length_linex(CXX_NEW(LINEX(m), m));
00271 Get_segment_length_linex()->Copy(to->Get_segment_length_linex());
00272 } else {
00273 to->Set_segment_length_linex(NULL);
00274 }
00275
00276 if (Get_segment_stride_linex() != NULL) {
00277 to->Set_segment_stride_linex(CXX_NEW(LINEX(m), m));
00278 Get_segment_stride_linex()->Copy(to->Get_segment_stride_linex());
00279 } else {
00280 to->Set_segment_stride_linex(NULL);
00281 }
00282 }
00283
00284
00285
00286
00287 void
00288 PROJECTED_REGION::Copy_projected_node(PROJECTED_NODE* node)
00289 {
00290 PROJECTED_NODE* to = Get_projected_node(Get_projected_array()->Newidx());
00291 node->Copy(to);
00292 }
00293
00294
00295
00296
00297 PROJECTED_REGION::PROJECTED_REGION(PROJECTED_REGION* p)
00298 {
00299 Set_Mem_Pool(Mem_Pool());
00300 Set_num_dims(p->Get_num_dims());
00301 Set_type(p->Get_type());
00302 Set_depth(p->Get_depth());
00303 Set_projected_kernel(p->Get_projected_kernel());
00304 Set_projected_array(CXX_NEW(PROJECTED_ARRAY(Mem_Pool()), Mem_Pool()));
00305 for (INT i = 0; i < Get_num_dims(); ++i) {
00306 Copy_projected_node(p->Get_projected_node(i));
00307 }
00308 }
00309
00310
00311
00312
00313 BOOL LINEX::Is_const()
00314 {
00315 return ((Num_terms() == 0) && (Get_term(0)->Get_type() == LTKIND_CONST));
00316 }
00317
00318
00319
00320
00321 INT
00322 LINEX::Max(LINEX* l)
00323 {
00324 Is_True(Is_const(), ("LINEX::Max - Expecting constant LINEX"));
00325 Is_True(l->Is_const(), ("LINEX::Max - Expecting constant LINEX"));
00326
00327 INT32 val1 = Get_term(0)->Get_coeff();
00328 INT32 val2 = l->Get_term(0)->Get_coeff();
00329
00330 return MAX(val1, val2);
00331 }
00332
00333
00334
00335
00336 BOOL
00337 LINEX::Equivalent(LINEX &b )
00338 {
00339 INT32 num_terms = Num_terms();
00340 if (num_terms != b.Num_terms()) {
00341 return FALSE;
00342 }
00343
00344 for (INT i = 0; i <= num_terms; ++i) {
00345 if (!Get_term(i)->Equivalent(*b.Get_term(i))) {
00346 return FALSE;
00347 }
00348 }
00349
00350 return TRUE;
00351 }
00352
00353
00354
00355
00356
00357 BOOL
00358 TERM::Equivalent (TERM& t)
00359 {
00360 return (Get_type() == t.Get_type() &&
00361 Get_coeff() == t.Get_coeff() &&
00362 Get_desc() == t.Get_desc());
00363 }
00364
00365
00366
00367
00368 void
00369 LINEX::Set_linex_terms(INT start_index, INT end_index, TERM* term)
00370 {
00371 for (INT i = start_index; i < end_index; ++i) {
00372 Set_term(&term[i]);
00373 }
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 void
00383 PROJECTED_NODE::Create_linex(TERM* term)
00384 {
00385 MEM_POOL* pool = Mem_Pool();
00386 INT uterm_index = Get_ub_term_index();
00387 INT lterm_index = Get_lb_term_index();
00388 INT sterm_index = Get_step_term_index();
00389 INT segment_length_index = Get_segment_length_term_index();
00390 INT segment_stride_index = Get_segment_stride_term_index();
00391
00392 INT uterm_count = Get_ub_term_count();
00393 INT lterm_count = Get_lb_term_count();
00394 INT sterm_count = Get_step_term_count();
00395 INT segment_length_count = Get_segment_length_term_count();
00396 INT segment_stride_count = Get_segment_stride_term_count();
00397
00398
00399 Set_upper_linex((LINEX*) CXX_NEW(LINEX(pool), pool));
00400 Set_lower_linex((LINEX*) CXX_NEW(LINEX(pool), pool));
00401 Set_step_linex((LINEX*) CXX_NEW(LINEX(pool), pool));
00402 if (segment_length_count > 0)
00403 Set_segment_length_linex((LINEX*) CXX_NEW(LINEX(pool), pool));
00404 else
00405 Set_segment_length_linex(NULL);
00406 if (segment_stride_count > 0)
00407 Set_segment_stride_linex((LINEX*) CXX_NEW(LINEX(pool), pool));
00408 else
00409 Set_segment_stride_linex(NULL);
00410
00411 Get_upper_linex()->Set_linex_terms(uterm_index, uterm_index+uterm_count,
00412 term);
00413 Get_lower_linex()->Set_linex_terms(lterm_index, lterm_index+lterm_count,
00414 term);
00415 Get_step_linex()->Set_linex_terms(sterm_index, sterm_index+sterm_count,
00416 term);
00417 if (segment_length_count > 0)
00418 Get_segment_length_linex()->Set_linex_terms(segment_length_index,
00419 segment_length_index+segment_length_count, term);
00420 if (segment_stride_count > 0)
00421 Get_segment_stride_linex()->Set_linex_terms(segment_stride_index,
00422 segment_stride_index+segment_stride_count, term);
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 void
00432 LOOPINFO::Create_linex(TERM* term)
00433 {
00434 MEM_POOL* pool = Mem_Pool();
00435
00436
00437
00438 INT ub_start = Get_ub_term_index();
00439 INT ub_end = ub_start + Get_ub_term_count();
00440 INT lb_start = Get_lb_term_index();
00441 INT lb_end = lb_start + Get_lb_term_count();
00442 INT step_start = Get_step_term_index();
00443 INT step_end = step_start + Get_step_term_count();
00444
00445 if (!Is_messy_ub()) {
00446 u1.u3._upper_linex = CXX_NEW(LINEX(pool), pool);
00447 u1.u3._upper_linex->Set_linex_terms(ub_start, ub_end, term);
00448 }
00449
00450 if (!Is_messy_lb()) {
00451 u1.u3._lower_linex = CXX_NEW(LINEX(pool), pool);
00452 u1.u3._lower_linex->Set_linex_terms(lb_start, lb_end, term);
00453 }
00454
00455 if (!Is_messy_step()) {
00456 u1.u3._step_linex = CXX_NEW(LINEX(pool), pool);
00457 u1.u3._step_linex->Set_linex_terms(step_start, step_end, term);
00458 }
00459 }
00460
00461
00462
00463
00464 void
00465 LINEX::Init(MEM_POOL *m)
00466 {
00467
00468 new (this) LINEX(m);
00469 }
00470
00471
00472
00473
00474
00475
00476 extern INT
00477 Locate_symbol(LOOP_SYMBOL_ARRAY* syms,
00478 SYSTEM_OF_EQUATIONS* soe,
00479 const LOOP_SYMBOL& symbol)
00480 {
00481 INT i;
00482
00483 for (i = 0; i < syms->Elements(); ++i) {
00484 if ((*syms)[i] == symbol) {
00485 return i;
00486 }
00487 }
00488
00489 syms->AddElement(symbol);
00490 soe->Add_Vars(1);
00491
00492 return i;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void
00505 LINEX::Add_access(SYSTEM_OF_EQUATIONS *soe,
00506 mUINT8 depth,
00507 INT num_dim,
00508 INT axle,
00509 INT num_syms,
00510 ACTION_TYPE act,
00511 LOOP_SYMBOL_ARRAY* sym,
00512 BOOL trace)
00513 {
00514 INT pos, c = 0;
00515 BOOL ltkind_subscr = FALSE;
00516
00517 if (trace) {
00518 fprintf(stderr, "\n Add_access: Adding a LINEX to the SOE\n");
00519 Print(stderr);
00520 fprintf(stderr, "\n to SOE:\n");
00521 soe->Print(stderr);
00522 }
00523
00524
00525
00526 INT vector_size = num_dim + depth + num_syms + 1;
00527 if (trace) {
00528 printf("num_dim = %d, depth = %d, num_syms = %d vector size %d \n",
00529 num_dim, depth, num_syms,vector_size);
00530 }
00531
00532 mINT32* v = (mINT32*) alloca(sizeof(mINT32) * vector_size);
00533 BZERO(v, sizeof(mINT32) * vector_size);
00534
00535
00536 for (INT i = 0; i <= Num_terms(); ++i) {
00537 TERM* term = Get_term(i);
00538 switch (term->Get_type()) {
00539
00540 case LTKIND_CONST:
00541 c = term->Get_coeff();
00542 break;
00543
00544 case LTKIND_LINDEX:
00545
00546
00547
00548
00549
00550 v[num_dim+term->Get_desc()] = term->Get_coeff();
00551 break;
00552
00553 case LTKIND_SUBSCR:
00554 v[term->Get_desc()] = term->Get_coeff();
00555 ltkind_subscr = TRUE;
00556 break;
00557
00558 case LTKIND_IV:
00559 pos = Locate_symbol(sym, soe, LOOP_SYMBOL(term->Get_desc()));
00560 v[num_dim + depth + pos] = term->Get_coeff();
00561 break;
00562
00563 case LTKIND_NONE:
00564 Fail_FmtAssertion("Add_access: invalid ltkind = LTKIND_NONE");
00565 break;
00566 }
00567 }
00568
00569 if (!ltkind_subscr) {
00570 if (act == ACTION_LO)
00571 v[axle] = -1;
00572 else
00573 v[axle] = 1;
00574 }
00575
00576
00577
00578
00579
00580
00581 if (act != ACTION_LO) {
00582 for (INT i = num_dim; i < vector_size; ++i)
00583 v[i] = -v[i];
00584 }
00585
00586
00587 if (act == ACTION_LO)
00588 c = -c;
00589
00590
00591
00592 if (act != ACTION_EQ)
00593 soe->Add_Le(v, c);
00594 else
00595
00596
00597 soe->Add_Eq(v,c);
00598
00599 if (trace) {
00600 fprintf(stderr,"\n Add_access: New SOE is:\n");
00601 soe->Print(stderr);
00602 }
00603 }
00604
00605
00606
00607
00608
00609 extern void
00610 Add_to_SOE(PROJECTED_REGION* a,
00611 const INT pos,
00612 SYSTEM_OF_EQUATIONS* soe,
00613 const BOOL convert_equation,
00614 LOOP_SYMBOL_ARRAY* sym,
00615 INT depth,
00616 BOOL trace)
00617 {
00618 #ifdef IPA_SUMMARY
00619 INT num_syms = Ivar->Elements();
00620 #else
00621 INT num_syms = IPA_Ivar_Count;
00622 #endif
00623
00624 PROJECTED_ARRAY* array = a->Get_projected_array();
00625 PROJECTED_NODE* node = &(*array)[pos];
00626
00627 if (!node->Is_unprojected() &&
00628 node->Get_upper_linex()->Num_terms() != -1) {
00629 node->Get_lower_linex()->Add_access(soe, depth, a->Get_num_dims(), pos,
00630 num_syms, ACTION_LO,
00631 sym, trace);
00632
00633 node->Get_upper_linex()->Add_access(soe, depth, a->Get_num_dims(), pos,
00634 num_syms, ACTION_UP,
00635 sym, trace);
00636 }
00637 else {
00638 if (convert_equation) {
00639 node->Get_lower_linex()->Add_access(soe, depth, a->Get_num_dims(), pos,
00640 num_syms, ACTION_LO,
00641 sym, trace);
00642
00643 node->Get_lower_linex()->Add_access(soe, depth, a->Get_num_dims(), pos,
00644 num_syms, ACTION_UP,
00645 sym, trace);
00646 }
00647 else {
00648 node->Get_lower_linex()->Add_access(soe, depth, a->Get_num_dims(), pos,
00649 num_syms, ACTION_EQ,
00650 sym, trace);
00651 }
00652 }
00653 }
00654
00655
00656
00657
00658 PROJECTED_REGION::PROJECTED_REGION(mINT16 type,
00659 mUINT8 depth,
00660 mUINT8 dim,
00661 MEM_POOL* mem_pool)
00662 : _type (type),
00663 _num_dims (dim),
00664 _depth (depth),
00665 _mem_pool (mem_pool)
00666 {
00667 u2._projected_kernel = 0;
00668 u1._region = CXX_NEW(PROJECTED_ARRAY(mem_pool), mem_pool);
00669 u1._region->Force_Alloc_array(dim);
00670 u1._region->Setidx(dim-1);
00671 for (INT i = 0; i < dim; i++) {
00672 (*(u1._region))[i].Init(mem_pool);
00673 }
00674 }
00675
00676
00677
00678
00679 void
00680 PROJECTED_NODE::Init(MEM_POOL *m)
00681 {
00682 Set_Mem_Pool(m);
00683
00684 Set_upper_linex(CXX_NEW(LINEX(m), m));
00685 Get_upper_linex()->Init(m);
00686
00687 Set_lower_linex(CXX_NEW(LINEX(m), m));
00688 Get_lower_linex()->Init(m);
00689
00690 Set_step_linex(CXX_NEW(LINEX(m), m));
00691 Get_step_linex()->Init(m);
00692
00693 Set_segment_length_linex(NULL);
00694 Set_segment_stride_linex(NULL);
00695
00696 Set_flags(0);
00697 }
00698
00699
00700
00701
00702
00703 BOOL
00704 PROJECTED_NODE::Equivalent(PROJECTED_NODE &b)
00705 {
00706 return ((Get_flags() == b.Get_flags()) &&
00707 (Get_upper_linex()->Equivalent(*b.Get_upper_linex())) &&
00708 (Get_lower_linex()->Equivalent(*b.Get_lower_linex())) &&
00709 (Get_step_linex()->Equivalent(*b.Get_step_linex())) &&
00710 (Get_segment_length_linex() == NULL &&
00711 b.Get_segment_length_linex() == NULL ||
00712 Get_segment_length_linex() != NULL &&
00713 b.Get_segment_length_linex() == NULL &&
00714 Get_segment_length_linex()->
00715 Equivalent(*b.Get_segment_length_linex())) &&
00716 (Get_segment_stride_linex() == NULL &&
00717 b.Get_segment_stride_linex() == NULL ||
00718 Get_segment_stride_linex() != NULL &&
00719 b.Get_segment_stride_linex() == NULL &&
00720 Get_segment_stride_linex()->
00721 Equivalent(*b.Get_segment_stride_linex())));
00722 }
00723
00724
00725
00726
00727
00728 BOOL
00729 PROJECTED_REGION::Equivalent(PROJECTED_REGION* p)
00730 {
00731 if (Is_messy_region() && p->Is_messy_region()) {
00732 return TRUE;
00733 }
00734
00735 INT num_dims = Get_num_dims();
00736 if (num_dims != p->Get_num_dims()) {
00737 return FALSE;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747 for (INT i = 1; i < num_dims; ++i) {
00748 PROJECTED_NODE* p1 = Get_projected_node(i);
00749 PROJECTED_NODE* p2 = p->Get_projected_node(i);
00750 Is_True(p1 && p2, ("PROJECTED_REGION::Equivalent: NULL projected node\n"));
00751 if (!p1->Equivalent(*p2)) {
00752 return FALSE;
00753 }
00754 }
00755
00756 return TRUE;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 BOOL
00769 PROJECTED_REGION::May_Union(PROJECTED_REGION& b,
00770 BOOL trace)
00771 {
00772 if (trace) {
00773 fprintf(stderr,"Union two PROJECTED REGIONs \n");
00774 b.Print(stderr);
00775 Print(stderr);
00776 }
00777
00778
00779 if (Is_messy_region()) {
00780 return FALSE;
00781 }
00782 else if (b.Is_messy_region()) {
00783 Set_messy_region();
00784 return TRUE;
00785 }
00786
00787 BOOL change = FALSE;
00788 MEM_POOL* local_pool = Mem_Pool();
00789 LOOPINFO l(local_pool);
00790
00791 for (INT i = 0; i < Get_num_dims(); ++i) {
00792
00793
00794 PROJECTED_NODE* ax = Get_projected_node(i);
00795 if (ax->Has_all_messy_bounds()) {
00796 continue;
00797 }
00798
00799
00800 PROJECTED_NODE* bx = b.Get_projected_node(i);
00801 if (ax->Is_messy_lb() || ax->Is_messy_ub() ||
00802 bx->Is_messy_lb() || bx->Is_messy_ub()) {
00803 ax->Set_all_messy_bounds();
00804 change = TRUE;
00805 continue;
00806 }
00807
00808 ax->Fill_Out();
00809 bx->Fill_Out();
00810
00811
00812 LINEX* lx_a_step = ax->Get_step_linex();
00813 LINEX* lx_b_step = bx->Get_step_linex();
00814 if (!lx_a_step->Is_const() || !lx_b_step->Is_const()) {
00815 if (!lx_a_step->Is_const() || lx_a_step->Get_constant_term() != 1) {
00816 lx_a_step->Free_terms();
00817 lx_a_step->Set_term(LTKIND_CONST, (mINT32) 1, CONST_DESC, 0);
00818 change = TRUE;
00819 }
00820 }
00821 else {
00822 INT a_coeff = lx_a_step->Get_term(0)->Get_coeff();
00823 INT b_coeff = lx_b_step->Get_term(0)->Get_coeff();
00824 INT gcd = Gcd(a_coeff, b_coeff);
00825 LINEX* ax_lower = ax->Get_lower_linex();
00826 LINEX* bx_lower = bx->Get_lower_linex();
00827 LINEX* lx_diff = ax_lower->Subtract(bx_lower);
00828 lx_diff->Simplify();
00829 if (!lx_diff->Is_const()) {
00830 if (lx_a_step->Get_term(0)->Get_coeff() != 1) {
00831 lx_a_step->Get_term(0)->Set_coeff(1);
00832 change = TRUE;
00833 }
00834 }
00835 else {
00836 INT diff = lx_diff->Get_term(0)->Get_coeff();
00837 if (diff < 0)
00838 diff = -diff;
00839 if (diff % gcd != 0) {
00840 if (lx_a_step->Get_term(0)->Get_coeff() != 1) {
00841 lx_a_step->Get_term(0)->Set_coeff(1);
00842 change = TRUE;
00843 }
00844 }
00845 else {
00846 if (lx_a_step->Get_term(0)->Get_coeff() != gcd) {
00847 lx_a_step->Get_term(0)->Set_coeff(gcd);
00848 change = TRUE;
00849 }
00850 }
00851 }
00852 }
00853
00854
00855 SYSTEM_OF_EQUATIONS* soe =
00856 CXX_NEW(SYSTEM_OF_EQUATIONS(0, 0, b.Get_num_dims() + b.Get_depth(),
00857 local_pool), local_pool);
00858 LOOP_SYMBOL_ARRAY* syms =
00859 CXX_NEW(LOOP_SYMBOL_ARRAY(local_pool), local_pool);
00860
00861
00862 Add_to_SOE(this, i, soe, TRUE, syms, Get_depth(), trace);
00863 Add_to_SOE(&b, i, soe, TRUE, syms, Get_depth(), trace);
00864
00865
00866
00867 if (soe->Copy_To_Work()) {
00868 BOOL* is_redundant =
00869 CXX_NEW_ARRAY(BOOL, soe->Num_Le_Constraints(), local_pool);
00870 INT num_con = soe->Num_Le_Constraints();
00871
00872 num_con -= soe->Mark_Simple_Redundant(is_redundant);
00873 if (num_con > 2) {
00874
00875
00876 num_con -= soe->Mark_New_Redundant(is_redundant);
00877 }
00878
00879
00880 if (num_con == 2) {
00881 if (!((is_redundant[0] && !is_redundant[2]
00882 || !is_redundant[0] && is_redundant[2])
00883 && (is_redundant[1] && !is_redundant[3]
00884 || !is_redundant[1] && is_redundant[3]))) {
00885 ax->Set_all_messy_bounds();
00886 change = TRUE;
00887 continue;
00888 }
00889 if (!ax->Matching_Segment_Stride(bx)
00890 || ax->Get_segment_length_linex() != NULL
00891 && !ax->Get_segment_length_linex()->Is_const()
00892 || bx->Get_segment_length_linex() != NULL
00893 && !bx->Get_segment_length_linex()->Is_const()) {
00894 LINEX* lx_seg_length = ax->Get_segment_length_linex();
00895 lx_seg_length->Free_terms();
00896 LINEX* lx_seg_stride = ax->Get_segment_stride_linex();
00897 lx_seg_stride->Free_terms();
00898 }
00899 else if (ax->Get_segment_stride_linex() != NULL) {
00900 LINEX* lx_a_seg_length = ax->Get_segment_length_linex();
00901 INT a_const_value = lx_a_seg_length->Get_constant_term();
00902 LINEX* lx_b_seg_length = bx->Get_segment_length_linex();
00903 INT b_const_value = lx_b_seg_length->Get_constant_term();
00904 INT difference = a_const_value > b_const_value
00905 ? a_const_value - b_const_value : b_const_value - a_const_value;
00906 ax->Get_segment_length_linex()->Set_term(LTKIND_CONST,
00907 difference, CONST_DESC, 0);
00908 ax->Get_segment_length_linex()->Simplify();
00909 LINEX* ax_lower = ax->Get_lower_linex();
00910 LINEX* bx_lower = bx->Get_lower_linex();
00911 LINEX* lx_diff = ax_lower->Subtract(bx_lower);
00912 if (!lx_diff->Is_const()) {
00913 ax->Get_segment_length_linex()->Free_terms();
00914 ax->Set_segment_length_linex(NULL);
00915 ax->Get_segment_stride_linex()->Free_terms();
00916 ax->Set_segment_stride_linex(NULL);
00917 }
00918 else {
00919 INT difference = lx_diff->Get_constant_term();
00920 if (difference < 0)
00921 difference = -difference;
00922 ax->Get_segment_length_linex()->Set_term(LTKIND_CONST,
00923 difference, CONST_DESC,0);
00924 ax->Get_segment_length_linex()->Simplify();
00925 }
00926 }
00927
00928
00929 LINEX* lb = ax->Get_lower_linex();
00930 if (lb && !lb->Equivalent(*(bx->Get_lower_linex()))) {
00931 if (!is_redundant[0]) {
00932 lb->Free_terms();
00933 (bx->Get_lower_linex())->Copy(lb);
00934 change = TRUE;
00935 }
00936 }
00937
00938 LINEX* ub = ax->Get_upper_linex();
00939 if (ub && !ub->Equivalent(*(bx->Get_upper_linex()))) {
00940 if (!is_redundant[1]) {
00941 ub->Free_terms();
00942 (bx->Get_upper_linex())->Copy(ub);
00943 change = TRUE;
00944 }
00945 }
00946
00947 }
00948 else {
00949
00950 ax->Set_all_messy_bounds();
00951 change = TRUE;
00952 }
00953 }
00954 else {
00955
00956 ax->Set_all_messy_bounds();
00957 change = TRUE;
00958 }
00959 }
00960
00961 if (trace) {
00962 fprintf(stderr,"Result of Unioning two PROJECTED REGIONs \n");
00963 Print(stderr);
00964 }
00965
00966 return change;
00967 }
00968
00969
00970
00971
00972 BOOL
00973 TERM::Is_equal(TERM* t, INT count)
00974 {
00975 for (INT i = 0; i <= count; ++i) {
00976 if (! t[i].Equivalent(this[i])) {
00977 return FALSE;
00978 }
00979 }
00980 return TRUE;
00981 }
00982
00983
00984
00985
00986 void
00987 PROJECTED_REGION::Copy_write(PROJECTED_REGION *p_in)
00988 {
00989 Set_type(p_in->Get_type());
00990 Set_num_dims(p_in->Get_num_dims());
00991 Set_depth(p_in->Get_depth());
00992 if (p_in->Is_passed())
00993 {
00994 Set_callsite_id(p_in->Get_callsite_id());
00995 Set_actual_id(p_in->Get_actual_id());
00996 }
00997 }
00998
00999 void
01000 Print_Symbol_Array(LOOP_SYMBOL_ARRAY* sa, FILE *fp)
01001 {
01002 for (INT i = 0; i <= sa->Lastidx(); i++) {
01003 fprintf(fp, "[%d] ", i);
01004 (*sa)[i].Print(fp);
01005 }
01006 }
01007
01008
01009
01010
01011
01012 BOOL
01013 PROJECTED_REGION::Constant_bounds(mUINT8 first_dim)
01014 {
01015 for (INT i = first_dim; i < _num_dims; ++i) {
01016 PROJECTED_NODE *node = Get_projected_node(i);
01017 LINEX* lower = node->Get_upper_linex();
01018 LINEX* upper = node->Get_upper_linex();
01019 if (!lower || !lower->Is_const() || !upper || !upper->Is_const()) {
01020 return FALSE;
01021 }
01022 }
01023 return TRUE;
01024 }
01025
01026
01027
01028
01029 INT
01030 LINEX::Get_constant_term()
01031 {
01032 for (INT i = 0; i <= Num_terms(); ++i) {
01033 if (Get_term(i)->Get_type() == LTKIND_CONST)
01034 return Get_term(i)->Get_coeff();
01035 }
01036
01037 return 0;
01038 }
01039
01040
01041
01042
01043 PROJECTED_REGION*
01044 REGION_ARRAYS::Get_Projected_Region(INT i)
01045 {
01046 PROJECTED_REGION_INFO_ARRAY *info = Get_projected_region_array();
01047
01048 Is_True(info && info->Lastidx() != -1, ("Expecting at least 1 projected region in Reshape \n"));
01049 Is_True(info->Lastidx() >= i, ("Projected_Region %d exceeded size of array %d \n", i, info->Lastidx()));
01050
01051 PROJECTED_REGION_INFO *region_info = &(*info)[i];
01052 PROJECTED_REGION *proj_shape = region_info->Get_projected_region();
01053 Is_True(proj_shape, ("NULL Projected Region in REGION_ARRAYS::Get_Projected_Region \n"));
01054
01055 return proj_shape;
01056 }
01057
01058
01059
01060
01061
01062
01063 void LINEX::Remove_Zero_Terms()
01064 {
01065 INT j = 0;
01066 INT num_init_terms = Num_terms();
01067 INT i;
01068
01069 for (i = 0; i <= Num_terms(); i++) {
01070 TERM* tm = Get_term(i);
01071 if (tm->Get_coeff() != 0) {
01072 if (i != j)
01073 _larray[j] = _larray[i];
01074 j++;
01075 }
01076 }
01077
01078 INT difference = i - j;
01079 for (i = 0; i < difference; i++)
01080 _larray.Decidx();
01081
01082
01083
01084
01085 if ((Num_terms() == -1) && (num_init_terms != -1))
01086 {
01087 Set_term(LTKIND_CONST, 0, CONST_DESC, 0);
01088 }
01089 }
01090
01091
01092
01093
01094
01095
01096
01097 void LINEX::Simplify()
01098 {
01099 for (INT i = 0; i <= Num_terms(); i++) {
01100 TERM* tm_i = Get_term(i);
01101 for (INT j = i + 1; j <= Num_terms(); j++) {
01102 TERM* tm_j = Get_term(j);
01103 if (tm_i->Get_type() == tm_j->Get_type()
01104 && tm_i->Get_desc() == tm_j->Get_desc()
01105 && tm_i->Get_projected_level() == tm_j->Get_projected_level()) {
01106 tm_i->Set_coeff(tm_i->Get_coeff() + tm_j->Get_coeff());
01107 tm_j->Set_coeff(0);
01108 }
01109 }
01110 }
01111 Remove_Zero_Terms();
01112 }
01113
01114
01115
01116
01117
01118
01119 void PROJECTED_NODE::Simplify()
01120 {
01121 if (!Is_messy_lb()) {
01122 LINEX* lx_lower = Get_lower_linex();
01123 lx_lower->Simplify();
01124 }
01125 if (!Is_messy_ub()) {
01126 LINEX* lx_upper = Get_upper_linex();
01127 lx_upper->Simplify();
01128 }
01129 if (!Is_messy_step()) {
01130 LINEX* lx_step = Get_step_linex();
01131 lx_step->Simplify();
01132 }
01133 if (Get_segment_length_linex() != NULL)
01134 Get_segment_length_linex()->Simplify();
01135 if (Get_segment_stride_linex() != NULL)
01136 Get_segment_stride_linex()->Simplify();
01137 }
01138
01139
01140
01141
01142
01143
01144 void PROJECTED_REGION::Simplify()
01145 {
01146 if (Is_messy_region())
01147 return;
01148 for (INT i = 0; i < Get_num_dims(); i++) {
01149 PROJECTED_NODE* pn = Get_projected_node(i);
01150 pn->Simplify();
01151 }
01152 }
01153
01154 BOOL PROJECTED_REGION::Has_Messy_Bounds()
01155 {
01156 for (INT i = 0; i < Get_num_dims(); i++) {
01157 PROJECTED_NODE* pn = Get_projected_node(i);
01158 if (pn->Has_a_messy_bound())
01159 return TRUE;
01160 }
01161 return FALSE;
01162 }
01163
01164 BOOL PROJECTED_REGION::Has_Important_Messy_Bounds()
01165 {
01166 for (INT i = 1; i < Get_num_dims(); i++) {
01167 PROJECTED_NODE* pn = Get_projected_node(i);
01168 if (pn->Has_a_messy_bound())
01169 return TRUE;
01170 }
01171 return FALSE;
01172 }
01173
01174 void PROJECTED_REGION::Fill_Out()
01175 {
01176 if (Is_messy_region())
01177 return;
01178 Reset_is_unprojected();
01179 for (INT i = 0; i < Get_num_dims(); i++) {
01180 PROJECTED_NODE* pn = Get_projected_node(i);
01181 pn->Fill_Out();
01182 }
01183 }
01184
01185 BOOL PROJECTED_NODE::Matching_Segment_Stride(PROJECTED_NODE* pn)
01186 {
01187 if (pn == NULL)
01188 return FALSE;
01189
01190 LINEX* ss_one = Get_segment_stride_linex();
01191 LINEX* ss_two = pn->Get_segment_stride_linex();
01192
01193 if (ss_one == NULL && ss_two == NULL)
01194 return TRUE;
01195 if (ss_one == NULL || ss_two == NULL)
01196 return FALSE;
01197 return ss_one->Equivalent(*ss_two);
01198 }
01199
01200 BOOL PROJECTED_REGION::Matching_Segment_Stride(PROJECTED_REGION* pr)
01201 {
01202 if (pr == NULL)
01203 return FALSE;
01204 if (Is_messy_region() || pr->Is_messy_region())
01205 return (Is_messy_region() == pr->Is_messy_region());
01206 if (Get_num_dims() != pr->Get_num_dims())
01207 return FALSE;
01208 for (INT i = 0; i < Get_num_dims(); i++) {
01209 PROJECTED_NODE* pn_one = Get_projected_node(i);
01210 PROJECTED_NODE* pn_two = pr->Get_projected_node(i);
01211 if (!pn_one->Matching_Segment_Stride(pn_two))
01212 return FALSE;
01213 }
01214 return TRUE;
01215 }
01216
01217
01218
01219
01220
01221
01222 LINEX* LINEX::Merge(LINEX *l1)
01223 {
01224 INT c = 0;
01225
01226
01227 FmtAssert(_larray.Get_Mem_Pool() == l1->_larray.Get_Mem_Pool(),
01228 ("LINEX::Merge: Inconsistent mem pools"));
01229 MEM_POOL* mem_pool = _larray.Get_Mem_Pool();
01230
01231
01232 INT coeff_max = -1;
01233 INT sub_coeff_max = -1;
01234 INT isym_coeff_max = -1;
01235 INT i;
01236
01237 for (i = 0; i <= Num_terms(); i++) {
01238 TERM* term = Get_term(i);
01239 switch (term->Get_type()) {
01240 case LTKIND_LINDEX:
01241 if (term->Get_desc() > coeff_max)
01242 coeff_max = term->Get_desc();
01243 break;
01244 case LTKIND_SUBSCR:
01245 if (term->Get_desc() > sub_coeff_max)
01246 sub_coeff_max = term->Get_desc();
01247 break;
01248 case LTKIND_IV:
01249 if (term->Get_desc() > isym_coeff_max)
01250 isym_coeff_max = term->Get_desc();
01251 break;
01252 }
01253 }
01254
01255 for (i = 0; i <= l1->Num_terms(); i++) {
01256 TERM* term = l1->Get_term(i);
01257 switch (term->Get_type()) {
01258 case LTKIND_LINDEX:
01259 if (term->Get_desc() > coeff_max)
01260 coeff_max = term->Get_desc();
01261 break;
01262 case LTKIND_SUBSCR:
01263 if (term->Get_desc() > sub_coeff_max)
01264 sub_coeff_max = term->Get_desc();
01265 break;
01266 case LTKIND_IV:
01267 if (term->Get_desc() > isym_coeff_max)
01268 isym_coeff_max = term->Get_desc();
01269 break;
01270 }
01271 }
01272
01273
01274 INT* coeff = (INT*) alloca(sizeof(INT) * (coeff_max + 1));
01275 INT* sub_coeff = (INT*) alloca(sizeof(INT) * (sub_coeff_max + 1));
01276 INT* isym_coeff = (INT*) alloca(sizeof(INT) * (isym_coeff_max + 1));
01277 BZERO(coeff, sizeof(INT) * (coeff_max + 1));
01278 BZERO(sub_coeff, sizeof(INT) * (sub_coeff_max + 1));
01279 BZERO(isym_coeff, sizeof(INT) * (isym_coeff_max + 1));
01280
01281 LINEX* l = CXX_NEW(LINEX(mem_pool), mem_pool);
01282
01283
01284 for (i = 0; i <= Num_terms(); i++) {
01285 TERM *term = Get_term(i);
01286 switch (term->Get_type()) {
01287 case LTKIND_NONE:
01288 break;
01289 case LTKIND_CONST:
01290 c += term->Get_coeff();
01291 break;
01292 case LTKIND_LINDEX:
01293 coeff[term->Get_desc()] += term->Get_coeff();
01294 break;
01295 case LTKIND_SUBSCR:
01296 sub_coeff[term->Get_desc()] += term->Get_coeff();
01297 break;
01298 case LTKIND_IV:
01299 isym_coeff[term->Get_desc()] += term->Get_coeff();
01300 break;
01301 }
01302 }
01303 for (i = 0; i<= l1->Num_terms(); ++i) {
01304 TERM *term = l1->Get_term(i);
01305 switch (term->Get_type()) {
01306 case LTKIND_NONE:
01307 break;
01308 case LTKIND_CONST:
01309 c += term->Get_coeff();
01310 break;
01311 case LTKIND_LINDEX:
01312 coeff[term->Get_desc()] += term->Get_coeff();
01313 break;
01314 case LTKIND_SUBSCR:
01315 sub_coeff[term->Get_desc()] += term->Get_coeff();
01316 break;
01317 case LTKIND_IV:
01318 isym_coeff[term->Get_desc()] += term->Get_coeff();
01319 break;
01320 }
01321 }
01322
01323
01324 l->Set_term(LTKIND_CONST, c, CONST_DESC, 0);
01325 for (i = 0; i <= coeff_max; i++)
01326 if (coeff[i])
01327 l->Set_term(LTKIND_LINDEX, coeff[i], i, 0);
01328 for (i = 0; i <= sub_coeff_max; i++)
01329 if (sub_coeff[i])
01330 l->Set_term(LTKIND_SUBSCR, sub_coeff[i], i, 0);
01331 for (i = 0; i <= isym_coeff_max; i++)
01332 if (isym_coeff[i])
01333 l->Set_term(LTKIND_IV, isym_coeff[i], i, 0);
01334
01335 return l;
01336 }
01337
01338
01339
01340
01341
01342 LINEX* LINEX::Subtract(LINEX *l1)
01343 {
01344 INT c = 0;
01345
01346
01347 FmtAssert(_larray.Get_Mem_Pool() == l1->_larray.Get_Mem_Pool(),
01348 ("LINEX::Subtract: Inconsistent mem pools"));
01349 MEM_POOL* mem_pool = _larray.Get_Mem_Pool();
01350
01351
01352 INT coeff_max = -1;
01353 INT sub_coeff_max = -1;
01354 INT isym_coeff_max = -1;
01355 INT i;
01356
01357 for (i = 0; i <= Num_terms(); i++) {
01358 TERM* term = Get_term(i);
01359 switch (term->Get_type()) {
01360 case LTKIND_LINDEX:
01361 if (term->Get_desc() > coeff_max)
01362 coeff_max = term->Get_desc();
01363 break;
01364 case LTKIND_SUBSCR:
01365 if (term->Get_desc() > sub_coeff_max)
01366 sub_coeff_max = term->Get_desc();
01367 break;
01368 case LTKIND_IV:
01369 if (term->Get_desc() > isym_coeff_max)
01370 isym_coeff_max = term->Get_desc();
01371 break;
01372 }
01373 }
01374
01375 for (i = 0; i <= l1->Num_terms(); i++) {
01376 TERM* term = l1->Get_term(i);
01377 switch (term->Get_type()) {
01378 case LTKIND_LINDEX:
01379 if (term->Get_desc() > coeff_max)
01380 coeff_max = term->Get_desc();
01381 break;
01382 case LTKIND_SUBSCR:
01383 if (term->Get_desc() > sub_coeff_max)
01384 sub_coeff_max = term->Get_desc();
01385 break;
01386 case LTKIND_IV:
01387 if (term->Get_desc() > isym_coeff_max)
01388 isym_coeff_max = term->Get_desc();
01389 break;
01390 }
01391 }
01392
01393
01394 INT* coeff = (INT*) alloca(sizeof(INT) * (coeff_max + 1));
01395 INT* sub_coeff = (INT*) alloca(sizeof(INT) * (sub_coeff_max + 1));
01396 INT* isym_coeff = (INT*) alloca(sizeof(INT) * (isym_coeff_max + 1));
01397 BZERO(coeff, sizeof(INT) * (coeff_max + 1));
01398 BZERO(sub_coeff, sizeof(INT) * (sub_coeff_max + 1));
01399 BZERO(isym_coeff, sizeof(INT) * (isym_coeff_max + 1));
01400
01401 LINEX* l = CXX_NEW(LINEX(mem_pool), mem_pool);
01402
01403
01404 for (i = 0; i <= Num_terms(); i++) {
01405 TERM *term = Get_term(i);
01406 switch (term->Get_type()) {
01407 case LTKIND_NONE:
01408 break;
01409 case LTKIND_CONST:
01410 c += term->Get_coeff();
01411 break;
01412 case LTKIND_LINDEX:
01413 coeff[term->Get_desc()] += term->Get_coeff();
01414 break;
01415 case LTKIND_SUBSCR:
01416 sub_coeff[term->Get_desc()] += term->Get_coeff();
01417 break;
01418 case LTKIND_IV:
01419 isym_coeff[term->Get_desc()] += term->Get_coeff();
01420 break;
01421 }
01422 }
01423 for (i = 0; i<= l1->Num_terms(); ++i) {
01424 TERM *term = l1->Get_term(i);
01425 switch (term->Get_type()) {
01426 case LTKIND_NONE:
01427 break;
01428 case LTKIND_CONST:
01429 c -= term->Get_coeff();
01430 break;
01431 case LTKIND_LINDEX:
01432 coeff[term->Get_desc()] -= term->Get_coeff();
01433 break;
01434 case LTKIND_SUBSCR:
01435 sub_coeff[term->Get_desc()] -= term->Get_coeff();
01436 break;
01437 case LTKIND_IV:
01438 isym_coeff[term->Get_desc()] -= term->Get_coeff();
01439 break;
01440 }
01441 }
01442
01443
01444 l->Set_term(LTKIND_CONST, c, CONST_DESC, 0);
01445 for (i = 0; i <= coeff_max; i++)
01446 if (coeff[i])
01447 l->Set_term(LTKIND_LINDEX, coeff[i], i, 0);
01448 for (i = 0; i <= sub_coeff_max; i++)
01449 if (sub_coeff[i])
01450 l->Set_term(LTKIND_SUBSCR, sub_coeff[i], i, 0);
01451 for (i = 0; i <= isym_coeff_max; i++)
01452 if (isym_coeff[i])
01453 l->Set_term(LTKIND_IV, isym_coeff[i], i, 0);
01454
01455 return l;
01456 }
01457