00001 // ---------------------------------------------------------------------- 00002 // 00003 // C-Breeze 00004 // C Compiler Framework 00005 // 00006 // Copyright (c) 2000 University of Texas at Austin 00007 // 00008 // Samuel Z. Guyer 00009 // Daniel A. Jimenez 00010 // Calvin Lin 00011 // 00012 // Permission is hereby granted, free of charge, to any person 00013 // obtaining a copy of this software and associated documentation 00014 // files (the "Software"), to deal in the Software without 00015 // restriction, including without limitation the rights to use, copy, 00016 // modify, merge, publish, distribute, sublicense, and/or sell copies 00017 // of the Software, and to permit persons to whom the Software is 00018 // furnished to do so, subject to the following conditions: 00019 // 00020 // The above copyright notice and this permission notice shall be 00021 // included in all copies or substantial portions of the Software. 00022 // 00023 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00024 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00025 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00026 // NONINFRINGEMENT. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT 00027 // AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 00028 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 00029 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00030 // THE SOFTWARE. 00031 // 00032 // We acknowledge the C-to-C Translator from MIT Laboratory for 00033 // Computer Science for inspiring parts of the C-Breeze design. 00034 // 00035 // ---------------------------------------------------------------------- 00036 00037 #ifndef CBZ_PATH_H 00038 #define CBZ_PATH_H 00039 00040 #include "location.h" 00041 00042 class Path; 00043 00044 // ------------------------------------------------------------ 00045 // PathDB 00046 // ------------------------------------------------------------ 00047 00048 // Store the paths in a multi-map from parent to children 00049 00050 typedef multimap< const Path *, const Path * > path_map; 00051 typedef path_map::iterator path_map_p; 00052 typedef path_map::const_iterator path_map_cp; 00053 typedef pair< const Path *, const Path * > path_map_pair; 00054 00055 class PathDB 00056 { 00057 private: 00058 00059 path_map _paths; 00060 00061 public: 00062 00063 PathDB(); 00064 00065 // --- Add a path to the database, eliminating duplicates and 00066 // sharing structure wherever possible. 00067 00068 const Path * intern(const Path * con); 00069 00070 // --- Look up a path, without creating a new entry. If the 00071 // path doesn't exist in the database, then it returns null. 00072 00073 const Path * lookup(const Path * con); 00074 00075 // --- Equality and dominance tests 00076 00077 static bool equals(const Path * one, const Path * two); 00078 static bool dominates(const Path * dom, const Path * cur); 00079 static bool strictly_dominates(const Path * dom, const Path * cur); 00080 00081 // --- Print some statistics 00082 00083 void stats(); 00084 00085 // --- Output 00086 00087 void print(ostream & o) const; 00088 00089 friend ostream& operator<<(ostream & o, const PathDB & cdb) { 00090 cdb.print(o); 00091 return o; 00092 } 00093 }; 00094 00095 // ------------------------------------------------------------ 00096 // Path 00097 // ------------------------------------------------------------ 00098 00099 // A path is a chain of Locations. We use the PathDB class to 00100 // allow "interning" of paths so that common components of the 00101 // chain are shared. This also makes other comparisons more efficient 00102 // because two identical paths will have the same pointer value. 00103 00104 // The PathDB passed into the constructors always interns the 00105 // parent pointer. This maintains the invariant that all components of 00106 // a path chain are interned, with the one exception of the 00107 // last. This exception is primarily for performance: we don't want to 00108 // end up with every single program position in the database. 00109 00110 class Path : public Location 00111 { 00112 friend class PathDB; 00113 00114 private: 00115 00116 const Path * _parent; 00117 int _depth; 00118 // int _refs; 00119 bool _dominates_exit; 00120 PathDB * _db; 00121 00122 // --- Private default constructor 00123 00124 Path(); 00125 00126 static const Path * Always; 00127 00128 public: 00129 00130 // --- Constructor: build a new path by "pushing" a new procedure 00131 // on the end. The parent is automatically interned. 00132 00133 Path(PathDB * db, const Path * parent, 00134 procNode * callee); 00135 00136 Path(PathDB * db, const Path * parent, 00137 procNode * callee, basicblockNode * block); 00138 00139 Path(PathDB * db, const Path * parent, 00140 const Location & loc); 00141 00142 // --- Copy a path: this is useful for modifying one that has 00143 // been interned (and thus cannot be modified!). 00144 00145 Path(const Path & other); 00146 00147 // --- Destructor 00148 00149 ~Path(); 00150 00151 // --- Fields 00152 00153 inline const Path * parent() const { return _parent; } 00154 inline int depth() const { return _depth; } 00155 inline bool dominates_exit() const { return _dominates_exit; } 00156 00157 // --- Useful query functions 00158 00159 bool is_recursive() const; 00160 bool is_proc_present(procNode * proc) const; 00161 bool is_always() const { return this == Always; } 00162 00163 // --- The special "Always" path 00164 00165 static const Path * always() { return Always; } 00166 00167 // --- Output 00168 00169 void print_shallow(ostream & o) const { 00170 if (is_always()) 00171 o << "Always"; 00172 else 00173 print(o); 00174 } 00175 00176 void print_deep(ostream & o) const { 00177 print_shallow(o); 00178 if (parent()) { 00179 o << ":"; 00180 parent()->print_deep(o); 00181 } 00182 } 00183 00184 friend ostream& operator<<(ostream & o, const Path & c) { 00185 c.print_deep(o); 00186 return o; 00187 } 00188 00189 private: 00190 00191 // void inc_refs() { _refs++; } 00192 // void dec_refs() { _refs--; } 00193 00194 }; 00195 00196 #endif //