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 #include <errno.h>
00041 #include <stdio.h>
00042 #ifdef __MINGW32__
00043 #include <WINDOWS.h>
00044 #else
00045 #include <libgen.h>
00046 #endif
00047 #include <sys/stat.h>
00048 #if ! defined(BUILD_OS_DARWIN)
00049 #include <elf.h>
00050 #endif
00051 #include "defs.h"
00052 #include "mempool.h"
00053 #include "wn.h"
00054 #include "wn_simp.h"
00055 #include "stab.h"
00056 #include "const.h"
00057 #include "pu_info.h"
00058 #include "irbdata.h"
00059 #include "ir_reader.h"
00060 #include "ir_bwrite.h"
00061 #include "ir_bread.h"
00062 #include "dwarf_DST_dump.h"
00063 #include "erglob.h"
00064 #include "errors.h"
00065 #include "err_host.tab"
00066 #include "config.h"
00067 #include "config_opt.h"
00068 #include "tracing.h"
00069 #include "profile_com.h"
00070 #include "fb_info.h"
00071
00072 static BOOL simplify_tree = FALSE;
00073
00074 extern BOOL
00075 file_exists (char *path)
00076 {
00077 INT st;
00078 struct stat sbuf;
00079 st = stat(path, &sbuf);
00080 if (st == -1 && (errno == ENOENT || errno == ENOTDIR))
00081 return FALSE;
00082 else
00083 return TRUE;
00084 }
00085
00086
00087 template <class T>
00088 void
00089 FB_Print (const T* info, INT size, const char* name)
00090 {
00091 if (size != 0)
00092 printf ("%s Profile:\n", name);
00093 for (INT i = 0; i < size; ++i) {
00094 printf("\t%s id = %d\t", name, i);
00095 info[i].Print (stdout);
00096 fputc ('\n', stdout);
00097 }
00098 }
00099
00100 static void
00101 Print_Feedback_Info (const Pu_Hdr* pu_hdr)
00102 {
00103 const char* base = (const char*) pu_hdr;
00104
00105 const FB_Info_Invoke* fb_invoke =
00106 (const FB_Info_Invoke*) (base + pu_hdr->pu_inv_offset);
00107 FB_Print (fb_invoke, pu_hdr->pu_num_inv_entries, "Invoke");
00108
00109 const FB_Info_Branch* fb_branch =
00110 (const FB_Info_Branch*) (base + pu_hdr->pu_br_offset);
00111 FB_Print (fb_branch, pu_hdr->pu_num_br_entries, "Branch");
00112
00113 const FB_FREQ* fb_switch =
00114 (const FB_FREQ*) (base + pu_hdr->pu_switch_offset);
00115 const INT32* fb_switch_target =
00116 (const INT32*) (base + pu_hdr->pu_switch_target_offset);
00117 if (pu_hdr->pu_num_switch_entries != 0)
00118 printf ("Switch Profile:\n");
00119 for (INT32 i = 0; i < pu_hdr->pu_num_switch_entries; ++i) {
00120 FB_Info_Switch info;
00121 info.freq_targets.insert (info.freq_targets.begin (),
00122 fb_switch, fb_switch + *fb_switch_target);
00123 info.Print (stdout);
00124 fb_switch += *fb_switch_target;
00125 ++fb_switch_target;
00126 }
00127
00128 const FB_Info_Loop* fb_loop =
00129 (const FB_Info_Loop*) (base + pu_hdr->pu_loop_offset);
00130 FB_Print (fb_loop, pu_hdr->pu_num_loop_entries, "Loop");
00131
00132 const FB_Info_Circuit* fb_circuit =
00133 (const FB_Info_Circuit*) (base + pu_hdr->pu_scircuit_offset);
00134 FB_Print (fb_circuit, pu_hdr->pu_num_scircuit_entries, "Short Circuit");
00135
00136 const FB_Info_Call* fb_call =
00137 (const FB_Info_Call*) (base + pu_hdr->pu_call_offset);
00138 FB_Print (fb_call, pu_hdr->pu_num_call_entries, "Call");
00139 }
00140
00141
00142
00143 static void
00144 ir_b2a_process_PUs (PU_Info *pu_tree, BOOL stflag, BOOL fbflag)
00145 {
00146 PU_Info *pu;
00147 WN *wn;
00148
00149 for (pu = pu_tree; pu != NULL; pu = PU_Info_next (pu)) {
00150 if (!stflag) {
00151 MEM_POOL_Push(MEM_pu_nz_pool_ptr);
00152 MEM_POOL_Push(MEM_pu_pool_ptr);
00153 }
00154 Read_Local_Info (MEM_pu_nz_pool_ptr, pu);
00155
00156 wn = PU_Info_tree_ptr(pu);
00157 if (simplify_tree) wn = WN_Simplify_Tree(wn);
00158
00159 IR_put_func (wn, NULL);
00160
00161 if (PU_Info_child(pu)) {
00162 ir_b2a_process_PUs(PU_Info_child(pu), stflag, fbflag);
00163 }
00164
00165 if (stflag) {
00166 SYMTAB_IDX level =
00167 PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]);
00168 Print_local_symtab (stdout, Scope_tab[level]);
00169 }
00170
00171 if (fbflag) {
00172 if (PU_Info_feedback_ptr (pu)) {
00173 const Pu_Hdr* pu_hdr = (const Pu_Hdr*)
00174 PU_Info_feedback_ptr (pu);
00175 printf ("\n********* Feedback Info *********\n");
00176 Print_Feedback_Info (pu_hdr);
00177 printf ("=======================================================================\n");
00178 }
00179 }
00180
00181 if (!stflag) {
00182 Free_Local_Info (pu);
00183 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
00184 MEM_POOL_Pop(MEM_pu_pool_ptr);
00185 }
00186 }
00187 }
00188
00189
00190 static void
00191 ir_b2a (char *global_file, char *input_file, char *output_file, BOOL stflag,
00192 BOOL fbflag)
00193 {
00194 PU_Info *pu_tree;
00195
00196 if (global_file == NULL) {
00197 (void)Open_Input_Info (input_file);
00198 } else {
00199 (void)Open_Global_Input (global_file);
00200 (void)Open_Local_Input (input_file);
00201 }
00202
00203 Initialize_Symbol_Tables (FALSE);
00204 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, FALSE);
00205 pu_tree = Read_Global_Info (NULL);
00206
00207 if (output_file != NULL) {
00208 if (freopen (output_file, "w+", stdout) == NULL) {
00209 fprintf (stderr, "Can't open output file %s\n", output_file);
00210 exit (1);
00211 }
00212 }
00213
00214 IR_reader_init();
00215 IR_Dwarf_Gen_File_Table(TRUE);
00216
00217 ir_b2a_process_PUs(pu_tree, stflag, fbflag);
00218
00219 if (stflag) {
00220
00221 Print_global_symtab (stdout);
00222 Dump_DST (stdout);
00223 }
00224
00225 Free_Input_Info ();
00226
00227 }
00228
00229
00230
00231 static void
00232 ir_sel (char *input_file, char *output_file, char *func_name)
00233 {
00234 WN *wn;
00235 PU_Info *pu_tree, *pu = NULL;
00236 BOOL found = FALSE;
00237
00238 (void)Open_Input_Info (input_file);
00239 #ifdef KEY
00240 Initialize_Symbol_Tables (FALSE);
00241 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, FALSE);
00242 #endif
00243 pu_tree = Read_Global_Info (NULL);
00244
00245 Open_Output_Info (output_file);
00246
00247
00248
00249
00250 for (pu = pu_tree; pu != NULL; pu = PU_Info_next (pu)) {
00251 MEM_POOL_Push(MEM_pu_nz_pool_ptr);
00252 MEM_POOL_Push(MEM_pu_pool_ptr);
00253 Read_Local_Info (MEM_pu_nz_pool_ptr, pu);
00254
00255 wn = PU_Info_tree_ptr(pu);
00256 if ((WN_opcode(wn) == OPC_FUNC_ENTRY) &&
00257 (strcmp(func_name, ST_name(WN_st(wn))) == 0)) {
00258
00259 Write_PU_Info (pu);
00260 found = TRUE;
00261
00262 Free_Local_Info (pu);
00263 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
00264 MEM_POOL_Pop(MEM_pu_pool_ptr);
00265
00266
00267 PU_Info_next(pu) = NULL;
00268 PU_Info_child(pu) = NULL;
00269 pu_tree = pu;
00270
00271 break;
00272 }
00273
00274 Free_Local_Info (pu);
00275 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
00276 MEM_POOL_Pop(MEM_pu_pool_ptr);
00277 }
00278
00279 if (!found) {
00280 fprintf (stderr, "Can't find function %s\n", func_name);
00281 exit (1);
00282 }
00283
00284 Write_Global_Info(pu_tree);
00285 Close_Output_Info ();
00286 Free_Input_Info ();
00287
00288 }
00289
00290 static void
00291 ir_all (char *input_file, char *output_file)
00292 {
00293 WN *wn;
00294 PU_Info *pu_tree, *pu = NULL;
00295
00296 (void)Open_Input_Info (input_file);
00297 #ifdef KEY
00298 Initialize_Symbol_Tables (FALSE);
00299 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, FALSE);
00300 #endif
00301 pu_tree = Read_Global_Info (NULL);
00302
00303 Open_Output_Info (output_file);
00304
00305
00306
00307
00308 for (pu = pu_tree; pu != NULL; pu = PU_Info_next (pu)) {
00309 MEM_POOL_Push(MEM_pu_nz_pool_ptr);
00310 MEM_POOL_Push(MEM_pu_pool_ptr);
00311 Read_Local_Info (MEM_pu_nz_pool_ptr, pu);
00312
00313 wn = PU_Info_tree_ptr(pu);
00314 Write_PU_Info (pu);
00315
00316 Free_Local_Info (pu);
00317 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
00318 MEM_POOL_Pop(MEM_pu_pool_ptr);
00319 }
00320
00321 Write_Global_Info(pu_tree);
00322 Close_Output_Info ();
00323 Free_Input_Info ();
00324
00325 }
00326
00327 static void
00328 usage (char *progname)
00329 {
00330 INT a2b, b2a, sel, all;
00331
00332
00333 a2b = (strncmp (progname, "ir_a2b",6) == 0);
00334 b2a = (strncmp (progname, "ir_b2a",6) == 0);
00335 sel = (strncmp (progname, "ir_sel",6) == 0);
00336 all = (strncmp (progname, "ir_all",6) == 0);
00337
00338 if (a2b) {
00339 fprintf (stderr, "New symbol table format not supported by ir_a2b (yet)\n");
00340 } else if (b2a) {
00341 fprintf (stderr, "Usage: %s [-st] [-v] <Binary IR> [<ASCII IR>]\n",
00342 progname);
00343 fprintf (stderr, "\t(will write to stdout if ascii file not given)\n");
00344 fprintf (stderr, "\t-st option will also print out the symbol table\n");
00345 fprintf (stderr, "\t-opcodes option will print out opcodes as seen\n");
00346 fprintf (stderr, "\t-lines option will print out line numbers\n");
00347 fprintf (stderr, "\t-global_local <.G file> option will use separate global table\n");
00348 fprintf (stderr, "\t-sym <.G file> is the same as -global_local\n");
00349 } else if (sel) {
00350 fprintf (stderr, "Usage: %s <function> <Binary IR input> [<Binary IR output>]\n", progname);
00351
00352 } else if (all) {
00353 fprintf (stderr, "Usage: %s <Binary IR input> [<Binary IR output>]\n", progname);
00354 }
00355
00356 exit (1);
00357 }
00358
00359 main (INT argc, char *argv[])
00360 {
00361 register char *progname;
00362 register INT a2b, b2a, sel, all;
00363 char *infile;
00364 char *outfile;
00365 INT binarg = 1;
00366 BOOL stflag = FALSE;
00367 BOOL fbflag = FALSE;
00368
00369
00370 MEM_Initialize();
00371 Set_Error_Tables (Phases, host_errlist);
00372 Init_Error_Handler (10);
00373 Set_Error_File(NULL);
00374 Set_Error_Line(ERROR_LINE_UNKNOWN);
00375 WHIRL_Mldid_Mstid_On = TRUE;
00376 #ifdef __MINGW32__
00377 progname = argv[0] + strlen (argv[0]);
00378 while (progname >= argv[0]) {
00379 if (*progname == '/' || *progname == '\\') {
00380 progname++;
00381 break;
00382 }
00383 progname--;
00384 }
00385 #else
00386 progname = basename (argv[0]);
00387 #endif
00388
00389
00390 if (*progname == '/') ++progname;
00391
00392 a2b = (strncmp (progname, "ir_a2b",6) == 0);
00393 b2a = (strncmp (progname, "ir_b2a",6) == 0);
00394 sel = (strncmp (progname, "ir_sel",6) == 0);
00395 all = (strncmp (progname, "ir_all",6) == 0);
00396
00397 if (a2b) {
00398 usage (progname);
00399 }
00400 else if (b2a) {
00401 Read_Global_Data = NULL;
00402 if (argc < 2)
00403 usage(progname);
00404
00405 while (*argv[binarg] == '-') {
00406 if (strncmp(argv[binarg], "-st", 3) == 0) {
00407 stflag = TRUE;
00408 } else if (strcmp(argv[binarg], "-fb") == 0) {
00409 fbflag = TRUE;
00410 } else if (strcmp(argv[binarg], "-v") == 0) {
00411 IR_dump_map_info = TRUE;
00412 } else if (strcmp(argv[binarg], "-opcodes") == 0) {
00413
00414
00415
00416 Set_Verbose_Info(TRUE);
00417 IR_dump_map_info = TRUE;
00418 } else if (strcmp(argv[binarg], "-ws") == 0) {
00419 simplify_tree = TRUE;
00420 (void) WN_Simplifier_Enable(TRUE);
00421 } else if (strcmp(argv[binarg], "-wsa") == 0) {
00422 simplify_tree = TRUE;
00423 (void) WN_Simplifier_Enable(TRUE);
00424
00425 Roundoff_Level=ROUNDOFF_ANY;
00426 Enable_Cfold_Reassociate=TRUE;
00427 Rsqrt_Allowed=TRUE;
00428 Recip_Allowed=TRUE;
00429 Div_Split_Allowed=TRUE;
00430 Enable_Cfold_Aggressive=TRUE;
00431 IEEE_Arithmetic = IEEE_ANY;
00432 Simp_Multiply_To_Shift = TRUE;
00433 } else if (strcmp(argv[binarg], "-wst") == 0) {
00434 Set_Trace(TP_WHIRLSIMP,1);
00435 Set_Trace(TP_WHIRLSIMP,2);
00436 } else if (strcmp(argv[binarg], "-pre") == 0) {
00437 (void) IR_set_dump_order(TRUE);
00438 } else if (strcmp(argv[binarg], "-lines") == 0) {
00439 IR_dump_line_numbers = TRUE;
00440 } else if (strcmp(argv[binarg], "-global_local") == 0 ||
00441 strcmp(argv[binarg], "-sym") == 0) {
00442 ++binarg;
00443 Read_Global_Data = argv[binarg];
00444 } else {
00445 usage(progname);
00446 }
00447 ++binarg;
00448 }
00449
00450 if (argc < binarg+1)
00451 usage(progname);
00452 if (!file_exists(argv[binarg]))
00453 usage(progname);
00454
00455 infile = argv[binarg];
00456 outfile = argv[binarg+1];
00457 ir_b2a (Read_Global_Data, infile, outfile, stflag, fbflag);
00458 }
00459 else if (sel) {
00460 if (argc < 3)
00461 usage(progname);
00462 if (!file_exists(argv[2]))
00463 usage(progname);
00464
00465 if (argc == 3) {
00466 outfile = (char *) malloc(strlen(argv[1])+3);
00467 strcpy(outfile, argv[1]);
00468 strcat(outfile, ".B");
00469 } else {
00470 outfile = argv[3];
00471 }
00472 ir_sel (argv[2], outfile, argv[1]);
00473 }
00474 else if (all) {
00475 if (argc < 2)
00476 usage(progname);
00477 if (!file_exists(argv[1]))
00478 usage(progname);
00479 outfile = argv[2];
00480 ir_all (argv[1], outfile);
00481 }
00482 else
00483 fprintf(stderr, "unrecognized command %s\n", progname);
00484
00485 exit (0);
00486 }
00487
00488
00489
00490
00491
00492 void
00493 Signal_Cleanup (INT sig) { }
00494
00495 const char *
00496 Host_Format_Parm (INT kind, MEM_PTR parm)
00497 {
00498 fprintf (stderr, "Internal: Host_Format_Parm () not implemented\n");
00499 return "";
00500 }
00501
00502 INT8 Debug_Level = 0;