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