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 "c_breeze.h"
00040 #include "bits.h"
00041 #include "reaching.h"
00042
00045 class reachingDefinitionsWalker::defFlowVal {
00046 friend class reachingGenKillWalker;
00047 private:
00048
00049 int size;
00050 map <threeAddrNode*, int> *def2num;
00051
00052 Bits *bits;
00053 threeAddrNode **definitions;
00054
00055
00056 public:
00065 defFlowVal (int n, map<threeAddrNode*,int> *m, threeAddrNode **d)
00066 : size(n), def2num(m), definitions(d), bits(new Bits(n+1)) { to_top (); }
00067
00068 ~defFlowVal (void) { delete bits; }
00069
00070
00071 void to_top (void) { bits->reset_all(); }
00072
00073
00074 defFlowVal * clone (void) const {
00075 defFlowVal *other = new defFlowVal (size, def2num, definitions);
00076 other->bits = bits->clone();
00077 return other;
00078 }
00079
00080
00081 bool diff (defFlowVal *other) const {
00082 if(!other) return true;
00083 for (int i=1; i<=size; i++)
00084 if (other->bits->value(i) != bits->value(i))
00085 return true;
00086 return false;
00087 }
00088
00089
00090 bool in (threeAddrNode *s) const { return bits->value((*def2num)[s]); }
00091
00092
00093 bool in (int i) const { return bits->value(i); }
00094
00096 void insert (threeAddrNode *s) { bits->set ((*def2num)[s], true); }
00097
00099 void insert (int i) { bits->set (i, true); }
00100
00102 void remove (threeAddrNode *s) { bits->set ((*def2num)[s], false); }
00103
00105 void remove (int i) { bits->set (i, false); }
00106
00108 void copy (defFlowVal *other) { if(other) bits->copy (other->bits); }
00109
00111 void Union (const defFlowVal *v) { if(v) bits->Or (v->bits); }
00112
00114 void Intersect (const defFlowVal *v) { if(v) bits->And (v->bits); }
00115
00116
00117
00118 void Difference (defFlowVal *other) {
00119 if(!other) return;
00120 Bits comp(size+1);
00121 comp.copy (other->bits);
00122 comp.Not ();
00123 bits->And (&comp);
00124 }
00125
00127 void meet (const defFlowVal *v) { Union(v); }
00128 };
00129
00130
00132
00135 class reachingDefinitionsWalker::reachingGenKillWalker : public Walker {
00136 friend class reachingDefinitionsWalker;
00137
00138 private:
00139
00140
00141
00142 class GetDefsWalker : public Walker {
00143 private:
00144
00145
00146
00147 map<threeAddrNode*, declNode*> * defines;
00148
00149
00150
00151 stmt_list * ambiguous_defs;
00152
00153 public:
00154 GetDefsWalker (map<threeAddrNode*, declNode*> *d, stmt_list *l) :
00155 Walker (Preorder, Subtree), ambiguous_defs(l), defines(d) { }
00156
00157
00158
00159 void at_threeAddr (threeAddrNode *stmt, Order) {
00160 bool ambiguous = false;
00161 if(stmt->lhs()) {
00162 operandNode *lhs = stmt->lhs();
00163 if(lhs->star() || ! lhs->fields().empty() || lhs->index())
00164 ambiguous = true;
00165 else {
00166 assert(lhs->var()->typ() == Id);
00167 (*defines)[stmt] = ((idNode*)lhs->var())->decl();
00168 }
00169 }
00170 if(stmt->op() && stmt->op()->id() == Operator::FUNC_CALL)
00171 ambiguous = true;
00172 if(ambiguous)
00173 ambiguous_defs->push_back (stmt);
00174 }
00175 };
00176
00178
00179
00181 map <threeAddrNode *, int> * node2num;
00182
00184 map <threeAddrNode *, declNode *> * defines;
00185
00187 map <declNode *, defFlowVal *> *defs;
00188
00190 stmt_list ambiguous_defs;
00191
00192
00193 threeAddrNode ***num2node;
00194
00196 int *n;
00197
00198
00199 reachingDefinitionsWalker *_rd;
00200
00202 defFlowVal * _flowval;
00203
00205 defFlowVal * _everything;
00206
00207
00208 stmt_list & _dummies;
00209
00210 public:
00211
00212
00213 reachingGenKillWalker (map <threeAddrNode *, int> *n2n,
00214 map <threeAddrNode *, declNode *> *dfns,
00215 map <declNode *, defFlowVal *> *dfs,
00216 threeAddrNode ***num2n,
00217 int *numdefs,
00218 reachingDefinitionsWalker *rd,
00219 stmt_list & dummies) :
00220 Walker (Preorder, Subtree),
00221 node2num(n2n),
00222 defines(dfns),
00223 defs(dfs),
00224 n(numdefs),
00225 _flowval(NULL),
00226 num2node(num2n),
00227 _rd(rd),
00228 _dummies(dummies) { }
00229
00230
00231 ~reachingGenKillWalker (void) {}
00232
00238 defFlowVal * new_flowval (void) {
00239 defFlowVal *f = (defFlowVal *) _flowval->clone();
00240 f->to_top();
00241 return f;
00242 }
00243
00244 void at_proc (procNode *, Order);
00245
00246 void at_basicblock (basicblockNode *, Order);
00247
00248
00249
00250 void at_unit (unitNode *, Order) {
00251 cerr << "Don't invoke the reachingGenKillWalker from a unitNode!\n";
00252 exit (1);
00253 }
00254
00255 };
00256
00257
00258 void reachingDefinitionsWalker::reachingGenKillWalker
00259 ::at_proc(procNode *p, Order ord) {
00260 int i;
00261
00262
00263
00264 defines->clear();
00265 GetDefsWalker gdw (defines, & ambiguous_defs);
00266 p->walk (gdw);
00267
00268
00269
00270 decl_list vars;
00271 map <threeAddrNode *, declNode *>::iterator r;
00272 for (r=defines->begin(); r!=defines->end(); r++)
00273 vars.push_back ((*r).second);
00274 vars.sort();
00275 vars.unique();
00276
00277
00278
00279
00280 *n = defines->size() + vars.size();
00281
00282
00283
00284
00285
00286 *num2node = new threeAddrNode *[*n + 1];
00287
00288
00289
00290 _flowval = new defFlowVal (*n, node2num, *num2node);
00291 _flowval->to_top();
00292
00293
00294
00295
00296
00297
00298 for (i=1, r=defines->begin(); r!=defines->end(); i++,r++) {
00299
00300
00301
00302 (*node2num)[(*r).first] = i;
00303
00304
00305
00306 (*num2node)[i] = (*r).first;
00307
00308
00309
00310
00311 defFlowVal *v = (*defs)[(*r).second];
00312
00313
00314
00315 if (v == NULL) {
00316 v = (defFlowVal *) _flowval->clone();
00317 (*defs)[(*r).second] = v;
00318 }
00319 v->insert (i);
00320 }
00321
00322
00323
00324 _everything = (defFlowVal *) _flowval->clone();
00325 decl_list_p q;
00326 for (q=vars.begin(); q!=vars.end(); q++, i++) {
00327
00328
00329
00330
00331 threeAddrNode *dummy = new threeAddrNode (NULL,(operandNode*)NULL);
00332 _dummies.push_back(dummy);
00333
00334
00335
00336
00337 (*node2num)[dummy] = i;
00338 (*num2node)[i] = dummy;
00339
00340
00341
00342 (*defines)[dummy] = *q;
00343
00344
00345
00346 defFlowVal *v = (*defs)[*q];
00347
00348
00349
00350 assert (v);
00351
00352
00353
00354 v->insert (i);
00355
00356
00357
00358
00359
00360 _everything->insert (i);
00361 }
00362
00363
00364
00365
00366
00367
00368 basicblockNode *b = (basicblockNode *) p->body()->stmts().front();
00369 if (b->stmts().size() && b->stmts().front()->typ() == Label) {
00370
00371 stmt_list new_stmt;
00372 new_stmt.push_back( new gotoNode((labelNode*) b->stmts().front()) );
00373
00374
00375
00376 b = new basicblockNode (NULL, & new_stmt);
00377 b->comment() = "preheader to generate parameters and globals";
00378
00379
00380
00381 ((basicblockNode *)(p->body()->stmts().front()))->
00382 preds().push_back (b);
00383 b->succs().push_back ((basicblockNode *)
00384 p->body()->stmts().front());
00385 p->body()->stmts().push_front (b);
00386 }
00387
00388
00389
00390
00391 stmt_list_p t;
00392 for (t=p->body()->stmts().begin(); t!=p->body()->stmts().end(); t++) {
00393 b = (basicblockNode *) *t;
00394 stmt_list_p r;
00395 for (r=b->stmts().begin(); r!=b->stmts().end(); r++) {
00396 _rd->gen[*r] = (defFlowVal *) _flowval->clone();
00397 _rd->kill[*r] = (defFlowVal *) _flowval->clone();
00398 }
00399 }
00400
00401
00402
00403
00404 for (t=ambiguous_defs.begin(); t!=ambiguous_defs.end(); t++) {
00405 defFlowVal *v = _rd->gen[*t];
00406 assert (v);
00407 v->Union (_everything);
00408 }
00409
00410
00411 }
00412
00413
00414 void reachingDefinitionsWalker::reachingGenKillWalker
00415 ::at_basicblock(basicblockNode *b, Order ord) {
00416 stmt_list_p r;
00417
00418 defFlowVal *gen;
00419 defFlowVal *kill;
00420
00421
00422
00423 for (r=b->stmts().begin(); r!=b->stmts().end(); r++) {
00424 if((*r)->typ() != ThreeAddr) continue;
00425
00426
00427
00428 threeAddrNode *d = (threeAddrNode*) *r;
00429
00430
00431
00432 gen = _rd->gen[d];
00433 kill = _rd->kill[d];
00434
00435
00436
00437 declNode *v = (*defines)[d];
00438 if (v == NULL) {
00439
00440
00441
00442
00443
00444 } else {
00445
00446
00447
00448
00449 kill->Union ((*defs)[v]);
00450
00451
00452
00453 kill->remove (d);
00454
00455
00456
00457 gen->insert (d);
00458 }
00459 }
00460
00461
00462
00463
00464
00465 gen = (defFlowVal *) _flowval->clone();
00466 kill = (defFlowVal *) _flowval->clone();
00467
00468
00469
00470
00471
00472 if (b->preds().size() == 0) gen->Union (_everything);
00473
00474 for (r=b->stmts().begin(); r!=b->stmts().end(); r++) {
00475 stmtNode *d = *r;
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 gen->Difference (_rd->kill[d]);
00486 gen->Union (_rd->gen[d]);
00487 kill->Difference (_rd->gen[d]);
00488 kill->Union (_rd->kill[d]);
00489 }
00490 _rd->gen[b] = gen;
00491 _rd->kill[b] = kill;
00492 }
00493
00495
00496
00497 void reachingDefinitionsWalker::at_proc (procNode *p, Order ord) {
00498 if (ord == Postorder) {
00499
00500 delete [] num2node;
00501 num2node = NULL;
00502 for(stmt_list_p d=dummies.begin(); d!=dummies.end(); d++) delete *d;
00503 return;
00504 }
00505 node2num.clear();
00506 defines.clear();
00507 in.clear();
00508 out.clear();
00509 defs.clear();
00510
00511
00512
00513 reachingGenKillWalker gcw (&node2num, &defines, &defs, &num2node, &n, this,
00514 dummies);
00515 p->walk (gcw);
00516 defFlowVal *v = gcw.new_flowval();
00517 blockNode *b = p->body();
00518
00519
00520
00521
00522
00523 stmt_list_p r;
00524 for (r=b->stmts().begin(); r!=b->stmts().end(); r++) {
00525 basicblockNode *B = (basicblockNode *) *r;
00526 out[B] = (defFlowVal *) gen[B]->clone();
00527 in[B] = (defFlowVal *) v->clone();
00528 }
00529
00530 defFlowVal *oldout = gcw.new_flowval();
00531 bool change = true;
00532
00533
00534
00535
00536
00537
00538
00539 while (change) {
00540 change = false;
00541
00542
00543
00544 for (r=b->stmts().begin(); r!=b->stmts().end(); r++) {
00545 basicblockNode *B = (basicblockNode *) *r;
00546 defFlowVal *inb = in[B];
00547 defFlowVal *outb = out[B];
00548
00549
00550
00551
00552 inb->to_top();
00553 basicblock_list_p q;
00554 for (q=B->preds().begin(); q!=B->preds().end(); q++)
00555 inb->Union (out[*q]);
00556
00557 oldout->copy (outb);
00558
00559
00560
00561
00562 v->copy (inb);
00563 v->Difference (kill[B]);
00564 v->Union (gen[B]);
00565 outb->copy (v);
00566 if (oldout->diff(v)) change = true;
00567 }
00568 }
00569 delete v;
00570 delete oldout;
00571 delete gcw._flowval;
00572
00573 }
00574
00575
00576 void reachingDefinitionsWalker::at_basicblock (basicblockNode *b,
00577 Order ord) {
00578 stmt_list_p p;
00579 if (ord == Postorder) {
00580
00581 for (p=b->stmts().begin(); p!=b->stmts().end(); p++) {
00582 stmtNode *s = *p;
00583 if (gen[s]) {
00584 delete gen[s];
00585 gen[s] = NULL;
00586 }
00587 if (kill[s]) {
00588 delete kill[s];
00589 kill[s] = NULL;
00590 }
00591 }
00592 if (gen[b]) {
00593 delete gen[b];
00594 gen[b] = NULL;
00595 }
00596 if (kill[b]) {
00597 delete kill[b];
00598 kill[b] = NULL;
00599 }
00600 delete in[b];
00601 delete out[b];
00602 return;
00603 }
00604
00605 current_in = (defFlowVal *) in[b]->clone();
00606 for (p=b->stmts().begin(); p!=b->stmts().end(); p++) {
00607 make_ud_chains (*p);
00608
00609
00610
00611
00612
00613
00614 current_in->Difference (kill[*p]);
00615 current_in->Union (gen[*p]);
00616 }
00617 delete current_in;
00618 }
00619
00620
00621
00622 void reachingDefinitionsWalker::make_ud_chains (stmtNode *s) {
00623 switch(s->typ()) {
00624 case Condition: {
00625 conditiongotoNode *g = (conditiongotoNode*) s;
00626 make_ud_chains(g->left(), NULL, s);
00627 make_ud_chains(g->right(), NULL, s);
00628 break;
00629 }
00630
00631 case ThreeAddr: {
00632 threeAddrNode *S = (threeAddrNode*) s;
00633 if(S->lhs() && S->lhs()->index())
00634 make_ud_chains(S->lhs()->index(), NULL, s);
00635 make_ud_chains(S->rhs1(), NULL, s);
00636 make_ud_chains(S->rhs2(), NULL, s);
00637 for(operand_list_p a=S->arg_list().begin(); a!=S->arg_list().end(); a++)
00638 make_ud_chains(*a, NULL, s);
00639 break;
00640 }
00641
00642 case Return: make_ud_chains(((returnNode*)s)->expr(), NULL, s);
00643 break;
00644
00645 case Expr: assert(! ((exprstmtNode*)s)->expr());
00646 break;
00647
00648 case Label:
00649 case Goto: break;
00650 default: cout << s->typ() << " " << s->coord() << endl;
00651 assert(false);
00652 }
00653 }
00654
00655
00656 void reachingDefinitionsWalker::make_ud_chains (exprNode *e,
00657 exprNode *E,
00658 stmtNode *usesite) {
00659 if (!e) return;
00660 if (!E) E=e;
00661
00662
00663 switch (e->typ()) {
00664 case Id: {
00665 idNode *i = (idNode *) e;
00666
00667
00668
00669 defFlowVal *i_defs = defs[i->decl()];
00670
00671
00672
00673 if (!i_defs) return;
00674
00675 bool has_ambiguous = false;
00676 for (int j=1; j<=n; j++)
00677 if (i_defs->in (j) && current_in->in (j)) {
00678 threeAddrNode *t = num2node[j];
00679 assert(t);
00680 if (!t->lhs() && !t->rhs1())
00681
00682 has_ambiguous = true;
00683 else {
00684 udChain->add(E, num2node[j], usesite);
00685 if(E!=i) udChain->add(i, num2node[j], usesite);
00686 }
00687 }
00688 if (has_ambiguous) {
00689 udChain->add(E, NULL, usesite);
00690 if(E!=i) udChain->add(E, NULL, usesite);
00691 }
00692 break;
00693 }
00694
00695 case Operand: {
00696 operandNode *o = (operandNode*) e;
00697 if(o->addr()) break;
00698 make_ud_chains(o->var(), o, usesite);
00699 make_ud_chains(o->index(), NULL, usesite);
00700 break;
00701 }
00702
00703 case Const: break;
00704
00705 default: assert(false);
00706 }
00707 }
00708