Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
driver_util.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  * $Revisionr: 1.34 $
00040  *
00041  * Revision history:
00042  *  16-Feb-95 - Original Version
00043  *
00044  * Description:
00045  *  Utility functions for the be driver.
00046  *
00047  * ====================================================================
00048  * ====================================================================
00049  */
00050 
00051 #include <ctype.h>
00052 #include <cmplrs/rcodes.h>
00053 #include "defs.h"
00054 #include "glob.h"                   /* for Src_File_Name, etc. */
00055 #include "erglob.h"                 /* for EC_File_Name, etc. */
00056 #include "file_util.h"              /* for New_Extension() */
00057 #include "phase.h"                  /* for phase_ogroup_table */
00058 #include "flags.h"                  /* for Process_Command_Line_Group() */
00059 #include "config.h"                 /* for Debug_Level */
00060 #include "config_list.h"
00061 #include "timing.h"                 /* for Initialize_Timing() */
00062 #include "tracing.h"                /* for Set_Trace() */
00063 #include "wn.h"                     /* for WN */
00064 #include "stab.h"
00065 #include "stblock.h"
00066 #include "wn_lower.h"
00067 #include "wn_fio.h"
00068 #include "wn_instrument.h"
00069 #include "driver_util.h"
00070 
00071 int compiling_upc_flag = 0;
00072 
00073 
00074 /* argc and argv for phase-specific flags */
00075 static UINT phase_argc[PHASE_COUNT];
00076 static STRING *phase_argv[PHASE_COUNT];
00077 static UINT phase_max_argc[PHASE_COUNT];
00078 
00079 /* Options based on user flags: */
00080 # define MAX_MSG_LEVEL 2
00081 
00082 /* Default file extensions: */
00083 #define ERR_FILE_EXTENSION ".e"     /* Error file */
00084 #define TRC_FILE_EXTENSION ".t"     /* Trace file */
00085 #define IRB_FILE_EXTENSION ".B"     /* WHIRL file */
00086 #define LST_FILE_EXTENSION ".l"     /* Listing file */
00087 #define TLOG_FILE_EXTENSION ".tlog" /* Transformation log file */
00088 
00089 static BOOL Tlog_Enabled = FALSE;
00090 extern BOOL Run_Dsm_Cloner;
00091 extern BOOL Run_Dsm_Check;
00092 extern BOOL Run_Dsm_Common_Check;
00093 extern BOOL Run_autopar;
00094 extern BOOL Run_MemCtr;
00095 static BOOL Dsm_Recompile = FALSE;
00096 
00097 char* Config_File_Name = ""; 
00098 
00099 /*
00100  * Handle_Phase_Specific_Options
00101  */
00102 static void
00103 add_phase_args (BE_PHASES phase, char *flag)
00104 {
00105     if (phase_argc[phase] == 0) {
00106         phase_max_argc[phase] = 4;
00107         phase_argv[phase] = (STRING *)
00108             malloc (phase_max_argc[phase] * sizeof(STRING *));
00109     } else if (phase_argc[phase] >= phase_max_argc[phase]) {
00110         phase_max_argc[phase] *= 2;
00111         phase_argv[phase] = (STRING *)
00112             realloc (phase_argv[phase],
00113                      phase_max_argc[phase] * sizeof(STRING *));
00114     }
00115     
00116     FmtAssert (phase_argv[phase], ("No more memory."));
00117     phase_argv[phase][(phase_argc[phase])++] = flag;
00118     
00119 } /* add_phase_args */
00120 
00121 
00122 void
00123 Get_Phase_Args (BE_PHASES phase, INT *argc, char ***argv)
00124 {
00125     *argc = phase_argc[phase];
00126     *argv = phase_argv[phase];
00127 } /* Get_Phase_Args */
00128 
00129 
00130 /*
00131  * Recognize phase-specific option groups and put them aside for later
00132  * processing.
00133  */
00134 static BOOL
00135 Handle_Phase_Specific_Options (char *flag)
00136 {
00137     register PHASE_SPECIFIC_OPTION_GROUP *og;
00138     BE_PHASES phase = PHASE_COMMON;
00139 
00140     for (og = phase_ogroup_table; og->group_name != NULL; og++)
00141         /* skip the leading '-' before comparing */
00142         if (flag[1] == og->group_name[0] &&
00143             strncmp (flag+1, og->group_name, og->group_name_length) == 0) {
00144             phase = og->phase;
00145             break;
00146         }
00147 
00148     if (phase == PHASE_COMMON || phase >= PHASE_COUNT)
00149         return FALSE;
00150 
00151     add_phase_args (phase, flag);
00152 
00153     return TRUE;
00154 
00155 } /* Handle_Phase_Specific_Options */
00156 
00157 
00158 /* ====================================================================
00159  *
00160  * Process_Command_Line
00161  *
00162  * Process the command line arguments.  Evaluate all flags and set up
00163  * global options. 
00164  *
00165  * ==================================================================== */
00166 
00167 void
00168 Process_Command_Line (INT argc, char **argv)
00169 {
00170     INT16 i,j;
00171     char *cp;
00172     BOOL Echo_Flag = FALSE;
00173     INT Src_Count = 0;
00174     char *myname;
00175     BOOL opt_set = FALSE;
00176     BOOL dashdash_flag = FALSE;
00177     
00178     /* Check the command line flags: */
00179     for (i = 1; i < argc; i++) {
00180         if ( argv[i] != NULL && (strcmp(argv[i],"--")==0)) {
00181           dashdash_flag = TRUE;
00182           continue;
00183         }
00184         if ( !dashdash_flag && argv[i] != NULL && *(argv[i]) == '-' ) {
00185             cp = argv[i]+1;         /* Pointer to next flag character */
00186 
00187             if (Handle_Phase_Specific_Options (argv[i]))
00188                 continue;
00189       
00190             /* process as command-line option group */
00191             if (Process_Command_Line_Group (cp, Common_Option_Groups))
00192                 continue;
00193 
00194             switch ( *cp++ ) {
00195               
00196             case 'c':
00197                 if (strcmp (cp, "mds") == 0 && Run_ipl) {
00198                     while (i < argc) {
00199                         add_phase_args (PHASE_IPL, argv[i]);
00200                         i++;
00201                     }
00202                 } else
00203                     ErrMsg (EC_Unknown_Flag, *(cp-1), argv[i]);
00204                 break;
00205             case 'd':
00206                 if (strcmp (cp, "sm_clone") == 0 )
00207                     Run_Dsm_Cloner = TRUE;
00208                 else if (strcmp (cp, "sm") == 0 )
00209                     Run_Dsm_Common_Check = TRUE;
00210                 else if (strcmp (cp, "sm_check") == 0 )
00211                     Run_Dsm_Check = TRUE;
00212                 else if (strcmp (cp, "sm_recompile") == 0 )
00213                     Dsm_Recompile = TRUE;
00214                 else
00215                     ErrMsg (EC_Unknown_Flag, *(cp-1), argv[i]);
00216                 break;
00217 
00218             case '#':               /* Echo command lines: */
00219             case 'v':
00220                 if ( Echo_Flag )
00221                     break;          /* Don't do this twice */
00222                 Echo_Flag = TRUE;
00223                 for ( j=0; j<=argc; j++ )
00224                     if ( argv[j] ) fprintf (stderr," %s",argv[j]);
00225                 fprintf   (stderr, "\n");
00226                 break;
00227 
00228             case 'f':               /* file options */
00229                 if (*cp == 0)
00230                     ErrMsg (EC_File_Name, '?', argv[i]);
00231                 else if (*(cp+1) != ',' && *(cp+1) != ':')
00232                     ErrMsg (EC_File_Name, *cp, argv[i]);
00233                 else {
00234                     switch (*cp) {
00235                     case 'f':
00236                         Feedback_File_Name = cp + 2;
00237                         break;
00238                     case 'o':
00239                         Obj_File_Name = cp + 2;
00240                         /* fall through */
00241                     case 's':       /* CG-specific */
00242                     case 'a':
00243                         add_phase_args (PHASE_CG, argv[i]);
00244                         break;
00245                         
00246                     case 'l':       /* listing file */
00247                         List_Enabled = TRUE;
00248                         Lst_File_Name = cp + 2;
00249                         break;
00250                         
00251                     case 'q':       /* Transformation log file: */
00252                         Tlog_File_Name = cp + 2;
00253                         break;
00254 
00255                     case 't':       /* Error file: */
00256                         Trc_File_Name = cp + 2;
00257                         break;
00258 
00259                     case 'B':       /* WHIRL file */
00260                         Irb_File_Name = cp + 2;
00261                         break;
00262 
00263                     case 'G':       /* WHIRL file */
00264                         Global_File_Name = cp + 2;
00265                         break;
00266 
00267                     case 'C':
00268                       //WEI: new case for the config file
00269                       Config_File_Name = cp + 2;
00270                       break;
00271 
00272                     default:
00273                         ErrMsg ( EC_File_Flag, *cp, argv[i] );
00274                         break;
00275                     }
00276                 }
00277                 break;
00278                 
00279             case 'g':               /* Debug level: */
00280                 Debug_Level = Get_Numeric_Flag (&cp, 0, MAX_DEBUG_LEVEL, 2,
00281                                                 argv[i]);
00282                 if (Debug_Level > 0 && !opt_set)
00283                     Opt_Level = 0;
00284                 break;
00285               
00286             case 'G':               /* max size of elements in .sdata/.sbss */
00287                 Max_Sdata_Elt_Size =
00288                     Get_Numeric_Flag (&cp, 0, MAX_SDATA_ELT_SIZE,
00289                                       DEF_SDATA_ELT_SIZE, argv[i] ); 
00290                 break;
00291               
00292             case 'm':               /* Message reporting: */
00293                 if (!strcmp(cp, "plist")) {
00294                   Run_w2fc_early = TRUE; 
00295                   cp += 5; 
00296                   break;
00297                 } else if (!strcmp(cp, "emctr")) {
00298                   Run_MemCtr = TRUE;
00299                   cp += 5;
00300                   break;
00301                 }
00302                 j = Get_Numeric_Flag (&cp, 0, MAX_MSG_LEVEL, MAX_MSG_LEVEL,
00303                                       argv[i] ); 
00304                 switch (j) {
00305                 case 0: Min_Error_Severity = ES_ERROR;    break;
00306                 case 1: Min_Error_Severity = ES_WARNING;  break;
00307                 case 2: Min_Error_Severity = ES_ADVISORY; break;
00308                 }
00309                 break;
00310 
00311             case 'n':
00312                 if (!strcmp( cp, "o_exceptions" )) {
00313                   CXX_Exceptions_On = FALSE;
00314                 }
00315                 else {
00316                   ErrMsg ( EC_Unknown_Flag, *(cp-1), argv[i] );
00317                 }
00318                 break;
00319 
00320             case 'e':
00321                 if (!strcmp( cp, "xceptions" )) {
00322                   CXX_Exceptions_On = TRUE;
00323                 }
00324                 else {
00325                   ErrMsg ( EC_Unknown_Flag, *(cp-1), argv[i] );
00326                 }
00327                 break;
00328 
00329             case 'o':
00330                 if (!strcmp( cp, "penad" )) {
00331                   add_phase_args (PHASE_W2F, argv[i]);
00332                 }
00333                 else if (!strcmp( cp, "penadType" )) {
00334                   add_phase_args (PHASE_W2F, argv[i]);
00335                   if (i<argc)
00336                     i++;
00337                   else { 
00338                     fprintf(stderr,
00339                             "error: the openadType option requires an argument\n");
00340                     exit(-1);
00341                   }
00342                   add_phase_args (PHASE_W2F, argv[i]);
00343                 }
00344                 else {
00345                   ErrMsg ( EC_Unknown_Flag, *(cp-1), argv[i] );
00346                 }
00347                 break;
00348         
00349             case 'O':               /* Optimization level: */
00350                 Opt_Level = Get_Numeric_Flag (&cp, 0, MAX_OPT_LEVEL,
00351                                               DEF_O_LEVEL, argv[i] ); 
00352                 opt_set = TRUE;
00353                 break;
00354 
00355             case 's':
00356                 if (strcmp (cp, "how") == 0) {
00357                     Show_Progress = TRUE;
00358                     break;
00359                 } else if( strcmp(cp, "td=upc") == 0) {
00360                   Compile_Upc = TRUE;
00361                   break;
00362                 }
00363                 /* else fall through */
00364                                     /* CG-specific flags */
00365             case 'a':               /* -align(8,16,32,64) */
00366             case 'S':               /* -S: Produce assembly file: */
00367                 add_phase_args (PHASE_CG, argv[i]);
00368                 break;
00369               
00370             case 't':               /* Trace specification: */
00371                 /* handle the -tfprev10 option to fix tfp hardware bugs. */
00372                 if ( strncmp ( cp-1, "tfprev10", 8 ) == 0 ) {
00373                   add_phase_args (PHASE_CG, argv[i]);
00374                   break;
00375                 } else {
00376                   Process_Trace_Option ( cp-2 );
00377                 }
00378 
00379                 break;
00380 
00381             case 'w':               /* Suppress warnings */
00382                 if (strncmp(cp, "off", 3) == 0) {
00383                     Rag_Handle_Woff_Args(cp + 3);
00384                 }
00385                 else {
00386                     Min_Error_Severity = ES_ERROR;
00387                 }
00388                 break;
00389 
00390             case 'p': 
00391                 if (strncmp(cp, "fa", 2) == 0) { 
00392                   Run_autopar = TRUE; 
00393                   cp += 2;
00394                 } else 
00395                   ErrMsg (EC_Unknown_Flag, *(cp-1), argv[i]); 
00396                 break;
00397            
00398             case 'l':
00399               if(strncmp(cp,"ang=upc",7) == 0)
00400                 compiling_upc_flag = 1;
00401               break;
00402             default:                /* What's this? */
00403                 ErrMsg ( EC_Unknown_Flag, *(cp-1), argv[i] );
00404                 break;
00405             }
00406         } else if (argv[i] != NULL) {
00407             dashdash_flag = FALSE;
00408             Src_Count++;
00409             Src_File_Name = argv[i];
00410         } 
00411     }
00412 
00413     if (Dsm_Recompile)
00414       Run_Dsm_Common_Check = FALSE;
00415 
00416     if ( Tracing_Enabled ) {
00417       Initialize_Timing (TRUE);
00418     }
00419 
00420     myname = Last_Pathname_Component (argv[0]);
00421 
00422     if (myname[0] == 'i' && strcmp (myname, "ipl") == 0) {
00423         Run_ipl = TRUE;
00424         /* We don't support olimit region for ipl (yet).  So if we overflow
00425            the olimit, we don't want to run preopt, but still run ipl. */
00426         Olimit_opt = FALSE;
00427     } else {
00428         Run_ipl = FALSE;
00429 
00430         switch (myname[0]) {
00431         case 'l':
00432             if (strcmp (myname, "lnopt") == 0)
00433                 Run_lno = TRUE;
00434             break;
00435         case 'w':
00436             if (strcmp (myname, "wopt") == 0)
00437                 Run_wopt = TRUE;
00438             else if (strcmp (myname, "whirl2c") == 0 || 
00439                      strcmp(myname,"whirl2c_be") == 0 ) //FMZ:we need debug version
00440                 Run_w2c = TRUE;
00441             else if (strcmp (myname, "whirl2f") == 0)
00442                 Run_w2f = TRUE;
00443             break;
00444         case 'p':
00445             if (strcmp (myname, "preopt") == 0)
00446                 Run_preopt = TRUE;
00447             else if (strcmp (myname, "purple") == 0)
00448                 Run_purple = TRUE;
00449             break;
00450         case 'c':
00451             if (strcmp (myname, "cg") == 0)
00452                 Run_cg = TRUE;
00453             break;
00454         }
00455     }
00456 
00457     if (Src_Count == 0) {
00458         ErrMsg ( EC_No_Sources );
00459         exit (RC_USER_ERROR);
00460     }
00461     
00462     if (Run_lno && Run_preopt)
00463         Run_preopt = FALSE;
00464 
00465     /* -tt1:1 requests all of the performance trace flags: */
00466     if ( Get_Trace ( TP_PTRACE1, TP_PTRACE1_ALL ) ) {
00467       Set_Trace ( TP_PTRACE1, 0xffffffff );
00468       Set_Trace ( TP_PTRACE2, 0xffffffff );
00469     }
00470     /* and any individual performance tracing enables tlogs */
00471     if ( Get_Trace ( TP_PTRACE1, 0xffffffff ) ||
00472          Get_Trace ( TP_PTRACE2, 0xffffffff ) )
00473     {
00474       Tlog_Enabled=TRUE;
00475     }
00476 
00477     /* -ti64 requests a listing of all the -tt flags: */
00478     if ( Get_Trace ( TKIND_INFO, TINFO_TFLAGS ) ) {
00479       List_Phase_Numbers ();
00480     }
00481 
00482 } /* Process_Command_Line */
00483 
00484 /* ====================================================================
00485  *
00486  * Prepare_Source
00487  *
00488  * Process the source argument and associated files, except the listing
00489  * file, which may not be opened until after Configure_Source has
00490  * determined whether it is required.
00491  *
00492  * ====================================================================
00493  */
00494 void
00495 Prepare_Source (void)
00496 {
00497     char *fname = Last_Pathname_Component ( Src_File_Name );
00498     
00499     if (Err_File_Name && Err_File_Name[0] == 0)
00500         Err_File_Name = New_Extension (fname, ERR_FILE_EXTENSION);
00501     Set_Error_File ( Err_File_Name );
00502 
00503     /* Transformation log file */
00504     if ( Tlog_Enabled ) {
00505         if ( Tlog_File_Name == NULL ) {
00506             /* Replace source file extension to get trace file: */
00507             Tlog_File_Name = New_Extension (fname, TLOG_FILE_EXTENSION);
00508         }
00509         if ( (Tlog_File = fopen ( Tlog_File_Name, "w" ) ) == NULL ) {
00510           ErrMsg ( EC_Tlog_Open, Tlog_File_Name, errno );
00511           Tlog_File_Name = NULL;
00512           Tlog_File = stdout;
00513         }
00514     }
00515 
00516     /* Trace file */
00517     if ( Trc_File_Name == NULL ) {
00518         if ( Tracing_Enabled ) {
00519             /* Replace source file extension to get trace file: */
00520             Trc_File_Name = New_Extension (fname, TRC_FILE_EXTENSION);
00521         }
00522     } else if ( *Trc_File_Name == '-' ) {
00523         /* Leave trace file on stdout: */
00524         Trc_File_Name = NULL;
00525     }
00526     Set_Trace_File ( Trc_File_Name );
00527     if ( Get_Trace (TKIND_INFO, TINFO_TIME) )
00528         Tim_File = TFile;
00529     else if ( Get_Trace (TKIND_INFO, TINFO_CTIME) )
00530         Tim_File = TFile;
00531 
00532     if (Irb_File_Name == NULL)
00533         Irb_File_Name = New_Extension (Src_File_Name, IRB_FILE_EXTENSION);
00534 
00535 } /* Prepare_Source */
00536 
00537 /* ====================================================================
00538  *
00539  * Prepare_Listing_File
00540  *
00541  * Determine the listing file name and open it.
00542  *
00543  * ====================================================================
00544  */
00545 void
00546 Prepare_Listing_File (void)
00547 {
00548   char *fname = Last_Pathname_Component ( Src_File_Name );
00549   
00550   if ( List_Enabled ) {
00551     if (Lst_File_Name == NULL) {
00552       /* Replace source file extension to get listing file: */
00553       Lst_File_Name = New_Extension (fname, LST_FILE_EXTENSION);
00554     } else if ( *Lst_File_Name == '-' ) {
00555       /* Send listing file to stdout: */
00556       Lst_File_Name = NULL;
00557     }
00558     if (Lst_File_Name) {
00559       if ( (Lst_File = fopen ( Lst_File_Name, "w" ) ) == NULL ) {
00560         ErrMsg ( EC_Lst_Open, Lst_File_Name, errno );
00561         Lst_File_Name = NULL;
00562         Lst_File = stdout;
00563       }
00564     } else Lst_File = stdout;
00565   }
00566 } /* Prepare_Listing_File */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines