C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

defuse.cc

Go to the documentation of this file.
00001 // $Id: defuse.cc,v 1.7 2003/08/07 23:14:13 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 // defuse.cc
00039 //
00040 // For each node, gen() will contain the set of variables used in that
00041 // node (unless they are defined first in that node).
00042 // kill() will contain the set of variables defined in that node
00043 // (unless they are used first in that node).
00044 //
00045 
00046 #include "c_breeze.h"
00047 #include "bits.h"
00048 #include "defuse.h"
00049 
00050 // traverse a right hand side, collecting the names of
00051 // all the variables used into the declSetFlowVal v
00052 
00053 void DefUseWalker::get_uses (Node *r) {
00054         if (!r) return;
00055         switch (r->typ()) {
00056                 case Id: {
00057 
00058                         // if this id hasn't been def'ed 
00059                         // before, it is a use.
00060 
00061                         idNode *i = (idNode *) r;
00062                         if (!(defs->in (i->name())))
00063                                 uses->insert (i->name());
00064                         break;
00065                 }
00066 
00067                 // the rest of the cases basically
00068                 // traverse the expression tree
00069                 // trying to get to the first case
00070 
00071                 case If: {
00072                         ifNode *i = (ifNode *) r;
00073                         get_uses (i->expr());
00074                         break;
00075                 }
00076                 case Expr: {
00077                         exprstmtNode *ex = (exprstmtNode *) r;
00078                         get_uses (ex->expr());
00079                         break;
00080                 }
00081                 case Return: {
00082                         returnNode *re = (returnNode *) r;
00083                         get_uses (re->expr());
00084                         break; 
00085                 }
00086                 case Binary: {
00087                         binaryNode *b = (binaryNode *) r;
00088                         get_uses (b->left());
00089 
00090                         // the rhs of a -> may look like
00091                         // a use of a local variable with
00092                         // the same name as the struct field,
00093                         // so we won't go there.
00094 
00095                         if (b->op()->id() != Operator::ARROW)
00096                                 get_uses (b->right());
00097                         break;
00098                 }
00099                 case Unary: {
00100                         unaryNode *b = (unaryNode *) r;
00101                         get_uses (b->expr());
00102                         break;
00103                 }
00104                 case Cast: {
00105                         castNode *c = (castNode *) r;
00106                         get_uses (c->expr());
00107                         break;
00108                 }
00109                 case Call: {
00110                         callNode *c = (callNode *) r;
00111 
00112                         // function pointer?
00113 
00114                         get_uses (c->name());
00115 
00116                         // all the args
00117 
00118                         for (expr_list_p i=c->args().begin(); 
00119                                 i!=c->args().end(); i++)
00120                                 get_uses (*i);
00121                         break;
00122                 }
00123                 default: 
00124                         ; // we don't care
00125         }
00126 }
00127 
00128 // get a def from n, putting it in defs.
00129 
00130 void DefUseWalker::get_def (Node *n) {
00131         // is it an expression stmt?
00132         if (n->typ() == Expr) {
00133                 exprstmtNode *ex = (exprstmtNode *) n;
00134                 exprNode *e = ex->expr();
00135 
00136                 // e could be NULL ( e.g. dummy node inserted during cfg phase)
00137                 
00138                 if (e==NULL)
00139                   return;
00140                 
00141                 // is it a binary expression?
00142 
00143                 if (e->typ() == Binary) {
00144                         binaryNode *bi = (binaryNode *) e;
00145 
00146                         // is it an assignment?
00147 
00148                         if (bi->op()->id() == '=') {
00149                                 exprNode *lhs = bi->left();
00150 
00151                                 // is the lhs an id?
00152 
00153                                 if (lhs->typ() == Id) {
00154                                         idNode *i = (idNode *) lhs;
00155 
00156                                         // before we suspect this is really
00157                                         // a def, let's check to see whether
00158                                         // something (e.g. lhs!) is used
00159                                         // in the rhs
00160 
00161                                         get_uses (bi->right());
00162 
00163                                         // has it not been used before?
00164 
00165                                         if (!(uses->in(i->name()))) {
00166 
00167                                                 // it's a def.
00168 
00169                                                 defs->insert (i->name());
00170                                         }
00171                                 }
00172                         }
00173                 }
00174         }
00175 }
00176 
00177 // at a basic block, get all the defs and uses and stick them
00178 // in kill and gen, resp. (which have been renamed with macros)
00179 
00180 void DefUseWalker::at_basicblock (basicblockNode *b, Order ord) {
00181         if (ord != Preorder) return;
00182         declSetFlowVal *v = new declSetFlowVal (flowsize, name2num, decls);
00183         defs = new declSetFlowVal (flowsize, name2num, decls);
00184         uses = new declSetFlowVal (flowsize, name2num, decls);
00185         for (stmt_list_p i=b->stmts().begin(); 
00186                 i!=b->stmts().end(); i++) {
00187                 stmtNode *n = *i;
00188                 
00189                 // get a def
00190 
00191                 get_def (n);
00192 
00193                 // get uses
00194 
00195                 get_uses (n);
00196         }
00197         b->def (defs);
00198         b->use (uses);
00199 
00200         // put in a comment giving the defs and uses for this block
00201 
00202         string s = "defs: ";
00203         for (int i=1; i<=flowsize; i++) {
00204                 if (defs->in (i))
00205                         s += decls[i]->name() + " ";
00206         }
00207         s += "; uses: ";
00208         for (int i=1; i<=flowsize; i++) {
00209                 if (uses->in (i))
00210                         s += decls[i]->name() + " ";
00211         }
00212         b->comment() = s;
00213 }
00214 
00215 class fixPointerWalker : public Walker {
00216 
00217 private:
00218         map <basicblockNode *, bool> marks;
00219         basicblockNode *current_block;
00220         map <var_id, int> *name2num;
00221 
00222 public:
00223         fixPointerWalker (map <var_id, int> *m, basicblockNode *c) :
00224                 name2num(m), 
00225                 current_block(c),
00226                 Walker (Preorder, Subtree) { }
00227 
00228         void at_unary (unaryNode *, Order);
00229         void dfs_used (basicblockNode *, int);
00230         void at_basicblock (basicblockNode *b, Order) {
00231                 current_block = b;
00232         }
00233 };
00234 
00235 void DefUseWalker::at_proc (procNode *p, Order ord) {
00236         if (ord == Postorder) {
00237                 basicblockNode *b;
00238                 assert (p->body()->stmts().size());
00239                 b = (basicblockNode *) p->body()->stmts().front();
00240                 assert (b->typ() == Block);
00241                 fixPointerWalker w (name2num, b);
00242                 p->walk (w);
00243         }
00244 }
00245 
00246 void fixPointerWalker::at_unary (unaryNode *u, Order) {
00247         // if the address of a local is taken, it could be used
00248         // (or def'ed) when it looks dead, so we must mark it used
00249         // anywhere reachable from the current basic block
00250 
00251         if (u->op()->id() == Operator::ADDRESS && u->expr()->typ() == Id) {
00252                 idNode *id = (idNode *) u->expr();
00253                 int i = (*name2num)[id->name()];
00254                 if (i > 0) {
00255                         marks.clear();
00256                         dfs_used (current_block, i);
00257                 }
00258         }
00259 }
00260 
00261 void fixPointerWalker::dfs_used (basicblockNode *b, int i) {
00262         marks[b] = true;
00263         if (!b) return;
00264         declSetFlowVal *v = (declSetFlowVal *) b->def();
00265         if (!v) return;
00266         if (!(v->in (i))) {
00267                 declSetFlowVal *w = (declSetFlowVal *) b->use();
00268                 if (!w) return;
00269                 w->insert (i);
00270         }
00271         if (b->succs().size())
00272         for (basicblock_list_p p=b->succs().begin(); p!=b->succs().end(); p++)
00273                 if (!(marks[*p])) dfs_used (*p, i);
00274 }

Generated on August 27, 2003
Back to the C-Breeze home page