00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifdef USE_PCH
00063 #include "common_com_pch.h"
00064 #endif
00065 #pragma hdrstop
00066 #include <stdio.h>
00067 #include <string.h>
00068 #include <sys/types.h>
00069 #include <sys/mman.h>
00070 #include <sys/stat.h>
00071 #include <fcntl.h>
00072 #include <stdarg.h>
00073 #include <ctype.h>
00074 #include <unistd.h>
00075 #include <cmplrs/rcodes.h>
00076
00077
00078 #ifndef USE_STANDARD_TYPES
00079 #define USE_STANDARD_TYPES // to allow wn_tree_op.h to include ... vector.h
00080 #endif // which uses standard types.
00081
00082 #include "wn_tree_util.h"
00083 #include "defs.h"
00084 #include "errors.h"
00085 #include "srcpos.h"
00086 #include "opcode.h"
00087 #include "stab.h"
00088 #include "const.h"
00089 #include "targ_const.h"
00090 extern char * Targ_Print ( const char *fmt, TCON c );
00091 #include "targ_sim.h"
00092 #include "strtab.h"
00093 #include "irbdata.h"
00094 #include "wn.h"
00095 #include "wn_simp.h"
00096 #include "dwarf_DST.h"
00097 #include "dwarf_DST_mem.h"
00098 #include "ir_reader.h"
00099 #include "tracing.h"
00100
00101 #ifdef BACK_END
00102 #include "opt_alias_mgr.h"
00103 #endif
00104
00105 #include "wio.h"
00106 #include "wintrinsic.h"
00107 #include "wn_pragmas.h"
00108 #include "wutil.h"
00109 #ifdef BACK_END
00110 #include "region_util.h"
00111 #include "dvector.h"
00112 #endif
00113
00114
00115
00116 enum OPR_EXTENDED {
00117 OPR_END_BLOCK = OPERATOR_LAST+1,
00118 OPR_BODY = OPERATOR_LAST+2,
00119 OPR_NOOP = OPERATOR_LAST+3,
00120 OPR_THEN = OPERATOR_LAST+4,
00121 OPR_ELSE = OPERATOR_LAST+5,
00122 OPR_END_IF = OPERATOR_LAST+6,
00123 OPR_INIT = OPERATOR_LAST+7,
00124 OPR_COMP = OPERATOR_LAST+8,
00125 OPR_INCR = OPERATOR_LAST+9,
00126 OPR_END_COMPGOTO = OPERATOR_LAST+10,
00127 OPR_END_XGOTO = OPERATOR_LAST+11,
00128 OPR_LOC = OPERATOR_LAST+12,
00129 OPR_END_LINFO = OPERATOR_LAST+13,
00130 OPR_END_SWITCH = OPERATOR_LAST+14
00131 };
00132
00133 enum OPC_EXTENDED {
00134 OPC_END_BLOCK = OPCODE_LAST+1,
00135 OPC_BODY = OPCODE_LAST+2,
00136 OPC_NOOP = OPCODE_LAST+3,
00137 OPC_THEN = OPCODE_LAST+4,
00138 OPC_ELSE = OPCODE_LAST+5,
00139 OPC_END_IF = OPCODE_LAST+6,
00140 OPC_INIT = OPCODE_LAST+7,
00141 OPC_COMP = OPCODE_LAST+8,
00142 OPC_INCR = OPCODE_LAST+9,
00143 OPC_END_COMPGOTO = OPCODE_LAST+10,
00144 OPC_END_XGOTO = OPCODE_LAST+11,
00145 OPC_LOC = OPCODE_LAST+12,
00146 OPC_END_LINFO = OPCODE_LAST+13,
00147 OPC_END_SWITCH = OPCODE_LAST+14,
00148 MAX_OPCODE = OPCODE_LAST+15
00149 };
00150
00151 typedef struct {
00152 char *pr_name;
00153 INT n_kids;
00154 INT flags;
00155 } IR_OPCODE_TABLE;
00156
00157
00158 IR_OPCODE_TABLE ir_opcode_table[1];
00159
00160
00161 #define HASH_LEN 2413
00162 #define IR_MAX_ARGS 3
00163
00164 IR_OPCODE_TABLE *opcode_hash[HASH_LEN];
00165
00166 #define LINE_LEN 1024
00167
00168 typedef struct {
00169 OPCODE opcode;
00170 INT _operator;
00171 INT n_kids;
00172 INT flags;
00173 ST *st;
00174 TY_IDX ty;
00175 TY_IDX load_addr_ty;
00176 INT id;
00177 INT num_dim;
00178 INT num_entries;
00179 INT last_label;
00180 WN_OFFSET offset;
00181 INT16 offset1_of_2;
00182 INT16 offset2_of_2;
00183 WN_ESIZE esize;
00184 INT16 cvtl_bits;
00185 INT64 const_val;
00186 INT32 label_number;
00187 UINT32 flags_val;
00188 INT cgoto;
00189 INT intrinsic;
00190 char *intrinsic_name;
00191 char *args[IR_MAX_ARGS+1];
00192 } TOKEN;
00193
00194 static void ir_error(char *s);
00195 static INT ir_get_expr_list(void);
00196 static WN * ir_get_expr(void);
00197 static WN * ir_get_stmt(void);
00198 static void ir_skip_token(void);
00199 static char *ir_read_line(char *buf, INT size, FILE *ir_file);
00200 static void ir_match_token(OPERATOR opr);
00201 static void ir_expect_token(OPERATOR opc);
00202 static TOKEN *ir_next_token(void);
00203 static void ir_get_token(TOKEN *token);
00204 static BOOL ir_insert_hash(char *s, IR_OPCODE_TABLE *irt);
00205 static INT ir_lookup(char *s);
00206 static void ir_build_hashtable(void);
00207 static void ir_put_wn(WN * wn, INT indent);
00208 static void ir_put_expr(WN * wn, INT indent);
00209 static void ir_put_marker(char *str, INT indent);
00210 static void ir_put_stmt(WN * wn, INT indent);
00211 static void WN_TREE_put_stmt(WN *, INT);
00212
00213
00214
00215
00216 static BOOL dump_parent_before_children = FALSE;
00217
00218 BOOL IR_dump_map_info = FALSE;
00219 BOOL IR_dump_region = FALSE;
00220 BOOL IR_DUMPDEP_info = FALSE;
00221 BOOL IR_dump_line_numbers = FALSE;
00222 BOOL IR_dump_wn_addr = FALSE;
00223
00224 WN_MAP IR_alias_map = WN_MAP_UNDEFINED;
00225 const struct ALIAS_MANAGER *IR_alias_mgr = NULL;
00226 WN_MAP IR_freq_map = WN_MAP_UNDEFINED;
00227
00228 #define OPCODE_has_alias_info(opc) (OPCODE_is_load(opc) ||\
00229 OPCODE_is_store(opc) ||\
00230 OPCODE_operator(opc) == OPR_PARM)
00231
00232 #define IR_dump_alias_info(opc) (IR_alias_map != WN_MAP_UNDEFINED && OPCODE_has_alias_info(opc))
00233
00234 typedef struct DUMPDEP
00235 {
00236 WN *node;
00237 INT32 id;
00238 struct DUMPDEP *next;
00239 } DUMPDEP, *DUMPDEPp;
00240
00241 #define DUMPDEP_node(x) (x)->node
00242 #define DUMPDEP_id(x) (x)->id
00243 #define DUMPDEP_next(x) ((x)->next)
00244
00245
00246 DUMPDEPp IR_DUMPDEP_head= NULL;
00247 static INT32 AddToDUMPDEP(WN *node);
00248
00249
00250
00251
00252
00253
00254
00255 static INT32 AddToDUMPDEP(WN *node)
00256 {
00257 static DUMPDEPp last;
00258 static INT32 id= 0;
00259
00260 if (IR_DUMPDEP_head==NULL)
00261 {
00262 id= 1;
00263 last= NULL;
00264 }
00265
00266 {
00267 DUMPDEPp p;
00268
00269 p = TYPE_L_ALLOC(DUMPDEP);
00270
00271 DUMPDEP_node(p)= node;
00272 DUMPDEP_id(p)= id++;
00273 DUMPDEP_next(p)= NULL;
00274
00275 if (last)
00276 {
00277 DUMPDEP_next(last) = p;
00278 last= p;
00279 }
00280 else
00281 {
00282 IR_DUMPDEP_head= p;
00283 last= p;
00284 }
00285 return DUMPDEP_id(p);
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296 #ifndef MONGOOSE_BE
00297 static FILE *ir_file;
00298 #endif
00299 static FILE *ir_ofile;
00300 static INT ir_line;
00301 #ifdef IR_TOOLS
00302 static char *line;
00303 static char *errmsg;
00304 #endif
00305 static BOOL follow_st;
00306 static USRCPOS last_srcpos;
00307 static BOOL is_initialized = FALSE;
00308 static WN_MAP ir_put_map = WN_MAP_UNDEFINED;
00309
00310 extern void IR_reader_init(void)
00311 {
00312 is_initialized = TRUE;
00313 MEM_POOL_Push(&MEM_local_pool);
00314 #ifdef IR_TOOLS
00315 errmsg = (char *) MEM_POOL_Alloc(&MEM_local_pool, LINE_LEN);
00316 line = (char *) MEM_POOL_Alloc(&MEM_local_pool, LINE_LEN);
00317
00318 #endif
00319 ir_ofile = stdout;
00320 follow_st = TRUE;
00321 USRCPOS_clear(last_srcpos);
00322 }
00323
00324
00325
00326
00327 extern BOOL IR_set_dump_order(BOOL prefix)
00328 {
00329 BOOL old_order;
00330 old_order = dump_parent_before_children;
00331 dump_parent_before_children = prefix;
00332 return (old_order);
00333 }
00334
00335
00336 #ifndef MONGOOSE_BE
00337 extern void IR_reader_finish(void)
00338 {
00339 MEM_POOL_Pop(&MEM_local_pool);
00340 }
00341
00342
00343 extern FILE *IR_open(const char *filename)
00344 {
00345 char prefix_check[6];
00346 ir_file = fopen(filename, "r");
00347 ir_line = 0;
00348
00349
00350 (void) fread(prefix_check,6,1,ir_file);
00351 if (strncmp(prefix_check,"PREFIX",6)==0) {
00352 fclose(ir_file);
00353 fprintf(stderr,"File %s is prefix ordered and cannot be read.\n",filename);
00354 } else {
00355
00356 rewind(ir_file);
00357 }
00358 return ir_file;
00359 }
00360
00361 extern void IR_close(void)
00362 {
00363 fclose(ir_file);
00364 }
00365
00366
00367
00368
00369
00370 extern BOOL IR_open_output(const char *filename)
00371 {
00372 if (filename == NULL)
00373 ir_ofile = stdout;
00374 else
00375 if ((ir_ofile = fopen(filename, "w+")) == NULL) {
00376 ir_error("cannot open file for write");
00377 return FALSE;
00378 }
00379 return TRUE;
00380 }
00381
00382
00383 extern void IR_close_output(void)
00384 {
00385 if (ir_ofile != NULL && ir_ofile != stdout)
00386 fclose(ir_ofile);
00387 }
00388 #endif
00389
00390
00391
00392
00393
00394
00395
00396
00397 #define ir_chk_kids(m,n) {if (m != n) ir_error("wrong number of kids"); }
00398
00399 static void ir_error(char *s)
00400 {
00401 fprintf(stderr, "Error parsing ascii IR at line %d: %s.\n", ir_line, s);
00402 exit(RC_INTERNAL_ERROR);
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 typedef struct {
00413 char *filename;
00414 INT incl_index;
00415 FILE *fileptr;
00416 INT max_line_printed;
00417 } file_info;
00418
00419 static file_info *file_table = NULL;
00420 static char **incl_table;
00421 static INT cur_file_index = 0;
00422 static BOOL file_table_generated = FALSE;
00423
00424
00425
00426
00427
00428
00429 static void ir_print_filename(BOOL dump_filenames)
00430 {
00431
00432
00433
00434
00435
00436 INT count;
00437 DST_IDX idx;
00438 DST_FILE_NAME *file;
00439 char *name;
00440 INT file_table_size;
00441 INT new_size;
00442
00443
00444 file_table_size = 0;
00445 file_table = NULL;
00446 count = 1;
00447 for (idx = DST_get_file_names ();
00448 !DST_IS_NULL(idx);
00449 idx = DST_FILE_NAME_next(file))
00450 {
00451 file = DST_FILE_IDX_TO_PTR (idx);
00452 if (DST_IS_NULL(DST_FILE_NAME_name(file))) {
00453 name = "NULLNAME";
00454 }
00455 else {
00456 name = DST_STR_IDX_TO_PTR (DST_FILE_NAME_name(file));
00457 }
00458 if (count >= file_table_size) {
00459 new_size = count + 10;
00460 if (file_table == NULL)
00461 file_table = (file_info *) malloc (new_size * sizeof (file_info));
00462 else
00463 file_table = (file_info *) realloc (file_table,
00464 new_size * sizeof (file_info));
00465 if (file_table == NULL)
00466 fprintf(stderr, "IR_Dwarf_Gen_File_Table: Run out of memory\n");
00467 file_table_size = new_size;
00468 }
00469 file_table[count].filename = name;
00470 file_table[count].incl_index = DST_FILE_NAME_dir(file);
00471 file_table[count].fileptr = NULL;
00472 file_table[count].max_line_printed = 0;
00473 if (dump_filenames)
00474 fprintf (ir_ofile, " LOC 0 0 source files:\t%d\t\"%s/%s\"\n",
00475 count,
00476 incl_table[DST_FILE_NAME_dir(file)],
00477 name);
00478 count++;
00479 }
00480
00481 while (count < file_table_size) {
00482 file_table[count].fileptr = NULL;
00483 count++;
00484 }
00485
00486 }
00487
00488 extern void IR_Dwarf_Gen_File_Table (BOOL dump_filenames)
00489 {
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 INT count;
00500 DST_IDX idx;
00501 DST_INCLUDE_DIR *incl;
00502 char *name;
00503 INT incl_table_size;
00504 INT new_size;
00505
00506 if (file_table_generated && file_table != NULL) {
00507
00508 for (count = 1; file_table[count].fileptr != NULL; count++) {
00509 fclose (file_table[count].fileptr);
00510 file_table[count].fileptr = NULL;
00511 file_table[count].max_line_printed = 0;
00512 }
00513 cur_file_index = 0;
00514 return;
00515 }
00516
00517 incl_table_size = 0;
00518 incl_table = NULL;
00519 file_table = NULL;
00520 count = 1;
00521 for (idx = DST_get_include_dirs ();
00522 !DST_IS_NULL(idx);
00523 idx = DST_INCLUDE_DIR_next(incl))
00524 {
00525 incl = DST_DIR_IDX_TO_PTR (idx);
00526 name = DST_STR_IDX_TO_PTR (DST_INCLUDE_DIR_path(incl));
00527 if (count >= incl_table_size) {
00528 new_size = count + 10;
00529 if (incl_table == NULL)
00530 incl_table = (char **) malloc (new_size * sizeof (char *));
00531 else
00532 incl_table = (char **) realloc (incl_table, new_size * sizeof (char *));
00533 if (incl_table == NULL)
00534 fprintf(stderr, "IR_Dwarf_Gen_File_Table: Run out of memory\n");
00535 incl_table_size = new_size;
00536 }
00537 incl_table[count] = name;
00538 count++;
00539 }
00540
00541 ir_print_filename(dump_filenames);
00542
00543 file_table_generated = TRUE;
00544 }
00545
00546
00547 extern void IR_Srcpos_Filename(SRCPOS srcpos,
00548 const char **fname,
00549 const char **dirname)
00550 {
00551
00552
00553
00554
00555
00556
00557
00558 USRCPOS usrcpos;
00559
00560 USRCPOS_srcpos(usrcpos) = srcpos;
00561 if (USRCPOS_filenum(usrcpos) == 0)
00562 {
00563 *fname = NULL;
00564 *dirname = NULL;
00565 }
00566 else
00567 {
00568 file_info *cur_file;
00569
00570 if (!file_table_generated)
00571 IR_Dwarf_Gen_File_Table(FALSE);
00572
00573 cur_file = &file_table[USRCPOS_filenum(usrcpos)];
00574 *fname = cur_file->filename;
00575 *dirname = incl_table[cur_file->incl_index];
00576 }
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 static void
00586 print_source (SRCPOS srcpos)
00587 {
00588 USRCPOS usrcpos;
00589 char srcfile[1024];
00590 char text[1024];
00591 file_info *cur_file;
00592 INT i;
00593 INT newmax;
00594
00595 USRCPOS_srcpos(usrcpos) = srcpos;
00596
00597 if (USRCPOS_filenum(usrcpos) == 0) {
00598
00599 fprintf(ir_ofile, "LOC 0 %d\n", USRCPOS_linenum(usrcpos));
00600 return;
00601 }
00602
00603 cur_file = &file_table[USRCPOS_filenum(usrcpos)];
00604 if (USRCPOS_filenum(usrcpos) != cur_file_index) {
00605 if (cur_file_index != 0) {
00606
00607 file_info *prev_file = &file_table[cur_file_index];
00608 fclose (prev_file->fileptr);
00609 prev_file->fileptr = NULL;
00610 }
00611 cur_file_index = USRCPOS_filenum(usrcpos);
00612 cur_file = &file_table[cur_file_index];
00613
00614 sprintf (srcfile, "%s/%s", incl_table[cur_file->incl_index],
00615 cur_file->filename);
00616 cur_file->fileptr = fopen (srcfile, "r");
00617 if (cur_file->fileptr == NULL) {
00618 cur_file_index = 0;
00619 fprintf (ir_ofile, " LOC %d %d\n", cur_file_index,
00620 USRCPOS_linenum(usrcpos));
00621 return;
00622 }
00623 cur_file->max_line_printed = 0;
00624 newmax = USRCPOS_linenum(usrcpos) - 2;
00625 }
00626 else {
00627 newmax = USRCPOS_linenum(usrcpos) - 5;
00628 }
00629 if (cur_file->max_line_printed < newmax) {
00630 for (i = cur_file->max_line_printed; i < newmax; i++) {
00631 fgets (text, sizeof(text), cur_file->fileptr);
00632 }
00633 cur_file->max_line_printed = newmax;
00634 }
00635 if (cur_file->max_line_printed < USRCPOS_linenum(usrcpos)) {
00636 for (i = cur_file->max_line_printed; i < USRCPOS_linenum(usrcpos); i++) {
00637 if (fgets (text, sizeof(text), cur_file->fileptr) != NULL)
00638 fprintf (ir_ofile, " LOC %d %d %s", cur_file_index, i+1, text);
00639 }
00640 cur_file->max_line_printed = USRCPOS_linenum(usrcpos);
00641 }
00642 else if (cur_file->max_line_printed != USRCPOS_linenum(usrcpos)
00643 && USRCPOS_linenum(usrcpos) != 0)
00644 {
00645
00646
00647
00648
00649 fprintf (ir_ofile, " LOC %d %d\n", cur_file_index,
00650 USRCPOS_linenum(usrcpos));
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661 #ifdef IR_TOOLS
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 static BOOL ir_insert_hash(char *s, IR_OPCODE_TABLE *opcode_entry)
00678 {
00679 char *p;
00680 UINT sum = 0;
00681 INT i;
00682
00683 for (p = s; *p != '\0'; p++)
00684 sum = (sum+sum+3377)^*p;
00685
00686 sum %= HASH_LEN;
00687 for (i = 0; i < HASH_LEN; i++) {
00688 if (opcode_hash[sum] == NULL) {
00689 opcode_hash[sum] = opcode_entry;
00690 return TRUE;
00691 }
00692 if (strcmp(opcode_hash[sum]->pr_name, s) == 0)
00693 return FALSE;
00694 sum = (sum + 1) % HASH_LEN;
00695 }
00696 return FALSE;
00697 }
00698
00699
00700
00701
00702
00703 static INT ir_lookup(char *s)
00704 {
00705 char *p;
00706 INT sum = 0;
00707 INT i;
00708
00709 for (p = s; *p != '\0'; p++)
00710 sum = (sum+sum+3377)^*p;
00711 sum %= HASH_LEN;
00712 for (i = 0; i < HASH_LEN; i++) {
00713 if (opcode_hash[sum] == NULL)
00714 return -1;
00715 if (strcmp(opcode_hash[sum]->pr_name, s) == 0)
00716 return (opcode_hash[sum] - ir_opcode_table);
00717 sum = (sum + 1) % HASH_LEN;
00718 }
00719 return -1;
00720 }
00721
00722
00723
00724
00725
00726 static void enter_opcode_table(char *name, OPCODE opc, INT opr)
00727 {
00728 ir_opcode_table[opc].pr_name = name;
00729 if (!ir_insert_hash(ir_opcode_table[opc].pr_name, &ir_opcode_table[opc])) {
00730 sprintf(errmsg, "cannot insert %s into hash table", OPCODE_name(opc));
00731 ir_error(errmsg);
00732 }
00733 }
00734
00735
00736 static inline
00737 void enter_opcode_table (char *name, OPC_EXTENDED opc, INT opr)
00738 {
00739 enter_opcode_table (name, (OPCODE) opc, opr);
00740 }
00741
00742
00743
00744
00745 static void ir_build_hashtable(void)
00746 {
00747 INT i;
00748 INT opr;
00749
00750
00751 memset(ir_opcode_table, 0, sizeof(ir_opcode_table));
00752 memset(opcode_hash, 0, sizeof(opcode_hash));
00753
00754
00755 for (i = OPCODE_FIRST; i <= OPCODE_LAST; i++) {
00756 OPCODE opc = (OPCODE) i;
00757 opr = OPCODE_operator(opc);
00758 enter_opcode_table(((char *)OPCODE_name(opc))+strlen("OPC_"), opc, opr);
00759 }
00760
00761
00762 enter_opcode_table("BODY", OPC_BODY, OPR_BODY);
00763 enter_opcode_table("NOOP", OPC_NOOP, OPR_NOOP);
00764 enter_opcode_table("END_BLOCK", OPC_END_BLOCK, OPR_END_BLOCK);
00765 enter_opcode_table("THEN", OPC_THEN, OPR_THEN);
00766 enter_opcode_table("ELSE", OPC_ELSE, OPR_ELSE);
00767 enter_opcode_table("END_IF", OPC_END_IF, OPR_END_IF);
00768 enter_opcode_table("INIT", OPC_INIT, OPR_INIT);
00769 enter_opcode_table("COMP", OPC_COMP, OPR_COMP);
00770 enter_opcode_table("INCR", OPC_INCR, OPR_INCR);
00771 enter_opcode_table("END_COMPGOTO", OPC_END_COMPGOTO, OPR_END_COMPGOTO);
00772 enter_opcode_table("END_XGOTO", OPC_END_XGOTO, OPR_END_XGOTO);
00773 enter_opcode_table("LOC", OPC_LOC, OPR_LOC);
00774 enter_opcode_table("END_LOOP_INFO", OPC_END_LINFO, OPR_END_LINFO);
00775 enter_opcode_table("END_SWITCH", OPC_END_SWITCH, OPR_END_SWITCH);
00776 }
00777
00778 #endif
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 static void
00792 ir_put_st (ST_IDX st_idx)
00793 {
00794 char *name;
00795 char *p;
00796
00797 if (st_idx == (ST_IDX) 0) {
00798
00799 fprintf(ir_ofile, " <null-st>");
00800
00801 } else if (!follow_st) {
00802
00803
00804 fprintf(ir_ofile, " <st %d>", (INT32) st_idx);
00805
00806 } else {
00807 const ST* st = &St_Table[st_idx];
00808 if (ST_class(st) == CLASS_CONST) {
00809 name = Targ_Print(NULL, STC_val(st));
00810
00811
00812
00813 for (p = name; *p != '\0'; p++)
00814 switch (*p) {
00815 case ' ':
00816 case '\t':
00817 case '\n':
00818 *p = '_';
00819 }
00820 } else
00821 name = ST_name(st);
00822 fprintf (ir_ofile, " <%d,%d,%s>", ST_level (st), ST_index (st), name);
00823 }
00824 }
00825
00826
00827
00828
00829
00830 static void
00831 ir_put_ty(TY_IDX ty)
00832 {
00833 fprintf(ir_ofile, " T<%d,%s,%d", TY_id(ty),
00834 TY_name(ty),TY_align(ty));
00835
00836 if (TY_is_restrict(ty))
00837 fprintf(ir_ofile, ",R");
00838
00839 if (TY_is_volatile(ty))
00840 fprintf(ir_ofile, ",V");
00841
00842 if (TY_is_const(ty))
00843 fprintf(ir_ofile, ",C");
00844
00845 fprintf(ir_ofile, ">");
00846 }
00847
00848
00849 static void
00850 ir_put_parm_keyword(ST * st)
00851 {
00852 TCON strcon = STC_val(st);
00853 INT32 strlen ;
00854 INT32 stridx ;
00855 const char *strbase;
00856 char *keyword;
00857
00858 strlen = Targ_String_Length(strcon);
00859 strbase = Targ_String_Address(strcon);
00860
00861 keyword = (char *) malloc((strlen+1)* sizeof(char));
00862 FmtAssert (keyword,("No more memory for holding keyword."));
00863
00864 for (stridx = 0; stridx<strlen;stridx++)
00865 keyword[stridx] = strbase[stridx];
00866 keyword[stridx] = '\0';
00867 fprintf(ir_ofile, keyword);
00868 free(keyword);
00869 }
00870
00871
00872
00873
00874 static void ir_put_wn(WN * wn, INT indent)
00875 {
00876 OPCODE opcode;
00877
00878 if (wn == NULL) {
00879
00880
00881 fprintf(ir_ofile, "### attention: null WN pointer, place holder\n");
00882 return;
00883 } else {
00884 if (IR_dump_wn_addr) {
00885 fprintf(ir_ofile, "0x%8p: ", wn);
00886 }
00887 opcode = WN_opcode(wn);
00888 }
00889 if (opcode == 0) {
00890 fprintf(ir_ofile,"### error: WN opcode 0\n");
00891 return;
00892 }
00893
00894
00895
00896 if (IR_DUMPDEP_info) {
00897 INT32 handle= 0;
00898 if (OPCODE_has_alias_info(WN_opcode(wn)) && WN_map_id(wn) != -1) {
00899 handle= AddToDUMPDEP(wn);
00900 }
00901 fprintf(ir_ofile, "[%5d]", handle);
00902 }
00903
00904 if (indent > 0 && opcode == OPC_LABEL)
00905 fprintf(ir_ofile, "%*s", indent-1, "");
00906 else
00907 fprintf(ir_ofile, "%*s", indent, "");
00908
00909 fprintf(ir_ofile, "%s", OPCODE_name(opcode) + strlen("OPC_"));
00910 if (OPCODE_has_offset(opcode)) {
00911 if (OPCODE_operator(opcode) == OPR_PRAGMA ||
00912 OPCODE_operator(opcode) == OPR_XPRAGMA)
00913 fprintf(ir_ofile, " %d %d", WN_pragma_flags(wn), WN_pragma(wn));
00914 else
00915 fprintf(ir_ofile, " %d", WN_offset(wn));
00916 } else if (OPCODE_has_2offsets(opcode)) {
00917 fprintf(ir_ofile, " %d %d",
00918 WN_loop_trip_est(wn), WN_loop_depth(wn));
00919 }
00920
00921 switch (OPCODE_operator(opcode)) {
00922
00923 case OPR_INTRINSIC_OP:
00924 case OPR_ARRAYEXP:
00925 fprintf(ir_ofile, " %d", WN_kid_count(wn));
00926 break;
00927
00928 case OPR_REGION:
00929 fprintf(ir_ofile, " %d", WN_region_id(wn));
00930 fprintf(ir_ofile, " (kind=%d)",WN_region_kind(wn));
00931 break;
00932
00933 case OPR_LDBITS:
00934 case OPR_ILDBITS:
00935 case OPR_STBITS:
00936 case OPR_ISTBITS:
00937 case OPR_EXTRACT_BITS:
00938 case OPR_COMPOSE_BITS:
00939 fprintf(ir_ofile, " <bofst:%d bsize:%d>", WN_bit_offset(wn),
00940 WN_bit_size(wn));
00941 break;
00942
00943 case OPR_ASM_INPUT:
00944 fprintf(ir_ofile, " opnd:%d", WN_asm_opnd_num(wn));
00945 break;
00946
00947 default:
00948 break;
00949 }
00950
00951 if (OPCODE_has_inumber(opcode)) {
00952 switch (opcode) {
00953 case OPC_IO:
00954 fprintf(ir_ofile, " <%d,%s,%s>", WN_intrinsic(wn),
00955 IOSTATEMENT_name((IOSTATEMENT) WN_intrinsic(wn)),
00956 get_iolibrary_name(WN_IO_Library(wn)));
00957 break;
00958 case OPC_IO_ITEM:
00959 fprintf(ir_ofile, " <%d,%s>", WN_intrinsic(wn),
00960 IOITEM_name((IOITEM) WN_intrinsic(wn)));
00961 break;
00962 default:
00963 Is_True(OPCODE_operator(opcode) == OPR_INTRINSIC_OP ||
00964 OPCODE_operator(opcode) == OPR_INTRINSIC_CALL,
00965 ("ir_put_wn, expected an intrinsic"));
00966 fprintf(ir_ofile, " <%d,%s>", WN_intrinsic(wn),
00967 INTRINSIC_name((INTRINSIC) WN_intrinsic(wn)));
00968 break;
00969 }
00970 }
00971
00972 if (OPCODE_has_bits(opcode))
00973 fprintf(ir_ofile, " %d", WN_cvtl_bits(wn));
00974 if (OPCODE_has_label(opcode))
00975 fprintf(ir_ofile, " L%d", WN_label_number(wn));
00976 if (OPCODE_has_flags(opcode))
00977 fprintf(ir_ofile, " %d", WN_flag(wn));
00978 if (OPCODE_has_sym(opcode)) {
00979 ir_put_st (WN_st_idx(wn));
00980 }
00981
00982 if (OPCODE_has_1ty(opcode)) {
00983 if (WN_ty(wn) != (TY_IDX) 0)
00984 ir_put_ty(WN_ty(wn));
00985 else
00986 if (opcode != OPC_IO_ITEM)
00987 fprintf(ir_ofile, " T<### ERROR: null ptr>");
00988 } else if (OPCODE_has_2ty(opcode)) {
00989 if (WN_ty(wn) != (TY_IDX) 0)
00990 ir_put_ty(WN_ty(wn));
00991 else
00992 fprintf(ir_ofile, " T<### ERROR: null ptr>");
00993 if (WN_load_addr_ty(wn) != (TY_IDX) 0)
00994 ir_put_ty(WN_load_addr_ty(wn));
00995 else
00996 fprintf(ir_ofile, " T<### ERROR: null ptr>");
00997 }
00998
00999 if (OPCODE_has_ndim(opcode))
01000 fprintf(ir_ofile, " %d", WN_num_dim(wn));
01001 if (OPCODE_has_esize(opcode))
01002 fprintf(ir_ofile, " %lld", WN_element_size(wn));
01003
01004 if (OPCODE_has_num_entries(opcode))
01005 fprintf(ir_ofile, " %d", WN_num_entries(wn));
01006 if (OPCODE_has_last_label(opcode))
01007 fprintf(ir_ofile, " %d", WN_last_label(wn));
01008
01009 if (OPCODE_has_value(opcode)) {
01010 fprintf(ir_ofile, " %lld", WN_const_val(wn));
01011
01012 if (OPCODE_operator(opcode) == OPR_INTCONST || opcode == OPC_PRAGMA) {
01013 fprintf(ir_ofile, " (0x%llx)", WN_const_val(wn));
01014 }
01015 }
01016
01017 if (OPCODE_has_field_id(opcode) && WN_field_id(wn)) {
01018 fprintf(ir_ofile, " <field_id:%d>", WN_field_id(wn));
01019 }
01020
01021
01022 if (OPCODE_has_ereg_supp(opcode)) {
01023 INITO_IDX ino = WN_ereg_supp(wn);
01024 if (ino != 0)
01025 fprintf (ir_ofile, " INITO<%d,%s>", INITO_IDX_index (ino),
01026 ST_name (INITO_st_idx (Inito_Table[ino])));
01027 }
01028 if (opcode == OPC_COMMENT) {
01029 fprintf(ir_ofile, " # %s", Index_To_Str(WN_offset(wn)));
01030 }
01031
01032 if (follow_st && OPCODE_has_sym(opcode) && OPCODE_has_offset(opcode)
01033 && WN_st_idx(wn) != (ST_IDX) 0 && (ST_class(WN_st(wn)) == CLASS_PREG)
01034 && opcode != OPC_PRAGMA)
01035 {
01036 if (Preg_Is_Dedicated(WN_offset(wn))) {
01037 if (Preg_Offset_Is_Int(WN_offset(wn))) {
01038 fprintf(ir_ofile, " # $r%d", WN_offset(wn));
01039 }
01040 else if (Preg_Offset_Is_Float(WN_offset(wn))) {
01041 fprintf(ir_ofile, " # $f%d",
01042 WN_offset(wn) - Float_Preg_Min_Offset);
01043 }
01044 }
01045 else {
01046
01047 if ((WN_offset(wn) - Last_Dedicated_Preg_Offset)
01048 < PREG_Table_Size (CURRENT_SYMTAB) )
01049 fprintf(ir_ofile, " # %s", Preg_Name(WN_offset(wn)));
01050 else
01051 fprintf(ir_ofile, " # <Invalid PREG Table index (%d)>",
01052 WN_offset(wn));
01053 }
01054 }
01055
01056 if (opcode == OPC_XPRAGMA) {
01057 fprintf(ir_ofile, " # %s", WN_pragmas[WN_pragma(wn)].name);
01058 }
01059
01060 if (OPCODE_operator(opcode) == OPR_ASM_INPUT) {
01061 fprintf(ir_ofile, " # \"%s\"", WN_asm_input_constraint(wn));
01062 }
01063
01064 if (opcode == OPC_PRAGMA) {
01065 fprintf(ir_ofile, " # %s", WN_pragmas[WN_pragma(wn)].name);
01066 switch(WN_pragma(wn)) {
01067 case WN_PRAGMA_DISTRIBUTE:
01068 case WN_PRAGMA_REDISTRIBUTE:
01069 case WN_PRAGMA_DISTRIBUTE_RESHAPE:
01070 fprintf(ir_ofile, ", %d",WN_pragma_index(wn));
01071 switch(WN_pragma_distr_type(wn)) {
01072 case DISTRIBUTE_STAR:
01073 fprintf(ir_ofile, ", *");
01074 break;
01075 case DISTRIBUTE_BLOCK:
01076 fprintf(ir_ofile, ", BLOCK");
01077 break;
01078 case DISTRIBUTE_CYCLIC_CONST:
01079 fprintf(ir_ofile, ", CYCLIC(%d)", WN_pragma_preg(wn));
01080 break;
01081 case DISTRIBUTE_CYCLIC_EXPR:
01082 fprintf(ir_ofile, ", CYCLIC(expr)");
01083 break;
01084 }
01085 break;
01086 case WN_PRAGMA_ASM_CONSTRAINT:
01087 fprintf(ir_ofile, ", \"%s\", opnd:%d preg:%d",
01088 WN_pragma_asm_constraint(wn),
01089 WN_pragma_asm_opnd_num(wn),
01090 WN_pragma_asm_copyout_preg(wn));
01091 break;
01092 default:
01093 if (WN_pragma_arg2(wn) != 0 )
01094 fprintf(ir_ofile, ", %d, %d", WN_pragma_arg1(wn), WN_pragma_arg2(wn));
01095 else
01096 if (WN_pragma_arg1(wn) != 0 )
01097 fprintf(ir_ofile, ", %d", WN_pragma_arg1(wn));
01098 break;
01099 }
01100 }
01101
01102 if (OPCODE_operator(opcode) == OPR_ASM_STMT) {
01103 fprintf(ir_ofile, " # \"%s\"", WN_asm_string(wn));
01104 if (WN_Asm_Volatile(wn))
01105 fprintf(ir_ofile, " (volatile)");
01106 if (WN_Asm_Clobbers_Mem(wn))
01107 fprintf(ir_ofile, " (memory)");
01108 if (WN_Asm_Clobbers_Cc(wn))
01109 fprintf(ir_ofile, " (cc)");
01110 }
01111
01112 if (OPCODE_is_call(opcode))
01113 fprintf(ir_ofile, " # flags 0x%x", WN_call_flag(wn));
01114
01115 if (OPCODE_operator(opcode) == OPR_PARM) {
01116 INT flag = WN_flag(wn);
01117 fprintf(ir_ofile, " # ");
01118 if (flag & WN_PARM_BY_REFERENCE) fprintf(ir_ofile, " by_reference ");
01119 if (flag & WN_PARM_BY_VALUE) fprintf(ir_ofile, " by_value ");
01120 if (flag & WN_PARM_OUT) fprintf(ir_ofile, " out ");
01121 if (flag & WN_PARM_DUMMY) fprintf(ir_ofile, " dummy ");
01122 if (flag & WN_PARM_READ_ONLY) fprintf(ir_ofile, " read_only ");
01123 if (flag & WN_PARM_PASSED_NOT_SAVED) fprintf(ir_ofile, "passed_not_saved ");
01124 if (flag & WN_PARM_NOT_EXPOSED_USE) fprintf(ir_ofile, " not_euse ");
01125 if (flag & WN_PARM_IS_KILLED) fprintf(ir_ofile, " killed ");
01126
01127
01128 if (flag & WN_PARM_PASS_ADDRESS) fprintf(ir_ofile, "PASS_ADDRESS ");
01129 if (flag & WN_PARM_PASS_ADDRESS_FROM_DV) fprintf(ir_ofile, "PASS_ADDRESS_FROM_DV ");
01130 if (flag & WN_PARM_PASS_DV) fprintf(ir_ofile, "PASS_DV ");
01131 if (flag & WN_PARM_PASS_DV_COPY) fprintf(ir_ofile, "PASS_DV_COPY ");
01132 if (flag & WN_PARM_COPY_IN) fprintf(ir_ofile, "COPY_IN ");
01133 if (flag & WN_PARM_COPY_IN_COPY_OUT ) fprintf(ir_ofile, "COPY_IN_COPY_OUT ");
01134 if (flag & WN_PARM_MAKE_DV) fprintf(ir_ofile, "MAKE_DV ");
01135 if (flag & WN_PARM_COPY_IN_MAKE_DV) fprintf(ir_ofile, "COPY_IN_MAKE_DV ");
01136 if (flag & WN_PARM_MAKE_NEW_DV) fprintf(ir_ofile, "MAKE_NEW_DV ");
01137 if (flag & WN_PARM_PASS_SECTION_ADDRESS) fprintf(ir_ofile, "PASS_SECTION_ADDRESS ");
01138 if (flag & WN_PARM_CHECK_CONTIG_FLAG) fprintf(ir_ofile, "CHECK_CONTIG_FLAG ");
01139
01140 if ( wn->u3.ty_fields.ty) {
01141 ST * kwrd = &St_Table[wn->u3.ty_fields.ty];
01142 fprintf(ir_ofile, "Keyword: ");
01143 ir_put_parm_keyword(kwrd);
01144 }
01145
01146 }
01147
01148 if (IR_dump_map_info) {
01149 fprintf(ir_ofile, " # <id %d:%d>", OPCODE_mapcat(opcode),
01150 WN_map_id(wn));
01151 if (ir_put_map && ( WN_map_id(wn) != -1 )) {
01152 switch ( WN_MAP_Get_Kind( ir_put_map ) ) {
01153 case WN_MAP_KIND_VOIDP:
01154 fprintf(ir_ofile, " <map %8p>", WN_MAP_Get( ir_put_map, wn ));
01155 break;
01156 case WN_MAP_KIND_INT32:
01157 fprintf(ir_ofile, " <map %08x>", WN_MAP32_Get( ir_put_map, wn ));
01158 break;
01159 case WN_MAP_KIND_INT64:
01160 fprintf(ir_ofile, " <map %08llx>", WN_MAP64_Get( ir_put_map, wn ));
01161 break;
01162 }
01163 }
01164 }
01165
01166 if (IR_dump_line_numbers &&
01167 (OPCODE_is_scf(WN_opcode(wn)) || OPCODE_is_stmt(WN_opcode(wn)))) {
01168
01169 USRCPOS srcpos;
01170 USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
01171
01172 fprintf(ir_ofile, " {line: %d}", USRCPOS_linenum(srcpos));
01173 }
01174
01175
01176 if (IR_freq_map != WN_MAP_UNDEFINED && (OPCODE_is_scf(WN_opcode(wn)) ||
01177 OPCODE_is_stmt(WN_opcode(wn)))) {
01178 USRCPOS srcpos;
01179 USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
01180
01181 fprintf(ir_ofile, " {freq: %d, ln: %d, col: %d}",
01182 WN_MAP32_Get(IR_freq_map, wn),
01183 USRCPOS_linenum(srcpos),
01184 USRCPOS_column(srcpos));
01185 }
01186 if (Current_Map_Tab != NULL
01187 && WN_MAP32_Get(WN_MAP_ALIAS_CLASS, wn) != 0)
01188 {
01189 fprintf(ir_ofile, " {class %d}",
01190 WN_MAP32_Get(WN_MAP_ALIAS_CLASS, wn));
01191 }
01192 fprintf(ir_ofile, "\n");
01193 }
01194
01195
01196
01197
01198
01199
01200 static void ir_put_expr(WN * wn, INT indent)
01201 {
01202 INT i;
01203 WN * wn2;
01204
01205
01206 if (dump_parent_before_children) {
01207 ir_put_wn(wn,indent);
01208 }
01209 for (i = 0; i < WN_kid_count(wn); i++) {
01210 wn2 = WN_kid(wn,i);
01211 if (wn2) {
01212 OPCODE op = WN_opcode(wn2);
01213 if ((OPCODE_FIRST <= op && op <= OPCODE_LAST) &&
01214 (OPCODE_is_expression(op) || OPCODE_is_call(op)))
01215 ir_put_expr(WN_kid(wn,i), indent+1);
01216 else
01217 if ( op == OPC_BLOCK
01218 && ( (WN_operator(wn) == OPR_RCOMMA && i == 1)
01219 || (WN_operator(wn) == OPR_COMMA && i == 0)))
01220 ir_put_stmt(wn2, indent+1);
01221 else
01222
01223 if (op == OPC_IMPLICIT_BND)
01224 fprintf(ir_ofile,"%*sIMPLICIT_BND\n",indent+1,"");
01225 else
01226 fprintf(ir_ofile, "%*sopcode %d not an expression\n", indent+1, "", op);
01227
01228 } else
01229 fprintf(ir_ofile, "%*snull-expression\n", indent+1, "");
01230 }
01231 if (!dump_parent_before_children) {
01232 ir_put_wn(wn, indent);
01233 }
01234 }
01235
01236
01237
01238
01239
01240 static void ir_put_marker(char *str, INT indent)
01241 {
01242 fprintf(ir_ofile, "%*s%s\n", indent, "", str);
01243 }
01244
01245
01246
01247
01248
01249 static void ir_put_stmt(WN * wn, INT indent)
01250 {
01251 INT i;
01252 WN * wn2;
01253 USRCPOS srcpos;
01254
01255 if (wn) {
01256 OPCODE opc = WN_opcode(wn);
01257 BOOL already_dumped_wn = FALSE;
01258 USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
01259 if (USRCPOS_srcpos(srcpos) != 0 &&
01260 USRCPOS_srcpos(srcpos) != USRCPOS_srcpos(last_srcpos)) {
01261 last_srcpos = srcpos;
01262 #ifdef FRONT_END
01263 fprintf(ir_ofile, "%*sLOC %d %d\n", indent, "",
01264 USRCPOS_filenum(srcpos), USRCPOS_linenum(srcpos));
01265 #else
01266 print_source(USRCPOS_srcpos(srcpos));
01267 #endif
01268 }
01269
01270 if (OPCODE_is_scf(opc) || dump_parent_before_children) {
01271 ir_put_wn(wn, indent);
01272 already_dumped_wn = TRUE;
01273 }
01274
01275 switch (opc) {
01276
01277 case OPC_BLOCK:
01278 wn2 = WN_first(wn);
01279 while (wn2) {
01280 ir_put_stmt(wn2, indent);
01281 wn2 = WN_next(wn2);
01282 }
01283 ir_put_marker("END_BLOCK", indent);
01284 break;
01285
01286 case OPC_LABEL:
01287 ir_put_wn(wn, indent);
01288 if ( WN_label_loop_info(wn) != NULL ) {
01289 ir_put_stmt(WN_label_loop_info(wn), indent+1);
01290 }
01291 already_dumped_wn = TRUE;
01292 break;
01293
01294 case OPC_IF:
01295 ir_put_expr(WN_if_test(wn), indent+1);
01296 if (WN_then(wn)) {
01297 ir_put_marker("THEN", indent);
01298 ir_put_stmt(WN_then(wn), indent+1);
01299 }
01300 if (WN_else(wn)) {
01301 ir_put_marker("ELSE", indent);
01302 ir_put_stmt(WN_else(wn), indent+1);
01303 }
01304 ir_put_marker("END_IF", indent);
01305 break;
01306
01307 case OPC_DO_LOOP:
01308 ir_put_expr(WN_index(wn), indent+1);
01309 ir_put_marker("INIT",indent);
01310 ir_put_stmt(WN_start(wn), indent+1);
01311 ir_put_marker("COMP", indent);
01312 ir_put_expr(WN_end(wn), indent+1);
01313 ir_put_marker("INCR", indent);
01314 ir_put_stmt(WN_step(wn), indent+1);
01315
01316 if ( WN_do_loop_info(wn) != NULL ) {
01317 ir_put_stmt(WN_do_loop_info(wn), indent);
01318 }
01319 ir_put_marker("BODY", indent);
01320 ir_put_stmt(WN_do_body(wn), indent+1);
01321 break;
01322
01323 case OPC_LOOP_INFO:
01324 ir_put_wn(wn, indent);
01325 if ( WN_loop_induction(wn) != NULL ) {
01326 ir_put_expr(WN_loop_induction(wn), indent+1);
01327 }
01328 if ( WN_loop_trip(wn) != NULL ) {
01329 ir_put_expr(WN_loop_trip(wn), indent+1);
01330 }
01331 ir_put_marker("END_LOOP_INFO", indent);
01332 already_dumped_wn = TRUE;
01333 break;
01334
01335 case OPC_COMPGOTO:
01336 ir_put_wn(wn, indent);
01337 ir_put_expr(WN_kid(wn,0), indent+1);
01338 ir_put_stmt(WN_kid(wn,1), indent+1);
01339 if (WN_kid_count(wn) > 2)
01340 ir_put_stmt(WN_kid(wn,2), indent+1);
01341 ir_put_marker("END_COMPGOTO", indent);
01342 already_dumped_wn = TRUE;
01343 break;
01344
01345 case OPC_SWITCH:
01346 ir_put_wn(wn, indent);
01347 ir_put_expr(WN_kid(wn,0), indent+1);
01348 ir_put_stmt(WN_kid(wn,1), indent+1);
01349 if (WN_kid_count(wn) > 2)
01350 ir_put_stmt(WN_kid(wn,2), indent+1);
01351 ir_put_marker("END_SWITCH", indent);
01352 already_dumped_wn = TRUE;
01353 break;
01354
01355 case OPC_XGOTO:
01356 ir_put_wn(wn, indent);
01357 ir_put_expr(WN_kid(wn,0), indent+1);
01358 ir_put_stmt(WN_kid(wn,1), indent+1);
01359 ir_put_marker("END_XGOTO", indent);
01360 already_dumped_wn = TRUE;
01361 break;
01362
01363 case OPC_WHERE:
01364 ir_put_expr(WN_kid(wn,0), indent+1);
01365 ir_put_marker("BODY", indent);
01366 ir_put_stmt(WN_kid(wn,1), indent+1);
01367 ir_put_stmt(WN_kid(wn,2), indent+1);
01368 break;
01369
01370 case OPC_EXC_SCOPE_BEGIN:
01371 {
01372 INT i;
01373 for (i = 0; i < WN_kid_count(wn); i++)
01374 ir_put_stmt(WN_kid(wn, i), indent+1);
01375 break;
01376 }
01377 case OPC_EXC_SCOPE_END:
01378 break;
01379
01380 case OPC_ASM_STMT:
01381 ir_put_wn(wn, indent);
01382 already_dumped_wn = TRUE;
01383 ir_put_stmt(WN_kid(wn,0), indent+1);
01384 ir_put_stmt(WN_kid(wn,1), indent+1);
01385 ir_put_marker("ASM_INPUTS", indent);
01386 {
01387 INT i;
01388 for (i = 2; i < WN_kid_count(wn); i++) {
01389 ir_put_expr(WN_kid(wn,i), indent+1);
01390 }
01391 }
01392 ir_put_marker("END_ASM_INPUTS", indent);
01393 break;
01394
01395 case OPC_VUSE:
01396 case OPC_BUSE:
01397 ir_put_marker("USE!!!!!", indent);
01398 break;
01399
01400 default:
01401 {
01402 INT last_is_expr = TRUE;
01403 OPCODE opc2;
01404 for (i = 0; i < WN_kid_count(wn); i++) {
01405 wn2 = WN_kid(wn,i);
01406 if (wn2) {
01407 opc2 = WN_opcode(wn2);
01408 if (opc2 == 0) {
01409 fprintf(ir_ofile, "### error: WN opcode 0\n");
01410 } else if (OPCODE_is_expression(opc2)) {
01411 ir_put_expr(wn2, indent+1);
01412 last_is_expr = 1;
01413 }
01414 else if (OPCODE_is_stmt(opc2) || OPCODE_is_scf(opc2)) {
01415 if (last_is_expr) {
01416 ir_put_marker("BODY", indent);
01417 ir_put_stmt(wn2, indent+1);
01418 } else
01419 ir_put_stmt(WN_kid(wn,i), indent+1);
01420 last_is_expr = 0;
01421 } else {
01422 fprintf(ir_ofile, "### error: unknown opcode type %d\n",opc2);
01423 }
01424 } else
01425 ir_put_stmt(wn2, indent+1);
01426 }
01427 }
01428 }
01429 if (!already_dumped_wn)
01430 ir_put_wn(wn, indent);
01431 } else
01432 ir_put_wn(wn, indent);
01433 }
01434
01435
01436
01437
01438 extern void IR_put_func(WN * wn, FILE *f)
01439 {
01440 FILE *save;
01441 if (f) {
01442 save = ir_ofile;
01443 ir_ofile = f;
01444 }
01445 ir_put_stmt(wn, 0);
01446 if (f) {
01447 ir_ofile = save;
01448 }
01449 }
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461 extern void dump_wn(WN *wn)
01462 {
01463 FILE *save;
01464
01465 if (!is_initialized) IR_reader_init();
01466 save = ir_ofile;
01467 ir_ofile = stdout;
01468 IR_Dwarf_Gen_File_Table(TRUE);
01469 ir_put_wn(wn, 0);
01470 ir_ofile = save;
01471 }
01472
01473 extern void fdump_wn(FILE *fp, WN *wn)
01474 {
01475 FILE *save;
01476
01477 if (!is_initialized) IR_reader_init();
01478 save = ir_ofile;
01479 ir_ofile = fp;
01480 IR_Dwarf_Gen_File_Table(TRUE);
01481 ir_put_wn(wn, 0);
01482 ir_ofile = save;
01483 }
01484
01485 extern void dump_tree(WN *wn)
01486 {
01487 fdump_tree(stdout,wn);
01488 }
01489
01490
01491 extern void dump_region_tree(WN *wn)
01492 {
01493 BOOL save = IR_dump_region;
01494 IR_dump_region = TRUE;
01495 fdump_tree(stdout, wn);
01496 IR_dump_region = save;
01497 }
01498
01499 extern void dump_wn_no_st(WN *wn)
01500 {
01501 BOOL save_follow_st;
01502 if (!is_initialized) IR_reader_init();
01503 save_follow_st = follow_st;
01504 follow_st = FALSE;
01505 dump_wn(wn);
01506 follow_st = save_follow_st;
01507 }
01508
01509 extern void fdump_wn_no_st(FILE *fp, WN *wn)
01510 {
01511 BOOL save_follow_st;
01512 FILE *save = ir_ofile;
01513 if (!is_initialized) IR_reader_init();
01514 save_follow_st = follow_st;
01515 ir_ofile = fp;
01516 follow_st = FALSE;
01517 IR_Dwarf_Gen_File_Table(TRUE);
01518 ir_put_wn(wn, 0);
01519 follow_st = save_follow_st;
01520 ir_ofile = save;
01521 }
01522
01523 extern void dump_tree_no_st(WN *wn)
01524 {
01525 BOOL save_follow_st;
01526 if (!is_initialized) IR_reader_init();
01527 save_follow_st = follow_st;
01528 follow_st = FALSE;
01529 dump_tree(wn);
01530 follow_st = save_follow_st;
01531 }
01532
01533 extern void fdump_tree(FILE *f, WN *wn)
01534 {
01535 FILE *save;
01536
01537
01538 if (!is_initialized) IR_reader_init();
01539 save = ir_ofile;
01540 ir_ofile = f;
01541 IR_Dwarf_Gen_File_Table(TRUE);
01542 if (!wn) {
01543 fprintf(ir_ofile, "<null whirl tree>\n");
01544 } else if (OPCODE_is_stmt(WN_opcode(wn)) || OPCODE_is_scf(WN_opcode(wn)))
01545 ir_put_stmt(wn, 0);
01546 else if (OPCODE_is_expression(WN_opcode(wn)))
01547 ir_put_expr(wn, 0);
01548 else if (WN_opcode(wn) == OPC_FUNC_ENTRY)
01549 IR_put_func(wn, NULL);
01550 else
01551 fprintf(ir_ofile, "unknown opcode in (WN *) 0x%p\n", wn);
01552 ir_ofile = save;
01553 }
01554
01555
01556 extern void fdump_tree_no_st( FILE *f, WN *wn )
01557 {
01558 BOOL save_follow_st;
01559 if (!is_initialized) IR_reader_init();
01560 save_follow_st = follow_st;
01561 follow_st = FALSE;
01562 fdump_tree( f, wn );
01563 follow_st = save_follow_st;
01564 }
01565
01566 extern void fdump_tree_with_alias( FILE *f, const WN *wn, WN_MAP map, const struct ALIAS_MANAGER *am)
01567 {
01568 WN_MAP save = IR_alias_map;
01569 const struct ALIAS_MANAGER *save_am = am;
01570 IR_alias_map = map;
01571 IR_alias_mgr = am;
01572 fdump_tree( f, (WN *)wn );
01573 IR_alias_map = save;
01574 IR_alias_mgr = save_am;
01575 }
01576
01577 extern void enable_tree_freq_display(void)
01578 {
01579 IR_freq_map = WN_MAP_FEEDBACK;
01580 }
01581
01582 extern void disable_tree_freq_display(void)
01583 {
01584 IR_freq_map = WN_MAP_UNDEFINED;
01585 }
01586
01587 extern void fdump_tree_with_freq( FILE *f, const WN *wn, WN_MAP map)
01588 {
01589 WN_MAP save = IR_freq_map;
01590 IR_freq_map = map;
01591 fdump_tree( f, (WN *)wn );
01592 IR_freq_map = save;
01593 }
01594
01595 extern void fdump_region_tree(FILE *f, WN *wn)
01596 {
01597 BOOL save = IR_dump_region;
01598 IR_dump_region = TRUE;
01599 fdump_tree(f, wn);
01600 IR_dump_region = save;
01601 }
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 static void WN_TREE_put_expr(WN * wn, INT indent) {
01612 WN * wn2;
01613 WN * parent_wn;
01614
01615 Is_True(OPCODE_is_expression(WN_opcode(wn)) || OPCODE_is_call(WN_opcode(wn)),
01616 ("WN_TREE_put_expr invoked with non-expression, opcode = %s",
01617 OPCODE_name(WN_opcode(wn))));
01618
01619
01620 if (dump_parent_before_children) {
01621
01622
01623 WN_TREE_ITER<PRE_ORDER> tree_iter(wn);
01624
01625 #ifndef __GNU_BUG_WORKAROUND
01626 while (tree_iter != LAST_PRE_ORDER_ITER) {
01627 #else
01628 while (tree_iter != WN_TREE_ITER<PRE_ORDER, WN*>()) {
01629 #endif
01630 wn2 = tree_iter.Wn();
01631
01632 if (OPCODE_is_expression(WN_opcode(wn2)) ||
01633 OPCODE_is_call(WN_opcode(wn2)))
01634 ir_put_wn(wn2,indent+tree_iter.Depth());
01635
01636 else if (WN_operator(wn2) == OPR_BLOCK) {
01637
01638 parent_wn = tree_iter.Get_parent_wn();
01639 Is_True(parent_wn &&
01640 ((WN_operator(parent_wn) == OPR_COMMA) ||
01641 (WN_operator(parent_wn) == OPR_RCOMMA)),
01642 ("block under expression not a part of comma/rcomma"));
01643
01644 WN_TREE_put_stmt(wn2, indent + tree_iter.Depth());
01645 tree_iter.Unwind();
01646
01647 }
01648
01649 else
01650 fprintf(ir_ofile, "%*sopcode %d not an expression\n",
01651 indent+1,"", WN_opcode(wn2));
01652 ++tree_iter;
01653 }
01654 }
01655 else {
01656
01657
01658
01659
01660
01661 ir_put_expr(wn,indent);
01662 }
01663 }
01664
01665
01666
01667
01668
01669
01670
01671 static void WN_TREE_put_stmt(WN * wn, INT indent)
01672 {
01673 INT i;
01674 WN * wn2;
01675 USRCPOS srcpos;
01676
01677 Is_True(wn != 0, ("WN_TREE_put_stmt called with null whirl tree"));
01678
01679 OPCODE opc = WN_opcode(wn);
01680 Is_True(OPCODE_is_scf(opc) || OPCODE_is_stmt(opc),
01681 ("WN_TREE_put_stmt invoked on non statement: opcode = %s",
01682 OPCODE_name(opc)));
01683
01684 if (wn) {
01685 BOOL already_dumped_wn = FALSE;
01686 USRCPOS_srcpos(srcpos) = WN_Get_Linenum(wn);
01687 if (USRCPOS_srcpos(srcpos) != 0 &&
01688 USRCPOS_srcpos(srcpos) != USRCPOS_srcpos(last_srcpos)) {
01689 last_srcpos = srcpos;
01690 #ifdef FRONT_END
01691 fprintf(ir_ofile, "%*sLOC %d %d\n", indent, "",
01692 USRCPOS_filenum(srcpos), USRCPOS_linenum(srcpos));
01693 #else
01694 print_source(USRCPOS_srcpos(srcpos));
01695 #endif
01696 }
01697
01698 if (OPCODE_is_scf(opc) || dump_parent_before_children) {
01699 ir_put_wn(wn, indent);
01700 already_dumped_wn = TRUE;
01701 }
01702
01703
01704 WN_TREE_ITER<PRE_ORDER> tree_iter(wn);
01705
01706 switch (opc) {
01707
01708 case OPC_BLOCK:
01709 if (WN_first(wn)) {
01710 ++tree_iter;
01711 #ifndef __GNU_BUG_WORKAROUND
01712 while (tree_iter != LAST_PRE_ORDER_ITER) {
01713 #else
01714 while (tree_iter != WN_TREE_ITER<PRE_ORDER, WN*>()) {
01715 #endif
01716 wn2 = tree_iter.Wn();
01717 WN_TREE_put_stmt(wn2, indent);
01718 tree_iter.Unwind();
01719
01720 }
01721 }
01722 ir_put_marker("END_BLOCK", indent);
01723 break;
01724
01725 case OPC_LABEL:
01726 ir_put_wn(wn, indent);
01727 if ( WN_label_loop_info(wn) != NULL ) {
01728 WN_TREE_put_stmt(WN_label_loop_info(wn), indent+1);
01729 }
01730 already_dumped_wn = TRUE;
01731 break;
01732
01733 case OPC_IF:
01734 WN_TREE_put_expr(WN_if_test(wn), indent+1);
01735 if (WN_then(wn)) {
01736 ir_put_marker("THEN", indent);
01737 WN_TREE_put_stmt(WN_then(wn), indent+1);
01738 }
01739 if (WN_else(wn)) {
01740 ir_put_marker("ELSE", indent);
01741 WN_TREE_put_stmt(WN_else(wn), indent+1);
01742 }
01743 ir_put_marker("END_IF", indent);
01744 break;
01745
01746 case OPC_DO_LOOP:
01747 WN_TREE_put_expr(WN_index(wn), indent+1);
01748 ir_put_marker("INIT",indent);
01749 WN_TREE_put_stmt(WN_start(wn), indent+1);
01750 ir_put_marker("COMP", indent);
01751 WN_TREE_put_expr(WN_end(wn), indent+1);
01752 ir_put_marker("INCR", indent);
01753 WN_TREE_put_stmt(WN_step(wn), indent+1);
01754
01755 if ( WN_do_loop_info(wn) != NULL ) {
01756 WN_TREE_put_stmt(WN_do_loop_info(wn), indent);
01757 }
01758 ir_put_marker("BODY", indent);
01759 WN_TREE_put_stmt(WN_do_body(wn), indent+1);
01760 break;
01761
01762 case OPC_LOOP_INFO:
01763 ir_put_wn(wn, indent);
01764 if ( WN_loop_induction(wn) != NULL ) {
01765 WN_TREE_put_expr(WN_loop_induction(wn), indent+1);
01766 }
01767 if ( WN_loop_trip(wn) != NULL ) {
01768 WN_TREE_put_expr(WN_loop_trip(wn), indent+1);
01769 }
01770 ir_put_marker("END_LOOP_INFO", indent);
01771 already_dumped_wn = TRUE;
01772 break;
01773
01774 case OPC_COMPGOTO:
01775 ir_put_wn(wn, indent);
01776 WN_TREE_put_expr(WN_kid(wn,0), indent+1);
01777 WN_TREE_put_stmt(WN_kid(wn,1), indent+1);
01778 if (WN_kid_count(wn) > 2)
01779 WN_TREE_put_stmt(WN_kid(wn,2), indent+1);
01780 ir_put_marker("END_COMPGOTO", indent);
01781 already_dumped_wn = TRUE;
01782 break;
01783
01784 case OPC_SWITCH:
01785 ir_put_wn(wn, indent);
01786 WN_TREE_put_expr(WN_kid(wn,0), indent+1);
01787 WN_TREE_put_stmt(WN_kid(wn,1), indent+1);
01788 if (WN_kid_count(wn) > 2)
01789 WN_TREE_put_stmt(WN_kid(wn,2), indent+1);
01790 ir_put_marker("END_SWITCH", indent);
01791 already_dumped_wn = TRUE;
01792 break;
01793
01794 case OPC_XGOTO:
01795 ir_put_wn(wn, indent);
01796 WN_TREE_put_expr(WN_kid(wn,0), indent+1);
01797 WN_TREE_put_stmt(WN_kid(wn,1), indent+1);
01798 ir_put_marker("END_XGOTO", indent);
01799 already_dumped_wn = TRUE;
01800 break;
01801
01802 case OPC_WHERE:
01803 WN_TREE_put_expr(WN_kid(wn,0), indent+1);
01804 ir_put_marker("BODY", indent);
01805 WN_TREE_put_stmt(WN_kid(wn,1), indent+1);
01806 WN_TREE_put_stmt(WN_kid(wn,2), indent+1);
01807 break;
01808
01809 case OPC_EXC_SCOPE_BEGIN:
01810 {
01811 INT i;
01812 for (i = 0; i < WN_kid_count(wn); i++)
01813 WN_TREE_put_stmt(WN_kid(wn, i), indent+1);
01814 break;
01815 }
01816 case OPC_EXC_SCOPE_END:
01817 break;
01818 default:
01819 {
01820 INT last_is_expr = TRUE;
01821 OPCODE opc2;
01822 for (i = 0; i < WN_kid_count(wn); i++) {
01823 wn2 = WN_kid(wn,i);
01824 if (wn2) {
01825 opc2 = WN_opcode(wn2);
01826 if (opc2 == 0) {
01827 fprintf(ir_ofile, "### error: WN opcode 0\n");
01828 } else if (OPCODE_is_expression(opc2)) {
01829 WN_TREE_put_expr(wn2, indent+1);
01830 last_is_expr = 1;
01831 }
01832 else if (OPCODE_is_stmt(opc2) || OPCODE_is_scf(opc2)) {
01833 if (last_is_expr) {
01834 ir_put_marker("BODY", indent);
01835 WN_TREE_put_stmt(wn2, indent+1);
01836 } else
01837 WN_TREE_put_stmt(WN_kid(wn,i), indent+1);
01838 last_is_expr = 0;
01839 } else {
01840 fprintf(ir_ofile, "### error: unknown opcode type %d\n",opc2);
01841 }
01842 } else
01843 WN_TREE_put_stmt(wn2, indent+1);
01844 }
01845 }
01846 }
01847 if (!already_dumped_wn)
01848 ir_put_wn(wn, indent);
01849 } else
01850 ir_put_wn(wn, indent);
01851 }
01852
01853 extern void WN_TREE_put_func(WN * wn, FILE *f)
01854 {
01855 FILE *save;
01856 if (f) {
01857 save = ir_ofile;
01858 ir_ofile = f;
01859 }
01860 WN_TREE_put_stmt(wn, 0);
01861 if (f) {
01862 ir_ofile = save;
01863 }
01864 }
01865
01866 extern void WN_TREE_fdump_tree(FILE *f, WN *wn)
01867 {
01868 FILE *save;
01869
01870
01871 if (!is_initialized) IR_reader_init();
01872 save = ir_ofile;
01873 ir_ofile = f;
01874 IR_Dwarf_Gen_File_Table(TRUE);
01875 ir_print_filename(TRUE);
01876 if (!wn) {
01877 fprintf(ir_ofile, "<null whirl tree>\n");
01878 } else if (OPCODE_is_stmt(WN_opcode(wn)) || OPCODE_is_scf(WN_opcode(wn)))
01879 WN_TREE_put_stmt(wn, 0);
01880 else if (OPCODE_is_expression(WN_opcode(wn)))
01881 WN_TREE_put_expr(wn, 0);
01882 else if (WN_opcode(wn) == OPC_FUNC_ENTRY)
01883 WN_TREE_put_func(wn, NULL);
01884 else
01885 fprintf(ir_ofile, "unknown opcode in (WN *) 0x%p\n", wn);
01886 ir_ofile = save;
01887 }
01888
01889 extern void WN_TREE_dump_tree(WN *wn)
01890 {
01891 WN_TREE_fdump_tree(stdout,wn);
01892 }
01893
01894
01895 #ifdef BACK_END
01896 #endif
01897
01898 extern void Check_for_IR_Dump(INT phase, WN *pu, const char *phase_name)
01899 {
01900 BOOL dump_ir;
01901 BOOL dump_symtab;
01902 dump_ir = Get_Trace ( TKIND_IR, phase );
01903 dump_symtab = Get_Trace ( TKIND_SYMTAB, phase );
01904 if (dump_ir || dump_symtab) {
01905 fprintf(TFile,"\n\n========== Driver dump after %s ==========\n",
01906 phase_name);
01907 if (dump_ir) fdump_tree (TFile,pu);
01908 if (dump_symtab) {
01909 Print_symtab (TFile, GLOBAL_SYMTAB);
01910 Print_symtab (TFile, CURRENT_SYMTAB);
01911 }
01912 }
01913 }