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 #ifdef __MINGW32__
00048 #include "WINDOWS.h"
00049 #endif
00050 #if defined(BUILD_OS_DARWIN)
00051 #include <limits.h>
00052 #else
00053 #include <values.h>
00054 #endif
00055 #include <sys/types.h>
00056 #if ! defined(BUILD_OS_DARWIN)
00057 #include <elf.h>
00058 #endif
00059 #include "defs.h"
00060 #include "config.h"
00061 #include "config_debug.h"
00062 #include "config_list.h"
00063 #include "config_targ_opt.h"
00064 #include "controls.h"
00065 #include "erglob.h"
00066 #include "erlib.h"
00067 #include "file_util.h"
00068 #include "flags.h"
00069 #include "glob.h"
00070 #include "mempool.h"
00071 #include "tracing.h"
00072 #include "util.h"
00073 #include "errors.h"
00074
00075 #include "err_host.tab"
00076 #include <stdarg.h>
00077 #include "gnu_config.h"
00078 extern "C" {
00079 #include "gnu/system.h"
00080 #include "gnu/tree.h"
00081 }
00082 #include "wn.h"
00083 #include "wn_util.h"
00084 #include "wn_simp.h"
00085 #include "symtab.h"
00086 #include "pu_info.h"
00087 #include "ir_reader.h"
00088 #include "ir_bwrite.h"
00089 #ifdef KEY // get REAL_VALUE_TYPE
00090 #include "real.h"
00091 #endif // KEY
00092 #include "wfe_decl.h"
00093 #include "wfe_expr.h"
00094 #include "wfe_dst.h"
00095 #include "wfe_misc.h"
00096 #include "wfe_stmt.h"
00097 #include "c_int_model.h"
00098
00099 #ifndef KEY
00100 int WFE_Keep_Zero_Length_Structs = FALSE;
00101 #else
00102 int WFE_Keep_Zero_Length_Structs = TRUE;
00103 #endif
00104
00105 extern int optimize;
00106
00107 PU_Info *PU_Tree_Root = NULL;
00108 int wfe_invoke_inliner = FALSE;
00109
00110 extern void Initialize_IRB (void);
00111 extern char *asm_file_name;
00112
00113 int trace_verbose = FALSE;
00114
00115
00116 static BOOL Prepare_Source (void);
00117 static void WFE_Stmt_Stack_Init (void);
00118 static void WFE_Stmt_Stack_Free (void);
00119
00120
00121
00122 enum debug_info_level
00123 {
00124 DINFO_LEVEL_NONE,
00125 DINFO_LEVEL_TERSE,
00126 DINFO_LEVEL_NORMAL,
00127 DINFO_LEVEL_VERBOSE
00128 };
00129
00130
00131 extern enum debug_info_level debug_info_level;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 # define DEF_DEBUG_LEVEL 0
00145 INT8 Debug_Level = DEF_DEBUG_LEVEL;
00146 # define MAX_MSG_LEVEL 2
00147 # define DEF_MSG_LEVEL 2
00148
00149 #ifdef MONGOOSE_CIF
00150 mUINT32 Cif_Level = 0;
00151 #define MAX_CIF_LEVEL 3
00152 #define DEF_CIF_LEVEL 2
00153 #endif
00154
00155
00156 #define IRB_FILE_EXTENSION ".B"
00157 #define IRD_FILE_EXTENSION ".D"
00158 #define ERR_FILE_EXTENSION ".e"
00159 #define LST_FILE_EXTENSION ".l"
00160 #define TRC_FILE_EXTENSION ".t"
00161 #define DSTDUMP_FILE_EXTENSION ".fe.dst"
00162
00163
00164 static INT32 Argc;
00165 static char **Argv;
00166 static INT32 Source_Arg = 0;
00167 static INT32 Src_Count = 0;
00168 static char Dash [] = "-";
00169
00170
00171 static BOOL Echo_Flag = FALSE;
00172 static BOOL Delete_IR_File = FALSE;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 void
00188 Cleanup_Files ( BOOL report, BOOL delete_dotofile )
00189 {
00190
00191 Set_Error_Line (ERROR_LINE_UNKNOWN);
00192
00193
00194 if ( Src_File != NULL && Src_File != stdin && fclose (Src_File) ) {
00195 if ( report ) ErrMsg ( EC_Src_Close, Src_File_Name, errno );
00196 }
00197 Src_File = NULL;
00198
00199
00200 if ( IR_File != NULL && fclose (IR_File) ) {
00201 if ( report ) ErrMsg ( EC_IR_Close, IR_File_Name, errno );
00202 }
00203 IR_File = NULL;
00204 if ( Delete_IR_File && unlink (IR_File_Name) ) {
00205 if ( report ) ErrMsg ( EC_IR_Delete, IR_File_Name, errno );
00206 }
00207
00208
00209 if ( Lst_File != NULL && Lst_File != stdout && fclose (Lst_File) ) {
00210 if ( report ) ErrMsg ( EC_Lst_Close, Lst_File_Name, errno );
00211 }
00212 Lst_File = NULL;
00213
00214
00215 Set_Trace_File ( NULL );
00216
00217
00218 Tim_File = NULL;
00219
00220
00221 Set_Error_File ( NULL );
00222 Set_Error_Source ( NULL );
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 void
00236 Terminate ( INT status )
00237 {
00238
00239 Cleanup_Files ( FALSE, FALSE);
00240
00241 exit (status);
00242 }
00243
00244 static void
00245 Process_Command_Line (void)
00246 {
00247 INT16 i;
00248 char *cp;
00249 INT16 len;
00250 BOOL dashdash_flag = FALSE;
00251
00252
00253 while ( ++Source_Arg < Argc ) {
00254 i = Source_Arg;
00255
00256 if ( !dashdash_flag && (*(Argv[i]) == '-' )) {
00257 cp = Argv[i]+1;
00258
00259
00260 if ( *cp == 'o' ) {
00261 ++cp;
00262 if ( *cp == 0 ) {
00263
00264 ++Source_Arg;
00265 }
00266 continue;
00267 }
00268
00269
00270 if (strncmp(cp, "OPT:", 4) == 0) {
00271 Process_Command_Line_Group (cp, Common_Option_Groups);
00272 continue;
00273 }
00274
00275 if (*cp == 't') {
00276 Process_Trace_Option ( Argv[i] );
00277 continue;
00278 }
00279 }
00280 else {
00281 Src_Count++;
00282 dashdash_flag = FALSE;
00283
00284
00285 len = strlen ( Argv[i] );
00286 Src_File_Name = (char *) malloc (len+5);
00287 strcpy ( Src_File_Name, Argv[i] );
00288 }
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 static BOOL
00308 Prepare_Source ( void )
00309 {
00310 INT16 i;
00311 char *cp;
00312 char *fname;
00313 INT16 len;
00314 BOOL dashdash_flag = FALSE;
00315 BOOL okay;
00316
00317
00318 if ( Src_Count == 0 || Src_File_Name == NULL) {
00319 ErrMsg ( EC_No_Sources );
00320 }
00321
00322
00323
00324
00325
00326 fname = Last_Pathname_Component ( Src_File_Name );
00327
00328
00329 if ( Err_File_Name == NULL ) {
00330
00331 Err_File_Name = New_Extension
00332 ( fname, ERR_FILE_EXTENSION );
00333 } else if ( *Err_File_Name == '-' ) {
00334
00335 Err_File_Name = NULL;
00336 }
00337 Set_Error_File ( Err_File_Name );
00338
00339
00340 if ( Trc_File_Name == NULL ) {
00341 if ( Tracing_Enabled ) {
00342
00343 Trc_File_Name = New_Extension
00344 ( fname, TRC_FILE_EXTENSION );
00345 }
00346 } else if ( *Trc_File_Name == '-' ) {
00347
00348 Trc_File_Name = NULL;
00349 }
00350 Set_Trace_File ( Trc_File_Name );
00351 if ( Get_Trace (TKIND_INFO, TINFO_TIME) ) Tim_File = TFile;
00352
00353
00354 IR_File_Name = Src_File_Name;
00355
00356
00357 if ( Irb_File_Name == NULL ) {
00358 if (asm_file_name == NULL) {
00359
00360 Irb_File_Name = New_Extension ( fname, IRB_FILE_EXTENSION );
00361 }
00362 else {
00363 Irb_File_Name = asm_file_name;
00364 }
00365 }
00366
00367 if ( (Irb_File = fopen ( Irb_File_Name, "w" )) == NULL ) {
00368 ErrMsg ( EC_IR_Open, IR_File_Name, errno );
00369 Cleanup_Files ( TRUE, FALSE );
00370 return FALSE;
00371 } else {
00372 if ( Get_Trace ( TP_MISC, 1) ) {
00373 fprintf ( TFile,
00374 "\n%sControl Values: Open_Dot_B_File\n%s\n", DBar, DBar );
00375 Print_Controls ( TFile, "", TRUE );
00376 }
00377 }
00378
00379
00380 Configure_Source ( Src_File_Name );
00381
00382 return TRUE;
00383 }
00384
00385 #ifdef KEY
00386 extern void WFE_Omp_Init (void);
00387 #endif // KEY
00388
00389
00390 void
00391 WFE_Init (INT argc, char **argv, char **envp )
00392 {
00393 Set_Error_Tables ( Phases, host_errlist );
00394 #ifdef KEY
00395 Initialize_C_Int_Model();
00396 #endif
00397 MEM_Initialize();
00398 Handle_Signals();
00399
00400
00401 Set_Error_Line ( ERROR_LINE_UNKNOWN );
00402 Set_Error_Phase ( "Front End Driver" );
00403 Preconfigure ();
00404 #ifdef TARG_MIPS
00405 ABI_Name = "n64";
00406 #endif
00407 #ifdef TARG_IA64
00408 ABI_Name = "i64";
00409 #endif
00410 #if defined(TARG_IA32) || defined(TARG_X8664) || defined(TARG_NVISA)
00411 if (TARGET_64BIT)
00412 ABI_Name = "n64";
00413 else ABI_Name = "n32";
00414 #endif
00415 Init_Controls_Tbl();
00416 Argc = argc;
00417 Argv = argv;
00418
00419
00420 Init_Error_Handler ( 100 );
00421 Set_Error_Line ( ERROR_LINE_UNKNOWN );
00422 Set_Error_File ( NULL );
00423 Set_Error_Phase ( "Front End Driver" );
00424
00425
00426 Src_File_Name = NULL;
00427 IR_File_Name = NULL;
00428 Irb_File_Name = NULL;
00429 Err_File_Name = Dash;
00430 Lst_File_Name = NULL;
00431 Trc_File_Name = NULL;
00432 DSTdump_File_Name = NULL;
00433 Delete_IR_File = FALSE;
00434
00435 Process_Command_Line();
00436
00437 Configure ();
00438
00439 IR_reader_init();
00440 Initialize_Symbol_Tables (TRUE);
00441 WFE_Stmt_Stack_Init ();
00442 WFE_Stmt_Init ();
00443 #ifdef KEY
00444 WFE_Omp_Init ();
00445 #endif
00446 WFE_Expr_Init ();
00447 WHIRL_Mldid_Mstid_On = TRUE;
00448 WN_Simp_Fold_LDA = TRUE;
00449
00450 WHIRL_Keep_Cvt_On = TRUE;
00451 Opt_Level = optimize;
00452
00453
00454
00455 Debug_Level = (debug_info_level >= DINFO_LEVEL_NORMAL)? 2:0;
00456 }
00457
00458 void
00459 WFE_File_Init (INT argc, char **argv)
00460 {
00461
00462 Prepare_Source();
00463 MEM_POOL_Push (&MEM_src_pool);
00464
00465 Restore_Cmd_Line_Ctrls();
00466
00467 Open_Output_Info ( Irb_File_Name );
00468 DST_build(argc, argv);
00469 }
00470
00471 void
00472 WFE_File_Finish (void)
00473 {
00474 Verify_SYMTAB (GLOBAL_SYMTAB);
00475 Write_Global_Info (PU_Tree_Root);
00476 Close_Output_Info ();
00477 IR_reader_finish ();
00478 MEM_POOL_Pop (&MEM_src_pool);
00479 }
00480
00481 void
00482 WFE_Finish ()
00483 {
00484 WFE_Stmt_Stack_Free ();
00485 }
00486
00487 void
00488 WFE_Check_Errors (int *error_count, int *warning_count, BOOL *need_inliner)
00489 {
00490
00491
00492 Get_Error_Count ( error_count, warning_count);
00493 *need_inliner = wfe_invoke_inliner;
00494 }
00495
00496 #define ENLARGE(x) (x + (x >> 1))
00497 #define WN_STMT_STACK_SIZE 32
00498
00499 typedef struct wn_stmt {
00500 WN *wn;
00501 WFE_STMT_KIND kind;
00502 } WN_STMT;
00503
00504 static WN_STMT *wn_stmt_stack;
00505 static WN_STMT *wn_stmt_sp;
00506 static WN_STMT *wn_stmt_stack_last;
00507 static INT wn_stmt_stack_size;
00508
00509 char * WFE_Stmt_Kind_Name [wfe_stmk_last+1] = {
00510 "'unknown'",
00511 "'function entry'",
00512 "'function pragma'",
00513 "'function body'",
00514 "'region pragmas'",
00515 "'scope'",
00516 "'if condition'",
00517 "'if then clause'",
00518 "'if else clause'",
00519 "'while condition'",
00520 "'while body'",
00521 "'dowhile condition'",
00522 "'dowhile body'",
00523 "'for condition'",
00524 "'for body'",
00525 "'switch'",
00526 "'comma'",
00527 "'rcomma'",
00528 #ifdef KEY
00529 "'dummy'",
00530 #endif // KEY
00531 "'last'"
00532 };
00533
00534 static void
00535 WFE_Stmt_Stack_Init (void)
00536 {
00537 wn_stmt_stack_size = WN_STMT_STACK_SIZE;
00538 wn_stmt_stack = (WN_STMT *) malloc (sizeof (WN_STMT) *
00539 wn_stmt_stack_size );
00540 wn_stmt_sp = wn_stmt_stack - 1;
00541 wn_stmt_stack_last = wn_stmt_stack + wn_stmt_stack_size - 1;
00542 }
00543
00544 static void
00545 WFE_Stmt_Stack_Free (void)
00546 {
00547 free (wn_stmt_stack);
00548 wn_stmt_stack = NULL;
00549 }
00550
00551 void
00552 WFE_Stmt_Push (WN* wn, WFE_STMT_KIND kind, SRCPOS srcpos)
00553 {
00554 INT new_stack_size;
00555
00556 if (wn_stmt_sp == wn_stmt_stack_last) {
00557 new_stack_size = ENLARGE(wn_stmt_stack_size);
00558 wn_stmt_stack =
00559 (WN_STMT *) realloc (wn_stmt_stack, new_stack_size * sizeof (WN_STMT));
00560 wn_stmt_sp = wn_stmt_stack + wn_stmt_stack_size - 1;
00561 wn_stmt_stack_size = new_stack_size;
00562 wn_stmt_stack_last = wn_stmt_stack + wn_stmt_stack_size - 1;
00563 }
00564 ++wn_stmt_sp;
00565 wn_stmt_sp->wn = wn;
00566 wn_stmt_sp->kind = kind;
00567
00568 if (srcpos)
00569 WN_Set_Linenum ( wn, srcpos );
00570 }
00571
00572 WN*
00573 WFE_Stmt_Top (void)
00574 {
00575 FmtAssert (wn_stmt_sp >= wn_stmt_stack,
00576 ("no more entries on stack in function WFE_Stmt_Top"));
00577
00578 return (wn_stmt_sp->wn);
00579 }
00580
00581 void
00582 WFE_Stmt_Append (WN* wn, SRCPOS srcpos)
00583 {
00584 WN * body;
00585 WN * last;
00586
00587 if (srcpos) {
00588 WN_Set_Linenum ( wn, srcpos );
00589 if (WN_operator(wn) == OPR_BLOCK && WN_first(wn) != NULL)
00590 WN_Set_Linenum ( WN_first(wn), srcpos );
00591 }
00592
00593 body = WFE_Stmt_Top ();
00594
00595 if (body) {
00596
00597 last = WN_last(body);
00598 WN_INSERT_BlockAfter (body, last, wn);
00599 }
00600 }
00601
00602
00603 WN*
00604 WFE_Stmt_Last (void)
00605 {
00606 WN * body;
00607
00608 body = WFE_Stmt_Top ();
00609 return (WN_last(body));
00610 }
00611
00612
00613 WN *
00614 WFE_Stmt_Delete ()
00615 {
00616 WN * body;
00617 WN * last;
00618 WN * prev;
00619
00620 body = WFE_Stmt_Top ();
00621 last = WN_last(body);
00622 prev = WN_prev(last);
00623 if (prev)
00624 WN_next(prev) = NULL;
00625 else
00626 WN_first(body) = NULL;
00627 WN_last(body) = prev;
00628 WN_prev(last) = NULL;
00629
00630 return last;
00631 }
00632
00633
00634 WN*
00635 WFE_Stmt_Pop (WFE_STMT_KIND kind)
00636 {
00637 WN * wn;
00638
00639 FmtAssert (wn_stmt_sp >= wn_stmt_stack,
00640 ("no more entries on stack in function WFE_Stmt_Pop"));
00641
00642 FmtAssert (wn_stmt_sp->kind == kind,
00643 ("mismatch in statements: expected %s, got %s\n",
00644 WFE_Stmt_Kind_Name [kind],
00645 WFE_Stmt_Kind_Name [wn_stmt_sp->kind]));
00646
00647 wn = wn_stmt_sp->wn;
00648 wn_stmt_sp--;
00649
00650 return (wn);
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660 #ifdef KEY
00661
00662
00663
00664
00665
00666
00667 void
00668 WFE_Stmt_Prepend_Last (WN* wn, SRCPOS srcpos)
00669 {
00670 WN * body;
00671 WN * last;
00672
00673 if (srcpos) {
00674 WN_Set_Linenum ( wn, srcpos );
00675 if (WN_operator(wn) == OPR_BLOCK && WN_first(wn) != NULL)
00676 WN_Set_Linenum ( WN_first(wn), srcpos );
00677 }
00678
00679 body = WFE_Stmt_Top ();
00680
00681 if (body) {
00682
00683 last = WN_last(body);
00684 WN_INSERT_BlockBefore (body, last, wn);
00685 }
00686 }
00687 #endif
00688
00689 #ifdef KEY
00690 WFE_STMT_KIND
00691 WFE_Stmt_Top_Kind (void)
00692 {
00693 FmtAssert (wn_stmt_sp >= wn_stmt_stack,
00694 ("no more entries on stack in function WFE_Stmt_Top"));
00695
00696 return (wn_stmt_sp->kind);
00697 }
00698
00699 void WFE_Stmt_Append_Before (WN* wn, SRCPOS srcpos)
00700 {
00701 WN * body;
00702 WN * last;
00703
00704 if (srcpos) {
00705 WN_Set_Linenum ( wn, srcpos );
00706 if (WN_operator(wn) == OPR_BLOCK && WN_first(wn) != NULL)
00707 WN_Set_Linenum ( WN_first(wn), srcpos );
00708 }
00709
00710 body = (wn_stmt_sp-1)->wn;
00711
00712 if (body) {
00713
00714 last = WN_last(body);
00715 WN_INSERT_BlockAfter (body, last, wn);
00716 }
00717
00718 }
00719
00720
00721
00722 WN *
00723 WFE_Find_Stmt_In_Stack (WFE_STMT_KIND kind)
00724 {
00725 WN_STMT * sp = wn_stmt_sp;
00726 Is_True (sp, ("Null WN stack pointer"));
00727
00728 while (sp->kind != wfe_stmk_func_entry)
00729 {
00730 if (sp->kind == kind)
00731 break;
00732 sp--;
00733 Is_True (sp, ("FUNC_ENTRY node not found"));
00734 }
00735 FmtAssert (sp->kind == kind, ("Stmt kind not found in stack"));
00736 Is_True (sp->wn, ("Null WN stmt in apparently valid stack location"));
00737 return sp->wn;
00738 }
00739 #endif
00740