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 "c_breeze.h"
00039 #include "ssa.h"
00040
00041 SSA::SSA(procNode * proc, bool forward, bool do_renaming)
00042 : _proc(proc),
00043 _root(0),
00044 _cfg(),
00045 DF(proc)
00046 {
00047
00048
00049 stmt_list & sts = proc->body()->stmts();
00050
00051 for (stmt_list_p p = sts.begin();
00052 p != sts.end();
00053 ++p)
00054 {
00055 stmtNode * s = *p;
00056 assert(s->typ() == Block);
00057 _cfg.push_back( (basicblockNode *) s);
00058 }
00059
00060 _root = _cfg.front();
00061
00062
00063
00064 for (basicblock_list_p p = _cfg.begin();
00065 p != _cfg.end();
00066 ++p)
00067 {
00068 basicblockNode * cur = (*p);
00069 cur->info(new ssa_info());
00070 }
00071
00072
00073
00074 place_phi_functions();
00075
00076
00077
00078 if (do_renaming)
00079 rename();
00080
00081
00082
00083 for (basicblock_list_p p = _cfg.begin();
00084 p != _cfg.end();
00085 ++p)
00086 {
00087 basicblockNode * curblock = (*p);
00088 if (curblock->info())
00089 delete curblock->info();
00090
00091 curblock->info(0);
00092 }
00093 }
00094
00095 typedef map<declNode *, basicblock_bitset> assignment_map;
00096 typedef assignment_map::iterator assignment_map_p;
00097
00098
00099
00100 class Assignment_walker : public Walker
00101 {
00102 private:
00103
00104 int basicblock;
00105 assignment_map & _a_map;
00106
00107 public:
00108
00109 Assignment_walker(assignment_map & a_map, int basicblock_num)
00110 : Walker(Preorder, Subtree),
00111 basicblock(basicblock_num),
00112 _a_map(a_map)
00113 {}
00114
00115 void at_binary(binaryNode * the_binary, Order ord);
00116 };
00117
00118 void Assignment_walker::at_binary(binaryNode * the_binary, Order ord)
00119 {
00120 if (the_binary->op()->is_assignment())
00121 if (the_binary->left()->typ() == Id) {
00122 idNode * id = (idNode *) the_binary->left();
00123 declNode * de = id->decl();
00124 if (SSA::need_ssa (de)) {
00125 if (_a_map.find(de) == _a_map.end())
00126 _a_map[de] = basicblock_bitset();
00127
00128 _a_map[de].set(basicblock);
00129
00130 }
00131 }
00132 }
00133
00134
00135
00136
00137
00138 void SSA::place_phi_functions()
00139 {
00140 int IterCount = 0;
00141 assignment_map a_map;
00142 basicblock_vec df_vec;
00143
00144
00145
00146
00147 df_vec.resize(_cfg.size(), (basicblockNode *) 0);
00148
00149 for (basicblock_list_p p = _cfg.begin();
00150 p != _cfg.end();
00151 ++p)
00152 {
00153 basicblockNode * X = (*p);
00154 Assignment_walker aw(a_map, X->dfn());
00155 X->walk(aw);
00156
00157 df_vec[X->dfn()] = X;
00158 }
00159
00160 int num_nodes = df_vec.size();
00161
00162
00163
00164 Stack.clear();
00165 Changes.clear();
00166
00167 basicblock_list W;
00168
00169
00170
00171 for (assignment_map_p p = a_map.begin();
00172 p != a_map.end();
00173 ++p)
00174 {
00175 declNode * d = (*p).first;
00176 basicblock_bitset & defs = (*p).second;
00177
00178
00179
00180 IterCount++;
00181
00182
00183
00184
00185
00186 for (int i = 0; i < num_nodes; i++)
00187 if (defs.test(i)) {
00188 basicblockNode * X = df_vec[i];
00189 Work(X) = IterCount;
00190 W.push_back(X);
00191 }
00192
00193
00194
00195 Stack[d] = int_list();
00196
00197
00198
00199
00200 if (d->decl_location() == declNode::FORMAL
00201 || d->storage_class() == declNode::STATIC )
00202 Counter[d] = 1;
00203 else Counter[d] = 0;
00204
00205
00206
00207 while ( ! W.empty() ) {
00208
00209
00210
00211 basicblockNode * X = W.front();
00212 W.pop_front();
00213
00214
00215
00216 basicblock_list & DFX = DF[X];
00217 for (basicblock_list_p dfp = DFX.begin();
00218 dfp != DFX.end();
00219 ++dfp)
00220 {
00221 basicblockNode * Y = (* dfp);
00222
00223
00224
00225 if (HasAlready(Y) < IterCount) {
00226 place_one_phi(d, Y);
00227 HasAlready(Y) = IterCount;
00228
00229
00230
00231 if (Work(Y) < IterCount) {
00232 Work(Y) = IterCount;
00233 W.push_back(Y);
00234 }
00235 }
00236 }
00237 }
00238 }
00239 }
00240
00241 void SSA::place_one_phi(declNode * d, basicblockNode * block)
00242 {
00243
00244
00245
00246
00247 idNode * phi = new idNode("__phi");
00248
00249 callNode * call = new callNode(phi, 0);
00250
00251
00252
00253 int sz = block->preds().size();
00254 for (int i = 0; i < sz; i++) {
00255 idNode * v2 = new idNode(d->name().c_str());
00256 v2->decl(d);
00257 typeNode * t = d->no_tdef_type();
00258 if (t)
00259 v2->type((typeNode *) ref_clone_changer::clone(t, false));
00260
00261 call->args().push_back(v2);
00262 }
00263
00264
00265
00266 idNode * v3 = new idNode(d->name().c_str());
00267 v3->decl(d);
00268 typeNode * t = d->no_tdef_type();
00269 if (t)
00270 v3->type((typeNode *) ref_clone_changer::clone(t, false));
00271
00272 binaryNode * a = new binaryNode('=', v3, call);
00273
00274 exprstmtNode * e = new exprstmtNode(a);
00275
00276
00277
00278
00279 stmt_list_p p = block->stmts().begin();
00280 stmtNode * s;
00281
00282 do {
00283 s = (*p);
00284 p++;
00285 } while ((s->typ() != Label) &&
00286 (p != block->stmts().end()));
00287
00288 block->stmts().insert(p, e);
00289 }
00290
00291 int SSA::which_pred(basicblockNode * node, basicblockNode * pred)
00292 {
00293 basicblock_list & bbl = node->preds();
00294 int which = 0;
00295
00296 for (basicblock_list_p p = bbl.begin();
00297 p != bbl.end();
00298 ++p)
00299 if (pred == (*p))
00300 return which;
00301 else
00302 which++;
00303
00304 return -1;
00305 }
00306
00307
00308
00309
00310
00311 void SSA::rename()
00312 {
00313
00314
00315 search(_root);
00316
00317 rename_all_variables();
00318 }
00319
00320
00321 void SSA::record_index(idNode * the_id)
00322 {
00323 declNode * de = the_id->decl();
00324 if (Stack.find(de) != Stack.end())
00325 if ( ! Stack[de].empty() ) {
00326 int index = Stack[de].front();
00327 Changes.push_back(var_change(the_id, index));
00328 }
00329 }
00330
00331 class renumber_walker : public Walker
00332 {
00333 public:
00334
00335 static void renum(Node * n, SSA * ssa)
00336 {
00337 renumber_walker rnw(ssa);
00338
00339 n->walk(rnw);
00340 }
00341
00342 private:
00343
00344 SSA * ssa;
00345
00346 renumber_walker(SSA * the_ssa)
00347 : Walker(Preorder, Subtree),
00348 ssa(the_ssa)
00349 {}
00350
00351 void at_id(idNode * the_id, Order ord)
00352 {
00353
00354
00355
00356
00357 ssa->record_index(the_id);
00358 }
00359 };
00360
00361
00362
00363 binaryNode * SSA::assignment(stmtNode * s)
00364 {
00365 if (s->typ() == Expr) {
00366 exprNode * e = ((exprstmtNode *) s)->expr();
00367 if (e && (e->typ() == Binary)) {
00368 binaryNode * the_binary = (binaryNode *) e;
00369 if (the_binary->op()->is_assignment())
00370 return the_binary;
00371 }
00372 }
00373
00374 return 0;
00375 }
00376
00377 idNode * SSA::lhs(stmtNode * s)
00378 {
00379 binaryNode * b = assignment(s);
00380
00381 if (b && (b->left()->typ() == Id)) {
00382 idNode* id = (idNode*) b->left();
00383 if (need_ssa (id->decl()))
00384 return (idNode *) b->left();
00385 }
00386 return 0;
00387 }
00388
00389 callNode * SSA::phi(stmtNode * s)
00390 {
00391 binaryNode * b = assignment(s);
00392
00393 if (b && (b->right()->typ() == Call)) {
00394 callNode * c = (callNode *) b->right();
00395 if (c->name()->typ() == Id) {
00396 idNode * id = (idNode *) c->name();
00397 if (id->name() == string("__phi"))
00398 return c;
00399 }
00400 }
00401
00402 return 0;
00403 }
00404
00405
00406
00407 bool SSA::need_ssa (declNode* decl) {
00408 declNode::Decl_location loc = decl->decl_location();
00409
00410 if ( (loc == declNode::FORMAL || loc == declNode::BLOCK)
00411 && decl->storage_class() != declNode::TYPEDEF) {
00412 typeNode* t = decl->no_tdef_type();
00413
00414 return (t && (t->typ() != Struct) && (t->typ() != Union));
00415 }
00416 return false;
00417 }
00418
00419
00420
00421 void SSA::search(basicblockNode * X)
00422 {
00423
00424
00425 for (stmt_list_p p = X->stmts().begin();
00426 p != X->stmts().end();
00427 ++p)
00428 {
00429 stmtNode * s = *p;
00430 binaryNode * A = assignment(s);
00431 callNode * Phi = phi(s);
00432
00433
00434
00435 if ((s->typ() == Expr) && ! Phi) {
00436
00437 if ( A && A->left()->typ() == Id ) {
00438
00439
00440
00441 renumber_walker::renum(A->right(), this);
00442 }
00443 else {
00444
00445
00446
00447 renumber_walker::renum(s, this);
00448 }
00449 }
00450
00451
00452
00453 if (s->typ() == If || s->typ() == Return)
00454 renumber_walker::renum(s, this);
00455
00456
00457
00458 idNode * LHS = lhs(s);
00459
00460 if (LHS) {
00461 declNode * de = LHS->decl();
00462 int i = Counter[de];
00463 Stack[de].push_front(i);
00464 record_index(LHS);
00465 Counter[de] = i + 1;
00466 }
00467 }
00468
00469
00470
00471 basicblock_list & bbl = X->succs();
00472
00473 for (basicblock_list_p p = bbl.begin();
00474 p != bbl.end();
00475 ++p)
00476 {
00477 basicblockNode * Y = *p;
00478 int j = which_pred(Y, X);
00479
00480
00481
00482
00483 for (stmt_list_p p = Y->stmts().begin();
00484 p != Y->stmts().end();
00485 ++p)
00486 {
00487 callNode * Phi = phi(*p);
00488 if (Phi) {
00489
00490
00491
00492 int i = 0;
00493 for (expr_list_p ap = Phi->args().begin();
00494 ap != Phi->args().end();
00495 ++ap, ++i)
00496 if (i == j) {
00497 idNode * nid = (idNode *) (*ap);
00498 declNode * de = nid->decl();
00499
00500 if ( ! Stack[de].empty()) {
00501 record_index(nid);
00502
00503 }
00504 break;
00505 }
00506 }
00507 }
00508 }
00509
00510
00511
00512 for (basicblock_list_p p = X->children().begin();
00513 p != X->children().end();
00514 ++p)
00515 search(*p);
00516
00517
00518
00519 for (stmt_list_p p = X->stmts().begin();
00520 p != X->stmts().end();
00521 ++p)
00522 {
00523 stmtNode * s = *p;
00524 idNode * LHS = lhs(s);
00525 if (LHS) {
00526 declNode * de = LHS->decl();
00527 Stack[de].pop_front();
00528 }
00529 }
00530 }
00531
00532 string SSA::name_with_index(string & name, int index)
00533 {
00534
00535
00536
00537
00538
00539
00540 char buf[256];
00541 sprintf(buf, "%s@%d", name.c_str(), index);
00542 return string(buf);
00543 }
00544
00545 void SSA::rename_all_variables()
00546 {
00547 decl_decl_map NewDeclarations;
00548
00549
00550
00551 for (counter_map_p p = Counter.begin();
00552 p != Counter.end();
00553 ++p)
00554 {
00555 declNode * de = (*p).first;
00556 int max = (*p).second;
00557
00558 NewDeclarations[de] = decl_vector(max);
00559
00560
00561
00562
00563
00564 for (int i = 1; i < max; ++i) {
00565
00566
00567
00568 declNode * sde = new subdeclNode( de, i );
00569 sde->decl_location(declNode::BLOCK);
00570
00571
00572
00573 NewDeclarations[de][i] = sde;
00574
00575
00576
00577 _proc->body()->decls().push_back(sde);
00578 }
00579 }
00580
00581
00582
00583
00584 for (var_changes_p p = Changes.begin();
00585 p != Changes.end();
00586 ++p)
00587 {
00588 idNode * id = (*p).first;
00589 int index = (*p).second;
00590 declNode * de = id->decl();
00591
00592
00593
00594
00595 if (index > 0) {
00596 subdeclNode * new_decl = (subdeclNode*) NewDeclarations[de][index];
00597
00598 id->decl(new_decl);
00599 id->name(new_decl->name_with_index());
00600 }
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611 bool SSA::add_phi_function(declNode * d, basicblockNode * block)
00612 {
00613
00614
00615 for (stmt_list_p p = block->stmts().begin();
00616 p != block->stmts().end();
00617 ++p)
00618 {
00619 callNode * Phi = phi(*p);
00620 idNode * id = lhs(*p);
00621
00622 if (Phi && id && (id->decl() == d))
00623 return false;
00624 }
00625
00626 place_one_phi(d, block);
00627
00628 return true;
00629 }
00630