00001
00002
00003
00004 #include "define.h"
00005
00006 #ifdef POLARIS_GNU_PRAGMAS
00007 #pragma implementation
00008 #endif
00009
00010 #include <stdio.h>
00011 #include <time.h>
00012 #include <sys/time.h>
00013
00014 #include "ProgramUnit.h"
00015 #include "Relinkable.h"
00016 #include "TranslateObject.h"
00017
00018 #include "BinRep.h"
00019 #include "Collection/Iterator.h"
00020 #include "Collection/KeyIterator.h"
00021 #include "Collection/RefMap.h"
00022 #include "DDgraph.h"
00023 #include "ExprTable.h"
00024 #include "Statement/EntryStmt.h"
00025 #include "Symbol/ProgramSymbol.h"
00026 #include "version.h"
00027 #include "utilities/switches_util.h"
00028 #include "utilities/symbol_util.h"
00029 #include "wide_output.h"
00030
00031 #include <set>
00032
00033 template class RefList<ProgramUnit>;
00034 template class RefSet<ProgramUnit>;
00035 template class List<RefList<ProgramUnit> >;
00036 template class Iterator<ProgramUnit>;
00037 template class Iterator<RefList<ProgramUnit> >;
00038 template class Map<ProgramUnit,List<Expression> >;
00039 template class Map<ProgramUnit,RefList<Symbol> >;
00040 template class RefMap<ProgramUnit,ProgramUnit>;
00041 template class RefMap<ProgramUnit,Symbol>;
00042 template class Assign<RefList<ProgramUnit> >;
00043 template class TypedCollection<RefList<ProgramUnit> >;
00044 template class TypedBaseMap<ProgramUnit,List<Expression> >;
00045 template class TypedBaseMap<ProgramUnit,List<Symbol> >;
00046 template class TypedBaseMap<ProgramUnit,RefList<Symbol> >;
00047 template class TypedBaseRefMap<ProgramUnit,ProgramUnit>;
00048 template class TypedBaseRefMap<ProgramUnit,Symbol>;
00049 template class ProtoMap<ProgramUnit,List<Expression> >;
00050 template class ProtoMap<ProgramUnit,RefList<Symbol> >;
00051 template class ProtoRefMap<ProgramUnit,ProgramUnit>;
00052 template class ProtoRefMap<ProgramUnit,Symbol>;
00053 template class KeyIterator<ProgramUnit,List<Expression> >;
00054 template class KeyIterator<ProgramUnit,ProgramUnit>;
00055 template class KeyIterator<ProgramUnit,RefList<Symbol> >;
00056 template class KeyIterator<ProgramUnit,Symbol>;
00057 template ostream &operator << (ostream &, const List<RefList<ProgramUnit> > &);
00058
00059
00060
00061 static const char *routine_type_names[NUM_PU_TYPES] = {
00062 "UNDEFINED ROUTINE TYPE",
00063 "BLOCK DATA",
00064 "PROGRAM",
00065 "SUBROUTINE",
00066 "FUNCTION"
00067 };
00068
00069 ProgramUnit::ProgramUnit(const ProgramUnit &p)
00070 : Definition(p._tag)
00071 {
00072 #ifdef CLASS_INSTANCE_REGISTRY
00073 register_instance(PROGRAM_UNIT, sizeof(ProgramUnit), this);
00074 #endif
00075
00076 _symtab = NULL;
00077 _data_list = NULL;
00078 _common_blocks = NULL;
00079 _namelists = NULL;
00080 _equivalences = NULL;
00081 _formats = NULL;
00082 _overflow = NULL;
00083 _ddgraph = NULL;
00084 _gsa_deflocs = NULL;
00085 _gsa_names = NULL;
00086 _ranges = NULL;
00087 _inline_map = NULL;
00088 #ifdef PERFORMANCE_EVAL
00089 _perf_estimator = NULL;
00090 #endif
00091 *this = p;
00092 }
00093
00094 ProgramUnit &
00095 ProgramUnit::operator = (const ProgramUnit &p)
00096 {
00097 _routine_type = p._routine_type;
00098 _original_file = p._original_file;
00099 _work_stack = p._work_stack;
00100
00101 delete _symtab;
00102 _symtab = p._symtab->clone();
00103
00104 delete _common_blocks;
00105 _common_blocks = p._common_blocks->clone();
00106
00107 delete _namelists;
00108 _namelists = p._namelists->clone();
00109
00110 delete _equivalences;
00111 _equivalences = p._equivalences->clone();
00112
00113 delete _formats;
00114 _formats = p._formats->clone();
00115
00116 delete _gsa_deflocs;
00117 delete _gsa_names;
00118
00119 if (_ranges) {
00120 delete _ranges;
00121 _ranges = 0;
00122 }
00123
00124 if (_inline_map) {
00125 delete _inline_map;
00126 _inline_map = 0;
00127 }
00128
00129 _formats->_pgm = this;
00130
00131 if (_overflow != NULL)
00132 delete _overflow;
00133 _overflow = p._overflow->clone();
00134
00135 if (_data_list != NULL)
00136 delete _data_list;
00137 _data_list = p._data_list->clone();
00138 _data_list->relink_ptrs(*this);
00139
00140 _statements = p._statements;
00141
00142 _statements._pgm = this;
00143
00144
00145 _symtab->relink_ptrs(*this);
00146
00147 relink_all_lptrs((List<Statement> &) _statements, *this);
00148 _common_blocks->relink_ptrs(*this);
00149 _namelists->relink_ptrs(*this);
00150 _equivalences->relink_ptrs(*this);
00151 if (p.gsa_valid()) {
00152 _gsa_deflocs = new DefLocMap(*p._gsa_deflocs, *this);
00153 _gsa_names = new TranslateObject(*p._gsa_names, *this);
00154 }
00155
00156 _multithread = p._multithread;
00157
00158 #ifdef PERFORMANCE_EVAL
00159 _perf_estimator = p._perf_estimator;
00160 #endif
00161 return (*this);
00162 }
00163
00164 ProgramUnit *
00165 ProgramUnit::clone() const
00166 {
00167 return new ProgramUnit( *this );
00168 }
00169
00170 Definition *
00171 ProgramUnit::definition_clone() const
00172 {
00173 return (Definition *) clone();
00174 }
00175
00176 ProgramUnit::ProgramUnit(const char *tag, PU_TYPE routine_type)
00177 : Definition(tag)
00178 {
00179 #ifdef CLASS_INSTANCE_REGISTRY
00180 register_instance(PROGRAM_UNIT, sizeof(ProgramUnit), this);
00181 #endif
00182
00183 _routine_type = routine_type;
00184 _symtab = new Symtab;
00185 _common_blocks = new CommonBlockDict;
00186 _namelists = new NamelistDict;
00187 _equivalences = new EquivalenceDict;
00188 _gsa_deflocs = NULL;
00189 _gsa_names = NULL;
00190
00191 _overflow = new BinRep;
00192 Set<BinRep> *S = new Set<BinRep>;
00193 _overflow->put_set( S );
00194
00195 _data_list = new DataList;
00196
00197 _formats = new FormatDB( *this );
00198
00199 _statements._pgm = this;
00200 _formats->_pgm = this;
00201
00202 _inline_map = NULL;
00203
00204 _ddgraph = NULL;
00205 _ranges = NULL;
00206
00207 #ifdef PERFORMANCE_EVAL
00208 _perf_estimator = NULL;
00209 #endif
00210
00211 }
00212
00213 ProgramUnit::ProgramUnit(const char *tag, const VDL & vdl_bs)
00214 : Definition(tag)
00215 {
00216 #ifdef CLASS_INSTANCE_REGISTRY
00217 register_instance(PROGRAM_UNIT, sizeof(ProgramUnit), this);
00218 #endif
00219
00220 _ddgraph = NULL;
00221 _ranges = NULL;
00222 _gsa_deflocs = NULL;
00223 _gsa_names = NULL;
00224
00225 _inline_map = NULL;
00226
00227 #ifdef PERFORMANCE_EVAL
00228 _perf_estimator = NULL;
00229 #endif
00230
00231 if (vdl_bs.data_ref() != 0) {
00232 create_program_unit( *vdl_bs.data_ref() );
00233
00234 _statements._pgm = this;
00235 _formats->_pgm = this;
00236 }
00237 }
00238
00239 ProgramUnit::ProgramUnit(const char *tag, const BinRep & bs)
00240 : Definition(tag)
00241 {
00242 #ifdef CLASS_INSTANCE_REGISTRY
00243 register_instance(PROGRAM_UNIT, sizeof(ProgramUnit), this);
00244 #endif
00245
00246 _ddgraph = NULL;
00247 _ranges = NULL;
00248 _gsa_deflocs = NULL;
00249 _gsa_names = NULL;
00250
00251 create_program_unit( bs );
00252
00253 _statements._pgm = this;
00254 _formats->_pgm = this;
00255
00256 _inline_map = NULL;
00257
00258 #ifdef PERFORMANCE_EVAL
00259 _perf_estimator = NULL;
00260 #endif
00261 }
00262
00263 void
00264 ProgramUnit::create_program_unit( const BinRep & bs )
00265 {
00266 BinRep & dict = CASTAWAY(BinRep &) bs;
00267
00268 Boolean errors = False;
00269
00270
00271
00272
00273
00274 {
00275 if (dict.find_ref("messages")) {
00276 BinRep & messages = dict["messages"];
00277
00278 for (Iterator<BinRep> file_iter = messages.to_set();
00279 file_iter.valid(); ++file_iter) {
00280 String curr_file;
00281 file_iter.current()[0].to_string(curr_file);
00282
00283 cerr << endl;
00284 cerr << "In " << curr_file << endl;
00285
00286 Iterator<BinRep> line_iter = file_iter.current()[1].to_tuple();
00287
00288 for (; line_iter.valid(); ++line_iter) {
00289 String event, msg;
00290
00291 line_iter.current()[1].to_string(event);
00292 line_iter.current()[2].to_string(msg);
00293
00294 cerr << " >>> " << event << " on line ";
00295 cerr << (line_iter.current()[0]).to_integer();
00296 cerr << " " << msg << endl;
00297 }
00298 cerr << endl;
00299 }
00300
00301 dict.del("messages");
00302 errors = True;
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313 {
00314 if (dict.find_ref("file")) {
00315 if (dbx_program_debug_level >= 1)
00316 cout << "*ProgramUnit: Converting original_file ....";
00317
00318 dict["file"].to_string(_original_file);
00319
00320 if (dbx_program_debug_level >= 1)
00321 cout << _original_file << endl;
00322
00323 dict.del("file");
00324 }
00325 }
00326
00327
00328
00329 {
00330 if (dbx_program_debug_level >= 1)
00331 cout << "*ProgramUnit: Converting routine_type....";
00332
00333 String routine_type;
00334
00335 if (! dict.find_ref("routine_type")) {
00336 if (errors)
00337 cerr << "\nPolaris aborted due to errors.\n\n";
00338 else
00339 cerr << "\nPolaris aborted due to missing routine type.\n\n";
00340
00341 p_abort( "Abort.");
00342 }
00343
00344 dict["routine_type"].to_string(routine_type);
00345
00346 if (dbx_program_debug_level >= 1)
00347 cout << routine_type << endl;
00348
00349 if (routine_type == "BLOCKDATA")
00350 _routine_type = BLOCK_DATA_PU_TYPE;
00351 else if (routine_type == "PROGRAM")
00352 _routine_type = PROGRAM_PU_TYPE;
00353 else if (routine_type == "SUBROUTINE")
00354 _routine_type = SUBROUTINE_PU_TYPE;
00355 else if (routine_type == "FUNCTION")
00356 _routine_type = FUNCTION_PU_TYPE;
00357 else {
00358 cerr << "Error: ProgramUnit: Unrecognized routine type '"
00359 << routine_type << "'\n";
00360 }
00361 dict.del("routine_type");
00362 }
00363
00364
00365
00366 if (dbx_program_debug_level >= 1) {
00367 cout << "*ProgramUnit: First pass over symbol table.\n";
00368 }
00369 _symtab = new Symtab( dict["symtab"] );
00370
00371
00372
00373
00374
00375
00376 if (dbx_program_debug_level >= 1) {
00377 cout << "*ProgramUnit: Gathering expression table....\n";
00378 }
00379
00380 ExprTable exprs( dict["expression"], *_symtab);
00381
00382 dict.del("expression");
00383
00384 if (dbx_program_debug_level >= 1) {
00385 cout << "*ProgramUnit: "
00386 << "Translating/creating Dictionary<VoidPtrDef> for stmts....\n";
00387 }
00388
00389 if (dict.find_ref("final_statement")) {
00390
00391 dict.del("final_statement");
00392 }
00393
00394
00395
00396 if (dict.find_ref("formats")) {
00397 if (dbx_program_debug_level >= 1) {
00398 cout << "*ProgramUnit: Converting Formats....\n";
00399 }
00400 _formats = new FormatDB( *this, dict["formats"] );
00401 dict.del("formats");
00402 }
00403 else {
00404 _formats = new FormatDB( *this );
00405 }
00406
00407
00408
00409 if (dict.find_ref("namelist_blocks")) {
00410 if (dbx_program_debug_level >= 1)
00411 cout << "*ProgramUnit: Converting Namelists....\n";
00412
00413 _namelists = new NamelistDict( dict["namelist_blocks"], *_symtab);
00414 dict.del("namelist_blocks");
00415 }
00416 else {
00417 _namelists = new NamelistDict;
00418 }
00419
00420 if (dict.find_ref("initial_statement")) {
00421 String init_stmt;
00422
00423 dict["initial_statement"].to_string(init_stmt);
00424 dict.del("initial_statement");
00425
00426
00427
00428 if (dbx_program_debug_level >= 1)
00429 cout << "*ProgramUnit: Converting statements....\n";
00430
00431 _statements.convert( dict["statements"], exprs, *_symtab, *_namelists,
00432 *_formats, init_stmt);
00433
00434 if (dict.find_ref("statements"))
00435 dict.del("statements");
00436 }
00437 else {
00438
00439
00440
00441 p_assert( _routine_type == BLOCK_DATA_PU_TYPE ||
00442 _routine_type == PROGRAM_PU_TYPE,
00443 "the statement list is empty, not a BLOCKDATA or PROGRAM");
00444
00445 dict.del("statements");
00446 }
00447
00448
00449
00450 if (dict.find_ref("equivalences")) {
00451 if (dbx_program_debug_level >= 1) {
00452 cout << "*ProgramUnit: Converting equivalences....\n";
00453 }
00454 _equivalences =
00455 new EquivalenceDict( dict["equivalences"], *_symtab);
00456 dict.del("equivalences");
00457 }
00458 else {
00459 _equivalences = new EquivalenceDict;
00460 }
00461
00462
00463
00464 if (dict.find_ref("common_blocks")) {
00465 if (dbx_program_debug_level >= 1)
00466 cout << "*ProgramUnit: Converting Common Blocks....\n";
00467
00468 _common_blocks = new CommonBlockDict( dict["common_blocks"], *_symtab);
00469 dict.del("common_blocks");
00470 }
00471 else {
00472 _common_blocks = new CommonBlockDict;
00473 }
00474
00475
00476
00477 if (dict.find_ref("data_expr")) {
00478 if (dbx_program_debug_level >= 1) {
00479 cout << "*ProgramUnit: Converting DATA statement info....\n";
00480 }
00481 _data_list = new DataList( dict["data_expr"], exprs);
00482 dict.del("data_expr");
00483 }
00484 else {
00485 _data_list = new DataList;
00486 }
00487
00488
00489
00490 Dictionary<VoidPtrDef> equiv_dict, common_dict, namelist_dict;
00491
00492 {
00493 if (dbx_program_debug_level >= 1) {
00494 cout << "*ProgramUnit: "
00495 << "Preparing Dictionary<VoidPtrDef> of Common Blocks....\n";
00496 }
00497
00498 KeyIterator<String,CommonBlock> iter = *_common_blocks;
00499
00500 for (; iter.valid(); ++iter) {
00501 common_dict.ins(new VoidPtrDef(iter.current_data().name_ref(),
00502 &iter.current_data()));
00503 }
00504 }
00505
00506 {
00507 if (dbx_program_debug_level >= 1) {
00508 cout << "*ProgramUnit: "
00509 << "Preparing Dictionary<VoidPtrDef> of Namelists....\n";
00510 }
00511
00512 KeyIterator<String,Namelist>iter = *_namelists;
00513
00514 for (; iter.valid(); ++iter) {
00515 namelist_dict.ins(new VoidPtrDef(iter.current_data().name_ref(),
00516 &iter.current_data()));
00517 }
00518 }
00519
00520 {
00521 if (dbx_program_debug_level >= 1) {
00522 cout << "*ProgramUnit: "
00523 << "Preparing Dictionary<VoidPtrDef> of Equivalences....\n";
00524 }
00525
00526 KeyIterator<String,Equivalence> iter = *_equivalences;
00527
00528 for ( ; iter.valid(); ++iter) {
00529 equiv_dict.ins(new VoidPtrDef(iter.current_data().name_ref(),
00530 &iter.current_data()));
00531 }
00532 }
00533
00534
00535
00536
00537 if (dbx_program_debug_level >= 1)
00538 cout << "*ProgramUnit: Filling in the Symbol Table....\n";
00539
00540 _symtab->fill_in( dict["symtab"], exprs, *(stmts()._stmt_tag_dict),
00541 common_dict, equiv_dict);
00542 dict.del("symtab");
00543
00544
00545
00546 _overflow = new BinRep;
00547 Set<BinRep> *S = new Set<BinRep>;
00548 _overflow->put_set( S );
00549
00550 if (dbx_program_debug_level >= 1) {
00551 cout << "*ProgramUnit: "
00552 << "Putting anything else into overflow fields....\n";
00553 }
00554
00555 {
00556 for (Iterator<BinRep> iter = dict.to_set(); iter.valid(); ++iter) {
00557 warn_overflow_map("ProgramUnit", iter.current() );
00558 _overflow->ins( iter.current() );
00559 }
00560 }
00561
00562
00563
00564
00565 Iterator<Statement> entries = _statements.stmts_of_type(ENTRY_STMT);
00566
00567 if ((!entries.valid()) &&
00568 (pu_class() == PROGRAM_PU_TYPE)) {
00569 String new_entry_name = "MAIN";
00570
00571 Symbol *pgm_name = symtab().find_ref(new_entry_name);
00572
00573 if (pgm_name) {
00574 while (symtab().find_ref(new_entry_name)) {
00575 pgm_name->renaming_suggestion(new_entry_name);
00576 }
00577 }
00578 pgm_name = new ProgramSymbol(new_entry_name, 0);
00579 Statement *entry_stmt = new EntryStmt(_statements.new_tag(),
00580 id(*pgm_name),
00581 comma());
00582 pgm_name->entry(entry_stmt);
00583 symtab().ins(pgm_name);
00584 entry_stmt->routine(id(*pgm_name));
00585
00586
00587
00588 Iterator<Statement> flowiter = _statements.iterate_entry_points();
00589
00590 p_assert(flowiter.valid(), "ProgramUnit missing FLOW_ENTRY_STMT");
00591
00592 _statements.ins_after(entry_stmt, &flowiter.current());
00593 }
00594
00595 stmts().create_flow_graph();
00596
00597
00598
00599 _propagate_symbol_dimensions();
00600
00601
00602
00603
00604 _propagate_types();
00605 }
00606
00607
00608
00609
00610 void
00611 ProgramUnit::_propagate_types()
00612 {
00613 for (Iterator<Statement> stmt_iter = stmts().iterator();
00614 stmt_iter.valid(); ++stmt_iter) {
00615 Statement & s = stmt_iter.current();
00616 for (Iterator<Expression> expr_iter = s.iterate_expressions();
00617 expr_iter.valid(); ++expr_iter) {
00618 propagate_expr_types(expr_iter.current());
00619 }
00620
00621 if (stmt_iter.current().stmt_class() == RETURN_STMT) {
00622
00623 }
00624 }
00625 }
00626
00627
00628
00629 void
00630 ProgramUnit::_propagate_symbol_dimensions()
00631 {
00632 for (DictionaryIter<Symbol> sym = symtab().iterator(); sym.valid(); ++sym) {
00633 Symbol & s = sym.current_data();
00634
00635 switch (s.sym_class()) {
00636 case VARIABLE_CLASS:
00637 {
00638 Type & sym_type = CASTAWAY(Type &) s.type();
00639
00640 sym_type.rank_known( True );
00641 sym_type.redimension( s.dim().entries() );
00642 }
00643 break;
00644 default: break;
00645 }
00646 }
00647 }
00648
00649 ProgramUnit::~ProgramUnit()
00650 {
00651 #ifdef CLASS_INSTANCE_REGISTRY
00652 unregister_instance(PROGRAM_UNIT, this);
00653 #endif
00654
00655 if (_ddgraph)
00656 delete _ddgraph;
00657 if (_data_list)
00658 delete _data_list;
00659 if (_ranges)
00660 delete _ranges;
00661 if (_inline_map)
00662 delete _inline_map;
00663 delete _common_blocks;
00664 delete _namelists;
00665 delete _equivalences;
00666 delete _formats;
00667 delete _overflow;
00668 delete _gsa_deflocs;
00669 delete _gsa_names;
00670 delete _symtab;
00671 }
00672
00673 const char *
00674 ProgramUnit::pu_tag_ref() const
00675 {
00676 return _tag;
00677 }
00678
00679 void
00680 ProgramUnit::burst_header( ostream &o ) const
00681 {
00682 static time_t t = 0;
00683
00684 if (switch_value( "burst_header" ) > 0) {
00685 o << "*\f";
00686
00687 o << " * V" << polaris_major_version << "." << polaris_minor_version;
00688
00689 if (t == 0)
00690 time( &t );
00691
00692 char *c = ctime( &t );
00693
00694 c[ strlen(c)-1 ] = ' ';
00695
00696 o << " * DATE: " << c;
00697
00698 if (_original_file.defined())
00699 o << " * FILE: " << _original_file;
00700
00701 o << endl;
00702 }
00703 }
00704
00705 void
00706 ProgramUnit::display(ostream & o) const
00707 {
00708 const int space_for_label = 6;
00709
00710 if (_original_file.defined())
00711 o << "FILE: " << _original_file << endl;
00712
00713 _symtab->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00714 _common_blocks->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00715 _equivalences->write(o, space_for_label, FORTRAN_MAX_LINE_LEN, *_symtab);
00716 _data_list->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00717 _namelists->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00718
00719
00720 _statements.display(o);
00721
00722 _formats->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00723 }
00724
00725 void
00726 ProgramUnit::write(ostream & o) const
00727 {
00728 const int space_for_label = 0;
00729
00730 burst_header( o );
00731
00732 Iterator<Statement> entries = _statements.stmts_of_type(ENTRY_STMT);
00733
00734 if (entries.valid()) {
00735 int ind = 0;
00736
00737 blank_wide_output( o );
00738 entries.current().write(o, ind, (char *)routine_type_names[pu_class()]);
00739 }
00740 else if (pu_class() == BLOCK_DATA_PU_TYPE) {
00741 blank_wide_output( o );
00742 o << " BLOCK DATA\n";
00743 }
00744
00745 _symtab->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00746 _common_blocks->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00747 _equivalences->write(o, space_for_label, FORTRAN_MAX_LINE_LEN, *_symtab);
00748 _data_list->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00749 _namelists->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00750 _statements.write(o);
00751 _formats->write(o, space_for_label, FORTRAN_MAX_LINE_LEN);
00752
00753 blank_wide_output( o );
00754 o << " END\n";
00755 }
00756
00757
00758 void
00759 ProgramUnit::display_debug(ostream & o) const
00760 {
00761
00762
00763 if (_routine_type < 0 || _routine_type >= NUM_PU_TYPES) {
00764 cerr << "Error: ProgramUnit: display(): Unknown routine type: "
00765 << _routine_type << endl;
00766 p_abort( "(see above message)" );
00767 }
00768
00769 display(o);
00770
00771
00772 o << "\nSymtab:\n" << *_symtab << endl;
00773
00774
00775 o << "\nEquivalences:\n" << *_equivalences << endl;
00776
00777
00778 o << "\nCommon Blocks:\n" << *_common_blocks << endl;
00779
00780
00781 o << "\nData:\n" << *_data_list << endl;
00782
00783
00784 o << "\nNamelists:\n" << *_namelists << endl;
00785
00786
00787 o << "\nFormats:\n" << *_formats << endl;
00788
00789
00790 o << "\nOverflow:\n" << *_overflow << endl;
00791 }
00792
00793 ostream &
00794 operator << (ostream & o, const ProgramUnit & pr)
00795 {
00796 pr.display(o);
00797 return o;
00798 }
00799
00800 void
00801 ProgramUnit::print(ostream & o) const
00802 {
00803 display(o);
00804 }
00805
00806 int
00807 ProgramUnit::structures_OK() const
00808 {
00809 cout << "Testing ProgramUnit structures....\n";
00810
00811 if ( !_statements.structures_OK()
00812
00813
00814 || !_common_blocks->structures_OK()
00815 || !_namelists->structures_OK()
00816 || !_equivalences->structures_OK()
00817
00818
00819 ) {
00820 cerr << "\n\n**** Error found in structure of pgm:" << flush << endl;
00821 cerr << *this << endl << endl;
00822 return 0;
00823 }
00824
00825 return 1;
00826 }
00827
00828 const char *
00829 ProgramUnit::routine_name_ref() const
00830 {
00831 Iterator<Statement> entries = stmts().stmts_of_type(ENTRY_STMT);
00832
00833 if (entries.valid()) {
00834
00835 if (entries.current().routine_valid())
00836 return entries.current().routine_guarded().symbol().name_ref();
00837 }
00838
00839
00840 return "";
00841 }
00842
00843 const char *
00844 ProgramUnit::original_file_ref() const
00845 {
00846 return ((_original_file.defined()) ? (const char *) _original_file : 0);
00847 }
00848
00849 void
00850 ProgramUnit::clean_workspace(unsigned int pass_tag)
00851 {
00852 work_stack().pop(pass_tag);
00853
00854 Iterator<Statement> iter = stmts().iterator();
00855
00856 for ( ; iter.valid(); ++iter)
00857 iter.current().work_stack().pop(pass_tag);
00858 }
00859
00860
00861
00862 typedef set<const Symbol*> SymbolSet;
00863
00864 static void
00865 collect_all_symbols(const Expression &e, SymbolSet &used )
00866 {
00867 if (e.op() != ID_OP) {
00868 for (Iterator<Expression> iter = e.arg_list(); iter.valid(); ++iter)
00869 collect_all_symbols( iter.current(), used );
00870 }
00871 else {
00872 const Symbol & sym = e.symbol();
00873
00874 if (used.find( &sym ) == used.end()) {
00875 used.insert( &sym);
00876
00877 switch (sym.sym_class()) {
00878 case VARIABLE_CLASS:
00879 if (sym.is_array()) {
00880 for (Iterator<ArrayBounds> iter = sym.dim();
00881 iter.valid(); ++iter) {
00882 ArrayBounds & ad = iter.current();
00883
00884 if (ad.lower_exists())
00885 collect_all_symbols( ad.lower_guarded(), used );
00886
00887 if (ad.upper_exists())
00888 collect_all_symbols( ad.upper_guarded(), used );
00889 }
00890 }
00891 break;
00892
00893 case SYMBOLIC_CONSTANT_CLASS:
00894 if (sym.expr_ref())
00895 collect_all_symbols( *sym.expr_ref(), used );
00896 break;
00897 default: break;
00898 }
00899 }
00900 }
00901 }
00902
00903 void
00904 ProgramUnit::clean()
00905 {
00906 SymbolSet used;
00907 SymbolSet assertion_symbols;
00908
00909
00910
00911
00912 for (Iterator<Statement> st_iter = this->stmts().iterator();
00913 st_iter.valid(); ++st_iter) {
00914 Statement & st = st_iter.current();
00915
00916 for (Iterator<Expression> e_iter = st.iterate_expressions();
00917 e_iter.valid(); ++e_iter) {
00918 Expression &e = e_iter.current();
00919
00920
00921 collect_all_symbols( e, used );
00922 }
00923
00924 if (st.s_control_valid()) {
00925 for (Iterator<s_control_type> sc_iter = st.s_control_guarded();
00926 sc_iter.valid(); ++sc_iter) {
00927 for (Iterator<Expression> e_iter = sc_iter.current().expr;
00928 e_iter.valid(); ++e_iter) {
00929 Expression &e = e_iter.current();
00930 collect_all_symbols( e, used );
00931 }
00932 }
00933 }
00934
00935 for (Iterator<Assertion> a_iter = st.assertions();
00936 a_iter.valid(); ++a_iter) {
00937 Assertion & a = a_iter.current();
00938 if (a.arg_list_valid()) {
00939 for (Iterator<Expression> e_iter = a.arg_list_guarded();
00940 e_iter.valid(); ++e_iter) {
00941 Expression &e = e_iter.current();
00942
00943 collect_all_symbols( e, used );
00944 }
00945
00946 }
00947 }
00948 }
00949
00950
00951
00952 {
00953 for (Iterator<Data> iter = this->data(); iter.valid(); ++iter) {
00954 collect_all_symbols( iter.current().variable_list(), used );
00955 collect_all_symbols( iter.current().value_list(), used );
00956 }
00957 }
00958
00959
00960
00961 {
00962 for (DictionaryIter<CommonBlock> iter = this->common_blocks();
00963 iter.valid(); ++iter) {
00964 for (Iterator<Symbol> sym_iter = iter.current().iterator();
00965 sym_iter.valid(); ++sym_iter) {
00966 Symbol & sym = sym_iter.current();
00967
00968 if (used.find( &sym ) == used.end())
00969 used.insert( &sym );
00970 }
00971 }
00972 }
00973
00974
00975
00976 {
00977 for (DictionaryIter<Namelist> iter = this->namelists();
00978 iter.valid(); ++iter) {
00979 for (Iterator<Symbol> sym_iter = iter.current().iterator();
00980 sym_iter.valid(); ++sym_iter) {
00981 Symbol & sym = sym_iter.current();
00982
00983 if (used.find( &sym ) == used.end() )
00984 used.insert( &sym );
00985 }
00986 }
00987 }
00988
00989
00990
00991 {
00992 for (DictionaryIter<Symbol> symscn = this->_symtab->iterator();
00993 symscn.valid(); ++symscn) {
00994
00995 Symbol &sym = symscn.current();
00996
00997 if (sym.is_array()) {
00998
00999 RefSet<Symbol> symb_const;
01000 collect_symb_const(symb_const, sym.dim());
01001
01002 for (Iterator<Symbol> siter = symb_const;
01003 siter.valid();
01004 ++siter) {
01005 Symbol & constant = siter.current();
01006 used.insert(&constant);
01007 }
01008 } else if (sym.expr_ref()) {
01009
01010
01011
01012
01013
01014
01015
01016
01017 collect_all_symbols (*sym.expr_ref (), used);
01018 }
01019
01020 }
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 for (DictionaryIter<Symbol> iter = this->symtab().iterator();
01062 iter.valid(); ++iter) {
01063 Symbol & sym = iter.current_data();
01064
01065 if (used.find( &sym ) == used.end() ) {
01066
01067
01068
01069 if (sym.common_ref())
01070 sym.clear_common();
01071
01072 if (sym.equivalence_ref()) {
01073 Equivalence *eq = sym.equivalence_ref();
01074 sym.clear_equivalence();
01075
01076
01077 this->equivalences().clean( *eq );
01078 }
01079
01080 this->symtab().del( iter.current_key() );
01081 }
01082 }
01083 }
01084
01085 BinRep *
01086 ProgramUnit::exchange()
01087 {
01088 VDL vdl;
01089
01090 vdl.start_object();
01091 vdl.start_set();
01092 vdl.end_set();
01093 vdl.end_object();
01094
01095 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref();
01096
01097 if (b != 0) {
01098 List<BinRep> *L = new List<BinRep>;
01099 L->ins_last( new BinRep( "routine_type" ) );
01100 L->ins_last( new BinRep( (char *) routine_type_names[pu_class()] ));
01101 b->to_set().ins( new BinRep( L ) );
01102 }
01103
01104 if (_original_file.defined()) {
01105 List<BinRep> *L = new List<BinRep>;
01106 L->ins_last( new BinRep( "file" ) );
01107 L->ins_last( new BinRep( _original_file ) );
01108 b->to_set().ins( new BinRep( L ) );
01109 }
01110
01111 {
01112 List<BinRep> *L = new List<BinRep>;
01113 L->ins_last( new BinRep( "expression" ) );
01114 L->ins_last( new BinRep( new List<BinRep> ));
01115 b->to_set().ins( new BinRep( L ) );
01116 }
01117
01118 symtab().exchange_convert( vdl );
01119 common_blocks().exchange_convert( vdl );
01120 equivalences().exchange_convert( vdl );
01121 data().exchange_convert( vdl );
01122 formats().exchange_convert( vdl );
01123 namelists().exchange_convert( vdl );
01124 stmts().exchange_convert( vdl );
01125
01126 if (_overflow != 0) {
01127 for (Iterator<BinRep> iter = _overflow->to_set(); iter.valid(); ++iter)
01128 vdl.data_ref()->to_set().ins( iter.current().clone() );
01129 }
01130
01131 return vdl.give_up_data();
01132 }
01133
01134 void
01135 ProgramUnit::ddgraph(DDgraph *ddg)
01136 {
01137 if (_ddgraph)
01138 delete _ddgraph;
01139
01140 _ddgraph = ddg;
01141 }
01142
01143 void
01144 ProgramUnit::gsa_deflocs(DefLocMap * new_map)
01145 {
01146 delete _gsa_deflocs;
01147 _gsa_deflocs = new_map;
01148 }
01149
01150 void
01151 ProgramUnit::gsa_names(TranslateObject * new_names)
01152 {
01153 delete _gsa_names;
01154 _gsa_names = new_names;
01155 }
01156
01157 void
01158 ProgramUnit::function_to_subroutine() {
01159
01160 p_assert(_routine_type == FUNCTION_PU_TYPE,
01161 "ProgramUnit::function_to_subroutine: isn't a function");
01162
01163 _routine_type = SUBROUTINE_PU_TYPE;
01164 }
01165
01166 void
01167 ProgramUnit::subroutine_to_function() {
01168
01169 p_assert(_routine_type == SUBROUTINE_PU_TYPE,
01170 "ProgramUnit::subroutine_to_function: isn't a subroutine");
01171
01172 _routine_type = FUNCTION_PU_TYPE;
01173 }
01174
01175 void
01176 ProgramUnit::program_to_subroutine() {
01177
01178 p_assert(_routine_type == PROGRAM_PU_TYPE,
01179 "ProgramUnit::program_to_subroutine: isn't a program");
01180
01181 _routine_type = SUBROUTINE_PU_TYPE;
01182 }
01183
01184
01185 Expression *
01186 ProgramUnit::distribution_of(Symbol *sym)
01187 {
01188 if (sym->sym_class() != VARIABLE_CLASS)
01189 return 0;
01190
01191 Iterator<Assertion> iter = _statements.first().assertions();
01192
01193 for (; iter.valid(); ++iter)
01194 if (iter.current().type() == AS_SHARED)
01195 break;
01196
01197 if (!iter.valid())
01198 return 0;
01199
01200
01201 for (Iterator<Expression> eiter = iter.current().arg_list_guarded();
01202 eiter.valid(); ++eiter)
01203 if (eiter.current().op() == DISTRIBUTE_OP &&
01204 sym == &eiter.current().symbol())
01205 return &eiter.current();
01206
01207 return 0;
01208 }
01209