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 #include "defs.h"
00056 #include "errors.h"
00057 #include "tracing.h"
00058 #include "opcode.h"
00059 #include "wn_util.h"
00060 #include "wn_map.h"
00061 #include "region_util.h"
00062 #include "region_main.h"
00063 #include "opt_alias_interface.h"
00064 #include "optimizer.h"
00065 #include "ir_reader.h"
00066 #include "wn_pragmas.h"
00067 #include "cxx_memory.h"
00068 #include "region_whirl_templates.h"
00069
00070
00071 #include "pragma_weak.h"
00072
00073 #if defined(TARG_SL)
00074 #include "fb_whirl.h"
00075 #endif
00076
00077 #if defined(__linux__) || defined(BUILD_OS_DARWIN)
00078 extern void (*Print_points_to_p) (FILE *fp, POINTS_TO *ptmp);
00079 #define Print_points_to (*Print_points_to_p)
00080 #else
00081 #pragma weak Print_points_to
00082 #endif
00083
00084
00085 #define tf(x) ((x) ? 'T' : 'F')
00086
00087
00088
00089
00090
00091 void REGION_new_wn(WN *new_wn, WN *old_wn)
00092 {
00093 RID *rid;
00094 if (new_wn == old_wn)
00095 return;
00096 rid = REGION_get_rid(old_wn);
00097 if (rid == NULL) {
00098 if (PU_has_region (Get_Current_PU ())) {
00099 FmtAssert(rid != NULL, ("REGION_new_wn, could not find matching RID"));
00100 }
00101 return;
00102 }
00103 WN_MAP_Set(RID_map, new_wn, rid);
00104 RID_rwn(rid) = new_wn;
00105
00106
00107 Is_True(RID_id(rid) == WN_region_id(new_wn),
00108 ("REGION_new_wn, region ids do not match"));
00109 }
00110
00111
00112
00113
00114
00115
00116 BOOL REGION_consistency_check(WN *wn)
00117 {
00118 #ifdef Is_True_On
00119 if (PU_has_region (Get_Current_PU ())) {
00120 RID *rid = REGION_get_rid(wn);
00121 FmtAssert(rid != NULL,("REGION_consistency_check, could not find RID"));
00122 FmtAssert(RID_id(rid) == WN_region_id(wn),
00123 ("REGION_consistency_check, region ids mismatch, RID %d, WN %d",
00124 RID_id(rid), WN_region_id(wn)));
00125 }
00126 #endif
00127 return TRUE;
00128 }
00129
00130
00131
00132
00133
00134
00135 void REGION_update_alias_info(WN *wn, struct ALIAS_MANAGER *alias_mgr)
00136 {
00137 WN *wtmp;
00138 mINT16 i;
00139 OPCODE opc = WN_opcode(wn);
00140 BOOL trace = Get_Trace(TP_REGION, TT_REGION_ALL);
00141
00142 if (PU_has_region (Get_Current_PU ())) {
00143 if (!alias_mgr)
00144 return;
00145
00146
00147 if (OPCODE_is_load(opc) || OPCODE_is_store(opc)) {
00148 if (Valid_alias(alias_mgr,wn) == FALSE) {
00149 Is_Trace(trace,
00150 (TFile, "REGION_update_alias_info, alias id is zero\n"));
00151 Is_Trace_cmd(trace, fdump_wn(TFile, wn));
00152 Create_alias(alias_mgr, wn);
00153 }
00154 }
00155
00156
00157 switch (opc) {
00158 case OPR_BLOCK:
00159 for (wtmp=WN_first(wn); wtmp; wtmp=WN_next(wtmp))
00160 REGION_update_alias_info(wtmp,alias_mgr);
00161 break;
00162 default:
00163 for (i=0; i<WN_kid_count(wn); i++)
00164 REGION_update_alias_info(WN_kid(wn,i),alias_mgr);
00165 break;
00166 }
00167 }
00168 }
00169
00170
00171
00172
00173 RID *REGION_get_rid(const WN *wn)
00174 {
00175 if (RID_map == WN_MAP_UNDEFINED)
00176 return NULL;
00177 return (wn) ? (RID *) WN_MAP_Get(RID_map, wn) : NULL;
00178 }
00179
00180
00181 static RID *REGION_get_rid2(WN_MAP_TAB *maptab, const WN *wn)
00182 {
00183 if (RID_map == WN_MAP_UNDEFINED)
00184 return NULL;
00185 return (wn) ? (RID *) IPA_WN_MAP_Get(maptab, RID_map, wn) : NULL;
00186 }
00187
00188
00189
00190
00191
00192 WN *REGION_find_pu(WN *wn)
00193 {
00194 RID *rtmp;
00195 WN *parent;
00196
00197 Is_True(REGION_consistency_check(wn), ("REGION_find_pu"));
00198
00199 for (rtmp=REGION_get_rid(wn); RID_parent(rtmp); rtmp=RID_parent(rtmp))
00200 ;
00201
00202 parent = RID_rwn(rtmp);
00203
00204 Is_True(REGION_consistency_check(parent), ("REGION_find_pu"));
00205 return parent;
00206 }
00207
00208
00209
00210
00211
00212
00213 BOOL REGION_has_black_regions(RID *rid)
00214 {
00215 Is_True(rid != NULL, ("REGION_has_black_regions, RID is NULL"));
00216 Is_True(RID_TYPE_func_entry(rid) || !RID_TYPE_transparent(rid),
00217 ("REGION_has_black_regions, called on a transparent region"));
00218
00219
00220 #ifdef TARG_SL //region_type_for_major
00221 Is_True(RID_TYPE_func_entry(rid) || RID_TYPE_olimit(rid) || RID_TYPE_major(rid) ||
00222 #else
00223 Is_True(RID_TYPE_func_entry(rid) || RID_TYPE_olimit(rid) ||
00224 #endif
00225 RID_TYPE_pragma(rid),
00226 ("REGION_has_no_black_regions, unsupported region type"));
00227
00228 if (RID_contains_black(rid))
00229 return TRUE;
00230
00231 if (!RID_TYPE_func_entry(rid)) {
00232
00233 RID *rtmp;
00234 for (rtmp=rid; rtmp; rtmp=RID_parent(rtmp))
00235 RID_contains_black(rtmp) = TRUE;
00236 }
00237 return RID_contains_black(rid);
00238 }
00239
00240
00241
00242
00243
00244 void REGION_set_level(RID *rid, REGION_LEVEL level)
00245 {
00246 RID *rtmp;
00247
00248 RID_level(rid) = level;
00249
00250 for (rtmp=RID_first_kid(rid); rtmp; rtmp=RID_next(rtmp))
00251 REGION_set_level(rtmp, level);
00252 }
00253
00254
00255
00256
00257
00258 INT32 REGION_count_exits(WN *exit_blk)
00259 {
00260 INT32 count = 0;
00261 WN *wtmp;
00262
00263 Is_True(WN_opcode(exit_blk) == OPC_BLOCK,
00264 ("REGION_count_exits, can't find exit block"));
00265
00266 if (WN_first(exit_blk) != NULL) {
00267 for (wtmp=WN_first(exit_blk); wtmp; wtmp=WN_next(wtmp))
00268 count++;
00269 }
00270 return count;
00271 }
00272
00273
00274
00275
00276
00277 void REGION_fix_up_exits(RID *rid, WN *rwn)
00278 {
00279 INT32 new_exits = REGION_count_exits(WN_region_exits(rwn));
00280 if (new_exits != RID_num_exits(rid)) {
00281 INT32 i, limit;
00282 PREG_LIST **new_pregs_out = TYPE_MEM_POOL_ALLOC_N(PREG_LIST *,
00283 ®ION_mem_pool, new_exits);
00284 limit = MAX(new_exits, RID_num_exits(rid));
00285 for (i=0; i<limit; i++) {
00286 if (i < RID_num_exits(rid))
00287 new_pregs_out[i] = RID_pregs_out_i(rid, i);
00288 else
00289 new_pregs_out[i] = NULL;
00290 }
00291 RID_pregs_out(rid) = new_pregs_out;
00292 RID_num_exits(rid) = new_exits;
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301 BOOL REGION_scan_exits(WN *wn, INT32 label_no)
00302 {
00303 WN *wtmp;
00304
00305 Is_True(wn && label_no, ("REGION_scan_exits, parameters out of range"));
00306 Is_True(WN_opcode(wn) == OPC_BLOCK,
00307 ("REGION_scan_exits, can't find exit block"));
00308 for (wtmp=WN_first(wn); wtmp; wtmp=WN_next(wtmp))
00309 if (WN_label_number(wtmp) == label_no)
00310 return TRUE;
00311 return FALSE;
00312 }
00313
00314
00315
00316
00317 RID *RID_Create( INT id, INT depth, WN *wn )
00318 {
00319 RID *rid, *wrid;
00320
00321 rid = TYPE_MEM_POOL_ALLOC(RID, ®ION_mem_pool);
00322 RID_id(rid) = (id == RID_CREATE_NEW_ID) ? New_Region_Id() : id;
00323 RID_depth(rid) = depth;
00324 RID_flags(rid) = 0;
00325
00326 if (wn) {
00327 if (wrid = (RID *)WN_MAP_Get(RID_map, wn))
00328 RID_srcpos(rid) = RID_srcpos(wrid);
00329 else
00330 RID_srcpos(rid) = WN_Get_Linenum(wn);
00331 RID_rwn(rid) = wn;
00332 } else {
00333 RID_srcpos(rid) = (SRCPOS)0;
00334 RID_rwn(rid) = (WN *)NULL;
00335 }
00336
00337 RID_num_exits(rid) = 0;
00338
00339
00340 RID_pregs_in (rid) = (PREG_LIST *)NULL;
00341 RID_pregs_out(rid) = (PREG_LIST **)NULL;
00342 RID_used_in(rid) = (POINTS_TO_SET *)NULL;
00343 RID_def_in_live_out(rid) = (POINTS_TO_SET *)NULL;
00344
00345 RID_options(rid) = (char *)NULL;
00346 RID_parent(rid) = (RID *)NULL;
00347 RID_first_kid(rid) = (RID *)NULL;
00348 RID_next(rid) = (RID *)NULL;
00349 RID_lowered(rid) = (LOWER_ACTIONS)NULL;
00350 RID_parent_block(rid) = (WN *)NULL;
00351
00352 return rid;
00353 }
00354
00355
00356 void RID_Add_kid(RID *new_kid, RID *parent)
00357 {
00358 RID *rtmp;
00359
00360 if (RID_first_kid(parent) == NULL) {
00361 RID_first_kid(parent) = new_kid;
00362 } else {
00363 for (rtmp=RID_first_kid(parent); rtmp; rtmp=RID_next(rtmp)) {
00364 if (RID_next(rtmp) == NULL) {
00365 RID_next(rtmp) = new_kid;
00366 break;
00367 }
00368 }
00369 }
00370 RID_parent(new_kid) = parent;
00371 }
00372
00373
00374 void RID_unlink(RID *rid)
00375 {
00376 RID *rtmp, *rprev, *parent = RID_parent(rid);
00377
00378 for (rprev=rtmp=RID_first_kid(parent); rtmp; rtmp=RID_next(rtmp)) {
00379 if (rtmp == rid) {
00380 if (rtmp == RID_first_kid(parent))
00381 RID_first_kid(parent) = RID_next(rtmp);
00382 else
00383 RID_next(rprev) = RID_next(rtmp);
00384 RID_next(rid) = NULL;
00385 return;
00386 }
00387 rprev = rtmp;
00388 }
00389 FmtAssert(FALSE, ("RID_unlink, did not find rid"));
00390 }
00391
00392
00393 void RID_replace (RID *old_rid, RID *new_rid)
00394 {
00395 RID *rtmp, *rprev, *parent = RID_parent(old_rid);
00396
00397 for (rprev=rtmp=RID_first_kid(parent); rtmp; rtmp=RID_next(rtmp)) {
00398 if (rtmp == old_rid) {
00399
00400 RID_next(new_rid) = RID_next(rtmp);
00401 if (rtmp == RID_first_kid(parent))
00402 RID_first_kid(parent) = new_rid;
00403 else
00404 RID_next(rprev) = new_rid;
00405 RID_next(old_rid) = NULL;
00406 RID_parent(new_rid) = parent;
00407 return;
00408 }
00409 rprev = rtmp;
00410 }
00411 FmtAssert(FALSE, ("RID_replace, did not find rid"));
00412 }
00413
00414
00415
00416
00417 static RID *RID_last_kid(RID *parent)
00418 {
00419 RID *rtmp;
00420 Is_True(parent != NULL && RID_first_kid(parent) != NULL,
00421 ("RID_last_kid, parent or first kid is NULL"));
00422 for (rtmp=RID_first_kid(parent); RID_next(rtmp); rtmp=RID_next(rtmp))
00423 ;
00424 Is_True(rtmp != NULL, ("RID_last_kid, null last kid"));
00425 return rtmp;
00426 }
00427
00428
00429
00430
00431
00432 static void RID_set_parents(RID *list, RID *parent)
00433 {
00434 RID *rtmp;
00435 Is_True(parent != NULL && list != NULL,
00436 ("RID_set_parents, parent or RID list is NULL"));
00437 for (rtmp=list; rtmp; rtmp=RID_next(rtmp))
00438 RID_parent(rtmp) = parent;
00439 }
00440
00441
00442
00443
00444
00445
00446 void RID_Delete(WN_MAP_TAB *maptab, WN *wn)
00447 {
00448 RID *rid = REGION_get_rid2(maptab, wn);
00449
00450 Is_True(rid != NULL, ("RID_Delete, could not find rid"));
00451 IPA_WN_MAP_Set(maptab, RID_map, wn, NULL);
00452
00453 RID_Delete2(rid);
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 void RID_Delete2(RID *rid)
00463 {
00464 RID *rtmp, *rprev, *parent, *last;
00465
00466 Is_True(rid != NULL && RID_id(rid) != -1,
00467 ("RID_Delete2, passed in NULL rid"));
00468 parent = RID_parent(rid);
00469 Is_True(parent != NULL && RID_id(parent) != -1,
00470 ("RID_Delete2, tried to delete root RID"));
00471 rprev = RID_first_kid(parent);
00472 Is_True(rprev != NULL && RID_id(rprev) != -1,
00473 ("RID_Delete2, RID tree inconsistency"));
00474
00475 if (rprev == rid) {
00476 if (RID_first_kid(rid) != NULL) {
00477 RID_set_parents(RID_first_kid(rid),parent);
00478 last = RID_last_kid(rid);
00479 RID_next(last) = RID_next(rid);
00480 RID_first_kid(parent) = RID_first_kid(rid);
00481 } else
00482 RID_first_kid(parent) = RID_next(rid);
00483 } else {
00484 for (rtmp=RID_next(rprev); rtmp; rtmp=RID_next(rtmp)) {
00485 if (rtmp == rid) {
00486 if (RID_first_kid(rid) != NULL) {
00487 RID_set_parents(RID_first_kid(rid),parent);
00488 last = RID_last_kid(rid);
00489 RID_next(last) = RID_next(rid);
00490 RID_next(rprev) = RID_first_kid(rid);
00491 } else
00492 RID_next(rprev) = RID_next(rid);
00493 break;
00494 }
00495 rprev = rtmp;
00496 }
00497 }
00498
00499 RID_id(rid) = -1;
00500 RID_rwn(rid) = NULL;
00501 RID_parent_block(rid) = NULL;
00502 RID_parent(rid) = NULL;
00503 RID_first_kid(rid) = NULL;
00504 RID_next(rid) = NULL;
00505
00506 if (RID_options(rid) != NULL)
00507 CXX_DELETE_ARRAY(RID_options(rid), ®ION_mem_pool);
00508 RID_options(rid) = NULL;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 void REGION_clone(WN *old_wn, WN *new_wn, WN *parent_wn)
00527 {
00528 RID *o_rid, *n_rid, *p_rid;
00529
00530 Is_True(WN_opcode(old_wn) == OPC_REGION,
00531 ("REGION_clone, old_wn not a region"));
00532 Is_True(WN_opcode(new_wn) == OPC_REGION,
00533 ("REGION_clone, new_wn not a region"));
00534 Is_True(parent_wn == NULL || WN_opcode(parent_wn) == OPC_REGION ||
00535 WN_opcode(parent_wn) == OPC_FUNC_ENTRY,
00536 ("REGION_clone, expecting a REGION or PU for parent_wn"));
00537
00538 o_rid = REGION_get_rid(old_wn);
00539 Is_True(o_rid != NULL, ("REGION_clone, no original region"));
00540 if (parent_wn)
00541 p_rid = REGION_get_rid(parent_wn);
00542 else
00543 p_rid = RID_parent(o_rid);
00544
00545 Is_True(WN_region_id(new_wn) != 0, ("REGION_clone, can't clone PU"));
00546 n_rid = RID_Create(WN_region_id(new_wn), RID_level(o_rid), new_wn);
00547
00548
00549 RID_level(n_rid) = RID_level(o_rid);
00550 RID_type(n_rid) = RID_type(o_rid);
00551 RID_depth(n_rid) = RID_depth(o_rid);
00552 RID_srcpos(n_rid) = WN_Get_Linenum(new_wn);
00553 RID_bounds_exist(n_rid) = REGION_BOUND_UNKNOWN;
00554 Is_True(RID_bounds_exist(o_rid) == REGION_BOUND_UNKNOWN,
00555 ("REGION_clone, not enough information to clone boundary sets"));
00556 RID_has_return(n_rid) = REGION_NO_RETURN;
00557 RID_num_exits(n_rid) = RID_num_exits(o_rid);
00558 RID_eh_range_ptr(n_rid) = RID_eh_range_ptr(o_rid);
00559 Is_True(RID_num_exits(o_rid) == 1 || RID_num_exits(o_rid) == 0,
00560 ("REGION_clone, not enough information to clone region exits"));
00561
00562
00563 WN_MAP_Set(RID_map, new_wn, (void *)n_rid);
00564 RID_rwn(n_rid) = new_wn;
00565 if (p_rid)
00566 RID_Add_kid(n_rid, p_rid);
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 void REGION_emit(RID *rid, WN *rwn, INT32 level, INT32 nexits, INT64 linenum)
00579 {
00580 FmtAssert(rid != NULL,("REGION_emit, can't find RID"));
00581 RID_rwn(rid) = rwn;
00582 RID_level(rid) = level;
00583 WN_MAP_Set(RID_map, rwn, (void *)rid);
00584 RID_num_exits(rid) = nexits;
00585 if (linenum != 0)
00586 WN_Set_Linenum(rwn, linenum);
00587 Is_True(rid == REGION_get_rid(rwn), ("REGION_emit, map error"));
00588 }
00589
00590
00591
00592
00593
00594 void RID_copy_sets(RID *new_rid, RID *rid_orig)
00595 {
00596 RID_used_in(new_rid) = RID_used_in(rid_orig);
00597 RID_def_in_live_out(new_rid) = RID_def_in_live_out(rid_orig);
00598 RID_pregs_in(new_rid) = RID_pregs_in(rid_orig);
00599 RID_pregs_quad(new_rid) = RID_pregs_quad(rid_orig);
00600 RID_pregs_complex_quad(new_rid) = RID_pregs_complex_quad(rid_orig);
00601 if (RID_num_exits(new_rid) > 0 && RID_pregs_out(rid_orig) != NULL) {
00602 INT32 i;
00603 RID_pregs_out(new_rid) = TYPE_MEM_POOL_ALLOC_N(PREG_LIST *,
00604 ®ION_mem_pool, RID_num_exits(new_rid));
00605 for (i=0; i<RID_num_exits(new_rid); i++)
00606 RID_pregs_set_out_i(new_rid,i) = RID_pregs_out_i(rid_orig,i);
00607 }
00608 }
00609
00610
00611
00612
00613
00614 REGION_LEVEL RID_preopt_level(INT phase)
00615 {
00616
00617 switch (phase) {
00618 case PREOPT_IPA0_PHASE: return RL_IPA_PREOPT;
00619 case PREOPT_IPA1_PHASE: return RL_IPA_PREOPT;
00620 case PREOPT_LNO_PHASE: return RL_LNO_PREOPT;
00621 case PREOPT_DUONLY_PHASE: return RL_DU_PREOPT;
00622 case PREOPT_PHASE: return RL_PREOPT;
00623 case MAINOPT_PHASE: return RL_MAINOPT;
00624 }
00625 Is_True(FALSE,("RID_preopt_level, Preopt called by unknown phase"));
00626 return RL_UNKNOWN;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635 void REGION_add_wn_points_to(POINTS_TO_SET **pset, WN *wn,
00636 struct ALIAS_MANAGER *am)
00637 {
00638 POINTS_TO_SET *ptr;
00639
00640 if (am) {
00641 ST *st = WN_st(wn);
00642 Is_True(st != NULL && ST_class(st) != CLASS_PREG,
00643 ("REGION_add_wn_points_to, found a PREG"));
00644 Is_Trace(Get_Trace(TP_REGION,TT_REGION_BOUND_DEBUG),
00645 (TFile,"REGION_add_wn_points_to, adding wn to POINTS_TO_SET\n"));
00646 Is_Trace_cmd(Get_Trace(TP_REGION,TT_REGION_BOUND_DEBUG),
00647 fdump_tree(TFile,wn));
00648 ptr = TYPE_MEM_POOL_ALLOC(POINTS_TO_SET, ®ION_mem_pool);
00649 ptr->Next = *pset;
00650 *pset = ptr;
00651 Create_alias(am, wn);
00652 ptr->Pt = Points_to_copy(Points_to(am, wn), ®ION_mem_pool);
00653 }
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663 void REGION_add_points_to(POINTS_TO_SET **pset, POINTS_TO *pt,
00664 struct ALIAS_MANAGER *am)
00665 {
00666 POINTS_TO_SET *ptr;
00667
00668 if (am) {
00669 Is_Trace(Get_Trace(TP_REGION,TT_REGION_ALL),
00670 (TFile,"REGION_add_points_to, adding pt to POINTS_TO_SET\n"));
00671 Is_Trace_cmd(Get_Trace(TP_REGION,TT_REGION_ALL),
00672 Print_points_to(TFile,pt));
00673
00674 ptr = TYPE_MEM_POOL_ALLOC(POINTS_TO_SET, ®ION_mem_pool);
00675 ptr->Next = *pset;
00676 *pset = ptr;
00677 ptr->Pt = Points_to_copy(pt, ®ION_mem_pool);
00678 }
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688 BOOL REGION_add_preg_in(RID *rid, PREG_NUM pr, TYPE_ID quad)
00689 {
00690 BOOL ret = FALSE;
00691 Is_True(rid != NULL, ("REGION_add_preg_in, NULL RID"));
00692 #ifdef Is_True_On
00693 BOOL trace = Get_Trace(TP_REGION,TT_REGION_ALL) ||
00694 Get_Trace(TP_REGION,TT_REGION_BOUND_DEBUG);
00695 #endif
00696
00697 INT32 npregs = Preg_Increment(quad);
00698 if (npregs == 2) {
00699
00700
00701 if ((quad == MTYPE_FQ || quad == MTYPE_C8) &&
00702 !REGION_search_preg_set(RID_pregs_quad(rid), pr)) {
00703 RID_pregs_quad(rid) = PREG_LIST_Push(pr, RID_pregs_quad(rid),
00704 ®ION_mem_pool);
00705 ret = TRUE;
00706 }
00707
00708 if (!REGION_search_preg_set(RID_pregs_in(rid), pr+1)) {
00709 RID_pregs_in(rid) = PREG_LIST_Push(pr+1,RID_pregs_in(rid),
00710 ®ION_mem_pool);
00711 ret = TRUE;
00712 Is_Trace(trace, (TFile,"REGION_add_preg_in, adding quad part 2 "
00713 "PREG %d to in-set, RGN %d\n", pr+1, RID_id(rid)));
00714 }
00715 } else if (npregs == 4) {
00716 Is_True(quad == MTYPE_CQ, ("REGION_add_preg_in, not a complex quad"));
00717
00718 if (!REGION_search_preg_set(RID_pregs_complex_quad(rid), pr)) {
00719 RID_pregs_complex_quad(rid) = PREG_LIST_Push(pr,
00720 RID_pregs_complex_quad(rid),
00721 ®ION_mem_pool);
00722 ret = TRUE;
00723 }
00724
00725 for (PREG_NUM ptmp=pr+3; ptmp>=pr+1; ptmp--) {
00726 if (REGION_search_preg_set(RID_pregs_in(rid), ptmp))
00727 continue;
00728 RID_pregs_in(rid) = PREG_LIST_Push(ptmp, RID_pregs_in(rid),
00729 ®ION_mem_pool);
00730 ret = TRUE;
00731 Is_Trace(trace, (TFile,"REGION_add_preg_in, adding complex quad "
00732 "PREG %d to in-set, RGN %d\n", ptmp, RID_id(rid)));
00733 }
00734 }
00735
00736
00737 if (!REGION_search_preg_set(RID_pregs_in(rid), pr)) {
00738 RID_pregs_in(rid) = PREG_LIST_Push(pr, RID_pregs_in(rid),
00739 ®ION_mem_pool);
00740 ret = TRUE;
00741 }
00742 Is_Trace(trace && ret, (TFile,"REGION_add_preg_in, adding PREG %d (%s) "
00743 "to in-set, RGN %d\n", pr, MTYPE_name(quad),
00744 RID_id(rid)));
00745 return ret;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755 BOOL REGION_add_preg_out(RID *rid, INT32 which_set, PREG_NUM pr, TYPE_ID quad)
00756 {
00757 INT32 i;
00758 BOOL ret = FALSE;
00759 #ifdef Is_True_On
00760 BOOL trace = Get_Trace(TP_REGION,TT_REGION_ALL) ||
00761 Get_Trace(TP_REGION,TT_REGION_BOUND_DEBUG);
00762 #endif
00763
00764 Is_True(rid != NULL, ("REGION_add_preg_out, NULL RID"));
00765 Is_True(which_set >=0 && which_set < RID_num_exits(rid),
00766 ("REGION_add_preg_out, trying to add to preg set %d", which_set));
00767
00768 if (RID_pregs_out(rid) == NULL) {
00769 RID_pregs_out(rid) = TYPE_MEM_POOL_ALLOC_N(PREG_LIST *,
00770 ®ION_mem_pool, RID_num_exits(rid));
00771 for (i=0; i<RID_num_exits(rid); i++)
00772 RID_pregs_set_out_i(rid, i) = (PREG_LIST *)NULL;
00773 }
00774
00775 INT32 npregs = Preg_Increment(quad);
00776 if (npregs == 2) {
00777
00778
00779 if ((quad == MTYPE_FQ || quad == MTYPE_C8) &&
00780 !REGION_search_preg_set(RID_pregs_quad(rid), pr)) {
00781 RID_pregs_quad(rid) = PREG_LIST_Push(pr, RID_pregs_quad(rid),
00782 ®ION_mem_pool);
00783 ret = TRUE;
00784 }
00785
00786 if (!REGION_search_preg_set(RID_pregs_out_i(rid, which_set), pr+1)) {
00787 RID_pregs_set_out_i(rid, which_set) = PREG_LIST_Push(pr+1,
00788 RID_pregs_out_i(rid,which_set),
00789 ®ION_mem_pool);
00790 ret = TRUE;
00791 Is_Trace(trace, (TFile,"REGION_add_preg_out, adding quad part 2 "
00792 "PREG %d to out-set %d, RGN %d\n",
00793 pr+1, which_set, RID_id(rid)));
00794 }
00795 } else if (npregs == 4) {
00796 Is_True(quad == MTYPE_CQ, ("REGION_add_preg_in, not a complex quad"));
00797
00798 if (!REGION_search_preg_set(RID_pregs_complex_quad(rid), pr)) {
00799 RID_pregs_complex_quad(rid) = PREG_LIST_Push(pr,
00800 RID_pregs_complex_quad(rid),
00801 ®ION_mem_pool);
00802 ret = TRUE;
00803 }
00804
00805 for (PREG_NUM ptmp=pr+3; ptmp>=pr+1; ptmp--) {
00806 if (REGION_search_preg_set(RID_pregs_out_i(rid, which_set), ptmp))
00807 continue;
00808 RID_pregs_set_out_i(rid, which_set) = PREG_LIST_Push(ptmp,
00809 RID_pregs_out_i(rid,which_set),
00810 ®ION_mem_pool);
00811 ret = TRUE;
00812 Is_Trace(trace, (TFile,"REGION_add_preg_out, adding complex quad "
00813 "PREG %d to out-set %d, RGN %d\n",
00814 ptmp, which_set, RID_id(rid)));
00815 }
00816 }
00817
00818
00819 if (!REGION_search_preg_set(RID_pregs_out_i(rid, which_set), pr)) {
00820 RID_pregs_set_out_i(rid, which_set) = PREG_LIST_Push(pr,
00821 RID_pregs_out_i(rid,which_set),
00822 ®ION_mem_pool);
00823 ret = TRUE;
00824 }
00825 Is_Trace(trace && ret, (TFile,"REGION_add_preg_out, adding PREG %d (%s) "
00826 "to out-set %d, RGN %d\n",
00827 pr, MTYPE_name(quad), which_set, RID_id(rid)));
00828 return ret;
00829 }
00830
00831
00832
00833
00834
00835
00836 BOOL
00837 REGION_remove_preg(RID *rid, PREG_NUM pr, BOOL outset)
00838 {
00839 INT i;
00840 Is_True(rid != NULL, ("REGION_remove_preg, NULL RID"));
00841 Is_True(!RID_TYPE_transparent(rid), ("REGION_remove_preg, transparent RID"));
00842 Is_True(RID_bounds_exist(rid) == REGION_BOUND_EXISTS,
00843 ("REGION_remove_preg, region bounds do not exist"));
00844
00845 if (outset) {
00846
00847 if (RID_pregs_out(rid) == NULL)
00848 return FALSE;
00849
00850
00851 for (i=0; i<RID_num_exits(rid); i++) {
00852
00853 RID_pregs_set_out_i(rid,i) = PREG_LIST_Delete(pr,
00854 RID_pregs_set_out_i(rid,i));
00855 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00856 (TFile,"REGION_remove_preg(RGN %d), removing PREG %d "
00857 "from out-set %d\n", RID_id(rid), pr, i));
00858
00859
00860 if (REGION_search_preg_set(RID_pregs_quad(rid), pr)) {
00861 RID_pregs_set_out_i(rid,i) = PREG_LIST_Delete(pr+1,
00862 RID_pregs_set_out_i(rid,i));
00863 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00864 (TFile,"REGION_remove_preg(RGN %d), removing quad part 2 "
00865 "PREG %d from out-set %d\n", RID_id(rid), pr+1, i));
00866
00867
00868 }
00869
00870
00871 if (REGION_search_preg_set(RID_pregs_complex_quad(rid), pr)) {
00872 for (PREG_NUM ptmp=pr+1; ptmp<pr+4; ptmp++) {
00873 RID_pregs_set_out_i(rid,i) = PREG_LIST_Delete(ptmp,
00874 RID_pregs_set_out_i(rid,i));
00875 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00876 (TFile,"REGION_remove_preg(RGN %d), removing complex quad "
00877 "PREG %d from out-set %d\n", RID_id(rid), ptmp, i));
00878 }
00879
00880
00881 }
00882
00883 }
00884
00885 } else {
00886
00887 if (RID_pregs_in(rid) == NULL)
00888 return FALSE;
00889
00890 RID_pregs_in(rid) = PREG_LIST_Delete(pr, RID_pregs_in(rid));
00891 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00892 (TFile,"REGION_remove_preg(RGN %d), removing PREG %d "
00893 "from in-set\n", RID_id(rid), pr));
00894
00895
00896 if (REGION_search_preg_set(RID_pregs_quad(rid), pr)) {
00897 RID_pregs_in(rid) = PREG_LIST_Delete(pr+1, RID_pregs_in(rid));
00898 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00899 (TFile,"REGION_remove_preg(RGN %d), removing quad part 2 "
00900 "PREG %d from in-set\n", RID_id(rid), pr+1));
00901
00902
00903 }
00904
00905
00906 if (REGION_search_preg_set(RID_pregs_complex_quad(rid), pr)) {
00907 for (PREG_NUM ptmp=pr+1; ptmp<pr+4; ptmp++) {
00908 RID_pregs_in(rid) = PREG_LIST_Delete(pr+1, RID_pregs_in(rid));
00909 Is_Trace(Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00910 (TFile,"REGION_remove_preg(RGN %d), removing complex quad "
00911 "PREG %d from in-set\n", RID_id(rid), ptmp));
00912 }
00913
00914
00915 }
00916
00917 }
00918 return TRUE;
00919 }
00920
00921
00922
00923
00924
00925
00926 WN *
00927 REGION_add_exit(WN *block, WN *after, WN *region)
00928 {
00929 WN *wn_label, *wn_exit, *wn_last;
00930
00931 LABEL_IDX label;
00932 New_LABEL(CURRENT_SYMTAB, label);
00933 wn_label = WN_CreateLabel(label, 0, NULL);
00934 WN_Set_Linenum(wn_label, (after) ? WN_Get_Linenum(after) :
00935 WN_Get_Linenum(block));
00936
00937 WN_INSERT_BlockBefore(block, after, wn_label);
00938
00939
00940 wn_exit = WN_CreateRegionExit (label);
00941 wn_last = WN_last(WN_region_body(region));
00942 WN_Set_Linenum(wn_exit, WN_Get_Linenum(wn_last));
00943 WN_INSERT_BlockAfter(WN_region_body(region), wn_last, wn_exit);
00944
00945 return wn_label;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954 void
00955 REGION_delete_exit(RID *rid, INT32 label, WN *exit_block, BOOL recursive_call)
00956 {
00957 WN *wtmp;
00958 INT32 which_set = 0;
00959 BOOL found = FALSE;
00960
00961 Is_True(RID_num_exits(rid) > 0,
00962 ("REGION_delete_exit, no exit to remove, RGN %d",RID_id(rid)));
00963 Is_Trace(Get_Trace(TP_REGION, TT_REGION_ALL), (TFile,
00964 "REGION_delete_exit, REGION_EXIT L%d from RGN %d, #exits %d\n",
00965 label, RID_id(rid), RID_num_exits(rid)));
00966
00967
00968 Is_True (WN_first(exit_block) != NULL,("REGION_delete_exit, no exit block"));
00969 for (wtmp=WN_first(exit_block); wtmp; wtmp=WN_next(wtmp)) {
00970 Is_True(WN_opcode(wtmp) == OPC_REGION_EXIT,
00971 ("REGION_delete_exit, illegal opcode in exit block"));
00972 if (WN_label_number(wtmp) == label) {
00973
00974 WN_DELETE_FromBlock(exit_block, wtmp);
00975
00976 if (RID_pregs_out(rid) != NULL) {
00977 INT32 i;
00978 for (i=which_set; i<RID_num_exits(rid)-1; i++)
00979 RID_pregs_set_out_i(rid, i) = RID_pregs_out_i(rid, i+1);
00980 }
00981
00982 RID_num_exits(rid)--;
00983 found = TRUE;
00984 }
00985 which_set++;
00986 }
00987
00988
00989 if (recursive_call == FALSE)
00990 Is_True(found == TRUE,
00991 ("REGION_delete_exit, region exit not found, RGN %d, label %d",
00992 RID_id(rid), label));
00993
00994
00995 if (found) {
00996 RID *parent_rid = RID_parent(rid);
00997 WN *parent_wn;
00998
00999 Is_True(parent_rid != NULL, ("REGION_delete_exit, could not find parent"));
01000 parent_wn = RID_rwn(parent_rid);
01001
01002
01003
01004 if (RID_TYPE_func_entry(parent_rid) || parent_wn == NULL)
01005 return;
01006 Is_True(parent_wn != NULL &&
01007 (WN_opcode(parent_wn) == OPC_FUNC_ENTRY ||
01008 WN_opcode(parent_wn) == OPC_REGION),
01009 ("REGION_delete_exit, parent RID has invalid WHIRL"));
01010 exit_block = WN_region_exits(parent_wn);
01011 Is_True(exit_block != NULL && WN_opcode(exit_block) == OPC_BLOCK,
01012 ("REGION_delete_exit, parent exit block is malformed"));
01013 REGION_delete_exit(parent_rid, label, exit_block, TRUE);
01014 }
01015 }
01016
01017
01018
01019
01020 void
01021 REGION_propagate_return(RID *rid)
01022 {
01023 RID *rtmp;
01024
01025 for (rtmp=rid; rtmp; rtmp=RID_parent(rtmp)) {
01026 if (RID_has_return(rtmp) == REGION_NO_RETURN) {
01027 RID_has_return(rtmp) = REGION_RETURN;
01028 if (Get_Trace(TP_REGION,TT_REGION_ALL))
01029 fprintf(TFile,"REGION_propagate_return(RGN %d)\n",RID_id(rtmp));
01030 }
01031 }
01032 }
01033
01034
01035
01036
01037 char *RID_level_str(RID *rid)
01038 {
01039 static char buff[20];
01040
01041 switch (RID_level(rid)) {
01042 case RL_UNKNOWN: strcpy(buff,"RL_UNKNOWN"); break;
01043 case RL_SRC: strcpy(buff,"RL_SRC"); break;
01044 case RL_MP: strcpy(buff,"RL_MP"); break;
01045 case RL_RGN_INIT: strcpy(buff,"RL_RGN_INIT"); break;
01046 case RL_LNO_PREOPT: strcpy(buff,"RL_LNO_PREOPT"); break;
01047 case RL_LNO: strcpy(buff,"RL_LNO"); break;
01048 case RL_RAIL: strcpy(buff,"RL_RAIL"); break;
01049 case RL_RBI: strcpy(buff,"RL_RBI"); break;
01050 case RL_PREOPT: strcpy(buff,"RL_PREOPT"); break;
01051 case RL_MAINOPT: strcpy(buff,"RL_MAINOPT"); break;
01052 case RL_RVI1: strcpy(buff,"RL_RVI1"); break;
01053 case RL_RVI2: strcpy(buff,"RL_RVI2"); break;
01054 case RL_CG: strcpy(buff,"RL_CG"); break;
01055 case RL_CGSCHED: strcpy(buff,"RL_CGSCHED"); break;
01056 default:
01057 strcpy(buff,"ILLEGAL");
01058 Is_True(FALSE,("RID_level_str, internal inconsistency"));
01059 break;
01060 }
01061 return buff;
01062 }
01063
01064
01065
01066
01067 char *RID_type_str(RID_TYPE type)
01068 {
01069 static char buff[100];
01070
01071 buff[0] = '\0';
01072
01073 if (type & RID_TYPE_func_entry)
01074 strcat(buff," FUNC_ENTRY");
01075 if (type & RID_TYPE_loop)
01076 strcat(buff," LOOP");
01077 if (type & RID_TYPE_pragma)
01078 strcat(buff," PRAGMA");
01079 if (type & RID_TYPE_olimit)
01080 strcat(buff," OLIMIT");
01081 if (type & RID_TYPE_mp)
01082 strcat(buff," MP");
01083 if (type & RID_TYPE_rpi)
01084 strcat(buff," RPI");
01085 if (type & RID_TYPE_cold)
01086 strcat(buff," COLD");
01087 if (type & RID_TYPE_swp)
01088 strcat(buff," SWP");
01089 #ifdef TARG_SL //fork_joint
01090 if (type & RID_TYPE_major)
01091 strcat(buff," SL2_MAJOR");
01092 if(type & RID_TYPE_minor)
01093 strcat(buff, "SL2_MINOR");
01094 #endif
01095 if (type & RID_TYPE_try)
01096 strcat(buff," TRY");
01097 if (type & RID_TYPE_cleanup)
01098 strcat(buff," CLEANUP");
01099 if (type & RID_TYPE_exc_spec)
01100 strcat(buff," EXC_SPEC");
01101 if (type & RID_TYPE_mask)
01102 strcat(buff," MASK");
01103 if (type & RID_TYPE_guard)
01104 strcat(buff," GUARD");
01105 if (type & RID_TYPE_null_cleanup)
01106 strcat(buff," NULL_CLEANUP");
01107
01108 if (type & RID_TYPE_eh)
01109 strcat(buff," EH");
01110
01111 if (type == RID_TYPE_undefined)
01112 strcpy(buff," UNDEFINED");
01113
01114 return buff;
01115 }
01116
01117
01118
01119
01120
01121 static void RID_lower_Fprint(FILE *FD, LOWER_ACTIONS actions)
01122 {
01123 UINT64 i = 1;
01124
01125 while(actions) {
01126 if (actions & i) {
01127 fprintf(FD, "%s ", LOWER_ACTIONS_name( i ));
01128 actions = actions ^ i;
01129 }
01130 i <<= 1;
01131 }
01132 fprintf(FD, "\n");
01133 }
01134
01135
01136
01137
01138 static void
01139 Dump_preg_list(FILE *FD, PREG_LIST *plist)
01140 {
01141 PREG_LIST *ptmp;
01142 PREG_NUM pr;
01143 INT count = 0;
01144
01145 if (plist)
01146 fprintf(FD," ");
01147 for (ptmp = plist; ptmp; ptmp = PREG_LIST_rest(ptmp)) {
01148 pr = PREG_LIST_first(ptmp);
01149 fprintf(FD,"%d ",pr);
01150 if (++count >= 10 && PREG_LIST_rest(ptmp) != NULL) {
01151 count = 0;
01152 fprintf(FD,"\n ");
01153 }
01154 }
01155 if (plist)
01156 fprintf(FD,"\n");
01157 }
01158
01159 static void
01160 Dump_points_to_list(FILE *FD, POINTS_TO_SET *ptset, const char *str)
01161 {
01162 fprintf(FD," %s\n",str);
01163 if (ptset == NULL)
01164 fprintf(FD," NULL\n");
01165 else {
01166 POINTS_TO_SET *ptmp;
01167 for (ptmp=ptset; ptmp; ptmp=ptmp->Next) {
01168 fprintf(FD," ");
01169 Print_points_to(FD,ptmp->Pt);
01170 }
01171 }
01172 }
01173
01174
01175 static void
01176 Dump_region_exits(FILE *FD, WN *exit_blk)
01177 {
01178 WN *wtmp;
01179 Is_True(WN_opcode(exit_blk) == OPC_BLOCK,
01180 ("Dump_region_exits, illegal input"));
01181 if (WN_first(exit_blk) != NULL) {
01182 fprintf(FD," region exits: ");
01183 for (wtmp=WN_first(exit_blk); wtmp; wtmp=WN_next(wtmp))
01184 fprintf(FD,"L%d ",WN_label_number(wtmp));
01185 fprintf(FD,"\n");
01186 }
01187 }
01188
01189
01190
01191
01192
01193
01194 void RID_set_print(FILE *FD, RID *rid)
01195 {
01196 Is_True(rid != NULL,("RID_set_print, inconsistency in RID"));
01197
01198 fprintf(FD,
01199 "===== RID_set_print(%s %d), num_exits %d, has_return=%c, "
01200 "bounds_defined=%c, parent_block=0x%p\n",
01201 RID_TYPE_func_entry(rid) ? "PU" : "RGN", RID_id(rid),
01202 RID_num_exits(rid), tf(RID_has_return(rid)),
01203 tf(RID_bounds_exist(rid)), RID_parent_block(rid));
01204 fprintf(FD, " aliased_to_globals=%c, aliased_to_indirects=%c, "
01205 "contains_uplevel=%c\n contains_bounds=%c, contains_barrier=%c\n",
01206 tf(RID_aliased_to_globals(rid)), tf(RID_aliased_to_indirects(rid)),
01207 tf(RID_contains_uplevel(rid)), tf(RID_contains_bounds(rid)),
01208 tf(RID_contains_barrier(rid)));
01209
01210
01211 fprintf(FD," pregs_in:\n");
01212 Dump_preg_list(FD, RID_pregs_in(rid));
01213
01214
01215 if (RID_pregs_out(rid) != NULL) {
01216 INT32 nexits;
01217 for (nexits = 0; nexits < RID_num_exits(rid); nexits++) {
01218 fprintf(FD," pregs_out(exit %d):\n",nexits);
01219 Dump_preg_list(FD, RID_pregs_out(rid)[nexits]);
01220 }
01221 }
01222
01223
01224 if (RID_pregs_quad(rid) != NULL) {
01225 fprintf(FD," pregs_quad:\n");
01226 Dump_preg_list(FD, RID_pregs_quad(rid));
01227 }
01228
01229
01230 if (RID_pregs_complex_quad(rid) != NULL) {
01231 fprintf(FD," pregs_complex_quad:\n");
01232 Dump_preg_list(FD, RID_pregs_complex_quad(rid));
01233 }
01234
01235
01236 Dump_points_to_list(FD, RID_used_in(rid), "used_in:");
01237
01238
01239 Dump_points_to_list(FD, RID_def_in_live_out(rid), "def_in_live_out:");
01240
01241
01242 if (RID_first_kid(rid) != NULL) {
01243 RID *rtmp;
01244 for (rtmp=RID_first_kid(rid); rtmp; rtmp=RID_next(rtmp))
01245 RID_set_print(FD,rtmp);
01246 }
01247 }
01248
01249
01250
01251
01252
01253
01254 void RID_Fprint(FILE *FD, RID *rid)
01255 {
01256 INT id, depth;
01257 char *level, *type;
01258 BOOL bound, ret;
01259 SRCPOS s;
01260 USRCPOS us;
01261 UINT32 flags;
01262 RID *kid;
01263 WN *rwn;
01264
01265 id = RID_id(rid);
01266 depth = RID_depth(rid);
01267 level = RID_level_str(rid);
01268 type = RID_type_str(RID_type(rid));
01269 bound = RID_bounds_exist(rid);
01270 ret = RID_has_return(rid);
01271 flags = RID_flags(rid);
01272 s = RID_srcpos(rid);
01273 USRCPOS_srcpos(us) = s;
01274
01275
01276 rwn = RID_rwn(rid);
01277 if (rwn != NULL && WN_region_id(rwn) != id)
01278 fprintf(TFile,"**** RID_Fprint: RID_id = %d, WN_region_id = %d\n",
01279 id, WN_region_id(rwn));
01280
01281
01282 fprintf(FD, "RID %d: loop depth %d, processed to %s, linenum %d,\n",
01283 id, depth, level, USRCPOS_linenum(us));
01284 fprintf(FD, " exits %d, flags 0x%x, type%s, parent RID %d\n",
01285 RID_num_exits(rid), flags, type,
01286 RID_parent(rid) ? RID_id(RID_parent(rid)) : -1);
01287 fprintf(FD, " parent_block=0x%p, cginfo=0x%p, has_return=%c, "
01288 "bounds_defined=%c\n", RID_parent_block(rid),
01289 RID_cginfo(rid), tf(ret), tf(bound == REGION_BOUND_EXISTS));
01290 fprintf(FD, " aliased_to_globals=%c, aliased_to_indirects=%c, "
01291 "contains_uplevel=%c\n contains_bounds=%c, contains_barrier=%c\n",
01292 tf(RID_aliased_to_globals(rid)), tf(RID_aliased_to_indirects(rid)),
01293 tf(RID_contains_uplevel(rid)), tf(RID_contains_bounds(rid)),
01294 tf(RID_contains_barrier(rid)));
01295
01296
01297 if (RID_options(rid) != NULL)
01298 fprintf(FD, " options=%s\n", RID_options(rid));
01299
01300
01301 if (!RID_TYPE_func_entry(rid) && RID_rwn(rid)) {
01302 INT32 count = REGION_count_exits(WN_region_exits(RID_rwn(rid)));
01303 Dump_region_exits(FD, WN_region_exits(RID_rwn(rid)));
01304 Is_True(count == RID_num_exits(rid),
01305 ("# exits mismatch in RGN%d: num_exits=%d, actual=%d",
01306 RID_id(rid), RID_num_exits(rid), count));
01307 }
01308
01309
01310 for (kid=RID_first_kid(rid); kid; kid=RID_next(kid)) {
01311 if (kid == RID_first_kid(rid))
01312 fprintf(FD," kids: ");
01313 fprintf(FD,"RID%d ",RID_id(kid));
01314 if (RID_next(kid) == NULL)
01315 fprintf(FD,"\n");
01316 if (RID_lowered(rid))
01317 RID_lower_Fprint(FD, RID_lowered(rid));
01318 }
01319 if (RID_next(rid) != NULL) {
01320 fprintf(FD," next: RID%d\n",RID_id(RID_next(rid)));
01321 }
01322 }
01323
01324
01325
01326
01327 void RID_Tree_Print(FILE *FD, RID *rid)
01328 {
01329 if (rid) {
01330 RID *kid;
01331 RID_Fprint(FD,rid);
01332 for (kid=RID_first_kid(rid); kid; kid=RID_next(kid))
01333 RID_Tree_Print(FD,kid);
01334 }
01335 }
01336
01337
01338
01339
01340 void RID_WN_Tree_Print(FILE *FD, WN *tree)
01341 {
01342 RID *rid = REGION_get_rid(tree);
01343 RID_Tree_Print(FD, rid);
01344 }
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 static void update_parent_block(WN *block, WN *wn)
01359 {
01360 RID *rid;
01361 WN *wtmp;
01362 INT i;
01363
01364 switch (WN_opcode(wn)) {
01365
01366 case OPC_BLOCK:
01367 for (wtmp=WN_first(wn); wtmp; wtmp=WN_next(wtmp))
01368 update_parent_block(wn, wtmp);
01369 break;
01370
01371 case OPC_REGION:
01372 Is_True(block != NULL, ("update_parent_block, block is NULL"));
01373 rid = REGION_get_rid(wn);
01374 Is_True(rid != NULL, ("update_parent_block, NULL rid"));
01375 RID_parent_block(rid) = block;
01376
01377 if (RID_first_kid(rid) != NULL) {
01378 for (wtmp=WN_first(WN_region_body(wn)); wtmp; wtmp=WN_next(wtmp))
01379 update_parent_block(WN_region_body(wn), wtmp);
01380 }
01381 break;
01382
01383 case OPC_FUNC_ENTRY:
01384 Is_True (PU_has_region (Get_Current_PU ()),
01385 ("update_parent_block, no regions"));
01386 Is_True(block == NULL, ("update_parent_block, block is not NULL"));
01387 rid = REGION_get_rid(wn);
01388 Is_True(rid != NULL, ("update_parent_block, NULL rid"));
01389 RID_parent_block(rid) = NULL;
01390
01391 if (RID_first_kid(rid) != NULL) {
01392 for (wtmp=WN_first(WN_func_body(wn)); wtmp; wtmp=WN_next(wtmp))
01393 update_parent_block(WN_func_body(wn), wtmp);
01394 }
01395 break;
01396
01397 default:
01398
01399
01400 for (i=0; i<WN_kid_count(wn); i++)
01401 update_parent_block(NULL, WN_kid(wn,i));
01402 break;
01403 }
01404 }
01405
01406
01407
01408
01409 void REGION_CS_ITER_init(REGION_CS_ITER *iter, WN *pu)
01410 {
01411 INT32 i;
01412
01413 REGION_CS_ITER_me(iter) = NULL;
01414 REGION_CS_ITER_kid(iter) = NULL;
01415 REGION_CS_ITER_type(iter) = RID_TYPE_undefined;
01416 REGION_CS_ITER_is_pu(iter) = FALSE;
01417 REGION_CS_ITER_is_not_stacked(iter) = FALSE;
01418 REGION_CS_ITER_sp(iter) = 0;
01419 for (i=0; i<REGION_STACK_SIZE; i++)
01420 REGION_CS_ITER_marker(iter,i) = NULL;
01421
01422
01423
01424 if (PU_has_region (Get_Current_PU ()))
01425 update_parent_block(NULL, pu);
01426 }
01427
01428
01429
01430
01431
01432
01433 BOOL REGION_CS_NoEarlierSub_While(REGION_CS_ITER *iter)
01434 {
01435 return (!REGION_CS_ITER_is_not_stacked(iter) &&
01436 REGION_CS_ITER_kid(iter) != NULL);
01437 }
01438
01439
01440
01441
01442
01443
01444 static void
01445 REGION_CS_Next(REGION_CS_ITER *iter)
01446 {
01447 RID *me = REGION_CS_ITER_me(iter);
01448 RID *kid = REGION_CS_ITER_kid(iter);
01449 RID_TYPE type = REGION_CS_ITER_type(iter);
01450 RID *parent = (me != NULL) ? RID_parent(me) : NULL;
01451 Is_True(type & RID_TYPE_loop || type & RID_TYPE_pragma ||
01452 #ifdef TARG_SL
01453 type & RID_TYPE_olimit || type & RID_TYPE_func_entry || type & RID_TYPE_major ||
01454 #else
01455 type & RID_TYPE_olimit || type & RID_TYPE_func_entry ||
01456 #endif
01457 type & RID_TYPE_eh,
01458 ("REGION_CS_Next, unknown region type, 0x%x",type));
01459
01460 if (me == NULL) {
01461 REGION_CS_ITER_kid(iter) = NULL;
01462 return;
01463 }
01464
01465 if (kid == NULL) {
01466 if (RID_first_kid(me) == NULL) {
01467 REGION_CS_ITER_kid(iter) = me;
01468 REGION_CS_ITER_me(iter) = parent;
01469 } else {
01470 REGION_CS_ITER_kid(iter) = NULL;
01471 REGION_CS_ITER_me(iter) = RID_first_kid(me);
01472 REGION_CS_Next(iter);
01473 }
01474 } else {
01475 if (RID_next(kid)) {
01476 if (RID_first_kid(RID_next(kid))) {
01477 REGION_CS_ITER_kid(iter) = NULL;
01478 REGION_CS_ITER_me(iter) = RID_next(kid);
01479 REGION_CS_Next(iter);
01480 } else
01481 REGION_CS_ITER_kid(iter) = RID_next(kid);
01482 } else if (RID_is_glue_code(RID_parent(kid))
01483 && RID_next(RID_parent(kid)) != NULL)
01484 {
01485
01486 REGION_CS_ITER_kid(iter) = RID_parent(kid);
01487 REGION_CS_Next(iter);
01488 } else {
01489 REGION_CS_ITER_kid(iter) = me;
01490 REGION_CS_ITER_me(iter) = parent;
01491 }
01492 }
01493 }
01494
01495
01496
01497
01498
01499 void REGION_CS_NoEarlierSub_Next(REGION_CS_ITER *iter)
01500 {
01501 BOOL done;
01502
01503
01504 do {
01505 done = TRUE;
01506 REGION_CS_Next(iter);
01507 if (REGION_CS_ITER_kid(iter) != NULL) {
01508 RID *rid;
01509 rid = REGION_CS_ITER_kid(iter);
01510
01511 Is_True(RID_type(rid) != RID_TYPE_undefined,
01512 ("REGION_CS_NoEarlierSub_Next, undefined RID type"));
01513 #ifdef Is_True_On
01514 {
01515 WN *rwn;
01516 RID *rid2;
01517 rwn = REGION_CS_ITER_wn(iter);
01518 Is_True(rwn != NULL, ("REGION_CS_NoEarlierSub_Next, NULL rwn"));
01519 rid2 = REGION_get_rid(rwn);
01520 Is_True(rid2 != NULL, ("REGION_CS_NoEarlierSub_Next, NULL rid"));
01521 Is_True(REGION_consistency_check(rwn), (""));
01522 Is_True(rid2 == rid,
01523 ("REGION_CS_NoEarlierSub_Next, RIDs do not match"));
01524 Is_True(RID_type(rid2) != RID_TYPE_undefined,
01525 ("REGION_CS_NoEarlierSub_Next, undefined RID type"));
01526 }
01527 #endif
01528 if (!(RID_type(rid) & REGION_CS_ITER_type(iter) ||
01529 RID_type(rid) & RID_TYPE_func_entry))
01530 done = FALSE;
01531 }
01532 } while (!done);
01533 }
01534
01535
01536
01537
01538
01539
01540 void REGION_CS_NoEarlierSub_First(REGION_CS_ITER *iter, WN *tree,
01541 RID_TYPE type)
01542 {
01543 RID *my_rid;
01544
01545 my_rid = (RID*)WN_MAP_Get(RID_map, tree);
01546 Is_True(my_rid != NULL, ("REGION_CS_NoEarlierSub_First, can't find region"));
01547
01548 REGION_CS_ITER_me(iter) = my_rid;
01549 REGION_CS_ITER_kid(iter) = (RID *)NULL;
01550 REGION_CS_ITER_type(iter) = type;
01551
01552
01553
01554
01555
01556 REGION_CS_NoEarlierSub_Next(iter);
01557 }
01558
01559
01560
01561
01562 void REGION_CS_print(REGION_CS_ITER *iter)
01563 {
01564 #ifdef Is_True_On
01565 fprintf(TFile, "me = RGN %d\n", iter->me ? RID_id(iter->me) : -1);
01566 fprintf(TFile, "kid = RGN %d\n", iter->kid ? RID_id(iter->kid) : -1);
01567 fprintf(TFile, "type = %s\n", RID_type_str(iter->type));
01568 fprintf(TFile, "parent_block = 0x%p\n", iter->parent_block);
01569 fprintf(TFile, "is_pu = %c\n", tf(iter->is_pu));
01570 fprintf(TFile, "is_not_stacked = %c\n", tf(iter->is_not_stacked));
01571 #endif
01572 }
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584 WN *REGION_remove_and_mark(WN *pu, REGION_CS_ITER *iter)
01585 {
01586 WN *new_rwn, *rwn;
01587
01588 rwn = REGION_CS_ITER_wn(iter);
01589
01590 if (pu == rwn || rwn == NULL || WN_opcode(rwn) == OPC_FUNC_ENTRY) {
01591 if (WN_opcode(pu) == OPC_FUNC_ENTRY)
01592 REGION_CS_ITER_is_pu(iter) = TRUE;
01593 REGION_CS_ITER_is_not_stacked(iter) = TRUE;
01594 return pu;
01595 }
01596
01597 Is_True(REGION_consistency_check(pu), (""));
01598 Is_True(REGION_consistency_check(rwn), (""));
01599 Is_True(WN_opcode(rwn) == OPC_REGION,
01600 ("REGION_remove_and_mark, can't find region"));
01601
01602
01603 Is_True(RID_parent_block(REGION_get_rid(rwn)),
01604 ("REGION_remove_and_mark, parent_block not set"));
01605 REGION_CS_ITER_parent_block(iter) = RID_parent_block(REGION_get_rid(rwn));
01606
01607 RID_parent_block(REGION_get_rid(rwn)) = NULL;
01608
01609
01610 new_rwn = WN_CopyNode(rwn);
01611 #if defined(TARG_SL)
01612 WN_CopyMap(new_rwn,WN_MAP_FEEDBACK,rwn);
01613 #endif
01614 WN_region_exits(new_rwn) = WN_region_exits(rwn);
01615 WN_region_pragmas(new_rwn) = WN_region_pragmas(rwn);
01616 WN_region_body(new_rwn) = WN_region_body(rwn);
01617
01618 REGION_new_wn(new_rwn, rwn);
01619
01620
01621 REGION_CS_ITER_marker(iter,REGION_CS_ITER_sp(iter)++) = rwn;
01622 FmtAssert(REGION_CS_ITER_sp(iter) < REGION_STACK_SIZE,
01623 ("REGION_remove_and_mark, region stack overflow"));
01624
01625
01626
01627 {
01628 WN *new_cmt, *new_blk = WN_CreateBlock();
01629 char str[100];
01630 sprintf(str,"REGION %d currently being processed",
01631 RID_id(REGION_get_rid(rwn)));
01632 new_cmt = WN_CreateComment(str);
01633 WN_INSERT_BlockBefore(new_blk,NULL,new_cmt);
01634 WN_region_body(rwn) = new_blk;
01635 WN_region_exits(rwn) = WN_CreateBlock();
01636 WN_region_pragmas(rwn) = WN_CreateBlock();
01637 }
01638
01639 Is_True(REGION_consistency_check(pu),(""));
01640 Is_True(REGION_consistency_check(new_rwn),(""));
01641 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01642 fprintf(TFile,"===== REGION_remove_and_mark RGN %d\n",
01643 RID_id(REGION_get_rid(new_rwn)));
01644 }
01645
01646 WN_verifier(rwn);
01647 WN_verifier(new_rwn);
01648 return new_rwn;
01649 }
01650
01651
01652
01653
01654
01655 void REGION_replace_from_mark(WN *rwn, REGION_CS_ITER *iter)
01656 {
01657 WN *r_marker;
01658
01659
01660
01661 if (REGION_CS_ITER_is_not_stacked(iter) || rwn == NULL)
01662 return;
01663
01664 --REGION_CS_ITER_sp(iter);
01665 FmtAssert(REGION_CS_ITER_sp(iter) >= 0,
01666 ("REGION_replace_from_mark, region stack underflow"));
01667 r_marker = REGION_CS_ITER_marker(iter, REGION_CS_ITER_sp(iter));
01668 REGION_CS_ITER_marker(iter,REGION_CS_ITER_sp(iter)) = NULL;
01669
01670
01671 if (WN_operator(rwn) == OPR_BLOCK) {
01672 WN *wtmp;
01673 BOOL found = FALSE;
01674 WN *parent_block = REGION_CS_ITER_parent_block(iter);
01675 Is_True(parent_block != NULL,
01676 ("REGION_replace_from_mark, parent_block not set"));
01677 Is_True(WN_opcode(r_marker) == OPC_REGION,
01678 ("REGION_replace_from_mark, marker is wrong"));
01679
01680 #ifdef Is_True_On
01681
01682 for (wtmp=WN_first(parent_block); wtmp!=NULL && !found; wtmp=WN_next(wtmp))
01683 found = (wtmp == r_marker);
01684 Is_True(found, ("REGION_replace_from_mark, marker not found"));
01685 #endif
01686
01687
01688 WN_INSERT_BlockAfter(parent_block, r_marker, rwn);
01689
01690
01691 WN_DELETE_Tree(WN_region_body(r_marker));
01692 WN_region_exits(r_marker) = NULL;
01693 WN_region_pragmas(r_marker) = NULL;
01694 WN_region_body(r_marker) = NULL;
01695
01696
01697 WN_DELETE_FromBlock(parent_block, r_marker);
01698 } else {
01699
01700 Is_True(WN_operator(rwn) == OPR_REGION,
01701 ("REGION_replace_from_mark, not a region"));
01702 Is_True(REGION_consistency_check(rwn), (""));
01703
01704
01705 WN_region_exits(r_marker) = WN_region_exits(rwn);
01706 WN_region_pragmas(r_marker) = WN_region_pragmas(rwn);
01707 WN_region_body(r_marker) = WN_region_body(rwn);
01708
01709
01710 WN_region_exits(rwn) = NULL;
01711 WN_region_pragmas(rwn) = NULL;
01712 WN_region_body(rwn) = NULL;
01713
01714
01715 WN_set_region_kind(r_marker, WN_region_kind(rwn));
01716 WN_set_region_id(r_marker, WN_region_id(rwn));
01717
01718
01719 REGION_new_wn(r_marker, rwn);
01720
01721 Is_True(REGION_consistency_check(r_marker), (""));
01722 if (Get_Trace(TP_REGION, TT_REGION_ALL)) {
01723 fprintf(TFile,"===== REGION_replace_from_mark RGN %d, stacked=1\n",
01724 RID_id(REGION_get_rid(r_marker)));
01725 }
01726 }
01727 }
01728
01729
01730
01731
01732
01733 char *REGION_get_options_string(WN *wn)
01734 {
01735 WN *wtmp;
01736 Is_True(WN_opcode(wn) == OPC_REGION || WN_opcode(wn) == OPC_FUNC_ENTRY,
01737 ("REGION_get_options_string, unexpected WN"));
01738
01739
01740 wtmp = REGION_search_block(
01741 (WN_opcode(wn) == OPC_REGION) ? WN_region_pragmas(wn) : WN_func_pragmas(wn),
01742 comp_same_pragma(WN_PRAGMA_OPTIONS));
01743
01744 if (wtmp == NULL)
01745 return NULL;
01746
01747
01748 ST *st = WN_st(wtmp);
01749 Is_True(st != NULL, ("REGION_get_options_string, NULL st"));
01750 Is_True (ST_tcon(st) != 0, ("REGION_get_options_string, NULL tcon"));
01751 TCON *tc = &Tcon_Table[ST_tcon (st)];
01752 char *s = Targ_String_Address(*tc);
01753 Is_True(s != NULL, ("REGION_get_options_string, NULL string"));
01754 Is_True(strlen(s) == Targ_String_Length(*tc),
01755 ("REGION_get_options_string, wrong string length"));
01756 if (*s == '\0')
01757 s = NULL;
01758 return s;
01759 }
01760
01761
01762
01763
01764
01765 BOOL REGION_is_EH(WN * wn)
01766 {
01767 #ifdef Is_True_On
01768 if (WN_region_kind(wn) & REGION_KIND_EH) {
01769 RID *rid = REGION_get_rid(wn);
01770 if (rid)
01771 Is_True(RID_TYPE_eh(rid) &&
01772 (RID_TYPE_try(rid) || RID_TYPE_cleanup(rid) ||
01773 RID_TYPE_exc_spec(rid) || RID_TYPE_mask(rid) ||
01774 RID_TYPE_guard(rid) || RID_TYPE_null_cleanup(rid)),
01775 ("REGION_is_EH, region type/kind inconsistency"));
01776 }
01777 #endif
01778 return WN_region_kind(wn) & REGION_KIND_EH;
01779 }
01780
01781
01782 BOOL REGION_is_mp(WN * wn)
01783 {
01784 #ifdef Is_True_On
01785 if (WN_region_kind(wn) == REGION_KIND_MP) {
01786 RID *rid = REGION_get_rid(wn);
01787 if (rid)
01788 Is_True(RID_TYPE_mp(rid),
01789 ("REGION_is_mp, region type/kind inconsistency"));
01790 }
01791 #endif
01792 return WN_region_kind(wn) == REGION_KIND_MP;
01793 }
01794
01795 #if defined(TARG_SL)
01796
01797 BOOL REGION_is_sl2_para(WN * wn)
01798 {
01799 if (WN_region_kind(wn) == REGION_KIND_MAJOR ||
01800 WN_region_kind(wn) == REGION_KIND_MINOR) {
01801
01802 RID *rid = REGION_get_rid(wn);
01803 if (rid)
01804 Is_True(RID_TYPE_sl2_para(rid),
01805 ("REGION_is_sl2_para, region type/kind inconsistency"));
01806 }
01807 return (WN_region_kind(wn) == REGION_KIND_MAJOR ||
01808 WN_region_kind(wn) == REGION_KIND_MINOR);
01809 }
01810 #endif
01811
01812 REGION_KIND REGION_type_to_kind(RID *rid)
01813 {
01814 Is_True(rid != NULL, ("REGION_type_to_kind, NULL RID"));
01815
01816 if (RID_type(rid) & RID_TYPE_func_entry)
01817 return REGION_KIND_FUNC_ENTRY;
01818 if (RID_type(rid) & RID_TYPE_loop)
01819 return REGION_KIND_LOOP;
01820 if (RID_type(rid) & RID_TYPE_pragma)
01821 return REGION_KIND_PRAGMA;
01822 if (RID_type(rid) & RID_TYPE_olimit)
01823 return REGION_KIND_OLIMIT;
01824 if (RID_type(rid) & RID_TYPE_mp)
01825 return REGION_KIND_MP;
01826 if (RID_type(rid) & RID_TYPE_rpi)
01827 return REGION_KIND_RPI;
01828 if (RID_type(rid) & RID_TYPE_cold)
01829 return REGION_KIND_COLD;
01830 if (RID_type(rid) & RID_TYPE_swp)
01831 return REGION_KIND_SWP;
01832 #ifdef TARG_SL //fork_joint
01833 if (RID_type(rid) & RID_TYPE_major)
01834 return REGION_KIND_MAJOR;
01835 if(RID_type(rid) & RID_TYPE_minor)
01836 return REGION_KIND_MINOR;
01837 #endif
01838 if (RID_type(rid) & RID_TYPE_try)
01839 return REGION_KIND_TRY;
01840 if (RID_type(rid) & RID_TYPE_cleanup)
01841 return REGION_KIND_CLEANUP;
01842 if (RID_type(rid) & RID_TYPE_exc_spec)
01843 return REGION_KIND_EXC_SPEC;
01844 if (RID_type(rid) & RID_TYPE_mask)
01845 return REGION_KIND_MASK;
01846 if (RID_type(rid) & RID_TYPE_guard)
01847 return REGION_KIND_GUARD;
01848 if (RID_type(rid) & RID_TYPE_null_cleanup)
01849 return REGION_KIND_NULL_CLEANUP;
01850 Is_True(FALSE,("REGION_type_to_kind, unknown RID type"));
01851 return REGION_KIND_PRAGMA;
01852 }
01853
01854
01855 void REGION_kind_to_type(WN *wn, RID *rid)
01856 {
01857 if (REGION_is_EH(wn)) {
01858 switch (WN_region_kind(wn)) {
01859 case REGION_KIND_TRY:
01860 RID_TYPE_try_Set(rid);
01861 break;
01862 case REGION_KIND_CLEANUP:
01863 RID_TYPE_cleanup_Set(rid);
01864 break;
01865 case REGION_KIND_EXC_SPEC:
01866 RID_TYPE_exc_spec_Set(rid);
01867 break;
01868 case REGION_KIND_MASK:
01869 RID_TYPE_mask_Set(rid);
01870 break;
01871 case REGION_KIND_GUARD:
01872 RID_TYPE_guard_Set(rid);
01873 break;
01874 case REGION_KIND_NULL_CLEANUP:
01875 RID_TYPE_null_cleanup_Set(rid);
01876 break;
01877 default:
01878 Is_True(FALSE,("REGION_kind_to_type, unknown kind"));
01879 break;
01880 }
01881 } else {
01882 switch (WN_region_kind(wn)) {
01883 case REGION_KIND_PRAGMA:
01884 RID_TYPE_pragma_Set(rid);
01885 break;
01886 case REGION_KIND_FUNC_ENTRY:
01887 RID_TYPE_pragma_Set(rid);
01888 break;
01889 case REGION_KIND_LOOP:
01890 RID_TYPE_loop_Set(rid);
01891 break;
01892 case REGION_KIND_OLIMIT:
01893 RID_TYPE_olimit_Set(rid);
01894 break;
01895 case REGION_KIND_MP:
01896 Is_True(REGION_is_mp(wn), ("REGION_kind_to_type, internal error"));
01897 RID_TYPE_mp_Set(rid);
01898 break;
01899 case REGION_KIND_RPI:
01900 RID_TYPE_rpi_Set(rid);
01901 break;
01902 case REGION_KIND_COLD:
01903 RID_TYPE_cold_Set(rid);
01904 break;
01905 case REGION_KIND_SWP:
01906 RID_TYPE_swp_Set(rid);
01907 break;
01908 #ifdef TARG_SL //fork_joint
01909 case REGION_KIND_MINOR:
01910 RID_TYPE_minor_Set(rid);
01911 break;
01912 case REGION_KIND_MAJOR:
01913 RID_TYPE_major_Set(rid);
01914 break;
01915 #endif
01916
01917 default:
01918 Is_True(FALSE,("REGION_kind_to_type, unknown kind"));
01919 break;
01920 }
01921 }
01922 }
01923
01924
01925
01926
01927
01928 #define LWN_Get_Parent_From_Map(wn,Parent_Map) \
01929 ((WN*)WN_MAP_Get(Parent_Map, (WN*)wn))
01930
01931 BOOL WN_Fake_Call_EH_Region(WN * wn, WN_MAP Parent_Map) {
01932
01933 WN * parent;
01934 WN * grandparent;
01935
01936 FmtAssert(WN_opcode(wn) == OPC_VCALL,("In EH pragma, not a call"));
01937 parent = LWN_Get_Parent_From_Map(wn,Parent_Map);
01938 if (parent && (WN_operator(parent) == OPR_BLOCK)) {
01939 grandparent = LWN_Get_Parent_From_Map(parent,Parent_Map);
01940 if (grandparent &&
01941 (WN_operator(grandparent) == OPR_REGION) &&
01942 (REGION_is_EH(grandparent)) &&
01943 (WN_region_pragmas(grandparent) == parent))
01944 return TRUE;
01945 }
01946 return FALSE;
01947 }