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 #include <list>
00041 #include "defs.h"
00042 #include "config.h"
00043 #include "tracing.h"
00044 #include "timing.h"
00045 #include "cgir.h"
00046 #include "cg.h"
00047 #include "cgtarget.h"
00048 #include "cg_flags.h"
00049 #include "ttype.h"
00050 #include "bitset.h"
00051 #include "bb_set.h"
00052 #include "freq.h"
00053 #include "whirl2ops.h"
00054 #include "dominate.h"
00055 #include "findloops.h"
00056 #include "gra_live.h"
00057 #include "cxx_memory.h"
00058
00059 #include "hb.h"
00060 #include "hb_trace.h"
00061 #include "hb_id_candidates.h"
00062 #include "hb_block_select.h"
00063 #include "hb_if_convert.h"
00064 #include "hb_tail_duplication.h"
00065
00066 #include "pqs_cg.h"
00067
00068 MEM_POOL MEM_HB_pool;
00069 static MEM_POOL MEM_HB_loop_pool;
00070 std::list<HB *> HB_list;
00071 BB_MAP HB_bb_map;
00072 float HB_minimum_priority;
00073
00074 BOOL HB_did_tail_duplication = FALSE;
00075
00077 void
00078 HB_Predecessor_Count(HB* hb, BB_MAP& predecessor_count)
00080
00081
00082
00084 {
00085 BB* bb;
00086
00087
00088
00089
00090 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
00091 BBLIST* bl;
00092 FOR_ALL_BB_PREDS(bb, bl) {
00093 BB* pred = BBLIST_item(bl);
00094 if (HB_Contains_Block(hb, pred)) {
00095 INT count = BB_MAP32_Get(predecessor_count, bb);
00096 BB_MAP32_Set(predecessor_count, bb, ++count);
00097 }
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106 BB_MAP32_Set(predecessor_count, HB_Entry(hb), 0);
00107 }
00108
00109
00110 HB* HB_Alloc(MEM_POOL* pool)
00112
00114 {
00115 HB* hb = CXX_NEW(HB, pool);
00116 HB_Blocks_Set(hb, BB_SET_Create_Empty(PU_BB_Count+2, pool));
00117 HB_Flags_Clear(hb);
00118 HB_Entry_Set(hb, NULL);
00119 return hb;
00120 }
00121
00123 void
00124 HB_Add_BBs_And_Map(HB* hb, BB_SET* bbset)
00126
00127
00128
00130 {
00131 BB* bb;
00132
00133 HB_Add_BB_SET(hb, bbset, &MEM_pu_pool);
00134 FOR_ALL_BB_SET_members(bbset, bb) {
00135 BB_MAP_Set(HB_bb_map, bb, (void *) hb);
00136 }
00137 }
00138
00140 void
00141 HB_Copy_BBs_And_Map(HB* hb, BB_SET* bbset)
00143
00144
00145
00147 {
00148 BB* bb;
00149
00150 HB_Blocks_Copy(hb, bbset);
00151 FOR_ALL_BB_SET_members(bbset, bb) {
00152 BB_MAP_Set(HB_bb_map, bb, (void *) hb);
00153 }
00154 }
00155
00156
00158
00160 static void
00161 HB_Map_BBs(HB *hb)
00162 {
00163 BB *bb;
00164 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
00165 if (bb) BB_MAP_Set(HB_bb_map, bb, (void *) hb);
00166 }
00167 }
00168
00169
00171
00173 extern void
00174 Setup_HB_bb_map(void)
00175 {
00176 std::list<HB*>::iterator hbi;
00177 BB *bb;
00178
00179 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
00180 BB_MAP_Set(HB_bb_map,bb,NULL);
00181 }
00182
00183 for (hbi = HB_list.begin(); hbi != HB_list.end(); hbi++) {
00184 HB_Map_BBs(*hbi);
00185 }
00186 }
00187
00189
00190
00191
00192
00193
00194
00195 static void
00196 HB_Form_HB_List(void)
00197 {
00198 BB *bb;
00199 HB *hb;
00200 BB *bb_hb;
00201 LOOP_DESCR *hb_loop;
00202
00203
00204 HB_list.clear();
00205
00206
00207 Free_Dominators_Memory();
00208 Calculate_Dominators();
00209 (void) LOOP_DESCR_Detect_Loops(&MEM_HB_pool);
00210
00211
00212 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
00213 hb = (HB *) BB_MAP_Get(HB_bb_map, bb);
00214 if (hb && !HB_Flags_Check(hb,HB_SEEN_FLAG)) {
00215
00216 hb_loop = LOOP_DESCR_Find_Loop(HB_Entry(hb));
00217 FOR_ALL_BB_SET_members(HB_Blocks(hb),bb_hb) {
00218 if (hb_loop != LOOP_DESCR_Find_Loop(bb_hb)) {
00219 HB_Remove_Block(hb,bb_hb);
00220 BB_MAP_Set(HB_bb_map,bb_hb,NULL);
00221 }
00222 }
00223
00224
00225
00226 if (!BB_SET_EmptyP(HB_Blocks(hb)) && HB_Contains_Block(hb,HB_Entry(hb))) {
00227 HB_list.push_front(hb);
00228 HB_Flags_Set(hb,HB_SEEN_FLAG);
00229 }
00230 }
00231 }
00232
00233
00234
00235 std::list<HB *>::iterator hbi;
00236 std::list<BB *> *bl;
00237 for (hbi = HB_list.begin(); hbi != HB_list.end(); hbi++) {
00238 bl = HB_Blocks_List(*hbi);
00239 bl->clear();
00240 for (bb = HB_Entry(*hbi); bb != NULL && HB_Contains_Block(*hbi, bb);
00241 bb = BB_next(bb)) {
00242 bl->push_back(bb);
00243 }
00244 }
00245 }
00246
00248
00250 void Get_HB_Blocks_List(std::list<BB *> &blocks, HB* hb)
00251 {
00252 blocks = hb->block_list;
00253 #ifdef Is_True_On
00254
00255
00256 std::list<BB *>::iterator i,j;
00257 for (i = blocks.begin(); i != blocks.end(); i++) {
00258 j = i;
00259 j++;
00260 for (; j != blocks.end(); j++) {
00261 if (*i == *j) {
00262 DevWarn(("Get_HB_Blocks_List: duplicate block found %d\n"),BB_id(*i));
00263 }
00264 }
00265 }
00266 #endif
00267 }
00268
00270
00271
00272
00273
00274
00275
00276 static void
00277 HB_Remove_BBs_From_Hyperblocks(BB_SET * orig_blocks, BB_SET *current_blocks)
00278 {
00279 BB *bb;
00280 HB *hb;
00281 FOR_ALL_BB_SET_members(orig_blocks,bb) {
00282 hb = (HB *) BB_MAP_Get(HB_bb_map,bb);
00283 if (hb) {
00284 HB_Remove_Blocks(hb,current_blocks);
00285 }
00286 }
00287 }
00288
00290
00291
00292
00293 void
00294 HB_Remove_Deleted_Blocks(void)
00295 {
00296 BB_SET *live_bbs;
00297 BB *bb;
00298 MEM_POOL_Push(&MEM_local_pool);
00299
00300
00301 live_bbs = BB_SET_Create_Empty(PU_BB_Count+2,&MEM_local_pool);
00302 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
00303 live_bbs = BB_SET_Union1D(live_bbs,bb,&MEM_local_pool);
00304 }
00305
00306
00307 std::list<HB*>::iterator hbi;
00308 for (hbi = HB_list.begin(); hbi != HB_list.end(); ) {
00309 HB_Blocks_Set(*hbi, BB_SET_IntersectionD(HB_Blocks(*hbi), live_bbs ));
00310
00311 if (BB_SET_EmptyP(HB_Blocks(*hbi))) {
00312 hbi = HB_list.erase(hbi);
00313 } else {
00314 hbi++;
00315 }
00316 }
00317
00318 MEM_POOL_Pop(&MEM_local_pool);
00319 }
00320
00321
00322
00324
00325
00326
00327 void
00328 HB_Init(void)
00329 {
00330
00331
00332
00333 HB_list.clear();
00334 HB_minimum_priority = atof(HB_min_priority);
00335 HB_bb_map = BB_MAP_Create();
00336 HB_Trace_Init();
00337 #ifndef TARG_IA64
00338
00339 if (!CGTARG_Can_Predicate()) {
00340 #else
00341 if (0) {
00342 #endif
00343 HB_formation = 0;
00344 }
00345 }
00346
00347
00349 static void
00350 Initialize_Memory()
00352
00353
00354
00356 {
00357 static BOOL did_init = FALSE;
00358
00359 if ( ! did_init ) {
00360 MEM_POOL_Initialize(&MEM_HB_pool,"HB pool",FALSE);
00361 MEM_POOL_Initialize(&MEM_HB_loop_pool,"HB loop pool",FALSE);
00362 did_init = TRUE;
00363 }
00364 MEM_POOL_Push(&MEM_HB_pool);
00365 MEM_POOL_Push(&MEM_HB_loop_pool);
00366 MEM_POOL_Push(&MEM_local_pool);
00367 }
00368
00370 static void
00371 Finalize_Memory()
00373
00374
00375
00377 {
00378 Free_Dominators_Memory();
00379 MEM_POOL_Pop(&MEM_local_pool);
00380 MEM_POOL_Pop(&MEM_HB_pool);
00381 MEM_POOL_Pop(&MEM_HB_loop_pool);
00382 }
00383
00385 static void
00386 Clear_Visited_Bits(std::list<HB_CAND_TREE*>& candidate_regions)
00387 {
00388 std::list<HB_CAND_TREE*>::iterator cands;
00389 for (cands = candidate_regions.begin(); cands != candidate_regions.end();
00390 cands++) {
00391 HB_CAND_TREE_Reset_Flag(*cands, HCT_VISITED);
00392 }
00393 }
00394
00395
00397 static void
00398 Update_Tree(HB_CAND_TREE* cand)
00400
00401
00402
00403
00405 {
00406 std::list<HB_CAND_TREE*>::iterator kids;
00407 std::list<HB_CAND_TREE*>::iterator current_kid;
00408
00409 HB_CAND_TREE_Set_Flag(cand, HCT_FULLY_CONVERTED);
00410
00411
00412
00413
00414
00415 for (kids = HB_CAND_TREE_Kids(cand).begin();
00416 kids != HB_CAND_TREE_Kids(cand).end();) {
00417 current_kid = kids++;
00418 HB* hb_cand = HB_CAND_TREE_Candidate(cand);
00419 HB* hb_kid = HB_CAND_TREE_Candidate(*current_kid);
00420 HB_Add_BBs_And_Map(hb_cand, HB_Blocks(hb_kid));
00421 HB_CAND_TREE_Kids(*kids).erase(current_kid);
00422 }
00423 }
00424
00426 static void
00427 Convert_Tree_Leaves(HB_CAND_TREE* cand, BOOL* leaves_converted,
00428 std::list<HB_CAND_TREE*>& candidate_regions)
00430
00431
00432
00433
00434
00435
00436
00438 {
00439 std::list<HB_CAND_TREE*>::iterator kids;
00440
00441 if (HB_CAND_TREE_Check_Flag(cand, HCT_VISITED)) return;
00442
00443 HB_CAND_TREE_Set_Flag(cand, HCT_VISITED);
00444
00445 if (HB_Trace(HB_TRACE_CONVERT)) {
00446 fprintf(HB_TFile, "<HB> Converting tree leaves for Candidate: ");
00447 HB_Trace_Print_Cand_Tree(cand);
00448 fprintf(HB_TFile,"\n");
00449 }
00450
00451 if (!HB_CAND_TREE_Kids(cand).empty()) {
00452 BOOL leaf = TRUE;
00453 for (kids = HB_CAND_TREE_Kids(cand).begin();
00454 kids != HB_CAND_TREE_Kids(cand).end();
00455 kids++) {
00456 Convert_Tree_Leaves(*kids, leaves_converted, candidate_regions);
00457 if (!HB_CAND_TREE_Check_Flag(*kids, HCT_FULLY_CONVERTED)) {
00458 leaf = FALSE;
00459 }
00460 }
00461
00462
00463
00464
00465
00466
00467 if (!leaf) {
00468 return;
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 HB* hb = HB_CAND_TREE_Candidate(cand);
00479 if (HB_Safe_For_If_Conversion(hb) && HB_Block_Select(hb, TRUE)) {
00480 HB_bb_list no_tail_dups;
00481 HB_If_Convert(hb, candidate_regions);
00482 HB_Map_BBs(hb);
00483 Update_Tree(cand);
00484 *leaves_converted = TRUE;
00485 }
00486 }
00487
00488
00490 void
00491 Convert_Candidate_Leaves(std::list<HB_CAND_TREE*>& candidate_regions,
00492 BOOL* leaves_converted)
00494
00495
00496
00497
00498
00500 {
00501 std::list<HB_CAND_TREE*>::iterator hbct;
00502
00503 for (hbct = candidate_regions.begin(); hbct != candidate_regions.end();
00504 hbct++) {
00505 Convert_Tree_Leaves(*hbct, leaves_converted, candidate_regions);
00506 }
00507 }
00508
00509 #ifdef KEY
00510 BOOL hammock_region;
00511 #endif
00513 void
00514 Form_Hyperblocks(HB_CAND_TREE* cand,
00515 BB_MAP duplicate,
00516 BOOL post_tail_duplication,
00517 std::list<HB_CAND_TREE*>& candidate_regions,
00518 BB_SET *orig_blocks)
00520
00521
00522
00523
00524
00526 {
00527 HB* hb = HB_CAND_TREE_Candidate(cand);
00528 HB* orig_hb;
00529 BB* entry = HB_Entry(hb);
00530
00531 if (HB_CAND_TREE_Check_Flag(cand, HCT_VISITED)) return;
00532
00533 HB_CAND_TREE_Set_Flag(cand, HCT_VISITED);
00534
00535 orig_hb = (HB *) BB_MAP_Get(HB_bb_map, entry);
00536 if (!orig_hb || (!BB_SET_EqualP(HB_Blocks(hb),HB_Blocks(orig_hb)) &&
00537 BB_SET_ContainsP(HB_Blocks(hb),HB_Blocks(orig_hb)))) {
00538
00539
00540
00541
00542
00543
00544 if (HB_Trace(HB_TRACE_CONVERT)) {
00545 if (!orig_hb) {
00546 fprintf(HB_TFile, "<HB> Forming hyperblock for candidate: ");
00547 } else {
00548 fprintf(HB_TFile, "<HB> Forming merge hyperblock for candidate: ");
00549 }
00550 hb->Print();
00551 fprintf(HB_TFile,"\n");
00552 }
00553
00554 orig_blocks = BB_SET_CopyD(orig_blocks,HB_Blocks(hb), &MEM_local_pool);
00555 #ifdef KEY
00556 hammock_region = FALSE;
00557 #endif
00558 if (HB_Block_Select(hb, FALSE)) {
00559 HB_bb_list duplicate_bbs;
00560 if (HB_Tail_Duplicate(hb, duplicate, duplicate_bbs,
00561 post_tail_duplication)) {
00562 HB_If_Convert(hb, candidate_regions);
00563 HB_Remove_BBs_From_Hyperblocks(orig_blocks,HB_Blocks(hb));
00564 HB_Map_BBs(hb);
00565 }
00566 }
00567 }
00568
00569
00570
00571
00572 std::list<HB_CAND_TREE*>::iterator kids;
00573
00574 for (kids = HB_CAND_TREE_Kids(cand).begin();
00575 kids != HB_CAND_TREE_Kids(cand).end();
00576 kids++) {
00577 Form_Hyperblocks(*kids, duplicate, post_tail_duplication, candidate_regions,orig_blocks);
00578 }
00579 }
00580
00581
00583 void
00584 HB_Form_Hyperblocks(RID *rid, const BB_REGION& bb_region)
00586
00588 {
00589 std::list<HB_CAND_TREE*> candidate_regions;
00590 BB_SET *orig_blocks;
00591
00592 if (!HB_formation || !(HB_simple_ifc || HB_complex_non_loop)) {
00593 return;
00594 }
00595
00596
00597
00598
00599
00600 if (HB_complex_non_loop && !HB_simple_ifc_set) {
00601 HB_simple_ifc = FALSE;
00602 }
00603
00604 Start_Timer (T_HBF_CU);
00605
00606 HB_did_tail_duplication = FALSE;
00607
00608
00609
00610
00611
00612 if (!Alias_Manager && HB_require_alias) {
00613 return;
00614 }
00615
00616 Set_Error_Phase ("Hyperblock Formation");
00617
00618 Initialize_Memory();
00619 HB_Identify_Candidates_Init();
00620
00621 if (HB_Trace(HB_TRACE_BEFORE)) {
00622 Trace_IR(TP_HBF, "Before Hyperblock Formation", NULL);
00623 }
00624
00625 if (HB_Trace(HB_TRACE_DRAWFLOW1)) {
00626 draw_flow_graph();
00627 }
00628
00629
00630
00631
00632
00633 Setup_HB_bb_map();
00634
00635 BB_MAP hct_entry_map = BB_MAP_Create();
00636
00637 HB_Identify_Hammock_Candidates(candidate_regions, hct_entry_map);
00638
00639 if (HB_Trace(HB_TRACE_ID)) {
00640 HB_Trace_Candidates("Hammock Pass", candidate_regions);
00641 }
00642
00643 if (HB_complex_non_loop) {
00644 HB_Identify_General_Candidates(candidate_regions, hct_entry_map, 1);
00645 }
00646 BB_MAP_Delete(hct_entry_map);
00647
00648 if (HB_Trace(HB_TRACE_ID)) {
00649 HB_Trace_Candidates("First General Pass", candidate_regions);
00650 }
00651
00652
00653
00654
00655 BOOL leaves_converted = FALSE;
00656 if (HB_simple_ifc) {
00657 Convert_Candidate_Leaves(candidate_regions, &leaves_converted);
00658 if (HB_Trace(HB_TRACE_DRAWFLOW2)) {
00659 draw_flow_graph();
00660 }
00661 }
00662
00663 if (leaves_converted && Get_Trace(TKIND_IR, TP_HBF, REGION_First_BB)) {
00664 Trace_IR(TP_HBF, "After Initial If-conversion", NULL);
00665 }
00666
00667 if (HB_complex_non_loop) {
00668 BB_MAP duplicate = BB_MAP_Create();
00669
00670
00671
00672 std::list<HB_CAND_TREE*>::iterator cands;
00673
00674 Clear_Visited_Bits(candidate_regions);
00675 orig_blocks = BB_SET_Create_Empty(PU_BB_Count+2,&MEM_local_pool);
00676 for (cands = candidate_regions.begin(); cands != candidate_regions.end();
00677 cands++) {
00678
00679
00680
00681 if (!HB_CAND_TREE_Check_Flag(*cands, HCT_FULLY_CONVERTED)) {
00682 Form_Hyperblocks(*cands, duplicate, FALSE, candidate_regions,orig_blocks);
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691 hct_entry_map = BB_MAP_Create();
00692 candidate_regions.clear();
00693
00694
00695
00696
00697 if (HB_did_tail_duplication) {
00698 Free_Dominators_Memory();
00699 Calculate_Dominators();
00700 HB_Identify_General_Candidates(candidate_regions, hct_entry_map, 2);
00701 if (HB_Trace(HB_TRACE_ID)) {
00702 HB_Trace_Candidates("Second General pass", candidate_regions);
00703 }
00704 for (cands = candidate_regions.begin(); cands != candidate_regions.end();
00705 cands++) {
00706 Form_Hyperblocks(*cands, duplicate, TRUE, candidate_regions, orig_blocks);
00707 }
00708 } else if (HB_Trace(HB_TRACE_ID)) {
00709 fprintf(HB_TFile,
00710 "<HB> No second pass. No tail duplication performed.\n");
00711 }
00712 BB_MAP_Delete(hct_entry_map);
00713 BB_MAP_Delete(duplicate);
00714 }
00715
00716 HB_Form_HB_List();
00717 if (HB_Trace(HB_TRACE_SELECT)) {
00718 HB_Trace_HB_List();
00719 }
00720
00721 GRA_LIVE_Recalc_Liveness(rid);
00722
00723 if (Get_Trace(TKIND_IR, TP_HBF, REGION_First_BB)) {
00724 Trace_IR(TP_HBF, "Hyperblock Formation", NULL);
00725 }
00726 if (HB_Trace(HB_TRACE_DRAWFLOW3)) {
00727 draw_flow_graph();
00728 }
00729
00730 Finalize_Memory();
00731 Stop_Timer (T_HBF_CU);
00732 }