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
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #ifndef opt_etable_INCLUDED
00099 #define opt_etable_INCLUDED "opt_etable.h"
00100
00101 #include "defs.h"
00102 #include "mempool.h"
00103 #include "cxx_template.h"
00104 #include "opt_defs.h"
00105 #include "opt_array.h"
00106 #include "cxx_base.h"
00107 #include "opt_base.h"
00108 #include "bb_node_set.h"
00109 #include "opt_htable.h"
00110 #include "opt_vnfre.h"
00111
00112 class ALIAS_RULE;
00113 class BB_NODE;
00114 class BB_NODE_SET;
00115 class CODEMAP;
00116 class CODEREP;
00117 class COMP_UNIT;
00118 class CFG;
00119 class ETABLE;
00120 class EXP_OCCURS;
00121 class EXP_ALL_REAL_ITER;
00122 class EXP_WORKLST;
00123 class LFTR;
00124 class OPT_STAB;
00125 class PHI_NODE;
00126 class STMTREP;
00127 class STR_RED;
00128 class E_VER_TAB;
00129 class REHASH_CACHE_LIST;
00130 class EXP_HOISTING;
00131 class SSU;
00132 class OCCUR_REPLACEMENT;
00133
00134 enum PRE_KIND {
00135 PK_EPRE = 0,
00136 PK_LPRE = 1,
00137 PK_SPRE = 2,
00138 PK_VNFRE = 3,
00139 };
00140
00141 extern const char *pre_kind_name(PRE_KIND);
00142
00143 class REHASH_INFO;
00144 template <class NODE_TYPE, class KEY_TYPE> class ID_MAP;
00145
00146 class EXP_OCCURS_LIST : public SLIST_NODE {
00147 private:
00148 EXP_OCCURS *_node;
00149 mINT32 _opnd_idx;
00150
00151 EXP_OCCURS_LIST(const EXP_OCCURS_LIST&);
00152 EXP_OCCURS_LIST& operator = (const EXP_OCCURS_LIST&);
00153 public:
00154 EXP_OCCURS_LIST(void) { }
00155 EXP_OCCURS_LIST(EXP_OCCURS *node, mINT32 i)
00156 { Init(node, i); }
00157 ~EXP_OCCURS_LIST(void) { }
00158
00159 DECLARE_SLIST_NODE_CLASS(EXP_OCCURS_LIST)
00160
00161 void Init(EXP_OCCURS *nd, mINT32 i)
00162 { _node = nd; _opnd_idx = i; }
00163
00164 EXP_OCCURS *Node(void) const { return _node; }
00165
00166 mINT32 Opnd_idx(void) const { return _opnd_idx; }
00167 };
00168
00169 class USE_LIST_ENTRY : public SLIST_NODE {
00170 private:
00171 EXP_PHI *_node;
00172 mINT32 _opnd_idx;
00173
00174 USE_LIST_ENTRY(const USE_LIST_ENTRY&);
00175 USE_LIST_ENTRY& operator = (const USE_LIST_ENTRY&);
00176 public:
00177 USE_LIST_ENTRY(void) { }
00178 USE_LIST_ENTRY(EXP_PHI *node, mINT32 i)
00179 { Init(node, i); }
00180 ~USE_LIST_ENTRY(void) { }
00181
00182 DECLARE_SLIST_NODE_CLASS(USE_LIST_ENTRY)
00183
00184 void Init(EXP_PHI *node, mINT32 i)
00185 { _node = node; _opnd_idx = i; }
00186
00187 EXP_PHI *Node(void) const { return _node; }
00188
00189 mINT32 Opnd_idx(void) const { return _opnd_idx; }
00190 };
00191
00192 class USE_LIST_ITER : public SLIST_ITER {
00193 public:
00194
00195
00196 USE_LIST_ITER(USE_LIST_ENTRY *nd) { SLIST_ITER::Init(nd); }
00197 USE_LIST_ITER(void) { SLIST_ITER::Init(); }
00198 USE_LIST_ENTRY *First(void)
00199 { return (USE_LIST_ENTRY *) SLIST_ITER::First(); }
00200 USE_LIST_ENTRY *Next(void)
00201 { return (USE_LIST_ENTRY *) SLIST_ITER::Next(); }
00202 };
00203
00204 class EXP_PHI : public SLIST_NODE {
00205 DECLARE_SLIST_NODE_CLASS(EXP_PHI)
00206 friend class ETABLE;
00207 public:
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 enum EXP_PHI_OPND_FLAGS {
00221 EPOF_NONE = 0x0,
00222 EPOF_HAS_REAL_OCC = 0x1,
00223 EPOF_DELAYED_RENAME = 0x2,
00224 EPOF_INJURED = 0x4,
00225 EPOF_OPND_STOPS = 0x8,
00226 EPOF_NULL_SSU_VERSION = 0x10,
00227
00228 };
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 enum EXP_PHI_FLAGS {
00253 EPF_NONE = 0x0,
00254 EPF_I_A_SEEN = 0x1,
00255 EPF_NOT_DOWN_SAFE = 0x2,
00256 EPF_IS_LIVE = 0x4,
00257 EPF_NOT_USER_AVAIL = 0x8,
00258 EPF_CANT_BE_AVAIL = 0x10,
00259 EPF_STOPS = 0x20,
00260 EPF_IDENTITY = 0x40,
00261 EPF_KNOW_REPLACEMENT = 0x80,
00262 EPF_IDENT_INJURED = 0x100,
00263 EPF_REVERSE_PHI = 0x400,
00264 EPF_DEAD_PHI_REGION = 0x800,
00265 EPF_PARTIAL_AVAIL = 0x1000,
00266 EPF_LOCAL_PRED = 0x2000
00267 };
00268
00269 private:
00270 EXP_ID _e_num;
00271 mINT32 _opnd_count;
00272 UINT16 _flags;
00273 UINT16 _saved_flags;
00274
00275 union {
00276 EXP_OCCURS *_cached_identity_assignment;
00277 EXP_OCCURS *_identical_to;
00278 };
00279
00280 BB_NODE *_bb;
00281 EXP_OCCURS *_result;
00282
00283 class PHI_ELEM {
00284 friend class EXP_PHI;
00285 EXP_OCCURS *_occ;
00286 UINT32 _flags;
00287 EXP_OCCURS *_pred_or_succ;
00288
00289 };
00290 PHI_ELEM *_vec;
00291
00292
00293
00294
00295 USE_LIST_ENTRY *_uses;
00296
00297
00298
00299 EXP_PHI(void);
00300 EXP_PHI(const EXP_PHI&);
00301 EXP_PHI& operator = (const EXP_PHI&);
00302
00303 void Set_result(EXP_OCCURS *o){ _result = o; }
00304
00305 void Set_cached_identity_assignment(EXP_OCCURS *occ)
00306 { _cached_identity_assignment = occ; }
00307
00308 EXP_OCCURS *Cached_identity_assignment(void)
00309 { return _cached_identity_assignment; }
00310
00311 void Set_flag(EXP_PHI_FLAGS bit)
00312 { _flags |= bit; }
00313 void Reset_flag(EXP_PHI_FLAGS bit)
00314 { _flags &= ~bit; }
00315 BOOL Is_flag_set(EXP_PHI_FLAGS bit) const
00316 { return _flags & bit; }
00317
00318 public:
00319 INT32 id;
00320
00321 EXP_PHI(EXP_ID e_num,
00322 INT opnd_count,
00323 BB_NODE *bb,
00324 MEM_POOL *pool) { Init(e_num,opnd_count,bb,pool); }
00325 ~EXP_PHI(void) { }
00326
00327 void Init(EXP_ID e_num,
00328 INT size,
00329 BB_NODE *bb,
00330 MEM_POOL *pool);
00331
00332 EXP_ID E_num(void) const { return _e_num; }
00333 EXP_OCCURS *Result(void) const { return _result; }
00334
00335 EXP_OCCURS *Opnd(INT i) const { return _vec[i]._occ; }
00336 EXP_OCCURS *Pred(INT i) const { return _vec[i]._pred_or_succ; }
00337 EXP_OCCURS *Succ(INT i) const { return _vec[i]._pred_or_succ; }
00338 void Set_opnd(INT i,
00339 EXP_OCCURS *occ){ _vec[i]._occ = occ; }
00340 void Set_pred(INT i,
00341 EXP_OCCURS *occ){ _vec[i]._pred_or_succ = occ; }
00342 void Set_succ(INT i,
00343 EXP_OCCURS *occ){ _vec[i]._pred_or_succ = occ; }
00344 INT Opnd_count(void) const { return _opnd_count; }
00345 BB_NODE *Bb(void) const { return _bb; }
00346
00347 void Set_not_down_safe(void) { Set_flag(EPF_NOT_DOWN_SAFE); }
00348 void Reset_not_down_safe(void){ Reset_flag(EPF_NOT_DOWN_SAFE); }
00349 BOOL Not_down_safe(void) const
00350 { return Is_flag_set(EPF_NOT_DOWN_SAFE); }
00351
00352 void Set_not_user_avail(void) { Set_flag(EPF_NOT_USER_AVAIL); }
00353 BOOL Not_user_avail(void) const
00354 { return Is_flag_set(EPF_NOT_USER_AVAIL); }
00355
00356 void Set_cant_be_avail(void) { Set_flag(EPF_CANT_BE_AVAIL); }
00357 BOOL Cant_be_avail(void) const
00358 { return Is_flag_set(EPF_CANT_BE_AVAIL); }
00359
00360 void Set_live(void) { Set_flag(EPF_IS_LIVE); }
00361 BOOL Is_live(void) const
00362 {
00363 return TRUE; }
00364
00365 void Set_has_real_occ(INT i)
00366 { _vec[i]._flags |= EPOF_HAS_REAL_OCC; }
00367 BOOL Has_real_occ(INT i) const
00368 { return (_vec[i]._flags & EPOF_HAS_REAL_OCC); }
00369
00370 void Set_identity(void) { Set_flag(EPF_IDENTITY); }
00371 void Reset_identity(void) { Reset_flag(EPF_IDENTITY); }
00372 BOOL Identity(void) const
00373 { return Is_flag_set(EPF_IDENTITY); }
00374
00375 void Set_reverse_phi(void) { Set_flag(EPF_REVERSE_PHI); }
00376 BOOL Reverse_phi(void) const
00377 { return Is_flag_set(EPF_REVERSE_PHI); }
00378
00379 void Set_identical_to(EXP_OCCURS *const occ)
00380 { _identical_to = occ; }
00381 EXP_OCCURS *Identical_to(void) const
00382 {
00383 Is_True(Will_b_avail() && Identity(),
00384 ("EXP_PHI::Identical_to: availability and "
00385 "identity are required"));
00386 return _identical_to;
00387 }
00388
00389 void Set_identity_injured(void)
00390 { Set_flag(EPF_IDENT_INJURED); }
00391 BOOL Identity_injured(void) const
00392 { return Is_flag_set(EPF_IDENT_INJURED); }
00393
00394 void Set_replacing_occur_known(void)
00395 { Set_flag(EPF_KNOW_REPLACEMENT); }
00396 BOOL Replacing_occur_known(void) const
00397 { return Is_flag_set(EPF_KNOW_REPLACEMENT); }
00398
00399 void Set_I_A_Seen(void) { Set_flag(EPF_I_A_SEEN); }
00400 void Reset_I_A_Seen(void) { Reset_flag(EPF_I_A_SEEN); }
00401 BOOL I_A_Seen(void)const { return Is_flag_set(EPF_I_A_SEEN); }
00402
00403 void Set_stops(void) { Set_flag(EPF_STOPS); }
00404 BOOL Stops(void) const { return Is_flag_set(EPF_STOPS); }
00405
00406 void Set_dead_phi_region(void) { Set_flag(EPF_DEAD_PHI_REGION); }
00407 BOOL Dead_phi_region(void) const { return Is_flag_set(EPF_DEAD_PHI_REGION); }
00408
00409 BOOL Will_b_avail(void) const
00410 { return !Cant_be_avail() && Stops(); }
00411
00412 BOOL Partial_avail() const { return Is_flag_set(EPF_PARTIAL_AVAIL); }
00413
00414 void Set_partial_avail() { Set_flag(EPF_PARTIAL_AVAIL); }
00415
00416 void Set_injured(INT i)
00417 { _vec[i]._flags |= EPOF_INJURED; }
00418 void Reset_injured(INT i)
00419 { _vec[i]._flags &= ~EPOF_INJURED; }
00420 BOOL Injured(INT i) const
00421 { return (_vec[i]._flags & EPOF_INJURED); }
00422 BOOL Any_opnd_injured(void) const;
00423
00424 void Set_has_real_use() {Set_flag(EPF_LOCAL_PRED);}
00425 void Reset_has_real_use() {Reset_flag(EPF_LOCAL_PRED);}
00426 BOOL Has_real_use() {return Is_flag_set(EPF_LOCAL_PRED);}
00427
00428 USE_LIST_ENTRY *Uses(void) const { return _uses; }
00429
00430 void Set_uses(USE_LIST_ENTRY *use)
00431 { _uses = use; }
00432
00433 void Add_use(EXP_PHI *use,
00434 INT opnd_idx,
00435 MEM_POOL *pool)
00436 {
00437 USE_LIST_ENTRY *new_ll_node =
00438 CXX_NEW(USE_LIST_ENTRY(use, opnd_idx),
00439 pool);
00440 if (Uses() == NULL) {
00441 Set_uses(new_ll_node);
00442 }
00443 else {
00444 Uses()->Insert_After(new_ll_node);
00445 }
00446 }
00447
00448 BOOL Delayed_rename(INT i) const
00449 { return (_vec[i]._flags &
00450 EPOF_DELAYED_RENAME); }
00451
00452 void Set_delayed_rename(INT i){ _vec[i]._flags |=
00453 EPOF_DELAYED_RENAME; }
00454
00455 void Reset_delayed_rename(INT i)
00456 { _vec[i]._flags &=
00457 ~EPOF_DELAYED_RENAME; }
00458
00459 void Set_opnd_stops(INT i) { _vec[i]._flags |=
00460 EPOF_OPND_STOPS; }
00461
00462 BOOL Opnd_stops(INT i) const { return (_vec[i]._flags &
00463 EPOF_OPND_STOPS); }
00464
00465 void Set_null_ssu_version(INT i) { _vec[i]._flags |=
00466 EPOF_NULL_SSU_VERSION; }
00467
00468 BOOL Null_ssu_version(INT i) const { return (_vec[i]._flags &
00469 EPOF_NULL_SSU_VERSION); }
00470 BOOL Identity_assignment(BOOL &, EXP_PHI *, BOOL, STACK<EXP_PHI*> &);
00471
00472 BOOL Need_insertion(INT) const;
00473
00474 void Save_flags() { _saved_flags = _flags; }
00475 void Restore_flags() { _flags =_saved_flags; }
00476
00477
00478 BOOL Phi_opnd_not_avail(INT) const;
00479
00480 void Print(FILE *fp=stderr, BOOL show_preds = TRUE) const;
00481 };
00482
00483 class EXP_PHI_LIST : public SLIST {
00484 DECLARE_SLIST_CLASS (EXP_PHI_LIST, EXP_PHI)
00485
00486 private:
00487 INT32 _out_degree;
00488
00489 EXP_PHI_LIST(const EXP_PHI_LIST&);
00490 EXP_PHI_LIST& operator = (const EXP_PHI_LIST&);
00491
00492 public:
00493 EXP_PHI_LIST(INT32 out_degree) { _out_degree = out_degree; }
00494 EXP_PHI_LIST(BB_NODE *bb);
00495 ~EXP_PHI_LIST(void) {}
00496
00497 INT32 Out_degree() const { return _out_degree; }
00498
00499
00500 void Remove_opnd(INT32 i);
00501 void Print(FILE *fp=stderr);
00502 };
00503
00504
00505 class EXP_PHI_LIST_ITER : public SLIST_ITER {
00506 private:
00507 DECLARE_SLIST_ITER_CLASS (EXP_PHI_LIST_ITER, EXP_PHI, EXP_PHI_LIST)
00508
00509 EXP_PHI_LIST_ITER(const EXP_PHI_LIST_ITER&);
00510 EXP_PHI_LIST_ITER& operator = (const EXP_PHI_LIST_ITER&);
00511
00512 public:
00513 ~EXP_PHI_LIST_ITER(void) {}
00514
00515 EXP_PHI *First_elem(void) { return First(); }
00516 EXP_PHI *Next_elem(void) { return Next(); }
00517 };
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 class EXP_OCCURS : public SLIST_NODE {
00537
00538 DECLARE_SLIST_NODE_CLASS( EXP_OCCURS )
00539
00540 private:
00541
00542
00543
00544
00545 enum OCC_FLAG {
00546 OCC_NONE = 0x000,
00547 OCC_MULT_REAL_OCCUR = 0x001,
00548 OCC_FAKE_STORE_OCCUR = 0x001,
00549
00550 OCC_INSERTED_OCCUR = 0x002,
00551
00552
00553
00554
00555
00556
00557
00558 OCC_CODEREP_OWNER = 0x002,
00559
00560
00561
00562
00563
00564
00565
00566
00567 OCC_ENCL_STMT_SET = 0x004,
00568
00569
00570
00571 OCC_AS_L_VALUE = 0x008,
00572
00573 OCC_REQUIRED_PRED = 0x008,
00574 OCC_INJURED = 0x010,
00575
00576 OCC_DELETE_COMP = 0x020,
00577
00578
00579
00580 OCC_SAVE_TO_TEMP = 0x040,
00581
00582
00583
00584
00585 OCC_HOISTED = 0x080,
00586 OCC_REHASH_CHANGED = 0x100,
00587 OCC_FOR_SPRE = 0x200,
00588 OCC_OBSOLETE_COMPARISON = 0x400,
00589
00590 OCC_SUNK_L_VALUE = 0x800,
00591
00592
00593
00594 #if defined(TARG_SL) // PARA_EXTENSION
00595 OCC_IN_PARA_REGION = 0x1000,
00596 #endif
00597 };
00598
00599 UINT32 _kind:3;
00600 UINT32 _flag:13;
00601 UINT32 _stmt_kid_num:16;
00602
00603 UINT32 _saved_flags:13;
00604
00605 union {
00606 CODEREP *_occurrence;
00607 } _oc;
00608 IDTYPE _e_version:24;
00609
00610
00611 enum { OCC_REHASH_COST_LIMIT = 255 };
00612
00613 UINT32 _rehash_cost:8;
00614
00615
00616
00617
00618
00619 union {
00620 EXP_OCCURS *_def_occur;
00621
00622
00623
00624
00625
00626
00627
00628 CODEREP *_temp_cr;
00629
00630
00631
00632
00633 EXP_WORKLST *_spre_wk;
00634
00635
00636
00637 } _temp;
00638
00639 union {
00640 STMTREP *_stmt;
00641 EXP_PHI *_exp_phi;
00642 BB_NODE *_bb;
00643 } _enclosed_in;
00644
00645 #if defined(TARG_SL) // PARA_EXTENSION
00646 RID* _rid;
00647 #endif
00648
00649 EXP_OCCURS(const EXP_OCCURS&);
00650 EXP_OCCURS& operator = (const EXP_OCCURS&);
00651
00652 void Reset_flag(void) { _flag = OCC_NONE; }
00653 void Reset_flag(OCC_FLAG f) { _flag = (_flag & (~f)); }
00654 void Set_flag(OCC_FLAG f) { _flag = (_flag|f); }
00655 BOOL Is_flag_set(OCC_FLAG f)
00656 const { return _flag & f; }
00657
00658 public:
00659
00660
00661
00662
00663
00664
00665
00666 enum OCC_KIND {
00667 OCC_UNKNOWN_OCCUR = 0,
00668 OCC_PHI_OCCUR = 1,
00669 OCC_REAL_OCCUR = 2,
00670 OCC_COMP_OCCUR = 3,
00671 OCC_PHI_PRED_OCCUR = 4,
00672 OCC_EXIT_OCCUR = 5,
00673 #if defined(TARG_SL)
00674 OCC_PI_OCCUR = 6,
00675 #endif
00676 };
00677
00678 enum E_VERSION_VALUE {
00679 ILLEGAL_E_VERSION = 0,
00680 };
00681
00682 EXP_OCCURS(CODEREP*, STMTREP*, EXP_PHI*, BOOL);
00683 void Init(void);
00684 EXP_OCCURS(void) { Init(); }
00685 ~EXP_OCCURS(void) { }
00686
00687 OCC_KIND Occ_kind(void) const { return (OCC_KIND)_kind; }
00688 void Set_kind(OCC_KIND k) { _kind = k; }
00689
00690 mINT16 Stmt_kid_num(void) const
00691 { Is_True(Occ_kind() == OCC_REAL_OCCUR || Occ_kind() == OCC_COMP_OCCUR,
00692 ("EXP_OCCURS::Stmt_kid_num: Must be real occ!"));
00693 return _stmt_kid_num;
00694 }
00695 CODEREP *Occurrence(void)const { return _oc._occurrence; }
00696 IDTYPE E_version(void) const
00697 { Is_True(Occ_kind() != OCC_PHI_PRED_OCCUR || Inserted_computation() ||
00698 Sunk_lvalue(),
00699 ("EXP_OCCURS::E_version: Cannot be phi pred occ!"));
00700 return _e_version;
00701 }
00702
00703 void Set_rehash_cost(UINT32 rehash_cost)
00704 {
00705 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00706 Occ_kind() == OCC_UNKNOWN_OCCUR,
00707 ("EXP_OCCURS::Set_rehash_cost: Must be real occ!"));
00708 if (rehash_cost <= OCC_REHASH_COST_LIMIT) {
00709 _rehash_cost = rehash_cost;
00710 }
00711 else {
00712 _rehash_cost = OCC_REHASH_COST_LIMIT;
00713 }
00714 }
00715
00716 UINT32 Rehash_cost(void) const
00717 {
00718 Is_True(Occ_kind() == OCC_REAL_OCCUR,
00719 ("EXP_OCCURS::Rehash_cost: Must be real occ!"));
00720 return _rehash_cost;
00721 }
00722
00723 CODEREP *Temp_cr(void) const
00724 {
00725
00726 Is_True(!Is_flag_set(OCC_DELETE_COMP) &&
00727 (Occ_kind() == OCC_PHI_OCCUR ||
00728 Is_flag_set(OCC_SAVE_TO_TEMP) ||
00729 Is_flag_set(OCC_SUNK_L_VALUE) ||
00730 _temp._temp_cr == NULL),
00731
00732
00733
00734 ("EXP_OCCURS::Temp_cr: cannot use temp_cr field"));
00735 return _temp._temp_cr;
00736 }
00737
00738 void Set_temp_cr(CODEREP *x) {
00739 Is_True(!Is_flag_set(OCC_DELETE_COMP) &&
00740 !(Occ_kind() == OCC_REAL_OCCUR && !Is_flag_set(OCC_SAVE_TO_TEMP)),
00741 ("EXP_OCCURS::Set_temp_cr: cannot use temp_cr field"));
00742 _temp._temp_cr = x;
00743 }
00744
00745 void Clear_temp_cr(void) { _temp._temp_cr = NULL; }
00746
00747
00748 CODEREP *Get_temp_cr(EXP_WORKLST *wk, CODEMAP *htable);
00749
00750 EXP_OCCURS *Def_occur(void) const
00751 {
00752 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00753 Occ_kind() == OCC_COMP_OCCUR ||
00754 (Occ_kind() == OCC_PHI_PRED_OCCUR &&
00755 Inserted_computation()),
00756 ("EXP_OCCURS::Def_occur: Must be real or comp occur."));
00757 return _temp._def_occur;
00758 }
00759 void Set_def_occur(EXP_OCCURS *def_occur)
00760 {
00761 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00762 Occ_kind() == OCC_COMP_OCCUR ||
00763 (Occ_kind() == OCC_PHI_PRED_OCCUR &&
00764 def_occur == NULL),
00765 ("EXP_OCCURS::Set_def_occur: Must be real or comp occur."));
00766 _temp._def_occur = def_occur;
00767 }
00768
00769
00770
00771
00772
00773 BOOL Is_real_avail_def(void) const
00774 {
00775 return ((Occ_kind() == OCC_PHI_PRED_OCCUR &&
00776 (Inserted_computation() || Sunk_lvalue())) ||
00777 (Occ_kind() == OCC_REAL_OCCUR &&
00778 Def_occur() == NULL));
00779 }
00780
00781 EXP_WORKLST *Spre_wk(void) const { return _temp._spre_wk; }
00782 void Set_spre_wk(EXP_WORKLST *wk)
00783 {
00784 Is_True(Occ_kind() == OCC_PHI_OCCUR,
00785 ("EXP_OCCURS::Set_spre_wk: Must be phi occur"));
00786 _temp._spre_wk = wk;
00787 }
00788
00789 STMTREP *Stmt(void) const;
00790 STMTREP *Enclosed_in_stmt(void) const
00791 { Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00792 Occ_kind() == OCC_COMP_OCCUR ||
00793 (Occ_kind() == OCC_PHI_PRED_OCCUR &&
00794 Inserted_computation() && Encl_stmt_set()),
00795 ("EXP_OCCURS::Enclosed_in_stmt: Must be real occ!"));
00796 return Stmt();
00797 }
00798 STMTREP *Spre_store(void) const { return _enclosed_in._stmt; }
00799 STMTREP *Spre_kill_stmt(void) const { return _enclosed_in._stmt; }
00800
00801 EXP_PHI *Exp_phi(void) const
00802 { Is_True(Occ_kind() == OCC_PHI_OCCUR,
00803 ("Must be phi occ!"));
00804 return _enclosed_in._exp_phi;
00805 }
00806
00807 const BB_NODE *Enclosed_in_bb(void) const
00808 { Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR ||
00809 Occ_kind() == OCC_EXIT_OCCUR ||
00810 (Occ_kind() == OCC_REAL_OCCUR &&
00811 Inserted_computation()) ||
00812 (Occ_kind() == OCC_REAL_OCCUR &&
00813 Is_flag_set(OCC_HOISTED)),
00814 ("Must be fake or inserted real occ!"));
00815 return _enclosed_in._bb;
00816 }
00817 void Set_occurrence(CODEREP *cr) { _oc._occurrence = cr; }
00818 void Set_e_version(IDTYPE v) { _e_version = v; }
00819 void Set_stmt_kid_num(INT stmt_kid_num)
00820 { Is_True(Occ_kind() == OCC_REAL_OCCUR || Occ_kind() == OCC_COMP_OCCUR ||
00821 (Occ_kind() == OCC_PHI_PRED_OCCUR && Inserted_computation()),
00822 ("EXP_OCCURS::Set_stmt_kid_num: Must be real occ!"));
00823 FmtAssert((stmt_kid_num>=0) && (stmt_kid_num<=32767),
00824 ("Kid number < 0 or > 32767"));
00825 _stmt_kid_num = stmt_kid_num;
00826 }
00827 void Clear_flags(void) { Reset_flag(); }
00828 void Reset_enclosed_in(void) { _enclosed_in._stmt = NULL; }
00829 void Set_enclose_stmt(STMTREP *stmt)
00830 { Is_True(Occ_kind() == OCC_REAL_OCCUR || Occ_kind() == OCC_COMP_OCCUR ||
00831 (Occ_kind() == OCC_PHI_PRED_OCCUR &&
00832 (Inserted_computation() || Sunk_lvalue())),
00833 ("EXP_OCCURS::Set_enclose_stmt: Must be real occ!"));
00834 _enclosed_in._stmt = stmt;
00835 }
00836 void Set_exp_phi(EXP_PHI *exp_phi)
00837 { Is_True(Occ_kind() == OCC_PHI_OCCUR,
00838 ("EXP_OCCURS::Set_exp_phi: Must be phi occ!"));
00839 _enclosed_in._exp_phi = exp_phi;
00840 }
00841 void Set_enclose_bb(BB_NODE *bb)
00842 { Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR ||
00843 Occ_kind() == OCC_EXIT_OCCUR ||
00844 (Occ_kind() == OCC_REAL_OCCUR &&
00845 Inserted_computation()) ||
00846 (Occ_kind() == OCC_REAL_OCCUR &&
00847 Is_flag_set(OCC_HOISTED)),
00848 ("EXP_OCCURS::Set_enclose_bb: Must be fake or inserted"
00849 "real occ!"));
00850 _enclosed_in._bb = bb;
00851 }
00852
00853 void Set_rehash_changed_expr(void)
00854 { Set_flag(OCC_REHASH_CHANGED); }
00855 void Set_mult_real(void) { Set_flag(OCC_MULT_REAL_OCCUR); }
00856 void Reset_mult_real(void) { Reset_flag(OCC_MULT_REAL_OCCUR); }
00857 void Set_fake_store(void) { Set_flag(OCC_FAKE_STORE_OCCUR); }
00858 void Reset_encl_stmt_set(void){
00859 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
00860 ("EXP_OCCURS::Reset_encl_stmt_set: bad occurrence kind"));
00861 Reset_flag(OCC_ENCL_STMT_SET);
00862 }
00863 void Set_encl_stmt_set(void)
00864 {
00865 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
00866 ("EXP_OCCURS::Set_encl_stmt_set: bad occurrence kind"));
00867 Set_flag(OCC_ENCL_STMT_SET);
00868 }
00869 void Reset_for_spre(void) { Reset_flag(OCC_FOR_SPRE); }
00870 void Set_for_spre(void) { Set_flag(OCC_FOR_SPRE); }
00871 void Set_delete_comp(void) { Set_flag(OCC_DELETE_COMP); }
00872 void Reset_save_to_temp(void) { Reset_flag(OCC_SAVE_TO_TEMP); }
00873 void Set_save_to_temp(void) { Set_flag(OCC_SAVE_TO_TEMP); }
00874 void Reset_inserted(void) { Reset_flag(OCC_INSERTED_OCCUR); }
00875 void Set_inserted(void)
00876 {
00877 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
00878 ("EXP_OCCURS::Set_inserted: bad occurrence kind"));
00879 Set_flag(OCC_INSERTED_OCCUR);
00880 }
00881
00882 void Reset_t_ver_owns_coderep(void)
00883 {
00884 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00885 Occ_kind() == OCC_PHI_OCCUR,
00886 ("EXP_OCCURS::Reset_t_ver_owns_coderep: bad occurrence kind"));
00887 Reset_flag(OCC_CODEREP_OWNER);
00888 }
00889
00890 void Set_t_ver_owns_coderep(void)
00891 {
00892 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00893 Occ_kind() == OCC_PHI_OCCUR,
00894 ("EXP_OCCURS::Set_t_ver_owns_coderep: bad occurrence kind"));
00895 Set_flag(OCC_CODEREP_OWNER);
00896 }
00897
00898 void Set_occurs_as_lvalue(void)
00899 {
00900 Is_True(OPERATOR_is_scalar_istore (Stmt()->Opr()) ||
00901 OPERATOR_is_scalar_store (Stmt()->Opr()),
00902 ("EXP_OCCURS::Set_occurs_as_lvalue: not ISTORE"));
00903 Set_flag(OCC_AS_L_VALUE);
00904 }
00905
00906 void Set_injured_occ(void)
00907 {
00908
00909
00910
00911
00912
00913
00914
00915 Set_flag(OCC_INJURED);
00916 }
00917
00918 void Reset_injured_occ(void) { Reset_flag(OCC_INJURED); }
00919
00920 #if defined(TARG_SL) // PARA_EXTENSION
00921 BOOL Occ_in_para_region(void) { Is_flag_set(OCC_IN_PARA_REGION); }
00922 void Set_occ_in_para_region(void) { Set_flag(OCC_IN_PARA_REGION);}
00923 void Reset_occ_in_para_region(void) { Reset_flag(OCC_IN_PARA_REGION); }
00924 #endif
00925
00926 void Set_sunk_lvalue(void) { Set_flag(OCC_SUNK_L_VALUE); }
00927 #if defined(TARG_SL) // PARA_EXTENSION
00928 void Reset_sunk_lvalue(void) { return Reset_flag(OCC_SUNK_L_VALUE);}
00929 #endif
00930
00931 BOOL Mult_real(void) const { return Is_flag_set
00932 (OCC_MULT_REAL_OCCUR); }
00933 BOOL Fake_store(void) const { return Is_flag_set
00934 (OCC_FAKE_STORE_OCCUR); }
00935 BOOL Encl_stmt_set(void) const{ return Is_flag_set
00936 (OCC_ENCL_STMT_SET); }
00937 BOOL For_spre(void) const { return Is_flag_set
00938 (OCC_FOR_SPRE); }
00939 BOOL Rehash_changed_expr(void) const { return Is_flag_set
00940 (OCC_REHASH_CHANGED); }
00941
00942 BOOL Delete_comp(void) const
00943 {
00944 Is_True(Occ_kind() == OCC_REAL_OCCUR, ("Bad occurrence kind"));
00945 return Is_flag_set(OCC_DELETE_COMP);
00946 }
00947
00948 BOOL Save_to_temp(void) const
00949 {
00950 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00951 Occ_kind() == OCC_PHI_PRED_OCCUR, ("Bad occurrence kind"));
00952 return Is_flag_set(OCC_SAVE_TO_TEMP);
00953 }
00954
00955 BOOL Inserted_computation(void) const
00956 {
00957
00958
00959
00960 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR ||
00961 Occ_kind() == OCC_PHI_OCCUR ||
00962 Occ_kind() == OCC_REAL_OCCUR,
00963 ("EXP_OCCURS::Inserted_computation: Bad occurrence kind"));
00964
00965
00966 if (Occ_kind() == OCC_REAL_OCCUR) {
00967 return FALSE;
00968 }
00969 else {
00970 return Is_flag_set(OCC_INSERTED_OCCUR);
00971 }
00972 }
00973
00974 BOOL T_ver_owns_coderep(void) const
00975 {
00976 Is_True(Occ_kind() == OCC_PHI_OCCUR ||
00977 Occ_kind() == OCC_REAL_OCCUR,
00978 ("EXP_OCCURS::T_ver_owns_coderep: Bad occurrence kind"));
00979
00980 return Is_flag_set(OCC_CODEREP_OWNER);
00981 }
00982
00983 void Bid_for_coderep(const ETABLE *const,
00984 ID_MAP<REHASH_INFO *, INT32> &,
00985 const UINT32);
00986
00987 void Render_coderep_unownable(const ETABLE *const,
00988 ID_MAP<REHASH_INFO *, INT32> &);
00989
00990 BOOL Occurs_as_lvalue(void) const
00991 {
00992 return Is_flag_set(OCC_AS_L_VALUE);
00993 }
00994
00995 BOOL Sunk_lvalue(void) const
00996 {
00997 return Is_flag_set(OCC_SUNK_L_VALUE);
00998 }
00999
01000 void Set_required_pred(void)
01001 {
01002 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
01003 ("EXP_OCCURS::Set_required_pred: Only preds can be required"));
01004 Set_flag(OCC_REQUIRED_PRED);
01005 }
01006
01007 void Reset_required_pred(void)
01008 {
01009 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
01010 ("EXP_OCCURS::Set_required_pred: Only preds can be required"));
01011 Reset_flag(OCC_REQUIRED_PRED);
01012 }
01013
01014 BOOL Required_pred(void) const
01015 {
01016 Is_True(Occ_kind() == OCC_PHI_PRED_OCCUR,
01017 ("EXP_OCCURS::Required_pred: Only preds can be required"));
01018 return Is_flag_set(OCC_REQUIRED_PRED);
01019 }
01020
01021 BOOL Temp_eligible_as_owner(EXP_WORKLST *worklist) const;
01022
01023 BOOL Occurs_as_hoisted(void) const
01024 {
01025 return Is_flag_set(OCC_HOISTED);
01026 }
01027
01028
01029 CODEREP *Load_use_cr(ETABLE *etable, CODEREP *old_cr, CODEREP *cr);
01030
01031 BOOL Injured_occ(void) const
01032 {
01033
01034 return Is_flag_set(OCC_INJURED);
01035 }
01036
01037 BOOL Obsolete_comparison(void) const
01038 {
01039 Is_True(Occ_kind() == OCC_COMP_OCCUR,
01040 ("EXP_OCCURS::Obsolete_comparison: Bad occurrence kind"));
01041 return Is_flag_set(OCC_OBSOLETE_COMPARISON);
01042 }
01043
01044 void Set_obsolete_comparison(void)
01045 {
01046 Is_True(Occ_kind() == OCC_COMP_OCCUR,
01047 ("EXP_OCCURS::Set_obsolete_comparison: Bad occurrence kind"));
01048 Set_flag(OCC_OBSOLETE_COMPARISON);
01049 }
01050
01051
01052 BOOL Is_DT_descendant_of( EXP_OCCURS *anc );
01053
01054
01055
01056 BOOL Is_DPO_less_than(EXP_OCCURS *x);
01057
01058 BOOL Stmt_order_less_or_equal(EXP_OCCURS *x) const
01059 { return Stmt()->Stmt_order_less_or_equal(x->Stmt()); }
01060
01061 #if defined(TARG_SL) // PARA_EXTENSION
01062 RID* Rid(void) { return _rid; }
01063 void Set_Rid(RID* rid) { _rid = rid;}
01064 #endif
01065
01066 BB_NODE *Bb(void) const;
01067
01068 void Print(FILE *fp = stderr, BOOL show_phi_preds = TRUE) const;
01069
01070
01071 void Set_hoisted_occ(void)
01072 {
01073 Set_kind(OCC_REAL_OCCUR);
01074 Set_flag(OCC_HOISTED);
01075 }
01076
01077
01078 void Reset_hoisted(void) { Reset_flag(OCC_HOISTED); }
01079
01080 void Save_flags() { _saved_flags = _flag; }
01081 void Restore_flags() { _flag = _saved_flags; }
01082
01083
01084
01085 EXP_OCCURS *Occ_identical_to(void);
01086
01087 bool Will_b_deleted() { return Occ_kind() == OCC_REAL_OCCUR &&
01088 !Occurs_as_lvalue() &&
01089 Def_occur() != NULL &&
01090 (Def_occur()->Occ_kind() == OCC_REAL_OCCUR ||
01091 (Def_occur()->Occ_kind() == OCC_PHI_OCCUR &&
01092 Def_occur()->Exp_phi()->Will_b_avail())); }
01093 };
01094
01095 class EXP_OCCURS_CONTAINER : public SLIST {
01096 private:
01097 EXP_OCCURS_CONTAINER(const EXP_OCCURS_CONTAINER&);
01098 EXP_OCCURS_CONTAINER& operator = (const EXP_OCCURS_CONTAINER&);
01099
01100 DECLARE_SLIST_CLASS( EXP_OCCURS_CONTAINER, EXP_OCCURS )
01101 public:
01102 ~EXP_OCCURS_CONTAINER(void) { }
01103 void Init(void);
01104 void Print(FILE *fp = stderr);
01105
01106 void Set_Head(EXP_OCCURS *exp) { SLIST::Set_Head(exp); }
01107 void Set_Tail(EXP_OCCURS *exp) { SLIST::Set_Tail(exp); }
01108 };
01109
01110
01111 class EXP_OCCURS_ITER : public SLIST_ITER {
01112 DECLARE_SLIST_ITER_CLASS(EXP_OCCURS_ITER,
01113 EXP_OCCURS,
01114 EXP_OCCURS_CONTAINER )
01115 public:
01116 void Init(void) { }
01117 };
01118
01119 class EXP_PHI_OPND_USE_ITER {
01120 private:
01121 EXP_PHI *_phi;
01122 mINT32 _cur;
01123
01124 public:
01125 EXP_PHI_OPND_USE_ITER(void) { }
01126 EXP_PHI_OPND_USE_ITER(EXP_PHI *const phi) { Init(phi); }
01127
01128 void Init(void) { _cur = 0; }
01129 void Init(EXP_PHI *const phi) { _cur = 0; _phi = phi; }
01130 void Init(EXP_PHI_OPND_USE_ITER *const iter)
01131 { Init(iter->_phi); }
01132
01133 BOOL Is_Empty(void) const { return _cur >= _phi->Opnd_count(); }
01134
01135 EXP_PHI_OPND_USE_ITER *First(void)
01136 {
01137 _cur = 0;
01138 while (!Is_Empty() &&
01139 (_phi->Opnd(_cur) == NULL ||
01140 _phi->Has_real_occ(_cur))) {
01141 ++_cur;
01142 }
01143 return this;
01144 }
01145
01146 EXP_PHI_OPND_USE_ITER *Next(void)
01147 {
01148 ++_cur;
01149 while (!Is_Empty() &&
01150 (_phi->Opnd(_cur) == NULL ||
01151 _phi->Has_real_occ(_cur))) {
01152 ++_cur;
01153 }
01154 return this;
01155 }
01156
01157 EXP_PHI *Node(void) const
01158 {
01159 Is_True(_phi->Opnd(_cur) != NULL,
01160 ("EXP_PHI_OPND_USE_ITER::Node: current operand "
01161 "must not be NULL"));
01162 return _phi->Opnd(_cur)->Exp_phi();
01163 }
01164
01165
01166 INT Opnd_idx(void) const { return 0; }
01167 };
01168
01169
01170
01171
01172 class EXP_PHI_OCC_ITER {
01173 private:
01174 EXP_OCCURS_ITER _occ_iter;
01175
01176 public:
01177 EXP_PHI_OCC_ITER(void) { };
01178 EXP_PHI_OCC_ITER(EXP_OCCURS_CONTAINER &occs) :
01179 _occ_iter(occs.Head())
01180 { }
01181
01182 void Init(void) { };
01183 void Init(EXP_OCCURS_CONTAINER &occs) { _occ_iter.Init(occs.Head()); }
01184
01185 EXP_PHI *First(void)
01186 {
01187 EXP_OCCURS *phi_occ = _occ_iter.First();
01188 return (phi_occ != NULL ? phi_occ->Exp_phi() : NULL);
01189 }
01190
01191 EXP_PHI *Next(void)
01192 {
01193 EXP_OCCURS *phi_occ = _occ_iter.Next();
01194 return (phi_occ != NULL ? phi_occ->Exp_phi() : NULL);
01195 }
01196
01197 BOOL Is_Empty(void) { return _occ_iter.Is_Empty(); }
01198 };
01199
01200 class EXP_OCCURS_PAIR {
01201 private:
01202 EXP_OCCURS *_occ[2];
01203
01204 EXP_OCCURS_PAIR(const EXP_OCCURS_PAIR&);
01205 EXP_OCCURS_PAIR& operator = (const EXP_OCCURS_PAIR&);
01206 public:
01207 EXP_OCCURS_PAIR(void) { Clear(); }
01208
01209 ~EXP_OCCURS_PAIR(void) {}
01210
01211 void Clear(void) { _occ[0] = NULL;
01212 _occ[1] = NULL; }
01213 void Set_occ(INT i, EXP_OCCURS *occ) { _occ[i] = occ; }
01214 EXP_OCCURS *Occ1(void) const { return _occ[0]; }
01215 EXP_OCCURS *Occ2(void) const { return _occ[1]; }
01216 BOOL Is_Empty(void) const { return _occ[0] == NULL
01217 && _occ[1] == NULL; }
01218 };
01219
01220
01221
01222
01223 class OCC_ITER_LIST : public SLIST_NODE {
01224 private:
01225 union {
01226 EXP_OCCURS_ITER *_occ_iter;
01227 EXP_ALL_REAL_ITER *_all_real_iter;
01228 } _node;
01229 BOOL _is_occ_iter;
01230
01231 BOOL Is_occ_iter(void) const { return _is_occ_iter; }
01232
01233 EXP_OCCURS_ITER *Occ_iter(void) const
01234 { Is_True(_is_occ_iter,
01235 ("OCC_ITER_LIST::Occ_iter, _is_occ_iter incorrect"));
01236 return _node._occ_iter;
01237 }
01238
01239 EXP_ALL_REAL_ITER *All_real_iter(void) const
01240 { Is_True(!_is_occ_iter,
01241 ("OCC_ITER_LIST::All_real_iter, _is_occ_iter incorrect"));
01242 return _node._all_real_iter;
01243 }
01244
01245 OCC_ITER_LIST(const OCC_ITER_LIST&);
01246 OCC_ITER_LIST& operator = (const OCC_ITER_LIST&);
01247 public:
01248 OCC_ITER_LIST(void) { }
01249 OCC_ITER_LIST(EXP_OCCURS_ITER *occ_iter)
01250 { _node._occ_iter = occ_iter;
01251 _is_occ_iter = TRUE;
01252 }
01253 OCC_ITER_LIST(EXP_ALL_REAL_ITER *all_real_iter)
01254 { _node._all_real_iter = all_real_iter;
01255 _is_occ_iter = FALSE;
01256 }
01257 ~OCC_ITER_LIST(void) { }
01258
01259 DECLARE_SLIST_NODE_CLASS( OCC_ITER_LIST )
01260
01261
01262 EXP_OCCURS *Get_cur(void) const;
01263
01264 EXP_OCCURS *Next_occ(void) const;
01265
01266 };
01267
01268
01269 class OCC_CONTAINER : public SLIST {
01270 private:
01271 OCC_CONTAINER(const OCC_CONTAINER&);
01272 OCC_CONTAINER& operator = (const OCC_CONTAINER&);
01273
01274 DECLARE_SLIST_CLASS( OCC_CONTAINER, OCC_ITER_LIST )
01275 public:
01276 ~OCC_CONTAINER(void) { }
01277
01278 void Insert_sort(OCC_ITER_LIST *l);
01279 };
01280
01281
01282 class OCC_ITER_LIST_ITER : public SLIST_ITER {
01283 DECLARE_SLIST_ITER_CLASS(OCC_ITER_LIST_ITER,
01284 OCC_ITER_LIST,
01285 OCC_CONTAINER )
01286 public:
01287 void Init(void) { }
01288 };
01289
01290
01291
01292
01293
01294
01295 class EXP_ALL_REAL_ITER {
01296 private:
01297
01298 EXP_OCCURS_ITER _real;
01299 EXP_OCCURS_ITER _comp1;
01300 EXP_OCCURS_ITER _comp2;
01301
01302
01303 OCC_ITER_LIST _real_iter;
01304 OCC_ITER_LIST _comp1_iter;
01305 OCC_ITER_LIST _comp2_iter;
01306
01307
01308 OCC_CONTAINER _all_iter;
01309
01310
01311 EXP_ALL_REAL_ITER(void);
01312 EXP_ALL_REAL_ITER(const EXP_ALL_REAL_ITER&);
01313 EXP_ALL_REAL_ITER& operator=(const EXP_ALL_REAL_ITER&);
01314
01315 EXP_OCCURS *Get_cur(void) const;
01316
01317 public:
01318 EXP_ALL_REAL_ITER(EXP_OCCURS *, EXP_OCCURS_PAIR *);
01319 ~EXP_ALL_REAL_ITER(void) { }
01320
01321 void Init(void) { }
01322
01323 EXP_OCCURS *First(void);
01324 EXP_OCCURS *Next(void);
01325 EXP_OCCURS *Cur(void) { return Get_cur(); }
01326 BOOL Is_Empty(void) const;
01327 };
01328
01329
01330
01331
01332
01333
01334
01335 class EXP_ALL_OCCURS_ITER {
01336 private:
01337
01338 EXP_ALL_REAL_ITER _real;
01339 EXP_OCCURS_ITER _phi;
01340 EXP_OCCURS_ITER _phi_pred;
01341 EXP_OCCURS_ITER _exit;
01342
01343
01344 OCC_ITER_LIST _real_iter;
01345 OCC_ITER_LIST _phi_iter;
01346 OCC_ITER_LIST _pred_iter;
01347 OCC_ITER_LIST _exit_iter;
01348
01349
01350 OCC_CONTAINER _all_iter;
01351
01352
01353 EXP_OCCURS **_fast_array;
01354
01355 EXP_ALL_OCCURS_ITER(void);
01356 EXP_ALL_OCCURS_ITER(const EXP_ALL_OCCURS_ITER&);
01357 EXP_ALL_OCCURS_ITER& operator = (const EXP_ALL_OCCURS_ITER&);
01358
01359 EXP_OCCURS *Get_cur(void) const;
01360
01361 public:
01362
01363 EXP_ALL_OCCURS_ITER(EXP_OCCURS *real, EXP_OCCURS_PAIR *comp,
01364 EXP_OCCURS *phi, EXP_OCCURS *phi_pred,
01365 EXP_OCCURS *exit);
01366
01367 EXP_ALL_OCCURS_ITER(EXP_WORKLST *worklst, ETABLE *etable, LFTR *lftr);
01368 ~EXP_ALL_OCCURS_ITER(void) { }
01369
01370 void Init(void) { }
01371 EXP_OCCURS *First(void);
01372 EXP_OCCURS *Next(void);
01373 BOOL Is_Empty(void) const;
01374 void Remove_iter(void);
01375 };
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 class EXP_WORKLST : public SLIST_NODE {
01400 DECLARE_SLIST_NODE_CLASS( EXP_WORKLST )
01401 public:
01402 enum EXP_WORKLST_FLAG {
01403 EWF_NONE = 0x00,
01404 EWF_SIGN_EXTD = 0x01,
01405 EWF_EXCLUDE_SR_CAND = 0x02,
01406 EWF_IS_PROCESSED = 0x04,
01407
01408 EWF_IS_URGENT = 0x08,
01409 EWF_PHI_PREDS_PRUNED = 0x10,
01410
01411 EWF_HAS_CONST = 0x20,
01412 EWF_HAS_RCONST = 0x40,
01413 EWF_HAS_LDA = 0x80,
01414 EWF_LR_SHRINK_CAND = 0x100,
01415 EWF_IVC_CAND = 0x200,
01416 EWF_NO_LFTR = 0x400,
01417
01418 EWF_SIZE_DIFFERENT = 0x800
01419 };
01420
01421 enum EXP_PREG_VALUE {
01422 ILLEGAL_PREG = 0,
01423 };
01424
01425 private:
01426 EXP_ID _e_num;
01427 CODEREP *_exp;
01428 IDTYPE _preg;
01429
01430 UINT32 _flags:30;
01431 UINT32 _pre_kind:2;
01432
01433 EXP_OCCURS_CONTAINER _real_occurs;
01434 EXP_OCCURS_CONTAINER _phi_occurs;
01435 EXP_OCCURS_CONTAINER _phi_pred_occurs;
01436 EXP_OCCURS_PAIR _comp_occurs;
01437 IDTYPE _temp_id;
01438 INT _cur_e_version;
01439
01440 EXP_ALL_OCCURS_ITER *_iterator;
01441 union {
01442 BB_NODE_SET *_iphi_bbs;
01443 STACK<EXP_OCCURS*> *_spre_stack;
01444 } _u1;
01445 INT _phi_cnt;
01446 INT _realocc_cnt;
01447 INT _ssa_edge_cnt;
01448 INT _optimistic_ssa_cnt;
01449 INT _dense_ssa_cnt;
01450 INT _insert_cnt;
01451 INT _save_cnt;
01452 INT _reload_cnt;
01453 INT _temp_phi_cnt;
01454 INT _hoisted_cnt;
01455 INT _temp_owner_cnt;
01456
01457 EXP_WORKLST(void);
01458 EXP_WORKLST(const EXP_WORKLST&);
01459 EXP_WORKLST& operator = (const EXP_WORKLST&);
01460
01461
01462 BOOL Verify_dpo_order(EXP_OCCURS_CONTAINER &worklist,
01463 EXP_OCCURS *occ);
01464 BOOL Verify_dpo_order(EXP_OCCURS_CONTAINER &worklist);
01465
01466 void Compute_du_info(MEM_POOL *);
01467 void Compute_user_avail(BOOL);
01468 void Compute_avail(BOOL);
01469 void Compute_stops(BOOL);
01470 void Compute_partial_avail(BOOL);
01471
01472 void Insert_one_operand(ETABLE *,
01473 CODEMAP *,
01474 EXP_PHI *,
01475 INT);
01476 BOOL Determine_inserts_saves_deletions(CODEMAP *,
01477 ETABLE *,
01478 E_VER_TAB *,
01479 EXP_OCCURS_PAIR *);
01480 void SPRE_Determine_inserts_saves_deletions(CODEMAP *,
01481 ETABLE *,
01482 E_VER_TAB *);
01483 #if Is_True_On
01484 void Verify_saved_occurs(E_VER_TAB *);
01485 #endif
01486
01487
01488 void Generate_variable_phi_list(INT, BB_NODE_SET&, BOOL, ETABLE*);
01489
01490 void Generate_ivariable_phi_list_addr(BB_NODE_SET&, BOOL, ETABLE*);
01491 void Generate_ivariable_phi_list_vsym(BB_NODE_SET&, BOOL);
01492
01493 public:
01494 EXP_WORKLST(EXP_ID e_num, CODEREP *exp, PRE_KIND pre_kind)
01495 { _pre_kind = pre_kind; Init (e_num, exp); Exam_const(); }
01496
01497 ~EXP_WORKLST(void) { }
01498
01499
01500 EXP_OCCURS_CONTAINER&
01501 Real_occurs(void) { return _real_occurs; }
01502 EXP_OCCURS_CONTAINER&
01503 Phi_occurs(void) { return _phi_occurs; }
01504 EXP_OCCURS_CONTAINER&
01505 Phi_pred_occurs(void) { return _phi_pred_occurs; }
01506 EXP_OCCURS_PAIR&
01507 Comp_occurs(void) { return _comp_occurs; }
01508
01509 PRE_KIND Pre_kind(void) const { return (PRE_KIND)_pre_kind; }
01510 EXP_ID E_num(void) const { return _e_num; }
01511 void Set_e_num(EXP_ID n) { _e_num = n; }
01512 CODEREP *Exp(void) const { return _exp; }
01513 IDTYPE Preg(void) const { return _preg; }
01514 void Set_preg(IDTYPE s) { _preg = s; }
01515 STACK<EXP_OCCURS*>
01516 *Spre_stack(void) const { Is_True(_pre_kind == PK_SPRE,
01517 ("Spre_stack must be SPRE"));
01518 return _u1._spre_stack;}
01519 void Set_spre_stack
01520 (STACK<EXP_OCCURS*> *s){ Is_True(_pre_kind == PK_SPRE,
01521 ("Set_spre_stack must be SPRE"));
01522 _u1._spre_stack = s;}
01523 BB_NODE_SET *Iphi_bbs(void) const { Is_True(_pre_kind == PK_SPRE,
01524 ("Iphi_bbs must be SPRE"));
01525 return _u1._iphi_bbs;}
01526 void Set_iphi_bbs(BB_NODE_SET *s) { Is_True(_pre_kind == PK_SPRE,
01527 ("Set_iphi_bbs must be SPRE"));
01528 _u1._iphi_bbs = s;}
01529 IDTYPE Temp_id(void) const { Is_True(_pre_kind == PK_SPRE,
01530 ("temp_id must be SPRE"));
01531 return _temp_id; }
01532 void Set_temp_id(IDTYPE s) { Is_True(_pre_kind == PK_SPRE,
01533 ("Set_temp_id must be SPRE"));
01534 _temp_id = s; }
01535 INT Insert_count(void) const { return _insert_cnt; }
01536 void Inc_insert_count(void) { _insert_cnt++; }
01537 INT Save_count(void) const { return _save_cnt; }
01538 void Inc_save_count(void) { _save_cnt++; }
01539 INT Reload_count(void) const { return _reload_cnt; }
01540 void Inc_reload_count(void) { _reload_cnt++; }
01541 INT Temp_phi_count(void) const { return _temp_phi_cnt; }
01542 void Inc_temp_phi_count(void) { _temp_phi_cnt++; }
01543 INT Hoisted_count(void) const { return _hoisted_cnt; }
01544 void Inc_hoisted_count(void) { _hoisted_cnt++; }
01545 INT Temp_owner_count(void) const { return _temp_owner_cnt; }
01546 void Inc_temp_owner_count(void) { _temp_owner_cnt++; }
01547
01548 void Reset_statistics(void) { _phi_cnt = 0;
01549 _realocc_cnt = 0;
01550 _ssa_edge_cnt = 0;
01551 _optimistic_ssa_cnt = 0;
01552 _dense_ssa_cnt = 0;
01553 _insert_cnt = 0;
01554 _save_cnt = 0;
01555 _reload_cnt = 0;
01556 _temp_phi_cnt = 0;
01557 _hoisted_cnt = 0;
01558 _temp_owner_cnt = 0;
01559 }
01560 INT Phi_count(void) const { return _phi_cnt; }
01561 INT Realocc_count(void) const { return _realocc_cnt; }
01562 INT Ssa_edge_count(void) const { return _ssa_edge_cnt; }
01563 INT Optimistic_ssa_count(void) const { return _optimistic_ssa_cnt; }
01564 INT Dense_ssa_count(void) const { return _dense_ssa_cnt; }
01565 void Inc_phi_count(void) { _phi_cnt++; }
01566 void Inc_realocc_count(void) { _realocc_cnt++; }
01567 void Inc_ssa_edge_count(void) { _ssa_edge_cnt++; }
01568 void Inc_optimistic_ssa_count(INT n) { _optimistic_ssa_cnt += n; }
01569 void Inc_dense_ssa_count(void) { _dense_ssa_cnt++; }
01570
01571
01572
01573
01574 INT Cur_e_version(void) const { return _cur_e_version; }
01575 void New_e_version(void) { ++_cur_e_version; }
01576 void Init_e_version(void) { _cur_e_version =
01577 EXP_OCCURS::ILLEGAL_E_VERSION + 1;}
01578
01579
01580 void Set_iterator(EXP_ALL_OCCURS_ITER *iter) { _iterator = iter; }
01581 EXP_ALL_OCCURS_ITER *Iterator(void) { return _iterator; }
01582
01583 void Init(EXP_ID e_num, CODEREP *exp);
01584 void Exam_const(void);
01585
01586 void Adjust_combined_types(CODEREP *cr);
01587 void Set_sign_extd( void ) { _flags |= EWF_SIGN_EXTD; }
01588 void Reset_sign_extd( void ) { _flags &= ~EWF_SIGN_EXTD; }
01589 BOOL Sign_extd( void ) { return _flags & EWF_SIGN_EXTD; }
01590
01591
01592
01593
01594 void Clear_flags(void) { _flags = EWF_NONE; }
01595
01596 BOOL Exclude_sr_cand(void)const{ return (Pre_kind()==PK_EPRE) &&
01597 (_flags & EWF_EXCLUDE_SR_CAND);}
01598 void Set_exclude_sr_cand( void){ _flags |= EWF_EXCLUDE_SR_CAND; }
01599 void Reset_exclude_sr_cand(void){ _flags &= ~EWF_EXCLUDE_SR_CAND;}
01600
01601
01602 BOOL Is_processed(void)const { return _flags&EWF_IS_PROCESSED;}
01603 void Set_is_processed( void ) { _flags |= EWF_IS_PROCESSED; }
01604 void Reset_is_processed( void ){ _flags &= ~EWF_IS_PROCESSED; }
01605
01606
01607 BOOL Is_urgent(void)const { return _flags & EWF_IS_URGENT;}
01608 void Set_is_urgent( void ) { _flags |= EWF_IS_URGENT; }
01609 void Reset_is_urgent( void ) { _flags &=
01610 ~EWF_IS_URGENT; }
01611
01612 BOOL Has_const(void)const { return _flags & EWF_HAS_CONST;}
01613 void Set_has_const( void ) { _flags |= EWF_HAS_CONST; }
01614 void Reset_has_const( void ) { _flags &=
01615 ~EWF_HAS_CONST; }
01616
01617
01618 BOOL Has_rconst(void)const { return _flags & EWF_HAS_RCONST;}
01619 void Set_has_rconst( void ) { _flags |= EWF_HAS_RCONST; }
01620 void Reset_has_rconst( void ) { _flags &=
01621 ~EWF_HAS_RCONST; }
01622
01623
01624 BOOL Has_lda(void)const { return _flags & EWF_HAS_LDA;}
01625 void Set_has_lda( void ) { _flags |= EWF_HAS_LDA; }
01626 void Reset_has_lda( void ) { _flags &= ~EWF_HAS_LDA; }
01627
01628
01629 BOOL LR_shrink_cand(void) const { return _flags & EWF_LR_SHRINK_CAND;}
01630 void Set_LR_shrink_cand( void ) { _flags |= EWF_LR_SHRINK_CAND; }
01631
01632
01633 BOOL Has_unequal_sizes(void) const {
01634 return _flags & EWF_SIZE_DIFFERENT;}
01635 void Set_has_unequal_sizes(void) {
01636 _flags |= EWF_SIZE_DIFFERENT; }
01637
01638
01639 BOOL Ivc_cand(void) const { return _flags & EWF_IVC_CAND;}
01640 void Set_ivc_cand( void ) { _flags |= EWF_IVC_CAND; }
01641 void Reset_ivc_cand( void ) { _flags &= ~EWF_IVC_CAND; }
01642
01643
01644
01645
01646 BOOL No_lftr(void) const { return _flags & EWF_NO_LFTR; }
01647 void Set_no_lftr(void) { _flags |= EWF_NO_LFTR; }
01648 void Reset_no_lftr(void) { _flags &= EWF_NO_LFTR; }
01649
01650 BOOL Weight_less_than(EXP_WORKLST*);
01651
01652
01653
01654 BOOL Phi_preds_pruned(void) const
01655 { return _flags & EWF_PHI_PREDS_PRUNED; }
01656 void Set_phi_preds_pruned(void)
01657 { _flags |= EWF_PHI_PREDS_PRUNED; }
01658
01659
01660 void Remove_occurs(ETABLE *etable);
01661
01662
01663
01664 void Append_occurrence(EXP_OCCURS *occ);
01665
01666
01667
01668
01669 void Insert_occurrence(EXP_OCCURS *occ, ETABLE *etable);
01670
01671
01672
01673
01674
01675 void Insert_occurrence(EXP_OCCURS *, BB_NODE *);
01676
01677
01678 BOOL Remove_real_occurrence(STMTREP *stmt);
01679
01680
01681 BOOL Is_the_same_as(const CODEREP *cr);
01682
01683
01684 EXP_OCCURS *Lookup_phi_occ(const BB_NODE *bb);
01685
01686
01687 CODEREP *Save_use_cr(const ETABLE *etable, CODEREP *old_cr);
01688
01689
01690
01691 void Exclude_strength_reduction_cands(ETABLE *etable);
01692
01693 void Remove_if_saved_to_preg(ETABLE *etable);
01694
01695
01696 BOOL Insert_exp_phi(ETABLE *etable);
01697
01698
01699 void Rename_expression(ETABLE *etable);
01700
01701
01702 void Rename_valnums(ETABLE *etable);
01703
01704
01705 BOOL Propagate_downsafe(ETABLE *etable);
01706
01707
01708 void Determine_live_phi(ETABLE *etable);
01709
01710
01711 void Compute_forward_attributes(ETABLE *etable, BOOL compute_partial_avail = FALSE);
01712
01713
01714 void Compute_fully_avail(ETABLE *etable);
01715 void Compute_fully_avail_stops(ETABLE *etable, BOOL &found_redundancy);
01716
01717
01718
01719 void Prune_phi_phi_pred(ETABLE *);
01720
01721
01722 BOOL Compute_save_delete(CODEMAP *htable, ETABLE *etable,
01723 EXP_OCCURS_PAIR *comp_occurs);
01724
01725 void Hoist_expression(EXP_HOISTING *);
01726
01727
01728 void Minimize_temp_ssa(const ETABLE *, BOOL);
01729
01730
01731 void Generate_save_reload(ETABLE *etable);
01732
01733 void Verify(void);
01734
01735 void Print(FILE *fp = stderr, EXP_OCCURS_PAIR *comp_occurs=NULL);
01736
01737
01738 void SPRE_append_occurrence(EXP_OCCURS *occ) {
01739 occ->Set_for_spre();
01740 Append_occurrence(occ); }
01741 void SPRE_create_iphi_succ(ETABLE *etable);
01742 void SPRE_determine_live_phi(ETABLE *etable);
01743 void SPRE_compute_backward_attributes(ETABLE *etable);
01744 void SPRE_compute_insert_delete(CODEMAP *htable, ETABLE *etable);
01745 void SPRE_perform_insert_delete(ETABLE *etable);
01746 void Estimate_cost(ETABLE *, PRE_KIND);
01747 void Save_flags();
01748 };
01749
01750
01751 class EXP_WORKLST_CONTAINER : public SLIST {
01752 DECLARE_SLIST_CLASS( EXP_WORKLST_CONTAINER, EXP_WORKLST )
01753 private:
01754 EXP_WORKLST_CONTAINER(const EXP_WORKLST_CONTAINER&);
01755 EXP_WORKLST_CONTAINER& operator=(const EXP_WORKLST_CONTAINER&);
01756
01757 public:
01758 ~EXP_WORKLST_CONTAINER(void){};
01759 void Init(EXP_WORKLST *w) { SLIST::Set_Head(w); }
01760 void Clear(void) { SLIST::Clear(); }
01761 void Insert_sorted(EXP_WORKLST*);
01762 };
01763
01764 class EXP_WORKLST_ITER : public SLIST_ITER {
01765 DECLARE_SLIST_ITER_CLASS(EXP_WORKLST_ITER,
01766 EXP_WORKLST,
01767 EXP_WORKLST_CONTAINER )
01768 public:
01769 void Init(void) { }
01770 };
01771
01772
01773
01774
01775
01776
01777
01778 class EXP_WORKLST_NODE : public SLIST_NODE {
01779 private:
01780 EXP_WORKLST *node;
01781
01782 EXP_WORKLST_NODE(const EXP_WORKLST_NODE&);
01783 EXP_WORKLST_NODE& operator = (const EXP_WORKLST_NODE&);
01784 public:
01785 EXP_WORKLST_NODE(void) {}
01786 EXP_WORKLST_NODE
01787 (EXP_WORKLST *nd) { node = nd; }
01788 ~EXP_WORKLST_NODE(void) {}
01789
01790 DECLARE_SLIST_NODE_CLASS( EXP_WORKLST_NODE )
01791
01792 void Init(EXP_WORKLST *nd) { node = nd; }
01793 BOOL Contains(EXP_WORKLST *);
01794
01795
01796 EXP_WORKLST *Node(void) const { return node; }
01797 };
01798
01799
01800 #define EXP_WORKLST_NODE_CONTAINER EXP_WORKLST_NODE_CONT
01801 class EXP_WORKLST_NODE_CONT : public SLIST {
01802 private:
01803 EXP_WORKLST_NODE_CONT(const EXP_WORKLST_NODE_CONT&);
01804 EXP_WORKLST_NODE_CONT& operator =
01805 (const EXP_WORKLST_NODE_CONT&);
01806
01807 DECLARE_SLIST_CLASS( EXP_WORKLST_NODE_CONT, EXP_WORKLST_NODE )
01808 public:
01809 ~EXP_WORKLST_NODE_CONT(void){};
01810 void Init(EXP_WORKLST_NODE *w){ SLIST::Set_Head(w); }
01811 void Clear(void) { SLIST::Clear(); }
01812 EXP_WORKLST_NODE *Find_exp_worklst(const CODEREP *cr);
01813 void Append (EXP_WORKLST_NODE *worklst,
01814 IDX_32 idx,
01815 ETABLE *etable);
01816 };
01817
01818 class EXP_WORKLST_NODE_ITER : public SLIST_ITER {
01819 DECLARE_SLIST_ITER_CLASS( EXP_WORKLST_NODE_ITER, EXP_WORKLST_NODE, EXP_WORKLST_NODE_CONT )
01820 public:
01821 void Init(void) { }
01822 };
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832 class EXP_WORKLST_ITER2 {
01833 private:
01834 EXP_WORKLST_CONTAINER *_exp_worklst;
01835 EXP_WORKLST_CONTAINER *_urgent_worklst;
01836 EXP_WORKLST *_cur;
01837
01838 void Set_cur(EXP_WORKLST *c) { _cur = c; }
01839
01840 public:
01841 EXP_WORKLST_ITER2(EXP_WORKLST_CONTAINER
01842 *exp_worklst,
01843 EXP_WORKLST_CONTAINER
01844 *urgent_worklst) { _exp_worklst = exp_worklst;
01845 _urgent_worklst = urgent_worklst;
01846 _cur = NULL;
01847 }
01848 void Init(void) { }
01849
01850 EXP_WORKLST *Cur(void) { return _cur; }
01851 EXP_WORKLST *First(void);
01852 EXP_WORKLST *Next(void);
01853 BOOL Is_Empty(void) { return _cur == NULL; }
01854 };
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884 class ETABLE {
01885
01886 friend class EXP_WORKLST;
01887
01888 private:
01889 CFG *_cfg;
01890 OPT_STAB *_opt_stab;
01891 CODEMAP *_htable;
01892 SSU *_ssu;
01893 ALIAS_RULE *_arule;
01894 STR_RED *_str_red;
01895 LFTR *_lftr;
01896 MEM_POOL *_etable_pool;
01897 MEM_POOL *_per_expr_pool;
01898 MEM_POOL *_etable_local_pool;
01899 EXP_ID _cur_e_num;
01900 EXP_OCCURS_CONTAINER _exit_occurs;
01901 EXP_OCCURS **_dpo_exp_phi;
01902 CODEREP **_phi_pred_cr;
01903 BB_NODE_SET _phi_work_set;
01904 BB_NODE_SET _var_phi_set;
01905 ARRAY<EXP_WORKLST_NODE*>_exp_hash;
01906
01907 EXP_WORKLST_CONTAINER _exp_worklst;
01908 EXP_WORKLST_CONTAINER _urgent_worklst;
01909
01910 STACK<EXP_OCCURS*> _occ_freelist;
01911 STACK<EXP_OCCURS*> _deferred_ocopy_occurs;
01912 STACK<STMTREP*> _deferred_cfold_stmts;
01913 EXP_OCCURS _nil_exp_phi_opnd;
01914 PRE_KIND _pre_kind;
01915 BOOL _tracing;
01916 BOOL _lpre_do_consts;
01917 BOOL _lpre_do_loads;
01918 INT32 _num_cse_reloads;
01919 INT32 _num_cse_saves;
01920 INT32 _num_inserted_saves;
01921 INT32 _num_temp_phis;
01922 INT32 _num_hoisted;
01923 INT32 _num_temp_owners;
01924 COMP_UNIT *_comp_unit;
01925 EXP_HOISTING *_exp_hoisting;
01926
01927 STMTREP *_entry_chi;
01928
01929
01930
01931 REHASH_CACHE_LIST *_rehash_cache;
01932
01933
01934 ETABLE(void);
01935 ETABLE(const ETABLE&);
01936 ETABLE& operator = (const ETABLE&);
01937
01938
01939 EXP_WORKLST_CONTAINER *Urgent_worklst(void) { return &_urgent_worklst; }
01940
01941 STACK<EXP_OCCURS*> *Occ_freelist(void) { return &_occ_freelist; }
01942 EXP_ID Alloc_e_num(void) { return ++_cur_e_num; }
01943
01944 void Clear_dpo_exp_phi(void);
01945 void Clear_dpo_exp_phi(EXP_OCCURS_CONTAINER &worklist);
01946 EXP_OCCURS *Set_exp_phi_bb(const BB_NODE *bb, EXP_OCCURS *exp_phi);
01947 EXP_OCCURS *Get_exp_phi_bb(const BB_NODE *bb);
01948
01949 BB_NODE_SET &Phi_work_set(void) { return _phi_work_set; }
01950 BB_NODE_SET &Var_phi_set(void) { return _var_phi_set; }
01951
01952
01953 void Per_worklst_cleanup(EXP_WORKLST *exp_worklst) const;
01954
01955
01956 void Init_worklst( void );
01957
01958 EXP_OCCURS *Alloc_occurs_node(void);
01959
01960
01961 IDX_32 Exp_hashvalue(const CODEREP *cr);
01962 IDX_32 Hash_exp(const CODEREP *cr);
01963 EXP_WORKLST_NODE*Exp_hash_bucket(IDX_32 idx) const
01964 { return _exp_hash[idx]; }
01965
01966
01967 void New_temp_id(void) { Htable()->New_temp_id(); }
01968 INT32 Cur_temp_id(void) const { return Htable()->Cur_temp_id(); }
01969
01970
01971 void Clear_rehash_cache(void) { _rehash_cache = NULL; }
01972 void Add_rehash_expr(CODEREP *cr, CODEREP *rehash_cr);
01973 CODEREP *Lookup_rehash_expr(CODEREP *);
01974
01975
01976
01977 CODEREP *Recursive_rehash_and_replace(
01978 CODEREP *x,
01979 EXP_OCCURS *occur,
01980 OCCUR_REPLACEMENT *repl,
01981 const BOOL replacing_istr_base,
01982 UINT depth,
01983 OPCODE opc);
01984 CODEREP *Rehash_and_replace(CODEREP *x,
01985 EXP_OCCURS *occur,
01986 OCCUR_REPLACEMENT *repl,
01987 const BOOL replacing_istr_base,
01988 OPCODE parent_opc);
01989 void Replace_occurs(EXP_OCCURS *occur, OCCUR_REPLACEMENT *repl);
01990
01991
01992 BOOL Remove_real_occurrence(EXP_WORKLST_CONTAINER *worklist,
01993 CODEREP *old_cr, STMTREP *stmt);
01994
01995 STMTREP *Entry_chi(void) const { return _entry_chi; }
01996 void Set_entry_chi(STMTREP *entry_chi) { _entry_chi = entry_chi; }
01997
01998 #ifdef KEY
01999 void Mark_phi_live(PHI_NODE *phi);
02000 #endif
02001 public:
02002 ETABLE(CFG *cfg,
02003 OPT_STAB *opt_stab,
02004 CODEMAP *htable,
02005 ALIAS_RULE *ar,
02006 IDX_32 exp_hash_size,
02007 MEM_POOL *etable_pool,
02008 MEM_POOL *per_expr_pool,
02009 MEM_POOL *etable_local_pool,
02010 COMP_UNIT *comp_unit,
02011 PRE_KIND pre_kind);
02012
02013 ~ETABLE(void);
02014
02015 enum {
02016 ILLEGAL_E_NUMBER = 0,
02017 };
02018
02019 enum URGENCY {
02020 NOT_URGENT = 0,
02021 URGENT_INSERT = 1,
02022 NOT_URGENT_INS= 2,
02023 };
02024
02025 CFG *Cfg(void) const { return _cfg; }
02026 OPT_STAB *Opt_stab(void) const { return _opt_stab; }
02027 CODEMAP *Htable(void) const { return _htable; }
02028 SSU *Ssu(void) const { return _ssu; }
02029 ALIAS_RULE *Arule(void) const { return _arule; }
02030 STR_RED *Str_red(void) const { return _str_red; }
02031 LFTR *Lftr(void) const { return _lftr; }
02032 MEM_POOL *Per_expr_pool(void) const{ return _per_expr_pool; }
02033 EXP_HOISTING *Exp_hoisting(void) const { return _exp_hoisting; }
02034 EXP_WORKLST_CONTAINER *Exp_worklst(void) { return &_exp_worklst; }
02035
02036 void Count_lex_ident_exprs(INT32);
02037
02038
02039 void Remove_real_occurrence(CODEREP *old_cr, STMTREP *stmt);
02040
02041
02042
02043
02044 EXP_OCCURS *Alloc_occurs_node(CODEREP *);
02045
02046
02047 MEM_POOL *Etable_pool(void) const { return _etable_pool; }
02048 MEM_POOL *Etable_local_pool(void) const
02049 { return _etable_local_pool; }
02050
02051
02052 EXP_WORKLST *Get_worklst(CODEREP *cr,
02053 BOOL urgent = FALSE,
02054 BOOL lookup_only = FALSE);
02055
02056
02057 CODEREP *New_temp_cr(MTYPE dtype, ADDRESSABILITY addressable,
02058 CODEREP *rhs);
02059
02060
02061 void Check_lftr_non_candidate(STMTREP *stmt, CODEREP *cr, OPCODE opc);
02062 void Bottom_up_stmt(STMTREP *stmt);
02063 void Bottom_up_cr(STMTREP *stmt,
02064 INT stmt_kid_num,
02065 CODEREP *cr,
02066 BOOL is_store,
02067 URGENCY urgent,
02068 UINT depth,
02069 OPCODE opc,
02070 BOOL no_estr);
02071
02072
02073 void LPRE_set_do_loads(BOOL truth) {_lpre_do_loads = truth;}
02074 void LPRE_set_do_consts(BOOL truth) {_lpre_do_consts = truth;}
02075
02076 BOOL LPRE_do_loads() const {return _lpre_do_loads;}
02077 BOOL LPRE_do_consts() const {return _lpre_do_consts;}
02078
02079 void LPRE_bottom_up_stmt(STMTREP *stmt);
02080 void LPRE_bottom_up_cr(STMTREP *stmt,
02081 INT stmt_kid_num,
02082 CODEREP *cr,
02083 BOOL is_store,
02084 UINT depth,
02085 CODEREP *parent,
02086 INT whichkid);
02087
02088
02089 STMTREP *Generate_stid_to_preg( CODEREP *lhs, CODEREP *rhs,
02090 MTYPE rhs_type, BB_NODE *bb, SRCPOS linenum ) const;
02091
02092 STMTREP *Save_replace_rhs_by_preg(STMTREP *stmt, CODEREP *pregcr,
02093 EXP_WORKLST *wk);
02094
02095 void Insert_stmtrep_after(STMTREP *new_stmt,
02096 STMTREP *old_stmt);
02097
02098 void Replace_by_temp(EXP_OCCURS *occur, CODEREP *tempcr);
02099 void Replace_by_const(EXP_OCCURS *occur, TCON tcon);
02100
02101
02102 CODEREP *Rehash_exp(CODEREP *cr, UINT32 gvn, BOOL canon=TRUE) const;
02103
02104 void No_replace(EXP_OCCURS *occur, BOOL dont_rehash);
02105
02106 void Find_1st_order_exprs_with_temp(STMTREP *stmt,
02107 INT stmt_kid_num,
02108 CODEREP *cr,
02109 CODEREP *tempcr,
02110 BOOL is_store,
02111 UINT depth);
02112
02113 void Find_new_1st_order_exprs(EXP_OCCURS *occur, CODEREP *tempcr);
02114
02115 CODEREP *Rehash_but_no_replace(CODEREP *x,
02116 EXP_OCCURS *occur,
02117 BOOL replacing_istr_base,
02118 INT32 orig_coderep_id);
02119
02120
02121 void Append_real_occurrence(CODEREP *cr,
02122 STMTREP *stmt,
02123 INT stmt_kid_num,
02124 UINT depth,
02125 BOOL is_istore = FALSE);
02126
02127
02128 void Insert_real_occurrence(CODEREP *cr,
02129 STMTREP *stmt,
02130 INT stmt_kid_num,
02131 UINT depth,
02132 BOOL is_istore = FALSE,
02133 BOOL urgent = FALSE);
02134
02135
02136 EXP_OCCURS *Append_phi_occurrence(CODEREP *cr, EXP_PHI *phi,
02137 EXP_WORKLST *worklist);
02138
02139
02140 EXP_OCCURS *Append_phi_pred_occurrence(CODEREP *cr, BB_NODE *bb,
02141 EXP_WORKLST *worklist);
02142
02143
02144 void Append_exit_occurrence(BB_NODE *bb);
02145
02146
02147 void Insert_phi_occurrence(EXP_PHI *phi);
02148
02149 EXP_OCCURS *Append_spre_real_occurrence(STMTREP *stmt,
02150 EXP_WORKLST *worklist);
02151 EXP_OCCURS *Append_iphi_succ_occurrence(BB_NODE *bb,
02152 EXP_WORKLST *worklist);
02153
02154 void Set_exp_hash_bucket(IDX_32 idx, EXP_WORKLST_NODE *etmp)
02155 { _exp_hash[idx] = etmp; }
02156
02157 EXP_PHI *Lookup_exp_phi(const BB_NODE *bb, const CODEREP *cr) const;
02158
02159
02160 PHI_NODE *Lookup_var_phi(const BB_NODE *bb, const AUX_ID id) const
02161 { return Htable()->Lookup_var_phi(bb,id); }
02162
02163
02164 void Set_phi_pred_cr(const BB_NODE *bb, CODEREP *cr) const
02165 { _phi_pred_cr[bb->Id()] = cr; }
02166 CODEREP *Phi_pred_cr(const BB_NODE *bb) const
02167 { return _phi_pred_cr[bb->Id()]; }
02168
02169
02170 CODEREP *Generate_cur_expr(const BB_NODE *, INT, CODEREP *, BOOL);
02171 CODEREP *Get_cached_cur_expr(const BB_NODE *, INT);
02172 void Update_cached_cur_expr(const BB_NODE *, INT, CODEREP *);
02173 CODEREP *Alloc_and_generate_cur_expr(const CODEREP *,
02174 const BB_NODE *,
02175 INT,
02176 MEM_POOL *,
02177 BOOL) ;
02178
02179 STACK<EXP_OCCURS *> *Deferred_ocopy_occurs(void)
02180 { return &_deferred_ocopy_occurs; }
02181 STACK<STMTREP *> *Deferred_cfold_stmts(void) { return &_deferred_cfold_stmts; }
02182
02183 void Schedule_for_ocopy(EXP_OCCURS *);
02184 void Perform_deferred_ocopy_and_get_new_exprs(EXP_WORKLST *);
02185 void Perform_deferred_cfold();
02186
02187 EXP_OCCURS_CONTAINER &Exit_occurs(void) { return _exit_occurs; }
02188 EXP_OCCURS *Nil_exp_phi_opnd(void) { return &_nil_exp_phi_opnd; }
02189
02190 PRE_KIND Pre_kind(void) const { return _pre_kind; }
02191
02192 BOOL Tracing(void) const { return _tracing; }
02193
02194 void Inc_cse_reloads(INT32 n) { _num_cse_reloads += n; }
02195 void Inc_cse_saves(INT32 n) { _num_cse_saves += n; }
02196 void Inc_inserted_saves(INT32 n) { _num_inserted_saves += n; }
02197 void Inc_temp_phis(INT32 n) { _num_temp_phis += n; }
02198 void Inc_hoisted(INT32 n) { _num_hoisted += n; }
02199 void Inc_temp_owners(INT32 n) { _num_temp_owners += n; }
02200
02201
02202 void Perform_PRE_optimization(void);
02203
02204
02205 void Perform_LPRE_optimization(void);
02206
02207
02208 void Perform_VNFRE_optimization(void);
02209
02210
02211 void Perform_SPRE_optimization(void);
02212 void SPRE_update_ssa(void);
02213 EXP_OCCURS *New_phi_occurrence(EXP_WORKLST *worklst,
02214 MEM_POOL *pool,
02215 BB_NODE *bb);
02216
02217 void Add_stmt(STMTREP *, BB_NODE *);
02218 void SPRE_rename(BB_NODE *);
02219 void SPRE_rename_stmt(STMTREP *, BB_NODE *);
02220 CODEREP *SPRE_rename_expr(CODEREP *, BB_NODE *);
02221 CODEREP *SPRE_rename_var(CODEREP *, BOOL);
02222
02223 BOOL Stmt_is_redundant(STMTREP *);
02224 BOOL RHS_is_fully_avail(CODEREP *, CODEREP *);
02225
02226 void Add_to_occ_freelist(EXP_OCCURS *node);
02227
02228
02229
02230
02231
02232 UINT32 Gvn(const CODEREP *cr) const
02233 {
02234 return (Pre_kind() == PK_VNFRE? VNFRE::get_valnum(cr) : 0U);
02235 }
02236
02237 void Init_vnfre_worklist(EXP_WORKLST *occurs,
02238 EXP_OCCURS_CONTAINER &exit_occurs)
02239 {
02240 Is_True(Pre_kind() == PK_VNFRE,
02241 ("Illegal call to ETABLE::Init_vnfre_worklist()"));
02242 Exit_occurs().Set_Head(exit_occurs.Head());
02243 Exit_occurs().Set_Tail(exit_occurs.Tail());
02244 Exp_worklst()->Init(occurs);
02245 }
02246
02247 void Reset_vnfre_worklist()
02248 {
02249 Is_True(Pre_kind() == PK_VNFRE,
02250 ("Illegal call to TABLE::Reset_vnfre_worklist()"));
02251 Exp_worklst()->Head()->Remove_occurs(this);
02252 Exp_worklst()->Clear();
02253 Exit_occurs().Set_Head(NULL);
02254 Exit_occurs().Set_Tail(NULL);
02255 }
02256
02257 EXP_OCCURS *Alloc_vnfre_occurs_node()
02258 {
02259
02260
02261
02262
02263 return Alloc_occurs_node();
02264 }
02265
02266 BB_NODE_SET &Reuse_phi_list()
02267 {
02268 Phi_work_set().ClearD();
02269 return Phi_work_set();
02270 }
02271
02272 void Set_phi_result(EXP_PHI *phi, EXP_OCCURS *occurs) const
02273 {
02274 phi->Set_result(occurs);
02275 }
02276
02277 void Set_dpo_phi_occurs(const BB_NODE *bb, EXP_OCCURS *phi_occ)
02278 {
02279 (void) Set_exp_phi_bb(bb, phi_occ);
02280 }
02281 };
02282
02283
02284 extern EXP_HOISTING *New_EXP_HOISTING(ETABLE *, MEM_POOL *);
02285 extern void Delete_EXP_HOISTING(EXP_HOISTING *);
02286 extern BOOL Subsumable_by_branch(CODEREP *cr);
02287
02288 #endif // opt_etable_INCLUDED