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