|
||
Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
memoryaccess.hGo to the documentation of this file.00001 // $Id: memoryaccess.h,v 1.33 2003/08/07 23:14:23 pnav Exp $ 00002 // ---------------------------------------------------------------------- 00003 // 00004 // C-Breeze 00005 // C Compiler Framework 00006 // 00007 // Copyright (c) 2000 University of Texas at Austin 00008 // 00009 // Samuel Z. Guyer 00010 // Daniel A. Jimenez 00011 // Calvin Lin 00012 // 00013 // Permission is hereby granted, free of charge, to any person 00014 // obtaining a copy of this software and associated documentation 00015 // files (the "Software"), to deal in the Software without 00016 // restriction, including without limitation the rights to use, copy, 00017 // modify, merge, publish, distribute, sublicense, and/or sell copies 00018 // of the Software, and to permit persons to whom the Software is 00019 // furnished to do so, subject to the following conditions: 00020 // 00021 // The above copyright notice and this permission notice shall be 00022 // included in all copies or substantial portions of the Software. 00023 // 00024 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00025 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00026 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00027 // NONINFRINGEMENT. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT 00028 // AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 00029 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 00030 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00031 // THE SOFTWARE. 00032 // 00033 // We acknowledge the C-to-C Translator from MIT Laboratory for 00034 // Computer Science for inspiring parts of the C-Breeze design. 00035 // 00036 // ---------------------------------------------------------------------- 00037 00038 #ifndef CBZ_MEMORYACCESS_H 00039 #define CBZ_MEMORYACCESS_H 00040 00041 #include <set> 00042 #include "pointeroptions.h" 00043 #include "location.h" 00044 00045 // microsoft compiler does not like this include 00046 #ifndef _MSC_VER 00047 #include <ext/hash_map> 00048 #include <ext/hash_set> 00049 #endif 00050 00051 // -- Some forward declarations 00052 00053 class memoryBlock; 00054 class memoryDef; 00055 class memoryUse; 00056 class memorydef_key; 00057 00069 template< class T > 00070 class vector_set : public vector< T > 00071 { 00072 public: 00073 00074 vector_set() 00075 { 00076 reserve(10); 00077 } 00078 00079 inline void insert(T element) 00080 { 00081 int s = size(); 00082 for (int i = 0; i < s; i++) 00083 if ((*this)[i] == element) 00084 return; 00085 00086 // if (std::find(begin(), end(), element) == end()) 00087 00088 push_back(element); 00089 } 00090 00091 inline void insert(typename vector< T >::const_iterator b, 00092 typename vector< T >::const_iterator e) 00093 { 00094 for (typename vector< T >::const_iterator p = b; 00095 p != e; 00096 p++) 00097 insert(*p); 00098 } 00099 00100 inline typename vector< T >::const_iterator find(T element) const { 00101 return std::find(begin(), end(), element); 00102 } 00103 00104 inline typename vector< T >::iterator find(T element) { 00105 return std::find(begin(), end(), element); 00106 } 00107 }; 00108 00115 typedef vector_set< memoryBlock * > memoryblock_set; 00116 typedef memoryblock_set::iterator memoryblock_set_p; 00117 typedef memoryblock_set::const_iterator memoryblock_set_cp; 00118 00127 typedef vector< memorydef_key > memorydef_list; 00128 typedef memorydef_list::iterator memorydef_list_p; 00129 typedef memorydef_list::const_iterator memorydef_list_cp; 00130 00134 typedef set< memoryDef * > memorydef_set; 00135 typedef memorydef_set::iterator memorydef_set_p; 00136 typedef memorydef_set::const_iterator memorydef_set_cp; 00137 00138 typedef map< Location *, memoryDef * > memorydef_location_map; 00139 typedef memorydef_location_map::iterator memorydef_location_map_p; 00140 typedef memorydef_location_map::const_iterator memorydef_location_map_cp; 00141 00142 00143 //typedef list< memoryUse *, memoryuse_alloc > memoryuse_list; 00144 typedef vector< memoryUse * /* , memoryuse_alloc */ > memoryuse_list; 00145 typedef memoryuse_list::iterator memoryuse_list_p; 00146 typedef memoryuse_list::const_iterator memoryuse_list_cp; 00147 00148 typedef set< memoryUse * > memoryuse_set; 00149 typedef memoryuse_set::iterator memoryuse_set_p; 00150 typedef memoryuse_set::const_iterator memoryuse_set_cp; 00151 00152 // ------------------------------------------------------------ 00153 // memoryAccess 00154 // ------------------------------------------------------------ 00155 00158 typedef enum Multiplicity 00159 { Top, Deallocated, Unallocated, Single, Bounded, Unbounded, Error } Multiplicity; 00160 00161 // Common base class for both defs and uses 00162 00163 class memoryAccess : public PerClassHeap< PointersHeap > 00164 { 00165 public: 00166 00167 static bool Verbose; 00168 static unsigned int def_count; 00169 static unsigned int use_count; 00170 static unsigned int merge_use_count; 00171 00172 static void stats(); 00173 00174 typedef enum { MultipleLHS, HighMultiplicity, Forced } WeakReason; 00175 00176 private: 00177 00180 Location * _where; 00181 00184 int _is_weak:1; 00185 00188 int _multiplicity:8; 00189 00192 int _search_for_def:1; 00193 00196 int _active:1; 00197 00200 memoryBlock * const _owner; 00201 00207 // memoryAssignment * _assignment; 00208 00209 public: 00210 00211 // --- Constructor 00212 00213 memoryAccess(Location * where, memoryBlock * owner); 00214 00215 // --- Fields 00216 00217 inline Location * where() const { return _where; } 00218 00219 inline bool is_weak() const { return _is_weak; } 00220 inline void set_weak(bool is) { _is_weak = is; } 00221 00222 // --- Get and set the multiplicity 00223 00224 inline Multiplicity multiplicity() const { return (Multiplicity)_multiplicity; } 00225 inline void set_multiplicity(Multiplicity lin) { _multiplicity = lin; } 00226 00227 inline bool search_for_def() const { return _search_for_def; } 00228 inline void search_for_def(bool val) { _search_for_def = val; } 00229 00230 inline bool is_active() const { return _active; } 00231 inline void set_active() { _active = true; } 00232 inline void set_inactive() { _active = false; } 00233 00234 /* 00235 inline WeakReason why_weak() const { return _why_weak; } 00236 inline void set_why_weak(WeakReason reason) { _why_weak = reason; } 00237 */ 00238 00239 inline memoryBlock * owner() const { return _owner; } 00240 00241 /* 00242 inline memoryAssignment * assignment() const { return _assignment; } 00243 inline void set_assignment(memoryAssignment * a) { _assignment = a; } 00244 */ 00245 }; 00246 00247 00248 // ------------------------------------------------------------ 00249 // memoryDef 00250 // ------------------------------------------------------------ 00251 00252 // A memoryDef represents a single definition of (assignment to) a 00253 // particular memoryBlock. It records the place where the def occured, 00254 // and the object deing modified. In addition, it is used to record 00255 // the points-to values of any pointer objects. 00256 00257 class memoryDef : public memoryAccess 00258 { 00259 private: 00260 00263 // memoryuse_list _uses; 00264 00267 memoryblock_set _points_to; 00268 00271 // memoryDef * _previous; 00272 00275 const constant * _value; 00276 00284 memoryUse * _self_assign_use; 00285 00286 public: 00287 00288 // --- Constructor 00289 00290 memoryDef(Location * where, memoryBlock * owner); 00291 00292 // --- Destructor 00293 00294 ~memoryDef(); 00295 00296 // --- Fields 00297 00298 // inline memoryuse_list & uses() { return _uses; } 00299 inline const memoryblock_set & points_to() const { return _points_to; } 00300 00301 // inline memoryDef * previous() const { return _previous; } 00302 // inline void set_previous(memoryDef * previous_def) { _previous = previous_def; } 00303 00304 inline const constant * value() const { return _value; } 00305 inline void set_value(const constant * newval) { _value = newval; } 00306 00307 // -- Self assign use 00308 00309 inline memoryUse * self_assign_use() const { return _self_assign_use; } 00310 inline void set_self_assign_use(memoryUse * new_use) { _self_assign_use = new_use; } 00311 00316 void add_pointers(const memoryblock_set & mbs); 00317 00323 void clear_points_to(); 00324 00325 // --- Output 00326 00327 void print(ostream & o) const; 00328 }; 00329 00330 // ------------------------------------------------------------ 00331 // orderedDefs 00332 // ------------------------------------------------------------ 00333 00334 // An orderedDef object holds a sequence of memoryDefs in dominating 00335 // order (a particular def always comes before the defs that dominate 00336 // it). 00337 00338 // -- Store each def along with the location and the subtree ID 00339 00340 class memorydef_key 00341 { 00342 public: 00343 00344 memoryDef * def; 00345 Location * location; 00346 // int subtree_id; 00347 00348 memorydef_key(memoryDef * the_def) 00349 : def(the_def), 00350 location(the_def->where()) 00351 // subtree_id(location->subtree_id()) 00352 {} 00353 }; 00354 00355 class orderedUses; 00356 00357 class orderedDefs 00358 { 00359 private: 00360 00361 memorydef_list _defs; 00362 00363 memorydef_location_map _quick_lookup; 00364 00365 public: 00366 00367 orderedDefs() 00368 : _defs(), 00369 _quick_lookup() 00370 {} 00371 00372 // --- Return the list of defs 00373 00374 const memorydef_list & def_list() const { return _defs; } 00375 00376 // --- Find the memoryDef for a given program location 00377 00378 memoryDef * find_def(Location * where); 00379 00380 // --- Find the nearest strictly dominating memoryDef (use this to 00381 // find the reaching definition for a regular use. 00382 00383 memoryDef * find_strictly_dominating_def(Location * where); 00384 00385 // --- Find the nearest dominating memoryDef (use this to find the 00386 // reaching definition for a merge-point use. 00387 00388 memoryDef * find_dominating_def(Location * where); 00389 00390 // --- Add a new memoryDef in the proper place, and return a 00391 // reference to it. If there is already an entry for the given path, 00392 // just return that memoryDef. 00393 00394 memoryDef * make_def_at(Location * where, memoryBlock * owner, bool & is_new); 00395 00396 // --- Prune out unnecessary defs 00397 00398 void prune(orderedUses & Uses); 00399 00400 // --- Output 00401 00402 void print(ostream & o) const; 00403 00404 // --- Clear 00405 00406 void clear(); 00407 00408 // --- Stats 00409 00410 void stats(int & total_defs, int & merge_defs, int & weak_defs); 00411 00412 }; 00413 00414 // ------------------------------------------------------------ 00415 // memoryUse 00416 // ------------------------------------------------------------ 00417 00418 // A memoryUse represents a single use of the memoryBlock. It points 00419 // to the reaching definition (from the orderedDefs list). For merges 00420 // (phi functions) we create one for each of the control-flow 00421 // predecessors. 00422 00423 class memoryUse : public memoryAccess 00424 { 00425 private: 00426 00427 memoryDef * _reaching_def; 00428 00429 public: 00430 00431 // --- Constructor 00432 00433 memoryUse(Location * where, memoryBlock * owner); 00434 00435 // --- Destructor 00436 00437 ~memoryUse(); 00438 00439 // --- Fields 00440 00441 memoryDef * reaching_def() const { return _reaching_def; } 00442 void reaching_def(memoryDef * def); 00443 00444 // --- Output 00445 00446 void print(ostream & o) const; 00447 }; 00448 00449 00450 typedef map< Location *, memoryUse * > memoryuse_map; 00451 typedef memoryuse_map::iterator memoryuse_map_p; 00452 typedef memoryuse_map::const_iterator memoryuse_map_cp; 00453 typedef memoryuse_map::value_type memoryuse_map_pair; 00454 00455 typedef map< basicblockNode *, memoryUse *> pred_use_map; 00456 typedef pred_use_map::iterator pred_use_map_p; 00457 typedef pred_use_map::const_iterator pred_use_map_cp; 00458 00459 typedef map< Location *, pred_use_map > merge_use_map; 00460 typedef merge_use_map::iterator merge_use_map_p; 00461 typedef merge_use_map::const_iterator merge_use_map_cp; 00462 00463 // ------------------------------------------------------------ 00464 // orderedUses 00465 // ------------------------------------------------------------ 00466 00467 class orderedUses 00468 { 00469 private: 00470 00471 memoryuse_map _uses; 00472 merge_use_map _merge_uses; 00473 00474 public: 00475 00476 orderedUses() 00477 : _uses(), 00478 _merge_uses() 00479 {} 00480 00481 // --- Find an existing use for the given location (doesn't work for 00482 // merge/phi functions). 00483 00484 memoryUse * find_use(Location * where) const; 00485 00486 // -- Find uses at (works for phi functions) 00487 00488 void find_uses_at(Location * where, memoryuse_set & uses); 00489 00490 // --- Add a new use for the given location, or return the existing 00491 // one. 00492 00493 memoryUse * make_use_at(Location * where, memoryBlock * owner); 00494 00495 // --- Add a new set of uses for a particular merge point: one use 00496 // for each control-flow predecessor, with the reaching definitions 00497 // set appropriately. 00498 00499 const pred_use_map & make_merge_uses_at(basicblockLocation * where, 00500 memoryBlock * owner); 00501 00502 // --- Update the def-use chains (only performed once at the end of 00503 // analysis by the memoryModel). 00504 00505 void update_def_use_chains(); 00506 00512 void def_uses(memoryDef * def, 00513 memoryuse_list & uses); 00514 00515 // --- Prune uses for a particular location 00516 00517 void prune(Location * where); 00518 00519 // --- Output 00520 00521 void print(ostream & o) const; 00522 00523 // --- Clear 00524 00525 void clear(); 00526 00527 // --- Stats 00528 00529 void stats(int & total_uses, int & merge_uses); 00530 }; 00531 00532 // ---------------------------------------------------------------------- 00533 // memoryAssignment 00534 // ---------------------------------------------------------------------- 00535 00536 class memoryAssignment : public PerClassHeap< PointersHeap > 00537 { 00538 private: 00539 00544 Location * _where; 00545 00550 memoryuse_set _uses; 00551 00556 memorydef_set _defs; 00557 00558 public: 00559 00562 memoryAssignment(Location * where) 00563 : _where(), 00564 _uses(), 00565 _defs() 00566 {} 00567 00570 inline Location * where() const { return _where; } 00571 00574 inline void add_use(memoryUse * use) { _uses.insert(use); } 00575 00578 inline void add_def(memoryDef * def) { _defs.insert(def); } 00579 00582 inline const memoryuse_set & uses() const { return _uses; } 00583 00586 inline const memorydef_set & defs() const { return _defs; } 00587 }; 00588 00589 // ---------------------------------------------------------------------- 00590 // Assignments 00591 // ---------------------------------------------------------------------- 00592 00593 typedef pair< Location *, memoryBlock *> assignment_key; 00594 00595 typedef map< assignment_key, memoryAssignment * > assignment_map; 00596 typedef assignment_map::iterator assignment_map_p; 00597 00598 class assignmentSet 00599 { 00600 private: 00601 00604 assignment_map _assignments; 00605 00606 public: 00607 00610 assignmentSet() 00611 : _assignments() 00612 {} 00613 00620 memoryAssignment * assignment_at(Location * where, memoryBlock * block, 00621 bool create); 00622 }; 00623 00624 #endif // CBZ_MEMORYACCESS_H 00625 |
Generated on February 1, 2006
Back to the C-Breeze home page