00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "c_breeze.h"
00047 #include "bits.h"
00048 #include "defuse.h"
00049
00050
00051
00052
00053 void DefUseWalker::get_uses (Node *r) {
00054 if (!r) return;
00055 switch (r->typ()) {
00056 case Id: {
00057
00058
00059
00060
00061 idNode *i = (idNode *) r;
00062 if (!(defs->in (i->name())))
00063 uses->insert (i->name());
00064 break;
00065 }
00066
00067
00068
00069
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
00091
00092
00093
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
00113
00114 get_uses (c->name());
00115
00116
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 ;
00125 }
00126 }
00127
00128
00129
00130 void DefUseWalker::get_def (Node *n) {
00131
00132 if (n->typ() == Expr) {
00133 exprstmtNode *ex = (exprstmtNode *) n;
00134 exprNode *e = ex->expr();
00135
00136
00137
00138 if (e==NULL)
00139 return;
00140
00141
00142
00143 if (e->typ() == Binary) {
00144 binaryNode *bi = (binaryNode *) e;
00145
00146
00147
00148 if (bi->op()->id() == '=') {
00149 exprNode *lhs = bi->left();
00150
00151
00152
00153 if (lhs->typ() == Id) {
00154 idNode *i = (idNode *) lhs;
00155
00156
00157
00158
00159
00160
00161 get_uses (bi->right());
00162
00163
00164
00165 if (!(uses->in(i->name()))) {
00166
00167
00168
00169 defs->insert (i->name());
00170 }
00171 }
00172 }
00173 }
00174 }
00175 }
00176
00177
00178
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
00190
00191 get_def (n);
00192
00193
00194
00195 get_uses (n);
00196 }
00197 b->def (defs);
00198 b->use (uses);
00199
00200
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
00248
00249
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 }