Polaris: SSAFullRangeDict.h Source File

SSAFullRangeDict.h

Go to the documentation of this file.
00001 #ifndef _SSA_FULL_RANGE_DICT_H
00002 #define _SSA_FULL_RANGE_DICT_H
00003 ///
00004 /// file SSAFullRangeDict.h
00005 ///
00006 /// \class SSAFullRangeDict 
00007 /// \brief Collection of ranges extracted from SSA program's control flow
00008 /// \defgroup Polaris
00009 /// \ingroup Polaris
00010 ///  Range
00011 /// \see SSAFullRangeDict.h
00012 /// \see SSAFullRangeDict.h
00013 /// \see SSAFullRangeDict.cc
00014 ///
00015 /// \endcode
00016 /// \section Overview Overview
00017 /// An SSAFullRangeDict object is a repository for variable
00018 /// ranges for a program unit in SSA form.  Ranges derived from
00019 /// both data flow and control flow are collected, (unlike
00020 /// SSAControlRangeDict.h).
00021 ///
00022 /// \endcode
00023 /// \section Description Description
00024 /// An SSAFullRangeDict object is a repository of the variable
00025 /// ranges for all points of a program unit in SSA form.  These ranges
00026 /// are extracted from the data flow and control flow of the program;
00027 /// that is, they are taken from IF conditional tests, DO statements,
00028 /// and CSRD$ ASSERT statements, assignment statements, and phi
00029 /// statements.
00030 ///
00031 /// SSAFullRangeDict objects are demand-driven.  That is, they
00032 /// compute the ranges for a particular statement only when they
00033 /// are asked for.  If instead, the user wishes to have all the
00034 /// program unit's ranges to be computed at once, the user can
00035 /// call the touch() method..
00036 ///
00037 /// The algorithm for computing the ranges of a program on demand
00038 /// using SSA form can be found in Blume and Eigenmann, "Demand-
00039 /// Driven Symbolic Range Propagation".
00040 ///
00041 #include "Collection/Map.h"
00042 #include "Collection/RefMap.h"
00043 #include "Collection/Database.h"
00044 #include "Symbol/Symbol.h"
00045 #include "Expression/Expression.h"
00046 #include "Statement/Statement.h"
00047 #include "Array.h"
00048 #include "String.h"
00049 #include "IntElem.h"
00050 ///
00051 #include "RangeDict.h"
00052 #include "SSAControlRangeDict.h"
00053 #include "SSAFullRangeData.h"
00054 #include "ExprSet.h"
00055 ///
00056 class IntSet;
00057 class SSAProgramUnit;
00058 
00059 class SSAFullRangeDict : public RangeDict {
00060     friend SSAFullRangeData;
00061 public:
00062     SSAFullRangeDict(SSAProgramUnit &pgm, int debug = 0);
00063     virtual ~SSAFullRangeDict();
00064 
00065     void touch();
00066     ///< Force this object to compute the ranges for each statement
00067     ///< in the program unit.
00068 
00069     void control_touch();
00070     ///< Force this object to compute the ranges for each statement
00071     ///< in the program unit.  Only ranges derived from control flow
00072     ///< is touched.
00073 
00074     void data_touch();
00075     ///< Force this object to compute the ranges for each statement
00076     ///< in the program unit.  Only ranges derived from data flow
00077     ///< is touched.  (However, touching these data ranges may
00078     ///< cause some control ranges to be computed.)
00079 
00080     void clear();
00081     ///< Clear all saved data and control ranges stored within myself.
00082 
00083     void clear_ranges();
00084     ///< Clear all saved data and control ranges stored within myself.
00085     ///< Like clear() except some control range information is still
00086     ///< kept.
00087 
00088     SSAControlRangeDict &control_range_dict();
00089     ///< Return my control range dictionary.
00090 
00091     int num_data_ranges() const;
00092     ///< Return the number of data ranges created since my construction
00093     ///< or the last call to clear().
00094 
00095     int num_poisoned_ranges() const;
00096     ///< Return the number of poisoned ranges created during the
00097     ///< last invocation of _get_range_ref().
00098 
00099     virtual void print(ostream & o) const;
00100     ///< Print out the range dictionary.  This operation is
00101     ///< essentially just a dump of the data structures of the
00102     ///< range dictionary.
00103 
00104     virtual void pretty_print(ostream & o, const Statement &stmt) const;
00105     ///< Print out the range dictionary in a more user-readable
00106     ///< manner.
00107 
00108     virtual Listable *listable_clone(void) const;
00109     virtual int structures_OK() const;
00110     ///< Methods required by Listable
00111 
00112 protected:
00113     virtual void _set_range(const Symbol &var, const Statement &stmt,
00114                     Expression *range);
00115     ///< Not implemented.  Will p_assert if called.
00116 
00117     virtual void _del_range(const Symbol &var, const Statement &stmt);
00118     ///< Not implemented.  Will p_assert if called.
00119 
00120     virtual const Expression *_get_range_ref(const Symbol &var,
00121                                  const Statement &stmt);
00122     ///< Return the range associated with the given variable.  If the
00123     ///< variable doesn't have an associated range, return 0;
00124 
00125 private:
00126     SSAProgramUnit *_pgm_ref;   ///< Program unit for this range dict.
00127     Database<String, IntElem> *_stmt_toporder;
00128                                 ///< Topological ordering of the pgm's stmts.
00129     ExprSet _range_values;      ///< All the values that ranges may take.
00130     Map<Statement, RefMap<Symbol, Expression> > _pgm_ranges;
00131                                 ///< Variable ranges for each statement
00132                                 ///< in the program.
00133     SSAControlRangeDict _control_ranges;
00134                                 ///< The control ranges of the program.
00135     Map<Symbol, Expression> _data_ranges;
00136                                 ///< Data ranges holding for each statement.
00137     ExprSet _poisoned_ranges;
00138                                 ///< Poisoned ranges holding for each
00139                                 ///< statement.  Used only as a receptacle
00140                                 ///< for ownership of the poisoned ranges,
00141                                 ///< which are temporary.
00142     Map<Symbol, SSAFullRangeData> _pending_ranges;
00143                                 ///< Info on ranges currently being computed.
00144     int _timestamp;             ///< Timestamp indicating current invocation
00145                                 ///< of _get_data_range_ref().
00146     int _num_poisoned_ranges;   ///< Number of poisoned ranges created
00147                 ///< during last call to _get_range_ref.
00148 
00149     const Expression &_ins_data_range(const Symbol &var, Expression *range);
00150     void _order_args(SSAFullRangeData &data) const;
00151     SSAFullRangeData *_create_data(const Statement &stmt, int &df_num,
00152                                    RefList<SSAFullRangeData> &scc_node_stack);
00153     void _mark_data_as_computed(SSAFullRangeData &data);
00154     void _commit_data(SSAFullRangeData &data);
00155     void _delete_data(SSAFullRangeData &data);
00156     SSARangeOrData _probe_data_ranges(const Symbol &var, int &df_num,
00157                                       RefList<SSAFullRangeData> &scc_node_stack);
00158     void _calc_iter_order1(SSAFullRangeData &data,
00159                            RefList<SSAFullRangeData> &iter_order_list);
00160     Array<SSAFullRangeData *> *_calc_iter_order(SSAFullRangeData &root_node);
00161     void _iterate_to_fixed_point_phase(const Array<SSAFullRangeData *> &toporder_to_stmt,
00162                                        const IntSet &start_stmts,
00163                                        bool widening_phase);
00164     void _iterate_to_fixed_point(SSAFullRangeData &root_node);
00165     const Expression *_get_data_range_ref(const Symbol &var,
00166                                           bool &is_poisoned);
00167 };
00168 
00169 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:08 2005