00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "bb.h"
00044 #include "DaVinci.h"
00045 #include "glob.h"
00046 #include "mempool.h"
00047 #include "cg.h"
00048 #include "whirl2ops.h"
00049 #include "op.h"
00050 #include "tag.h"
00051 #include "region.h"
00052 #include "vt_region.h"
00053 #include "cg_loop.h"
00054 #include "ipfec_options.h"
00055 #include <deque>
00056
00057 static char* sPrint_OP (OP *op, char *buf);
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 typedef struct cfg_label_info {
00070 float prob;
00071 float freq;
00072 NODE_ID dest_node_id;
00073 }CFG_LABEL_INFO;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 void draw_bb_op (BB *bb,const char *mes)
00088 {
00089 if (! DaVinci::enabled(TRUE)) return;
00090
00091 MEM_POOL dv_pool;
00092 dv_pool.magic_num = 0;
00093 MEM_POOL_Constructor pool( &dv_pool, "DaVinci", FALSE);
00094
00095 DaVinci dv (&dv_pool, NULL);
00096
00097 char window_title[128];
00098 if ( NULL == mes)
00099 sprintf(window_title,"OP in BB %d , BB Freq is %#.5f - %s",
00100 BB_id(bb), bb -> freq, Cur_PU_Name);
00101 else
00102 sprintf(window_title,"OP in BB %d , BB Freq is %#.5f - %s - %s ",
00103 BB_id(bb), bb -> freq, Cur_PU_Name, mes);
00104 Is_True(strlen(window_title) < 128, ("Window Title buf overflowed"));
00105 dv.Title(window_title);
00106
00107
00108 NODE_TYPE nt;
00109 EDGE_TYPE et;
00110
00111 et.Direction(ED_NONE);
00112 et.Color ("gray");
00113
00114 dv.Graph_Begin();
00115
00116 OPS op_list = bb->ops;
00117
00118 for (OP* op = op_list.first ; op != NULL ; op = op -> next)
00119 {
00120
00121 char buffer[1024];
00122 char *nlabel = sPrint_OP (op, buffer);
00123 Is_True(strlen(nlabel) < 1024, ("Node Label buf overflowed"));
00124
00125 dv.Node_Begin (NODE_ID (op), nlabel, nt);
00126 if ( NULL != (op -> next) )
00127 dv.Out_Edge ( EDGE_ID ( NODE_ID(op), NODE_ID(op -> next)),
00128 et,
00129 NODE_ID (op -> next));
00130 dv.Node_End();
00131 }
00132
00133 dv.Graph_End();
00134 dv.Event_Loop(NULL);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 class Regional_CFG_Callback : public DaVinci_Callback {
00157 private:
00158 DaVinci *_dv;
00159 INT32 _pseudo_node_num;
00160 REGIONAL_CFG *_cfg;
00161 public:
00162 Regional_CFG_Callback (DaVinci *dv,REGIONAL_CFG *cfg,INT32 label_num = 0)
00163 {
00164 _dv = dv;
00165 _pseudo_node_num = label_num;
00166 _cfg = cfg;
00167 }
00168 ~Regional_CFG_Callback (){}
00169
00170 virtual void Node_Select( const INT n_ids, const NODE_ID id_array[] );
00171 virtual void Edge_Select( const EDGE_ID& edge_id);
00172 };
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 void
00186 Regional_CFG_Callback::Node_Select(const INT n_ids, const NODE_ID id_array[])
00187 {
00188 REGIONAL_CFG_NODE* node;
00189 for (INT32 i = 0; i < n_ids; ++i) {
00190 node = (REGIONAL_CFG_NODE*) id_array[i];
00191 if ( ((INT32)node) > _pseudo_node_num)
00192 if ( node -> Is_Region() )
00193 draw_regional_cfg ( node -> Region_Node() );
00194 else draw_bb_op ( node -> BB_Node() );
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 void
00208 Regional_CFG_Callback::Edge_Select(const EDGE_ID& edge_id)
00209 {
00210 if (! VT_Enable_CFG_Label)
00211 {
00212 REGIONAL_CFG_NODE *src_node = (REGIONAL_CFG_NODE*) edge_id.src;
00213 REGIONAL_CFG_NODE *dst_node = (REGIONAL_CFG_NODE*) edge_id.dst;
00214 REGIONAL_CFG_EDGE *edge = src_node -> Find_Succ_Edge(dst_node);
00215 float freq = _cfg -> Edge_Freq (edge);
00216
00217 char message[128];
00218 sprintf ( message, "Selected Edge Frequence: %#.5f", freq);
00219 Is_True(strlen(message)<128, ("daVinci message buffer overflowed"));
00220 _dv -> Show_Message (message);
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 void draw_regional_cfg (REGION *r,const char *mes)
00239 {
00240 if (! DaVinci::enabled (TRUE)) return;
00241
00242 MEM_POOL dv_pool;
00243 dv_pool.magic_num = 0;
00244 MEM_POOL_Constructor pool (&dv_pool, "DaVinci", FALSE);
00245
00246 DaVinci dv (&dv_pool, NULL);
00247
00248 char window_title[128];
00249 if ( NULL == mes)
00250 sprintf(window_title,"Regional CFG for Region %d - %s",
00251 r -> Id(), Cur_PU_Name);
00252 else
00253 sprintf(window_title,"Regional CFG for Region %d - %s - %s ",
00254 r -> Id(), Cur_PU_Name, mes);
00255 Is_True(strlen(window_title) < 128, ("Window Title buf overflowed"));
00256 dv.Title(window_title);
00257
00258
00259 char nlabel[64];
00260 INT32 pseudo_node_id=0;
00261 CFG_LABEL_INFO label_info_item;
00262 vector<CFG_LABEL_INFO> label_info_vector;
00263 BOOL show_edge_label;
00264 NODE_TYPE nt,nt_bb,nt_region,nt_pseudo;
00265 EDGE_TYPE et_source,et_destination;
00266 REGIONAL_CFG_NODE *being_drawn_node;
00267
00268 nt_bb.Shape (NS_CIRCLE);
00269 nt_region.Color ("pink");
00270 nt_region.Boarder (NB_DOUBLE);
00271 nt_pseudo.Shape (NS_TEXT);
00272 et_source.Direction (ED_NONE);
00273
00274 if (VT_Enable_CFG_Label) show_edge_label = TRUE;
00275 else show_edge_label = FALSE;
00276
00277 dv.Graph_Begin();
00278
00279 REGIONAL_CFG *cfg = r -> Regional_Cfg();
00280
00281 for (SEQ_REGIONAL_CFG_ITER iter(cfg) ; iter != 0 ; ++ iter)
00282 {
00283 being_drawn_node = *iter;
00284
00285 if ( being_drawn_node -> Is_Region() ) {
00286 nt = nt_region;
00287 sprintf(nlabel, " %d ", being_drawn_node->Region_Node()->Id() );
00288 }
00289 else {
00290 nt = nt_bb;
00291 if (BB_entry(being_drawn_node -> BB_Node())) nt.Shape(NS_RHOMBUS);
00292 if (BB_exit(being_drawn_node -> BB_Node())) nt.Shape(NS_ELLIPSE);
00293 sprintf(nlabel, "%d", being_drawn_node -> BB_Node() -> id );
00294 }
00295
00296 Is_True(strlen(nlabel) < 64, ("Node Label buf overflowed"));
00297 dv.Node_Begin (NODE_ID (being_drawn_node), nlabel, nt);
00298
00299 for (CFG_SUCC_NODE_ITER kid_iter(being_drawn_node);
00300 kid_iter!=0; ++ kid_iter)
00301 {
00302 REGIONAL_CFG_NODE *kid_node = *kid_iter;
00303 if (show_edge_label)
00304 {
00305 REGIONAL_CFG_EDGE
00306 *edge = being_drawn_node -> Find_Succ_Edge(kid_node);
00307
00308 label_info_item.prob = cfg -> Edge_Prob (edge);
00309 label_info_item.freq = cfg -> Edge_Freq (edge);
00310 label_info_item.dest_node_id = NODE_ID (kid_node);
00311 label_info_vector.push_back (label_info_item);
00312
00313 dv.Out_Edge (EDGE_ID (NODE_ID (being_drawn_node),
00314 NODE_ID (pseudo_node_id)),
00315 et_source,
00316 NODE_ID (pseudo_node_id));
00317
00318 pseudo_node_id ++;
00319 }
00320 else {
00321
00322 dv.Out_Edge(EDGE_ID(NODE_ID(being_drawn_node),
00323 NODE_ID(kid_node)),
00324 et_destination,
00325 NODE_ID(kid_node));
00326 }
00327
00328 }
00329 dv.Node_End();
00330 }
00331
00332
00333 if (show_edge_label)
00334 for (INT32 i=0; i<pseudo_node_id ; i++)
00335 {
00336
00337 sprintf(nlabel,"%#.2f / %#.2f", label_info_vector [i].prob,
00338 label_info_vector [i].freq);
00339 Is_True(strlen(nlabel) < 64, ("Node Label buf overflowed"));
00340 dv.Node_Begin (NODE_ID (i), nlabel, nt_pseudo);
00341 dv.Out_Edge(EDGE_ID(NODE_ID(i),label_info_vector[i].dest_node_id),
00342 et_destination,
00343 label_info_vector [i].dest_node_id );
00344 dv.Node_End ();
00345 }
00346 dv.Graph_End ();
00347
00348 Regional_CFG_Callback regional_cfg_callback(&dv, cfg, pseudo_node_id);
00349 dv.Event_Loop( (DaVinci_Callback*) ®ional_cfg_callback );
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 class Region_Tree_Callback : public DaVinci_Callback {
00374 public:
00375 Region_Tree_Callback (){}
00376 ~Region_Tree_Callback (){}
00377
00378 virtual void Node_Select( const INT n_ids, const NODE_ID id_array[] );
00379 };
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 void
00392 Region_Tree_Callback::Node_Select(const INT n_ids, const NODE_ID id_array[])
00393 {
00394 NODE_ID node_id;
00395 for (INT32 i = 0; i < n_ids; ++i) {
00396 node_id = id_array[i];
00397 draw_regional_cfg ( (REGION*) node_id );
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void draw_region_tree (REGION *r,const char *mes)
00417 {
00418 if (! DaVinci::enabled(TRUE)) return;
00419
00420 MEM_POOL dv_pool;
00421 dv_pool.magic_num = 0;
00422 MEM_POOL_Constructor pool( &dv_pool, "DaVinci", FALSE);
00423
00424 DaVinci dv (&dv_pool, NULL);
00425
00426 char window_title[128];
00427 if ( NULL == mes)
00428 sprintf(window_title,"Region Tree for Region %d - %s",
00429 r -> Id(), Cur_PU_Name);
00430 else
00431 sprintf(window_title,"Region Tree for Region %d - %s - %s ",
00432 r -> Id(), Cur_PU_Name, mes);
00433 Is_True(strlen(window_title) < 128, ("Window Title buf overflowed"));
00434 dv.Title(window_title);
00435
00436
00437 char nlabel[16];
00438 NODE_TYPE nt, nt_plain;
00439 EDGE_TYPE et;
00440 std::deque<REGION*> r_deque;
00441 REGION *being_drawn_region, *kid_r;
00442
00443 r_deque.push_back (r);
00444 dv.Graph_Begin();
00445
00446 while ( ! r_deque.empty() )
00447 {
00448 being_drawn_region = r_deque[0];
00449 r_deque.pop_front();
00450
00451 nt = nt_plain;
00452 switch( being_drawn_region -> Region_Type() )
00453 {
00454 case UNKNOWN : break;
00455 case ROOT : nt.Color ("lightgoldenrod"); break;
00456 case MEME : nt.Color ("pink"); break;
00457 case SEME : nt.Color ("palegreen"); break;
00458 case IMPROPER : nt.Color ("gray"); break;
00459 case LOOP : nt.Shape (NS_CIRCLE); break;
00460 }
00461 switch( being_drawn_region -> Attribute() )
00462 {
00463 case NONE : break;
00464 case NO_FURTHER_OPTIMIZATION: nt.Shape (NS_RHOMBUS);
00465 nt.Boarder(NB_DOUBLE); break;
00466 case RIGID : nt.Shape (NS_RHOMBUS); break;
00467 case PERSISTENT_BOUNDARY : nt.Boarder(NB_DOUBLE); break;
00468 case NO_OPTIMIZAION_ACROSS_BOUNDARY:
00469 nt.Shape (NS_ELLIPSE); break;
00470 }
00471
00472
00473 sprintf(nlabel,"%d",being_drawn_region -> Id() );
00474 Is_True(strlen(nlabel) < 16, ("Node Label buf overflowed"));
00475 dv.Node_Begin (NODE_ID (being_drawn_region), nlabel, nt);
00476
00477 if (being_drawn_region -> N_Kids() > 0 )
00478 for (REGION_KID_ITER r_kid_iter(being_drawn_region);
00479 r_kid_iter != 0; ++ r_kid_iter )
00480 {
00481 kid_r = * r_kid_iter;
00482 r_deque.push_back (kid_r);
00483 dv.Out_Edge ( EDGE_ID ( NODE_ID(being_drawn_region),
00484 NODE_ID(kid_r) ),
00485 et, NODE_ID (kid_r));
00486 }
00487
00488 dv.Node_End();
00489 }
00490
00491 dv.Graph_End();
00492
00493 Region_Tree_Callback region_tree_callback;
00494 dv.Event_Loop( (DaVinci_Callback*) ®ion_tree_callback );
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 class Global_CFG_Callback : public DaVinci_Callback {
00518 private:
00519 INT32 _pseudo_node_num;
00520 public:
00521 Global_CFG_Callback (INT32 label_num = 0)
00522 {_pseudo_node_num = label_num;}
00523 ~Global_CFG_Callback (){}
00524
00525 virtual void Node_Select( const INT n_ids, const NODE_ID id_array[] );
00526 };
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 void
00538 Global_CFG_Callback::Node_Select(const INT n_ids, const NODE_ID id_array[])
00539 {
00540 BB* node;
00541 for (INT32 i = 0; i < n_ids; ++i) {
00542 node = (BB*) id_array[i];
00543 if ( ((INT32)node) > _pseudo_node_num)
00544 draw_bb_op ( (BB*) node );
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 void
00564 draw_global_cfg(const char *mes)
00565 {
00566 if (! DaVinci::enabled (TRUE)) return;
00567
00568 MEM_POOL dv_pool;
00569 dv_pool.magic_num = 0;
00570 MEM_POOL_Constructor pool (&dv_pool, "DaVinci", FALSE);
00571
00572 DaVinci dv (&dv_pool, NULL);
00573
00574 char window_title[128];
00575 if ( NULL == mes)
00576 sprintf(window_title,"Global CFG - %s", Cur_PU_Name);
00577 else
00578 sprintf(window_title,"Global CFG - %s - %s ", Cur_PU_Name, mes);
00579 Is_True(strlen(window_title) < 128, ("Window Title buf overflowed"));
00580 dv.Title(window_title);
00581
00582
00583 char nlabel[64];
00584 INT32 pseudo_node_id=0;
00585 CFG_LABEL_INFO label_info_item;
00586 vector<CFG_LABEL_INFO> label_info_vector;
00587 BOOL show_edge_label;
00588 NODE_TYPE nt, nt_plain, nt_entry, nt_exit, nt_multi,
00589 nt_call, nt_pseudo;
00590 EDGE_TYPE et_source,et_destination;
00591
00592
00593 nt_entry.Shape (NS_RHOMBUS);
00594 nt_exit.Shape (NS_ELLIPSE);
00595 nt_multi.Shape (NS_CIRCLE);
00596 nt_pseudo.Shape (NS_TEXT);
00597
00598 et_source.Direction(ED_NONE);
00599
00600 if (VT_Enable_CFG_Label) show_edge_label = TRUE;
00601 else show_edge_label = FALSE;
00602
00603 dv.Graph_Begin ();
00604
00605
00606 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00607 sprintf(nlabel,"%d",BB_id(bb));
00608 Is_True(strlen(nlabel) < 64, ("Node Label buf overflowed"));
00609
00610 nt = nt_plain;
00611 if (BBlist_Len(BB_preds(bb)) > 1 || BBlist_Len(BB_succs(bb)) > 1)
00612 nt = nt_multi;
00613 if (BB_entry(bb)) nt = nt_entry;
00614 if (BB_exit(bb)) nt = nt_exit;
00615
00616 if (BB_call(bb)) nt.Boarder (NB_DOUBLE);
00617
00618
00619 OP *br_op = BB_xfer_op(bb);
00620
00621
00622 dv.Node_Begin (NODE_ID (bb), nlabel, nt);
00623 BBLIST *sedge;
00624 BB *succ_bb;
00625 for (sedge = bb->succs; sedge != NULL; sedge = sedge-> next)
00626 {
00627 succ_bb = sedge -> item;
00628
00629 if (show_edge_label)
00630 {
00631
00632 label_info_item.prob = sedge -> prob;
00633
00634 label_info_item.dest_node_id = NODE_ID (succ_bb);
00635 label_info_vector.push_back (label_info_item);
00636
00637 dv.Out_Edge (EDGE_ID (NODE_ID (bb), NODE_ID (pseudo_node_id)),
00638 et_source,
00639 NODE_ID (pseudo_node_id));
00640
00641 pseudo_node_id ++;
00642 }
00643 else {
00644
00645 dv.Out_Edge (EDGE_ID (NODE_ID (bb), NODE_ID (succ_bb)),
00646 et_destination,
00647 NODE_ID (succ_bb));
00648 }
00649 }
00650 dv.Node_End ();
00651 }
00652
00653
00654 if (show_edge_label)
00655 for (INT32 i=0; i<pseudo_node_id ; i++)
00656 {
00657
00658 sprintf(nlabel,"%#.2f / %#.2f", label_info_vector [i].prob,
00659 label_info_vector [i].freq);
00660 Is_True(strlen(nlabel) < 64, ("Node Label buf overflowed"));
00661 dv.Node_Begin (NODE_ID (i), nlabel, nt_pseudo);
00662 dv.Out_Edge(EDGE_ID(NODE_ID(i),label_info_vector[i].dest_node_id),
00663 et_destination,
00664 label_info_vector [i].dest_node_id );
00665 dv.Node_End ();
00666 }
00667
00668 dv.Graph_End ();
00669
00670 Global_CFG_Callback global_cfg_callback(pseudo_node_id);
00671 dv.Event_Loop( (DaVinci_Callback*) &global_cfg_callback );
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 extern char * sPrint_TN ( TN *tn, BOOL verbose, char *buf );
00683 static char *
00684 sPrint_OP (OP *op, char *buf)
00685 {
00686 char *result = buf;
00687
00688 WN *wn;
00689 BOOL cg_loop_op = Is_CG_LOOP_Op(op);
00690 buf += sprintf(buf,"[ %d ] ", OP_map_idx(op) );
00691 if (OP_has_tag(op)) {
00692 LABEL_IDX tag = Get_OP_Tag(op);
00693 buf += sprintf (buf, "<tag %s>: ", LABEL_name(tag) );
00694 }
00695 for (INT32 i = 0; i < OP_results(op); i++) {
00696 char buffer[1024];
00697
00698 char *s = sPrint_TN (OP_result(op,i), FALSE, buffer);
00699 Is_True(strlen(s) < 1024, ("Print_TN buffer overflowed"));
00700 buf += sprintf(buf, " %s", s);
00701 }
00702 buf += sprintf(buf," %s", TOP_Name((TOP)(op->opr)) );
00703 if ( OP_variant(op) != 0 )
00704 buf += sprintf (buf, " (%x)", OP_variant(op) );
00705 for (INT32 i=0; i<OP_opnds(op); i++) {
00706 TN *tn = OP_opnd(op,i);
00707 char buffer[1024];
00708 char *s = sPrint_TN (tn, FALSE, buffer);
00709 Is_True(strlen(s) < 1024, ("Print_TN buffer overflowed"));
00710 buf += sprintf(buf, " %s", s);
00711
00712 if ( cg_loop_op ) {
00713 INT omega = TN_is_symbol(tn) ? OP_restore_omega(op) :
00714 OP_omega(op,i);
00715 if (omega)
00716 buf += sprintf(buf, "[%d]", omega);
00717 }
00718 if (OP_Defs_TN(op, tn)) buf += sprintf(buf, "<defopnd>");
00719 buf += sprintf(buf, " ");
00720 }
00721 if (OP_glue(op)) buf += sprintf (buf, " glue");
00722 if (OP_no_alias(op)) buf += sprintf (buf, " noalias");
00723 if (OP_copy(op)) buf += sprintf (buf, " copy");
00724 if (OP_volatile(op)) buf += sprintf (buf, " volatile");
00725 if (OP_side_effects(op))buf += sprintf (buf, " side_effects");
00726 if (OP_hoisted(op)) buf += sprintf (buf, " hoisted");
00727 if (OP_cond_def(op)) buf += sprintf (buf, " cond_def");
00728 if (OP_end_group(op)) buf += sprintf (buf, " end_group");
00729 if (OP_tail_call(op)) buf += sprintf (buf, " tail_call");
00730 if (OP_no_move_before_gra(op)) buf += sprintf (buf, " no_move");
00731
00732 if (wn = Get_WN_From_Memory_OP(op)) {
00733 char buffer[500];
00734 buffer[0] = '\0';
00735 if (Alias_Manager) Print_alias_info (buffer, Alias_Manager, wn);
00736 buf += sprintf(buf, " WN=%p %s", wn, buffer);
00737 }
00738 if (OP_unrolling(op)) {
00739 UINT16 unr = OP_unrolling(op);
00740 buf += sprintf(buf, " %d%s unrolling", unr,
00741 unr == 1 ? "st" : unr == 2 ? "nd" : unr == 3 ? "rd" : "th");
00742 }
00743 return result;
00744 }