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 #include <vector>
00040 #include <queue>
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 "cg_flags.h"
00048 #include "ttype.h"
00049 #include "bitset.h"
00050 #include "bb.h"
00051 #include "bb_set.h"
00052 #include "freq.h"
00053 #include "whirl2ops.h"
00054 #include "dominate.h"
00055 #include "cgtarget.h"
00056 #include "gra_live.h"
00057 #include "cgexp.h"
00058 #include "gtn_universe.h"
00059 #include "gtn_set.h"
00060 #include "findloops.h"
00061 #include "pqs_cg.h"
00062
00063 #ifdef TARG_IA64
00064 #include "if_conv.h"
00065 #endif
00066
00067 #include "hb.h"
00068 #include "hb_trace.h"
00069 #include "hb_id_candidates.h"
00070 #ifdef KEY
00071 #include "ti_res.h"
00072 #include "data_layout.h"
00073 #endif
00074
00076 static void
00077 dump_control_dependencies(const char * title, HB* hb, BB_MAP control_dependences,
00078 BB_MAP true_edges)
00079 {
00080 BB * bb;
00081 BB_SET* deps;
00082 BB_SET* trues;
00083 fprintf(HB_TFile,"Control dependence dump %s=============================\n",title);
00084 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
00085 fprintf(HB_TFile,"BB%d: C=",BB_id(bb));
00086 deps = (BB_SET*) BB_MAP_Get(control_dependences, bb);
00087 trues = (BB_SET*) BB_MAP_Get(true_edges, bb);
00088 if (deps) {
00089 BB_SET_Print(deps, HB_TFile);
00090 } else {
00091 fprintf(HB_TFile,"<none>");
00092 }
00093 fprintf(HB_TFile," T=");
00094 if (trues) {
00095 BB_SET_Print(trues, HB_TFile);
00096 } else {
00097 fprintf(HB_TFile,"<none>");
00098 }
00099 fprintf(HB_TFile,"\n");
00100 }
00101 fprintf(HB_TFile,"================================================================\n");
00102 }
00103
00104
00106
00107
00108
00109
00110
00111
00112
00114 static void
00115 Calculate_Control_Dependences(HB* hb, BB_MAP control_dependences,
00116 BB_MAP true_edges)
00117 {
00118 BB* bb;
00119 BBLIST* bl;
00120 BB_SET *hb_blocks;
00121 BB *hb_entry;
00122
00123 BB_SET * bb_to_add = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
00124
00125
00126 BB_SET_Calculate_Dominators(HB_Blocks(hb),FALSE,TRUE);
00127
00128
00129
00130
00131 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
00132 BB_SET* deps = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
00133 BB_SET* trues = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
00134 BB_MAP_Set(control_dependences, bb, deps);
00135 BB_MAP_Set(true_edges, bb, trues);
00136 }
00137
00138
00139
00140
00141
00142 hb_blocks = HB_Blocks(hb);
00143 hb_entry = HB_Entry(hb);
00144 FOR_ALL_BB_SET_members(hb_blocks, bb) {
00145 FOR_ALL_BB_SUCCS(bb,bl) {
00146 BB* bb_dep;
00147 BB* bb_succ = BBLIST_item(bl);
00148 #ifdef TARG_IA64
00149 Remove_Explicit_Branch(bb);
00150 #endif
00151 BOOL true_edge = (BB_Fall_Thru_Successor(bb) != bb_succ);
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 if (BB_SET_MemberP(hb_blocks,bb_succ) && (bb_succ != hb_entry)) {
00164 BB_SET_CopyD(bb_to_add,BB_pdom_set(bb_succ),NULL);
00165 bb_to_add = BB_SET_DifferenceD(bb_to_add,BB_pdom_set(bb));
00166 bb_to_add = BB_SET_IntersectionD(bb_to_add,HB_Blocks(hb));
00167 FOR_ALL_BB_SET_members(bb_to_add, bb_dep) {
00168 BB_SET* deps = (BB_SET*) BB_MAP_Get(control_dependences, bb_dep);
00169 BB_SET* trues = (BB_SET*) BB_MAP_Get(true_edges, bb_dep);
00170 BB_SET_Union1D(deps, bb, &MEM_local_pool);
00171 if (true_edge) BB_SET_Union1D(trues, bb, &MEM_local_pool);
00172 }
00173 }
00174 }
00175 }
00176
00177 if (HB_Trace(HB_TRACE_CDEP)) {
00178 dump_control_dependencies("",hb,control_dependences,true_edges);
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 #define CASE_MASK 0xf // 15 bits, but only seven cases
00192 #define CASE_ALL_IN_HB 1 // All sucessors in hyperblock
00193 #define CASE_CALL 2 // A call block, with its successor outside
00194 #define CASE_UNCOND_BR 3 // Unconditional branch to outside HB
00195 #define CASE_FALL_OUT 4 // no branch, fall through outside
00196 #define CASE_IF_FALL_IN 5 // conditional branch to outside HB
00197 #define CASE_IF_FALL_OUT 6 // conditional branch, fallthrough outside HB
00198 #define CASE_IF_OUT 7 // both successors outside HB
00199 #define CASE_CALL_IN 8 // call with successors in HB
00200 #define NO_MERGE 0x100 // next block cannot be merged
00201 #define NEEDS_FTG 0x200 // needs a fall-thru goto
00202
00203 #define Get_Case(x) ((x)&CASE_MASK)
00204 #define No_Merge(x) (((x)&NO_MERGE) != 0)
00205 #define Needs_FTG(x) (((x)&NEEDS_FTG) != 0)
00206
00207
00208
00209
00210
00211 struct FREQ_DATA {
00212 float block_prob;
00213 float branch_prob;
00214 BB * fall_thru;
00215 BB * branch_bb;
00216 FREQ_DATA() {
00217 block_prob = 0.0;
00218 branch_prob = 0.0;
00219 fall_thru = NULL;
00220 branch_bb = NULL;
00221 }
00222 };
00223
00224
00225
00226 static void
00227 Reset_Freq_Data_For_BB(BB *bb, BB_MAP freq_map)
00228 {
00229 BBLIST *bl;
00230 FREQ_DATA *bb_freq_data = (FREQ_DATA *) BB_MAP_Get(freq_map,bb);
00231 #ifdef TARG_IA64
00232 Remove_Explicit_Branch(bb);
00233 #endif
00234 bb_freq_data->fall_thru = BB_Fall_Thru_Successor(bb);
00235 if (bb_freq_data->fall_thru) {
00236 bb_freq_data->branch_prob =
00237 1.0 - BBLIST_prob(BB_Find_Succ(bb, bb_freq_data->fall_thru));
00238 } else {
00239 bb_freq_data->branch_prob = 1.0;
00240 }
00241 bb_freq_data->branch_bb = NULL;
00242 FOR_ALL_BB_SUCCS(bb,bl) {
00243 BB *succ = BBLIST_item(bl);
00244 if (succ != bb_freq_data->fall_thru) {
00245 bb_freq_data->branch_bb = succ;
00246 }
00247 }
00248 }
00249
00250
00251 static
00252 FREQ_DATA * Get_Freq_Data_For_BB(BB *bb, BB_MAP freq_map)
00253 {
00254 FREQ_DATA * bb_freq_data;
00255 bb_freq_data = (FREQ_DATA *) BB_MAP_Get(freq_map, bb);
00256 if (!bb_freq_data) {
00257 bb_freq_data = CXX_NEW(FREQ_DATA, &MEM_local_pool);
00258 BB_MAP_Set(freq_map,bb,bb_freq_data);
00259 Reset_Freq_Data_For_BB(bb,freq_map);
00260 }
00261 return bb_freq_data;
00262 }
00263
00264
00265
00266
00267 static float
00268 Get_Branch_Prob(BB *source, BB *dest, BB_MAP freq_map)
00269 {
00270 FREQ_DATA *fdata = Get_Freq_Data_For_BB(source, freq_map);
00271 if (dest == fdata->fall_thru) {
00272 return ((1.0 - fdata->branch_prob) * fdata->block_prob);
00273 } else {
00274 return (fdata->branch_prob * fdata->block_prob);
00275 }
00276 }
00277
00278
00279
00280
00281 static float
00282 Get_Block_Prob(BB *source,BB_MAP freq_map)
00283 {
00284 FREQ_DATA *fdata = Get_Freq_Data_For_BB(source, freq_map);
00285 return (fdata->block_prob);
00286 }
00287
00288 static BB *
00289 Get_Branch_Block(BB *source,BB_MAP freq_map)
00290 {
00291 FREQ_DATA *fdata = Get_Freq_Data_For_BB(source, freq_map);
00292 return (fdata->branch_bb);
00293 }
00294
00295
00296
00297
00298
00299 static void
00300 replace_block_walk(BB *bb_first, BB *bb_second, HB_CAND_TREE* c, BOOL walk_kids)
00301 {
00302 HB *hb = HB_CAND_TREE_Candidate(c);
00303 BB_SET *blocks = HB_Blocks(hb);
00304 if (BB_SET_MemberP(blocks, bb_second)) {
00305 HB_Remove_Block(hb, bb_second);
00306 HB_Add_Block(hb, bb_first);
00307 }
00308 if (HB_Entry(hb) == bb_second) HB_Entry_Set(hb, bb_first);
00310
00311
00312
00313 if (walk_kids) {
00314 std::list<HB_CAND_TREE*> kids = HB_CAND_TREE_Kids(c);
00315 std::list<HB_CAND_TREE*>::iterator k;
00316 for (k = kids.begin(); k != kids.end(); k++) {
00317 replace_block_walk(bb_first,bb_second,*k,walk_kids);
00318 }
00319 }
00320 }
00321
00322 static void
00323 Replace_Block(BB *bb_first, BB *bb_second, std::list<HB_CAND_TREE*>& candidate_regions)
00324 {
00325 std::list<HB_CAND_TREE*>::iterator hbct;
00326 for (hbct = candidate_regions.begin(); hbct != candidate_regions.end();
00327 hbct++) {
00328 replace_block_walk(bb_first,bb_second,*hbct,TRUE);
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337 static void
00338 add_block_walk(BB *bb, BB *bb_to_add, HB_CAND_TREE* c, BOOL walk_kids)
00339 {
00340 HB *hb = HB_CAND_TREE_Candidate(c);
00341 BB_SET *blocks = HB_Blocks(hb);
00342 if (BB_SET_MemberP(blocks, bb)) {
00343 HB_Add_Block(hb, bb_to_add);
00344 }
00345
00346
00347
00348 if (walk_kids) {
00349 std::list<HB_CAND_TREE*> kids = HB_CAND_TREE_Kids(c);
00350 std::list<HB_CAND_TREE*>::iterator k;
00351 for (k = kids.begin(); k != kids.end(); k++) {
00352 add_block_walk(bb,bb_to_add,*k,walk_kids);
00353 }
00354 }
00355 }
00356
00357 static void
00358 Add_Block(BB *bb, BB *bb_to_add, std::list<HB_CAND_TREE*>& candidate_regions)
00359 {
00360 std::list<HB_CAND_TREE*>::iterator hbct;
00361 for (hbct = candidate_regions.begin(); hbct != candidate_regions.end();
00362 hbct++) {
00363 add_block_walk(bb,bb_to_add,*hbct,TRUE);
00364 }
00365 }
00366
00367
00368 #ifdef KEY
00369 static BOOL merge_failed;
00370 #endif
00372 static void
00373 Merge_Blocks(HB* hb,
00374 BB* bb_first,
00375 BB* bb_second,
00376 BB_MAP freq_map,
00377 BOOL last_block,
00378 std::list<HB_CAND_TREE*>& candidate_regions)
00380
00381
00382
00383
00384
00385
00387 {
00388 OP* op;
00389 BB *succ;
00390 BBLIST *bl;
00391
00392 #if defined KEY && defined TARG_MIPS
00393
00394 if (merge_failed)
00395 return;
00396
00397
00398 OP *op_first = BB_branch_op(bb_first);
00399 OP *op_second = BB_branch_op(bb_second);
00400 if (op_first && op_second) {
00401 if ((OP_code(op_first) == OP_code(op_second)) &&
00402 (OP_code(op_first) == TOP_beq ||
00403 OP_code(op_first) == TOP_bne)) {
00404 FmtAssert((TN_is_label(OP_opnd(op_first, 2)) &&
00405 TN_is_label(OP_opnd(op_second, 2))),
00406 ("branch target should be labelled"));
00407 if (TN_label(OP_opnd(op_first, 2)) !=
00408 TN_label(OP_opnd(op_second, 2))) {
00409 merge_failed = TRUE;
00410 return;
00411 }
00412 } else if ((OP_code(op_first) == OP_code(op_second)) &&
00413 (OP_code(op_first) == TOP_bc1f ||
00414 OP_code(op_first) == TOP_bc1t)) {
00415 FmtAssert((TN_is_label(OP_opnd(op_first, 1)) &&
00416 TN_is_label(OP_opnd(op_second, 1))),
00417 ("branch target should be labelled"));
00418 if (TN_label(OP_opnd(op_first, 1)) !=
00419 TN_label(OP_opnd(op_second, 1))) {
00420 merge_failed = TRUE;
00421 return;
00422 }
00423 } else {
00424
00425 merge_failed = TRUE;
00426 return;
00427 }
00428 }
00429 #endif
00430
00431
00432
00433 OP* op_next;
00434 OP* last = BB_last_op(bb_first);
00435 for (op = BB_first_op(bb_second); op; op = op_next) {
00436 op_next = OP_next(op);
00437 if (last) {
00438 BB_Move_Op(bb_first, last, bb_second, op, FALSE);
00439 } else {
00440 BB_Append_Op (bb_first, op);
00441 }
00442 last = op;
00443 }
00444
00445
00446
00447 while (bl = BB_succs(bb_first)) {
00448 succ = BBLIST_item(bl);
00449 Unlink_Pred_Succ(bb_first, succ);
00450 }
00451
00452
00453
00454
00455 Remove_BB(bb_second);
00456
00457
00458
00459
00460
00461 if (BB_exit(bb_second)) {
00462 BB_Transfer_Exitinfo(bb_second, bb_first);
00463 Exit_BB_Head = BB_LIST_Delete(bb_second, Exit_BB_Head);
00464 Exit_BB_Head = BB_LIST_Push(bb_first, Exit_BB_Head, &MEM_pu_pool);
00465 }
00466
00467
00468
00469
00470 if (BB_call(bb_second)) {
00471 BB_Copy_Annotations(bb_first, bb_second, ANNOT_CALLINFO);
00472 }
00473
00474
00475
00476
00477 FmtAssert(BBlist_Len(BB_succs(bb_second))<=2,("Too many successors"));
00478 if (BBlist_Len(BB_succs(bb_second)) == 1) {
00479 bl = BB_succs(bb_second);
00480 float old_prob = BBLIST_prob(bl);
00481 succ = BBLIST_item(bl);
00482 Unlink_Pred_Succ(bb_second, succ);
00483 Link_Pred_Succ_with_Prob(bb_first, succ, old_prob);
00484 } else {
00485 while (bl = BB_succs(bb_second)) {
00486 succ = BBLIST_item(bl);
00487 Unlink_Pred_Succ(bb_second, succ);
00488 float prob = Get_Branch_Prob(bb_second,succ,freq_map);;
00489 if (succ != Get_Branch_Block(bb_second,freq_map)) {
00490 prob = 1.0 - Get_Branch_Prob(bb_second,succ,freq_map);
00491 }
00492 Link_Pred_Succ_with_Prob(bb_first, succ, prob);
00493 }
00494 }
00495
00496
00497
00498 if (HB_Exit(hb) == bb_second) {
00499 HB_Exit_Set(hb, bb_first);
00500 }
00501
00502 Replace_Block(bb_first,bb_second,candidate_regions);
00503 #if defined KEY && defined TARG_MIPS
00504
00505
00506
00507 OP *op1, *op2, *op3;
00508 op2 = NULL;
00509 FOR_ALL_BB_OPs(bb_first,op1) {
00510 if (OP_code(op1) == TOP_beq ||
00511 OP_code(op1) == TOP_bne ||
00512 OP_code(op1) == TOP_bc1f ||
00513 OP_code(op1) == TOP_bc1t) {
00514 if (op2 == NULL)
00515 op2 = op1;
00516 else {
00517 OPS new_ops;
00518 OPS_Init(&new_ops);
00519 Build_OP(TOP_j, OP_opnd(op2,
00520 (OP_code(op2) == TOP_beq ||
00521 OP_code(op2) == TOP_bne)? 2: 1), &new_ops);
00522 BB_Append_Ops(bb_first, &new_ops);
00523 OP_Change_To_Noop(op2);
00524 OP_Change_To_Noop(op1);
00525 break;
00526 }
00527 }
00528 }
00529 printf("MERGE PASSED\n");
00530 #endif
00531 }
00532
00533
00534
00535 static void
00536 AND_Predicate_To_OP (OP *op, TN *ptn1, TN *ptn2,
00537 BB *bb_insert_point, OP *op_insert_point, BB_SET *hb_blocks)
00538 {
00539
00540
00541 typedef struct {
00542 BB *bb;
00543 TN *ptn1;
00544 TN *ptn2;
00545 TN *new_ptn;
00546 } last_and_pred_t;
00547 static last_and_pred_t last_and_pred = {NULL,NULL,NULL,NULL};
00548 BB *bb;
00549 BB *insert_bb;
00550 OP *insert_before_op = NULL;
00551 OP *o;
00552 OP *new_op;
00553 OP *def_ptn1_op = NULL;
00554 OP *def_ptn2_op = NULL;
00555 TN *new_ptn;
00556 if (ptn2 == ptn1) return;
00557 if (ptn2 == True_TN) {
00558 Set_OP_opnd(op, OP_PREDICATE_OPND, ptn1);
00559 return;
00560 }
00561 if (bb_insert_point == last_and_pred.bb
00562 && ptn1 == last_and_pred.ptn1
00563 && ptn2 == last_and_pred.ptn2)
00564 {
00565 DevWarn("reusing last predicate and");
00566 new_ptn = last_and_pred.new_ptn;
00567 Set_OP_opnd(op, OP_PREDICATE_OPND, new_ptn);
00568 return;
00569 }
00570 else {
00571 last_and_pred.bb = NULL;
00572 last_and_pred.ptn1 = last_and_pred.ptn2
00573 = last_and_pred.new_ptn = NULL;
00574 }
00575
00576 DevWarn("and controlling predicate TN%d to current predicate TN%d", TN_number(ptn1), TN_number(ptn2));
00577
00578
00579
00580
00581
00582
00583 #if 0
00584 DEF_KIND kind;
00585 compare_op = TN_Reaching_Value_At_Op(ptn1, op, &kind, TRUE);
00586 if (compare_op == NULL
00587 || kind != VAL_KNOWN
00588 || OP_cond_def(compare_op))
00589 {
00590 compare_op = NULL;
00591 }
00592 #else
00593
00594
00595
00596
00597 FOR_ALL_BB_SET_members(hb_blocks, bb) {
00598 FOR_ALL_BB_OPs(bb,o) {
00599 if (OP_Defs_TN (o, ptn1)) {
00600 if (HB_Trace(HB_TRACE_CONVERT)) {
00601 fprintf(TFile, "def_ptn1_op: ");
00602 Print_OP_No_SrcLine(o);
00603 if (def_ptn1_op != NULL) Print_All_BBs();
00604 }
00605 FmtAssert(def_ptn1_op == NULL,
00606 ("and_pred mult defs; try recompiling with -CG:hb_exclude_pgtns=on"));
00607 def_ptn1_op = o;
00608 }
00609 if (OP_Defs_TN (o, ptn2)) {
00610 if (HB_Trace(HB_TRACE_CONVERT)) {
00611 fprintf(TFile, "def_ptn2_op: ");
00612 Print_OP_No_SrcLine(o);
00613 if (def_ptn2_op != NULL) Print_All_BBs();
00614 }
00615 FmtAssert(def_ptn2_op == NULL,
00616 ("and_pred mult defs; try recompiling with -CG:hb_exclude_pgtns=on"));
00617 def_ptn2_op = o;
00618 }
00619 }
00620 }
00621 #endif
00622 FmtAssert(def_ptn1_op != NULL, ("and_pred no def; try recompiling with -CG:hb_exclude_pgtns=on"));
00623 FmtAssert(def_ptn2_op != NULL, ("and_pred2 no def; try recompiling with -CG:hb_exclude_pgtns=on"));
00624 FmtAssert(OP_has_predicate(def_ptn1_op), ("and_pred no qp; try recompiling with -CG:hb_exclude_pgtns=on"));
00625 FmtAssert(OP_has_predicate(def_ptn2_op), ("and_pred2 no qp; try recompiling with -CG:hb_exclude_pgtns=on"));
00626
00627 new_op = Dup_OP(def_ptn1_op);
00628 if (OP_opnd(new_op, OP_PREDICATE_OPND) != True_TN) {
00629
00630
00631
00632 if (HB_Trace(HB_TRACE_CONVERT)) {
00633 fprintf(TFile, "bbs before recursive predicate AND:");
00634 Print_All_BBs();
00635 }
00636 AND_Predicate_To_OP (new_op, ptn2,
00637 OP_opnd(new_op, OP_PREDICATE_OPND),
00638 bb_insert_point, op_insert_point, hb_blocks);
00639 }
00640 else {
00641 Set_OP_opnd(new_op, OP_PREDICATE_OPND, ptn2);
00642 }
00643 new_ptn = Gen_Predicate_TN();
00644 Set_OP_opnd(op, OP_PREDICATE_OPND, new_ptn);
00645 if (OP_result(new_op,0) == ptn1) {
00646 Set_OP_result(new_op, 0, new_ptn);
00647 Set_OP_result(new_op, 1, True_TN);
00648 }
00649 else if (OP_result(new_op,1) == ptn1) {
00650 Set_OP_result(new_op, 0, True_TN);
00651 Set_OP_result(new_op, 1, new_ptn);
00652 }
00653 else
00654 FmtAssert(FALSE, ("where is ptn1 defined?"));
00655
00656 if (OP_bb(def_ptn1_op) != OP_bb(def_ptn2_op)) {
00657 DevWarn("and_pred defs in different bb");
00658 if (HB_Trace(HB_TRACE_CONVERT)) {
00659 Print_All_BBs();
00660 }
00661
00662
00663
00664 insert_bb = bb_insert_point;
00665 insert_before_op = op_insert_point;
00666
00667 Set_TN_is_global_reg (ptn1);
00668 Set_TN_is_global_reg (ptn2);
00669 INT i;
00670 for (i=0; i<OP_opnds(new_op); i++) {
00671 if (i == OP_PREDICATE_OPND) continue;
00672 if (! TN_is_register(OP_opnd(new_op,i))) continue;
00673 if (TN_is_dedicated(OP_opnd(new_op,i))) continue;
00674 Set_TN_is_global_reg (OP_opnd(new_op,i));
00675 }
00676 }
00677 else {
00678
00679
00680
00681 insert_bb = OP_bb(def_ptn1_op);
00682 insert_before_op = BB_xfer_op(insert_bb);
00683 }
00684 if (HB_Trace(HB_TRACE_CONVERT)) {
00685 fprintf(TFile, "before insert: ");
00686 Print_BB_No_Srclines(insert_bb);
00687 }
00688 if (insert_before_op != NULL) {
00689 BB_Insert_Op_Before (insert_bb, insert_before_op, new_op);
00690 } else {
00691 BB_Append_Op (insert_bb, new_op);
00692 }
00693 if (HB_Trace(HB_TRACE_CONVERT)) {
00694 fprintf(TFile, "after insert: ");
00695 Print_BB_No_Srclines(insert_bb);
00696 }
00697 last_and_pred.bb = bb_insert_point;
00698 last_and_pred.ptn1 = ptn1;
00699 last_and_pred.ptn2 = ptn2;
00700 last_and_pred.new_ptn = new_ptn;
00701 if (HB_Trace(HB_TRACE_CONVERT)) {
00702 fprintf(TFile, "new_op: ");
00703 Print_OP_No_SrcLine(new_op);
00704 Print_OP_No_SrcLine(op);
00705 }
00706 }
00707
00708 #if defined KEY && defined TARG_MIPS
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 static ST *ifcbh_node_int = NULL;
00722 static ST *ifcbh_node_float = NULL;
00723 static ST *latest_pu = NULL;
00724
00725 void
00726 Generate_Black_Holes()
00727 {
00728
00729 if ( latest_pu == Get_Current_PU_ST() )
00730 return;
00731
00732 latest_pu = Get_Current_PU_ST();
00733
00734 ifcbh_node_int = Gen_Temp_Symbol( Spill_Int_Type, "ifc_blackhole_int" );
00735 ifcbh_node_float = Gen_Temp_Symbol( Spill_Float_Type, "ifc_blackhole_float" );
00736 Allocate_Temp_To_Memory( ifcbh_node_int );
00737 Allocate_Temp_To_Memory( ifcbh_node_float );
00738 }
00739
00740 #define MAX_BLACK_HOLE_OFFSET 0x800
00741
00742 BOOL
00743 Safe_Offset( INT64 offset, OP *op )
00744 {
00745 return offset > - (0x8000 - MAX_BLACK_HOLE_OFFSET);
00746 }
00747
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 void
00761 Predicate_Read_Write( OPS *ops, OP *op, TN *tn_predicate )
00762 {
00763 Generate_Black_Holes();
00764
00765 BOOL op_is_load = FALSE;
00766 if (OP_load(op))
00767 op_is_load = TRUE;
00768
00769
00770
00771
00772
00773
00774
00775 UINT8 opnd_base = OP_find_opnd_use( op, OU_base );
00776 UINT8 opnd_offset = OP_find_opnd_use( op, OU_offset );
00777 TN *tn_offset = OP_opnd( op, opnd_offset );
00778 if ( ! TN_is_constant( tn_offset ) || ! TN_has_value( tn_offset ) ||
00779 Safe_Offset( TN_value( tn_offset ), op ) == FALSE ) {
00780
00781 TN *tn_zero = Gen_Literal_TN( 0, 4 );
00782 TN *tn_new_base = Build_TN_Like( OP_opnd( op, opnd_base ) );
00783
00784 Exp_OP2( Pointer_Size == 4 ? OPC_I4ADD : OPC_I8ADD,
00785 tn_new_base, OP_opnd( op, opnd_base ), tn_offset, ops );
00786
00787
00788
00789 TOP new_opcode = CGTARG_Equiv_Nonindex_Memory_Op( op );
00790 if ( new_opcode != TOP_UNDEFINED ) {
00791 OP_Change_Opcode( op, new_opcode );
00792 }
00793 Set_OP_opnd( op, opnd_base, tn_new_base );
00794 Set_OP_opnd( op, opnd_offset, tn_zero );
00795 tn_offset = tn_zero;
00796 }
00797
00798
00799
00800
00801 TN *tn_loadstoreval =
00802 (op_is_load != TRUE)? OP_opnd( op, OP_find_opnd_use( op, OU_storeval ) )
00803 : OP_result( op, 0);
00804 ST *st_addr =
00805 TN_is_float( tn_loadstoreval ) ? ifcbh_node_float : ifcbh_node_int;
00806 TN *tn_hole_base = Build_TN_Like( OP_opnd( op, opnd_base ) );
00807 Exp_Lda( Pointer_type, tn_hole_base, st_addr,
00808 - TN_value( tn_offset ), OPERATOR_UNKNOWN, ops );
00809
00810
00811
00812
00813 TN *tn_base = OP_opnd( op, opnd_base );
00814 TN *tn_safe_base = Build_TN_Like( tn_base );
00815 Build_OP(TOP_or, tn_safe_base, tn_base, Zero_TN, ops);
00816 if (TN_register_class(tn_predicate) == ISA_REGISTER_CLASS_fcc)
00817 Build_OP(TOP_movt, tn_safe_base, tn_hole_base, tn_predicate, ops);
00818 else
00819 Build_OP(TOP_movn, tn_safe_base, tn_hole_base, tn_predicate, ops);
00820 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00821 Set_OP_opnd( op, opnd_base, tn_safe_base );
00822 }
00823 #endif
00825 void
00826 Predicate_Block(BB* bb, TN *pred_tn, BB_SET *hb_blocks)
00828
00829
00830
00831
00832
00833
00835 {
00836 BOOL all_local;
00837 INT i;
00838 TN *result_tn;
00839
00840 if (pred_tn && pred_tn != True_TN) {
00841 for (OP* op = BB_first_op(bb); op != NULL; op = OP_next(op)) {
00842 #if defined KEY && defined TARG_MIPS
00843 switch(op->opr) {
00844 case TOP_j:
00845 {
00846
00847 OPS new_ops;
00848 OPS_Init(&new_ops);
00849 if (TN_register_class(pred_tn) == ISA_REGISTER_CLASS_fcc)
00850 Build_OP(TOP_bc1f, pred_tn, OP_opnd(op, 0), &new_ops);
00851 else
00852 Build_OP(TOP_beq, pred_tn, Zero_TN, OP_opnd(op, 0), &new_ops);
00853 BB_Insert_Ops_Before(bb, op, &new_ops);
00854 OP_Change_To_Noop(op);
00855 break;
00856 }
00857 default:
00858 {
00859 if (OP_load(op)) {
00860 OPS new_ops;
00861 OPS_Init(&new_ops);
00862 Predicate_Read_Write(&new_ops, op, pred_tn);
00863 BB_Insert_Ops_Before(bb, op, &new_ops);
00864 break;
00865 } else if (OP_results(op) == 1) {
00866
00867
00868 if (!GRA_LIVE_TN_Live_Outof_BB (OP_result(op, 0), bb))
00869 break;
00870 if (Eager_Level >= EAGER_MEMORY) {
00871
00872
00873
00874 BOOL unremovable_op = FALSE;
00875 for (OP *op_next = op->next;
00876 op_next != NULL && unremovable_op != TRUE;
00877 op_next = op_next->next) {
00878 if (OP_load(op_next)) {
00879 TN *tn = OP_result(op, 0);
00880 for (INT i = 0; i < OP_opnds(op_next); i ++) {
00881 if (OP_opnd(op_next, i) == tn) {
00882 unremovable_op = TRUE;
00883 break;
00884 }
00885 }
00886 }
00887 }
00888 if (unremovable_op)
00889 break;
00890 }
00891
00892 if (TN_register_class(OP_result(op, 0)) ==
00893 ISA_REGISTER_CLASS_hilo)
00894 break;
00895 TN *res_tn = Build_TN_Like(OP_result(op, 0));
00896 OPS new_ops;
00897 OPS_Init(&new_ops);
00898 INT opnds = OP_opnds(op);
00899 FmtAssert((opnds != 0 && opnds <= 3), ("Handle this case"));
00900 if (OP_cond_def(op))
00901
00902 opnds = 4;
00903 switch(opnds) {
00904 case 1:
00905 Build_OP(OP_code(op), res_tn, OP_opnd(op, 0),
00906 &new_ops);
00907 break;
00908 case 2:
00909 Build_OP(OP_code(op), res_tn, OP_opnd(op, 0), OP_opnd(op, 1),
00910 &new_ops);
00911 break;
00912 case 3:
00913 Build_OP(OP_code(op), res_tn, OP_opnd(op, 0), OP_opnd(op, 1),
00914 OP_opnd(op, 2),
00915 &new_ops);
00916 break;
00917 }
00918 FmtAssert(!TN_is_fcc_register(res_tn),
00919 ("Handle this case"));
00920 if (!OP_cond_def(op)) {
00921 if (!TN_is_float(res_tn)) {
00922 if (TN_register_class(pred_tn) == ISA_REGISTER_CLASS_fcc)
00923 Build_OP(TOP_movf, OP_result(op, 0), res_tn,
00924 pred_tn, &new_ops);
00925 else
00926 Build_OP(TOP_movz, OP_result(op, 0), res_tn,
00927 pred_tn, &new_ops);
00928 } else {
00929 if (TN_register_class(pred_tn) == ISA_REGISTER_CLASS_fcc)
00930 Build_OP(TN_size(res_tn)==4?TOP_movf_s:TOP_movf_d,
00931 OP_result(op, 0), res_tn, pred_tn, &new_ops);
00932 else
00933 Build_OP(TN_size(res_tn)==4?TOP_movz_s:TOP_movz_d,
00934 OP_result(op, 0), res_tn, pred_tn, &new_ops);
00935 }
00936 } else {
00937 FmtAssert(TN_register_class(pred_tn) != ISA_REGISTER_CLASS_fcc,
00938 ("We do not handle float branches yet"));
00939 FmtAssert(TN_register_class(OP_opnd(op, 2)) !=
00940 ISA_REGISTER_CLASS_fcc,
00941 ("We do not handle float cond ops yet"));
00942 TN *tmp_tn = Build_TN_Like(pred_tn);
00943 if (OP_code(op) == TOP_movz || OP_code(op) == TOP_movz_d ||
00944 OP_code(op) == TOP_movz_d) {
00945 Build_OP(TOP_or, tmp_tn, OP_opnd(op, 1), pred_tn, &new_ops);
00946 Build_OP(OP_code(op), OP_result(op, 0), OP_opnd(op, 0),
00947 tmp_tn, &new_ops);
00948 } else {
00949
00950
00951 Build_OP(TOP_xor, tmp_tn, OP_opnd(op, 1), Zero_TN, &new_ops);
00952 Build_OP(TOP_sltiu, tmp_tn, tmp_tn, Gen_Literal_TN(1, 4),
00953 &new_ops);
00954 Build_OP(TOP_or, tmp_tn, tmp_tn, pred_tn, &new_ops);
00955 switch(OP_code(op)) {
00956 case TOP_movn:
00957 Build_OP(TOP_movz, OP_result(op, 0), OP_opnd(op, 0), tmp_tn,
00958 &new_ops);
00959 break;
00960 case TOP_movn_d:
00961 Build_OP(TOP_movz_d, OP_result(op, 0), OP_opnd(op, 0),
00962 tmp_tn,&new_ops);
00963 break;
00964 case TOP_movn_s:
00965 Build_OP(TOP_movz_s, OP_result(op, 0), OP_opnd(op, 0),
00966 tmp_tn, &new_ops);
00967 break;
00968 default:
00969 FmtAssert(FALSE, ("Handle this case"));
00970 }
00971 }
00972 }
00973 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
00974 BB_Insert_Ops_Before(bb, op, &new_ops);
00975 OP_Change_To_Noop(op);
00976 break;
00977 } else if (OP_store(op)) {
00978 OPS new_ops;
00979 OPS_Init(&new_ops);
00980 Predicate_Read_Write(&new_ops, op, pred_tn);
00981 BB_Insert_Ops_Before(bb, op, &new_ops);
00982 break;
00983 }
00984 }
00985 }
00986 #endif
00987 if ( ! OP_has_predicate(op)) continue;
00988
00989 if (TN_is_true_pred(OP_opnd(op, OP_PREDICATE_OPND))) {
00990 CGTARG_Predicate_OP(bb, op, pred_tn);
00991 #ifdef TARG_IA64
00992 if (OP_icmp(op)
00993 || OP_code(op) == TOP_tbit_nz
00994 || OP_code(op) == TOP_tbit_z
00995 || OP_code(op) == TOP_fcmp_eq
00996 || OP_code(op) == TOP_fcmp_ge
00997 || OP_code(op) == TOP_fcmp_gt
00998 || OP_code(op) == TOP_fcmp_le
00999 || OP_code(op) == TOP_fcmp_lt
01000 || OP_code(op) == TOP_fcmp_neq
01001 || OP_code(op) == TOP_fcmp_nge
01002 || OP_code(op) == TOP_fcmp_ngt
01003 || OP_code(op) == TOP_fcmp_nle
01004 || OP_code(op) == TOP_fcmp_nlt
01005 || OP_code(op) == TOP_fcmp_ord
01006 || OP_code(op) == TOP_fcmp_unord)
01007 {
01008
01009
01010
01011 TOP top = CGTARG_Get_unc_Variant(OP_code(op));
01012 if (top != OP_code(op)) {
01013 DevWarn("predicate, so change opcode to %s", TOP_Name(top));
01014 OP_Change_Opcode(op, top);
01015 }
01016 }
01017
01018
01019 if (Is_Para_Comp_May_Def(op))
01020 continue;
01021 #endif
01022
01023
01024
01025
01026
01027
01028 if (OP_store(op)) {
01029 all_local = FALSE;
01030 } else {
01031 all_local = TRUE;
01032 }
01033 for ( i = OP_results(op) - 1; i >= 0; --i ) {
01034 result_tn = OP_result(op, i);
01035 if (TN_is_register(result_tn) && !TN_is_const_reg(result_tn)) {
01036 if (TN_is_global_reg(result_tn) || TN_is_dedicated(result_tn)) {
01037 all_local = FALSE;
01038 break;
01039 }
01040 }
01041 }
01042
01043 if (all_local && OP_cond_def(op)) {
01044 Set_OP_cond_def_kind(op,OP_ALWAYS_UNC_DEF);
01045 }
01046 }
01047 else if ( ! HB_exclude_pgtns) {
01048
01049
01050
01051
01052 TN *ptn = OP_opnd(op, OP_PREDICATE_OPND);
01053 if (TN_is_global_reg(ptn) && ptn != pred_tn) {
01054 DevWarn("bb %d: need to predicate existing predicate %d with %d", BB_id(bb), TN_number(ptn), TN_number(pred_tn));
01055 if (HB_Trace(HB_TRACE_CONVERT)) {
01056 fprintf(TFile, "predicate global pred in: ");
01057 Print_OP_No_SrcLine(op);
01058 }
01059 if ( PQSCG_is_disjoint(pred_tn, ptn)) {
01060 DevWarn("disjoint predicates so remove op");
01061 BB_Remove_Op(bb, op);
01062 }
01063 else if ( PQSCG_is_subset_of(ptn, pred_tn)) {
01064
01065 }
01066 else if ( PQSCG_is_subset_of(pred_tn, ptn)) {
01067
01068 DevWarn("subset predicates so switch predicates");
01069 Set_OP_opnd(op, OP_PREDICATE_OPND, pred_tn);
01070 }
01071 else {
01072 AND_Predicate_To_OP (op, pred_tn, ptn, bb, op, hb_blocks);
01073 }
01074 }
01075 }
01076 }
01077 }
01078 }
01079
01081
01082
01083
01084
01085
01086
01087
01088 static BB*
01089 Make_Fall_Thru_Goto(BB* bb,
01090 BB* fall_thru_exit,
01091 TN * pred_tn,
01092 float block_freq,
01093 float fall_thru_prob,
01094 float goto_executes_prob,
01095 std::list<HB_CAND_TREE*>& candidate_regions,
01096 BOOL last_block,
01097 BB_SET *hb_blocks)
01098 {
01099 BB* fall_thru_goto = Gen_And_Insert_BB_After(bb);
01100 Unlink_Pred_Succ(bb, fall_thru_exit);
01101 Link_Pred_Succ_with_Prob(bb, fall_thru_goto,fall_thru_prob);
01102 BB_freq(fall_thru_goto) = block_freq;
01103
01104 Add_Goto(fall_thru_goto, fall_thru_exit);
01105 if (pred_tn && pred_tn != True_TN) {
01106 Make_Branch_Conditional(fall_thru_goto);
01107 Predicate_Block(fall_thru_goto,pred_tn, hb_blocks);
01108 Unlink_Pred_Succ(fall_thru_goto, fall_thru_exit);
01109 Link_Pred_Succ_with_Prob(fall_thru_goto,fall_thru_exit,goto_executes_prob);
01110 }
01111
01112
01113 Add_Block(bb,fall_thru_goto,candidate_regions);
01114 GRA_LIVE_Compute_Liveness_For_BB(fall_thru_goto);
01115
01116 return fall_thru_goto;
01117 }
01118
01119
01120 static INT
01121 Classify_BB(BB *bb, HB *hb)
01122 {
01123 INT result;
01124 BB *fall_thru;
01125 BB *other_succ;
01126 BOOL fall_thru_out;
01127 BOOL other_out;
01128 OP *br;
01129 BBLIST *bl;
01130
01131 result = 0;
01132
01133 if (BB_exit(bb) || BB_call(bb)) {
01134 result |= NO_MERGE;
01135 }
01136
01137 #ifdef TARG_IA64
01138 Remove_Explicit_Branch(bb);
01139 #endif
01140 fall_thru = BB_Fall_Thru_Successor(bb);
01141 other_succ = NULL;
01142
01143 FOR_ALL_BB_SUCCS(bb, bl) {
01144 other_succ = BBLIST_item(bl);
01145 if (other_succ != fall_thru) break;
01146 }
01147
01148
01149 other_out = FALSE;
01150 fall_thru_out = FALSE;
01151
01152 if (fall_thru && (!HB_Contains_Block(hb, fall_thru) ||
01153 fall_thru == HB_Entry(hb))) {
01154 fall_thru_out = TRUE;
01155 }
01156 if (other_succ && (!HB_Contains_Block(hb, other_succ) ||
01157 other_succ == HB_Entry(hb))) {
01158 other_out = TRUE;
01159 }
01160 if (!other_out && !fall_thru_out) {
01161 if (BB_exit(bb) || BB_call(bb)) {
01162 result |= CASE_CALL_IN;
01163 } else {
01164 result |= CASE_ALL_IN_HB;
01165 }
01166 return (result);
01167 }
01168
01169
01170 result |= NO_MERGE;
01171 if (BB_exit(bb) || BB_call(bb)) {
01172 result |= CASE_CALL;
01173 result |= NEEDS_FTG;
01174 return result;
01175 }
01176
01177 br = BB_branch_op(bb);
01178
01179 if (!br) {
01180
01181
01182 result |= CASE_FALL_OUT;
01183 return result;
01184 }
01185
01186 if (!OP_cond(br)) {
01187
01188 result |= CASE_UNCOND_BR;
01189 return result;
01190 }
01191
01192
01193 FmtAssert(fall_thru && other_succ,
01194 ("Conditional branch block (BB%d) with only one successor",BB_id(bb)));
01195 FmtAssert(fall_thru_out || other_out,("Bad identification logic"));
01196 if (fall_thru_out && other_out) {
01197 result |= NEEDS_FTG;
01198 result |= CASE_IF_OUT;
01199 } else if (fall_thru_out && !other_out) {
01200 result |= CASE_IF_FALL_OUT;
01201 } else {
01202 result |= CASE_IF_FALL_IN;
01203 }
01204 return result;
01205 }
01206
01207
01209
01210
01211
01212
01213
01214
01215
01217
01218 static BOOL
01219 Order_And_Classify_Blocks(HB* hb,
01220 std::vector<BB *> &block_order,
01221 std::vector<INT> &block_class)
01222 {
01223 std::queue<BB *> blocks_to_do;
01224 BB * bb;
01225 BBLIST *bl;
01226 BB *succ;
01227
01228
01229 BB_MAP predecessor_count = BB_MAP32_Create();
01230 HB_Predecessor_Count(hb, predecessor_count);
01231
01232
01233
01234
01235 blocks_to_do.push(HB_Entry(hb));
01236
01237
01238
01239
01240
01241
01242 INT pred_count;
01243 while (!blocks_to_do.empty()) {
01244 bb = blocks_to_do.front();
01245 blocks_to_do.pop();
01246 pred_count = BB_MAP32_Get(predecessor_count, bb);
01247 if (pred_count == 0) {
01248
01249
01250
01251
01252
01253 BB_MAP32_Set(predecessor_count, bb, -1);
01254 block_order.push_back(bb);
01255 block_class.push_back(Classify_BB(bb,hb));
01256
01257 FOR_ALL_BB_SUCCS(bb,bl) {
01258 succ = BBLIST_item(bl);
01259
01260 if (BB_SET_MemberP(HB_Blocks(hb),succ) && succ != HB_Entry(hb)) {
01261 BB_MAP32_Set(predecessor_count, succ, BB_MAP32_Get(predecessor_count,succ)-1);
01262 blocks_to_do.push(succ);
01263 }
01264 }
01265 } else if (pred_count > 0) {
01266
01267 blocks_to_do.push(bb);
01268 }
01269 }
01270
01271 BB_MAP_Delete(predecessor_count);
01272
01273
01274
01275
01276
01277
01278 INT i;
01279 for (i = 0; i < block_order.size()-1; i++) {
01280 if (No_Merge(block_class[i])) return (FALSE);
01281 }
01282
01283 return (TRUE);
01284 }
01285
01286 #undef CHECK_FREQENCIES
01287 #ifdef CHECK_FREQENCIES
01289 //
01290
01291
01292 static void
01293 Check_Block_Frequencies(BB_SET* bbs, char *label)
01294 {
01295 INT idx;
01296 BB *b;
01297 BBLIST *bl;
01298 float succ_total;
01299 float succ_prob;
01300 INT num_succs;
01301
01302 FOR_ALL_BB_SET_members(bbs,b) {
01303 succ_total = 0;
01304 num_succs = 0;
01305
01306 FOR_ALL_BB_SUCCS(b,bl) {
01307 ++num_succs;
01308 succ_prob = BBLIST_prob(bl);
01309 if (succ_prob < 0 || succ_prob > 1.0) {
01310 fprintf(HB_TFile,"%s: Bad succ prob %e on arc BB%d -> BB%d\n",label,
01311 succ_prob,BB_id(b),BB_id(BBLIST_item(bl)));
01312 }
01313 succ_total += succ_prob;
01314 }
01315 if (num_succs != 0 && (succ_total < 0.9999 || succ_total > 1.0001)) {
01316 fprintf(HB_TFile,"%s: Bad succ total %e for BB%d\n",label,
01317 succ_total,BB_id(b));
01318 }
01319 }
01320 }
01321 #endif
01322
01324
01325
01326
01327 static void
01328 Compute_Block_Frequencies(std::vector<BB *> &block_order, BB_MAP freq_map)
01329 {
01330 INT idx;
01331 FREQ_DATA *bb_freq_data;
01332 BB *bb;
01333 BB *succ;
01334 BBLIST *bl;
01335
01336 for (idx = 0; idx < block_order.size(); idx++) {
01337
01338 bb = block_order[idx];
01339 bb_freq_data = Get_Freq_Data_For_BB(bb,freq_map);
01340 if (idx == 0) {
01341
01342 bb_freq_data->block_prob = 1.0;
01343 }
01344
01345
01346
01347
01348
01349
01350 FOR_ALL_BB_SUCCS(bb,bl) {
01351 float succ_prob = BBLIST_prob(bl);
01352 succ = BBLIST_item(bl);
01353 if (succ != block_order[0]) {
01354
01355
01356
01357
01358 FREQ_DATA * succ_freq_data = Get_Freq_Data_For_BB(succ,freq_map);
01359 succ_freq_data->block_prob += succ_prob*bb_freq_data->block_prob;
01360 }
01361 }
01362 }
01363 }
01364
01365
01366 #if defined KEY && defined TARG_MIPS
01367 BOOL Okay_To_Predicate_BB (BB *bb, BB *prev_bb)
01368 {
01369 if (BB_branch_op(bb) && BB_branch_op(prev_bb) &&
01370 !OP_cond(BB_branch_op(bb)) && OP_cond(BB_branch_op(prev_bb))) {
01371 if (OP_code(BB_branch_op(prev_bb)) == TOP_beq ||
01372 OP_code(BB_branch_op(prev_bb)) == TOP_bne) {
01373 if (TN_is_label(OP_opnd(BB_branch_op(bb), 0)) &&
01374 TN_is_label(OP_opnd(BB_branch_op(prev_bb), 2))) {
01375 if (TN_label(OP_opnd(BB_branch_op(bb), 0)) ==
01376 TN_label(OP_opnd(BB_branch_op(prev_bb), 2)))
01377 return TRUE;
01378 else
01379 return FALSE;
01380 } else {
01381 return FALSE;
01382 }
01383 } else {
01384 FmtAssert((OP_code(BB_branch_op(prev_bb)) == TOP_bc1f ||
01385 OP_code(BB_branch_op(prev_bb)) == TOP_bc1t),
01386 ("Handle this case"));
01387 if (TN_is_label(OP_opnd(BB_branch_op(bb), 0)) &&
01388 TN_is_label(OP_opnd(BB_branch_op(prev_bb), 1))) {
01389 if (TN_label(OP_opnd(BB_branch_op(bb), 0)) ==
01390 TN_label(OP_opnd(BB_branch_op(prev_bb), 1)))
01391 return TRUE;
01392 else
01393 return FALSE;
01394 } else {
01395 return FALSE;
01396 }
01397 }
01398 } else if (BB_length(prev_bb) == 0) {
01399 return FALSE;
01400 } else {
01401 return TRUE;
01402 }
01403 }
01404 #endif
01406 //
01407
01408
01409
01411 static BB *
01412 Remove_Branches(HB* hb,
01413 BB_MAP predicate_tns,
01414 std::vector<BB *> &block_order,
01415 std::vector<INT> &block_class,
01416 std::list<HB_CAND_TREE*>& candidate_regions)
01417 {
01418 BB * bb;
01419 BB * last_ft_block = NULL;
01420 BB * prev_bb;
01421 INT idx;
01422 BB *fall_thru;
01423 BB *branch_bb;
01424 BB *fall_thru_goto;
01425 BOOL last_block;
01426 BOOL prev_bb_unmergeable;
01427 BB_MAP freq_map;
01428 FREQ_DATA *bb_freq_data;
01429 float hb_continuation_prob;
01430 float prev_hb_continuation_prob;
01431 float block_freq;
01432
01433 #ifdef CHECK_FREQENCIES
01434 Check_Block_Frequencies(HB_Blocks(hb),"Before");
01435 #endif
01436
01437
01438
01439
01440 freq_map = BB_MAP_Create();
01441 Compute_Block_Frequencies(block_order,freq_map);
01442
01443
01444 if (!PQSCG_pqs_valid()) {
01445 PQSCG_reinit(REGION_First_BB);
01446 }
01447
01448
01449 if (HB_Trace(HB_TRACE_CONVERT)) {
01450 INT i;
01451 fprintf(HB_TFile, "<HB> Converted block order:\n<HB>\t");
01452 for (i = 0; i < block_order.size(); i++) {
01453 fprintf(HB_TFile, "%d(%d[%5.3f]) ",BB_id(block_order[i]),Get_Case(block_class[i]),
01454 Get_Block_Prob(block_order[i],freq_map));
01455 if (No_Merge(block_class[i])) {
01456 fprintf(HB_TFile, "| ");
01457 }
01458 if (Needs_FTG(block_class[i])) {
01459 fprintf(HB_TFile, "G | ");
01460 }
01461 }
01462 fprintf(HB_TFile, "\n");
01463 }
01464
01465
01466
01467
01468
01469 fall_thru_goto = NULL;
01470 prev_bb = NULL;
01471 block_freq = BB_freq(block_order[0]);
01472
01473 for (idx=0; idx < block_order.size(); idx++) {
01474 bb = block_order[idx];
01475 INT bclass = block_class[idx];
01476 last_block = (idx == block_order.size()-1);
01477
01478
01479
01480
01481 bb_freq_data = Get_Freq_Data_For_BB(bb,freq_map);
01482 fall_thru = bb_freq_data->fall_thru;
01483 branch_bb = bb_freq_data->branch_bb;
01484
01485 switch (Get_Case(bclass)) {
01486
01487 case CASE_ALL_IN_HB:
01488
01489
01490 BB_Remove_Branch(bb);
01491 hb_continuation_prob = 1.0;
01492 break;
01493
01494 case CASE_CALL_IN:
01495
01496
01497 if (fall_thru) {
01498 Unlink_Pred_Succ(bb,fall_thru);
01499 }
01500 hb_continuation_prob = 1.0;
01501 break;
01502
01503 case CASE_CALL:
01504
01505
01506
01507
01508 if (fall_thru) {
01509 if (!last_block) {
01510 fall_thru_goto = Make_Fall_Thru_Goto(bb,fall_thru,
01511 (TN*) BB_MAP_Get(predicate_tns,bb),
01512 block_freq,
01513 1.0,
01514 Get_Block_Prob(bb,freq_map),
01515 candidate_regions,FALSE,
01516 HB_Blocks(hb));
01517 } else {
01518 fall_thru_goto = Make_Fall_Thru_Goto(bb,fall_thru,
01519 NULL,
01520 block_freq,
01521 1.0,
01522 1.0,
01523 candidate_regions,FALSE,
01524 HB_Blocks(hb));
01525 }
01526 }
01527 hb_continuation_prob = 1.0 - Get_Block_Prob(bb,freq_map);
01528 break;
01529
01530
01531 case CASE_UNCOND_BR:
01532 if (!last_block) {
01533
01534 Make_Branch_Conditional(bb);
01535
01536 Unlink_Pred_Succ(bb,branch_bb);
01537 Link_Pred_Succ_with_Prob(bb,branch_bb,Get_Block_Prob(bb,freq_map));
01538 hb_continuation_prob = 1.0 - Get_Block_Prob(bb,freq_map);
01539 } else {
01540 Unlink_Pred_Succ(bb,branch_bb);
01541 Link_Pred_Succ_with_Prob(bb,branch_bb,1.0);
01542 }
01543
01544 break;
01545
01546 case CASE_FALL_OUT:
01547
01548 if (!last_block) {
01549 Add_Goto(bb, fall_thru);
01550 Make_Branch_Conditional(bb);
01551 Unlink_Pred_Succ(bb,fall_thru);
01552 Link_Pred_Succ_with_Prob(bb,fall_thru,Get_Block_Prob(bb,freq_map));
01553
01554 } else {
01555 Unlink_Pred_Succ(bb,fall_thru);
01556 Add_Goto(bb, fall_thru);
01557 }
01558 hb_continuation_prob = 1.0 - Get_Block_Prob(bb,freq_map);
01559 break;
01560
01561 case CASE_IF_FALL_OUT:
01562
01563
01564 TN *inverse_pred,*current_pred;
01565
01566
01567 Exp_True_False_Preds_For_Block(bb, current_pred, inverse_pred);
01568
01569 BB_Remove_Branch(bb);
01570 Unlink_Pred_Succ(bb,branch_bb);
01571
01572 fall_thru_goto = Make_Fall_Thru_Goto(bb,fall_thru,inverse_pred,
01573 block_freq,
01574 1.0,
01575 Get_Branch_Prob(bb,fall_thru,freq_map),
01576 candidate_regions,last_block,
01577 HB_Blocks(hb));
01578 hb_continuation_prob = 1.0 - Get_Branch_Prob(bb,fall_thru,freq_map);
01579 break;
01580
01581 case CASE_IF_FALL_IN:
01582
01583
01584 Unlink_Pred_Succ(bb,branch_bb);
01585 Link_Pred_Succ_with_Prob(bb,branch_bb,Get_Branch_Prob(bb,branch_bb,freq_map));
01586 Unlink_Pred_Succ(bb,fall_thru);
01587 hb_continuation_prob = 1.0 - Get_Branch_Prob(bb,branch_bb,freq_map);
01588 break;
01589
01590
01591 case CASE_IF_OUT:
01592
01593
01594
01595
01596 Unlink_Pred_Succ(bb,branch_bb);
01597 Link_Pred_Succ_with_Prob(bb,branch_bb,Get_Branch_Prob(bb,branch_bb,freq_map));
01598 if (!last_block) {
01599 TN *inverse_pred,*current_pred;
01600 float ft_goto_prob,ft_prob;
01601 ft_goto_prob = 1.0 - Get_Branch_Prob(bb,branch_bb,freq_map);
01602 ft_prob = Get_Branch_Prob(bb,fall_thru,freq_map);
01603 if (ft_goto_prob == 0.0) {
01604
01605 ft_prob = 0.5;
01606 } else {
01607 ft_prob = ft_prob / ft_goto_prob;
01608 }
01609
01610
01611
01612 Exp_True_False_Preds_For_Block(bb, current_pred, inverse_pred);
01613 fall_thru_goto = Make_Fall_Thru_Goto(bb,fall_thru,inverse_pred,
01614 block_freq * ft_goto_prob,
01615 ft_goto_prob,
01616 ft_prob,
01617 candidate_regions,last_block,
01618 HB_Blocks(hb));
01619
01620 hb_continuation_prob = 1.0 - ft_prob;
01621 } else {
01622 float ft_goto_prob = 1.0 - Get_Branch_Prob(bb,branch_bb,freq_map);
01623
01624 fall_thru_goto = Make_Fall_Thru_Goto(bb,fall_thru,NULL,
01625 block_freq * ft_goto_prob,
01626 ft_goto_prob,
01627 1.0,candidate_regions,last_block,
01628 HB_Blocks(hb));
01629 }
01630 break;
01631
01632 default:
01633 FmtAssert(0,("Unknown block classification"));
01634 }
01635
01636 #if defined KEY && defined TARG_MIPS
01637 merge_failed = FALSE;
01638
01639 if (last_block) {
01640 if (!prev_bb_unmergeable) {
01641
01642 if (Okay_To_Predicate_BB(bb, prev_bb))
01643 Predicate_Block(bb,(TN*) BB_MAP_Get(predicate_tns, bb),
01644 HB_Blocks(hb));
01645 else
01646 merge_failed = TRUE;
01647 }
01648 } else
01649
01650 #endif
01651
01652 Predicate_Block(bb,(TN*) BB_MAP_Get(predicate_tns, bb), HB_Blocks(hb));
01653
01654
01655 BB_freq(bb) = block_freq;
01656
01657
01658
01659 if (prev_bb) {
01660 if (prev_bb_unmergeable) {
01661 Unlink_Pred_Succ(prev_bb, bb);
01662 Move_BB(bb, prev_bb);
01663 Link_Pred_Succ_with_Prob(prev_bb, bb, prev_hb_continuation_prob);
01664 prev_bb = bb;
01665 } else {
01666 Merge_Blocks(hb,prev_bb,bb,freq_map,last_block,candidate_regions);
01667 #ifndef TARG_IA64
01668 if (merge_failed) {
01669 printf("MERGE FAILED\n\n\n");
01670 Unlink_Pred_Succ(prev_bb, bb);
01671 Move_BB(bb, prev_bb);
01672 Link_Pred_Succ_with_Prob(prev_bb, bb, prev_hb_continuation_prob);
01673 prev_bb = bb;
01674 } else
01675 #endif
01676
01677
01678
01679
01680 if (fall_thru_goto) {
01681 Add_Block(prev_bb,fall_thru_goto,candidate_regions);
01682 }
01683 }
01684 } else {
01685 prev_bb = bb;
01686 }
01687
01688 if (fall_thru_goto) {
01689
01690
01691 Move_BB(fall_thru_goto,prev_bb);
01692 prev_bb = fall_thru_goto;
01693 prev_bb_unmergeable = TRUE;
01694 if (last_block) {
01695 last_ft_block = fall_thru_goto;
01696 }
01697 fall_thru_goto = NULL;
01698 } else {
01699 #ifndef TARG_IA64
01700 if (prev_bb == bb)
01701
01702
01703 #endif
01704 prev_bb_unmergeable = No_Merge(bclass);
01705 }
01706
01707 prev_hb_continuation_prob = hb_continuation_prob;
01708 block_freq *= hb_continuation_prob;
01709 }
01710
01711
01712
01713
01714 GRA_LIVE_Detect_GTNs_In_Set(HB_Blocks(hb));
01715
01716
01717 BB_MAP_Delete(freq_map);
01718
01719 #ifdef CHECK_FREQENCIES
01720 Check_Block_Frequencies(HB_Blocks(hb),"After");
01721 #endif
01722 return last_ft_block;
01723
01724 }
01725
01726
01727
01728
01729
01730
01731
01733
01734
01735
01736
01737
01738 struct equiv_classes {
01739 BB_SET* control_dependences;
01740 BB_SET* true_edges;
01741 TN* pred_tn;
01742 };
01743
01744 struct control_dep_data {
01745 TN* true_tn;
01746 TN* false_tn;
01747 std::vector <TN*> true_or_tns;
01748 std::vector <TN*> false_or_tns;
01749
01750 control_dep_data() {
01751 true_tn = NULL;
01752 false_tn = NULL;
01753 }
01754 };
01755
01756
01758
01759
01760
01761
01762
01763
01764 static void
01765 Insert_ORs_For_BB(BB *bb, control_dep_data *bb_cdep_data)
01766 {
01767 OPS ops = OPS_EMPTY;
01768 INT i;
01769 INT num_to_set;
01770 TN *r1;
01771 TN *r2;
01772 TN *q;
01773
01774
01775 num_to_set = bb_cdep_data->true_or_tns.size();
01776 q = bb_cdep_data->true_tn;
01777 for (i = 0; i < num_to_set; i += 2) {
01778 r1 = bb_cdep_data->true_or_tns[i];
01779 if (i+1 < num_to_set) {
01780 r2 = bb_cdep_data->true_or_tns[i+1];
01781 } else {
01782 r2 = True_TN;
01783 }
01784 Exp_Generic_Pred_Calc(r1,r2, COMPARE_TYPE_or, q, &ops);
01785 }
01786
01787
01788 num_to_set = bb_cdep_data->false_or_tns.size();
01789 q = bb_cdep_data->false_tn;
01790 for (i = 0; i < num_to_set; i += 2) {
01791 r1 = bb_cdep_data->false_or_tns[i];
01792 if (i+1 < num_to_set) {
01793 r2 = bb_cdep_data->false_or_tns[i+1];
01794 } else {
01795 r2 = True_TN;
01796 }
01797 Exp_Generic_Pred_Calc(r1,r2, COMPARE_TYPE_or, q, &ops);
01798 }
01799
01800
01801 OP* br_op = BB_branch_op(bb);
01802 BB_Insert_Ops(bb, br_op, &ops, TRUE);
01803 }
01804
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 static void
01825 Setup_True_False_Predicates(BB *bb, control_dep_data *bb_cdep_data)
01826 {
01827 Exp_True_False_Preds_For_Block(bb, bb_cdep_data->true_tn, bb_cdep_data->false_tn);
01828 }
01829
01830
01831 #ifndef TARG_IA64
01832
01833 static BOOL multiple_dependencies;
01834 #endif
01836 void
01837 Insert_Predicates(HB* hb, BB_MAP control_dependences, BB_MAP true_edges,
01838 BB_MAP predicate_tns)
01840
01841
01842
01843
01844
01845
01847 {
01848 BB* bb;
01849 BB* bb_cd;
01850 std::vector <equiv_classes *> eclass;
01851 std::vector <equiv_classes *>::iterator ec_iter;
01852 equiv_classes *ec;
01853
01854 control_dep_data *bb_cdep_data;
01855 BB_SET* cds;
01856 BB_SET* trues;
01857
01858 BB_MAP equiv_classes_map = BB_MAP_Create();
01859 BB_MAP control_dep_info = BB_MAP_Create();
01860
01861
01862
01863
01864 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
01865
01866
01867
01868
01869
01870
01871
01872 ec = NULL;
01873 cds = (BB_SET*) BB_MAP_Get(control_dependences, bb);
01874 trues = (BB_SET*) BB_MAP_Get(true_edges, bb);
01875
01876
01877
01878
01879
01880 for (ec_iter = eclass.begin(); ec_iter != eclass.end(); ec_iter++) {
01881 if (BB_SET_EqualP((*ec_iter)->control_dependences, cds) &&
01882 BB_SET_EqualP((*ec_iter)->true_edges, trues)) {
01883 ec = *ec_iter;
01884 }
01885 }
01886 if (!ec) {
01887 ec = TYPE_MEM_POOL_ALLOC(equiv_classes, &MEM_local_pool);
01888 ec->control_dependences = cds;
01889 #ifndef TARG_IA64
01890 if (BB_SET_Size(cds) > 1) {
01891
01892 multiple_dependencies = TRUE;
01893 return;
01894 }
01895 #endif
01896 ec->true_edges = trues;
01897 eclass.push_back(ec);
01898 }
01899 BB_MAP_Set(equiv_classes_map,bb,ec);
01900
01901
01902 bb_cdep_data = CXX_NEW(control_dep_data, &MEM_local_pool);
01903 bb_cdep_data->true_tn = NULL;
01904 bb_cdep_data->false_tn = NULL;
01905 BB_MAP_Set(control_dep_info,bb,bb_cdep_data);
01906 }
01907
01908 #if defined KEY && defined TARG_MIPS
01909
01910
01911 BOOL countBranch = FALSE;
01912 OP *hb_br_op;
01913 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
01914 OP *br_op = BB_branch_op(bb);
01915 if (br_op && OP_cond(br_op)) {
01916 if (countBranch && !hammock_region) {
01917 multiple_dependencies = TRUE;
01918 return;
01919 }
01920 countBranch = TRUE;
01921 hb_br_op = br_op;
01922 }
01923 }
01924
01925
01926
01927
01928
01929 BOOL is_float_br = FALSE;
01930 if (hb_br_op &&
01931 (OP_code(hb_br_op) == TOP_bc1f ||
01932 OP_code(hb_br_op) == TOP_bc1t))
01933 is_float_br = TRUE;
01934 INT bb_id = hb_br_op?hb_br_op->bb->id:-1;
01935 if (hb_br_op) {
01936 OP *op;
01937 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
01938 if (bb->id == bb_id)
01939 continue;
01940 FOR_ALL_BB_OPs(bb, op) {
01941 if ((OP_cond_def(op) &&
01942 is_float_br) ||
01943 (!is_float_br &&
01944 (OP_code(op) == TOP_movf || OP_code(op) == TOP_movt ||
01945 OP_code(op) == TOP_movf_d || OP_code(op) == TOP_movf_s ||
01946 OP_code(op) == TOP_movt_d || OP_code(op) == TOP_movt_s))) {
01947 multiple_dependencies = TRUE;
01948 return;
01949 }
01950 }
01951 }
01952 }
01953 #endif
01954
01955
01956
01957 for (ec_iter = eclass.begin(); ec_iter != eclass.end(); ec_iter++) {
01958 ec = *ec_iter;
01959 cds = ec->control_dependences;
01960 trues = ec->true_edges;
01961 INT num_deps = BB_SET_Size(cds);
01962 if (num_deps == 0) {
01963
01964 ec->pred_tn = NULL;
01965 } else if (num_deps == 1) {
01966
01967 bb_cd = BB_SET_Choose(cds);
01968 bb_cdep_data = (control_dep_data*) BB_MAP_Get(control_dep_info, bb_cd);
01969 #ifndef TARG_IA64
01970
01971
01972 if (!bb_cdep_data->true_tn && !bb_cdep_data->false_tn)
01973 #endif
01974 Setup_True_False_Predicates(bb_cd, bb_cdep_data);
01975
01976
01977 if (BB_SET_MemberP(trues, bb_cd)) {
01978 ec->pred_tn = bb_cdep_data->true_tn;
01979 } else {
01980 ec->pred_tn = bb_cdep_data->false_tn;
01981 }
01982 } else {
01983
01984 OPS ops = OPS_EMPTY;
01985 ec->pred_tn = Gen_Predicate_TN();
01986 Exp_Pred_Set(ec->pred_tn, True_TN, 0, &ops);
01987 OP *xfer_op;
01988
01989
01990
01991
01992 if (xfer_op = BB_xfer_op(HB_Entry(hb))) {
01993 BB_Insert_Ops_Before (HB_Entry(hb), xfer_op, &ops);
01994 } else {
01995 BB_Append_Ops (HB_Entry(hb), &ops);
01996 }
01997
01998
01999
02000
02001 FOR_ALL_BB_SET_members(ec->control_dependences, bb_cd) {
02002 bb_cdep_data = (control_dep_data*) BB_MAP_Get(control_dep_info,bb_cd);
02003 Setup_True_False_Predicates(bb_cd,bb_cdep_data);
02004
02005 if (BB_SET_MemberP(trues, bb_cd)) {
02006 bb_cdep_data->true_or_tns.push_back(ec->pred_tn);
02007 } else {
02008 bb_cdep_data->false_or_tns.push_back(ec->pred_tn);
02009 }
02010 }
02011 }
02012 }
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
02025
02026 ec = (equiv_classes *) BB_MAP_Get(equiv_classes_map,bb);
02027 BB_MAP_Set(predicate_tns, bb, ec->pred_tn);
02028
02029
02030
02031
02032 bb_cdep_data = (control_dep_data*) BB_MAP_Get(control_dep_info,bb);
02033 Insert_ORs_For_BB(bb, bb_cdep_data);
02034
02035
02036
02037
02038
02039 if (HB_Trace(HB_TRACE_CONVERT)) {
02040 if (ec->pred_tn) {
02041 fprintf(HB_TFile, "<HB> BB%d predicated with TN%d\n", BB_id(bb),
02042 TN_number(ec->pred_tn));
02043 } else {
02044 fprintf(HB_TFile, "<HB> BB%d has no predicate\n", BB_id(bb));
02045 }
02046 fprintf(HB_TFile, "<HB> Control dependences data:");
02047 INT ttn = bb_cdep_data->true_tn ? TN_number(bb_cdep_data->true_tn) : 0;
02048 INT ftn = bb_cdep_data->false_tn ? TN_number(bb_cdep_data->false_tn) : 0;
02049 fprintf(HB_TFile, " True TN = TN%d False TN = TN%d\n",ttn,ftn);
02050 INT i;
02051 if (bb_cdep_data->true_or_tns.size() > 0) {
02052 fprintf(HB_TFile, "<HB> True ORs:");
02053 for (i = 0; i < bb_cdep_data->true_or_tns.size(); i++) {
02054 fprintf(HB_TFile, "TN%d ",TN_number(bb_cdep_data->true_or_tns[i]));
02055 }
02056 fprintf(HB_TFile, "\n");
02057 }
02058 if (bb_cdep_data->false_or_tns.size() > 0) {
02059 fprintf(HB_TFile,"<HB> False ORs:");
02060 for (i = 0; i < bb_cdep_data->false_or_tns.size(); i++) {
02061 fprintf(HB_TFile, "TN%d ",TN_number(bb_cdep_data->false_or_tns[i]));
02062 }
02063 fprintf(HB_TFile, "\n");
02064 }
02065 fprintf(HB_TFile,"\n");
02066 }
02067
02068 CXX_DELETE(bb_cdep_data,&MEM_local_pool);
02069 }
02070
02071
02072
02073 BB_MAP_Delete(control_dep_info);
02074 BB_MAP_Delete(equiv_classes_map);
02075 }
02077
02078
02079
02080
02081
02082
02083 BOOL
02084 HB_Safe_For_If_Conversion(HB* hb)
02085 {
02086 BB *bb;
02087 BB *bb_pred;
02088 BB_SET *hb_blocks;
02089 BBLIST* bl;
02090
02091 hb_blocks = HB_Blocks(hb);
02092
02093 FOR_ALL_BB_SET_members(hb_blocks, bb) {
02094 if (bb != HB_Entry(hb)) {
02095 FOR_ALL_BB_PREDS(bb,bl) {
02096 bb_pred = BBLIST_item(bl);
02097 if (!BB_SET_MemberP(hb_blocks,bb_pred)) {
02098
02099 return FALSE;
02100 }
02101 }
02102 }
02103 }
02104
02105 return TRUE;
02106 }
02107
02108
02109 #if defined KEY && defined TARG_MIPS
02110
02111
02112
02113
02114
02115 float
02116 HB_If_Convert_Cost_Diff(HB *hb)
02117 {
02118 BB *bb;
02119 float initial_cost = 0, transformed_cost = 0;
02120 float freq;
02121 OP *op;
02122 INT sum_of_latencies;
02123 INT count_cond_moves = 0;
02124 INT op_latency;
02125 if (hammock_region)
02126
02127
02128
02129
02130 return 0.0;
02131 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) {
02132 if (HB_Entry(hb) == bb) {
02133
02134 continue;
02135 }
02136 freq = BB_freq(bb);
02137 sum_of_latencies = 0;
02138 FOR_ALL_BB_OPs(bb, op) {
02139 op_latency = TI_RES_Cycle_Count(OP_code(op));
02140 sum_of_latencies += (op_latency?op_latency:1);
02141 if (OP_results(op) == 1)
02142 count_cond_moves ++;
02143 }
02144 initial_cost += sum_of_latencies*freq;
02145 transformed_cost += (sum_of_latencies + count_cond_moves);
02146 if (BB_branch_op(bb))
02147 transformed_cost --;
02148 }
02149
02150
02151
02152 if (BB_branch_op(HB_Entry(hb)) &&
02153 (OP_code(BB_branch_op(HB_Entry(hb))) == TOP_bc1f ||
02154 OP_code(BB_branch_op(HB_Entry(hb))) == TOP_bc1t))
02155 transformed_cost += 4 ;
02156 else
02157 transformed_cost += 3 ;
02158 return transformed_cost - initial_cost;
02159 }
02160 #endif
02162 void
02163 HB_If_Convert(HB* hb, std::list<HB_CAND_TREE*>& candidate_regions)
02165
02166
02167
02169 {
02170 #if defined KEY && defined TARG_MIPS
02171
02172 if (HB_If_Convert_Cost_Diff(hb) > (float)HB_if_conversion_cut_off)
02173 return;
02174 #endif
02175 vector<BB *> block_order;
02176 vector<INT> block_class;
02177 MEM_POOL_Push(&MEM_local_pool);
02178 BB_MAP true_edges = BB_MAP_Create();
02179 BB_MAP control_dependences = BB_MAP_Create();
02180 BB_MAP predicate_tns = BB_MAP_Create();
02181
02182 if (HB_Trace(HB_TRACE_CONVERT)) {
02183 HB_Trace_If_Convert_Blocks(hb);
02184 }
02185
02186 Order_And_Classify_Blocks(hb,block_order,block_class);
02187 Calculate_Control_Dependences(hb, control_dependences, true_edges);
02188 #ifndef TARG_IA64
02189 multiple_dependencies = FALSE;
02190 Insert_Predicates(hb, control_dependences, true_edges, predicate_tns);
02191 if (!multiple_dependencies)
02192 Remove_Branches(hb, predicate_tns, block_order, block_class, candidate_regions);
02193 else
02194
02195 IGLS_Enable_HB_Scheduling = 0;
02196 #else
02197 Insert_Predicates(hb, control_dependences, true_edges, predicate_tns);
02198 Remove_Branches(hb, predicate_tns, block_order, block_class, candidate_regions);
02199 #endif
02200
02201 BB_MAP_Delete(true_edges);
02202 BB_MAP_Delete(control_dependences);
02203 BB_MAP_Delete(predicate_tns);
02204 MEM_POOL_Pop(&MEM_local_pool);
02205 }
02206
02207 static BOOL
02208 Check_for_Cycles(HB* hb, BB* bb, BB_SET *visited)
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02225 {
02226 BB* succ;
02227 BBLIST* bl;
02228
02229 if (BB_SET_MemberP(visited,bb)) {
02230
02231 return FALSE;
02232 }
02233
02234
02235 visited = BB_SET_Union1D(visited, bb, &MEM_local_pool);
02236
02237 FOR_ALL_BB_SUCCS(bb, bl) {
02238 succ = BBLIST_item(bl);
02239
02240
02241
02242
02243 if (succ != HB_Entry(hb) && HB_Contains_Block(hb, succ)) {
02244 if (!Check_for_Cycles(hb, succ, visited)) {
02245 return FALSE;
02246 }
02247 }
02248 }
02249
02250
02251 visited = BB_SET_Difference1D(visited,bb);
02252 return TRUE;
02253 }
02254
02255
02257 BB *
02258 Force_If_Convert(LOOP_DESCR *loop, BOOL allow_multi_bb)
02260
02261
02262
02263
02264
02265
02267 {
02268 std::vector<BB *> block_order;
02269 std::vector<INT> block_class;
02270 BOOL one_bb;
02271 BOOL ok_to_convert;
02272 BOOL all_blocks_ok;
02273 BB *single_bb=NULL;
02274 BB *fall_thru_block;
02275 BB *bb;
02276 BB *bb_entry;
02277 HB hbs;
02278 HB *hb=&hbs;
02279 std::list<HB_CAND_TREE*> candidate_regions;
02280
02281 #ifdef KEY
02282
02283 if (!HB_formation)
02284 return NULL;
02285 #endif
02286 MEM_POOL_Push(&MEM_local_pool);
02287 fall_thru_block = NULL;
02288
02289 BB_SET * bbs = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
02290 BB_SET * added_bbs;
02291 BB_SET * removed_bbs;
02292 bb_entry = LOOP_DESCR_loophead(loop);
02293
02294 bbs = BB_SET_UnionD(bbs,LOOP_DESCR_bbset(loop), &MEM_local_pool);
02295
02296
02297
02298 if (BB_SET_Size(bbs) == 1) {
02299 MEM_POOL_Pop(&MEM_local_pool);
02300 return bb_entry;
02301 }
02302
02303 #ifdef KEY
02304
02305
02306 EAGER_LEVEL Eager_Level_Temp = Eager_Level;
02307 Eager_Level = EAGER_MEMORY;
02308 #endif
02309 HB_Blocks_Set(hb, bbs);
02310 HB_Entry_Set(hb, bb_entry);
02311
02312 ok_to_convert = HB_Safe_For_If_Conversion(hb);
02313 if (ok_to_convert) {
02314 BB_SET * visited = BB_SET_Create_Empty(PU_BB_Count+2, &MEM_local_pool);
02315 ok_to_convert = Check_for_Cycles(hb, bb_entry, visited);
02316 }
02317
02318 if (ok_to_convert) {
02319 one_bb = Order_And_Classify_Blocks(hb,block_order,block_class);
02320 }
02321
02322 all_blocks_ok = FALSE;
02323 if (ok_to_convert && (one_bb || allow_multi_bb)) {
02324
02325
02326
02327 all_blocks_ok = TRUE;
02328 FOR_ALL_BB_SET_members(bbs, bb) {
02329 all_blocks_ok = all_blocks_ok && Check_BB_For_HB_Suitability(bb, bb_entry);
02330 if (!all_blocks_ok) break;
02331 }
02332 }
02333 all_blocks_ok = all_blocks_ok && Check_HB_For_PQS_Suitability(bbs, bb_entry);
02334
02335 if (all_blocks_ok && CG_skip_local_hbf) {
02336 BOOL skip;
02337 skip = (BB_id(bb_entry) < CG_local_skip_before ||
02338 BB_id(bb_entry) > CG_local_skip_after ||
02339 BB_id(bb_entry) == CG_local_skip_equal);
02340 if (skip) DevWarn("skip hyperblock loop at BB %d", BB_id(bb_entry));
02341 else DevWarn("process hyperblock loop at BB %d", BB_id(bb_entry));
02342 if (skip) all_blocks_ok = FALSE;
02343 }
02344
02345
02346 if (all_blocks_ok) {
02347
02348 HB_CAND_TREE* hct = HB_CAND_TREE_Alloc(&MEM_local_pool);
02349 HB_CAND_TREE_Candidate_Set(hct, hb);
02350 candidate_regions.push_front(hct);
02351 BB_MAP true_edges = BB_MAP_Create();
02352 BB_MAP control_dependences = BB_MAP_Create();
02353 BB_MAP predicate_tns = BB_MAP_Create();
02354
02355 if (HB_Trace(HB_TRACE_CONVERT)) {
02356 HB_Trace_If_Convert_Blocks(hb);
02357 }
02358 Calculate_Control_Dependences(hb, control_dependences, true_edges);
02359 #ifndef TARG_IA64
02360 multiple_dependencies = FALSE;
02361 Insert_Predicates(hb, control_dependences, true_edges, predicate_tns);
02362 if (!multiple_dependencies)
02363 fall_thru_block = Remove_Branches(
02364 hb, predicate_tns, block_order, block_class, candidate_regions);
02365 else {
02366
02367 IGLS_Enable_HB_Scheduling = 0;
02368 one_bb = FALSE;
02369 }
02370 #else
02371 Insert_Predicates(hb, control_dependences, true_edges, predicate_tns);
02372 fall_thru_block = Remove_Branches(hb, predicate_tns, block_order, block_class, candidate_regions);
02373 #endif
02374
02375 BB_MAP_Delete(true_edges);
02376 BB_MAP_Delete(control_dependences);
02377 BB_MAP_Delete(predicate_tns);
02378
02379
02380 added_bbs = BB_SET_Difference(HB_Blocks(hb),LOOP_DESCR_bbset(loop),&MEM_local_pool);
02381 removed_bbs = BB_SET_Difference(LOOP_DESCR_bbset(loop),HB_Blocks(hb),&MEM_local_pool);
02382
02383
02384 FOR_ALL_BB_SET_members(removed_bbs,bb) {
02385 LOOP_DESCR_Delete_BB(loop,bb);
02386 }
02387
02388
02389 if (fall_thru_block) {
02390 added_bbs = BB_SET_Difference1D(added_bbs,fall_thru_block);
02391 LOOP_DESCR *enclosing_loop = LOOP_DESCR_Next_Enclosing_Loop(loop);
02392 if (enclosing_loop) {
02393 LOOP_DESCR_Add_BB(enclosing_loop, fall_thru_block);
02394 }
02395 }
02396
02397 FOR_ALL_BB_SET_members(added_bbs,bb) {
02398 if (bb != fall_thru_block) {
02399 LOOP_DESCR_Add_BB(loop,bb);
02400 }
02401 }
02402
02403 if (one_bb) {
02404 single_bb = HB_Entry(hb);
02405 }
02406 if (Get_Trace(TKIND_IR, TP_HBF, bb_entry)) {
02407 Trace_IR(TP_HBF, "Force_If_Convert", NULL);
02408 }
02409 }
02410
02411 MEM_POOL_Pop(&MEM_local_pool);
02412 #ifdef KEY
02413
02414 Eager_Level = Eager_Level_Temp;
02415 #endif
02416 return single_bb;
02417 }