00001
00002 #ifdef POLARIS_GNU_PRAGMAS
00003 #pragma implementation
00004 #endif
00005
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <stream.h>
00009 #include <fstream.h>
00010 #include <unistd.h>
00011 #include <sys/types.h>
00012 #include <sys/stat.h>
00013
00014 #include "Collection/KeyIterator.h"
00015 #include "EntryPoints.h"
00016 #include "Program.h"
00017 #include "ProgramTag.h"
00018 #include "utilities/lambda_util.h"
00019 #include "utilities/loopMark.h"
00020 #include "utilities/stmt_util.h"
00021 #include "utilities/switches_util.h"
00022 #include "VDL.h"
00023 #include "version.h"
00024 #include "mem_manager.h"
00025
00026 #include "p-assert.h"
00027
00028 template class TypedCollection<Program>;
00029 template class List<Program>;
00030 template ostream & operator << (ostream &, const List<Program> &);
00031 template class Assign<Program>;
00032
00033 Program::Program()
00034 {
00035 #ifdef CLASS_INSTANCE_REGISTRY
00036 register_instance(PROGRAM, sizeof(Program), this);
00037 #endif
00038 }
00039
00040 Program::Program(ProgramUnit *pgm)
00041 {
00042 #ifdef CLASS_INSTANCE_REGISTRY
00043 register_instance(PROGRAM, sizeof(Program), this);
00044 #endif
00045
00046 absorb( pgm );
00047 }
00048
00049 Program::Program(const Program &p)
00050 {
00051 #ifdef CLASS_INSTANCE_REGISTRY
00052 register_instance(PROGRAM, sizeof(Program), this);
00053 #endif
00054
00055 clear();
00056 Database<String,ProgramUnit>::operator = ( p );
00057 }
00058
00059 Program &
00060 Program::operator = (const Program & p)
00061 {
00062 clear();
00063 Database<String,ProgramUnit>::operator = ( p );
00064
00065 return (*this);
00066 }
00067
00068
00069 Program *
00070 Program::clone() const
00071 {
00072 return new Program( *this );
00073 }
00074
00075 Program::~Program()
00076 {
00077 #ifdef CLASS_INSTANCE_REGISTRY
00078 unregister_instance(PROGRAM, this);
00079 #endif
00080 }
00081
00082 void
00083 Program::absorb( ProgramUnit * pgm )
00084 {
00085 String tag = pgm->tag_ref();
00086
00087 ins( tag, pgm );
00088 }
00089
00090 void
00091 Program::absorb(Program * p)
00092 {
00093 for (KeyIterator<String,ProgramUnit> iter = *p; iter.valid(); ++iter) {
00094 ProgramUnit *pgm = p->grab( iter.current_key() );
00095 absorb( pgm );
00096 }
00097
00098 delete p;
00099 }
00100
00101 EntryPoints *
00102 Program::entry_points() const
00103 {
00104 EntryPoints *ep = new EntryPoints;
00105
00106 for (KeyIterator<String,ProgramUnit> iter = *this; iter.valid(); ++iter) {
00107 Iterator<Statement> entries =
00108 iter.current_data().stmts().stmts_of_type(ENTRY_STMT);
00109
00110 if (! entries.valid()) {
00111 String name = "";
00112 ep->ins( name, iter.current_data() );
00113 }
00114 else {
00115 for (; entries.valid(); ++entries) {
00116 Statement &stmt = entries.current();
00117 if (stmt.routine_valid()) {
00118 String name = stmt.routine_guarded().symbol().name_ref();
00119 ep->ins( name, iter.current_data() );
00120 }
00121 }
00122 }
00123 }
00124
00125 return ep;
00126 }
00127
00128 int
00129 Program::structures_OK() const
00130 {
00131 int rc = 1;
00132
00133 for (KeyIterator<String,ProgramUnit> iter = *this; iter.valid(); ++iter) {
00134 if (! iter.current_data().structures_OK()) {
00135 rc = 0;
00136 cout << "Error in ProgramUnit";
00137 }
00138 }
00139
00140 return rc;
00141 }
00142
00143 void
00144 Program::write(ostream & o) const
00145 {
00146 KeyIterator<String,ProgramUnit> iter = *this;
00147
00148 if (switch_value( "burst_page" ) > 0) {
00149 o << "*\f" << "Polaris ";
00150 o << "v" << polaris_major_version << "." << polaris_minor_version;
00151 o << " Switches Database:" << endl;
00152 o << endl;
00153 dump_switches( o );
00154 o << endl;
00155 }
00156
00157 if (iter.valid()) {
00158 iter.current_data().write( o );
00159 for (++iter; iter.valid(); ++iter) {
00160 o << endl;
00161 iter.current_data().write( o );
00162 }
00163 }
00164 }
00165
00166 void
00167 Program::print(ostream & o) const
00168 {
00169 KeyIterator<String,ProgramUnit> iter = *this;
00170
00171 if (switch_value( "burst_page" ) > 0) {
00172 o << "*\f" << "Polaris ";
00173 o << "v" << polaris_major_version << "." << polaris_minor_version;
00174 o << " Switches Database:" << endl;
00175 o << endl;
00176 dump_switches( o );
00177 o << endl;
00178 }
00179
00180 if (iter.valid()) {
00181 iter.current_data().print( o );
00182 for (++iter; iter.valid(); ++iter) {
00183 o << endl;
00184 iter.current_data().print( o );
00185 }
00186 }
00187 }
00188
00189
00190 inline bool is_vdl(const char* fname){
00191 String name=fname;
00192 if (name.index(".vdl")==name.len()-4){
00193 return true;
00194 } else {
00195 return false;
00196 }
00197 }
00198
00199
00200 void
00201 Program::read(const char *fname)
00202 {
00203 BinRep vdl;
00204
00205 String cmd;
00206 int x;
00207
00208 if (switch_value("p_subst_fld") != 0) {
00209 set_subst_field_print();
00210 }
00211
00212
00213
00214 char *vname=(char*)fname;
00215 if (!is_vdl(fname)){
00216
00217
00218
00219
00220
00221
00222 vname = ( char * )malloc( 100 );
00223 char *wname = ( char * )malloc( 100 );
00224
00225 strcpy( vname, "/tmp/PVDLXXXXXX" );
00226 strcpy( wname, "/tmp/PVDLWXXXXXX" );
00227 int vfid = mkstemp( vname );
00228 int wfid = mkstemp( wname );
00229
00230
00231
00232
00233
00234
00235
00236 p_assert( vfid > -1, "can not allocate temporary file name" );
00237
00238 if ((x = switch_value("kap_scanner")) != 0)
00239 cmd = "p-kap-scanner";
00240 else
00241 cmd = "p-scanner3 +vdl";
00242
00243 if ((x = switch_value("comments")) != 0)
00244 cmd += " +comment";
00245
00246 if ((x = switch_value("integer_len")) != 0) {
00247 change_default_type_size(INTEGER_TYPE, x);
00248 cmd += " -i";
00249 char buffer[32];
00250 sprintf( buffer, "%d", x );
00251 cmd += buffer;
00252 }
00253
00254 if ((x = switch_value("real_len")) != 0) {
00255 change_default_type_size(REAL_TYPE, x);
00256 cmd += " -r";
00257 char buffer[32];
00258 sprintf( buffer, "%d", x );
00259 cmd += buffer;
00260 }
00261
00262 if ((x = switch_value("logical_len")) != 0) {
00263 change_default_type_size(LOGICAL_TYPE, x);
00264 cmd += " -l";
00265 char buffer[32];
00266 sprintf( buffer, "%d", x );
00267 cmd += buffer;
00268 }
00269
00270 if ((x = switch_value("nolinelenwarn")) != 0) {
00271 cmd += " -nowarnlong ";
00272 }
00273
00274 if ((x = switch_value("double_len")) != 0) {
00275 change_default_type_size(DOUBLE_PRECISION_TYPE, x);
00276
00277
00278 }
00279
00280 if ((x = switch_value("complex_len")) != 0) {
00281 change_default_type_size(COMPLEX_TYPE, x);
00282
00283
00284 }
00285
00286 cmd += " -o ";
00287 cmd += vname;
00288 cmd += " ";
00289 cmd += fname;
00290 cmd += " -e ";
00291 cmd += wname;
00292
00293 system( cmd );
00294
00295 struct stat buf;
00296 stat(wname, &buf);
00297
00298 if (buf.st_size == 0) {
00299
00300 unlink( wname );
00301 #ifdef CLASS_INSTANCE_REGISTRY
00302 pfree( wname );
00303 #else
00304 free( wname );
00305 #endif
00306 } else {
00307
00308 ifstream warnings( wname );
00309 char input;
00310 while (warnings) {
00311 warnings.get(input);
00312 cerr << input;
00313 }
00314 warnings.close();
00315 unlink( wname );
00316 #ifdef CLASS_INSTANCE_REGISTRY
00317 pfree( wname );
00318 #else
00319 free( wname );
00320 #endif
00321 }
00322 }
00323
00324
00325
00326
00327 ifstream ifs( vname );
00328
00329
00330 if (vname!=fname){
00331 unlink( vname );
00332
00333 #ifdef CLASS_INSTANCE_REGISTRY
00334 pfree( vname );
00335 #else
00336 free( vname );
00337 #endif
00338
00339 }
00340
00341 while (! ifs.eof()) {
00342 vdl.read( ifs );
00343
00344 if (vdl.is_set()) {
00345 ProgramTag tag;
00346
00347 ProgramUnit *pgm = new ProgramUnit( tag, vdl );
00348
00349 if (pgm && pgm->stmts().entries() > 0) {
00350 pgm->stmts()._set_block_structure( pgm->stmts().first_ref(),
00351 pgm->stmts().last_ref(),
00352 "Program::read" );
00353 pgm->stmts().create_assertions();
00354 mark_loops_with_location(*pgm);
00355 remove_all_statement_functions(*pgm);
00356 }
00357 absorb( pgm );
00358 }
00359 }
00360 }
00361
00362 void
00363 Program::clean()
00364 {
00365 KeyIterator<String,ProgramUnit> iter = *this;
00366
00367 for ( ; iter.valid(); ++iter)
00368 iter.current_data().clean();
00369 }
00370
00371 void
00372 Program::compute_call_lists()
00373 {
00374
00375 RefDatabase<StringElem, ProgramUnit> entrydb;
00376
00377 for (KeyIterator<String, ProgramUnit> piter = *this;
00378 piter.valid();
00379 ++piter) {
00380
00381 ProgramUnit & p = piter.current_data();
00382
00383 p.calls().clear();
00384 p.called_by().clear();
00385
00386 const char * namech = p.routine_name_ref();
00387 StringElem * name = new StringElem(namech);
00388 entrydb.ins(*name, p);
00389 }
00390
00391 for (KeyIterator<String, ProgramUnit> piter = *this;
00392 piter.valid();
00393 ++piter) {
00394
00395 ProgramUnit & p = piter.current_data();
00396
00397
00398
00399
00400 for(Iterator<Statement> stit=p.stmts().iterator();
00401 stit.valid(); ++stit){
00402 Statement& s=stit.current();
00403 if (s.stmt_class()==CALL_STMT){
00404 ProgramUnit* callee=
00405 entrydb.find_ref(s.routine_guarded().symbol().tag_ref());
00406 if (callee) {
00407 p.add_call(*callee);
00408 callee->add_called_by(p);
00409 }
00410 } else {
00411 if (s.stmt_class()==ASSIGNMENT_STMT){
00412 if (s.rhs().op()==FUNCTION_CALL_OP) {
00413 ProgramUnit* callee=
00414 entrydb.find_ref(s.rhs().function().symbol().tag_ref());
00415 if (callee) {
00416 p.add_call(*callee);
00417 callee->add_called_by(p);
00418 }
00419 }
00420 }
00421 }
00422 }
00423
00424 #if 0
00425 for (DictionaryIter<Symbol> dictiter = p.symtab().iterator();
00426 dictiter.valid();
00427 ++dictiter)
00428 {
00429
00430 Symbol & sym = dictiter.current_data();
00431
00432
00433
00434 if (((sym.sym_class() == SUBROUTINE_CLASS) ||
00435 (sym.sym_class() == FUNCTION_CLASS)) &&
00436 sym.external()) {
00437
00438 const StringElem & name(sym.name_ref());
00439 ProgramUnit * callee = entrydb.find_ref(name);
00440
00441 if (callee) {
00442 p.add_call(*callee);
00443 callee->add_called_by(p);
00444 }
00445 }
00446 }
00447 #endif
00448
00449 }
00450 }
00451