Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 00037 #ifdef USE_PCH 00038 #include "be_com_pch.h" 00039 #endif /* USE_PCH */ 00040 #pragma hdrstop 00041 #include <sys/types.h> 00042 #include <elf.h> 00043 #include <ctype.h> 00044 #include "wn.h" 00045 #include "wn_map.h" 00046 #include "wn_util.h" 00047 #include <stdio.h> 00048 #include "opt_du.h" 00049 #include "opt_alias_mgr.h" 00050 #include "dep_graph.h" 00051 #include "prompf.h" 00052 #include "ir_reader.h" 00053 #include "access_vector.h" 00054 #include "if_info.h" 00055 #include "loop_info.h" 00056 #include "wb_util.h" 00057 #include "wb_buffer.h" 00058 #include "wb_carray.h" 00059 #include "wb_browser.h" 00060 #include "whirl2src.h" 00061 00062 00063 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__) 00064 00065 void WB_BROWSER::Summary(FILE *fp) { } 00066 void ACCESS_ARRAY::Print(FILE *, int) const { } 00067 void DO_LOOP_INFO_BASE::Print(FILE *, INT) { } 00068 void IF_INFO::Print(FILE *fp) { } 00069 00070 #endif 00071 00072 // Solaris CC workaround 00073 00074 #if !defined(__GNUC__) && defined(_SOLARIS_SOLARIS) 00075 00076 #pragma weak "__1cKWB_BROWSERHSummary6MpnG__FILE__v_" 00077 #pragma weak "__1cRDO_LOOP_INFO_BASEFPrint6MpnG__FILE_i_v_" 00078 #pragma weak "__1cMACCESS_ARRAYFPrint6kMpnG__FILE_i_v_" 00079 #pragma weak "__1cHIF_INFOFPrint6MpnG__FILE__v_" 00080 00081 #elif !defined(__GNUC__) 00082 #pragma weak Id__13ALIAS_MANAGERCGPC2WN 00083 #pragma weak Print__12ACCESS_ARRAYCGP8__file_si 00084 #pragma weak Print__17DO_LOOP_INFO_BASEGP8__file_si 00085 #pragma weak Print__7IF_INFOGP8__file_s 00086 #pragma weak Summary__10WB_BROWSERGP8__file_s 00087 #else 00088 #pragma weak Print__17DO_LOOP_INFO_BASEP8_IO_FILEi 00089 #pragma weak Print__7IF_INFOP8_IO_FILE 00090 #pragma weak Print__C12ACCESS_ARRAYP8_IO_FILEi 00091 #pragma weak Print__C13ACCESS_VECTORP8_IO_FILEii 00092 #pragma weak Summary__10WB_BROWSERP8_IO_FILE 00093 00094 // Solaris GNU g++ workaround - 00095 // somehow when compiled with Solaris g++, the linker still complains undefined "WB_BROWSER::Summary" 00096 // and wb_browser.o showed the following symbols undefined, too! So I added them. This solution 00097 // seems to be better than making up a dummy funciton (?) 00098 #pragma weak Print__17DO_LOOP_INFO_BASEP4FILEi 00099 #pragma weak Print__7IF_INFOP4FILE 00100 #pragma weak Print__C12ACCESS_ARRAYP4FILEi 00101 #pragma weak Summary__10WB_BROWSERP4FILE 00102 #endif 00103 00104 static char *operator_table[OPERATOR_LAST + 1] = 00105 { 00106 "UNKNOWN", 00107 "ABS", 00108 "ADD", 00109 "AGOTO", 00110 "ALTENTRY", 00111 "ARRAY", 00112 "ARRAYEXP", 00113 "ARRSECTION", 00114 "ASHR", 00115 "ASSERT", 00116 "BACKWARD_BARRIER", 00117 "BAND", 00118 "BIOR", 00119 "BLOCK", 00120 "BNOR", 00121 "BNOT", 00122 "BXOR", 00123 "CALL", 00124 "CAND", 00125 "CASEGOTO", 00126 "CEIL", 00127 "CIOR", 00128 "COMMA", 00129 "COMMENT", 00130 "COMPGOTO", 00131 "COMPLEX", 00132 "CONST", 00133 "CSELECT", 00134 "CVT", 00135 "CVTL", 00136 "DIV", 00137 "DIVREM", 00138 "DO_LOOP", 00139 "DO_WHILE", 00140 "EQ", 00141 "EVAL", 00142 "EXC_SCOPE_BEGIN", 00143 "EXC_SCOPE_END", 00144 "FALSEBR", 00145 "FLOOR", 00146 "FORWARD_BARRIER", 00147 "FUNC_ENTRY", 00148 "GE", 00149 "GOTO", 00150 "GT", 00151 "HIGHMPY", 00152 "HIGHPART", 00153 "ICALL", 00154 "IDNAME", 00155 "IF", 00156 "ILDA", 00157 "ILDBITS", 00158 "ILOAD", 00159 "ILOADX", 00160 "IMAGPART", 00161 "INTCONST", 00162 "INTRINSIC_CALL", 00163 "INTRINSIC_OP", 00164 "IO", 00165 "IO_ITEM", 00166 "ISTBITS", 00167 "ISTORE", 00168 "ISTOREX", 00169 "LABEL", 00170 "LAND", 00171 "LDA", 00172 "LDBITS", 00173 "LDID", 00174 "LE", 00175 "LIOR", 00176 "LNOT", 00177 "LOOP_INFO", 00178 "LOWPART", 00179 "LSHR", 00180 "LT", 00181 "MADD", 00182 "MAX", 00183 "MAXPART", 00184 "MIN", 00185 "MINMAX", 00186 "MINPART", 00187 "MLOAD", 00188 "MOD", 00189 "MPY", 00190 "MSTORE", 00191 "MSUB", 00192 "NE", 00193 "NEG", 00194 "NMADD", 00195 "NMSUB", 00196 "OPTPARM", 00197 "OPT_CHI", 00198 "OPT_RESERVE2", 00199 "PAREN", 00200 "PARM", 00201 "PICCALL", 00202 "PRAGMA", 00203 "PREFETCH", 00204 "PREFETCHX", 00205 "RCOMMA", 00206 "REALPART", 00207 "RECIP", 00208 "REGION", 00209 "REGION_EXIT", 00210 "REM", 00211 "RETURN", 00212 "RETURN_VAL", 00213 "RND", 00214 "RSQRT", 00215 "SELECT", 00216 "SHL", 00217 "SQRT", 00218 "STBITS", 00219 "STID", 00220 "SUB", 00221 "SWITCH", 00222 "TAS", 00223 "TRAP", 00224 "TRIPLET", 00225 "TRUEBR", 00226 "TRUNC", 00227 "VFCALL", 00228 "WHERE", 00229 "WHILE_DO", 00230 "XGOTO", 00231 "XMPY", 00232 "XPRAGMA", 00233 "AFFIRM", 00234 "ALLOCA", 00235 "DEALLOCA", 00236 "LDMA" 00237 }; 00238 00239 //----------------------------------------------------------------------- 00240 // NAME: WB_BROWSER::WB_BROWSER 00241 // FUNCTION: Default constructor for Whirl Browser 00242 //----------------------------------------------------------------------- 00243 00244 WB_BROWSER::WB_BROWSER() 00245 { 00246 _global_fd = NULL; 00247 _du = NULL; 00248 _alias_mgr = NULL; 00249 _command_list = NULL; 00250 _old_command_list = NULL; 00251 _is_subcommand = FALSE; 00252 _dg = NULL; 00253 _parent_map = WN_MAP_UNDEFINED; 00254 _prompf_id_map = WN_MAP_UNDEFINED; 00255 _access_array_map = WN_MAP_UNDEFINED; 00256 _reduction_map = WN_MAP_UNDEFINED; 00257 _pu = NULL; 00258 _prompf_info = NULL; 00259 _scalar_summary = NULL; 00260 _array_summary = NULL; 00261 _cnode = NULL; 00262 _fancy_level = 2; 00263 _source_language = WB_SRC_NONE; 00264 _sanity_check_level = 0; 00265 for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++) 00266 _keymap[i] = i; 00267 } 00268 00269 //----------------------------------------------------------------------- 00270 // NAME: WB_BROWSER::Unmappable_Character 00271 // FUNCTION: Return TRUE if the character 'ch' is not remappable in the 00272 // .wb_keymap file. Return FALSE otherwise. 00273 //----------------------------------------------------------------------- 00274 00275 BOOL WB_BROWSER::Unmappable_Character(char ch) 00276 { 00277 switch (ch) { 00278 case ' ': 00279 case '\t': 00280 case '\n': 00281 case 'Q': 00282 case 'q': 00283 case 'H': 00284 case 'h': 00285 return TRUE; 00286 default: 00287 return FALSE; 00288 } 00289 } 00290 00291 //----------------------------------------------------------------------- 00292 // NAME: WB_BROWSER::WB_BROWSER 00293 // FUNCTION: Constructor for Whirl Browser 00294 //----------------------------------------------------------------------- 00295 00296 WB_BROWSER::WB_BROWSER(WN* global_fd, 00297 DU_MANAGER* du, 00298 ALIAS_MANAGER* alias_mgr, 00299 WN_MAP prompf_id_map, 00300 WN_MAP access_array_map, 00301 WN_MAP reduction_map, 00302 PU* pu, 00303 WB_COMMAND* command_list) : 00304 _global_fd(global_fd), _du(du), _alias_mgr(alias_mgr), 00305 _prompf_id_map(prompf_id_map), _access_array_map(access_array_map), 00306 _reduction_map(reduction_map), _pu(pu), _command_list(command_list) 00307 { 00308 _old_command_list = NULL; 00309 _is_subcommand = FALSE; 00310 _dg = NULL; 00311 _parent_map = WN_MAP_UNDEFINED; 00312 _prompf_info = NULL; 00313 _scalar_summary = NULL; 00314 _array_summary = NULL; 00315 _cnode = global_fd; 00316 _fancy_level = 2; 00317 _source_language = WB_SRC_NONE; 00318 _sanity_check_level = 0; 00319 for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++) 00320 _keymap[i] = i; 00321 } 00322 00323 //----------------------------------------------------------------------- 00324 // NAME: WB_BROWSER::This_Node 00325 // FUNCTION: Write the address of 'wn' and its whirl symbol to 'stdout'. 00326 //----------------------------------------------------------------------- 00327 00328 void WB_BROWSER::This_Node(WN* wn, 00329 BOOL print_vertex, 00330 BOOL print_brackets) 00331 { 00332 if (wn == NULL) { 00333 fprintf(stdout, "<NULL>"); 00334 return; 00335 } 00336 const char* ch = OPCODE_name(WN_opcode(wn)); 00337 if (print_brackets) 00338 fprintf(stdout, "[0x%p] ", wn); 00339 else 00340 fprintf(stdout, "0x%p ", wn); 00341 if (print_vertex && Dg() != NULL && Dg()->Get_Vertex(wn) != 0) 00342 fprintf(stdout, "V#%d ", Dg()->Get_Vertex(wn)); 00343 fprintf(stdout, "%s ", ch); 00344 if (Fancy_Level() >= 3) 00345 if (OPCODE_has_next_prev(WN_opcode(wn))) 00346 fprintf(stdout, "(%d) ", (INT) WN_linenum(wn)); 00347 if (Fancy_Level() >= 3 && Prompf_Id_Map() == -1) 00348 fprintf(stdout, "<%d> ", WN_MAP32_Get(Prompf_Id_Map(), wn)); 00349 if (WN_operator(wn) == OPR_INTCONST) { 00350 fprintf(stdout, "%lld ", WN_const_val(wn)); 00351 } else { 00352 const char* wn_symbol = WB_Whirl_Symbol(wn); 00353 if (wn_symbol != NULL) 00354 fprintf(stdout, "%s ", wn_symbol); 00355 } 00356 } 00357 00358 //----------------------------------------------------------------------- 00359 // NAME: WB_BROWSER::Print_This_Node 00360 // FUNCTION: Print the node 'wn' and a newline. 00361 //----------------------------------------------------------------------- 00362 00363 void WB_BROWSER::Print_This_Node(WN* wn, 00364 BOOL print_vertex, 00365 BOOL print_brackets) 00366 { 00367 This_Node(wn, print_vertex, print_brackets); 00368 fprintf(stdout, "\n"); 00369 } 00370 00371 //----------------------------------------------------------------------- 00372 // NAME: Address_Walk 00373 // FUNCTION: Walk the tree rooted at 'wn_tree', printing the adddresses 00374 // of all of the nodes in the subtree, with a short description of each 00375 // node. 00376 //----------------------------------------------------------------------- 00377 00378 void WB_BROWSER::Address_Walk(WN* wn_tree, 00379 INT spaces, 00380 INT increment) 00381 { 00382 for (INT i = 0; i < spaces; i++) 00383 fprintf(stdout, " "); 00384 Print_This_Node(wn_tree, FALSE, TRUE); 00385 00386 if (WN_opcode(wn_tree) == OPC_BLOCK) { 00387 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn)) 00388 Address_Walk(wn, spaces + increment, increment); 00389 } else { 00390 for (INT i = 0; i < WN_kid_count(wn_tree); i++) 00391 Address_Walk(WN_kid(wn_tree, i), spaces + increment, increment); 00392 } 00393 } 00394 00395 //----------------------------------------------------------------------- 00396 // NAME: WB_BROWSER::Addresses 00397 // WHIRL BROWSER COMMAND: '%' 00398 // FUNCTION: Print the addresses of nodes in this subtree 00399 //----------------------------------------------------------------------- 00400 00401 void WB_BROWSER::Addresses() 00402 { 00403 Address_Walk(Cnode(), 0, 2); 00404 } 00405 00406 //----------------------------------------------------------------------- 00407 // NAME: WB_BROWSER::Error_Cleanup 00408 // FUNCTION: Sound the bell, write the prompt to 'stdout' and reload the 00409 // input buffer, scanning past blanks and tabs. 00410 //----------------------------------------------------------------------- 00411 00412 void WB_BROWSER::Error_Cleanup() 00413 { 00414 WB_Bell(); 00415 WB_Prompt(); 00416 Buffer().Load_Buffer(); 00417 Buffer().Scan_Blanks_And_Tabs(); 00418 } 00419 00420 //----------------------------------------------------------------------- 00421 // NAME: WB_BROWSER::Root 00422 // WHIRL BROWSER COMMAND: 'R' 00423 // FUNCTION: Go to the root of the program unit 00424 //----------------------------------------------------------------------- 00425 00426 void WB_BROWSER::Root() 00427 { 00428 Set_Cnode(Global_Fd()); 00429 Print_This_Node(Cnode()); 00430 } 00431 00432 //----------------------------------------------------------------------- 00433 // NAME: WB_BROWSER::Next 00434 // WHIRL BROWSER COMMAND: 'N' 00435 // FUNCTION: Go to the next node in the subtree chain 00436 //----------------------------------------------------------------------- 00437 00438 void WB_BROWSER::Next() 00439 { 00440 WN* pnode = WN_next(Cnode()); 00441 if (pnode == NULL) { 00442 Error_Cleanup(); 00443 return; 00444 } 00445 Set_Cnode(pnode); 00446 Print_This_Node(Cnode()); 00447 } 00448 00449 //----------------------------------------------------------------------- 00450 // NAME: WB_BROWSER::Previous 00451 // WHIRL BROWSER COMMAND: 'P' 00452 // FUNCTION: Go to the previous node in the subtree chain 00453 //----------------------------------------------------------------------- 00454 00455 void WB_BROWSER::Previous() 00456 { 00457 WN* pnode = WN_prev(Cnode()); 00458 if (pnode == NULL) { 00459 Error_Cleanup(); 00460 return; 00461 } 00462 Set_Cnode(pnode); 00463 Print_This_Node(Cnode()); 00464 } 00465 00466 //----------------------------------------------------------------------- 00467 // NAME: WB_BROWSER::Set_Node() 00468 // WHIRL BROWSER COMMAND: '=' 00469 // FUNCTION: Set the current node to the following address 00470 //----------------------------------------------------------------------- 00471 00472 void WB_BROWSER::Set_Node() 00473 { 00474 INT node; 00475 Buffer().Scan_HexInteger(&node); 00476 Set_Cnode((WN*) node); 00477 Print_This_Node(Cnode()); 00478 } 00479 00480 //----------------------------------------------------------------------- 00481 // NAME: WB_BROWSER::Address() 00482 // WHIRL BROWSER COMMAND: '@' 00483 // FUNCTION: Set the current node to this numbered node 00484 //----------------------------------------------------------------------- 00485 00486 void WB_BROWSER::Address() 00487 { 00488 INT integer; 00489 Buffer().Scan_Integer(&integer); 00490 if (integer < 0 || integer >= Carray().Next_Index()) { 00491 Error_Cleanup(); 00492 return; 00493 } 00494 Set_Cnode(Carray().Element(integer)); 00495 Print_This_Node(Cnode()); 00496 } 00497 00498 //----------------------------------------------------------------------- 00499 // NAME: WB_BROWSER::Fancy_Up() 00500 // WHIRL BROWSER COMMAND: '>' 00501 // FUNCTION: Increase fanciness level for printing 00502 //----------------------------------------------------------------------- 00503 00504 void WB_BROWSER::Fancy_Up() 00505 { 00506 const INT fancy_max = 3; 00507 if (Fancy_Level() == fancy_max) { 00508 Error_Cleanup(); 00509 return; 00510 } 00511 INT fancy_level = Fancy_Level(); 00512 Set_Fancy_Level(++fancy_level); 00513 } 00514 00515 //----------------------------------------------------------------------- 00516 // NAME: WB_BROWSER::Fancy_Down() 00517 // WHIRL BROWSER COMMAND: '<' 00518 // FUNCTION: Decrease fanciness level for printing 00519 //----------------------------------------------------------------------- 00520 00521 void WB_BROWSER::Fancy_Down() 00522 { 00523 const INT fancy_min = 2; 00524 if (Fancy_Level() == fancy_min) { 00525 Error_Cleanup(); 00526 return; 00527 } 00528 INT fancy_level = Fancy_Level(); 00529 Set_Fancy_Level(--fancy_level); 00530 } 00531 00532 //----------------------------------------------------------------------- 00533 // NAME: WB_BROWSER::Kids() 00534 // WHIRL BROWSER COMMAND: 'K' 00535 // FUNCTION: Print the kids of this node 00536 //----------------------------------------------------------------------- 00537 00538 void WB_BROWSER::Kids() 00539 { 00540 if (WN_kid_count(Cnode()) == 0) { 00541 Error_Cleanup(); 00542 return; 00543 } 00544 Carray().Reset_Index(); 00545 for (INT i = 0; i < WN_kid_count(Cnode()); i++) { 00546 WN* kid = WN_kid(Cnode(), i); 00547 fprintf(stdout, "[%d] ", i); 00548 This_Node(kid); 00549 Carray().Enter_This_Node(kid); 00550 fprintf(stdout, "\n"); 00551 } 00552 } 00553 00554 //----------------------------------------------------------------------- 00555 // NAME: WB_BROWSER::Statements() 00556 // WHIRL BROWSER COMMAND: 'S' 00557 // FUNCTION: Print the list of statements under this node 00558 //----------------------------------------------------------------------- 00559 00560 void WB_BROWSER::Statements() 00561 { 00562 INT i = 0; 00563 if (WN_opcode(Cnode()) != OPC_BLOCK) { 00564 Error_Cleanup(); 00565 return; 00566 } 00567 if (WN_first(Cnode()) == NULL) { 00568 Error_Cleanup(); 00569 return; 00570 } 00571 Carray().Reset_Index(); 00572 for (WN* node = WN_first(Cnode()); node != NULL; i++, node = WN_next(node)) { 00573 fprintf(stdout, "[%d] ", i); 00574 This_Node(node); 00575 Carray().Enter_This_Node(node); 00576 fprintf(stdout, "\n"); 00577 } 00578 } 00579 00580 //----------------------------------------------------------------------- 00581 // NAME: WB_BROWSER::This_Tree() 00582 // WHIRL BROWSER COMMAND: 'T' 00583 // FUNCTION: Print the tree at the current node 00584 //----------------------------------------------------------------------- 00585 00586 void WB_BROWSER::This_Tree() 00587 { 00588 if (Cnode() == NULL) { 00589 Error_Cleanup(); 00590 return; 00591 } 00592 dump_tree(Cnode()); 00593 } 00594 00595 //----------------------------------------------------------------------- 00596 // NAME: Compute_ST_IDX 00597 // FUNCTION: Convert a <'st_level','st_index'> to its ST_IDX and return 00598 // the value. 00599 //----------------------------------------------------------------------- 00600 00601 extern ST_IDX Compute_ST_IDX(UINT32 st_level, 00602 UINT32 st_index) 00603 { 00604 UINT32 st_idx = st_level + (st_index << 8); 00605 return (ST_IDX) (st_idx); 00606 } 00607 00608 //----------------------------------------------------------------------- 00609 // NAME: WB_BROWSER::Symbol() 00610 // WHIRL BROWSER COMMAND: 's' 00611 // FUNCTION: Print the symbol table entry for this node 00612 //----------------------------------------------------------------------- 00613 00614 void WB_BROWSER::Symbol() 00615 { 00616 if (Buffer().Is('<')) { 00617 UINT32 st_level; 00618 UINT32 st_index; 00619 Buffer().Scan_Character(); 00620 Buffer().Scan_Unsigned(&st_level); 00621 char separator = Buffer().Scan_Character(); 00622 if (separator != ',') { 00623 Error_Cleanup(); 00624 return; 00625 } 00626 Buffer().Scan_Unsigned(&st_index); 00627 char right_angle_bracket = Buffer().Scan_Character(); 00628 if (right_angle_bracket != '>') { 00629 Error_Cleanup(); 00630 return; 00631 } 00632 ST_IDX st_idx = Compute_ST_IDX(st_level, st_index); 00633 ST* st = &St_Table[st_idx]; 00634 fprintf(stdout, "ST_IDX: %d\n", st_idx); 00635 Print_ST(stdout, st, TRUE); 00636 } else if (Buffer().Is_Integer()) { 00637 ST_IDX st_idx; 00638 Buffer().Scan_Unsigned(&st_idx); 00639 ST* st = &St_Table[st_idx]; 00640 fprintf(stdout, "ST_IDX: %d\n", st_idx); 00641 Print_ST(stdout, st, TRUE); 00642 } else { 00643 if (!OPCODE_has_sym(WN_opcode(Cnode()))) { 00644 Error_Cleanup(); 00645 return; 00646 } 00647 Print_ST(stdout, WN_st(Cnode()), TRUE); 00648 } 00649 } 00650 00651 //----------------------------------------------------------------------- 00652 // NAME: WB_BROWSER::Type() 00653 // WHIRL BROWSER COMMAND: 't' 00654 // FUNCTION: Print the type table entry for this node 00655 //----------------------------------------------------------------------- 00656 00657 void WB_BROWSER::Type() 00658 { 00659 if (Buffer().Is('<')) { 00660 UINT32 ty_index = 0; 00661 Buffer().Scan_Character(); 00662 Buffer().Scan_Unsigned(&ty_index); 00663 char right_angle_bracket = Buffer().Scan_Character(); 00664 if (right_angle_bracket != '>') { 00665 Error_Cleanup(); 00666 return; 00667 } 00668 Ty_tab[ty_index].Print(stdout); 00669 } else if (Buffer().Is_Integer()) { 00670 TY_IDX ty_idx = 0; 00671 Buffer().Scan_Unsigned(&ty_idx); 00672 Print_TY(stdout, ty_idx); 00673 } else { 00674 if (!OPCODE_has_sym(WN_opcode(Cnode()))) { 00675 Error_Cleanup(); 00676 return; 00677 } 00678 Ty_Table[ST_type(WN_st(Cnode()))].Print(stdout); 00679 } 00680 } 00681 00682 //----------------------------------------------------------------------- 00683 // NAME: Is_Substring 00684 // FUNCTION: Return TRUE if 's1' is a substring of 's2', return FALSE 00685 // otherwise. 00686 //----------------------------------------------------------------------- 00687 00688 static BOOL Is_Substring(char s1[], 00689 char s2[]) 00690 { 00691 INT substring_length = strlen(s1); 00692 INT string_length = strlen(s2); 00693 INT difference = string_length - substring_length; 00694 if (substring_length > string_length) 00695 return FALSE; 00696 INT i, j; 00697 for (i = 0; i <= difference; i++) { 00698 for (j = 0; j < substring_length; j++) 00699 if (s1[j] != s2[i + j]) 00700 break; 00701 if (j == substring_length) 00702 return TRUE; 00703 } 00704 return FALSE; 00705 } 00706 00707 //----------------------------------------------------------------------- 00708 // NAME: WB_BROWSER::Find() 00709 // WHIRL BROWSER COMMAND: 'F' 00710 // FUNCTION: Find nodes with this symbol in the subtree 00711 //----------------------------------------------------------------------- 00712 00713 void WB_BROWSER::Find_Walk(char *s, WN* wn) 00714 { 00715 if (wn == NULL) 00716 return; 00717 char* wn_symbol = (char *) WB_Whirl_Symbol(wn); 00718 BOOL test_substring = s[0] == '\''; 00719 if (wn_symbol != NULL && (!test_substring && strcmp(wn_symbol, s) == 0 00720 || test_substring && Is_Substring(&s[1], wn_symbol))) { 00721 fprintf(stdout, "[%d] ", Carray().Next_Index()); 00722 This_Node(wn); 00723 Carray().Enter_This_Node(wn); 00724 fprintf(stdout, "\n"); 00725 } 00726 for (INT i = 0; i < WN_kid_count(wn); i++) 00727 Find_Walk(s, WN_kid(wn, i)); 00728 if (WN_opcode(wn) == OPC_BLOCK) 00729 for (WN* wn_sub = WN_first(wn); wn_sub != NULL; wn_sub = WN_next(wn_sub)) 00730 Find_Walk(s, wn_sub); 00731 } 00732 00733 void WB_BROWSER::Find() 00734 { 00735 char s[WB_MAX_STRING_LENGTH]; 00736 Buffer().Scan_Alphanumeric(s); 00737 Carray().Reset_Index(); 00738 Find_Walk(s, Cnode()); 00739 } 00740 00741 //----------------------------------------------------------------------- 00742 // NAME: WB_BROWSER::Find_Operator() 00743 // WHIRL BROWSER COMMAND: 'o' 00744 // FUNCTION: Find nodes with this operator in the subtree 00745 //----------------------------------------------------------------------- 00746 00747 void WB_BROWSER::Find_Operator_Walk(OPERATOR opr_test, WN* wn) 00748 { 00749 if (wn == NULL) 00750 return; 00751 if (WN_operator(wn) == opr_test) { 00752 fprintf(stdout, "[%d] ", Carray().Next_Index()); 00753 This_Node(wn); 00754 Carray().Enter_This_Node(wn); 00755 fprintf(stdout, "\n"); 00756 } 00757 if (WN_opcode(wn) == OPC_BLOCK) { 00758 for (WN* wn_sub = WN_first(wn); wn_sub != NULL; wn_sub = WN_next(wn_sub)) 00759 Find_Operator_Walk(opr_test, wn_sub); 00760 } else { 00761 for (INT i = 0; i < WN_kid_count(wn); i++) 00762 Find_Operator_Walk(opr_test, WN_kid(wn, i)); 00763 } 00764 } 00765 00766 void WB_BROWSER::Find_Operator() 00767 { 00768 char s[WB_MAX_STRING_LENGTH]; 00769 Buffer().Scan_Alphanumeric(s); 00770 INT i; 00771 for (i = 1; i <= OPERATOR_LAST; i++) 00772 if (!strcmp(s, operator_table[i])) 00773 break; 00774 if (i > OPERATOR_LAST) { 00775 Error_Cleanup(); 00776 return; 00777 } 00778 Carray().Reset_Index(); 00779 Find_Operator_Walk((OPERATOR) i, Cnode()); 00780 } 00781 00782 //----------------------------------------------------------------------- 00783 // NAME: WB_BROWSER::Uses() 00784 // WHIRL BROWSER COMMAND: 'U' 00785 // FUNCTION: Print the uses at the current node 00786 //----------------------------------------------------------------------- 00787 00788 void WB_BROWSER::Uses() 00789 { 00790 if (Du() == NULL) { 00791 Error_Cleanup(); 00792 return; 00793 } 00794 USE_LIST *use_list = Du()->Du_Get_Use(Cnode()); 00795 if (use_list == NULL) { 00796 Error_Cleanup(); 00797 return; 00798 } 00799 Carray().Reset_Index(); 00800 if (use_list->Incomplete()) 00801 fprintf(stdout, "WARNING: USE LIST INCOMPLETE\n"); 00802 USE_LIST_ITER iter(use_list); 00803 const DU_NODE* node = NULL; 00804 INT i = 0; 00805 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) { 00806 WN* use = node->Wn(); 00807 fprintf(stdout, "[%d] ", i++); 00808 Print_This_Node(use); 00809 Carray().Enter_This_Node(use); 00810 } 00811 } 00812 00813 //----------------------------------------------------------------------- 00814 // NAME: WB_BROWSER::Defs 00815 // WHIRL BROWSER COMMAND: 'D' 00816 // FUNCTION: Print the definitions at the current node 00817 //----------------------------------------------------------------------- 00818 00819 void WB_BROWSER::Defs() 00820 { 00821 if (Du() == NULL) { 00822 Error_Cleanup(); 00823 return; 00824 } 00825 DEF_LIST* def_list = Du()->Ud_Get_Def(Cnode()); 00826 if (def_list == NULL) { 00827 Error_Cleanup(); 00828 return; 00829 } 00830 if (def_list->Incomplete()) 00831 fprintf(stdout, "WARNING: DEF LIST INCOMPLETE\n"); 00832 fprintf(stdout, "Loop Statement: 0x%p\n", def_list->Loop_stmt()); 00833 DEF_LIST_ITER iter(def_list); 00834 const DU_NODE* node = NULL; 00835 INT i = 0; 00836 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) { 00837 WN* def = node->Wn(); 00838 fprintf(stdout, "[%d] ", i++); 00839 Print_This_Node(def); 00840 Carray().Enter_This_Node(def); 00841 } 00842 } 00843 00844 //----------------------------------------------------------------------- 00845 // NAME: WB_BROWSER::Access_Array() 00846 // WHIRL BROWSER COMMAND: 'A' 00847 // FUNCTION: Print the access array info for this node 00848 //----------------------------------------------------------------------- 00849 00850 void WB_BROWSER::Access_Array() 00851 { 00852 if (Access_Array_Map() == -1) { 00853 Error_Cleanup(); 00854 return; 00855 } 00856 if (WN_operator(Cnode()) == OPR_ARRAY) { 00857 ACCESS_ARRAY *array 00858 = (ACCESS_ARRAY *) WN_MAP_Get(Access_Array_Map(), Cnode()); 00859 if (array != NULL) { 00860 fprintf(stdout, "The access array is \n"); 00861 array->Print(stdout); 00862 } else { 00863 fprintf(stdout, "Null ACCESS_ARRAY\n"); 00864 } 00865 } else if (WN_operator(Cnode()) == OPR_IF) { 00866 IF_INFO *info = (IF_INFO *) WN_MAP_Get(Access_Array_Map(), Cnode()); 00867 if (info != NULL) { 00868 fprintf(stdout, "The if info is \n"); 00869 info->Print(stdout); 00870 } else { 00871 fprintf(stdout, "Null IF_INFO\n"); 00872 } 00873 } else if (WN_operator(Cnode()) == OPR_DO_LOOP) { 00874 DO_LOOP_INFO_BASE* info 00875 = (DO_LOOP_INFO_BASE*) WN_MAP_Get(Access_Array_Map(), Cnode()); 00876 if (info != NULL) { 00877 fprintf(stdout, "The loop info is \n"); 00878 info->Print(stdout); 00879 } else { 00880 fprintf(stdout, "NulleDO_LOOP_INFO_BASE\n"); 00881 } 00882 } else { 00883 Error_Cleanup(); 00884 } 00885 } 00886 00887 //----------------------------------------------------------------------- 00888 // NAME: WB_BROWSER::Reduction() 00889 // WHIRL BROWSER COMMAND: 'r' 00890 // FUNCTION: Print the reduction manager 00891 //----------------------------------------------------------------------- 00892 00893 void WB_BROWSER::Reduction_Node(WN* wn, 00894 FILE* fp) 00895 { 00896 if (OPCODE_is_load(WN_opcode(wn)) || OPCODE_is_store(WN_opcode(wn))) { 00897 INT32 red_type = WN_MAP32_Get(Reduction_Map(), wn); 00898 switch (red_type) { 00899 case RED_ADD: 00900 fprintf(fp, "[%d] 0x%p RED_ADD ", Carray().Next_Index(), wn); 00901 break; 00902 case RED_MPY: 00903 fprintf(fp, "[%d] 0x%p RED_MPY ", Carray().Next_Index(), wn); 00904 break; 00905 case RED_MIN: 00906 fprintf(fp, "[%d] 0x%p RED_MIN ", Carray().Next_Index(), wn); 00907 break; 00908 case RED_MAX: 00909 fprintf(fp, "[%d] 0x%p RED_MAX ", Carray().Next_Index(), wn); 00910 break; 00911 } 00912 switch (red_type) { 00913 case RED_ADD: 00914 case RED_MPY: 00915 case RED_MIN: 00916 case RED_MAX: 00917 OPERATOR oper = WN_operator(wn); 00918 if (oper == OPR_ILOAD || oper == OPR_ISTORE) { 00919 Dep_Symbol(wn); 00920 fprintf(fp, "\n"); 00921 } else { 00922 const char *name = WB_Whirl_Symbol(wn); 00923 fprintf(fp, "%s\n", name); 00924 } 00925 Carray().Enter_This_Node(wn); 00926 break; 00927 } 00928 } 00929 } 00930 00931 void WB_BROWSER::Reduction_Walk(WN* wn_tree, 00932 FILE* fp) 00933 { 00934 if (WN_operator(wn_tree) == OPR_BLOCK) { 00935 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn)) 00936 Reduction_Walk(wn, fp); 00937 } else { 00938 Reduction_Node(wn_tree, fp); 00939 for (INT i = 0; i < WN_kid_count(wn_tree); i++) 00940 Reduction_Walk(WN_kid(wn_tree, i), fp); 00941 } 00942 } 00943 00944 void WB_BROWSER::Reduction() 00945 { 00946 if (Reduction_Map() == WN_MAP_UNDEFINED) { 00947 Error_Cleanup(); 00948 return; 00949 } 00950 Carray().Reset_Index(); 00951 Reduction_Walk(Cnode(), stdout); 00952 } 00953 00954 //----------------------------------------------------------------------- 00955 // NAME: WB_BROWSER::Alias() 00956 // WHIRL BROWSER COMMAND: 'a' 00957 // FUNCTION: Print the alias info for this node 00958 //----------------------------------------------------------------------- 00959 00960 BOOL WB_BROWSER::Aliased_Node(WN* wn) 00961 { 00962 OPCODE opc = WN_opcode(wn); 00963 OPERATOR opr = OPCODE_operator(opc); 00964 return (OPCODE_is_load(opc) || OPCODE_is_store(opc) || opr == OPR_PARM) 00965 && Alias_Mgr()->Id(wn) != 0; 00966 } 00967 00968 void WB_BROWSER::Alias_Walk(WN* wn_test, 00969 WN* wn_start, 00970 ALIAS_RESULT ar) 00971 { 00972 if (Aliased_Node(wn_start)) { 00973 ALIAS_RESULT result = Aliased(Alias_Mgr(), wn_test, wn_start); 00974 switch (result) { 00975 case NOT_ALIASED: 00976 break; 00977 case POSSIBLY_ALIASED: 00978 case SAME_LOCATION: 00979 if (ar == result) { 00980 fprintf(stdout, " [%d] ", Carray().Next_Index()); 00981 Print_This_Node(wn_start); 00982 Carray().Enter_This_Node(wn_start); 00983 } 00984 break; 00985 } 00986 } 00987 00988 if (WN_opcode(wn_start) == OPC_BLOCK) { 00989 for (WN* wn = WN_first(wn_start); wn != NULL; wn = WN_next(wn)) 00990 Alias_Walk(wn_test, wn, ar); 00991 } else { 00992 for (INT i = 0; i < WN_kid_count(wn_start); i++) 00993 Alias_Walk(wn_test, WN_kid(wn_start, i), ar); 00994 } 00995 } 00996 00997 void WB_BROWSER::Alias() 00998 { 00999 if (!Aliased_Node(Cnode())) { 01000 Error_Cleanup(); 01001 return; 01002 } 01003 Carray().Reset_Index(); 01004 fprintf(stdout, "POSSIBLY ALIASED: \n"); 01005 Alias_Walk(Cnode(), Global_Fd(), POSSIBLY_ALIASED); 01006 if (Carray().Next_Index() == 0) 01007 fprintf(stdout, " NO LOCATIONS\n"); 01008 INT possible_aliases = Carray().Next_Index(); 01009 fprintf(stdout, "SAME LOCATION: \n"); 01010 Alias_Walk(Cnode(), Global_Fd(), SAME_LOCATION); 01011 if (Carray().Next_Index() == possible_aliases) 01012 fprintf(stdout, " NO LOCATIONS\n"); 01013 } 01014 01015 //----------------------------------------------------------------------- 01016 // NAME: WB_Parent_Search 01017 // FUNCTION: For the tree rooted at 'wn_root', find the path of nodes 01018 // leading from this node to 'wn_node' and push it on the stack 01019 // 'stk_parent'. If there is no path from 'wn_root' to 'wn_node', 01020 // return an empty stack. 01021 //----------------------------------------------------------------------- 01022 01023 static BOOL WB_Parent_Search(WN* wn_root, 01024 STACK<WN*>* stk_parent, 01025 WN* wn_node) 01026 { 01027 stk_parent->Push(wn_root); 01028 if (wn_root == wn_node) 01029 return TRUE; 01030 if (WN_opcode(wn_root) == OPC_BLOCK) { 01031 for (WN* wn = WN_first(wn_root); wn != NULL; wn = WN_next(wn)) { 01032 BOOL found_path = WB_Parent_Search(wn, stk_parent, wn_node); 01033 if (found_path) 01034 return TRUE; 01035 } 01036 } else { 01037 for (INT i = 0; i < WN_kid_count(wn_root); i++) { 01038 BOOL found_path = WB_Parent_Search(WN_kid(wn_root, i), stk_parent, 01039 wn_node); 01040 if (found_path) 01041 return TRUE; 01042 } 01043 } 01044 stk_parent->Pop(); 01045 return FALSE; 01046 } 01047 01048 //----------------------------------------------------------------------- 01049 // NAME: WB_BROWSER::Parent 01050 // WHIRL BROWSER COMMAND: 'E' 01051 // FUNCTION: Go to the parent of the current node 01052 //----------------------------------------------------------------------- 01053 01054 void WB_BROWSER::Parent() 01055 { 01056 if (Cnode() == Global_Fd()) { 01057 Error_Cleanup(); 01058 return; 01059 } 01060 if (Parent_Map() == -1) { 01061 MEM_POOL_Push(&MEM_local_pool); 01062 STACK<WN*> stk_parent(&MEM_local_pool); 01063 BOOL found_path = WB_Parent_Search(Global_Fd(), &stk_parent, Cnode()); 01064 if (!found_path) { 01065 Error_Cleanup(); 01066 MEM_POOL_Pop(&MEM_local_pool); 01067 return; 01068 } 01069 Set_Cnode(stk_parent.Bottom_nth(stk_parent.Elements() - 2)); 01070 Print_This_Node(Cnode()); 01071 MEM_POOL_Pop(&MEM_local_pool); 01072 } else { 01073 WN* pnode = (WN*) WN_MAP_Get(Parent_Map(), Cnode()); 01074 if (pnode == NULL) { 01075 Error_Cleanup(); 01076 return; 01077 } 01078 Set_Cnode(pnode); 01079 Print_This_Node(Cnode()); 01080 } 01081 } 01082 01083 //----------------------------------------------------------------------- 01084 // NAME: WB_BROWSER:Ancestors 01085 // WHIRL BROWSER COMMAND: 'e' 01086 // FUNCTION: Print the ancestors of this node 01087 //----------------------------------------------------------------------- 01088 01089 void WB_BROWSER::Ancestors() 01090 { 01091 if (Cnode() == Global_Fd()) { 01092 Error_Cleanup(); 01093 return; 01094 } 01095 if (Parent_Map() == -1) { 01096 Carray().Reset_Index(); 01097 MEM_POOL_Push(&MEM_local_pool); 01098 STACK<WN*> stk_parent(&MEM_local_pool); 01099 BOOL found_path = WB_Parent_Search(Global_Fd(), &stk_parent, Cnode()); 01100 if (!found_path) { 01101 Error_Cleanup(); 01102 MEM_POOL_Pop(&MEM_local_pool); 01103 return; 01104 } 01105 INT i = 0; 01106 for (INT j = stk_parent.Elements() - 1; j >= 0; j--) { 01107 Carray().Enter_This_Node(stk_parent.Bottom_nth(j)); 01108 fprintf(stdout, "[%d] ", i++); 01109 Print_This_Node(stk_parent.Bottom_nth(j)); 01110 } 01111 MEM_POOL_Pop(&MEM_local_pool); 01112 } else { 01113 Carray().Reset_Index(); 01114 WN* wnn = NULL; 01115 INT i = 0; 01116 for (WN* wn = Cnode(); wn != NULL; wn = wnn) { 01117 wnn = ((WN*) WN_MAP_Get(Parent_Map(), (WN*) wn)); 01118 Carray().Enter_This_Node(wn); 01119 fprintf(stdout, "[%d] ", i++); 01120 Print_This_Node(wn); 01121 } 01122 } 01123 } 01124 01125 //----------------------------------------------------------------------- 01126 // NAME: WB_BROWSER::Promp_Map 01127 // WHIRL BROWSER COMMAND: 'i' 01128 // FUNCTION: Print the PROMPF ids for tree at this node 01129 //----------------------------------------------------------------------- 01130 01131 void WB_BROWSER::Promp_Map() 01132 { 01133 if (Prompf_Id_Map() == -1) { 01134 Error_Cleanup(); 01135 return; 01136 } 01137 Carray().Reset_Index(); 01138 WN_ITER* itr = WN_WALK_TreeIter(Cnode()); 01139 for (INT i = 0; itr != NULL; itr = WN_WALK_TreeNext(itr)) { 01140 WN* wn = itr->wn; 01141 INT32 map_id = WN_MAP32_Get(Prompf_Id_Map(), wn); 01142 if (map_id != 0) { 01143 fprintf(stdout, "[%d] %3d ", i++, map_id); 01144 Print_This_Node(wn); 01145 Carray().Enter_This_Node(wn); 01146 } 01147 } 01148 } 01149 01150 //----------------------------------------------------------------------- 01151 // NAME: WB_BROWSER::Promp_Info 01152 // WHIRL BROWSER COMMAND: 'I' 01153 // FUNCTION: Print the PROMPF_INFO 01154 //----------------------------------------------------------------------- 01155 01156 void WB_BROWSER::Promp_Info() 01157 { 01158 if (!(Prompf_Info() != NULL)) { 01159 Error_Cleanup(); 01160 return; 01161 } 01162 Prompf_Info()->Print(stdout); 01163 } 01164 01165 //----------------------------------------------------------------------- 01166 // NAME: WB_BROWSER::Whirl2fc() 01167 // WHIRL BROWSER COMMAND: 'W' 01168 // FUNCTION: Print tree in whirl2[fc] format at current node 01169 //----------------------------------------------------------------------- 01170 01171 void WB_BROWSER::Whirl2fc() 01172 { 01173 if (Source_Language() == WB_SRC_NONE) { 01174 Whirl2Src_Init(Global_Fd()); 01175 Whirl2Src_Emit(stdout, Cnode()); 01176 fprintf(stdout, "\n"); 01177 } else if (Source_Language() == WB_SRC_FORTRAN) { 01178 Whirl2F_Init(Global_Fd()); 01179 Whirl2F_Emit(stdout, Cnode()); 01180 fprintf(stdout, "\n"); 01181 } else if (Source_Language() == WB_SRC_C) { 01182 Whirl2C_Init(Global_Fd()); 01183 Whirl2C_Emit(stdout, Cnode()); 01184 fprintf(stdout, "\n"); 01185 } 01186 } 01187 01188 //----------------------------------------------------------------------- 01189 // NAME: WB_BROWSER::Whirl2fset 01190 // WHIRL BROWSER COMMAND: 'f' 01191 // FUNCTION: Change WHIRL-TO-SOURCE language to FORTRAN 01192 //----------------------------------------------------------------------- 01193 01194 void WB_BROWSER::Whirl2fset() 01195 { 01196 if (Source_Language() != WB_SRC_FORTRAN) { 01197 Whirl2F_Init(Global_Fd()); 01198 Set_Source_Language(WB_SRC_FORTRAN); 01199 } 01200 fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n"); 01201 } 01202 01203 //----------------------------------------------------------------------- 01204 // NAME: WB_BROWSER::Whirl2cset 01205 // WHIRL BROWSER COMMAND: 'c' 01206 // FUNCTION: Change WHIRL-TO-SOURCE language to C 01207 //----------------------------------------------------------------------- 01208 01209 void WB_BROWSER::Whirl2cset() 01210 { 01211 if (Source_Language() != WB_SRC_C) { 01212 Whirl2C_Init(Global_Fd()); 01213 Set_Source_Language(WB_SRC_C); 01214 } 01215 fprintf(stdout, "WHIRL-TO-SOURCE language is C.\n"); 01216 } 01217 01218 //----------------------------------------------------------------------- 01219 // NAME: Compact_Buffer 01220 // FUNCTION: Compact 'buffer' by replacing strings like '+-' with '-' 01221 // and '--' with '+'. 01222 //----------------------------------------------------------------------- 01223 01224 static void Compact_Buffer(char buffer[]) 01225 { 01226 INT i, j; 01227 for (i = 0, j = 0; buffer[i] != '\0'; i++) { 01228 if (buffer[i] == '+' && buffer[i+1] == '-') { 01229 buffer[j++] = '-'; 01230 i++; 01231 } else if (buffer[i] == '-' && buffer[i+1] == '-') { 01232 buffer[j++] = '+'; 01233 i++; 01234 } else { 01235 buffer[j++] = buffer[i]; 01236 } 01237 } 01238 buffer[j] = '\0'; 01239 } 01240 01241 //----------------------------------------------------------------------- 01242 // NAME: WB_BROWSER::Dep_Symbol() 01243 // FUNCTION: Write to 'stdout' a representation of the symbol for 'wn'. 01244 //----------------------------------------------------------------------- 01245 01246 void WB_BROWSER::Dep_Symbol(WN *wn) 01247 { 01248 WN* symbol_node = NULL; 01249 char buffer[WB_MAX_STRING_LENGTH]; 01250 switch (WN_operator(wn)) { 01251 case OPR_ISTORE: 01252 symbol_node = WN_kid1(wn); 01253 break; 01254 case OPR_ILOAD: 01255 symbol_node = WN_kid0(wn); 01256 break; 01257 } 01258 if (symbol_node == NULL) 01259 return; 01260 INT cc = WB_Dump_Whirl_Expr(symbol_node, symbol_node, buffer, 0); 01261 Compact_Buffer(buffer); 01262 if (cc > WB_MAX_STRING_LENGTH - 1) { 01263 fprintf(stdout, "Expression too long!\n"); 01264 Error_Cleanup(); 01265 return; 01266 } 01267 fputs(buffer, stdout); 01268 } 01269 01270 //----------------------------------------------------------------------- 01271 // NAME: WB_BROWSER::Deps() 01272 // WHIRL BROWSER COMMAND: 'G' 01273 // FUNCTION: Print the dep graph info at the current node 01274 //----------------------------------------------------------------------- 01275 01276 void WB_BROWSER::Deps_Loop() 01277 { 01278 if (Dg() == NULL) { 01279 Error_Cleanup(); 01280 return; 01281 } 01282 Carray().Reset_Index(); 01283 WN* start_node = NULL; 01284 switch (WN_opcode(Cnode())) { 01285 case OPC_DO_LOOP: 01286 start_node = WN_do_body(Cnode()); 01287 break; 01288 case OPC_DO_WHILE: 01289 case OPC_WHILE_DO: 01290 start_node = WN_while_body(Cnode()); 01291 break; 01292 } 01293 WN_ITER* itr = WN_WALK_TreeIter(start_node); 01294 for (; itr != NULL; itr = WN_WALK_TreeNext(itr)) { 01295 WN* wn = itr->wn; 01296 VINDEX16 v = Dg()->Get_Vertex(wn); 01297 if (v == 0) 01298 continue; 01299 INT j = Carray().Enter_This_Node_Unique(wn); 01300 fprintf(stdout, "[%d] ", j); 01301 This_Node(wn); 01302 fprintf(stdout, "V#%d ", v); 01303 Dep_Symbol(wn); 01304 fprintf(stdout, "\n"); 01305 EINDEX16 e; 01306 if (Dg()->Get_In_Edge(v)) { 01307 fprintf(stdout, " "); 01308 fprintf(stdout, "IN EDGES:\n"); 01309 for (e = Dg()->Get_In_Edge(v); e != 0; e = Dg()->Get_Next_In_Edge(e)) { 01310 fprintf(stdout, " "); 01311 INT j = Carray().Enter_This_Node_Unique( 01312 Dg()->Get_Wn(Dg()->Get_Source(e))); 01313 fprintf(stdout, "[%d] ", j); 01314 This_Node(Dg()->Get_Wn(Dg()->Get_Source(e))); 01315 fprintf(stdout, "E#%d ", e); 01316 Dep_Symbol(Dg()->Get_Wn(Dg()->Get_Source(e))); 01317 } 01318 } 01319 if (Dg()->Get_Out_Edge(v)) { 01320 fprintf(stdout, " "); 01321 fprintf(stdout, "OUT EDGES:\n"); 01322 for (e = Dg()->Get_Out_Edge(v); e != 0; e = Dg()->Get_Next_Out_Edge(e)) { 01323 fprintf(stdout, " "); 01324 INT j = Carray().Enter_This_Node_Unique( 01325 Dg()->Get_Wn(Dg()->Get_Sink(e))); 01326 fprintf(stdout, "[%d] ", j); 01327 This_Node(Dg()->Get_Wn(Dg()->Get_Sink(e))); 01328 fprintf(stdout, "E#%d ", e); 01329 Dep_Symbol(Dg()->Get_Wn(Dg()->Get_Sink(e))); 01330 } 01331 } 01332 } 01333 } 01334 01335 void WB_BROWSER::Deps_Ref() 01336 { 01337 if (Dg() == NULL) { 01338 Error_Cleanup(); 01339 return; 01340 } 01341 VINDEX16 v = Dg()->Get_Vertex(Cnode()); 01342 if (v == 0) { 01343 Error_Cleanup(); 01344 return; 01345 } 01346 EINDEX16 e; 01347 if (!Dg()->Get_In_Edge(v) && !Dg()->Get_Out_Edge(v)) 01348 fprintf(stdout, "V#%d\n", v); 01349 Carray().Reset_Index(); 01350 if (Dg()->Get_In_Edge(v)) { 01351 fprintf(stdout, "V#%d ", v); 01352 fprintf(stdout, "IN EDGES:\n"); 01353 for (e = Dg()->Get_In_Edge(v); e != 0; e = Dg()->Get_Next_In_Edge(e)) { 01354 INT j = Carray().Enter_This_Node_Unique( 01355 Dg()->Get_Wn(Dg()->Get_Source(e))); 01356 fprintf(stdout, "[%d] ", j); 01357 This_Node(Dg()->Get_Wn(Dg()->Get_Source(e))); 01358 fprintf(stdout, "E#%d ", e); 01359 } 01360 } 01361 if (Dg()->Get_Out_Edge(v)) { 01362 fprintf(stdout, "V#%d ", v); 01363 fprintf(stdout, "OUT EDGES:\n"); 01364 for (e = Dg()->Get_Out_Edge(v); e != 0; e = Dg()->Get_Next_Out_Edge(e)) { 01365 INT j = Carray().Enter_This_Node_Unique( 01366 Dg()->Get_Wn(Dg()->Get_Sink(e))); 01367 fprintf(stdout, "[%d] ", j); 01368 This_Node(Dg()->Get_Wn(Dg()->Get_Sink(e))); 01369 fprintf(stdout, "E#%d ", e); 01370 } 01371 } 01372 } 01373 01374 void WB_BROWSER::Deps() 01375 { 01376 switch (WN_opcode(Cnode())) { 01377 case OPC_DO_LOOP: 01378 case OPC_DO_WHILE: 01379 case OPC_WHILE_DO: 01380 Deps_Loop(); 01381 break; 01382 default: 01383 Deps_Ref(); 01384 break; 01385 } 01386 } 01387 01388 //----------------------------------------------------------------------- 01389 // NAME: WB_BROWSER::Vertices 01390 // WHIRL BROWSER COMMAND: 'V' 01391 // FUNCTION: Print the vertices of the dep graph 01392 //----------------------------------------------------------------------- 01393 01394 void WB_BROWSER::Vertices() 01395 { 01396 if (Dg() == NULL) { 01397 Error_Cleanup(); 01398 return; 01399 } 01400 VINDEX16 v; 01401 for (v = Dg()->Get_Vertex(); v; v = Dg()->Get_Next_Vertex(v)) { 01402 WN* wn = Dg()->Get_Wn(v); 01403 fprintf(stdout, "V#%d ", (INT) v); 01404 This_Node(wn, FALSE); 01405 Dep_Symbol(wn); 01406 fprintf(stdout, "\n"); 01407 } 01408 01409 VINDEX16 w; 01410 for (v = Dg()->Get_Vertex(); v; v = Dg()->Get_Next_Vertex(v)) 01411 for (w = Dg()->Get_Next_Vertex(v); w; w = Dg()->Get_Next_Vertex(w)) 01412 if (Dg()->Get_Wn(v) == Dg()->Get_Wn(w)) 01413 fprintf(stdout, "Vertices %d and %d are for the same node!\n", v, w); 01414 } 01415 01416 //----------------------------------------------------------------------- 01417 // NAME: WB_BROWSER::Vertex_Set_Node 01418 // WHIRL BROWSER COMMAND: 'v' 01419 // FUNCTION: Set the current node to the node with the following vertex 01420 // number 01421 //----------------------------------------------------------------------- 01422 01423 void WB_BROWSER::Vertex_Set_Node() 01424 { 01425 if (Dg() == NULL) { 01426 Error_Cleanup(); 01427 return; 01428 } 01429 INT vertex_number = 0; 01430 Buffer().Scan_Integer(&vertex_number); 01431 VINDEX16 v; 01432 for (v = Dg()->Get_Vertex(); v != 0; v = Dg()->Get_Next_Vertex(v)) 01433 if (v == (VINDEX16) vertex_number) 01434 break; 01435 if (v == 0) { 01436 Error_Cleanup(); 01437 return; 01438 } 01439 Set_Cnode(Dg()->Get_Wn((VINDEX16) vertex_number)); 01440 Print_This_Node(Cnode()); 01441 } 01442 01443 INT loop_count = 0; 01444 01445 //----------------------------------------------------------------------- 01446 // NAME: Dump_Spaces 01447 // FUNCTION: Print 'spaces' number of spaces to the file 'fp'. 01448 //----------------------------------------------------------------------- 01449 01450 static void Dump_Spaces(FILE* fp, 01451 INT spaces) 01452 { 01453 for (INT i = 0; i < spaces; i++) 01454 fprintf(fp, " "); 01455 } 01456 01457 //----------------------------------------------------------------------- 01458 // NAME: WB_BROWSER::Loops() 01459 // WHIRL BROWSER COMMAND: 'L' 01460 // FUNCTION: Sketch the loop nests in the program unit 01461 //----------------------------------------------------------------------- 01462 01463 void WB_BROWSER::Loops_Walk(WN* wn, 01464 FILE* fp, 01465 INT spaces, 01466 INT increment) 01467 { 01468 WN* w = 0; 01469 const char* name = NULL; 01470 switch (WN_opcode(wn)) { 01471 case OPC_BLOCK: 01472 for (w = WN_first(wn); w; w = WN_next(w)) 01473 Loops_Walk(w, fp, spaces, increment); 01474 break; 01475 case OPC_DO_LOOP: 01476 Dump_Spaces(fp, spaces); 01477 name = WB_Whirl_Symbol(wn); 01478 if (Prompf_Id_Map() != -1) { 01479 fprintf(fp, "[%d] 0x%p DOLOOP (%d) <%d> %s\n", Carray().Next_Index(), wn, 01480 (INT) WN_linenum(wn), WN_MAP32_Get(Prompf_Id_Map(), wn), name); 01481 } else { 01482 fprintf(fp, "[%d] 0x%p DOLOOP (%d) %s\n", Carray().Next_Index(), wn, 01483 (INT) WN_linenum(wn), name); 01484 } 01485 Carray().Enter_This_Node(wn); 01486 Loops_Walk(WN_do_body(wn), fp, spaces + increment, increment); 01487 break; 01488 case OPC_FUNC_ENTRY: 01489 Dump_Spaces(fp, spaces); 01490 if (Prompf_Id_Map() != -1) { 01491 fprintf(fp, "[%d] 0x%p FUNC_ENTRY <%d> %s\n", Carray().Next_Index(), wn, 01492 WN_MAP32_Get(Prompf_Id_Map(), wn), WB_Whirl_Symbol(wn)); 01493 } else { 01494 fprintf(fp, "[%d] 0x%p FUNC_ENTRY %s\n", Carray().Next_Index(), wn, 01495 WB_Whirl_Symbol(wn)); 01496 } 01497 Carray().Enter_This_Node(wn); 01498 Loops_Walk(WN_func_body(wn), fp, spaces + increment, increment); 01499 break; 01500 case OPC_IF: 01501 if (Fancy_Level() < 3) { 01502 Loops_Walk(WN_then(wn), fp, spaces, increment); 01503 Loops_Walk(WN_else(wn), fp, spaces, increment); 01504 } else { 01505 Dump_Spaces(fp, spaces); 01506 fprintf(fp, "[%d] 0x%p IF ([%d] 0x%p) THEN [%d] 0x%p\n", 01507 Carray().Next_Index(), wn, Carray().Next_Index() + 1, WN_if_test(wn), 01508 Carray().Next_Index() + 2, WN_then(wn)); 01509 INT if_loop_count = Carray().Next_Index(); 01510 Carray().Enter_This_Node(wn); 01511 Carray().Enter_This_Node(WN_if_test(wn)); 01512 Carray().Enter_This_Node(WN_then(wn)); 01513 Loops_Walk(WN_then(wn), fp, spaces + increment, increment); 01514 if (!WN_else_is_empty(wn)) { 01515 Dump_Spaces(fp, spaces); 01516 fprintf(fp, "[%d] 0x%p ELSE\n", Carray().Next_Index(), WN_else(wn)); 01517 Carray().Enter_This_Node(WN_else(wn)); 01518 Loops_Walk(WN_else(wn), fp, spaces + increment, increment); 01519 } 01520 Dump_Spaces(fp, spaces); 01521 fprintf(fp, "[%d] 0x%p ENDIF\n", if_loop_count, wn); 01522 } 01523 break; 01524 case OPC_DO_WHILE: 01525 Dump_Spaces(fp, spaces); 01526 fprintf(fp, "[%d] 0x%p DO_WHILE_LOOP \n", Carray().Next_Index(), wn); 01527 Carray().Enter_This_Node(wn); 01528 Loops_Walk(WN_while_body(wn), fp, spaces + increment, increment); 01529 break; 01530 case OPC_WHILE_DO: 01531 Dump_Spaces(fp, spaces); 01532 fprintf(fp, "[%d] 0x%p WHILE_DO_LOOP \n", Carray().Next_Index(), wn); 01533 Carray().Enter_This_Node(wn); 01534 Loops_Walk(WN_while_body(wn), fp, spaces + increment, increment); 01535 break; 01536 case OPC_REGION: 01537 if (Fancy_Level() >= 3) { 01538 Dump_Spaces(fp, spaces); 01539 if (Prompf_Id_Map() != -1) { 01540 fprintf(fp, "[%d] 0x%p REGION <%d>\n", Carray().Next_Index(), wn, 01541 WN_MAP32_Get(Prompf_Id_Map(), wn)); 01542 } else { 01543 fprintf(fp, "[%d] 0x%p REGION \n", Carray().Next_Index(), wn); 01544 } 01545 Carray().Enter_This_Node(wn); 01546 for (INT i = 0; i < WN_kid_count(wn); i++) 01547 Loops_Walk(WN_kid(wn, i), fp, spaces + increment, increment); 01548 } else { 01549 for (INT i = 0; i < WN_kid_count(wn); i++) 01550 Loops_Walk(WN_kid(wn, i), fp, spaces, increment); 01551 } 01552 } 01553 } 01554 01555 void WB_BROWSER::Loops() 01556 { 01557 Carray().Reset_Index(); 01558 Loops_Walk(Cnode(), stdout, 0, 2); 01559 } 01560 01561 //----------------------------------------------------------------------- 01562 // NAME: WB_BROWSER::Set_Map_Id 01563 // WHIRL BROWSER COMMAND: 'M' 01564 // FUNCTION: Set the current node to node with this map id 01565 //----------------------------------------------------------------------- 01566 01567 void WB_BROWSER::Set_Map_Id() 01568 { 01569 INT map_id = 0; 01570 Buffer().Scan_Integer(&map_id); 01571 WN_ITER* itr = WN_WALK_TreeIter(Global_Fd()); 01572 for (; itr != NULL; itr = WN_WALK_TreeNext(itr)) 01573 if (WN_map_id(itr->wn) == map_id) 01574 break; 01575 if (itr == NULL) { 01576 Error_Cleanup(); 01577 return; 01578 } 01579 Set_Cnode(itr->wn); 01580 Print_This_Node(Cnode()); 01581 } 01582 01583 //----------------------------------------------------------------------- 01584 // NAME: WB_BROWSER::Map_Id 01585 // WHIRL BROWSER COMMAND: 'm' 01586 // FUNCTION: Print the map-id at this node 01587 //----------------------------------------------------------------------- 01588 01589 void WB_BROWSER::Map_Id() 01590 { 01591 fprintf(stdout, "%d\n", WN_map_id(Cnode())); 01592 } 01593 01594 //----------------------------------------------------------------------- 01595 // NAME: WB_BROWSER::DaVinci_Toggle 01596 // WHIRL BROWSER COMMAND: 'd' 01597 // FUNCTION: Toggle Da Vinci mode 01598 //----------------------------------------------------------------------- 01599 01600 void WB_BROWSER::DaVinci_Toggle() 01601 { 01602 if (DaVinci_Mode()) { 01603 _davinci_mode = FALSE; 01604 fprintf(stdout, "DAVINCI is OFF.\n"); 01605 } else { 01606 _davinci_mode = TRUE; 01607 fprintf(stdout, "DAVINCI is ON.\n"); 01608 } 01609 } 01610 01611 //----------------------------------------------------------------------- 01612 // NAME: WB_BROWSER::Find_Symbols 01613 // WHIRL BROWSER COMMAND: '$' 01614 // FUNCTION: Print the symbol table entry with this name 01615 //----------------------------------------------------------------------- 01616 01617 void WB_BROWSER::Find_Symbols() 01618 { 01619 ST* st = NULL; 01620 char s[WB_MAX_STRING_LENGTH]; 01621 Buffer().Scan_Alphanumeric(s); 01622 Carray().Reset_Index(); 01623 BOOL test_substring = s[0] == '\''; 01624 INT i; 01625 FOREACH_SYMBOL(CURRENT_SYMTAB, st, i) { 01626 if ((!test_substring && strcmp(ST_name(st), s) == 0 01627 || test_substring && Is_Substring(&s[1], ST_name(st)))) { 01628 Print_ST(stdout, st, TRUE); 01629 } 01630 } 01631 FOREACH_SYMBOL(GLOBAL_SYMTAB, st, i) { 01632 if ((!test_substring && strcmp(ST_name(st), s) == 0 01633 || test_substring && Is_Substring(&s[1], ST_name(st)))) { 01634 Print_ST(stdout, st, TRUE); 01635 } 01636 } 01637 } 01638 01639 //----------------------------------------------------------------------- 01640 // NAME: WB_BROWSER::Required_Fields_Present 01641 // FUNCTION: Return TRUE if the 'num'th command has all of the fields 01642 // in the WB_BROWSER needed to print the associated information. 01643 //----------------------------------------------------------------------- 01644 01645 BOOL WB_BROWSER::Required_Fields_Present(INT num) 01646 { 01647 if (Required_Fields(num) == WBR_NONE) 01648 return TRUE; 01649 if ((Required_Fields(num) & WBR_DU) && Du() == NULL) 01650 return FALSE; 01651 if ((Required_Fields(num) & WBR_DG) && Dg() == NULL) 01652 return FALSE; 01653 if ((Required_Fields(num) & WBR_ALIAS) && Alias_Mgr() == NULL) 01654 return FALSE; 01655 if ((Required_Fields(num) & WBR_PARENT) && Parent_Map() == WN_MAP_UNDEFINED) 01656 return FALSE; 01657 if ((Required_Fields(num) & WBR_MPFMAP) && Prompf_Id_Map() == WN_MAP_UNDEFINED) 01658 return FALSE; 01659 if ((Required_Fields(num) & WBR_MPFINFO) && Prompf_Info() == NULL) 01660 return FALSE; 01661 if ((Required_Fields(num) & WBR_AAMAP) && Access_Array_Map() == WN_MAP_UNDEFINED) 01662 return FALSE; 01663 if ((Required_Fields(num) & WBR_REDMAP) && Reduction_Map() == WN_MAP_UNDEFINED) 01664 return FALSE; 01665 return TRUE; 01666 } 01667 01668 //----------------------------------------------------------------------- 01669 // NAME: WB_BROWSER::Help 01670 // WHIRL BROWSER COMMAND: 'H' 01671 // FUNCTION: Print this information 01672 //----------------------------------------------------------------------- 01673 01674 void WB_BROWSER::Help() 01675 { 01676 for (INT i = 0; Command(i) != '\0'; i++) { 01677 if (Required_Fields_Present(i)) { 01678 for (INT j = 0; j < WB_ASCII_CHAR_COUNT; j++) 01679 if (_keymap[j] == Command(i)) 01680 fprintf(stdout, " %c: %s\n", j, Command_Text(i)); 01681 } 01682 } 01683 fprintf(stdout, " Q: Exit the debugger\n"); 01684 fprintf(stdout, " q: Exit the debugger\n"); 01685 } 01686 01687 //----------------------------------------------------------------------- 01688 // NAME: WB_BROWSER::Invoke_Command 01689 // FUNCTION: Invoke the command indicated by character 'ch'. 01690 //----------------------------------------------------------------------- 01691 01692 void WB_BROWSER::Invoke_Command(char ch) 01693 { 01694 switch (_keymap[ch]) { 01695 case 'R': 01696 Root(); 01697 break; 01698 case 'N': 01699 Next(); 01700 break; 01701 case 'P': 01702 Previous(); 01703 break; 01704 case '=': 01705 Set_Node(); 01706 break; 01707 case '@': 01708 Address(); 01709 break; 01710 case '>': 01711 Fancy_Up(); 01712 break; 01713 case '<': 01714 Fancy_Down(); 01715 break; 01716 case 'K': 01717 Kids(); 01718 break; 01719 case 'S': 01720 Statements(); 01721 break; 01722 case 'T': 01723 This_Tree(); 01724 break; 01725 case '%': 01726 Addresses(); 01727 break; 01728 case 's': 01729 Symbol(); 01730 break; 01731 case 't': 01732 Type(); 01733 break; 01734 case 'F': 01735 Find(); 01736 break; 01737 case '$': 01738 Find_Symbols(); 01739 break; 01740 case 'o': 01741 Find_Operator(); 01742 break; 01743 case 'H': 01744 case 'h': 01745 Help(); 01746 break; 01747 case 'U': 01748 Uses(); 01749 break; 01750 case 'D': 01751 Defs(); 01752 break; 01753 case 'G': 01754 Deps(); 01755 break; 01756 case 'V': 01757 Vertices(); 01758 break; 01759 case 'v': 01760 Vertex_Set_Node(); 01761 break; 01762 case 'A': 01763 Access_Array(); 01764 break; 01765 case 'a': 01766 Alias(); 01767 break; 01768 case 'r': 01769 Reduction(); 01770 break; 01771 case 'E': 01772 Parent(); 01773 break; 01774 case 'e': 01775 Ancestors(); 01776 break; 01777 case 'i': 01778 Promp_Map(); 01779 break; 01780 case 'I': 01781 Promp_Info(); 01782 break; 01783 case 'W': 01784 Whirl2fc(); 01785 break; 01786 case 'f': 01787 Whirl2fset(); 01788 break; 01789 case 'c': 01790 Whirl2cset(); 01791 break; 01792 case 'L': 01793 Loops(); 01794 break; 01795 case 'M': 01796 Set_Map_Id(); 01797 break; 01798 case 'm': 01799 Map_Id(); 01800 break; 01801 case 'd': 01802 DaVinci_Toggle(); 01803 break; 01804 case '~': 01805 Summary(stdout); 01806 break; 01807 default: 01808 fprintf(stdout, "Bad character: %c\n", ch); 01809 break; 01810 } 01811 } 01812 01813 //----------------------------------------------------------------------- 01814 // NAME: WB_BROWSER::Initialize_Language 01815 // FUNCTION: Set the value of 'WB_language' and print out that language. 01816 //----------------------------------------------------------------------- 01817 01818 void WB_BROWSER::Initialize_Language() 01819 { 01820 if (Pu() != NULL) { 01821 switch (PU_src_lang(*Pu())) { 01822 case PU_C_LANG: 01823 case PU_CXX_LANG: 01824 Set_Source_Language(WB_SRC_C); 01825 fprintf(stdout, "WHIRL-TO-SOURCE language is C.\n"); 01826 break; 01827 case PU_F90_LANG: 01828 case PU_F77_LANG: 01829 Set_Source_Language(WB_SRC_FORTRAN); 01830 fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n"); 01831 break; 01832 default: 01833 Set_Source_Language(WB_SRC_NONE); 01834 fprintf(stdout, 01835 "Can't do WHIRL-TO-SOURCE tranformations in this language.\n"); 01836 break; 01837 } 01838 } else { 01839 Set_Source_Language(WB_SRC_FORTRAN); 01840 fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n"); 01841 } 01842 } 01843 01844 //----------------------------------------------------------------------- 01845 // NAME: Scan_Blanks_And_Tabs 01846 // FUNCTION: In the 'buffer' advance 'buffer_start' past all blanks and 01847 // tabs. 01848 //----------------------------------------------------------------------- 01849 01850 static void Scan_Blanks_And_Tabs(char buffer[], 01851 INT* buffer_start) 01852 { 01853 char ch; 01854 do { 01855 ch = buffer[(*buffer_start)++]; 01856 } while (ch == ' ' || ch == '\t'); 01857 (*buffer_start)--; 01858 } 01859 01860 //----------------------------------------------------------------------- 01861 // NAME: WB_BROWSER::Initialize_Keymap 01862 // FUNCTION: Initialize the keymap my writing over the default key settings 01863 // with other, user specified key settings. 01864 //----------------------------------------------------------------------- 01865 01866 void WB_BROWSER::Initialize_Keymap(char ch) 01867 { 01868 const INT BUFFER_MAX = 132; 01869 char file_name[BUFFER_MAX]; 01870 strcpy(file_name, getenv("HOME")); 01871 strcat(file_name, "/.wb_keymap"); 01872 FILE* fp_keymap = fopen(file_name, "r"); 01873 if (fp_keymap == NULL) 01874 return; 01875 BOOL print_log = TRUE; 01876 char key_buffer[BUFFER_MAX]; 01877 INT line_number = 0; 01878 while (fgets(key_buffer, BUFFER_MAX-1, fp_keymap) != NULL) { 01879 line_number++; 01880 INT key_buffer_start = 0; 01881 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start); 01882 if (strncasecmp(&key_buffer[key_buffer_start], "SILENT", 01883 strlen("SILENT")) == 0) { 01884 print_log = FALSE; 01885 } else if (strncasecmp(&key_buffer[key_buffer_start], "VERBOSE", 01886 strlen("VERBOSE")) == 0) { 01887 print_log = TRUE; 01888 } else if (strncasecmp(&key_buffer[key_buffer_start], "TRANSLATE", 01889 strlen("TRANSLATE")) == 0) { 01890 key_buffer_start += strlen("TRANSLATE"); 01891 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start); 01892 char old_char = key_buffer[key_buffer_start++]; 01893 if (Unmappable_Character(old_char)) { 01894 fprintf(stdout, 01895 ".wb_keymap: Error on line %d: Cannot map %c\n", 01896 line_number, old_char); 01897 continue; 01898 } 01899 if (ch == ' ') { 01900 if (key_buffer[key_buffer_start] != ' ' 01901 && key_buffer[key_buffer_start] != '\t') 01902 continue; 01903 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start); 01904 char new_char = key_buffer[key_buffer_start++]; 01905 if (Unmappable_Character(new_char)) { 01906 fprintf(stdout, 01907 ".wb_keymap: Error on line %d: Cannot map %c\n", 01908 line_number, new_char); 01909 continue; 01910 } 01911 if (print_log) 01912 fprintf(stdout, ".wb_keymap: Translating '%c' to '%c'\n", 01913 old_char, new_char); 01914 _keymap[new_char] = old_char; 01915 } else { 01916 if (old_char == ch) { 01917 old_char = key_buffer[key_buffer_start++]; 01918 if (Unmappable_Character(old_char)) { 01919 fprintf(stdout, 01920 ".wb_keymap: Error on line %d: Cannot map %c\n", 01921 line_number, old_char); 01922 continue; 01923 } 01924 Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start); 01925 char new_char = key_buffer[key_buffer_start++]; 01926 if (Unmappable_Character(new_char)) { 01927 fprintf(stdout, 01928 ".wb_keymap: Error on line %d: Cannot map %c\n", 01929 line_number, new_char); 01930 continue; 01931 } 01932 if (print_log) 01933 fprintf(stdout, ".wb_keymap: Translating '%c' to '%c'\n", 01934 old_char, new_char); 01935 _keymap[new_char] = old_char; 01936 } 01937 } 01938 } else { 01939 fprintf(stdout, ".wb_keymap: Error on line %d: Unrecognized command\n", 01940 line_number); 01941 } 01942 } 01943 fclose(fp_keymap); 01944 } 01945 01946 //----------------------------------------------------------------------- 01947 // NAME: WB_BROWSER::Sdebug 01948 // FUNCTION: The 'string debugger'. Run the whirl browser using 'init_buffer' 01949 // as the initial set of commands. 01950 // NOTE: 'sdebug' can be called from the compiler as an aid to debugging in 01951 // batch mode. For example, to print out the loop nests at a certain 01952 // place during compiler execution, put a call of the form: 01953 // sdebug("RLQ"); 01954 // in the compiler where you want to see the loops. 01955 //----------------------------------------------------------------------- 01956 01957 void WB_BROWSER::Sdebug(char init_buffer[]) 01958 { 01959 char ch; 01960 BOOL reload; 01961 01962 if (Global_Fd() == NULL) { 01963 fprintf(stdout, "Whirl browser not valid in this phase.\n"); 01964 Error_Cleanup(); 01965 return; 01966 } 01967 Initialize_Keymap(' '); 01968 Initialize_Language(); 01969 Root(); 01970 fprintf(stdout, "Root node is: "); 01971 Print_This_Node(Cnode()); 01972 WB_Prompt(); 01973 Buffer().Reset_Buffer(); 01974 if (init_buffer[0] == '\0') { 01975 reload = TRUE; 01976 } else { 01977 reload = FALSE; 01978 Buffer().Load_Buffer(init_buffer); 01979 for (INT i = 0; init_buffer[i] != '\0'; i++) 01980 fprintf(stdout, "%c", init_buffer[i]); 01981 fprintf(stdout, "\n"); 01982 } 01983 while (TRUE) { 01984 if (reload) { 01985 Buffer().Load_Buffer(); 01986 reload = FALSE; 01987 } 01988 ch = Buffer().Get_Command(); 01989 if (ch == '\n') { 01990 WB_Prompt(); 01991 reload = TRUE; 01992 continue; 01993 } 01994 if (ch == 'Q' || ch == 'q') 01995 return; 01996 Invoke_Command(ch); 01997 } 01998 } 01999 02000 //----------------------------------------------------------------------- 02001 // NAME: WB_BROWSER::Set_Subcommand 02002 // FUNCTION: Set the command list to the list corresponding to the 02003 // command whose character is 'ch'. 02004 //----------------------------------------------------------------------- 02005 02006 void WB_BROWSER::Set_Subcommand(char ch) 02007 { 02008 INT i; 02009 for (i = 0; Command(i) != '\0'; i++) 02010 if (Command(i) == ch) 02011 break; 02012 if (Command(i) == '\0') 02013 return; 02014 if (Subcommand(i) == NULL) 02015 return; 02016 _is_subcommand = TRUE; 02017 Set_Old_Command_List(Command_List()); 02018 Set_Command_List(Subcommand(i)); 02019 for (i = 0; i < WB_ASCII_CHAR_COUNT; i++) 02020 _old_keymap[i] = _keymap[i]; 02021 for (i = 0; i < WB_ASCII_CHAR_COUNT; i++) 02022 _keymap[i] = i; 02023 Initialize_Keymap(ch); 02024 } 02025 02026 //----------------------------------------------------------------------- 02027 // NAME: WB_BROWSER::Reset_Subcommand 02028 // FUNCTION: Reset the command list to its original value. 02029 //----------------------------------------------------------------------- 02030 02031 void WB_BROWSER::Reset_Subcommand() 02032 { 02033 _is_subcommand = FALSE; 02034 Set_Command_List(Old_Command_List()); 02035 Set_Old_Command_List(NULL); 02036 for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++) 02037 _keymap[i] = _old_keymap[i]; 02038 } 02039 02040 //----------------------------------------------------------------------- 02041 // NAME: WB_BROWSER::Debug 02042 // FUNCTION: The main entry point to the whirl browser. To start up the 02043 // whirl browser in dbx, say 'p debug()'. 02044 //----------------------------------------------------------------------- 02045 02046 void WB_BROWSER::Debug() 02047 { 02048 Sdebug(""); 02049 } 02050