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