Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
anl_driver.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 /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */
00037 // TODO:
00038 //   *  remove unnecessary includes
00039 //
00040 //
00041 #include <time.h>
00042 #include "anl_common.h"
00043 #include "stamp.h"           // For INCLUDE_STAMP
00044 #include "config_promp.h"    // For Current_PROMP
00045 #include "w2c_driver.h"      // For whirl2c.so utilities
00046 #include "w2f_driver.h"      // For whirl2f.so utilities
00047 #include "anl_file_mngr.h"   // For managing an analysis file
00048 #include "w2cf_translator.h" // For C++ interface to whirl2[fc] utilities
00049 #include "anl_func_entry.h"  // For processing FUNC_ENTRY nodes
00050 #include "anl_driver.h" 
00051 #include "wb_anl.h" 
00052 #include "prompf.h" 
00053 
00054 // Avoid errors due to uses of "int" in stdio.h macros.
00055 //
00056 #undef int
00057 
00058 #pragma weak W2F_Get_Transformed_Src_Path
00059 #pragma weak W2C_Get_Transformed_Src_Path
00060 
00061 
00062 // ================== Define the global objects =============
00063 // ==========================================================
00064 
00065 // Macros that dispatch on the language in wich the extracted
00066 // sources should be expressed (Fortran or C).
00067 //
00068 #define USE_C_TRANSFORMED_SRC() \
00069    (Language == LANG_KR_C  || Language == LANG_ANSI_C || \
00070     Language == LANG_CPLUS || Language == LANG_DELTA)
00071 #define USE_F77_TRANSFORMED_SRC() \
00072    (Language == LANG_F77 || Language == LANG_F90)
00073 
00074 
00075 // Imported objects
00076 extern const char *Fe_Version;  // From be.so
00077 
00078 
00079 // Global C++ objects
00080 //
00081 MEM_POOL          Anl_Default_Pool; // Pool used for temporary anl memory alloc
00082 WN_MAP            Parent_Map;       // Used by LWN_Set_Parent/LWN_Get_Parent
00083 ANL_DIAGNOSTICS  *Anl_Diag;         // Diagnostics handler
00084 
00085 
00086 // Local C++ objects
00087 //
00088 static ANL_FILE_MNGR *Anl_File_Mngr;        // File handler
00089 static COUNTER        Next_Construct_Id(1); // Next id to use for wn-->id map
00090 static BOOL           Pool_Initialized = FALSE;
00091 
00092 // Command-line options variables
00093 //
00094 BOOL               Anl_Owhile = FALSE;           // Generate owhile descriptors
00095 static BOOL        Anl_Enabled = TRUE;           // Generate analysis file?
00096 static BOOL        Anl_Verbose = FALSE;          // Show progress
00097 static const char *Anl_Filename = NULL;          // Output file name
00098 static const char *Anl_OrignSrc_Filename = NULL; // Original src file name
00099 static const char *Anl_Version = NULL;           // Compiler version
00100 static       char *Anl_Progname = NULL;          // Name of this executable
00101 
00102 
00103 static void
00104 Anl_Help_Page(void)
00105 {
00106    fprintf(stderr,
00107      "\n"
00108      "-PROMPF<opts> will produce a \".anl\" file, and may be invoked with\n"
00109      "any of the following <opts>:\n"
00110      "\n"
00111      "\t\":show\" Will show .anl generation progress.\n"
00112      "\t\":owhile\" Will generate owhile descriptors for while loops, and\n"
00113        "\t\twill also try to identify while loops as for loops for C code.\n"
00114      "\t\":anl=<filename>\" Explicitly defines the name and path of the\n"
00115        "\t\toutput file to be <filename>.  The default will be a file with\n"
00116        "\t\tthe same name as the original, in the current working directory,\n"
00117        "\t\tand with the suffix \".anl\".\n"
00118      "\t\":src=<filename>\" Explicitly defines the name and path of the\n"
00119        "\t\toriginal source file to be <filename>.  The default will be\n"
00120        "\t\tsupplied to the compiler back-end by the driver.\n"
00121      );
00122 } // Anl_Help_Page
00123 
00124 
00125 static void
00126 Anl_Validate_Options(ANL_DIAGNOSTICS *diag)
00127 {
00128    // The option assumptions, are specified below.  When any of them
00129    // are violated, this routine will terminate execution with a
00130    // fatal assertion failure.
00131    //
00132    //   1) Anl_OrignSrc_Filename != NULL || Src_File_Name != NULL
00133    //
00134    // Postcondition: The above condition is TRUE,
00135    //                or else Anl_Enabled == FALSE.
00136    //
00137    if (Anl_OrignSrc_Filename == NULL)
00138    {
00139       // The original source-file must be explicitly given, either 
00140       // as an optional argument or as a back-end (be) argument.
00141       //
00142       if (Src_File_Name == NULL) // (2)
00143       {
00144          Anl_Help_Page();
00145          diag->Error("Missing source file name");
00146          Anl_Enabled = FALSE;
00147       }
00148       else
00149       {
00150          Anl_OrignSrc_Filename = Src_File_Name; // Our default
00151       }
00152    } // if
00153 } // Anl_Validate_Options
00154 
00155 
00156 static void
00157 Derive_Anl_Filename(void)
00158 {
00159    // Unless explicitly provided, we need to derive the name to be
00160    // used for the anl file from the Anl_OrignSrc_Filename.
00161    //
00162    char *anl_name;
00163 
00164    if (Anl_Filename == NULL)
00165    {
00166       if (Anl_OrignSrc_Filename != NULL)
00167       {
00168          // Derive Anl_Filename from Anl_OrignSrc_Filename, but remove
00169          // any pathnames, since output-files should reside in the 
00170          // current (working) directory.
00171          //
00172          anl_name = Last_Pathname_Component((char *)Anl_OrignSrc_Filename);
00173          Anl_Filename = New_Extension(anl_name, ".anl");
00174       }
00175    } // if
00176 } // Derive_Anl_Filename
00177 
00178 
00179 // ========= Define the external interface routines =========
00180 // ==========================================================
00181 
00182 extern "C" void
00183 Anl_Process_Command_Line (INT phase_argc, char *phase_argv[],
00184                           INT argc, char *argv[])
00185 {
00186    // Note that the Anl_Default_Pool cannot be used while
00187    // executing this subroutine, since it will not be initialized
00188    // until Prp_Init() is called (after a call to this routine).
00189    //
00190    if (argv[0] != NULL)
00191       Anl_Progname = argv[0];
00192 
00193    // The processing of the PROMP group was moved out to the back-end.
00194    // Instead of directly using Current_PROMP, we initiate
00195    // prompf_anl specific variables to hold the values.
00196    //
00197    Anl_Enabled = (PROMP_enabled ||
00198                   PROMP_owhile || 
00199                   PROMP_show ||
00200                   PROMP_anl_filename!=NULL ||
00201                   PROMP_src_filename!=NULL);
00202    Anl_Owhile = PROMP_owhile;
00203    Anl_Verbose = PROMP_show;
00204    Anl_Filename = PROMP_anl_filename;
00205    Anl_OrignSrc_Filename = PROMP_src_filename;
00206    Next_Construct_Id.Reset(PROMP_next_id);
00207 } // Anl_Process_Command_Line
00208 
00209 
00210 extern "C" BOOL
00211 Anl_Needs_Whirl2c()
00212 {
00213    // Precondition: Must have done Anl_Process_Command_Line()
00214    //
00215    return USE_C_TRANSFORMED_SRC();
00216 } // Prp_Needs_Whirl2c
00217 
00218 
00219 extern "C" BOOL
00220 Anl_Needs_Whirl2f()
00221 {
00222    // Precondition: Must have done Anl_Process_Command_Line()
00223    //
00224    return !USE_C_TRANSFORMED_SRC();
00225 } // Anl_Needs_Whirl2f
00226 
00227 
00228 extern "C" void 
00229 Anl_Init()
00230 {
00231    // Precondition: Must have done Anl_Process_Command_Line() and
00232    // loaded whirl2c.so or whirl2f.so, as is appropriate for the
00233    // language to be processed.  Note that the options passed on
00234    // to whirl2c or whirl2f are independent of options passed to
00235    // prompf_anl.so.
00236    //
00237    Set_Error_Phase ("ProMpf Analysis File Generation");
00238 
00239    // Create new mempool.
00240    //
00241    MEM_POOL_Initialize(&Anl_Default_Pool, "Anl_Default_Pool", FALSE);
00242    MEM_POOL_Push(&Anl_Default_Pool);
00243    Pool_Initialized = TRUE;
00244    Anl_Diag = CXX_NEW(ANL_DIAGNOSTICS(stderr), &Anl_Default_Pool);
00245 
00246    // Infer information missing from explicit options.
00247    //
00248    Anl_Validate_Options(Anl_Diag);
00249    Derive_Anl_Filename();
00250 
00251    if (Anl_Enabled)
00252    {      
00253       // Open the analysis file (overwrites an existing file)
00254       //
00255       Anl_File_Mngr = CXX_NEW(ANL_FILE_MNGR(Anl_Diag), &Anl_Default_Pool);
00256       Anl_File_Mngr->Open_Create(Anl_Filename);
00257       if (Anl_Diag->Error_Was_Reported())
00258          Anl_Diag->Fatal("Cannot open .anl file for static analysis output!!");
00259 
00260       // Emit time and date information
00261       //
00262       //   systime = time(NULL);
00263       //   Anl_File_Mngr->Write_String("Timestamp: \"");
00264       //   if ((systime != (time_t)-1))
00265       //      Anl_File_Mngr->Write_String(ctime);
00266       //   else
00267       //      Anl_File_Mngr->Write_String("unknown time");
00268       //   Anl_File_Mngr->Write_String("\"\n");
00269 
00270       // Emit product information
00271       //         
00272       Anl_File_Mngr->Write_String("product \"Mongoose\"\n");
00273 
00274       // Emit version information
00275       //
00276       Anl_File_Mngr->Write_String("version \"");
00277       if (Fe_Version != NULL)
00278          Anl_File_Mngr->Write_String(Fe_Version);
00279       else
00280          Anl_File_Mngr->Write_String(INCLUDE_STAMP);
00281       Anl_File_Mngr->Write_String("\"\n");
00282 
00283       // Emit language information
00284       //
00285       Anl_File_Mngr->Write_String("language \"");
00286       switch (Language)
00287       {
00288       case LANG_F77:
00289          Anl_File_Mngr->Write_String("f77\"\n");
00290          break;
00291       case LANG_F90:
00292          Anl_File_Mngr->Write_String("f90\"\n");
00293          break;
00294       case LANG_KR_C:    // Kernighan & Richie C
00295          Anl_File_Mngr->Write_String("kr-c\"\n");
00296          break;
00297       case LANG_ANSI_C:  // ANSI standard C
00298          Anl_File_Mngr->Write_String("ansi-c\"\n");
00299          break;
00300       case LANG_CPLUS:   // Regular C++
00301          Anl_File_Mngr->Write_String("c++\"\n");
00302          break;
00303       case LANG_DELTA:   // Delta C++
00304          Anl_File_Mngr->Write_String("delta-c++\"\n");
00305          break;
00306       case LANG_UNKNOWN:
00307       default:
00308          Anl_File_Mngr->Write_String("unknown\"\n");
00309          break;
00310       }
00311 
00312       // Emit information about the path to the flist/clist file:
00313       //
00314       if (USE_C_TRANSFORMED_SRC())
00315       {
00316          Anl_File_Mngr->Write_String("whirl2c \"");
00317          Anl_File_Mngr->Write_String(W2C_Get_Transformed_Src_Path());
00318       }
00319       else // (USE_F77_TRANSFORMED_SRC())
00320       {
00321          Anl_File_Mngr->Write_String("whirl2f \"");
00322          Anl_File_Mngr->Write_String(W2F_Get_Transformed_Src_Path());
00323       }
00324       Anl_File_Mngr->Write_String("\"\n\n");
00325       Anl_File_Mngr->Close_File();
00326    }
00327 } // Anl_Init
00328 
00329 
00330 extern "C" WN_MAP
00331 Anl_Init_Map(MEM_POOL *id_map_pool)
00332 {
00333   return WN_MAP32_Create(id_map_pool);
00334 } 
00335 
00336 extern "C" void 
00337 Anl_Static_Analysis(WN *pu, WN_MAP id_map)
00338 {
00339    // Precondition: Must have done Anl_Init()
00340    //
00341    // Note: Any memory allocations using Anl_Default_Pool (including 
00342    // uses of ANL_CBUFs) will be freed up upon exit from this 
00343    // subroutine, so *never* let such allocated objects be accessible
00344    // beyond the lifetime of this invokation.
00345    //
00346    // Setup the construct id mapping.  This mapping must survive until
00347    // after LNO and whirl2[cf] processing.
00348    //
00349    ANL_FUNC_ENTRY  *anl_func;
00350    W2CF_TRANSLATOR *translator;
00351 
00352    Set_Error_Phase ("ProMpf Analysis File Generation");
00353    if (Anl_Enabled)
00354    {
00355       // Cleanup from previous run!
00356       //
00357       if (Prompf_Info != NULL) { 
00358         Prompf_Info = NULL;
00359         MEM_POOL_Pop(&PROMPF_pool);
00360         MEM_POOL_Delete(&PROMPF_pool);
00361       } 
00362 
00363       MEM_POOL_Push_Freeze(&Anl_Default_Pool);
00364       Anl_File_Mngr->Open_Append(Anl_Filename);
00365       if (Anl_Diag->Error_Was_Reported())
00366          Anl_Diag->Fatal("Cannot open .anl file for static analysis output!!");
00367 
00368       // Setup the parent mapping.  We only need this mapping until we
00369       // pop the Anl_Default_Pool.
00370       //
00371       Parent_Map = WN_MAP_Create(&Anl_Default_Pool);
00372       LWN_Parentize(pu);
00373       
00374       // Generate ANL original source construct information.
00375       //
00376       translator = 
00377          CXX_NEW(W2CF_TRANSLATOR(pu,
00378                                  &Anl_Default_Pool,
00379                                  USE_C_TRANSFORMED_SRC()),
00380                  &Anl_Default_Pool);
00381       anl_func = 
00382          CXX_NEW(ANL_FUNC_ENTRY(pu, 
00383                                 &Anl_Default_Pool, 
00384                                 translator,
00385                                 id_map,
00386                                 &Next_Construct_Id),
00387                  &Anl_Default_Pool);
00388       anl_func->Emit_Original_Construct(Anl_File_Mngr);
00389       CXX_DELETE(anl_func, &Anl_Default_Pool);
00390       CXX_DELETE(translator, &Anl_Default_Pool);
00391 
00392       // Free up the parent mapping before freeing up the mempools
00393       //
00394       WN_MAP_Delete(Parent_Map);
00395       Parent_Map = NULL;
00396 
00397       Anl_File_Mngr->Close_File();
00398 
00399       // Pop the mempool segment used
00400       //
00401       MEM_POOL_Pop_Unfreeze(&Anl_Default_Pool);
00402 
00403       // Initialize transaction log structures
00404       MEM_POOL_Initialize(&PROMPF_pool, "PROMPF_pool", FALSE);
00405       MEM_POOL_Push(&PROMPF_pool);
00406       Prompf_Info = CXX_NEW(PROMPF_INFO(pu, &PROMPF_pool), &PROMPF_pool);
00407 
00408    } // if (Anl_Enabled)
00409 
00410 } // Anl_Static_Analysis
00411 
00412 
00413 extern "C" INT64 
00414 Get_Next_Construct_Id()
00415 {
00416    return Next_Construct_Id.Value();
00417 } // Get_Next_Construct_Id
00418 
00419 
00420 extern "C" INT64
00421 New_Construct_Id()
00422 {
00423    return Next_Construct_Id.Post_Incr();
00424 } // New_Construct_Id
00425 
00426 
00427 extern "C" const char *
00428 Anl_File_Path()
00429 {
00430    return Anl_Filename;
00431 } // Anl_File_Path
00432 
00433 
00434 extern "C" void
00435 Anl_Fini()
00436 {
00437    // Precondition: Must have done Anl_Init()
00438    //
00439    if (Anl_Enabled)
00440    {
00441       Set_Error_Phase ("ProMpf Analysis File Generation");
00442 
00443       // Cleanup Prompf_Info
00444       if (Prompf_Info != NULL) { 
00445         Prompf_Info = NULL;
00446         MEM_POOL_Pop(&PROMPF_pool);
00447         MEM_POOL_Delete(&PROMPF_pool);
00448       } 
00449       WN_MAP_Delete(Prompf_Id_Map);
00450 
00451       // Reset the prp state to what it was initially.
00452       Anl_Verbose = FALSE;          // Show progress
00453       Anl_Filename = NULL;          // Output file name
00454       Anl_OrignSrc_Filename = NULL; // Original src file name
00455       Anl_Version = NULL;           // Compiler version
00456       Anl_Enabled = FALSE;          // Generate analysis file?
00457 
00458       CXX_DELETE(Anl_File_Mngr, &Anl_Default_Pool);
00459       Anl_File_Mngr = NULL;
00460    } // if (Anl_Enabled)
00461 
00462    // Delete diagnostic system and mempool
00463    //
00464    CXX_DELETE(Anl_Diag, &Anl_Default_Pool);
00465    MEM_POOL_Delete(&Anl_Default_Pool);
00466    Pool_Initialized = FALSE;
00467 } // Anl_Fini
00468 
00469 
00470 extern "C" void
00471 Anl_Cleanup()
00472 {
00473    // Cleanup in case of error condition (or a forgotten call to Anl_Fini())
00474    //
00475    if (Anl_File_Mngr != NULL && Anl_File_Mngr->File_Is_Open())
00476        Anl_File_Mngr->Close_File();
00477 } // Anl_Cleanup
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines