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 #define rbi_CXX "rbi.cxx"
00073 #ifdef _KEEP_RCS_ID
00074 static char *rcs_id = rbi_CXX"$Revision: 1.2 $";
00075 #endif
00076
00077 #include "opt_wn.h"
00078 #include "opt_base.h"
00079 #include "wn_util.h"
00080 #include "stab.h"
00081 #include "cxx_base.h"
00082 #include "cxx_memory.h"
00083 #include "region_util.h"
00084 #include "ir_reader.h"
00085 #include "tracing.h"
00086 #include "opt_du.h"
00087 #include "opt_points_to.h"
00088 #include "opt_alias_mgr.h"
00089 #include "rbi.h"
00090
00091
00092
00093
00094 #ifdef AFTER_MR
00095 #pragma weak Print__8USE_LISTGP8__file_s
00096 #pragma weak Print__8DEF_LISTGP8__file_s
00097 #pragma weak Id__13ALIAS_MANAGERCGPC2WN
00098 #endif
00099
00100 #if 0
00101 this whole file is out of date and needs to be upgraded
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 typedef enum {
00112 RBI_DEAD,
00113 RBI_LIVE,
00114 RBI_NUM_LIVENESS
00115 } RBI_LIVENESS_STATE;
00116
00117
00118 BOOL RBI_WN_Aliasable( const WN *const );
00119
00120
00121
00122
00123 class RBI_WN_REF : public SLIST_NODE {
00124 DECLARE_SLIST_NODE_CLASS(RBI_WN_REF);
00125 private:
00126 WN *const _wn;
00127 public:
00128 RBI_WN_REF(WN *const wn) : _wn(wn) { }
00129 ~RBI_WN_REF(void) { }
00130
00131 WN *Wn( void ) const { return _wn; }
00132 BOOL Aliasable( void ) const { return RBI_WN_Aliasable(_wn); }
00133 void Print(FILE *FD)
00134 { fprintf(FD,"%s ",(Aliasable()) ? "<aliasable>" : "<not aliasable>");
00135 fdump_wn(FD,_wn);
00136 }
00137 };
00138
00139 class RBI_WN_SET : public SLIST {
00140 friend class RBI_WN_USED_SET;
00141 friend class RBI_WN_DEF_SET;
00142
00143 private:
00144 RBI *_rbi;
00145 DECLARE_SLIST_CLASS( RBI_WN_SET, RBI_WN_REF );
00146
00147 public:
00148 RBI_WN_SET( RBI *const rbi ) { _rbi = rbi; }
00149
00150 ~RBI_WN_SET( void )
00151 { while ( !Is_Empty() ) {
00152 RBI_WN_REF *tmp = Remove_Headnode();
00153 CXX_DELETE(tmp, _rbi->Mem_Pool());
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 BOOL Compare(WN *const wn1, WN *const wn2)
00166 {
00167 OPCODE op = WN_opcode(wn1);
00168 if (op == WN_opcode(wn2)) {
00169 switch (OPCODE_operator(op)) {
00170 case OPR_ILOAD:
00171 case OPR_ISTORE:
00172 if (WN_load_offset(wn1) != WN_load_offset(wn2))
00173 return FALSE;
00174 return Compare(WN_kid0(wn1),WN_kid0(wn1));
00175 case OPR_MLOAD:
00176 case OPR_MSTORE:
00177 case OPR_ILOADX:
00178 case OPR_ISTOREX:
00179 if (WN_load_offset(wn1) != WN_load_offset(wn2))
00180 return FALSE;
00181 BOOL tmp = Compare(WN_kid0(wn1),WN_kid0(wn1));
00182 if (tmp == FALSE)
00183 return FALSE;
00184 return Compare(WN_kid1(wn1),WN_kid1(wn1));
00185 case OPR_LDID:
00186 case OPR_STID:
00187 if (WN_load_offset(wn1) != WN_load_offset(wn2))
00188 return FALSE;
00189 return WN_st(wn1) == WN_st(wn2);
00190 default:
00191 return FALSE;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201 }
00202 return FALSE;
00203 }
00204
00205
00206 void Add( WN *const wn )
00207 {
00208
00209 RBI_WN_REF *tmp;
00210 BOOL found = FALSE;
00211 for (tmp = Head(); tmp != NULL; tmp = tmp->Next()) {
00212 if (Compare(wn,tmp->Wn())) {
00213 found = TRUE;
00214 break;
00215 }
00216 }
00217 if (!found)
00218 Prepend(wn);
00219 }
00220
00221
00222 void Prepend( WN *const wn )
00223 {
00224 RBI_WN_REF *tmp = CXX_NEW(RBI_WN_REF(wn), _rbi->Mem_Pool());
00225 SLIST::Prepend(tmp);
00226 }
00227 };
00228
00229 class RBI_WN_SET_ITER : public SLIST_ITER {
00230 DECLARE_SLIST_ITER_CLASS( RBI_WN_SET_ITER, RBI_WN_REF, RBI_WN_SET );
00231 };
00232
00233 class RBI_WN_USED_SET : public RBI_WN_SET {
00234 private:
00235 BOOL _all_aliasable;
00236
00237
00238
00239 public:
00240 RBI_WN_USED_SET( RBI *const rbi ) : RBI_WN_SET( rbi )
00241 { _all_aliasable = FALSE; }
00242
00243 void Add( WN *const wn )
00244 { if (!_all_aliasable || !RBI_WN_Aliasable(wn))
00245 RBI_WN_SET::Add(wn);
00246 }
00247
00248 void Set_All_Aliasable( void )
00249 {
00250 _all_aliasable = TRUE;
00251
00252
00253
00254
00255
00256 RBI_WN_REF *prev = NULL;
00257 RBI_WN_REF *curr = Head();
00258
00259 while (curr != NULL) {
00260 if (curr->Aliasable()) {
00261 Remove(prev, curr);
00262 curr = curr->Next();
00263 CXX_DELETE( curr, _rbi->Mem_Pool() );
00264 }
00265 else {
00266 prev = curr;
00267 curr = curr->Next();
00268 }
00269 }
00270 }
00271
00272 BOOL All_Aliasable( void ) { return _all_aliasable; }
00273
00274 void Print(FILE *FD)
00275 {
00276 if (All_Aliasable())
00277 fprintf(FD,"<All Aliasable>\n");
00278 else {
00279 RBI_WN_REF *tmp = Head();
00280 if (tmp == NULL)
00281 fprintf(FD," NULL\n");
00282 else {
00283 while (tmp != NULL) {
00284 tmp->Print(FD);
00285 tmp = tmp->Next();
00286 }
00287 }
00288 }
00289 }
00290 };
00291
00292 class RBI_WN_DEF_SET : public RBI_WN_SET {
00293 private:
00294
00295
00296 BOOL _all_aliasable[RBI_NUM_LIVENESS];
00297
00298 public:
00299 RBI_WN_DEF_SET( RBI *const rbi ) : RBI_WN_SET( rbi )
00300 { _all_aliasable[RBI_LIVE] = FALSE;
00301 _all_aliasable[RBI_DEAD] = FALSE;
00302 }
00303
00304 void Add( WN *const wn, const RBI_LIVENESS_STATE state )
00305 {
00306
00307
00308
00309
00310 if (!((_all_aliasable[RBI_LIVE] && (state == RBI_LIVE)) &&
00311 (_all_aliasable[RBI_DEAD] && (state == RBI_DEAD))) ||
00312 !RBI_WN_Aliasable(wn)) {
00313 RBI_WN_SET::Add(wn);
00314 }
00315 }
00316
00317 void Set_All_Aliasable( const RBI_LIVENESS_STATE state )
00318 {
00319 if (state == RBI_LIVE) {
00320 _all_aliasable[RBI_LIVE] = TRUE;
00321 _all_aliasable[RBI_DEAD] = FALSE;
00322 } else
00323 _all_aliasable[RBI_DEAD] = TRUE;
00324
00325
00326
00327
00328
00329 RBI_WN_REF *prev = NULL;
00330 RBI_WN_REF *curr = Head();
00331
00332 while (curr != NULL) {
00333
00334
00335
00336 if (curr->Aliasable() &&
00337 (_all_aliasable[RBI_LIVE] ||
00338 ((_rbi->Get_WN_Prop(curr->Wn()) & WN_PROP_LIVE_OUT) == 0))) {
00339 Remove(prev, curr);
00340 curr = curr->Next();
00341 CXX_DELETE( curr, _rbi->Mem_Pool() );
00342 } else {
00343 prev = curr;
00344 curr = curr->Next();
00345 }
00346 }
00347 }
00348
00349 BOOL All_Aliasable( const RBI_LIVENESS_STATE state )
00350 { return _all_aliasable[state]; }
00351
00352 void Print(FILE *FD)
00353 {
00354 if (All_Aliasable(RBI_LIVE))
00355 fprintf(FD,"<All Aliasable>\n");
00356 else {
00357 RBI_WN_REF *tmp = Head();
00358 if (tmp == NULL)
00359 fprintf(FD," NULL\n");
00360 else {
00361 while (tmp != NULL) {
00362 tmp->Print(FD);
00363 tmp = tmp->Next();
00364 }
00365 }
00366 }
00367 }
00368 };
00369
00370
00371
00372
00373
00374
00375 RBI::RBI(MEM_POOL *RBI_pool)
00376 {
00377 if (Get_Trace(TP_REGION, TT_REGION_RBI_DEBUG)) {
00378 _trace_level = 2;
00379 if (Get_Trace(TP_REGION, ~TT_REGION_RBI_DEBUG))
00380 _trace_level = 1;
00381 } else
00382 _trace_level = 0;
00383
00384 _pool = RBI_pool;
00385
00386 _prop_map = WN_MAP32_Create( _pool );
00387 FmtAssert(_prop_map != (WN_MAP) -1,("RBI::RBI Cannot create RBI._prop_map"));
00388
00389 _tag_map = WN_MAP32_Create( _pool );
00390 FmtAssert(_tag_map != (WN_MAP) -1,("RBI::RBI Cannot create RBI._tag_map"));
00391
00392 MEM_POOL_Initialize( _pool, "Region Boundary Info pool", FALSE );
00393 MEM_POOL_Push( _pool );
00394 }
00395
00396
00397 RBI::~RBI(void)
00398 {
00399 WN_MAP_Delete( _prop_map );
00400 MEM_POOL_Pop( _pool );
00401 MEM_POOL_Delete( _pool );
00402 }
00403
00404
00405 void
00406 RBI::Set_WN_Prop(WN *const wn, const INT32 prop)
00407 {
00408 INT32 curprop = WN_MAP32_Get( _prop_map, wn );
00409 curprop |= (INT32) prop;
00410 WN_MAP32_Set( _prop_map, wn, curprop );
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 static BOOL
00424 RBI_WN_Aliasable(const WN *const wn)
00425 {
00426 const OPCODE opc = WN_opcode(wn);
00427 const OPERATOR opr = OPCODE_operator(opc);
00428
00429 if (opc == OPC_FUNC_ENTRY)
00430 return FALSE;
00431
00432 if (opr == OPR_LDID || opr == OPR_STID) {
00433
00434
00435
00436
00437 if (ST_is_global(WN_st(wn)) && !SYMTAB_IPA_on(Global_Symtab))
00438 return FALSE;
00439 else
00440 return ST_addr_taken(WN_st(wn));
00441 }
00442
00443 if (opc == OPC_RETURN || opr == OPR_CALL)
00444 return TRUE;
00445
00446 if (opr == OPR_ILOAD || opr == OPR_ISTORE) {
00447
00448
00449 WN *kid = WN_kid0(wn);
00450 return WN_operator(kid) != OPR_ARRAY;
00451 }
00452
00453 FmtAssert(FALSE, ("Unknown opcode in BOOL RBI_WN_Aliasable( WN* )"));
00454 return TRUE;
00455 }
00456
00457
00458
00459
00460 inline static BOOL
00461 OPCODE_is_use(OPCODE op)
00462 {
00463 if (op == OPC_RETURN)
00464 return TRUE;
00465
00466 OPERATOR opr = OPCODE_operator(op);
00467 return (opr == OPR_LDID || opr == OPR_ILOAD || opr == OPR_CALL);
00468 }
00469
00470
00471
00472
00473 inline static BOOL
00474 OPCODE_is_def(OPCODE op)
00475 {
00476 if (op == OPC_FUNC_ENTRY)
00477 return TRUE;
00478
00479 OPERATOR opr = OPCODE_operator(op);
00480 return (opr == OPR_STID || opr == OPR_ISTORE || opr == OPR_CALL);
00481 }
00482
00483
00484
00485
00486 static BOOL
00487 Is_Array_ILOAD( const WN *const wn )
00488 {
00489 Is_True(WN_operator(wn)==OPR_ILOAD,("Non-ILOAD passed to Is_Array_ILOAD"));
00490 return WN_operator(WN_kid0(wn)) == OPR_ARRAY;
00491 }
00492
00493
00494
00495
00496
00497 static BOOL
00498 Is_Array_ISTORE( const WN *const wn )
00499 {
00500 Is_True(WN_operator(wn)==OPR_ISTORE,("Non-ILOAD passed to Is_Array_ISTORE"));
00501 return WN_operator(WN_kid0(wn)) == OPR_ARRAY;
00502 }
00503
00504
00505
00506
00507
00508 inline static BOOL
00509 Is_PREG(ST *st)
00510 {
00511 return ST_symclass(st) == CLASS_PREG;
00512 }
00513
00514 inline static BOOL
00515 Find_PREG(PREG_LIST *l, PREG_NUM p_num)
00516 {
00517 for (PREG_LIST *ptmp = l; ptmp; ptmp = PREG_LIST_rest(ptmp)) {
00518 if (PREG_LIST_first(ptmp) == p_num)
00519 return TRUE;
00520 }
00521 return FALSE;
00522 }
00523
00524 inline static void
00525 Add_To_PREG_LIST(PREG_LIST **l, WN *wn)
00526 {
00527
00528 PREG_NUM p_num = WN_load_offset(wn);
00529 if (!Find_PREG(*l,p_num))
00530 *l = PREG_LIST_Push(p_num,*l,®ION_mem_pool);
00531 }
00532
00533 inline static void
00534 Add_To_All_PREG_LISTs(PREG_LIST **l, WN *wn, INT32 n)
00535 {
00536 for (INT32 i = 0; i < n; i++)
00537 Add_To_PREG_LIST(&l[i], wn);
00538 }
00539
00540
00541
00542
00543
00544 BOOL RBI_PT_Aliasable( const POINTS_TO *const pt )
00545 {
00546
00547
00548
00549 Is_True(pt != NULL,("RBI_PT_Aliasable, NULL pt"));
00550 return FALSE;
00551 }
00552
00553
00554
00555
00556 void
00557 RBI::Add_To_PT_SET(POINTS_TO_SET *pt_set, POINTS_TO *pt)
00558 {
00559 POINTS_TO_REF *tmp;
00560
00561
00562 for (tmp = pt_set->Elements; tmp != NULL; tmp = tmp->Next) {
00563 if (tmp->Pt == pt)
00564 return;
00565 }
00566 POINTS_TO_REF *ptr = TYPE_MEM_POOL_ALLOC(POINTS_TO_REF, ®ION_mem_pool);
00567 ptr->Next = pt_set->Elements;
00568 ptr->Pt = Points_to_copy(pt,®ION_mem_pool);
00569 pt_set->Elements = ptr;
00570 }
00571
00572
00573
00574
00575 void
00576 RBI::Set_PT_SET_All_Aliasable(POINTS_TO_SET *pt_set)
00577 {
00578 pt_set->All_Aliasable = TRUE;
00579
00580 #if 0
00581
00582 POINTS_TO_REF *tmp1, *tmp2;
00583 while (pt_set->Elements != NULL) {
00584 if (RBI_PT_Aliasable(pt_set->Elements->Pt)) {
00585 tmp1 = pt_set->Elements;
00586 pt_set->Elements = tmp1->Next;
00587 MEM_POOL_FREE(®ION_mem_pool, (void *) tmp1);
00588 } else
00589 break;
00590 }
00591 #endif
00592
00593 #if 0
00594
00595 if (pt_set->Elements != NULL) {
00596 tmp1 = pt_set->Elements;
00597 tmp2 = pt_set->Elements->Next;
00598
00599 while (tmp2 != NULL) {
00600 if (RBI_PT_Aliasable(tmp2->Pt)) {
00601 tmp1->Next = tmp2->Next;
00602 MEM_POOL_FREE(®ION_mem_pool, (void *) tmp2);
00603 } else
00604 tmp1 = tmp2;
00605 tmp2 = tmp1->Next;
00606 }
00607 }
00608 #endif
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 void
00691 RBI::RBI_Calc_Rgn(RID *const rid_node, const DU_MANAGER *const du_mgr,
00692 const ALIAS_MANAGER *const am)
00693 {
00694 WN *const wn = RID_rwn(rid_node);
00695 Is_True(wn != NULL,("RBI::RBI_Calc_Rgn, NULL WHIRL tree"));
00696 if (RID_type(rid_node) & RID_TYPE_func_entry)
00697 return;
00698 RBI_WN_SET relevant_nodes(this);
00699 RID_level(rid_node) = RL_RBI;
00700 RID_bounds_exist(rid_node) = REGION_BOUND_EXISTS;
00701
00702 Is_True(REGION_get_rid(wn) == rid_node,
00703 ("RBI::RBI_Calc_Rgn: RID refers to incorrect WHIRL node"));
00704 Is_True(RID_rwn(rid_node) == wn,
00705 ("RBI::RBI_Calc_Rgn: inconsistency between RID and WHIRL"));
00706 Is_True(WN_operator(wn) == OPR_REGION,
00707 ("RBI::RBI_Calc_Rgn: RID refers to non-REGION node"));
00708
00709
00710
00711
00712
00713
00714
00715 if (Trace())
00716 fprintf(TFile,"===== RBI::RBI_Calc_Rgn (RGN %d): marking nodes\n",
00717 RID_id(rid_node));
00718 for (WN_ITER *wni=WN_WALK_TreeIter(wn); wni; wni = WN_WALK_TreeNext(wni)) {
00719 WN *wtmp = WN_ITER_wn(wni);
00720 Set_WN_Cur_Rgn(wtmp,RID_id(rid_node));
00721 OPCODE op = WN_opcode(wtmp);
00722 if (OPCODE_is_use(op) || OPCODE_is_def(op))
00723 relevant_nodes.Prepend(wtmp);
00724 }
00725
00726
00727 Is_True(RID_num_exits(rid_node) > 0,
00728 ("RBI::RBI_Calc_Rgn, incorrect # exits"));
00729 Is_True(RID_pregs_out(rid_node) == NULL,
00730 ("RBI::RBI_Calc_Rgn, preg out set exists"));
00731 RID_pregs_out(rid_node) = TYPE_MEM_POOL_ALLOC_N(PREG_LIST *,
00732 ®ION_mem_pool,RID_num_exits(rid_node));
00733
00734
00735
00736 if (Trace())
00737 fprintf(TFile,"===== RBI::RBI_Calc_Rgn (RGN %d): use_list, def_list\n",
00738 RID_id(rid_node));
00739
00740 RBI_WN_USED_SET used_in(this);
00741 RBI_WN_DEF_SET def_in(this);
00742
00743 RBI_WN_SET_ITER relevant_iter;
00744 RBI_WN_REF *wnr;
00745
00746 FOR_ALL_NODE(wnr, relevant_iter, Init(&relevant_nodes)) {
00747 WN *const wn = wnr->Wn();
00748 USE_LIST *use_list;
00749 DEF_LIST *def_list;
00750 OPERATOR opr = WN_operator(wn);
00751
00752 if (Trace2()) {
00753 fprintf(TFile,"wn: ");
00754 fdump_wn(TFile,wn);
00755 }
00756
00757 #if 0
00758
00759
00760
00761
00762 FmtAssert(use_list != NULL || def_list != NULL,
00763 ("RBI_Calc_Rgn: Relevant WN with no uses and no defs\n"));
00764 #endif
00765
00766 if (opr == OPR_CALL) {
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 used_in.Set_All_Aliasable();
00777 def_in.Set_All_Aliasable(RBI_LIVE);
00778 continue;
00779 }
00780
00781
00782
00783 if (opr == OPR_ISTORE) {
00784 def_in.Add(wn, RBI_LIVE);
00785 Set_WN_Prop(wn, WN_PROP_DEF_IN | WN_PROP_LIVE_OUT);
00786 goto bottom;
00787 } else if (opr == OPR_ILOAD) {
00788 used_in.Add(wn);
00789 Set_WN_Prop(wn, WN_PROP_USED_IN);
00790 goto bottom;
00791 }
00792
00793 use_list = du_mgr->Du_Get_Use(wn);
00794 def_list = du_mgr->Ud_Get_Def(wn);
00795 if (Trace2()) {
00796 if (use_list) {
00797 fprintf(TFile,"use_list: ");
00798 #ifdef AFTER_MR
00799 use_list->Print(TFile);
00800 #endif
00801 fprintf(TFile,"\n");
00802 } else
00803 fprintf(TFile,"use_list: NULL\n");
00804 if (def_list) {
00805 fprintf(TFile,"def_list: ");
00806 #ifdef AFTER_MR
00807 def_list->Print(TFile);
00808 #endif
00809 fprintf(TFile,"\n");
00810 } else
00811 fprintf(TFile,"def_list: NULL\n");
00812 }
00813
00814 Is_True(WN_opcode(wn) != OPC_RETURN || use_list == NULL,
00815 ("RBI_Calc_Rgn: OPC_RETURN has non-NULL use-list"));
00816
00817
00818
00819
00820
00821
00822 if (use_list != NULL) {
00823 if (use_list->Incomplete()) {
00824 if (Trace2())
00825 fprintf(TFile,"use_list incomplete\n");
00826
00827
00828
00829
00830
00831
00832 if (WN_operator(wn) == OPR_STID ||
00833 WN_operator(wn) == OPR_FUNC_ENTRY || Is_Array_ISTORE(wn)) {
00834 def_in.Add(wn, RBI_LIVE);
00835 Set_WN_Prop(wn, WN_PROP_DEF_IN | WN_PROP_LIVE_OUT);
00836 } else
00837 def_in.Set_All_Aliasable( RBI_LIVE );
00838 }
00839 else {
00840 if (Trace2())
00841 fprintf(TFile,"use_list complete\n");
00842
00843
00844 USE_LIST_CONST_ITER use_list_iter;
00845 const DU_NODE *tmp;
00846
00847
00848
00849
00850
00851
00852
00853
00854 if (WN_operator(wn) == OPR_STID || WN_operator(wn) == OPR_FUNC_ENTRY ||
00855 Is_Array_ISTORE(wn)) {
00856 def_in.Add(wn, RBI_DEAD);
00857 Set_WN_Prop(wn, WN_PROP_DEF_IN);
00858
00859
00860 FOR_ALL_NODE( tmp, use_list_iter, Init(use_list) ) {
00861 if (Outside_Cur_Rgn(tmp->Wn(), RID_id(rid_node))) {
00862 Set_WN_Prop(wn, WN_PROP_LIVE_OUT);
00863 break;
00864 }
00865 }
00866 } else {
00867
00868 RBI_LIVENESS_STATE state = RBI_DEAD;
00869
00870 FOR_ALL_NODE ( tmp, use_list_iter, Init(use_list) ) {
00871 if (Outside_Cur_Rgn(tmp->Wn(), RID_id(rid_node))) {
00872 state = RBI_LIVE;
00873 if ((WN_operator(tmp->Wn()) == OPR_LDID) ||
00874 Is_Array_ILOAD(tmp->Wn())) {
00875 def_in.Add(tmp->Wn(), RBI_LIVE);
00876 Set_WN_Prop(wn, WN_PROP_DEF_IN | WN_PROP_LIVE_OUT);
00877 } else {
00878 def_in.Set_All_Aliasable( RBI_LIVE );
00879 break;
00880 }
00881 }
00882 }
00883
00884
00885
00886 if (state == RBI_DEAD)
00887 def_in.Set_All_Aliasable( RBI_DEAD );
00888 }
00889 }
00890 }
00891
00892 if (def_list != NULL) {
00893 if (def_list->Incomplete()) {
00894 if (Trace2())
00895 fprintf(TFile,"def_list incomplete\n");
00896
00897
00898
00899
00900
00901
00902 if ((WN_operator(wn) == OPR_LDID) || Is_Array_ILOAD(wn)) {
00903 used_in.Add(wn);
00904 Set_WN_Prop(wn, WN_PROP_USED_IN);
00905 } else
00906 used_in.Set_All_Aliasable();
00907 }
00908 else {
00909 if (Trace2())
00910 fprintf(TFile,"def_list complete\n");
00911
00912
00913 DEF_LIST_CONST_ITER def_list_iter;
00914 const DU_NODE *tmp;
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 if ((WN_operator(wn) == OPR_LDID) || Is_Array_ILOAD(wn)) {
00926 FOR_ALL_NODE( tmp, def_list_iter, Init(def_list) ) {
00927 if (Outside_Cur_Rgn(tmp->Wn(), RID_id(rid_node))) {
00928 if (Trace2())
00929 fprintf(TFile,"def is outside region\n");
00930 used_in.Add(wn);
00931 Set_WN_Prop(wn, WN_PROP_USED_IN);
00932 break;
00933 }
00934 }
00935 } else {
00936
00937
00938
00939
00940
00941 FOR_ALL_NODE( tmp, def_list_iter, Init(def_list) ) {
00942 if (Outside_Cur_Rgn(tmp->Wn(), RID_id(rid_node))) {
00943 if ((WN_operator(tmp->Wn()) == OPR_STID) ||
00944 (WN_operator(tmp->Wn()) == OPR_FUNC_ENTRY) ||
00945 Is_Array_ISTORE(tmp->Wn())) {
00946 used_in.Add(tmp->Wn());
00947 Set_WN_Prop(tmp->Wn(), WN_PROP_USED_IN);
00948 } else {
00949 used_in.Set_All_Aliasable();
00950 break;
00951 }
00952 }
00953 }
00954 }
00955 }
00956 }
00957
00958 bottom:
00959 if (Trace2()) {
00960 fprintf(TFile,"Bottom of loop, used_in:\n");
00961 used_in.Print(TFile);
00962 fprintf(TFile,"Bottom of loop, def_in:\n");
00963 def_in.Print(TFile);
00964 fprintf(TFile,"\n");
00965 }
00966
00967 }
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 if (Trace2()) {
00989 fprintf(TFile,"===== RBI::RBI_Calc_Rgn (RGN %d): used_in/pregs_in sets\n",
00990 RID_id(rid_node));
00991 fprintf(TFile,"used_in:\n");
00992 used_in.Print(TFile);
00993 }
00994
00995 RBI_WN_SET_ITER use_def_iter;
00996
00997 if (used_in.All_Aliasable())
00998 Set_PT_SET_All_Aliasable(&RID_used_in(rid_node));
00999
01000 FOR_ALL_NODE( wnr, use_def_iter, Init(&used_in) ) {
01001 WN *wn = wnr->Wn();
01002 if (Trace2()) {
01003 fprintf(TFile,"used_in wn: ");
01004 fdump_wn(TFile,wn);
01005 }
01006 Is_True(!(used_in.All_Aliasable() && RBI_WN_Aliasable(wn)),
01007 ("Aliasable WN in used-in set marked all aliasable"));
01008
01009
01010 if (WN_opcode(wn) == OPC_FUNC_ENTRY) {
01011 INT i;
01012 for (i = WN_num_formals(wn) - 1; i >= 0; i--) {
01013 WN *kid = WN_kid(wn, i);
01014 FmtAssert(WN_opcode(kid) == OPC_IDNAME,
01015 ("Non-IDNAME function parameter"));
01016 if (Is_PREG(WN_st(kid))) {
01017 Add_To_PREG_LIST(&RID_pregs_in(rid_node), kid);
01018 } else {
01019
01020
01021 #ifdef AFTER_MR
01022 Add_To_PT_SET(&RID_used_in(rid_node), am->Pt(am->Id(kid)));
01023 #endif
01024 }
01025 }
01026 } else {
01027 if (Is_PREG(WN_st(wn))) {
01028 Add_To_PREG_LIST(&RID_pregs_in(rid_node), wn);
01029 if (Trace2())
01030 fprintf(TFile,"Adding to pregs_in list\n");
01031 } else {
01032
01033
01034 #ifdef AFTER_MR
01035 Add_To_PT_SET(&RID_used_in(rid_node), am->Pt(am->Id(wn)));
01036 #endif
01037 if (Trace2())
01038 fprintf(TFile,"Adding to used_in list\n");
01039 }
01040 }
01041 }
01042
01043
01044 if (Trace2()) {
01045
01046
01047
01048 fprintf(TFile,"===== RBI::RBI_Calc_Rgn (RGN %d): def_in_* sets\n",
01049 RID_id(rid_node));
01050 fprintf(TFile,"def_in:\n");
01051 def_in.Print(TFile);
01052 }
01053
01054 if (def_in.All_Aliasable(RBI_LIVE))
01055 Set_PT_SET_All_Aliasable(&RID_def_in_live_out(rid_node));
01056 else if (def_in.All_Aliasable(RBI_DEAD))
01057 Set_PT_SET_All_Aliasable(&RID_def_in_dead_out(rid_node));
01058
01059 FOR_ALL_NODE( wnr, use_def_iter, Init(&def_in) ) {
01060 WN *wn = wnr->Wn();
01061 BOOL live_out = ((Get_WN_Prop(wn) & WN_PROP_LIVE_OUT) != 0);
01062 if (Trace2()) {
01063 fprintf(TFile,"def wn: <%s> <%s> ",live_out?"live_out":"dead_out",
01064 def_in.All_Aliasable(RBI_LIVE)?"aliasable live":
01065 (def_in.All_Aliasable(RBI_DEAD)?"aliasable dead":"not aliasable"));
01066 fdump_wn(TFile,wn);
01067 }
01068
01069 Is_True(!(RBI_WN_Aliasable(wn) && live_out &&
01070 def_in.All_Aliasable(RBI_LIVE)),
01071 ("Live out aliasable WN in def_in when all aliasable(RBI_LIVE)"));
01072 Is_True(!(RBI_WN_Aliasable(wn) && !live_out &&
01073 def_in.All_Aliasable(RBI_DEAD)),
01074 ("Dead out aliasable WN in def_in when all aliasable(RBI_DEAD)"));
01075
01076 if (live_out || !def_in.All_Aliasable(RBI_DEAD)) {
01077
01078
01079 if (WN_opcode(wn) == OPC_FUNC_ENTRY) {
01080 for (INT i = WN_num_formals(wn) - 1; i >= 0; i--) {
01081 WN *kid = WN_kid(wn, i);
01082 FmtAssert(WN_opcode(kid) == OPC_IDNAME,
01083 ("Non-IDNAME function parameter"));
01084
01085 if (live_out) {
01086 if (Is_PREG(WN_st(wn))) {
01087 if (Trace2())
01088 fprintf(TFile,"Adding to pregs_out list\n");
01089
01090 Add_To_All_PREG_LISTs(RID_pregs_out(rid_node),kid,
01091 RID_num_exits(rid_node));
01092 } else {
01093 if (Trace2())
01094 fprintf(TFile,"Adding to def_in_live_out list\n");
01095
01096
01097
01098 #ifdef AFTER_MR
01099 Add_To_PT_SET(&RID_def_in_live_out(rid_node),
01100 am->Pt(am->Id(kid)));
01101 #endif
01102 }
01103 } else {
01104
01105
01106 if (!Is_PREG(WN_st(wn))) {
01107 if (Trace2())
01108 fprintf(TFile,"Adding to def_in_dead_out list\n");
01109 #ifdef AFTER_MR
01110 Add_To_PT_SET(&RID_def_in_dead_out(rid_node),
01111 am->Pt(am->Id(kid)));
01112 #endif
01113 }
01114 }
01115 }
01116 }
01117 else {
01118 if (live_out) {
01119 if (Is_PREG(WN_st(wn))) {
01120 if (Trace2())
01121 fprintf(TFile,"Adding to pregs_out list (2)\n");
01122
01123 Add_To_All_PREG_LISTs(RID_pregs_out(rid_node),wn,
01124 RID_num_exits(rid_node));
01125 } else {
01126
01127
01128 if (Trace2())
01129 fprintf(TFile,"Adding to def_in_live_out list (2)\n");
01130 #ifdef AFTER_MR
01131 Add_To_PT_SET(&RID_def_in_live_out(rid_node),am->Pt(am->Id(wn)));
01132 #endif
01133 }
01134 } else {
01135
01136
01137 if (!Is_PREG(WN_st(wn))) {
01138 if (Trace2())
01139 fprintf(TFile,"Adding to def_in_dead_out list (2)\n");
01140 #ifdef AFTER_MR
01141 Add_To_PT_SET(&RID_def_in_dead_out(rid_node),
01142 am->Pt(am->Id(wn)));
01143 #endif
01144 } else {
01145 if (Trace2()) {
01146 fprintf(TFile,"Discarding Dead-out PREG\n");
01147 fdump_wn_no_st(TFile,wn);
01148 }
01149 }
01150 }
01151 }
01152 }
01153 }
01154 if (Trace2())
01155 RID_set_print(TFile,REGION_get_rid(wn));
01156 }
01157
01158
01159
01160
01161 void
01162 RBI::RBI_Calc_Kids(RID *root, const DU_MANAGER *du_mgr,
01163 const ALIAS_MANAGER *am)
01164 {
01165 for (RID *kid = RID_first_kid(root); kid != NULL; kid = RID_next(kid)) {
01166 RBI_Calc_Rgn(kid, du_mgr, am);
01167 RBI_Calc_Kids(kid, du_mgr, am);
01168 }
01169 RID_level(root) = RL_RBI;
01170 RID_bounds_exist(root) = REGION_BOUND_EXISTS;
01171 }
01172
01173 #endif
01174
01175
01176
01177
01178 extern "C"
01179 void
01180 Region_Bound_Info(WN *tree, DU_MANAGER *du_mgr, ALIAS_MANAGER *am)
01181 {
01182 #if 0
01183 if (!SYMTAB_has_rgn(Current_Symtab))
01184 return;
01185
01186 FmtAssert(WN_operator(tree) == OPR_FUNC_ENTRY ||
01187 WN_operator(tree) == OPR_REGION,
01188 ("Region_Bound_Info: Expected FUNC_ENTRY; Got %s instead.\n",
01189 OPCODE_name(WN_opcode(tree))));
01190
01191
01192 RID *root = REGION_get_rid(tree);
01193 Is_True(root != NULL,("Region_Bound_Info, NULL RID"));
01194
01195
01196 MEM_POOL RBI_pool;
01197 RBI Cur_RBI(&RBI_pool);
01198
01199
01200
01201
01202
01203
01204 #ifdef AFTER_MR
01205 Cur_RBI.RBI_Calc_Kids(root, du_mgr, am);
01206 #endif
01207
01208 if (Cur_RBI.Trace())
01209 RID_set_print(TFile,REGION_get_rid(tree));
01210
01211 #endif
01212 }
01213