Polaris: PropConstMap.h Source File

PropConstMap.h

Go to the documentation of this file.
00001 ///
00002 #ifndef _PROPCONSTMAP_H
00003 #define _PROPCONSTMAP_H
00004 ///
00005 ///
00006 /// file PropConstMap.h
00007 ///
00008 /// \class PropConstMap 
00009 /// \brief Holds the constant values of program variables
00010 /// \defgroup Polaris
00011 /// \ingroup Polaris
00012 ///  Constant
00013 /// \see PropConstMap.h
00014 /// \see PropConstMap.h
00015 /// \see PropConstMap.cc
00016 ///
00017 /// \endcode
00018 /// \section Description Description
00019 /// This file declares a PropConstMap object and its subcomponents.  A
00020 /// PropConstMap object maps a set of variables to their symbolic or
00021 /// integer constant values.  A PropConstIntMap object maps a set of
00022 /// variables to only their integer constant values.  A PropConstElem
00023 /// object represents the constant value of a single variable, if it is
00024 /// constant.  A PropConstValue object represents a constant symbolic
00025 /// expression.
00026 ///
00027 /// PropConstValue objects represent the constant symbolic expressions
00028 /// that variables may take.  These objects not only keep track of
00029 /// the symbolic constant values, but also the statement that these
00030 /// values originated from.  This is necessary for the constant propagator
00031 /// to determine which definitions reach each variable used by the
00032 /// constant expression.
00033 ///
00034 /// PropConstElem objects indicate whether a particular variable is
00035 /// a symbolic constant or not.  They also hold the variable's constant
00036 /// value, if it is a symbolic constant.  PropConstElem objects also
00037 /// include methods for updating or computing the constant status
00038 /// of individual variables.
00039 ///
00040 /// PropConstIntMap objects determine which variables are integer
00041 /// constants as well as their constant values.  Integer constants
00042 /// are constants that can take on only integer values.  Logical
00043 /// constants are treated as integer constants that can take on only
00044 /// the values 0 or 1.  Integer constants and symbolic constants are
00045 /// kept and computed separately since variables can take on
00046 /// an integer constant value but not a symbolic constant value or
00047 /// vice versa.  For example, for A=<non-const> and B=A, variable B
00048 /// takes on the symbolic constant value "A" but has no integer constant
00049 /// value.  On the other hand, at a join statement where B=1+3 for
00050 /// one path and B=2+2 for the other, B takes on the integer constant
00051 /// of 4 at this join but has no symbolic constant value since the
00052 /// unevaluated expressions differ.
00053 ///
00054 /// PropConstMap objects determine which variables are symbolic
00055 /// constants as well as their constant values.  They also contain
00056 /// PropConstIntMap objects, so in fact they keep track of both integer
00057 /// and symbolic constants.  Various methods are provided to update
00058 /// the constant values within themselves.
00059 ///
00060 #include <stream.h>
00061 ///
00062 #include "../Expression/Expression.h"
00063 #include "../Statement/Statement.h"
00064 #include "../Symbol/Symbol.h"
00065 #include "../Collection/Map.h"
00066 #include "../Array.h"
00067 #include "../IntElem.h"
00068 #include "../IntSet.h"
00069 #include "../p-assert.h"
00070 ///
00071 class PropConstValue : public Listable {
00072 public:
00073     PropConstValue(const Expression &expr, const Statement &stmt,
00074                    int stmt_toporder, const Map<Symbol,IntElem> &candidates);
00075     PropConstValue(const PropConstValue &other);
00076     virtual ~PropConstValue();
00077 
00078     inline const Expression &expr() const;
00079     ///< Return my constant expression.
00080 
00081     inline const Statement &stmt() const;
00082     ///< Return the statement that defines my constant expression.
00083 
00084     inline const IntSet &use_set() const;
00085     ///< Return the set of variables that my constant expression uses.
00086 
00087     inline int stmt_toporder() const;
00088     inline void stmt_toporder(int val);
00089     ///< Return the topolgical ordering of my statement.
00090     ///< Used as a tie-breaker for choosing between two equivalent
00091     ///< PropConstValue objects.
00092 
00093     virtual Listable *listable_clone() const;
00094     virtual void print(ostream &o) const;
00095     virtual int structures_OK() const;
00096     ///< Functions required by Listable.
00097 
00098 private:
00099     Expression *_expr;      ///< A constant expression.
00100     const Statement *_stmt; ///< Statement defining the constant expr 
00101     IntSet _use_set;            ///< Set of variables used in constant expr
00102     Boolean _has_integer_val;   ///< True if constant is an integer constant
00103     int _integer_val;       ///< Integer value of constant expr.
00104     int _toporder;      ///< Reverse topological sort order pf stmt
00105 };
00106 
00107 enum CONST_STATE {
00108     MAY_BE_CONST,      ///< Var. may or may not be constant.
00109     CONST,         ///< Var. is constant.
00110     NON_CONST,         ///< Var. is not constant.
00111 };
00112 
00113 class PropConstElem {
00114 public:
00115     PropConstElem();
00116     ///< Create a PropConstElem object in a MAY_BE_CONST state.
00117 
00118     PropConstElem(const PropConstElem &);
00119     ~PropConstElem();
00120 
00121     inline const Statement *last_mod() const;
00122     ///< Return the earliest statement in the control flow graph where
00123     ///< the current variable would have the same value as it would have
00124     ///< at the current statement.
00125 
00126     const Expression &expr() const;
00127     ///< If I am constant, return its value.
00128 
00129     const IntSet &use_set() const;
00130     ///< Return the set of candidate variables used by the constant
00131     ///< expression.  Only valid when I am a constant.
00132 
00133     const PropConstValue &const_val() const;
00134     ///< If I am constant, return my PropConstValue object.
00135 
00136     inline CONST_STATE state() const;
00137     ///< Return the state.
00138 
00139     void constant(const PropConstValue &const_val);
00140     ///< Become a constant whose value is the right hand side of the
00141     ///< given workspace object.
00142     ///< Illegal if my state is NON_CONST.
00143 
00144     void non_const(const Statement &);
00145     ///< Make the variable be no longer be a constant.  The last
00146     ///< modification of the variable would be set to the given
00147     ///< statement.
00148 
00149     void intersect(const PropConstElem &other, const Statement &curr_stmt);
00150     ///< Intersect the other constant holder with myself.  That is,
00151     ///< if the other constant holder is non-constant or is a
00152     ///< constant with a different constant value than myself, make
00153     ///< myself be non-constant.
00154     
00155     PropConstElem &operator = (const PropConstElem &);
00156     ///< Set my value to the other object's value.
00157 
00158     int operator == (const PropConstElem &) const;
00159     inline int operator != (const PropConstElem &) const;
00160     ///< Compare the two objects.  Two PropConstElems are equal if and
00161     ///< only if their states are equal, their last_mods are equal,
00162     ///< and if they are both have constant states, their constant
00163     ///< expressions and value numbers are equal.
00164 
00165     void print(ostream &o) const;
00166     friend ostream & operator << (ostream &o, const PropConstElem &pce);
00167     ///< Print out the constant value stored within myself
00168 
00169     int structures_OK(void) const;
00170     ///< Return 1 if my structures are in a valid state.  Otherwise,
00171     ///< print an error and return 0.
00172 
00173 private:
00174     const Statement *_last_mod; ///< Last modification point for variable.
00175     const PropConstValue *_const_val; ///< Workspace belonging to const stmt.
00176     
00177     Boolean _const_equal(const PropConstElem &) const;
00178 };
00179 
00180 class PropConstIntMap {
00181 public:
00182     PropConstIntMap(int num_consts, const Array<Symbol *> &tag_to_candidate);
00183     PropConstIntMap(const PropConstIntMap &other);
00184     virtual ~PropConstIntMap();
00185 
00186     inline const Array<Symbol *> &tag_to_candidate() const;
00187     ///< Return the map from integer tags to variable candidates.
00188 
00189     CONST_STATE state(int sym_tag) const;
00190     ///< Return the constant state for the variable with the given tag.
00191 
00192     void constant(int sym_tag, int const_val);
00193     ///< Make the variable with the given tag be a constant with the 
00194     ///< given value.
00195 
00196     void non_const(int sym_tag);
00197     ///< Make the variable with the given tag be non-constant.
00198 
00199     int int_const_val(int sym_tag) const;
00200     ///< Return the integer constant value for the variable with the
00201     ///< given symbol tag.  Not valid if the variable is not constant.
00202 
00203     inline int entries() const;
00204     ///< Return the number of entries in the constant map
00205 
00206     void all_non_const();
00207     ///< Make all variables within myself be non-constant.
00208 
00209     void intersect(const PropConstIntMap &other);
00210     ///< Intersect the other constant map with myself.
00211 
00212     PropConstIntMap &operator = (const PropConstIntMap &other);
00213     ///< Set my constant values to the other objects value
00214 
00215     int operator == (const PropConstIntMap &) const;
00216     inline int operator != (const PropConstIntMap &) const;
00217     ///< Compare the two maps.
00218 
00219     void print(ostream &o) const;
00220     friend ostream & operator << (ostream &o, const PropConstIntMap &pcm);
00221     ///< Print out the constant value stored within myself.
00222 
00223     void pretty_print(ostream &o) const;
00224     ///< Print out the constant values stored within myself in a more
00225     ///< lengthy but user readable format.
00226 
00227     int structures_OK(void) const;
00228     ///< Return 1 if my structures are in a valid state.  Otherwise,
00229     ///< print an error and return 0.
00230 
00231 private:
00232     Array<int> _const_map;  ///< Collection of constant values for vars.
00233     IntSet _const_elems;    ///< Set of constant variables.
00234     IntSet _undefined_elems;    ///< Set of undefined variables.
00235     const Array<Symbol *> *_tag_to_candidate;
00236                 ///< Maps integers to variable candidates.
00237 };
00238 
00239 class PropConstMap {
00240 public:
00241     PropConstMap(int num_consts, const Array<Symbol *> &tag_to_candidate);
00242     PropConstMap(const PropConstMap &other);
00243     virtual ~PropConstMap();
00244 
00245     inline const Array<Symbol *> &tag_to_candidate() const;
00246     ///< Return the map from integer tags to variable candidates.
00247 
00248     inline PropConstElem &operator [] (int sym_tag) const;
00249     ///< Return the constant value of the variable with the given symbol
00250     ///< tag.
00251 
00252     inline int entries() const;
00253     ///< Return the number of entries in the constant map
00254 
00255     void all_non_const(const Statement &stmt);
00256     ///< Make all variables within myself be non-constant.
00257 
00258     inline CONST_STATE int_state(int sym_tag) const;
00259     ///< Return the integer constant state for the variable with the
00260     ///< given tag.
00261 
00262     inline void int_const(int sym_tag, int const_val);
00263     ///< Make the variable with the given tag be an integer constant with
00264     ///< the given value.
00265 
00266     inline void int_non_const(int sym_tag);
00267     ///< Make the variable with the given tag be an integer non-constant.
00268 
00269     inline int int_const_val(int sym_tag) const;
00270     ///< Return the integer constant value for the variable with the
00271     ///< given symbol tag.  Not valid if the variable is not constant.
00272 
00273     void intersect(const PropConstMap &other, const Statement &stmt);
00274     ///< Intersect the other constant map with myself.
00275 
00276     PropConstMap &operator = (const PropConstMap &other);
00277     ///< Set my constant values to the other objects value
00278 
00279     int operator == (const PropConstMap &) const;
00280     inline int operator != (const PropConstMap &) const;
00281     ///< Compare the two maps.
00282 
00283     void print(ostream &o) const;
00284     friend ostream & operator << (ostream &o, const PropConstMap &pcm);
00285     ///< Print out the constant value stored within myself.
00286 
00287     void pretty_print(ostream &o) const;
00288     ///< Print out the constant values stored within myself in a more
00289     ///< lengthy but user readable format.
00290 
00291     int structures_OK(void) const;
00292     ///< Return 1 if my structures are in a valid state.  Otherwise,
00293     ///< print an error and return 0.
00294 
00295 private:
00296     Array<PropConstElem> _const_map;
00297                 ///< Collection of symbolic constant values
00298     PropConstIntMap _int_const_map;
00299                 ///< Collection of integer constant values.
00300     const Array<Symbol *> *_tag_to_candidate;
00301                 ///< Maps integers to variable candidates.
00302 };
00303 
00304 
00305 ///< inline implementations
00306 
00307 
00308 inline const Expression &
00309 PropConstValue::expr() const
00310 {
00311     return *_expr;
00312 }
00313 
00314 inline const Statement &
00315 PropConstValue::stmt() const
00316 {
00317     return *_stmt;
00318 }
00319 
00320 inline const IntSet &
00321 PropConstValue::use_set() const
00322 {
00323     return _use_set;
00324 }
00325 
00326 inline int
00327 PropConstValue::stmt_toporder() const
00328 {
00329     return _toporder;
00330 }
00331 
00332 inline void
00333 PropConstValue::stmt_toporder(int val)
00334 {
00335     _toporder = val;
00336 }
00337 
00338 inline const Statement *
00339 PropConstElem::last_mod() const
00340 {
00341     return _last_mod;
00342 }
00343 
00344 inline CONST_STATE
00345 PropConstElem::state() const
00346 {
00347     if (! _last_mod)
00348     return MAY_BE_CONST;
00349     else if (_const_val)
00350     return CONST;
00351     else
00352     return NON_CONST;
00353 }
00354 
00355 inline int
00356 PropConstElem::operator != (const PropConstElem &other) const
00357 {
00358     return (! (*this == other));
00359 }
00360 
00361 inline const Array<Symbol *> &
00362 PropConstIntMap::tag_to_candidate() const
00363 {
00364     return *_tag_to_candidate;
00365 }
00366 
00367 inline int
00368 PropConstIntMap::entries() const
00369 {
00370     return _const_map.entries();
00371 }
00372 
00373 inline int
00374 PropConstIntMap::operator != (const PropConstIntMap &other) const
00375 {
00376     return (! (*this == other));
00377 }
00378 
00379 inline const Array<Symbol *> &
00380 PropConstMap::tag_to_candidate() const
00381 {
00382     return *_tag_to_candidate;
00383 }
00384 
00385 inline PropConstElem &
00386 PropConstMap::operator [] (int sym_tag) const
00387 {
00388     return CASTAWAY(PropConstElem &) _const_map[sym_tag];
00389 }
00390 
00391 inline int
00392 PropConstMap::entries() const
00393 {
00394     return _const_map.entries();
00395 }
00396 
00397 inline CONST_STATE
00398 PropConstMap::int_state(int sym_tag) const
00399 {
00400     return _int_const_map.state(sym_tag);
00401 }
00402 
00403 inline void
00404 PropConstMap::int_const(int sym_tag, int const_val)
00405 {
00406     _int_const_map.constant(sym_tag, const_val);
00407 }
00408 
00409 inline void 
00410 PropConstMap::int_non_const(int sym_tag)
00411 {
00412     _int_const_map.non_const(sym_tag);
00413 }
00414 
00415 inline int
00416 PropConstMap::int_const_val(int sym_tag) const
00417 {
00418     return _int_const_map.int_const_val(sym_tag);
00419 }
00420 
00421 inline int
00422 PropConstMap::operator != (const PropConstMap &other) const
00423 {
00424     return (! (*this == other));
00425 }
00426 
00427 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:02 2005