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 /* -*-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