Polaris: IPCPProcData.h Source File

IPCPProcData.h

Go to the documentation of this file.
00001 ///
00002 #ifndef _IPCP_PROC_DATA_H
00003 #define _IPCP_PROC_DATA_H
00004 ///
00005 /// file IPCPProcData.h
00006 ///
00007 /// \class IPCPProcData 
00008 /// \brief Various procedural data for InterProcConstProp.
00009 /// \defgroup Polaris
00010 /// \ingroup Polaris
00011 ///  Constant
00012 /// \see IPCPProcData.h
00013 /// \see IPCPProcData.h
00014 ///
00015 /// \endcode
00016 /// \section Overview Overview
00017 /// This class contains a variety of data needed by the
00018 /// interprocedural constant propagation pass for a single procedure.
00019 ///
00020 #include "../Listable.h"
00021 #include "../Collection/Map.h"
00022 #include "../Collection/RefMap.h"
00023 #include "../Collection/Set.h"
00024 #include "../Collection/RefSet.h"
00025 #include "../Collection/RefList.h"
00026 #include "../Symbol/Symbol.h"
00027 #include "../Expression/Expression.h"
00028 #include "../Statement/Statement.h"
00029 #include "../Statement/AssignmentStmt.h"
00030 #include "../String.h"
00031 #include "../Boolean.h"
00032 ///
00033 #include "IPCPConstants.h"
00034 #include "constant.h"
00035 ///
00036 class ProgramUnit;
00037 class InterProcConstProp;
00038 class IPCPProcData;
00039 class JumpFunction;
00040 class ReturnJumpFunction;
00041 
00042 class IPCPCallData : public Listable {
00043 public:
00044     IPCPCallData(IPCPProcData *called_pgm_data);
00045     IPCPCallData(const IPCPCallData &other);
00046     virtual ~IPCPCallData();
00047     
00048     inline const IPCPProcData *data_ref() const;
00049     inline void data_ref(IPCPProcData *data);
00050     ///< Return the IPCPProcData object associated with procedure called
00051     ///< at this call site.
00052 
00053     inline Boolean jump_function_valid() const;
00054     inline const JumpFunction &jump_function() const;
00055     void jump_function(JumpFunction *jump_func);
00056     ///< Return the jump function for this call site.  This jump
00057     ///< function holds the constant values of all global variables,
00058     ///< and call site parameters for the call site.  These constant
00059     ///< values are symbolic expressions in terms of the global variables
00060     ///< and parameters of the calling routine.
00061     ///< It is assumed that the method return_jump_function() has
00062     ///< been called previously.
00063 
00064     void add_constant_set(IPCPConstants *constants,
00065               const List<Expression> &param_values);
00066     ///< Add a constant set to my IPCPProcData object.
00067 
00068     void compute_rtoporder(int &max_visited_elems);
00069     ///< Compute the reverse topological ordering for my
00070     ///< IPCPProcData object;
00071 
00072     virtual Listable *listable_clone() const;
00073     virtual void print(ostream &o) const;
00074     virtual int structures_OK() const;
00075     ///< Functions required by Listable.
00076 
00077 private:
00078     IPCPProcData *_called_pgm_data;
00079     JumpFunction *_jump_function;
00080 };
00081 
00082 class IPCPProcData : public Listable {
00083 public:
00084     IPCPProcData(ProgramUnit &pgm, InterProcConstProp &ipcp,
00085                  const Statement &entry, int debug = 0);
00086     ///< Create a new IPCPProcData object for the given program unit,
00087     ///< entering at the given entry.  This constructor will compute
00088     ///< the side effects of this program unit.  It will also build
00089     ///< IPCPProcData objects for its called routines, if they
00090     ///< haven't already been built.
00091 
00092     IPCPProcData(ProgramUnit &cloned_proc,
00093          const Statement &clone_entry,
00094          IPCPProcData &orig_proc_data);
00095     ///< Create a new IPCPProcData object for the given cloned program unit
00096     ///< from the IPCPProcData object of the original program unit.
00097     ///< The constant sets of the other IPCPProcData object is not
00098     ///< copied to this object.
00099 
00100     virtual ~IPCPProcData();
00101 
00102     inline ProgramUnit &pgm();
00103     ///< Return the program unit associated with myself.
00104 
00105     inline const Statement &entry() const;
00106     ///< Return the ENTRY statement associated with myself.
00107 
00108     const IPCPCallData *call_data(const Statement &call_site) const;
00109     ///< Return the interprocedural constant data associated with the
00110     ///< the given call site.  If the given statement is not a call
00111     ///< site or the data structure does not exist, this method
00112     ///< returns NULL.
00113 
00114     inline const RefSet<Symbol> &used_global_vars() const;
00115     ///< Return the set of global variables used by this routine and
00116     ///< all called subroutines.
00117 
00118     inline const RefSet<Symbol> &usable_global_vars() const;
00119     ///< Return the set of global variables that may be used in a
00120     ///< constant expression belonging to this routine or a called
00121     ///< subroutine.
00122 
00123     RefSet<Symbol> *local_vars(const RefSet<Symbol> &vars) const;
00124     ///< Return the given set of variables, but renamed to the
00125     ///< procedure's local variable names.
00126 
00127     inline const RefList<Symbol> &param_list() const;
00128     ///< Return a list of my procedure's parameters.  These variables
00129     ///< are all global variables.
00130 
00131     inline const Symbol *return_var() const;
00132     ///< Return the global variable name of my function's return value.
00133     ///< If my procedure is not a function, this method returns NULL.
00134 
00135     inline const Boolean is_called_externally() const;
00136     ///< Return true if my program unit may be called by some call site
00137     ///< not recorded in some othe IPCPProcData object's call_data
00138     ///< field.
00139 
00140     inline void called_externally();
00141     ///< Mark my program unit as called externally.
00142 
00143     void create_return_jump_function(Map<Symbol, Expression> *old_const_mods,
00144                      Map<Symbol, Expression> *new_consts);
00145     ///< Create a return jump function for this object, where mod_vars
00146     ///< is a mapping from global variables to their new constant
00147     ///< expressions.
00148 
00149     void create_jump_function(const Statement &call_site,
00150                               Map<Symbol, Expression> *old_const_mods,
00151                               Map<Symbol, Expression> *new_consts,
00152                               List<Expression> *actuals);
00153     ///< Create a jump function for the given call site, where mod_vars
00154     ///< is a mapping from global variables to their new constant
00155     ///< expressions.
00156 
00157     inline const ReturnJumpFunction &return_jump_function() const;
00158     ///< Return the return jump function for this procedure.  This return
00159     ///< jump function captures all the side effects of this procedure.
00160     ///< It is assumed that the method create_return_jump_function has
00161     ///< been called previously.
00162 
00163     const RefList<Symbol> *call_formals(const Statement &call_site) const;
00164     ///< Return the list of formal parameters for the given call site,
00165     ///< if possible.
00166 
00167     Map<Symbol,Expression> *local_old_const_mods(const Statement &call_site,
00168                          const ReturnJumpFunction &jump_function) const;
00169     ///< Return a map of all the variable modifications (i.e., side-effects)
00170     ///< for the given jump function and for the actual parameters in
00171     ///< the given call site.  This method differs from
00172     ///< jump_function->old_const_mods() in that the returned mapping is
00173     ///< in terms of local variables rather than global variables.
00174 
00175     Map<Symbol,Expression> *local_new_consts(const Statement &call_site,
00176                          const ReturnJumpFunction &jump_function) const;
00177     ///< Return a map of all the new constant expressions generated by
00178     ///< the given call site.  This method differs from 
00179     ///< jump_function->new_consts() in that the returned mapping is
00180     ///< in terms of local variables rather than global variables.
00181 
00182     void add_constant_set(IPCPConstants *constants,
00183               const List<Expression> &param_values);
00184     ///< Add the given constant set to my set of constant sets.
00185 
00186     inline const List<IPCPConstants> &const_sets() const;
00187     ///< Return all the sets of constants that hold for my routine.
00188 
00189     void transfer_const_set(IPCPConstants &constants, IPCPProcData &other);
00190     ///< Transfer ownership of the given constant set from the other
00191     ///< IPCPProcData object to myself.  This method will also rename any
00192     ///< calls made to the program unit owning the other IPCPProcData
00193     ///< object, which the given constants are passed in, to the
00194     ///< program unit owning myself.  This method assumes that my
00195     ///< program unit is a clone of the other program unit.
00196 
00197     void add_consts_to_pgm(const IPCPConstants &consts);
00198     ///< Add all the constants in the given constant set to my program
00199     ///< unit.  This is done by inserting assignments to the constant
00200     ///< variables at the begining of the program.
00201 
00202     void add_consts_to_pgm();
00203     ///< Add my single constant set to my program unit.
00204     ///< This method will do nothing if I have no constant sets and
00205     ///< will 'p-assert' out if I have multiple constant sets.
00206     
00207     void build_jump_functions(int debug = 0);
00208     ///< Compute the side-effects of my program unit.  These side
00209     ///< effects, called jump functions, are computed for the exit of
00210     ///< this program unit as well as for the entry for each call site
00211     ///< in my program unit.
00212     ///<
00213     ///< If there is a a single constant set in my consts_sets field,
00214     ///< these constants would be used to compute my side effects.
00215 
00216     void propagate_constants(PC_UNREACH_BOOL remove_unreachable,
00217                  int debug = 0);
00218     ///< Propagate all local constants through my program, using the
00219     ///< interprocedural side-effect information I collected in my
00220     ///< constructor.
00221     ///< 
00222     ///< If one also wishes to also propagate interprocedural constants
00223     ///< in the program, the method add_consts_to_pgm() should be
00224     ///< called beforehand.
00225 
00226     void expand_all_substituted();
00227     ///< Expand all the constants stored in the substituted() fields
00228     ///< by the propagate_constants() method.
00229 
00230     void make_consts_sets_old();
00231     ///< Make all constant sets be old constant sets.  Used by
00232     ///< the have_consts_sets_changed() method below.
00233 
00234     Boolean have_consts_sets_changed() const;
00235     ///< Return True of the constant sets differ from the old constant
00236     ///< sets.
00237     
00238     inline int rtoporder() const;
00239     ///< Return the reverse topological ordering of my program unit in the
00240     ///< program's call graph.
00241 
00242     void init_rtoporder();
00243     ///< Initialize the rtoporder fields.
00244     ///< Should be called before calling compute_rtoporder();
00245 
00246     void compute_rtoporder(int &max_visited_elems);
00247     ///< Compute the reverse topological ordering for myself and
00248     ///< all called program units.
00249 
00250     void add_maymods();
00251     ///< Add MAYMOD assertions to all call sites within myself which I
00252     ///< know the side-effects to.
00253 
00254     virtual void print(ostream &o, Boolean pretty_print) const;
00255     ///< Print out all my fields.  If pretty_print=True, then
00256     ///< add carriage returns between my fields.
00257     
00258     virtual Listable *listable_clone() const;
00259     virtual void print(ostream &o) const;
00260     virtual int structures_OK() const;
00261     ///< Functions required by Listable.
00262 
00263 private:
00264     ProgramUnit *_pgm_ref;      ///< The ProgramUnit that my data belongs to.
00265     InterProcConstProp *_ipcp_ref; ///< Interprocedural constant propagator.
00266     const Statement *_entry;    ///< The entry statement I am associated_with.
00267     Database<String, IPCPCallData> _call_data;
00268                 ///< Data for each call site in program.
00269     RefSet<Symbol> _used_global_vars;
00270                                 ///< Set of all global vars.
00271     RefSet<Symbol> _usable_global_vars;
00272                                 ///< Set of all usable global vars.
00273     RefMap<Symbol, Symbol> _local_to_global_vars;
00274                                 ///< Map from local to global variable names. 
00275     RefMap<Symbol, Symbol> _global_to_local_vars;
00276                                 ///< Map from global to local variable names.
00277     RefList<Symbol> _param_list;
00278                                 ///< List of global parameter variables.
00279     const Symbol *_return_var;  ///< Global variable that holds return value.
00280     ReturnJumpFunction *_return_jump_function;
00281                                 ///< Side-effects of my program.
00282     List<IPCPConstants> _consts_sets; ///< Sets of constant variables.
00283     List<IPCPConstants> _old_consts_sets; ///< Sets of old constant variables.
00284     int _rtoporder;     ///< Reverse topological order of my program.
00285     Boolean _called_externally; ///< True if I may be called by some call
00286                 ///< site not contained in some IPCPProcData
00287                 ///< object's _call_data field.
00288 
00289     void _mark_external_func_calls(const Expression &expr);
00290     void _init_call_sites();
00291     const Symbol &_convert_local_to_global(const Symbol &local_var,
00292                            const char *global_namespace);
00293     void _init_params();
00294     void _add_params_to_set(RefSet<Symbol> &vars) const;
00295     void _init_usable_global_vars();
00296     void _add_refs_to_globals(const RefSet<Expression> &refs);
00297     void _init_used_global_vars();
00298     RefSet<Symbol> *_candidates() const;
00299     Boolean _contains_local_vars(const Expression &expr) const;
00300     Boolean _contains_local_vars(const Expression &expr,
00301                  const RefList<Symbol> &caller_formals) const;
00302     void _filter_out_local_vars(Map<Symbol, Expression> &var_mods) const;
00303     void _filter_out_local_vars(Map<Symbol, Expression> &var_mods,
00304                 const RefList<Symbol> &caller_formals) const;
00305     void _rename_locals_to_globals(Expression &expr) const;
00306     void _rename_locals_to_globals(Map<Symbol,Expression> &var_mods) const;
00307     void _rename_locals_to_globals(List<Expression> &expr_list) const;
00308     void _rename_globals_to_locals(Expression &expr) const;
00309     void _rename_globals_to_locals(Map<Symbol,Expression> &var_mods) const;
00310     Map<Symbol,Expression> *_local_consts(const IPCPConstants &consts) const;
00311     void _update_call_site(const char *call_site_tag,
00312                IPCPProcData &new_call_proc_data);
00313     Expression *_expr_del_global_substituted(Expression *expr);
00314     void _del_global_substituted();
00315 };
00316 
00317 
00318 ///< inline implementations
00319 
00320 
00321 inline const IPCPProcData *
00322 IPCPCallData::data_ref() const
00323 {
00324     return _called_pgm_data;
00325 }
00326 
00327 inline void
00328 IPCPCallData::data_ref(IPCPProcData *data)
00329 {
00330     _called_pgm_data = data;
00331 }
00332 
00333 inline Boolean
00334 IPCPCallData::jump_function_valid() const
00335 {
00336     return _jump_function != 0;
00337 }
00338 
00339 inline const JumpFunction &
00340 IPCPCallData::jump_function() const
00341 {
00342     p_assert(_jump_function,
00343              "IPCPCallData::_jump_function():  Jump function was not initialized.");
00344     return *_jump_function;
00345 }
00346 
00347 inline ProgramUnit &
00348 IPCPProcData::pgm()
00349 {
00350     return *_pgm_ref;
00351 }
00352 
00353 inline const Statement &
00354 IPCPProcData::entry() const
00355 {
00356     return *_entry;
00357 }
00358 
00359 inline const RefSet<Symbol> &
00360 IPCPProcData::used_global_vars() const
00361 {
00362     return _used_global_vars;
00363 }
00364 
00365 inline const RefSet<Symbol> &
00366 IPCPProcData::usable_global_vars() const
00367 {
00368     return _usable_global_vars;
00369 }
00370 
00371 inline const RefList<Symbol> &
00372 IPCPProcData::param_list() const
00373 {
00374     return _param_list;
00375 }
00376 
00377 inline const Symbol *
00378 IPCPProcData::return_var() const
00379 {
00380     return _return_var;
00381 }
00382 
00383 inline const ReturnJumpFunction &
00384 IPCPProcData::return_jump_function() const
00385 {
00386     p_assert(_return_jump_function,
00387              "IPCPProcData::_return_jump_function():  Return jump function was not initialized.");
00388     return *_return_jump_function;
00389 }
00390 
00391 inline const List<IPCPConstants> &
00392 IPCPProcData::const_sets() const
00393 {
00394     return _consts_sets;
00395 }
00396 
00397 inline int
00398 IPCPProcData::rtoporder() const
00399 {
00400     return _rtoporder;
00401 }
00402 
00403 inline const Boolean
00404 IPCPProcData::is_called_externally() const
00405 {
00406     return _called_externally;
00407 }
00408 
00409 inline void
00410 IPCPProcData::called_externally()
00411 {
00412     _called_externally = True;
00413 }
00414 
00415 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:57 2005