00001 #ifndef HINDEXED_LATTICE_H 00002 #define HINDEXED_LATTICE_H 00003 00004 // This is a lattice indexed ONLY by a hash function 00005 // on the IndexObj 00006 00007 #include <common/suif_hash_map.h> 00008 #include "lattice_utils_forwarders.h" 00009 00010 // This contains a map from variable->lattice_value 00011 // All this does is look up 00012 // It should just become a class parameterized by the 00013 // index. 00014 // 00015 template <class IndexObj, class SubLattice> 00016 class HIndexedLattice { 00017 00018 typedef suif_hash_map<IndexObj, SubLattice> VMap; 00019 typedef typename VMap::const_iterator ConstVIter; 00020 typedef typename VMap::iterator VIter; 00021 VMap *_values; 00022 SubLattice _default_value; 00023 public: 00024 HIndexedLattice(SubLattice def); 00025 HIndexedLattice(const HIndexedLattice &other); 00026 HIndexedLattice &operator=(const HIndexedLattice &other); 00027 ~HIndexedLattice(); 00028 void set_value(IndexObj v, SubLattice val); 00029 SubLattice get_value(IndexObj v) const; 00030 SubLattice get_default_value() const; 00031 00032 bool do_meet_with_test(const HIndexedLattice &other); 00033 HIndexedLattice *clone() const; 00034 00035 // pass in a function pointer to a function that 00036 // works on one 00037 bool do_apply_fn_with_test(const HIndexedLattice &other, 00038 bool(*fn) (SubLattice &, const SubLattice &)); 00039 00040 // To string must be passed functions that convert 00041 #if 0 00042 // egcs 1.1.2 bug prevents this 00043 String to_string( String (*index_to_string) (const IndexObj &), 00044 String (*lattice_to_string) (const SubLattice &), 00045 String delimiter) const; 00046 #endif 00047 00048 class iterator { 00049 suif_hash_map<IndexObj,SubLattice> *_map; 00050 suif_hash_map<IndexObj,SubLattice>::iterator _iter; 00051 suif_hash_map<IndexObj,SubLattice>::iterator _iter_end; 00052 public: 00053 iterator(const HIndexedLattice *map) : 00054 _map(map->_values), 00055 _iter(map->_values->begin()), 00056 _iter_end(map->_values->end()) 00057 {} 00058 iterator(const iterator &other) : 00059 _map(other._map), 00060 _iter(other._iter), 00061 _iter_end(other._iter_end) 00062 {} 00063 iterator &operator=(const iterator &other) { 00064 _map = other._map; 00065 _iter = other._iter; 00066 _iter_end = other._iter_end; 00067 return(*this); 00068 } 00069 IndexObj current() const { 00070 return ((*_iter).first); 00071 } 00072 SubLattice current_val() const { 00073 return ((*_iter).second); 00074 } 00075 bool is_valid() const { 00076 return (_iter != _iter_end); 00077 } 00078 void next() { _iter++; } 00079 void reset() { 00080 _iter = _map->_values->begin(); 00081 _iter_end = _map->_values->end(); 00082 } 00083 }; 00084 friend class iterator; 00085 00086 }; 00087 00088 // Here are the definitions 00089 00090 template <class IndexObj, class SubLattice> 00091 HIndexedLattice<IndexObj, SubLattice>:: 00092 HIndexedLattice(SubLattice def) : 00093 _values( new suif_hash_map<IndexObj, SubLattice>()), 00094 _default_value(def) 00095 {} 00096 00097 template <class IndexObj, class SubLattice> 00098 HIndexedLattice<IndexObj, SubLattice>:: 00099 HIndexedLattice(const HIndexedLattice<IndexObj, SubLattice> &other) : 00100 _values( new suif_hash_map<IndexObj, SubLattice>()), 00101 _default_value(other._default_value) 00102 { 00103 for (VIter iter = 00104 other._values->begin(); iter != other._values->end(); iter++) { 00105 _values->enter_value((*iter).first, (*iter).second); 00106 } 00107 } 00108 00109 template <class IndexObj, class SubLattice> 00110 HIndexedLattice<IndexObj, SubLattice> & 00111 HIndexedLattice<IndexObj, SubLattice>:: 00112 operator=(const HIndexedLattice<IndexObj, SubLattice> &other) { 00113 _values->clear(); 00114 for (VIter iter = 00115 other._values->begin(); iter != other._values->end(); iter++) { 00116 _values->enter_value((*iter).first, (*iter).second); 00117 } 00118 _default_value = other._default_value; 00119 return(*this); 00120 } 00121 00122 00123 00124 template <class IndexObj, class SubLattice> 00125 HIndexedLattice<IndexObj, SubLattice>:: 00126 ~HIndexedLattice() { 00127 delete _values; 00128 } 00129 00130 template <class IndexObj, class SubLattice> 00131 void HIndexedLattice<IndexObj, SubLattice>:: 00132 set_value(IndexObj v, SubLattice val) { 00133 _values->enter_value(v, val); 00134 } 00135 00136 template <class IndexObj, class SubLattice> 00137 SubLattice HIndexedLattice<IndexObj, SubLattice>:: 00138 get_value(IndexObj v) const { 00139 suif_hash_map<IndexObj, SubLattice>::const_iterator iter = 00140 _values->find(v); 00141 if (iter == _values->end()) 00142 return(get_default_value()); 00143 return((*iter).second); 00144 } 00145 00146 template <class IndexObj, class SubLattice> 00147 SubLattice HIndexedLattice<IndexObj, SubLattice>:: 00148 get_default_value() const { 00149 return(_default_value); 00150 } 00151 00152 template <class IndexObj, class SubLattice> 00153 bool HIndexedLattice<IndexObj, SubLattice>:: 00154 do_meet_with_test(const HIndexedLattice &other) { 00155 // This is just do_apply_fn with test but the FN is 00156 // meet. 00157 00158 bool changed = false; 00159 // Make a list of all of the ones that are not default 00160 suif_hash_map<IndexObj, bool> v; 00161 for (iterator iter(this); iter.is_valid(); iter.next()) { 00162 v.enter_value(iter.current(), true); 00163 } 00164 for (iterator iter(&other); iter.is_valid(); iter.next()) { 00165 v.enter_value(iter.current(), true); 00166 } 00167 00168 // Now walk over that list and apply for each 00169 for (suif_hash_map<IndexObj, bool>::iterator it = 00170 v.begin(); it != v.end(); it++) { 00171 IndexObj obj = (*it).first; 00172 SubLattice v1 = get_value(obj); 00173 SubLattice v2 = other.get_value(obj); 00174 // This is the function 00175 if (v1.do_meet_with_test(v2)) { 00176 changed = true; 00177 set_value(obj, v1); 00178 } 00179 } 00180 return(changed); 00181 } 00182 00183 template <class IndexObj, class SubLattice> 00184 HIndexedLattice<IndexObj,SubLattice> *HIndexedLattice<IndexObj, SubLattice>:: 00185 clone() const { 00186 HIndexedLattice *new_l = 00187 new HIndexedLattice(*this); 00188 return(new_l); 00189 } 00190 00191 template <class IndexObj, class SubLattice> 00192 bool HIndexedLattice<IndexObj, SubLattice>:: 00193 do_apply_fn_with_test(const HIndexedLattice &other, 00194 bool(*fn) (SubLattice &, const SubLattice &)) { 00195 bool changed = false; 00196 // Make a list of all of the ones that are not default 00197 suif_hash_map<IndexObj, bool> v; 00198 for (iterator iter(this); iter.is_valid(); iter.next()) { 00199 v.enter_value(iter.current(), true); 00200 } 00201 for (iterator iter(&other); iter.is_valid(); iter.next()) { 00202 v.enter_value(iter.current(), true); 00203 } 00204 00205 // Now walk over that list and apply for each 00206 for (suif_hash_map<IndexObj, bool>::iterator it = 00207 v.begin(); it != v.end(); it++) { 00208 IndexObj obj = (*it).first; 00209 SubLattice v1 = get_value(obj); 00210 SubLattice v2 = other.get_value(obj); 00211 if ((*fn)(v1, v2)) { 00212 changed = true; 00213 set_value(obj, v1); 00214 } 00215 } 00216 return(changed); 00217 } 00218 00219 /* This does NOT work in egcs 1.1.2 because of template problems */ 00220 #if 0 00221 template <class IndexObj, class SubLattice> 00222 String HIndexedLattice<IndexObj, SubLattice>:: 00223 to_string( 00224 String (*index_to_string)(const IndexObj &), 00225 String (*lattice_to_string)(const SubLattice &), 00226 String delimiter) const { 00227 String s; 00228 // Print the default value first 00229 s += "default: "; 00230 s += lattice_to_string(get_default_value()); 00231 s += delimiter; 00232 00233 for ( terator iter(this); 00234 iter.is_valid(); iter.next()) { 00235 IndexObj idx = iter.current(); 00236 s += index_to_string(idx); 00237 s += ": "; 00238 SubLattice l = get_value(idx); 00239 s += lattice_to_string(l); 00240 s += delimiter; 00241 } 00242 return(s); 00243 }; 00244 #endif 00245 00246 00247 #endif /* HINDEXED_LATTICE_H */