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