Polaris: ProgramUnit.h Source File

ProgramUnit.h

Go to the documentation of this file.
00001 ///
00002 #ifndef _PROGRAM_UNIT_H
00003 #define _PROGRAM_UNIT_H
00004 ///
00005 /// \class ProgramUnit 
00006 /// \brief a class for Fortran program units
00007 /// \defgroup Base
00008 /// \ingroup Base
00009 ///  General utility routines
00010 /// \see ProgramUnit.h
00011 /// \see ProgramUnit.cc
00012 /// \see ProgramUnit.h
00013 ///
00014 /// \endcode
00015 /// \section Description Description
00016 /// This class represents a Fortran program unit and contains
00017 /// all of the major structures of such an object.  It also
00018 /// contains the statement copying/deleting/insertion
00019 /// routines as well as some block listing routines
00020 /// such as iterate_loop_body()
00021 ///
00022 /// \endcode
00023 /// \section KNOWN KNOWN/POSSIBLE BUGS/LIMITATIONS
00024 ///
00025 #ifdef POLARIS_GNU_PRAGMAS
00026 #pragma interface
00027 #endif
00028 ///
00029 #include "ClassNames.h"
00030 #include "DataList.h"
00031 #include "define.h"
00032 #include "EquivalenceDict.h"
00033 #include "Expression/Expression.h"
00034 #include "FormatDB.h"
00035 #include "Collection/List.h"
00036 #include "InlineObject.h"
00037 #include "Symtab.h"
00038 #include "BinRep.h"
00039 #include "PredicateRepository.h"
00040 #include "Range/RangeDict.h"
00041 #include "Statement/Statement.h"
00042 #include "StmtList.h"
00043 #include "VDL.h"
00044 #include "Collection/RefList.h"
00045 #include "Collection/Iterator.h"
00046 #include "Namelist.h"
00047 #include "NamelistDict.h"
00048 #include "DefLocMap.h"
00049 ///
00050 class DDgraph;
00051 class TranslateObject;
00052 
00053 #ifdef PERFORMANCE_EVAL
00054 class PerformanceEstimator;
00055 #endif
00056 
00057 ///< Program Unit Types
00058 enum PU_TYPE {
00059     UNDEFINED_PU_TYPE = 0,
00060     BLOCK_DATA_PU_TYPE,
00061     PROGRAM_PU_TYPE,
00062     SUBROUTINE_PU_TYPE,
00063     FUNCTION_PU_TYPE,
00064 
00065     NUM_PU_TYPES
00066 };
00067 
00068 class Program;
00069 
00070 class ProgramUnit : public Definition {
00071     friend class Program;
00072 
00073  protected:
00074     PU_TYPE          _routine_type;
00075     String           _original_file;
00076     StmtList         _statements;
00077     Symtab          *_symtab;
00078     DataList        *_data_list;
00079     DDgraph         *_ddgraph;
00080     CommonBlockDict *_common_blocks;
00081     NamelistDict    *_namelists;
00082     EquivalenceDict *_equivalences;
00083     FormatDB        *_formats;
00084     DefLocMap       *_gsa_deflocs;
00085     TranslateObject *_gsa_names;
00086     PredicateRepository _repository;
00087 
00088     RefSet<ProgramUnit> _calls;     ///< ProgramUnits this ProgramUnit calls
00089     RefSet<ProgramUnit> _called_by; ///< ProgramUnits which call this ProgramUnit
00090 
00091 #ifdef PERFORMANCE_EVAL
00092   PerformanceEstimator *_perf_estimator;
00093 #endif
00094 
00095     Map<Statement,InlineObject> * _inline_map;
00096 
00097     RangeDict       *_ranges;
00098     BinRep          *_overflow;
00099     int             _multithread;   ///<_
00100     WorkSpaceStack  _work_stack;
00101     ///< Stack of WorkSpaces for this program unit.
00102 
00103     void            create_program_unit( const BinRep & bs );
00104     void            _propagate_symbol_dimensions();
00105     void            _propagate_types();
00106     void            _propagate_types(Expression &);    
00107 
00108  public:
00109     ProgramUnit(const char *pu_tag, PU_TYPE routine_type);
00110 
00111     ProgramUnit(const ProgramUnit & p);
00112 
00113     ProgramUnit(const char *pu_tag, const BinRep & bs);
00114 
00115     ProgramUnit(const char *pu_tag, const VDL & vdl_bs);
00116 
00117     ProgramUnit & operator = ( const ProgramUnit & pgm);
00118 
00119     virtual ProgramUnit *clone() const;
00120     ///< Return (and give control of) a new ProgramUnit which has
00121     ///< been copied from this one.
00122 
00123     virtual         ~ProgramUnit();
00124 
00125     void burst_header( ostream &o ) const;
00126     ///< Issue a page break and header information is the switch is
00127     ///< enabled.
00128 
00129     const char     *pu_tag_ref() const;
00130     ///< Returns the pu_tag of the program unit (not to be confused with
00131     ///< the routine_name).  The pu_tag has nothing to do with the
00132     ///< Fortran source, but is just an identifier useful in
00133     ///< has tables, etc.
00134 
00135      PU_TYPE         pu_class() const;
00136     ///< Returns the flavor of program unit
00137 
00138     const char     *routine_name_ref() const;
00139     ///< Returns the name of this ProgramUnit, if there is such a
00140     ///< name (otherwise returns an empty string [""]), collected
00141     ///< from the Fortran source.  I.e. if this program unit is
00142     ///< a SUBROUTINE called "SUB1", then routine_name_ref() returns
00143     ///< "SUB1".  This information is obtained by grabbing the
00144     ///< the first ENTRY statement in the program, if any.
00145 
00146     const char     *original_file_ref() const;
00147     ///< Return a character pointer to the file from which this routine
00148     ///< was obtained.
00149 
00150      const StmtList  &stmts() const;
00151      StmtList        &stmts();
00152     ///< The Statement list.
00153 
00154      const Symtab    &symtab() const;
00155      Symtab          &symtab();
00156     ///< The Symbol table.
00157 
00158      const DataList  &data() const;
00159      DataList        &data() ;
00160     ///< The List of DATA statements.
00161 
00162      const CommonBlockDict &common_blocks() const;
00163      CommonBlockDict       &common_blocks();
00164     ///< The List of COMMON blocks.
00165 
00166      const NamelistDict &namelists() const;
00167      NamelistDict       &namelists() ;
00168     ///< The NAMELIST dictionary.
00169 
00170      const EquivalenceDict &equivalences() const;
00171      EquivalenceDict       &equivalences();
00172     ///< The EQIUVALENCE dictionary.
00173 
00174      const FormatDB  &formats() const;
00175      FormatDB        &formats();
00176     ///< The FORMAT database.
00177 
00178      PredicateRepository & pred_repos();
00179     ///< Repository for AbstractAccess predicates for this ProgramUnit
00180 
00181 #ifdef PERFORMANCE_EVAL
00182    PerformanceEstimator *perf_estimator();
00183    void set_perf_estimator(PerformanceEstimator *pe);
00184   ///< Performance estimation data
00185 #endif
00186 
00187      const WorkSpaceStack  &work_stack() const;
00188      WorkSpaceStack        &work_stack();
00189     ///< The stack of WorkSpaces for the ProgramUnit.
00190 
00191      BinRep          *overflow_ref() const;
00192     ///< Any unrecognized interchange objects.
00193 
00194      DDgraph  &ddgraph();
00195     ///< Outmoded.  Call ddgraph_guarded() instead.
00196 
00197      DDgraph  &ddgraph_guarded();
00198     ///< Return a reference to the DDgraph associated with the program.
00199 
00200      Boolean  ddgraph_valid();
00201     ///< Return true if the program unit has a ddgraph.
00202 
00203     void            ddgraph(DDgraph *ddg);
00204     ///< Set my DDgraph to the given object.
00205 
00206      const DefLocMap &gsa_deflocs_guarded() const;
00207      DefLocMap       &gsa_deflocs_guarded();
00208     ///< Return a reference to the DefLocMap associated with the program
00209     ///< (which must be in GSA form)
00210 
00211      const TranslateObject & gsa_names_guarded() const;
00212      TranslateObject       & gsa_names_guarded();
00213     ///< Return a reference to the TranslateObject associated with the program
00214     ///< (which must be in GSA form)
00215 
00216      bool            gsa_valid() const;
00217     ///< Is ProgramUnit in gsa form or not?
00218 
00219     void            gsa_deflocs(DefLocMap * new_map);
00220     ///< Set my DefLocMap to the given object (or NULL)
00221 
00222     void            gsa_names(TranslateObject * new_names);
00223     ///< Set my TranslateObject to the given object (or NULL)
00224 
00225     Map<Statement,InlineObject> & inline_map_guarded();
00226     ///< Return a reference to the inline_map for this ProgramUnit
00227 
00228     bool inline_map_valid();
00229     ///< Does the inline_map exist?
00230 
00231     void inline_map(Map<Statement,InlineObject> *map);
00232     ///< Assign inline_map for this ProgramUnit
00233 
00234     RangeDict       & range_dict_guarded();
00235     ///< Give access to the Range Dictionary in the ProgramUnit
00236 
00237     bool            range_dict_valid();
00238     ///< Does the range dictionary exist?
00239 
00240     void range_dict(RangeDict * rdict);
00241     ///< Record the Range Dictionary for this ProgramUnit
00242 
00243     RefSet<ProgramUnit> & calls();
00244     RefSet<ProgramUnit> & called_by();
00245     void add_call(ProgramUnit & pgm);
00246     void add_called_by(ProgramUnit & pgm);
00247 
00248     void            multithread();
00249     void            singlethread();
00250     void            undefined_thread();
00251     ///<_ Set _multithread flag to True/False/No(initalized value)
00252 
00253     int             is_multithread() const;
00254     int             is_thread_defined() const;
00255     ///<_ If True, this programunit has some doalls in it.
00256     ///<_ If False, it has not or may have doalls.(Conservative)
00257 
00258     Expression     *distribution_of(Symbol *sym);
00259     ///< Return the corresponding DistributeExpr for sym if it is shared 'ARRAY'.
00260     ///< Return 0 either if it is scalar or if it is private array
00261 
00262     void            clean_workspace(unsigned int pass_tag);
00263     ///< Delete all WorkSpaces with the given pass tag from the program unit's
00264     ///< WorkSpaceStack and all of the WorkSpaceStacks for the ProgramUnit's
00265     ///< statements.
00266 
00267     void            clean();
00268     ///< Search through the ProgramUnit and find all symbol uses.  Remove
00269     ///< any symbols from the Symtab that are not found.
00270 
00271     BinRep         *exchange();
00272     ///< Return a BinRep object which encapsulates the ProgramUnit in a
00273     ///< portable format.
00274 
00275     void            display(ostream & o) const;
00276     ///< Display the program unit in a form which includes statement tags
00277     ///< and other information.  To print a program unit in a correct
00278     ///< Fortran format, use 'write(...)' instead.
00279 
00280     void            display_debug(ostream & o) const;
00281     ///< Display the program unit in a form which includes the
00282     ///< symbol table and details of all the other program unit
00283     ///< structures, useful for debugging. To print a program in
00284     ///< a more readable FORTRAN format, use 'display(...)' or
00285     ///< 'write(...)' instead.
00286 
00287     friend ostream & operator << (ostream & o, const ProgramUnit & pr);
00288 
00289     virtual void    print(ostream & o) const;
00290     ///< Satisfies the Definition requirements.  Equivalent to display()
00291 
00292     virtual int     structures_OK() const;
00293     ///< Check the structure of the data for errors or inconsistency
00294     ///< Return 0 and print error message if problems found, otherwise
00295     ///< return 1 without message.
00296 
00297     void            write(ostream & o) const;
00298     ///< Display the program unit in FORTRAN format
00299 
00300     virtual Definition *definition_clone() const;
00301     ///< Copy and return a Definition
00302 
00303     void            function_to_subroutine();
00304     ///< Convert a program unit of type FUNCTION_PU_TYPE into a program
00305     ///< unit of type SUBROUTINE_PU_TYPE.  This does NOT make any changes
00306     ///< to the structure of the program unit, only to _routine_type.
00307 
00308     void            subroutine_to_function();
00309     ///< Convert a program unit of type SUBROUTINE_PU_TYPE into a program
00310     ///< unit of type FUNCTION_PU_TYPE.  This does NOT make any changes
00311     ///< to the structure of the program unit, only to _routine_type.
00312 
00313     void            program_to_subroutine();
00314     ///< Convert a program unit of type PROGRAM_PU_TYPE into a program
00315     ///< unit of type SUBROUTINE_PU_TYPE.  This does NOT make any changes
00316     ///< to the structure of the program unit, only to _routine_type.
00317 };
00318 
00319 
00320 ///< inline functions
00321 
00322 inline DDgraph &
00323 ProgramUnit::ddgraph()
00324 {
00325     p_abort("Method ProgramUnit::ddgraph() is no longer supported.  Call ddgraph_guarded() instead.");
00326     return *_ddgraph;
00327 }
00328 
00329 inline DDgraph &
00330 ProgramUnit::ddgraph_guarded()
00331 {
00332     p_assert(_ddgraph, "ProgramUnit::ddgraph_guarded(): I do not have a valid DDgraph.");
00333     return *_ddgraph ;
00334 }
00335 
00336 inline Boolean
00337 ProgramUnit::ddgraph_valid()
00338 {
00339     return (_ddgraph != 0) ;
00340 }
00341 
00342 inline bool
00343 ProgramUnit::gsa_valid() const
00344 {
00345   if (_gsa_deflocs && _gsa_names)
00346     return true;
00347   p_assert(!_gsa_deflocs && !_gsa_names,
00348        "ProgramUnit in invalid GSA state");
00349   return false;
00350 }
00351 
00352 inline const DefLocMap &
00353 ProgramUnit::gsa_deflocs_guarded() const
00354 {
00355   return *_gsa_deflocs;
00356 }
00357 
00358 inline DefLocMap &
00359 ProgramUnit::gsa_deflocs_guarded()
00360 {
00361   return *_gsa_deflocs;
00362 }
00363 
00364 inline const TranslateObject &
00365 ProgramUnit::gsa_names_guarded() const
00366 {
00367   return *_gsa_names;
00368 }
00369 
00370 inline TranslateObject &
00371 ProgramUnit::gsa_names_guarded()
00372 {
00373   return *_gsa_names;
00374 }
00375 
00376 inline RangeDict &
00377 ProgramUnit::range_dict_guarded()
00378 {
00379     return *_ranges;
00380 }
00381 
00382 inline void
00383 ProgramUnit::range_dict(RangeDict * rdict)
00384 {
00385     if (_ranges) {
00386     delete _ranges;
00387     }
00388     _ranges = rdict;
00389 }
00390 
00391 inline bool 
00392 ProgramUnit::range_dict_valid()
00393 {
00394     return (_ranges != 0);
00395 }
00396 
00397 inline Map<Statement,InlineObject> &
00398 ProgramUnit::inline_map_guarded( )
00399 {
00400     return (Map<Statement,InlineObject> &) *_inline_map;
00401 }
00402 
00403 inline void
00404 ProgramUnit::inline_map(Map<Statement,InlineObject> * map)
00405 {
00406     _inline_map = map;
00407 }
00408 
00409 inline bool
00410 ProgramUnit::inline_map_valid()
00411 {
00412     return (_inline_map != 0);
00413 }
00414 
00415 inline const StmtList & 
00416 ProgramUnit::stmts() const
00417 {
00418     return (const StmtList &) _statements;
00419 }
00420 
00421 inline StmtList & 
00422 ProgramUnit::stmts()
00423 {
00424     return (StmtList &) _statements;
00425 }
00426 
00427 inline const Symtab & 
00428 ProgramUnit::symtab() const
00429 {
00430     return (const Symtab &) * _symtab;
00431 }
00432 
00433 inline Symtab & 
00434 ProgramUnit::symtab()
00435 {
00436     return (Symtab &) * _symtab;
00437 }
00438 
00439 inline const DataList & 
00440 ProgramUnit::data() const
00441 {
00442     return (const DataList &) * _data_list;
00443 }
00444 
00445 inline DataList & 
00446 ProgramUnit::data() 
00447 {
00448     return (DataList &) * _data_list;
00449 }
00450 
00451 inline const CommonBlockDict & 
00452 ProgramUnit::common_blocks() const
00453 {
00454     return (const CommonBlockDict &) * _common_blocks;
00455 }
00456 
00457 inline CommonBlockDict & 
00458 ProgramUnit::common_blocks()
00459 {
00460     return (CommonBlockDict &) * _common_blocks;
00461 }
00462 
00463 inline const NamelistDict & 
00464 ProgramUnit::namelists() const
00465 {
00466     return (const NamelistDict &) * _namelists;
00467 }
00468 
00469 inline NamelistDict & 
00470 ProgramUnit::namelists() 
00471 {
00472     return (NamelistDict &) * _namelists;
00473 }
00474 
00475 inline const EquivalenceDict & 
00476 ProgramUnit::equivalences() const
00477 {
00478     return (const EquivalenceDict &) * _equivalences;
00479 }
00480 
00481 inline EquivalenceDict & 
00482 ProgramUnit::equivalences()
00483 {
00484     return (EquivalenceDict &) * _equivalences;
00485 }
00486 
00487 inline PredicateRepository &
00488 ProgramUnit::pred_repos()
00489 {
00490     return (PredicateRepository &) _repository;
00491 }
00492 
00493 #ifdef PERFORMANCE_EVAL
00494 inline PerformanceEstimator *ProgramUnit::perf_estimator()
00495 { 
00496   return _perf_estimator;
00497 }    
00498 
00499 inline void ProgramUnit::set_perf_estimator(PerformanceEstimator *pe)
00500 { 
00501   _perf_estimator = pe; 
00502 }    
00503 #endif
00504 
00505 inline const FormatDB & 
00506 ProgramUnit::formats() const
00507 {
00508     return (const FormatDB &) * _formats;
00509 }
00510 
00511 inline FormatDB & 
00512 ProgramUnit::formats()
00513 {
00514     return (FormatDB &) * _formats;
00515 }
00516 
00517 inline const WorkSpaceStack &
00518 ProgramUnit::work_stack() const
00519 {
00520     return (const WorkSpaceStack &) _work_stack;
00521 }
00522 
00523 inline WorkSpaceStack &
00524 ProgramUnit::work_stack()
00525 {
00526     return (WorkSpaceStack &) _work_stack;
00527 }
00528 
00529 inline BinRep *
00530 ProgramUnit::overflow_ref() const
00531 {
00532     return _overflow;
00533 }
00534 
00535 inline PU_TYPE 
00536 ProgramUnit::pu_class() const
00537 {
00538     return _routine_type;
00539 }
00540 
00541 ///<_
00542 
00543 inline int
00544 ProgramUnit::is_multithread() const
00545 {
00546     return (_multithread > 0 ? 1 : 0);
00547 }
00548 
00549 inline int
00550 ProgramUnit::is_thread_defined() const
00551 {
00552     return (_multithread < 0 ? 0 : 1);
00553 }
00554 
00555 inline void
00556 ProgramUnit::multithread()
00557 {
00558     _multithread = 1;
00559 }
00560 
00561 inline void
00562 ProgramUnit::undefined_thread()
00563 {
00564     _multithread = -1;
00565 }
00566 
00567 inline void
00568 ProgramUnit::singlethread()
00569 {
00570     _multithread = 0;
00571 }
00572 
00573 inline RefSet<ProgramUnit> &
00574 ProgramUnit::calls()
00575 {
00576     return _calls;
00577 }
00578 
00579 inline RefSet<ProgramUnit> &
00580 ProgramUnit::called_by()
00581 {
00582     return _called_by;
00583 }
00584 
00585 inline void
00586 ProgramUnit::add_call(ProgramUnit & pgm)
00587 {
00588     _calls.ins(pgm);
00589 }
00590 
00591 inline void
00592 ProgramUnit::add_called_by(ProgramUnit & pgm)
00593 {
00594     _called_by.ins(pgm);
00595 }
00596 
00597 ///<_
00598 
00599 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:02 2005