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 <iostream>
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 "ori.h"
00083 #include "w2c_driver.h"
00084 #include "w2f_driver.h"
00085 #include "anl_driver.h"
00086 #include "region_util.h"
00087 #include "region_main.h"
00088 #include "tracing.h"
00089 #include "ir_reader.h"
00090 #include "dwarf_DST.h"
00091 #include "fb_whirl.h"
00092 #include "iter.h"
00093 #include "dra_export.h"
00094 #include "ti_init.h"
00095 #include "opt_alias_interface.h"
00096 #include "omp_lower.h"
00097 #include "cxx_memory.h"
00098 #include "options_stack.h"
00099 #include "be_symtab.h"
00100 #include "prompf.h"
00101 #include "wb_omp.h"
00102 #include "wb_lwr.h"
00103 #include "wb_anl.h"
00104 #include "wn_instrument.h"
00105 #include "mem_ctr.h"
00106 #include "upc_symtab_utils.h"
00107
00108
00109 #if defined(__CYGWIN__)
00110 # define DSOext ".dll"
00111 #else
00112 # define DSOext ".so"
00113 #endif
00114
00115
00116 extern void Initialize_Targ_Info(void);
00117
00118 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00119 extern "C" {
00120 INT64 New_Construct_Id(void) { return 0; }
00121 INT64 Get_Next_Construct_Id(void) { return 0; }
00122 }
00123 #endif
00124
00125
00126
00127 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00128
00129 extern void (*wopt_main_p) (INT argc, char **argv, INT, char **);
00130 #define wopt_main (*wopt_main_p)
00131
00132 extern void (*Wopt_Init_p) ();
00133 #define Wopt_Init (*Wopt_Init_p)
00134
00135 extern void (*Wopt_Fini_p) ();
00136 #define Wopt_Fini (*Wopt_Fini_p)
00137
00138 extern WN* (*Perform_Preopt_Optimization_p) (WN *, WN *);
00139 #define Perform_Preopt_Optimization (*Perform_Preopt_Optimization_p)
00140
00141 extern WN* (*Perform_Global_Optimization_p) (WN *, WN *, ALIAS_MANAGER *);
00142 #define Perform_Global_Optimization (*Perform_Global_Optimization_p)
00143
00144 extern WN* (*Pre_Optimizer_p) (INT32, WN*, DU_MANAGER*, ALIAS_MANAGER*);
00145 #define Pre_Optimizer (*Pre_Optimizer_p)
00146
00147 extern DU_MANAGER* (*Create_Du_Manager_p) (MEM_POOL *);
00148 #define Create_Du_Manager (*Create_Du_Manager_p)
00149
00150 extern void (*Delete_Du_Manager_p) (DU_MANAGER *, MEM_POOL *);
00151 #define Delete_Du_Manager (*Delete_Du_Manager_p)
00152
00153 extern BOOL (*Verify_alias_p) (ALIAS_MANAGER *, WN *);
00154 #define Verify_alias (*Verify_alias_p)
00155
00156 #else
00157
00158 #pragma weak wopt_main
00159 #pragma weak Wopt_Init
00160 #pragma weak Wopt_Fini
00161 #pragma weak Perform_Global_Optimization
00162 #pragma weak Perform_Preopt_Optimization
00163 #pragma weak Pre_Optimizer
00164 #pragma weak Create_Du_Manager
00165 #pragma weak Delete_Du_Manager
00166 #pragma weak Verify_alias
00167
00168 #endif // __linux__
00169
00170
00171
00172 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00173
00174 extern void (*lno_main_p) (INT, char**, INT, char**);
00175 #define lno_main (*lno_main_p)
00176
00177 extern void (*Lno_Init_p) ();
00178 #define Lno_Init (*Lno_Init_p)
00179
00180 extern void (*Lno_Fini_p) ();
00181 #define Lno_Fini (*Lno_Fini_p)
00182
00183 extern WN* (*Perform_Loop_Nest_Optimization_p) (PU_Info*, WN*, WN*, BOOL);
00184 #define Perform_Loop_Nest_Optimization (*Perform_Loop_Nest_Optimization_p)
00185
00186 #else
00187
00188 #pragma weak lno_main
00189 #pragma weak Lno_Init
00190 #pragma weak Lno_Fini
00191 #pragma weak Perform_Loop_Nest_Optimization
00192
00193 #endif // __linux__
00194
00195
00196
00197 #if defined(__linux__) || defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00198
00199 extern void (*Ipl_Extra_Output_p) (Output_File *);
00200 #define Ipl_Extra_Output (*Ipl_Extra_Output_p)
00201
00202 extern void (*Ipl_Init_p) ();
00203 #define Ipl_Init (*Ipl_Init_p)
00204
00205 extern void (*Ipl_Fini_p) ();
00206 #define Ipl_Fini (*Ipl_Fini_p)
00207
00208 extern void (*ipl_main_p) (INT, char **);
00209 #define ipl_main (*ipl_main_p)
00210
00211 extern void (*Perform_Procedure_Summary_Phase_p) (WN*, DU_MANAGER*,
00212 ALIAS_MANAGER*, void*);
00213 #define Perform_Procedure_Summary_Phase (*Perform_Procedure_Summary_Phase_p)
00214
00215 #else
00216
00217 #pragma weak ipl_main
00218 #pragma weak Ipl_Init
00219 #pragma weak Ipl_Fini
00220 #pragma weak Ipl_Extra_Output
00221 #pragma weak Perform_Procedure_Summary_Phase
00222
00223 #endif // __linux__
00224
00225
00226 #include "w2c_weak.h"
00227 #include "w2f_weak.h"
00228
00229
00230 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00231
00232 extern "C" {
00233 void Anl_Process_Command_Line (INT phase_argc, char *phase_argv[],
00234 INT argc, char *argv[]) { }
00235 BOOL Anl_Needs_Whirl2c(void) { return false; }
00236 BOOL Anl_Needs_Whirl2f(void) { return false; }
00237 void Anl_Init(void) { }
00238 WN_MAP Anl_Init_Map(MEM_POOL *id_map_pool) { return NULL; }
00239 void Anl_Static_Analysis(WN *pu, WN_MAP id_map) { }
00240 const char *Anl_File_Path(void) { return NULL; }
00241 void Anl_Fini(void) { }
00242 void Anl_Cleanup(void){ }
00243 }
00244
00245 void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu,
00246 WN* func_nd) { }
00247
00248 #else
00249
00250 #pragma weak Anl_Cleanup
00251 #pragma weak Anl_Process_Command_Line
00252 #pragma weak Anl_Needs_Whirl2c
00253 #pragma weak Anl_Needs_Whirl2f
00254 #pragma weak Anl_Init
00255 #pragma weak Anl_Init_Map
00256 #pragma weak Anl_Static_Analysis
00257 #pragma weak Anl_Fini
00258
00259 #endif
00260
00261
00262
00263
00264
00265
00266
00267 #if !defined(__GNUC__) && defined(_SOLARIS_SOLARIS)
00268 # pragma weak "__1cbBPrompf_Emit_Whirl_to_Source6FpnHpu_info_pnCWN__v_"
00269 #elif !defined(__GNUC__)
00270 # pragma weak Prompf_Emit_Whirl_to_Source__GP7pu_infoP2WN
00271 #else
00272 # pragma weak Prompf_Emit_Whirl_to_Source__FP7pu_infoP2WN
00273
00274
00275 # if defined(_LINUX_LINUX) && !defined(__CYGWIN__) \
00276 && defined(__GNUC__) && (__GNUC__ >= 3)
00277 void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu, WN* func_nd) { }
00278 # endif
00279 #endif
00280
00281 extern void Prompf_Emit_Whirl_to_Source(PU_Info* current_pu, WN* func_nd);
00282
00283
00284 static INT ecount = 0;
00285 static BOOL need_wopt_output = FALSE;
00286 static BOOL need_lno_output = FALSE;
00287 static BOOL need_ipl_output = FALSE;
00288 static Output_File *ir_output = 0;
00289
00290
00291 static OPTIONS_STACK *Options_Stack;
00292
00293 static BOOL reset_opt_level = FALSE;
00294 static struct ALIAS_MANAGER *alias_mgr = NULL;
00295
00296 static BOOL Run_Distr_Array = FALSE;
00297 BOOL Run_MemCtr = FALSE;
00298
00299 static BOOL Saved_run_prompf = FALSE;
00300 static BOOL Saved_run_w2c = FALSE;
00301 static BOOL Saved_run_w2f = FALSE;
00302 static BOOL Saved_run_w2fc_early = FALSE;
00303
00304 extern WN_MAP Prompf_Id_Map;
00305
00306
00307
00308
00309 static BOOL wopt_loaded = FALSE;
00310 extern BOOL Prompf_anl_loaded;
00311 extern BOOL Purple_loaded;
00312 extern BOOL Whirl2f_loaded;
00313 extern BOOL Whirl2c_loaded;
00314
00315 extern void *Current_Dep_Graph;
00316 FILE *DFile = stderr;
00317
00318
00319 int s_size = 16, p_size = 16, r_size = 4, m_size = 4;
00320
00321 static void
00322 load_components (INT argc, char **argv)
00323 {
00324 INT phase_argc;
00325 char **phase_argv;
00326
00327 if (Run_cg || Run_lno || Run_autopar) {
00328
00329 Initialize_Targ_Info();
00330 }
00331
00332 if (!(Run_lno || Run_wopt || Run_preopt || Run_cg ||
00333 Run_prompf || Run_purple || Run_w2c || Run_w2f
00334 || Run_w2fc_early || Run_ipl))
00335 Run_cg = TRUE;
00336
00337 if (Run_ipl) {
00338 Run_lno = Run_wopt = Run_cg = Run_w2fc_early
00339 = Run_prompf = Run_purple = Run_w2c = Run_w2f = FALSE;
00340 }
00341
00342 if (Run_prompf || Run_w2fc_early) {
00343 Get_Phase_Args (PHASE_PROMPF, &phase_argc, &phase_argv);
00344 load_so("prompf_anl" DSOext, Prompf_Anl_Path, Show_Progress);
00345 Prompf_anl_loaded = TRUE;
00346 Anl_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00347 }
00348
00349 if (Run_w2f)
00350 {
00351 Get_Phase_Args (PHASE_W2F, &phase_argc, &phase_argv);
00352 load_so("whirl2f" DSOext, W2F_Path, Show_Progress);
00353 Whirl2f_loaded = TRUE;
00354 if (Run_prompf)
00355 W2F_Set_Prompf_Emission(&Prompf_Id_Map);
00356
00357 W2F_Process_Command_Line(phase_argc, phase_argv, argc, argv);
00358 }
00359 }
00360
00361
00362
00363
00364
00365 static void
00366 Phase_Init (void)
00367 {
00368 char *output_file_name = Obj_File_Name;
00369
00370 if (Run_Distr_Array &&
00371 (Run_w2c || Run_w2f) &&
00372 !Run_lno &&
00373 !Run_wopt &&
00374 !Run_cg)
00375 {
00376
00377
00378
00379
00380
00381 Run_Distr_Array = FALSE;
00382 }
00383 if ( LNO_Run_Lego_Set && ( LNO_Run_Lego == FALSE ) )
00384 Run_Distr_Array = FALSE;
00385
00386 if (Run_w2c || (Run_prompf && Anl_Needs_Whirl2c()))
00387 W2C_Outfile_Init (TRUE);
00388 if (Run_w2f || (Run_prompf && Anl_Needs_Whirl2f()))
00389 W2F_Outfile_Init ();
00390 if (Run_prompf)
00391 Anl_Init ();
00392
00393 if ((Run_lno || Run_preopt) && !Run_cg && !Run_wopt)
00394 need_lno_output = TRUE;
00395 if (Run_wopt && !Run_cg)
00396 need_wopt_output = TRUE;
00397
00398 if (Run_ipl) {
00399 need_ipl_output = TRUE;
00400 need_lno_output = need_wopt_output = FALSE;
00401 }
00402
00403 if (output_file_name == 0) {
00404 if (Src_File_Name)
00405 output_file_name = Last_Pathname_Component (Src_File_Name);
00406 else
00407 output_file_name = Irb_File_Name;
00408 }
00409
00410 if (need_lno_output) {
00411 Write_BE_Maps = TRUE;
00412 ir_output = Open_Output_Info(New_Extension(output_file_name,".N"));
00413 }
00414 if (need_wopt_output) {
00415 Write_ALIAS_CLASS_Map = TRUE;
00416 Write_BE_Maps = TRUE;
00417 ir_output = Open_Output_Info(New_Extension(output_file_name,".O"));
00418 }
00419 if (need_ipl_output) {
00420 Write_BE_Maps = FALSE;
00421 ir_output = Open_Output_Info (Obj_File_Name ?
00422 Obj_File_Name :
00423 New_Extension(output_file_name, ".o"));
00424 }
00425 if (Emit_Global_Data) {
00426 Write_BE_Maps = FALSE;
00427 ir_output = Open_Output_Info (Global_File_Name);
00428 }
00429
00430 }
00431
00432
00433 static void
00434 Phase_Fini (void)
00435 {
00436 CURRENT_SYMTAB = GLOBAL_SYMTAB;
00437
00438
00439 if (Run_prompf)
00440 Anl_Fini();
00441 if (Run_w2f || (Run_prompf && Anl_Needs_Whirl2f()))
00442 W2F_Outfile_Fini ();
00443 Verify_SYMTAB (CURRENT_SYMTAB);
00444 }
00445
00446 char *
00447 Get_Orig_PU_Name (PU_Info * current_pu)
00448 {
00449 DST_IDX dst;
00450 DST_INFO *info;
00451 DST_SUBPROGRAM *PU_attr;
00452
00453 dst = PU_Info_pu_dst(current_pu);
00454
00455 if (DST_IS_NULL (dst)) {
00456 return ST_name(PU_Info_proc_sym(current_pu));
00457 }
00458
00459 info = DST_INFO_IDX_TO_PTR (dst);
00460
00461 if ( (DST_INFO_tag(info) != DW_TAG_subprogram)
00462 || DST_IS_declaration(DST_INFO_flag(info)) )
00463 {
00464 return ST_name(PU_Info_proc_sym(current_pu));
00465 }
00466 PU_attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
00467 if (PU_attr->def.name.byte_idx < 0) {
00468 return NULL;
00469
00470
00471
00472 }
00473 return DST_STR_IDX_TO_PTR(DST_SUBPROGRAM_def_name(PU_attr));
00474 }
00475
00476 static void
00477 Save_Cur_PU_Name (char *name, INT rid_id)
00478 {
00479 if ( Cur_PU_Name == NULL ) {
00480
00481
00482
00483
00484
00485
00486
00487 Cur_PU_Name = TYPE_MEM_POOL_ALLOC_N(char, &MEM_pu_nz_pool,
00488 strlen(name) + 8);
00489 Cur_PU_Name = strcpy(Cur_PU_Name, name);
00490 }
00491 if (rid_id != 0) {
00492
00493 sprintf(Cur_PU_Name,"%s.RGN%03d", name, rid_id);
00494 }
00495 else if (strlen(name) != strlen(Cur_PU_Name)) {
00496
00497 Cur_PU_Name = strcpy(Cur_PU_Name, name);
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506 static WN *
00507 Adjust_Opt_Level (PU_Info* current_pu, WN *pu, char *pu_name)
00508 {
00509 INT new_opt_level = 0;
00510 COMPUTE_PU_OLIMIT;
00511
00512 if (Get_Trace(TKIND_INFO, TINFO_STATS)) {
00513
00514 INT PU_Var_Cnt = ST_Table_Size (CURRENT_SYMTAB) +
00515 PREG_Table_Size (CURRENT_SYMTAB);
00516 fprintf (TFile, "PU_Olimit for %s is %d (bbs=%d,stms=%d,vars=%d)\n",
00517 pu_name, PU_Olimit, PU_WN_BB_Cnt, PU_WN_Stmt_Cnt, PU_Var_Cnt);
00518 }
00519
00520 if ((Opt_Level > 0 || Run_autopar) && PU_Olimit > Olimit && !Olimit_opt) {
00521 if (Show_OPT_Warnings)
00522 ErrMsg (EC_Olimit_Exceeded, pu_name, PU_Olimit);
00523 reset_opt_level = TRUE;
00524 }
00525 if (((Opt_Level > 0 || Run_autopar) || Olimit_opt)
00526 && Query_Skiplist ( Optimization_Skip_List, Current_PU_Count() ) )
00527 {
00528 if (Show_OPT_Warnings)
00529 ErrMsg (EC_Not_Optimized, pu_name, Current_PU_Count() );
00530 reset_opt_level = TRUE;
00531 }
00532 if (
00533
00534
00535 PU_calls_setjmp (Get_Current_PU ())) {
00536 reset_opt_level = TRUE;
00537 new_opt_level = 1;
00538 ErrMsg (EC_Not_Ansi_Setjmp, pu_name, Current_PU_Count(), new_opt_level );
00539 }
00540 if (reset_opt_level) {
00541 Opt_Level = new_opt_level;
00542 Run_lno = Run_preopt = Run_wopt = Run_autopar = FALSE;
00543 alias_mgr = NULL;
00544 Olimit_opt = FALSE;
00545 if (Run_prompf)
00546 Prompf_Emit_Whirl_to_Source(current_pu, pu);
00547 }
00548
00549 return pu;
00550 }
00551
00552
00553
00554 static void
00555 Post_LNO_Processing (PU_Info *current_pu, WN *pu)
00556 {
00557 BOOL is_user_visible_pu = (CURRENT_SYMTAB == GLOBAL_SYMTAB + 1) ||
00558 ((Language == LANG_F90) &&
00559 (CURRENT_SYMTAB == GLOBAL_SYMTAB + 2) &&
00560 (!Is_Set_PU_Info_flags(current_pu, PU_IS_COMPILER_GENERATED))) ;
00561
00562
00563
00564 if (Run_w2c && !Run_w2fc_early && !Run_prompf) {
00565 if (W2C_Should_Emit_Nested_PUs() || is_user_visible_pu) {
00566 W2C_Outfile_Translate_Pu(pu, TRUE);
00567 }
00568 }
00569 if (Run_w2f && !Run_w2fc_early && !Run_prompf) {
00570 if (W2F_Should_Emit_Nested_PUs() || is_user_visible_pu) {
00571 if (PU_need_unparsed(ST_pu(WN_st(pu))))
00572 W2F_Outfile_Translate_Pu(pu);
00573 }
00574 }
00575
00576
00577
00578 if (need_lno_output) {
00579 Set_PU_Info_tree_ptr(current_pu, pu);
00580 Write_PU_Info(current_pu);
00581 Verify_SYMTAB (CURRENT_SYMTAB);
00582 }
00583
00584 }
00585
00586
00587 extern "C" {
00588 extern void Process_Fill_Align_Pragmas (WN* func_wn);
00589 extern void Rewrite_Pragmas_On_Structs (WN* block_wn, WN* wn);
00590 }
00591
00592
00593
00594
00595
00596
00597 static void Update_EHRegion_Inito_Used (WN *wn) {
00598 if (!wn) return;
00599
00600 OPERATOR opr = WN_operator(wn);
00601
00602 if (opr == OPR_REGION && WN_ereg_supp(wn)) {
00603 INITO_IDX ino_idx = WN_ereg_supp(wn);
00604 ST *st = INITO_st(ino_idx);
00605 Clear_ST_is_not_used(st);
00606 }
00607
00608
00609 if (opr == OPR_BLOCK) {
00610 WN *kid = WN_first (wn);
00611 while (kid) {
00612 Update_EHRegion_Inito_Used(kid);
00613 kid = WN_next(kid);
00614 }
00615 } else {
00616 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00617 Update_EHRegion_Inito_Used(WN_kid(wn,kidno));
00618 }
00619 }
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 static void Update_EHRegion_Inito (WN *pu) {
00631 INT i;
00632 INITO *ino;
00633
00634
00635 FOREACH_INITO (CURRENT_SYMTAB, ino, i) {
00636 ST *st = INITO_st(ino);
00637 if (ST_sclass(st) == SCLASS_EH_REGION ||
00638 ST_sclass(st) == SCLASS_EH_REGION_SUPP) {
00639 Set_ST_is_not_used(st);
00640 }
00641 }
00642
00643
00644
00645 Update_EHRegion_Inito_Used (pu);
00646 }
00647
00648 static void
00649 Backend_Processing (PU_Info *current_pu, WN *pu)
00650 {
00651 {
00652
00653
00654
00655
00656 static BOOL done_first_pu = FALSE;
00657 BOOL needs_fill_align_lowering =
00658 PU_needs_fill_align_lowering (Get_Current_PU ());
00659 if (needs_fill_align_lowering || !done_first_pu) {
00660 Process_Fill_Align_Pragmas (pu);
00661 done_first_pu = TRUE;
00662 }
00663 }
00664
00665 PU_adjust_addr_flags(Get_Current_PU_ST(), pu);
00666
00667 if (Run_MemCtr)
00668 MemCtr_Add (pu);
00669
00670
00671
00672
00673
00674 if (WHIRL_Return_Val_On || WHIRL_Mldid_Mstid_On) {
00675 Is_True(WHIRL_Return_Val_On && WHIRL_Mldid_Mstid_On,
00676 ("-INTERNAL:return_val and -INTERNAL:mldid_mstid must be on the same time"));
00677 }
00678
00679
00680 Set_Error_Phase ( "Post LNO Processing" );
00681 Post_LNO_Processing (current_pu, pu);
00682
00683 return;
00684 }
00685
00686 static WN *
00687 Preprocess_PU (PU_Info *current_pu)
00688 {
00689 WN *pu = NULL;
00690
00691 Initialize_PU_Stats ();
00692
00693 Current_PU_Info = current_pu;
00694 MEM_POOL_Push(MEM_pu_nz_pool_ptr);
00695 MEM_POOL_Push(MEM_pu_pool_ptr);
00696
00697 BOOL is_mp_nested_pu = FALSE;
00698
00699
00700 Start_Timer ( T_ReadIR_CU );
00701
00702
00703 if (PU_Info_state (current_pu, WT_TREE) != Subsect_InMem) {
00704 Read_Local_Info (MEM_pu_nz_pool_ptr, current_pu);
00705 } else {
00706
00707 Current_Map_Tab = PU_Info_maptab(current_pu);
00708 Current_pu = &PU_Info_pu(current_pu);
00709 CURRENT_SYMTAB = PU_lexical_level(*Current_pu);
00710 if ((PU_is_nested_func(*Current_pu) && PU_mp(*Current_pu)) ||
00711 Is_Set_PU_Info_flags(current_pu, PU_IS_DRA_CLONE)) {
00712 is_mp_nested_pu = TRUE;
00713
00714 Restore_Local_Symtab(current_pu);
00715 } else {
00716 Is_True(FALSE, ("Robert doesn't understand where symtabs come from"));
00717 }
00718 }
00719
00720 BE_symtab_alloc_scope_level(CURRENT_SYMTAB);
00721 Scope_tab[CURRENT_SYMTAB].st_tab->Register(*Be_scope_tab[CURRENT_SYMTAB].be_st_tab);
00722
00723
00724
00725
00726 pu = PU_Info_tree_ptr(current_pu);
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 if (!Saved_run_prompf &&
00738 Run_prompf &&
00739 Is_Set_PU_Info_flags(current_pu, PU_IS_COMPILER_GENERATED) &&
00740 !PU_mp (Get_Current_PU ())) {
00741 Saved_run_prompf = Run_prompf;
00742 Saved_run_w2c = Run_w2c;
00743 Saved_run_w2f = Run_w2f;
00744 Saved_run_w2fc_early = Run_w2fc_early;
00745 Run_prompf = FALSE;
00746 Run_w2c = FALSE;
00747 Run_w2f = FALSE;
00748 Run_w2fc_early = FALSE;
00749 }
00750
00751
00752 Orig_PU_Name = Get_Orig_PU_Name(current_pu);
00753 Save_Cur_PU_Name(ST_name(PU_Info_proc_sym(current_pu)), 0);
00754
00755 Set_Current_PU_For_Trace(ST_name(PU_Info_proc_sym(current_pu)),
00756 Current_PU_Count());
00757
00758 Stop_Timer (T_ReadIR_CU);
00759 Check_for_IR_Dump(TP_IR_READ,pu,"IR_READ");
00760
00761 if (Show_Progress) {
00762 fprintf(stderr, "Compiling %s(%d)\n",
00763 ST_name(PU_Info_proc_sym(current_pu)),
00764 Current_PU_Count());
00765 }
00766
00767 if (Get_Trace(TP_REGION,TT_REGION_ALL)) {
00768 fprintf(TFile,"===== BE driver, PU loop: PU %s(%d)\n",
00769 ST_name(PU_Info_proc_sym(current_pu)),Current_PU_Count());
00770 }
00771
00772 if (Tlog_File) {
00773 fprintf(Tlog_File,"BEGIN %s\n",ST_name(PU_Info_proc_sym(current_pu)));
00774 }
00775
00776 WN_Mem_Push ();
00777
00778 pu = Adjust_Opt_Level (current_pu, pu, ST_name(PU_Info_proc_sym(current_pu)));
00779
00780 return pu;
00781 }
00782
00783 static void
00784 Postprocess_PU (PU_Info *current_pu)
00785 {
00786 if (Tlog_File) {
00787 fprintf (Tlog_File, "END %s\n", ST_name(PU_Info_proc_sym(current_pu)));
00788 }
00789
00790 Current_Map_Tab = PU_Info_maptab(current_pu);
00791
00792
00793 WN_Mem_Pop ();
00794
00795
00796 SYMTAB_IDX scope_level = PU_lexical_level(PU_Info_pu(current_pu));
00797
00798 Scope_tab[scope_level].st_tab->
00799 Un_register(*Be_scope_tab[scope_level].be_st_tab);
00800 Be_scope_tab[scope_level].be_st_tab->Clear();
00801
00802 Free_Local_Info(current_pu);
00803 MEM_POOL_Pop(MEM_pu_nz_pool_ptr);
00804 MEM_POOL_Pop(MEM_pu_pool_ptr);
00805
00806
00807
00808
00809
00810
00811
00812 if (Saved_run_prompf) {
00813 Run_prompf = Saved_run_prompf;
00814 Run_w2c = Saved_run_w2c;
00815 Run_w2f = Saved_run_w2f;
00816 Run_w2fc_early = Saved_run_w2fc_early;
00817 Saved_run_prompf = FALSE;
00818 Saved_run_w2c = FALSE;
00819 Saved_run_w2f = FALSE;
00820 Saved_run_w2fc_early = FALSE;
00821 }
00822 }
00823
00824
00825 static void
00826 Preorder_Process_PUs (PU_Info *current_pu)
00827 {
00828 INT orig_opt_level = Opt_Level;
00829 BOOL orig_run_lno = Run_lno;
00830 BOOL orig_run_preopt = Run_preopt;
00831 BOOL orig_run_wopt = Run_wopt;
00832 BOOL orig_olimit_opt = Olimit_opt;
00833
00834 WN *pu;
00835 Start_Timer(T_BE_PU_CU);
00836
00837 pu = Preprocess_PU(current_pu);
00838
00839
00840
00841
00842
00843 Scope_tab[CURRENT_SYMTAB].preg_tab->Register(Be_preg_tab);
00844
00845 WN_verifier(pu);
00846
00847 Verify_SYMTAB (CURRENT_SYMTAB);
00848
00849 Backend_Processing (current_pu, pu);
00850 Verify_SYMTAB (CURRENT_SYMTAB);
00851
00852 if (reset_opt_level) {
00853 Opt_Level = orig_opt_level;
00854 Run_lno = orig_run_lno;
00855 Run_preopt = orig_run_preopt;
00856 Run_wopt = orig_run_wopt;
00857 reset_opt_level = FALSE;
00858 Olimit_opt = orig_olimit_opt;
00859 }
00860
00861 Scope_tab[CURRENT_SYMTAB].preg_tab->Un_register(Be_preg_tab);
00862 Be_preg_tab.Clear();
00863
00864 Stop_Timer(T_BE_PU_CU);
00865 Finish_BE_Timing ( Tim_File, ST_name(PU_Info_proc_sym(current_pu)) );
00866 Advance_Current_PU_Count();
00867
00868 Cur_PU_Name = NULL;
00869
00870
00871
00872
00873
00874
00875 Print_PU_Stats ();
00876
00877
00878
00879 for (PU_Info *child = PU_Info_child(current_pu);
00880 child != NULL;
00881 child = PU_Info_next(child)) {
00882 Preorder_Process_PUs(child);
00883 }
00884
00885 Postprocess_PU (current_pu);
00886 }
00887
00888 static void Print_Tlog_Header(INT argc, char **argv)
00889 {
00890 INT i;
00891 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_NOHDR))
00892 return;
00893 fprintf(Tlog_File,"1.0\n");
00894 fprintf(Tlog_File,"{ ");
00895 for (i=0; i<argc; i++)
00896 fprintf(Tlog_File,"%s ", argv[i]);
00897 fprintf(Tlog_File,"}\n");
00898 }
00899
00900
00901 #define FEEDBACK_PATH_MAXLEN 1024
00902
00903
00904
00905 extern "C" {
00906 void be_debug(void) {}
00907 }
00908
00909
00910 void RiceWhirl2f (INT * argc, char * **argv);
00911
00912
00913
00914 INT
00915 main (INT argc, char **argv)
00916 {
00917 INT local_ecount, local_wcount;
00918 PU_Info *pu_tree;
00919
00920
00921 setlinebuf (stdout);
00922 setlinebuf (stderr);
00923 Handle_Signals ();
00924 MEM_Initialize ();
00925 Cur_PU_Name = NULL;
00926 Init_Error_Handler ( 100 );
00927 Set_Error_Line ( ERROR_LINE_UNKNOWN );
00928 Set_Error_File ( NULL );
00929 Set_Error_Phase ( "Back End Driver" );
00930 Preconfigure ();
00931
00932 RiceWhirl2f ( & argc, & argv);
00933
00934 Process_Command_Line (argc, argv);
00935
00936 if (Inhibit_EH_opt && Opt_Level > 1) Opt_Level = 1;
00937 Reset_Timers ();
00938 Start_Timer(T_BE_Comp);
00939 Prepare_Source ();
00940 Initialize_Stats ();
00941
00942 Configure ();
00943 Configure_Source(NULL);
00944 #ifdef Is_True_On
00945 if (Get_Trace (TKIND_ALLOC, TP_MISC)) {
00946 MEM_Tracing_Enable();
00947 }
00948 #endif
00949 if ( List_Enabled ) {
00950 Prepare_Listing_File ();
00951 List_Compile_Options ( Lst_File, "", FALSE, List_All_Options, FALSE );
00952 }
00953
00954 Init_Operator_To_Opcode_Table();
00955
00956
00957
00958
00959 load_components (argc, argv);
00960 be_debug();
00961
00962 MEM_POOL_Push (&MEM_src_pool);
00963 MEM_POOL_Push (&MEM_src_nz_pool);
00964 if ( Show_Progress ) {
00965 fprintf ( stderr, "Compiling %s (%s) -- Back End\n",
00966 Src_File_Name, Irb_File_Name );
00967 fflush ( stderr );
00968 }
00969 Set_Error_Source (Src_File_Name);
00970
00971
00972 Options_Stack = CXX_NEW(OPTIONS_STACK(&MEM_src_nz_pool), &MEM_src_nz_pool);
00973 Options_Stack->Push_Current_Options();
00974
00975 Start_Timer (T_ReadIR_Comp);
00976
00977 if (Read_Global_Data) {
00978
00979 Irb_File = (FILE *)Open_Global_Input (Global_File_Name);
00980 Irb_File = (FILE *)Open_Local_Input (Irb_File_Name);
00981 }
00982 else {
00983 Irb_File = (FILE *)Open_Input_Info (Irb_File_Name);
00984 }
00985 Initialize_Symbol_Tables (FALSE);
00986 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, FALSE);
00987 pu_tree = Read_Global_Info (NULL);
00988 Stop_Timer (T_ReadIR_Comp);
00989
00990 Initialize_Special_Global_Symbols ();
00991
00992
00993
00994 if (FILE_INFO_ipa (File_info)) {
00995 if (Instrumentation_Enabled &&
00996 Instrumentation_Phase_Num <= PROFILE_PHASE_IPA_CUTOFF) {
00997 Instrumentation_Enabled = FALSE;
00998 Instrumentation_Phase_Num = PROFILE_PHASE_NONE;
00999 }
01000 }
01001
01002
01003
01004
01005 BE_symtab_initialize_be_scopes();
01006 BE_symtab_alloc_scope_level(GLOBAL_SYMTAB);
01007 SYMTAB_IDX scope_level;
01008 for (scope_level = 0;
01009 scope_level <= GLOBAL_SYMTAB;
01010 ++scope_level) {
01011
01012
01013 if (Scope_tab[scope_level].st_tab != NULL) {
01014 Scope_tab[scope_level].st_tab->
01015 Register(*Be_scope_tab[scope_level].be_st_tab);
01016 }
01017 else {
01018 Is_True(scope_level == 0,
01019 ("Nonexistent st_tab for level %d", scope_level));
01020 }
01021 }
01022
01023 Phase_Init ();
01024
01025 if (Run_preopt || Run_wopt || Run_lno || Run_Distr_Array || Run_autopar
01026 || Run_cg) {
01027 Set_Error_Descriptor (EP_BE, EDESC_BE);
01028 }
01029
01030 if (Compile_Upc) {
01031 Run_lno = 0;
01032 if (Run_w2c) {
01033
01034 Find_Upc_Vars();
01035 }
01036 }
01037
01038 if (Tlog_File)
01039 Print_Tlog_Header(argc, argv);
01040
01041
01042 for (PU_Info *current_pu = pu_tree;
01043 current_pu != NULL;
01044 current_pu = PU_Info_next(current_pu)) {
01045 Preorder_Process_PUs(current_pu);
01046 }
01047
01048 if(Compile_Upc && !Run_w2c)
01049 Upc_Lower_SymbolTable();
01050
01051
01052 if (Show_Progress) {
01053 fprintf (stderr, "\n");
01054 fflush (stderr);
01055 }
01056
01057 Phase_Fini ();
01058
01059
01060
01061 Is_True(scope_level == GLOBAL_SYMTAB + 1,
01062 ("scope_level must be GLOBAL_SYMTAB + 1, left from earlier loop"));
01063
01064 do {
01065 --scope_level;
01066
01067
01068 if (Scope_tab[scope_level].st_tab != NULL) {
01069 Scope_tab[scope_level].st_tab->
01070 Un_register(*Be_scope_tab[scope_level].be_st_tab);
01071 Be_scope_tab[scope_level].be_st_tab->Clear();
01072 }
01073 else {
01074 Is_True(scope_level == 0,
01075 ("Nonexistent st_tab for level %d", scope_level));
01076 }
01077 } while (scope_level != 0);
01078
01079 BE_symtab_free_be_scopes();
01080
01081
01082 if (need_wopt_output || need_lno_output || need_ipl_output) {
01083 Write_Global_Info (pu_tree);
01084 if (need_ipl_output)
01085 Ipl_Extra_Output (ir_output);
01086 Close_Output_Info ();
01087 }
01088 else if (Emit_Global_Data) {
01089 Write_Global_Info (NULL);
01090 Close_Output_Info ();
01091 }
01092
01093
01094 Print_Total_Stats ();
01095 if ((Opt_Level > 0 || Run_autopar)
01096 && Max_Src_Olimit > Olimit && !Olimit_opt && Show_OPT_Warnings) {
01097 ErrMsg (EC_File_Olimit_Exceeded, Max_Src_Olimit);
01098 }
01099
01100 Stop_Timer(T_BE_Comp);
01101 Finish_Compilation_Timing ( Tim_File, Src_File_Name );
01102
01103 MEM_POOL_Pop ( &MEM_src_pool );
01104 MEM_POOL_Pop ( &MEM_src_nz_pool );
01105 #ifdef Is_True_On
01106 if (Get_Trace (TKIND_ALLOC, TP_MISC)) {
01107 fprintf (TFile, "\n%s\tMemory allocation information after be\n", DBar);
01108 MEM_Trace ();
01109 }
01110 #endif
01111
01112
01113 if ( Get_Error_Count ( &local_ecount, &local_wcount ) ) {
01114 ecount += local_ecount;
01115 }
01116
01117 if ( ecount > 0 ) {
01118 Terminate(Had_Internal_Error() ? RC_INTERNAL_ERROR : RC_NORECOVER_USER_ERROR) ;
01119 }
01120
01121
01122 Cleanup_Files ( TRUE, FALSE );
01123
01124
01125 exit ( RC_OKAY );
01126
01127
01128
01129 }
01130
01131
01132 static BOOL
01133 Has_Extension__1 (char *name,
01134 char *ext)
01135 {
01136 INT16 nlen = strlen(name);
01137 INT16 elen = strlen(ext);
01138
01139
01140 if ( elen > nlen ) return FALSE;
01141
01142
01143 return ( strcmp ( &name[nlen-elen], ext ) == 0 );
01144 }
01145
01146
01147 static char *libpath[3] =
01148 {"LD_LIBRARY_PATH",
01149 "LD_LIBRARYN32_PATH",
01150 "LD_LIBRARY64_PATH"
01151 };
01152 static const char * const errstring = "%s: can't allocate memory\n";
01153
01154 void RiceWhirl2f (INT * _argc, char * **_argv) {
01155 char path[PATH_MAX];
01156 char *p;
01157 char *env;
01158 char * myname;
01159 int argidx, i, len;
01160 char **new_argv;
01161 BOOL dash_fB_option = FALSE;
01162 char *newlibpath[3];
01163 int argc = *_argc;
01164 char **argv = *_argv;
01165 myname= Last_Pathname_Component (argv[0]);
01166
01167 if (myname && strcmp(myname, "whirl2f90") == 0) {
01168
01169
01170 Run_w2f=1;
01171 strcpy (path, argv[0]);
01172 if (p = strrchr(path, '/'))
01173 p[0] = 0;
01174 else
01175 strcpy (path, ".");
01176
01177 for (i = 0; i<3; i++)
01178 {
01179 len = strlen (path) + 1;
01180 len += strlen (libpath[i]) + 1;
01181
01182 env = getenv (libpath[i]);
01183
01184 if (env) {
01185 len += strlen (env) + 1;
01186
01187 newlibpath[i] = (char *) malloc (len);
01188 if (newlibpath[i] == 0) {
01189 fprintf (stderr, errstring, argv[0]);
01190 exit(RC_NORECOVER_USER_ERROR);
01191 }
01192
01193 sprintf (newlibpath[i], "%s=%s:%s", libpath[i], env, path);
01194 } else {
01195 newlibpath[i] = (char *) malloc (len);
01196 if (newlibpath[i] == 0) {
01197 fprintf (stderr, errstring, argv[0]);
01198 exit(RC_NORECOVER_USER_ERROR);
01199 }
01200
01201 sprintf (newlibpath[i], "%s=%s", libpath[i], path);
01202 }
01203 }
01204 for (i = 0; i<3; i++)
01205 putenv (newlibpath[i]);
01206
01207
01208
01209
01210
01211
01212 new_argv = (char **) malloc((argc+2)*sizeof(char *));
01213 for (argidx = 0; argidx < argc; argidx++)
01214 {
01215 new_argv[argidx] = (char *) malloc(strlen(argv[argidx]) + 1);
01216 new_argv[argidx] = strcpy(new_argv[argidx], argv[argidx]);
01217 if (new_argv[argidx][0] == '-' &&
01218 new_argv[argidx][1] == 'f' &&
01219 new_argv[argidx][2] == 'B')
01220 dash_fB_option = TRUE;
01221 }
01222
01223 if (!dash_fB_option)
01224 {
01225
01226
01227
01228
01229 argidx = argc-1;
01230 while (argidx > 0)
01231 {
01232 if (new_argv[argidx][0] != '-' &&
01233 (Has_Extension__1(new_argv[argidx], ".B") ||
01234 Has_Extension__1(new_argv[argidx], ".I") ||
01235 Has_Extension__1(new_argv[argidx], ".N") ||
01236 Has_Extension__1(new_argv[argidx], ".o")))
01237 {
01238
01239
01240
01241
01242
01243 dash_fB_option = TRUE;
01244 new_argv[argc] = (char *) malloc(strlen(new_argv[argidx]) + 5);
01245 (void)strcpy(new_argv[argc], "-fB,");
01246 (void)strcpy(&new_argv[argc][4], new_argv[argidx]);
01247 argc++;
01248
01249 new_argv[argidx][strlen(new_argv[argidx])-1] = 'f';
01250 argidx = 1;
01251 }
01252 argidx--;
01253 }
01254 }
01255 new_argv[argc] = NULL;
01256
01257
01258 new_argv[0][ strlen(new_argv[0])-2 ] = 0;
01259
01260 * _argc = argc;
01261 * _argv = new_argv;
01262 }
01263 }
01264