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