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 #include "defs.h"
00030 #include "tracing.h"
00031 #include "cxx_memory.h"
00032 #include "opt_base.h"
00033 #include "bb_node_set.h"
00034 #include "opt_lmv_helper.h"
00035
00036
00037
00038
00039 static TY_IDX
00040 get_field_type (TY_IDX agg_ty, INT field_id) {
00041 UINT cur_field_id = 0;
00042 FLD_HANDLE fld = FLD_get_to_field (agg_ty, field_id, cur_field_id);
00043 Is_True (!fld.Is_Null(), ("Invalid field id %d for type %p",
00044 field_id, agg_ty));
00045 return FLD_type (fld);
00046 }
00047
00048
00049 static TY_IDX
00050 coderep_obj_ty (CODEREP* cr) {
00051
00052 if (cr->Kind () == CK_VAR || cr->Kind() == CK_IVAR) {
00053
00054 TY_IDX ty;
00055 UINT32 fld_id;
00056
00057 if (cr->Kind() == CK_VAR) {
00058 ty = cr->Lod_ty();
00059 fld_id = cr->Field_id ();
00060 } else {
00061 ty = cr->Ilod_ty();
00062 fld_id = cr->I_field_id ();
00063 }
00064
00065 if (fld_id != 0) {
00066 if (TY_kind(ty) == KIND_STRUCT) {
00067 return get_field_type (ty, fld_id);
00068 } else {
00069 #if 0
00070
00071 DevWarn ("CODEREP-%d has non-zero field-id, "
00072 "but Lod_ty()/Ilod_ty() returns non aggregate type '%s'",
00073 cr->Coderep_id(), TY_name(ty));
00074 #endif
00075 }
00076 }
00077 return ty;
00078 }
00079
00080 return (TY_IDX)0;
00081 }
00082
00084
00085
00086
00088
00089 inline BOOL
00090 ADDR_LINEAR_EXPR::operator == (const ADDR_LINEAR_EXPR& that) const {
00091 if (_flags != that._flags || _flags == 0) {
00092 return FALSE;
00093 }
00094 if (Is_const ()) return _const == that._const;
00095 return _coeff == that._coeff && _const == that._const &&
00096 _var == that._var && _ver == that._ver;
00097 }
00098
00099
00100
00101
00102
00103 BOOL
00104 ADDR_LINEAR_EXPR::Add (const ADDR_LINEAR_EXPR &that) {
00105
00106 Is_True ((Is_const() || Is_nonconst()) &&
00107 (that.Is_const() || that.Is_nonconst()),
00108 ("linear addresses are not valid"));
00109
00110 if (Is_const()) {
00111 INT v = Const_val();
00112 *this = that;
00113 _const += v;
00114 return TRUE;
00115 }
00116
00117 if (that.Is_const ()) {
00118 _const += that.Const_val ();
00119 return TRUE;
00120 }
00121
00122
00123 if (that.Var () != _var) return FALSE;
00124
00125
00126 if (that.Var_ver() == _ver) _ver = 0;
00127
00128 _coeff += that._coeff;
00129 _const += that._const;
00130
00131 return TRUE;
00132 }
00133
00134 void
00135 ADDR_LINEAR_EXPR::Multiply (INT v) {
00136 Is_True (Is_const() || Is_nonconst(), ("not linear expr"));
00137 _const *= v;
00138 }
00139
00141
00142
00143
00145
00146
00147 TY_IDX
00148 MA_POINTER::Pointed_ty (void) const {
00149 if (_ty == (TY_IDX)0) return (TY_IDX)0;
00150 if (TY_kind(_ty) != KIND_POINTER) {
00151 return (TY_IDX)0;
00152 }
00153
00154 TY_IDX pt_ty = TY_pointed(_ty);
00155
00156 if (_kind == MA_PTR_LDA) {
00157 if (_is_lda._afield_id != (TY_IDX)0)
00158 pt_ty = get_field_type (pt_ty, _is_lda._afield_id);
00159 }
00160
00161 return pt_ty;
00162 }
00163
00165
00166
00167
00169
00170 BOOL
00171 MA_OFFSET::operator == (const MA_OFFSET& that) const {
00172 if (Kind () != that.Kind()) return FALSE;
00173
00174 switch (Kind()) {
00175 case MA_OFST_FIXED:
00176 case MA_OFST_LINEAR:
00177 return _ofst.low == that._ofst.low;
00178
00179 case MA_OFST_RANGE:
00180 return _ofst.low == that._ofst.low &&
00181 _ofst.high == that._ofst.high;
00182
00183 case MA_OFST_TOO_MESSY:
00184 return Expr() == that.Expr() && Expr() != NULL;
00185
00186 case MA_OFST_INVALID:
00187 case MA_OFST_UNKNOWN:
00188 break;
00189
00190 default:
00191 FmtAssert (FALSE, ("invalid ofst kind"));
00192 }
00193 return FALSE;
00194 }
00195
00196 void
00197 MA_OFFSET::Add (INT adjust) {
00198 switch (Kind()) {
00199 case MA_OFST_FIXED:
00200 case MA_OFST_LINEAR:
00201 _ofst.low.Add (adjust);
00202 break;
00203
00204 case MA_OFST_RANGE:
00205 _ofst.low.Add (adjust);
00206 _ofst.high.Add (adjust);
00207 break;
00208
00209 case MA_OFST_TOO_MESSY:
00210 if (adjust != 0) {
00211 Set_unknown_ofst ();
00212 }
00213 break;
00214
00215 case MA_OFST_UNKNOWN:
00216 break;
00217
00218 case MA_OFST_INVALID:
00219 default:
00220 FmtAssert (FALSE, ("Offset is invalid"));
00221 return;
00222 }
00223 }
00224
00225 void
00226 MA_OFFSET::Add (MA_OFFSET* adjust) {
00227 BOOL add_succ = TRUE;
00228
00229 switch (_kind) {
00230 case MA_OFST_FIXED:
00231 case MA_OFST_LINEAR:
00232 if (adjust->Kind() == MA_OFST_FIXED ||
00233 adjust->Kind() == MA_OFST_LINEAR) {
00234 if (add_succ = _ofst.low.Add (*adjust->Linear_ofst())) {
00235 if (_ofst.low.Is_nonconst())
00236 _kind = MA_OFST_LINEAR;
00237 }
00238 } else if (adjust->Kind() == MA_OFST_RANGE) {
00239 const ADDR_LINEAR_EXPR_RANGE* r = adjust->Linear_ofst_range ();
00240 add_succ = _ofst.low.Add (r->low);
00241 if (add_succ)
00242 add_succ = _ofst.low.Add (r->high);
00243 } else {
00244 Set_unknown_ofst ();
00245 }
00246
00247 break;
00248
00249 case MA_OFST_RANGE:
00250 if (adjust->Kind() == MA_OFST_FIXED ||
00251 adjust->Kind() == MA_OFST_LINEAR) {
00252 add_succ = _ofst.low.Add (*adjust->Linear_ofst());
00253 if (add_succ)
00254 _ofst.high.Add (*adjust->Linear_ofst());
00255 } else if (adjust->Kind() == MA_OFST_RANGE) {
00256 const ADDR_LINEAR_EXPR_RANGE* r = adjust->Linear_ofst_range ();
00257 add_succ = _ofst.low.Add (r->low);
00258 if (add_succ)
00259 add_succ = _ofst.high.Add (r->high);
00260 }
00261 break;
00262
00263 case MA_OFST_TOO_MESSY:
00264 if (adjust->Kind() != MA_OFST_FIXED ||
00265 adjust->Get_fixed_ofst () != 0) {
00266 Set_unknown_ofst ();
00267 }
00268 break;
00269
00270 case MA_OFST_UNKNOWN:
00271 break;
00272
00273 case MA_OFST_INVALID:
00274 default:
00275 FmtAssert (FALSE, ("Offset is invalid"));
00276 return;
00277 }
00278
00279 if (!add_succ) Set_unknown_ofst ();
00280 }
00281
00282
00283
00284 void
00285 MA_OFFSET::Union (const MA_OFFSET* that, LMV_LOOP_INFO* loopinfo) {
00286
00287 Is_True (Kind() != MA_OFST_INVALID && that->Kind() != MA_OFST_INVALID,
00288 ("Invalid offset kind"));
00289
00290 if (Kind() == MA_OFST_UNKNOWN || *this == *that) {
00291 return;
00292 }
00293
00294 if ((INT)Kind() > (INT)that->Kind()) {
00295
00296
00297
00298 MA_OFFSET tmp;
00299 tmp = *that;
00300 tmp.Union (this, loopinfo);
00301 *this = tmp;
00302 return;
00303 }
00304
00305 INT low, high;
00306 if (Kind() == MA_OFST_FIXED) {
00307 switch (that->Kind()) {
00308 case MA_OFST_FIXED:
00309 {
00310 low = _ofst.low.Const_val();
00311 high = that->Get_fixed_ofst ();
00312 if (low < high) { INT t = low; low = high; high = t; }
00313 Set_linear_ofst_range (ADDR_LINEAR_EXPR(low), ADDR_LINEAR_EXPR(high));
00314 }
00315 return;
00316
00317 case MA_OFST_LINEAR:
00318 {
00319 VAR_VAL_RANGE vr;
00320 that->Linear_ofst()->Get_range (&vr,loopinfo);
00321 if (vr.Low_is_const() && vr.High_is_const()) {
00322 low = high = Get_fixed_ofst();
00323 low = MIN(low, vr.Low_val());
00324 high = MAX(high, vr.High_val());
00325 Set_linear_ofst_range (ADDR_LINEAR_EXPR(low),
00326 ADDR_LINEAR_EXPR(high));
00327 return;
00328 }
00329 }
00330 break;
00331
00332 case MA_OFST_RANGE:
00333 {
00334 if (that->_ofst.low.Is_invalid() ||
00335 that->_ofst.high.Is_invalid()) {
00336 break;
00337 }
00338
00339 low = high = Get_fixed_ofst ();
00340 if (!that->_ofst.low.Is_const()) {
00341 VAR_VAL_RANGE vr ;
00342 loopinfo->Analyze_var_value_range (
00343 that->_ofst.low.Var(),
00344 that->_ofst.low.Var_ver(),
00345 &vr);
00346 if (!vr.Low_is_const() || !vr.High_is_const())
00347 break;
00348
00349 low = MIN(low, vr.Low_val ());
00350 high = MAX(high, vr.High_val ());
00351 }
00352
00353 if (!that->_ofst.high.Is_const()) {
00354 VAR_VAL_RANGE vr ;
00355 loopinfo->Analyze_var_value_range (
00356 that->_ofst.high.Var(),
00357 that->_ofst.high.Var_ver(),
00358 &vr);
00359 if (!vr.Low_is_const() || !vr.High_is_const())
00360 break;
00361
00362 low = MIN(low, vr.Low_val ());
00363 high = MAX(high, vr.High_val ());
00364 }
00365
00366 Set_linear_ofst_range (ADDR_LINEAR_EXPR(low), ADDR_LINEAR_EXPR(high));
00367 }
00368 return;
00369
00370 case MA_OFST_TOO_MESSY:
00371 if (Get_fixed_ofst () == 0) {
00372 *this = *that;
00373 return;
00374 }
00375 break;
00376
00377 case MA_OFST_UNKNOWN:
00378 break;
00379
00380 default:
00381 FmtAssert (FALSE, ("Invalid offset kind"));
00382 }
00383
00384 Set_unknown_ofst ();
00385 return;
00386 }
00387
00388 if (Kind () == MA_OFST_LINEAR) {
00389 switch (that->Kind()) {
00390 case MA_OFST_LINEAR:
00391 {
00392 VAR_VAL_RANGE that_vr, this_vr;
00393 loopinfo->Analyze_var_value_range (
00394 that->_ofst.low.Var(),
00395 that->_ofst.low.Var_ver(),
00396 &that_vr);
00397
00398 if (!that_vr.Low_is_const() || !that_vr.High_is_const()) {
00399 break;
00400 }
00401
00402 loopinfo->Analyze_var_value_range
00403 (_ofst.low.Var(), _ofst.low.Var_ver(), &this_vr);
00404
00405 if (!this_vr.Low_is_const() || !this_vr.High_is_const())
00406 break;
00407
00408 low = MIN(that_vr.Low_val(), this_vr.Low_val());
00409 high = MAX(that_vr.High_val(), that_vr.High_val());
00410
00411 Set_linear_ofst_range (ADDR_LINEAR_EXPR(low), ADDR_LINEAR_EXPR(high));
00412 return;
00413 }
00414 break;
00415
00416 case MA_OFST_RANGE:
00417 {
00418 const ADDR_LINEAR_EXPR_RANGE* r = that->Linear_ofst_range ();
00419
00420 MA_OFFSET tl(&r->low), th(&r->high);
00421 tl.Union (this, loopinfo);
00422 th.Union (this, loopinfo);
00423
00424 const ADDR_LINEAR_EXPR* addr1, *addr2;
00425 addr1 = addr2 = NULL;
00426 switch (tl.Kind()) {
00427 case MA_OFST_FIXED:
00428 Is_True (FALSE, ("it is impossible to be fixed ofst"));
00429 break;
00430 case MA_OFST_LINEAR:
00431 addr1 = tl.Linear_ofst(); break;
00432
00433 case MA_OFST_RANGE:
00434 addr1 = &tl.Linear_ofst_range ()->low; break;
00435 default:
00436 break;
00437 }
00438
00439 switch (th.Kind()) {
00440 case MA_OFST_FIXED:
00441 Is_True (FALSE, ("it is impossible to be fixed ofst"));
00442 break;
00443 case MA_OFST_LINEAR:
00444 addr2 = th.Linear_ofst(); break;
00445
00446 case MA_OFST_RANGE:
00447 addr2 = &th.Linear_ofst_range ()->high; break;
00448 default:
00449 break;
00450 }
00451 if (addr1 && addr2) {
00452 Set_linear_ofst_range (*addr1, *addr2);
00453 return;
00454 }
00455 }
00456 break;
00457
00458 case MA_OFST_TOO_MESSY:
00459 case MA_OFST_UNKNOWN:
00460 break;
00461
00462 default:
00463 FmtAssert (FALSE, ("unknown offset kind"));
00464 }
00465 Set_unknown_ofst ();
00466 return;
00467 }
00468
00469 if (Kind() == MA_OFST_RANGE) {
00470 switch (that->Kind()) {
00471 case MA_OFST_RANGE:
00472 {
00473 MA_OFFSET t1(&that->Linear_ofst_range()->low);
00474 Union (&t1, loopinfo);
00475 if (Kind() == MA_OFST_UNKNOWN) break;
00476
00477 MA_OFFSET t2(&that->Linear_ofst_range()->high);
00478 Union (&t2, loopinfo);
00479 return;
00480 }
00481 break;
00482
00483 case MA_OFST_TOO_MESSY:
00484 case MA_OFST_UNKNOWN:
00485 Set_unknown_ofst ();
00486 break;
00487
00488 default:
00489 FmtAssert (FALSE, ("Unkown offset kind"));
00490 }
00491 Set_unknown_ofst ();
00492 return;
00493 }
00494
00495 if (Kind() == MA_OFST_TOO_MESSY) {
00496 Set_unknown_ofst ();
00497 } else {
00498 FmtAssert (FALSE, ("omit other offset kind"));
00499 }
00500 }
00501
00502 void
00503 MEM_ACCESS::Adjust_ofst (MA_POINTER* ptr, MA_OFFSET* ofst) {
00504 ptr = ptr;
00505 _ofst.Add (ofst);
00506 }
00507
00508 MEM_ACCESS_ANALYZER::MEM_ACCESS_ANALYZER
00509 (OPT_STAB* opt_stab, LMV_LOOP_INFO* loopinfo,
00510 MEM_POOL* mp, BOOL trace):
00511 _mp(mp), _opt_stab(opt_stab), _cfg(opt_stab->Cfg()), _loopinfo(loopinfo),
00512 _ma_map (256, NULL, _mp, FALSE), _ptr_mgr (_mp), _all_ma(_mp) {
00513
00514 Is_True (_loopinfo->Loop()->Header()->Loopdepth() == 1,
00515 ("MEM_ACCESS_ANALYZER can handle only inner most loops"));
00516
00517 _ma_map.Init ();
00518 _read_cnt = _write_cnt = 0;
00519 _last_ma_id = 1;
00520 _trace = trace;
00521 _trace_detail = FALSE;
00522 }
00523
00524 inline MEM_ACCESS*
00525 MEM_ACCESS_ANALYZER::Alloc_mem_access (void) {
00526 MEM_ACCESS* ma = CXX_NEW (MEM_ACCESS(_last_ma_id++), _mp);
00527 _all_ma.push_back (ma);
00528 return ma;
00529 }
00530
00531
00532 BOOL
00533 MEM_ACCESS_ANALYZER::Expr_of_ptr_ty (CODEREP* cr) {
00534
00535 if (cr->Kind () == CK_VAR) {
00536 ST* st = _opt_stab->Aux_stab_entry (cr->Aux_id())->St ();
00537 if (ST_class(st) == CLASS_VAR || (ST_class(st) == CLASS_PREG)) {
00538 return TY_kind(cr->Lod_ty()) == KIND_POINTER;
00539 } else {
00540 return FALSE;
00541 }
00542 } else if (cr->Kind () == CK_IVAR) {
00543 TY_IDX ld_ty = cr->Ilod_ty();
00544 if (cr->I_field_id() != (TY_IDX)0) {
00545 ld_ty = get_field_type (ld_ty, cr->I_field_id());
00546 }
00547 return TY_kind(ld_ty) == KIND_POINTER;
00548 } else if (cr->Kind() == CK_OP) {
00549 if (cr->Opr() == OPR_ARRAY) {
00550 return TRUE;
00551 } else if (cr->Opr() == OPR_ADD &&
00552 Pointer_Size == MTYPE_byte_size(cr->Dtyp())) {
00553 BOOL b1 = Expr_of_ptr_ty (cr->Opnd(0));
00554 BOOL b2 = Expr_of_ptr_ty (cr->Opnd(1));
00555
00556
00557 return b1 && !b2 || !b1 && b2;
00558 }
00559 } else if (cr->Kind() == CK_LDA) {
00560 return TRUE;
00561 }
00562
00563 return FALSE;
00564 }
00565
00567
00568
00569
00570
00571
00573
00574 PTR_OFST_PAIR*
00575 MEM_ACCESS_ANALYZER::Analyze_preg_pointer (CODEREP* addr, BOOL is_read) {
00576
00577 Is_True (addr->Kind() == CK_VAR, ("CODEREP is not direct load/store"));
00578 MA_POINTER* ptr = _ptr_mgr.Alloc_ptr ();
00579 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00580 ofst->Set_fixed_ofst (0);
00581
00582 ptr->Init_ptr_as_preg (addr->Offset(), addr->Version(), addr->Lod_ty(), addr);
00583 if (Is_loop_invariant (addr)) {
00584 ptr->Set_loop_invar();
00585 }
00586 ptr->Set_indirect_level (1);
00587 ptr->Set_coderep (addr);
00588
00589 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr, ofst);
00590 Map_pointer (addr, pair);
00591
00592 return pair;
00593 }
00594
00595 PTR_OFST_PAIR*
00596 MEM_ACCESS_ANALYZER::Analyze_named_symbol_pointer
00597 (CODEREP* addr, BOOL is_read) {
00598
00599 Is_True (addr->Kind() == CK_VAR, ("CODEREP is not direct load/store"));
00600
00601 MA_POINTER* ptr = _ptr_mgr.Alloc_ptr ();
00602 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00603 ofst->Set_fixed_ofst (0);
00604
00605 ptr->Init_ptr_as_named_sym (addr->Aux_id(), addr->Version(),
00606 _opt_stab->Aux_stab_entry (addr->Aux_id())->St (),
00607 addr->Lod_ty(), addr);
00608 if (is_read) ptr->Set_ld_cnt(1); else ptr->Set_st_cnt(1);
00609 ptr->Set_indirect_level (1);
00610 ptr->Set_coderep (addr);
00611
00612 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr, ofst);
00613 Map_pointer (addr, pair);
00614
00615 return pair;
00616 }
00617
00618 PTR_OFST_PAIR*
00619 MEM_ACCESS_ANALYZER::Analyze_lda_pointer
00620 (CODEREP* addr, BOOL is_read) {
00621
00622 Is_True (addr->Kind() == CK_LDA, ("CODEREP is not LDA"));
00623
00624 MA_POINTER* ptr = _ptr_mgr.Alloc_ptr ();
00625 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00626 ofst->Set_fixed_ofst (0);
00627
00628 ptr->Init_lda_ptr (addr->Lda_aux_id(), addr->Lda_base_st(),
00629 addr->Lda_ty(), addr->Afield_id(), addr);
00630 if (is_read) ptr->Set_ld_cnt(1); else ptr->Set_st_cnt(1);
00631 ptr->Set_indirect_level (1);
00632
00633 ofst->Set_fixed_ofst (addr->Offset());
00634 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr, ofst);
00635
00636 Map_pointer (addr, pair);
00637
00638 return pair;
00639 }
00640
00641
00643
00644
00645
00646
00647
00649 PTR_OFST_PAIR*
00650 MEM_ACCESS_ANALYZER::Analyze_iload_pointer
00651 (CODEREP* addr, STMTREP* stmt, BOOL is_read) {
00652
00653 Is_True (addr->Kind() == CK_IVAR, ("CODEREP is not indirect load/store"));
00654
00655 PTR_OFST_PAIR* ptr_ofst = Get_pointer_ofst_pair (addr);
00656 if (ptr_ofst) {
00657 return ptr_ofst;
00658 }
00659
00660 MEM_ACCESS* ld_ptr = Analyze_mem_access (addr, stmt, TRUE);
00661 MA_POINTER* ptr = _ptr_mgr.Alloc_ptr ();
00662 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00663 ofst->Set_fixed_ofst (addr->Offset());
00664 ptr->Init_indirect_ptr (ld_ptr, ld_ptr->Obj_ty(),
00665 ld_ptr->Indirect_level()+1, addr);
00666 ptr->Set_coderep (addr);
00667 if (is_read) ptr->Set_ld_cnt(1); else ptr->Set_st_cnt(1);
00668
00669 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr, ofst);
00670 Map_pointer (addr, pair);
00671
00672 return pair;
00673 }
00674
00675 PTR_OFST_PAIR*
00676 MEM_ACCESS_ANALYZER::Analyze_array_access
00677 (CODEREP* addr, STMTREP* stmt, BOOL is_read) {
00678
00679 Is_True (addr->Opr() == OPR_ARRAY, ("operator is not ARRAY."));
00680 PTR_OFST_PAIR* ptr_ofst = Get_pointer_ofst_pair (addr);
00681 if (ptr_ofst) {
00682 return ptr_ofst;
00683 }
00684
00685 CODEREP* kid0 = addr->Opnd(0);
00686 ptr_ofst = Analyze_pointer (addr->Opnd(0), stmt, is_read);
00687
00688
00689
00690 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00691
00692 mINT64 elm_size = addr->Elm_siz ();
00693 if (elm_size < 0) {
00694
00695
00696
00697
00698 return Gen_messy_access_pair (addr, stmt, is_read);
00699 }
00700
00701
00702 INT32 n_dim = addr->Kid_count();
00703 Is_True (n_dim & 1, ("CODEREP of ARRAY should have odd number of kids"));
00704 n_dim = n_dim >> 1;
00705
00706
00707 mINT64 lower, higher;
00708 lower = higher = 0;
00709
00710 BOOL range_is_unknown = FALSE;
00711
00712
00713
00714 for (INT32 i = 1; i <= n_dim; i++) {
00715 CODEREP* dim = addr->Opnd (i);
00716 CODEREP* index = addr->Opnd (i + n_dim);
00717
00718 INT low_idx, high_idx;
00719
00720 if (dim->Kind() == CK_CONST && dim->Const_val() > 1) {
00721 if (index->Kind() == CK_CONST) {
00722 low_idx = high_idx = index->Const_val();
00723 } else {
00724 low_idx = 0; high_idx = dim->Const_val()-1;
00725 }
00726
00727 lower = lower * dim->Const_val() + low_idx;
00728 higher = higher * dim->Const_val() + high_idx;
00729 } else {
00730
00731 range_is_unknown = TRUE;
00732 break;
00733 }
00734 }
00735
00736 lower *= elm_size;
00737 higher *= elm_size;
00738
00739
00740
00741 if (!range_is_unknown) {
00742 if (lower != higher) {
00743 ofst->Set_linear_ofst_range (ADDR_LINEAR_EXPR(lower),
00744 ADDR_LINEAR_EXPR(higher));
00745 } else {
00746 ofst->Set_fixed_ofst (lower);
00747 }
00748 } else {
00749 ofst->Set_unknown_ofst ();
00750 }
00751 ofst->Add (ptr_ofst->second);
00752
00753
00754 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr_ofst->first, ofst);
00755 Map_pointer (addr, pair);
00756
00757 return pair;
00758 }
00759
00760 PTR_OFST_PAIR*
00761 MEM_ACCESS_ANALYZER::Gen_messy_access_pair
00762 (CODEREP* addr, STMTREP* stmt, BOOL is_read) {
00763
00764 MA_POINTER* ptr = _ptr_mgr.Alloc_ptr ();
00765 ptr->Init_too_messy_ptr ((TY_IDX)0, addr);
00766 if (is_read) ptr->Set_ld_cnt (1); else ptr->Set_st_cnt (1);
00767 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst ();
00768 ofst->Set_fixed_ofst (0);
00769 PTR_OFST_PAIR* pair = _ptr_mgr.Alloc_ptr_ofst_pair (ptr,ofst);
00770
00771 Map_pointer (addr, pair);
00772 return pair;
00773 }
00774
00776
00777
00778
00779
00780
00781
00783 PTR_OFST_PAIR*
00784 MEM_ACCESS_ANALYZER::Analyze_pointer
00785 (CODEREP* addr, STMTREP* stmt, BOOL is_read) {
00786
00787 PTR_OFST_PAIR* ptr_ofst = Get_pointer_ofst_pair (addr);
00788 if (ptr_ofst != NULL) {
00789
00790
00791
00792 MA_POINTER* ptr = ptr_ofst->first;
00793 MA_OFFSET* ofst = ptr_ofst->second;
00794 if (is_read)
00795 ptr->Set_ld_cnt (ptr->Ld_cnt()+1);
00796 else
00797 ptr->Set_st_cnt (ptr->St_cnt()+1);
00798
00799 return ptr_ofst;
00800 }
00801
00802 if (addr->Kind() == CK_VAR) {
00803
00804 ST* st = _opt_stab->Aux_stab_entry (addr->Aux_id())->St ();
00805 if (ST_class(st) == CLASS_PREG) {
00806 return Analyze_preg_pointer (addr, is_read);
00807 } else {
00808 return Analyze_named_symbol_pointer (addr, is_read);
00809 }
00810 } else if (addr->Kind() == CK_IVAR) {
00811
00812 return Analyze_iload_pointer (addr, stmt, is_read);
00813 } else if (addr->Kind() == CK_OP) {
00814
00815
00816 if (addr->Opr () == OPR_ADD) {
00817 CODEREP* opnd0 = addr->Opnd(0);
00818 CODEREP* opnd1 = addr->Opnd(1);
00819
00820 BOOL opnd0_is_ptr = Expr_of_ptr_ty (opnd0);
00821 BOOL opnd1_is_ptr = Expr_of_ptr_ty (opnd1);
00822
00823 if (opnd0_is_ptr && !opnd1_is_ptr ||
00824 !opnd0_is_ptr && opnd1_is_ptr) {
00825 CODEREP* addr_kid = opnd0_is_ptr ? opnd0 : opnd1;
00826 CODEREP* ofst_kid = opnd0_is_ptr ? opnd1 : opnd0;
00827
00828 PTR_OFST_PAIR* pair = Analyze_pointer (addr_kid, stmt, is_read);
00829 MA_POINTER* ptr = pair->first;
00830 if (is_read) ptr->Set_ld_cnt (1); else ptr->Set_st_cnt (1);
00831
00832 MA_OFFSET* ofst = _ptr_mgr.Alloc_ofst();
00833 Analyze_ofst (ofst_kid, ofst);
00834 ofst->Add (pair->second);
00835
00836 PTR_OFST_PAIR* merge_pair =
00837 _ptr_mgr.Alloc_ptr_ofst_pair(ptr, ofst);
00838 Map_pointer (addr, merge_pair);
00839
00840 return merge_pair;
00841 } else if (_trace_detail) {
00842 fprintf (TFile, "cannot distinct pointer kid from this expr:\n");
00843 addr->Print(0,stderr);
00844 }
00845 } else if (addr->Opr () == OPR_ARRAY) {
00846 return Analyze_array_access (addr, stmt, is_read);
00847 }
00848 } else if (addr->Kind() == CK_LDA) {
00849 return Analyze_lda_pointer (addr, is_read);
00850 }
00851
00852 return Gen_messy_access_pair (addr, stmt, is_read);
00853 }
00854
00855 void
00856 MEM_ACCESS_ANALYZER::Analyze_ofst_helper (CODEREP* ofst, MA_OFFSET* res) {
00857 res->Set_unknown_ofst ();
00858
00859 if (ofst->Kind() == CK_OP) {
00860 switch (ofst->Opr()) {
00861 case OPR_CVT:
00862 switch (ofst->Op()) {
00863 case OPC_I8I4CVT:
00864 case OPC_U8I8CVT:
00865 case OPC_I8U8CVT:
00866 case OPC_U8U4CVT:
00867 Analyze_ofst (ofst->Opnd(0), res);
00868 return;
00869 }
00870 break;
00871
00872 case OPR_MPY:
00873 {
00874 if (!MTYPE_is_integral(ofst->Dtyp())) {
00875 break;
00876 }
00877 CODEREP* ckid, *nckid;
00878 ckid = nckid = NULL;
00879 if (ofst->Opnd(0)->Kind() == CK_CONST) {
00880 ckid = ofst->Opnd(0), nckid = ofst->Opnd(1);
00881 } else if (ofst->Opnd(1)->Kind() == CK_CONST) {
00882 ckid = ofst->Opnd(1), nckid = ofst->Opnd(0);
00883 }
00884 if (ckid && nckid) {
00885 MA_OFFSET t;
00886 INT scale = ckid->Const_val();
00887 Analyze_ofst (nckid, &t);
00888
00889 if (t.Kind() == MA_OFST_LINEAR) {
00890 const ADDR_LINEAR_EXPR* r = t.Linear_ofst ();
00891 t.Set_linear_ofst (r->Coefficient() * scale,
00892 r->Var(), r->Var_ver(), r->Const_part () * scale);
00893 } else if (t.Kind() == MA_OFST_RANGE) {
00894 ADDR_LINEAR_EXPR_RANGE r = *t.Linear_ofst_range();
00895 r.low.Multiply (scale);
00896 r.high.Multiply (scale);
00897 t.Set_linear_ofst_range (r.low, r.high);
00898 } else if (t.Kind() == MA_OFST_FIXED) {
00899 t.Set_fixed_ofst (t.Get_fixed_ofst() * scale);
00900 } else {
00901 t.Set_unknown_ofst();
00902 }
00903 *res = t;
00904 return;
00905 }
00906 }
00907 break;
00908
00909 case OPR_ADD:
00910 {
00911 if (!MTYPE_is_integral(ofst->Dtyp())) {
00912 break;
00913 }
00914 MA_OFFSET t1, t2;
00915 Analyze_ofst (ofst->Opnd(0), &t1);
00916 Analyze_ofst (ofst->Opnd(0), &t2);
00917 t1.Add (&t2);
00918 *res = t1;
00919 }
00920 return;
00921 }
00922
00923 } else if (ofst->Kind() == CK_CONST) {
00924 res->Set_fixed_ofst (ofst->Const_val());
00925 return;
00926 } else if (ofst->Kind() == CK_VAR) {
00927 if (ofst->Aux_id() == _loopinfo->Iv()) {
00928 res->Set_linear_ofst (1, ofst->Aux_id(), (VER_ID)0, 0);
00929 return;
00930 }
00931 }
00932
00933 res->Set_unknown_ofst ();
00934 return;
00935 }
00936
00937 void
00938 MEM_ACCESS_ANALYZER::Analyze_ofst (CODEREP* ofst, MA_OFFSET* res) {
00939 Analyze_ofst_helper (ofst, res);
00940 if (_trace_detail) {
00941 ofst->Print(0,TFile);
00942 res->Print (TFile);
00943 }
00944 }
00945
00947
00948
00949
00950
00951
00952
00954 MEM_ACCESS*
00955 MEM_ACCESS_ANALYZER::Analyze_mem_access
00956 (CODEREP* cr, STMTREP* stmt, BOOL is_read) {
00957
00958 if (cr->Kind () == CK_OP) {
00959 for (INT i = cr->Kid_count () - 1; i >= 0; i--) {
00960 Analyze_mem_access (cr->Opnd(i), stmt, TRUE);
00961 }
00962 return NULL;
00963 } else if (cr->Kind() == CK_VAR) {
00964
00965 ST* st = _opt_stab->Aux_stab_entry (cr->Aux_id())->St ();
00966 if (ST_class(st) == CLASS_PREG) return NULL;
00967 } else if (cr->Kind () != CK_IVAR) {
00968
00969 return NULL;
00970 }
00971
00972 if (cr->Non_leaf() &&
00973 !OPERATOR_is_load (cr->Opr()) && !OPERATOR_is_store (cr->Opr())) {
00974
00975
00976
00977
00978
00979 return NULL;
00980 }
00981
00982
00983 if (is_read) _read_cnt++ ; else _write_cnt++;
00984
00985 MEM_ACCESS* ma = NULL;
00986 if (ma = Get_mem_access (cr)) {
00987
00988 return ma;
00989 }
00990
00991 MA_POINTER* ptr = NULL;
00992 MA_OFFSET* ofst = NULL;
00993 ma = Alloc_mem_access ();
00994 if (cr->Kind() == CK_VAR) {
00995
00996 ST* st = _opt_stab->Aux_stab_entry (cr->Aux_id())->St ();
00997 ma->Set_indirect_level(0);
00998 ma->Set_st (st);
00999 ma->Ofst().Set_fixed_ofst (cr->Offset());
01000 } else {
01001
01002 CODEREP* addr = is_read ? cr->Ilod_base () : cr->Istr_base();
01003
01004 PTR_OFST_PAIR* pair = Analyze_pointer (addr, stmt, is_read);
01005 ptr = pair->first;
01006 ofst = pair->second;
01007 ma->Set_indirect_level(ptr->Indirect_level ());
01008 Is_True (ma->Indirect_level() != 0, ("indirect level is not set properly"));
01009 ma->Set_ptr (ptr);
01010 ptr->Add_mem_access (ma);
01011
01012 ma->Ofst().Set_fixed_ofst (cr->Offset());
01013 ma->Adjust_ofst (pair->first, pair->second);
01014 }
01015
01016
01017 TY_IDX obj_ty, hl_ty;
01018 UINT field_id = 0;
01019 if (cr->Kind() == CK_VAR) {
01020 obj_ty = hl_ty = cr->Lod_ty();
01021 if (field_id = cr->Field_id()) {
01022 obj_ty = coderep_obj_ty (cr);
01023 }
01024 } else {
01025 obj_ty = hl_ty = cr->Ilod_ty();
01026 if (field_id = cr->I_field_id()) {
01027 obj_ty = coderep_obj_ty (cr);
01028 }
01029 }
01030 ma->Set_obj_ty (obj_ty);
01031 ma->Set_hl_ty (hl_ty);
01032 ma->Set_field_id (field_id);
01033
01034 if (is_read) ma->Set_is_read (cr); else ma->Set_is_write(stmt);
01035
01036
01037 ma->Set_byte_size (TY_size(ma->Obj_ty()));
01038
01039
01040
01041
01042
01043 Map_mem_access (cr, ma);
01044
01045 return ma;
01046 }
01047
01049
01050
01051
01052
01054 void
01055 MEM_ACCESS_ANALYZER::Analyze_mem_access (void) {
01056
01057 BB_NODE_SET_ITER iter;
01058 BB_NODE* blk;
01059 FOR_ALL_ELEM (blk, iter, Init(_loopinfo->Loop()->True_body_set())) {
01060 STMTREP_ITER stmt_iter (blk->Stmtlist());
01061 STMTREP* stmt;
01062 FOR_ALL_NODE (stmt, stmt_iter, Init()) {
01063 if (stmt->Lhs()) Analyze_mem_access (stmt->Lhs(), stmt, FALSE);
01064 if (stmt->Rhs()) Analyze_mem_access (stmt->Rhs(), stmt, TRUE);
01065 }
01066 }
01067
01068 if (_trace) {
01069 Print (TFile);
01070 }
01071 }
01072
01073
01075
01076
01077
01079
01080 void
01081 MEM_RANGE::Set_access_range (MA_OFFSET* ofst, LMV_LOOP_INFO*
01082 loopinfo, INT access_sz) {
01083
01084 switch (ofst->Kind()) {
01085 case MA_OFST_FIXED:
01086 case MA_OFST_LINEAR:
01087 _access_range.low = *ofst->Linear_ofst ();
01088 _access_range.high = _access_range.low;
01089 _access_range.high.Add (access_sz);
01090 break;
01091
01092 case MA_OFST_RANGE:
01093 {
01094 const ADDR_LINEAR_EXPR_RANGE* r = ofst->Linear_ofst_range ();
01095 _access_range.low = r->low;
01096 _access_range.high = r->high;
01097 _access_range.high.Add (access_sz);
01098 }
01099 break;
01100
01101 case MA_OFST_TOO_MESSY:
01102 case MA_OFST_UNKNOWN:
01103 _access_range.low.Init();
01104 _access_range.high.Init();
01105 break;
01106
01107 default:
01108 FmtAssert (FALSE, ("Unknown ofset kind %d", ofst->Kind()));
01109 }
01110
01111 if (!_access_range.low.Is_invalid() && !_access_range.high.Is_invalid()) {
01112 return;
01113 }
01114
01115 TY_IDX ty = (TY_IDX)0;
01116 if (Base_is_symbol ()) ty = ST_type(Base_sym ());
01117 else ty = Base_ptr()->Pointed_ty();
01118
01119 if (ty != (TY_IDX)0 && TY_kind(ty) == KIND_ARRAY) {
01120 INT sz = TY_size(ty);
01121 if (sz != 0) {
01122 _access_range.low.Set_const_expr (0);
01123 _access_range.high.Set_const_expr (sz);
01124 }
01125 }
01126 }
01127
01128
01129 LMV_LOOP_INFO::LMV_LOOP_INFO (BB_LOOP* loop, MEM_POOL* mp) :
01130 _loop(loop), _mp(mp),
01131
01132 _val_range_map(32, NULL, _mp, FALSE) {
01133 _val_range_map.Init ();
01134 _iv = _loop->Iv() ? _loop->Iv()->Aux_id() : (AUX_ID)0;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143 BOOL
01144 LMV_LOOP_INFO::Get_iv_upperbound (INT& upbound) {
01145
01146 if (!_loop->Well_formed() || _loop->Exit_early()) {
01147 return FALSE;
01148 }
01149
01150 if (_loop->Flags() != LOOP_WHILE &&
01151 _loop->Flags() != LOOP_PRE_WHILE) {
01152 return FALSE;
01153 }
01154
01155 BB_NODE *header = _loop->Header();
01156 BB_NODE *preheader = _loop->Preheader();
01157 BB_NODE *loopback = _loop->Loopback();
01158 INT loopback_opnd_num = _loop->Loopback_pred_num();
01159
01160 if (loopback_opnd_num != 1) {
01161 return FALSE;
01162 }
01163
01164 STMTREP_ITER stmt_iter(header->Stmtlist());
01165 STMTREP *sr;
01166 FOR_ALL_NODE( sr, stmt_iter, Init() ) {
01167 if (sr->Op() != OPC_LABEL && sr != header->Last_stmtrep()) {
01168
01169
01170 return FALSE;
01171 }
01172 }
01173
01174 STMTREP *cond_br = header->Branch_stmtrep();
01175
01176
01177 if (cond_br->Op() != OPC_TRUEBR && cond_br->Op() != OPC_FALSEBR )
01178 return FALSE;
01179
01180
01181 CODEREP *cmp = cond_br->Rhs();
01182 if (cmp->Kind() != CK_OP || !OPCODE_is_compare(cmp->Op()))
01183 return FALSE;
01184
01185
01186
01187 OPERATOR cond_opr = cmp->Opr();
01188 if (!(cond_opr == OPR_LE || cond_opr == OPR_GE ||
01189 cond_opr == OPR_LT || cond_opr == OPR_GT)) {
01190 return FALSE;
01191 }
01192
01193 CODEREP* iv, *upbound_cr;
01194 iv = upbound_cr = NULL;
01195 if (cmp->Opnd(0)->Kind() == CK_CONST) {
01196 upbound_cr = cmp->Opnd(0); iv = cmp->Opnd(1);
01197 } else if (cmp->Opnd(1)->Kind() == CK_CONST) {
01198 upbound_cr = cmp->Opnd(1); iv = cmp->Opnd(0);
01199 }
01200 if (!iv || iv->Kind() != CK_VAR || iv->Aux_id() != _iv)
01201 return FALSE;
01202
01203 BOOL reverse = FALSE;
01204 if (iv == cmp->Opnd(1)) reverse = TRUE;
01205 if (cond_br->Op() == OPC_TRUEBR) {
01206 reverse = !reverse;
01207 }
01208
01209 if (reverse) {
01210 switch (cond_opr) {
01211 case OPR_LE: cond_opr = OPR_GE; break;
01212 case OPR_LT: cond_opr = OPR_GT; break;
01213 case OPR_GE: cond_opr = OPR_LE; break;
01214 case OPR_GT: cond_opr = OPR_GE; break;
01215 }
01216 }
01217
01218 if (cond_opr == OPR_LE) {
01219 upbound = upbound_cr->Const_val(); return TRUE;
01220 } else if (cond_opr == OPR_LT) {
01221 upbound = upbound_cr->Const_val()-1; return TRUE;
01222 }
01223
01224 return FALSE;
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 void
01239 LMV_LOOP_INFO::Analyze_var_value_range
01240 (AUX_ID var, VER_ID ver, VAR_VAL_RANGE* val) {
01241
01242
01243 ver = ver;
01244 VAR_VAL_RANGE* vr = _val_range_map.Lookup (var);
01245 if (vr != NULL) {
01246 *val = *vr;
01247 return;
01248 }
01249
01250 val->Init();
01251 if (_iv == (AUX_ID)0 || var != _iv) {
01252 return;
01253 }
01254
01255 vr = CXX_NEW (VAR_VAL_RANGE, _mp);
01256
01257
01258
01259 PHI_LIST_ITER phi_iter;
01260 PHI_NODE* phi;
01261 BOOL found = FALSE;
01262 FOR_ALL_ELEM (phi, phi_iter, Init(_loop->Header()->Phi_list())) {
01263 if (!phi->Live()) continue;
01264 CODEREP* res = phi->RESULT();
01265 if (res->Aux_id() == _iv) { found = TRUE; break; }
01266 }
01267 Is_True (found,
01268 ("Can't find the phi node for the primary IV in loop-BB:%d",
01269 _loop->Header()->Id()));
01270
01271
01272 BB_NODE* pred;
01273 BB_LIST_ITER bb_iter;
01274 FOR_ALL_ELEM (pred, bb_iter, Init(_loop->Header()->Pred())) {
01275 CODEREP* opnd = phi->OPND(bb_iter.Idx());
01276 if (_loop->Invariant_cr(opnd)) {
01277 if (opnd->Kind() == CK_CONST) {
01278 vr->Set_low (opnd->Const_val ());
01279 break;
01280 }
01281
01282
01283
01284
01285
01286
01287
01288 if (opnd->Defstmt() != NULL &&
01289 !opnd->Is_flag_set ((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI))) {
01290 STMTREP* stmt = opnd->Defstmt();
01291 if (stmt->Opr() == OPR_STID &&
01292 stmt->Rhs()->Kind() == CK_CONST) {
01293 vr->Set_low (stmt->Rhs()->Const_val ());
01294 break;
01295 }
01296 }
01297 vr->Set_low (opnd);
01298 break;
01299 }
01300 }
01301
01302
01303 CODEREP* trip = _loop->Trip_count_expr();
01304 if (trip) {
01305 if (trip->Kind() == CK_CONST && vr->Low_is_const ()) {
01306 vr->Set_high (trip->Const_val() + vr->Low_val() - 1);
01307 }
01308 } else {
01309 INT upperbound;
01310 if (Get_iv_upperbound (upperbound)) {
01311 vr->Set_high (upperbound);
01312 }
01313 }
01314
01315 _val_range_map.Insert (var, vr);
01316 *val = *vr;
01317 }
01318
01319 void
01320 ADDR_LINEAR_EXPR::Get_range
01321 (VAR_VAL_RANGE* vr, LMV_LOOP_INFO* loopinfo) const {
01322
01323 if (Is_const()) {
01324 vr->Set_low (Const_val ());
01325 vr->Set_high (Const_val ());
01326 return;
01327 }
01328
01329 vr->Init();
01330 if (Is_nonconst()) {
01331 VAR_VAL_RANGE t;
01332 loopinfo->Analyze_var_value_range (Var(), Var_ver(), &t);
01333
01334 if (t.Low_is_const() && t.High_is_const()) {
01335 INT low = Coefficient() * t.Low_val() + Const_part ();
01336 INT high = Coefficient() * t.High_val() + Const_part ();
01337
01338 low = MIN(low, Const_part ());
01339 high = MAX(high, Const_part ());
01340
01341 vr->Set_low (low);
01342 vr->Set_high (high);
01343 }
01344 }
01345 }
01346
01348
01349
01350
01352 void
01353 MA_POINTER::Print (FILE* f, BOOL verbose) {
01354 fprintf (f, "[%3d] ", _id);
01355
01356 switch (_kind) {
01357 case MA_PTR_INVALID: fprintf (f, "invalid\n"); return;
01358 case MA_PTR_PREG:
01359 fprintf (f, "R%d,v%d,", _is_preg._preg_num, _ver);
01360 break;
01361 case MA_PTR_SYM:
01362 fprintf (f, "%s,v%d,", ST_name(_is_sym._name), _ver);
01363 break;
01364 case MA_PTR_INDIRECT:
01365 fprintf (f, "indirect MA-%d,", _is_indirect._ma->Id());
01366 break;
01367 case MA_PTR_TOO_MESSY:
01368 fprintf (f, "too-messy cr%d,", _cr->Coderep_id());
01369 break;
01370 case MA_PTR_LDA:
01371 fprintf (f, "&%s, cr%d,", ST_name(_is_lda._base), _cr->Coderep_id());
01372 break;
01373 default:
01374 FmtAssert (FALSE, ("Unknown pointer type"));
01375 }
01376
01377 if (_ty != (TY_IDX)0) {
01378 if (TY_kind(_ty) == KIND_POINTER)
01379 fprintf (f, "Ty:->'%s',", TY_name(Pointed_ty()));
01380 else
01381 fprintf (f, "Ty:'%s',", TY_name(_ty));
01382 }
01383
01384 fprintf (f, "ilevel:%d,ld:%d,st:%d,", _ind_level, _ld_cnt, _st_cnt);
01385 if (Is_loop_invar()) { fprintf (f, "invar,"); }
01386 fprintf (f, "\n");
01387
01388 if (_kind == MA_PTR_INDIRECT || _kind == MA_PTR_TOO_MESSY) {
01389 _cr->Print (4, f);
01390 }
01391
01392 if (verbose) {
01393 fprintf (f, "All memops via this pointer:\n");
01394 for (MEM_ACCESS_VECT_ITER iter = _mem_access.begin ();
01395 iter != _mem_access.end (); iter ++) {
01396 (*iter)->Print (f);
01397 }
01398 }
01399 }
01400
01401 void
01402 MA_OFFSET::Print (FILE* f) {
01403
01404 switch (_kind) {
01405 case MA_OFST_INVALID: fprintf (f, "invalid"); break;
01406 case MA_OFST_FIXED: fprintf (f, "fixed,%d", Get_fixed_ofst()); break;
01407 case MA_OFST_LINEAR:
01408 fprintf (f, "linear %d*aux_%dv%d+%d", _ofst.low.Coefficient (),
01409 _ofst.low.Var(), _ofst.low.Var_ver(), _ofst.low.Const_part ());
01410 break;
01411 case MA_OFST_RANGE:
01412 fprintf (f, "range [");
01413 if (_ofst.low.Is_nonconst ()) {
01414 fprintf (f, "linear %d*aux_%dv%d+%d", _ofst.low.Coefficient (),
01415 _ofst.low.Var(), _ofst.low.Var_ver(), _ofst.low.Const_part ());
01416 } else {
01417 fprintf (f, "fixed,%d", _ofst.low.Const_val());
01418 }
01419
01420 fprintf (f, ",");
01421 if (_ofst.high.Is_nonconst ()) {
01422 fprintf (f, "%d*aux_%dv%d+%d", _ofst.high.Coefficient (),
01423 _ofst.high.Var(), _ofst.high.Var_ver(), _ofst.high.Const_part ());
01424 } else {
01425 fprintf (f, "fixed,%d", _ofst.high.Const_val());
01426 }
01427 fprintf (f, "]");
01428 break;
01429
01430 case MA_OFST_UNKNOWN: fprintf (f, "unknown"); break;
01431 case MA_OFST_TOO_MESSY:
01432 fprintf (f, "ofst is:\n");
01433 _expr->Print (4, TFile);
01434 break;
01435
01436 default:
01437 FmtAssert (FALSE, ("unknown ofst kind"));
01438 break;
01439 }
01440 }
01441
01442 void
01443 MEM_ACCESS::Print (FILE* f) {
01444 fprintf (f, "[%3d] cr%d,", _id, _coderep ? _coderep->Coderep_id() : 0);
01445 if (_ind_level == 0) {
01446 fprintf (f, "var:%s,", ST_name(_st));
01447 } else {
01448 fprintf (f, "ivar:ptr%d,", _ptr ? _ptr->Id() : 0);
01449 }
01450
01451 fprintf (f, "ofst:");
01452 _ofst.Print (f);
01453
01454 fprintf (f, ",sz:%d,fld:%d,", (INT)_size, _field_id);
01455 if (_obj_ty != (TY_IDX)0) {
01456 fprintf (f, "Ty:%s,", TY_name(_obj_ty));
01457 }
01458 if (_hl_ty != (TY_IDX)0) {
01459 fprintf (f, "Hlty:%s,", TY_name(_hl_ty));
01460 }
01461 fprintf (f, "%s\n", Is_read() ? "ld" : "st");
01462 }
01463
01464 void
01465 MEM_ACCESS_ANALYZER::Print (FILE* f) {
01466
01467 fprintf (f, "\nMEM_ACCESS_ANALYZER:\n%s\n", DBar);
01468 fprintf (f, "LOOP:hdr-bb%d, ld:%d, st:%d, MEM_ACCESS are:\n",
01469 _loopinfo->Loop()->Header()->Id(), _read_cnt, _write_cnt);
01470
01471
01472
01473 for (MEM_ACCESS_VECT_ITER iter = _all_ma.begin();
01474 iter != _all_ma.end(); iter++) {
01475 (*iter)->Print (f);
01476 }
01477
01478
01479 fprintf (f, "MA_POINTERS are:\n");
01480 MA_PTR_VECT& all_ptrs = _ptr_mgr.All_ptrs();
01481 for (MA_PTR_VECT_ITER iter = all_ptrs.begin();
01482 iter != all_ptrs.end(); iter++) {
01483 (*iter)->Print (f);
01484 }
01485 }
01486
01487 void
01488 ADDR_LINEAR_EXPR::Print (FILE* f) {
01489 if (Is_const()) {
01490 fprintf (f, "%d ", Const_val());
01491 } else if (Is_nonconst ()) {
01492 fprintf (f, "%d*aux%dv%d+%d ", Coefficient (),
01493 (INT)Var(), (INT)Var_ver(), Const_val());
01494 } else {
01495 fprintf (f, "invalid ");
01496 }
01497 }
01498
01499 void
01500 ADDR_LINEAR_EXPR_RANGE::Print (FILE* f) {
01501 fprintf (f, "[");
01502 low.Print (f);
01503 fprintf (f, ",");
01504 high.Print (f);
01505 fprintf (f, "]");
01506 }
01507
01508 void
01509 MEM_RANGE::Print (FILE* f) {
01510 if (Base_is_symbol ()) {
01511 fprintf (f, "base:");
01512 Base_sym()->Print (f, FALSE);
01513 } else if (Base_is_ptr ()) {
01514 fprintf (f, "pointer is:");
01515 Base_ptr()->Print (f);
01516 } else {
01517 fprintf (f, "Invalid\n");
01518 return;
01519 }
01520
01521 _access_range.Print (f);
01522 fprintf (f, "\n");
01523 }
01524
01525 void VAR_VAL_RANGE::Print(FILE* f) {
01526 }