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 #include "live.h"
00040 #include "cfg.h"
00041
00042 LivenessWalker::LivenessWalker():
00043 Walker (Both, Subtree),
00044 _num_decls(0),
00045 _num2decl()
00046 {}
00047
00048 LivenessWalker * LivenessWalker::walk(procNode * the_proc) {
00049 LivenessWalker * lw = new LivenessWalker();
00050 the_proc->walk(*lw);
00051 return lw;
00052 }
00053
00054 void LivenessWalker::at_proc(procNode * the_proc, Order ord) {
00055 if ( ord == Preorder ) {
00056 assert(the_proc->decl()->type()->typ() == Func);
00057 funcNode * the_func = (funcNode *) the_proc->decl()->type();
00058 blockNode * the_body = the_proc->body();
00059
00060
00061
00062 int num_decls = the_func->args().size() + the_body->decls().size();
00063 _num2decl.push_back(NULL);
00064 int i = 1;
00065 for ( decl_list_p p = the_func->args().begin();
00066 p != the_func->args().end();
00067 p++, i++ ) {
00068 _decl2num[*p] = i;
00069 _num2decl.push_back(*p);
00070 }
00071 for ( decl_list_p p = the_body->decls().begin();
00072 p != the_body->decls().end();
00073 p++, i++ ) {
00074 _decl2num[*p] = i;
00075 _num2decl.push_back(*p);
00076 }
00077
00078 assert(i == num_decls + 1);
00079 _num_decls = i;
00080 } else {
00081
00082
00083
00084
00085 bool changed = false;
00086 do {
00087 changed = false;
00088 for ( stmt_list_p p = the_proc->body()->stmts().begin();
00089 p != the_proc->body()->stmts().end();
00090 p++ ) {
00091 basicblockNode * the_bb = dynamic_cast<basicblockNode *> (*p);
00092 assert(the_bb);
00093
00094
00095 for ( basicblock_list_p q = the_bb->succs().begin();
00096 q != the_bb->succs().end();
00097 q++ ) {
00098 _live_out[the_bb]->Or(_live_in[*q]);
00099 }
00100
00101
00102 Bits old_in(_num_decls);
00103 old_in.copy(_live_in[the_bb]);
00104 _live_in[the_bb]->copy(_live_out[the_bb]);
00105 _live_in[the_bb]->Difference(_def[the_bb]);
00106 _live_in[the_bb]->Or(_use[the_bb]);
00107
00108 if ( *_live_in[the_bb] != old_in )
00109 changed = true;
00110 }
00111
00112 } while ( changed );
00113
00114
00115
00116
00117
00118 for ( stmt_list_p p = the_proc->body()->stmts().begin();
00119 p != the_proc->body()->stmts().end();
00120 p++ ) {
00121 stmt_list::reverse_iterator q;
00122 basicblockNode * the_bb = (basicblockNode *) *p;
00123 Bits current(_num_decls);
00124 current.copy(_live_out[the_bb]);
00125 for ( q = the_bb->stmts().rbegin(); q != the_bb->stmts().rend(); q++ ) {
00126 if ( _live_out.find(*q) != _live_out.end() ) {
00127 _live_out[*q]->Or(¤t);
00128 current.Difference(_def[*q]);
00129 _live_in[*q]->Or(¤t);
00130 }
00131 }
00132 }
00133 }
00134 }
00135
00136 void LivenessWalker::at_basicblock(basicblockNode * the_bb, Order ord) {
00137 if ( ord == Postorder ) {
00138
00139 Bits current(_num_decls);
00140 Bits block_def(_num_decls);
00141 Bits block_use(_num_decls);
00142 stmt_list::reverse_iterator p;
00143 for ( p = the_bb->stmts().rbegin(); p != the_bb->stmts().rend(); p++ ) {
00144 if ( _def.find(*p) != _def.end() ) {
00145 _live_out[*p]->copy(¤t);
00146
00147
00148 current.Difference(_def[*p]);
00149 current.Or(_use[*p]);
00150 _live_in[*p]->copy(¤t);
00151
00152 block_def.Or(_def[*p]);
00153 block_use.Difference(_def[*p]);
00154 block_use.Or(_use[*p]);
00155 }
00156 }
00157 _def[the_bb] = block_def.clone();
00158 _use[the_bb] = block_use.clone();
00159 _live_in[the_bb] = new Bits(_num_decls);
00160 _live_out[the_bb] = new Bits(_num_decls);
00161 }
00162 }
00163
00164 void LivenessWalker::at_return(returnNode * the_return, Order ord) {
00165 if ( ord == Preorder ) {
00166 _use[the_return] = new Bits(_num_decls);
00167 _def[the_return] = new Bits(_num_decls);
00168 _live_in[the_return] = new Bits(_num_decls);
00169 _live_out[the_return] = new Bits(_num_decls);
00170 if ( the_return->expr() ) {
00171 idNode * return_expr = dynamic_cast<idNode *> (the_return->expr());
00172 assert(return_expr);
00173 _use[the_return]->set(_decl2num[return_expr->decl()]);
00174 }
00175 }
00176 }
00177
00178 void LivenessWalker::at_conditiongoto(conditiongotoNode * the_condgoto,
00179 Order ord) {
00180 if ( ord == Preorder ) {
00181 _use[the_condgoto] = new Bits(_num_decls);
00182 _def[the_condgoto] = new Bits(_num_decls);
00183 _live_in[the_condgoto] = new Bits(_num_decls);
00184 _live_out[the_condgoto] = new Bits(_num_decls);
00185 idNode * left = dynamic_cast<idNode *> (the_condgoto->left());
00186 if ( left )
00187 _use[the_condgoto]->set(_decl2num[left->decl()]);
00188 idNode * right = dynamic_cast<idNode *> (the_condgoto->right());
00189 if ( right )
00190 _use[the_condgoto]->set(_decl2num[right->decl()]);
00191 }
00192 }
00193
00194 void LivenessWalker::at_threeAddr(threeAddrNode * the_3addr, Order ord) {
00195 if ( ord == Preorder ) {
00196
00197 _use[the_3addr] = new Bits(_num_decls);
00198 _def[the_3addr] = new Bits(_num_decls);
00199 _live_in[the_3addr] = new Bits(_num_decls);
00200 _live_out[the_3addr] = new Bits(_num_decls);
00201
00202 if ( the_3addr->lhs() )
00203 defUseOperand(the_3addr, the_3addr->lhs(), true, false);
00204 if ( the_3addr->rhs1() )
00205 defUseOperand(the_3addr, the_3addr->rhs1(), false, false);
00206 if ( the_3addr->rhs2() )
00207 defUseOperand(the_3addr, the_3addr->rhs2(), false, false);
00208 if ( !the_3addr->arg_list().empty() )
00209 for ( operand_list_p p = the_3addr->arg_list().begin();
00210 p != the_3addr->arg_list().end();
00211 p++ )
00212 defUseOperand(the_3addr, *p, false, true);
00213 }
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223 void LivenessWalker::defUseOperand(threeAddrNode * the_3addr,
00224 operandNode * the_oper,
00225 bool on_left,
00226 bool func_arg) {
00227 if ( on_left ) {
00228 if ( the_oper->star() ) {
00229 _def[the_3addr]->set_all();
00230 _use[the_3addr]->set(_decl2num[((idNode *) the_oper->var())->decl()]);
00231 } else
00232 _def[the_3addr]->set(_decl2num[((idNode *) the_oper->var())->decl()]);
00233 } else if ( func_arg ) {
00234 idNode * var = dynamic_cast<idNode *> (the_oper->var());
00235 if ( var ) {
00236 if ( the_oper->star() )
00237 _use[the_3addr]->set_all();
00238 else if ( the_oper->addr() )
00239 _def[the_3addr]->set(_decl2num[var->decl()]);
00240 else
00241 _use[the_3addr]->set(_decl2num[var->decl()]);
00242 }
00243 } else {
00244 idNode * var = dynamic_cast<idNode *> (the_oper->var());
00245 if ( var ) {
00246 if ( the_oper->star() )
00247 _use[the_3addr]->set_all();
00248 else if ( the_oper->addr() )
00249 ;
00250 else
00251 _use[the_3addr]->set(_decl2num[var->decl()]);
00252 }
00253 }
00254
00255 if ( the_oper->index()
00256 && the_oper->index()->typ() == Id )
00257 _use[the_3addr]->set(_decl2num[((idNode *) the_oper->index())->decl()]);
00258 }
00259
00260 void LivenessWalker::at_stmt(stmtNode * the_stmt, Order ord) {
00261
00262
00263
00264 if ( ord == Preorder ) {
00265 _use[the_stmt] = new Bits(_num_decls);
00266 _def[the_stmt] = new Bits(_num_decls);
00267 _live_in[the_stmt] = new Bits(_num_decls);
00268 _live_out[the_stmt] = new Bits(_num_decls);
00269 }
00270 }
00271
00272
00273 decl_set * LivenessWalker::bits2decls(Bits * bits) {
00274 if ( !bits )
00275 return NULL;
00276 decl_set * the_set = new decl_set;
00277 for ( int i = 1; i < bits->size(); i++ )
00278 if ( bits->value(i) )
00279 the_set->insert(_num2decl[i]);
00280 return the_set;
00281 }
00282
00283
00284
00285 decl_set * LivenessWalker::defs(stmtNode * the_stmt) {
00286 return bits2decls(_def[the_stmt]);
00287 }
00288
00289
00290
00291 decl_set * LivenessWalker::uses(stmtNode * the_stmt) {
00292 return bits2decls(_use[the_stmt]);
00293 }
00294
00295
00296
00297 decl_set * LivenessWalker::live_in(stmtNode * the_stmt) {
00298 return bits2decls(_live_in[the_stmt]);
00299 }
00300
00301
00302
00303 decl_set * LivenessWalker::live_out(stmtNode * the_stmt) {
00304 return bits2decls(_live_out[the_stmt]);
00305 }
00306
00307 LivenessComments::LivenessComments(void):
00308 Walker(Both, Subtree),
00309 _lw(NULL)
00310 {}
00311
00312 void LivenessComments::at_proc(procNode * the_proc, Order ord) {
00313 if ( ord == Preorder )
00314 _lw = LivenessWalker::walk(the_proc);
00315 else
00316 if ( _lw )
00317 delete _lw;
00318 }
00319
00320 void LivenessComments::comment_stmt(stmtNode * the_stmt) {
00321 ostringstream ost;
00322 ost << endl << "defs: ";
00323 decl_set * defs = _lw->defs(the_stmt);
00324 for ( decl_set_p p = defs->begin(); p != defs->end(); p++ )
00325 ost << (*p)->name() << " ";
00326 delete defs;
00327 decl_set * uses = _lw->uses(the_stmt);
00328 ost << "; uses: ";
00329 for ( decl_set_p p = uses->begin(); p != uses->end(); p++ )
00330 ost << (*p)->name() << " ";
00331 delete uses;
00332 decl_set * live_in = _lw->live_in(the_stmt);
00333 ost << "; live_in: ";
00334 for ( decl_set_p p = live_in->begin(); p != live_in->end(); p++ )
00335 ost << (*p)->name() << " ";
00336 delete live_in;
00337 decl_set * live_out = _lw->live_out(the_stmt);
00338 ost << "; live_out: ";
00339 for ( decl_set_p p = live_out->begin(); p != live_out->end(); p++ )
00340 ost << (*p)->name() << " ";
00341 delete live_out;
00342 the_stmt->comment() += ost.str();
00343 }
00344 void LivenessComments::at_threeAddr(threeAddrNode * the_3addr, Order ord) {
00345 if ( ord == Preorder )
00346 comment_stmt(the_3addr);
00347 }
00348
00349 void LivenessComments::at_basicblock(basicblockNode * the_bb, Order ord) {
00350 if ( ord == Preorder )
00351 comment_stmt(the_bb);
00352 }
00353
00354 void LivenessComments::at_return(returnNode * the_return, Order ord) {
00355 if ( ord == Preorder )
00356 comment_stmt(the_return);
00357 }
00358
00359 void LivenessComments::at_conditiongoto(conditiongotoNode * the_condgoto,
00360 Order ord) {
00361 if ( ord == Preorder )
00362 comment_stmt(the_condgoto);
00363 }
00364
00368 class LiveTest : public Phase {
00369 public:
00370 void run(void) {
00371 for ( unit_list_p u = CBZ::Program.begin(); u != CBZ::Program.end();
00372 u++ ) {
00373 cfg_changer::generate_cfg(*u);
00374
00375 LivenessComments lc;
00376 (*u)->walk(lc);
00377 }
00378 }
00379 };
00380
00381 Phases LiveTestPhase("livetest", new LiveTest());