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 #include <vector>
00044 #include <set>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include "bb.h"
00048 #include "defs.h"
00049 #include "mempool.h"
00050 #include "error.h"
00051 #include "bb_set.h"
00052 #include "region.h"
00053 #include "cgtarget.h"
00054 #include "if_conv.h"
00055 #include "timing.h"
00056 #include "tracing.h"
00057 #include "cg.h"
00058 #include "profile_util.h"
00059 #include "region_bb_util.h"
00060 #include "ti_res_count.h"
00061 #include "ti_latency.h"
00062 #include "ipfec_defs.h"
00063 #include "cg_dep_graph.h"
00064 #include "dominate.h"
00065 #include "vt_region.h"
00066 #include "recovery.h"
00067 #include <math.h>
00068 #include "whirl2ops.h"
00069 #include "tlog.h"
00070 #include "glob.h"
00071 #include "ipfec_options.h"
00072 #include "be_util.h"
00073 #include "freq.h"
00074 #include "op.h"
00075
00076 #define MAX_NUM_PARA_CMP 2
00077 #define COMP_TOP_NUM 32
00078 #define PARA_COMP_TYPE_NUM 6
00079
00080 void fPrint_TN ( FILE *f, char *fmt, TN *tn);
00081 BOOL CGTARG_Unconditional_Compare(OP *, TOP *);
00082 void BB_SET_Calculate_Dominators(BB_SET *, BOOL, BOOL);
00083 void Calculate_Dominators(void);
00084 void Free_Dominators_Memory(void);
00085 void Exp_True_False_Preds_For_Block(BB *, TN *&, TN *&);
00086 void Exp_Pred_Set(TN *dest, TN *cdest, INT val, OPS *ops);
00087 void Exp_Generic_Pred_Calc(TN*,TN *, COMPARE_TYPE, TN *, OPS*);
00088 void draw_classic_BB_dependence_graph(BB *bb);
00089 void Predicate_Block(BB* bb, TN *pred_tn, BB_SET*);
00090 void Print_BB (BB *);
00091 void Print_OPS(ops const *);
00092 void Print_OP_No_SrcLine(const OP *op);
00093 void GRA_LIVE_Compute_Liveness_For_BB(BB *bb);
00094 BOOL FREQ_Match(float f1, float f2);
00095 BOOL Is_In_Abnormal_Loop(REGION* r);
00096 COMPARE_TYPE Compare_Type(TOP opcode);
00097
00098 hTN_MAPf frequency_of_predicates = 0;
00099 TN_INFO_MEM info_mem;
00100 hTN_MAP init_op_info = 0;
00101
00102
00103 BOOL
00104 Is_Para_Comp_May_Def(OP *op)
00105 {
00106 COMPARE_TYPE comp_type = Compare_Type(OP_code(op));
00107 return ((comp_type != COMPARE_TYPE_unc)
00108 && (comp_type != COMPARE_TYPE_normal)
00109 && (comp_type != (COMPARE_TYPE)-1));
00110 }
00111
00112 BOOL
00113 Is_In_Infinite_Loop(REGION* region)
00114 {
00115 REGION* reg = region;
00116 while (reg) {
00117 if ( reg -> Region_Type() == LOOP
00118 && reg ->Exits().empty())
00119 return TRUE;
00120 reg = reg -> Parent();
00121 }
00122 return FALSE;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 BOOL
00148 Is_Abnormal_Loop(REGION* region)
00149 {
00150 if ( region -> Region_Type() != LOOP)
00151 return FALSE;
00152
00153
00154 REGIONAL_CFG_NODE* loop_tail = NULL;
00155 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter( region -> Regional_Cfg());
00156 iter!=0;
00157 ++iter)
00158 {
00159 REGIONAL_CFG_NODE *node = *iter;
00160 if ( node -> Succ_Num() == 0)
00161 {
00162 if(loop_tail ||
00163 (node -> Is_Region() && node->Region_Node()->Exits().size() >1 ) )
00164 return TRUE;
00165 loop_tail = node;
00166 }
00167
00168 }
00169
00170 NODE_VECTOR exits = region -> Exits();
00171 for (NODE_VECTOR_ITER iter1 = exits.begin();
00172 iter1 != exits.end();
00173 iter1++)
00174 {
00175 if ((*iter1) == loop_tail) {
00176 return FALSE;
00177 }
00178 }
00179
00180
00181 if ( region -> Entries().size() != 1) {
00182 DevWarn("MEME region is illegal in Is_Abnormal_Loop!\n");
00183 return FALSE;
00184 }
00185 if ( region -> Exits().size() == 1)
00186 {
00187 REGIONAL_CFG_NODE* entry = *(region -> Entries().begin());
00188 REGIONAL_CFG_NODE* exit = *(region -> Exits().begin());
00189 if (!entry->Is_Region() && entry == exit)
00190 return FALSE;
00191 }
00192
00193 return TRUE;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 OP *
00222 TN_Defined_At_Op (TN *tn, OP *op, std::vector<OP *> *ops) {
00223 OP *value_op;
00224
00225 if (ops==NULL) {
00226 FmtAssert(0, ("Parameter ops is NULL pointer!"));
00227 }
00228
00229 if (TN_register(tn) != REGISTER_UNDEFINED) {
00230 return NULL;
00231 }
00232
00233 for (value_op=OP_prev(op); value_op!=NULL; value_op=OP_prev(value_op)) {
00234 if (OP_Defs_TN(value_op, tn)) {
00235 ops->push_back(value_op);
00236 if (Is_OP_Cond(value_op)) {
00237 if (OP_has_predicate(value_op) && OP_has_predicate(op)) {
00238 TN *p1 = OP_opnd((OP*) value_op, OP_PREDICATE_OPND);
00239 TN *p2 = OP_opnd((OP*) op, OP_PREDICATE_OPND);
00240
00241 if (p1 == p2) {
00242 return value_op;
00243 }
00244 }
00245 }
00246 else {
00247 return value_op;
00248 }
00249 }
00250 }
00251
00252 return NULL;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 void
00270 Find_BB_Predicates(BB* bb, TN*& first_pred,TN*& second_pred)
00271 {
00272 vector<OP *>::iterator op;
00273 vector<OP *> ops;
00274 OP *br = BB_branch_op(bb);
00275
00276 first_pred = NULL;
00277 second_pred = NULL;
00278
00279 TN *pred_1;
00280 TN *pred_2;
00281
00282 if (BB_succs_len(bb) != 2 || !br) {
00283 return;
00284 }
00285
00286 pred_1 = OP_opnd(br, OP_PREDICATE_OPND);
00287 Is_True(pred_1, ("conditional branch has no guarded predicate!\n"));
00288
00289 OP *compare_op = TN_Defined_At_Op(pred_1, br, &ops);
00290
00291 if(!compare_op) {
00292 return;
00293 }
00294
00295 Is_True(compare_op,
00296 (" the predicate of br has reaching definition!\n"));
00297 Is_True(OP_results(compare_op),
00298 (" compare_op must has result.\n"));
00299
00300 first_pred = OP_result(compare_op,0);
00301 if (OP_results(compare_op) > 1)
00302 {
00303 second_pred = OP_result(compare_op,1);
00304 }
00305
00306
00307
00308
00309
00310
00311
00312 BOOL create_neg_of_br_pred = FALSE;
00313
00314 if (ops.size() < 2) {
00315 return;
00316 }
00317
00318 for (op = ops.begin(); op != ops.end(); op++) {
00319 if (OP_results(*op) > 1) {
00320 if ( !( (first_pred == OP_result(*op,0)) &&
00321 (second_pred == OP_result(*op,1))
00322 ) &&
00323 !( (first_pred == OP_result(*op,1)) &&
00324 (second_pred == OP_result(*op,0))
00325 )
00326 )
00327 {
00328
00329
00330
00331 create_neg_of_br_pred = TRUE;
00332 break;
00333 }
00334 }
00335 else {
00336
00337
00338
00339 create_neg_of_br_pred = TRUE;
00340 break;
00341 }
00342 }
00343
00344 if (create_neg_of_br_pred) {
00345 OP *neg_op;
00346
00347
00348
00349 neg_op = OP_prev(br);
00350
00351 if ( (OP_code(neg_op)==TOP_cmp_ne_unc) &&
00352 (OP_Refs_TN(neg_op, pred_1)) &&
00353 (OP_Refs_TN(neg_op, Zero_TN)) &&
00354 (OP_Defs_TN(neg_op, True_TN)) )
00355 {
00356 pred_2 = OP_result(neg_op, 1);
00357 }
00358 else {
00359 pred_2 = Gen_Predicate_TN();
00360 neg_op = Mk_OP(TOP_cmp_ne_unc, True_TN, pred_2, True_TN, pred_1, Zero_TN);
00361 OP_srcpos(neg_op) = OP_srcpos(br);
00362 BB_Insert_Op(bb, br, neg_op, TRUE);
00363 }
00364
00365 first_pred = pred_1;
00366 second_pred = pred_2;
00367 }
00368
00369 return;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 IF_CONV_AREA::IF_CONV_AREA(BB *bb, IF_CONVERTOR *convertor):
00382 _included_blocks(BB_CONTAINER(&(convertor -> _m))),
00383 _predecessors(IF_CONV_ALLOC(&(convertor -> _m))),
00384 _successors(IF_CONV_ALLOC(&(convertor -> _m)))
00385 {
00386 _head = bb;
00387
00388
00389 _included_blocks.push_back(bb);
00390
00391
00392
00393
00394
00395 AREA_TYPE type = convertor -> Suitable_For_If_Conv(bb);
00396 _if_suitable = type;
00397 _need_if_convert = NO_IF_CONV;
00398 if (type != UNSUITABLE)
00399 {
00400 _cycled_critical_length = convertor ->
00401 Compute_Critical_Path_Len(bb, true);
00402 _critical_length = convertor ->
00403 Compute_Critical_Path_Len(bb,false);
00404 } else {
00405 _cycled_critical_length = 0;
00406 _critical_length = 0;
00407 }
00408
00409 _control_deps = 0;
00410 _pred_assign_info = 0;
00411 }
00412
00413 void
00414 IF_CONV_AREA::Combine_Blocks_With(IF_CONV_AREA *area, MEM_POOL *mem_pool)
00415 {
00416 BB_CONTAINER& set = area -> Blocks();
00417 BB_CONTAINER::iterator iter;
00418 for (iter = set.begin();
00419 iter != set.end();
00420 iter++)
00421 {
00422 _included_blocks.push_back(*iter);
00423 }
00424 }
00425
00426 void
00427 IF_CONV_AREA::Init_Conversion_Info(MEM_POOL *mem_pool)
00428 {
00429 _control_deps = CXX_NEW(
00430 CNTL_DEP(_head, _included_blocks, mem_pool), mem_pool);
00431 _pred_assign_info = BB_MAP_Create();
00432
00433 BB_CONTAINER::iterator iter;
00434 for (iter = _included_blocks.begin();
00435 iter != _included_blocks.end();
00436 iter++)
00437 {
00438 BB_PREDICATE_INFO* info =
00439 CXX_NEW(BB_PREDICATE_INFO(mem_pool), mem_pool);
00440 BB_MAP_Set(_pred_assign_info, *iter, info);
00441 }
00442 }
00443 void
00444 IF_CONV_AREA::Remove_BB(BB* bb)
00445 {
00446 BB_CONTAINER::iterator iter;
00447 for (iter = _included_blocks.begin();
00448 iter != _included_blocks.end();
00449 iter++)
00450 {
00451 if ( *iter == bb)
00452 {
00453 _included_blocks.erase(iter);
00454 return;
00455 }
00456 }
00457 }
00458 EXIT_TARGET_INFO*
00459 IF_CONV_AREA::Exit_Target(BB* bb)
00460 {
00461 EXIT_CONTAINER::iterator iter;
00462 for (iter = _exit_targets.begin();
00463 iter != _exit_targets.end();
00464 iter++)
00465 {
00466 if ( (*iter) -> Target() == bb) {
00467 return *iter;
00468 }
00469 }
00470 return NULL;
00471 }
00472 void
00473 IF_CONV_AREA::Add_Exit_Target(BB* target, TN* predicate, MEM_POOL* mem_pool)
00474 {
00475 EXIT_TARGET_INFO* info =
00476 CXX_NEW(EXIT_TARGET_INFO(target, mem_pool), mem_pool);
00477 info -> Add_Main_Predicate(predicate);
00478 _exit_targets.push_back(info);
00479 }
00480
00481 BOOL
00482 EXIT_TARGET_INFO::Is_Main_Predicate(TN* tn)
00483 {
00484 TN_CONTAINER::iterator iter;
00485 for (iter = _main_predicates.begin();
00486 iter != _main_predicates.end();
00487 iter++)
00488 {
00489 if ( *iter == tn) return true;
00490 }
00491 return false;
00492 }
00493 void
00494 EXIT_TARGET_INFO::Assign_Aux_Predicates(BB* bb, OP *br)
00495 {
00496 OPS ops = OPS_EMPTY;
00497
00498 if ( _aux_predicates.size() == 0 || _main_predicates.size() ==0 )
00499 return;
00500
00501 Is_True(_main_predicates.size() == 1,
00502 ("Wrong number of main predicates!\n"));
00503
00504 TN *main_tn = *(_main_predicates.begin());
00505 TN_CONTAINER::iterator iter;
00506 for (iter = _aux_predicates.begin();
00507 iter != _aux_predicates.end();
00508 iter++)
00509 {
00510 Is_True(*iter, ("NULL predicate.\n"));
00511 Build_OP(TOP_cmp_eq, main_tn, True_TN,
00512 *iter,Zero_TN, Zero_TN, &ops);
00513 }
00514
00515 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
00516 {
00517 Print_OPS(&ops);
00518 }
00519 OP* new_op;
00520 FOR_ALL_OPS_OPs_FWD((&ops),new_op){
00521 Set_OP_cond_def_kind(new_op, OP_ALWAYS_COND_DEF);
00522 }
00523 BB_Insert_Ops_Before (bb, br, &ops);
00524
00525 }
00526 void
00527 EXIT_TARGET_INFO::Del_Main_Predicate(TN* tn){
00528 TN_CONTAINER::iterator iter;
00529 for (iter = _main_predicates.begin();
00530 iter != _main_predicates.end();
00531 iter++)
00532 {
00533 Is_True(*iter, ("NULL predicate.\n"));
00534 if (*iter == tn)
00535 {
00536 _main_predicates.erase(iter);
00537 break;
00538 }
00539 }
00540 }
00541 void
00542 EXIT_TARGET_INFO::Update_Predicate(TN *old_tn, TN* new_tn)
00543 {
00544 if (old_tn == new_tn) return;
00545
00546 TN_CONTAINER::iterator iter;
00547 for (iter = _main_predicates.begin();
00548 iter != _main_predicates.end();
00549 iter++)
00550 {
00551 Is_True(*iter, ("NULL predicate.\n"));
00552 if (*iter == old_tn)
00553 {
00554 _main_predicates.erase(iter);
00555 _main_predicates.push_back(new_tn);
00556 break;
00557 }
00558 }
00559
00560 for (iter = _aux_predicates.begin();
00561 iter != _aux_predicates.end();
00562 iter++)
00563 {
00564 Is_True(*iter, ("NULL predicate.\n"));
00565 if (*iter == old_tn)
00566 {
00567 _aux_predicates.erase(iter);
00568 _aux_predicates.push_back(new_tn);
00569 break;
00570 }
00571 }
00572
00573 return;
00574
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 CNTL_DEP::CNTL_DEP(BB *entry, BB_CONTAINER& bbs, MEM_POOL *mem_pool)
00598 {
00599 _entry = entry;
00600
00601 _bb_set = BB_SET_Create_Empty(PU_BB_Count, mem_pool);
00602 BB_CONTAINER::iterator bb_iter;
00603 BB *bb;
00604 for (bb_iter = bbs.begin();
00605 bb_iter != bbs.end();
00606 bb_iter++)
00607 {
00608 bb = *bb_iter;
00609 _bb_set = BB_SET_Union1D(_bb_set, bb, mem_pool);
00610 }
00611
00612
00613 _control_dependences = BB_MAP_Create();
00614 _true_edges = BB_MAP_Create();
00615
00616 FOR_ALL_BB_SET_members(_bb_set, bb)
00617 {
00618 BB_SET *deps = BB_SET_Create_Empty(PU_BB_Count, mem_pool);
00619 BB_SET *trues = BB_SET_Create_Empty(PU_BB_Count, mem_pool);
00620 BB_MAP_Set(_control_dependences, bb, deps);
00621 BB_MAP_Set(_true_edges, bb, trues);
00622 }
00623
00624
00625
00626 BBLIST *bl;
00627 BB_SET *bb_to_add = BB_SET_Create_Empty(PU_BB_Count+2, mem_pool);
00628 FOR_ALL_BB_SET_members(_bb_set, bb)
00629 {
00630 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
00631 {
00632 fprintf(TFile, " Computing BB%d:\n", BB_id(bb));
00633 }
00634 BB *fall_thru = BB_Fall_Thru_Successor(bb);
00635 TN *second_pred = NULL;
00636 TN *first_pred = NULL;
00637 OP *br = NULL;
00638 if ( BB_succs_len(bb) == 2)
00639 {
00640 br = BB_branch_op(bb);
00641 Find_BB_Predicates(bb, first_pred, second_pred);
00642 }
00643
00644 FOR_ALL_BB_SUCCS(bb, bl)
00645 {
00646 BB *bb_dep;
00647 BB *bb_succ = BBLIST_item(bl);
00648 BOOL true_edge = FALSE;
00649
00650 if ( br )
00651 {
00652 true_edge = (( first_pred == OP_opnd(br, OP_PREDICATE_OPND)
00653 && bb_succ != fall_thru)
00654 || ( second_pred == OP_opnd(br, OP_PREDICATE_OPND)
00655 && bb_succ == fall_thru));
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
00669 {
00670 fprintf(TFile, " ===== succ BB%d:", BB_id(bb_succ));
00671 }
00672 if (BB_SET_MemberP(_bb_set, bb_succ) && (bb_succ != entry))
00673 {
00674 BB_SET_CopyD(bb_to_add, BB_pdom_set(bb_succ), mem_pool);
00675 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
00676 {
00677 BB* bb_tmp;
00678 fprintf(TFile, " ** pdoms:");
00679 FOR_ALL_BB_SET_members(bb_to_add, bb_tmp)
00680 {
00681 fprintf(TFile, " BB%d, ", BB_id(bb_tmp));
00682 }
00683 fprintf(TFile, "\n");
00684 }
00685
00686 bb_to_add = BB_SET_DifferenceD(bb_to_add, BB_pdom_set(bb));
00687 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
00688 {
00689 BB* bb_tmp;
00690 fprintf(TFile, " ** after -pdoms(bb):");
00691 FOR_ALL_BB_SET_members(bb_to_add, bb_tmp)
00692 {
00693 fprintf(TFile, " BB%d, ", BB_id(bb_tmp));
00694 }
00695 fprintf(TFile, "\n");
00696 }
00697
00698 bb_to_add = BB_SET_IntersectionD(bb_to_add, _bb_set);
00699 FOR_ALL_BB_SET_members(bb_to_add, bb_dep)
00700 {
00701 BB_SET *deps, *trues, *new_deps, *new_trues;
00702
00703 deps = (BB_SET*)BB_MAP_Get(_control_dependences, bb_dep);
00704 Is_True(deps != NULL,
00705 ("Can't find cntl deps for BB%d.\n", BB_id(bb_dep)));
00706
00707 trues = (BB_SET*)BB_MAP_Get(_true_edges, bb_dep);
00708 Is_True(trues != NULL,
00709 ("Can't find true edges for BB%d.\n", BB_id(bb_dep)));
00710
00711 new_deps = BB_SET_Union1D(deps, bb, mem_pool);
00712 if ( deps != new_deps)
00713 {
00714 BB_MAP_Set(_control_dependences, bb_dep, new_deps);
00715 }
00716 if (true_edge)
00717 {
00718 new_trues = BB_SET_Union1D(trues, bb, mem_pool);
00719 if ( trues != new_trues )
00720 {
00721 BB_MAP_Set( _true_edges, bb_dep, mem_pool);
00722 }
00723 }
00724 }
00725 }
00726 }
00727 }
00728 }
00729 BOOL
00730 CNTL_DEP::Is_Cntl_Dep(BB *bb1, BB *bb2)
00731 {
00732 BB *bb;
00733 if (bb1 == bb2) return true;
00734
00735 BB_SET *set = Cntl_Dep_Parents(bb2);
00736 Is_True(set != NULL,
00737 (" Can not find control dependent parents for BB%d", BB_id(bb2)));
00738
00739 FOR_ALL_BB_SET_members(set, bb)
00740 {
00741 if (Is_Cntl_Dep(bb1, bb))
00742 return true;
00743 }
00744 return false;
00745 }
00746
00747 void
00748 CNTL_DEP::Cntl_Dep_Children(BB_SET*& result, BB *bb, MEM_POOL *mem_pool)
00749 {
00750 BB *block;
00751 FOR_ALL_BB_SET_members(_bb_set, block)
00752 {
00753 BB_SET *cds = (BB_SET*)BB_MAP_Get(_control_dependences, block);
00754 Is_True(cds != NULL,
00755 (" Can not find control dependent parents for BB%d",
00756 BB_id(block)));
00757
00758 if (BB_SET_MemberP(cds, bb))
00759 {
00760 result = BB_SET_Union1D( result, block, mem_pool);
00761 }
00762 }
00763 }
00764
00765 void
00766 CNTL_DEP::_Post_Order_Helper(BB_CONTAINER& result,
00767 BB *bb,
00768 IF_CONVERTOR* convertor)
00769 {
00770 BB *child;
00771 BB_SET *child_set;
00772
00773 if (convertor -> Is_BB_Container_Member(result, bb))
00774 return;
00775
00776 child_set = BB_SET_Create_Empty(PU_BB_Count, &(convertor -> _m));
00777 Cntl_Dep_Children(child_set, bb, &(convertor -> _m));
00778 FOR_ALL_BB_SET_members(child_set, child)
00779 {
00780 _Post_Order_Helper(result, child, convertor);
00781 }
00782 result.push_back(bb);
00783 }
00784
00785 void
00786 CNTL_DEP::Get_Post_Order(BB_CONTAINER& result,
00787 IF_CONVERTOR* convertor)
00788 {
00789 BB *block;
00790 FOR_ALL_BB_SET_members(_bb_set, block)
00791 {
00792 _Post_Order_Helper(result, block, convertor);
00793 }
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 AREA_TYPE
00814 IF_CONVERTOR::Suitable_For_If_Conv(BB *bb)
00815 {
00816
00817 if (BB_kind(bb) == BBKIND_VARGOTO || BB_kind(bb) == BBKIND_INDGOTO)
00818 {
00819 return UNSUITABLE;
00820 }
00821
00822 if (BB_call(bb)) return UNSUITABLE;
00823
00824
00825 if (BB_Has_Exc_Label(bb))
00826 {
00827 return UNSUITABLE;
00828 }
00829
00830
00831 if (BB_Has_Addr_Taken_Label(bb))
00832 {
00833 return UNSUITABLE;
00834 }
00835
00836 AREA_TYPE ty = SUITABLE_FOR_IF_CONV;
00837 OP* op;
00838 FOR_ALL_BB_OPs_FWD(bb, op)
00839 {
00840
00841
00842
00843
00844
00845 if (!OP_has_predicate(op) && !OP_xfer(op))
00846 {
00847 ty = (AREA_TYPE)((INT)ty & UPWARD_UNSUITABLE);
00848 }
00849
00850
00851
00852 if (OP_has_predicate(op) &&
00853 !TN_is_true_pred(OP_opnd(op, OP_PREDICATE_OPND)))
00854 {
00855 TN *pred_tn = OP_opnd(op, OP_PREDICATE_OPND);
00856 if (TN_is_global_reg(pred_tn))
00857 {
00858 return UNSUITABLE;
00859 }
00860 vector<OP *> ops;
00861 OP *def_op = TN_Defined_At_Op(pred_tn, op, &ops);
00862
00863
00864 if (!def_op)
00865 {
00866 DevWarn("Predicated instruction with no reaching def in BB%d "
00867 "in Suitable_For_If_Conv.", BB_id(bb));
00868 return UNSUITABLE;
00869 }
00870
00871
00872
00873 if (OP_bb(def_op)!= bb)
00874 {
00875 DevWarn("An up-exposed predicate use stops if-converter BB%d "
00876 "in Suitable_For_If_Conv.",BB_id(bb));
00877 return UNSUITABLE;
00878 }
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 COMPARE_TYPE ty = Compare_Type(OP_code(op));
00905 if ( ty != (COMPARE_TYPE)-1) {
00906
00907 Is_True(OP_results(op) <=2, ("too many results!\n"));
00908
00909 TN *pred_tn = OP_result(op, 0);
00910 if (Is_Partial_Redundant_Def(bb, op, pred_tn)) {
00911 return UNSUITABLE;
00912 }
00913 pred_tn = OP_result(op, 1);
00914 if (Is_Partial_Redundant_Def(bb, op, pred_tn)) {
00915 return UNSUITABLE;
00916 }
00917 }
00918 }
00919 return ty;
00920 }
00921 BOOL
00922 IF_CONVERTOR::Is_Partial_Redundant_Def(BB* bb, OP* op, TN* tn)
00923 {
00924
00925
00926 OP *def_op = NULL;
00927 OP *def_bb = NULL;
00928 vector<OP *> ops;
00929
00930 def_op = TN_Defined_At_Op(tn, op, &ops);
00931 if (def_op)
00932 {
00933 BB *def_bb = OP_bb(def_op);
00934 if ( def_bb != bb && !BB_SET_MemberP(BB_pdom_set(def_bb), bb))
00935 {
00936 return TRUE;
00937 }
00938 } else {
00939 BB_SET* bb_queue = BB_SET_Create_Empty(PU_BB_Count, &_m);
00940 bb_queue = BB_SET_Union1D(bb_queue, bb, &_m);
00941 BB_SET* bb_processed = BB_SET_Create_Empty(PU_BB_Count, &_m);
00942
00943 while ( BB_SET_Size(bb_queue) )
00944 {
00945 BB* bb1 = BB_SET_Choose(bb_queue);
00946 BS_Difference1D(bb_queue, BB_id(bb1));
00947 BB_SET_Union1D(bb_processed, bb1, &_m);
00948
00949 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb1);
00950 for (CFG_PRED_NODE_ITER pred_iter(node);
00951 pred_iter!=0;
00952 ++pred_iter)
00953 {
00954 REGIONAL_CFG_NODE *pred = *pred_iter;
00955 if (pred -> Is_Region()) continue;
00956
00957 BB* pred_bb = pred -> BB_Node();
00958 if ( GTN_SET_MemberP(BB_live_in(pred_bb),tn)
00959 && !BB_SET_MemberP(BB_pdom_set(pred_bb), bb))
00960 {
00961 return TRUE;
00962 } else if (!BB_SET_MemberP(bb_processed, pred_bb)){
00963 bb_queue = BB_SET_Union1D(bb_queue, pred_bb, &_m);
00964 }
00965 }
00966 }
00967 }
00968 return FALSE;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 void
00983 IF_CONVERTOR::Compute_Min_Cycle(INT32& base, BB_CONTAINER& set)
00984 {
00985 TI_RES_COUNT *counter = TI_RES_COUNT_Alloc(&_m);
00986 BB_CONTAINER::iterator iter;
00987 for (iter = set.begin();
00988 iter != set.end();
00989 iter++)
00990 {
00991 OP *op;
00992 FOR_ALL_BB_OPs_FWD(*iter, op)
00993 {
00994 TI_RES_COUNT_Add_Op_Resources(counter, OP_code(op));
00995 }
00996 }
00997 base += (INT32)ceil(TI_RES_COUNT_Min_Cycles(counter));
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007 float
01008 IF_CONVERTOR::Prob_Of_Area(IF_CONV_AREA *area1,
01009 IF_CONV_AREA *area2)
01010 {
01011 float freq = 0.0;
01012
01013 BB *head = area2 -> Entry_BB();
01014
01015 BB *bb;
01016 BBLIST *bl;
01017 FOR_ALL_BB_PREDS(head, bl)
01018 {
01019 BB *bb_pred = BBLIST_item(bl);
01020 BB_CONTAINER& bbs = area1 -> Blocks();
01021 if (Is_BB_Container_Member(bbs, bb_pred))
01022 {
01023 freq += Prob_Local(bb_pred, head) * BB_freq(bb_pred);
01024
01025 }
01026 }
01027 float result = BB_freq(area1 -> Entry_BB()) ?
01028 freq / BB_freq(area1 -> Entry_BB()):0;
01029
01030 return result <1.0 ||FREQ_Match(result, 1.0) ? result: 1.0;
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 INT32
01047 IF_CONVERTOR::Compute_Critical_Path_Len(BB *bb,
01048 BOOL cycled)
01049 {
01050
01051 BB_OP_MAP earliest_time_table = BB_OP_MAP32_Create(bb, &_m);
01052 INT32 critical_path_cycle = 0;
01053
01054
01055 if (CG_DEP_Has_Graph(bb))
01056 {
01057 CG_DEP_Delete_Graph(bb);
01058 }
01059 CG_DEP_Compute_Graph (
01060 bb,
01061 INCLUDE_ASSIGNED_REG_DEPS,
01062 NON_CYCLIC,
01063 NO_MEMREAD_ARCS,
01064 INCLUDE_MEMIN_ARCS,
01065 INCLUDE_CONTROL_ARCS,
01066 NULL);
01067
01068
01069
01070 OP *op;
01071 FOR_ALL_BB_OPs_FWD(bb,op)
01072 {
01073 if ( OP_xfer(op))
01074 break;
01075
01076 INT32 earliest_start_time = 0;
01077 INT32 latency;
01078
01079
01080
01081
01082 for (ARC_LIST* arcs = OP_preds(op);
01083 arcs != NULL;
01084 arcs = ARC_LIST_rest(arcs))
01085 {
01086 ARC* arc = ARC_LIST_first(arcs);
01087
01088 OP* pred = ARC_pred(arc);
01089 if (OP_bb(pred) != bb) continue;
01090
01091 INT32 start_time;
01092 start_time = BB_OP_MAP32_Get(earliest_time_table, pred);
01093 latency = cycled ? ARC_latency(arc):1;
01094 start_time += latency;
01095 if ( start_time > earliest_start_time)
01096 earliest_start_time = start_time;
01097 }
01098
01099
01100
01101 BB_OP_MAP32_Set(earliest_time_table, op, earliest_start_time);
01102
01103 latency = cycled ? TI_LATENCY_Result_Available_Cycle(OP_code(op),0):1;
01104 INT32 path_time = earliest_start_time + latency;
01105 if (critical_path_cycle < path_time)
01106 {
01107 critical_path_cycle = path_time;
01108 }
01109 }
01110
01111 CG_DEP_Delete_Graph(bb);
01112
01113 return critical_path_cycle;
01114 }
01115
01116
01117
01118
01119
01120
01121
01122 AREA_CONTAINER::iterator
01123 IF_CONVERTOR::Find_Area(AREA_CONTAINER& areas,
01124 IF_CONV_AREA* area)
01125 {
01126
01127 AREA_CONTAINER::iterator iter;
01128 for (iter = areas.begin();
01129 iter!= areas.end();
01130 iter++)
01131 {
01132 if ( area == *iter)
01133 {
01134 return iter;
01135 }
01136 }
01137 return iter;
01138 }
01139 inline
01140 void
01141 IF_CONVERTOR::Add_Edge(IF_CONV_AREA *area1, IF_CONV_AREA *area2)
01142 {
01143 area1 -> Add_Succ(area2, this);
01144 area2 -> Add_Pred(area1, this);
01145 }
01146 BOOL
01147 IF_CONVERTOR::Is_BB_Container_Member(BB_CONTAINER& bbs, BB* bb)
01148 {
01149 BB *block;
01150 BB_CONTAINER::iterator iter;
01151 for (iter = bbs.begin();
01152 iter != bbs.end();
01153 iter++)
01154 {
01155 block = *iter;
01156 if (block == bb) return true;
01157 }
01158 return false;
01159 }
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 void
01190 IF_CONVERTOR::If_Conversion_Init(REGION *region,
01191 AREA_CONTAINER& area_list)
01192 {
01193
01194
01195
01196
01197 BB_MAP area_table = BB_MAP_Create();
01198 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter( region -> Regional_Cfg());
01199 iter!=0;
01200 ++iter)
01201 {
01202 REGIONAL_CFG_NODE *node = *iter;
01203 BB *pred_bb;
01204 IF_CONV_AREA *pred_area;
01205
01206 if (node -> Is_Region())
01207 {
01208
01209
01210 for (CFG_PRED_NODE_ITER pred_iter(node);
01211 pred_iter!=0;
01212 ++pred_iter)
01213 {
01214 REGIONAL_CFG_NODE *pred = *pred_iter;
01215 if (pred -> Is_Region()) continue;
01216
01217 pred_bb = pred -> BB_Node();
01218 pred_area = (IF_CONV_AREA*)BB_MAP_Get(area_table, pred_bb);
01219 Is_True(pred_area != NULL,
01220 ("Can't find corresponding area for BB%d.\n",
01221 BB_id(pred_bb)));
01222 pred_area -> Area_Type(DOWNWARD_UNSUITABLE);
01223 }
01224 continue;
01225 }
01226
01227 BB *bb = node -> BB_Node();
01228 IF_CONV_AREA *area;
01229
01230 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
01231 {
01232 fprintf(TFile,
01233 " -- solving BB%d: \n", BB_id(bb));
01234 }
01235
01236
01237
01238
01239 if ( BB_recovery(bb))
01240 {
01241 Is_True(node -> Pred_Num() == 1,
01242 ("the basic block can only have one predecessor"));
01243
01244 REGIONAL_CFG_NODE *pred = node -> First_Pred() -> Src();
01245 if (!pred -> Is_Region())
01246 {
01247 area = (IF_CONV_AREA*)BB_MAP_Get(area_table,
01248 pred -> BB_Node());
01249 Is_True(pred_area != NULL,
01250 ("Can't find corresponding area for BB%d.\n",
01251 BB_id(pred_bb)));
01252 area -> Blocks().push_back(bb);
01253 BB_MAP_Set(area_table, bb, area);
01254 continue;
01255 }
01256 }
01257
01258
01259 area = CXX_NEW(IF_CONV_AREA(bb, this), &_m);
01260 area_list.push_back(area);
01261
01262
01263 BB_MAP_Set(area_table, bb, area);
01264
01265
01266 for (CFG_PRED_NODE_ITER pred_iter(node);
01267 pred_iter!=0;
01268 ++pred_iter)
01269 {
01270 REGIONAL_CFG_NODE *pred = *pred_iter;
01271 if ( pred -> Is_Region())
01272 {
01273 area -> Area_Type(UPWARD_UNSUITABLE);
01274 continue;
01275 }
01276
01277 pred_bb = pred -> BB_Node();
01278 pred_area = (IF_CONV_AREA*)BB_MAP_Get( area_table, pred_bb);
01279 Is_True(pred_area != NULL,
01280 ("Can't find corresponding area for BB%d.\n",
01281 BB_id(pred_bb)));
01282 Add_Edge( pred_area,area );
01283 }
01284
01285 if ( node -> Is_Exit())
01286 {
01287 area -> Area_Type(DOWNWARD_UNSUITABLE);
01288 }
01289 }
01290
01291 BB_MAP_Delete(area_table);
01292 }
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 CFLOW_TYPE
01323 IF_CONVERTOR::Detect_Type(IF_CONV_AREA* area,
01324 AREA_CONTAINER& cand_list,
01325 BOOL forced)
01326 {
01327 if (area -> Area_Type() == UNSUITABLE
01328 || area -> Area_Type() == DOWNWARD_UNSUITABLE)
01329 return NO_TYPE;
01330
01331
01332 AREA_CONTAINER succs = area -> Succ_Set();
01333 AREA_CONTAINER::iterator iter;
01334
01335
01336 for ( iter = succs.begin();
01337 iter != succs.end();
01338 iter++)
01339 {
01340 IF_CONV_AREA *succ = *iter;
01341 if (succ -> Area_Type() == UNSUITABLE
01342 || succ -> Area_Type() == UPWARD_UNSUITABLE)
01343 return NO_TYPE;
01344 }
01345
01346
01347 if (area -> Succ_Num() == 1 )
01348 {
01349 IF_CONV_AREA *succ = *(succs.begin());
01350 if (succ -> Pred_Num() == 1)
01351 {
01352 cand_list.push_back(area);
01353 cand_list.push_back(succ);
01354 return SERIAL_TYPE;
01355 }
01356 }
01357
01358 if ( area -> Succ_Num() == 2 )
01359 {
01360 IF_CONV_AREA *succ1, *succ2;
01361 iter = succs.begin();
01362 succ1 = *iter;
01363 iter ++;
01364 succ2 = *iter;
01365
01366
01367 if (succ1 -> Pred_Num() == 1
01368 && Find_Area( succ1 -> Succ_Set(), succ2) != succ1->Succ_Set().end())
01369 {
01370 cand_list.push_back(area);
01371 cand_list.push_back(succ1);
01372 cand_list.push_back(succ2);
01373
01374 return IF_THEN_TYPE;
01375 }
01376
01377 if (succ2 -> Pred_Num() == 1
01378 && Find_Area( succ2 -> Succ_Set(), succ1) != succ2->Succ_Set().end())
01379 {
01380 cand_list.push_back(area);
01381 cand_list.push_back(succ2);
01382 cand_list.push_back(succ1);
01383
01384 return IF_THEN_TYPE;
01385 }
01386
01387
01388 if ( succ1 -> Pred_Num() == 1
01389 && succ2 -> Pred_Num() == 1)
01390 {
01391 IF_CONV_AREA* common_succ = NULL;
01392
01393 for ( iter = succ1 -> Succ_Set().begin();
01394 iter != succ1 -> Succ_Set().end();
01395 iter++)
01396 {
01397 IF_CONV_AREA* succ_of_succ1 = *iter;
01398 if ( Find_Area( succ2 -> Succ_Set(), succ_of_succ1)
01399 != succ2 -> Succ_Set().end())
01400 {
01401 common_succ = succ_of_succ1;
01402 break;
01403 }
01404 }
01405
01406 if ( common_succ)
01407 {
01408 cand_list.push_back(area);
01409 cand_list.push_back(succ2);
01410 cand_list.push_back(succ1);
01411 cand_list.push_back(common_succ);
01412 return IF_THEN_ELSE_TYPE;
01413 }
01414 }
01415 }
01416
01417 if (forced && area -> Succ_Num() == 3) {
01418 IF_CONV_AREA *area1, *area2, *area3;
01419 IF_CONV_AREA *succ1, *succ2, *common_succ;
01420 iter = succs.begin();
01421 area1 = *iter;
01422 iter++;
01423 area2 = *iter;
01424 iter++;
01425 area3 = *iter;
01426
01427 if ( area1->Pred_Num() >= 3
01428 && area2->Pred_Num() == 1
01429 && area3->Pred_Num() == 1)
01430 {
01431
01432 common_succ = area1;
01433 succ1 = area2;
01434 succ2 = area3;
01435 }
01436 else if ( area1->Pred_Num() == 1
01437 && area2->Pred_Num() >= 3
01438 && area3->Pred_Num() == 1)
01439 {
01440
01441 common_succ = area2;
01442 succ1 = area1;
01443 succ2 = area3;
01444 }
01445 else if ( area1->Pred_Num() == 1
01446 && area2->Pred_Num() == 1
01447 && area3->Pred_Num() >= 3)
01448 {
01449
01450 common_succ = area3;
01451 succ1 = area1;
01452 succ2 = area2;
01453 }
01454 else {
01455 return NO_TYPE;
01456 }
01457
01458 if (Find_Area (succ1->Succ_Set(), common_succ)
01459 == succ1->Succ_Set().end())
01460 {
01461 return NO_TYPE;
01462 }
01463
01464 if (Find_Area (succ2->Succ_Set(), common_succ)
01465 == succ2->Succ_Set().end())
01466 {
01467 return NO_TYPE;
01468 }
01469
01470 cand_list.push_back(area);
01471 cand_list.push_back(succ1);
01472 cand_list.push_back(succ2);
01473 cand_list.push_back(common_succ);
01474
01475 return IF_THEN_ELSE_TYPE;
01476 }
01477
01478 return NO_TYPE;
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497 BOOL
01498 IF_CONVERTOR::Worth_If_Convert (AREA_CONTAINER& cand_list,
01499 CFLOW_TYPE type,
01500 BOOL forced)
01501 {
01502 if ( Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
01503 {
01504 fprintf(TFile, " \nConsider profitablity:");
01505 }
01506
01507
01508 AREA_CONTAINER::iterator iter = cand_list.begin();
01509 IF_CONV_AREA *head = *iter;
01510 Is_True(head != NULL, (" All if-conv types have a head-BB.\n "));
01511
01512 iter++;
01513 IF_CONV_AREA *succ1 = *iter;
01514 IF_CONV_AREA *succ2 = NULL;
01515 Is_True(succ1 != NULL,
01516 (" All if-conv types have at least one successor.\n "));
01517
01518 if ( type == IF_THEN_ELSE_TYPE )
01519 {
01520 iter++;
01521 succ2 = *iter;
01522 }
01523
01524
01525
01526 INT32 time = 0;
01527 float exe_time = 0.0;
01528 INT32 min_cycle_1 = 0;
01529 Compute_Min_Cycle(min_cycle_1, succ1 -> Blocks());
01530 INT32 min_cycle_2 = 0;
01531 if ( succ2 )
01532 Compute_Min_Cycle(min_cycle_2, succ2 -> Blocks());
01533
01534 if (succ1 -> Cycled_Critical_Len() > min_cycle_1)
01535 {
01536 time = succ1 -> Cycled_Critical_Len();
01537 } else {
01538 time = min_cycle_1;
01539 }
01540
01541 float taken_rate_1 = Prob_Of_Area(head, succ1);
01542 float taken_rate_2 = 1 - taken_rate_1;
01543 exe_time += taken_rate_1 * time;
01544 if (succ2)
01545 {
01546 if (succ2 -> Cycled_Critical_Len() > min_cycle_2)
01547 {
01548 time = succ2 -> Cycled_Critical_Len();
01549 } else {
01550 time = min_cycle_2;
01551 }
01552 exe_time += taken_rate_2 * time;
01553 }
01554
01555 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
01556 {
01557 fprintf(TFile, " \n Prob : Area_%d ==> Area_%d: %f\n",
01558 head -> Area_Label(),
01559 succ1 -> Area_Label(),
01560 taken_rate_1);
01561 if ( succ2 )
01562 {
01563 fprintf(TFile, " Prob : Area_%d ==> Area_%d: %f\n",
01564 head -> Area_Label(),
01565 succ2 -> Area_Label(),
01566 taken_rate_2);
01567 }
01568 fprintf(TFile, " min_cycle_1 : %d, min_cycle_2 : %d \n",
01569 min_cycle_1, min_cycle_2);
01570 fprintf(TFile, " critical_cycle_1 : %d ",
01571 succ1 -> Cycled_Critical_Len());
01572 if ( succ2 )
01573 {
01574 fprintf(TFile, ", critical_cycle_2 : %d \n",
01575 succ2 -> Cycled_Critical_Len());
01576 } else {
01577 fprintf(TFile, "\n");
01578 }
01579 }
01580
01581 float branch_predict_miss_rate;
01582 if ( taken_rate_1 > taken_rate_2)
01583 {
01584 branch_predict_miss_rate = taken_rate_2;
01585 } else {
01586 branch_predict_miss_rate = taken_rate_1;
01587 }
01588
01589 INT32 branch_predict_miss_panelty, fixed, brtaken;
01590 double factor;
01591
01592 CGTARG_Compute_Branch_Parameters(&branch_predict_miss_panelty,
01593 &fixed, &brtaken, &factor);
01594
01595 float unpredicated_time;
01596 unpredicated_time = exe_time +
01597 branch_predict_miss_rate * branch_predict_miss_panelty;
01598
01599 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
01600 {
01601 fprintf(TFile,
01602 " unpredicated %f cycles vs", unpredicated_time);
01603 }
01604
01605
01606 INT32 max_res_height = 0;
01607 exe_time= 0.0;
01608 if ( succ2 )
01609 {
01610
01611 if (succ1 -> Cycled_Critical_Len() > succ2 -> Critical_Len())
01612 {
01613 time = succ1 -> Cycled_Critical_Len();
01614 } else {
01615 time = succ2 -> Critical_Len();
01616 }
01617 exe_time += taken_rate_1* time;
01618
01619 if (succ2 -> Cycled_Critical_Len() > succ1 -> Critical_Len())
01620 {
01621 time = succ2 -> Cycled_Critical_Len();
01622 } else {
01623 time = succ1 -> Critical_Len();
01624 }
01625 exe_time += taken_rate_2* time;
01626
01627
01628 Compute_Min_Cycle(max_res_height, succ1 -> Blocks());
01629 Compute_Min_Cycle(max_res_height, succ2 -> Blocks());
01630
01631 } else {
01632 exe_time += succ1 -> Cycled_Critical_Len();
01633 Compute_Min_Cycle(max_res_height, succ1 -> Blocks());
01634 }
01635
01636 float predicated_time;
01637 predicated_time = exe_time > max_res_height ? exe_time : max_res_height;
01638
01639 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
01640 {
01641 fprintf(TFile,
01642 " predicated %f cycles\n", predicated_time);
01643 }
01644
01645
01646
01647
01648 if (unpredicated_time > predicated_time) {
01649 return TRUE;
01650 }
01651 else if (forced &&
01652 ((predicated_time*100) < (_loop_length*IF_CONV_BIASE_THRESHOLD)))
01653 {
01654 return TRUE;
01655 }
01656 else {
01657 return FALSE;
01658 }
01659 }
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 void
01684 IF_CONVERTOR::Reduce_By_Type(AREA_CONTAINER& cand_list,
01685 CFLOW_TYPE type,
01686 AREA_CONTAINER& area_list)
01687 {
01688 AREA_CONTAINER::iterator iter= cand_list.begin();
01689 IF_CONV_AREA *head = *iter;
01690 Is_True(head != NULL,
01691 (" All if-conv types have head-BB.\n "));
01692 iter++;
01693
01694 INT32 max_length1 = 0;
01695 INT32 max_length2 = 0;
01696
01697 IF_CONV_AREA *succ1 = NULL;
01698 IF_CONV_AREA *succ2 = NULL;
01699 IF_CONV_AREA *tail = NULL;
01700
01701 succ1 = *iter;
01702 iter++;
01703 Is_True(succ1 != NULL,
01704 (" All if-conv types have at least one successor.\n "));
01705
01706 if (type == IF_THEN_ELSE_TYPE)
01707 {
01708 succ2 = *iter;
01709 iter++;
01710 Is_True(succ2 != NULL,
01711 (" IF_THEN_ELSE_TYPE have at least two successor.\n "));
01712 }
01713
01714 if (iter != cand_list.end())
01715 {
01716 tail = *iter;
01717 }
01718
01719 if (type == SERIAL_TYPE)
01720 {
01721 if (head -> Conv_Type() == FULLY_IF_CONV
01722 || succ1 -> Conv_Type() == FULLY_IF_CONV)
01723 {
01724 head -> Conv_Type(FULLY_IF_CONV);
01725 }
01726
01727 } else {
01728 head -> Conv_Type(FULLY_IF_CONV);
01729 }
01730
01731 if ( succ1 -> Area_Type() == DOWNWARD_UNSUITABLE
01732 || ( succ2 && succ2 -> Area_Type() == DOWNWARD_UNSUITABLE))
01733 {
01734 if ( head -> Area_Type() == UPWARD_UNSUITABLE)
01735 {
01736 head -> Area_Type(UNSUITABLE);
01737 } else {
01738 head -> Area_Type(DOWNWARD_UNSUITABLE);
01739 }
01740 }
01741
01742
01743 head -> Combine_Blocks_With(succ1, &_m);
01744
01745 if ( type == IF_THEN_ELSE_TYPE )
01746 {
01747 head -> Combine_Blocks_With(succ2, &_m);
01748 }
01749
01750
01751 AREA_CONTAINER successors = succ1 -> Succ_Set();
01752 for (iter = successors.begin();
01753 iter != successors.end();
01754 iter++)
01755 {
01756 IF_CONV_AREA *succ_of_succ1 = *iter;
01757 if (tail && succ_of_succ1 == tail) continue;
01758
01759 head -> Add_Succ(succ_of_succ1, this);
01760 succ_of_succ1 -> Add_Pred(head, this);
01761 succ_of_succ1 -> Del_Pred(succ1, this);
01762 }
01763 if (type == SERIAL_TYPE)
01764 {
01765 head -> Del_Succ(succ1, this);
01766 }
01767
01768 if (type == IF_THEN_TYPE)
01769 {
01770 head -> Del_Succ(succ1, this);
01771 tail -> Del_Pred(succ1, this);
01772 }
01773
01774 if (type == IF_THEN_ELSE_TYPE)
01775 {
01776 AREA_CONTAINER successors = succ2 -> Succ_Set();
01777 for (iter = successors.begin();
01778 iter != successors.end();
01779 iter++)
01780 {
01781 IF_CONV_AREA* succ_of_succ2 = *iter;
01782 if (tail && succ_of_succ2 == tail)
01783 continue;
01784
01785 head -> Add_Succ(succ_of_succ2, this);
01786 succ_of_succ2 -> Add_Pred(head, this);
01787 succ_of_succ2 -> Del_Pred(succ2, this);
01788 }
01789 head -> Del_Succ(succ1, this);
01790 head -> Del_Succ(succ2, this);
01791 head -> Add_Succ(tail, this);
01792
01793 tail -> Del_Pred(succ1, this);
01794 tail -> Del_Pred(succ2, this);
01795 tail -> Add_Pred(head, this);
01796 }
01797
01798
01799 if (type == IF_THEN_ELSE_TYPE)
01800 {
01801 max_length1 =
01802 succ1 -> Cycled_Critical_Len() > succ2 -> Cycled_Critical_Len()?
01803 succ1 -> Cycled_Critical_Len():succ2 -> Cycled_Critical_Len();
01804 max_length2 =
01805 succ1 -> Critical_Len() > succ2 -> Critical_Len()?
01806 succ1 -> Critical_Len():succ2 -> Critical_Len();
01807 } else {
01808 max_length1 = succ1 -> Cycled_Critical_Len();
01809 max_length2 = succ1 -> Critical_Len() ;
01810 }
01811 head -> Cycled_Critical_Len(head-> Cycled_Critical_Len() + max_length1);
01812 head -> Critical_Len(head -> Critical_Len() + max_length2);
01813
01814
01815 area_list.erase(Find_Area(area_list, succ1));
01816 CXX_DELETE(succ1, &_m);
01817
01818 if (type == IF_THEN_ELSE_TYPE)
01819 {
01820 area_list.erase( Find_Area(area_list, succ2));
01821 CXX_DELETE(succ2, &_m);
01822 }
01823
01824 }
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 void
01845 IF_CONVERTOR::Select_Candidates (AREA_CONTAINER& area_list, BOOL forced)
01846 {
01847 IF_CONV_ALLOC temp_alloc(&_m);
01848
01849 AREA_CONTAINER cand_list(temp_alloc);
01850 AREA_CONTAINER::iterator iter;
01851
01852 BOOL reduced = TRUE;
01853 INT time = 0;
01854 while (reduced)
01855 {
01856
01857 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY)){
01858 fprintf(TFile," **** iteration %d ****\n", time);
01859 }
01860
01861 reduced = FALSE;
01862 for (iter = area_list.begin();
01863 iter!= area_list.end();
01864 iter++)
01865 {
01866 IF_CONV_AREA *area = *iter;
01867 cand_list.clear();
01868
01869 if ( Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
01870 {
01871 fprintf(TFile,
01872 " -- solving AREA%d: \n", area -> Area_Label());
01873 }
01874
01875
01876
01877 CFLOW_TYPE type = Detect_Type (area, cand_list, forced);
01878 if (type == NO_TYPE) continue;
01879
01880 if ( Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
01881 {
01882 fprintf(TFile, " Selected areas:");
01883 AREA_CONTAINER::iterator it;
01884 for (it = cand_list.begin();
01885 it != cand_list.end();
01886 it++)
01887 {
01888 fprintf(TFile, "%d ", (*it)->Area_Label());
01889 }
01890 fprintf(TFile,"\n");
01891 }
01892
01893
01894 if (type == SERIAL_TYPE ||
01895 Worth_If_Convert (cand_list, type, forced))
01896 {
01897 reduced = TRUE;
01898 }
01899 else {
01900 continue;
01901 }
01902 Reduce_By_Type(cand_list, type, area_list);
01903 }
01904 time++;
01905 }
01906 }
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947 void
01948 IF_CONVERTOR::Find_Start_Node(IF_CONV_AREA* area,
01949 BB* bb)
01950 {
01951 BB_PREDICATE_INFO *info = area -> Pred_Assign_Info(bb);
01952 Is_True( info != NULL,
01953 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
01954
01955 CNTL_DEP *cntl_info = area -> Cntl_Dep_Info();
01956 BB_SET *cds = cntl_info -> Cntl_Dep_Parents(bb);
01957
01958
01959
01960
01961 if (!IPFEC_Force_Para_Comp_Gen)
01962 {
01963 if (info -> Transitional() && BB_SET_Size(cds) == 1)
01964 {
01965 return;
01966 }
01967 }
01968
01969
01970 BB *cd;
01971
01972 FOR_ALL_BB_SET_members(cds, cd)
01973 {
01974 BB *sn = cd;
01975 if (!IPFEC_Force_Para_Comp_Gen && info -> Transitional())
01976 {
01977
01978
01979
01980
01981 info -> Start_Node(sn, cd);
01982 continue;
01983 }
01984 INT n = 0;
01985 while (n < MAX_NUM_PARA_CMP)
01986 {
01987 BB_PREDICATE_INFO *f = area -> Pred_Assign_Info(sn);
01988 Is_True( f != NULL,
01989 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(sn)));
01990
01991
01992
01993 if (!f -> Transitional()) break;
01994
01995
01996
01997
01998 BB_SET *cds_of_sn = cntl_info -> Cntl_Dep_Parents(sn);
01999 Is_True( cds_of_sn != NULL,
02000 ("Can't find cntl deps for BB%d.\n", BB_id(sn)));
02001
02002
02003
02004 if (BB_SET_Size(cds_of_sn) != 1) break;
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 if (BB_SET_Size(cds) > 1
02025 && !BB_SET_MemberP(cds, BB_SET_Choose(cds_of_sn)) )
02026 break;
02027
02028 sn = BB_SET_Choose(cds_of_sn);
02029 n ++;
02030 }
02031
02032 info -> Start_Node(sn, cd);
02033 }
02034 }
02035
02036 BOOL
02037 IF_CONVERTOR::Check_If_Gen_Useless_Predicate( BB_PREDICATE_INFO* info)
02038 {
02039
02040
02041 if ( info -> True_TN() || info -> False_TN())
02042 return false;
02043
02044 TN_CONTAINER set;
02045 set = info -> Or_TNs();
02046 if (!set.empty())
02047 return false;
02048 set = info -> And_TNs();
02049 if (!set.empty())
02050 return false;
02051 set = info -> Orcm_TNs();
02052 if (!set.empty())
02053 return false;
02054 set = info -> Andcm_TNs();
02055 if (!set.empty())
02056 return false;
02057
02058 return true;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075 void
02076 IF_CONVERTOR::Record_Para_Comp_Info(IF_CONV_AREA *area,
02077 BB *bb)
02078 {
02079 CNTL_DEP *cntl_info = area -> Cntl_Dep_Info();
02080 BB_PREDICATE_INFO *pred_info = area -> Pred_Assign_Info(bb);
02081 Is_True(pred_info != NULL,
02082 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
02083
02084 TN *p = pred_info -> Predicate();
02085 BB *entry = area -> Entry_BB();
02086
02087 BB_SET *cds = cntl_info -> Cntl_Dep_Parents(bb);
02088 BB_SET *true_edges = cntl_info -> True_Cntl_Dep_Parents(bb);
02089
02090
02091 if (!pred_info -> Has_Start_Node())
02092 {
02093 Is_True(BB_SET_Size(cds) <=1,("non-parallel-comparea-candidate "
02094 "can only has one control dependentor!\n"));
02095
02096 if (BB_SET_Size(cds) == 0) return;
02097 TN *true_tn = NULL;
02098 TN *false_tn = NULL;
02099 BB *bb_cd = BB_SET_Choose(cds);
02100 BB_PREDICATE_INFO *pred_info_of_cd = area -> Pred_Assign_Info(bb_cd);
02101 Is_True(pred_info != NULL,
02102 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb_cd)));
02103
02104 if (BB_SET_MemberP(true_edges, bb_cd))
02105 {
02106 pred_info_of_cd -> True_TN(p);
02107 } else {
02108 pred_info_of_cd -> False_TN(p);
02109 }
02110 return;
02111 }
02112
02113 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_CG))
02114 {
02115 char tmp_string[6]="";
02116 sprintf(tmp_string, "%d", BB_id(bb));
02117 Generate_Tlog("AIC", "parallel_compare_generation", (SRCPOS)0,
02118 tmp_string, "", "", "");
02119 }
02120
02121 if ( BB_SET_Size(cds) > 1)
02122 {
02123
02124
02125
02126 OPS ops = OPS_EMPTY;
02127 Exp_Pred_Set(p, True_TN, 0, &ops);
02128 hTN_MAP_Set(init_op_info, p, ops.first);
02129 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02130 {
02131 Print_OPS(&ops);
02132 }
02133
02134
02135
02136 OP *xfer_op;
02137 if (xfer_op = BB_xfer_op(entry))
02138 {
02139 BB_Insert_Ops_Before (entry, xfer_op, &ops);
02140 } else {
02141 BB_Append_Ops (entry, &ops);
02142 }
02143
02144
02145
02146 BB *cd;
02147 FOR_ALL_BB_SET_members(cds, cd)
02148 {
02149 BB_PREDICATE_INFO* info_of_cd = area -> Pred_Assign_Info(cd);
02150
02151 Is_True(info_of_cd != NULL,
02152 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(cd)));
02153
02154 if (BB_SET_MemberP(true_edges, cd))
02155 {
02156 info_of_cd -> Add_Or_TNs(p);
02157 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02158 {
02159 fPrint_TN(TFile, "add or %s ", p);
02160 fprintf(TFile,
02161 " into BB%d when solving BB%d\n", BB_id(cd), BB_id(bb));
02162 }
02163 } else {
02164 info_of_cd -> Add_Orcm_TNs(p);
02165 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02166 {
02167 fPrint_TN(TFile, "add orcm %s ", p);
02168 fprintf(TFile,
02169 " into BB%d when solving BB%d\n", BB_id(cd), BB_id(bb));
02170 }
02171 }
02172 }
02173 } else {
02174 Is_True( BB_SET_Size(cds) == 1,
02175 (" and-type node can only have one cd.\n"));
02176
02177
02178
02179
02180 p = Gen_Predicate_TN();
02181 pred_info -> Orig_Pred(pred_info -> Predicate());
02182 pred_info -> Predicate(p);
02183
02184 BB *cd = BB_SET_Choose(cds);
02185
02186
02187 OPS ops = OPS_EMPTY;
02188 Exp_Pred_Set(p, True_TN, 1, &ops);
02189 hTN_MAP_Set(init_op_info, p, ops.first);
02190 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02191 {
02192 Print_OPS(&ops);
02193 }
02194
02195 BB* start_node = pred_info -> Start_Node(cd);
02196 OP *xfer_op;
02197 if (xfer_op = BB_xfer_op(start_node))
02198 {
02199 BB_Insert_Ops_Before (start_node, xfer_op, &ops);
02200 } else {
02201 BB_Append_Ops (start_node, &ops);
02202 }
02203
02204 BB *sn = pred_info -> Start_Node(cd);
02205 BB_PREDICATE_INFO *info_of_cd;
02206 Is_True(info_of_cd != NULL,
02207 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(cd)));
02208
02209 BOOL is_start = false;
02210 while (!is_start)
02211 {
02212 is_start = (cd == sn);
02213 info_of_cd = area -> Pred_Assign_Info(cd);
02214
02215 if (BB_SET_MemberP(true_edges, cd))
02216 {
02217 info_of_cd -> Add_And_TNs(p);
02218 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02219 {
02220 fPrint_TN(TFile, "add and %s ", p);
02221 fprintf(TFile,
02222 " into BB%d when solving BB%d\n", BB_id(cd), BB_id(bb));
02223 }
02224 } else {
02225 info_of_cd -> Add_Andcm_TNs(p);
02226 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02227 {
02228 fPrint_TN(TFile, "add andcm %s ", p);
02229 fprintf(TFile,
02230 " into BB%d when solving BB%d\n", BB_id(cd), BB_id(bb));
02231 }
02232 }
02233 true_edges = cntl_info -> True_Cntl_Dep_Parents(cd);
02234 cds = cntl_info -> Cntl_Dep_Parents(cd);
02235 cd = BB_SET_Choose(cds);
02236 }
02237 }
02238 }
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275 void
02276 IF_CONVERTOR::Detect_Para_Comp(IF_CONV_AREA* area)
02277 {
02278
02279 BB_CONTAINER& bbs = area -> Blocks();
02280 CNTL_DEP *cntl_info = area -> Cntl_Dep_Info();
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02297 {
02298 fprintf(TFile, " Start to decide transitional!\n");
02299 }
02300 BB_CONTAINER::iterator bb_iter;
02301 BB *bb;
02302 for (bb_iter = bbs.begin();
02303 bb_iter != bbs.end();
02304 bb_iter++)
02305 {
02306 bb = *bb_iter;
02307 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02308 {
02309 fprintf(TFile, " -- solving BB%d:", BB_id(bb));
02310 }
02311
02312 if (BB_recovery(bb)) continue;
02313
02314 OP *br_op = BB_branch_op(bb);
02315 OP *cmp_op = NULL;
02316 if (br_op && OP_has_predicate(br_op))
02317 {
02318 TN *pred_tn = OP_opnd(br_op, OP_PREDICATE_OPND);
02319 vector<OP *> ops;
02320 cmp_op = TN_Defined_At_Op(pred_tn, br_op, &ops);
02321 }
02322
02323 OP *op;
02324 BOOL is_transitional = TRUE;
02325
02326 BB_SET* cd_children = BB_SET_Create_Empty(PU_BB_Count, &_m);
02327 cntl_info -> Cntl_Dep_Children(cd_children, bb, &_m);
02328 if (BB_SET_Size(cntl_info -> Cntl_Dep_Parents(bb)) ==0
02329 || BB_SET_Size(cd_children) == 0)
02330 {
02331 is_transitional = FALSE;
02332 } else if ( cmp_op && !Has_Para_Comp_Top(cmp_op)) {
02333 is_transitional =FALSE;
02334 } else {
02335 if ( !br_op || !cmp_op ) {
02336 is_transitional = FALSE;
02337 } else {
02338 FOR_ALL_BB_OPs_FWD(bb, op)
02339 {
02340 if ( op != br_op && op != cmp_op ) {
02341 is_transitional = FALSE;
02342 break;
02343 }
02344 }
02345 }
02346 }
02347
02348 if (IPFEC_Force_Para_Comp_Gen ||
02349 (is_transitional && IPFEC_Para_Comp_Gen))
02350 {
02351 BB_PREDICATE_INFO *pred_info = area -> Pred_Assign_Info(bb);
02352 Is_True(pred_info != NULL,
02353 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
02354
02355 pred_info -> Set_Transitional();
02356 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02357 {
02358 fprintf(TFile, " transitional \n");
02359 }
02360 } else {
02361 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02362 {
02363 fprintf(TFile, " not transitional \n");
02364 }
02365 }
02366
02367 }
02368
02369 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02370 {
02371 fprintf(TFile,
02372 " Start to find starting node and collect info of pred! \n");
02373 }
02374
02375
02376 BB_CONTAINER result;
02377 cntl_info -> Get_Post_Order(result, this);
02378 for (bb_iter = result.begin();
02379 bb_iter != result.end();
02380 bb_iter++)
02381 {
02382 bb = *bb_iter;
02383
02384 BB_PREDICATE_INFO *info = area -> Pred_Assign_Info(bb);
02385 Is_True(info != NULL,
02386 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
02387
02388 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02389 {
02390 fprintf(TFile, " -- solving BB%d:\n", BB_id(bb));
02391 }
02392
02393 if ( BB_recovery(bb)) continue;
02394 if (!info -> Eqv_Class_Head())
02395 {
02396 BB_PREDICATE_INFO *head_info =
02397 area -> Pred_Assign_Info(info -> Eqv_Class_Head_BB());
02398 info -> Orig_Pred( info -> Predicate() );
02399 info -> Predicate(head_info -> Predicate());
02400 continue;
02401 }
02402
02403
02404 BB_SET* cds = cntl_info -> Cntl_Dep_Parents(bb);
02405 Is_True( cds != NULL,
02406 ("Can't find cntl deps for BB%d.\n", BB_id(bb)));
02407
02408 BOOL cd_is_transitional = false;
02409 if (BB_SET_Size(cds) == 1)
02410 {
02411 BB* cd = BB_SET_Choose(cds);
02412 BB_PREDICATE_INFO *info_of_cd = area -> Pred_Assign_Info(cd);
02413 cd_is_transitional = info_of_cd -> Transitional();
02414 }
02415 if ( BB_SET_Size(cds) >1 || cd_is_transitional)
02416 Find_Start_Node(area,bb);
02417
02418
02419
02420 Record_Para_Comp_Info(area, bb);
02421 }
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441 void
02442 IF_CONVERTOR::Gen_Para_Comp (IF_CONV_AREA *area)
02443 {
02444 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02445 {
02446 area -> Print(TFile);
02447 }
02448 BB_CONTAINER& bbs = area -> Blocks();
02449 BB_CONTAINER::iterator bb_iter;
02450 BB *bb;
02451 for (bb_iter = bbs.begin();
02452 bb_iter != bbs.end();
02453 bb_iter++)
02454 {
02455 bb = *bb_iter;
02456
02457 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02458 {
02459 fprintf(TFile, " -- solving BB%d:\n", BB_id(bb));
02460 }
02461
02462 BB_PREDICATE_INFO *info = area -> Pred_Assign_Info(bb);
02463 Is_True( info != NULL,
02464 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
02465 if (BB_recovery(bb)) continue;
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477 OPS op_list = OPS_EMPTY;
02478
02479
02480 if (Check_If_Gen_Useless_Predicate(info)) continue;
02481
02482 OP *br_op = BB_branch_op(bb);
02483 OP *cmp_op = NULL;
02484 if (br_op && OP_has_predicate(br_op))
02485 {
02486 TN *pred_tn = OP_opnd(br_op, OP_PREDICATE_OPND);
02487 vector<OP *> ops;
02488 cmp_op = TN_Defined_At_Op(pred_tn, br_op, &ops);
02489 }
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503 TN *p1, *p2, *start_qp;
02504 TOP pred_top;
02505 TN *qp;
02506 COMPARE_TYPE type;
02507 while (Get_2_Pred_And_Erase(p1, p2, type, bb, info))
02508 {
02509 TN *qp1 = Get_Start_Node_Pred(p1, bb, area);
02510 TN* qp2 = NULL;
02511 if (p2 != True_TN)
02512 {
02513 qp2 = Get_Start_Node_Pred(p2, bb, area);
02514 }
02515 if (p2 == True_TN || qp1 == qp2)
02516 {
02517 pred_top = Get_Para_Comp_Top(cmp_op, type);
02518 qp = qp1;
02519 } else {
02520 pred_top = TOP_UNDEFINED;
02521 }
02522 if (pred_top == TOP_UNDEFINED)
02523 {
02524 TN *true_tn = NULL;
02525 TN *false_tn = NULL;
02526 Find_BB_Predicates(bb, true_tn, false_tn);
02527
02528 if (type == COMPARE_TYPE_or
02529 || type == COMPARE_TYPE_andcm
02530 || type == COMPARE_TYPE_or_andcm)
02531 {
02532 qp = true_tn ? true_tn : True_TN;
02533 } else if (type == COMPARE_TYPE_orcm
02534 || type == COMPARE_TYPE_and
02535 || type == COMPARE_TYPE_and_orcm)
02536 {
02537 qp = false_tn ? false_tn: True_TN;
02538 } else {
02539 Is_True(0, ("wrong compare type!\n"));
02540 }
02541 }
02542 Gen_Predicate_Assign(p1,p2, cmp_op, type, pred_top, qp,
02543 &op_list);
02544 }
02545
02546 OP* new_op;
02547 FOR_ALL_OPS_OPs_FWD((&op_list),new_op){
02548 Set_OP_cond_def_kind(new_op, OP_ALWAYS_COND_DEF);
02549 }
02550
02551 if (OPS_first(&op_list))
02552 {
02553 Is_True(br_op,
02554 ("parallel compare can only added into split bb.\n"));
02555
02556 BB_Insert_Ops(bb, br_op, &op_list, true);
02557 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
02558 {
02559 Print_OPS(&op_list);
02560 }
02561 }
02562 }
02563
02564 }
02565 TOP
02566 cmp_top_index[COMP_TOP_NUM] =
02567 { TOP_cmp_ne, TOP_cmp_ne_unc,
02568 TOP_cmp4_ne, TOP_cmp4_ne_unc,
02569 TOP_cmp_i_ne, TOP_cmp_i_ne_unc,
02570 TOP_cmp4_i_ne, TOP_cmp4_i_ne_unc,
02571 TOP_cmp4_ge, TOP_cmp4_ge_unc,
02572 TOP_cmp4_gt, TOP_cmp4_gt_unc,
02573 TOP_cmp4_le, TOP_cmp4_le_unc,
02574 TOP_cmp4_lt, TOP_cmp4_lt_unc,
02575 TOP_cmp_ge, TOP_cmp_ge_unc,
02576 TOP_cmp_gt, TOP_cmp_gt_unc,
02577 TOP_cmp_le, TOP_cmp_le_unc,
02578 TOP_cmp_lt, TOP_cmp_lt_unc,
02579 TOP_cmp4_i_eq, TOP_cmp4_i_eq_unc,
02580 TOP_cmp4_eq, TOP_cmp4_eq_unc,
02581 TOP_cmp_i_eq, TOP_cmp_i_eq_unc,
02582 TOP_cmp_eq, TOP_cmp_eq_unc
02583 };
02584 TOP
02585 para_comp_top[COMP_TOP_NUM][PARA_COMP_TYPE_NUM] = {
02586 { TOP_cmp_ne_or, TOP_cmp_ne_orcm , TOP_cmp_ne_and,
02587 TOP_cmp_ne_andcm, TOP_cmp_ne_or_andcm, TOP_cmp_ne_and_orcm },
02588 { TOP_cmp_ne_or, TOP_cmp_ne_orcm , TOP_cmp_ne_and,
02589 TOP_cmp_ne_andcm, TOP_cmp_ne_or_andcm, TOP_cmp_ne_and_orcm },
02590 { TOP_cmp4_ne_or, TOP_cmp4_ne_orcm, TOP_cmp4_ne_and,
02591 TOP_cmp4_ne_andcm, TOP_cmp4_ne_or_andcm, TOP_cmp4_ne_and_orcm },
02592 { TOP_cmp4_ne_or, TOP_cmp4_ne_orcm, TOP_cmp4_ne_and,
02593 TOP_cmp4_ne_andcm, TOP_cmp4_ne_or_andcm, TOP_cmp4_ne_and_orcm },
02594 { TOP_cmp_i_ne_or, TOP_cmp_i_ne_orcm, TOP_cmp_i_ne_and,
02595 TOP_cmp_i_ne_andcm, TOP_cmp_i_ne_or_andcm, TOP_cmp_i_ne_and_orcm },
02596 { TOP_cmp_i_ne_or, TOP_cmp_i_ne_orcm, TOP_cmp_i_ne_and,
02597 TOP_cmp_i_ne_andcm, TOP_cmp_i_ne_or_andcm, TOP_cmp_i_ne_and_orcm },
02598 { TOP_cmp4_i_ne_or, TOP_cmp4_i_ne_orcm, TOP_cmp4_i_ne_and,
02599 TOP_cmp4_i_ne_andcm, TOP_cmp4_i_ne_or_andcm, TOP_cmp4_i_ne_and_orcm },
02600 { TOP_cmp4_i_ne_or, TOP_cmp4_i_ne_orcm, TOP_cmp4_i_ne_and,
02601 TOP_cmp4_i_ne_andcm, TOP_cmp4_i_ne_or_andcm, TOP_cmp4_i_ne_and_orcm },
02602 { TOP_cmp4_ge_or, TOP_cmp4_ge_orcm, TOP_cmp4_ge_and,
02603 TOP_cmp4_ge_andcm, TOP_cmp4_ge_or_andcm, TOP_cmp4_ge_and_orcm },
02604 { TOP_cmp4_ge_or, TOP_cmp4_ge_orcm, TOP_cmp4_ge_and,
02605 TOP_cmp4_ge_andcm, TOP_cmp4_ge_or_andcm, TOP_cmp4_ge_and_orcm },
02606 { TOP_cmp4_gt_or, TOP_cmp4_gt_orcm, TOP_cmp4_gt_and,
02607 TOP_cmp4_gt_andcm, TOP_cmp4_gt_or_andcm, TOP_cmp4_gt_and_orcm },
02608 { TOP_cmp4_gt_or, TOP_cmp4_gt_orcm, TOP_cmp4_gt_and,
02609 TOP_cmp4_gt_andcm, TOP_cmp4_gt_or_andcm, TOP_cmp4_gt_and_orcm },
02610 { TOP_cmp4_le_or, TOP_cmp4_le_orcm, TOP_cmp4_le_and,
02611 TOP_cmp4_le_andcm, TOP_cmp4_le_or_andcm, TOP_cmp4_le_and_orcm },
02612 { TOP_cmp4_le_or, TOP_cmp4_le_orcm, TOP_cmp4_le_and,
02613 TOP_cmp4_le_andcm, TOP_cmp4_le_or_andcm, TOP_cmp4_le_and_orcm },
02614 { TOP_cmp4_lt_or, TOP_cmp4_lt_orcm, TOP_cmp4_lt_and,
02615 TOP_cmp4_lt_andcm, TOP_cmp4_lt_or_andcm, TOP_cmp4_lt_and_orcm },
02616 { TOP_cmp4_lt_or, TOP_cmp4_lt_orcm, TOP_cmp4_lt_and,
02617 TOP_cmp4_lt_andcm, TOP_cmp4_lt_or_andcm, TOP_cmp4_lt_and_orcm },
02618 { TOP_cmp_ge_or, TOP_cmp_ge_orcm, TOP_cmp_ge_and,
02619 TOP_cmp_ge_andcm, TOP_cmp_ge_or_andcm, TOP_cmp_ge_and_orcm },
02620 { TOP_cmp_ge_or, TOP_cmp_ge_orcm, TOP_cmp_ge_and,
02621 TOP_cmp_ge_andcm, TOP_cmp_ge_or_andcm, TOP_cmp_ge_and_orcm },
02622 { TOP_cmp_gt_or, TOP_cmp_gt_orcm, TOP_cmp_gt_and,
02623 TOP_cmp_gt_andcm, TOP_cmp_gt_or_andcm, TOP_cmp_gt_and_orcm },
02624 { TOP_cmp_gt_or, TOP_cmp_gt_orcm, TOP_cmp_gt_and,
02625 TOP_cmp_gt_andcm, TOP_cmp_gt_or_andcm, TOP_cmp_gt_and_orcm },
02626 { TOP_cmp_le_or, TOP_cmp_le_orcm, TOP_cmp_le_and,
02627 TOP_cmp_le_andcm, TOP_cmp_le_or_andcm, TOP_cmp_le_and_orcm },
02628 { TOP_cmp_le_or, TOP_cmp_le_orcm, TOP_cmp_le_and,
02629 TOP_cmp_le_andcm, TOP_cmp_le_or_andcm, TOP_cmp_le_and_orcm },
02630 { TOP_cmp_lt_or, TOP_cmp_lt_orcm, TOP_cmp_lt_and,
02631 TOP_cmp_lt_andcm, TOP_cmp_lt_or_andcm, TOP_cmp_lt_and_orcm },
02632 { TOP_cmp_lt_or, TOP_cmp_lt_orcm, TOP_cmp_lt_and,
02633 TOP_cmp_lt_andcm, TOP_cmp_lt_or_andcm, TOP_cmp_lt_and_orcm },
02634 { TOP_cmp4_i_eq_or, TOP_cmp4_i_eq_orcm, TOP_cmp4_i_eq_and,
02635 TOP_cmp4_i_eq_andcm, TOP_cmp4_i_eq_or_andcm, TOP_cmp4_i_eq_and_orcm },
02636 { TOP_cmp4_i_eq_or, TOP_cmp4_i_eq_orcm, TOP_cmp4_i_eq_and,
02637 TOP_cmp4_i_eq_andcm, TOP_cmp4_i_eq_or_andcm, TOP_cmp4_i_eq_and_orcm },
02638 { TOP_cmp4_eq_or, TOP_cmp4_eq_orcm, TOP_cmp4_eq_and,
02639 TOP_cmp4_eq_andcm, TOP_cmp4_eq_or_andcm, TOP_cmp4_eq_and_orcm },
02640 { TOP_cmp4_eq_or, TOP_cmp4_eq_orcm, TOP_cmp4_eq_and,
02641 TOP_cmp4_eq_andcm, TOP_cmp4_eq_or_andcm, TOP_cmp4_eq_and_orcm },
02642 { TOP_cmp_i_eq_or, TOP_cmp_i_eq_orcm, TOP_cmp_i_eq_and,
02643 TOP_cmp_i_eq_andcm, TOP_cmp_i_eq_or_andcm, TOP_cmp_i_eq_and_orcm },
02644 { TOP_cmp_i_eq_or, TOP_cmp_i_eq_orcm, TOP_cmp_i_eq_and,
02645 TOP_cmp_i_eq_andcm, TOP_cmp_i_eq_or_andcm, TOP_cmp_i_eq_and_orcm },
02646 { TOP_cmp_eq_or, TOP_cmp_eq_orcm, TOP_cmp_eq_and,
02647 TOP_cmp_eq_andcm, TOP_cmp_eq_or_andcm, TOP_cmp_eq_and_orcm },
02648 { TOP_cmp_eq_or, TOP_cmp_eq_orcm, TOP_cmp_eq_and,
02649 TOP_cmp_eq_andcm, TOP_cmp_eq_or_andcm, TOP_cmp_eq_and_orcm }
02650 };
02651 BOOL
02652 IF_CONVERTOR::Has_Para_Comp_Top(OP* cmp_op) {
02653
02654 if (OP_flop(cmp_op)) {
02655 return false;
02656 }
02657
02658 TOP cmp_top = OP_code(cmp_op);
02659 if (OP_opnd(cmp_op, 1) != Zero_TN && OP_opnd(cmp_op, 2) != Zero_TN)
02660 {
02661 switch (cmp_top)
02662 {
02663 case TOP_cmp_ne:
02664 case TOP_cmp4_ne:
02665 case TOP_cmp_i_ne:
02666 case TOP_cmp4_i_ne:
02667 case TOP_cmp4_i_eq:
02668 case TOP_cmp4_eq:
02669 case TOP_cmp_i_eq:
02670 case TOP_cmp_eq:
02671 case TOP_cmp_ne_unc:
02672 case TOP_cmp4_ne_unc:
02673 case TOP_cmp_i_ne_unc:
02674 case TOP_cmp4_i_ne_unc:
02675 case TOP_cmp4_i_eq_unc:
02676 case TOP_cmp4_eq_unc:
02677 case TOP_cmp_i_eq_unc:
02678 case TOP_cmp_eq_unc:
02679 break;
02680 default:
02681 return false;
02682 }
02683 }
02684 return false;
02685 }
02686 TOP
02687 IF_CONVERTOR::Get_Para_Comp_Top(OP* cmp_op, COMPARE_TYPE ctype)
02688 {
02689 if ( !Has_Para_Comp_Top(cmp_op) )
02690 return TOP_UNDEFINED;
02691
02692 TOP cmp_top = OP_code(cmp_op);
02693 INT index = 0;
02694 while (index < COMP_TOP_NUM)
02695 {
02696 if ( cmp_top == cmp_top_index[index])
02697 break;
02698 index++;
02699 }
02700 if (index >= COMP_TOP_NUM)
02701 return TOP_UNDEFINED;
02702 INT id = (int)ctype;
02703 Is_True( id>=1 && id <= PARA_COMP_TYPE_NUM, ("no such a ctype!"));
02704
02705 return para_comp_top[index][id-1];
02706 }
02707
02708
02709 TN*
02710 IF_CONVERTOR::Get_1_Pred_And_Erase(TN_CONTAINER& tn_set)
02711 {
02712 TN_CONTAINER::iterator iter;
02713 TN *p1; iter = tn_set.begin();
02714 p1 = *iter;
02715 tn_set.erase(iter);
02716 return p1;
02717 }
02718
02719 BOOL
02720 IF_CONVERTOR::Get_2_Pred_And_Erase(TN*& p1,
02721 TN*& p2,
02722 COMPARE_TYPE& type,
02723 BB* bb,
02724 BB_PREDICATE_INFO *info)
02725 {
02726
02727 TN_CONTAINER& tn_set1 = info -> And_TNs();
02728 TN_CONTAINER& tn_set2 = info -> Orcm_TNs();
02729 if (tn_set1.size() >=2)
02730 {
02731 p1 = Get_1_Pred_And_Erase(tn_set1);
02732 p2 = Get_1_Pred_And_Erase(tn_set1);
02733 type = COMPARE_TYPE_and;
02734 return true;
02735 }
02736
02737 if ( tn_set1.size())
02738 {
02739 p1 = Get_1_Pred_And_Erase(tn_set1);
02740
02741 if (tn_set2.size())
02742 {
02743 p2 = Get_1_Pred_And_Erase(tn_set2);
02744 type = COMPARE_TYPE_and_orcm;
02745 return true;
02746 } else {
02747 p2 = True_TN;
02748 type = COMPARE_TYPE_and;
02749 return true;
02750 }
02751 }
02752
02753 if (tn_set2.size() >=1)
02754 {
02755 p1 = Get_1_Pred_And_Erase(tn_set2);
02756
02757 if (tn_set2.size())
02758 {
02759 p2 = Get_1_Pred_And_Erase(tn_set2);
02760 } else {
02761 p2 = True_TN;
02762 }
02763 type = COMPARE_TYPE_orcm;
02764 return true;
02765 }
02766
02767
02768 TN_CONTAINER& tn_set3 = info -> Or_TNs();
02769 TN_CONTAINER& tn_set4 = info -> Andcm_TNs();
02770 if (tn_set3.size() >=2)
02771 {
02772 p1 = Get_1_Pred_And_Erase(tn_set3);
02773 p2 = Get_1_Pred_And_Erase(tn_set3);
02774 type = COMPARE_TYPE_or;
02775 return true;
02776 }
02777
02778 if ( tn_set3.size())
02779 {
02780 p1 = Get_1_Pred_And_Erase(tn_set3);
02781
02782 if (tn_set4.size())
02783 {
02784 p2 = Get_1_Pred_And_Erase(tn_set4);
02785 type = COMPARE_TYPE_or_andcm;
02786 return true;
02787 } else {
02788 p2 = True_TN;
02789 type = COMPARE_TYPE_or;
02790 return true;
02791 }
02792 }
02793
02794 if ( tn_set4.size() >=1)
02795 {
02796 p1 = Get_1_Pred_And_Erase(tn_set4);
02797 if ( tn_set4.size())
02798 {
02799 p2 = Get_1_Pred_And_Erase(tn_set4);
02800 } else {
02801 p2 = True_TN;
02802 }
02803 type = COMPARE_TYPE_andcm;
02804 return true;
02805 }
02806 return false;
02807 }
02808
02809 TN*
02810 IF_CONVERTOR:: Get_Start_Node_Pred(TN *pred,
02811 BB *present_solving_bb,
02812 IF_CONV_AREA *area)
02813 {
02814 BB *bb_of_pred;
02815 BB_PREDICATE_INFO *info = NULL;
02816 BB_CONTAINER& bbs = area -> Blocks();
02817 BB_CONTAINER::iterator bb_iter;
02818 BB *bb;
02819 for (bb_iter = bbs.begin();
02820 bb_iter != bbs.end();
02821 bb_iter++)
02822 {
02823 bb = *bb_iter;
02824 info = area -> Pred_Assign_Info(bb);
02825 if ( pred == info -> Predicate())
02826 {
02827 bb_of_pred = bb;
02828 break;
02829 }
02830 }
02831 Is_True( info, (" Generate useless predicate assignment.\n"));
02832
02833 TN *result = NULL;
02834 CNTL_DEP *cd_info = area -> Cntl_Dep_Info();
02835 BB_SET *cds = cd_info -> Cntl_Dep_Parents(bb_of_pred);
02836 if (BB_SET_Size(cds) == 1)
02837 {
02838 BB* cd = BB_SET_Choose(cds);
02839 BB* start_node = info -> Start_Node(cd);
02840 result = area -> Pred_Assign_Info(start_node) -> Predicate();
02841 } else {
02842 Is_True(BB_SET_MemberP(cds, present_solving_bb),
02843 ("predicate assign holder must in cds"));
02844 BB* start_node = info -> Start_Node(present_solving_bb);
02845 result = area -> Pred_Assign_Info(start_node) -> Predicate();
02846
02847 }
02848 if ( !result )
02849 result = True_TN;
02850 return result;
02851 }
02852 void
02853 IF_CONVERTOR::Gen_Predicate_Assign(TN* result1,
02854 TN *result2,
02855 OP* cmp_op,
02856 COMPARE_TYPE ctype,
02857 TOP pred_top,
02858 TN *qual_pred,
02859 OPS* ops)
02860 {
02861 if ( pred_top != TOP_UNDEFINED) {
02862 Build_OP(pred_top,
02863 result1,
02864 result2,
02865 qual_pred,
02866 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
02867 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
02868 ops);
02869 } else {
02870 TOP top;
02871 switch (ctype) {
02872 case COMPARE_TYPE_or:
02873 top = TOP_cmp_eq_or;
02874 break;
02875 case COMPARE_TYPE_andcm:
02876 top = TOP_cmp_eq_andcm;
02877 break;
02878 case COMPARE_TYPE_or_andcm:
02879 top = TOP_cmp_eq_or_andcm;
02880 break;
02881 case COMPARE_TYPE_and:
02882 top = TOP_cmp_ne_and;
02883 break;
02884 case COMPARE_TYPE_orcm:
02885 top = TOP_cmp_ne_orcm;
02886 break;
02887 case COMPARE_TYPE_and_orcm:
02888 top = TOP_cmp_ne_and_orcm;
02889 break;
02890 default:
02891 Is_True(0,("Illegal Compare Type.\n"));
02892 }
02893 Build_OP(top, result1, result2, qual_pred, Zero_TN, Zero_TN,
02894 ops);
02895 }
02896 }
02897 TN*
02898 Predicate_Of_Succ(BB *bb, BB * succ, BB *fall_thru, BB_PREDICATE_INFO *info) {
02899 TN *pp = NULL;
02900 if ( BB_succs_len(bb) == 1 ) {
02901 pp = info -> Predicate();
02902 }
02903 else if (BB_succs_len(bb) == 2) {
02904 TN *first_pred = NULL;
02905 TN *second_pred = NULL;
02906 Find_BB_Predicates(bb, first_pred, second_pred);
02907 Is_True(first_pred && second_pred,
02908 (" lack of a predicate!\n"));
02909
02910 OP *br = BB_branch_op(bb);
02911 Is_True(br, (" two-successor bb must have br\n"));
02912
02913 if (( first_pred == OP_opnd(br, OP_PREDICATE_OPND)
02914 && succ != fall_thru)
02915 || ( second_pred == OP_opnd(br, OP_PREDICATE_OPND)
02916 && succ == fall_thru))
02917 {
02918 pp = first_pred;
02919 }
02920 else {
02921 pp = second_pred;
02922 }
02923 }
02924
02925 return pp;
02926 }
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938 BOOL
02939 IF_CONVERTOR::Insert_Predicate(IF_CONV_AREA *area)
02940 {
02941
02942
02943
02944
02945
02946
02947
02948
02949 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02950 {
02951 fprintf(TFile, "\n Start to assign predicates!\n");
02952 }
02953
02954
02955
02956
02957 BB_SET *equal_classes = BB_SET_Create_Empty(PU_BB_Count, &_m);
02958 CNTL_DEP *cd_info = area -> Cntl_Dep_Info();
02959 BB_CONTAINER& bbs = area -> Blocks();
02960
02961 BB_CONTAINER::iterator bb_iter;
02962 BB *bb;
02963 for (bb_iter = bbs.begin();
02964 bb_iter != bbs.end();
02965 bb_iter++)
02966 {
02967 bb = *bb_iter;
02968 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02969 {
02970 fprintf(TFile, " -- solving BB%d: ", BB_id(bb));
02971 }
02972
02973 if ( BB_recovery(bb))
02974 {
02975 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
02976 {
02977 fprintf(TFile, " it is a recovery bb.\n");
02978 }
02979 continue;
02980 }
02981
02982 BB_PREDICATE_INFO *pred_info = area ->Pred_Assign_Info(bb);
02983
02984 BB_SET *cds_of_bb = cd_info -> Cntl_Dep_Parents(bb);
02985 BB_SET *te_of_bb = cd_info -> True_Cntl_Dep_Parents(bb);
02986
02987
02988
02989
02990 BOOL find_ec = false;
02991 BB *ec;
02992 FOR_ALL_BB_SET_members(equal_classes, ec)
02993 {
02994
02995 BB_SET *cds_of_ec = cd_info -> Cntl_Dep_Parents(ec);
02996 Is_True( cds_of_ec != NULL,
02997 ("Can't find cntl deps for BB%d.\n", BB_id(ec)));
02998
02999 BB_SET *te_of_ec = cd_info -> True_Cntl_Dep_Parents(ec);
03000 Is_True( te_of_ec != NULL,
03001 ("Can't find true edges for BB%d.\n", BB_id(ec)));
03002
03003 if (BB_SET_EqualP(cds_of_bb, cds_of_ec)
03004 &&BB_SET_EqualP(te_of_bb, te_of_ec))
03005 {
03006 BB_PREDICATE_INFO *pred_of_ec =
03007 area ->Pred_Assign_Info (ec);
03008 Is_True(pred_of_ec != NULL,
03009 ("Can't find BB_PREDICATE_INFO for BB%d.\n",
03010 BB_id(bb)));
03011
03012 pred_info -> Predicate(pred_of_ec -> Predicate());
03013 pred_info -> Eqv_Class_Head_BB(ec);
03014
03015 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03016 {
03017 fPrint_TN(TFile,
03018 " got(share): %s", pred_of_ec -> Predicate());
03019 }
03020 find_ec = true;
03021 break;
03022 }
03023 }
03024
03025 if (!find_ec)
03026 {
03027 equal_classes = BB_SET_Union1D(equal_classes, bb, &_m);
03028 pred_info -> Set_Eqv_Class_Head();
03029
03030
03031 INT num_deps = BB_SET_Size(cds_of_bb);
03032
03033 if (num_deps == 1)
03034 {
03035
03036
03037 TN *true_tn = NULL;
03038 TN *false_tn = NULL;
03039 BB *bb_cd = BB_SET_Choose(cds_of_bb);
03040 Find_BB_Predicates(bb_cd, true_tn, false_tn);
03041
03042
03043 if (BB_SET_MemberP(te_of_bb, bb_cd))
03044 {
03045 pred_info ->Predicate(true_tn);
03046 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03047 {
03048 fPrint_TN(TFile, " got: %s\n", true_tn);
03049 }
03050 } else {
03051 pred_info ->Predicate(false_tn);
03052 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03053 {
03054 fPrint_TN(TFile, " got: %s\n", false_tn);
03055 }
03056 }
03057 } else if (num_deps > 1)
03058 {
03059
03060 TN *pred_tn;
03061 pred_tn = Gen_Predicate_TN();
03062 pred_info -> Predicate(pred_tn);
03063 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03064 {
03065 fPrint_TN(TFile, " got: %s\n", pred_tn);
03066 }
03067 }
03068 }
03069 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03070 {
03071 fprintf(TFile, "\n");
03072 }
03073 }
03074
03075
03076
03077
03078
03079 for (bb_iter = bbs.begin();
03080 bb_iter != bbs.end();
03081 bb_iter++)
03082 {
03083 bb = *bb_iter;
03084 BB* fall_thru = BB_Fall_Thru_Successor(bb);
03085
03086 BBLIST *succ_bl;
03087 FOR_ALL_BB_SUCCS(bb, succ_bl)
03088 {
03089 BB* succ = BBLIST_item(succ_bl);
03090 if (!Is_BB_Container_Member(bbs, succ)
03091 || Regional_Cfg_Node(bb) -> First_Succ() == NULL)
03092 {
03093
03094 EXIT_TARGET_INFO *tgt = area -> Exit_Target(succ);
03095 BB_PREDICATE_INFO *info = area -> Pred_Assign_Info(bb);
03096 TN *pp = Predicate_Of_Succ(bb, succ, fall_thru, info);
03097 if ( tgt != NULL)
03098 {
03099 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03100 {
03101 fprintf(TFile, " BB%d target: BB%d ",
03102 BB_id(bb), BB_id(succ));
03103 fPrint_TN(TFile, " %s => main \n", pp);
03104 }
03105 if ( IPFEC_Combine_Exit )
03106 {
03107 Is_True(tgt -> Main_Predicate().size() == 1,
03108 ("Wrong number of main predicate!\n"));
03109 TN *old_main = *(tgt -> Main_Predicate().begin());
03110 tgt -> Add_Aux_Predicate(old_main);
03111 tgt -> Del_Main_Predicate(old_main);
03112 }
03113 tgt -> Add_Main_Predicate(pp);
03114 } else {
03115 area -> Add_Exit_Target(succ, pp, &_m);
03116 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03117 {
03118 fprintf(TFile, " BB%d target(new): BB%d ",
03119 BB_id(bb), BB_id(succ));
03120 fPrint_TN(TFile, " %s => main \n", pp);
03121 }
03122 }
03123 }
03124 }
03125 }
03126
03127
03128
03129
03130 INT exit_num = 0;
03131 INT inner_br_num = 0;
03132 for (bb_iter = bbs.begin();
03133 bb_iter != bbs.end();
03134 bb_iter++)
03135 {
03136 bb = *bb_iter;
03137
03138 BOOL all_targets_hidden = TRUE;
03139 BOOL has_inner_succ = FALSE;
03140 BB* fall_thru = BB_Fall_Thru_Successor(bb);
03141
03142 BBLIST *succ_bl;
03143 FOR_ALL_BB_SUCCS(bb, succ_bl)
03144 {
03145 BB* succ = BBLIST_item(succ_bl);
03146 if (!Is_BB_Container_Member(bbs, succ)
03147 || Regional_Cfg_Node(bb) -> First_Succ() == NULL)
03148 {
03149
03150 EXIT_TARGET_INFO *tgt = area -> Exit_Target(succ);
03151 BB_PREDICATE_INFO *info = area -> Pred_Assign_Info(bb);
03152
03153 TN *pp = Predicate_Of_Succ(bb, succ, fall_thru, info);
03154 Is_True(tgt, ("exit must have exit info.!\n"));
03155
03156 if ( tgt -> Is_Main_Predicate(pp))
03157 {
03158 all_targets_hidden = FALSE;
03159 }
03160 } else {
03161 has_inner_succ = TRUE;
03162 }
03163 }
03164
03165 if (! all_targets_hidden) exit_num ++;
03166 if ( has_inner_succ && BB_succs_len(bb) > 1 )
03167 {
03168 inner_br_num++;
03169 }
03170 }
03171
03172 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03173 {
03174 fprintf(TFile, "\n Area_%d: exit_num : %d vs. br_num : %d\n",
03175 area -> Area_Label(), exit_num, inner_br_num);
03176 }
03177 if ( (exit_num > inner_br_num) && !IPFEC_Force_If_Conv) return FALSE;
03178
03179
03180 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
03181 {
03182 fprintf(TFile, "\n Start to detect parallel compare!\n");
03183 }
03184
03185
03186 Detect_Para_Comp(area);
03187
03188 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
03189 {
03190 fprintf(TFile, "\n Start to generate parallel compare!\n");
03191 }
03192
03193
03194 Gen_Para_Comp(area);
03195 return TRUE;
03196 }
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209 void
03210 IF_CONVERTOR::Merge_Area(IF_CONV_AREA *area)
03211 {
03212 BB_SET *hold_bbs = BB_SET_Create_Empty(PU_BB_Count, &_m);
03213 BB_SET *area_bb_set = BB_SET_Create_Empty(PU_BB_Count, &_m);
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224 BB_CONTAINER& bbs = area -> Blocks();
03225 BB_CONTAINER::iterator bb_iter;
03226 BB *bb;
03227 BB *last_bb = NULL;
03228
03229 INT exit_num = 0;
03230 for (bb_iter = bbs.begin();
03231 bb_iter != bbs.end();
03232 bb_iter++)
03233 {
03234 bb = *bb_iter;
03235 area_bb_set = BB_SET_Union1D(area_bb_set, bb, &_m);
03236 BBLIST *succ_bl;
03237 FOR_ALL_BB_SUCCS(bb, succ_bl)
03238 {
03239 BB* succ = BBLIST_item(succ_bl);
03240 if (!Is_BB_Container_Member(bbs, succ))
03241 {
03242 exit_num++;
03243 break;
03244 }
03245 }
03246 last_bb =bb;
03247 }
03248 INT last_bb_type = 0;
03249 for (bb_iter = bbs.begin();
03250 bb_iter != bbs.end();
03251 bb_iter++)
03252 {
03253 bb = *bb_iter;
03254 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
03255 {
03256 fprintf(TFile," -- solving BB%d:\n", BB_id(bb));
03257 }
03258
03259 if ( BB_recovery(bb))
03260 {
03261 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03262 {
03263 fprintf(TFile, " (recovery bb)");
03264 }
03265 continue;
03266 }
03267 CNTL_DEP *cntl_info = area -> Cntl_Dep_Info();
03268 BB_SET *set = cntl_info -> Cntl_Dep_Parents(bb);
03269 Is_True( cntl_info != NULL,
03270 ("Can't find cntl_info for BB%d.\n", BB_id(bb)));
03271
03272 BB_PREDICATE_INFO *pred_info = area -> Pred_Assign_Info (bb);
03273 Is_True( pred_info != NULL,
03274 ("Can't find BB_PREDICATE_INFO for BB%d.\n", BB_id(bb)));
03275 TN *pred = pred_info -> Predicate();
03276 TN *orig_pred = pred_info -> Orig_Pred()?pred_info -> Orig_Pred():pred;
03277
03278 if (IPFEC_Disable_Merge_BB)
03279 {
03280 Predicate_Block(bb, pred, area_bb_set);
03281 continue;
03282 }
03283
03284
03285 if (pred)
03286 {
03287 float f = BB_freq(bb);
03288 hTN_MAPf_Set(frequency_of_predicates, pred, f);
03289 }
03290
03291 BB_MERGE_TYPE bb_type = Classify_BB(bb, area);
03292
03293 BBLIST *bl;
03294 BB *pred_bb = NULL;
03295 if (bb == area -> Entry_BB())
03296 {
03297 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03298 {
03299 fprintf(TFile, " (entry) ");
03300 }
03301 } else {
03302 BOOL has_recovery_pred = false;
03303 BBLIST *pred_bl;
03304 FOR_ALL_BB_PREDS(bb, pred_bl)
03305 {
03306 if (BB_recovery(BBLIST_item(pred_bl)))
03307 {
03308 has_recovery_pred = true;
03309 break;
03310 }
03311 }
03312
03313 if ( !has_recovery_pred) {
03314 Is_True(BB_preds_len(bb) == 1,
03315 ("one bb only has one predecessor during merging!\n"));
03316 bl = BB_preds(bb);
03317 pred_bb = BBLIST_item(bl);
03318 } else {
03319 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03320 {
03321 fprintf(TFile, " => it is successor of recovery bb.\n");
03322 }
03323 }
03324 }
03325
03326
03327
03328
03329 BB_SET* bb_to_solve = BB_SET_Create_Empty(PU_BB_Count, &_m);
03330 BB *succ_bb_of_pred;
03331
03332 if (pred_bb && BB_succs_len(pred_bb) > 1)
03333 {
03334
03335 FOR_ALL_BB_SUCCS(pred_bb, bl)
03336 {
03337 succ_bb_of_pred = BBLIST_item(bl);
03338 if (succ_bb_of_pred != bb )
03339 {
03340 if (Is_BB_Container_Member(bbs, succ_bb_of_pred))
03341 {
03342 bb_to_solve = BB_SET_Union1D(bb_to_solve,
03343 succ_bb_of_pred, &_m);
03344 }
03345
03346 }
03347 }
03348 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03349 {
03350 BB* bb_tmp;
03351 fprintf(TFile, " (pred_bb:%d) ", BB_id(pred_bb));
03352 fprintf(TFile, " (bb_to_solve:");
03353 FOR_ALL_BB_SET_members(bb_to_solve, bb_tmp)
03354 {
03355 fprintf(TFile, " BB%d, ", BB_id(bb_tmp));
03356 }
03357 fprintf(TFile, ") ");
03358 }
03359 }
03360
03361 BOOL can_be_merged_into = FALSE;
03362 BB *fall_thru = BB_Fall_Thru_Successor(bb);
03363 BB *fall_thru_goto = NULL;
03364
03365 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03366 {
03367 Print_BB_Merge_Type(bb_type, TFile);
03368 }
03369 switch ( bb_type) {
03370 case CASE_ALL_IN_AREA:
03371 {
03372
03373 BB_Remove_Branch(bb);
03374 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03375 {
03376 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03377 }
03378 can_be_merged_into = TRUE;
03379 break;
03380 }
03381
03382 case CASE_CALL_IN:
03383 {
03384 break;
03385 }
03386 case CASE_CALL_OUT:
03387 {
03388 Is_True(BB_succs_len(bb) == 1,
03389 ("here call-inst can only have one succ!\n"));
03390 bl = BB_succs(bb);
03391 BB* exit_target = BBLIST_item(bl);
03392
03393 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(exit_target);
03394 BOOL is_main_exit = tgt_info -> Is_Main_Predicate(orig_pred);
03395 tgt_info -> Update_Predicate(orig_pred, pred);
03396
03397 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03398 {
03399 if ( is_main_exit )
03400 {
03401 fprintf(TFile,
03402 "\n exit-target(main): BB%d ",
03403 BB_id(exit_target));
03404 } else {
03405 fprintf(TFile,
03406 "\n exit-target(aux): BB%d ",
03407 BB_id(exit_target));
03408 }
03409 }
03410
03411
03412
03413
03414
03415
03416
03417 if ( is_main_exit &&
03418 (BB_SET_Size(bb_to_solve)
03419 || tgt_info -> Aux_Predicates().size()))
03420 {
03421
03422 REGIONAL_CFG* cfg = Home_Region(bb) -> Regional_Cfg();
03423 fall_thru = exit_target;
03424
03425 fall_thru_goto = RGN_Gen_And_Insert_BB(bb, fall_thru, cfg);
03426 Add_Goto_Op(fall_thru_goto, fall_thru);
03427
03428
03429
03430 Set_Prob(bb, fall_thru_goto, 1.0);
03431 BB_freq(fall_thru_goto) = BB_freq(bb);
03432
03433 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03434 {
03435 fprintf(TFile, " fall-thru-succ: BB%d\n",
03436 BB_id(fall_thru));
03437 fprintf(TFile, " gen fall-thru-goto: BB%d.\n",
03438 BB_id(fall_thru_goto));
03439 }
03440
03441 Make_Branch_Conditional(fall_thru_goto);
03442 Predicate_Block(fall_thru_goto, pred, area_bb_set);
03443
03444 Move_BB(fall_thru_goto, bb);
03445 GRA_LIVE_Compute_Liveness_For_BB(fall_thru_goto);
03446
03447 if (tgt_info -> Aux_Predicates().size()){
03448 OP *br = BB_branch_op(fall_thru_goto);
03449
03450 tgt_info -> Assign_Aux_Predicates(fall_thru_goto, br);
03451 }
03452 }
03453
03454 if (!is_main_exit) {
03455 RGN_Unlink_Pred_Succ(bb, exit_target);
03456 }
03457 break;
03458 }
03459 case CASE_UNCOND_BR:
03460 {
03461 Is_True(BB_succs_len(bb) == 1,
03462 ("here uncond-br can only have one succ!\n"));
03463 bl = BB_succs(bb);
03464 BB* exit_target = BBLIST_item(bl);
03465
03466 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(exit_target);
03467 BOOL is_main_exit = tgt_info -> Is_Main_Predicate(orig_pred);
03468 tgt_info -> Update_Predicate(orig_pred, pred);
03469
03470 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03471 {
03472 if ( is_main_exit )
03473 {
03474 fprintf(TFile,
03475 "\n exit-target(main): BB%d ",
03476 BB_id(exit_target));
03477 } else {
03478 fprintf(TFile,
03479 "\n exit-target(aux): BB%d ",
03480 BB_id(exit_target));
03481 }
03482 }
03483
03484 if (BB_SET_Size(set))
03485 {
03486 Make_Branch_Conditional(bb);
03487 }
03488 if ( is_main_exit)
03489 {
03490 OP* br = BB_branch_op(bb);
03491 Is_True(br, ("uncond-br must has a br-op!\n"));
03492 tgt_info -> Assign_Aux_Predicates(bb, br);
03493
03494 } else {
03495 BB_Remove_Branch(bb);
03496 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03497 {
03498 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03499 }
03500 can_be_merged_into = TRUE;
03501 RGN_Unlink_Pred_Succ(bb, exit_target);
03502 }
03503 break;
03504 }
03505 case CASE_FALL_OUT:
03506 {
03507 Is_True(fall_thru, ("fall_thru can not be empty!\n"));
03508
03509 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(fall_thru);
03510 BOOL is_main_exit = tgt_info -> Is_Main_Predicate(orig_pred);
03511 tgt_info -> Update_Predicate(orig_pred, pred);
03512
03513 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03514 {
03515 if ( is_main_exit )
03516 {
03517 fprintf(TFile,
03518 "\n exit-target(main): BB%d \n",
03519 BB_id(fall_thru));
03520 } else {
03521 fprintf(TFile,
03522 "\n exit-target(aux): BB%d \n",
03523 BB_id(fall_thru));
03524 }
03525 }
03526
03527 if ( is_main_exit)
03528 {
03529 if (tgt_info -> Aux_Predicates().size())
03530 {
03531 Add_Goto_Op(bb, fall_thru);
03532 Make_Branch_Conditional(bb);
03533 OP* br = BB_branch_op(bb);
03534 tgt_info -> Assign_Aux_Predicates(bb, br);
03535
03536
03537 float pb1 = 1.0;
03538 if (pred_bb)
03539 {
03540 BB *other_succ = NULL;
03541 BBLIST *bl;
03542 FOR_ALL_BB_SUCCS(bb, bl)
03543 {
03544 BB *tmp_bb = BBLIST_item(bl);
03545 if (tmp_bb != bb)
03546 {
03547 other_succ = tmp_bb;
03548 break;
03549 }
03550 }
03551 if ( other_succ)
03552 pb1 = 1.0 - Prob_Local(pred_bb,other_succ);
03553 }
03554 Set_Prob(bb, fall_thru, pb1);
03555 } else {
03556 if ( bb != last_bb)
03557 {
03558 Add_Goto_Op(bb, fall_thru);
03559 Make_Branch_Conditional(bb);
03560 }
03561 }
03562
03563 } else {
03564 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03565 {
03566 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03567 }
03568 can_be_merged_into = TRUE;
03569 RGN_Unlink_Pred_Succ(bb, fall_thru);
03570 }
03571
03572 break;
03573 }
03574 case CASE_IF_FALL_OUT:
03575 {
03576 Is_True(fall_thru, ("fall_thru can not be empty!\n"));
03577
03578 TN *first_pred = NULL;
03579 TN *second_pred = NULL;
03580
03581 Find_BB_Predicates(bb, first_pred, second_pred);
03582 Is_True(first_pred && second_pred,
03583 (" lack of a predicate!\n"));
03584
03585 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(fall_thru);
03586 BOOL is_main_exit;
03587
03588 OP *br = BB_branch_op(bb);
03589 Is_True(br, (" two-successor bb must have br\n"));
03590 if (first_pred == OP_opnd(br, OP_PREDICATE_OPND))
03591 {
03592 is_main_exit = tgt_info -> Is_Main_Predicate(second_pred);
03593
03594 } else {
03595 Is_True(second_pred == OP_opnd(br, OP_PREDICATE_OPND),
03596 ("conditional br must have a predicate.\n"));
03597 is_main_exit = tgt_info -> Is_Main_Predicate(first_pred);
03598 }
03599
03600
03601 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03602 {
03603 if ( is_main_exit )
03604 {
03605 fprintf(TFile,
03606 "\n exit-target(main): BB%d \n",
03607 BB_id(fall_thru));
03608 } else {
03609 fprintf(TFile,
03610 "\n exit-target(aux): BB%d \n",
03611 BB_id(fall_thru));
03612 }
03613 }
03614
03615
03616 BB_Remove_Branch(bb);
03617
03618 if (is_main_exit)
03619 {
03620
03621 Add_Goto_Op(bb, fall_thru);
03622 RGN_Link_Pred_Succ_With_Prob(bb, fall_thru, 1.0);
03623 Make_Branch_Conditional(bb);
03624 OP* br = BB_branch_op(bb);
03625
03626 float pb1 = pred_bb ? Prob_Local(pred_bb, bb):1;
03627 float pb2 = Prob_Local(bb, fall_thru);
03628 Set_Prob(bb, fall_thru, pb1 * pb2);
03629
03630 tgt_info -> Assign_Aux_Predicates(bb, br);
03631 } else {
03632 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03633 {
03634 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03635 }
03636 can_be_merged_into = TRUE;
03637 BB* other_succ = BB_Other_Successor(bb, fall_thru);
03638 RGN_Unlink_Pred_Succ(bb, other_succ);
03639
03640 }
03641 break;
03642 }
03643 case CASE_IF_FALL_IN:
03644 {
03645 Is_True(fall_thru, ("fall_thru can not be empty!\n"));
03646
03647 BB* other_succ = BB_Other_Successor(bb, fall_thru);
03648 Is_True(other_succ, ("fall_thru can not be empty!\n"));
03649 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(other_succ);
03650
03651 TN *first_pred = NULL;
03652 TN *second_pred = NULL;
03653
03654 Find_BB_Predicates(bb, first_pred, second_pred);
03655 Is_True(first_pred && second_pred,
03656 (" lack of a predicate!\n"));
03657
03658 BOOL is_main_exit;
03659 OP *br = BB_branch_op(bb);
03660 Is_True(br, (" two-successor bb must have br\n"));
03661 if (first_pred == OP_opnd(br, OP_PREDICATE_OPND))
03662 {
03663 is_main_exit = tgt_info -> Is_Main_Predicate(first_pred);
03664 } else {
03665 Is_True(second_pred == OP_opnd(br, OP_PREDICATE_OPND),
03666 ("conditional br must have a predicate.\n"));
03667 is_main_exit = tgt_info -> Is_Main_Predicate(second_pred);
03668 }
03669
03670 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03671 {
03672 fprintf(TFile, "\n exit-target");
03673 if ( is_main_exit )
03674 {
03675 fprintf(TFile, "(main)");
03676 } else {
03677 fprintf(TFile, "(aux)");
03678 }
03679 fprintf(TFile,": BB%d ", BB_id(other_succ));
03680 }
03681 if (is_main_exit)
03682 {
03683 OP* br = BB_branch_op(bb);
03684 tgt_info -> Assign_Aux_Predicates(bb, br);
03685
03686 } else {
03687 BB_Remove_Branch(bb);
03688 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03689 {
03690 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03691 }
03692 can_be_merged_into = TRUE;
03693 RGN_Unlink_Pred_Succ(bb, other_succ);
03694
03695 }
03696 break;
03697 }
03698 case CASE_IF_OUT:
03699 {
03700 Is_True(fall_thru, ("fall_thru can not be empty!\n"));
03701
03702 TN *first_pred = NULL;
03703 TN *second_pred = NULL;
03704
03705 Find_BB_Predicates(bb, first_pred, second_pred);
03706 Is_True(first_pred && second_pred,
03707 (" lack of a predicate!\n"));
03708
03709 BOOL is_main_exit;
03710 OP *br = BB_branch_op(bb);
03711 Is_True(br, (" two-successor bb must have br\n"));
03712
03713
03714
03715 TN *fall_thru_pred = NULL;
03716 BB* other_succ = BB_Other_Successor(bb, fall_thru);
03717 EXIT_TARGET_INFO* tgt_info = area -> Exit_Target(other_succ);
03718 if (first_pred == OP_opnd(br, OP_PREDICATE_OPND))
03719 {
03720 is_main_exit = tgt_info -> Is_Main_Predicate(first_pred);
03721 fall_thru_pred = second_pred;
03722
03723 } else {
03724 Is_True(second_pred == OP_opnd(br, OP_PREDICATE_OPND),
03725 ("conditional br must have a predicate.\n"));
03726 is_main_exit = tgt_info -> Is_Main_Predicate(second_pred);
03727 fall_thru_pred = first_pred;
03728 }
03729
03730 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03731 {
03732 fprintf(TFile, "\n exit-target");
03733 if ( is_main_exit )
03734 {
03735 fprintf(TFile, "(main)");
03736 } else {
03737 fprintf(TFile, "(aux)");
03738 }
03739 fprintf(TFile,": BB%d ", BB_id(other_succ));
03740 }
03741
03742 BOOL need_add_fall_thru = TRUE;
03743 if ( is_main_exit )
03744 {
03745 OP* br = BB_branch_op(bb);
03746 tgt_info -> Assign_Aux_Predicates(bb, br);
03747 } else {
03748 BB_Remove_Branch(bb);
03749 RGN_Unlink_Pred_Succ(bb, other_succ);
03750 need_add_fall_thru = FALSE;
03751 }
03752
03753
03754 tgt_info = area -> Exit_Target(fall_thru);
03755 if (first_pred == OP_opnd(br, OP_PREDICATE_OPND))
03756 {
03757 is_main_exit = tgt_info -> Is_Main_Predicate(second_pred);
03758 } else {
03759 Is_True(second_pred == OP_opnd(br, OP_PREDICATE_OPND),
03760 ("conditional br must have a predicate.\n"));
03761 is_main_exit = tgt_info -> Is_Main_Predicate(first_pred);
03762 }
03763 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03764 {
03765 fprintf(TFile, "\n exit-target");
03766 if ( is_main_exit )
03767 {
03768 fprintf(TFile, "(main)");
03769 } else {
03770 fprintf(TFile, "(aux)");
03771 }
03772 fprintf(TFile,": BB%d ", BB_id(fall_thru));
03773 }
03774
03775
03776 br = NULL;
03777 if ( is_main_exit)
03778 {
03779 if ( need_add_fall_thru &&
03780 (tgt_info -> Aux_Predicates().size() || bb != last_bb))
03781 {
03782
03783 REGIONAL_CFG* cfg = BB_SET_Size(bb_to_solve) ?
03784 Home_Region(bb) -> Regional_Cfg(): NULL;
03785 fall_thru_goto = RGN_Gen_And_Insert_BB(bb, fall_thru, cfg);
03786 Add_Goto_Op(fall_thru_goto, fall_thru);
03787 if (fall_thru_pred && fall_thru_pred != True_TN)
03788 {
03789 Make_Branch_Conditional(fall_thru_goto);
03790 Predicate_Block(fall_thru_goto,
03791 fall_thru_pred, area_bb_set);
03792 }
03793
03794
03795 br = BB_branch_op(fall_thru_goto);
03796 tgt_info -> Assign_Aux_Predicates(fall_thru_goto, br);
03797
03798 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03799 {
03800 fprintf(TFile, " fall-thru-succ: BB%d\n",
03801 BB_id(fall_thru));
03802 fprintf(TFile, " gen fall-thru-goto: BB%d.\n",
03803 BB_id(fall_thru_goto));
03804 }
03805
03806 Move_BB(fall_thru_goto, bb);
03807 GRA_LIVE_Compute_Liveness_For_BB(fall_thru_goto);
03808 float pb1 = Prob_Local(pred_bb, bb);
03809 float pb2 = Prob_Local(bb, other_succ);
03810
03811 Set_Prob(bb, other_succ, pb1 * pb2);
03812 Set_Prob(bb, fall_thru_goto, 1 - pb1 * pb2);
03813
03814 BB_freq(fall_thru_goto) =
03815 BB_freq(pred_bb) * (1 -pb1 * pb2);
03816
03817
03818 } else if (bb != last_bb ||
03819 tgt_info -> Aux_Predicates().size())
03820 {
03821 Add_Goto_Op(bb, fall_thru);
03822 Make_Branch_Conditional(bb);
03823 br = BB_branch_op(bb);
03824 if (fall_thru_pred && fall_thru_pred != True_TN)
03825 {
03826 Set_OP_opnd(br, OP_PREDICATE_OPND, fall_thru_pred);
03827 }
03828
03829
03830 tgt_info -> Assign_Aux_Predicates(bb, br);
03831 }
03832 } else {
03833 RGN_Unlink_Pred_Succ(bb, fall_thru);
03834 }
03835
03836 if (!need_add_fall_thru && !br)
03837 {
03838 if(!pred_bb || !BB_SET_MemberP(hold_bbs, pred_bb))
03839 {
03840 hold_bbs = BB_SET_Union1D(hold_bbs, bb, &_m);
03841 }
03842 can_be_merged_into = TRUE;
03843 }
03844 break;
03845 }
03846
03847
03848 case CASE_CHECK_IN:
03849 case CASE_CHECK_OUT:
03850 {
03851 break;
03852 }
03853 default:
03854 Is_True(0,("Unknown block classification"));
03855 }
03856
03857
03858 Predicate_Block(bb, pred, area_bb_set);
03859
03860
03861
03862
03863 if (pred_bb && BB_SET_MemberP(hold_bbs, pred_bb))
03864 {
03865 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03866 {
03867 fprintf(TFile, " => merged.\n");
03868 }
03869
03870 if (pred)
03871 {
03872 if (!pred_info -> Eqv_Class_Head()
03873 && pred_info -> Eqv_Class_Head_BB() != pred_bb)
03874 {
03875 Set_TN_is_global_reg(pred);
03876 Set_BB_has_globals(bb);
03877 Set_BB_has_globals(pred_info -> Eqv_Class_Head_BB());
03878 } else if (pred_info -> Has_Start_Node())
03879 {
03880 BB* st_n = pred_info -> Start_Node(BB_SET_Choose(set));
03881 if (st_n != pred_bb)
03882 {
03883 Set_TN_is_global_reg(pred);
03884 Set_BB_has_globals(bb);
03885 Set_BB_has_globals(st_n);
03886 }
03887
03888 }
03889 }
03890 BB *succ_of_goto = NULL;
03891 if (fall_thru_goto)
03892 {
03893 Is_True(BB_succs_len(fall_thru_goto) == 1,
03894 ("here fall-thru-goto can only have one succ!\n"));
03895 bl = BB_succs(fall_thru_goto);
03896 succ_of_goto = BBLIST_item(bl);
03897 }
03898 FOR_ALL_BB_SET_members(bb_to_solve, succ_bb_of_pred)
03899 {
03900 if (fall_thru_goto)
03901 {
03902
03903
03904 float pb = Prob_Local(pred_bb, succ_bb_of_pred);
03905 RGN_Unlink_Pred_Succ(pred_bb, succ_bb_of_pred);
03906 RGN_Link_Pred_Succ_With_Prob(fall_thru_goto,
03907 succ_bb_of_pred, pb);
03908 Set_Fall_Thru(fall_thru_goto, succ_bb_of_pred);
03909
03910 Set_Prob(fall_thru_goto, succ_of_goto, 1 - pb);
03911
03912 } else {
03913
03914 float pb = Prob_Local(pred_bb, succ_bb_of_pred);
03915 RGN_Unlink_Pred_Succ(pred_bb, succ_bb_of_pred);
03916 RGN_Link_Pred_Succ_With_Prob(bb, succ_bb_of_pred, pb);
03917
03918 }
03919 }
03920
03921 if ( BB_call(bb) )
03922 {
03923 BB_Transfer_Callinfo( bb, pred_bb);
03924 }
03925 Merge_Blocks(pred_bb, bb);
03926 if (!can_be_merged_into)
03927 {
03928 BB_SET_Difference1D(hold_bbs, pred_bb);
03929 }
03930 }else if (pred_bb){
03931
03932 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
03933 {
03934 fprintf(TFile, " => appended .\n");
03935 }
03936
03937
03938 if (pred &&
03939 (!pred_info -> Eqv_Class_Head()|| pred_info -> Has_Start_Node()))
03940 {
03941 Set_TN_is_global_reg(pred);
03942 Set_BB_has_globals(bb);
03943 if (!pred_info -> Eqv_Class_Head())
03944 Set_BB_has_globals(pred_info -> Eqv_Class_Head_BB());
03945 }
03946
03947 if ( BB_SET_Size(bb_to_solve) )
03948 {
03949 BB *succ_of_goto = NULL;
03950 if (fall_thru_goto)
03951 {
03952 Is_True(BB_succs_len(fall_thru_goto) == 1,
03953 ("here fall-thru-goto can only have one succ!\n"));
03954 bl = BB_succs(fall_thru_goto);
03955 succ_of_goto = BBLIST_item(bl);
03956 }
03957 FOR_ALL_BB_SET_members(bb_to_solve, succ_bb_of_pred)
03958 {
03959 if (fall_thru_goto)
03960 {
03961
03962
03963 float pb = Prob_Local(pred_bb, succ_bb_of_pred);
03964 RGN_Unlink_Pred_Succ(pred_bb, succ_bb_of_pred);
03965 RGN_Link_Pred_Succ_With_Prob(fall_thru_goto,
03966 succ_bb_of_pred, pb);
03967 Set_Fall_Thru(fall_thru_goto, succ_bb_of_pred);
03968
03969 Set_Prob(fall_thru_goto, succ_of_goto, 1 - pb);
03970
03971 } else {
03972
03973 float pb = Prob_Local(pred_bb, succ_bb_of_pred);
03974 RGN_Unlink_Pred_Succ(pred_bb, succ_bb_of_pred);
03975 RGN_Link_Pred_Succ_With_Prob(bb, succ_bb_of_pred, pb);
03976 }
03977 }
03978
03979
03980 }
03981 if (last_bb_type == CASE_CALL_OUT)
03982 {
03983 Set_Fall_Thru(pred_bb, bb);
03984 }
03985 float out_pb = 0.0;
03986
03987 if (pred_bb && BB_succs_len(pred_bb) > 1)
03988 {
03989 Is_True(BB_succs_len(pred_bb) == 2,
03990 ("a bb can not have more than 2 succs!\n"));
03991
03992
03993 FOR_ALL_BB_SUCCS(pred_bb, bl)
03994 {
03995 succ_bb_of_pred = BBLIST_item(bl);
03996 if (succ_bb_of_pred != bb
03997 && !Is_BB_Container_Member(bbs, succ_bb_of_pred))
03998 {
03999 out_pb = Prob_Local(pred_bb, succ_bb_of_pred);
04000 Set_Fall_Thru(pred_bb, bb);
04001 }
04002
04003 }
04004 }
04005
04006
04007
04008 BB_freq(bb) = BB_freq(pred_bb) * ( 1- out_pb);
04009 Set_Prob(pred_bb, bb, 1.0 - out_pb);
04010 } else {
04011 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04012 {
04013 fprintf(TFile, "\n");
04014 }
04015 }
04016 last_bb_type = bb_type;
04017 }
04018
04019
04020
04021 for (bb_iter = bbs.begin();
04022 bb_iter != bbs.end();
04023 bb_iter++)
04024 {
04025 bb = *bb_iter;
04026 OP *br = BB_branch_op(bb);
04027 if ( !br ) continue;
04028 if ( OP_cond(br) && BB_succs_len(bb) == 1 )
04029 {
04030 BB *fall_thru = BB_Fall_Thru_Successor(bb);
04031 if ( fall_thru && fall_thru == BB_next(bb) && OP_bb(br) )
04032 {
04033 BB_Remove_Op(bb, br);
04034 } else if (!fall_thru ) {
04035
04036
04037
04038
04039 TOP new_top;
04040 switch (OP_code(br)) {
04041 case TOP_br_cond:
04042 new_top = TOP_br;
04043 break;
04044 case TOP_br_r_cond:
04045 new_top = TOP_br_r;
04046 break;
04047 default:
04048 FmtAssert(0, ("Weird branch instruction!"));
04049 break;
04050 }
04051 OP* new_br = Mk_OP(new_top,
04052 Gen_Enum_TN(ECV_ph_few),
04053 Gen_Enum_TN(ECV_dh),
04054 OP_opnd(br,4));
04055 OP_srcpos(new_br) = OP_srcpos(br);
04056 BB_Insert_Op_After(bb, br, new_br);
04057 BB_Remove_Op(bb, br);
04058 }
04059 }
04060 }
04061
04062 }
04063 BB_MERGE_TYPE
04064 IF_CONVERTOR::Classify_BB(BB *bb,
04065 IF_CONV_AREA *area)
04066 {
04067 BB_MERGE_TYPE result;
04068 BB *entry = area -> Entry_BB();
04069
04070 BB *fall_thru;
04071 BB *other_succ;
04072 fall_thru = BB_Fall_Thru_Successor(bb);
04073 other_succ = NULL;
04074
04075 BBLIST *bl;
04076 FOR_ALL_BB_SUCCS(bb, bl)
04077 {
04078 other_succ = BBLIST_item(bl);
04079 if (other_succ != fall_thru) break;
04080 }
04081
04082
04083 BOOL fall_thru_out = false;
04084 BOOL other_out = false;
04085
04086 BB_CONTAINER& bbs_1 = area -> Blocks();
04087 if (fall_thru &&
04088 (!Is_BB_Container_Member(bbs_1, fall_thru) ||fall_thru == entry))
04089 {
04090 fall_thru_out = TRUE;
04091 }
04092
04093 if (other_succ &&
04094 (!Is_BB_Container_Member(bbs_1, other_succ) || other_succ == entry))
04095 {
04096 other_out = TRUE;
04097 }
04098
04099 if (!other_out && !fall_thru_out)
04100 {
04101 if (BB_exit(bb) || BB_call(bb))
04102 {
04103 result = CASE_CALL_IN;
04104 } else if (BB_chk_op(bb))
04105 {
04106 result = CASE_CHECK_IN;
04107 } else {
04108 result = CASE_ALL_IN_AREA;
04109 }
04110 return result;
04111 }
04112
04113
04114 if (BB_exit(bb) || BB_call(bb))
04115 {
04116 result = CASE_CALL_OUT;
04117 return result;
04118 }
04119 if (BB_chk_op(bb))
04120 {
04121 result = CASE_CHECK_OUT;
04122 return result;
04123 }
04124
04125 OP *br = BB_branch_op(bb);
04126 if (!br)
04127 {
04128
04129 result = CASE_FALL_OUT;
04130 return result;
04131 }
04132
04133 if (!OP_cond(br))
04134 {
04135
04136 result = CASE_UNCOND_BR;
04137 return result;
04138 }
04139
04140 if (fall_thru_out && other_out)
04141 {
04142 result = CASE_IF_OUT;
04143 } else if (fall_thru_out && !other_out) {
04144 result = CASE_IF_FALL_OUT;
04145 } else {
04146 result = CASE_IF_FALL_IN;
04147 }
04148 return result;
04149 }
04150 void
04151 IF_CONVERTOR::Set_Fall_Thru(BB* bb, BB* fall_thru)
04152 {
04153 BB* before_bb = bb;
04154 while (fall_thru) {
04155 BB* next = BB_next(fall_thru);
04156
04157
04158
04159 BOOL stop_iter = FALSE;
04160 OP *br_op = BB_branch_op(fall_thru);
04161 if (next && br_op) {
04162 INT tfirst, tcount;
04163 CGTARG_Branch_Info(br_op, &tfirst, &tcount);
04164 if (tcount != 0) {
04165 TN *dest = OP_opnd(br_op, tfirst);
04166 Is_True(tcount == 1,
04167 ("%d branch targets, expected 1", tcount));
04168 Is_True(TN_is_label(dest), ("expected label"));
04169 if (Is_Label_For_BB(TN_label(dest), next)) {
04170 stop_iter = TRUE;
04171 }
04172 }
04173 }
04174
04175 if (stop_iter || next != BB_Fall_Thru_Successor(fall_thru))
04176 {
04177 next = NULL;
04178 }
04179 Move_BB(fall_thru, before_bb);
04180 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04181 {
04182 fprintf(TFile, "\n => move BB:%d after BB:%d\n",
04183 BB_id(fall_thru), BB_id(before_bb));
04184 }
04185 before_bb = fall_thru;
04186 fall_thru = next;
04187 }
04188 }
04189 void
04190 IF_CONVERTOR::Merge_Blocks(BB *bb_first,
04191 BB *bb_second)
04192 {
04193
04194 BOOL need_maintain = TRUE;
04195 OP *br_op = BB_branch_op(bb_second);
04196 BB* next = BB_next(bb_second);
04197 if (next && br_op) {
04198
04199 INT tfirst, tcount;
04200 CGTARG_Branch_Info(br_op, &tfirst, &tcount);
04201 if (tcount != 0) {
04202 TN *dest = OP_opnd(br_op, tfirst);
04203 Is_True(tcount == 1, ("%d branch targets, expected 1", tcount));
04204 Is_True(TN_is_label(dest), ("expected label"));
04205 if (Is_Label_For_BB(TN_label(dest), next)) {
04206 need_maintain = FALSE;
04207 }
04208 }
04209 }
04210
04211 if ( need_maintain && bb_second != BB_next(bb_first))
04212 {
04213 BB* fall_thru = BB_Fall_Thru_Successor(bb_second);
04214 Set_Fall_Thru(bb_first, fall_thru);
04215 }
04216
04217
04218 OP *op;
04219 OP *op_next;
04220 OP *last = BB_last_op(bb_first);
04221 for (op = BB_first_op(bb_second);
04222 op;
04223 op = op_next)
04224 {
04225 op_next = OP_next(op);
04226 if (last)
04227 {
04228 BB_Move_Op(bb_first, last, bb_second, op, FALSE);
04229 } else {
04230 BB_Append_Op (bb_first, op);
04231 }
04232 last = op;
04233 }
04234
04235
04236 RGN_Unlink_Pred_Succ(bb_first, bb_second);
04237
04238
04239 BB *succ;
04240 BBLIST *bl;
04241 while (bl = BB_succs(bb_second))
04242 {
04243 succ = BBLIST_item(bl);
04244 float pb = Prob_Local(bb_second, succ);
04245 RGN_Unlink_Pred_Succ(bb_second, succ);
04246 RGN_Link_Pred_Succ_With_Prob(bb_first, succ, pb);
04247 }
04248
04249
04250 RGN_Remove_BB_And_Edges(bb_second);
04251
04252
04253
04254
04255 if (BB_exit(bb_second))
04256 {
04257 BB_Transfer_Exitinfo(bb_second, bb_first);
04258 Exit_BB_Head = BB_LIST_Delete(bb_second, Exit_BB_Head);
04259 Exit_BB_Head = BB_LIST_Push(bb_first, Exit_BB_Head, &MEM_pu_pool);
04260 }
04261
04262
04263 if (BB_call(bb_second))
04264 {
04265 BB_Copy_Annotations(bb_first, bb_second, ANNOT_CALLINFO);
04266 }
04267
04268 }
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282 BOOL
04283 IF_CONVERTOR::Convert_Candidates(AREA_CONTAINER& areas)
04284 {
04285 AREA_CONTAINER:: iterator iter;
04286 BOOL converted = FALSE;
04287 for ( iter = areas.begin();
04288 iter != areas.end();
04289 iter++)
04290 {
04291 IF_CONV_AREA* area = *iter;
04292 BB_CONTAINER& bbs = area -> Blocks();
04293
04294 if (IPFEC_Query_Skiplist(if_conv_skip_area, area -> Area_Label()))
04295 continue;
04296 if ( area -> Conv_Type() != FULLY_IF_CONV)
04297 continue;
04298
04299 converted = TRUE;
04300 char if_conversion_key[6] = "";
04301 char input_string[100] = "";
04302 char output_string[60] = "";
04303 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_CG))
04304 {
04305 BB_CONTAINER::iterator bb_iter;
04306 BB *bb;
04307 sprintf(if_conversion_key, "%d", area -> Area_Label());
04308 for (bb_iter = bbs.begin();
04309 bb_iter != bbs.end();
04310 bb_iter++)
04311 {
04312 bb = *bb_iter;
04313 char tmp_string[6];
04314 sprintf(tmp_string, "%d", BB_id(bb));
04315 strcat(input_string, tmp_string);
04316 strcat(input_string, "||");
04317 }
04318 }
04319 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04320 {
04321 fprintf(TFile, "\n IF_CONV_AREA %d:\n", area -> Area_Label());
04322 }
04323
04324 area -> Init_Conversion_Info(&_m);
04325
04326 if ( !Insert_Predicate(area)) {
04327 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04328 {
04329 fprintf(TFile, "\n too many exits, give up!!\n");
04330 }
04331 continue;
04332 }
04333 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04334 {
04335 fprintf(TFile, "\n Start to merge basic blocks!\n");
04336 }
04337
04338 Merge_Area(area);
04339
04340 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_CG))
04341 {
04342 BB_CONTAINER& bbs = area -> Blocks();
04343 BB_CONTAINER::iterator bb_iter;
04344 BB *bb;
04345 sprintf(if_conversion_key, "%d", area -> Area_Label());
04346 for (bb_iter = bbs.begin();
04347 bb_iter != bbs.end();
04348 bb_iter++)
04349 {
04350 bb = *bb_iter;
04351
04352 if (Regional_Cfg_Node(bb))
04353 {
04354 char tmp_string[6];
04355 sprintf(tmp_string, "%d", BB_id(bb));
04356 strcat(output_string, tmp_string);
04357 strcat(output_string, "||");
04358 }
04359 }
04360 Generate_Tlog("AIC", "if_conversion", (SRCPOS)0,
04361 if_conversion_key, input_string, output_string, "");
04362 }
04363 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04364 {
04365 fprintf(TFile, "\n after merging basic blocks:\n");
04366 area -> Print_IR(TFile);
04367 }
04368 }
04369 return converted;
04370 }
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382 IF_CONVERTOR::IF_CONVERTOR(REGION_TREE *region_tree)
04383 {
04384
04385 Start_Timer(T_Ipfec_If_Conv_CU);
04386
04387
04388 if (Get_Trace(TKIND_IR, TP_A_IFCONV, REGION_First_BB))
04389 Trace_IR(TP_A_IFCONV, "IF_CONV", NULL, FALSE);
04390
04391 if (!frequency_of_predicates)
04392 {
04393 frequency_of_predicates = hTN_MAPf_Create(&(info_mem._m));
04394 }
04395
04396 if (!init_op_info)
04397 {
04398 init_op_info = hTN_MAP_Create(&(info_mem._m));
04399 }
04400
04401 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_GRAPHIC))
04402 {
04403 draw_global_cfg();
04404 }
04405
04406 BOOL changed = TRUE;
04407 for (INNERMOST_REGION_FIRST_ITER iter(region_tree);
04408 iter != 0;
04409 ++iter)
04410 {
04411 REGION* region = *iter;
04412
04413 if (IPFEC_Query_Skiplist(if_conv_skip_rgn, region -> Id(), Current_PU_Count()))
04414 continue;
04415
04416 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_GRAPHIC))
04417 {
04418 draw_regional_cfg(region);
04419 }
04420 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04421 {
04422 fprintf(TFile, " \nIF CONVERSION -- region %d\n", region -> Id());
04423 }
04424
04425 if ( Is_In_Infinite_Loop(region) )
04426 continue;
04427
04428 if (Is_In_Abnormal_Loop(region))
04429 continue;
04430
04431 if (region->Region_Type () == IMPROPER)
04432 continue;
04433
04434
04435
04436 if( changed )
04437 Calculate_Dominators();
04438
04439
04440 IF_CONV_ALLOC temp_alloc(&_m);
04441 AREA_CONTAINER areas(temp_alloc);
04442
04443 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04444 {
04445 fprintf(TFile, " \n Start to initialize!\n");
04446 }
04447
04448 If_Conversion_Init(region,areas);
04449
04450 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04451 {
04452 fprintf(TFile, " IF_CONV_AREAs after initialization:\n\n");
04453 Print_All_Areas(areas, TFile);
04454 }
04455
04456 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04457 {
04458 fprintf(TFile, " \n Start to select proper areas!\n");
04459 }
04460
04461
04462 Select_Candidates(areas);
04463
04464 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04465 {
04466 fprintf(TFile, " IF_CONV_AREAs after selection:\n\n");
04467 Print_All_Areas(areas, TFile);
04468 }
04469
04470 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04471 {
04472 fprintf(TFile, " \n Start to convert candidates!\n");
04473 }
04474
04475 changed = Convert_Candidates(areas);
04476
04477 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_GRAPHIC))
04478 {
04479 draw_regional_cfg(region);
04480 }
04481
04482 CXX_DELETE(&areas, &_m);
04483 if( changed )
04484 Free_Dominators_Memory();
04485 }
04486 if(!changed)
04487 Free_Dominators_Memory();
04488
04489 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_GRAPHIC))
04490 {
04491 draw_global_cfg();
04492 }
04493
04494
04495 if (Get_Trace(TKIND_IR, TP_A_IFCONV, REGION_First_BB))
04496 Trace_IR(TP_A_IFCONV, "IF_CONV", NULL);
04497
04498 Stop_Timer(T_Ipfec_If_Conv_CU);
04499 }
04500 IF_CONVERTOR::IF_CONVERTOR()
04501 {
04502 if (!frequency_of_predicates)
04503 {
04504 frequency_of_predicates = hTN_MAPf_Create(&(info_mem._m));
04505 }
04506 if (!init_op_info)
04507 {
04508 init_op_info = hTN_MAP_Create(&(info_mem._m));
04509 }
04510
04511 _loop_length = 0;
04512 }
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528 BB *
04529 IF_CONVERTOR::Force_If_Convert(LOOP_DESCR *loop, BOOL allow_multi_bb)
04530 {
04531 BB *bb_entry = LOOP_DESCR_loophead(loop);
04532
04533
04534 if (BB_SET_Size(LOOP_DESCR_bbset(loop)) == 1) {
04535 return bb_entry;
04536 }
04537
04538
04539 IF_CONV_ALLOC temp_alloc(&_m);
04540 AREA_CONTAINER areas(temp_alloc);
04541
04542 REGION* region = Home_Region(bb_entry);
04543 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_GRAPHIC))
04544 {
04545 draw_regional_cfg(region);
04546 }
04547 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04548 {
04549 fprintf(TFile, " ======start to force_if_convert\n\n");
04550 }
04551
04552 if ( Is_In_Infinite_Loop(region) )
04553 {
04554 return NULL;
04555 }
04556
04557 If_Conversion_Init(region,areas);
04558 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04559 {
04560 fprintf(TFile, " IF_CONV_AREAs after initialization:\n\n");
04561 Print_All_Areas(areas, TFile);
04562 }
04563
04564
04565 BOOL is_legal = Can_Merge_Into_One_Area(areas);
04566 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY))
04567 {
04568 fprintf(TFile, " is_legal: %d\n", (int)is_legal);
04569 }
04570 if (!is_legal)
04571 {
04572 return NULL;
04573 }
04574
04575
04576
04577
04578
04579
04580 if (IPFEC_Relaxed_If_Conv) {
04581 if (Get_Trace (TP_A_IFCONV, TT_IF_CONV_SUMMARY)) {
04582 fprintf(TFile, " ======use relaxed_if_conv\n\n");
04583 }
04584
04585
04586 INT32 loop_length1, loop_length2;
04587 loop_length1 = Calculate_Loop_Critical_Length (areas[0]);
04588 loop_length2 = Calculate_Loop_Cycled_Critical_Length (areas[0]);
04589
04590 _loop_length = loop_length1 > loop_length2 ? loop_length1 : loop_length2;
04591
04592 if (Get_Trace (TP_A_IFCONV, TT_IF_CONV_DETAILED)) {
04593 fprintf (TFile,
04594 " Loop Length: %i\n",
04595 _loop_length);
04596 }
04597
04598 Select_Candidates (areas, TRUE);
04599
04600 if (Get_Trace (TP_A_IFCONV, TT_IF_CONV_DETAILED)) {
04601 fprintf (TFile, " IF_CONV_AREAs after selection:\n\n");
04602 Print_All_Areas (areas, TFile);
04603 }
04604
04605
04606
04607 if (areas.size()!=1) {
04608 return NULL;
04609 }
04610 }
04611 else {
04612
04613 AREA_CONTAINER::iterator area_iter;
04614 area_iter = areas.begin();
04615 IF_CONV_AREA *head_area = *area_iter;
04616 area_iter++;
04617
04618 for (; area_iter != areas.end(); area_iter++) {
04619 head_area -> Combine_Blocks_With (*area_iter, &_m);
04620 }
04621
04622
04623
04624 areas.erase (areas.begin()+1,areas.end());
04625 head_area -> Conv_Type(FULLY_IF_CONV);
04626 }
04627
04628 BOOL can_one_bb = Can_Merge_Into_One_BB (*(areas.begin()));
04629 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_SUMMARY)) {
04630 fprintf (TFile, " can_one_bb: %d\n", (int) can_one_bb);
04631 }
04632
04633
04634 if (can_one_bb || allow_multi_bb) {
04635 if (Get_Trace (TP_A_IFCONV, TT_IF_CONV_SUMMARY)) {
04636 fprintf (TFile, " \n Start to convert candidates!\n");
04637 }
04638 Convert_Candidates(areas);
04639
04640
04641 BB* fall_thru_bb = NULL;
04642 BB* bb;
04643 IF_CONV_AREA* area = *(areas.begin());
04644 BB_CONTAINER del_blks(&_m);
04645 BB_CONTAINER::iterator bb_iter;
04646 for (bb_iter = area -> Blocks().begin();
04647 bb_iter != area -> Blocks().end();
04648 bb_iter++)
04649 {
04650 bb = *bb_iter;
04651 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
04652 REGION* home_region = node ? node -> Home_Region() : NULL;
04653
04654 if (!home_region) {
04655
04656
04657
04658
04659
04660 del_blks.push_back (bb);
04661 }
04662 else if (home_region != region) {
04663 FmtAssert (fall_thru_bb == NULL,
04664 (" can only have one fall_thru_bb\n"));
04665 fall_thru_bb = bb;
04666
04667
04668 LOOP_DESCR *enc_loop = LOOP_DESCR_Next_Enclosing_Loop(loop);
04669 if (enc_loop) {
04670 LOOP_DESCR_Add_BB (enc_loop, fall_thru_bb);
04671 }
04672 }
04673 }
04674
04675 for (BB_CONTAINER::iterator iter = del_blks.begin();
04676 iter != del_blks.end ();
04677 iter++)
04678 {
04679 LOOP_DESCR_Delete_BB (loop, *iter);
04680 }
04681
04682 BB* single_bb = NULL;
04683 if (can_one_bb) {
04684 FmtAssert (areas.size() ==1, (" loop should be shrinked to one bb"));
04685 IF_CONV_AREA* area = *(areas.begin());
04686 if (BB_SET_Size(LOOP_DESCR_bbset(loop)) == 1) {
04687 single_bb = area -> Entry_BB();
04688 }
04689 }
04690
04691 if (Get_Trace (TP_A_IFCONV, TT_IF_CONV_GRAPHIC)) {
04692 draw_regional_cfg(region);
04693 }
04694
04695 return single_bb;
04696 }
04697
04698 return NULL;
04699 }
04700
04701
04702 BOOL
04703 IF_CONVERTOR::Can_Merge_Into_One_Area(AREA_CONTAINER& areas)
04704 {
04705 INT break_num = 0;
04706 AREA_CONTAINER::iterator iter;
04707 for ( iter = areas.begin();
04708 iter != areas.end();
04709 iter++)
04710 {
04711 IF_CONV_AREA* area = *iter;
04712 if (area -> Area_Type() == UNSUITABLE)
04713 {
04714 return false;
04715 }
04716
04717 if (area -> Area_Type() == UPWARD_UNSUITABLE
04718 && area -> Pred_Num())
04719 {
04720 return false;
04721 }
04722
04723 if (area -> Area_Type() == DOWNWARD_UNSUITABLE
04724 && area -> Succ_Num())
04725 {
04726
04727 return false;
04728 }
04729 }
04730 return true;
04731 }
04732 BOOL
04733 IF_CONVERTOR::Can_Merge_Into_One_BB(IF_CONV_AREA* area)
04734 {
04735 BB_CONTAINER& bbs = area -> Blocks();
04736 BB_CONTAINER::iterator bb_iter;
04737 BB *bb;
04738 BOOL break_num = FALSE;
04739 for (bb_iter = bbs.begin();
04740 bb_iter != bbs.end();
04741 bb_iter++)
04742 {
04743 bb =*bb_iter;
04744 BB_MERGE_TYPE merge_type = Classify_BB(bb, area);
04745
04746 if (Get_Trace(TP_A_IFCONV, TT_IF_CONV_DETAILED))
04747 {
04748 fprintf(TFile, " => BB_%d is",BB_id(bb));
04749 Print_BB_Merge_Type(merge_type,TFile);
04750 fprintf(TFile,"type.\n");
04751 }
04752 switch ( merge_type) {
04753 case CASE_ALL_IN_AREA:
04754 {
04755 break;
04756 }
04757 case CASE_CALL_IN:
04758 case CASE_IF_FALL_OUT:
04759 case CASE_IF_FALL_IN:
04760 case CASE_CHECK_IN:
04761 {
04762 return false;
04763 }
04764 case CASE_CALL_OUT:
04765 case CASE_UNCOND_BR:
04766 case CASE_FALL_OUT:
04767 case CASE_IF_OUT:
04768 case CASE_CHECK_OUT:
04769 {
04770 if (!break_num) {
04771 break_num= TRUE;
04772 break;
04773 } else
04774 return false;
04775 }
04776 default:
04777 Is_True(0,("Unknown block classification"));
04778 }
04779 }
04780 return true;
04781 }
04782
04783
04784
04785
04786 void
04787 IF_CONVERTOR::Print_BB_Merge_Type(BB_MERGE_TYPE merge_type,FILE* file)
04788 {
04789 switch ( merge_type) {
04790 case CASE_ALL_IN_AREA:
04791 {
04792 fprintf(file, "CASE_ALL_IN_AREA");
04793 break;
04794 }
04795 case CASE_CALL_IN:
04796 {
04797 fprintf(file, "CASE_CALL_IN");
04798 break;
04799 }
04800 case CASE_CALL_OUT:
04801 {
04802 fprintf(file, "CASE_CALL_OUT");
04803 break;
04804 }
04805 case CASE_UNCOND_BR:
04806 {
04807 fprintf(file, "CASE_UNCOND_BR");
04808 break;
04809 }
04810 case CASE_FALL_OUT:
04811 {
04812 fprintf(file, "CASE_FALL_OUT");
04813 break;
04814 }
04815 case CASE_IF_FALL_OUT:
04816 {
04817 fprintf(file, "CASE_IF_FALL_OUT");
04818 break;
04819 }
04820 case CASE_IF_FALL_IN:
04821 {
04822 fprintf(file, "CASE_IF_FALL_IN");
04823 break;
04824 }
04825 case CASE_IF_OUT:
04826 {
04827 fprintf(file, "CASE_IF_OUT");
04828 break;
04829 }
04830 case CASE_CHECK_IN:
04831 {
04832 fprintf(file, "CASE_CHECK_IN");
04833 break;
04834 }
04835 case CASE_CHECK_OUT:
04836 {
04837 fprintf(file, "CASE_CHECK_OUT");
04838 break;
04839 }
04840 default:
04841 {
04842 Is_True(0,("Unknown block classification"));
04843 }
04844 }
04845 }
04846 void
04847 IF_CONVERTOR::Print_All_Areas(AREA_CONTAINER& areas, FILE* file)
04848 {
04849 AREA_CONTAINER::iterator iter;
04850 for (iter = areas.begin();
04851 iter != areas.end();
04852 iter++)
04853 {
04854 IF_CONV_AREA* area = *iter;
04855 area -> Print(TFile);
04856 }
04857 }
04858
04859
04860
04861 INT32
04862 IF_CONVERTOR::Calculate_Loop_Critical_Length (IF_CONV_AREA* area) {
04863 INT32 critical_length = 0;
04864 INT32 length1, length2;
04865 AREA_CONTAINER::iterator area_succs;
04866
04867 FmtAssert(area!=NULL, ("Parameter area is NULL pointer!"));
04868
04869 critical_length += area->Critical_Len ();
04870
04871 area_succs = area->Succ_Set().begin();
04872
04873 switch (area->Succ_Num ()) {
04874 case 0: break;
04875
04876 case 1: critical_length +=
04877 Calculate_Loop_Critical_Length (*area_succs);
04878 break;
04879
04880 case 2: length1 =
04881 Calculate_Loop_Critical_Length (*area_succs);
04882 area_succs++;
04883 length2 =
04884 Calculate_Loop_Critical_Length (*area_succs);
04885
04886 if (length1 > length2 ) {
04887 critical_length += length1;
04888 }
04889 else {
04890 critical_length += length2;
04891 }
04892 break;
04893
04894 default: FmtAssert (0, ("Unexpected number of successors!"));
04895 break;
04896
04897 }
04898
04899 return critical_length;
04900 }
04901
04902
04903
04904
04905 INT32
04906 IF_CONVERTOR::Calculate_Loop_Cycled_Critical_Length (IF_CONV_AREA* area) {
04907 INT32 cycled_critical_length = 0;
04908 INT32 length1, length2;
04909 AREA_CONTAINER::iterator area_succs;
04910
04911 FmtAssert(area!=NULL, ("Parameter area is NULL pointer!"));
04912
04913 cycled_critical_length += area->Cycled_Critical_Len ();
04914
04915 area_succs = area->Succ_Set().begin();
04916
04917 switch (area->Succ_Num ()) {
04918 case 0: break;
04919
04920 case 1: cycled_critical_length +=
04921 Calculate_Loop_Cycled_Critical_Length (*area_succs);
04922 break;
04923
04924 case 2: length1 =
04925 Calculate_Loop_Cycled_Critical_Length (*area_succs);
04926 area_succs++;
04927 length2 =
04928 Calculate_Loop_Cycled_Critical_Length (*area_succs);
04929
04930 if (length1 > length2 ) {
04931 cycled_critical_length += length1;
04932 }
04933 else {
04934 cycled_critical_length += length2;
04935 }
04936 break;
04937
04938 default: FmtAssert (0, ("Unexpected number of successors!"));
04939 break;
04940
04941 }
04942
04943 return cycled_critical_length;
04944 }
04945
04946
04947 void
04948 IF_CONV_AREA::Print(FILE* file)
04949 {
04950 fprintf(file,
04951 "\nIF_CONV_AREA_%d: (",
04952 Area_Label());
04953 fprintf(file, " suitable type : ");
04954 switch (_if_suitable) {
04955 case UPWARD_UNSUITABLE:
04956 {
04957 fprintf(file, " UPWARD_UNSUITABLE; ");
04958 break;
04959 }
04960 case DOWNWARD_UNSUITABLE:
04961 {
04962 fprintf(file, " DOWNWARD_UNSUITABLE; ");
04963 break;
04964 }
04965 case UNSUITABLE:
04966 {
04967 fprintf(file, " UNSUITABLE; ");
04968 break;
04969 }
04970 case SUITABLE_FOR_IF_CONV:
04971 {
04972 fprintf(file, " SUITABLE_FOR_IF_CONV; ");
04973 break;
04974 }
04975 default:
04976 {
04977 Is_True(0, (" Illegal AREA_TYPE.\n"));
04978 }
04979 }
04980
04981 fprintf(file, " if-conv type : ");
04982 switch (_need_if_convert ) {
04983 case NO_IF_CONV:
04984 {
04985 fprintf(file, " NO_IF_CONV;");
04986 break;
04987 }
04988 case PARTIAL_IF_CONV:
04989 {
04990 fprintf(file, " PARTIAL_IF_CONV;");
04991 break;
04992 }
04993 case FULLY_IF_CONV:
04994 {
04995 fprintf(file, " FULLY_IF_CONV;");
04996 break;
04997 }
04998 default:
04999 {
05000 Is_True(0, (" Illegal IF_CONV_TYPE.\n"));
05001 }
05002 }
05003
05004 fprintf(file, " length(cycled): %d; ",_cycled_critical_length);
05005 fprintf(file, " length : %d ", _critical_length);
05006
05007 fprintf(file,")\n -- included blocks : ");
05008 BB_CONTAINER& bbs = _included_blocks;
05009 BB_CONTAINER::iterator bb_iter;
05010 BB *block;
05011 for (bb_iter = bbs.begin();
05012 bb_iter != bbs.end();
05013 bb_iter++)
05014 {
05015 block = *bb_iter;
05016 fprintf(file,"BB%d, ", block -> id);
05017 }
05018 fprintf(file,"\n");
05019
05020 AREA_CONTAINER::iterator iter;
05021 fprintf(file, " -- predecessors : ");
05022 for ( iter = _predecessors.begin();
05023 iter!=_predecessors.end();
05024 iter++)
05025 {
05026 IF_CONV_AREA* pred = *iter;
05027 fprintf(file,"AREA_%d, ", pred->Area_Label());
05028 }
05029
05030 fprintf(file, "\n -- successors : ");
05031 for ( iter = _successors.begin();
05032 iter!= _successors.end();
05033 iter++)
05034 {
05035 IF_CONV_AREA* succ = *iter;
05036 fprintf(file,"AREA_%d, ", succ->Area_Label());
05037 }
05038 fprintf(file, "\n");
05039
05040 if (_control_deps)
05041 {
05042 Is_True(_pred_assign_info, (" _pred_true_edges must be initialized!"));
05043
05044 _control_deps -> Print(file);
05045
05046 fprintf(file, " -- more detailed information for each bb : \n");
05047 BB_CONTAINER::iterator bb_iter;
05048 for (bb_iter = bbs.begin();
05049 bb_iter != bbs.end();
05050 bb_iter++)
05051 {
05052 block = *bb_iter;
05053 BB_SET *set;
05054 BB *bb;
05055 BB_PREDICATE_INFO *info;
05056
05057 fprintf(file, " \n** BB%d : ", BB_id(block));
05058 info = (BB_PREDICATE_INFO*)BB_MAP_Get( _pred_assign_info, block);
05059 fPrint_TN(file,
05060 " predicate: %s ; ",
05061 info -> Predicate());
05062 fprintf(file,
05063 " transitional: %c ;",
05064 info -> Transitional()?'y':'n');
05065 fPrint_TN(file,
05066 " true pred: %s ;",
05067 info -> True_TN());
05068 fPrint_TN(file,
05069 " false pred: %s\n",
05070 info -> False_TN());
05071
05072
05073 TN_CONTAINER::iterator iter;
05074 TN_CONTAINER tn_set;
05075
05076 fprintf(file," # or preds:");
05077 tn_set = info ->Or_TNs();
05078 for (iter = tn_set.begin();
05079 iter != tn_set.end();
05080 iter++)
05081 {
05082 fPrint_TN(file, " %s,", *iter);
05083 }
05084
05085 fprintf(file," # orcm preds:");
05086 tn_set = info -> Orcm_TNs();
05087 for (iter = tn_set.begin();
05088 iter != tn_set.end();
05089 iter++)
05090 {
05091 fPrint_TN(file, " %s,", *iter);
05092 }
05093
05094 fprintf(file," # and preds:\n");
05095 tn_set = info -> And_TNs();
05096 for (iter = tn_set.begin();
05097 iter != tn_set.end();
05098 iter++)
05099 {
05100 fPrint_TN(file, " %s,", *iter);
05101 }
05102
05103 fprintf(file," # andcm preds:");
05104 tn_set = info -> Andcm_TNs();
05105 for (iter = tn_set.begin();
05106 iter != tn_set.end();
05107 iter++)
05108 {
05109 fPrint_TN(file, " %s,", *iter);
05110 }
05111 fprintf(file, "\n");
05112
05113 if ( !info -> Has_Start_Node()) continue;
05114 fprintf(file,
05115 " # starting nodes for each control dependentor:\n");
05116 BB_SET* cds = _control_deps -> Cntl_Dep_Parents(block);
05117 BB* cd;
05118 FOR_ALL_BB_SET_members(cds, cd)
05119 {
05120 BB* sn = info -> Start_Node(cd);
05121 if (sn)
05122 {
05123 fprintf(file, " BB%d ==> BB%d ; ",
05124 BB_id(cd), BB_id(sn));
05125 }
05126 }
05127
05128 fprintf(file, "\n");
05129 }
05130 }
05131 }
05132
05133 void
05134 IF_CONV_AREA::Print_IR(FILE *file)
05135 {
05136 fprintf(file,
05137 "\nIF_CONV_AREA_%d:========================\n",
05138 Area_Label());
05139
05140 BB_CONTAINER& bbs = _included_blocks;
05141 BB_CONTAINER::iterator bb_iter;
05142 BB *block;
05143 for (bb_iter = bbs.begin();
05144 bb_iter != bbs.end();
05145 bb_iter++)
05146 {
05147 block = *bb_iter;
05148 Print_BB (block);
05149 }
05150 fprintf(file,"\n");
05151 }
05152 void
05153 CNTL_DEP::Print(FILE* file)
05154 {
05155 BB *block;
05156
05157 fprintf(file, "\n -- control dependence information \n");
05158 FOR_ALL_BB_SET_members(_bb_set, block)
05159 {
05160 BB_SET *set;
05161 BB *bb;
05162
05163 fprintf(file, " ** BB_%d: cds : ", block -> id);
05164 set = (BB_SET*)BB_MAP_Get(_control_dependences, block);
05165 FOR_ALL_BB_SET_members(set, bb)
05166 {
05167 fprintf(file, " BB%d, ", BB_id(bb));
05168 }
05169
05170 fprintf(file, " true edges : ");
05171 set = (BB_SET*)BB_MAP_Get(_true_edges, block);
05172 FOR_ALL_BB_SET_members(set, bb)
05173 {
05174 fprintf(file, " BB%d, ", BB_id(bb));
05175 }
05176 fprintf(file, "\n");
05177 }
05178 }
05179