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 #include <elf.h>
00056 #include <sys/elf_whirl.h>
00057 #include <sys/types.h>
00058 #include <alloca.h>
00059
00060 #include "defs.h"
00061 #include "erglob.h"
00062 #include "tracing.h"
00063 #include "cxx_memory.h"
00064 #include "access_vector.h"
00065 #include "loop_info.h"
00066 #include "soe.h"
00067 #include "lno_bv.h"
00068 #include "ipl_summary.h"
00069 #include "ipl_summarize.h"
00070 #include "ipl_summarize_util.h"
00071 #include "ipl_main.h"
00072 #include "ipl_array_bread_write.h"
00073 #include "ipa_section_main.h"
00074 #include "ipa_lno_file.h"
00075 #include "ipl_lno_util.h"
00076
00077
00078 extern SUMMARY *Summary;
00079 extern ARRAY_SUMMARY Array_Summary;
00080
00081 BOOL Trace_Sections = FALSE;
00082
00083 IVAR_ARRAY *Ivar = NULL;
00084
00085
00086 LOOPINFO_TO_DLI_MAP* IPL_Loopinfo_Map = NULL;
00087 PROJ_REGION_TO_ACCESS_ARRAY_MAP* IPL_Access_Array_Map = NULL;
00088
00089 mINT32
00090 SYSTEM_OF_EQUATIONS::_work_cols;
00091 mINT32
00092 SYSTEM_OF_EQUATIONS::_work_rows_eq;
00093 mINT32
00094 SYSTEM_OF_EQUATIONS::_work_rows;
00095
00096
00097
00098
00099 extern void
00100 Init_ivar_arrays()
00101 {
00102 Ivar = Array_Summary_Output->Get_ivar_array();
00103 Ipl_Summary_Symbol = Summary->Get_symbol(0);
00104 }
00105
00106
00107
00108
00109 static INT32
00110 Get_ivar(const IVAR_ARRAY& iv_array, const IVAR& iv)
00111 {
00112 for (INT32 i = 0; i < iv_array.Elements(); ++i) {
00113 if (iv_array[i] == iv) {
00114 return i;
00115 }
00116 }
00117 return -1;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 static BOOL
00127 Access_vector_is_too_messy(ACCESS_VECTOR* av)
00128 {
00129 if (av->Too_Messy ||
00130 av->Delinearized_Symbol ||
00131 av->Contains_Non_Lin_Symb()) {
00132 return TRUE;
00133 }
00134
00135 if (av->Contains_Lin_Symb()) {
00136
00137 INTSYMB_ITER iter(av->Lin_Symb);
00138 for (INTSYMB_NODE* cur = iter.First();
00139 !iter.Is_Empty();
00140 cur = iter.Next()) {
00141
00142 ST* st = cur->Symbol.St();
00143
00144 if (ST_class(st) == CLASS_CONST) {
00145 INT64 const_value;
00146 if (!Targ_Is_Integral(STC_val(st), &const_value) ||
00147 const_value * cur->Coeff < INT32_MIN ||
00148 const_value * cur->Coeff > INT32_MAX) {
00149 return TRUE;
00150 }
00151 }
00152 else if (ST_class(st) != CLASS_VAR) {
00153 return TRUE;
00154 }
00155 else if (ST_level(st) != GLOBAL_SYMTAB) {
00156 if ((ST_sclass(st) != SCLASS_FORMAL &&
00157 ST_sclass(st) != SCLASS_FORMAL_REF) ||
00158 ST_level(st) != CURRENT_SYMTAB) {
00159 return TRUE;
00160 }
00161 }
00162 }
00163 }
00164
00165 return FALSE;
00166 }
00167
00168
00169
00170
00171
00172 LOOPINFO::LOOPINFO(MEM_POOL* m, INT16 cd_idx)
00173 : _nest_level(0),
00174 _flags(0),
00175 _mem_pool(m),
00176 _kernel(CXX_NEW(PROJECTED_KERNEL_ARRAY(m),m))
00177 {
00178 u1.u3._upper_linex = 0;
00179 u1.u3._lower_linex = 0;
00180 u1.u3._step_linex = 0;
00181 u1.u3._symbols = CXX_NEW(LOOP_SYMBOL_ARRAY(m), m);
00182 u1.u3._cd_idx = cd_idx;
00183 }
00184
00185
00186
00187
00188 LINEX*
00189 LOOPINFO::Build_linex(ACCESS_VECTOR* av)
00190 {
00191 if (!av ||
00192 av->Too_Messy ||
00193 av->Delinearized_Symbol ||
00194 av->Contains_Non_Lin_Symb() ||
00195 Access_vector_is_too_messy(av)) {
00196 return 0;
00197 }
00198
00199 LINEX* linex = CXX_NEW(LINEX(Mem_Pool()), Mem_Pool());
00200 linex->Map_access_vector(av, FALSE, NULL);
00201 return linex;
00202 }
00203
00204
00205
00206
00207
00208 void
00209 LOOPINFO::Map_do_loop_info(DO_LOOP_INFO_BASE *dli)
00210 {
00211
00212 IPL_Loopinfo_Map->Enter(this, dli);
00213
00214 Set_nest_level(dli->Get_depth());
00215
00216 ACCESS_ARRAY* lb = dli->Get_lb();
00217 ACCESS_ARRAY* ub = dli->Get_ub();
00218 ACCESS_VECTOR* step = dli->Get_step();
00219
00220 if (lb->Num_Vec() > 1 || ub->Num_Vec() > 1 || !step->Is_Const()) {
00221 if (Trace_Sections) {
00222 fprintf(TFile, "----LOOP has messy bounds---- \n");
00223 dli->Print(TFile);
00224 fprintf(stdout, "----LOOP has messy bounds---- \n");
00225 dli->Print(stdout);
00226 }
00227 Set_messy_bounds();
00228 return;
00229 }
00230
00231 if (!(u1.u3._upper_linex = Build_linex(ub->Dim(0)))) {
00232 Set_messy_ub();
00233 }
00234 if (!(u1.u3._lower_linex = Build_linex(lb->Dim(0)))) {
00235 Set_messy_lb();
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245 INT64 const_offset = step->Const_Offset;
00246 if (step->Const_Offset < 0) {
00247 step->Const_Offset = -step->Const_Offset;
00248 }
00249 u1.u3._step_linex = Build_linex(step);
00250 step->Const_Offset = const_offset;
00251 }
00252
00253
00254
00255
00256
00257 void
00258 LINEX::Map_access_vector(ACCESS_VECTOR *av,
00259 BOOL Is_LNO,
00260 IPA_LNO_READ_FILE* IPA_LNO_File)
00261 {
00262
00263 Is_True(!Access_vector_is_too_messy(av),
00264 ("Messy access vectos can't be mapped into LINEX"));
00265
00266 BOOL processed = FALSE;
00267
00268 for (INT i = 0; i < av->Nest_Depth(); ++i) {
00269 if (av->Loop_Coeff(i) != 0) {
00270 Set_term(LTKIND_LINDEX, (COEFF)av->Loop_Coeff(i), i, 0);
00271 processed = TRUE;
00272 }
00273 }
00274
00275 if (av->Const_Offset != 0) {
00276 Set_term(LTKIND_CONST, (COEFF)av->Const_Offset, CONST_DESC, 0);
00277 processed = TRUE;
00278 }
00279
00280 if (av->Contains_Lin_Symb()) {
00281
00282 INTSYMB_ITER iter(av->Lin_Symb);
00283 for (INTSYMB_NODE* cur = iter.First();
00284 !iter.Is_Empty();
00285 cur = iter.Next()) {
00286
00287
00288 ST* st = cur->Symbol.St();
00289
00290 if (ST_class(st) == CLASS_CONST) {
00291 INT64 const_value = Targ_To_Host(STC_val(st));
00292 Set_term (LTKIND_CONST, (COEFF)const_value*cur->Coeff, CONST_DESC, 0);
00293 processed = TRUE;
00294 }
00295 else {
00296 Is_True(ST_class(st) == CLASS_VAR,
00297 ("LINEX::Map_access_vector(): Unexpected ST_clas"));
00298
00299 IVAR ivar;
00300
00301 if (ST_IDX_level(ST_st_idx(st)) == GLOBAL_SYMTAB) {
00302 new (&ivar) IVAR(st, cur->Symbol.WN_Offset(), cur->Symbol.Type);
00303 }
00304 else {
00305 UINT32 pos = Formal_Position(st);
00306 new (&ivar) IVAR(pos, cur->Symbol.WN_Offset(), cur->Symbol.Type);
00307 }
00308
00309
00310 INT32 ivar_index = -1;
00311 if (!Is_LNO) {
00312 ivar_index = Get_ivar(*Ivar, ivar);
00313
00314 if (ivar_index == -1) {
00315 Ivar->AddElement(ivar);
00316 ivar_index = Ivar->Lastidx();
00317 }
00318 } else {
00319 INT i;
00320
00321 for (i = 0; i < IPA_LNO_File->Ivar_Count(); i++)
00322 if (*(IPA_LNO_File->Ivar(i)) == ivar)
00323 break;
00324
00325 if (i < IPA_LNO_File->Ivar_Count()) {
00326 ivar_index = i;
00327 } else {
00328 ivar_index = IPA_LNO_File->Add_Translated_Ivar(ivar);
00329 }
00330 }
00331
00332 Set_term(LTKIND_IV, cur->Coeff, ivar_index, 0);
00333 processed = TRUE;
00334 }
00335 }
00336 }
00337
00338
00339 if (!processed) {
00340 Set_term(LTKIND_CONST, (COEFF)av->Const_Offset, CONST_DESC, 0);
00341 }
00342 }
00343
00344
00345
00346
00347 INT
00348 LINEX::Num_loop_coeff_terms()
00349 {
00350 INT num_loop_coeff = 0;
00351 for (INT i = 0; i <= Num_terms(); ++i) {
00352 if (Get_term(i)->Get_type() == LTKIND_LINDEX) {
00353 ++num_loop_coeff;
00354 }
00355 }
00356 return num_loop_coeff;
00357 }
00358
00359
00360
00361
00362 BOOL
00363 LINEX::Loop_coeff_terms_equal(LINEX *kernel_linex)
00364 {
00365 INT i;
00366 INT num_coeffs = Num_loop_coeff_terms();
00367 INT num_coeffs_kernel = kernel_linex->Num_loop_coeff_terms();
00368
00369 if (num_coeffs != num_coeffs_kernel)
00370 return FALSE;
00371
00372 for (i=0; i < num_coeffs; ++i)
00373 {
00374 TERM *kernel_term = kernel_linex->Get_term(i);
00375 TERM *term = Get_term(i);
00376 FmtAssert((term->Get_type() == LTKIND_LINDEX),
00377 ("Expecting a term with kind == LTKIND_LINDEX"));
00378 if (term->Get_coeff() != kernel_term->Get_coeff()
00379 || term->Get_desc() != kernel_term->Get_desc())
00380 return FALSE;
00381 }
00382
00383
00384 return TRUE;
00385 }
00386
00387
00388
00389
00390 BOOL
00391 LINEX::Has_loop_coeff(INT depth)
00392 {
00393 INT i;
00394
00395 for (i=0; i <= _larray.Lastidx(); ++i)
00396 {
00397 TERM *t = &(_larray)[i];
00398 if ((t->Get_type() == LTKIND_LINDEX) &&
00399 (t->Get_desc() == depth))
00400 return TRUE;
00401 }
00402 return FALSE;
00403 }
00404
00405
00406
00407
00408
00409
00410 LINEX_ARRAY*
00411 PROJECTED_REGION::Map_to_linex_array()
00412 {
00413 MEM_POOL* m = Mem_Pool();
00414 LINEX_ARRAY* l = CXX_NEW(LINEX_ARRAY(m), m);
00415 PROJECTED_ARRAY* p = Get_projected_array();
00416
00417 for (INT i = 0; i < p->Elements(); ++i) {
00418 PROJECTED_NODE* node = &(*p)[i];
00419 FmtAssert(node->Is_unprojected(), ("Node has been projected\n"));
00420 FmtAssert(!node->Is_messy_lb(), ("Messy lower bound\n"));
00421
00422
00423 LINEX* to = &(*l)[l->Newidx()];
00424 new (to) LINEX(m);
00425 node->Get_lower_linex()->Copy(to);
00426 }
00427
00428 return l;
00429 }
00430
00431
00432
00433
00434
00435 void
00436 LINEX::Add_coupled_terms(LINEX* from)
00437 {
00438 for (INT i = 0; i<=from->Num_terms(); ++i) {
00439 TERM* term = from->Get_term(i);
00440 switch (term->Get_type()) {
00441 case LTKIND_NONE:
00442 case LTKIND_CONST:
00443 case LTKIND_LINDEX:
00444 case LTKIND_IV:
00445 break;
00446 case LTKIND_SUBSCR:
00447 Set_term(term);
00448 break;
00449 default:
00450 Fail_FmtAssertion("Unknown term type encountered \n");
00451 break;
00452 }
00453 }
00454 }
00455
00456
00457
00458
00459
00460 void
00461 PROJECTED_NODE::Set_to_kernel_image(PROJECTED_NODE* pn_kernel,
00462 LINEX* lx_offset)
00463 {
00464 LINEX* lx_lower = pn_kernel->Get_lower_linex();
00465 LINEX* lx_upper = pn_kernel->Get_upper_linex();
00466 LINEX* lx_step = pn_kernel->Get_step_linex();
00467
00468 if (lx_offset != NULL) {
00469 LINEX* lx_new_lower = lx_lower->Merge(lx_offset);
00470 Get_lower_linex()->Free_terms();
00471 Set_lower_linex(lx_new_lower);
00472 if (lx_upper->Num_terms() >= 0) {
00473 LINEX* lx_new_upper = lx_upper->Merge(lx_offset);
00474 Get_upper_linex()->Free_terms();
00475 Set_upper_linex(lx_new_upper);
00476 }
00477 }
00478 else {
00479 Get_lower_linex()->Free_terms();
00480 Get_upper_linex()->Free_terms();
00481 lx_lower->Copy(Get_lower_linex());
00482 lx_upper->Copy(Get_upper_linex());
00483 }
00484 Get_step_linex()->Free_terms();
00485 lx_step->Copy(Get_step_linex());
00486
00487 if (pn_kernel->Get_segment_length_linex() &&
00488 pn_kernel->Get_segment_stride_linex()) {
00489 MEM_POOL* apool = Mem_Pool();
00490 if (Get_segment_length_linex()) {
00491 Get_segment_length_linex()->Free_terms();
00492 }
00493 else {
00494 Set_segment_length_linex(CXX_NEW(LINEX(apool), apool));
00495 }
00496 if (Get_segment_stride_linex()) {
00497 Get_segment_stride_linex()->Free_terms();
00498 }
00499 else {
00500 Set_segment_stride_linex(CXX_NEW(LINEX(apool), apool));
00501 }
00502 pn_kernel->Get_segment_length_linex()->Copy(Get_segment_length_linex());
00503 pn_kernel->Get_segment_stride_linex()->Copy(Get_segment_stride_linex());
00504 }
00505
00506 if (pn_kernel->Is_unprojected())
00507 Set_unprojected();
00508 else
00509 Reset_is_unprojected();
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 void
00540 PROJECTED_REGION::Project(INT depth, LOOPINFO* loop_info)
00541 {
00542 if (Is_messy_region()) {
00543 return;
00544 }
00545
00546
00547 PROJECTED_KERNEL* p = Get_projected_kernel();
00548 FmtAssert(p, ("Null projected kernel encounterd\n"));
00549 if (p->Is_independent(depth)) {
00550 return;
00551 }
00552
00553
00554 if (p->Get_projected_level() > depth) {
00555 p->Project(depth, loop_info);
00556 }
00557
00558 if (p->Get_region() && p->Get_region()->Is_messy_region()) {
00559 Set_messy_region();
00560 return;
00561 }
00562
00563
00564
00565 PROJECTED_ARRAY* array = Get_projected_array();
00566
00567 for (INT i = 0; i < Get_num_dims(); ++i) {
00568
00569 PROJECTED_NODE* node = &(*array)[i];
00570
00571
00572
00573
00574
00575
00576 if (node->Get_lower_linex()->Has_loop_coeff(depth) ||
00577 (!Is_unprojected_region() &&
00578 node->Get_upper_linex()->Has_loop_coeff(depth))) {
00579 PROJECTED_NODE* pnode = p->Get_region()->Get_projected_node(i);
00580 node->Set_to_kernel_image(pnode, p->Get_Difference(i));
00581 if (p->Get_Difference(i)) {
00582 p->Get_Difference(i)->Free_terms();
00583 }
00584 }
00585 }
00586
00587 if (p->Get_Difference()) {
00588 p->Get_Difference()->Resetidx();
00589 }
00590
00591 return;
00592 }
00593
00594
00595
00596
00597 INT
00598 PROJECTED_NODE::Get_constant_term()
00599 {
00600 LINEX* lower = Get_lower_linex();
00601 for (INT i=0; i<lower->Num_terms(); ++i)
00602 {
00603 TERM *term = lower->Get_term(i);
00604 if (term->Get_type() == LTKIND_CONST)
00605 return term->Get_coeff();
00606
00607 }
00608 return 0;
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 void
00621 LINEX::Map_from_SOE(const SYSTEM_OF_EQUATIONS* soe,
00622 INT i,
00623 const LOOP_SYMBOL_ARRAY* syms,
00624 INT depth,
00625 INT dim,
00626 INT which_array,
00627 BOOL is_lower_bound)
00628 {
00629 switch (which_array) {
00630 case 0: {
00631 INT k;
00632 INT32 sign = is_lower_bound ? 1 : -1;
00633
00634
00635 for (k = 0; k < depth; ++k) {
00636 if (soe->Work(i, dim+k) != 0)
00637 Set_term(LTKIND_LINDEX, sign * soe->Work(i, dim+k), k, 0);
00638 }
00639
00640
00641 INT64 Const_Offset = -sign * soe->Work_Const(i);
00642 Set_term(LTKIND_CONST, (COEFF)Const_Offset, CONST_DESC, 0);
00643
00644
00645 for (INT iter = 0;
00646 k+dim < soe->Num_Vars() && iter < syms->Elements();
00647 ++k, ++iter) {
00648 if (soe->Work(i, k+dim)) {
00649 Set_term(LTKIND_IV,
00650 sign * soe->Work(i,k+dim),
00651 (*syms)[iter].Ivar_Index(), 0);
00652 }
00653 }
00654 break;
00655 }
00656
00657 case 1: {
00658 const IMAT& aeq = soe->Aeq();
00659 const INT64* beq = soe->Beq();
00660 INT k;
00661
00662
00663 for (k = 0; k < depth; ++k) {
00664 if (aeq(i, dim+k) != 0)
00665 Set_term(LTKIND_LINDEX, -aeq(i, dim+k), k, 0);
00666 }
00667
00668 INT64 Const_Offset = beq[i];
00669 Set_term(LTKIND_CONST, (COEFF)Const_Offset, CONST_DESC, 0);
00670
00671 for (INT iter=0;
00672 k+dim < soe->Num_Vars() && iter < syms->Elements();
00673 ++k, ++iter) {
00674 if (aeq(i,k+dim)) {
00675 Set_term(LTKIND_IV, aeq(i, k+dim), (*syms)[iter].Ivar_Index(), 0);
00676 }
00677 }
00678 break;
00679 }
00680
00681 case 2: {
00682 const IMAT& ale = soe->Ale();
00683 const INT64* ble = soe->Ble();
00684 INT k;
00685 INT32 sign = is_lower_bound ? 1 : -1;
00686
00687 for (k = 0; k < depth; ++k) {
00688 if (ale(i, dim+k) != 0)
00689 Set_term(LTKIND_LINDEX, sign * ale(i, dim+k), k, 0);
00690 }
00691
00692 INT64 Const_Offset = -sign * ble[i];
00693 Set_term(LTKIND_CONST, (COEFF)Const_Offset, CONST_DESC, 0);
00694
00695 for (INT iter = 0;
00696 k+dim < soe->Num_Vars() && iter < syms->Elements();
00697 ++k, ++iter) {
00698 if (ale(i, k+dim)) {
00699 Set_term(LTKIND_IV,
00700 sign * ale(i, k+dim),
00701 (*syms)[iter].Ivar_Index(),
00702 0);
00703 }
00704 }
00705 break;
00706 }
00707
00708 default:
00709 Fail_FmtAssertion("Illegal Which Array \n");
00710 break;
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719
00720 void LINEX::Substitute_Lindex(INT lindex,
00721 LINEX* lx_substitute)
00722 {
00723 INT lindex_coeff = 0;
00724 LINEX lx_temp(_larray.Get_Mem_Pool());
00725 INT freeze_num_terms = Num_terms();
00726 INT i;
00727
00728 for (i = 0; i <= freeze_num_terms; i++) {
00729 TERM* tm = Get_term(i);
00730 if (tm->Get_type() == LTKIND_LINDEX && tm->Get_desc() == lindex) {
00731 lindex_coeff += tm->Get_coeff();
00732 } else {
00733 lx_temp.Set_term(tm);
00734 }
00735 }
00736 Free_terms();
00737 for (i = 0; i <= lx_temp.Num_terms(); i++)
00738 Set_term(lx_temp.Get_term(i));
00739 if (lindex_coeff == 0)
00740 return;
00741 for (i = 0; i <= lx_substitute->Num_terms(); i++) {
00742 TERM* tm = lx_substitute->Get_term(i);
00743 Set_term(tm->Get_type(), tm->Get_coeff() * lindex_coeff, tm->Get_desc(),
00744 tm->Get_projected_level());
00745 }
00746 Simplify();
00747 }
00748
00749
00750
00751
00752 void
00753 PROJECTED_REGION::Set_region(SYSTEM_OF_EQUATIONS* soe,
00754 LOOP_SYMBOL_ARRAY* syms,
00755 INT strides[],
00756 INT pivot_row,
00757 INT pos,
00758 INT loop_step,
00759 INT projected_axle)
00760 {
00761 FmtAssert(soe, ("NULL SOE pointer passed to Set_Region"));
00762
00763 if (Trace_Sections) {
00764 fprintf(stdout, "PROJECTED_REGION::Set_region() BEGIN\n");
00765 fprintf(stdout, "pivot_row = %d\n", pivot_row);
00766 fprintf(stdout, "pos = %d\n", pos);
00767 fprintf(stdout, "loop_step = %d\n", loop_step);
00768 fprintf(stdout, "projected_axle = %d\n", projected_axle);
00769 fprintf(TFile, "PROJECTED_REGION::Set_region() BEGIN\n");
00770 fprintf(TFile, "pivot_row = %d\n", pivot_row);
00771 fprintf(TFile, "pos = %d\n", pos);
00772 fprintf(TFile, "loop_step = %d\n", loop_step);
00773 fprintf(TFile, "projected_axle = %d\n", projected_axle);
00774 }
00775
00776 Set_type(NON_MESSY_REGION);
00777
00778
00779 PROJECTED_ARRAY* array = Get_projected_array();
00780 if (!array) {
00781 array = CXX_NEW(PROJECTED_ARRAY(Mem_Pool()), Mem_Pool());
00782 Set_projected_array(array);
00783 }
00784
00785
00786 INT num_dims = Get_num_dims();
00787 INT depth = Get_depth();
00788 array->Force_Alloc_array(num_dims);
00789 array->Setidx(num_dims-1);
00790 for (INT ii = 0; ii < num_dims; ++ii) {
00791 (*array)[ii].Init(Mem_Pool());
00792 (*array)[ii].Set_unprojected();
00793 }
00794
00795
00796
00797
00798 INT pivot_column = num_dims+pos;
00799 INT multiple = -soe->Aeq()(pivot_row, pivot_column);
00800 INT i;
00801
00802 for (i = 0; i < num_dims; ++i) {
00803 if (soe->Aeq()(pivot_row,i) != 0) {
00804 strides[i] = multiple*loop_step;
00805 break;
00806 }
00807 }
00808
00809 {
00810 BIT_VECTOR *ancestor_lo = CXX_NEW(BIT_VECTOR(num_dims,
00811 Array_Summary.Get_local_pool()), Array_Summary.Get_local_pool());
00812 BIT_VECTOR *ancestor_up = CXX_NEW(BIT_VECTOR(num_dims,
00813 Array_Summary.Get_local_pool()), Array_Summary.Get_local_pool());
00814
00815
00816 INT k = 0;
00817 for (i = 0; i < soe->Num_Eq_Constraints(); ++i) {
00818 if (i != pivot_row) {
00819 for (; k < num_dims; ++k) {
00820 if (k != projected_axle && soe->Aeq()(i,k) != 0) {
00821 (*array)[k].Set_linex_eq(soe, i, k, syms, depth, num_dims,
00822 strides[k]);
00823 ancestor_lo->Set(k);
00824 ancestor_up->Set(k);
00825 break;
00826 }
00827 }
00828 }
00829 }
00830
00831
00832 BOOL progress = TRUE;
00833 while (progress &&
00834 ((ancestor_up->Pop_Count() != num_dims) ||
00835 (ancestor_lo->Pop_Count() != num_dims))) {
00836 progress = FALSE;
00837 for (i = 0; i < soe->Num_Le_Constraints(); ++i) {
00838 INT axle = -1;
00839 for (k = 0; k < num_dims; ++k) {
00840 if (soe->Ale()(i,k) < 0 && !ancestor_lo->Test(k) ||
00841 soe->Ale()(i,k) > 0 && !ancestor_up->Test(k)) {
00842 if (axle>=0) {
00843 axle = -1;
00844 break;
00845 }
00846 else {
00847 axle = k;
00848 }
00849 }
00850 }
00851
00852 if (axle >= 0) {
00853
00854
00855 progress = TRUE;
00856 if (soe->Ale()(i,axle) < 0) {
00857 (*array)[axle].Set_linex_le(soe, i, axle, syms, depth, num_dims,
00858 strides[axle]);
00859 ancestor_lo->Set(axle);
00860 }
00861 else {
00862 (*array)[axle].Set_linex_le(soe, i, axle, syms, depth, num_dims,
00863 strides[axle]);
00864 ancestor_up->Set(axle);
00865 }
00866 (*array)[axle].Reset_is_unprojected();
00867 }
00868 }
00869 }
00870 if (!progress) {
00871 Set_messy_region();
00872 if (Trace_Sections) {
00873 fprintf(TFile, "PROJECTED_REGION::Set_Region: No progress\n");
00874 fprintf(stdout, "PROJECTED_REGION::Set_Region: No progress\n");
00875 }
00876 }
00877 }
00878 }
00879
00880
00881
00882
00883
00884
00885
00886 BOOL
00887 is_equality(const SYSTEM_OF_EQUATIONS *soe, const INT i, const INT j)
00888 {
00889 for (INT k = 0; k < soe->Num_Vars(); ++k)
00890 if ((soe->Work(i,k)+soe->Work(j,k)) != 0)
00891 return FALSE;
00892
00893 return (soe->Work_Const(i) + soe->Work_Const(j) == 0);
00894 }
00895
00896
00897
00898
00899
00900 void
00901 PROJECTED_NODE::Set_linexs(const SYSTEM_OF_EQUATIONS *soe,
00902 INT i,
00903 INT j,
00904 const LOOP_SYMBOL_ARRAY* syms,
00905 INT depth,
00906 INT dim,
00907 INT stride)
00908 {
00909 INT k;
00910 BOOL Has_subscr_ltkind = FALSE;
00911
00912
00913 Reset_node();
00914
00915 LINEX* lower = Get_lower_linex();
00916 LINEX* upper = Get_upper_linex();
00917 LINEX* step = Get_step_linex();
00918
00919 step->Set_term(LTKIND_CONST, abs(stride), CONST_DESC, 0);
00920
00921
00922 if (is_equality(soe, i, j)) {
00923 lower->Map_from_SOE(soe, i, syms, depth, dim, 0, TRUE);
00924
00925
00926 for (k = 0; k < dim; ++k) {
00927 if (soe->Work(i,k) != 0 && 2*k != i) {
00928 Has_subscr_ltkind = TRUE;
00929 break;
00930 }
00931 }
00932
00933 if (Has_subscr_ltkind) {
00934 for (k = 0; k<dim; ++k) {
00935 if (soe->Work(i,k) != 0) {
00936 lower->Set_term(LTKIND_SUBSCR, soe->Work(i,k),k,0);
00937 }
00938 }
00939 }
00940
00941 return;
00942 }
00943
00944
00945 lower->Map_from_SOE(soe, i, syms, depth,dim, 0, TRUE);
00946
00947 for (k = 0; k < dim; ++k) {
00948 if (soe->Work(i,k) != 0 && 2*k != i) {
00949 Has_subscr_ltkind = TRUE;
00950 break;
00951 }
00952 }
00953
00954 if (Has_subscr_ltkind) {
00955 for (k = 0 ; k < dim; ++k) {
00956 if (soe->Work(i,k)) {
00957 lower->Set_term(LTKIND_SUBSCR, soe->Work(i,k),k,0);
00958 }
00959 }
00960 }
00961
00962
00963 Has_subscr_ltkind = FALSE;
00964
00965 upper->Map_from_SOE(soe, i, syms, depth, dim, 0, FALSE);
00966
00967 for (k = 0; k < dim; ++k) {
00968 if (soe->Work(i,k) != 0 && 2*k != i) {
00969 Has_subscr_ltkind = TRUE;
00970 break;
00971 }
00972 }
00973
00974 if (Has_subscr_ltkind) {
00975 for (k = 0; k < dim; ++k) {
00976 if (soe->Work(i,k)) {
00977 upper->Set_term(LTKIND_SUBSCR, soe->Work(i,k), k, 0);
00978 }
00979 }
00980 }
00981 }
00982
00983
00984
00985
00986
00987
00988
00989 void
00990 PROJECTED_NODE::Set_linex_eq(const SYSTEM_OF_EQUATIONS *soe,
00991 INT i,
00992 INT j,
00993 const LOOP_SYMBOL_ARRAY *syms,
00994 INT depth,
00995 INT dim,
00996 INT stride)
00997 {
00998 INT k;
00999
01000 if (Trace_Sections) {
01001 fprintf(TFile, "Entered set_linex_eq: \n");
01002 fprintf(stdout, "Entered set_linex_eq: \n");
01003 }
01004
01005
01006 Reset_node();
01007 Set_unprojected();
01008
01009
01010 LINEX* step = Get_step_linex();
01011 step->Set_term(LTKIND_CONST, abs(stride), CONST_DESC, 0);
01012 if (Trace_Sections) {
01013 fprintf(TFile, "i = %d, depth = %d, dim = %d \n", i, depth, dim);
01014 fprintf(stdout, "i = %d, depth = %d, dim = %d \n", i, depth, dim);
01015 }
01016
01017 LINEX* lower = Get_lower_linex();
01018 if (Trace_Sections) {
01019 fprintf(stdout, "lower linex before mapping is\n");
01020 lower->Print(stdout);
01021 fprintf(TFile, "lower linex before mapping is\n");
01022 lower->Print(TFile);
01023 }
01024
01025 lower->Map_from_SOE(soe, i, syms, depth, dim, 1, TRUE);
01026
01027
01028 BOOL has_coupled_subscript_terms = FALSE;
01029 for (k = 0; k < dim; ++k) {
01030 if (soe->Aeq()(i,k) && k != j) {
01031 has_coupled_subscript_terms = TRUE;
01032 break;
01033 }
01034 }
01035
01036 if (has_coupled_subscript_terms) {
01037 for (k=0; k< dim; ++k) {
01038 if (soe->Aeq()(i,k) && k != j) {
01039 lower->Set_term(LTKIND_SUBSCR, -soe->Aeq()(i,k), k, 0);
01040 }
01041 }
01042 }
01043
01044 if (Trace_Sections) {
01045 fprintf(TFile, "lower linex after mapping is\n");
01046 lower->Print(TFile);
01047 fprintf(stdout, "lower linex after mapping is\n");
01048 lower->Print(stdout);
01049 }
01050 }
01051
01052
01053
01054
01055
01056 void
01057 PROJECTED_NODE::Set_linex_le(const SYSTEM_OF_EQUATIONS *soe,
01058 INT i,
01059 INT j,
01060 const LOOP_SYMBOL_ARRAY *syms,
01061 INT depth,
01062 INT dim,
01063 INT stride)
01064 {
01065 INT k;
01066
01067
01068 LINEX* step = Get_step_linex();
01069 FmtAssert(step, ("Set_linex_le: Null step encountered\n"));
01070 step->Free_terms();
01071 step->Set_term(LTKIND_CONST, abs(stride), CONST_DESC, 0);
01072
01073
01074 if (soe->Ale()(i,j)<0) {
01075 if (Trace_Sections) {
01076 fprintf(TFile, "Set_linex_le: setting the lower bound\n");
01077 fprintf(stdout, "Set_linex_le: setting the lower bound\n");
01078 }
01079
01080 LINEX* lower = Get_lower_linex();
01081 FmtAssert(lower, ("Set_linex_le: Null lower encountered\n"));
01082 lower->Free_terms();
01083 lower->Map_from_SOE(soe, i, syms, depth, dim, 2, TRUE);
01084
01085 BOOL Has_subscr_ltkind = FALSE;
01086 for (k = 0; k<dim; ++k) {
01087 if (soe->Ale()(i,k) != 0 && k != j) {
01088 Has_subscr_ltkind = TRUE;
01089 break;
01090 }
01091 }
01092
01093 if (Has_subscr_ltkind) {
01094 for (k = 0; k < dim; ++k) {
01095 if (soe->Ale()(i,k) && k != j) {
01096 lower->Set_term(LTKIND_SUBSCR, soe->Ale()(i,k), k, 0);
01097 }
01098 }
01099 }
01100 }
01101
01102 else {
01103 if (Trace_Sections) {
01104 fprintf(TFile, "Set_linex_le: setting the upper bound\n");
01105 fprintf(stdout, "Set_linex_le: setting the upper bound\n");
01106 }
01107
01108 LINEX* upper = Get_upper_linex();
01109 FmtAssert(upper, ("Set_linex_le: Null upper encountered\n"));
01110 upper->Free_terms();
01111 upper->Map_from_SOE(soe, i, syms, depth,dim, 2, FALSE);
01112
01113 BOOL Has_subscr_ltkind = FALSE;
01114 for (k = 0; k<dim; ++k) {
01115 if (soe->Ale()(i,k) != 0 && k != j) {
01116 Has_subscr_ltkind = TRUE;
01117 break;
01118 }
01119 }
01120
01121 if (Has_subscr_ltkind ) {
01122 for (k = 0; k < dim; ++k) {
01123 if (soe->Ale()(i,k) && k != j) {
01124 upper->Set_term(LTKIND_SUBSCR, -soe->Ale()(i,k), k, 0);
01125 }
01126 }
01127 }
01128 }
01129 }
01130
01131
01132
01133
01134
01135 PROJECTED_REGION::PROJECTED_REGION(ACCESS_ARRAY* array,
01136 MEM_POOL* m,
01137 LOOPINFO* loop,
01138 BOOL in_ipl,
01139 IPA_LNO_READ_FILE* IPA_LNO_File)
01140 {
01141 mUINT8 num_dim = array->Num_Vec();
01142 mUINT8 depth = loop ? loop->Get_nest_level()+1 : 0;
01143 INT i;
01144
01145
01146 Set_projected_array(NULL);
01147 Set_type(MESSY_REGION);
01148 Set_num_dims(num_dim);
01149 Set_depth(depth);
01150 Set_projected_kernel(NULL);
01151 Set_Mem_Pool(m);
01152
01153
01154 if (in_ipl) {
01155 IPL_Access_Array_Map->Enter(this, array);
01156 }
01157
01158
01159 if (!array || array->Too_Messy) {
01160 return;
01161 }
01162
01163 for (i = 0; i < num_dim; ++i) {
01164 if (Access_vector_is_too_messy(array->Dim(i))) {
01165 return;
01166 }
01167 }
01168
01169
01170
01171
01172 Set_type(NON_MESSY_REGION);
01173 Set_unprojected();
01174 Set_projected_array(CXX_NEW(PROJECTED_ARRAY(m), m));
01175 Get_projected_array()->Force_Alloc_array(num_dim);
01176 Get_projected_array()->Setidx(num_dim-1);
01177
01178 for (i = 0; i < num_dim; ++i) {
01179 PROJECTED_NODE* pn = Get_projected_node(i);
01180 pn->Init(m);
01181 pn->Get_lower_linex()->Map_access_vector(array->Dim(i), !in_ipl,
01182 IPA_LNO_File);
01183 pn->Set_unprojected();
01184 }
01185
01186
01187 if (!loop) {
01188 return;
01189 }
01190
01191
01192 BOOL match = TRUE;
01193 PROJECTED_KERNEL_ARRAY* kernels = loop->Get_kernels();
01194 for (i = 0; i <= kernels->Lastidx(); ++i) {
01195
01196 PROJECTED_KERNEL* kernel = &(*kernels)[i];
01197 INT j;
01198
01199
01200 if (kernel->Get_depth() != depth ||
01201 kernel->Get_num_dims() != num_dim) {
01202 continue;
01203 }
01204
01205 for (j = 0; j < num_dim; ++j) {
01206
01207
01208 LINEX* lower = Get_projected_node(j)->Get_lower_linex();
01209 LINEX* kernel_linex = kernel->Get_linex(j);
01210 if (!lower->Loop_coeff_terms_equal(kernel_linex)) {
01211 break;
01212 }
01213 }
01214
01215 if (j != num_dim) {
01216 match = FALSE;
01217 }
01218
01219 if (match) {
01220 kernel->Set_Difference(this);
01221 Set_projected_kernel(kernel);
01222 break;
01223 }
01224 }
01225
01226
01227
01228 if (Get_projected_kernel() == NULL) {
01229 PROJECTED_KERNEL* k = &(*kernels)[kernels->Newidx()];
01230 k->Init(this, loop);
01231 Set_projected_kernel(k);
01232 }
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 INT
01246 PROJECTED_REGION::Compare(PROJECTED_REGION *b)
01247 {
01248 INT i;
01249 INT result = 0;
01250
01251 if (Trace_Sections)
01252 {
01253 fprintf(TFile,"Compare two PROJECTED REGIONs \n");
01254 b->Print(TFile);
01255 Print(TFile);
01256 fprintf(stdout,"Compare two PROJECTED REGIONs \n");
01257 b->Print(stdout);
01258 Print(stdout);
01259 }
01260
01261
01262 if (Get_type() != b->Get_type())
01263 return 0;
01264
01265 if (Get_num_dims() != b->Get_num_dims())
01266 return 0;
01267
01268
01269 PROJECTED_ARRAY *array_a = Get_projected_array();
01270 PROJECTED_ARRAY *array_b = b->Get_projected_array();
01271
01272 for (i=0; i< Get_num_dims(); ++i)
01273 {
01274 PROJECTED_NODE *node_a, *node_b;
01275 node_a = &(*array_a)[i];
01276 node_b = &(*array_b)[i];
01277 if (!node_a->Equivalent(*node_b))
01278 return 0;
01279 }
01280
01281 MEM_POOL *local_pool = Array_Summary.Get_local_pool();
01282 MEM_POOL_Push(local_pool);
01283 {
01284
01285 SYSTEM_OF_EQUATIONS* soe =
01286 CXX_NEW(SYSTEM_OF_EQUATIONS(0, 0, Get_num_dims()+Get_depth(),
01287 local_pool), local_pool);
01288 LOOP_SYMBOL_ARRAY* syms =
01289 CXX_NEW(LOOP_SYMBOL_ARRAY(local_pool), local_pool);
01290
01291
01292
01293
01294
01295
01296 for (i = 0; i < Get_num_dims(); ++i) {
01297 Add_to_SOE(this, i, soe, TRUE, syms, Get_depth(), Trace_Sections);
01298 Add_to_SOE(b, i, soe, TRUE, syms, Get_depth(), Trace_Sections);
01299 }
01300
01301 if (!soe->Copy_To_Work()) goto return_point;
01302 {
01303 INT16 * lower = CXX_NEW_ARRAY(INT16, Get_num_dims(), local_pool);
01304 INT16 * upper = CXX_NEW_ARRAY(INT16, Get_num_dims(), local_pool);
01305
01306 for (i = 0; i < Get_num_dims(); ++i)
01307 {
01308 lower[i] = soe->Simple_Redundant(4*i, 4*i+2);
01309 upper[i] = soe->Simple_Redundant(4*i+1, 4*i+3);
01310 }
01311
01312
01313 for (i = 0; i < Get_num_dims(); ++i) {
01314 if (lower[i]!=3 || upper[i]!=3)
01315 break;
01316 }
01317
01318 if (i==Get_num_dims()) {
01319 CXX_DELETE(lower, local_pool);
01320 CXX_DELETE(upper, local_pool);
01321 result = 3;
01322 goto return_point;
01323 }
01324
01325 BOOL exists_1 = FALSE;
01326 BOOL exists_2 = FALSE;
01327
01328 for (; i < Get_num_dims(); ++i) {
01329 exists_1 = (exists_1 || lower[i]==1 || upper[i]==1);
01330 exists_2 = (exists_2 || lower[i]==2 || upper[i]==2);
01331 if (exists_1 && exists_2) {
01332 CXX_DELETE(lower, local_pool);
01333 CXX_DELETE(upper, local_pool);
01334 result = 0;
01335 goto return_point;
01336 }
01337 }
01338
01339 CXX_DELETE(lower, local_pool);
01340 CXX_DELETE(upper, local_pool);
01341
01342
01343
01344 BOOL redundant_1 = FALSE;
01345 BOOL redundant_2 = FALSE;
01346
01347 if (!exists_2) redundant_1 = soe->Prove_Redundant(0,Get_num_dims());
01348 if (redundant_1 && exists_1) {
01349 result = 2;
01350 goto return_point;
01351 }
01352
01353 if (!exists_1) redundant_2 = soe->Prove_Redundant(1,Get_num_dims());
01354 if (redundant_2 && exists_2) {
01355 result = 1;
01356 goto return_point;
01357 }
01358
01359 if (redundant_1 && redundant_2) {
01360 result = 3;
01361 goto return_point;
01362 }
01363 }
01364 return_point:
01365 CXX_DELETE(syms, local_pool);
01366 CXX_DELETE(soe, local_pool);
01367
01368 }
01369 MEM_POOL_Pop(local_pool);
01370
01371 return result;
01372
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385 void
01386 LOOPINFO::Add_bound(LINEX *l,
01387 SYSTEM_OF_EQUATIONS *soe,
01388 mUINT8 depth,
01389 INT num_dim,
01390 INT num_syms,
01391 LOOP_SYMBOL_ARRAY* sym)
01392 {
01393 INT pos, c = 0;
01394
01395 if (Trace_Sections) {
01396 fprintf(TFile, "\n Add_bound: Adding a LINEX to the SOE\n");
01397 l->Print(TFile);
01398 fprintf(stdout, "\n Add_bound: Adding a LINEX to the SOE\n");
01399 l->Print(stdout);
01400 }
01401
01402
01403
01404 INT vector_size = num_dim + depth + num_syms;
01405 if (Trace_Sections) {
01406 fprintf(TFile, "num_dim = %d, depth = %d, num_syms = %d vector size %d \n",
01407 num_dim, depth, num_syms,vector_size);
01408 fprintf(stdout,"num_dim = %d, depth = %d, num_syms = %d vector size %d \n",
01409 num_dim, depth, num_syms,vector_size);
01410 }
01411
01412 mINT32* v = (mINT32*) alloca(sizeof(mINT32) * vector_size);
01413 bzero (v, sizeof(mINT32)*vector_size);
01414
01415
01416
01417 for (INT i=0; i<= l->Num_terms(); ++i) {
01418 TERM* term = l->Get_term(i);
01419 switch (term->Get_type()) {
01420 case LTKIND_CONST:
01421 c = term->Get_coeff();
01422 break;
01423
01424 case LTKIND_LINDEX:
01425
01426 v[num_dim+term->Get_desc()] = term->Get_coeff();
01427 break;
01428
01429 case LTKIND_IV:
01430 pos = Locate_symbol(sym, soe, LOOP_SYMBOL(term->Get_desc()));
01431 v[num_dim+depth+pos] = term->Get_coeff();
01432 break;
01433
01434 case LTKIND_SUBSCR:
01435 Fail_FmtAssertion("Add_bound:: LTKIND_SUBSCR not supported\n");
01436 break;
01437
01438 case LTKIND_NONE:
01439 Fail_FmtAssertion("Add_bound:: unknown term kind LTKIND_NONE\n");
01440 break;
01441 }
01442 }
01443
01444 if (Trace_Sections) {
01445 int k;
01446 fprintf(TFile, "vector size = %d \n", vector_size);
01447
01448 for (k=0; k<vector_size; ++k)
01449 fprintf (TFile, "v[%d] = %d \n", k, v[k]);
01450
01451 fprintf(stdout, "vector size = %d \n", vector_size);
01452
01453 for (k=0; k<vector_size; ++k)
01454 fprintf (stdout, "v[%d] = %d \n", k, v[k]);
01455 }
01456
01457 soe->Add_Le(v, c);
01458
01459 if (Trace_Sections) {
01460 fprintf(TFile,"\n Add_bound: New SOE is: \n");
01461 soe->Print(TFile);
01462 fprintf(stdout,"\n Add_bound: New SOE is: \n");
01463 soe->Print(stdout);
01464 }
01465 }
01466
01467
01468
01469
01470
01471
01472
01473 LINEX* LOOPINFO::Min_value()
01474 {
01475 INT i;
01476 MEM_POOL* pool = Mem_Pool();
01477
01478 if (Is_messy_lb())
01479 return NULL;
01480
01481 INT lx_coeff = 0;
01482 LINEX* lx_lower = Get_lower_linex();
01483
01484 for (i = 0; i <= lx_lower->Num_terms(); i++) {
01485 TERM* tm = lx_lower->Get_term(i);
01486 if (tm->Get_type() == LTKIND_LINDEX) {
01487
01488 if (tm->Get_desc() != Get_nest_level())
01489 return NULL;
01490 lx_coeff += tm->Get_coeff();
01491 }
01492 }
01493
01494 if (lx_coeff != -1)
01495 return NULL;
01496
01497 LINEX* lx_result = CXX_NEW(LINEX(pool), pool);
01498 for (i = 0; i <= lx_lower->Num_terms(); i++) {
01499 TERM* tm = lx_lower->Get_term(i);
01500 if (tm->Get_type() != LTKIND_LINDEX)
01501 lx_result->Set_term(tm->Get_type(), tm->Get_type() == LTKIND_CONST
01502 ? -tm->Get_coeff() : tm->Get_coeff(), tm->Get_desc(),
01503 tm->Get_projected_level());
01504 }
01505
01506 return lx_result;
01507 }
01508
01509
01510
01511
01512
01513
01514
01515 LINEX* LOOPINFO::Max_value()
01516 {
01517 MEM_POOL* pool = Mem_Pool();
01518 INT i;
01519
01520 if (Is_messy_ub())
01521 return NULL;
01522
01523 INT lx_coeff = 0;
01524 LINEX* lx_upper = Get_upper_linex();
01525
01526 for (i = 0; i <= lx_upper->Num_terms(); i++) {
01527 TERM* tm = lx_upper->Get_term(i);
01528 if (tm->Get_type() == LTKIND_LINDEX) {
01529
01530 if (tm->Get_desc() != Get_nest_level())
01531 return NULL;
01532 lx_coeff += tm->Get_coeff();
01533 }
01534 }
01535
01536
01537 if (lx_coeff != 1)
01538 return NULL;
01539
01540 LINEX* lx_result = CXX_NEW(LINEX(pool), pool);
01541 for (i = 0; i <= lx_upper->Num_terms(); i++) {
01542 TERM* tm = lx_upper->Get_term(i);
01543
01544 if (tm->Get_type() != LTKIND_LINDEX)
01545 lx_result->Set_term(tm->Get_type(), tm->Get_type() == LTKIND_CONST
01546 ? tm->Get_coeff() : -tm->Get_coeff(), tm->Get_desc(),
01547 tm->Get_projected_level());
01548 }
01549
01550 return lx_result;
01551 }
01552
01553
01554
01555
01556 static BOOL
01557 Is_nested_within(WN* inner, WN* outer)
01558 {
01559 Is_True(WN_operator(inner) == OPR_DO_LOOP &&
01560 WN_operator(outer) == OPR_DO_LOOP,
01561 ("Is_nested_within: Both nodes must be DO loops"));
01562
01563 for (WN* parent = LWN_Get_Parent(inner);
01564 parent;
01565 parent = LWN_Get_Parent(parent)) {
01566 if (parent == outer) {
01567 return TRUE;
01568 }
01569 }
01570 return FALSE;
01571 }
01572
01573
01574
01575
01576 static INT
01577 Get_surrounding_loop_count(LOOPINFO *l)
01578 {
01579 INT count = 1;
01580 WN* current = Get_cd_by_idx(l->Get_cd_idx())->Get_wn();
01581 #if _RELY_ON_CD_
01582 SUMMARY_CONTROL_DEPENDENCE* cd = Get_controlling_stmt(current);
01583 while (cd) {
01584 WN* parent = cd->Get_wn();
01585 if (cd->Is_do_loop() && Is_nested_within(current, parent)) {
01586 ++count;
01587 current = parent;
01588 }
01589 cd = Get_controlling_stmt(parent);
01590 }
01591 #else
01592 Is_True(WN_operator(current) == OPR_DO_LOOP,
01593 ("WN for the LOOPINFO is not a OPR_DO_LOOP"));
01594 while (current = LWN_Get_Parent(current)) {
01595 if (WN_operator(current) == OPR_DO_LOOP) {
01596 ++count;
01597 }
01598 }
01599 #endif
01600 return count;
01601 }
01602
01603
01604
01605
01606 static LOOPINFO*
01607 Get_parent(LOOPINFO *l)
01608 {
01609 WN* wn = Get_cd_by_idx(l->Get_cd_idx())->Get_wn();
01610 SUMMARY_CONTROL_DEPENDENCE* cd = Get_controlling_stmt(wn);
01611 while (cd && !(cd->Is_do_loop() && Is_nested_within(wn, cd->Get_wn()))) {
01612 cd = Get_controlling_stmt(cd->Get_wn());
01613 }
01614 if (cd && cd->Is_do_loop()) {
01615 return Array_Summary.Get_cfg_node_array(Get_cd_idx(cd))->Get_loopinfo();
01616 }
01617 return NULL;
01618 }
01619
01620
01621
01622
01623
01624
01625
01626 void
01627 PROJECTED_KERNEL::Project(mUINT8 level, LOOPINFO* loop)
01628 {
01629 if (_projected_level <= level ) return;
01630 _projected_level = level;
01631
01632 MEM_POOL* local_array_pool = Array_Summary.Get_local_pool();
01633
01634 MEM_POOL_Push(local_array_pool);
01635 {
01636 INT num_vectors = Get_num_dims();
01637
01638
01639
01640 SYSTEM_OF_EQUATIONS* soe =
01641 CXX_NEW(SYSTEM_OF_EQUATIONS(0, 0, num_vectors+_depth, local_array_pool),
01642 local_array_pool);
01643
01644 LOOP_SYMBOL_ARRAY *syms = CXX_NEW(LOOP_SYMBOL_ARRAY(local_array_pool), local_array_pool);
01645
01646 INT* strides = CXX_NEW_ARRAY(INT, num_vectors, local_array_pool);
01647 INT* which_axle = CXX_NEW_ARRAY(INT, num_vectors, local_array_pool);
01648 INT eq_count = 0;
01649 INT i;
01650
01651 PROJECTED_REGION* region;
01652
01653 if ((region = Get_region()) != NULL) {
01654 for (i = 0; i < num_vectors; ++i) {
01655 Add_to_SOE(region, i, soe, FALSE, syms, _depth, Trace_Sections);
01656
01657 LINEX* step = region->Get_projected_node(i)->Get_step_linex();
01658 FmtAssert(step->Is_const(), ("Expecting a constant step"));
01659 strides[i] = step->Get_term(0)->Get_coeff();
01660 if (region->Get_projected_node(i)->Is_unprojected()) {
01661 which_axle[eq_count] = i;
01662 eq_count++;
01663 }
01664 }
01665 }
01666
01667
01668
01669 else {
01670 for (i = 0; i < num_vectors; ++i) {
01671 INT num_syms = Ivar->Elements();
01672 Get_linex(i)->Add_access(soe, _depth, num_vectors, i, num_syms,
01673 ACTION_EQ, syms, Trace_Sections);
01674 strides[i] = 1;
01675 which_axle[i] = i;
01676 }
01677
01678 region = CXX_NEW(PROJECTED_REGION(MESSY_REGION, _depth, num_vectors,
01679 Array_Summary.Get_array_pool()), Array_Summary.Get_array_pool());
01680 Set_region(region);
01681 eq_count = num_vectors;
01682 }
01683
01684
01685
01686 INT pivot_row;
01687 INT step;
01688 INT num_do_loops = Get_surrounding_loop_count(loop);
01689 INT endloop = num_do_loops - level;
01690
01691 LOOPINFO *cur_loop = loop;
01692 for (i = 0 ; i < endloop; ++i) {
01693 if (cur_loop->Is_messy_any_bounds()) {
01694 if (Trace_Sections) {
01695 fprintf(TFile, "Messy bounds for loop during projection");
01696 cur_loop->Print(TFile);
01697 fprintf(stdout, "Messy bounds for loop during projection");
01698 cur_loop->Print(stdout);
01699 }
01700 goto pop_and_return;
01701 }
01702 else {
01703 LINEX *step_linex = cur_loop->Get_step_linex();
01704
01705 FmtAssert(!cur_loop->Is_messy_step(),
01706 ("Project: expecting non-messy step "));
01707 FmtAssert(step_linex->Is_const(),
01708 ("Project: step is not a constant \n"));
01709
01710 step = step_linex->Get_term(0)->Get_coeff();
01711
01712
01713
01714 INT num_syms = Ivar->Elements();
01715
01716 if ( !cur_loop->Is_messy_lb() )
01717 cur_loop->Add_bound(cur_loop->Get_lower_linex(), soe,
01718 _depth, num_vectors, num_syms, syms);
01719
01720 if ( !cur_loop->Is_messy_ub() )
01721 cur_loop->Add_bound(cur_loop->Get_upper_linex(), soe,
01722 _depth, num_vectors, num_syms, syms);
01723
01724
01725
01726 if (Trace_Sections) {
01727 fprintf(TFile, "Num vectors = %d \n", num_vectors);
01728 fprintf(TFile, "Base = %d \n", num_do_loops-i-1);
01729 fprintf(stdout, "Num vectors = %d \n", num_vectors);
01730 fprintf(stdout, "Base = %d \n", num_do_loops-i-1);
01731 }
01732 pivot_row = soe->Change_Base(num_vectors,
01733 num_do_loops - i - 1,
01734 local_array_pool);
01735
01736 if (Trace_Sections) {
01737 fprintf(TFile, "After base change, the SOE is");
01738 soe->Print(TFile);
01739 fprintf(stdout, "After base change, the SOE is");
01740 soe->Print(stdout);
01741 }
01742
01743 if (pivot_row < 0) {
01744 if (Trace_Sections) {
01745 fprintf(TFile, "pivot row < 0 during projection");
01746 cur_loop->Print(TFile);
01747 fprintf(stdout, "pivot row < 0 during projection");
01748 cur_loop->Print(stdout);
01749 }
01750 goto pop_and_return;
01751 }
01752 }
01753 cur_loop = Get_parent(cur_loop);
01754 }
01755 FmtAssert(pivot_row >= 0 && pivot_row < eq_count,
01756 ("PROJECTED_KERNEL::Project(): Invalid indexing of which_axle[]"));
01757 region->Set_region(soe, syms, strides,
01758 pivot_row, level, step, which_axle[pivot_row]);
01759
01760 if (Trace_Sections) {
01761 fprintf(TFile, "PROJECTED_KERNEL:: region generated is: \n");
01762 if (region) {
01763 region->Print(TFile);
01764 }
01765 fprintf(stdout, "PROJECTED_KERNEL:: region generated is: \n");
01766 if (region) {
01767 region->Print(stdout);
01768 }
01769 }
01770 }
01771
01772 pop_and_return:
01773 MEM_POOL_Pop(local_array_pool);
01774 }
01775
01776
01777
01778
01779
01780 void
01781 PROJECTED_KERNEL::Init(PROJECTED_REGION* a, LOOPINFO* loop)
01782 {
01783 INT i;
01784 bzero(this, sizeof(PROJECTED_KERNEL));
01785 _mem_pool = a->Mem_Pool();
01786 _depth = loop->Get_nest_level() + 1;
01787 _projected_level = _depth + 1;
01788 _is_independent = CXX_NEW_ARRAY(BOOL,_depth,Array_Summary.Get_array_pool());
01789
01790 for (i = 0; i < _depth; ++i) {
01791 _is_independent[i] = TRUE;
01792 }
01793
01794 _array = a->Map_to_linex_array();
01795 _difference = CXX_NEW(LINEX_ARRAY(Array_Summary.Get_array_pool()),
01796 Array_Summary.Get_array_pool());
01797
01798
01799
01800
01801 PROJECTED_ARRAY* p = a->Get_projected_array();
01802 for (i = 0; i < p->Elements(); ++i) {
01803 PROJECTED_NODE *node = &(*p)[i];
01804
01805 FmtAssert((node->Is_unprojected()), (" Node has been projected\n"));
01806 FmtAssert(!(node->Is_messy_lb()), (" Messy lower bound\n"));
01807
01808 LINEX* lower = node->Get_lower_linex();
01809 for (INT j = 0; j <= lower->Num_terms(); ++j) {
01810 TERM* term = lower->Get_term(j);
01811
01812
01813
01814 if (term->Get_type() == LTKIND_LINDEX) {
01815 _is_independent[term->Get_desc()] = FALSE;
01816 }
01817 }
01818 }
01819 }
01820
01821
01822
01823
01824 void
01825 REGION_ARRAYS::Init(mINT32 index, mINT32 element_size, MEM_POOL *m)
01826 {
01827 u1._regions = CXX_NEW(PROJECTED_REGION_INFO_ARRAY(m), m);
01828 _type = 0;
01829 _sym_index = index;
01830 _element_size = element_size;
01831 }
01832
01833
01834
01835
01836 void
01837 REGION_ARRAYS::Copy_write(REGION_ARRAYS *r)
01838 {
01839 Set_type(r->Get_type());
01840 Set_sym_id(r->Get_sym_id());
01841 Set_element_size(r->Get_element_size());
01842 }
01843
01844
01845
01846
01847 void
01848 CFG_NODE_INFO::Add_def_array(PROJECTED_REGION* p,
01849 mINT32 element_size,
01850 mINT32 sym_index)
01851 {
01852 ARRAY_OF_REGION_ARRAYS *def = Get_def_array();
01853
01854
01855 PROJECTED_REGION_INFO_ARRAY* proj_array;
01856 for (INT i = 0; i <= def->Lastidx(); ++i) {
01857 REGION_ARRAYS* region_array = &(*def)[i];
01858 if (region_array->Get_sym_id() == sym_index) {
01859
01860 proj_array = region_array->Get_projected_region_array();
01861 INT id = proj_array->Newidx();
01862 (*proj_array)[id].Set_projected_region(p);
01863 return;
01864 }
01865 }
01866
01867 INT idx = def->Newidx();
01868 REGION_ARRAYS *r = &(*def)[idx];
01869 r->Init(sym_index, element_size, Array_Summary.Get_array_pool());
01870 r->Set_is_def();
01871 proj_array = r->Get_projected_region_array();
01872 idx = proj_array->Newidx();
01873 (*proj_array)[idx].Set_projected_region(p);
01874
01875 if (Trace_Sections) {
01876 fprintf(TFile, "adding array kill projected region node \n");
01877 r->Print(TFile);
01878 fprintf(TFile, "finished adding array kill node \n");
01879 fprintf(stdout, "adding array kill projected region node \n");
01880 r->Print(stdout);
01881 fprintf(stdout, "finished adding array kill node \n");
01882 }
01883 }
01884
01885
01886
01887
01888 void
01889 CFG_NODE_INFO::Add_may_def_array(PROJECTED_REGION* p,
01890 mINT32 element_size,
01891 mINT32 sym_index)
01892 {
01893 INT i;
01894 ARRAY_OF_REGION_ARRAYS *def = Get_def_array();
01895
01896 p->Set_is_may_kill();
01897
01898 PROJECTED_REGION_INFO_ARRAY* proj_array;
01899 for (i = 0; i <= def->Lastidx(); ++i) {
01900 REGION_ARRAYS* region_array = &(*def)[i];
01901 if (region_array->Get_sym_id() == sym_index) {
01902
01903 proj_array = region_array->Get_projected_region_array();
01904 INT id = proj_array->Newidx();
01905 (*proj_array)[id].Set_projected_region(p);
01906 return;
01907 }
01908 }
01909
01910 INT idx = def->Newidx();
01911 REGION_ARRAYS *r = &(*def)[idx];
01912 r->Init(sym_index, element_size, Array_Summary.Get_array_pool());
01913 r->Set_is_def();
01914 proj_array = r->Get_projected_region_array();
01915 idx = proj_array->Newidx();
01916 (*proj_array)[idx].Set_projected_region(p);
01917
01918 if (Trace_Sections) {
01919 fprintf(TFile, "adding array kill projected region node \n");
01920 r->Print(TFile);
01921 fprintf(TFile, "finished adding array kill node \n");
01922 fprintf(stdout, "adding array kill projected region node \n");
01923 r->Print(stdout);
01924 fprintf(stdout, "finished adding array kill node \n");
01925 }
01926 }
01927
01928
01929
01930
01931 void
01932 CFG_NODE_INFO::Add_use_array(PROJECTED_REGION *p,
01933 mINT32 element_size,
01934 mINT32 sym_index)
01935
01936 {
01937 INT i;
01938 ARRAY_OF_REGION_ARRAYS *use = Get_use_array();
01939
01940
01941 PROJECTED_REGION_INFO_ARRAY* proj_array;
01942 for (i = 0; i <= use->Lastidx(); ++i) {
01943 REGION_ARRAYS* region_array = &(*use)[i];
01944 if (region_array->Get_sym_id() == sym_index) {
01945
01946 proj_array = region_array->Get_projected_region_array();
01947 INT id = proj_array->Newidx();
01948 (*proj_array)[id].Set_projected_region(p);
01949 return;
01950 }
01951 }
01952
01953 INT idx = use->Newidx();
01954 REGION_ARRAYS *r = &(*use)[idx];
01955 r->Init(sym_index, element_size, Array_Summary.Get_array_pool());
01956 r->Set_is_use();
01957 proj_array = r->Get_projected_region_array();
01958 idx = proj_array->Newidx();
01959 (*proj_array)[idx].Set_projected_region(p);
01960 }
01961
01962
01963
01964
01965 void
01966 CFG_NODE_INFO::Add_may_use_array(PROJECTED_REGION *p,
01967 mINT32 element_size,
01968 mINT32 sym_index)
01969 {
01970 INT i;
01971 ARRAY_OF_REGION_ARRAYS *use = Get_use_array();
01972 p->Set_is_may_use();
01973
01974
01975 PROJECTED_REGION_INFO_ARRAY* proj_array;
01976 for (i = 0; i <= use->Lastidx(); ++i) {
01977 REGION_ARRAYS* region_array = &(*use)[i];
01978 if (region_array->Get_sym_id() == sym_index) {
01979
01980 proj_array = region_array->Get_projected_region_array();
01981 INT id = proj_array->Newidx();
01982 (*proj_array)[id].Set_projected_region(p);
01983 return;
01984 }
01985 }
01986
01987
01988 INT idx = use->Newidx();
01989 REGION_ARRAYS *r = &(*use)[idx];
01990 r->Init(sym_index, element_size, Array_Summary.Get_array_pool());
01991 r->Set_is_use();
01992 proj_array = r->Get_projected_region_array();
01993 idx = proj_array->Newidx();
01994 (*proj_array)[idx].Set_projected_region(p);
01995 }
01996
01997
01998
01999
02000 void
02001 CFG_NODE_INFO::Add_array_param(PROJECTED_REGION *p,
02002 mINT32 sym_index,
02003 mINT32 element_size,
02004 INT16 callsite_id,
02005 INT16 actual_id)
02006 {
02007 ARRAY_OF_REGION_ARRAYS *calls = Get_param_array();
02008
02009 p->Set_is_passed();
02010 if (Trace_Sections) {
02011 fprintf(TFile, "Callsite id = %d, actual_id = %d \n",
02012 callsite_id, actual_id);
02013 fprintf(stdout, "Callsite id = %d, actual_id = %d \n",
02014 callsite_id, actual_id);
02015 }
02016
02017 p->Set_callsite_id(callsite_id);
02018 p->Set_actual_id(actual_id);
02019
02020
02021 PROJECTED_REGION_INFO_ARRAY* proj_array;
02022
02023
02024 INT call_idx = calls->Newidx();
02025 REGION_ARRAYS *r = &(*calls)[call_idx];
02026 r->Init(sym_index, element_size, Array_Summary.Get_array_pool());
02027 r->Set_is_passed();
02028 proj_array = r->Get_projected_region_array();
02029 INT idx = proj_array->Newidx();
02030 (*proj_array)[idx].Set_projected_region(p);
02031 SUMMARY_CALLSITE* callsite = Summary->Get_callsite(callsite_id);
02032 INT actual_index = callsite->Get_actual_index() + actual_id;
02033 SUMMARY_ACTUAL* actual = Summary->Get_actual(actual_index);
02034 actual->Set_pass_type(PASS_ARRAY_SECTION);
02035 actual->Set_index(call_idx);
02036 }
02037
02038
02039
02040
02041 void
02042 CFG_NODE_INFO::Add_formal_array(PROJECTED_REGION *p,
02043 mINT32 element_size,
02044 mINT32 idx_symbol,
02045 mINT32 idx_formal)
02046 {
02047 ARRAY_OF_REGION_ARRAYS* ara_formal = Get_formal_array();
02048 p->Set_is_formal();
02049 INT formal_idx = ara_formal->Newidx();
02050 REGION_ARRAYS* r = &(*ara_formal)[formal_idx];
02051 r->Init(idx_symbol, element_size, Array_Summary.Get_array_pool());
02052 r->Set_is_formal();
02053 PROJECTED_REGION_INFO_ARRAY* proj_array = r->Get_projected_region_array();
02054 INT idx = proj_array->Newidx();
02055 (*proj_array)[idx].Set_projected_region(p);
02056 SUMMARY_FORMAL* sf = Summary->Get_formal(idx_formal);
02057 sf->Set_region_index(formal_idx);
02058 }
02059
02060
02061
02062
02063 void
02064 CFG_NODE_INFO::Add_scalar_use(mINT32 id)
02065 {
02066 INT i;
02067 INT_ARRAY* use;
02068 use = Get_scalar_use_array();
02069
02070 for (i=0; i<=use->Lastidx();++i)
02071 {
02072 SCALAR_INFO *val = &(*use)[i];
02073 if (val->Get_id() == id)
02074 {
02075 val->Set_use();
02076
02077
02078
02079
02080 if (!val->Is_kill() && !val->Is_may_kill())
02081 val->Set_euse();
02082 return;
02083 }
02084 }
02085
02086 i = use->Newidx();
02087 SCALAR_INFO* v = &(*use)[i];
02088 v->Init();
02089 v->Set_id(id);
02090 v->Set_use();
02091
02092 v->Set_euse();
02093 }
02094
02095
02096
02097
02098 void
02099 CFG_NODE_INFO::Add_scalar_def(mINT32 id)
02100 {
02101 INT i;
02102 INT_ARRAY* def;
02103 def = Get_scalar_def_array();
02104
02105 for (i=0; i<=def->Lastidx();++i)
02106 {
02107 SCALAR_INFO *val = &(*def)[i];
02108 if (val->Get_id() == id)
02109 {
02110 val->Set_kill();
02111 return;
02112 }
02113 }
02114
02115 i = def->Newidx();
02116 SCALAR_INFO* v = &(*def)[i];
02117 v->Init();
02118 v->Set_id(id);
02119 v->Set_kill();
02120
02121 }
02122
02123
02124
02125
02126 void
02127 CFG_NODE_INFO::Add_scalar_may_def(mINT32 id)
02128 {
02129 INT i;
02130 INT_ARRAY* def;
02131 def = Get_scalar_def_array();
02132
02133 for (i=0; i<=def->Lastidx();++i)
02134 {
02135 SCALAR_INFO *val = &(*def)[i];
02136 if (val->Get_id() == id)
02137 {
02138 val->Set_may_kill();
02139 return;
02140 }
02141 }
02142
02143 i = def->Newidx();
02144 SCALAR_INFO* v = &(*def)[i];
02145 v->Init();
02146 v->Set_id(id);
02147 v->Set_may_kill();
02148
02149 }
02150
02151
02152
02153
02154 void
02155 CFG_NODE_INFO::Add_scalar_may_use(mINT32 id)
02156 {
02157 INT i;
02158 INT_ARRAY* def;
02159 def = Get_scalar_def_array();
02160
02161 for (i=0; i<=def->Lastidx();++i)
02162 {
02163 SCALAR_INFO *val = &(*def)[i];
02164 if (val->Get_id() == id)
02165 {
02166 val->Set_may_use();
02167 return;
02168 }
02169 }
02170
02171 i = def->Newidx();
02172 SCALAR_INFO* v = &(*def)[i];
02173 v->Init();
02174 v->Set_id(id);
02175 v->Set_may_use();
02176
02177 }
02178
02179
02180
02181
02182 void
02183 CFG_NODE_INFO::Add_scalar_may_reduc(mINT32 id)
02184 {
02185 INT i;
02186 INT_ARRAY* def;
02187 def = Get_scalar_def_array();
02188
02189 for (i=0; i<=def->Lastidx();++i)
02190 {
02191 SCALAR_INFO *val = &(*def)[i];
02192 if (val->Get_id() == id)
02193 {
02194 val->Set_may_reduc();
02195 return;
02196 }
02197 }
02198
02199 i = def->Newidx();
02200 SCALAR_INFO* v = &(*def)[i];
02201 v->Init();
02202 v->Set_id(id);
02203 v->Set_may_reduc();
02204
02205 }
02206
02207
02208
02209
02210 void
02211 CFG_NODE_INFO::Add_scalar_reduc(mINT32 id)
02212 {
02213 INT i;
02214 INT_ARRAY* reduc;
02215 reduc = Get_scalar_reduc_array();
02216
02217 for (i=0; i<=reduc->Lastidx();++i)
02218 {
02219 SCALAR_INFO *val = &(*reduc)[i];
02220 if (val->Get_id() == id)
02221 {
02222 val->Set_reduc();
02223 return;
02224 }
02225 }
02226
02227 i = reduc->Newidx();
02228
02229 SCALAR_INFO* v = &(*reduc)[i];
02230 v->Init();
02231 v->Set_id(id);
02232 v->Set_reduc();
02233
02234 }
02235
02236
02237
02238
02239 INT
02240 CFG_NODE_INFO::Add_scalar_ref_passed(mINT32 id, mINT16 callsite_id)
02241 {
02242 INT i;
02243 INT_ARRAY* scalar_array;
02244 scalar_array = Get_scalar_array();
02245
02246 for (i=0; i<=scalar_array->Lastidx();++i)
02247 {
02248 SCALAR_INFO *val = &(*scalar_array)[i];
02249 if (val->Get_id() == id)
02250 {
02251 val->Set_passed_ref();
02252
02253
02254 if ((val->Get_callsite_id() == 0) && (!val->Is_kill()))
02255 {
02256 val->Set_callsite_id(callsite_id);
02257
02258 }
02259 return i;
02260 }
02261 }
02262
02263 i = scalar_array->Newidx();
02264 SCALAR_INFO* v = &(*scalar_array)[i];
02265 v->Init();
02266 v->Set_id(id);
02267 v->Set_passed_ref();
02268 v->Set_callsite_id(callsite_id);
02269
02270 return i;
02271 }
02272
02273
02274
02275
02276
02277 INT
02278 CFG_NODE_INFO::Add_scalar_ref_may_passed(mINT32 id, mINT16 callsite_id)
02279 {
02280 INT i;
02281 INT_ARRAY* scalar_array;
02282 scalar_array = Get_scalar_array();
02283
02284 for (i=0; i<=scalar_array->Lastidx();++i)
02285 {
02286 SCALAR_INFO *val = &(*scalar_array)[i];
02287 if (val->Get_id() == id)
02288 {
02289 val->Set_may_passed_ref();
02290 if (val->Get_callsite_id() == 0)
02291 val->Set_callsite_id(callsite_id);
02292 return i;
02293 }
02294 }
02295
02296 i = scalar_array->Newidx();
02297 SCALAR_INFO* v = &(*scalar_array)[i];
02298 v->Init();
02299 v->Set_id(id);
02300 v->Set_may_passed_ref();
02301 v->Set_callsite_id(callsite_id);
02302 return i;
02303 }
02304
02305
02306
02307
02308 void
02309 CFG_NODE_INFO::Add_array_reduc(mINT32 id)
02310 {
02311 INT i;
02312 INT_ARRAY* reduc;
02313 reduc = Get_array_reduc();
02314
02315 for (i=0; i<=reduc->Lastidx();++i)
02316 {
02317 SCALAR_INFO *val = &(*reduc)[i];
02318 if (val->Get_id() == id)
02319 {
02320 val->Set_array_reduc();
02321 return;
02322 }
02323 }
02324
02325 i = reduc->Newidx();
02326 SCALAR_INFO* v = &(*reduc)[i];
02327 v->Init();
02328 v->Set_id(id);
02329 v->Set_array_reduc();
02330
02331 }
02332
02333
02334
02335
02336
02337 void
02338 CFG_NODE_INFO::Add_array_may_reduc(mINT32 id)
02339 {
02340 INT i;
02341 INT_ARRAY* reduc;
02342 reduc = Get_array_reduc();
02343
02344 for (i=0; i<=reduc->Lastidx();++i)
02345 {
02346 SCALAR_INFO *val = &(*reduc)[i];
02347 if (val->Get_id() == id)
02348 {
02349 val->Set_array_may_reduc();
02350 return;
02351 }
02352 }
02353
02354 i = reduc->Newidx();
02355 SCALAR_INFO* v = &(*reduc)[i];
02356 v->Init();
02357 v->Set_id(id);
02358 v->Set_array_may_reduc();
02359
02360 }
02361
02362
02363
02364
02365 IVAR*
02366 ARRAY_SUMMARY::Get_ivar_array(INT i)
02367 {
02368 FmtAssert(i <= _ivar->Lastidx(),("illegal ivar index \n"));
02369 return &(*_ivar)[i];
02370 }
02371
02372
02373
02374
02375 TERM*
02376 ARRAY_SUMMARY::Get_term_array(INT i)
02377 {
02378 FmtAssert(i <= _term_array->Lastidx(),("illegal term index \n"));
02379 return &(*_term_array)[i];
02380 }
02381
02382
02383
02384
02385 PROJECTED_NODE*
02386 ARRAY_SUMMARY::Get_projected_array(INT i)
02387 {
02388 FmtAssert(i <= _project_nodes->Lastidx(),("illegal project index\n"));
02389 return &(*_project_nodes)[i];
02390 }
02391
02392
02393
02394
02395 PROJECTED_REGION*
02396 ARRAY_SUMMARY::Get_projected_region_array(INT i)
02397 {
02398 FmtAssert(i <= _projected_regions->Lastidx(),("illegal region index\n"));
02399 return &(*_projected_regions)[i];
02400 }
02401
02402
02403
02404
02405 REGION_ARRAYS*
02406 ARRAY_SUMMARY::Get_region_array(INT i)
02407 {
02408 FmtAssert(i <= _region_arrays->Lastidx(),("illegal region array index\n"));
02409 return &(*_region_arrays)[i];
02410 }
02411
02412
02413
02414
02415 CFG_NODE_INFO*
02416 ARRAY_SUMMARY::Get_cfg_node_array(INT i)
02417 {
02418 FmtAssert(i <= _cfg_nodes->Lastidx(),("illegal cfg node index\n"));
02419 return &(*_cfg_nodes)[i];
02420 }
02421
02422
02423
02424
02425 LOOPINFO*
02426 ARRAY_SUMMARY::Get_loopinfo_array(INT i)
02427 {
02428 FmtAssert(i <= _loop_nodes->Lastidx(),("illegal loopinfo index\n"));
02429 return &(*_loop_nodes)[i];
02430 }
02431
02432
02433
02434
02435
02436
02437
02438
02439 void
02440 ARRAY_SUMMARY::Record_tlogs(TERM_ARRAY *tarray, INT offset)
02441 {
02442 TLOG_INFO* tlog = Get_tlog_info();
02443
02444 if (tarray)
02445 {
02446 for (INT i=offset; i<=tarray->Lastidx();++i)
02447 {
02448 TERM *t = &(*tarray)[i];
02449 switch (t->Get_type())
02450 {
02451 case LTKIND_CONST:
02452 tlog->Set_cterm_count(tlog->Get_cterm_count()+1);
02453 break;
02454
02455 case LTKIND_LINDEX:
02456 tlog->Set_lterm_count(tlog->Get_lterm_count()+1);
02457 break;
02458
02459 case LTKIND_IV:
02460 tlog->Set_iv_term_count(tlog->Get_iv_term_count()+1);
02461 break;
02462
02463 case LTKIND_SUBSCR:
02464 tlog->Set_sub_term_count(tlog->Get_sub_term_count()+1);
02465 break;
02466 }
02467 }
02468 }
02469 }
02470
02471
02472
02473
02474
02475
02476
02477 void PROJECTED_KERNEL::Set_Difference(PROJECTED_REGION* pr)
02478 {
02479 for (INT i = 0; i < Get_num_dims(); i++) {
02480 LINEX* lx_kernel = Get_linex(i);
02481 LINEX* lx_region = pr->Get_projected_node(i)->Get_lower_linex();
02482 LINEX* lx_diff = lx_region->Subtract(lx_kernel);
02483 INT idx = _difference->Newidx();
02484 LINEX* lx_new = &(*_difference)[idx];
02485 lx_new->Init(Array_Summary.Get_array_pool());
02486 lx_diff->Copy(lx_new);
02487 }
02488 }