00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "defs.h"
00046 #include "errors.h"
00047
00048 #include "tn.h"
00049 #include "op.h"
00050 #include "op_map.h"
00051 #include "be_util.h"
00052
00053 #include "timing.h"
00054 #include "cg_dep_graph.h"
00055 #include "cgtarget.h"
00056 #include "targ_isa_bundle.h"
00057 #include "tracing.h"
00058
00059 #include "ipfec_options.h"
00060 #include "cggrp_microsched.h"
00061 #include "cggrp_ptn_table.h"
00062 #include "scheduler.h"
00063 #include "dag.h"
00064 #include "multi_branch.h"
00065
00066 static MEM_POOL MLBR_pool_struct;
00067 MEM_POOL* const MLBR_pool = &MLBR_pool_struct;
00068
00070 static void
00071 Initialize_Memory(void)
00073
00074
00075
00077 {
00078 static BOOL did_init = FALSE;
00079
00080 if ( ! did_init ) {
00081 MEM_POOL_Initialize(MLBR_pool,"multi-branch pool",FALSE);
00082 did_init = TRUE;
00083 }
00084 MEM_POOL_Push(MLBR_pool);
00085 }
00087 static void
00088 Finalize_Memory(void)
00090
00091
00092
00094 {
00095 MEM_POOL_Pop(MLBR_pool);
00096 MEM_POOL_Delete(MLBR_pool);
00097 }
00098
00099
00100
00101
00102
00103
00104 static BOOL
00105 BB_has_target_bb(BB *bb, BB *target_bb)
00106 {
00107 OP *op;
00108 FOR_ALL_BB_OPs_REV(bb, op) {
00109 if (OP_dummy(op)) continue;
00110 if (OP_xfer(op)){
00111 INT tfirst, tcount;
00112 CGTARG_Branch_Info(op, &tfirst, &tcount);
00113 if (tcount == 0 ) {
00114
00115 return TRUE;
00116 } else {
00117 TN *dest = OP_opnd(op, tfirst);
00118 if (Is_Label_For_BB(TN_label(dest), target_bb)) {
00119 return TRUE;
00120 }
00121 }
00122 } else {
00123 return FALSE;
00124 }
00125 }
00126 return FALSE;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 static BOOL
00136 BB_has_goto_bb(BB *bb, BB *target_bb) {
00137 OP *op;
00138 FOR_ALL_BB_OPs(bb, op) {
00139 if (OP_xfer(op) && !OP_chk(op)) {
00140 INT tfirst, tcount;
00141 CGTARG_Branch_Info(op, &tfirst, &tcount);
00142 if (tcount != 0) {
00143 TN *dest = OP_opnd(op, tfirst);
00144 if (Is_Label_For_BB(TN_label(dest), target_bb) &&
00145 (CGTARG_OP_is_counted_loop(op) ||
00146 OP_code(op) != TOP_br)) return FALSE;
00147 if (Is_Label_For_BB(TN_label(dest), target_bb) &&
00148 !OP_cond_def(op) && op == BB_branch_op(bb)) return TRUE;
00149 }
00150 }
00151 }
00152 return FALSE;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 BOOL Multi_Branch_Valid_BB(BB *bb, BB *partial_head=NULL)
00164 {
00165 if (!IPFEC_Enable_Multi_Branch ||
00166 !LOCS_Enable_Bundle_Formation) return FALSE;
00167
00168 if (partial_head && !IPFEC_Enable_Pre_Multi_Branch)
00169 return FALSE;
00170
00171
00172 if (bb == NULL) return FALSE;
00173
00174
00175
00176 if (BB_handler (bb) || BB_Has_Exc_Label (bb))
00177 return FALSE;
00178
00179
00180 if (IPFEC_Query_Skiplist(mlbr_skip_bb, BB_id(bb),
00181 Current_PU_Count()))
00182 return FALSE;
00183
00184 if (BB_cycle(bb) > 1) return FALSE;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 if (BB_freq(bb) <= 0.0 && partial_head != NULL) {
00195 return FALSE;
00196 }
00197
00198 if (partial_head) {
00199 if (!BB_last_op(partial_head) ||
00200 !OP_Scheduled(BB_last_op(partial_head))) return FALSE;
00201 }
00202
00203 BB *prev_bb = BB_prev(bb);
00204 if (prev_bb==NULL) return FALSE;
00205 for (BBLIST * bblst = BB_preds(bb); bblst; bblst = BBLIST_next(bblst)) {
00206 BB* pred_bb = BBLIST_item(bblst);
00207 if (pred_bb == prev_bb) {
00208 while (BB_length(prev_bb) == 0) {
00209 prev_bb=BB_prev(prev_bb);
00210 if (prev_bb == NULL || !BB_Is_Unique_Predecessor(BB_next(prev_bb),prev_bb) ||
00211 BB_has_target_bb(prev_bb,BB_next(prev_bb))) {
00212 return FALSE;
00213 }
00214 }
00215 } else {
00216
00217
00218
00219 if (BB_partial_bundle(pred_bb) || BB_chk_split(pred_bb) ||
00220 BB_chk_split_head(pred_bb) || BB_call(bb) ||
00221 (!BB_Is_Unique_Successor(pred_bb, bb) &&
00222 !BB_has_goto_bb(pred_bb, bb)))
00223 return FALSE;
00224
00225 if (BB_call(bb)) return FALSE;
00226 if (pred_bb == BB_next(bb)) return FALSE;
00227
00228 if (pred_bb ==bb){
00229 return false;
00230 }
00231 }
00232 }
00233
00234
00235 if (BB_has_target_bb(prev_bb, bb)) return FALSE;
00236
00237
00238 if (BB_call(prev_bb)) return FALSE;
00239
00240
00241 if (!BB_first_op(bb) || !OP_start_bundle(BB_first_op(bb))) return FALSE;
00242
00243
00244 if (partial_head) {
00245 INT ops_num=0;
00246 while (partial_head != prev_bb) {
00247 ops_num += BB_length(prev_bb);
00248
00249
00250 if (BB_scheduled(prev_bb) ||
00251 ops_num > ISA_MAX_SLOTS * ISA_MAX_ISSUE_BUNDLES)
00252 return FALSE;
00253
00254 prev_bb = BB_prev(prev_bb);
00255 if (prev_bb == NULL) return FALSE;
00256 }
00257 }
00258
00259 return TRUE;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 BOOL Multi_Branch_Valid_OP(OP *op, BB *partial_head=NULL)
00272 {
00273
00274
00275 if (OP_xfer(op) && !OP_chk(op)) {
00276
00277
00278 if (OP_code(op) == TOP_br_ret) return FALSE;
00279 if (CGTARG_OP_is_counted_loop(op)) return FALSE;
00280 if (BB_preds_len(OP_bb(op)) > 1 && OP_call(op)) return FALSE;
00281
00282 } else {
00283
00284 BB *bb = OP_bb(op);
00285
00286 while (bb = BB_prev(bb)) {
00287
00288 if (BB_chk_split(bb) && !BB_chk_split_head(OP_bb(op))
00289 && BB_chk_split(OP_bb(op))) {
00290 OP *tmp;
00291 FOR_ALL_BB_OPs_REV(bb, tmp) {
00292 if (OP_end_group(tmp)) break;
00293 }
00294 if (tmp && OP_end_group(tmp)) break;
00295 continue;
00296 }
00297 if (BB_length(bb) != 0) break;
00298 }
00299
00300 if (bb) {
00301 OP *last_br=BB_branch_op(bb);
00302
00303 if (last_br && !OP_chk(last_br)) {
00304 if (!OP_cond_def(op)) return FALSE;
00305 if (!OP_cond_def(last_br)) return FALSE;
00306 if (!OP_end_group(last_br)) return FALSE;
00307 TN *p_opnd = OP_opnd(last_br, OP_PREDICATE_OPND);
00308
00309
00310 for(OP *prev_op=OP_prev(last_br); prev_op; prev_op = OP_prev(prev_op)) {
00311 if (OP_end_group(prev_op)) break;
00312 if (OP_Defs_TN(prev_op, p_opnd)) {
00313 return FALSE;
00314 }
00315 }
00316 if (!OP_has_disjoint_predicate(op, last_br)) return FALSE;
00317 ISA_REGISTER_CLASS cl = TN_register_class(p_opnd);
00318 REGISTER reg = TN_register(p_opnd);
00319 if (OP_Defs_Reg(op, cl, reg)) return FALSE;
00320
00321
00322 }
00323 }
00324
00325 }
00326 return TRUE;
00327 }
00328
00329
00330
00331
00332
00333
00334 BOOL Add_Predicate_Valid_BB(BB *bb, OP **barrier)
00335 {
00336 if (!IPFEC_Enable_Pre_Multi_Branch ||
00337 !LOCS_Enable_Bundle_Formation) return FALSE;
00338
00339 if (!bb || !Multi_Branch_Valid_BB(bb)) return FALSE;
00340
00341 BB *prev=bb;
00342
00343 if (BB_Unique_Predecessor(bb) == NULL) return FALSE;
00344
00345 while (prev = BB_prev(prev)) {
00346 if (BB_length(prev) != 0) break;
00347 if (BB_Unique_Predecessor(prev) == NULL) return FALSE;
00348 }
00349
00350
00351
00352 if (prev == NULL) return FALSE;
00353 if (prev) {
00354 OP *last_br=BB_branch_op(prev);
00355 if (last_br == NULL || !OP_cond_def(last_br)) return FALSE;
00356 if (!OP_end_group(last_br) || !BB_scheduled(prev)) return FALSE;
00357 for(OP *prev_op=OP_prev(last_br); prev_op; prev_op = OP_prev(prev_op)) {
00358 if (OP_end_group(prev_op)) break;
00359 if (OP_Defs_TN(prev_op, OP_opnd(last_br, OP_PREDICATE_OPND))) {
00360 return FALSE;
00361 }
00362 if (OP_xfer(prev_op) && !OP_chk(prev_op)) return FALSE;
00363 }
00364
00365 *barrier = last_br;
00366 }
00367
00368
00369
00370 OP *tmp;
00371 INT num=0;
00372 FOR_ALL_BB_OPs(bb, tmp) {
00373 if (OP_dummy(tmp) || OP_simulated(tmp) || OP_noop(tmp)) continue;
00374 if (OP_br(tmp) && !OP_chk(tmp)) continue;
00375 num++;
00376 }
00377
00378
00379 if (BB_cycle(bb)>1 || num>=2 || num==0) return FALSE;
00380
00381 if (BB_freq(prev) > 0 && BB_freq(bb)/BB_freq(prev) >= 0.5)
00382 return TRUE;
00383
00384 return FALSE;
00385 }
00386
00387
00388
00389
00390
00391
00392 BOOL Add_Predicate_Valid_OP(OP *op, OP *barrier)
00393 {
00394
00395 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) return TRUE;
00396 if (OP_xfer(op) && !OP_chk(op)) return TRUE;
00397 if (CGTARG_Is_OP_Check_Load(op)) return FALSE;
00398 if (!OP_has_predicate(op)) return FALSE;
00399
00400
00401
00402
00403 if (OP_cond_def(op)) {return FALSE;}
00404 if (!TN_is_true_pred(OP_opnd(op,OP_PREDICATE_OPND)))
00405 return FALSE;
00406
00407 for (INT i =0; i<(OP_opnds(op)+OP_results(op)); i++) {
00408
00409 TN *tn;
00410 if (i < OP_opnds(op)) tn = OP_opnd(op, i);
00411 else tn = OP_result(op, i-OP_opnds(op));
00412
00413 INT num=0;
00414 for(OP *prev_op=OP_prev(barrier); prev_op; prev_op = OP_prev(prev_op)) {
00415 num++;
00416 if (OP_end_group(prev_op)) break;
00417
00418
00419 if (num > ISA_MAX_SLOTS * ISA_MAX_ISSUE_BUNDLES) break;
00420 if (OP_Defs_TN(prev_op, tn)) {
00421 return FALSE;
00422 }
00423
00424 if (OP_memory(prev_op) && OP_code(op)==TOP_mov) return FALSE;
00425 }
00426 }
00427
00428
00429
00430 if (OP_code(op) == TOP_mov_t_br) return FALSE;
00431 if (OP_memory(op)) return FALSE;
00432 if (OP_chk_a(op)) return FALSE;
00433
00434 return TRUE;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 void Post_Multi_Branch(void)
00460 {
00461 Set_Error_Phase("Multiple Branch");
00462 Start_Timer(T_Ipfec_Multi_Branch_CU);
00463
00464 if (Get_Trace(TP_A_MLBR, 0x01)) {
00465 fprintf(TFile, "--Begining of PU %d-----\n", Current_PU_Count());
00466 }
00467 for (BB *bb= REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00468 if (BB_length(bb)==0) continue;
00469 if (!OP_end_group(BB_last_op(bb)) && !BB_chk_split_head(bb)) continue;
00470 if (IPFEC_Query_Skiplist(mlbr_skip_bb, BB_id(bb), Current_PU_Count())) continue;
00471
00472
00473
00474 if (!Multi_Branch_Valid_BB(bb)) continue;
00475
00476
00477
00478
00479 OP *op;
00480 BOOL invalid_op = FALSE;
00481 INT valid_ops_num=0;
00482
00483 OP *next_op=op; BB *next_bb=bb;
00484 for(op = BB_first_op(next_bb); op; op = next_op) {
00485
00486 if (BB_chk_split_head(bb) && BB_next(next_bb) &&
00487 BB_chk_split(BB_next(next_bb)) &&
00488 BB_preds_len(BB_next(next_bb)) == 1 &&
00489 op == BB_last_op(next_bb)) {
00490
00491 next_bb = BB_next(next_bb);
00492 next_op = BB_first_op(next_bb);
00493 } else {
00494 next_op = OP_next(op);
00495 }
00496 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) continue;
00497 if (!Multi_Branch_Valid_OP(op)) {
00498 invalid_op = TRUE;
00499 break;
00500 }
00501
00502
00503
00504
00505
00506 else if ( BB_preds_len(bb) > 1 && OP_call(op) ) {
00507 invalid_op = TRUE;
00508 break;
00509 }
00510 else {
00511 valid_ops_num++;
00512 }
00513 }
00514 if (invalid_op) continue;
00515
00516
00517 if (valid_ops_num >= 4) continue;
00518
00519 BB *prev_bb = BB_prev(bb);
00520 while(prev_bb && BB_length(prev_bb) == 0) {
00521 prev_bb = BB_prev(prev_bb);
00522 }
00523 if (prev_bb == NULL) continue;
00524
00525
00526 OPS ops,new_ops,dup_new_ops;
00527 OPS_Init(&ops);
00528 OPS_Init(&new_ops);
00529 OPS_Init(&dup_new_ops);
00530 BOOL valid_ops =TRUE;
00531 BOOL bundle_succeed = FALSE;
00532 if (OP_end_group(BB_last_op(prev_bb))) {
00533 BOOL meet_stop_bit = FALSE;
00534 INT stop_idx = 0;
00535 INT ops_len = 0;
00536
00537
00538
00539
00540 for(prev_bb; prev_bb!=NULL; prev_bb=BB_prev(prev_bb)) {
00541 OP *cur_op = BB_last_op(prev_bb);
00542 while(cur_op) {
00543 if ( !OP_noop(cur_op) &&
00544 (OP_dummy(cur_op) || OP_simulated(cur_op))) {
00545 cur_op = OP_prev(cur_op);
00546 continue;
00547 }
00548 if (OP_end_group(cur_op) &&
00549 OPS_length(&ops) != 0) {
00550 meet_stop_bit = TRUE;
00551 if (ops_len % ISA_MAX_SLOTS == 0) break;
00552 }
00553
00554 OP *add_op = cur_op;
00555 cur_op = OP_prev(cur_op);
00556 BB_Remove_Op(prev_bb,add_op);
00557 OPS_Prepend_Op(&ops, add_op);
00558 add_op->bb = prev_bb;
00559 if (prev_bb != BB_prev(bb) &&
00560 !BB_Is_Unique_Predecessor(BB_next(prev_bb),prev_bb)) {
00561 valid_ops = FALSE;
00562 }
00563 ops_len += ISA_PACK_Inst_Words(OP_code(add_op));
00564
00565 if (meet_stop_bit) {stop_idx++;}
00566 if (meet_stop_bit &&
00567 ops_len % ISA_MAX_SLOTS == 0) break;
00568 }
00569 if (meet_stop_bit &&
00570 ops_len % ISA_MAX_SLOTS == 0) break;
00571 Is_True(OPS_length(&ops)<=(ISA_MAX_SLOTS*ISA_MAX_ISSUE_BUNDLES),
00572 ("too many ops %d in this cycle", OPS_length(&ops)));
00573 }
00574
00575 if (OPS_length(&ops) == 0) return;
00576
00577 prev_bb = OP_bb(OPS_first(&ops));
00578
00579
00580
00581
00582
00583 OP *next_op; BB *next_bb = bb;
00584 for(op = BB_first_op(next_bb); op; op=next_op){
00585
00586 if (BB_chk_split_head(bb) && BB_next(next_bb) &&
00587 BB_chk_split(BB_next(next_bb)) &&
00588 BB_preds_len(BB_next(next_bb)) == 1 &&
00589 op == BB_last_op(next_bb)) {
00590 BB_Remove_Op(next_bb,op);
00591 op->bb = next_bb;
00592 next_bb = BB_next(next_bb);
00593 next_op = BB_first_op(next_bb);
00594 } else {
00595 next_op = OP_next(op);
00596 BB_Remove_Op(next_bb,op);
00597 op->bb = next_bb;
00598 }
00599
00600 OPS_Append_Op(&new_ops,op);
00601 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) continue;
00602 OPS_Append_Op(&dup_new_ops, Dup_OP(op));
00603 }
00604
00605
00606 BB *src_end_bb = next_bb;
00607
00608 Is_True(OPS_length(&dup_new_ops) == valid_ops_num, ("get new ops is not correct!"));
00609
00610
00611 if (Get_Trace(TP_A_MLBR, 0x01)) {
00612 fprintf(TFile, "op list in last cycle is:\n");
00613 Print_OPS(&ops);
00614 fprintf(TFile, "\nop add in cur cycle is in BB %d:\n", BB_id(bb));
00615 Print_OPS(&new_ops);
00616 fprintf(TFile, "\nstop index: %d\n", stop_idx);
00617 fprintf(TFile, "\n");
00618 }
00619
00620
00621 if (valid_ops) {
00622
00623 INT32 save = IPFEC_sched_care_machine;
00624 IPFEC_sched_care_machine = Sched_care_bundle;
00625 if (CGGRP_Bundle_OPS(&ops, &new_ops, stop_idx)) {
00626
00627
00628
00629
00630 BBLIST *tmplst = NULL;
00631 BBLIST *succ = NULL;
00632 BB *fall_thru = BB_Fall_Thru_Successor(src_end_bb);
00633
00634
00635 if (fall_thru) succ = BB_Find_Succ(src_end_bb, fall_thru);
00636
00637 for (BBLIST *bblst = BB_preds(bb); bblst; bblst = BBLIST_next(bblst)) {
00638 BBlist_Add_BB(&tmplst, BBLIST_item(bblst));
00639 }
00640
00641
00642
00643 BBLIST *tmpsuc = NULL;
00644 for (BB *tmp=bb; tmp != BB_next(src_end_bb) ; tmp = BB_next(tmp)) {
00645 for (BBLIST *bblst = BB_succs(tmp); bblst; bblst = BBLIST_next(bblst)) {
00646 float prob = 1.0;
00647 if (BBLIST_item(bblst) != BB_next(tmp))
00648 BBlist_Add_BB_with_Prob(&tmpsuc, BBLIST_item(bblst), prob*BBLIST_prob(bblst));
00649 else
00650 prob = prob*BBLIST_prob(bblst);
00651
00652 }
00653 }
00654
00655 for (; tmplst; tmplst = BBLIST_next(tmplst)) {
00656 BB* pred_bb = BBLIST_item(tmplst);
00657 if (pred_bb != BB_prev(bb)) {
00658
00659 OP *cur_op;
00660 FOR_ALL_OPS_OPs(&dup_new_ops,cur_op) {
00661
00662 Is_True ( !OP_call(cur_op), ("call can not be here!") );
00663
00664 BB_Insert_Op_Before(pred_bb, BB_branch_op(pred_bb), Dup_OP(cur_op));
00665
00666 }
00667
00668
00669 BBLIST *succlst;
00670 FOR_ALL_BBLIST_ITEMS (tmpsuc, succlst) {
00671 Link_Pred_Succ_with_Prob(pred_bb, BBLIST_item(succlst), BBLIST_prob(succlst));
00672 }
00673 if (fall_thru && fall_thru!=BB_next(src_end_bb))
00674 Link_Pred_Succ_with_Prob(pred_bb, fall_thru, BBLIST_prob(succ));
00675 if (BB_next(src_end_bb)) BB_Retarget_Branch(pred_bb, bb, BB_next(src_end_bb));
00676 SCHEDULER local_scheduler(pred_bb, FALSE);
00677 local_scheduler.Schedule_BB();
00678
00679 if (Get_Trace(TP_A_MLBR, 0x02)) {
00680 fprintf(TFile, "Mutli_entry BB %d in PU %d need resched\n",
00681 BB_id(pred_bb), Current_PU_Count());
00682 Print_BB(pred_bb);
00683 }
00684 }
00685
00686 }
00687
00688
00689 for (BB *tmp = bb; tmp; tmp = BB_next(tmp)) {
00690 BB_Remove_All(tmp);
00691 BB_cycle(tmp)=0;
00692 Set_BB_partial_bundle(tmp);
00693 if (tmp == src_end_bb) break;
00694 }
00695
00696 for (BB *p_bb=prev_bb; p_bb!=bb; p_bb = BB_next(p_bb)){
00697 Is_True(p_bb!=NULL, ("partial bb is null!"));
00698 Set_BB_partial_bundle(p_bb);
00699 }
00700
00701 if (Get_Trace(TP_A_MLBR, 0x01)) {
00702 fprintf(TFile, "op list After Bundle:\n");
00703 Print_OPS(&ops);
00704 fprintf(TFile, "\n");
00705 }
00706 bundle_succeed = true;
00707
00708 if (Get_Trace(TP_A_MLBR, 0x02) && OPS_length(&dup_new_ops) >1) {
00709 fprintf(TFile, "change multi-branch succeed in BB %d PU %d\n",
00710 BB_id(bb),
00711 Current_PU_Count());
00712 }
00713 }
00714
00715 IPFEC_sched_care_machine = save;
00716 }
00717
00718
00719 BB *insert_bb = prev_bb;
00720 Is_True(insert_bb != NULL, ("You should know where to insert OPS"));
00721 for(OP *cur_op=OPS_first(&ops);cur_op;) {
00722 OP *next_op = OP_next(cur_op);
00723 if (bundle_succeed)
00724 if(!OP_bb(cur_op) || !OP_xfer(cur_op) ||OP_chk(cur_op) ) {
00725 BB_Append_Op(insert_bb, cur_op);
00726 cur_op = next_op;
00727 continue;
00728 }
00729 insert_bb = OP_bb(cur_op);
00730 BB_Append_Op(insert_bb, cur_op);
00731 cur_op = next_op;
00732 }
00733
00734
00735 for(OP *cur_op=OPS_first(&new_ops);cur_op;) {
00736 OP *next_op = OP_next(cur_op);
00737 insert_bb = OP_bb(cur_op);
00738 BB_Append_Op(insert_bb, cur_op);
00739 cur_op = next_op;
00740 }
00741
00742
00743 OPS_Remove_All(&dup_new_ops);
00744 }
00745 }
00746 Stop_Timer(T_Ipfec_Multi_Branch_CU);
00747 }
00749
00750
00751
00752
00753 void Check_Cross_Boundary()
00754 {
00755 BOOL partial_bundle_start = FALSE;
00756 BOOL valid_multi_branch = TRUE;
00757 BB *last_bb;
00758 BB_SET *partial_bbs;
00759
00760 Set_Error_Phase("Multiple Branch");
00761 Start_Timer(T_Ipfec_Multi_Branch_CU);
00762 Initialize_Memory();
00763 partial_bbs = BB_SET_Create_Empty(PU_BB_Count+2, MLBR_pool);
00764
00765
00766 for (BB *bb= REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00767 last_bb = bb;
00768 }
00769 for (BB *bb=last_bb; bb != NULL; bb = BB_prev(bb)) {
00770 if (!BB_partial_bundle(bb) &&
00771 !partial_bundle_start) continue;
00772
00773
00774 if (!partial_bundle_start &&
00775 (BB_length(bb) ==0 ||
00776 !OP_end_group(BB_last_op(bb)))
00777 ) {
00778 valid_multi_branch = FALSE;
00779 }
00780 partial_bundle_start = TRUE;
00781 if (BB_prev(bb) == NULL) {
00782 partial_bundle_start = FALSE;
00783 } else {
00784 if (BB_partial_bundle(bb)) {
00785 if (BB_partial_bundle(BB_prev(bb))) {
00786 if (!BB_scheduled(bb) ||
00787 !BB_Is_Unique_Predecessor(bb, BB_prev(bb))) {
00788 valid_multi_branch = FALSE;
00789 }
00790
00791 BB *prev_partial_bb = BB_prev(bb);
00792 BOOL end_bundle = BB_last_op(bb) ?
00793 OP_end_group(BB_last_op(prev_partial_bb)) : FALSE;
00794 if (BB_scheduled(prev_partial_bb) &&
00795 end_bundle) {
00796 DevWarn("two successor partial bundle BB %d and BB %d.",
00797 BB_id(bb),
00798 BB_id(prev_partial_bb));
00799 partial_bundle_start = FALSE;
00800 }
00801 } else {
00802 BOOL start_bundle = BB_first_op(bb) ?
00803 OP_start_bundle(BB_first_op(bb)): FALSE;
00804 if (!start_bundle ||
00805 !BB_scheduled(bb)) {
00806 valid_multi_branch = FALSE;
00807 }
00808
00809 partial_bundle_start = FALSE;
00810 }
00811 }else {
00812 valid_multi_branch = FALSE;
00813 }
00814 }
00815
00816 partial_bbs = BB_SET_Union1(partial_bbs, bb, MLBR_pool);
00817
00818 if (!partial_bundle_start && !valid_multi_branch) {
00819 BB *bb;
00820 FOR_ALL_BB_SET_members(partial_bbs, bb) {
00821 Reset_BB_scheduled(bb);
00822 Reset_BB_partial_bundle(bb);
00823 }
00824 valid_multi_branch = TRUE;
00825 if (Get_Trace(TP_A_MLBR, 0x01)) {
00826 fprintf(TFile, "You should check BB set:");
00827 BB_SET_Print(partial_bbs, TFile);
00828 fprintf(TFile, "\n");
00829 }
00830 }
00831 if (!partial_bundle_start) {
00832 partial_bbs = BB_SET_ClearD(partial_bbs);
00833 }
00834 }
00835 Finalize_Memory();
00836 Stop_Timer(T_Ipfec_Multi_Branch_CU);
00837 }
00838
00839 BOOL Create_Chance_For_MLBR(BB *target_bb)
00840 {
00841 OP *barrier=NULL;
00842 OP *tmp;
00843
00844 if (!Add_Predicate_Valid_BB(target_bb, &barrier)) return FALSE;
00845
00846 FOR_ALL_BB_OPs(target_bb, tmp)
00847 if (!Add_Predicate_Valid_OP(tmp, barrier)) return FALSE;
00848
00849
00850 if (barrier) {
00851
00852 TN *tn=NULL;
00853 TN *predicate_tn = OP_opnd(barrier, OP_PREDICATE_OPND);
00854
00855
00856
00857 DEF_KIND kind;
00858 OP *def_op = TN_Reaching_Value_At_Op(predicate_tn, barrier, &kind, TRUE);
00859 if (def_op && kind == VAL_KNOWN && OP_icmp(def_op) &&
00860 OP_Defs_TN(def_op, predicate_tn)) {
00861
00862 tn = OP_result(def_op,0);
00863 if (tn == predicate_tn) tn = OP_result(def_op,1);
00864 if (tn == NULL) return FALSE;
00865 }
00866
00867 if (tn) {
00868
00869 if (Get_Trace(TP_A_MLBR, 0x02)) fprintf(TFile, "currret BB's op is :\n");
00870
00871
00872 FOR_ALL_BB_OPs(target_bb, tmp) {
00873 if (OP_dummy(tmp) || OP_simulated(tmp) || OP_noop(tmp)) continue;
00874 if (OP_xfer(tmp) && !OP_chk(tmp)) continue;
00875
00876
00877 Set_OP_opnd(tmp, OP_PREDICATE_OPND, tn);
00878 Set_TN_is_global_reg(tn);
00879 if (Get_Trace(TP_A_MLBR, 0x02)) Print_OP_No_SrcLine(tmp);
00880 }
00881 if (Get_Trace(TP_A_MLBR, 0x02)) {
00882 fprintf(TFile, "change op use predicate tn: in BB %d PU %d\n",
00883 BB_id(target_bb),
00884 Current_PU_Count());
00885 Print_OP_No_SrcLine(def_op);
00886 Print_OP_No_SrcLine(barrier);
00887 }
00888 }
00889 }
00890 return FALSE;
00891 }
00892 void Post_Multi_Branch_Collect(void)
00893 {
00894 Set_Error_Phase("Multiple Branch");
00895 Start_Timer(T_Ipfec_Multi_Branch_CU);
00896
00897 if (!IPFEC_Enable_Pre_Multi_Branch ||
00898 !LOCS_Enable_Bundle_Formation) return;
00899
00900 if (PROCESSOR_Version != 2) return;
00901
00902 for (BB *bb= REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00903 if (BB_length(bb)==0) continue;
00904 if (IPFEC_Query_Skiplist(mlbr_skip_bb, BB_id(bb),
00905 Current_PU_Count())) continue;
00906
00907 Create_Chance_For_MLBR(bb);
00908 }
00909 }