00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdio.h>
00040 #include "stdlib.h"
00041 #include "bb.h"
00042 #include <stack>
00043 #include <vector>
00044 #include <list>
00045 #include "defs.h"
00046 #include "cxx_memory.h"
00047 #include "region.h"
00048 #include "interval_processor.h"
00049 #include "vt_region.h"
00050 #include "gra_live.h"
00051 #include "cgtarget.h"
00052 #include "region_bb_util.h"
00053 #include "region_verify.h"
00054 #include "tracing.h"
00055 #include "ipfec_defs.h"
00056 #include "global_cycles_finder.h"
00057 #include "cg_flags.h"
00058 #include "profile_util.h"
00059 #include "tlog.h"
00060 #include "freq.h"
00061 #include "ipfec_options.h"
00062
00063 BB_MAP bb_node_map;
00064 GLOBAL_CYCLE_VECTOR global_cycles;
00065
00066
00067
00068
00069 void Create_BB_Node_Map(void) {
00070 bb_node_map = BB_MAP_Create();
00071 }
00072
00073 void Delete_BB_Node_Map(void) {
00074 BB_MAP_Delete(bb_node_map);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 void Initialize_Temp_Rgn(TEMP_RGN& temp_rgn,MEM_POOL _m) {
00084 NODE_ALLOC temp_alloc(&_m);
00085 NODE_VECTOR temp_nodes(temp_alloc);
00086 temp_rgn.nodes = temp_nodes;
00087 temp_rgn.main_entry = NULL;
00088 temp_rgn.main_exit = NULL;
00089 temp_rgn.seed = NULL;
00090 temp_rgn.bb_num = 0;
00091 temp_rgn.op_num = 0;
00092 temp_rgn.dup_bb_num = 0;
00093 temp_rgn.dup_op_num = 0;
00094 temp_rgn.exit_prob = 0;
00095 temp_rgn.seed_freq = 0;
00096 }
00097
00098 NODE_VECTOR_ITER
00099 Find_In_Vector(REGIONAL_CFG_NODE *node,NODE_VECTOR& nodes) {
00100 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
00101 REGIONAL_CFG_NODE *n = *iter;
00102
00103 Is_True(n != NULL,("Node n NULL in Find_In_Vector."));
00104
00105 if (n == node) return iter;
00106 }
00107
00108 return nodes.end();
00109 }
00110
00111 BB_VECTOR_ITER
00112 Find_In_BB_Vector(BB *bb,BB_VECTOR& bbs) {
00113 for (BB_VECTOR_ITER iter = bbs.begin();iter != bbs.end();iter++) {
00114 BB *b = *iter;
00115
00116 Is_True(b != NULL,("BB NULL in Find_In_BB_Vector."));
00117
00118 if (b == bb) return iter;
00119 }
00120
00121 return bbs.end();
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 BOOL
00131 REGIONAL_CFG_NODE::Is_Loop_Head(void) {
00132 if (_home_r->Region_Type() == LOOP) {
00133
00134 if (_first_pred == NULL) {
00135 return TRUE;
00136 }
00137 }
00138
00139 return FALSE;
00140 }
00141
00142 BOOL
00143 REGIONAL_CFG_NODE::Is_Loop_Tail(void) {
00144 if (_home_r->Region_Type() == LOOP) {
00145
00146 if (_first_succ == NULL) {
00147 return TRUE;
00148 }
00149 }
00150
00151 return FALSE;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 REGIONAL_CFG_NODE*
00164 REGIONAL_CFG::Add_Node(REGION *r) {
00165 REGIONAL_CFG_NODE *p = CXX_NEW(REGIONAL_CFG_NODE(r),&_m);
00166
00167 Is_True(p != NULL,("New node failed in Add_Node."));
00168
00169 r->Regional_Cfg_Node(p);
00170 Insert(p);
00171
00172 return p;
00173 }
00174
00175 REGIONAL_CFG_NODE*
00176 REGIONAL_CFG::Add_Node(BB *bb) {
00177 REGIONAL_CFG_NODE *p = CXX_NEW(REGIONAL_CFG_NODE(bb),&_m);
00178
00179 Is_True(p != NULL,("New node failed in Add_Node."));
00180
00181 BB_MAP_Set(bb_node_map,bb,p);
00182 REGIONAL_CFG_NODE *pget = (REGIONAL_CFG_NODE*)BB_MAP_Get(bb_node_map,bb);
00183 Insert(p);
00184
00185 return p;
00186 }
00187
00188
00189
00190
00191 void
00192 REGIONAL_CFG::Del_Node(REGIONAL_CFG_NODE *v)
00193 {
00194
00195
00196 BB *pred;
00197 REGIONAL_CFG_NODE *node1=v;
00198 REGION *rgn,*root1,*par_rgn;
00199 BOOL has_single_bb;
00200
00201 while (v->First_Succ()) {
00202 Del_Edge(v->First_Succ());
00203 }
00204
00205 while (v->First_Pred()) {
00206 Del_Edge(v->First_Pred());
00207 }
00208
00209 if (v->Is_Entry())
00210 Remove_From_Entries(v);
00211 if (v->Is_Exit()){
00212 if (!(v->Is_Region())) {
00213 pred=v->BB_Node();
00214 node1 = Regional_Cfg_Node(pred);
00215 rgn = node1->Home_Region();
00216 root1 = rgn->Tree()->Root();
00217 }else{
00218 rgn=v->Region_Node();
00219
00220
00221 root1 = rgn->Tree()->Root();
00222 REGIONAL_CFG *cfg = rgn->Regional_Cfg();
00223 BB_VECTOR exits(&(cfg->_m));
00224 Collect_Exit_BBs(node1->Region_Node(), &exits);
00225 for(BB_VECTOR_ITER bb_iter=exits.begin(); bb_iter!=exits.end(); bb_iter++){
00226 BB *exit_bb = *bb_iter;
00227 BBLIST *succ_list;
00228 if(BB_succs_len(exit_bb) == 0) {
00229 has_single_bb= TRUE;
00230 break;
00231 }
00232
00233 }
00234 }
00235
00236 if(v->Is_Exit())
00237 Remove_From_Exits(v);
00238 if(!(v->Is_Region()) && BB_succs_len(pred)==0 || v->Is_Region() && has_single_bb==TRUE ){
00239
00240 rgn = v->Home_Region();
00241 while (rgn != root1){
00242 node1= rgn->Regional_Cfg_Node();
00243 par_rgn =node1->Home_Region();
00244 REGIONAL_CFG *cfg = par_rgn->Regional_Cfg();
00245 BB_VECTOR exits(&(cfg->_m));
00246
00247 if(node1->Is_Region()) {
00248 Collect_Exit_BBs(rgn, &exits);
00249 } else {
00250 exits.push_back(node1->BB_Node());
00251 }
00252 int has_other_exit_edge = FALSE;
00253 for (BB_VECTOR_ITER bb_iter=exits.begin();
00254 bb_iter!=exits.end(); bb_iter++){
00255 BB *exit_bb = *bb_iter;
00256 BBLIST *succ_list;
00257 if(BB_succs_len(exit_bb) == 0 && exit_bb != pred) {
00258 has_other_exit_edge= TRUE;
00259 break;
00260 }
00261
00262 FOR_ALL_BB_SUCCS(exit_bb, succ_list) {
00263 BB *succ_bb = BBLIST_item(succ_list);
00264 if(! Region_Contains_BB(par_rgn, succ_bb)){
00265 has_other_exit_edge = TRUE;
00266 break;
00267 }
00268 }
00269 if(has_other_exit_edge)
00270 break;
00271 }
00272
00273 if(!has_other_exit_edge){
00274 cfg->Remove_From_Exits(node1);
00275 }
00276 rgn=par_rgn;
00277 }
00278 }
00279 }
00280
00281
00282
00283 if (v->Is_Region()) {
00284 (v->Region_Node())->Regional_Cfg_Node(NULL);
00285 } else {
00286 BB_MAP_Set(bb_node_map,v->BB_Node(),NULL);
00287 }
00288
00289 Erase(v);
00290 CXX_DELETE(v,&_m);
00291 }
00292
00293 REGIONAL_CFG_EDGE*
00294 REGIONAL_CFG::Find_Edge(REGIONAL_CFG_NODE *v,REGIONAL_CFG_NODE *w) {
00295 for (CFG_SUCC_EDGE_ITER iter(v);iter != 0;++iter) {
00296 REGIONAL_CFG_EDGE *e = *iter;
00297
00298 if (e->Dest() == w) {
00299 return e;
00300 }
00301 }
00302
00303 return NULL;
00304 }
00305
00306 void
00307 REGIONAL_CFG::Add_To_Exits(REGIONAL_CFG_NODE *node) {
00308 if (node->Is_Exit()) {
00309 return;
00310 }
00311
00312 _exits.push_back(node);
00313 node->Is_Exit(TRUE);
00314 }
00315
00316 void
00317 REGIONAL_CFG::Add_To_Entries(REGIONAL_CFG_NODE *node) {
00318 if (node->Is_Entry()) {
00319 return;
00320 }
00321
00322 _entries.push_back(node);
00323 node->Is_Entry(TRUE);
00324 }
00325
00326 void
00327 REGIONAL_CFG::Remove_From_Exits(REGIONAL_CFG_NODE *node) {
00328 for (NODE_VECTOR_ITER iter = _exits.begin();iter != _exits.end();iter++) {
00329 if ((*iter) == node) {
00330 _exits.erase(iter);
00331
00332 break;
00333 }
00334 }
00335
00336 node->Is_Exit(FALSE);
00337 }
00338
00339 void
00340 REGIONAL_CFG::Remove_From_Entries(REGIONAL_CFG_NODE *node) {
00341 for (NODE_VECTOR_ITER iter = _entries.begin();
00342 iter != _entries.end();iter++) {
00343 if ((*iter) == node) {
00344 _entries.erase(iter);
00345
00346 break;
00347 }
00348 }
00349
00350 node->Is_Entry(FALSE);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 void
00373 REGIONAL_CFG::Find_MEME_Nodes(TEMP_RGN& meme_rgn,RGN_SIZE size,
00374 NODE_VECTOR bad_nodes) {
00375 NODE_ALLOC temp_alloc(&_m);
00376 NODE_VECTOR meme_nodes(temp_alloc);
00377 REGIONAL_CFG_NODE *main_entry = NULL;
00378 REGIONAL_CFG_NODE *node = NULL;
00379 INT32 bb_num = 0;
00380 INT32 op_num = 0;
00381
00382 REGIONAL_CFG_NODE *seed = Find_Seed(bad_nodes);
00383 Is_True(seed != NULL,("Can not find out a seed in Find_MEME_Node."));
00384
00385 if (!seed->Is_Region()) {
00386 BB *bb = seed->BB_Node();
00387 op_num = BB_length(bb);
00388 }
00389
00390 bb_num++;
00391 meme_nodes.push_back(seed);
00392
00393 main_entry = seed;
00394 REGIONAL_CFG_NODE *last_node = seed;
00395 float seed_freq = Node_Freq(seed);
00396 meme_rgn.seed = seed;
00397 meme_rgn.seed_freq = seed_freq;
00398
00399 float t = 0.49;
00400 float ts = 0.49;
00401 INT32 max_bb_num = size.max_bb_num;
00402 INT32 max_op_num = size.max_op_num;
00403 INT32 max_length = (INT32)(max_bb_num/1.5);
00404
00405 REGIONAL_CFG_EDGE *succ = Select_Freq_Succ(seed,meme_nodes);
00406 while ((succ != NULL) && (bb_num < max_length) && (op_num < max_op_num)
00407 && Succ_Suit(succ,seed_freq,t,ts)) {
00408 bb_num++;
00409 node = succ->Dest();
00410 meme_nodes.push_back(node);
00411 last_node = node;
00412
00413 if (!node->Is_Region()) {
00414 op_num += BB_length(node->BB_Node());
00415 }
00416
00417 succ = Select_Freq_Succ(node,meme_nodes);
00418 }
00419
00420 t = 0.8;
00421 ts = 0.8;
00422
00423 REGIONAL_CFG_EDGE *pred = Select_Freq_Pred(seed,meme_nodes,bad_nodes);
00424 while ((pred != NULL) && (bb_num < max_length) && (op_num < max_op_num)
00425 && Pred_Suit(pred,seed_freq,t,ts)) {
00426 bb_num++;
00427 node = pred->Src();
00428 meme_nodes.push_back(node);
00429 main_entry = node;
00430
00431 if (!node->Is_Region()) {
00432 op_num += BB_length(node->BB_Node());
00433 }
00434
00435 pred = Select_Freq_Pred(node,meme_nodes,bad_nodes);
00436 }
00437
00438
00439
00440 node = Select_Freq_Connected_Node(meme_nodes,last_node);
00441 while ((node != NULL) && (bb_num < max_bb_num) && (op_num < max_op_num)) {
00442 meme_nodes.push_back(node);
00443 bb_num++;
00444
00445 if (!node->Is_Region()) {
00446 op_num += BB_length(node->BB_Node());
00447 }
00448
00449 node = Select_Freq_Connected_Node(meme_nodes,last_node);
00450 }
00451
00452 meme_rgn.nodes = meme_nodes;
00453 meme_rgn.main_entry = main_entry;
00454 meme_rgn.bb_num = bb_num;
00455 meme_rgn.op_num = op_num;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 void
00478 REGIONAL_CFG::Find_SEME_Nodes(TEMP_RGN& seme_rgn,RGN_FORM_PAR par,
00479 NODE_VECTOR bad_nodes)
00480 {
00481
00482 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00483 fprintf(TFile,"Begin find base MEME nodes.\n");
00484 }
00485
00486 RGN_SIZE max_size = par.size;
00487 float dup_ratio = par.dup_ratio;
00488 float exit_prob = par.exit_prob;
00489 INT32 max_dup_num = par.max_dup_num;
00490
00491 Find_MEME_Nodes(seme_rgn,max_size,bad_nodes);
00492
00493 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00494 fprintf(TFile,"Finish find base MEME nodes.\n");
00495 }
00496
00497 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00498 fprintf(TFile,"Found MEME nodes:\n");
00499 Print_Node_Vector(seme_rgn.nodes);
00500 fprintf(TFile,"Number of found base MEME nodes %d \n",seme_rgn.bb_num);
00501 }
00502
00503
00504
00505
00506
00507 NODE_ALLOC temp_alloc(&_m);
00508 NODE_VECTOR side_entries(temp_alloc);
00509
00510 if (exit_prob == 0) {
00511 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00512 fprintf(TFile,"Begin compute side entries of MEME nodes.\n");
00513 }
00514
00515 Compute_Side_Entries(side_entries,seme_rgn.nodes,seme_rgn.main_entry);
00516
00517 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00518 fprintf(TFile,"The main entry is :");
00519 seme_rgn.main_entry->Print(TFile);
00520 fprintf(TFile,"Found side entries are:\n");
00521 Print_Node_Vector(side_entries);
00522 }
00523
00524 if (!side_entries.empty()) {
00525
00526 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00527 fprintf(TFile,"Before selective cut.\n");
00528 }
00529
00530 seme_rgn.main_exit = NULL;
00531 BOOL cut_succ = Do_Selective_Cut(seme_rgn.nodes,
00532 seme_rgn.main_entry,NULL,par);
00533
00534 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00535 fprintf(TFile,"Finish selective cut.\n");
00536 }
00537
00538 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00539 fprintf(TFile,"Nodes after selective cut.\n");
00540 Print_Node_Vector(seme_rgn.nodes);
00541 }
00542
00543 if (cut_succ) {
00544 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00545 fprintf(TFile,"Begin tail duplication.\n");
00546 }
00547
00548
00549 Tail_Duplicate(seme_rgn.nodes,seme_rgn.main_entry,
00550 seme_rgn.dup_bb_num,seme_rgn.dup_op_num,FALSE);
00551
00552 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00553 fprintf(TFile,"Finish tail duplication.\n");
00554 }
00555 } else {
00556 FmtAssert(FALSE,("Do selective cut failed even no main exit is set.Algorithm of selective cut is dead."));
00557 }
00558 }
00559 } else {
00560 float max_weight = 0;
00561 NODE_VECTOR meme_nodes(temp_alloc);
00562
00563 meme_nodes = seme_rgn.nodes;
00564 seme_rgn.nodes.clear();
00565
00566 REGIONAL_CFG_NODE *main_entry = seme_rgn.main_entry;
00567 for (NODE_VECTOR_ITER iter = meme_nodes.begin();
00568 iter != meme_nodes.end();iter++) {
00569 NODE_VECTOR temp_seme(temp_alloc);
00570 REGIONAL_CFG_NODE *node = *iter;
00571
00572 Compute_Scope_Based_On_Main_Exit(temp_seme,meme_nodes,node);
00573
00574 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00575
00576 if (node->Is_Region()) {
00577 fprintf(TFile,"The scope when REGION Node_%d is main exit :\n",
00578 (node->Region_Node())->Id());
00579 } else {
00580 fprintf(TFile,"The scope when BB Node_%d is main exit :\n",
00581 BB_id(node->BB_Node()));
00582 }
00583
00584 Print_Node_Vector(temp_seme);
00585 }
00586
00587 float prob = Compute_Completion_Prob(temp_seme,node,main_entry);
00588
00589 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00590 fprintf(TFile,"Completion prob :%f\n",prob);
00591 }
00592
00593 if (prob > exit_prob) {
00594 NODE_VECTOR temp_dup(temp_alloc);
00595 Compute_Nodes_To_Be_Duplicated(temp_dup,temp_seme,main_entry);
00596 float ratio = Compute_Duplicate_Ratio(temp_seme,
00597 temp_dup,max_size.max_bb_num,max_dup_num);
00598
00599 if (ratio > dup_ratio) {
00600 if (!Do_Selective_Cut(temp_seme,main_entry,node,par)) {
00601 continue;
00602 }
00603 }
00604
00605 float weight = Compute_Nodes_Weight(temp_seme);
00606 if (weight > max_weight) {
00607 seme_rgn.nodes = temp_seme;
00608 seme_rgn.main_exit = node;
00609 seme_rgn.exit_prob = prob;
00610 max_weight = weight;
00611 }
00612 }
00613 }
00614
00615 if (!(seme_rgn.nodes).empty()) {
00616
00617 side_entries.clear();
00618
00619 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00620 fprintf(TFile,"Begin compute side entries nodes of MEME nodes.\n");
00621 }
00622
00623 Compute_Side_Entries(side_entries,seme_rgn.nodes,
00624 seme_rgn.main_entry);
00625
00626 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
00627 fprintf(TFile,"The main entry is :\n");
00628 main_entry->Print(TFile);
00629 fprintf(TFile,"Found side entries are:\n");
00630 Print_Node_Vector(side_entries);
00631 }
00632
00633 if (!side_entries.empty()) {
00634
00635 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00636 fprintf(TFile,"Begin tail duplication.\n");
00637 }
00638
00639
00640 Tail_Duplicate(seme_rgn.nodes,seme_rgn.main_entry,
00641 seme_rgn.dup_bb_num,
00642 seme_rgn.dup_op_num,FALSE);
00643
00644 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
00645 fprintf(TFile,"Finished tail duplication.\n");
00646 }
00647 }
00648 } else {
00649 FmtAssert(FALSE,("The seme nodes is empty!This may cause error!"));
00650 }
00651 }
00652
00653
00654
00655 INT32 bb_num = 0;
00656 INT32 op_num = 0;
00657 for (NODE_VECTOR_ITER iter = (seme_rgn.nodes).begin();
00658 iter != (seme_rgn.nodes).end();iter++) {
00659 REGIONAL_CFG_NODE *node = *iter;
00660 Is_True(node != NULL,("Node is NULL in find SEME nodes when count bb num."));
00661 if (!node->Is_Region()) {
00662 bb_num ++;
00663 op_num += BB_length(node->BB_Node());
00664 }
00665 }
00666
00667
00668
00669
00670 seme_rgn.bb_num = bb_num;
00671 seme_rgn.op_num = op_num;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 float
00685 REGIONAL_CFG::Compute_Nodes_Weight(NODE_VECTOR nodes) {
00686 float weight = 0.0;
00687
00688 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
00689 REGIONAL_CFG_NODE *node = *iter;
00690
00691 Is_True(node != NULL,("Node is NULL in compute nodes weight!"));
00692
00693 float freq = Node_Freq(node);
00694 if (!node->Is_Region()) {
00695
00696
00697 weight += (freq + 1.0)*(BB_length(node->BB_Node()) + 1.0);
00698 } else {
00699
00700
00701
00702
00703 weight += freq*5*0.5;
00704 }
00705 }
00706
00707 return weight;
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 BOOL
00721 REGIONAL_CFG::Is_Unwanted_Node(REGIONAL_CFG_NODE *node) {
00722
00723
00724
00725 if (node->Is_Loop_Head() || node->Is_Loop_Tail()) {
00726 return TRUE;
00727 }
00728
00729 if (((node->Home_Region())->Region_Type() == LOOP) && node->Is_Exit()) {
00730 return TRUE;
00731 }
00732
00733 if (node->Is_Region()) {
00734
00735 if ((node->Region_Node())->Region_Type() == LOOP) {
00736 return TRUE;
00737 }
00738
00739 BB_VECTOR bbs;
00740 Compute_BBs_In_Region_Node(bbs,node);
00741
00742 for (BB_VECTOR_ITER bb_iter = bbs.begin();
00743 bb_iter != bbs.end();bb_iter++) {
00744 BB *bb = *bb_iter;
00745
00746
00747
00748
00749 if (BB_Not_Suit_Duplicate(bb)) {
00750 return TRUE;
00751 }
00752
00753
00754
00755
00756 }
00757 } else {
00758 BB *bb = node->BB_Node();
00759
00760 if (BB_Not_Suit_Duplicate(bb)) {
00761 return TRUE;
00762 }
00763 }
00764 return FALSE;
00765 }
00766
00767
00768 BOOL
00769 REGIONAL_CFG::BB_Not_Suit_Duplicate(BB *bb) {
00770 if (BB_exit(bb)) {
00771 return TRUE;
00772 }
00773
00774 OP *br = BB_branch_op(bb);
00775 INT nsuccs = BBlist_Len(BB_succs(bb));
00776 if (br == NULL) {
00777 if (nsuccs <= 1) {
00778 return FALSE;
00779 } else {
00780 Is_True(FALSE,("The BB %d has more than one succ but no br op!",BB_id(bb)));
00781 }
00782 }
00783
00784 INT32 tfirst,tcount;
00785 CGTARG_Branch_Info(br, &tfirst, &tcount);
00786
00787
00788 if(tcount==0) {
00789 return TRUE;
00790 }
00791
00792 if (nsuccs > 2) {
00793 return TRUE;
00794 }
00795
00796
00797 BBLIST *preds;
00798 FOR_ALL_BB_PREDS(bb,preds) {
00799 BB *pred = BBLIST_item(preds);
00800 br = BB_branch_op(pred);
00801 nsuccs = BBlist_Len(BB_succs(pred));
00802 if (br == NULL) {
00803 if (nsuccs <= 1) {
00804 return FALSE;
00805 } else {
00806 Is_True(FALSE,("The BB %d has more than one succ but no br op!",BB_id(pred)));
00807 }
00808 }
00809 CGTARG_Branch_Info(br, &tfirst, &tcount);
00810
00811
00812 if(tcount==0) {
00813 return TRUE;
00814 }
00815
00816 if (nsuccs > 2) {
00817 return TRUE;
00818 }
00819 }
00820
00821 return FALSE;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 INT32
00848 REGIONAL_CFG::Do_Selective_Add(NODE_VECTOR& nodes,NODE_VECTOR duplicate,
00849 NODE_VECTOR& leaf_nodes,REGIONAL_CFG_NODE *main_exit,
00850 REGIONAL_CFG_NODE *main_entry,INT32 op_num,RGN_FORM_PAR par) {
00851 NODE_ALLOC temp_alloc(&_m);
00852 NODE_VECTOR exits(temp_alloc);
00853
00854 INT32 max_bb_num = par.size.max_bb_num;
00855 INT32 max_op_num = par.size.max_op_num;
00856 float exit_prob = par.exit_prob;
00857 INT32 added_op_num = 0;
00858
00859 Compute_Exits(nodes,exits);
00860
00861 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
00862 REGIONAL_CFG_NODE *node = *iter;
00863 Is_True(node != NULL,("Node is NULL in Do Selective Add when iterate all nodes."));
00864 if ((node != main_exit)&&
00865 Find_In_Vector(node,duplicate) == duplicate.end()) {
00866
00867
00868 for (CFG_SUCC_NODE_ITER succ_iter(node);
00869 succ_iter != 0;++succ_iter) {
00870 REGIONAL_CFG_NODE *succ = *succ_iter;
00871
00872 if (Find_In_Vector(succ,nodes) == nodes.end()) {
00873 BOOL not_side_entry = TRUE;
00874
00875 for (CFG_PRED_NODE_ITER pred_iter(succ);
00876 pred_iter != 0;++pred_iter) {
00877 REGIONAL_CFG_NODE *pred = *pred_iter;
00878
00879 if (Find_In_Vector(pred,nodes) == nodes.end()) {
00880 not_side_entry = FALSE;
00881 }
00882 }
00883
00884 if (not_side_entry) {
00885 BOOL cand = TRUE;
00886 if (succ->First_Succ() == NULL) continue;
00887
00888 NODE_VECTOR single_path(temp_alloc);
00889 single_path.push_back(succ);
00890
00891 if (!succ->Is_Region()) {
00892 added_op_num += BB_length(succ->BB_Node());
00893 }
00894
00895 for (CFG_SUCC_NODE_ITER nsucc_iter(succ);
00896 nsucc_iter != 0;++nsucc_iter) {
00897 REGIONAL_CFG_NODE *end = *nsucc_iter;
00898
00899 if (Find_In_Vector(end,nodes) == nodes.end()) {
00900 if ((succ->Unique_Succ() == end)
00901 &&(end->Unique_Pred() == succ)) {
00902
00903
00904
00905
00906
00907
00908
00909 single_path.push_back(end);
00910
00911 if (!end->Is_Region()) {
00912 added_op_num += BB_length(end->BB_Node());
00913 }
00914
00915 while (end) {
00916
00917
00918
00919
00920 Is_True(end != NULL,("The end node is NULL in Do Selective Add!\n"));
00921
00922 end = end->Unique_Succ();
00923
00924 if (end) {
00925 if (Find_In_Vector(end,nodes) != nodes.end()) {
00926
00927 break;
00928 } else {
00929 single_path.push_back(end);
00930
00931 if (!end->Is_Region()) {
00932 added_op_num += BB_length(end->BB_Node());
00933 }
00934 }
00935 } else {
00936 cand = FALSE;
00937 }
00938 }
00939 } else {
00940 cand = FALSE;
00941 }
00942 }
00943
00944 if (cand) {
00945
00946
00947
00948
00949 if (!exit_prob == 0) {
00950 if ((end != main_exit)&&
00951 Find_In_Vector(end,exits) != exits.end()) {
00952
00953
00954
00955
00956
00957
00958 float prob = Compute_Completion_Prob(nodes,
00959 main_exit,main_entry);
00960
00961 if (prob < exit_prob) {
00962 cand = FALSE;
00963 }
00964 }
00965 }
00966 } else {
00967 break;
00968 }
00969 }
00970
00971 if (cand) {
00972 INT32 size = single_path.size()+nodes.size();
00973 op_num += added_op_num;
00974 if ((size < max_bb_num) && (op_num < max_op_num)) {
00975
00976 for (NODE_VECTOR_ITER path_iter = single_path.begin();path_iter != single_path.end();path_iter++) {
00977 REGIONAL_CFG_NODE *path_node = *path_iter;
00978 nodes.push_back(path_node);
00979 if (!path_node->Is_Region()) {
00980 added_op_num += BB_length(path_node->BB_Node());
00981 }
00982
00983 for (CFG_PRED_NODE_ITER pred_node_iter(path_node);pred_node_iter != 0;++pred_node_iter) {
00984 REGIONAL_CFG_NODE *pred_node = *pred_node_iter;
00985 NODE_VECTOR_ITER leaf = Find_In_Vector(pred_node,leaf_nodes);
00986
00987 if (leaf != leaf_nodes.end()) {
00988 leaf_nodes.erase(leaf);
00989 }
00990 }
00991 }
00992
00993 return added_op_num;
00994 }
00995 }
00996 }
00997 }
00998 }
00999 }
01000 }
01001
01002 return -1;
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 BOOL
01034 REGIONAL_CFG::Do_Selective_Cut(NODE_VECTOR& nodes,REGIONAL_CFG_NODE *main_entry,
01035 REGIONAL_CFG_NODE *main_exit,RGN_FORM_PAR par) {
01036 typedef std::list<REGIONAL_CFG_NODE *,NODE_ALLOC> NODE_LIST;
01037 typedef std::queue<REGIONAL_CFG_NODE *,NODE_LIST> NODE_QUEUE;
01038 NODE_ALLOC temp_alloc(&_m);
01039 NODE_VECTOR dup(temp_alloc);
01040
01041 INT32 node_nums = nodes.size();
01042 INT32 op_nums = Compute_Num_Of_Ops(nodes,FALSE);
01043
01044 INT32 max_bb_num = par.size.max_bb_num;
01045 INT32 max_op_num = par.size.max_op_num;
01046 INT32 max_dup_num = par.max_dup_num;
01047 float exit_prob = par.exit_prob;
01048 float dup_ratio = par.dup_ratio;
01049
01050 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
01051 fprintf(TFile,"Begin compute nodes to be duplicated.\n");
01052 }
01053
01054 Compute_Nodes_To_Be_Duplicated(dup,nodes,main_entry);
01055
01056 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01057 fprintf(TFile,"BBs should be duplicated are:\n");
01058 Print_Node_Vector(dup);
01059 }
01060
01061 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
01062 fprintf(TFile,"Finish compute nodes to be duplicated.\n");
01063 }
01064
01065 NODE_VECTOR leaf_nodes(temp_alloc);
01066
01067
01068
01069 for (NODE_VECTOR_ITER iter = dup.begin();iter != dup.end();iter++) {
01070 REGIONAL_CFG_NODE *node = *iter;
01071 if ((node->First_Succ() == NULL)&&(node != main_exit)) {
01072 leaf_nodes.push_back(node);
01073 } else {
01074 BOOL is_leaf = TRUE;
01075
01076 for (CFG_SUCC_NODE_ITER succ_iter(node);
01077 succ_iter != 0;++succ_iter) {
01078 if (Find_In_Vector((*succ_iter),nodes) != nodes.end()) {
01079 is_leaf = FALSE;
01080 }
01081 }
01082
01083 if ((is_leaf)&&(node != main_exit)) {
01084 leaf_nodes.push_back((*iter));
01085 }
01086 }
01087 }
01088
01089 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01090 fprintf(TFile,"The leaf nodes are:");
01091 Print_Node_Vector(leaf_nodes);
01092 }
01093
01094 NODE_VECTOR temp_dup(temp_alloc);
01095 Compute_Nodes_To_Be_Duplicated(temp_dup,nodes,main_entry);
01096 while (!(Compute_Duplicate_Ratio(nodes,temp_dup,max_bb_num,max_dup_num) <= dup_ratio)) {
01097
01098 float min_freq = 0.0;
01099 REGIONAL_CFG_NODE *to_be_cutted = NULL;
01100 INT32 added = -1;
01101 node_nums = nodes.size();
01102
01103 if ((node_nums < max_bb_num) && (op_nums < max_op_num)) {
01104 added = Do_Selective_Add(nodes,temp_dup,leaf_nodes,
01105 main_exit,main_entry,op_nums,par);
01106 op_nums += added;
01107 }
01108
01109 if (added == -1) {
01110
01111 for (NODE_VECTOR_ITER iter = leaf_nodes.begin();
01112 iter != leaf_nodes.end();iter++) {
01113
01114 if (Is_Unwanted_Node(*iter)) {
01115 to_be_cutted = *iter;
01116
01117 break;
01118 }
01119
01120 float freq = Node_Freq(*iter);
01121 if ((freq < min_freq)||(min_freq == 0.0)) {
01122 to_be_cutted = *iter;
01123 min_freq = freq;
01124 }
01125 }
01126
01127 if (to_be_cutted != NULL) {
01128 for (NODE_VECTOR_ITER iter = nodes.begin();
01129 iter != nodes.end();iter++) {
01130 if ((*iter) == to_be_cutted) {
01131 nodes.erase(iter);
01132
01133 if (!to_be_cutted->Is_Region()) {
01134 op_nums = op_nums - BB_length(to_be_cutted->BB_Node());
01135 }
01136
01137 break;
01138 }
01139 }
01140
01141
01142
01143 for (NODE_VECTOR_ITER iter = leaf_nodes.begin();
01144 iter != leaf_nodes.end();iter++) {
01145 if ((*iter) == to_be_cutted) {
01146 leaf_nodes.erase(iter);
01147
01148 break;
01149 }
01150 }
01151
01152 for (CFG_PRED_NODE_ITER pred_iter(to_be_cutted);
01153 pred_iter != 0;++pred_iter) {
01154 REGIONAL_CFG_NODE *pred = *pred_iter;
01155
01156 Is_True(pred != NULL,("Pred node is NULL in do selective cut.\n"));
01157
01158
01159
01160
01161
01162
01163
01164 if (Find_In_Vector(pred,temp_dup) != temp_dup.end()) {
01165 BOOL is_leaf = TRUE;
01166
01167 for (CFG_SUCC_NODE_ITER succ_iter(pred);
01168 succ_iter != 0;++succ_iter) {
01169 if (Find_In_Vector((*succ_iter),nodes) != nodes.end()) {
01170 is_leaf = FALSE;
01171
01172 break;
01173 }
01174 }
01175
01176 if ((is_leaf)&&(pred != main_exit)) {
01177 leaf_nodes.push_back(pred);
01178 }
01179 }
01180 }
01181
01182 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01183 fprintf(TFile,"The leaf nodes are:");
01184 Print_Node_Vector(leaf_nodes);
01185 }
01186 } else {
01187 return FALSE;
01188 }
01189 }
01190
01191 temp_dup.clear();
01192
01193
01194
01195
01196 Compute_Nodes_To_Be_Duplicated(temp_dup,nodes,main_entry);
01197 }
01198
01199 return TRUE;
01200 }
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 void
01212 REGIONAL_CFG::Compute_Side_Entries(NODE_VECTOR& side_entries,NODE_VECTOR nodes,
01213 REGIONAL_CFG_NODE *main_entry) {
01214
01215 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
01216 REGIONAL_CFG_NODE *node = *iter;
01217
01218 Is_True(node != NULL,("Node is NULL in compute side entries.\n"));
01219
01220 if (node != main_entry) {
01221
01222 for (CFG_PRED_NODE_ITER pred_iter(node);
01223 pred_iter != 0;++pred_iter) {
01224
01225 if (Find_In_Vector((*pred_iter),nodes) == nodes.end()) {
01226 side_entries.push_back(node);
01227 break;
01228 }
01229 }
01230 }
01231 }
01232 }
01233
01234
01235
01236
01237 void
01238 REGIONAL_CFG::Compute_Exits(NODE_VECTOR nodes,NODE_VECTOR& exits) {
01239 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end(); iter++) {
01240 REGIONAL_CFG_NODE *node = *iter;
01241 Is_True(node != NULL,("Node is NULL in compute exits.\n"));
01242
01243 if (node->Is_Exit()) {
01244 exits.push_back(node);
01245 } else {
01246 for (CFG_SUCC_NODE_ITER succ_iter(node);
01247 succ_iter != 0;++succ_iter) {
01248 REGIONAL_CFG_NODE *succ = *succ_iter;
01249
01250 if (Find_In_Vector(succ,nodes) == nodes.end()) {
01251 exits.push_back(node);
01252 break;
01253 }
01254 }
01255 }
01256 }
01257
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 float
01278 REGIONAL_CFG::Compute_Completion_Prob(NODE_VECTOR nodes,REGIONAL_CFG_NODE *exit,
01279 REGIONAL_CFG_NODE *main_entry) {
01280 NODE_ALLOC temp_alloc(&_m);
01281 NODE_VECTOR exits(temp_alloc);
01282
01283 if (nodes.size() == 1) {
01284 float prob = 1.0;
01285 return prob;
01286 }
01287
01288 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01289 fprintf(TFile,"The exit nodes are:\n");
01290 }
01291
01292 Compute_Exits(nodes,exits);
01293
01294 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01295 Print_Node_Vector(exits);
01296 }
01297
01298 NODE_VECTOR dup(temp_alloc);
01299 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01300 fprintf(TFile,"The nodes to be duplicated are:\n");
01301 }
01302
01303 Compute_Nodes_To_Be_Duplicated(dup,nodes,main_entry);
01304
01305 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
01306 Print_Node_Vector(dup);
01307 }
01308
01309 PROF_ALLOC prof_alloc(&_m);
01310 NODE_PROF_VECTOR node_profs(prof_alloc);
01311
01312 Compute_Node_Prof_Info(nodes,dup,main_entry,node_profs);
01313
01314
01315
01316 float exit_freq = 0.0;
01317 Is_True(!exits.empty(),("No exit node of this node set,is it possible?"));
01318 for (NODE_VECTOR_ITER iter = exits.begin();iter != exits.end();iter++) {
01319 REGIONAL_CFG_NODE *node = *iter;
01320 Is_True(node != NULL,("Node is NULL in compute completion prob.\n"));
01321
01322 if (node->First_Succ() != NULL) {
01323
01324 if (Find_In_Vector(node,dup) != dup.end()) {
01325
01326 for (NODE_PROF_VECTOR_ITER prof_iter = node_profs.begin();
01327 prof_iter != node_profs.end();prof_iter++) {
01328 NODE_PROF p = *prof_iter;
01329
01330 if ((p.src == node) &&
01331 Find_In_Vector(p.dest,nodes) == nodes.end()) {
01332 exit_freq += p.freq;
01333 }
01334 }
01335 } else {
01336 for (CFG_SUCC_EDGE_ITER succ_iter(node);
01337 succ_iter != 0;++succ_iter) {
01338 REGIONAL_CFG_NODE *succ = (*succ_iter)->Dest();
01339
01340 if (Find_In_Vector(succ,nodes) == nodes.end()) {
01341 exit_freq += (*succ_iter)->Freq();
01342 }
01343 }
01344 }
01345 } else if (node->First_Pred() != NULL){
01346
01347 if (Find_In_Vector(node,dup) != dup.end()) {
01348
01349 for (NODE_PROF_VECTOR_ITER prof_iter = node_profs.begin();
01350 prof_iter != node_profs.end();prof_iter++) {
01351 NODE_PROF p = *prof_iter;
01352
01353 if (p.dest == node) {
01354 exit_freq += p.freq;
01355 }
01356 }
01357 } else {
01358
01359
01360
01361
01362
01363
01364 for (CFG_PRED_EDGE_ITER pred_iter(node);
01365 pred_iter != 0;++pred_iter) {
01366 REGIONAL_CFG_NODE *pred = (*pred_iter)->Src();
01367
01368 if (Find_In_Vector(pred,nodes) != nodes.end()) {
01369 exit_freq += (*pred_iter)->Freq();
01370 }
01371 }
01372 }
01373 } else {
01374 FmtAssert(FALSE,("An exit without pred and succ will not be dealt with"));
01375 }
01376 }
01377
01378 float main_exit_freq = 0.0;
01379
01380
01381
01382 if (exit->First_Succ() != NULL) {
01383 if (Find_In_Vector(exit,dup) != dup.end()) {
01384
01385 for (NODE_PROF_VECTOR_ITER prof_iter = node_profs.begin();
01386 prof_iter != node_profs.end();prof_iter++) {
01387 NODE_PROF p = *prof_iter;
01388
01389 if ((p.src == exit) && (Find_In_Vector(p.dest,nodes) == nodes.end())) {
01390 main_exit_freq += p.freq;
01391 }
01392 }
01393 } else {
01394 for (CFG_SUCC_EDGE_ITER succ_iter(exit);
01395 succ_iter != 0;++succ_iter) {
01396 REGIONAL_CFG_NODE *succ = (*succ_iter)->Dest();
01397 main_exit_freq += (*succ_iter)->Freq();
01398 }
01399 }
01400 } else if (exit->First_Pred() != NULL) {
01401 if (Find_In_Vector(exit,dup) != dup.end()) {
01402
01403 for (NODE_PROF_VECTOR_ITER prof_iter = node_profs.begin();
01404 prof_iter != node_profs.end();prof_iter++) {
01405 NODE_PROF p = *prof_iter;
01406
01407 if (p.dest == exit) {
01408 main_exit_freq += p.freq;
01409 }
01410 }
01411 } else {
01412 for (CFG_PRED_EDGE_ITER pred_iter(exit);
01413 pred_iter != 0;++pred_iter) {
01414 REGIONAL_CFG_NODE *pred = (*pred_iter)->Src();
01415
01416 if (Find_In_Vector(pred,nodes) != nodes.end()) {
01417 main_exit_freq += (*pred_iter)->Freq();
01418 }
01419 }
01420 }
01421 } else {
01422 FmtAssert(FALSE,("An exit without pred and succ will not be dealt with"));
01423 }
01424
01425 float prob = 0.0;
01426 if (exit_freq == 0.0) {
01427 DevWarn("Exit prob is zero for main exit %d.\n",exit->Id());
01428 prob = 1.0;
01429 return prob;
01430 }
01431 prob = main_exit_freq/exit_freq;
01432 return prob;
01433 }
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 void
01449 REGIONAL_CFG::Compute_Scope_Based_On_Main_Exit(NODE_VECTOR& scope,
01450 NODE_VECTOR nodes,REGIONAL_CFG_NODE *exit) {
01451 typedef std::list<REGIONAL_CFG_NODE *,NODE_ALLOC> NODE_LIST;
01452 typedef std::queue<REGIONAL_CFG_NODE *,NODE_LIST> NODE_QUEUE;
01453
01454 NODE_ALLOC temp_alloc(&_m);
01455 NODE_LIST temp_list(temp_alloc);
01456 NODE_QUEUE queue(temp_list);
01457
01458 BS *cutted = BS_Create_Empty(2+_seq_num, &_m);
01459 BS *visited = BS_Create_Empty(2+_seq_num,&_m);
01460
01461
01462
01463
01464 for (CFG_SUCC_NODE_ITER iter(exit);iter != 0;++iter) {
01465 REGIONAL_CFG_NODE *node = *iter;
01466 Is_True(node != NULL,("Node is NULL in compute scope based on main exit."));
01467 BS_Union1D(cutted, node->Id(), &_m);
01468 queue.push(node);
01469 }
01470
01471
01472
01473
01474 while (!queue.empty()) {
01475 REGIONAL_CFG_NODE *node = queue.front();
01476 Is_True(node != NULL,("Node is NULL in compute scope based on main exit."));
01477 queue.pop();
01478
01479 for (CFG_SUCC_NODE_ITER succ_iter(node);succ_iter != 0;++succ_iter) {
01480 REGIONAL_CFG_NODE *succ = *succ_iter;
01481 Is_True(succ != NULL,("The succ of node is NULL."));
01482 if ((!BS_MemberP(visited,succ->Id()))&&
01483 Find_In_Vector(succ,nodes) != nodes.end()) {
01484 BS_Union1D(visited,node->Id(),&_m);
01485 BOOL is_cutted = TRUE;
01486
01487 for (CFG_PRED_NODE_ITER pred_iter(succ);
01488 pred_iter != 0;++pred_iter) {
01489 Is_True(*pred_iter != NULL,("Pred of succ is NULL in compute scope based on main exit."));
01490
01491
01492
01493
01494 if (!BS_MemberP(cutted,(*pred_iter)->Id())&&
01495 Find_In_Vector((*pred_iter),nodes) != nodes.end()) {
01496 is_cutted = FALSE;
01497 break;
01498 }
01499 }
01500
01501 if (is_cutted) {
01502 BS_Union1D(cutted,succ->Id(),&_m);
01503 queue.push(succ);
01504 }
01505 }
01506 }
01507 }
01508
01509 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
01510 REGIONAL_CFG_NODE *node = *iter;
01511 Is_True(node != NULL,("Node is NULL in compute scope based on main exit."));
01512
01513 if (!BS_MemberP(cutted,node->Id())) {
01514 scope.push_back(node);
01515 }
01516 }
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539 float
01540 REGIONAL_CFG::Compute_Duplicate_Ratio(NODE_VECTOR nodes,
01541 NODE_VECTOR& duplicated,INT32 max_bb_num,INT32 max_dup_num) {
01542 Is_True(!nodes.empty(),("Node set is empty in compute duplicate ratio."));
01543
01544 float dup_ops_num = 0.0;
01545
01546 if (!duplicated.empty()) {
01547
01548
01549
01550 dup_ops_num = (float)Compute_Num_Of_Ops(duplicated,TRUE);
01551 }
01552
01553 float ratio = 0.0;
01554
01555 if (dup_ops_num < 0.0) {
01556 ratio = 2.5;
01557 } else {
01558 INT32 dup_bbs_num = 0;
01559 for (NODE_VECTOR_ITER iter = duplicated.begin();
01560 iter != duplicated.end();iter++) {
01561 REGIONAL_CFG_NODE *node = *iter;
01562 if (!node->Is_Region()) {
01563 dup_bbs_num++;
01564 } else {
01565 BB_VECTOR bbs;
01566 Compute_BBs_In_Region_Node(bbs,node);
01567 dup_bbs_num += bbs.size();
01568 }
01569 }
01570
01571
01572
01573
01574
01575
01576
01577 float bb_ratio = 0;
01578 if (dup_bbs_num > max_dup_num) {
01579
01580
01581
01582 bb_ratio = 2.5;
01583 } else {
01584 bb_ratio = (float)dup_bbs_num / max_bb_num;
01585 bb_ratio = bb_ratio + 1.0;
01586 }
01587
01588 if (bb_ratio > ratio) {
01589 ratio = bb_ratio;
01590 }
01591 }
01592
01593 return ratio;
01594 }
01595
01596
01597
01598
01599
01600
01601
01602
01603 void
01604 REGIONAL_CFG::Compute_Nodes_To_Be_Duplicated(NODE_VECTOR& dup_nodes,
01605 NODE_VECTOR nodes,REGIONAL_CFG_NODE *main_entry) {
01606 typedef std::list<REGIONAL_CFG_NODE *,NODE_ALLOC> NODE_LIST;
01607 typedef std::queue<REGIONAL_CFG_NODE *,NODE_LIST> NODE_QUEUE;
01608
01609 NODE_ALLOC temp_alloc(&_m);
01610 NODE_LIST temp_list(temp_alloc);
01611 NODE_QUEUE queue(temp_list);
01612 queue.push(main_entry);
01613
01614 BS *visited = BS_Create_Empty(2+_seq_num,&_m);
01615 BS_Union1D(visited,main_entry->Id(),&_m);
01616
01617 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
01618 fprintf(TFile,"The main entry is:\n");
01619 main_entry->Print();
01620 }
01621
01622 while (!queue.empty()) {
01623 REGIONAL_CFG_NODE *node = queue.front();
01624 Is_True(node != NULL,("Node is NULL in compute nodes to be duplicated."));
01625 queue.pop();
01626
01627 for (CFG_SUCC_NODE_ITER succ_iter(node);succ_iter != 0;++succ_iter) {
01628 REGIONAL_CFG_NODE *succ = *succ_iter;
01629 Is_True(succ != NULL,("Succ is NULL in compute nodes to be duplicated."));
01630 BOOL all_pred_visited = TRUE;
01631
01632 for (CFG_PRED_NODE_ITER iter(succ);iter != 0;++iter) {
01633
01634 if (!BS_MemberP(visited,(*iter)->Id())
01635 && Find_In_Vector((*iter),nodes) != nodes.end()) {
01636 all_pred_visited = FALSE;
01637 }
01638 }
01639
01640
01641
01642 if ((!BS_MemberP(visited,succ->Id())) &&
01643 Find_In_Vector(succ,nodes) != nodes.end() &&
01644 all_pred_visited) {
01645 BS_Union1D(visited,succ->Id(),&_m);
01646 queue.push(succ);
01647
01648 for (CFG_PRED_NODE_ITER pred_iter(succ);
01649 pred_iter != 0;++pred_iter) {
01650
01651 if (Find_In_Vector((*pred_iter),nodes) == nodes.end()) {
01652 dup_nodes.push_back(succ);
01653 break;
01654 } else if (Find_In_Vector((*pred_iter),dup_nodes) != dup_nodes.end()) {
01655 if (Find_In_Vector(succ,dup_nodes) == dup_nodes.end()) {
01656 dup_nodes.push_back(succ);
01657 }
01658
01659 break;
01660 }
01661 }
01662 }
01663 }
01664 }
01665 }
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685 INT32
01686 REGIONAL_CFG::Compute_Num_Of_Ops(NODE_VECTOR nodes,BOOL is_dup) {
01687 INT32 num_of_ops = 0;
01688 BOOL has_unwanted_bb = FALSE;
01689
01690 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
01691 REGIONAL_CFG_NODE *node = *iter;
01692 Is_True(node != NULL,("Node is NULL in compute number of ops."));
01693 has_unwanted_bb = Is_Unwanted_Node(node);
01694 if (has_unwanted_bb) {
01695 break;
01696 }
01697
01698 if (!node->Is_Region()) {
01699 BB *bb = node->BB_Node();
01700 num_of_ops += BB_length(node->BB_Node());
01701 } else if (is_dup) {
01702 BB_VECTOR bbs;
01703
01704 Compute_BBs_In_Region_Node(bbs,node);
01705
01706 for (BB_VECTOR_ITER iter = bbs.begin();iter != bbs.end();iter++) {
01707 Is_True(*iter != NULL,("The BB is NULL in compute number of ops."));
01708 num_of_ops += BB_length((*iter));
01709 }
01710 }
01711 }
01712
01713 if (has_unwanted_bb) {
01714 num_of_ops = -1;
01715 }
01716
01717 return num_of_ops;
01718 }
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731 REGIONAL_CFG_NODE*
01732 REGIONAL_CFG::Find_Seed(NODE_VECTOR bad_nodes) {
01733 REGIONAL_CFG_NODE *seed = NULL;
01734
01735 float freq = 0.0;
01736 float max_freq = -1;
01737
01738 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(this);iter != 0;++iter) {
01739 REGIONAL_CFG_NODE *node = *iter;
01740 freq = Node_Freq(node);
01741 BOOL is_improper = FALSE;
01742 if (node->Is_Region()) {
01743 REGION *r = node->Region_Node();
01744
01745 if (r->Region_Type() == IMPROPER) {
01746 is_improper = TRUE;
01747 }
01748 }
01749
01750 if ((freq > max_freq)&&(!is_improper) &&
01751 Find_In_Vector(node,bad_nodes) == bad_nodes.end() &&
01752 !node->Is_Loop_Tail() && !node->Is_Region()) {
01753
01754
01755 seed = node;
01756 max_freq = freq;
01757 }
01758 }
01759
01760 return seed;
01761 }
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 REGIONAL_CFG_EDGE*
01772 REGIONAL_CFG::Select_Freq_Succ(REGIONAL_CFG_NODE *node,NODE_VECTOR nodes) {
01773 float freq;
01774 float max_freq = -1;
01775 REGIONAL_CFG_EDGE *result = NULL;
01776
01777 for (CFG_SUCC_EDGE_ITER iter(node);iter != 0;++iter) {
01778 REGIONAL_CFG_EDGE *succ = *iter;
01779 REGIONAL_CFG_NODE *succ_node = succ->Dest();
01780
01781 if (Find_In_Vector(succ_node,nodes) == nodes.end()) {
01782
01783 freq = Edge_Freq(succ);
01784
01785 BOOL is_improper = FALSE;
01786
01787 if (succ_node->Is_Region()) {
01788 REGION *r = succ_node->Region_Node();
01789 if (r->Region_Type() == IMPROPER) {
01790 is_improper = TRUE;
01791 }
01792 }
01793
01794 if ((freq > max_freq)&& (!is_improper)
01795 &&(!succ_node->Is_Loop_Tail())) {
01796
01797
01798 max_freq = freq;
01799 result = succ;
01800
01801 }
01802 }
01803 }
01804
01805 return result;
01806 }
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816 REGIONAL_CFG_EDGE*
01817 REGIONAL_CFG::Select_Freq_Pred(REGIONAL_CFG_NODE *node,NODE_VECTOR nodes,NODE_VECTOR bad_nodes) {
01818 float freq;
01819 float max_freq = -1;
01820 REGIONAL_CFG_EDGE *result = NULL;
01821
01822 for (CFG_PRED_EDGE_ITER iter(node);iter != 0;++iter) {
01823 REGIONAL_CFG_EDGE *pred = *iter;
01824 Is_True(pred != NULL,("The pred edge is NULL in select freq pred."));
01825
01826 REGIONAL_CFG_NODE *pred_node = pred->Src();
01827 Is_True(pred_node != NULL,("The src node of pred edge is NULL in select freq pred."));
01828
01829 if (Find_In_Vector(pred_node,nodes) == nodes.end()) {
01830 freq = Edge_Freq(pred);
01831
01832 BOOL is_improper = FALSE;
01833
01834 if (pred_node->Is_Region()) {
01835 REGION *r = pred_node->Region_Node();
01836 Is_True(r != NULL,("Node's region node is NULL in select freq pred."));
01837
01838 if (r->Region_Type() == IMPROPER) {
01839 is_improper = TRUE;
01840 }
01841 }
01842
01843 if ((freq > max_freq)&&(!is_improper)
01844 &&(Find_In_Vector(pred_node,bad_nodes) == bad_nodes.end())
01845 &&(!pred_node->Is_Loop_Tail())) {
01846
01847
01848 max_freq = freq;
01849 result = pred;
01850 }
01851 }
01852 }
01853
01854 return result;
01855 }
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871 REGIONAL_CFG_NODE*
01872 REGIONAL_CFG::Select_Freq_Connected_Node(NODE_VECTOR nodes,REGIONAL_CFG_NODE *last_node) {
01873
01874
01875 float max_freq = -1;
01876 REGIONAL_CFG_NODE *result = NULL;
01877
01878 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();++iter) {
01879 REGIONAL_CFG_NODE *node = *iter;
01880 Is_True(node != NULL,("Node is NULL in select freq connected node."));
01881
01882 for (CFG_SUCC_NODE_ITER succ_iter(node);succ_iter != 0;++succ_iter) {
01883
01884 float pred_freq = -1;
01885 float succ_freq = -1;
01886 float freq = -1;
01887
01888 REGIONAL_CFG_NODE *cand = *succ_iter;
01889 if (Find_In_Vector(cand,nodes) == nodes.end()) {
01890 pred_freq = 0.0;
01891 succ_freq = 0.0;
01892 freq = 0.0;
01893
01894 for (CFG_PRED_EDGE_ITER pred_edge_iter(cand);
01895 pred_edge_iter != 0;++pred_edge_iter) {
01896 REGIONAL_CFG_NODE *pred = (*pred_edge_iter)->Src();
01897
01898 if (Find_In_Vector(pred,nodes) != nodes.end()) {
01899 pred_freq += Edge_Freq((*pred_edge_iter));
01900 }
01901 }
01902
01903 for (CFG_SUCC_EDGE_ITER succ_edge_iter(cand);
01904 succ_edge_iter != 0;++succ_edge_iter) {
01905 REGIONAL_CFG_NODE *succ = (*succ_edge_iter)->Dest();
01906
01907 if (Find_In_Vector(succ,nodes) != nodes.end()) {
01908 succ_freq += Edge_Freq((*succ_edge_iter));
01909 }
01910 }
01911 }
01912
01913 freq = pred_freq;
01914 if ((pred_freq != -1)&&(succ_freq != -1)) {
01915 freq += succ_freq;
01916 freq = freq*2.0;
01917 }
01918
01919 BOOL is_improper = FALSE;
01920
01921
01922
01923
01924
01925
01926
01927 if (cand->Is_Region()) {
01928 REGION *r = cand->Region_Node();
01929
01930 if (r->Region_Type() == IMPROPER) {
01931 is_improper = TRUE;
01932 }
01933 }
01934
01935 BOOL is_last = FALSE;
01936 for (CFG_PRED_NODE_ITER pred_iter(cand);
01937 pred_iter != 0;++pred_iter) {
01938 if (*pred_iter == last_node) {
01939 is_last = TRUE;
01940
01941 break;
01942 }
01943 }
01944
01945
01946
01947 if ((freq > max_freq)&&(!is_improper)&&(!is_last)
01948 &&(!cand->Is_Loop_Tail())) {
01949
01950
01951 max_freq = freq;
01952 result = cand;
01953 }
01954 }
01955 }
01956
01957 return result;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967 BOOL
01968 REGIONAL_CFG::Succ_Suit(REGIONAL_CFG_EDGE *edge,float seed_freq,float T,float Ts) {
01969 REGIONAL_CFG_NODE *node;
01970 float t_succ = 0.0;
01971 float ts_succ = 0.0;
01972
01973 node = edge->Dest();
01974 float node_freq = Node_Freq(node);
01975 if (node_freq == 0.0) {
01976 t_succ = 1.0;
01977 } else {
01978 t_succ = Edge_Freq(edge) / node_freq;
01979 }
01980
01981 if (seed_freq == 0.0) {
01982 ts_succ = 1.0;
01983 } else {
01984 ts_succ = node_freq / seed_freq;
01985 }
01986
01987 if ((t_succ > T) && (ts_succ > Ts)) {
01988 return TRUE;
01989 }
01990
01991 return FALSE;
01992 }
01993
01994
01995
01996
01997
01998
01999
02000
02001 BOOL
02002 REGIONAL_CFG::Pred_Suit(REGIONAL_CFG_EDGE *edge,float seed_freq,
02003 float T,float Ts) {
02004 REGIONAL_CFG_NODE *node;
02005 float t_pred = 0.0;
02006 float ts_pred = 0.0;
02007
02008 node = edge->Src();
02009 float node_freq = Node_Freq(node);
02010 if (node_freq ==0.0) {
02011 t_pred = 1.0;
02012 } else {
02013 t_pred = Edge_Freq(edge) / node_freq;
02014 }
02015
02016 if (seed_freq == 0.0) {
02017 ts_pred = 1.0;
02018 } else {
02019 ts_pred = node_freq / seed_freq;
02020 }
02021
02022 if ((t_pred > T) && (ts_pred > Ts)) {
02023 return TRUE;
02024 }
02025
02026 return FALSE;
02027 }
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041 void
02042 REGIONAL_CFG::Compute_Edges_Freq(void) {
02043 typedef std::list<REGIONAL_CFG_NODE *,NODE_ALLOC> NODE_LIST;
02044 typedef std::queue<REGIONAL_CFG_NODE *,NODE_LIST> NODE_QUEUE;
02045
02046 NODE_ALLOC temp_alloc(&_m);
02047 NODE_LIST temp_list(temp_alloc);
02048 BS *bb_exits = BS_Create_Empty(2+PU_BB_Count, &_m);
02049 BS *bb_entries = BS_Create_Empty(2+PU_BB_Count, &_m);
02050 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(this);iter != 0; ++iter) {
02051 BS_ClearD(bb_exits);
02052 NODE_VECTOR node_exits(temp_alloc);
02053
02054 REGIONAL_CFG_NODE *node = *iter;
02055 float total_freq = 0.0;
02056
02057 if (node->First_Succ() == NULL) {
02058
02059 if (node->First_Pred() != NULL) {
02060 for (CFG_PRED_EDGE_ITER pred_iter(node);
02061 pred_iter != 0;++pred_iter) {
02062 total_freq += (*pred_iter)->Freq();
02063 }
02064
02065 node->Freq(total_freq);
02066 } else {
02067 if (node->Is_Region()) {
02068 DevWarn("Will we meet a node with only iteself?");
02069 node->Freq(1.0);
02070 } else {
02071 node->Freq(BB_freq(node->BB_Node()));
02072 }
02073 }
02074
02075 continue;
02076 }
02077
02078 if (node->Is_Region()) {
02079
02080
02081
02082 NODE_QUEUE que(temp_list);
02083 que.push(node);
02084
02085 while (!que.empty()) {
02086 REGIONAL_CFG_NODE *region_exit = que.front();
02087 que.pop();
02088 NODE_VECTOR exits = (region_exit->Region_Node())->Exits();
02089
02090 for (NODE_VECTOR_ITER exit_iter = exits.begin();
02091 exit_iter != exits.end();exit_iter++) {
02092 REGIONAL_CFG_NODE *exit = *exit_iter;
02093
02094 if (exit->Is_Region()) {
02095 que.push(exit);
02096 } else {
02097 BS_Union1D(bb_exits, BB_id(exit->BB_Node()), &_m);
02098 node_exits.push_back(exit);
02099 }
02100 }
02101 }
02102 }
02103
02104
02105
02106
02107
02108
02109 if (node->Is_Region()) {
02110 for (NODE_VECTOR_ITER iter = node_exits.begin();
02111 iter != node_exits.end(); iter++) {
02112 BBLIST *succ_list;
02113 REGIONAL_CFG_NODE *exit = *iter;
02114 BB *src = exit->BB_Node();
02115
02116 total_freq += BB_freq(src);
02117 }
02118 } else {
02119 total_freq = BB_freq(node->BB_Node());
02120 }
02121
02122
02123
02124
02125 for (CFG_SUCC_EDGE_ITER succ_iter(node);succ_iter != 0; ++succ_iter) {
02126
02127 REGIONAL_CFG_NODE *succ = (*succ_iter)->Dest();
02128
02129 if (succ->Is_Region()) {
02130 NODE_QUEUE que;
02131 BS_ClearD(bb_entries);
02132
02133 que.push(succ);
02134
02135
02136
02137
02138 while (!que.empty()) {
02139 REGIONAL_CFG_NODE *region_entry = que.front();
02140 que.pop();
02141
02142 NODE_VECTOR entries = (region_entry->Region_Node())->Entries();
02143
02144 for (NODE_VECTOR_ITER entry_iter = entries.begin();
02145 entry_iter != entries.end();entry_iter++) {
02146 REGIONAL_CFG_NODE *entry = *entry_iter;
02147 if (entry->Is_Region()) {
02148 que.push(entry);
02149 } else {
02150 BS_Union1D(bb_entries, BB_id(entry->BB_Node()), &_m);
02151 }
02152 }
02153 }
02154
02155
02156
02157
02158 if (!node->Is_Region()) {
02159 float freq = 0;
02160 BBLIST *succ_list;
02161 BB *src = node->BB_Node();
02162
02163
02164 for (succ_list = BB_succs(src);succ_list != NULL;
02165 succ_list = BBLIST_next(succ_list)) {
02166 BB *bb = BBLIST_item(succ_list);
02167
02168 if (BS_MemberP(bb_entries,BB_id(bb))) {
02169 freq += BB_freq(src)*BBLIST_prob(succ_list);
02170 }
02171 }
02172
02173 (*succ_iter)->Freq(freq);
02174 } else {
02175 float freq = 0;
02176
02177 for (NODE_VECTOR_ITER iter = node_exits.begin();
02178 iter != node_exits.end(); iter++) {
02179 BBLIST *succ_list;
02180 REGIONAL_CFG_NODE *exit = *iter;
02181 BB *src = exit->BB_Node();
02182
02183 for (succ_list = BB_succs(src);succ_list != NULL;
02184 succ_list = BBLIST_next(succ_list)) {
02185 BB *bb = BBLIST_item(succ_list);
02186
02187 if (BS_MemberP(bb_entries,BB_id(bb))) {
02188 freq += BB_freq(src)*BBLIST_prob(succ_list);
02189 }
02190 }
02191 }
02192
02193 (*succ_iter)->Freq(freq);
02194 }
02195 } else {
02196 if (!node->Is_Region()) {
02197 BB *src = node->BB_Node();
02198 BB *dest = succ->BB_Node();
02199 BBLIST *succ_list;
02200
02201 for (succ_list = BB_succs(src);succ_list != NULL;
02202 succ_list = BBLIST_next(succ_list)) {
02203 BB *bb = BBLIST_item(succ_list);
02204 if (bb == dest) {
02205 (*succ_iter)->Freq((BB_freq(src))*(BBLIST_prob(succ_list)));
02206
02207 break;
02208 }
02209 }
02210 } else {
02211 float freq = 0;
02212 BB *dest = succ->BB_Node();
02213
02214 for (NODE_VECTOR_ITER iter = node_exits.begin();
02215 iter != node_exits.end();iter++) {
02216 BB *bb = (*iter)->BB_Node();
02217 BBLIST *succ_list;
02218
02219 for (succ_list = BB_succs(bb);succ_list != NULL;
02220 succ_list = BBLIST_next(succ_list)) {
02221 BB *succ = BBLIST_item(succ_list);
02222
02223 if (succ == dest) {
02224 freq += BB_freq(bb)*BBLIST_prob(succ_list);
02225
02226 break;
02227 }
02228 }
02229 }
02230
02231 (*succ_iter)->Freq(freq);
02232 }
02233 }
02234 }
02235
02236 if (total_freq == 0.0) {
02237
02238 }
02239
02240 node->Freq(total_freq);
02241
02242
02243
02244 for (CFG_SUCC_EDGE_ITER succ_iter(node);succ_iter != 0;++succ_iter) {
02245 float prob = 0.0;
02246 if (total_freq == 0.0) {
02247 prob = 0.0;
02248 } else {
02249 prob = (*succ_iter)->Freq()/total_freq;
02250 }
02251 (*succ_iter)->Prob(prob);
02252 }
02253 }
02254 }
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264 void
02265 REGIONAL_CFG::Find_BBs_From_Nodes(BB_VECTOR& bbs,NODE_VECTOR nodes) {
02266
02267 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
02268 REGIONAL_CFG_NODE *node = *iter;
02269 Is_True(node != NULL,("The node is NULL in find bbs from nodes."));
02270
02271 if (node->Is_Region()) {
02272 Compute_BBs_In_Region_Node(bbs,node);
02273 } else {
02274 bbs.push_back(node->BB_Node());
02275 }
02276 }
02277 }
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287 void
02288 REGIONAL_CFG::Compute_BBs_In_Region_Node(BB_VECTOR& bbs,REGIONAL_CFG_NODE *node) {
02289 Is_True(node->Is_Region(),("Not a region node!\n"));
02290
02291 NODE_ALLOC temp_alloc(&_m);
02292 NODE_VECTOR temp_vector(temp_alloc);
02293 NODE_STACK region_nodes(temp_vector);
02294 region_nodes.push(node);
02295
02296 while (!region_nodes.empty()) {
02297 REGION *r = (region_nodes.top())->Region_Node();
02298 REGIONAL_CFG *cfg = r->Regional_Cfg();
02299 Is_True(cfg != NULL,("Cfg is NULL in compute BBs in region node."));
02300 region_nodes.pop();
02301
02302 for (SEQ_REGIONAL_CFG_ITER iter(cfg);iter != 0;++iter) {
02303 REGIONAL_CFG_NODE *n = *iter;
02304 Is_True(n != NULL,("Node is NULL in compute BBs in region node."));
02305
02306 if (n->Is_Region()) {
02307 region_nodes.push(n);
02308 } else {
02309 bbs.push_back(n->BB_Node());
02310 }
02311 }
02312 }
02313 }
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328 void
02329 REGIONAL_CFG::Tail_Duplicate(NODE_VECTOR& nodes,REGIONAL_CFG_NODE *main_entry,
02330 INT32& dup_bb_num,INT32& dup_op_num,BOOL re_shrink) {
02331 typedef std::list<BB *,BB_ALLOC> BB_LIST;
02332 typedef std::queue<BB *,BB_LIST> BB_QUEUE;
02333
02334 NODE_ALLOC temp_alloc(&_m);
02335 NODE_VECTOR dup_nodes(temp_alloc);
02336 BB_ALLOC bb_temp_alloc(&_m);
02337 BB_VECTOR bbs(bb_temp_alloc);
02338
02339 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02340 fprintf(TFile,"Begin compute nodes to be duplicated.\n");
02341 }
02342
02343 Compute_Nodes_To_Be_Duplicated(dup_nodes,nodes,main_entry);
02344
02345 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02346 fprintf(TFile,"The nodes should be duplicated are:\n");
02347 Print_Node_Vector(dup_nodes);
02348 }
02349
02350 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02351 fprintf(TFile,"Finish compute nodes to be duplicated.\n");
02352 }
02353
02354 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02355 fprintf(TFile,"Begin to find BBs from nodes.\n");
02356 }
02357
02358 Find_BBs_From_Nodes(bbs,nodes);
02359
02360 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02361 fprintf(TFile,"Finish find BBs from nodes.\n");
02362 }
02363
02364 BB* last_duplicated;
02365 BB* entry;
02366
02367 BB_MAP duplicate = BB_MAP_Create();
02368 BB_MAP rev_duplicate = BB_MAP_Create();
02369 BB_VECTOR duplicate_bbs(bb_temp_alloc);
02370 BB_VECTOR br_bbs(bb_temp_alloc);
02371
02372 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02373 fprintf(TFile,"Begin find the main entry bb of the bbs.\n");
02374 }
02375
02376
02377
02378 if (main_entry->Is_Region()) {
02379 REGIONAL_CFG_NODE *entry_node = main_entry;
02380
02381 while (entry_node->Is_Region()) {
02382 NODE_VECTOR entries(temp_alloc);
02383 entries = (entry_node->Region_Node())->Entries();
02384
02385 for (NODE_VECTOR_ITER iter = entries.begin();
02386 iter != entries.end();iter++) {
02387 if ((*iter)->First_Pred() == NULL) {
02388 entry_node = *iter;
02389 break;
02390 }
02391 }
02392 }
02393
02394 entry = entry_node->BB_Node();
02395 } else {
02396 entry = main_entry->BB_Node();
02397 }
02398
02399 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02400 fprintf(TFile,"The main entry bb is: %d\n",BB_id(entry));
02401 }
02402
02403 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02404 fprintf(TFile,"Finish find main entry bb of the bbs.\n");
02405 }
02406
02407 BB *bb;
02408 for (bb = entry; bb && Find_In_BB_Vector(bb,bbs) != bbs.end();
02409 last_duplicated = bb,bb = BB_next(bb));
02410
02411 if (bb) {
02412 for (; bb && BB_Fall_Thru_Successor(bb); bb = BB_next(bb));
02413 last_duplicated = bb;
02414 }
02415
02416
02417
02418 BB_VECTOR need_duplicate(bb_temp_alloc);
02419
02420 BS *unduplicated = BS_Create_Empty(PU_BB_Count+2,&_m);
02421
02422 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02423 fprintf(TFile,"Begin find bbs need to be duplicated.\n");
02424 }
02425
02426 Compute_BBs_Need_Duplicate(need_duplicate,unduplicated,dup_nodes);
02427
02428 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02429 fprintf(TFile,"BBs should be duplicated:\n");
02430 Print_BB_Vector(need_duplicate);
02431 }
02432
02433 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02434 fprintf(TFile,"Finish find bbs need to be duplicated.\n");
02435 }
02436
02437 BOOL has_cycle = FALSE;
02438
02439
02440
02441 BB_LIST bb_temp_list(bb_temp_alloc);
02442 BB_QUEUE entries(bb_temp_list);
02443
02444 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02445 fprintf(TFile,"Begin compute side entries of bbs.\n");
02446 }
02447
02448 for (BB_VECTOR_ITER iter = need_duplicate.begin();
02449 iter != need_duplicate.end();iter++) {
02450 BB *bb = *iter;
02451 BBLIST *preds;
02452 BOOL is_side_entry = TRUE;
02453
02454 FOR_ALL_BB_PREDS(bb,preds) {
02455 BB *pred = BBLIST_item(preds);
02456 BOOL is_cycle = FALSE;
02457
02458 for (GLOBAL_CYCLE_VECTOR_ITER cycle_iter = global_cycles.begin();
02459 cycle_iter != global_cycles.end();cycle_iter++) {
02460 if ((bb == (*cycle_iter).dest)&&(pred == (*cycle_iter).src)) {
02461 is_cycle = TRUE;
02462 has_cycle = TRUE;
02463 }
02464 }
02465
02466 if (BS_MemberP(unduplicated,BB_id(pred))&&(!is_cycle)) {
02467 is_side_entry = FALSE;
02468 }
02469
02470 }
02471
02472 if (is_side_entry) {
02473 entries.push(bb);
02474
02475 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02476 fprintf(TFile,"The side entry is %d\n",BB_id((*iter)));
02477 }
02478 }
02479 }
02480
02481 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02482 fprintf(TFile,"Finish compute side entries.\n Begin to do duplicate.\n");
02483 }
02484
02485 while (!entries.empty()) {
02486 BB *side_entry = entries.front();
02487 entries.pop();
02488
02489
02490 Duplicate(bbs,side_entry,entry,duplicate,rev_duplicate,
02491 &last_duplicated,duplicate_bbs,br_bbs);
02492 dup_bb_num = dup_bb_num + br_bbs.size() + 1;
02493 dup_op_num = dup_op_num + br_bbs.size() + BB_length(side_entry);
02494
02495 BS_Difference1D(unduplicated,BB_id(side_entry));
02496 BBLIST *succs;
02497 FOR_ALL_BB_SUCCS(side_entry,succs) {
02498 BB *succ = BBLIST_item(succs);
02499
02500 if (BS_MemberP(unduplicated,BB_id(succ))) {
02501 BOOL has_unduplicated_pred = FALSE;
02502 BBLIST *preds;
02503
02504 FOR_ALL_BB_PREDS(succ, preds) {
02505 BB *pred = BBLIST_item(preds);
02506 BOOL is_global_cycle = FALSE;
02507
02508 if (has_cycle) {
02509 for (GLOBAL_CYCLE_VECTOR_ITER iter = global_cycles.begin();iter != global_cycles.end();iter++) {
02510 if (((*iter).src == pred)&&((*iter).dest == succ)) {
02511 is_global_cycle = TRUE;
02512
02513 }
02514 }
02515 }
02516
02517 if (BS_MemberP(unduplicated,BB_id(pred))
02518 &&!is_global_cycle) {
02519 has_unduplicated_pred = TRUE;
02520
02521 break;
02522 }
02523 }
02524
02525 if (!has_unduplicated_pred) {
02526 entries.push(succ);
02527 }
02528 }
02529 }
02530 }
02531
02532 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02533 fprintf(TFile,"Finish do duplication.\n");
02534 }
02535
02536 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02537 fprintf(TFile,"Begin to do BB profiling information update.\n");
02538 }
02539
02540 Update_BB_Prof_Info(bbs,need_duplicate,duplicate,
02541 rev_duplicate,br_bbs,entry);
02542
02543 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02544 fprintf(TFile,"Finished doing BB profiling information update.\n");
02545 }
02546
02547 for (NODE_VECTOR_ITER iter = dup_nodes.begin();
02548 iter != dup_nodes.end();iter++) {
02549 REGIONAL_CFG_NODE *node = *iter;
02550
02551 for(CFG_PRED_EDGE_ITER pred_iter(node);pred_iter != 0;++pred_iter) {
02552 REGIONAL_CFG_EDGE *pred = *pred_iter;
02553 if (Find_In_Vector(pred->Src(),nodes) == nodes.end()) {
02554 Del_Edge(pred);
02555 }
02556 }
02557 }
02558
02559 Add_BBS_And_Edges(duplicate_bbs);
02560 REGION_TREE *tree = (this->_r)->Tree();
02561
02562 if (has_cycle) {
02563
02564 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02565 fprintf(TFile,"Duplicated loops,begin redo interval process.\n");
02566 }
02567
02568 tree->Process_Intervals(this->_r);
02569 printf("Finished print intervals!");
02570 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
02571 fprintf(TFile,"Duplicated loops,finish redo interval process.\n");
02572 }
02573 }
02574
02575 if (re_shrink) {
02576
02577 }
02578 }
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588 void
02589 REGIONAL_CFG::Add_BBS_And_Edges(BB_VECTOR bbs,NODE_VECTOR *new_nodes) {
02590 for (BB_VECTOR_ITER iter = bbs.begin();iter != bbs.end();iter++) {
02591 BB *new_bb = *iter;
02592
02593 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
02594 fprintf(TFile,"Newly added bb is %d",BB_id(new_bb));
02595 }
02596
02597 REGIONAL_CFG_NODE *new_node = Add_Node(new_bb);
02598
02599 Is_True(new_node != NULL,("The new node is null,add new node failed in add BBs and edges.\n",BB_id(new_bb)));
02600
02601 if(new_nodes != NULL) {
02602 new_nodes->push_back(new_node);
02603 }
02604
02605 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02606 fprintf(TFile,"Add a new node!\n");
02607 }
02608 }
02609
02610 for (BB_VECTOR_ITER iter = bbs.begin();iter != bbs.end();iter++) {
02611 BB *new_bb = *iter;
02612 REGIONAL_CFG_NODE *new_node = (REGIONAL_CFG_NODE *)BB_MAP_Get(bb_node_map,new_bb);
02613
02614 Is_True(new_node != NULL,("The new node is null,bb %d has no corresponding node.\n",BB_id(new_bb)));
02615
02616 BBLIST *preds;
02617
02618 FOR_ALL_BB_PREDS(new_bb,preds) {
02619 BB *pred = BBLIST_item(preds);
02620 RGN_Add_Regional_Cfg_Edge(pred,new_bb);
02621 }
02622
02623 BBLIST *succs;
02624
02625 FOR_ALL_BB_SUCCS(new_bb,succs) {
02626 BB *succ = BBLIST_item(succs);
02627 RGN_Add_Regional_Cfg_Edge(new_bb,succ);
02628 }
02629 }
02630 }
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640 void
02641 REGIONAL_CFG::Duplicate(BB_VECTOR bbs, BB* side_entrance,BB *entry,
02642 BB_MAP duplicate,BB_MAP rev_duplicate,BB** last,
02643 BB_VECTOR& duplicate_bbs,BB_VECTOR& br_bbs) {
02644 BBLIST* bl;
02645
02646 BB* dup = Copy_BB_For_Tail_Duplication(NULL, side_entrance);
02647 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02648 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
02649 fprintf(TFile,"The ops in the original bb is:\n");
02650 Print_Ops_In_BB(side_entrance);
02651 }
02652
02653 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
02654 fprintf(TFile,"The ops in the duplicated bb is:\n");
02655 Print_Ops_In_BB(dup);
02656 }
02657 }
02658
02659 GRA_LIVE_Compute_Liveness_For_BB(dup);
02660 duplicate_bbs.push_back(dup);
02661 BB_MAP_Set(duplicate, side_entrance, dup);
02662 BB_MAP_Set(rev_duplicate,dup,side_entrance);
02663
02664
02665
02666
02667
02668 FOR_ALL_BB_PREDS(side_entrance, bl) {
02669 BB* pred = BBLIST_item(bl);
02670 if (side_entrance == BB_Fall_Thru_Successor(pred)) {
02671 BB* fall_dup = (BB*) BB_MAP_Get(duplicate, pred);
02672
02673 if (fall_dup) {
02674 *last = fall_dup;
02675 } else if (Find_In_BB_Vector(pred,bbs) == bbs.end()) {
02676 *last = pred;
02677 }
02678
02679 break;
02680 }
02681 }
02682
02683 BB* fall_thru = NULL;
02684 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
02685 fprintf(TFile,"Before do fix up arcs!");
02686 }
02687
02688 Fixup_Arcs(bbs, side_entrance, dup, entry, duplicate,
02689 &fall_thru, duplicate_bbs,br_bbs);
02690
02691 if (Get_Trace(TP_A_REGION, TT_RGN_DEBUG)) {
02692 fprintf(TFile,"finished do fix up arcs!");
02693 }
02694
02695 Insert_BB(dup, *last);
02696
02697 if (fall_thru) {
02698 Insert_BB(fall_thru, dup);
02699 *last = fall_thru;
02700 } else {
02701 *last = dup;
02702 }
02703 }
02704
02705
02706
02707
02708
02709
02710 BOOL
02711 REGIONAL_CFG::ARN_Is_Log_If(BB *bb) {
02712 OP *br;
02713 br = BB_branch_op(bb);
02714
02715 if (br != NULL) {
02716
02717 if (OP_cond(br) && !OP_ijump(br)) {
02718 return TRUE;
02719 }
02720 }
02721
02722 return FALSE;
02723 }
02724
02725
02726
02727
02728
02729
02730
02731
02732 void
02733 REGIONAL_CFG::Fixup_Arcs(BB_VECTOR& bbs,BB *old_bb,BB *new_bb,BB *entry,
02734 BB_MAP duplicate,BB **fall_thru,
02735 BB_VECTOR& duplicate_bbs,BB_VECTOR& br_bbs) {
02736 BBLIST *bl;
02737 float new_freq = 0.0;
02738
02739
02740
02741
02742 for (bl = BB_preds(old_bb); bl != NULL;) {
02743 BB *pred = BBLIST_item(bl);
02744 bl = BBLIST_next(bl);
02745 if (pred == old_bb) continue;
02746
02747
02748
02749 BBLIST *blsucc = BB_Find_Succ(pred, old_bb);
02750
02751
02752
02753
02754
02755
02756 BB *dup = (BB*) BB_MAP_Get(duplicate, pred);
02757
02758 if (dup) {
02759 new_freq += BB_freq(pred) * BBLIST_prob(blsucc);
02760
02761
02762
02763
02764
02765 if (BB_Fall_Thru_Successor(pred) == old_bb) {
02766 Link_Pred_Succ_with_Prob(dup, new_bb, BBLIST_prob(blsucc));
02767 if (BB_kind(dup) == BBKIND_GOTO) {
02768 BB_Remove_Branch(dup);
02769 }
02770 } else if (ARN_Is_Log_If(dup)) {
02771
02772
02773
02774
02775
02776 Target_Cond_Branch(dup, new_bb, BBLIST_prob(blsucc));
02777 } else {
02778
02779
02780
02781 BB_Remove_Branch(dup);
02782 Add_Goto(dup, new_bb);
02783 }
02784 } else if (Find_In_BB_Vector(pred,bbs) != bbs.end()) {
02785 continue;
02786 } else {
02787 new_freq += BB_freq(pred) * BBLIST_prob(blsucc);
02788 if (BB_Fall_Thru_Successor(pred) == old_bb) {
02789 Change_Succ(pred, old_bb, new_bb);
02790 } else {
02791 BB_Retarget_Branch(pred, old_bb, new_bb);
02792 }
02793 }
02794 }
02795
02796
02797 BB_freq(new_bb) = new_freq;
02798
02799
02800
02801
02802 FOR_ALL_BB_SUCCS(old_bb, bl) {
02803 BB* succ = BBLIST_item(bl);
02804 if (Find_In_BB_Vector(succ,bbs) == bbs.end() || succ == entry) {
02805
02806 if (BB_Fall_Thru_Successor(old_bb) == succ) {
02807
02808
02809
02810
02811
02812
02813
02814
02815 BB *new_succ = Gen_And_Insert_BB_After(new_bb);
02816
02817 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
02818 fprintf(TFile,"New bb generated%d",BB_id(new_succ));
02819 }
02820
02821 Link_Pred_Succ(new_bb, new_succ);
02822
02823 if (BB_kind(new_bb) == BBKIND_GOTO) {
02824 BB_Remove_Branch(new_bb);
02825 }
02826
02827 Add_Goto(new_succ, succ);
02828 Link_Pred_Succ(new_succ, succ);
02829 GRA_LIVE_Compute_Liveness_For_BB(new_succ);
02830 duplicate_bbs.push_back(new_succ);
02831 br_bbs.push_back(new_succ);
02832 *fall_thru = new_succ;
02833 } else {
02834 Link_Pred_Succ_with_Prob(new_bb, succ, BBLIST_prob(bl));
02835 }
02836 } else {
02837
02838
02839
02840 BB *dup = (BB*) BB_MAP_Get(duplicate, succ);
02841
02842 if (dup) {
02843
02844 Target_Cond_Branch(new_bb,dup,BBLIST_prob(bl));
02845 }
02846 }
02847 }
02848 }
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860 void
02861 REGIONAL_CFG::Update_BB_Prof_Info(BB_VECTOR bbs,BB_VECTOR dup,BB_MAP duplicate,
02862 BB_MAP rev_duplicate,BB_VECTOR br_bbs,BB *main_entry) {
02863 typedef std::list<BB *,BB_ALLOC> BB_LIST;
02864 typedef std::queue<BB *,BB_LIST> BB_QUEUE;
02865
02866 BB_ALLOC temp_alloc(&_m);
02867 BB_LIST temp_list(temp_alloc);
02868 BB_QUEUE queue(temp_list);
02869 queue.push(main_entry);
02870
02871 BS *visited = BS_Create_Empty(PU_BB_Count+2, &_m);
02872 BS_Union1D(visited,BB_id(main_entry),&_m);
02873
02874 if (dup.empty()) {
02875 return;
02876 }
02877
02878
02879
02880
02881 while (!queue.empty()) {
02882 BB *entry = queue.front();
02883 queue.pop();
02884
02885 BBLIST *lists;
02886 FOR_ALL_BB_SUCCS(entry,lists) {
02887 BB* bb = BBLIST_item(lists);
02888
02889 if (Find_In_BB_Vector(bb,bbs) != bbs.end()) {
02890
02891 if (!BS_MemberP(visited,BB_id(bb))) {
02892 BOOL all_pred_visited = TRUE;
02893
02894 BBLIST *pred_list;
02895 FOR_ALL_BB_PREDS(bb,pred_list) {
02896 BB *pred_bb = BBLIST_item(pred_list);
02897
02898
02899
02900
02901
02902 BOOL is_cycle = FALSE;
02903 for (GLOBAL_CYCLE_VECTOR_ITER cycle_iter = global_cycles.begin();
02904 cycle_iter != global_cycles.end();cycle_iter++) {
02905 if ((bb == (*cycle_iter).dest)
02906 &&(pred_bb == (*cycle_iter).src)) {
02907 is_cycle = TRUE;
02908 break;
02909 }
02910 }
02911
02912 if ((!BS_MemberP(visited,BB_id(pred_bb)))
02913 &&(!is_cycle)) {
02914 all_pred_visited = FALSE;
02915
02916 break;
02917 }
02918 }
02919
02920 if (all_pred_visited) {
02921
02922 BS_Union1D(visited,BB_id(bb),&_m);
02923 queue.push(bb);
02924
02925 if (Find_In_BB_Vector(bb,dup) != dup.end()) {
02926 float total_freq = 0.0;
02927 BB *new_bb = (BB *)BB_MAP_Get(duplicate,bb);
02928
02929
02930
02931
02932
02933
02934 BBLIST *preds;
02935 FOR_ALL_BB_PREDS(bb,preds) {
02936 BB *pred = BBLIST_item(preds);
02937
02938 float freq = BB_freq(pred)*Prob_Local(pred,bb);
02939 float p = Prob_Local(pred,bb);
02940 if (freq == 0.0) {
02941 DevWarn("IN UPDATE BB PROFILE:Freq zero BB%d to BB%d.\n",BB_id(pred),BB_id(bb));
02942 }
02943 BB *old_bb = (BB *)BB_MAP_Get(rev_duplicate,pred);
02944
02945 if (old_bb == NULL &&
02946 Find_In_BB_Vector(pred,br_bbs) == br_bbs.end()) {
02947 Set_Freq(pred,bb,freq);
02948 }
02949
02950 total_freq += freq;
02951 }
02952
02953 BB_freq(bb) = total_freq;
02954
02955 BBLIST *succs;
02956 FOR_ALL_BB_SUCCS(bb,succs) {
02957 BB *succ = BBLIST_item(succs);
02958 float freq = 0.0;
02959
02960 if (Prob_Local(bb,succ) == 0.0) {
02961 DevWarn("The prob is zero between BB%d and BB%d.\n",BB_id(bb),BB_id(succ));
02962 }
02963
02964 float p = Prob_Local(bb,succ);
02965 freq = total_freq*Prob_Local(bb,succ);
02966 Set_Freq(bb,succ,freq);
02967 }
02968
02969 Is_True(new_bb != NULL,("The new bb is NULL for BB %d.\n",BB_id(bb)));
02970 float new_bb_freq = 0.0;
02971
02972
02973
02974
02975 BBLIST *new_preds;
02976 FOR_ALL_BB_PREDS(new_bb,new_preds) {
02977 BB *new_pred = BBLIST_item(new_preds);
02978
02979
02980
02981
02982
02983
02984
02985
02986 BB *old_pred = (BB *)BB_MAP_Get(rev_duplicate,new_pred);
02987 if (old_pred != NULL) {
02988 if (Freq(new_pred,new_bb) == 0.0) {
02989 DevWarn("IN UPDATE BB PROFILE:Freq zero BB%d to BB%d.\n",BB_id(new_pred),BB_id(new_bb));
02990 }
02991 new_bb_freq += Freq(new_pred,new_bb);
02992 } else if (Find_In_BB_Vector(new_pred,br_bbs) == br_bbs.end()) {
02993
02994
02995
02996
02997
02998
02999 float p = Prob_Local(new_pred,new_bb);
03000 float freq = Prob_Local(new_pred,new_bb)*BB_freq(new_pred);
03001 Set_Freq(new_pred,new_bb,freq);
03002
03003 if (freq == 0.0) {
03004 DevWarn("IN UPDATE BB PROFILE:Freq zero BB%d to BB%d.\n",BB_id(new_pred),BB_id(new_bb));
03005 }
03006 new_bb_freq += freq;
03007 }
03008 }
03009
03010 BB_freq(new_bb) = new_bb_freq;
03011
03012 BBLIST *new_succs;
03013 FOR_ALL_BB_SUCCS(new_bb,new_succs) {
03014 BB *new_succ = BBLIST_item(new_succs);
03015 BB *old_succ = NULL;
03016 BOOL is_br_bb = FALSE;
03017
03018
03019
03020
03021 if (Find_In_BB_Vector(new_succ,br_bbs) != br_bbs.end()) {
03022 is_br_bb = TRUE;
03023
03024
03025
03026
03027 BBLIST *succ_list = new_succ->succs;
03028 old_succ = BBLIST_item(succ_list);
03029 } else {
03030 BB *ori = (BB *)BB_MAP_Get(rev_duplicate,new_succ);
03031
03032 if (ori == NULL) {
03033 old_succ = new_succ;
03034 } else {
03035 old_succ = ori;
03036 }
03037 }
03038
03039 float prob = Prob_Local(bb,old_succ);
03040
03041 if (prob == 0.0) {
03042 DevWarn("IN UPDATE BB PROFILE:Prob zero BB%d to BB%d.\n",BB_id(bb),BB_id(old_succ));
03043 }
03044 Set_Prob(new_bb,new_succ,prob);
03045 float freq = BB_freq(new_bb);
03046
03047 if (freq == 0.0) {
03048 DevWarn("IN UPDATE BB PROFILE:Freq zero of BB%d.\n",BB_id(new_bb));
03049 }
03050
03051 Set_Freq(new_bb,new_succ,prob*freq);
03052 if (is_br_bb) {
03053
03054
03055
03056
03057
03058 Set_Prob(new_succ,old_succ,1.0);
03059 Set_Freq(new_succ,old_succ,prob*freq);
03060 BB_freq(new_succ) = prob*freq;
03061 }
03062 }
03063 }
03064 }
03065 }
03066 }
03067 }
03068 }
03069 }
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082 void
03083 REGIONAL_CFG::Compute_Node_Prof_Info(NODE_VECTOR nodes,NODE_VECTOR dup,
03084 REGIONAL_CFG_NODE *main_entry,
03085 NODE_PROF_VECTOR& node_profs) {
03086 typedef std::list<REGIONAL_CFG_NODE *,NODE_ALLOC> NODE_LIST;
03087 typedef std::queue<REGIONAL_CFG_NODE *,NODE_LIST> NODE_QUEUE;
03088
03089 NODE_ALLOC temp_alloc(&_m);
03090 NODE_LIST temp_list(temp_alloc);
03091 NODE_QUEUE queue(temp_list);
03092 queue.push(main_entry);
03093
03094 if (dup.empty()) {
03095 return;
03096 }
03097
03098 for (CFG_SUCC_EDGE_ITER iter(main_entry);iter != 0;++iter) {
03099 REGIONAL_CFG_EDGE *e = *iter;
03100 NODE_PROF p;
03101 p.freq = e->Freq();
03102 p.prob = e->Prob();
03103 p.src = e->Src();
03104 p.dest = e->Dest();
03105 node_profs.push_back(p);
03106 }
03107
03108 while (!queue.empty()) {
03109 REGIONAL_CFG_NODE *node = queue.front();
03110 queue.pop();
03111
03112 for (CFG_SUCC_NODE_ITER iter(node);iter != 0;++iter) {
03113 if (Find_In_Vector(*iter,nodes) != nodes.end()) {
03114
03115 if (Find_In_Vector(*iter,dup) != dup.end()) {
03116 REGIONAL_CFG_NODE *succ = *iter;
03117 float total_freq = 0.0;
03118
03119 for (NODE_PROF_VECTOR_ITER prof_iter = node_profs.begin();
03120 prof_iter != node_profs.end();prof_iter++) {
03121 NODE_PROF p = *prof_iter;
03122
03123 if (p.dest == succ) {
03124 total_freq += p.freq;
03125 }
03126 }
03127
03128 for (CFG_SUCC_EDGE_ITER succ_iter(succ);
03129 succ_iter != 0;++succ_iter) {
03130 REGIONAL_CFG_EDGE *e = *succ_iter;
03131
03132 float freq = 0.0;
03133 freq = total_freq*e->Prob();
03134 NODE_PROF p;
03135 Is_True(freq != 0.0,("Computed frequency is zero in compute node profile info!"));
03136 p.freq = freq;
03137 Is_True(e->Prob() != 0.0,("Probability is zero in compute node profile info!"));
03138 p.prob = e->Prob();
03139 p.src = e->Src();
03140 p.dest = e->Dest();
03141 node_profs.push_back(p);
03142 }
03143 } else {
03144 for (CFG_SUCC_EDGE_ITER succ_iter(*iter);
03145 succ_iter != 0;++succ_iter) {
03146 REGIONAL_CFG_EDGE *e = *succ_iter;
03147 NODE_PROF p;
03148 if (e->Freq() == 0.0) {
03149 DevWarn("Old frequency is zero in compute node profile info!");
03150 }
03151 p.freq = e->Freq();
03152 if (e->Prob() == 0.0) {
03153 DevWarn("Old prob is zero in compute node profile info!");
03154 }
03155
03156 p.prob = e->Prob();
03157 p.src = e->Src();
03158 p.dest = e->Dest();
03159 node_profs.push_back(p);
03160 }
03161 }
03162
03163 queue.push(*iter);
03164 }
03165 }
03166 }
03167 }
03168
03169
03170
03171
03172
03173
03174 void
03175 REGIONAL_CFG::Compute_BBs_Need_Duplicate(BB_VECTOR& need_duplicate,BS *unduplicated,NODE_VECTOR dup) {
03176 Find_BBs_From_Nodes(need_duplicate,dup);
03177
03178 for (BB_VECTOR_ITER iter = need_duplicate.begin();
03179 iter != need_duplicate.end();iter++) {
03180 BS_Union1D(unduplicated,BB_id(*iter),&_m);
03181 }
03182 }
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197 void
03198 TOPOLOGICAL_REGIONAL_CFG_ITER::Set_Cur(REGIONAL_CFG *cfg){
03199
03200
03201
03202 NODE_ALLOC temp_alloc(&cfg->_m);
03203 NODE_VECTOR node_set(temp_alloc);
03204 node_set = cfg->_node_set;
03205
03206 NODE_VECTOR_ITER iter;
03207 for(iter = node_set.begin(); iter != node_set.end(); iter++){
03208 REGIONAL_CFG_NODE *node = *iter;
03209
03210 if(node->First_Pred() == NULL)
03211 _candi_s.push(node);
03212 }
03213 _cur = _candi_s.front();
03214 _candi_s.pop();
03215 Set_Visited(_cur);
03216 }
03217
03218
03219 TOPOLOGICAL_REGIONAL_CFG_ITER &
03220 TOPOLOGICAL_REGIONAL_CFG_ITER::operator ++(void){
03221
03222
03223
03224
03225
03226 for(CFG_SUCC_NODE_ITER iter(_cur); iter!=0; ++iter){
03227 REGIONAL_CFG_NODE *node = *iter;
03228 BOOL all_preds_visited = 1;
03229
03230 for(CFG_PRED_NODE_ITER pred_iter(node); pred_iter!=0; ++pred_iter){
03231
03232 if(!Visited(*pred_iter)){
03233 all_preds_visited = 0;
03234 break;
03235 }
03236 }
03237
03238 if(all_preds_visited)
03239 _candi_s.push(node);
03240 }
03241
03242 if(_candi_s.empty()){
03243 _cur = NULL;
03244 }else{
03245 _cur = _candi_s.front();
03246 _candi_s.pop();
03247 Set_Visited(_cur);
03248 }
03249 return *this;
03250 }
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265 void
03266 REVERSE_TOPO_REGIONAL_CFG_ITER::Set_Cur(REGIONAL_CFG *cfg){
03267
03268
03269
03270 NODE_ALLOC temp_alloc(&cfg->_m);
03271 NODE_VECTOR node_set(temp_alloc);
03272 node_set = cfg->_node_set;
03273
03274 NODE_VECTOR_ITER iter;
03275 for(iter = node_set.begin(); iter != node_set.end(); iter++){
03276 REGIONAL_CFG_NODE *node = *iter;
03277
03278 if(node->First_Succ() == NULL)
03279 _candi_s.push(node);
03280 }
03281
03282 _cur = _candi_s.front();
03283 _candi_s.pop();
03284 Set_Visited(_cur);
03285
03286 }
03287
03288
03289
03290
03291
03292
03293
03294
03295 REVERSE_TOPO_REGIONAL_CFG_ITER &
03296 REVERSE_TOPO_REGIONAL_CFG_ITER::operator ++(void){
03297
03298
03299
03300
03301
03302 for(CFG_PRED_NODE_ITER iter(_cur); iter!=0; ++iter){
03303 REGIONAL_CFG_NODE *node = *iter;
03304 BOOL all_succs_visited = 1;
03305
03306 for(CFG_SUCC_NODE_ITER succ_iter(node); succ_iter!=0; ++succ_iter){
03307
03308 if(!Visited(*succ_iter)){
03309 all_succs_visited = 0;
03310 break;
03311 }
03312 }
03313
03314 if(all_succs_visited)
03315 _candi_s.push(node);
03316 }
03317 if(_candi_s.empty()){
03318 _cur = NULL;
03319 }else{
03320 _cur = _candi_s.front();
03321 _candi_s.pop();
03322 Set_Visited(_cur);
03323 }
03324 return *this;
03325 }
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341 void
03342 PREORDER_REGIONAL_CFG_ITER::Set_Cur(REGIONAL_CFG *cfg){
03343 NODE_ALLOC temp_alloc(&cfg->_m);
03344 NODE_VECTOR node_set(temp_alloc);
03345 node_set = cfg->_node_set;
03346 NODE_VECTOR_ITER iter;
03347
03348 for(iter = node_set.begin(); iter != node_set.end(); iter++){
03349 REGIONAL_CFG_NODE *node = *iter;
03350
03351 if(node->First_Pred() == NULL)
03352 _candi_s.push(node);
03353 }
03354
03355 _cur = _candi_s.front();
03356 _candi_s.pop();
03357 }
03358
03359
03360
03361
03362
03363
03364
03365
03366 PREORDER_REGIONAL_CFG_ITER &
03367 PREORDER_REGIONAL_CFG_ITER::operator ++(void){
03368
03369 if (_cur != NULL) {
03370
03371 for(CFG_SUCC_NODE_ITER iter(_cur); iter != 0; ++iter){
03372 REGIONAL_CFG_NODE *node = *iter;
03373
03374 if (!Visited(node)) {
03375 _candi_s.push(node);
03376 Set_Visited(node);
03377 }
03378 }
03379 }
03380
03381 if(_candi_s.empty()){
03382 _cur = NULL;
03383 }else{
03384 _cur = _candi_s.front();
03385 _candi_s.pop();
03386 }
03387 return *this;
03388 }
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402 REGION *
03403 REGION::Find_Common_Parent(REGION *r) {
03404 REGION *parent = this;
03405
03406 while (parent){
03407
03408 if (r->Is_Contained_By(parent) || parent == r) {
03409 return parent;
03410 }
03411
03412 parent = parent->Parent();
03413 }
03414
03415 Is_True((parent==NULL), ("there should be a common parent"));
03416
03417 return NULL;
03418 }
03419
03420
03421
03422
03423
03424
03425
03426
03427 BOOL
03428 REGION::Is_Contained_By(REGION *r) {
03429
03430 REGION *p = this->Parent();
03431
03432 while (p) {
03433 if (p == r) return TRUE;
03434 p = p->Parent();
03435 }
03436
03437 return FALSE;
03438 }
03439
03440
03441
03442
03443 BOOL
03444 REGION::Is_Kid_Region_Of(REGION *r) {
03445
03446 for (REGION_KID_ITER iter(r); iter != 0; ++iter) {
03447 if (this == *iter) return TRUE;
03448 }
03449
03450 return FALSE;
03451 }
03452
03453
03454
03455
03456 BB *
03457 REGION::Edge_Splitting(BB *from, BB *to){
03458
03459 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
03460 fprintf(TFile," from->Id is %d, to->Id is %d\n", BB_id(from),BB_id(to));
03461 }
03462
03463 Is_True((from!=NULL && to!=NULL),("only to edge splitting for BBs"));
03464
03465 OP *op = BB_last_op(from);
03466 INT nsuccs = BBlist_Len(BB_succs(from));
03467
03468 INT tfirst, tcount;
03469 Is_True(op != NULL,("BB %d to BB %d has no branch op.\n",BB_id(from),BB_id(to)));
03470 CGTARG_Branch_Info(op, &tfirst, &tcount);
03471
03472
03473
03474 if(tcount==0) {
03475 return NULL;
03476 }
03477 if (nsuccs != 2) {
03478 return NULL;
03479 }
03480 Is_True(nsuccs == 2, ("Edge_Splitting:from_BB:%d has %d succs (should be 2 succs)",BB_id(from), nsuccs));
03481 Is_True(BB_has_label(to),("Edge_Splitting:joined bb should has a label here"));
03482
03483 TN *tn = OP_opnd(op,tfirst);
03484 Is_True(tn != NULL,("The tn is NULL in Edge Splitting."));
03485 LABEL_IDX label = TN_label(tn);
03486
03487 BBLIST *edge = BBlist_Find_BB(BB_succs(from), to);
03488 REGIONAL_CFG *cfg = &_cfg;
03489 BB *new_bb ;
03490
03491 if(BB_next(from)==to){
03492
03493 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
03494 fprintf(TFile,"BB%d is fall through of BB%d\n",BB_id(to),BB_id(from));
03495 }
03496
03497
03498
03499 float prob = Prob_Local( from, to );
03500 new_bb = RGN_Gen_And_Insert_BB(from, to, cfg);
03501 BB_freq( new_bb ) = prob * BB_freq( from );
03502
03503 }else{
03504 Is_True(Is_Label_For_BB(label,to),("edge_splitting:to node should has the same label with if here"));
03505 float prob = Prob_Local( from, to );
03506 new_bb = RGN_Gen_And_Insert_BB(from, to, cfg);
03507 BB_freq( new_bb ) = prob * BB_freq( from );
03508 Add_Goto_Op(new_bb,to);
03509 LABEL_IDX new_label=Gen_Label_For_BB(new_bb);
03510 TN *new_tn = Dup_TN(tn);
03511 Set_OP_opnd(op,tfirst,new_tn);
03512 Set_TN_label(new_tn,new_label);
03513 }
03514
03515 if (!CG_localize_tns) {
03516 GRA_LIVE_Compute_Liveness_For_BB(new_bb);
03517 }
03518
03519 Set_BB_edge_splitting (new_bb);
03520
03521 return new_bb;
03522 }
03523
03524
03525
03526
03527 void
03528 REGION::Edge_Splitting(){
03529 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
03530 fprintf(TFile, "*** Begin Edge_Splitting *** \n");
03531 }
03532
03533 REGIONAL_CFG *cfg = &_cfg;
03534
03535 for(TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg);iter != 0;++iter){
03536 REGIONAL_CFG_NODE *node = *iter;
03537 if(node->Is_Region()) continue;
03538 if(node->Succ_Num() < 1) continue;
03539 if((node->Succ_Num() == 1) && (!node->Is_Exit())) continue;
03540
03541
03542
03543
03544
03545
03546
03547
03548 for (REGIONAL_CFG_EDGE *edge = node->First_Succ();
03549 edge!=NULL; edge = edge->Next_Succ()){
03550 REGIONAL_CFG_NODE *succ_node = edge->Dest();
03551
03552 if(succ_node->Is_Region()) continue;
03553 if(succ_node->Pred_Num()<=1) continue;
03554 BB *new_bb = Edge_Splitting(node->BB_Node(),succ_node->BB_Node());
03555 }
03556 }
03557
03558 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
03559 fprintf(TFile, "*** Finish Edge_Splitting *** \n");
03560 }
03561 }
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578 INT32
03579 REGION_TREE::Build_Regional_Cfg(BB *first_bb){
03580 typedef mempool_allocator<REGIONAL_CFG_NODE *> NODE_ALLOC;
03581 typedef std::vector<REGIONAL_CFG_NODE *, NODE_ALLOC> NODE_VECTOR;
03582
03583 extern BB_NUM PU_BB_Count;
03584 NODE_VECTOR node_container(PU_BB_Count+2, (REGIONAL_CFG_NODE *)NULL,
03585 NODE_ALLOC(&_m));
03586
03587 REGIONAL_CFG *local_cfg = _root->Regional_Cfg();
03588 Is_True((local_cfg != NULL), ("build_regional_cfg"));
03589
03590
03591
03592
03593 INT32 prev_bb_nums = 0;
03594 BB *bb;
03595
03596 for (bb = first_bb; bb != NULL; bb = BB_next(bb)) {
03597 prev_bb_nums++;
03598
03599
03600
03601
03602 REGIONAL_CFG_NODE *node = node_container[BB_id(bb)];
03603
03604 if(node == NULL) {
03605 node = local_cfg->Add_Node(bb);
03606 node_container[BB_id(bb)] = node;
03607 }
03608
03609
03610
03611
03612
03613 BBLIST *pred_list;
03614
03615 FOR_ALL_BB_PREDS(bb, pred_list) {
03616 BB *pred = BBLIST_item(pred_list);
03617 REGIONAL_CFG_NODE *pred_node = node_container[BB_id(pred)];
03618
03619 if(pred_node == NULL) {
03620 pred_node = local_cfg->Add_Node(pred);
03621 node_container[BB_id(pred)] = pred_node;
03622 }
03623
03624 local_cfg->Add_Edge(pred_node, node);
03625 }
03626 }
03627
03628
03629
03630
03631
03632 for (PREORDER_REGIONAL_CFG_ITER iter(local_cfg);iter != 0;++iter) {
03633 REGIONAL_CFG_NODE *node = *iter;
03634
03635 if (node->First_Pred() == NULL) {
03636 local_cfg->Add_To_Entries(node);
03637 }
03638
03639 if (node->First_Succ() == NULL)
03640 {
03641 local_cfg->Add_To_Exits(node);
03642 }
03643 }
03644
03645 return prev_bb_nums;
03646 }
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660 REGION_TREE::REGION_TREE(BB *first_bb):_region_set(REGION_ALLOC(&_m)) {
03661 INT32 prev_bb_nums = 0;
03662 INT32 after_bb_nums = 0;
03663 float total_exit_prob = 0.0;
03664
03665 Create_BB_Node_Map();
03666 _seq_num = 0;
03667
03668
03669
03670 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
03671 fprintf(TFile, "*** Begin Build Regional Cfg *** \n");
03672 }
03673
03674 _root = Add_Region();
03675 _root->Region_Type(ROOT);
03676
03677
03678
03679 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
03680 draw_global_cfg();
03681 }
03682
03683 prev_bb_nums = Build_Regional_Cfg(first_bb);
03684
03685 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
03686 fprintf(TFile, "*** Finished construct root region *** \n*** Begin Interval Process");
03687 }
03688
03689
03690
03691 Process_Intervals(_root);
03692
03693
03694
03695
03696
03697 REGIONAL_CFG_NODE *loop_head = NULL;
03698 REGIONAL_CFG_NODE *loop_tail = NULL;
03699 for (INNERMOST_REGION_FIRST_ITER iter (this) ; iter != 0; ++iter) {
03700 if ((*iter)->Regional_Cfg()->Num_Of_Entries()>1) {
03701 REGION *rgn = *iter;
03702 rgn->Attribute(NO_FURTHER_OPTIMIZATION);
03703 continue;
03704 }
03705
03706 if ((*iter)->Region_Type() == LOOP) {
03707 LOOP_REGION *r = (LOOP_REGION *)(*iter);
03708 loop_head = r->Loop_Head();
03709 loop_tail = r->Loop_Tail();
03710 if (loop_head->Is_Region()) {
03711 REGION *kid = loop_head->Region_Node();
03712 if (kid->Region_Type() == LOOP) {
03713 kid->Attribute(NO_FURTHER_OPTIMIZATION);
03714 r->Attribute(NO_FURTHER_OPTIMIZATION);
03715 }
03716 }
03717 if (loop_tail->Is_Region()) {
03718 REGION *kid = loop_tail->Region_Node();
03719 if (kid->Region_Type() == LOOP) {
03720 kid->Attribute(NO_FURTHER_OPTIMIZATION);
03721 r->Attribute(NO_FURTHER_OPTIMIZATION);
03722 }
03723 }
03724 }
03725 }
03726
03727 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
03728 fprintf(TFile, "*** Finished interval processing *** \n");
03729 }
03730
03731 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
03732 draw_region_tree(_root);
03733 }
03734 }
03735
03736
03737
03738
03739
03740
03741
03742
03743 REGION_TREE::~REGION_TREE() {
03744 Delete_BB_Node_Map();
03745 }
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755 void
03756 REGION_TREE::Process_Intervals(REGION *r) {
03757 INTERVAL_PROCESSOR inter(r);
03758 inter.Process();
03759
03760 if (!global_cycles.empty()) {
03761 global_cycles.clear();
03762 }
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793 GLOBAL_CYCLES_FINDER cycle_finder;
03794 cycle_finder.Find_Global_Cycles(global_cycles);
03795
03796 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
03797 fprintf(TFile,"The global cycles are:\n");
03798 cycle_finder.Print(global_cycles);
03799 }
03800 }
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810 REGION*
03811 REGION_TREE::Add_Region() {
03812 REGION *r=CXX_NEW(REGION(),&_m);
03813 Insert(r);
03814
03815 return r;
03816 }
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826 LOOP_REGION*
03827 REGION_TREE::Add_Loop_Region(void) {
03828 LOOP_REGION *r=CXX_NEW(LOOP_REGION(),&_m);
03829 Insert(r);
03830
03831 return r;
03832 }
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854 void
03855 REGION_TREE::Shrink (REGION *parent,REGION *kid,NODE_VECTOR nodes) {
03856
03857 REGIONAL_CFG *cfg = parent->Regional_Cfg();
03858 REGIONAL_CFG *kid_cfg = kid->Regional_Cfg();
03859 REGIONAL_CFG_NODE *kid_node = cfg->Add_Node(kid);
03860 BOOL is_exit;
03861 BOOL is_entry;
03862 BOOL kid_is_entry = FALSE;
03863 BOOL kid_is_exit = FALSE;
03864
03865 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
03866 REGIONAL_CFG_NODE *node = *iter;
03867 is_exit = FALSE;
03868 is_entry = FALSE;
03869
03870 for (CFG_PRED_EDGE_ITER pred_iter(node);pred_iter != 0;++pred_iter) {
03871 REGIONAL_CFG_EDGE *e = *pred_iter;
03872 REGIONAL_CFG_NODE *pred = e->Src();
03873
03874 if (Find_In_Vector(pred,nodes) == nodes.end()) {
03875 is_entry = TRUE;
03876 cfg->Del_Edge(e);
03877 cfg->Add_Edge(pred,kid_node);
03878 }
03879 }
03880
03881 for (CFG_SUCC_EDGE_ITER succ_iter(node);succ_iter != 0;++succ_iter) {
03882 REGIONAL_CFG_EDGE *e = *succ_iter;
03883 REGIONAL_CFG_NODE *succ = e->Dest();
03884
03885 if (Find_In_Vector(succ,nodes) == nodes.end()) {
03886 is_exit = TRUE;
03887 cfg->Del_Edge(e);
03888 cfg->Add_Edge(kid_node,succ);
03889 }
03890 }
03891
03892
03893
03894
03895 if (node->Is_Exit()) {
03896 kid_is_exit = TRUE;
03897 is_exit = TRUE;
03898 cfg->Remove_From_Exits(node);
03899 }
03900
03901
03902
03903
03904 if (node->Is_Entry()) {
03905 kid_is_entry = TRUE;
03906 is_entry = TRUE;
03907 cfg->Remove_From_Entries(node);
03908 }
03909
03910 if (is_exit) {
03911 kid_cfg->Add_To_Exits(node);
03912 }
03913
03914 if (is_entry) {
03915 kid_cfg->Add_To_Entries(node);
03916 }
03917
03918 if (node->Is_Region()) {
03919 REGION *r = node->Region_Node();
03920 parent->Del_Kid(r);
03921 kid->Add_Kid(r);
03922 }
03923
03924 cfg->Erase(node);
03925 kid_cfg->Insert(node);
03926 }
03927
03928
03929
03930
03931 if (parent->Region_Type() == LOOP){
03932 LOOP_REGION *loop;
03933 loop = (LOOP_REGION *) parent;
03934 if ((Find_In_Vector(loop->Loop_Head(),nodes) == nodes.end())
03935 && (Find_In_Vector(loop->Loop_Tail(),nodes) != nodes.end())){
03936 kid_cfg->Add_To_Exits(loop->Loop_Tail());
03937 }else if ((Find_In_Vector(loop->Loop_Head(),nodes) != nodes.end())
03938 && (Find_In_Vector(loop->Loop_Tail(),nodes) == nodes.end())){
03939 kid_cfg->Add_To_Entries(loop->Loop_Head());
03940 }
03941 }
03942
03943 if (kid_is_entry) {
03944 cfg->Add_To_Entries(kid_node);
03945 }
03946
03947 if (kid_is_exit) {
03948 cfg->Add_To_Exits(kid_node);
03949 }
03950 }
03951
03952
03953
03954
03955
03956
03957
03958
03959 LOOP_REGION*
03960 REGION_TREE::Add_Loop_Region(REGION *parent,REGIONAL_CFG_EDGE *backedge,
03961 NODE_VECTOR nodes) {
03962 LOOP_REGION *loop = CXX_NEW(LOOP_REGION(),&_m);
03963 Insert(loop);
03964
03965 Shrink(parent,loop,nodes);
03966 REGIONAL_CFG *cfg = loop->Regional_Cfg();
03967 REGIONAL_CFG_NODE *loop_head = backedge->Dest();
03968 REGIONAL_CFG_NODE *loop_tail = backedge->Src();
03969 loop->Loop_Head(loop_head);
03970 loop->Loop_Tail(loop_tail);
03971 cfg->Del_Edge(backedge);
03972 parent->Add_Kid(loop);
03973
03974 return loop;
03975 }
03976
03977
03978
03979
03980
03981
03982
03983
03984 MEME_REGION*
03985 REGION_TREE::Add_MEME_Region(REGION *parent,NODE_VECTOR nodes) {
03986 MEME_REGION *meme = CXX_NEW(MEME_REGION(),&_m);
03987 Insert(meme);
03988
03989 Shrink(parent,meme,nodes);
03990 parent->Add_Kid(meme);
03991
03992 return meme;
03993 }
03994
03995
03996
03997
03998
03999
04000
04001
04002 SEME_REGION*
04003 REGION_TREE::Add_SEME_Region(REGION *parent,NODE_VECTOR nodes) {
04004 SEME_REGION *seme = CXX_NEW(SEME_REGION(),&_m);
04005 Insert(seme);
04006
04007 Shrink(parent,seme,nodes);
04008 parent->Add_Kid(seme);
04009
04010 return seme;
04011 }
04012
04013
04014
04015
04016
04017
04018
04019
04020 IMPROPER_REGION*
04021 REGION_TREE::Add_Improper_Region(REGION *parent,NODE_VECTOR nodes) {
04022 IMPROPER_REGION *improper = CXX_NEW(IMPROPER_REGION(),&_m);
04023 Insert(improper);
04024
04025 Shrink(parent,improper,nodes);
04026 parent->Add_Kid(improper);
04027
04028 return improper;
04029 }
04030
04031
04032
04033
04034
04035 void
04036 REGION_TREE::Decomposition() {
04037 RGN_FORM_PAR par;
04038 par.size.max_bb_num = 20;
04039 par.size.max_op_num = 120;
04040 par.exit_prob = 0.0;
04041 par.dup_ratio = 1.0;
04042 par.max_dup_num = 0;
04043 if (IPFEC_Enable_Tail_Duplication != 0) {
04044 par.dup_ratio = 1 + (float)(IPFEC_Enable_Tail_Duplication/10);
04045 } else {
04046 par.dup_ratio = 1.0;
04047 }
04048
04049 if (IPFEC_Enable_Exit_Probability != 0) {
04050 par.exit_prob = (float)(IPFEC_Enable_Exit_Probability/10);
04051 } else {
04052 par.exit_prob = 0.0;
04053 }
04054
04055 REGION_VECTOR region_vector;
04056 for(INNERMOST_REGION_FIRST_ITER iter(this); iter!=0; ++iter) {
04057 if ((*iter)->Region_Type() != IMPROPER) {
04058 region_vector.push_back(*iter);
04059 }
04060 }
04061
04062 FREQ_Check_Consistency("REGION FORMATION PROFILE CHECK");
04063
04064 for (REGION_VECTOR::iterator iter = region_vector.begin();
04065 iter != region_vector.end();iter++) {
04066 REGION *r = *iter;
04067
04068 Decompose_Region_To_SEME(r,par);
04069 }
04070
04071 FREQ_Check_Consistency("REGION FORMATION PROFILE CHECK");
04072
04073 Statistic();
04074
04075 Set_Loop_Head_Tail();
04076 }
04077
04078
04079
04080
04081
04082
04083
04084 void
04085 REGION_TREE::Decompose_Region_To_MEME(REGION *r,RGN_SIZE size) {
04086 INT16 attribute;
04087 INT32 bb_num = 0;
04088 INT32 op_num = 0;
04089
04090 attribute = r->Attribute();
04091 Is_True(!(attribute&RIGID&NO_FURTHER_OPTIMIZATION),("Can not decompose this region.\n"));
04092
04093 REGIONAL_CFG *cfg = r->Regional_Cfg();
04094
04095
04096
04097 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg);iter != 0;++iter) {
04098 REGIONAL_CFG_NODE *node = *iter;
04099 bb_num++;
04100
04101 if (!node->Is_Region()) {
04102 op_num += BB_length((node->BB_Node()));
04103 }
04104 }
04105
04106 INT32 max_bb_num = size.max_bb_num;
04107 INT32 max_op_num = size.max_op_num;
04108 NODE_ALLOC temp_alloc(&_m);
04109 NODE_VECTOR bad_nodes(temp_alloc);
04110
04111 while ((bb_num > max_bb_num) && (op_num > max_op_num)) {
04112 TEMP_RGN meme_rgn;
04113 meme_rgn.bb_num = 0;
04114 meme_rgn.op_num = 0;
04115 meme_rgn.dup_bb_num = 0;
04116 meme_rgn.dup_op_num = 0;
04117 meme_rgn.main_entry = NULL;
04118 meme_rgn.main_exit = NULL;
04119 meme_rgn.exit_prob = 0;
04120
04121 NODE_VECTOR nodes(temp_alloc);
04122 meme_rgn.nodes = nodes;
04123
04124 cfg->Find_MEME_Nodes(meme_rgn,size,bad_nodes);
04125
04126
04127
04128
04129 Add_MEME_Region(r,nodes);
04130
04131 bb_num = bb_num - meme_rgn.bb_num;
04132 op_num = op_num - meme_rgn.op_num;
04133 }
04134 }
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159 void
04160 REGION_TREE::Decompose_Region_To_SEME(REGION* r,RGN_FORM_PAR par) {
04161 INT16 attribute;
04162 INT32 bb_num = 0;
04163 INT32 op_num = 0;
04164
04165 INT32 max_bb_num = par.size.max_bb_num;
04166 INT32 max_op_num = par.size.max_op_num;
04167
04168
04169
04170
04171 attribute = r->Attribute();
04172 Is_True(!(attribute&RIGID&NO_FURTHER_OPTIMIZATION),("Can not decompose this region."));
04173
04174 REGIONAL_CFG *cfg = r->Regional_Cfg();
04175
04176
04177
04178 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg);iter != 0;++iter) {
04179 REGIONAL_CFG_NODE *node = *iter;
04180
04181 bb_num++;
04182 if (!node->Is_Region()) {
04183 op_num += BB_length((node->BB_Node()));
04184 }
04185 }
04186
04187
04188
04189 par.max_dup_num = (INT32)((par.dup_ratio-1.0)*bb_num);
04190
04191 INT32 n = 0;
04192 NODE_ALLOC temp_alloc(&_m);
04193 NODE_VECTOR bad_nodes(temp_alloc);
04194
04195
04196
04197 while ((bb_num > max_bb_num) && (op_num > max_op_num)) {
04198 TEMP_RGN seme_rgn;
04199 Initialize_Temp_Rgn(seme_rgn,_m);
04200
04201 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
04202 fprintf(TFile,"Begin to find seme nodes.\n");
04203 }
04204
04205 cfg->Find_SEME_Nodes(seme_rgn,par,bad_nodes);
04206
04207 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
04208 fprintf(TFile,"SEME nodes found.\n");
04209 }
04210
04211 NODE_VECTOR_ITER iter = (seme_rgn.nodes).begin();
04212 if (((seme_rgn.nodes).size() == 1)&&(*iter)->Is_Region()) {
04213 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
04214 fprintf(TFile,"Found SEME nodes has bad node,discard.\n");
04215 }
04216
04217 bad_nodes.push_back((*iter));
04218 } else {
04219
04220 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
04221 Print_Node_Vector(seme_rgn.nodes);
04222 }
04223 REGION *seme = Add_SEME_Region(r,seme_rgn.nodes);
04224 if (Get_Trace(TP_A_REGION, TT_RGN_SUMMERY)) {
04225 fprintf(TFile,"SEME region added,REGION ID:%d \n",seme->Id());
04226 }
04227
04228 n++;
04229 if (Get_Trace(TP_A_REGION, TT_RGN_DETAILED)) {
04230 fprintf(TFile,"THE %dTH SEME REGION ADDED.\n",n);
04231 draw_region_tree(_root);
04232 }
04233
04234 bb_num = bb_num - seme_rgn.bb_num + seme_rgn.dup_bb_num;
04235 op_num = op_num - seme_rgn.op_num + seme_rgn.dup_op_num;
04236 par.max_dup_num -= seme_rgn.dup_bb_num;
04237
04238
04239
04240
04241
04242 if (par.max_dup_num < 0) {
04243 par.max_dup_num = 0;
04244 }
04245 }
04246 }
04247 }
04248
04249
04250
04251
04252 void
04253 REGION_TREE::Del_Region(REGION *r) {
04254 Is_True(r!=_root, ("can not delete the root region"));
04255
04256
04257
04258 REGION *parent = r->Parent();
04259 REGIONAL_CFG_NODE *node = r->Regional_Cfg_Node();
04260
04261
04262
04263
04264 if(node->Is_Entry()){
04265 BB_VECTOR *entries = CXX_NEW(BB_VECTOR(), &_m);
04266 Collect_Entry_BBs(r, entries);
04267
04268 for(BB_VECTOR_ITER iter=entries->begin(); iter!=entries->end(); iter++){
04269 BBLIST *pred_list;
04270
04271 FOR_ALL_BB_PREDS(*iter, pred_list) {
04272 BB *pred_bb = BBLIST_item(pred_list);
04273 REGION *pred_rgn = Home_Region(pred_bb);
04274
04275 if(! (pred_rgn==parent || pred_rgn->Is_Contained_By(parent))){
04276 REGION *com_par = pred_rgn->Find_Common_Parent(parent);
04277 REGIONAL_CFG_NODE *pred_node, *parent_node;
04278
04279 if(com_par == pred_rgn)
04280 pred_node = Regional_Cfg_Node(pred_bb);
04281 else
04282 pred_node = Regional_Cfg_Node(pred_rgn->Regional_Cfg_Node(),com_par);
04283
04284 if(com_par == parent)
04285 parent_node = node;
04286 else
04287 parent_node = Regional_Cfg_Node(parent->Regional_Cfg_Node(), com_par);
04288
04289 Del_Regional_Cfg_Edge(pred_node, parent_node, com_par);
04290 }
04291 }
04292 }
04293 CXX_DELETE(entries, &_m);
04294 }
04295
04296 if(node->Is_Exit()){
04297 BB_VECTOR *exits = CXX_NEW(BB_VECTOR(), &_m);
04298 Collect_Exit_BBs(r, exits);
04299
04300 for(BB_VECTOR_ITER iter=exits->begin(); iter!=exits->end(); iter++){
04301 BBLIST *succ_list;
04302
04303 FOR_ALL_BB_SUCCS(*iter, succ_list) {
04304 BB *succ_bb = BBLIST_item(succ_list);
04305 REGION *succ_rgn = Home_Region(succ_bb);
04306
04307 if(! (succ_rgn==parent || succ_rgn->Is_Contained_By(parent))){
04308 REGION *com_par = succ_rgn->Find_Common_Parent(parent);
04309 REGIONAL_CFG_NODE *succ_node, *parent_node;
04310
04311 if(com_par == succ_rgn)
04312 succ_node = Regional_Cfg_Node(succ_bb);
04313 else
04314 succ_node = Regional_Cfg_Node(succ_rgn->Regional_Cfg_Node(),com_par);
04315
04316 if(com_par == parent)
04317 parent_node = node;
04318 else
04319 parent_node = Regional_Cfg_Node(parent->Regional_Cfg_Node(), com_par);
04320
04321 Del_Regional_Cfg_Edge(parent_node, succ_node, com_par);
04322 }
04323 }
04324 }
04325 CXX_DELETE(exits, &_m);
04326 }
04327
04328
04329
04330
04331 parent->Regional_Cfg()->Del_Node(node);
04332
04333
04334
04335
04336 for(INNERMOST_REGION_FIRST_ITER iter(r); iter!=0; ){
04337 REGION *region = *iter;
04338 ++iter;
04339 Is_True(region->First_Kid()==NULL, ("del region after its kid regions are deleted"));
04340
04341
04342
04343 REGIONAL_CFG *cfg = region->Regional_Cfg();
04344 NODE_VECTOR *nodes = &(cfg->_node_set);
04345 for(NODE_VECTOR_ITER node_iter=nodes->begin(); node_iter!=nodes->end(); node_iter++){
04346 if (!(*node_iter)->Is_Region())
04347 BB_MAP_Set(bb_node_map,(*node_iter)->BB_Node(),NULL);
04348 }
04349
04350
04351
04352 REGION *p = region->Parent();
04353 p->Del_Kid(region);
04354
04355
04356
04357 Erase(region);
04358
04359
04360
04361 CXX_DELETE(region, &_m);
04362 }
04363 }
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374 void
04375 REGION_TREE::Set_Loop_Head_Tail(void){
04376 for(REGION_VECTOR_ITER iter=_region_set.begin(); iter!=_region_set.end(); iter++){
04377 REGION *rgn = *iter;
04378
04379 if(rgn->Region_Type()==LOOP){
04380 LOOP_REGION *loop=(LOOP_REGION *)rgn;
04381
04382 for (SEQ_REGIONAL_CFG_ITER node_iter(rgn->Regional_Cfg());
04383 node_iter!=0; ++node_iter){
04384 REGIONAL_CFG_NODE *node = *node_iter;
04385
04386 if(node->First_Pred()==NULL) {
04387 loop->Loop_Head(node);
04388 }
04389
04390 if(node->First_Succ()==NULL) {
04391 loop->Loop_Tail(node);
04392 }
04393 }
04394 }
04395 }
04396 }
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415 void
04416 REGION_TREE::Statistic(void) {
04417 REGION *r = NULL;
04418 REGION *r2 = NULL;
04419 REGION *max_ops_r = NULL;
04420 REGION *max_bbs_r = NULL;
04421 REGION *max_nodes_r = NULL;
04422
04423 float average_ops = 0;
04424 float average_bbs = 0;
04425 float average_nodes = 0;
04426 INT32 i = 0;
04427
04428 INT32 node_num = 0; INT32 bb_num = 0; INT32 op_num = 0;
04429 INT32 bbs = 0; INT32 nodes = 0; INT32 ops = 0;
04430
04431 INT32 max_ops = 0;
04432 INT32 max_bbs = 0;
04433 INT32 max_nodes = 0;
04434
04435 float aver_depth = 0;
04436 INT32 max_depth = 1; INT32 depth_temp = 0;
04437
04438 INT32 depth = 1;
04439
04440 char *input ; char tmp_str[100] = "";
04441
04442 int size = 50000;
04443
04444 input = (char *)malloc(size * sizeof(char));
04445
04446 input[0]='\n';input[1]='\0';
04447
04448 for(INNERMOST_REGION_FIRST_ITER region_iter(this);
04449 region_iter!=0;++region_iter) {
04450 if(strlen(input) > size - 1000) {
04451 size += 50000;
04452 input = (char *)realloc(input, size);
04453 }
04454 i++;
04455 r = *region_iter;
04456 bbs = 0;
04457 ops = 0;
04458 nodes = 0;
04459 REGIONAL_CFG *cfg = r->Regional_Cfg();
04460
04461 BOOL is_root = FALSE;
04462 if (r->Region_Type() == ROOT) {
04463 is_root = TRUE;
04464 }
04465
04466 for (SEQ_REGIONAL_CFG_ITER iter(cfg);iter != 0;++iter) {
04467 REGIONAL_CFG_NODE *node = *iter;
04468
04469 nodes++;
04470 node_num++;
04471
04472 if (!node->Is_Region()) {
04473 op_num += BB_length((node->BB_Node()));
04474 ops += BB_length((node->BB_Node()));
04475 bbs++;
04476 bb_num++;
04477 }
04478 }
04479
04480 if (ops > max_ops) {
04481 max_ops = ops;
04482 max_ops_r = r;
04483 }
04484
04485 if (nodes > max_nodes) {
04486 max_nodes = nodes;
04487 max_nodes_r = r;
04488 }
04489
04490 if (bbs > max_bbs) {
04491 max_bbs = bbs;
04492 max_bbs_r = r;
04493 }
04494
04495 r2= *region_iter;
04496
04497 depth= 1;
04498 while (r2 != this->Root()) {
04499 r2=r2->Parent();
04500 depth += 1;
04501 }
04502
04503 depth_temp += depth;
04504
04505 if (depth > max_depth) {
04506 max_depth = depth;
04507 }
04508
04509 char type[20] = "";
04510 if (r->Region_Type() == LOOP) {
04511 sprintf(type,"LOOP");
04512 } else if (r->Region_Type() == IMPROPER) {
04513 sprintf(type,"IMPR");
04514 } else if (is_root) {
04515 sprintf(type,"ROOT");
04516 } else {
04517 sprintf(type,"SEME");
04518 }
04519
04520 sprintf(tmp_str,"REGION(%s) %d HAS %d NODES : %d BBS : %d OPS : DEPTH: %d\n",type,r->Id(),nodes,bbs,ops,depth);
04521 strcat(input,tmp_str);
04522 }
04523
04524 average_bbs = (float)bb_num/i;
04525 average_nodes = (float)node_num/i;
04526 average_ops = (float)op_num/i;
04527 aver_depth = (float)depth_temp/i;
04528
04529 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_CG)) {
04530 sprintf(tmp_str,"THE STATICS ARE:\n");
04531 strcat(input,tmp_str);
04532 sprintf(tmp_str,"AVERAGE DEPTH : %f\n",aver_depth);
04533 strcat(input,tmp_str);
04534 sprintf(tmp_str,"REGION %d HAS THE MAX ND_NUM %d.\n",max_nodes_r->Id(),max_nodes);
04535 strcat(input,tmp_str);
04536 sprintf(tmp_str,"REGION %d HAS THE MAX OP_NUM %d.\n",max_ops_r->Id(),max_ops);
04537 strcat(input,tmp_str);
04538 sprintf(tmp_str,"REGION %d HAS THE MAX BB_NUM %d.\n",max_bbs_r->Id(),max_bbs);
04539 strcat(input,tmp_str);
04540 sprintf(tmp_str,"AVERAGE ND_NUM : %f. ",average_nodes);
04541 strcat(input,tmp_str);
04542 sprintf(tmp_str,"AVERAGE BB_NUM : %f. ",average_bbs);
04543 strcat(input,tmp_str);
04544 sprintf(tmp_str,"AVERAGE OP_NUM : %f.\n",average_ops);
04545 strcat(input,tmp_str);
04546 Generate_Tlog("ARN", "Region formation statistics\n", (SRCPOS)0,
04547 input,"" , "", "");
04548 }
04549 free(input);
04550
04551 }
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566 void
04567 INNERMOST_REGION_FIRST_ITER::Set_Cur(REGION *root) {
04568 _cur = root;
04569 REGION *kid = _cur->First_Kid();
04570
04571 while(kid != NULL){
04572 _cur = kid;
04573 kid = _cur->First_Kid();
04574 }
04575 }
04576
04577
04578
04579
04580
04581
04582
04583
04584 INNERMOST_REGION_FIRST_ITER &
04585 INNERMOST_REGION_FIRST_ITER::operator ++(void){
04586 if(_cur == _root){
04587 _cur = NULL;
04588 }else{
04589 if(_cur->Next_Sibling() == NULL){
04590 _cur = _cur->Parent();
04591 }else{
04592 _cur = _cur->Next_Sibling();
04593 REGION *kid = _cur->First_Kid();
04594
04595 while(kid != NULL){
04596 _cur = kid;
04597 kid = _cur->First_Kid();
04598 }
04599 }
04600 }
04601 return *this;
04602 }
04603
04604 void Print_Node_Vector(NODE_VECTOR nodes) {
04605 for (NODE_VECTOR_ITER iter = nodes.begin();iter != nodes.end();iter++) {
04606 REGIONAL_CFG_NODE *node = *iter;
04607
04608 Is_True(node != NULL,("Node NULL in Print_Node_Vector."));
04609
04610 if (!node->Is_Region()) {
04611 fprintf(TFile,"BB Node_%d\n",BB_id(node->BB_Node()));
04612 } else {
04613 fprintf(TFile,"REGION Node_%d\n",(node->Region_Node())->Id());
04614 }
04615 }
04616 }
04617
04618 void Print_Ops_In_BB(BB *bb) {
04619 OPS op_list = bb->ops;
04620
04621 for (OP* op = op_list.first ; op != NULL ; op = op->next) {
04622 printf("%s\n",TOP_Name((TOP)(op->opr)));
04623 }
04624 }
04625
04626 void Print_BB_Vector(BB_VECTOR bbs) {
04627 for (BB_VECTOR_ITER iter = bbs.begin();iter != bbs.end();iter++) {
04628 fprintf(TFile,"BB ID: %d\n",BB_id(*iter));
04629 }
04630 }
04631
04632
04633
04634
04635
04636
04637 void
04638 REGIONAL_CFG_EDGE::Print(FILE *f) {
04639 if (Get_Trace(TP_A_REGION, TT_RGN_CFG_DUMP)){
04640 fprintf(f, "Src:%d ",_src->Id());
04641 fprintf(f, "Dest:%d",_dest->Id());
04642 }
04643 }
04644
04645
04646
04647
04648
04649
04650 void
04651 REGIONAL_CFG_NODE::Print(FILE *f) {
04652 char *content = NULL;
04653
04654 if ( Get_Trace(TP_A_REGION, TT_RGN_CFG_DUMP)){
04655 if (Is_Region()) {
04656 fprintf(f,"Id:%d type:%s ",_id,"REGION");
04657 fprintf(f,"RGN_id:%d ", this->Region_Node()->Id());
04658 }
04659 else {
04660 fprintf(f,"Id:%d type:%s ",_id,"BB");
04661 fprintf(f,"BB_id:%d ",BB_id(this->BB_Node()));
04662 }
04663
04664 if(_is_entry) fprintf(f, "entry ");
04665 if(_is_exit) fprintf(f, "exit ");
04666 if(!_is_entry && !_is_exit) {
04667 fprintf(f, "plain ");
04668 }
04669
04670 fprintf(f,"#succs:%d ",_n_succ);
04671 fprintf(f,"#preds:%d\n",_n_pred);
04672
04673 INT i = 1;
04674 for (CFG_SUCC_NODE_ITER iter(this);iter != 0; ++iter) {
04675 REGIONAL_CFG_NODE *node = *iter;
04676 fprintf(f," Succ %d: ",i);
04677 if (node->Is_Region()) {
04678 fprintf(f,"type:%s Id:%d\n","REGION",node->Id());
04679 }
04680 else {
04681 fprintf(f,"type:%s Id:%d\n","BB",node->Id());
04682 }
04683 i++;
04684 }
04685 }
04686 }
04687
04688
04689
04690
04691
04692
04693
04694
04695 void
04696 REGIONAL_CFG::Print(FILE *f) {
04697
04698 if ( Get_Trace(TP_A_REGION, TT_RGN_CFG_DUMP)){
04699 fprintf(f,"#REGIONAL_CFG_NODE:%d ", _seq_num);
04700 fprintf(f,"#entries:%d ", (INT)_entries.size());
04701 fprintf(f,"#exits:%d\n", (INT)_exits.size());
04702
04703 for (NODE_VECTOR_ITER iter = _node_set.begin();
04704 iter != _node_set.end();iter++) {
04705 REGIONAL_CFG_NODE *node = *iter;
04706 node->Print(f);
04707 }
04708 }
04709 }
04710
04711
04712
04713
04714
04715
04716
04717
04718 void
04719 REGION::Print(FILE *f) {
04720 if (Get_Trace(TP_A_REGION, TT_RGN_TREE_DUMP)){
04721 fprintf(f,"REGION ID:%d ",_id);
04722 fprintf(f,"#kids:%d ",_n_kids);
04723 if (_parent != NULL) {
04724 fprintf(f,"Parent_id:%d ",_parent->Id());
04725 }
04726 else
04727 {
04728 fprintf(f,"Root,has no parent. ");
04729 }
04730 fprintf(f,"type:");
04731 switch(_type){
04732 case UNKNOWN:
04733 fprintf(f,"UNKNOWN ");
04734 break;
04735 case ROOT:
04736 fprintf(f,"ROOT ");
04737 break;
04738 case MEME:
04739 fprintf(f,"MEME ");
04740 break;
04741 case SEME:
04742 fprintf(f,"SEME ");
04743 break;
04744 case IMPROPER:
04745 fprintf(f,"IMPROPER ");
04746 break;
04747 case LOOP:
04748 fprintf(f,"LOOP ");
04749 fprintf(f,"head_id:%d ",((LOOP_REGION *)this)->Loop_Head()->Id());
04750 fprintf(f,"tail_id:%d ",((LOOP_REGION *)this)->Loop_Tail()->Id());
04751 break;
04752 default:
04753 fprintf(f,"**error*** ");
04754 break;
04755 }
04756 fprintf(f,"\n");
04757 }
04758
04759 if ( Get_Trace(TP_A_REGION, TT_RGN_CFG_DUMP)){
04760 fprintf(f,"REGIONAL CFG :\n");
04761 _cfg.Print(f);
04762 }
04763 }
04764
04765
04766
04767
04768
04769
04770
04771
04772 void
04773 REGION_TREE::Print(FILE *f) {
04774 REGION *r;
04775
04776 for (INNERMOST_REGION_FIRST_ITER iter(this);iter != 0;++iter) {
04777 r = *iter;
04778 r->Print(f);
04779 }
04780 }