Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * dd-mmm-95 - Original Version 00042 * 00043 * Description: contains administrative routines invoked from the Cray 00044 * FE at initialization and termination of the 00045 * compiler and around each program unit. PDGCS_* entry 00046 * points plus fei_* routines which deal with procedure 00047 * initialization and cleanup. 00048 * 00049 * ==================================================================== 00050 * ==================================================================== 00051 */ 00052 /*REFERENCED*/ 00053 static char *source_file = __FILE__; 00054 00055 #ifdef _KEEP_RCS_ID 00056 /*REFERENCED*/ 00057 #endif /* _KEEP_RCS_ID */ 00058 00059 00060 /* sgi includes */ 00061 00062 #include "defs.h" 00063 #include "config.h" 00064 #include "config_opt.h" 00065 #include "glob.h" 00066 #include "stab.h" 00067 #include "strtab.h" 00068 #include "wn.h" 00069 #include "elf.h" 00070 #include "pu_info.h" 00071 #include <sys/types.h> 00072 #include "ir_reader.h" 00073 #include "ir_bwrite.h" 00074 #include "cleanUpWhirl.h" 00075 #include "file_util.h" 00076 #include "tracing.h" 00077 #include "x_libgen.h" /* for dirname() */ 00078 00079 /* FE includes */ 00080 00081 #include "i_cvrt.h" 00082 00083 /* conversion includes */ 00084 00085 #include "cwh_defines.h" 00086 #include "cwh_addr.h" 00087 #include "cwh_dst.h" 00088 #include "cwh_data.h" 00089 #include "cwh_mkdepend.h" 00090 #include "cwh_stmt.h" 00091 #include "cwh_preg.h" 00092 #include "cwh_stab.h" 00093 #include "cwh_auxst.h" 00094 #include "cwh_stk.h" 00095 #include "cwh_block.h" 00096 /*#include "cwh_stats.h" */ 00097 #include "sgi_cmd_line.h" 00098 00099 /* OS includes */ 00100 #include <sys/stat.h> 00101 #include <errno.h> 00102 #include <unistd.h> 00103 00104 INT32 cwh_assign_label_id; 00105 static BOOL Generate_IR = TRUE; 00106 static BOOL FE_Write_Binary = TRUE; 00107 static PU_Info *PU_Tree_Root ; /* First PU (not internal) seen */ 00108 static PU_Info *PU_Current ; /* Current PU */ 00109 static PU_Info *PU_Parent ; /* Parent of PU_current if current is internal */ 00110 00111 #define IRB_FILE_EXTENSION ".B" 00112 #define DSTDUMP_FILE_EXTENSION ".fe.dst" 00113 00114 static PU_Info * cwh_pdgcs_pu_mem(void) ; 00115 static void update_rii_file ( void ) ; 00116 static void delete_rii_file ( void ) ; 00117 00118 /* Memory pool for WHIRL maps */ 00119 static MEM_POOL map_mem_pool_s; /* Place to put auxilliary data structures */ 00120 static MEM_POOL *map_mem_pool = &map_mem_pool_s; 00121 00122 /*=============================================== 00123 * 00124 * PDGCS_initialize 00125 * 00126 * Initialize data structures required for the 00127 * translation at the start of compilation. 00128 * 00129 * Configuration and initialization of memory, 00130 * error handling etc, has been done in 00131 * sgi_cmd_line. 00132 * 00133 *=============================================== 00134 */ 00135 00136 /*ARGSUSED*/ 00137 extern void 00138 PDGCS_initialize(LANG language_code, 00139 INT32 flags, 00140 char *cmplr_name, 00141 char *cmplr_rel, 00142 char *code_file_name, 00143 char *list_file_name, 00144 INT32 trunc_bits, 00145 INT32 debug_opts, 00146 char *src_path_name, 00147 char *cif_file_name, 00148 char *debug_file_name, 00149 FILE *debug_file, 00150 FILE *cif_file, 00151 char *src_fname, 00152 char *cwd, 00153 INT32 n_pes, 00154 INT32 meta_test) 00155 00156 { 00157 00158 Output_File *Irb_File1; 00159 00160 Set_Error_Line ( ERROR_LINE_UNKNOWN ); 00161 00162 WHIRL_Keep_Cvt_On = TRUE; 00163 00164 if ( Generate_IR ) { 00165 00166 Initialize_Symbol_Tables (TRUE); 00167 cwh_auxst_alloc_container_table(); 00168 cwh_auxst_register_table(); 00169 00170 if ( FE_Write_Binary ) { 00171 if (!Irb_File_Name) { 00172 Irb_File_Name = New_Extension(code_file_name, 00173 IRB_FILE_EXTENSION); 00174 } 00175 Irb_File1 = Open_Output_Info ( Irb_File_Name ); 00176 cwh_dst_init_file(src_path_name) ; 00177 cwh_stmt_init_file(test_flag(flags,PDGCS_INITIALIZE_MP)); 00178 fe_preg_init() ; 00179 00180 } 00181 } 00182 00183 if (Get_Trace (TKIND_IR,TP_IRB) || 00184 Get_Trace (TKIND_SYMTAB,TP_IRB) || 00185 Get_Trace (TP_IRB,TINFO_STATS)) { 00186 00187 /* Use the Cray debug file */ 00188 if (debug_file) { 00189 Set_Trace_File_internal(debug_file); 00190 } else if (debug_file_name) { 00191 Set_Trace_File_internal(init_debug_file()); 00192 } else { 00193 if (!Trc_File_Name) { 00194 /* We need to make our own trace file */ 00195 Trc_File_Name = New_Extension(code_file_name,".t"); 00196 } 00197 Set_Trace_File_internal(fopen(Trc_File_Name,"w")); 00198 } 00199 if (TFile == NULL) { 00200 fprintf(stderr,"Error opening trace file %s, using stdout\n",Trc_File_Name); 00201 Set_Trace_File_internal(stdout); 00202 } 00203 } 00204 00205 if (Get_Trace(TP_IRB, 0x2000)) /* -tt11:0x2000 */ 00206 DSTdump_File_Name = New_Extension(code_file_name, DSTDUMP_FILE_EXTENSION); 00207 00208 /* We want to split COMMON with large into component blocks if 00209 * (a) -OPT:pad_common is set (unconditional), or 00210 * (b) -OPT:reorg_common is set and -FE:full_split is not OFF. 00211 * -FE:full_split=OFF is implicitly set by the driver if -IPA or 00212 * -INLINE is set. 00213 * 00214 * Common block splitting requires cooperation from the linker. 00215 * Currently we do this only for MIPS targets. 00216 */ 00217 #ifdef TARG_MIPS 00218 if ( ! FE_Full_Split_Set ) 00219 FE_Full_Split = OPT_Reorg_Common || OPT_Pad_Common; 00220 #endif 00221 00222 /* update/delete the .rii file */ 00223 00224 if ( rii_file_name ) { 00225 00226 if ( enable_dsm_processing ) { 00227 if ( enable_dsm_recompile == FALSE ) 00228 update_rii_file (); 00229 } 00230 00231 else 00232 delete_rii_file (); 00233 } 00234 00235 00236 /* Initialize the WHIRL mapping mechanism */ 00237 00238 MEM_POOL_Initialize(map_mem_pool,"map_mem_pool",FALSE); /* Init to 0 always */ 00239 MEM_POOL_Push(map_mem_pool); 00240 Current_Map_Tab = WN_MAP_TAB_Create(map_mem_pool); 00241 00242 Set_Error_Phase ( "Front End Parse/Semantic"); 00243 } 00244 00245 /*=============================================== 00246 * 00247 * PDGCS_comp_unit 00248 * 00249 * Initialize data structures at the start of 00250 * a new compilation unit. 00251 * 00252 *=============================================== 00253 */ 00254 /*ARGSUSED*/ 00255 extern void 00256 PDGCS_comp_unit(char *comp_unit_name, 00257 INT32 module_node) 00258 00259 00260 { 00261 } 00262 00263 00264 /*=============================================== 00265 * 00266 * PDGCS_new_proc 00267 * 00268 * Initialize PU information at the start of 00269 * each procedure. 00270 * 00271 * If there is an internal procedure, allocate its 00272 * parent's PU_info to maintain the correct nesting, 00273 * and don't reallocate when the parent comes along. 00274 * PU_Tree_Root is the first level 1 PU we see. 00275 * PU_Parent is only set with an internal proc. 00276 * 00277 * A symtab is allocated in fei_proc_def. 00278 * 00279 *=============================================== 00280 */ 00281 /*ARGSUSED*/ 00282 extern void 00283 PDGCS_new_proc(INT32 ir_count, 00284 INTPTR func_st_idx, 00285 INT32 alt_entry_count, 00286 INT32 scalar_opt_level, 00287 INT32 vector_opt_level, 00288 INT32 task_opt_level, 00289 INT32 opt_flags, 00290 INT32 user_mobes, 00291 INT32 user_sades, 00292 INT32 lineno, 00293 INT32 meta_opt_level, 00294 INT32 ismodule) 00295 { 00296 00297 PU_Info *pu; 00298 PU_Info *pp; 00299 STB_pkt *p ; 00300 ST *fn; 00301 00302 00303 p = cast_to_STB(func_st_idx); 00304 fn = cast_to_ST(p->item); 00305 if (ismodule == 1) 00306 Set_ST_is_in_module(fn); 00307 00308 if (ismodule ==2) 00309 Set_ST_is_block_data(fn); 00310 00311 cwh_stab_set_symtab(fn); 00312 00313 if ( IN_NESTED_PU ) { 00314 00315 /* internal, allocate parent's PU info too */ 00316 00317 pu = cwh_pdgcs_pu_mem(); 00318 00319 if (PU_Parent == NULL) { 00320 00321 pp = cwh_pdgcs_pu_mem(); 00322 PU_Info_child(pp) = pu ; 00323 00324 if (PU_Tree_Root == NULL) 00325 PU_Tree_Root = pp; 00326 else 00327 PU_Info_next(PU_Current) = pp ; 00328 00329 PU_Parent = pp ; 00330 Set_PU_Info_flags(pp,PU_HAS_NESTED_PU); 00331 00332 } else 00333 PU_Info_next(PU_Current) = pu ; 00334 00335 } else if (PU_Tree_Root == NULL) { 00336 00337 /* 1st seen, external */ 00338 00339 pu = cwh_pdgcs_pu_mem(); 00340 PU_Tree_Root = pu; 00341 PU_Parent = NULL; 00342 00343 } else if (PU_Parent == NULL) { 00344 00345 /* another external */ 00346 00347 pu = cwh_pdgcs_pu_mem(); 00348 PU_Info_next(PU_Current) = pu ; 00349 00350 } else { 00351 00352 /* parent of internal */ 00353 00354 pu = PU_Parent; 00355 PU_Parent = NULL; 00356 } 00357 00358 PU_Info_proc_sym(pu) = ST_st_idx(fn) ; 00359 00360 PU_Info_maptab(pu) = Current_Map_Tab; 00361 PU_Current = pu ; 00362 00363 /* Reset label # for computed goto/assign for each PU */ 00364 00365 cwh_assign_label_id=0; 00366 00367 /* Create array information map, bounds checking needs array name */ 00368 00369 array_name_map = WN_MAP_Create(map_mem_pool); 00370 00371 Set_Error_Phase ( "IR->WHIRL Conversion" ); 00372 } 00373 00374 /*=============================================== 00375 * 00376 * fei_proc_body 00377 * 00378 * Initialize WN generation for procedure's body. 00379 * 00380 *=============================================== 00381 */ 00382 00383 extern void 00384 fei_proc_body( INT32 lineno ) 00385 { 00386 00387 ST *st; 00388 00389 st = &St_Table[PU_Info_proc_sym(PU_Current)]; 00390 cwh_stab_set_tylist_for_entries(st); 00391 cwh_stab_emit_commons_and_equivalences(CURRENT_SYMTAB); 00392 cwh_stmt_init_pu(st,lineno); 00393 00394 } 00395 00396 /*=============================================== 00397 * 00398 * PDGCS_do_proc 00399 * 00400 * Write out the IR for the current PU. Fill in 00401 * the PU info with the WN tree and symbol table. 00402 * Generate the DST information for this PU, but 00403 * don't write it out. 00404 * 00405 * If it was a main PU, then we exit with a call 00406 * to _END, called from the FE. The debuggger's 00407 * stack trace needs a return address to be spilled 00408 * correctly, so a return is added here. 00409 * 00410 * Free the space associated with WN Tree. 00411 * 00412 *=============================================== 00413 */ 00414 extern void 00415 PDGCS_do_proc(void) 00416 { 00417 00418 WN *wn; 00419 PU_Info *pu; 00420 TYPE tt; 00421 ST *st; 00422 00423 DST_IDX d ; 00424 00425 pu = PU_Current ; 00426 00427 st = &St_Table[PU_Info_proc_sym(pu)]; 00428 PU& p = Pu_Table[ST_pu(st)]; 00429 if (PU_is_mainpu (p)) { 00430 memset(&tt, 0, sizeof(tt)); /* eraxxon: initialize to avoid warnings */ 00431 fei_return(2,tt); /* It's OK for this to be uninitialized */ 00432 } 00433 00434 if (cwh_stab_pu_has_globals) { 00435 Set_PU_Info_flags(pu,PU_HAS_GLOBALS); 00436 } 00437 00438 cwh_stmt_postprocess_pu(); 00439 wn = cwh_stmt_end_pu(); 00440 d = cwh_dst_enter_pu(st); 00441 00442 Set_PU_Info_tree_ptr(pu, wn); 00443 Set_PU_Info_pu_dst(pu,d); 00444 Set_PU_Info_cu_dst(pu,d); 00445 00446 Set_PU_Info_state(pu, WT_SYMTAB, Subsect_InMem); 00447 Set_PU_Info_state(pu, WT_TREE, Subsect_InMem); 00448 Set_PU_Info_state(pu, WT_PROC_SYM, Subsect_InMem); 00449 00450 // Emit initializations 00451 cwh_data_emit_symbol_inits(CURRENT_SYMTAB); 00452 00453 if (Get_Trace (TKIND_IR,TP_IRB)) 00454 fdump_tree(TFile,wn); 00455 00456 if (Get_Trace (TKIND_SYMTAB,TP_IRB)) { 00457 00458 fprintf(TFile,"PU info: %s (0x%08x)\n", 00459 ST_name(PU_Info_proc_sym(pu)), 00460 PU_Info_flags(pu)); 00461 00462 Print_local_symtab (TFile, Scope_tab [CURRENT_SYMTAB]); 00463 } 00464 00465 cwh_stk_verify_empty(); 00466 Verify_SYMTAB (CURRENT_SYMTAB); 00467 if (cleanUpWhirl) 00468 cleanUpPUInfoTree(pu); 00469 Write_PU_Info (pu); 00470 00471 #if 0 00472 if (Get_Trace (TP_IRB,TINFO_STATS)) /* -ttIRB:16 */ 00473 cwh_stats_print(PU_Info_proc_sym(pu)); 00474 #endif 00475 00476 WN_MAP_Delete(array_name_map); 00477 WN_Mem_Pop(); 00478 00479 Set_Error_Phase ( "IR->WHIRL Conversion" ); 00480 } 00481 00482 /*=============================================== 00483 * 00484 * PDGCS_end_procs 00485 * 00486 * Clean up at the end of a procedure. 00487 * 00488 *=============================================== 00489 */ 00490 /*ARGSUSED*/ 00491 extern void 00492 PDGCS_end_procs(INT32 *code_size, 00493 INT32 *data_size ) 00494 { 00495 cwh_stab_end_procs(); 00496 Set_Error_Phase ( "Front End Parse/Semantic"); 00497 } 00498 00499 /*=============================================== 00500 * 00501 * PDGCS_terminate 00502 * 00503 * Clean up at the end of compilation. Write 00504 * out the global symbol table, the DST info 00505 * and the Makedepend information. 00506 * 00507 *=============================================== 00508 */ 00509 /*ARGSUSED*/ 00510 extern void 00511 PDGCS_terminate ( void) 00512 { 00513 00514 // Emit common & module data that was avoiding duplication 00515 cwh_stab_emit_commons_and_equivalences(GLOBAL_SYMTAB); 00516 00517 // Emit initializations 00518 cwh_data_emit_symbol_inits(GLOBAL_SYMTAB); 00519 00520 if (Get_Trace (TKIND_SYMTAB,TP_IRB)) { 00521 Print_global_symtab ( TFile ); 00522 } 00523 00524 cwh_dst_write(); 00525 00526 // TODO_NEW_SYMTAB: figure out how to setup FE_gdar_filename 00527 Verify_SYMTAB (GLOBAL_SYMTAB); 00528 Write_Global_Info (PU_Tree_Root); 00529 Close_Output_Info (); 00530 00531 cwh_write_makedepend(); 00532 00533 Set_Error_Phase ( "Front End Parse/Semantic"); 00534 } 00535 00536 /*=============================================== 00537 * 00538 * cwh_pdgcs_pu_mem 00539 * 00540 * Initalize the memory pools for a PU. The WN 00541 * pool is deleted after the WN tree is written 00542 * (PDGCS_do_proc), but the PU_info holds chains 00543 * of PUs and persists until the end. 00544 * 00545 *=============================================== 00546 */ 00547 static PU_Info * 00548 cwh_pdgcs_pu_mem(void) 00549 { 00550 00551 PU_Info *p; 00552 00553 p = TYPE_MEM_POOL_ALLOC(PU_Info, FE_Mempool); 00554 PU_Info_init(p); 00555 00556 WN_Mem_Push(); 00557 00558 return p ; 00559 00560 } 00561 /*=============================================== 00562 * 00563 * rii routines 00564 * 00565 * Handles the .rii files for dsm processing 00566 * 00567 * routines lifted from common/fe/edwhirl.c 00568 * 00569 *=============================================== 00570 */ 00571 00572 /* 00573 * Skip over leading lines upto and including the terminator (a line that 00574 * starts with ----). If the terminator is not found, rewind back to start. 00575 */ 00576 static void 00577 skip_old_rii_controls ( FILE * f ) 00578 { 00579 int c; 00580 int terminator_found = 0; 00581 00582 c = getc ( f ); 00583 00584 while ( c != EOF ) { 00585 00586 if ( c == '-' 00587 && ( c = getc ( f ) ) == '-' 00588 && ( c = getc ( f ) ) == '-' 00589 && ( c = getc ( f ) ) == '-' ) 00590 terminator_found = 1; 00591 00592 while ( c != '\n' && c != EOF ) 00593 c = getc ( f ); 00594 00595 if ( terminator_found ) 00596 break; 00597 00598 if (c == '\n') 00599 c = getc ( f ); 00600 } 00601 00602 if ( c == EOF ) 00603 rewind(f); 00604 } 00605 00606 00607 static void 00608 delete_rii_file ( void ) 00609 { 00610 FILE * f_rii_file; 00611 00612 f_rii_file = fopen ( rii_file_name, "r" ); 00613 00614 if ( f_rii_file ) { 00615 00616 fclose ( f_rii_file ); 00617 unlink ( rii_file_name ); 00618 } 00619 } /* delete_rii_file */ 00620 00621 00622 static void 00623 update_rii_file ( void ) 00624 { 00625 FILE * f_rii_file; 00626 FILE * f_old_rii_file; 00627 FILE * f_cmd_file; 00628 char * rii_dir_name; 00629 char * new_rii_file_name; 00630 int ch; 00631 00632 rii_dir_name = ux_dirname ( rii_file_name ); 00633 f_old_rii_file = fopen ( rii_file_name, "r" ); 00634 00635 if ( f_old_rii_file == NULL ) { 00636 00637 if ( mkdir ( rii_dir_name, 0777 ) < 0 && errno != EEXIST ) { 00638 00639 /* failed to create directory, and it does not already exists */ 00640 00641 /* str_catastrophe ( ec_could_not_create_ii_dir, rii_dir_name ); */ 00642 fprintf ( stderr, "could not create rii directory %s\n", rii_dir_name ); 00643 return; 00644 00645 } 00646 00647 else 00648 new_rii_file_name = rii_file_name; 00649 } 00650 00651 else { 00652 00653 skip_old_rii_controls ( f_old_rii_file ); 00654 00655 new_rii_file_name = (char *) malloc ( strlen ( rii_file_name ) + 5 ); 00656 sprintf ( new_rii_file_name, "%s.NEW", rii_file_name ); 00657 } 00658 00659 if ( access ( rii_dir_name, W_OK ) < 0 ) { 00660 00661 /* cannot write into instantiation info directory */ 00662 00663 /* str_catastrophe ( ec_no_write_permission_in_ii_dir, rii_dir_name ); */ 00664 fprintf ( stderr, "no write permissions in rii directory %s\n", 00665 rii_dir_name ); 00666 return; 00667 } 00668 00669 f_rii_file = fopen ( new_rii_file_name, "w" ); 00670 00671 if ( f_rii_file == NULL ) { 00672 00673 /* str_catastrophe ( ec_no_write_permission_in_ii_dir, rii_dir_name ); */ 00674 fprintf ( stderr, "unable to open rii file for writing %s\n", rii_file_name ); 00675 return; 00676 } 00677 00678 f_cmd_file = fopen ( FE_command_line, "r" ); 00679 00680 if ( f_cmd_file == NULL ) { 00681 00682 /* str_catastrophe ( ec_no_write_permission_in_ii_dir, FE_command_line ); */ 00683 fprintf ( stderr, "unable to open cmd file for reading %s\n", 00684 FE_command_line ); 00685 return; 00686 } 00687 00688 fputs ( "CMDLINE=", f_rii_file ); 00689 00690 while ( ( ch = getc ( f_cmd_file ) ) != '\n' ) 00691 putc ( ch, f_rii_file ); 00692 00693 fputs ( "\nPWD=", f_rii_file ); 00694 00695 while ( ( ch = getc ( f_cmd_file ) ) != '\n' ) 00696 putc ( ch, f_rii_file ); 00697 00698 fclose ( f_cmd_file ); 00699 00700 fputs ( "\n----\n", f_rii_file ); 00701 00702 if ( f_old_rii_file ) { 00703 00704 while ( ( ch = getc ( f_old_rii_file ) ) != EOF ) 00705 putc ( ch, f_rii_file ); 00706 00707 /* Rename the new file to replace the existing .rii file */ 00708 00709 fclose ( f_old_rii_file ); 00710 fclose ( f_rii_file ); 00711 00712 if ( rename ( new_rii_file_name, rii_file_name ) < 0 ) { 00713 00714 fprintf (stderr, "error in renaming %s %s\n", 00715 new_rii_file_name, rii_file_name ); 00716 } 00717 00718 free ( new_rii_file_name ); 00719 } 00720 00721 else 00722 fclose ( f_rii_file ); 00723 } /* update_rii_file */