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_REACHING_GENKILL_H 00038 #define CBZ_REACHING_GENKILL_H 00039 00040 // 00041 // reaching_genkill.h 00042 // 00043 // This file contains definitions for defFlowVal and 00044 // reachingGenKillWalker. 00045 00046 // A defFlowVal is a flow value for the reaching definitions 00047 // problem. This flow value represents a set of definitions, 00048 // a subset of the set of all definitions in a given procedure. 00049 // These definitions are found by the reachingGenKillWalker, 00050 // described below. The definitions are indexed starting 00051 // from 1, and can be referred to by either their index 00052 // or by a pointer to the definition's stmtNode pointer. 00053 // 00054 // defFlowVal is a subclass of FlowVal, an abstract 00055 // flow value class in C-Breeze, so it can live in the 00056 // gen() and kill() fields of nodes. 00057 // 00058 // When we refer to gen and kill sets, we're refering to 00059 // defFlowValue's occupying the gen() and kill() fields 00060 // of stmtNode's and basicblockNode's. 00061 00062 class defFlowVal : public FlowVal { 00063 00064 public: 00065 00066 // set this flow value to top (i.e., the empty set) 00067 void to_top (void); 00068 00069 // get a clone of this flow value 00070 FlowVal * clone (void) const; 00071 00072 // returns true iff the two flow values differ 00073 bool diff (FlowVal *other) const; 00074 00075 // return true if the definition is in the set, 00076 // by a pointer to the definition 00077 bool in (stmtNode *); 00078 00079 // return true if the definition is in the set, 00080 // by the index of the definition 00081 bool in (int); 00082 00083 // insert a definition into the set, by a pointer 00084 // to the definition 00085 void insert (stmtNode *); 00086 00087 // insert a definition into the set, by the index 00088 // of the definition 00089 void insert (int); 00090 00091 // remove a definition from the set, by a pointer 00092 // to the definition 00093 void remove (stmtNode *); 00094 00095 // remove a definition from the set, by the index 00096 // of the definition 00097 void remove (int); 00098 00099 // make this flow value a copy of the parameter 00100 void copy (FlowVal *); 00101 00102 // set this definition to the union of itself 00103 // with the parameter 00104 void Union (const FlowVal *); 00105 00106 // set this definition to the intersection of itself 00107 // with the parameter 00108 void Intersect (const FlowVal *v); 00109 00110 // set this definition to the set difference of itself 00111 // with the parameter (i.e. this - the other) 00112 void Difference (FlowVal *); 00113 00114 // meet operator (union for reaching definitions) 00115 void meet (const FlowVal *); 00116 00117 // Note: this constructor for defFlowVal is 00118 // called from within the reachingGenKillWalker; 00119 // you will likely not need to call it yourself. 00120 // Use the new_flowval() function of reachingGenKillWalker 00121 // to get a new flow value, set to top, with the 00122 // right values for the reaching definitions problem 00123 // the walker was called on. 00124 00125 // the constructor takes three parameters: 00126 defFlowVal 00127 00128 // the number of definitions 00129 (int, 00130 00131 // a map from a definition to its index 00132 map<stmtNode *, int> *, 00133 00134 // an array mapping a definition's index to its pointer 00135 stmtNode **); 00136 00137 // destructor 00138 ~defFlowVal (void); 00139 00140 private: 00141 00142 map <stmtNode*, int> *def2num; 00143 int size; 00144 Bits *bits; 00145 stmtNode **definitions; 00146 }; 00147 00148 // reachingGenKillWalker populates the gen() and kill() sets 00149 // of each stmtNode and basicblockNode in a procedure. It should 00150 // be supplied as the parameter to the walk() function of the 00151 // procNode, preferably from the at_proc() function of some 00152 // other walker that's doing reaching definitions analysis. 00153 // The constructor requires several parameters (described below) 00154 // that will be filled with useful information that can be 00155 // used by the caller. 00156 // 00157 // Note: it's the caller's responsibility to free memory for 00158 // gen() and kill() of each stmtNode and basicblockNode, and 00159 // to make sure that the variables supplied as arguments to 00160 // the constructor at least until the time the gen() and kill() 00161 // sets are deleted. In particular, the arguments should not 00162 // be local variables to an at_proc(), unless that at_proc() 00163 // is going to do all the dataflow analysis and then clean up 00164 // after itself before exiting. 00165 // 00166 // About definitions: there are two kinds of definitions this 00167 // walker gets information about. Unambiguous definitions are 00168 // statements of the form id = expression, where id is an idNode. 00169 // Pointers to these statements will be available in the maps 00170 // and array after walk() is called. Ambiguous definitions, which 00171 // take the form of an assignment through a pointer or a call 00172 // to a function, are not represented by pointers to the 00173 // statements themselves. Rather, for each variable defined 00174 // in the procedure, one empty expression statement is allocated 00175 // as "the" ambiguous definition of that variable. (Otherwise, 00176 // each ambiguous definition would generate a number of definitions 00177 // in the flow value equal to the number of variables, wasting 00178 // a lot of storage.) Thus, after reaching definitions analysis 00179 // is done, the particular ambiguous definition reaching a given 00180 // block isn't available, but the fact that some ambiguous definition 00181 // reaches the block is. 00182 00183 class reachingGenKillWalker : public Walker { 00184 00185 public: 00186 00187 // pointers to several variables needed by the walker 00188 // and useful to the caller are supplied to this 00189 // constructor 00190 reachingGenKillWalker ( 00191 00192 // map of definition statements to indices in flow values. 00193 map <stmtNode *, int> *, 00194 00195 // defines - will map definition statements 00196 // to the variables (declNode's) they define 00197 00198 map <stmtNode *, declNode *> *, 00199 00200 // map of variables (declarations) to a flow value 00201 // representing the set of all definitions for 00202 // that variable 00203 map <declNode *, defFlowVal *> *, 00204 00205 // an array mapping indices in flow values (integers) 00206 // to definitions (statement nodes) 00207 00208 stmtNode ***, 00209 00210 // the number of definitions 00211 int *); 00212 00213 ~reachingGenKillWalker (void); 00214 00215 // return a new flow value, set to top. 00216 // this is how you get new empty flow values 00217 // (rather than calling the defFlowValue constructor) 00218 defFlowVal * new_flowval (void); 00219 00220 void at_proc (procNode *, Order); 00221 00222 void at_basicblock (basicblockNode *, Order); 00223 00224 // we just want to populate gen and kill sets at the 00225 // procedure level; it makes no sense at the unit level. 00226 void at_unit (unitNode *, Order) { 00227 cerr << 00228 "Don't invoke the reachingGenKillWalker from a unitNode!\n"; 00229 exit (1); 00230 } 00231 00232 private: 00233 // map stmtNode's to bit positions 00234 00235 map <stmtNode *, int> * node2num; 00236 00237 // map stmtNode's to the variable (declarations) they degine 00238 00239 map <stmtNode *, declNode *> * defines; 00240 00241 // map variable declarations to the set of 00242 // definitions for them 00243 00244 map <declNode *, defFlowVal *> *defs; 00245 00246 // list of ambiguous definitions 00247 00248 stmt_list ambiguous_defs; 00249 00250 stmtNode **num2node, ***pn2n; 00251 00252 // number of definitions 00253 00254 int n, *pn; 00255 00256 // a generic flow value to clone 00257 00258 defFlowVal * _flowval; 00259 00260 // all ambiguous definitions 00261 00262 defFlowVal * _everything; 00263 00264 }; 00265 00266 #endif // CBZ_REACHING_GENKILL_H