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 #include "copyprop.h"
00039 #include "bits.h"
00040
00041
00042 class copyPropChanger::GetDefsWalker : public Walker {
00043 private:
00044
00045 threeAddr_set * copies,
00046 * ambiguous_defs;
00047 map<threeAddrNode*,declNode*> *defines;
00048
00049 public:
00050 GetDefsWalker (threeAddr_set *c, threeAddr_set *l,
00051 map<threeAddrNode*,declNode*> *d) :
00052 Walker (Preorder, Subtree), ambiguous_defs(l), copies(c), defines(d) { }
00053
00054 void at_threeAddr (threeAddrNode *stmt, Order) {
00055 bool ambiguous = false;
00056 if(stmt->lhs()) {
00057 operandNode *lhs = stmt->lhs();
00058 if(lhs->star() || ! lhs->fields().empty() || lhs->index())
00059
00060 ambiguous = true;
00061 else {
00062 assert(lhs->var()->typ() == Id);
00063 (*defines)[stmt] = ((idNode*)lhs->var())->decl();
00064 if(!stmt->rhs2() &&
00065 (!stmt->op() || stmt->op()->id() == Operator::UPLUS)) {
00066 operandNode *rhs = stmt->rhs1();
00067 if(rhs->var()->typ()==Id && !rhs->star() && rhs->fields().empty() &&
00068 !rhs->index() && !rhs->cast() && !rhs->addr())
00069 copies->insert(stmt);
00070 }
00071 }
00072 }
00073 if(stmt->op() && stmt->op()->id() == Operator::FUNC_CALL)
00074 ambiguous = true;
00075 if(ambiguous)
00076 ambiguous_defs->insert (stmt);
00077 }
00078 };
00079
00081
00082
00083 class copyPropChanger::copyFlowVal {
00084 private:
00085
00086 map<threeAddrNode*, int> def2num;
00087
00088 map<int, threeAddrNode*> num2def;
00089 int size;
00090 Bits *bits;
00091
00092 static threeAddr_set dummies;
00093
00094 public:
00097 copyFlowVal (threeAddr_set copy_stmts, threeAddr_set ambiguous_defs) {
00098
00099 decl_set vars;
00100 for(threeAddr_set_p s=copy_stmts.begin(); s!=copy_stmts.end();s++)
00101 vars.insert( ((idNode*) (*s)->lhs()->var())->decl() );
00102
00103
00104
00105 size = copy_stmts.size() + vars.size();
00106 bits = new Bits(size+1);
00107
00108
00109 int i=1;
00110 for(threeAddr_set_p s=copy_stmts.begin(); s!=copy_stmts.end();
00111 s++, i++) {
00112 def2num[*s] = i;
00113 num2def[i] = *s;
00114 }
00115
00116
00117 for (decl_set_p v=vars.begin(); v!=vars.end(); v++, i++) {
00118 threeAddrNode *dummy = new threeAddrNode (NULL,(operandNode*)NULL);
00119 dummies.insert(dummy);
00120 def2num[dummy] = i;
00121 num2def[i] = dummy;
00122 }
00123
00124 to_top ();
00125 }
00126
00127 ~copyFlowVal (void) { delete bits; }
00128
00130 void to_top (void) { bits->reset_all(); }
00131
00132 void to_bottom(void) { bits->set_all(); }
00133
00135 copyFlowVal * clone (void) const {
00136 copyFlowVal *other = new copyFlowVal (*this);
00137 other->bits = bits->clone();
00138 return other;
00139 }
00140
00141
00142 inline threeAddr_set stmts(void ) {
00143 threeAddr_set l;
00144 for (int i=1; i<=size; i++)
00145 if(in(i)) l.insert(num2def[i]);
00146 return l;
00147 }
00148
00150 bool diff (copyFlowVal *other) const {
00151 if(! other) return true;
00152 for (int i=1; i<=size; i++)
00153 if (other->bits->value(i) != bits->value(i))
00154 return true;
00155 return false;
00156 }
00157
00158
00159 bool in (threeAddrNode *s) { return bits->value(def2num[s]); }
00160
00161
00162 bool in (int i) const { return bits->value(i); }
00163
00165 void insert (threeAddrNode *s) { bits->set (def2num[s], true); }
00166
00168 void insert (int i) { bits->set (i, true); }
00169
00171 void remove (threeAddrNode *s) { bits->set (def2num[s], false); }
00172
00174 void remove (int i) { bits->set (i, false); }
00175
00177 void copy (copyFlowVal *other) { if(other) bits->copy (other->bits); }
00178
00180 void Union (const copyFlowVal *v) { if(v) bits->Or (v->bits); }
00181
00183 void Intersect (const copyFlowVal *v) { if(v) bits->And (v->bits); }
00184
00185
00186
00187 void Difference (copyFlowVal *other) {
00188 if(!other) return;
00189 Bits comp(size+1);
00190 comp.copy (other->bits);
00191 comp.Not ();
00192 bits->And (&comp);
00193 }
00194
00196 void meet (const copyFlowVal *v) { Union(v); }
00197
00198 void print() {
00199 cout << "{";
00200 for (int i=1; i<=size; i++) if(in(i)) cout << i << ",";
00201 cout << "}";
00202 }
00203
00204 static void clear_dummies() {
00205 for(threeAddr_set_p t=dummies.begin(); t!=dummies.end(); t++)
00206 delete *t;
00207 dummies.clear();
00208 }
00209 };
00210
00211 copyPropChanger::threeAddr_set copyPropChanger::copyFlowVal::dummies;
00212
00214
00215 Node *copyPropChanger::at_proc(procNode *p, Order ord) {
00216 if(!p) return p;
00217
00218
00219
00220 GetDefsWalker gdw(&copies, &ambiguous, &defines);
00221 p->walk(gdw);
00222
00223
00224 _top = new copyFlowVal(copies, ambiguous);
00225 _bottom = _top->clone();
00226 _bottom->to_bottom();
00227
00228
00229
00230
00231 basicblockNode *b = (basicblockNode *) p->body()->stmts().front();
00232 if (b->stmts().size() && b->stmts().front()->typ() == Label) {
00233
00234 stmt_list new_stmt;
00235 new_stmt.push_back( new gotoNode((labelNode*) b->stmts().front()) );
00236
00237 b = new basicblockNode (NULL, & new_stmt);
00238 b->comment() = "preheader to generate parameters and globals";
00239
00240
00241
00242 ((basicblockNode *)(p->body()->stmts().front()))->
00243 preds().push_back (b);
00244 b->succs().push_back ((basicblockNode *)
00245 p->body()->stmts().front());
00246 p->body()->stmts().push_front (b);
00247 }
00248
00249 stmt_list stmts = p->body()->stmts();
00250
00251
00252
00253 for(stmt_list_p s=stmts.begin(); s!=stmts.end(); s++) {
00254 assert( (*s)->typ() == Block);
00255 basicblockNode *b = (basicblockNode*) *s;
00256 Gen[b] = create_copy_set(b);
00257 }
00258 for(stmt_list_p s=stmts.begin(); s!=stmts.end(); s++) {
00259 basicblockNode *b = (basicblockNode*) *s;
00260 Kill[b] = create_kill_set(b, stmts);
00261 }
00262
00263 solve_global_dataflow(stmts);
00264
00265
00266 for(stmt_list_p s=stmts.begin(); s!=stmts.end(); s++) {
00267 basicblockNode *b = (basicblockNode*) *s;
00268 local_copy_prop(b);
00269 }
00270
00271
00272 copies.clear(); ambiguous.clear(); defines.clear();
00273 set<copyFlowVal*> flowvals;
00274 for(map<basicblockNode*, copyFlowVal*>::iterator m=Gen.begin();
00275 m!=Gen.end(); m++) if(m->second) flowvals.insert(m->second);
00276 for(map<basicblockNode*, copyFlowVal*>::iterator m=Kill.begin();
00277 m!=Kill.end(); m++) if(m->second) flowvals.insert(m->second);
00278 for(map<basicblockNode*, copyFlowVal*>::iterator m=In.begin();
00279 m!=In.end(); m++) if(m->second) flowvals.insert(m->second);
00280 for(map<basicblockNode*, copyFlowVal*>::iterator m=Out.begin();
00281 m!=Out.end(); m++) if(m->second) flowvals.insert(m->second);
00282 if(_top) flowvals.insert(_top);
00283 if(_bottom) flowvals.insert(_top);
00284 for(set<copyFlowVal*>::iterator f=flowvals.begin(); f!=flowvals.end(); f++)
00285 delete *f;
00286 Gen.clear(); Kill.clear(); In.clear(); Out.clear();
00287 copyFlowVal::clear_dummies();
00288
00289 return p;
00290 }
00291
00293
00294
00295 copyPropChanger::copyFlowVal *
00296 copyPropChanger::create_copy_set(basicblockNode *b) {
00297
00298
00299 if(!b) return _top;
00300
00301 threeAddr_set copy_stmts;
00302 for(stmt_list_p s=b->stmts().begin(); s!=b->stmts().end(); s++) {
00303 if((*s)->typ() != ThreeAddr) continue;
00304 threeAddrNode *t = (threeAddrNode*) *s;
00305 if(ambiguous.find(t) != ambiguous.end()) {
00306 copy_stmts.clear();
00307 continue;
00308 }
00309 if(! defines[t]) continue;
00310 for(threeAddr_set_p c=copy_stmts.begin(); c!=copy_stmts.end(); ) {
00311 bool kill_c = false;
00312 if(defines[*c] == defines[t]) kill_c = true;
00313 else {
00314 idNode *rhs = (idNode*) (*c)->rhs1()->var();
00315 if(rhs->decl() == defines[t]) kill_c = true;
00316 }
00317 if(kill_c) { threeAddrNode *C = *c; c++; copy_stmts.erase(C); }
00318 else c++;
00319 }
00320 if(copies.find(t) != copies.end())
00321 copy_stmts.insert(t);
00322 }
00323
00324 if(copy_stmts.empty()) return _top;
00325 copyFlowVal *fv= _top->clone();
00326 for(threeAddr_set_p c=copy_stmts.begin(); c!=copy_stmts.end(); c++)
00327 fv->insert(*c);
00328 return fv;
00329 }
00330
00331
00332 copyPropChanger::copyFlowVal *
00333 copyPropChanger::create_kill_set(basicblockNode *b, stmt_list bbs) {
00334
00335 if(!b) return _top;
00336
00337
00338 decl_set kill_vars;
00339 for(stmt_list_p s=b->stmts().begin(); s!=b->stmts().end(); s++) {
00340 if((*s)->typ() != ThreeAddr) continue;
00341 threeAddrNode *t = (threeAddrNode*) *s;
00342 if(ambiguous.find(t) != ambiguous.end())
00343 return _bottom;
00344
00345 if(defines[t])
00346 kill_vars.insert(defines[t]);
00347 }
00348 if(kill_vars.empty()) return _top;
00349
00350
00351 threeAddr_set kill_stmts;
00352 for(stmt_list_p o=bbs.begin(); o!=bbs.end(); o++) {
00353 if(*o == b) continue;
00354 basicblockNode *other = (basicblockNode*) *o;
00355 if(!Gen[other]) continue;
00356 threeAddr_set defs = Gen[other]->stmts();
00357 for(threeAddr_set_p d=defs.begin(); d!=defs.end(); d++)
00358 if(defines[*d] && kill_vars.find(defines[*d]) != kill_vars.end())
00359 kill_stmts.insert(*d);
00360 }
00361
00362 if(kill_stmts.empty()) return _top;
00363 copyFlowVal *fv= _top->clone();
00364 for(threeAddr_set_p k=kill_stmts.begin(); k!=kill_stmts.end(); k++)
00365 fv->insert(*k);
00366 return fv;
00367 }
00368
00369
00370 void copyPropChanger::solve_global_dataflow(stmt_list stmts) {
00371
00372 for(stmt_list_p s=stmts.begin(); s!=stmts.end(); s++) {
00373 basicblockNode *B = (basicblockNode *) *s;
00374 In[B] = _top->clone();
00375 Out[B] = _top->clone();
00376 }
00377
00378 stmt_list worklist = stmts;
00379
00380 copyFlowVal *oldout = _top->clone();
00381 while (! worklist.empty()) {
00382 basicblockNode *B = (basicblockNode *) worklist.front();
00383 worklist.remove(B);
00384 copyFlowVal *inb = In[B],
00385 *outb = Out[B];
00386
00387
00388 if(B->preds().empty()) inb->to_top();
00389 for (basicblock_list_p q=B->preds().begin(); q!=B->preds().end(); q++)
00390 if(q == B->preds().begin())
00391 inb->copy(Out[*q]);
00392 else
00393 inb->Intersect (Out[*q]);
00394
00395 oldout->copy (outb);
00396
00397 outb->copy (inb);
00398 outb->Difference (Kill[B]);
00399 outb->Union (Gen[B]);
00400 if (oldout->diff(outb))
00401 for (basicblock_list_p s=B->succs().begin(); s!=B->succs().end(); s++)
00402 if(find(worklist.begin(), worklist.end(), *s) == worklist.end())
00403 worklist.push_back(*s);
00404 }
00405 delete oldout;
00406 }
00407
00409
00410
00411 void copyPropChanger::local_copy_prop(basicblockNode *b) {
00412 if(!b) return;
00413
00414 ACP acp;
00415 if(In[b]) {
00416 threeAddr_set in = In[b]->stmts();
00417 for(threeAddr_set_p i=in.begin(); i!=in.end(); i++) {
00418 operandNode *lhs = (*i)->lhs(), *rhs = (*i)->rhs1();
00419 assert(lhs && lhs->var()->typ()==Id);
00420 assert(rhs && rhs->var()->typ()==Id);
00421 acp.insert(Var_pair(((idNode*)lhs->var())->decl(),
00422 ((idNode*)rhs->var())->decl()));
00423 }
00424 }
00425
00426
00427 for(stmt_list_p s=b->stmts().begin(); s!=b->stmts().end(); s++) {
00428 switch((*s)->typ()) {
00429 case ThreeAddr: {
00430 threeAddrNode *t = (threeAddrNode*) *s;
00431
00432 copy_value(t->rhs1(), acp);
00433 copy_value(t->rhs2(), acp);
00434 for(operand_list_p a=t->arg_list().begin(); a!=t->arg_list().end(); a++)
00435 copy_value(*a, acp);
00436
00437
00438 if(ambiguous.find(t) != ambiguous.end())
00439 acp.clear();
00440 else {
00441 operandNode *lhs = t->lhs();
00442 if(lhs && !lhs->star() && lhs->fields().empty() &&
00443 !lhs->index()) {
00444
00445 assert(lhs->var()->typ() == Id);
00446 remove_ACP(acp, ((idNode*)lhs->var())->decl());
00447 }
00448 if(copies.find(t) != copies.end()) {
00449 operandNode *rhs = t->rhs1();
00450 assert(rhs && !rhs->star() && rhs->fields().empty() &&
00451 !rhs->index() && rhs->var()->typ() == Id);
00452 acp.insert(Var_pair(((idNode*)lhs->var())->decl(),
00453 ((idNode*)rhs->var())->decl()));
00454 }
00455 }
00456 break;
00457 }
00458
00459
00460 case Condition: {
00461 conditiongotoNode *g = (conditiongotoNode*) *s;
00462 assert(g->left());
00463 if(g->left()->typ()==Id) {
00464 idNode *new_id = copy_value((idNode*) g->left(), acp);
00465 if(new_id != g->left()) g->left(new_id);
00466 }
00467 assert(g->right());
00468 if(g->right()->typ()==Id) {
00469 idNode *new_id = copy_value((idNode*) g->right(), acp);
00470 if(new_id != g->right()) g->right(new_id);
00471 }
00472 break;
00473 }
00474
00475 case Return: {
00476
00477
00478
00479 returnNode *r = (returnNode*) *s;
00480 idNode *new_id = copy_value((idNode*) r->expr(), acp);
00481 if(new_id != r->expr())
00482 r->expr(new_id);
00483 break;
00484 }
00485
00486 case Goto: case Label: break;
00487 case Expr: assert(! ((exprstmtNode*)*s)->expr());
00488 break;
00489 default: assert(false);
00490 }
00491 }
00492 }
00493
00494 void copyPropChanger::remove_ACP(ACP &acp, declNode *v) {
00495 if(!v) return;
00496 for(ACP::iterator m=acp.begin(); m!=acp.end(); )
00497 if(m->first==v || m->second==v) {
00498 Var_pair p=*m; m++; acp.erase(p);
00499 } else m++;
00500 }
00501
00502
00503 void copyPropChanger::copy_value(operandNode *opnd, const ACP &acp) {
00504 if(!opnd) return;
00505
00506 if(opnd->addr() ) return;
00507 if(opnd->var()->typ() != Id) return;
00508 idNode *new_id = copy_value((idNode*) opnd->var(), acp);
00509 if(new_id != opnd->var())
00510 opnd->var(new_id);
00511 if(opnd->index() && opnd->index()->typ() == Id) {
00512 new_id = copy_value((idNode*) opnd->index(), acp);
00513 if(new_id != opnd->index())
00514 opnd->index(new_id);
00515 }
00516 }
00517
00518
00519 idNode *copyPropChanger::copy_value(idNode *opnd, const ACP &acp) {
00520 if(!opnd) return opnd;
00521 declNode *decl = opnd->decl();
00522
00523 decl_set copy_found;
00524 for(ACP::const_iterator m=acp.begin(); m!=acp.end(); m++)
00525 if(m->first==decl)
00526 copy_found.insert( m->second );
00527
00528 if(copy_found.empty()) return opnd;
00529
00530 if(copy_found.size() == 1)
00531 return new idNode(* copy_found.begin());
00532
00533 assert(false);
00534
00535
00536 for(decl_set_p c=copy_found.begin(); c!=copy_found.end(); c++)
00537 if(*c != * copy_found.begin())
00538 return opnd;
00539
00540 return new idNode(* copy_found.begin());
00541 }
00542
00544
00545 void copyPropChanger::change() {
00546 for (unit_list_p n=CBZ::Program.begin(); n!=CBZ::Program.end(); n++)
00547 change(*n);
00548 }
00549
00550
00551 void copyPropChanger::change(unitNode *u) {
00552 if(!u) return;
00553 for(def_list_p d=u->defs().begin(); d!=u->defs().end(); d++)
00554 if((*d)->typ() == Proc) change((procNode*) *d);
00555 }
00556
00557 void copyPropChanger::change(procNode *p) {
00558 if(!p) return;
00559 copyPropChanger cpc;
00560 p->change (cpc);
00561 }
00562
00564
00565 class copypropphase : public Phase {
00566 void run() {
00567 copyPropChanger::change();
00568 }
00569 };
00570 Phases copyprop_phase("copyprop", new copypropphase());
00571