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