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 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #if defined(BUILD_OS_DARWIN)
00043 #include <darwin_elf.h>
00044 #else
00045 #include <elf.h>
00046 #endif
00047 #include <cmplrs/host.h>
00048 #include "assert.h"
00049 #define USE_STANDARD_TYPES
00050 #include "defs.h"
00051 #include "cxx_memory.h"
00052 #include "cxx_hash.h"
00053 #include "erglob.h"
00054 #include "glob.h"
00055 #include "mempool.h"
00056 #include "sparse_bv.h"
00057 #include "tracing.h"
00058 #include "strtab.h"
00059 #include "stab.h"
00060 #include "wn.h"
00061 #include "const.h"
00062 #include "pu_info.h"
00063 #include "irbdata.h"
00064 #include "dwarf_DST_mem.h"
00065 #include "ipc_defs.h"
00066 #include "ipc_weak.h"
00067 #include "ipc_file.h"
00068 #include "opt_du.h"
00069 #include "opt_alias_interface.h"
00070 #include "dep_graph.h"
00071 #include "prompf.h"
00072 #include "wb_util.h"
00073 #include "wb_browser.h"
00074 #include "wb.h"
00075 #include "wb_ipa.h"
00076 #include "cg_browser.h"
00077 #include "ipaa.h"
00078 #include "ipa_section_annot.h"
00079 #include "ipa_df.h"
00080 #include "ipa_cprop.h"
00081 #include "ipl_summary.h"
00082 #include "ipa_summary.h"
00083 #include "ipa_lno_write.h"
00084 #include "ipc_symtab_merge.h"
00085 #include "ipo_defs.h"
00086 #include "be_symtab.h"
00087
00088
00089
00090
00091
00092
00093 static void BE_Current_Init()
00094 {
00095 BE_symtab_alloc_scope_level(CURRENT_SYMTAB);
00096 Scope_tab[CURRENT_SYMTAB].st_tab->
00097 Register(*Be_scope_tab[CURRENT_SYMTAB].be_st_tab);
00098 }
00099
00100
00101
00102
00103
00104
00105 static void BE_Current_Fini()
00106 {
00107 Scope_tab[CURRENT_SYMTAB].st_tab->
00108 Un_register(*Be_scope_tab[CURRENT_SYMTAB].be_st_tab);
00109 Be_scope_tab[CURRENT_SYMTAB].be_st_tab->Clear();
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 BOOL CG_BROWSER::Bad_Node()
00119 {
00120 PU_Info* pu = Cnode()->PU_Info();
00121 Subsect_State state = PU_Info_state(pu, WT_TREE);
00122 return (state == Subsect_Missing || state == Subsect_Written);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131 BOOL CG_BROWSER::Bad_File()
00132 {
00133 const IP_FILE_HDR& file_header = Cnode()->File_Header();
00134 return
00135 IP_PROC_INFO_state(*IP_FILE_HDR_proc_info(file_header)) == IPA_WRITTEN;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 BOOL CG_BROWSER::Unmappable_Character(char ch)
00145 {
00146 switch (ch) {
00147 case ' ':
00148 case '\t':
00149 case '\n':
00150 case 'Q':
00151 case 'q':
00152 case 'H':
00153 case 'h':
00154 return TRUE;
00155 default:
00156 return FALSE;
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 void CG_BROWSER::Set_Subcommand(char ch)
00167 {
00168 INT i;
00169
00170 for (i = 0; Command(i) != '\0'; i++)
00171 if (Command(i) == ch)
00172 break;
00173 if (Command(i) == '\0')
00174 return;
00175 if (Subcommand(i) == NULL)
00176 return;
00177 _is_subcommand = TRUE;
00178 Set_Old_Command_List(Command_List());
00179 Set_Command_List(Subcommand(i));
00180 for (i = 0; i < CGB_ASCII_CHAR_COUNT; i++)
00181 _old_keymap[i] = _keymap[i];
00182 for (i = 0; i < CGB_ASCII_CHAR_COUNT; i++)
00183 _keymap[i] = i;
00184 Initialize_Keymap(ch);
00185 }
00186
00187
00188
00189
00190
00191
00192 void CG_BROWSER::Reset_Subcommand()
00193 {
00194 _is_subcommand = FALSE;
00195 Set_Command_List(Old_Command_List());
00196 Set_Old_Command_List(NULL);
00197 for (INT i = 0; i < CGB_ASCII_CHAR_COUNT; i++)
00198 _keymap[i] = _old_keymap[i];
00199 }
00200
00201
00202
00203
00204
00205
00206 extern void CGB_Prompt()
00207 {
00208 fprintf(stdout, "CGB> ");
00209 }
00210
00211
00212
00213
00214
00215
00216 CG_BROWSER::CG_BROWSER()
00217 {
00218 _ipa_cg = NULL;
00219 _cnode = NULL;
00220 _cvertex = 0;
00221 _command_list = NULL;
00222 _old_command_list = NULL;
00223 _fancy_level = 1;
00224 _is_subcommand = FALSE;
00225 _davinci_mode = FALSE;
00226 for (INT i = 0; i < CGB_ASCII_CHAR_COUNT; i++)
00227 _keymap[i] = i;
00228 }
00229
00230
00231
00232
00233
00234
00235 CG_BROWSER::CG_BROWSER(IPA_CALL_GRAPH* ipa_cg,
00236 CGB_COMMAND* command_list)
00237 {
00238 _ipa_cg = ipa_cg;
00239 _cnode = NULL;
00240 _cvertex = 0;
00241 _command_list = command_list;
00242 _old_command_list = NULL;
00243 _fancy_level = 1;
00244 _is_subcommand = FALSE;
00245 _davinci_mode = FALSE;
00246 for (INT i = 0; i < CGB_ASCII_CHAR_COUNT; i++)
00247 _keymap[i] = i;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256 BOOL CG_BROWSER::Required_Fields_Present(INT num)
00257 {
00258 if (Required_Fields(num) == CGBR_NONE)
00259 return TRUE;
00260 return FALSE;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269 void CG_BROWSER::Error_Cleanup()
00270 {
00271 WB_Bell();
00272 CGB_Prompt();
00273 Buffer().Load_Buffer();
00274 Buffer().Scan_Blanks_And_Tabs();
00275 }
00276
00277
00278
00279
00280
00281
00282 void CG_BROWSER::This_Node(FILE* fp,
00283 IPA_NODE* ipan,
00284 NODE_INDEX vdx)
00285 {
00286 if (ipan == NULL) {
00287 fprintf(fp, "<NULL>");
00288 return;
00289 }
00290 fprintf(fp, "%p ", ipan);
00291 fprintf(fp, "V#%d ", vdx);
00292 fprintf(fp, "%s", IPA_Node_Name(ipan));
00293 }
00294
00295
00296
00297
00298
00299
00300 void CG_BROWSER::Print_This_Node(FILE* fp,
00301 IPA_NODE* ipan,
00302 NODE_INDEX vdx)
00303 {
00304 This_Node(fp, ipan, vdx);
00305 fprintf(fp, "\n");
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 void CG_BROWSER::Fancy_Up()
00315 {
00316 if (_fancy_level == CGB_FANCY_MAX) {
00317 Error_Cleanup();
00318 return;
00319 }
00320 _fancy_level++;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 void CG_BROWSER::Fancy_Down()
00330 {
00331 if (_fancy_level == CGB_FANCY_MIN) {
00332 Error_Cleanup();
00333 return;
00334 }
00335 _fancy_level--;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 void CG_BROWSER::Address(FILE* fp)
00345 {
00346 INT integer;
00347 Buffer().Scan_Integer(&integer);
00348 if (integer < 0 || integer >= Carray().Next_Index()) {
00349 Error_Cleanup();
00350 return;
00351 }
00352 Set_Cnode(Carray().Node(integer));
00353 Set_Cvertex(Carray().Vertex(integer));
00354 Print_This_Node(fp, Cnode(), Cvertex());
00355 }
00356
00357
00358
00359
00360
00361
00362
00363 void CG_BROWSER::Root(FILE* fp)
00364 {
00365 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00366 NODE_INDEX ventry = GRAPH_root(ipa_graph);
00367 Set_Cnode(NULL);
00368 Set_Cvertex(ventry);
00369 Carray().Reset_Index();
00370 MEM_POOL_Push(&_pool);
00371 NODE_ITER viter(ipa_graph, Cvertex());
00372 INT root_count = 0;
00373 NODE_INDEX v = viter.First_Succ();
00374 for (; v != INVALID_NODE_INDEX; v = viter.Next_Succ())
00375 root_count++;
00376 if (root_count == 1) {
00377 NODE_INDEX v = viter.First_Succ();
00378 IPA_NODE* ipan = ipa_graph->Node_User(v);
00379 Set_Cnode(ipan);
00380 Set_Cvertex(v);
00381 } else {
00382 INT i = 0;
00383 fprintf(fp, "CALL GRAPH ROOT NODES:\n");
00384 NODE_INDEX v = viter.First_Succ();
00385 for (; v != INVALID_NODE_INDEX; v = viter.Next_Succ()) {
00386 IPA_NODE* ipan = ipa_graph->Node_User(v);
00387 fprintf(fp, "[%d] ", i++);
00388 This_Node(fp, ipan, v);
00389 Carray().Enter_This_Pair(ipan, v);
00390 fprintf(stdout, "\n");
00391 }
00392 Set_Cnode(Carray().Node(0));
00393 Set_Cvertex(Carray().Vertex(0));
00394 fprintf(fp, " SELECTING: ");
00395 }
00396 Print_This_Node(fp, Cnode(), Cvertex());
00397 MEM_POOL_Pop(&_pool);
00398 }
00399
00400
00401
00402
00403
00404
00405
00406 void CG_BROWSER::Callers(FILE* fp)
00407 {
00408 if (Cnode() == NULL) {
00409 Error_Cleanup();
00410 return;
00411 }
00412 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00413 MEM_POOL_Push(&_pool);
00414 NODE_ITER viter(ipa_graph, Cvertex());
00415 INT i = 0;
00416 NODE_INDEX v = viter.First_Pred();
00417 for (; v != INVALID_NODE_INDEX; v = viter.Next_Pred()) {
00418 IPA_NODE* ipan = ipa_graph->Node_User(v);
00419 if (ipan == NULL)
00420 continue;
00421 if (i++ == 0)
00422 Carray().Reset_Index();
00423 Carray().Enter_This_Pair_Unique(ipan, v);
00424 }
00425 MEM_POOL_Pop(&_pool);
00426 INT caller_count = i;
00427 if (caller_count == 0) {
00428 Error_Cleanup();
00429 return;
00430 }
00431 for (i = 0; i < Carray().Next_Index(); i++) {
00432 fprintf(fp, "[%d] ", i);
00433 Print_This_Node(fp, Carray().Node(i), Carray().Vertex(i));
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 void CG_BROWSER::Edges_In(FILE* fp)
00444 {
00445 if (Cnode() == NULL) {
00446 Error_Cleanup();
00447 return;
00448 }
00449 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00450 IPA_PRED_ITER edge_iter(Cnode());
00451 INT i = 0;
00452 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
00453 IPA_EDGE* e = edge_iter.Current_Edge();
00454 if (e == NULL)
00455 continue;
00456 IPA_NODE* ipan_caller = Ipa_Cg()->Caller(e->Edge_Index());
00457 if (ipan_caller == NULL)
00458 continue;
00459 NODE_INDEX v_caller = ipan_caller->Node_Index();
00460 if (i == 0)
00461 Carray().Reset_Index();
00462 Carray().Enter_This_Pair(ipan_caller, v_caller);
00463 fprintf(fp, "[%d] ", i);
00464 This_Node(fp, Carray().Node(i), Carray().Vertex(i));
00465 fprintf(stdout, " E#%d ", e->Edge_Index());
00466 VALUE_DYN_ARRAY* formal_array = (VALUE_DYN_ARRAY *) e->Cprop_Annot();
00467 Print_Formal_Cprop_Annot(fp, -1, formal_array);
00468 fprintf(stdout, "\n");
00469 i++;
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 void CG_BROWSER::Edges_Out(FILE* fp)
00480 {
00481 if (Cnode() == NULL) {
00482 Error_Cleanup();
00483 return;
00484 }
00485 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00486 IPA_SUCC_ITER edge_iter(Cnode());
00487 INT i = 0;
00488 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
00489 IPA_EDGE* e = edge_iter.Current_Edge();
00490 if (e == NULL)
00491 continue;
00492 IPA_NODE* ipan_callee = Ipa_Cg()->Callee(e->Edge_Index());
00493 if (ipan_callee == NULL)
00494 continue;
00495 NODE_INDEX v_callee = ipan_callee->Node_Index();
00496 if (i == 0)
00497 Carray().Reset_Index();
00498 Carray().Enter_This_Pair(ipan_callee, v_callee);
00499 fprintf(fp, "[%d] ", i);
00500 This_Node(fp, Carray().Node(i), Carray().Vertex(i));
00501 fprintf(stdout, " E#%d ", e->Edge_Index());
00502 VALUE_DYN_ARRAY* formal_array = (VALUE_DYN_ARRAY *) e->Cprop_Annot();
00503 Print_Formal_Cprop_Annot(fp, -1, formal_array);
00504 fprintf(stdout, "\n");
00505 i++;
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514
00515 void CG_BROWSER::Callees(FILE* fp)
00516 {
00517 if (Cnode() == NULL) {
00518 Error_Cleanup();
00519 return;
00520 }
00521 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00522 MEM_POOL_Push(&_pool);
00523 NODE_ITER viter(ipa_graph, Cvertex());
00524 INT i = 0;
00525 NODE_INDEX v = viter.First_Succ();
00526 for (; v != INVALID_NODE_INDEX; v = viter.Next_Succ()) {
00527 IPA_NODE* ipan = ipa_graph->Node_User(v);
00528 if (ipan == NULL)
00529 continue;
00530 if (i++ == 0)
00531 Carray().Reset_Index();
00532 Carray().Enter_This_Pair_Unique(ipan, v);
00533 }
00534 MEM_POOL_Pop(&_pool);
00535 INT callee_count = i;
00536 if (callee_count == 0) {
00537 Error_Cleanup();
00538 return;
00539 }
00540 for (i = 0; i < Carray().Next_Index(); i++) {
00541 fprintf(fp, "[%d] ", i);
00542 Print_This_Node(fp, Carray().Node(i), Carray().Vertex(i));
00543 }
00544 }
00545
00546
00547
00548
00549
00550
00551
00552 static BOOL Is_Substring(char s1[],
00553 char s2[])
00554 {
00555 INT substring_length = strlen(s1);
00556 INT string_length = strlen(s2);
00557 INT difference = string_length - substring_length;
00558
00559 if (substring_length > string_length)
00560 return FALSE;
00561
00562 for (INT i = 0; i <= difference; i++) {
00563 INT j;
00564
00565 for (j = 0; j < substring_length; j++)
00566 if (s1[j] != s2[i + j])
00567 break;
00568
00569 if (j == substring_length)
00570 return TRUE;
00571 }
00572 return FALSE;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581 void CG_BROWSER::Find(FILE* fp)
00582 {
00583 char s[CGB_MAX_STRING_LENGTH];
00584 Buffer().Scan_Alphanumeric(s);
00585 IPA_NODE* ipan = NULL;
00586 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00587 BOOL test_substring = s[0] == '\'';
00588 INT i = 0;
00589 for (NODE_INDEX v = 0; v < GRAPH_vmax(ipa_graph); v++) {
00590 if (!ipa_graph->Is_Node(v))
00591 continue;
00592 ipan = ipa_graph->Node_User(v);
00593 if (ipan == NULL)
00594 continue;
00595 if (!test_substring && !strcmp(s, IPA_Node_Name(ipan))
00596 || test_substring && Is_Substring(&s[1], IPA_Node_Name(ipan))) {
00597 if (i++ == 0)
00598 Carray().Reset_Index();
00599 Carray().Enter_This_Pair_Unique(ipan, v);
00600 }
00601 }
00602 for (i = 0; i < Carray().Next_Index(); i++) {
00603 fprintf(fp, "[%d] ", i);
00604 Print_This_Node(fp, Carray().Node(i), Carray().Vertex(i));
00605 }
00606 }
00607
00608
00609
00610
00611
00612
00613
00614 NODE_INDEX CG_BROWSER::Find_Vertex(IPA_NODE* ipan)
00615 {
00616 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00617 for (NODE_INDEX v = 0; v < GRAPH_vmax(ipa_graph); v++) {
00618 if (!ipa_graph->Is_Node(v))
00619 continue;
00620 IPA_NODE* node = ipa_graph->Node_User(v);
00621 if (ipan == (IPA_NODE*) node)
00622 return v;
00623 }
00624 return INVALID_NODE_INDEX;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633 void CG_BROWSER::Set_Node(FILE* fp)
00634 {
00635 INT node;
00636 Buffer().Scan_HexInteger(&node);
00637 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00638 NODE_INDEX v = Find_Vertex((IPA_NODE*)(INTPTR)node);
00639 if (v == INVALID_NODE_INDEX) {
00640 Error_Cleanup();
00641 return;
00642 }
00643 Set_Cnode((IPA_NODE*)(INTPTR)node);
00644 Set_Cvertex(v);
00645 Print_This_Node(fp, Cnode(), Cvertex());
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 void CG_BROWSER::Set_Vertex(FILE* fp)
00655 {
00656 INT vertex;
00657 Buffer().Scan_Integer(&vertex);
00658 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00659 NODE_INDEX v = (NODE_INDEX) vertex;
00660 if (v < 0 || v >= GRAPH_vmax(ipa_graph)) {
00661 Error_Cleanup();
00662 return;
00663 }
00664 if (!ipa_graph->Is_Node(v)) {
00665 Error_Cleanup();
00666 return;
00667 }
00668 IPA_NODE* ipan = ipa_graph->Node_User(v);
00669 Set_Cnode((IPA_NODE*) ipan);
00670 Set_Cvertex(v);
00671 Print_This_Node(fp, Cnode(), Cvertex());
00672 }
00673
00674
00675
00676
00677
00678
00679
00680 void CG_BROWSER::Graph(FILE* fp)
00681 {
00682 INT i = 0;
00683 const INT MAX_BAD_NODES = 25;
00684 INT bad_node_count = 0;
00685 IPA_NODE* bad_node[MAX_BAD_NODES];
00686 NODE_INDEX bad_vertex[MAX_BAD_NODES];
00687 BOOL bad_pred[MAX_BAD_NODES];
00688 IPA_GRAPH* ipa_graph = Ipa_Cg()->Graph();
00689 Carray().Reset_Index();
00690 IPA_NODE_ITER cg_iter(Ipa_Cg(), PREORDER);
00691 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00692 IPA_NODE* ipan = cg_iter.Current();
00693 if (ipan == NULL)
00694 continue;
00695 NODE_INDEX v = Find_Vertex(ipan);
00696 if (v == INVALID_NODE_INDEX) {
00697 fprintf(fp, "Could not find vertex for node.\n");
00698 Error_Cleanup();
00699 return;
00700 }
00701 Carray().Enter_This_Pair(ipan, v);
00702 }
00703 for (i = 0; i < Carray().Next_Index(); i++) {
00704 IPA_NODE* ipan = Carray().Node(i);
00705 NODE_INDEX varray = Carray().Vertex(i);
00706 fprintf(fp, "[%d] ", i);
00707 This_Node(fp, ipan, varray);
00708 fprintf(fp, " ");
00709 MEM_POOL_Push(&_pool);
00710 NODE_ITER viter(ipa_graph, varray);
00711 fprintf(fp, "[");
00712 NODE_INDEX v = viter.First_Pred();
00713 BOOL add_comma = FALSE;
00714 for (; v != INVALID_NODE_INDEX; v = viter.Next_Pred()) {
00715 if (add_comma)
00716 fprintf(fp, ",");
00717 IPA_NODE* ipan = ipa_graph->Node_User(v);
00718 if (ipan == NULL)
00719 continue;
00720 INT j = Carray().Find_This_Pair(ipan, v);
00721 if (j == -1) {
00722 j = Carray().Next_Index();
00723 Carray().Enter_This_Pair(ipan, v);
00724 bad_node[bad_node_count] = ipan;
00725 bad_vertex[bad_node_count] = v;
00726 bad_pred[bad_node_count] = TRUE;
00727 bad_node_count++;
00728 }
00729 fprintf(fp, "%d", j);
00730 add_comma = TRUE;
00731 }
00732 fprintf(fp, "|");
00733 v = viter.First_Succ();
00734 add_comma = FALSE;
00735 for (; v != INVALID_NODE_INDEX; v = viter.Next_Succ()) {
00736 if (add_comma)
00737 fprintf(fp, ",");
00738 IPA_NODE* ipan = ipa_graph->Node_User(v);
00739 if (ipan == NULL)
00740 continue;
00741 INT j = Carray().Find_This_Pair(ipan, v);
00742 if (j == -1) {
00743 j = Carray().Next_Index();
00744 Carray().Enter_This_Pair(ipan, v);
00745 bad_node[bad_node_count] = ipan;
00746 bad_vertex[bad_node_count] = v;
00747 bad_pred[bad_node_count] = FALSE;
00748 bad_node_count++;
00749 }
00750 fprintf(fp, "%d", j);
00751 add_comma = TRUE;
00752 }
00753 fprintf(fp, "]\n");
00754 MEM_POOL_Pop(&_pool);
00755 }
00756 if (bad_node_count > 0) {
00757 fprintf(fp, "WARNING!!\n");
00758 fprintf(fp, "These nodes were missed on a preorder traversal\n");
00759 for (i = 0; i < bad_node_count; i++) {
00760 fprintf(fp, "%p V#%d %s\n", bad_node[i], bad_vertex[i],
00761 bad_pred[i] ? "PRED" : "SUCC");
00762 }
00763 }
00764 }
00765
00766
00767
00768
00769
00770
00771 char* CG_BROWSER::Symbol_Name(INT i,
00772 char** function_name)
00773 {
00774 SUMMARY_SYMBOL* symbol_array = IPA_get_symbol_array(Cnode());
00775 SUMMARY_SYMBOL* ss = &symbol_array[i];
00776 if (ST_IDX_level(ss->St_idx()) > 1) {
00777 ST_IDX func_st_idx = ss->Get_st_idx_func();
00778 PU_IDX pu_idx = ST_pu(ST_ptr(func_st_idx));
00779 NODE_INDEX node_index = AUX_PU_node(Aux_Pu_Table[pu_idx]);
00780 IPA_NODE* cnode = IPA_Call_Graph->Graph()->Node_User(node_index);
00781 IPA_NODE_CONTEXT context(cnode);
00782 if (function_name != NULL)
00783 *function_name = ST_name(func_st_idx);
00784 return ST_name(ss->St_idx());
00785 } else {
00786 IPA_NODE_CONTEXT context(Cnode());
00787 if (function_name != NULL)
00788 *function_name = NULL;
00789 return ST_name(ss->St_idx());
00790 }
00791 }
00792
00793
00794
00795
00796
00797
00798 char* CG_BROWSER::Formal_Name(INT i)
00799 {
00800 SUMMARY_FORMAL* formal_array = IPA_get_formal_array(Cnode());
00801 SUMMARY_PROCEDURE* ipasp = Cnode()->Summary_Proc();
00802 INT formal_base = ipasp->Get_formal_index();
00803 INT formal_count = ipasp->Get_formal_count();
00804 FmtAssert(i >= 0 && i < formal_count,
00805 ("CG_BROWSER::Formal_Name: Formal index out of range"));
00806 INT formal_index = formal_base + i;
00807 SUMMARY_FORMAL* sf = &formal_array[formal_index];
00808 INT symbol_index = sf->Get_symbol_index();
00809 return Symbol_Name(symbol_index);
00810 }
00811
00812
00813
00814
00815
00816
00817 void CG_BROWSER::Mod_Ref_Formals(FILE* fp)
00818 {
00819 char buffer[CGB_MAX_STRING_LENGTH];
00820 IPAA_NODE_INFO* ipaa = Cnode()->Mod_Ref_Info();
00821 IPA_NODE_SECTION_INFO* ipas = Cnode()->Section_Annot();
00822 if (ipas == NULL) {
00823 INT formal_count = ipaa->Get_fcount();
00824 for (INT i = 0; i < formal_count; i++) {
00825 BOOL indent = FALSE;
00826 if (ipaa->Is_formal_dmod_elmt(i) || ipaa->Is_formal_imod_elmt(i)) {
00827 fprintf(fp, "MOD ");
00828 fprintf(fp, "%s", Formal_Name(i));
00829 indent = TRUE;
00830 }
00831 if (ipaa->Is_formal_dref_elmt(i) || ipaa->Is_formal_iref_elmt(i)) {
00832 if (indent)
00833 fprintf(fp, " ");
00834 fprintf(fp, "REF ");
00835 fprintf(fp, "%s", Formal_Name(i));
00836 indent = TRUE;
00837 }
00838 if (!indent)
00839 fprintf(fp, " %s", Formal_Name(i));
00840 fprintf(fp, "\n");
00841 }
00842 } else {
00843 INT formal_count = ipas->Get_formal_count();
00844 if (formal_count > 0) {
00845 for (INT i = 0; i < formal_count; i++) {
00846 fprintf(fp, "F#%d: ", i);
00847 STATE* ipaf = ipas->Get_formal(i);
00848 if (ipaf->Is_scalar()) {
00849 BOOL indent = FALSE;
00850 if (ipaa->Is_formal_dmod_elmt(i) || ipaa->Is_formal_imod_elmt(i)) {
00851 fprintf(fp, "MOD ");
00852 fprintf(fp, "%s", Formal_Name(i));
00853 indent = TRUE;
00854 }
00855 if (ipaa->Is_formal_dref_elmt(i) || ipaa->Is_formal_iref_elmt(i)) {
00856 if (indent)
00857 fprintf(fp, " ");
00858 fprintf(fp, "REF ");
00859 fprintf(fp, "%s", Formal_Name(i));
00860 indent = TRUE;
00861 }
00862 if (!indent)
00863 fprintf(fp, " %s", Formal_Name(i));
00864 fprintf(fp, "\n");
00865 } else {
00866 BOOL indent = FALSE;
00867 if (ipaf->Get_projected_mod_region() != NULL) {
00868 fprintf(fp, "MOD ");
00869 fprintf(fp, "%s", Formal_Name(i));
00870 INT cc = Print_Projected_Region(buffer, 0,
00871 ipaf->Get_projected_mod_region());
00872 if (cc >= CGB_MAX_STRING_LENGTH - 1)
00873 fprintf(fp, "Warning: string exceeded buffer length!!");
00874 fprintf(fp, "%s", buffer);
00875 fprintf(fp, "\n");
00876 indent = TRUE;
00877 }
00878 if (ipaf->Get_projected_ref_region() != NULL) {
00879 if (indent)
00880 fprintf(fp, " ");
00881 fprintf(fp, "REF ");
00882 fprintf(fp, "%s", Formal_Name(i));
00883 INT cc = Print_Projected_Region(buffer, 0,
00884 ipaf->Get_projected_ref_region());
00885 if (cc >= CGB_MAX_STRING_LENGTH - 1)
00886 fprintf(fp, "Warning: string exceeded buffer length!!");
00887 fprintf(fp, "%s", buffer);
00888 fprintf(fp, "\n");
00889 indent = TRUE;
00890 }
00891 if (ipaf->Get_projected_dcl_region() != NULL) {
00892 if (indent)
00893 fprintf(fp, " ");
00894 fprintf(fp, "DCL ");
00895 fprintf(fp, "%s", Formal_Name(i));
00896 INT cc = Print_Projected_Region(buffer, 0,
00897 ipaf->Get_projected_dcl_region());
00898 if (cc >= CGB_MAX_STRING_LENGTH - 1)
00899 fprintf(fp, "Warning: string exceeded buffer length!!");
00900 fprintf(fp, "%s", buffer);
00901 fprintf(fp, "\n");
00902 indent = TRUE;
00903 }
00904 if (!indent) {
00905 fprintf(fp, " %s", Formal_Name(i));
00906 fprintf(fp, "\n");
00907 }
00908 }
00909 }
00910 }
00911 }
00912 }
00913
00914
00915
00916
00917
00918
00919 void CG_BROWSER::Mod_Ref_Commons(FILE* fp)
00920 {
00921 char buffer[CGB_MAX_STRING_LENGTH];
00922
00923
00924 IPAA_NODE_INFO* ipaa = Cnode()->Mod_Ref_Info();
00925 ST* st;
00926 INT i;
00927 FOREACH_SYMBOL (GLOBAL_SYMTAB, st, i) {
00928 if (ST_class(st) == CLASS_VAR &&
00929 ST_base_idx(st) == ST_st_idx(st) &&
00930 TY_kind(ST_type(st)) != KIND_ARRAY &&
00931 !ST_is_split_common(st)) {
00932 UINT32 mod_ref_key = ST_IDX_index(ST_st_idx(st));
00933 if (ipaa->Is_def_elmt(mod_ref_key))
00934 fprintf(fp, "MOD /%s/\n", ST_name(st));
00935 if (ipaa->Is_eref_elmt(mod_ref_key))
00936 fprintf(fp, "REF /%s/\n", ST_name(st));
00937 }
00938 }
00939
00940
00941 IPA_NODE_SECTION_INFO* ipas = Cnode()->Section_Annot();
00942 if (ipas == NULL)
00943 return;
00944 GLOBAL_ARRAY_TABLE* cst = ipas->Global_Array_Table();
00945 GLOBAL_ARRAY_TABLE_ITER cst_iter(cst);
00946 GLOBAL_ARRAY_LIST* list = NULL;
00947 ST_IDX base_st_idx;
00948 while (cst_iter.Step(&base_st_idx, &list)) {
00949 if (list->Is_messy()) {
00950 fprintf(fp, " /%s/ <MESSY> ", ST_name(base_st_idx));
00951 fprintf(fp, "\n");
00952 continue;
00953 }
00954 GLOBAL_ARRAY_LIST_ITER iter(list);
00955 for (iter.First(); !iter.Is_Empty(); iter.Next()) {
00956 GLOBAL_ARRAY_INFO* css = iter.Cur();
00957 if (css->Get_projected_mod_region() != NULL) {
00958 fprintf(fp, "MOD ");
00959 fprintf(fp, "/%s/ ", ST_name(base_st_idx));
00960 fprintf(fp, "%s", ST_name(css->St_Idx()));
00961 if (Fancy_Level() >= 2) {
00962 INT64 common_offset = ST_ofst(ST_ptr(css->St_Idx()));
00963 INT64 common_size = TY_size(ST_type(css->St_Idx()));
00964 fprintf(fp, "(%lld:%lld)", common_offset, common_size);
00965 }
00966 INT cc = Print_Projected_Region(buffer, 0,
00967 css->Get_projected_mod_region());
00968 if (cc >= CGB_MAX_STRING_LENGTH - 1)
00969 fprintf(fp, "Warning: string exceeded buffer length!!");
00970 fprintf(fp, "%s", buffer);
00971 fprintf(fp, "\n");
00972 }
00973 if (css->Get_projected_ref_region() != NULL) {
00974 fprintf(fp, "REF ");
00975 fprintf(fp, "/%s/ ", ST_name(base_st_idx));
00976 fprintf(fp, "%s", ST_name(css->St_Idx()));
00977 if (Fancy_Level() >= 2) {
00978 INT64 common_offset = ST_ofst(ST_ptr(css->St_Idx()));
00979 INT64 common_size = TY_size(ST_type(css->St_Idx()));
00980 fprintf(fp, "(%lld:%lld)", common_offset, common_size);
00981 }
00982 INT cc = Print_Projected_Region(buffer, 0,
00983 css->Get_projected_ref_region());
00984 if (cc >= CGB_MAX_STRING_LENGTH - 1)
00985 fprintf(fp, "Warning: string exceeded buffer length!!");
00986 fprintf(fp, "%s", buffer);
00987 fprintf(fp, "\n");
00988 }
00989 }
00990 }
00991 }
00992
00993
00994
00995
00996
00997
00998
00999 void CG_BROWSER::Mod_Ref(FILE* fp)
01000 {
01001 if (Cnode() == NULL || Bad_Node()) {
01002 Error_Cleanup();
01003 return;
01004 }
01005 SECTION_FILE_ANNOT* ipaf = IP_FILE_HDR_section_annot(Cnode()->File_Header());
01006 if (ipaf == NULL) {
01007 Error_Cleanup();
01008 return;
01009 }
01010 if (Cnode()->Summary_Proc() != NULL
01011 && Cnode()->Summary_Proc()->Has_incomplete_array_info())
01012 fprintf(fp, "INCOMPLETE ARRAY INFO\n");
01013 Mod_Ref_Formals(fp);
01014 Mod_Ref_Commons(fp);
01015 }
01016
01017
01018
01019
01020
01021
01022
01023 void CG_BROWSER::Values(FILE* fp)
01024 {
01025 IPA_NODE_SECTION_INFO* ipas = Cnode()->Section_Annot();
01026 if (ipas == NULL) {
01027 Error_Cleanup();
01028 return;
01029 }
01030 DYN_ARRAY<SUMMARY_VALUE>* sv = ipas->Get_value();
01031 if (sv == NULL) {
01032 Error_Cleanup();
01033 return;
01034 }
01035 for (INT i = 0; i <= sv->Lastidx(); i++) {
01036 SUMMARY_VALUE* svv = &(*sv)[i];
01037 svv->WB_Print(fp, i);
01038 }
01039 }
01040
01041
01042
01043
01044
01045
01046
01047 void CG_BROWSER::Expressions(FILE* fp)
01048 {
01049 IPA_NODE_SECTION_INFO* ipas = Cnode()->Section_Annot();
01050 if (ipas == NULL) {
01051 Error_Cleanup();
01052 return;
01053 }
01054 DYN_ARRAY<SUMMARY_EXPR>* sx = ipas->Get_expr();
01055 if (sx == NULL) {
01056 Error_Cleanup();
01057 return;
01058 }
01059 for (INT i = 0; i <= sx->Lastidx(); i++) {
01060 SUMMARY_EXPR* sxx = &(*sx)[i];
01061 sxx->WB_Print(fp, i);
01062 }
01063 }
01064
01065
01066
01067
01068
01069
01070
01071 void CG_BROWSER::DaVinci_Toggle()
01072 {
01073 if (DaVinci_Mode()) {
01074 _davinci_mode = FALSE;
01075 fprintf(stdout, "DAVINCI is OFF.\n");
01076 } else {
01077 _davinci_mode = TRUE;
01078 fprintf(stdout, "DAVINCI is ON.\n");
01079 }
01080 }
01081
01082
01083
01084
01085
01086
01087
01088 void CG_BROWSER::Print_Formal_Cprop_Annot(FILE* fp,
01089 INT spaces,
01090 VALUE_DYN_ARRAY* formal_array)
01091 {
01092 if (formal_array == NULL) {
01093 fprintf(fp, "<TOP>");
01094 return;
01095 }
01096 if (formal_array == (void*) -1) {
01097 fprintf(fp, "<BOTTOM>");
01098 return;
01099 }
01100 if (spaces < 0) {
01101 BOOL add_comma = FALSE;
01102 fprintf(fp, "<%d:", formal_array->Lastidx() + 1);
01103 for (INT i = 0; i <= formal_array->Lastidx(); i++) {
01104 SUMMARY_VALUE* sv = &(*formal_array)[i];
01105 if (sv->Is_int_const()) {
01106 if (add_comma)
01107 fprintf(fp, ",");
01108 fprintf(fp, "F%d=%lld", i, sv->Get_int_const_value());
01109 add_comma = TRUE;
01110 } else if (sv->Is_const_st()) {
01111 if (add_comma)
01112 fprintf(fp, ",");
01113 ST_IDX st_idx = sv->Get_const_st_idx();
01114 ST* st = &St_Table[st_idx];
01115 fprintf(fp, "F%d=%s", i, Targ_Print(NULL, Tcon_Table[st->u1.tcon]));
01116 add_comma = TRUE;
01117 }
01118 }
01119 fprintf(fp, ">");
01120 } else {
01121 for (INT i = 0; i <= formal_array->Lastidx(); i++) {
01122 SUMMARY_VALUE* sv = &(*formal_array)[i];
01123 if (sv != NULL && !sv->Is_not_const()) {
01124 for (INT j = 0; j < spaces; j++)
01125 fprintf(fp, " ");
01126 fprintf(fp, "F#%d: ", i);
01127 Print_Summary_Value(fp, sv);
01128 fprintf(fp, "\n");
01129 }
01130 }
01131 }
01132 }
01133
01134
01135
01136
01137
01138
01139
01140 void CG_BROWSER::Cprop_Formals(FILE* fp)
01141 {
01142 const INT spaces = 0;
01143 VALUE_DYN_ARRAY* formal_array = (VALUE_DYN_ARRAY*) Cnode()->Cprop_Annot();
01144 if (formal_array == NULL)
01145 return;
01146 Print_Formal_Cprop_Annot(fp, spaces, formal_array);
01147 }
01148
01149
01150
01151
01152
01153
01154
01155 void CG_BROWSER::Print_Common_Cprop_Annot(FILE* fp,
01156 INT spaces,
01157 GLOBAL_ANNOT* global_annot)
01158 {
01159 for (UINT32 i = 0; i < GLOBAL_ANNOT::Size; ++i) {
01160 if (!global_annot->Top(i) && !global_annot->Bottom(i)) {
01161 char* name = ST_name(GLOBAL_ANNOT::Common_ST[i]);
01162 const GLOBAL_DYN_ARRAY& gvals = global_annot->Global_Value_Array(i);
01163 for (INT32 j = 0; j < gvals.Elements(); ++j) {
01164 if (gvals[j].Value()) {
01165 for (INT k = 0; k < spaces; k++)
01166 fprintf(fp, " ");
01167 fprintf(fp, "/%s/.", name);
01168 fprintf(fp, "%lld", gvals[j].Offset());
01169 fprintf(fp, "(%d)", gvals[j].Size());
01170 fprintf(fp, " ");
01171 Print_Summary_Value(fp, gvals[j].Value());
01172 fprintf(fp, "\n");
01173 }
01174 }
01175 }
01176 }
01177 }
01178
01179
01180
01181
01182
01183
01184
01185 void CG_BROWSER::Cprop_Commons(FILE* fp)
01186 {
01187 const INT spaces = 0;
01188 GLOBAL_ANNOT* ga = Cnode()->Global_Annot();
01189 if (ga == NULL)
01190 return;
01191 if (ga->Bottom()) {
01192 fprintf(fp, "COMMONS AT BOTTOM\n");
01193 return;
01194 }
01195 Print_Common_Cprop_Annot(fp, spaces, ga);
01196 }
01197
01198
01199
01200
01201
01202
01203
01204 void CG_BROWSER::Cprop_Predecessor_Edges(FILE* fp)
01205 {
01206 const INT spaces = 4;
01207 fprintf(fp, "PREDECESSORS:\n");
01208 IPA_PRED_ITER edge_iter(Ipa_Cg(), Cnode());
01209 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
01210 IPA_EDGE* e = edge_iter.Current_Edge();
01211 if (e != NULL && e->Cprop_Annot() != NULL) {
01212 IPA_NODE* ipan_caller = Ipa_Cg()->Caller(e);
01213 fprintf(fp, " ");
01214 Print_This_Node(fp, ipan_caller, ipan_caller->Node_Index());
01215 VALUE_DYN_ARRAY* formal_array = (VALUE_DYN_ARRAY *) e->Cprop_Annot();
01216 Print_Formal_Cprop_Annot(fp, spaces, formal_array);
01217 }
01218 }
01219 }
01220
01221
01222
01223
01224
01225
01226
01227 void CG_BROWSER::Cprop_Successor_Edges(FILE* fp)
01228 {
01229 const INT spaces = 4;
01230 fprintf(fp, "SUCCESSORS:\n");
01231 IPA_SUCC_ITER edge_iter(Ipa_Cg(), Cnode());
01232 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
01233 IPA_EDGE* e = edge_iter.Current_Edge();
01234 if (e != NULL && e->Cprop_Annot() != NULL) {
01235 IPA_NODE* ipan_callee = Ipa_Cg()->Callee(e);
01236 fprintf(fp, " ");
01237 Print_This_Node(fp, ipan_callee, ipan_callee->Node_Index());
01238 VALUE_DYN_ARRAY* formal_array = (VALUE_DYN_ARRAY *) e->Cprop_Annot();
01239 Print_Formal_Cprop_Annot(fp, spaces, formal_array);
01240 }
01241 }
01242 }
01243
01244
01245
01246
01247
01248
01249
01250 void CG_BROWSER::Cprop(FILE* fp)
01251 {
01252 if (Cnode() == NULL || Bad_Node()) {
01253 Error_Cleanup();
01254 return;
01255 }
01256 Cprop_Formals(fp);
01257 Cprop_Commons(fp);
01258 if (Fancy_Level() >= 2) {
01259 Cprop_Predecessor_Edges(fp);
01260 Cprop_Successor_Edges(fp);
01261 }
01262 }
01263
01264
01265
01266
01267
01268
01269
01270 void CG_BROWSER::Whirl_Browser()
01271 {
01272 PU_Info* pu = Cnode()->PU_Info();
01273 Subsect_State state = PU_Info_state(pu, WT_TREE);
01274 if (Cnode() == NULL || Bad_Node()) {
01275 Error_Cleanup();
01276 return;
01277 }
01278 IPA_NODE_CONTEXT context(Cnode());
01279 BE_Current_Init();
01280 WB_IPA_Initialize(Cnode()->Whirl_Tree(), &Cnode()->Get_PU());
01281 s_ipa_debug("");
01282 BE_Current_Fini();
01283 WB_IPA_Terminate();
01284 }
01285
01286
01287
01288
01289
01290
01291
01292 static ST_IDX Compute_ST_IDX(UINT32 st_level,
01293 UINT32 st_index)
01294 {
01295 UINT32 st_idx = st_level + (st_index << 8);
01296 return (ST_IDX) (st_idx);
01297 }
01298
01299
01300
01301
01302
01303
01304
01305 void CG_BROWSER::Symbol()
01306 {
01307 if (Buffer().Is('<')) {
01308 UINT32 st_level;
01309 UINT32 st_index;
01310 Buffer().Scan_Character();
01311 Buffer().Scan_Unsigned(&st_level);
01312 char separator = Buffer().Scan_Character();
01313 if (separator != ',') {
01314 Error_Cleanup();
01315 return;
01316 }
01317 Buffer().Scan_Unsigned(&st_index);
01318 char right_angle_bracket = Buffer().Scan_Character();
01319 if (right_angle_bracket != '>') {
01320 Error_Cleanup();
01321 return;
01322 }
01323 ST_IDX st_idx = Compute_ST_IDX(st_level, st_index);
01324 ST* st = &St_Table[st_idx];
01325 fprintf(stdout, "ST_IDX: %d\n", st_idx);
01326 Print_ST(stdout, st, TRUE);
01327 } else if (Buffer().Is_Integer()) {
01328 ST_IDX st_idx;
01329 Buffer().Scan_Unsigned(&st_idx);
01330 ST* st = &St_Table[st_idx];
01331 fprintf(stdout, "ST_IDX: %d\n", st_idx);
01332 Print_ST(stdout, st, TRUE);
01333 } else {
01334 Print_ST(stdout, Cnode()->Func_ST(), TRUE);
01335 }
01336 }
01337
01338
01339
01340
01341
01342
01343
01344 void CG_BROWSER::Type()
01345 {
01346 if (Buffer().Is('<')) {
01347 UINT32 ty_index = 0;
01348 Buffer().Scan_Character();
01349 Buffer().Scan_Unsigned(&ty_index);
01350 char right_angle_bracket = Buffer().Scan_Character();
01351 if (right_angle_bracket != '>') {
01352 Error_Cleanup();
01353 return;
01354 }
01355 Ty_tab[ty_index].Print(stdout);
01356 } else if (Buffer().Is_Integer()) {
01357 TY_IDX ty_idx = 0;
01358 Buffer().Scan_Unsigned(&ty_idx);
01359 Print_TY(stdout, ty_idx);
01360 } else {
01361 Ty_Table[ST_type(Cnode()->Func_ST())].Print(stdout);
01362 }
01363 }
01364
01365
01366
01367
01368
01369
01370
01371 void CG_BROWSER::Help()
01372 {
01373 for (INT i = 0; Command(i) != '\0'; i++)
01374 if (Required_Fields_Present(i))
01375 for (INT j = 0; j < CGB_ASCII_CHAR_COUNT; j++)
01376 if (_keymap[j] == Command(i))
01377 fprintf(stdout, " %c: %s\n", j, Command_Text(i));
01378 if (!Is_Subcommand()) {
01379 fprintf(stdout, " Q: Exit the debugger\n");
01380 fprintf(stdout, " q: Exit the debugger\n");
01381 }
01382 }
01383
01384
01385
01386
01387
01388
01389
01390 static void Scan_Blanks_And_Tabs(char buffer[],
01391 INT* buffer_start)
01392 {
01393 char ch;
01394 do {
01395 ch = buffer[(*buffer_start)++];
01396 } while (ch == ' ' || ch == '\t');
01397 (*buffer_start)--;
01398 }
01399
01400
01401
01402
01403
01404
01405
01406 void CG_BROWSER::Initialize_Keymap(char ch)
01407 {
01408 const INT BUFFER_MAX = 132;
01409 char file_name[BUFFER_MAX];
01410 strcpy(file_name, getenv("HOME"));
01411 strcat(file_name, "/.cgb_keymap");
01412 FILE* fp_keymap = fopen(file_name, "r");
01413 if (fp_keymap == NULL)
01414 return;
01415 BOOL print_log = TRUE;
01416 char key_buffer[BUFFER_MAX];
01417 INT line_number = 0;
01418 while (fgets(key_buffer, BUFFER_MAX-1, fp_keymap) != NULL) {
01419 line_number++;
01420 INT key_buffer_start = 0;
01421 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01422 if (strncasecmp(&key_buffer[key_buffer_start], "SILENT",
01423 strlen("SILENT")) == 0) {
01424 print_log = FALSE;
01425 } else if (strncasecmp(&key_buffer[key_buffer_start], "VERBOSE",
01426 strlen("VERBOSE")) == 0) {
01427 print_log = TRUE;
01428 } else if (strncasecmp(&key_buffer[key_buffer_start], "TRANSLATE",
01429 strlen("TRANSLATE")) == 0) {
01430 key_buffer_start += strlen("TRANSLATE");
01431 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01432 char old_char = key_buffer[key_buffer_start++];
01433 if (Unmappable_Character(old_char)) {
01434 fprintf(stdout,
01435 ".cgb_keymap: Error on line %d: Cannot map %c\n",
01436 line_number, old_char);
01437 continue;
01438 }
01439 if (ch == ' ') {
01440 if (key_buffer[key_buffer_start] != ' '
01441 && key_buffer[key_buffer_start] != '\t')
01442 continue;
01443 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01444 char new_char = key_buffer[key_buffer_start++];
01445 if (Unmappable_Character(new_char)) {
01446 fprintf(stdout,
01447 ".cgb_keymap: Error on line %d: Cannot map %c\n",
01448 line_number, new_char);
01449 continue;
01450 }
01451 if (print_log)
01452 fprintf(stdout, ".cgb_keymap: Translating '%c' to '%c'\n",
01453 old_char, new_char);
01454 _keymap[new_char] = old_char;
01455 } else {
01456 if (old_char == ch) {
01457 old_char = key_buffer[key_buffer_start++];
01458 if (Unmappable_Character(old_char)) {
01459 fprintf(stdout,
01460 ".cgb_keymap: Error on line %d: Cannot map %c\n",
01461 line_number, old_char);
01462 continue;
01463 }
01464 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01465 char new_char = key_buffer[key_buffer_start++];
01466 if (Unmappable_Character(new_char)) {
01467 fprintf(stdout,
01468 ".cgb_keymap: Error on line %d: Cannot map %c\n",
01469 line_number, new_char);
01470 continue;
01471 }
01472 if (print_log)
01473 fprintf(stdout, ".cgb_keymap: Translating '%c' to '%c'\n",
01474 old_char, new_char);
01475 _keymap[new_char] = old_char;
01476 }
01477 }
01478 } else {
01479 fprintf(stdout, ".cgb_keymap: Error on line %d: Unrecognized command\n",
01480 line_number);
01481 }
01482 }
01483 fclose(fp_keymap);
01484 }
01485
01486
01487
01488
01489
01490
01491 void CG_BROWSER::Invoke_Command(char ch)
01492 {
01493 switch (_keymap[ch]) {
01494 case 'R':
01495 Root(stdout);
01496 break;
01497 case 'C':
01498 Callers(stdout);
01499 break;
01500 case 'c':
01501 Callees(stdout);
01502 break;
01503 case 'E':
01504 Edges_In(stdout);
01505 break;
01506 case 'e':
01507 Edges_Out(stdout);
01508 break;
01509 case '=':
01510 Set_Node(stdout);
01511 break;
01512 case 'v':
01513 Set_Vertex(stdout);
01514 break;
01515 case '@':
01516 Address(stdout);
01517 break;
01518 case 'G':
01519 Graph(stdout);
01520 break;
01521 case 'F':
01522 Find(stdout);
01523 break;
01524 case 'P':
01525 Cprop(stdout);
01526 break;
01527 case 'M':
01528 Mod_Ref(stdout);
01529 break;
01530 case 'V':
01531 Values(stdout);
01532 break;
01533 case 'X':
01534 Expressions(stdout);
01535 break;
01536 case 'd':
01537 DaVinci_Toggle();
01538 break;
01539 case 'S':
01540 Summary(stdout);
01541 break;
01542 case 's':
01543 Symbol();
01544 break;
01545 case 't':
01546 Type();
01547 break;
01548 case '<':
01549 Fancy_Down();
01550 break;
01551 case '>':
01552 Fancy_Up();
01553 break;
01554 case 'W':
01555 Whirl_Browser();
01556 break;
01557 case 'H':
01558 case 'h':
01559 Help();
01560 break;
01561 default:
01562 fprintf(stdout, "Bad character: %c\n", ch);
01563 break;
01564 }
01565 }
01566
01567
01568
01569
01570
01571
01572
01573 void CG_BROWSER::Sdebug(const char init_buffer[])
01574 {
01575 char ch;
01576 BOOL reload;
01577
01578 if (Ipa_Cg() == NULL) {
01579 fprintf(stdout, "Call graph browser not valid in this phase.\n");
01580 Error_Cleanup();
01581 return;
01582 }
01583 MEM_POOL_Initialize(&_pool, "cgb_pool", FALSE);
01584 Buffer().Reset_Buffer();
01585 Initialize_Keymap(' ');
01586 fprintf(stdout, "CALL GRAPH BROWSER: \n");
01587 Root(stdout);
01588 CGB_Prompt();
01589 if (init_buffer[0] == '\0') {
01590 reload = TRUE;
01591 } else {
01592 reload = FALSE;
01593 Buffer().Load_Buffer(init_buffer);
01594 for (INT i = 0; init_buffer[i] != '\0'; i++)
01595 fprintf(stdout, "%c", init_buffer[i]);
01596 fprintf(stdout, "\n");
01597 }
01598 while (TRUE) {
01599 if (reload) {
01600 Buffer().Load_Buffer();
01601 reload = FALSE;
01602 }
01603 ch = Buffer().Get_Command();
01604 if (ch == '\n') {
01605 CGB_Prompt();
01606 reload = TRUE;
01607 continue;
01608 }
01609 if (ch == 'Q' || ch == 'q') {
01610 MEM_POOL_Delete(&_pool);
01611 return;
01612 }
01613 Invoke_Command(ch);
01614 }
01615 }
01616
01617
01618
01619
01620
01621
01622
01623 void CG_BROWSER::Debug()
01624 {
01625 Sdebug("");
01626 }