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 #include <sys/types.h>
00051 #include <elf.h>
00052 #include <cmplrs/rcodes.h>
00053 #include <dirent.h>
00054 #include <libgen.h>
00055
00056 #include "defs.h"
00057 #include "dso.h"
00058 #include "errors.h"
00059 #include "err_host.tab"
00060 #include "erglob.h"
00061 #include "erauxdesc.h"
00062 #include "mempool.h"
00063 #include "phase.h"
00064 #include "be_util.h"
00065 #include "wn.h"
00066 #include "driver_util.h"
00067 #include "timing.h"
00068 #include "glob.h"
00069 #include "stab.h"
00070 #include "pu_info.h"
00071 #include "ir_bread.h"
00072 #include "ir_bwrite.h"
00073 #include "config.h"
00074 #include "config_opt.h"
00075 #include "config_list.h"
00076 #include "config_lno.h"
00077 #include "file_util.h"
00078 #include "xstats.h"
00079 #include "data_layout.h"
00080 #include "opt_alias_interface.h"
00081 #include "wn_lower.h"
00082 #include "cgdriver.h"
00083 #include "optimizer.h"
00084 #include "ori.h"
00085 #include "wodriver.h"
00086 #include "lnodriver.h"
00087 #include "ipl_driver.h"
00088 #include "w2c_driver.h"
00089 #include "w2f_driver.h"
00090 #include "prp_driver.h"
00091 #include "anl_driver.h"
00092 #include "region_util.h"
00093 #include "region_main.h"
00094 #include "cg/cg.h"
00095 #include "tracing.h"
00096 #include "ir_reader.h"
00097 #include "dwarf_DST.h"
00098 #include "fb_whirl.h"
00099 #include "eh_region.h"
00100 #include "vho_lower.h"
00101 #include "iter.h"
00102 #include "dra_export.h"
00103 #include "ti_init.h"
00104 #include "opt_alias_interface.h"
00105 #include "omp_lower.h"
00106 #include "cxx_memory.h"
00107 #include "options_stack.h"
00108 #include "be_symtab.h"
00109 #include "prompf.h"
00110 #include "wb_omp.h"
00111 #include "wb_lwr.h"
00112 #include "wb_anl.h"
00113 #include "wn_instrument.h"
00114 #include "mem_ctr.h"
00115
00116
00117 #if defined(__CYGWIN__)
00118 # define DSOext ".dll"
00119 #else
00120 # define DSOext ".so"
00121 #endif
00122
00123
00124 extern void Initialize_Targ_Info(void);
00125
00126 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00127 extern "C" {
00128 INT64 New_Construct_Id(void) { return 0; }
00129 INT64 Get_Next_Construct_Id(void) { return 0; }
00130 }
00131 #endif
00132
00133
00134
00135 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00136
00137 extern void (*CG_Process_Command_Line_p) (INT, char **, INT, char **);
00138 #define CG_Process_Command_Line (*CG_Process_Command_Line_p)
00139
00140 extern void (*CG_Init_p) ();
00141 #define CG_Init (*CG_Init_p)
00142
00143 extern void (*CG_Fini_p) ();
00144 #define CG_Fini (*CG_Fini_p)
00145
00146 extern void (*CG_PU_Initialize_p) (WN*);
00147 #define CG_PU_Initialize (*CG_PU_Initialize_p)
00148
00149 extern void (*CG_PU_Finalize_p) ();
00150 #define CG_PU_Finalize (*CG_PU_Finalize_p)
00151
00152 extern WN* (*CG_Generate_Code_p) (WN*, ALIAS_MANAGER*, DST_IDX, BOOL);
00153 #define CG_Generate_Code (*CG_Generate_Code_p)
00154
00155 extern void (*EH_Generate_Range_List_p) (WN *);
00156 #define EH_Generate_Range_List (*EH_Generate_Range_List_p)
00157
00158 #else
00159
00160 #pragma weak CG_Process_Command_Line
00161 #pragma weak CG_Init
00162 #pragma weak CG_Fini
00163 #pragma weak CG_PU_Finalize
00164 #pragma weak CG_PU_Initialize
00165 #pragma weak CG_Generate_Code
00166 #pragma weak EH_Generate_Range_List
00167
00168 #endif // __linux__
00169
00170
00171
00172 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00173
00174 extern void (*wopt_main_p) (INT argc, char **argv, INT, char **);
00175 #define wopt_main (*wopt_main_p)
00176
00177 extern void (*Wopt_Init_p) ();
00178 #define Wopt_Init (*Wopt_Init_p)
00179
00180 extern void (*Wopt_Fini_p) ();
00181 #define Wopt_Fini (*Wopt_Fini_p)
00182
00183 extern WN* (*Perform_Preopt_Optimization_p) (WN *, WN *);
00184 #define Perform_Preopt_Optimization (*Perform_Preopt_Optimization_p)
00185
00186 extern WN* (*Perform_Global_Optimization_p) (WN *, WN *, ALIAS_MANAGER *);
00187 #define Perform_Global_Optimization (*Perform_Global_Optimization_p)
00188
00189 extern WN* (*Pre_Optimizer_p) (INT32, WN*, DU_MANAGER*, ALIAS_MANAGER*);
00190 #define Pre_Optimizer (*Pre_Optimizer_p)
00191
00192 extern DU_MANAGER* (*Create_Du_Manager_p) (MEM_POOL *);
00193 #define Create_Du_Manager (*Create_Du_Manager_p)
00194
00195 extern void (*Delete_Du_Manager_p) (DU_MANAGER *, MEM_POOL *);
00196 #define Delete_Du_Manager (*Delete_Du_Manager_p)
00197
00198 extern BOOL (*Verify_alias_p) (ALIAS_MANAGER *, WN *);
00199 #define Verify_alias (*Verify_alias_p)
00200
00201 #else
00202
00203 #pragma weak wopt_main
00204 #pragma weak Wopt_Init
00205 #pragma weak Wopt_Fini
00206 #pragma weak Perform_Global_Optimization
00207 #pragma weak Perform_Preopt_Optimization
00208 #pragma weak Pre_Optimizer
00209 #pragma weak Create_Du_Manager
00210 #pragma weak Delete_Du_Manager
00211 #pragma weak Verify_alias
00212
00213 #endif // __linux__
00214
00215
00216
00217 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00218
00219 extern void (*lno_main_p) (INT, char**, INT, char**);
00220 #define lno_main (*lno_main_p)
00221
00222 extern void (*Lno_Init_p) ();
00223 #define Lno_Init (*Lno_Init_p)
00224
00225 extern void (*Lno_Fini_p) ();
00226 #define Lno_Fini (*Lno_Fini_p)
00227
00228 extern WN* (*Perform_Loop_Nest_Optimization_p) (PU_Info*, WN*, WN*, BOOL);
00229 #define Perform_Loop_Nest_Optimization (*Perform_Loop_Nest_Optimization_p)
00230
00231 #else
00232
00233 #pragma weak lno_main
00234 #pragma weak Lno_Init
00235 #pragma weak Lno_Fini
00236 #pragma weak Perform_Loop_Nest_Optimization
00237
00238 #endif // __linux__
00239
00240
00241
00242 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00243
00244 extern void (*Ipl_Extra_Output_p) (Output_File *);
00245 #define Ipl_Extra_Output (*Ipl_Extra_Output_p)
00246
00247 extern void (*Ipl_Init_p) ();
00248 #define Ipl_Init (*Ipl_Init_p)
00249
00250 extern void (*Ipl_Fini_p) ();
00251 #define Ipl_Fini (*Ipl_Fini_p)
00252
00253 extern void (*ipl_main_p) (INT, char **);
00254 #define ipl_main (*ipl_main_p)
00255
00256 extern void (*Perform_Procedure_Summary_Phase_p) (WN*, DU_MANAGER*,
00257 ALIAS_MANAGER*, void*);
00258 #define Perform_Procedure_Summary_Phase (*Perform_Procedure_Summary_Phase_p)
00259
00260 #else
00261
00262 #pragma weak ipl_main
00263 #pragma weak Ipl_Init
00264 #pragma weak Ipl_Fini
00265 #pragma weak Ipl_Extra_Output
00266 #pragma weak Perform_Procedure_Summary_Phase
00267
00268 #endif // __linux__
00269
00270
00271 #include "w2c_weak.h"
00272 #include "w2f_weak.h"
00273
00274
00275 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00276 void Anl_Process_Command_Line (INT phase_argc, char *phase_argv[],
00277 INT argc, char *argv[]) { }
00278 BOOL Anl_Needs_Whirl2c(void) { return false; }
00279 BOOL Anl_Needs_Whirl2f(void) { return false; }
00280 void Anl_Init(void) { }
00281 WN_MAP Anl_Init_Map(MEM_POOL *id_map_pool) { return NULL; }
00282 void Anl_Static_Analysis(WN *pu, WN_MAP id_map) { }
00283 const char *Anl_File_Path(void) { return NULL; }
00284 void Anl_Fini(void) { }
00285 void Anl_Cleanup(void){ }
00286 void Prp_Process_Command_Line (INT phase_argc, char *phase_argv[],
00287 INT argc, char *argv[]) { }
00288 BOOL Prp_Needs_Whirl2c(void) { return false; }
00289 BOOL Prp_Needs_Whirl2f(void) { return false; }
00290 void Prp_Init(void) { }
00291 void Prp_Instrument_And_EmitSrc(WN *pu) { }
00292 void Prp_Fini(void) { }
00293 void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu,
00294 WN* func_nd) { }
00295
00296 #else
00297
00298 #pragma weak Prp_Process_Command_Line
00299 #pragma weak Prp_Needs_Whirl2c
00300 #pragma weak Prp_Needs_Whirl2f
00301 #pragma weak Prp_Init
00302 #pragma weak Prp_Instrument_And_EmitSrc
00303 #pragma weak Prp_Fini
00304 #pragma weak Anl_Cleanup
00305 #pragma weak Anl_Process_Command_Line
00306 #pragma weak Anl_Needs_Whirl2c
00307 #pragma weak Anl_Needs_Whirl2f
00308 #pragma weak Anl_Init
00309 #pragma weak Anl_Init_Map
00310 #pragma weak Anl_Static_Analysis
00311 #pragma weak Anl_Fini
00312
00313 #endif
00314
00315
00316
00317
00318
00319
00320
00321 #if !defined(__GNUC__) && defined(_SOLARIS_SOLARIS)
00322
00323 #pragma weak "__1cbBPrompf_Emit_Whirl_to_Source6FpnHpu_info_pnCWN__v_"
00324
00325 #elif !defined(__GNUC__)
00326 #pragma weak Prompf_Emit_Whirl_to_Source__GP7pu_infoP2WN
00327
00328 #else
00329 #pragma weak Prompf_Emit_Whirl_to_Source__FP7pu_infoP2WN
00330 #endif
00331
00332 extern void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu, WN* func_nd);
00333
00334
00335 static INT ecount = 0;
00336 static BOOL need_wopt_output = FALSE;
00337 static BOOL need_lno_output = FALSE;
00338 static BOOL need_ipl_output = FALSE;
00339 static Output_File *ir_output = 0;
00340
00341
00342 static OPTIONS_STACK *Options_Stack;
00343
00344 static BOOL reset_opt_level = FALSE;
00345 static struct ALIAS_MANAGER *alias_mgr = NULL;
00346
00347 static BOOL Run_Distr_Array = FALSE;
00348 BOOL Run_MemCtr = FALSE;
00349
00350 static BOOL Saved_run_prompf = FALSE;
00351 static BOOL Saved_run_w2c = FALSE;
00352 static BOOL Saved_run_w2f = FALSE;
00353 static BOOL Saved_run_w2fc_early = FALSE;
00354
00355 extern WN_MAP Prompf_Id_Map;
00356
00357
00358
00359
00360 static BOOL wopt_loaded = FALSE;
00361 extern BOOL Prompf_anl_loaded;
00362 extern BOOL Purple_loaded;
00363 extern BOOL Whirl2f_loaded;
00364 extern BOOL Whirl2c_loaded;
00365
00366 extern void *Current_Dep_Graph;
00367 FILE *DFile = stderr;
00368
00369 static void
00370 load_components (INT argc, char **argv)
00371 {
00372 INT phase_argc;
00373 char **phase_argv;
00374
00375 if (Run_cg || Run_lno || Run_autopar) {
00376
00377 Initialize_Targ_Info();
00378 }
00379
00380 if (!(Run_lno || Run_wopt || Run_preopt || Run_cg ||
00381 Run_prompf || Run_purple || Run_w2c || Run_w2f
00382 || Run_w2fc_early || Run_ipl))
00383 Run_cg = TRUE;
00384
00385 if (Run_ipl) {
00386 Run_lno = Run_wopt = Run_cg = Run_w2fc_early
00387 = Run_prompf = Run_purple = Run_w2c = Run_w2f = FALSE;
00388 }
00389
00390 if (Run_cg) {
00391 Get_Phase_Args (PHASE_CG, &phase_argc, &phase_argv);
00392 load_so ("cg" DSOext, CG_Path, Show_Progress);
00393 CG_Process_Command_Line (phase_argc, phase_argv, argc, argv);
00394 }
00395
00396 if (Run_wopt || Run_preopt || Run_lno || Run_autopar) {
00397 Get_Phase_Args (PHASE_WOPT, &phase_argc, &phase_argv);
00398 load_so ("wopt" DSOext, WOPT_Path, Show_Progress);
00399 wopt_main (phase_argc, phase_argv, argc, argv);
00400 wopt_loaded = TRUE;
00401 }
00402
00403 if (Run_ipl) {
00404 Get_Phase_Args (PHASE_IPL, &phase_argc, &phase_argv);
00405 load_so ("ipl" DSOext, Ipl_Path, Show_Progress);
00406 ipl_main (phase_argc, phase_argv);
00407 Set_Error_Descriptor (EP_BE, EDESC_BE);
00408 }
00409
00410 if (Run_lno || Run_autopar) {
00411 Get_Phase_Args (PHASE_LNO, &phase_argc, &phase_argv);
00412 load_so ("lno" DSOext, LNO_Path, Show_Progress);
00413 lno_main (phase_argc, phase_argv, argc, argv);
00414
00415
00416
00417
00418 if (Run_autopar && LNO_IPA_Enabled) {
00419 load_so("ipl" DSOext, Ipl_Path, Show_Progress);
00420 }
00421 }
00422
00423 if (Run_prompf || Run_w2fc_early) {
00424 Get_Phase_Args (PHASE_PROMPF, &phase_argc, &phase_argv);
00425 load_so("prompf_anl" DSOext, Prompf_Anl_Path, Show_Progress);
00426 Prompf_anl_loaded = TRUE;
00427 Anl_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00428 }
00429
00430 if (Run_purple) {
00431 Get_Phase_Args (PHASE_PURPLE, &phase_argc, &phase_argv);
00432 load_so("purple" DSOext, Purple_Path, Show_Progress);
00433 Purple_loaded = TRUE;
00434 Prp_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00435 }
00436
00437 if (Run_w2c ||
00438 (Run_prompf && Anl_Needs_Whirl2c()) ||
00439 (Run_purple && Prp_Needs_Whirl2c()))
00440 {
00441 Get_Phase_Args (PHASE_W2C, &phase_argc, &phase_argv);
00442 load_so("whirl2c" DSOext, W2C_Path, Show_Progress);
00443 Whirl2c_loaded = TRUE;
00444 if (Run_prompf)
00445 W2C_Set_Prompf_Emission(&Prompf_Id_Map);
00446 W2C_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00447 }
00448
00449 if (Run_w2f ||
00450 (Run_prompf && Anl_Needs_Whirl2f()) ||
00451 (Run_purple && Prp_Needs_Whirl2f()))
00452 {
00453 Get_Phase_Args (PHASE_W2F, &phase_argc, &phase_argv);
00454 load_so("whirl2f" DSOext, W2F_Path, Show_Progress);
00455 Whirl2f_loaded = TRUE;
00456 if (Run_prompf)
00457 W2F_Set_Prompf_Emission(&Prompf_Id_Map);
00458
00459 W2F_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00460 }
00461 }
00462
00463
00464
00465
00466
00467 static void
00468 Phase_Init (void)
00469 {
00470 char *output_file_name = Obj_File_Name;
00471
00472 if (Run_Distr_Array &&
00473 (Run_w2c || Run_w2f) &&
00474 !Run_lno &&
00475 !Run_wopt &&
00476 !Run_cg)
00477 {
00478
00479
00480
00481
00482
00483 Run_Distr_Array = FALSE;
00484 }
00485 if ( LNO_Run_Lego_Set && ( LNO_Run_Lego == FALSE ) )
00486 Run_Distr_Array = FALSE;
00487
00488 if (Run_cg)
00489 CG_Init ();
00490 if (Run_wopt || Run_preopt)
00491 Wopt_Init ();
00492 if (Run_ipl)
00493 Ipl_Init ();
00494 if (Run_lno || Run_Distr_Array || Run_autopar)
00495 Lno_Init ();
00496 if (Run_purple)
00497 Prp_Init();
00498 if (Run_w2c || (Run_prompf && Anl_Needs_Whirl2c()))
00499 W2C_Outfile_Init (TRUE);
00500 if (Run_w2f || (Run_prompf && Anl_Needs_Whirl2f()))
00501 W2F_Outfile_Init ();
00502 if (Run_prompf)
00503 Anl_Init ();
00504
00505 if ((Run_lno || Run_preopt) && !Run_cg && !Run_wopt)
00506 need_lno_output = TRUE;
00507 if (Run_wopt && !Run_cg)
00508 need_wopt_output = TRUE;
00509
00510 if (Run_ipl) {
00511 need_ipl_output = TRUE;
00512 need_lno_output = need_wopt_output = FALSE;
00513 }
00514
00515 if (output_file_name == 0) {
00516 if (Src_File_Name)
00517 output_file_name = Last_Pathname_Component (Src_File_Name);
00518 else
00519 output_file_name = Irb_File_Name;
00520 }
00521
00522 if (need_lno_output) {
00523 Write_BE_Maps = TRUE;
00524 ir_output = Open_Output_Info(New_Extension(output_file_name,".N"));
00525 }
00526 if (need_wopt_output) {
00527 Write_ALIAS_CLASS_Map = TRUE;
00528 Write_BE_Maps = TRUE;
00529 ir_output = Open_Output_Info(New_Extension(output_file_name,".O"));
00530 }
00531 if (need_ipl_output) {
00532 Write_BE_Maps = FALSE;
00533 ir_output = Open_Output_Info (Obj_File_Name ?
00534 Obj_File_Name :
00535 New_Extension(output_file_name, ".o"));
00536 }
00537 if (Emit_Global_Data) {
00538 Write_BE_Maps = FALSE;
00539 ir_output = Open_Output_Info (Global_File_Name);
00540 }
00541
00542 if (Run_wopt) {
00543 if (Language != LANG_KR_C) {
00544 Pad_Global_Arrays();
00545 }
00546 }
00547 if ((Run_cg || Run_wopt) && !Read_Global_Data)
00548 Allocate_File_Statics();
00549
00550 }
00551
00552
00553 static void
00554 Phase_Fini (void)
00555 {
00556 CURRENT_SYMTAB = GLOBAL_SYMTAB;
00557
00558
00559 if (Run_prompf)
00560 Anl_Fini();
00561 if (Run_purple)
00562 Prp_Fini();
00563 if (Run_w2c || (Run_prompf && Anl_Needs_Whirl2c()))
00564 W2C_Outfile_Fini (TRUE);
00565 if (Run_w2f || (Run_prompf && Anl_Needs_Whirl2f()))
00566 W2F_Outfile_Fini ();
00567
00568 if (Run_Dsm_Cloner || Run_Dsm_Common_Check)
00569 DRA_Finalize ();
00570
00571 if (Run_lno || Run_Distr_Array || Run_autopar)
00572 Lno_Fini ();
00573 if (Run_ipl)
00574 Ipl_Fini ();
00575 if (Run_wopt || Run_preopt)
00576 Wopt_Fini ();
00577 if (Run_cg)
00578 CG_Fini ();
00579
00580 Verify_SYMTAB (CURRENT_SYMTAB);
00581 }
00582
00583 char *
00584 Get_Orig_PU_Name (PU_Info * current_pu)
00585 {
00586 DST_IDX dst;
00587 DST_INFO *info;
00588 DST_SUBPROGRAM *PU_attr;
00589
00590 dst = PU_Info_pu_dst(current_pu);
00591
00592 if (DST_IS_NULL (dst)) {
00593 return ST_name(PU_Info_proc_sym(current_pu));
00594 }
00595
00596 info = DST_INFO_IDX_TO_PTR (dst);
00597
00598 if ( (DST_INFO_tag(info) != DW_TAG_subprogram)
00599 || DST_IS_declaration(DST_INFO_flag(info)) )
00600 {
00601 return ST_name(PU_Info_proc_sym(current_pu));
00602 }
00603 PU_attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
00604 if (PU_attr->def.name.byte_idx < 0) {
00605 return NULL;
00606
00607
00608
00609 }
00610 return DST_STR_IDX_TO_PTR(DST_SUBPROGRAM_def_name(PU_attr));
00611 }
00612
00613 static void
00614 Save_Cur_PU_Name (char *name, INT rid_id)
00615 {
00616 if ( Cur_PU_Name == NULL ) {
00617
00618
00619
00620
00621
00622
00623
00624 Cur_PU_Name = TYPE_MEM_POOL_ALLOC_N(char, &MEM_pu_nz_pool,
00625 strlen(name) + 8);
00626 Cur_PU_Name = strcpy(Cur_PU_Name, name);
00627 }
00628 if (rid_id != 0) {
00629
00630 sprintf(Cur_PU_Name,"%s.RGN%03d", name, rid_id);
00631 }
00632 else if (strlen(name) != strlen(Cur_PU_Name)) {
00633
00634 Cur_PU_Name = strcpy(Cur_PU_Name, name);
00635 }
00636 }
00637
00638
00639
00640
00641
00642
00643 static WN *
00644 Adjust_Opt_Level (PU_Info* current_pu, WN *pu, char *pu_name)
00645 {
00646 INT new_opt_level = 0;
00647 COMPUTE_PU_OLIMIT;
00648
00649 if (Get_Trace(TKIND_INFO, TINFO_STATS)) {
00650
00651 INT PU_Var_Cnt = ST_Table_Size (CURRENT_SYMTAB) +
00652 PREG_Table_Size (CURRENT_SYMTAB);
00653 fprintf (TFile, "PU_Olimit for %s is %d (bbs=%d,stms=%d,vars=%d)\n",
00654 pu_name, PU_Olimit, PU_WN_BB_Cnt, PU_WN_Stmt_Cnt, PU_Var_Cnt);
00655 }
00656
00657 if ((Opt_Level > 0 || Run_autopar) && PU_Olimit > Olimit && !Olimit_opt) {
00658 if (Show_OPT_Warnings)
00659 ErrMsg (EC_Olimit_Exceeded, pu_name, PU_Olimit);
00660 reset_opt_level = TRUE;
00661 }
00662 if (((Opt_Level > 0 || Run_autopar) || Olimit_opt)
00663 && Query_Skiplist ( Optimization_Skip_List, Current_PU_Count() ) )
00664 {
00665 if (Show_OPT_Warnings)
00666 ErrMsg (EC_Not_Optimized, pu_name, Current_PU_Count() );
00667 reset_opt_level = TRUE;
00668 }
00669 if (
00670
00671
00672 PU_calls_setjmp (Get_Current_PU ())) {
00673 reset_opt_level = TRUE;
00674 new_opt_level = 1;
00675 ErrMsg (EC_Not_Ansi_Setjmp, pu_name, Current_PU_Count(), new_opt_level );
00676 }
00677 if (reset_opt_level) {
00678 Opt_Level = new_opt_level;
00679 Run_lno = Run_preopt = Run_wopt = Run_autopar = FALSE;
00680 alias_mgr = NULL;
00681 Olimit_opt = FALSE;
00682 if (Run_prompf)
00683 Prompf_Emit_Whirl_to_Source(current_pu, pu);
00684 }
00685
00686 if ((PU_Olimit > Olimit) && Olimit_opt) {
00687
00688 pu = Olimit_Region_Insertion (pu, Olimit);
00689
00690
00691
00692
00693
00694
00695 if (Run_lno || Run_Distr_Array || Run_preopt || Run_autopar) {
00696 LNO_Outer_Unroll = 1;
00697 LNO_Fusion = 0;
00698 if (Show_OPT_Warnings)
00699 ErrMsg(EC_LNO_Backoff, pu_name, LNO_Outer_Unroll, LNO_Fusion);
00700 }
00701 }
00702
00703 return pu;
00704 }
00705
00706 static void
00707 Ipl_Processing (PU_Info *current_pu, WN *pu)
00708 {
00709 struct DU_MANAGER *du_mgr = NULL;
00710 struct ALIAS_MANAGER *al_mgr = NULL;
00711
00712 MEM_POOL_Push (&MEM_local_pool);
00713
00714 PU_adjust_addr_flags(Get_Current_PU_ST(), pu);
00715
00716 if (Run_preopt) {
00717 du_mgr = Create_Du_Manager(MEM_pu_nz_pool_ptr);
00718 al_mgr = Create_Alias_Manager(MEM_pu_nz_pool_ptr);
00719 pu = Pre_Optimizer(PREOPT_IPA0_PHASE, pu, du_mgr, al_mgr);
00720 #ifdef Is_True_On
00721 if (Get_Trace (TKIND_ALLOC, TP_IPA)) {
00722 fprintf (TFile, "\n%s%s\tMemory allocation information after"
00723 " IPA local pre_opt\n%s%s\n", DBar, DBar, DBar, DBar);
00724 MEM_Trace ();
00725 }
00726 #endif
00727 Delete_Alias_Manager (al_mgr, MEM_pu_nz_pool_ptr);
00728 Delete_Du_Manager (du_mgr, MEM_pu_nz_pool_ptr);
00729 } else {
00730 Set_Error_Phase ( "IPA Summary" );
00731 Perform_Procedure_Summary_Phase (pu, du_mgr, al_mgr, 0);
00732 }
00733
00734
00735 Set_PU_Info_tree_ptr(current_pu, pu);
00736
00737 Write_PU_Info (current_pu);
00738
00739 MEM_POOL_Pop (&MEM_local_pool);
00740
00741 }
00742
00743
00744
00745
00746 static WN *
00747 LNO_Processing (PU_Info *current_pu, WN *pu)
00748 {
00749 REGION_CS_ITER rgn_iter;
00750
00751 REGION_CS_ITER_init(&rgn_iter, pu);
00752
00753
00754
00755 for (REGION_CS_NoEarlierSub_First(&rgn_iter, pu, RID_TYPE_func_entry);
00756 REGION_CS_NoEarlierSub_While(&rgn_iter);
00757 REGION_CS_NoEarlierSub_Next(&rgn_iter)) {
00758
00759 WN *rwn;
00760
00761 rwn = REGION_remove_and_mark(pu, &rgn_iter);
00762 Is_True(rwn != NULL,
00763 ("BE driver, IR inconsistency, LNO loop"));
00764 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00765 fprintf(TFile,"===== BE driver, LNO loop: %s %d, stacked=%d\n",
00766 REGION_CS_ITER_is_pu(&rgn_iter) ? "PU" : "RGN",
00767 RID_id(REGION_get_rid(rwn)),
00768 !REGION_CS_ITER_is_not_stacked(&rgn_iter));
00769 RID_WN_Tree_Print(TFile, rwn);
00770 }
00771
00772
00773
00774
00775 BOOL is_mp = PU_mp (Get_Current_PU ());
00776 BOOL needs_lno = PU_mp_needs_lno (Get_Current_PU ());
00777
00778 if (!is_mp || Early_MP_Processing) {
00779 if (Run_lno || Run_autopar || (Run_Distr_Array && needs_lno)) {
00780
00781 if (Early_MP_Processing && is_mp) {
00782 Free_Dep_Graph();
00783 Current_Dep_Graph = PU_Info_depgraph_ptr(Current_PU_Info);
00784 }
00785 rwn = Perform_Loop_Nest_Optimization(current_pu, pu, rwn,
00786 TRUE );
00787 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
00788 if (Current_Dep_Graph) {
00789 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
00790 } else {
00791 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_Missing);
00792 }
00793
00794 Check_for_IR_Dump(TP_LNOPT, rwn, "LNO");
00795 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00796 fprintf(TFile,"===== After LNO, %s %d, stacked=%d\n",
00797 REGION_CS_ITER_is_pu(&rgn_iter) ? "PU" : "RGN",
00798 RID_id(REGION_get_rid(rwn)),
00799 !REGION_CS_ITER_is_not_stacked(&rgn_iter));
00800 RID_WN_Tree_Print(TFile, rwn);
00801 fdump_tree(TFile, rwn);
00802 RID_set_print(TFile,REGION_get_rid(rwn));
00803 }
00804 } else if (Run_preopt) {
00805 rwn = Perform_Preopt_Optimization(pu, rwn);
00806 Check_for_IR_Dump(TP_GLOBOPT, rwn, "PREOPT");
00807 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00808 fprintf(TFile,"===== After PREOPT (:p), %s %d, stacked=%d\n",
00809 REGION_CS_ITER_is_pu(&rgn_iter) ? "PU" : "RGN",
00810 RID_id(REGION_get_rid(rwn)),
00811 !REGION_CS_ITER_is_not_stacked(&rgn_iter));
00812 RID_WN_Tree_Print(TFile, rwn);
00813 fdump_tree(TFile, rwn);
00814 RID_set_print(TFile,REGION_get_rid(rwn));
00815 }
00816 }
00817 } else {
00818 Free_Dep_Graph();
00819 Current_Dep_Graph = PU_Info_depgraph_ptr(Current_PU_Info);
00820 }
00821
00822 if (REGION_CS_ITER_is_not_stacked(&rgn_iter))
00823 pu = rwn;
00824 REGION_replace_from_mark(rwn, &rgn_iter);
00825
00826 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00827 fprintf(TFile,"------------ bottom of LNO loop: -----------\n");
00828 REGION_consistency_check(pu);
00829 RID_WN_Tree_Print(TFile,pu);
00830 if (Run_cg)
00831 fdump_region_tree(TFile,pu);
00832 else
00833 fdump_tree(TFile,pu);
00834 fprintf(TFile,"--------------------------------------------\n");
00835 }
00836 }
00837
00838 return pu;
00839 }
00840
00841
00842
00843
00844 static void
00845 Post_LNO_Processing (PU_Info *current_pu, WN *pu)
00846 {
00847 BOOL is_user_visible_pu = (CURRENT_SYMTAB == GLOBAL_SYMTAB + 1) ||
00848 ((Language == LANG_F90) &&
00849 (CURRENT_SYMTAB == GLOBAL_SYMTAB + 2) &&
00850 (!Is_Set_PU_Info_flags(current_pu, PU_IS_COMPILER_GENERATED))) ;
00851
00852
00853
00854 if (Run_w2c && !Run_w2fc_early && !Run_prompf) {
00855 if (W2C_Should_Emit_Nested_PUs() || is_user_visible_pu) {
00856 if (Cur_PU_Feedback)
00857 W2C_Set_Frequency_Map(WN_MAP_FEEDBACK);
00858 W2C_Outfile_Translate_Pu(pu, TRUE);
00859 }
00860 }
00861 if (Run_w2f && !Run_w2fc_early && !Run_prompf) {
00862 if (W2F_Should_Emit_Nested_PUs() || is_user_visible_pu) {
00863 if (Cur_PU_Feedback)
00864 W2F_Set_Frequency_Map(WN_MAP_FEEDBACK);
00865 W2F_Outfile_Translate_Pu(pu);
00866 }
00867 }
00868
00869
00870
00871 if (need_lno_output) {
00872 Set_PU_Info_tree_ptr(current_pu, pu);
00873 Write_PU_Info(current_pu);
00874 Verify_SYMTAB (CURRENT_SYMTAB);
00875 }
00876
00877 }
00878
00879 static WN *
00880 WOPT_Processing (PU_Info *current_pu, WN *pu, REGION_CS_ITER *rgn_iter,
00881 WN *rwn)
00882 {
00883 rwn = Perform_Global_Optimization (pu, rwn, alias_mgr);
00884 Check_for_IR_Dump(TP_GLOBOPT, rwn, "WOPT");
00885 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00886 fprintf(TFile, "===== driver, after Perform_Global_Optimization");
00887 fprintf(TFile," RGN %d =====\n", RID_id(REGION_get_rid(rwn)));
00888 RID_WN_Tree_Print(TFile,pu);
00889 fdump_tree(TFile,rwn);
00890 fprintf(TFile,"===== driver ---------------------\n");
00891 fprintf(TFile,"#### Verify_alias, after mainopt, RGN %d\n",
00892 RID_id(REGION_get_rid(rwn)));
00893 Verify_alias(alias_mgr, rwn);
00894 if (Run_cg)
00895 fdump_region_tree(TFile,rwn);
00896 fprintf(TFile,"#### Verify_alias, done\n");
00897 }
00898
00899 return rwn;
00900 }
00901
00902
00903 static WN *
00904 Do_WOPT_and_CG_with_Regions (PU_Info *current_pu, WN *pu)
00905 {
00906 REGION_CS_ITER rgn_iter;
00907 BOOL Run_region_bounds;
00908 BOOL cg_one_time = TRUE;
00909
00910
00911 Initialize_Stack_Frame (pu);
00912
00913
00914 { RID *rid = REGION_get_rid(pu);
00915 Is_True(rid != NULL && RID_TYPE_func_entry(rid) && RID_id(rid) == 0,
00916 ("Do_WOPT_and_CG_with_Regions, RID is incorrect"));
00917 Run_region_bounds = RID_contains_bounds(rid);
00918 Is_Trace(Get_Trace(TP_REGION, TT_REGION_CG_DEBUG) ||
00919 Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG),
00920 (TFile,"Driver, RID_contains_bounds(%s) = %c\n",
00921 ST_name(PU_Info_proc_sym(current_pu)),
00922 Run_region_bounds ? 'T' : 'F'));
00923 }
00924
00925
00926
00927
00928
00929 if ((Run_wopt || Run_region_bounds) && alias_mgr == 0)
00930 alias_mgr = Create_Alias_Manager(MEM_pu_nz_pool_ptr);
00931
00932
00933 if (Run_region_bounds) {
00934 Set_Error_Phase("Generate Region Boundaries");
00935 Generate_region_boundaries(pu, alias_mgr);
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 REGION_CS_ITER_init(&rgn_iter, pu);
00948 for (REGION_CS_NoEarlierSub_First(&rgn_iter, pu,
00949 (RID_TYPE)(RID_TYPE_olimit | RID_TYPE_pragma | RID_TYPE_loop));
00950 REGION_CS_NoEarlierSub_While(&rgn_iter);
00951 REGION_CS_NoEarlierSub_Next(&rgn_iter)) {
00952 WN *rwn;
00953 BOOL need_options_pop;
00954
00955 rwn = REGION_remove_and_mark(pu, &rgn_iter);
00956
00957 Is_True(rwn != NULL, ("BE driver, IR inconsistency, WOPT-CG loop"));
00958 Is_True(REGION_get_rid(rwn) != NULL, ("BE driver, NULL RID"));
00959 Is_True(RID_type(REGION_get_rid(rwn)) != RID_TYPE_undefined,
00960 ("BE driver, undefined RID type"));
00961
00962 Set_Current_Region_For_Trace( RID_id(REGION_get_rid(rwn)) );
00963
00964 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00965 fprintf(TFile,"===== BE driver, WOPT-CG loop: %s %d, stacked=%d\n",
00966 REGION_CS_ITER_is_pu(&rgn_iter) ? "PU" : "RGN",
00967 RID_id(REGION_get_rid(rwn)),
00968 !REGION_CS_ITER_is_not_stacked(&rgn_iter));
00969 RID_WN_Tree_Print(TFile, rwn);
00970 }
00971
00972
00973 { RID *rid = REGION_get_rid(rwn);
00974 Is_True(rid != NULL, ("BE driver, NULL rid inside region loop"));
00975 if (RID_options(rid) != NULL) {
00976 Options_Stack->Process_Pragma_Options(RID_options(rid));
00977 need_options_pop = TRUE;
00978 } else
00979 need_options_pop = FALSE;
00980 }
00981
00982 if (Show_Progress) {
00983 if (rwn != pu)
00984 fprintf(stderr, "... compiling region (%d)\n",
00985 RID_id(REGION_get_rid(rwn)));
00986 else if (!cg_one_time)
00987 fprintf(stderr, "... compiling program unit\n");
00988 }
00989
00990 Save_Cur_PU_Name (ST_name(PU_Info_proc_sym(current_pu)),
00991 RID_id(REGION_get_rid(rwn)));
00992
00993
00994 if (Instrumentation_Enabled
00995 && Instrumentation_Phase_Num == PROFILE_PHASE_BEFORE_WOPT) {
00996 WN_Instrument(rwn, PROFILE_PHASE_BEFORE_WOPT);
00997 } else if (Feedback_Enabled[PROFILE_PHASE_BEFORE_WOPT]) {
00998 WN_Annotate(rwn, PROFILE_PHASE_BEFORE_WOPT, &MEM_pu_pool);
00999 }
01000 Set_Error_Phase ( "Before WOPT" );
01001
01002 if (Run_wopt) {
01003 rwn = WOPT_Processing (current_pu, pu, &rgn_iter, rwn);
01004 if (WN_opcode(rwn) == OPC_FUNC_ENTRY)
01005 Verify_SYMTAB (CURRENT_SYMTAB);
01006 if ( Cur_PU_Feedback ) {
01007 Cur_PU_Feedback->Verify("after WOPT");
01008 }
01009 #if 0 // this is now unnecessary because the lowering is done inside wopt
01010 if (Only_Unsigned_64_Bit_Ops && Delay_U64_Lowering)
01011 U64_lower_wn(rwn, FALSE);
01012 #endif
01013 }
01014
01015
01016
01017
01018
01019 if (need_wopt_output && REGION_CS_ITER_is_not_stacked(&rgn_iter)) {
01020 Set_PU_Info_tree_ptr(current_pu, rwn);
01021 Write_PU_Info(current_pu);
01022 }
01023
01024
01025
01026 Save_Cur_PU_Name (ST_name(PU_Info_proc_sym(current_pu)),
01027 RID_id(REGION_get_rid(rwn)));
01028
01029
01030 if (Instrumentation_Enabled
01031 && Instrumentation_Phase_Num == PROFILE_PHASE_BEFORE_CG) {
01032 rwn = WN_Lower(rwn, LOWER_SCF, NULL,
01033 "Lower structured control flow");
01034 WN_Instrument(rwn, PROFILE_PHASE_BEFORE_CG);
01035 #if 0
01036 extern void wb_gwe(WN*);
01037 wb_gwe(rwn);
01038 #endif
01039 } else if (Feedback_Enabled[PROFILE_PHASE_BEFORE_CG]) {
01040 rwn = WN_Lower(rwn, LOWER_SCF, NULL,
01041 "Lower structured control flow");
01042 WN_Annotate(rwn, PROFILE_PHASE_BEFORE_CG, &MEM_pu_pool);
01043 }
01044 Set_Error_Phase ( "Before CG" );
01045
01046 if (Run_cg) {
01047 Set_Error_Phase ("Lowering");
01048 WB_LWR_Initialize(rwn, alias_mgr);
01049 rwn = WN_Lower(rwn, LOWER_TO_CG, alias_mgr, "Lowering to CG");
01050 if (Only_Unsigned_64_Bit_Ops && ! Run_wopt)
01051 U64_lower_wn(rwn, FALSE);
01052 WB_LWR_Terminate();
01053 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01054 fprintf(TFile,"===== driver, after lowering\n");
01055 RID_WN_Tree_Print(TFile,rwn);
01056 }
01057
01058 if ( Cur_PU_Feedback ) {
01059 Cur_PU_Feedback->Verify("after LOWER_TO_CG");
01060 }
01061
01062 if (cg_one_time) {
01063 cg_one_time = FALSE;
01064
01065 Set_Error_Phase("Data Layout");
01066
01067 Calculate_Stack_Frame_Sizes (rwn);
01068 CG_PU_Initialize(pu);
01069 }
01070
01071 if (!REGION_CS_ITER_is_not_stacked(&rgn_iter) ||
01072 !REGION_CS_ITER_is_pu(&rgn_iter)) {
01073 DST_IDX tmp_idx;
01074 WN *compiled_block;
01075 tmp_idx.byte_idx = DST_INVALID_BYTE_IDX;
01076 FmtAssert(PU_has_region (Get_Current_PU ()),
01077 ("BE driver, found region when SYMTAB_has_rgn is off"));
01078 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01079 fprintf(TFile,
01080 "===== driver, before CG_Generate_Code (region)\n");
01081 RID_WN_Tree_Print(TFile,rwn);
01082 RID_set_print(TFile,REGION_get_rid(rwn));
01083 }
01084 compiled_block = CG_Generate_Code(rwn, alias_mgr, tmp_idx, TRUE);
01085 rwn = compiled_block;
01086 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01087 fprintf(TFile,
01088 "===== driver, after CG_Generate_Code\n");
01089 RID_WN_Tree_Print(TFile,rwn);
01090 }
01091 }
01092 }
01093
01094 if (REGION_CS_ITER_is_not_stacked(&rgn_iter))
01095 pu = rwn;
01096 REGION_replace_from_mark(rwn, &rgn_iter);
01097
01098 if (need_options_pop)
01099 Options_Stack->Pop_Current_Options();
01100 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01101 fprintf(TFile,
01102 "------------ bottom of WOPT-CG loop: ------------\n");
01103 Is_True(REGION_consistency_check(pu),(""));
01104 RID_WN_Tree_Print(TFile,pu);
01105 if (Run_cg)
01106 fdump_region_tree(TFile,pu);
01107 else
01108 fdump_tree(TFile,pu);
01109 fprintf(TFile,"--------------------------------------------\n");
01110 }
01111 if (rwn != pu)
01112 Report_CG_Region_Timing ( Tim_File, Cur_PU_Name );
01113 }
01114 Verify_SYMTAB (CURRENT_SYMTAB);
01115 return pu;
01116 }
01117
01118
01119 static void
01120 Post_Process_Backend (PU_Info *current_pu, WN *pu)
01121 {
01122 if (Run_cg) {
01123 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01124 fprintf(TFile,"BE driver, Post_Process_Backend "
01125 "+++++++++++++++++++++++++++++++\n");
01126 RID_WN_Tree_Print(TFile,pu);
01127 fdump_region_tree(TFile,pu);
01128 fprintf(TFile,"BE driver, Post_Process_Backend "
01129 "+++++++++++++++++++++++++++++++\n");
01130 fprintf(TFile,"Right before CG_Generate_Code (PU)\n");
01131 }
01132
01133 CG_Generate_Code(pu, alias_mgr, PU_Info_pu_dst(current_pu), FALSE);
01134 CG_PU_Finalize();
01135 }
01136
01137 if (alias_mgr) {
01138 Delete_Alias_Manager(alias_mgr, MEM_pu_nz_pool_ptr);
01139 alias_mgr = NULL;
01140 }
01141 }
01142
01143
01144
01145 extern "C" {
01146 extern void Process_Fill_Align_Pragmas (WN* func_wn);
01147 extern void Rewrite_Pragmas_On_Structs (WN* block_wn, WN* wn);
01148 }
01149
01150
01151
01152
01153
01154
01155 static void Update_EHRegion_Inito_Used (WN *wn) {
01156 if (!wn) return;
01157
01158 OPERATOR opr = WN_operator(wn);
01159
01160 if (opr == OPR_REGION && WN_ereg_supp(wn)) {
01161 INITO_IDX ino_idx = WN_ereg_supp(wn);
01162 ST *st = INITO_st(ino_idx);
01163 Clear_ST_is_not_used(st);
01164 }
01165
01166
01167 if (opr == OPR_BLOCK) {
01168 WN *kid = WN_first (wn);
01169 while (kid) {
01170 Update_EHRegion_Inito_Used(kid);
01171 kid = WN_next(kid);
01172 }
01173 } else {
01174 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
01175 Update_EHRegion_Inito_Used(WN_kid(wn,kidno));
01176 }
01177 }
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 static void Update_EHRegion_Inito (WN *pu) {
01189 INT i;
01190 INITO *ino;
01191
01192
01193 FOREACH_INITO (CURRENT_SYMTAB, ino, i) {
01194 ST *st = INITO_st(ino);
01195 if (ST_sclass(st) == SCLASS_EH_REGION ||
01196 ST_sclass(st) == SCLASS_EH_REGION_SUPP) {
01197 Set_ST_is_not_used(st);
01198 }
01199 }
01200
01201
01202
01203 Update_EHRegion_Inito_Used (pu);
01204 }
01205
01206 static void
01207 Backend_Processing (PU_Info *current_pu, WN *pu)
01208 {
01209 {
01210
01211
01212
01213
01214 static BOOL done_first_pu = FALSE;
01215 BOOL needs_fill_align_lowering =
01216 PU_needs_fill_align_lowering (Get_Current_PU ());
01217 if (needs_fill_align_lowering || !done_first_pu) {
01218 Process_Fill_Align_Pragmas (pu);
01219 done_first_pu = TRUE;
01220 }
01221 }
01222
01223 PU_adjust_addr_flags(Get_Current_PU_ST(), pu);
01224
01225 if (Run_MemCtr)
01226 MemCtr_Add (pu);
01227
01228
01229
01230
01231
01232 if (WHIRL_Return_Val_On || WHIRL_Mldid_Mstid_On) {
01233 Is_True(WHIRL_Return_Val_On && WHIRL_Mldid_Mstid_On,
01234 ("-INTERNAL:return_val and -INTERNAL:mldid_mstid must be on the same time"));
01235 pu = WN_Lower (pu, LOWER_RETURN_VAL | LOWER_MLDID_MSTID, NULL,
01236 "RETURN_VAL & MLDID/MSTID lowering");
01237 }
01238
01239
01240
01241 BOOL has_mp = PU_has_mp (Get_Current_PU ());
01242 if (has_mp && Early_MP_Processing) {
01243 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
01244 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
01245
01246 Set_Error_Phase ( "MP Lowering" );
01247 WB_LWR_Initialize(pu, NULL);
01248 pu = WN_Lower (pu, LOWER_MP, NULL, "Before MP Lowering");
01249 WB_LWR_Terminate();
01250 }
01251
01252
01253 if( Instrumentation_Enabled
01254 && Instrumentation_Phase_Num == PROFILE_PHASE_BEFORE_LNO ) {
01255 WN_Instrument(pu, PROFILE_PHASE_BEFORE_LNO);
01256 } else if ( Feedback_Enabled[PROFILE_PHASE_BEFORE_LNO] ) {
01257 WN_Annotate(pu, PROFILE_PHASE_BEFORE_LNO, &MEM_pu_pool);
01258 }
01259 Set_Error_Phase ( "LNO Processing" );
01260
01261 if (Run_lno || Run_Distr_Array || Run_preopt || Run_autopar) {
01262 pu = LNO_Processing (current_pu, pu);
01263 if (Run_autopar)
01264 Rewrite_Pragmas_On_Structs (NULL, WN_func_body(pu));
01265 }
01266
01267
01268 Set_Error_Phase ( "Post LNO Processing" );
01269 Post_LNO_Processing (current_pu, pu);
01270 if (!Run_wopt && !Run_cg) return;
01271
01272 Verify_SYMTAB (CURRENT_SYMTAB);
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 has_mp = PU_has_mp (Get_Current_PU ());
01285 if (has_mp && !Early_MP_Processing) {
01286 Set_Error_Phase ( "MP Lowering" );
01287 WB_LWR_Initialize(pu, NULL);
01288 pu = WN_Lower (pu, LOWER_MP, NULL, "Before MP Lowering");
01289 WB_LWR_Terminate();
01290 }
01291
01292 Update_EHRegion_Inito (pu);
01293
01294
01295
01296
01297 if (Run_cg)
01298 EH_Generate_Range_List(pu);
01299
01300 BOOL save_run_wopt = Run_wopt;
01301
01302
01303
01304 if (Run_wopt &&
01305 (WN_operator(pu) == OPR_FUNC_ENTRY) &&
01306 ST_asm_function_st(*WN_st(pu))) {
01307
01308
01309 Run_wopt = FALSE;
01310 }
01311
01312 Set_Error_Phase ( "WOPT/CG Processing" );
01313 pu = Do_WOPT_and_CG_with_Regions (current_pu, pu);
01314
01315 Run_wopt = save_run_wopt;
01316
01317 Set_Error_Phase ( "Post Backend Processing" );
01318 Post_Process_Backend (current_pu, pu);
01319
01320 }
01321
01322 static WN *
01323 Preprocess_PU (PU_Info *current_pu)
01324 {
01325 WN *pu = NULL;
01326
01327 Initialize_PU_Stats ();
01328
01329 Current_PU_Info = current_pu;
01330 MEM_POOL_Push(MEM_pu_nz_pool_ptr);
01331 MEM_POOL_Push(MEM_pu_pool_ptr);
01332
01333 Cur_PU_Feedback = NULL;
01334
01335 BOOL is_mp_nested_pu = FALSE;
01336
01337
01338 Start_Timer ( T_ReadIR_CU );
01339
01340
01341 if (PU_Info_state (current_pu, WT_TREE) != Subsect_InMem) {
01342 Read_Local_Info (MEM_pu_nz_pool_ptr, current_pu);
01343 if (PU_Info_state (current_pu, WT_FEEDBACK) == Subsect_InMem) {
01344 const Pu_Hdr* pu_hdr = (const Pu_Hdr*)
01345 PU_Info_feedback_ptr (current_pu);
01346 Cur_PU_Feedback = CXX_NEW (FEEDBACK (PU_Info_tree_ptr (current_pu),
01347 MEM_pu_nz_pool_ptr,
01348 pu_hdr->pu_num_inv_entries,
01349 pu_hdr->pu_num_br_entries,
01350 pu_hdr->pu_num_loop_entries,
01351 pu_hdr->pu_num_scircuit_entries,
01352 pu_hdr->pu_num_call_entries,
01353 pu_hdr->pu_num_switch_entries),
01354 MEM_pu_nz_pool_ptr);
01355 Read_Feedback_Info (Cur_PU_Feedback, PU_Info_tree_ptr (current_pu),
01356 *pu_hdr);
01357
01358 Instrumentation_Enabled = FALSE;
01359 memset (Feedback_Enabled, '\0', PROFILE_PHASE_LAST * sizeof(BOOL));
01360 } else
01361 Cur_PU_Feedback = NULL;
01362 } else {
01363
01364 Current_Map_Tab = PU_Info_maptab(current_pu);
01365 Current_pu = &PU_Info_pu(current_pu);
01366 CURRENT_SYMTAB = PU_lexical_level(*Current_pu);
01367 if ((PU_is_nested_func(*Current_pu) && PU_mp(*Current_pu)) ||
01368 Is_Set_PU_Info_flags(current_pu, PU_IS_DRA_CLONE)) {
01369 is_mp_nested_pu = TRUE;
01370
01371 Restore_Local_Symtab(current_pu);
01372
01373 if (PU_Info_state (current_pu, WT_FEEDBACK) == Subsect_InMem) {
01374
01375 Cur_PU_Feedback = (FEEDBACK *) PU_Info_feedback_ptr (current_pu);
01376 Is_True(Cur_PU_Feedback, ("invalid PU_Info for feedback"));
01377
01378 Instrumentation_Enabled = FALSE;
01379 memset(Feedback_Enabled, '\0', PROFILE_PHASE_LAST * sizeof(BOOL));
01380 } else
01381 Cur_PU_Feedback = NULL;
01382 } else {
01383 Is_True(FALSE, ("Robert doesn't understand where symtabs come from"));
01384 }
01385 }
01386
01387 BE_symtab_alloc_scope_level(CURRENT_SYMTAB);
01388 Scope_tab[CURRENT_SYMTAB].st_tab->Register(*Be_scope_tab[CURRENT_SYMTAB].be_st_tab);
01389
01390
01391
01392
01393 pu = PU_Info_tree_ptr(current_pu);
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404 if (!Saved_run_prompf &&
01405 Run_prompf &&
01406 Is_Set_PU_Info_flags(current_pu, PU_IS_COMPILER_GENERATED) &&
01407 !PU_mp (Get_Current_PU ())) {
01408 Saved_run_prompf = Run_prompf;
01409 Saved_run_w2c = Run_w2c;
01410 Saved_run_w2f = Run_w2f;
01411 Saved_run_w2fc_early = Run_w2fc_early;
01412 Run_prompf = FALSE;
01413 Run_w2c = FALSE;
01414 Run_w2f = FALSE;
01415 Run_w2fc_early = FALSE;
01416 }
01417
01418
01419 Orig_PU_Name = Get_Orig_PU_Name(current_pu);
01420 Save_Cur_PU_Name(ST_name(PU_Info_proc_sym(current_pu)), 0);
01421
01422 Set_Current_PU_For_Trace(ST_name(PU_Info_proc_sym(current_pu)),
01423 Current_PU_Count());
01424
01425 Stop_Timer (T_ReadIR_CU);
01426 Check_for_IR_Dump(TP_IR_READ,pu,"IR_READ");
01427
01428 if (Show_Progress) {
01429 fprintf(stderr, "Compiling %s(%d)\n",
01430 ST_name(PU_Info_proc_sym(current_pu)),
01431 Current_PU_Count());
01432 }
01433
01434 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
01435 fprintf(TFile,"===== BE driver, PU loop: PU %s(%d)\n",
01436 ST_name(PU_Info_proc_sym(current_pu)),Current_PU_Count());
01437 }
01438
01439 if (Tlog_File) {
01440 fprintf(Tlog_File,"BEGIN %s\n",ST_name(PU_Info_proc_sym(current_pu)));
01441 }
01442
01443 WN_Mem_Push ();
01444
01445 if (Run_wopt || Run_cg) {
01446 Lowering_Initialize();
01447 }
01448
01449 if (Run_prompf &&
01450 !Is_Set_PU_Info_flags(current_pu, PU_IS_COMPILER_GENERATED)) {
01451 Prompf_Id_Map = Anl_Init_Map(MEM_pu_pool_ptr);
01452 WB_ANL_Initialize(pu, Prompf_Id_Map);
01453 Anl_Static_Analysis(pu, Prompf_Id_Map);
01454 WB_ANL_Terminate();
01455 }
01456
01457 if (Run_purple) {
01458 Prp_Instrument_And_EmitSrc(pu);
01459 }
01460
01461
01462 if ( Instrumentation_Enabled
01463 && Instrumentation_Phase_Num == PROFILE_PHASE_BEFORE_VHO ) {
01464 if (!is_mp_nested_pu )
01465 WN_Instrument(pu, PROFILE_PHASE_BEFORE_VHO);
01466 #if 0
01467 extern void wb_gwe(WN*);
01468 wb_gwe(pu);
01469 #endif
01470 } else if ( Feedback_Enabled[PROFILE_PHASE_BEFORE_VHO] ) {
01471 WN_Annotate(pu, PROFILE_PHASE_BEFORE_VHO, &MEM_pu_pool);
01472 }
01473
01474 pu = VHO_Lower_Driver (current_pu, pu);
01475
01476 if ( Cur_PU_Feedback ) {
01477 Cur_PU_Feedback->Verify("after VHO lower");
01478 }
01479
01480 pu = Adjust_Opt_Level (current_pu, pu, ST_name(PU_Info_proc_sym(current_pu)));
01481
01482 if (wopt_loaded) {
01483 Create_Restricted_Map(MEM_pu_nz_pool_ptr);
01484 }
01485
01486
01487
01488
01489
01490
01491 REGION_Initialize (pu, PU_has_region (Get_Current_PU ()));
01492 return pu;
01493 }
01494
01495 static void
01496 Postprocess_PU (PU_Info *current_pu)
01497 {
01498 if (Tlog_File) {
01499 fprintf (Tlog_File, "END %s\n", ST_name(PU_Info_proc_sym(current_pu)));
01500 }
01501
01502 Current_Map_Tab = PU_Info_maptab(current_pu);
01503
01504 REGION_Finalize();
01505
01506 if (Run_wopt || Run_cg) {
01507
01508 Lowering_Finalize();
01509 }
01510
01511
01512 WN_Mem_Pop ();
01513
01514 if (wopt_loaded) {
01515 Delete_Restricted_Map();
01516 }
01517
01518 SYMTAB_IDX scope_level = PU_lexical_level(PU_Info_pu(current_pu));
01519
01520 Scope_tab[scope_level].st_tab->
01521 Un_register(*Be_scope_tab[scope_level].be_st_tab);
01522 Be_scope_tab[scope_level].be_st_tab->Clear();
01523
01524 Free_Local_Info(current_pu);
01525 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
01526 MEM_POOL_Pop(MEM_pu_pool_ptr);
01527
01528
01529
01530
01531
01532
01533
01534 if (Saved_run_prompf) {
01535 Run_prompf = Saved_run_prompf;
01536 Run_w2c = Saved_run_w2c;
01537 Run_w2f = Saved_run_w2f;
01538 Run_w2fc_early = Saved_run_w2fc_early;
01539 Saved_run_prompf = FALSE;
01540 Saved_run_w2c = FALSE;
01541 Saved_run_w2f = FALSE;
01542 Saved_run_w2fc_early = FALSE;
01543 }
01544 }
01545
01546
01547 static void
01548 Preorder_Process_PUs (PU_Info *current_pu)
01549 {
01550 INT orig_opt_level = Opt_Level;
01551 BOOL orig_run_lno = Run_lno;
01552 BOOL orig_run_preopt = Run_preopt;
01553 BOOL orig_run_wopt = Run_wopt;
01554 BOOL orig_olimit_opt = Olimit_opt;
01555
01556 WN *pu;
01557 Start_Timer(T_BE_PU_CU);
01558
01559 pu = Preprocess_PU(current_pu);
01560
01561
01562
01563
01564 Scope_tab[CURRENT_SYMTAB].preg_tab->Register(Be_preg_tab);
01565
01566 WN_verifier(pu);
01567
01568 Verify_SYMTAB (CURRENT_SYMTAB);
01569
01570 if (!PU_mp (Get_Current_PU ()) &&
01571 (Run_Dsm_Cloner || Run_Dsm_Common_Check || Run_Dsm_Check))
01572 DRA_Processing(current_pu, pu, Cur_PU_Feedback != NULL);
01573
01574
01575
01576
01577
01578 if (PU_has_mp (Get_Current_PU ()) && !FILE_INFO_ipa (File_info)) {
01579 Set_Error_Phase("OMP Pre-lowering");
01580 WB_OMP_Initialize(pu, Prompf_Id_Map);
01581 pu = OMP_Prelower(current_pu, pu);
01582 WB_OMP_Terminate();
01583 }
01584
01585 if (Run_ipl) {
01586 Ipl_Processing (current_pu, pu);
01587 Verify_SYMTAB (CURRENT_SYMTAB);
01588 }
01589 else {
01590 Backend_Processing (current_pu, pu);
01591 Verify_SYMTAB (CURRENT_SYMTAB);
01592 }
01593 if (reset_opt_level) {
01594 Opt_Level = orig_opt_level;
01595 Run_lno = orig_run_lno;
01596 Run_preopt = orig_run_preopt;
01597 Run_wopt = orig_run_wopt;
01598 reset_opt_level = FALSE;
01599 Olimit_opt = orig_olimit_opt;
01600 }
01601
01602 Scope_tab[CURRENT_SYMTAB].preg_tab->Un_register(Be_preg_tab);
01603 Be_preg_tab.Clear();
01604
01605 Stop_Timer(T_BE_PU_CU);
01606 Finish_BE_Timing ( Tim_File, ST_name(PU_Info_proc_sym(current_pu)) );
01607 Advance_Current_PU_Count();
01608
01609 Cur_PU_Name = NULL;
01610
01611
01612
01613
01614
01615
01616 Print_PU_Stats ();
01617
01618
01619
01620 for (PU_Info *child = PU_Info_child(current_pu);
01621 child != NULL;
01622 child = PU_Info_next(child)) {
01623 Preorder_Process_PUs(child);
01624 }
01625
01626 Postprocess_PU (current_pu);
01627 }
01628
01629 static void Print_Tlog_Header(INT argc, char **argv)
01630 {
01631 INT i;
01632 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_NOHDR))
01633 return;
01634 fprintf(Tlog_File,"1.0\n");
01635 fprintf(Tlog_File,"{ ");
01636 for (i=0; i<argc; i++)
01637 fprintf(Tlog_File,"%s ", argv[i]);
01638 fprintf(Tlog_File,"}\n");
01639 }
01640
01641
01642 #define FEEDBACK_PATH_MAXLEN 1024
01643
01644
01645 static void
01646 Process_Feedback_Options (OPTION_LIST* olist)
01647 {
01648 if (Feedback_File_Name) {
01649
01650
01651
01652
01653 INT t = strlen(Feedback_File_Name);
01654 Is_True(t < FEEDBACK_PATH_MAXLEN - 16,
01655 ("Process_Feedback_Options: Feedback file name too long(%d)",
01656 t));
01657 while (t > 0 && Feedback_File_Name[t - 1] != '/')
01658 t--;
01659
01660
01661
01662
01663 char path[FEEDBACK_PATH_MAXLEN];
01664 char *prefix = Feedback_File_Name + t;
01665 if (t > 0) {
01666
01667 strncpy(path, Feedback_File_Name, t);
01668 } else {
01669
01670 path[0] = '.';
01671 path[1] = '/';
01672 t = 2;
01673 }
01674 path[t] = '\0';
01675 char *dir_end = path + t;
01676
01677 INT prefix_len = strlen(prefix);
01678 DIR* dirp = opendir(path);
01679 struct dirent* direntp;
01680 while ((direntp = readdir(dirp)) != NULL) {
01681 if (strncmp(direntp->d_name, prefix, prefix_len) == 0) {
01682 strcpy(dir_end, direntp->d_name);
01683 Process_Feedback_File(path);
01684 }
01685 }
01686 closedir(dirp);
01687 }
01688
01689 OPTION_LIST *ol;
01690 for (ol = olist; ol != NULL; ol = OLIST_next(ol)) {
01691 char *val = OLIST_val(ol);
01692 Process_Feedback_File(val);
01693 }
01694 }
01695
01696
01697
01698 extern "C" {
01699 void be_debug(void) {}
01700 }
01701
01702 INT
01703 main (INT argc, char **argv)
01704 {
01705 INT local_ecount, local_wcount;
01706 PU_Info *pu_tree;
01707
01708 setlinebuf (stdout);
01709 setlinebuf (stderr);
01710 Handle_Signals ();
01711 MEM_Initialize ();
01712 Cur_PU_Name = NULL;
01713 Init_Error_Handler ( 100 );
01714 Set_Error_Line ( ERROR_LINE_UNKNOWN );
01715 Set_Error_File ( NULL );
01716 Set_Error_Phase ( "Back End Driver" );
01717
01718 Preconfigure ();
01719 Process_Command_Line (argc, argv);
01720 if (Inhibit_EH_opt && Opt_Level > 1) Opt_Level = 1;
01721 Reset_Timers ();
01722 Start_Timer(T_BE_Comp);
01723 Prepare_Source ();
01724 Initialize_Stats ();
01725 Configure ();
01726 Configure_Source(NULL);
01727 #ifdef Is_True_On
01728 if (Get_Trace (TKIND_ALLOC, TP_MISC)) {
01729 MEM_Tracing_Enable();
01730 }
01731 #endif
01732 if ( List_Enabled ) {
01733 Prepare_Listing_File ();
01734 List_Compile_Options ( Lst_File, "", FALSE, List_All_Options, FALSE );
01735 }
01736
01737 Init_Operator_To_Opcode_Table();
01738
01739
01740 load_components (argc, argv);
01741 be_debug();
01742
01743 MEM_POOL_Push (&MEM_src_pool);
01744 MEM_POOL_Push (&MEM_src_nz_pool);
01745 if ( Show_Progress ) {
01746 fprintf ( stderr, "Compiling %s (%s) -- Back End\n",
01747 Src_File_Name, Irb_File_Name );
01748 fflush ( stderr );
01749 }
01750 Set_Error_Source (Src_File_Name);
01751
01752
01753 Options_Stack = CXX_NEW(OPTIONS_STACK(&MEM_src_nz_pool), &MEM_src_nz_pool);
01754 Options_Stack->Push_Current_Options();
01755
01756 Start_Timer (T_ReadIR_Comp);
01757 if (Read_Global_Data) {
01758
01759 Irb_File = (FILE *)Open_Global_Input (Global_File_Name);
01760 Irb_File = (FILE *)Open_Local_Input (Irb_File_Name);
01761 }
01762 else {
01763 Irb_File = (FILE *)Open_Input_Info (Irb_File_Name);
01764 }
01765 Initialize_Symbol_Tables (FALSE);
01766 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, FALSE);
01767 pu_tree = Read_Global_Info (NULL);
01768 Stop_Timer (T_ReadIR_Comp);
01769
01770 Initialize_Special_Global_Symbols ();
01771
01772
01773
01774 if (FILE_INFO_ipa (File_info)) {
01775 if (Instrumentation_Enabled &&
01776 Instrumentation_Phase_Num <= PROFILE_PHASE_IPA_CUTOFF) {
01777 Instrumentation_Enabled = FALSE;
01778 Instrumentation_Phase_Num = PROFILE_PHASE_NONE;
01779 }
01780 } else {
01781 Process_Feedback_Options (Feedback_Option);
01782 }
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 if (Run_Dsm_Cloner || Run_Dsm_Common_Check) {
01794 DRA_Initialize();
01795 }
01796 BOOL needs_lno = FILE_INFO_needs_lno (File_info);
01797
01798 if (needs_lno && !Run_ipl) {
01799 Run_Distr_Array = TRUE;
01800 if (!Run_lno && !Run_autopar) {
01801
01802
01803 INT phase_argc;
01804 char **phase_argv;
01805
01806 if (!Run_wopt && !Run_preopt) {
01807
01808 Get_Phase_Args (PHASE_WOPT, &phase_argc, &phase_argv);
01809 load_so ("wopt" DSOext, WOPT_Path, Show_Progress);
01810 wopt_main (phase_argc, phase_argv, argc, argv);
01811 wopt_loaded = TRUE;
01812 }
01813
01814 Get_Phase_Args (PHASE_LNO, &phase_argc, &phase_argv);
01815 load_so ("lno" DSOext, LNO_Path, Show_Progress);
01816 lno_main (phase_argc, phase_argv, argc, argv);
01817 }
01818 }
01819
01820
01821
01822
01823 BE_symtab_initialize_be_scopes();
01824 BE_symtab_alloc_scope_level(GLOBAL_SYMTAB);
01825 SYMTAB_IDX scope_level;
01826 for (scope_level = 0;
01827 scope_level <= GLOBAL_SYMTAB;
01828 ++scope_level) {
01829
01830
01831 if (Scope_tab[scope_level].st_tab != NULL) {
01832 Scope_tab[scope_level].st_tab->
01833 Register(*Be_scope_tab[scope_level].be_st_tab);
01834 }
01835 else {
01836 Is_True(scope_level == 0,
01837 ("Nonexistent st_tab for level %d", scope_level));
01838 }
01839 }
01840
01841 Phase_Init ();
01842
01843 if (Run_preopt || Run_wopt || Run_lno || Run_Distr_Array || Run_autopar
01844 || Run_cg) {
01845 Set_Error_Descriptor (EP_BE, EDESC_BE);
01846 Set_Error_Descriptor (EP_CG, EDESC_CG);
01847 }
01848
01849 if (Tlog_File)
01850 Print_Tlog_Header(argc, argv);
01851
01852
01853 for (PU_Info *current_pu = pu_tree;
01854 current_pu != NULL;
01855 current_pu = PU_Info_next(current_pu)) {
01856 Preorder_Process_PUs(current_pu);
01857 }
01858
01859
01860
01861 if (Show_Progress) {
01862 fprintf (stderr, "\n");
01863 fflush (stderr);
01864 }
01865
01866 Phase_Fini ();
01867
01868
01869
01870 Is_True(scope_level == GLOBAL_SYMTAB + 1,
01871 ("scope_level must be GLOBAL_SYMTAB + 1, left from earlier loop"));
01872
01873 do {
01874 --scope_level;
01875
01876
01877 if (Scope_tab[scope_level].st_tab != NULL) {
01878 Scope_tab[scope_level].st_tab->
01879 Un_register(*Be_scope_tab[scope_level].be_st_tab);
01880 Be_scope_tab[scope_level].be_st_tab->Clear();
01881 }
01882 else {
01883 Is_True(scope_level == 0,
01884 ("Nonexistent st_tab for level %d", scope_level));
01885 }
01886 } while (scope_level != 0);
01887
01888 BE_symtab_free_be_scopes();
01889
01890
01891 if (need_wopt_output || need_lno_output || need_ipl_output) {
01892 Write_Global_Info (pu_tree);
01893 if (need_ipl_output)
01894 Ipl_Extra_Output (ir_output);
01895 Close_Output_Info ();
01896 }
01897 else if (Emit_Global_Data) {
01898 Write_Global_Info (NULL);
01899 Close_Output_Info ();
01900 }
01901
01902
01903 Print_Total_Stats ();
01904 if ((Opt_Level > 0 || Run_autopar)
01905 && Max_Src_Olimit > Olimit && !Olimit_opt && Show_OPT_Warnings) {
01906 ErrMsg (EC_File_Olimit_Exceeded, Max_Src_Olimit);
01907 }
01908
01909 Stop_Timer(T_BE_Comp);
01910 Finish_Compilation_Timing ( Tim_File, Src_File_Name );
01911
01912 MEM_POOL_Pop ( &MEM_src_pool );
01913 MEM_POOL_Pop ( &MEM_src_nz_pool );
01914 #ifdef Is_True_On
01915 if (Get_Trace (TKIND_ALLOC, TP_MISC)) {
01916 fprintf (TFile, "\n%s\tMemory allocation information after be\n", DBar);
01917 MEM_Trace ();
01918 }
01919 #endif
01920
01921
01922 if ( Get_Error_Count ( &local_ecount, &local_wcount ) ) {
01923 ecount += local_ecount;
01924 }
01925
01926 if ( ecount > 0 ) {
01927 Terminate(Had_Internal_Error() ? RC_INTERNAL_ERROR : RC_NORECOVER_USER_ERROR) ;
01928 }
01929
01930
01931 Cleanup_Files ( TRUE, FALSE );
01932
01933 exit ( RC_OKAY );
01934
01935
01936 }