Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_pdgcs.cxx
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines