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 <stack>
00041 #include <queue>
00042 #include "defs.h"
00043 #include "config.h"
00044 #include "mempool.h"
00045 #include "tracing.h"
00046 #include "timing.h"
00047 #include "cgir.h"
00048 #include "cg.h"
00049 #include "cgtarget.h"
00050 #include "cg_flags.h"
00051 #include "ttype.h"
00052 #include "bitset.h"
00053 #include "bb.h"
00054 #include "bb_set.h"
00055 #include "freq.h"
00056 #include "whirl2ops.h"
00057 #include "dominate.h"
00058 #include "findloops.h"
00059 #include "cg_loop.h"
00060 #include "gtn_universe.h"
00061 #include "gtn_set.h"
00062
00063 #include "hb.h"
00064 #include "hb_trace.h"
00065 #include "hb_id_candidates.h"
00066
00067 static BB_SET* region_bbs;
00068
00069
00071 static void
00072 verify_cand_tree(HB_CAND_TREE* c,FILE *f)
00074
00075
00076
00078 {
00079 if (!HB_CAND_TREE_Kids(c).empty()) {
00080 std::list<HB_CAND_TREE*>::iterator k;
00081 for (k = HB_CAND_TREE_Kids(c).begin(); k != HB_CAND_TREE_Kids(c).end();
00082 k++) {
00083 if (!BB_SET_ContainsP(HB_Blocks(HB_CAND_TREE_Candidate(c)),
00084 HB_Blocks(HB_CAND_TREE_Candidate(*k)))) {
00085 fprintf(f, "\nBad Tree ");
00086 BB_SET_Print(HB_Blocks(HB_CAND_TREE_Candidate(c)),f);
00087 fprintf(f, " -> ");
00088 BB_SET_Print(HB_Blocks(HB_CAND_TREE_Candidate(*k)),f);
00089 fprintf(f, "\n");
00090 } else {
00091 verify_cand_tree(*k,f);
00092 }
00093 }
00094 }
00095 }
00096
00097 static void verify_ctree(std::list<HB_CAND_TREE*> cands)
00098 {
00099 std::list<HB_CAND_TREE*>::iterator c;
00100 FILE *f=stderr;
00101
00102 fprintf(f,"Verifying HB candidates...");
00103 for (c = cands.begin(); c != cands.end(); c++) {
00104 verify_cand_tree(*c,f);
00105 }
00106 fprintf(f,"done\n");
00107 fflush(f);
00108 }
00109
00111
00112
00113
00114
00116 struct BB_Freq_Compare {
00117 BOOL operator () (BB* bb1, BB* bb2) {
00118 return BB_freq(bb1) > BB_freq(bb2);
00119 }
00120 };
00121
00123 BB*
00124 Find_Immediate_Dominator(BB* bb)
00126
00127
00128
00129
00130
00131
00132
00134 {
00135 BBLIST* bl;
00136 BB* dom = NULL;
00137 FOR_ALL_BB_PREDS(bb, bl) {
00138 BB* pred = BBLIST_item(bl);
00139
00140 if (BB_SET_MemberP(BB_dom_set(bb), pred) && bb != pred &&
00141 LOOP_DESCR_Find_Loop(bb) == LOOP_DESCR_Find_Loop(pred)) {
00142 dom = pred;
00143 break;
00144 }
00145 }
00146 if (dom && BB_call(dom)) {
00147
00148
00149
00150 return Find_Immediate_Dominator(dom);
00151 }
00152 return dom;
00153 }
00154
00155
00157 BB*
00158 Find_Immediate_Postdominator(BB* bb)
00160
00161
00162
00163
00164
00165
00166
00167
00169 {
00170 BBLIST* bl;
00171 FOR_ALL_BB_SUCCS(bb, bl) {
00172 BB* succ = BBLIST_item(bl);
00173
00174 if (BB_SET_MemberP(BB_pdom_set(bb), succ) && bb != succ &&
00175 LOOP_DESCR_Find_Loop(bb) == LOOP_DESCR_Find_Loop(succ)) {
00176 return succ;
00177 }
00178 }
00179 return NULL;
00180 }
00181
00183 BOOL
00184 Check_HB_For_PQS_Suitability(BB_SET* selected_hb, BB* bb_entry)
00186
00187
00188
00189
00190
00191
00192
00194 {
00195
00196
00197
00198
00199
00200
00201
00202 #ifdef TARG_IA64
00203
00204 BB *bb;
00205 GTN_SET *pgtn_defs = GTN_SET_Create(GTN_UNIVERSE_size, &MEM_local_pool);
00206 GTN_SET *pgtn_uses = GTN_SET_Create(GTN_UNIVERSE_size, &MEM_local_pool);
00207 #ifdef linux
00208 mINT16 *count_pgtns = (mINT16 *) alloca ((Last_TN + 1) * sizeof(mINT16));
00209 bzero(count_pgtns, (Last_TN+1) * sizeof(mINT16));
00210 #else
00211 mINT16 count_pgtns[Last_TN + 1];
00212 bzero(count_pgtns, sizeof(count_pgtns));
00213 #endif
00214
00215 FOR_ALL_BB_SET_members (selected_hb, bb) {
00216 OP *op;
00217 FOR_ALL_BB_OPs(bb, op) {
00218 INT i;
00219
00220 for (i = 0; i < OP_results(op); ++i) {
00221 TN *result_tn = OP_result(op, i);
00222 if (TN_is_global_reg(result_tn) &&
00223 TN_register_class(result_tn) == ISA_REGISTER_CLASS_predicate) {
00224
00225 INT16 count = count_pgtns[TN_number(result_tn)];
00226 count += 1;
00227
00228
00229
00230 if (count > 1) {
00231 return FALSE;
00232 } else {
00233 pgtn_defs = GTN_SET_Union1D(pgtn_defs, result_tn, &MEM_local_pool);
00234 }
00235
00236
00237
00238
00239
00240 BBLIST *succ_list;
00241 FOR_ALL_BB_SUCCS(bb, succ_list) {
00242 BB *succ_bb = BBLIST_item(succ_list);
00243 if (!BS_MemberP (selected_hb, BB_id(succ_bb)) &&
00244 GTN_SET_MemberP (BB_live_in(succ_bb), result_tn))
00245 return FALSE;
00246 }
00247 }
00248 }
00249
00250 for (i = 0; i < OP_opnds(op); ++i) {
00251 TN *opnd_tn = OP_opnd(op, i);
00252 if (TN_is_constant(opnd_tn)) continue;
00253
00254 if (TN_is_global_reg(opnd_tn) &&
00255 TN_register_class(opnd_tn) == ISA_REGISTER_CLASS_predicate) {
00256
00257 pgtn_uses = GTN_SET_Union1D(pgtn_uses, opnd_tn, &MEM_local_pool);
00258
00259
00260
00261
00262
00263 BBLIST *pred_list;
00264 FOR_ALL_BB_PREDS(bb, pred_list) {
00265 BB *pred_bb = BBLIST_item(pred_list);
00266 if (!BS_MemberP (selected_hb, BB_id(pred_bb)) &&
00267 GTN_SET_MemberP (BB_live_out(pred_bb), opnd_tn))
00268 return FALSE;
00269 }
00270 }
00271 }
00272 }
00273 }
00274
00275 TN *tn;
00276 FOR_ALL_GTN_SET_members(pgtn_uses, tn) {
00277 if (!GTN_SET_MemberP(pgtn_defs, tn)) return FALSE;
00278 }
00279
00280 #endif
00281
00282 return TRUE;
00283 }
00284
00286 BOOL
00287 Check_BB_For_HB_Suitability(BB* bb, BB* bb_entry)
00289
00290
00291
00292
00294 {
00295 #ifdef KEY
00296 if (BB_asm(bb))
00297 return FALSE;
00298 #endif
00299
00300
00301
00302 switch (BB_kind(bb)) {
00303 case BBKIND_GOTO:
00304 case BBKIND_LOGIF:
00305 break;
00306 case BBKIND_CALL:
00307 if (!CGTARG_Can_Predicate_Calls() || HB_exclude_calls) {
00308 return FALSE;
00309 }
00310 break;
00311 case BBKIND_RETURN:
00312 if (!CGTARG_Can_Predicate_Returns()) {
00313 return FALSE;
00314 }
00315 break;
00316 default:
00317 return FALSE;
00318 }
00319
00320
00321
00322
00323 if (BB_Has_Exc_Label(bb)) {
00324 return FALSE;
00325 }
00326
00327
00328
00329
00330
00331 if (BB_Has_Addr_Taken_Label(bb)) {
00332 return FALSE;
00333 }
00334
00335
00336
00337
00338 if (BB_rid(bb) != BB_rid(bb_entry)) {
00339 return FALSE;
00340 }
00341
00342
00343
00344 if (BB_exit(bb) && !BB_SET_MemberP(BB_pdom_set(bb_entry),bb)) {
00345 return FALSE;
00346 }
00347
00348
00349
00350
00351 if (LOOP_DESCR_Find_Loop(bb_entry) != LOOP_DESCR_Find_Loop(bb)) {
00352 return FALSE;
00353 }
00354
00355 #ifdef KEY
00356 if (bb != bb_entry) {
00357 #endif
00358
00359
00360
00361
00362
00363 OP* op;
00364 FOR_ALL_BB_OPs_FWD(bb, op) {
00365
00366
00367
00368
00369
00370
00371
00372
00373 if (!CGTARG_Check_OP_For_HB_Suitability(op)) return FALSE;
00374
00375 if (OP_has_predicate(op) &&
00376 !TN_is_true_pred(OP_opnd(op, OP_PREDICATE_OPND))) {
00377
00378 TN *pred_tn = OP_opnd(op, OP_PREDICATE_OPND);
00379
00380 if (TN_is_global_reg(pred_tn)) {
00381 if (HB_exclude_pgtns) {
00382 if (HB_Trace(HB_TRACE_HAMMOCK))
00383 fprintf(HB_TFile, "not forming hyperblock cause BB %d has global predicate GTN%d\n", BB_id(bb), TN_number(pred_tn));
00384 return FALSE;
00385 }
00386 }
00387 else {
00388
00389 DEF_KIND kind;
00390
00391 OP *def_op = TN_Reaching_Value_At_Op(pred_tn, op, &kind, TRUE);
00392 if (def_op && OP_has_predicate(def_op) &&
00393 TN_is_true_pred(OP_opnd(def_op, OP_PREDICATE_OPND))) {
00394
00395
00396
00397
00398
00399
00400
00401 TOP uncond_op;
00402 if (!CGTARG_Unconditional_Compare(def_op, &uncond_op)) {
00403 if (uncond_op != TOP_UNDEFINED) {
00404 OP_Change_Opcode(def_op, uncond_op);
00405 Set_OP_cond_def_kind(def_op,OP_ALWAYS_UNC_DEF);
00406 } else {
00407 DevWarn("No unconditional form of compare available in BB%d.",BB_id(bb));
00408 return FALSE;
00409 }
00410 }
00411 }
00412 }
00413 }
00414 }
00415 #ifdef KEY
00416 }
00417 #endif
00418
00419 return TRUE;
00420 }
00421
00423 void
00424 HB_Identify_Candidates_Init()
00426
00427
00428
00430 {
00431
00432
00433
00434
00435
00436
00437 Calculate_Dominators();
00438 (void) LOOP_DESCR_Detect_Loops(&MEM_HB_pool);
00439 region_bbs = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_HB_pool);
00440 }
00441
00443 HB_CAND_TREE*
00444 Make_New_Region(std::list<HB_CAND_TREE*>& candidates,
00445 BB* entry,
00446 BB* exit,
00447 BB* fall_thru_exit,
00448 BB_MAP* hct_entry_map,
00449 BB_SET* blocks,
00450 MEM_POOL* hb_pool)
00452
00453
00454
00455
00456
00457
00459 {
00460 HB_CAND_TREE* new_cand = HB_CAND_TREE_Alloc(&MEM_HB_pool);
00461 HB* new_hb = HB_Alloc(hb_pool);
00462 HB_CAND_TREE_Candidate_Set(new_cand, new_hb);
00463 HB_CAND_TREE_Set_Flag(new_cand, HCT_UNPROCESSED);
00464 HB_Entry_Set(new_hb, entry);
00465 if (hct_entry_map) {
00466 BB_MAP_Set(*hct_entry_map, entry, new_cand);
00467 }
00468 if (blocks) {
00469
00470
00471
00472
00473 HB_Add_BB_SET(new_hb, blocks, hb_pool);
00474 region_bbs = BB_SET_UnionD(region_bbs, blocks, &MEM_HB_pool);
00475 }
00476
00477 HB_Exit_Set(new_hb, exit);
00478 HB_Fall_Thru_Exit_Set(new_hb, fall_thru_exit);
00479 if (fall_thru_exit) {
00480
00481
00482
00483
00484
00485 HB_Remove_Block(new_hb, fall_thru_exit);
00486 }
00487 candidates.push_front(new_cand);
00488
00489 return new_cand;
00490 }
00491
00493 void
00494 Find_Interior_Blocks(std::list<HB_CAND_TREE*>& candidates)
00496
00497
00498
00499
00500
00502 {
00503 BB* bb;
00504 BB* succ;
00505
00506 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00507 fprintf(HB_TFile,"Initial hammock blocks:");
00508 }
00509
00510 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
00511 succ = BB_Unique_Successor(bb);
00512 if (succ && !BB_SET_MemberP(BB_dom_set(succ), bb) &&
00513 Check_BB_For_HB_Suitability(bb, bb)) {
00514 HB_CAND_TREE* cand;
00515 cand = Make_New_Region(candidates, bb, bb, NULL, NULL, NULL,
00516 &MEM_HB_pool);
00517 HB_CAND_TREE_Set_Flag(cand, HCT_SINGLE_BLOCK);
00518 HB_CAND_TREE_Set_Flag(cand, HCT_ERASE);
00519 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00520 fprintf(HB_TFile," %d",BB_id(bb));
00521 }
00522 }
00523 }
00524 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00525 fprintf(HB_TFile,"\n\n");
00526 }
00527 }
00528
00530 BOOL
00531 Check_Region_Recur(BB* dom,
00532 BB* current,
00533 BB* pdom,
00534 BB_SET* blocks,
00535 std::list<HB_CAND_TREE*>& kids,
00536 HB_CAND_TREE* hct_parent,
00537 BB_MAP hct_entry_map,
00538 BOOL* bad_region)
00540
00541
00542
00543
00545 {
00546 if (*bad_region) return FALSE;
00547
00548 if (BB_SET_MemberP(blocks, current)) {
00549 return TRUE;
00550 }
00551
00552
00553
00554
00555 if (BB_loop_head_bb(current) != BB_loop_head_bb(dom) ||
00556 BB_loop_head_bb(current) != BB_loop_head_bb(pdom)) {
00557 *bad_region = TRUE;
00558 return FALSE;
00559 }
00560
00561 blocks = BB_SET_Union1D(blocks, current, &MEM_local_pool);
00562
00563 if (!Check_BB_For_HB_Suitability(current, dom)) {
00564 *bad_region = TRUE;
00565 return FALSE;
00566 }
00567 if (current == pdom) {
00568 return TRUE;
00569 }
00570 if (!BB_SET_MemberP(BB_dom_set(current), dom)) {
00571 return FALSE;
00572 }
00573
00574 BBLIST* bl;
00575 FOR_ALL_BB_SUCCS(current, bl) {
00576 BB* succ = BBLIST_item(bl);
00577 HB_CAND_TREE* hct = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, succ);
00578 if (hct && hct_parent && HB_CAND_TREE_Parent(hct) == hct_parent) {
00579
00580
00581
00582
00583 kids.push_front(hct);
00584 }
00585 if (!Check_Region_Recur(dom, succ, pdom, blocks, kids, hct_parent,
00586 hct_entry_map,
00587 bad_region)) {
00588 return FALSE;
00589 }
00590 }
00591 return TRUE;
00592 }
00593
00594
00596 BOOL
00597 Check_Region(BB** orig_dom,
00598 BB** orig_pdom,
00599 BB_SET* blocks,
00600 std::list<HB_CAND_TREE*>& kids,
00601 HB_CAND_TREE* hct_parent,
00602 BB_MAP hct_entry_map)
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00617 {
00618 BOOL retval;
00619 BOOL bad_region = FALSE;
00620 BOOL found_region = Check_Region_Recur(*orig_dom, *orig_dom, *orig_pdom,
00621 blocks, kids, hct_parent,
00622 hct_entry_map, &bad_region);
00623
00624 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00625 fprintf(HB_TFile,"<HB> Check region BB%d to BB%d = %s found %s\n",
00626 BB_id(*orig_dom), BB_id(*orig_pdom),
00627 found_region ? "" : "not",
00628 bad_region ? "bad" : "");
00629 }
00630
00631 if (!found_region && !bad_region) {
00632 BB* dom = *orig_dom;
00633 BB* pdom = *orig_pdom;
00634 do {
00635 if (!BB_SET_MemberP(BB_dom_set(pdom), dom)) {
00636 for (dom = Find_Immediate_Dominator(dom);
00637 dom && !BB_SET_MemberP(BB_dom_set(pdom), dom);
00638 #ifdef TARG_IA64
00639 dom = Find_Immediate_Dominator(dom));
00640 #else
00641 dom = Find_Immediate_Dominator(pdom));
00642 #endif
00643 }
00644 if (dom && !BB_SET_MemberP(BB_pdom_set(dom), pdom)) {
00645 for (pdom = Find_Immediate_Postdominator(pdom);
00646 pdom && !BB_SET_MemberP(BB_pdom_set(dom), pdom);
00647 pdom = Find_Immediate_Postdominator(pdom));
00648 }
00649 } while (dom && pdom && !BB_SET_MemberP(BB_dom_set(pdom), dom) &&
00650 !BB_SET_MemberP(BB_pdom_set(dom), pdom));
00651
00652 if (dom && pdom) {
00653
00654
00655
00656 BB_SET_ClearD(blocks);
00657 kids.clear();
00658 found_region = Check_Region_Recur(dom, dom, pdom, blocks, kids, hct_parent,
00659 hct_entry_map, &bad_region);
00660 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00661 fprintf(HB_TFile,"<HB> Check region reprocess BB%d to BB%d = %s found %s\n",
00662 BB_id(dom), BB_id(pdom),
00663 found_region ? "" : "not",
00664 bad_region ? "bad" : "");
00665 }
00666 if (!found_region || bad_region) {
00667 dom = NULL;
00668 pdom = NULL;
00669 }
00670 } else {
00671
00672 dom = NULL;
00673 pdom = NULL;
00674 }
00675
00676 if (!dom || !pdom) {
00677 retval = FALSE;
00678 } else {
00679 retval = TRUE;
00680 *orig_dom = dom;
00681 *orig_pdom = pdom;
00682 }
00683 } else {
00684 retval = !bad_region;
00685 }
00686
00687
00688
00689
00690 return retval && BS_Size(blocks) <= HB_max_blocks;
00691 }
00692
00693
00694
00695
00696 static BOOL is_subtree_of(HB_CAND_TREE* parent, HB_CAND_TREE* child)
00697 {
00698 if (child == parent) return TRUE;
00699 if (child == NULL || parent == NULL) return FALSE;
00700 return is_subtree_of(parent,HB_CAND_TREE_Parent(child));
00701 }
00702
00704 void
00705 Insert_Parent(HB_CAND_TREE* new_parent,
00706 HB_CAND_TREE* child,
00707 std::list<HB_CAND_TREE*>& candidates,
00708 BB_MAP hct_entry_map)
00710
00711
00712
00714 {
00715 HB_CAND_TREE* old_parent = HB_CAND_TREE_Parent(child);
00716
00717 if (old_parent) {
00718 if (is_subtree_of(new_parent,old_parent)) {
00719
00720
00721
00722 return;
00723 }
00724 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00725 fprintf(HB_TFile,"<HB> Insert Parent (old):\n");
00726 HB_Trace_Print_Cand_Tree(old_parent,0);
00727 fprintf(HB_TFile,"---------------\n");
00728 HB_Trace_Print_Cand_Tree(new_parent,0);
00729 fprintf(HB_TFile,"---------------\n");
00730 HB_Trace_Print_Cand_Tree(child,0);
00731 fprintf(HB_TFile,"===============\n");
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 std::list<HB_CAND_TREE*>::iterator k;
00742 std::list<HB_CAND_TREE*>::iterator current;
00743 for (k = HB_CAND_TREE_Kids(old_parent).begin();
00744 k != HB_CAND_TREE_Kids(old_parent).end();) {
00745 current = k++;
00746 if (*current == child) {
00747 HB_CAND_TREE_Kids(old_parent).erase(current);
00748 break;
00749 }
00750 }
00751
00752
00753
00754
00755 if (!HB_CAND_TREE_Parent(new_parent)) {
00756 HB_CAND_TREE_Kids(old_parent).push_front(new_parent);
00757 HB_CAND_TREE_Parent_Set(new_parent, old_parent);
00758 HB_CAND_TREE_Set_Flag(new_parent,HCT_ERASE);
00759 }
00760 } else {
00761 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00762 fprintf(HB_TFile,"<HB> Insert Parent:\n");
00763 HB_Trace_Print_Cand_Tree(new_parent,0);
00764 fprintf(HB_TFile,"---------------\n");
00765 HB_Trace_Print_Cand_Tree(child,0);
00766 fprintf(HB_TFile,"===============\n");
00767 }
00768
00769
00770
00771
00772 std::list<HB_CAND_TREE*>::iterator c;
00773 std::list<HB_CAND_TREE*>::iterator cur;
00774 for (c = candidates.begin(); c != candidates.end();) {
00775 cur = c++;
00776 if (*cur == child) {
00777 HB_CAND_TREE_Set_Flag(*cur, HCT_ERASE);
00778 break;
00779 }
00780 }
00781 }
00782 HB_CAND_TREE_Parent_Set(child, new_parent);
00783 HB_CAND_TREE_Kids(new_parent).push_front(child);
00784 }
00785
00787 BOOL
00788 Attempt_Merge(HB_CAND_TREE* new_region,
00789 BB_MAP hct_entry_map,
00790 std::list<HB_CAND_TREE*>& candidates)
00792
00793
00794
00796 {
00797 HB_CAND_TREE* neighbor_region;
00798 BB* neighbor;
00799 BB* hb_exit;
00800
00801
00802
00803
00804 HB* hb = HB_CAND_TREE_Candidate(new_region);
00805 if (HB_Fall_Thru_Exit(hb)) {
00806 return FALSE;
00807 }
00808
00809 hb_exit = HB_Exit(hb);
00810
00811
00812
00813 neighbor_region = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, hb_exit);
00814
00815 if (neighbor_region) {
00816 neighbor = hb_exit;
00817 } else {
00818
00819
00820
00821 #ifdef TARG_IA64
00822 Remove_Explicit_Branch(hb_exit);
00823 #endif
00824 neighbor = BB_Fall_Thru_Successor(hb_exit);
00825 if (!neighbor) return FALSE;
00826
00827
00828
00829
00830 neighbor_region = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, neighbor);
00831 }
00832
00833 if (!neighbor_region) {
00834 return FALSE;
00835 }
00836
00837
00838 if (BB_loop_head_bb(neighbor) != BB_loop_head_bb(hb_exit)) {
00839 return FALSE;
00840 }
00841
00842
00843
00844
00845
00846
00847
00848 HB* hb_neighbor = HB_CAND_TREE_Candidate(neighbor_region);
00849
00850
00851 if (hb_neighbor == hb) {
00852 return FALSE;
00853 }
00854
00855 if ((hb_exit != neighbor) && (BS_Size(HB_Blocks(hb)) + BS_Size(HB_Blocks(hb_neighbor))) >
00856 HB_max_blocks) {
00857 return FALSE;
00858 }
00859
00860
00861
00862
00863
00864
00865 if (BB_loop_head_bb(HB_Entry(hb)) != BB_loop_head_bb(HB_Entry(hb_neighbor))){
00866 return FALSE;
00867 }
00868
00869
00870
00871
00872
00873 if (HB_Trace(HB_TRACE_HAMMOCK)) {
00874 fprintf(HB_TFile,"<HB> Merging HBs ");
00875 BB_SET_Print(HB_Blocks(hb),HB_TFile);
00876 fprintf(HB_TFile," ");
00877 BB_SET_Print(HB_Blocks(hb_neighbor),HB_TFile);
00878 fprintf(HB_TFile,"\n");
00879 }
00880
00881 HB_CAND_TREE* parent_region;
00882 if (HB_Fall_Thru_Exit(hb_neighbor)) {
00883
00884
00885
00886
00887 if (BB_SET_MemberP(BB_dom_set(HB_Fall_Thru_Exit(hb_neighbor)),HB_Entry(hb))) {
00888 parent_region = Make_New_Region(candidates, HB_Entry(hb), HB_Fall_Thru_Exit(hb_neighbor),
00889 NULL,
00890 &hct_entry_map,
00891 BB_SET_Union1D(BB_SET_Union(HB_Blocks(hb),
00892 HB_Blocks(hb_neighbor),
00893 &MEM_HB_pool),
00894 HB_Fall_Thru_Exit(hb_neighbor),
00895 &MEM_HB_pool),
00896 &MEM_pu_pool);
00897 } else {
00898 parent_region = Make_New_Region(candidates, HB_Entry(hb), NULL,
00899 HB_Fall_Thru_Exit(hb_neighbor),
00900 &hct_entry_map,
00901 BB_SET_Union(HB_Blocks(hb),
00902 HB_Blocks(hb_neighbor),
00903 &MEM_HB_pool),
00904 &MEM_pu_pool);
00905 }
00906 } else {
00907 parent_region = Make_New_Region(candidates, HB_Entry(hb),
00908 HB_Exit(hb_neighbor), NULL,
00909 &hct_entry_map,
00910 BB_SET_Union(HB_Blocks(hb),
00911 HB_Blocks(hb_neighbor),
00912 &MEM_HB_pool),
00913 &MEM_pu_pool);
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 Insert_Parent(parent_region, new_region, candidates, hct_entry_map);
00926 Insert_Parent(parent_region, neighbor_region, candidates, hct_entry_map);
00927 return (TRUE);
00928 }
00929
00931 static void
00932 Add_Children(HB_CAND_TREE* new_region,
00933 std::list<HB_CAND_TREE*>& kids,
00934 std::list<HB_CAND_TREE*>& candidates,
00935 BB_MAP hct_entry_map)
00937
00938
00939
00941 {
00942 std::list<HB_CAND_TREE*>::iterator k;
00943
00944 for (k = kids.begin(); k != kids.end(); k++) {
00945 Insert_Parent(new_region, *k, candidates, hct_entry_map);
00946 }
00947 }
00948
00949 static void Clean_Up_Candidates(std::list<HB_CAND_TREE*>& candidates)
00950 {
00951 std::list<HB_CAND_TREE*>::iterator cands;
00952 std::list<HB_CAND_TREE*>::iterator current;
00953 for (cands = candidates.begin(); cands != candidates.end();) {
00954 current = cands++;
00955 if (HB_CAND_TREE_Check_Flag(*current, HCT_ERASE)) {
00956 candidates.erase(current);
00957 }
00958 }
00959 }
00960
00961
00963 void
00964 Check_Parent(HB_CAND_TREE* hct_parent,
00965 HB_CAND_TREE* hct,
00966 std::list<HB_CAND_TREE*>& candidates,
00967 BB_MAP hct_entry_map)
00969
00970
00971
00972
00973
00974
00975
00976
00978 {
00979 if (!HB_CAND_TREE_Parent(hct) &&
00980 !HB_CAND_TREE_Check_Flag(hct, HCT_SINGLE_BLOCK)) {
00981 Insert_Parent(hct_parent, hct, candidates, hct_entry_map);
00982 }
00983 }
00984
00986 void
00987 HB_Identify_Hammock_Candidates(std::list<HB_CAND_TREE*>& candidates,
00988 BB_MAP hct_entry_map)
00990
00991
00992
00994 {
00995 std::list<HB_CAND_TREE*>::iterator cands;
00996
00997 MEM_POOL_Push(&MEM_local_pool);
00998
00999
01000
01001
01002 Find_Interior_Blocks(candidates);
01003
01004 BOOL done;
01005 do {
01006 done = TRUE;
01007
01008 for (cands = candidates.begin(); cands != candidates.end(); cands++) {
01009 HB_CAND_TREE* hct = *cands;
01010 HB_CAND_TREE* hct_parent;
01011
01012
01013
01014
01015
01016 if (!HB_CAND_TREE_Check_Flag(hct, HCT_UNPROCESSED)) {
01017 break;
01018 }
01019
01020 HB_CAND_TREE_Reset_Flag(hct, HCT_UNPROCESSED);
01021 done = FALSE;
01022
01023 HB* hb = HB_CAND_TREE_Candidate(hct);
01024 BB* entry = HB_Entry(hb);
01025 BB* dom;
01026 BB* pdom;
01027
01028 dom = Find_Immediate_Dominator(entry);
01029 for (; dom && BB_SET_MemberP(BB_pdom_set(dom), entry);
01030 dom = Find_Immediate_Dominator(dom));
01031
01032 if (!dom) {
01033
01034
01035
01036 continue;
01037 }
01038
01039 if (BB_kind(dom) != BBKIND_LOGIF) {
01040
01041
01042
01043 continue;
01044 }
01045
01046 hct_parent = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, dom);
01047 if (hct_parent) {
01048 Check_Parent(hct_parent, hct, candidates, hct_entry_map);
01049 continue;
01050 }
01051
01052
01053
01054
01055
01056
01057 if (HB_Fall_Thru_Exit(hb)) {
01058 pdom = HB_Fall_Thru_Exit(hb);
01059 } else {
01060 pdom = Find_Immediate_Postdominator(HB_Exit(hb));
01061 }
01062
01063
01064
01065
01066 for (; pdom && !BB_SET_MemberP(BB_pdom_set(dom), pdom);) {
01067 pdom = Find_Immediate_Postdominator(pdom);
01068 }
01069
01070
01071
01072
01073 if (!pdom || pdom==dom) {
01074 continue;
01075 }
01076
01077 BB_SET* blocks = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
01078 std::list <HB_CAND_TREE*> kids;
01079 if (!Check_Region(&dom, &pdom, blocks, kids,
01080 HB_CAND_TREE_Parent(hct), hct_entry_map)) {
01081 continue;
01082 } else {
01083 hct_parent = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, dom);
01084 if (hct_parent) {
01085 Check_Parent(hct_parent, hct, candidates, hct_entry_map);
01086 continue;
01087 }
01088 }
01089
01090 if ( ! Check_HB_For_PQS_Suitability(blocks, dom)) continue;
01091
01092 #ifdef KEY
01093
01094 BBLIST *succs;
01095 BB *succ;
01096 BOOL skip_this_hammock = FALSE;
01097 BB *member;
01098 FOR_ALL_BB_SET_members (blocks, member) {
01099 FOR_ALL_BB_SUCCS(member, succs) {
01100 succ = BBLIST_item(succs);
01101 if (succ == dom || BB_SET_MemberP(BB_dom_set(dom), succ)) {
01102 skip_this_hammock = TRUE;
01103 break;
01104 }
01105 }
01106 if (skip_this_hammock)
01107 break;
01108 }
01109 if (skip_this_hammock)
01110 continue;
01111 #endif
01112 if ( HB_skip_hammocks ) {
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 if (HB_Trace(HB_TRACE_ID)) fprintf(TFile, "stopping hbf on hammock at BB %d\n", BB_id(entry));
01123 continue;
01124 }
01125
01126
01127
01128
01129
01130
01131
01132 HB_CAND_TREE* new_region;
01133
01134 if (pdom == dom) continue;
01135 if (BB_SET_MemberP(BB_dom_set(pdom), dom)) {
01136 new_region = Make_New_Region(candidates, dom, pdom, NULL,
01137 &hct_entry_map, blocks, &MEM_pu_pool);
01138 } else {
01139 new_region = Make_New_Region(candidates, dom, NULL, pdom,
01140 &hct_entry_map, blocks, &MEM_pu_pool);
01141 }
01142
01143 if (!HB_CAND_TREE_Check_Flag(hct, HCT_SINGLE_BLOCK)) {
01144
01145
01146
01147
01148
01149
01150
01151
01152 Insert_Parent(new_region, hct, candidates, hct_entry_map);
01153
01154
01155
01156
01157 Add_Children(new_region, kids, candidates, hct_entry_map);
01158 }
01159
01160 }
01161 } while (!done);
01162
01163
01164 Clean_Up_Candidates(candidates);
01165
01166
01167
01168
01169 BOOL blocks_merged;
01170 do {
01171 blocks_merged = FALSE;
01172 for (cands = candidates.begin(); cands != candidates.end(); ++cands ) {
01173 if (!HB_CAND_TREE_Check_Flag(*cands, HCT_ERASE)) {
01174 blocks_merged |= Attempt_Merge(*cands, hct_entry_map, candidates);
01175 }
01176 }
01177 } while (blocks_merged);
01178
01179
01180
01181
01182
01183 Clean_Up_Candidates(candidates);
01184
01185 MEM_POOL_Pop(&MEM_local_pool);
01186 }
01187
01189 void
01190 Find_General_Region_Entry_Candidates(std::list<BB*>& entry_candidates,
01191 BB_MAP hct_entry_map)
01193
01194
01195
01196
01198 {
01199 BB* bb;
01200
01201 if (HB_Trace(HB_TRACE_HAMMOCK)) {
01202 fprintf(HB_TFile,"Initial general blocks:");
01203 }
01204
01205 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01206
01207
01208
01209
01210 if (BB_MAP_Get(HB_bb_map, bb) || BB_MAP_Get(hct_entry_map, bb)) {
01211 continue;
01212 }
01213
01214
01215
01216
01217
01218
01219 if (!BB_SET_MemberP(region_bbs, bb) && BB_freq(bb) > HB_minimum_priority
01220 && Check_BB_For_HB_Suitability(bb, bb) && !LOOP_DESCR_Find_Loop(bb)
01221 && BB_kind(bb) == BBKIND_LOGIF) {
01222 entry_candidates.push_front(bb);
01223 if (HB_Trace(HB_TRACE_HAMMOCK)) {
01224 fprintf(HB_TFile," %d",BB_id(bb));
01225 }
01226 }
01227 }
01228 if (HB_Trace(HB_TRACE_HAMMOCK)) {
01229 fprintf(HB_TFile,"\n\n");
01230 }
01231 entry_candidates.sort(BB_Freq_Compare());
01232 }
01233
01235 static BB*
01236 Process_Successors(BB* bb,
01237 std::priority_queue<BB*,vector<BB*>,BB_Freq_Compare>& bb_best,
01238 std::list<BB*>& bb_kids)
01240
01241
01242
01243
01244
01246 {
01247 int succ_count = 0;
01248 float max_prob = -1.0;
01249 BB* max_succ = NULL;
01250 BB* min_succ = NULL;
01251 BBLIST* bl;
01252
01253
01254 FOR_ALL_BB_SUCCS(bb, bl) {
01255 BB* succ = BBLIST_item(bl);
01256 succ_count++;
01257 if (BBLIST_prob(bl) > max_prob) {
01258 if (max_succ) {
01259 min_succ = max_succ;
01260 }
01261 max_prob = BBLIST_prob(bl);
01262 max_succ = succ;
01263 } else {
01264 min_succ = succ;
01265 }
01266 }
01267 if (succ_count > 1) {
01268
01269
01270
01271 if (HB_general_use_pq) {
01272 bb_best.push(min_succ);
01273 } else if (HB_general_from_top) {
01274 bb_kids.push_back(min_succ);
01275 } else {
01276
01277
01278
01279
01280 bb_kids.push_front(min_succ);
01281 }
01282 }
01283 return max_succ;
01284 }
01285
01287 static void
01288 Form_General_Region(BB* bb,
01289 BB* bb_entry,
01290 BB_MAP hct_entry_map,
01291 BB_SET* blocks,
01292 std::list<HB_CAND_TREE*>& kids,
01293 BOOL allow_nesting)
01295
01296
01297
01298
01299
01300
01302 {
01303 std::priority_queue<BB*,vector<BB*>,BB_Freq_Compare> bb_best;
01304
01305 std::list<BB*> bb_kids;
01306
01307
01308
01309
01310 if (BB_MAP_Get(HB_bb_map, bb)) {
01311 return;
01312 }
01313
01314
01315
01316
01317 if (BB_SET_MemberP(region_bbs, bb_entry)) {
01318 return;
01319 }
01320
01321
01322
01323
01324
01325 if (BB_SET_MemberP(region_bbs, bb) && !allow_nesting) {
01326 return;
01327 }
01328
01329 if (BS_Size(blocks) >= HB_max_blocks) {
01330 return;
01331 }
01332
01333
01334
01335
01336 while (bb != NULL) {
01337
01338
01339
01340 if (BB_SET_MemberP(blocks, bb)) {
01341 break;
01342 }
01343
01344
01345
01346
01347 if (!BB_SET_MemberP(BB_dom_set(bb), bb_entry)) {
01348 break;
01349 }
01350
01351
01352
01353
01354
01355 if (!Check_BB_For_HB_Suitability(bb, bb_entry)) {
01356 break;
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 HB_CAND_TREE* hct = (HB_CAND_TREE*) BB_MAP_Get(hct_entry_map, bb);
01369 if (hct && !HB_CAND_TREE_Check_Flag(hct, HCT_GENERAL)) {
01370 if (!allow_nesting) {
01371 break;
01372 }
01373 HB* hb = HB_CAND_TREE_Candidate(hct);
01374 if ((BS_Size(blocks) + BS_Size(HB_Blocks(hb))) > HB_max_blocks) {
01375 break;
01376 }
01377 blocks = BB_SET_UnionD(blocks, HB_Blocks(hb),&MEM_local_pool);
01378 kids.push_front(hct);
01379
01380
01381
01382
01383
01384 if (HB_Fall_Thru_Exit(hb)) {
01385 bb = HB_Fall_Thru_Exit(hb);
01386 continue;
01387 }
01388 bb = Process_Successors(HB_Exit(hb), bb_best, bb_kids);
01389 continue;
01390 }
01391
01392
01393
01394
01395 if (LOOP_DESCR_Find_Loop(bb)) {
01396 break;
01397 }
01398
01399
01400
01401
01402 blocks = BB_SET_Union1D(blocks, bb, &MEM_local_pool);
01403
01404 bb = Process_Successors(bb, bb_best, bb_kids);
01405 if (BS_Size(blocks) >= HB_max_blocks) {
01406 break;
01407 }
01408 }
01409
01410
01411
01412
01413
01414 BOOL done = FALSE;
01415 while (!done) {
01416 if (HB_general_use_pq) {
01417 if (bb_best.empty()) {
01418 done = TRUE;
01419 } else {
01420 Form_General_Region(bb_best.top(), bb_entry, hct_entry_map, blocks,
01421 kids, allow_nesting);
01422 bb_best.pop();
01423 }
01424 } else {
01425 if (bb_kids.empty()) {
01426 done = TRUE;
01427 } else {
01428 Form_General_Region(bb_kids.front(), bb_entry, hct_entry_map, blocks,
01429 kids, allow_nesting);
01430 bb_kids.pop_front();
01431 }
01432 }
01433 }
01434 }
01435
01437 static void
01438 Add_General_Region_To_Tree(BB* bb_entry,
01439 BB_SET* blocks,
01440 std::list<HB_CAND_TREE*>& kids,
01441 BB_MAP hct_entry_map,
01442 std::list<HB_CAND_TREE*>& candidates)
01444
01445
01446
01447
01448
01450 {
01451 if (BS_Size(blocks) < HB_min_blocks) {
01452 return;
01453 }
01454
01455 if (!Check_HB_For_PQS_Suitability(blocks, bb_entry)) return;
01456
01457 HB_CAND_TREE* new_region = Make_New_Region(candidates, bb_entry, NULL, NULL,
01458 &hct_entry_map, blocks,
01459 &MEM_pu_pool);
01460 HB_CAND_TREE_Set_Flag(new_region, HCT_GENERAL);
01461 Add_Children(new_region, kids, candidates, hct_entry_map);
01462 }
01463
01465 void
01466 HB_Identify_General_Candidates(std::list<HB_CAND_TREE*>& candidates,
01467 BB_MAP hct_entry_map,
01468 INT pass)
01470
01471
01472
01474 {
01475 std::list<BB*> entry_candidates;
01476 std::list<BB*>::iterator bbi;
01477
01478 MEM_POOL_Push (&MEM_local_pool);
01479
01480 BB_SET* blocks = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
01481 BOOL allow_nesting = (pass == 1);
01482
01483
01484
01485
01486
01487 if (pass != 1) {
01488 BB_SET_ClearD(region_bbs);
01489 }
01490
01491 Find_General_Region_Entry_Candidates(entry_candidates, hct_entry_map);
01492 for (bbi = entry_candidates.begin(); bbi != entry_candidates.end(); bbi++) {
01493 std::list<HB_CAND_TREE*> kids;
01494 BB_SET_ClearD(blocks);
01495 Form_General_Region(*bbi, *bbi, hct_entry_map, blocks, kids,
01496 allow_nesting);
01497 Add_General_Region_To_Tree(*bbi, blocks, kids, hct_entry_map, candidates);
01498 }
01499
01500 MEM_POOL_Pop (&MEM_local_pool);
01501 Clean_Up_Candidates(candidates);
01502 }