Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

reaching_genkill.h

Go to the documentation of this file.
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

Generated on Thu Jan 10 12:06:20 2002 for C-Breeze by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001