00001
00015
00016
00017 #ifdef NO_STD_CHEADERS
00018 # include <stdlib.h>
00019 # include <string.h>
00020 # include <assert.h>
00021 #else
00022 # include <cstdlib>
00023 # include <cstring>
00024 # include <cassert>
00025 using namespace std;
00026 #endif
00027
00028 #include <iostream>
00029 using std::ostream;
00030 using std::endl;
00031 using std::cout;
00032 using std::cerr;
00033 #include <list>
00034 #include <set>
00035 #include <map>
00036
00037
00038 #include "ManagerCFG.hpp"
00039
00040
00041 namespace OA {
00042 namespace CFG {
00043
00044 static bool debug = false;
00045
00046 ManagerCFGStandard::ManagerCFGStandard (OA_ptr<CFGIRInterface> _ir,
00047 bool _build_stmt_level_cfg )
00048 : mIR(_ir), mBuildStmtLevelCFG(_build_stmt_level_cfg)
00049 {
00050
00051
00052 OA_DEBUG_CTRL_MACRO("DEBUG_ManagerCFG:ALL", debug);
00053 mFallThrough.clear();
00054 }
00055
00056
00057 OA_ptr<CFG::CFG> ManagerCFGStandard::performAnalysis(ProcHandle proc)
00058 {
00059
00060 bool return_statements_allowed = mIR->returnStatementsAllowed();
00061
00062 mCFG = new CFG();
00063 OA_ptr<NodesIteratorInterface> nodes_iter;
00064
00065 OA_ptr<Node> entry;
00066 entry = new Node();
00067 mCFG->setEntry(entry);
00068 mCFG->addNode(entry);
00069
00070
00071 OA_ptr<Node> r; r = new Node();
00072 mCFG->addNode(r);
00073 mCFG->connect (mCFG->getEntry(), r, FALLTHROUGH_EDGE);
00074 CFG::NodeLabelList exit_nodes;
00075
00076
00077 OA_ptr<CFG::NodeLabelList> return_nodes;
00078 return_nodes = new CFG::NodeLabelList;
00079 OA_ptr<IRRegionStmtIterator> stmt_iterptr = mIR->procBody(proc);
00080 OA_ptr<CFG::NodeLabelList> nullList; nullList = NULL;
00081
00082 if (return_statements_allowed) {
00083 build_block(r, stmt_iterptr, exit_nodes, nullList, return_nodes, nullList);
00084 } else {
00085 build_block(r, stmt_iterptr, exit_nodes, nullList, nullList, nullList);
00086 }
00087
00088
00089 OA_ptr<Node> final; final = new Node();
00090 mCFG->addNode(final);
00091 mCFG->setExit(final);
00092
00093 mCFG->connect(exit_nodes, final);
00094
00095 mCFG->connect(*return_nodes, final);
00096
00097 HandleDelayedBranches();
00098 return mCFG;
00099
00100 }
00101
00102
00103
00104 IRStmtType
00105 ManagerCFGStandard::build_block (OA_ptr<Node> prev_node,
00106 OA_ptr<IRRegionStmtIterator> si_ptr,
00107 std::list<CFG::NodeLabel>& exit_nodes,
00108 OA_ptr<std::list<CFG::NodeLabel> > break_nodes,
00109 OA_ptr<std::list<CFG::NodeLabel> > return_nodes,
00110 OA_ptr<std::list<CFG::NodeLabel> > continue_nodes)
00111 {
00112 std::list<CFG::NodeLabel> x_nodes;
00113
00114 IRStmtType prev_statement = SIMPLE;
00115 while (si_ptr->isValid()) {
00116 StmtHandle stmt = si_ptr->current();
00117 if (debug) { std::cout << mIR->toString(stmt) << std::endl; }
00118
00119 if (mIR->getLabel(stmt)) {
00120 StmtLabel lab = mIR->getLabel(stmt);
00121 OA_ptr<Node> new_node;
00122
00123 if (mCFG->isLabelMappedToNode(lab)) {
00124 new_node = mCFG->node_from_label(lab);
00125 } else if (! prev_node->empty()) {
00126 new_node = new Node();
00127 mCFG->addNode(new_node);
00128 if(debug) {
00129 cout << "\nCFG Node";
00130 new_node->dump(cout , mIR);
00131 cout << "\n";
00132 }
00133 mCFG->mapLabelToNode(lab,new_node);
00134
00135 } else {
00136 mCFG->mapLabelToNode(lab,prev_node);
00137 new_node = prev_node;
00138 }
00139
00140 if (prev_statement != SIMPLE && !new_node.ptrEqual(prev_node)) {
00141 mCFG->connect(x_nodes, new_node);
00142 } else if (!prev_node.ptrEqual(NULL)
00143 && !new_node.ptrEqual(prev_node))
00144 {
00145 mCFG->connect(prev_node, new_node, FALLTHROUGH_EDGE);
00146 }
00147 x_nodes.clear();
00148 prev_node = new_node;
00149
00150
00151 } else if (mBuildStmtLevelCFG) {
00152 if (!prev_node->empty()) {
00153 OA_ptr<Node> new_node;
00154 new_node = new Node();
00155 mCFG->addNode(new_node);
00156 if(debug) {
00157 cout << "\n CFG Node";
00158 new_node->dump(cout , mIR);
00159 cout << "\n";
00160 }
00161
00162
00163 if (prev_statement == SIMPLE) {
00164 mCFG->connect(prev_node, new_node, FALLTHROUGH_EDGE);
00165 } else {
00166 mCFG->connect(x_nodes, new_node);
00167 }
00168 prev_node = new_node;
00169 }
00170 x_nodes.clear();
00171
00172 } else if (prev_statement != SIMPLE) {
00173
00174 prev_node = new Node();
00175 mCFG->addNode(prev_node);
00176 if(debug) {
00177 cout << "\n CFG Node";
00178 prev_node->dump(cout , mIR);
00179 cout << "\n";
00180 }
00181
00182
00183 mCFG->connect(x_nodes, prev_node);
00184 x_nodes.clear();
00185 }
00186 prev_statement = build_stmt(prev_node, stmt, x_nodes, break_nodes,
00187 return_nodes, continue_nodes);
00188 ++(*si_ptr);
00189 }
00190
00191
00192 if (prev_statement == SIMPLE) {
00193 exit_nodes.push_back(CFG::NodeLabel(prev_node,
00194 FALLTHROUGH_EDGE));
00195 } else {
00196 CFG::NodeLabelListIterator x_nodes_iter(x_nodes);
00197 while (x_nodes_iter.isValid()) {
00198 exit_nodes.push_back(x_nodes_iter.current());
00199 ++x_nodes_iter;
00200 }
00201 }
00202
00203 return NONE;
00204 }
00205
00206
00207
00220 IRStmtType
00221 ManagerCFGStandard::build_stmt (OA_ptr<Node> prev_node,
00222 OA::StmtHandle stmt,
00223 std::list<CFG::NodeLabel>& exit_nodes,
00224 OA_ptr<std::list<CFG::NodeLabel> > break_nodes,
00225 OA_ptr<std::list<CFG::NodeLabel> > return_nodes,
00226 OA_ptr<std::list<CFG::NodeLabel> > continue_nodes)
00227 {
00228 switch (mIR->getCFGStmtType(stmt)) {
00229 case SIMPLE:
00230 {
00231 prev_node->add(stmt);
00232 if (debug) { std::cout << mIR->toString(stmt) << std::endl; }
00233 return SIMPLE;
00234 }
00235 case COMPOUND:
00236 {
00237 build_block(prev_node, mIR->getFirstInCompound(stmt), exit_nodes,
00238 break_nodes, return_nodes, continue_nodes);
00239 return COMPOUND;
00240 }
00241 case BREAK:
00242 {
00243 prev_node->add(stmt);
00244 if (break_nodes.ptrEqual(0)) {
00245
00246 } else {
00247 break_nodes->push_back(CFG::NodeLabel(prev_node,
00248 BREAK_EDGE));
00249 }
00250 return BREAK;
00251 }
00252 case RETURN:
00253 {
00254 prev_node->add(stmt);
00255 if (return_nodes.ptrEqual(0)) {
00256
00257 } else {
00258 return_nodes->push_back(CFG::NodeLabel(prev_node,
00259 RETURN_EDGE));
00260 }
00261 return RETURN;
00262 }
00263 case LOOP:
00264 {
00265 return build_CFG_loop (prev_node, stmt, exit_nodes, return_nodes);
00266 }
00267
00268 case STRUCT_TWOWAY_CONDITIONAL:
00269 {
00270 return build_CFG_twoway_branch (prev_node, stmt, exit_nodes, break_nodes,
00271 return_nodes, continue_nodes);
00272 }
00273
00274 case STRUCT_MULTIWAY_CONDITIONAL:
00275 {
00276 if (mIR->isBreakImplied(stmt)) {
00277 return build_CFG_multiway_branch (prev_node, stmt, exit_nodes,
00278 break_nodes, return_nodes,
00279 continue_nodes);
00280 }else {
00281 return build_CFG_multiway_branch_with_fallthrough (prev_node, stmt, exit_nodes, return_nodes, continue_nodes);
00282 }
00283
00284 }
00285
00286 case END_TESTED_LOOP:
00287 {
00288 return build_CFG_end_tested_loop (prev_node, stmt, exit_nodes, return_nodes);
00289 }
00290
00291 case LOOP_CONTINUE:
00292 {
00293 prev_node->add(stmt);
00294 if (continue_nodes.ptrEqual(0)) {
00295
00296 } else {
00297 continue_nodes->push_back(CFG::NodeLabel(prev_node,
00298 CONTINUE_EDGE));
00299 }
00300 return LOOP_CONTINUE;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 case UNCONDITIONAL_JUMP:
00310 {
00311 if (mIR->numberOfDelaySlots(stmt) == 0) {
00312 return build_CFG_unconditional_jump (prev_node, stmt);
00313 } else {
00314 prev_node->add(stmt);
00315 return SIMPLE;
00316 }
00317 }
00318 case USTRUCT_TWOWAY_CONDITIONAL_T:
00319 case USTRUCT_TWOWAY_CONDITIONAL_F:
00320 {
00321 if (mIR->numberOfDelaySlots(stmt) == 0) {
00322 return build_CFG_ustruct_twoway_branch (prev_node, stmt, exit_nodes);
00323 } else {
00324 prev_node->add(stmt);
00325 return SIMPLE;
00326 }
00327 }
00328 case UNCONDITIONAL_JUMP_I:
00329 {
00330 if (mIR->numberOfDelaySlots(stmt) == 0) {
00331 return build_CFG_unconditional_jump_i (prev_node, stmt);
00332 } else {
00333 prev_node->add(stmt);
00334 return SIMPLE;
00335 }
00336 }
00337 case USTRUCT_MULTIWAY_CONDITIONAL:
00338 {
00339
00340 assert(mIR->numberOfDelaySlots(stmt) == 0);
00341 return build_CFG_ustruct_multiway_branch (prev_node, stmt);
00342 }
00343
00344 case ALTERNATE_PROC_ENTRY:
00345 {
00346 cout << "FIXME: ALTERNATE_PROC_ENTRY not yet implemented" << endl;
00347 assert (0);
00348 return ALTERNATE_PROC_ENTRY;
00349 }
00350 default:
00351 {
00352 assert (0);
00353 }
00354
00355
00356 }
00357 }
00358
00359
00360 IRStmtType
00361 ManagerCFGStandard::build_CFG_loop(OA_ptr<Node> prev_node,
00362 StmtHandle th,
00363 std::list<CFG::NodeLabel>& exit_nodes,
00364 OA_ptr<std::list<CFG::NodeLabel> > return_nodes)
00365 {
00366
00367
00368
00369
00370 OA_ptr<Node> c;
00371
00372 StmtHandle header = mIR->loopHeader(th);
00373 if (header) {
00374 prev_node->add(header);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 bool definedAtEntry = mIR->loopIterationsDefinedAtEntry(th);
00394 if (definedAtEntry) {
00395 prev_node->add(th);
00396 }
00397 if (prev_node->empty()) {
00398 prev_node->add(th);
00399 c = prev_node;
00400 }
00401 else {
00402 c = new Node(th);
00403 mCFG->addNode(c);
00404 mCFG->connect(prev_node, c, FALLTHROUGH_EDGE);
00405 }
00406 exit_nodes.push_back(CFG::NodeLabel(c, FALSE_EDGE));
00407
00408
00409 std::list<CFG::NodeLabel> x_nodes;
00410 OA_ptr<IRRegionStmtIterator> body = mIR->loopBody(th);
00411 if (body->isValid() && body->current()) {
00412 OA_ptr<Node> b;
00413 b = new Node();
00414 mCFG->addNode(b);
00415
00416 if(debug)
00417 {
00418 cout << "\n CFG Node";
00419 b->dump(cout , mIR);
00420 cout << "\n";
00421 }
00422
00423
00424
00425
00426 OA_ptr<std::list<CFG::NodeLabel> > break_statements, continue_statements;
00427 break_statements = new std::list<CFG::NodeLabel>;
00428 continue_statements = new std::list<CFG::NodeLabel>;
00429 if (build_block(b, body, x_nodes, break_statements, return_nodes,
00430 continue_statements) == SIMPLE)
00431 {
00432 x_nodes.push_back(CFG::NodeLabel(b, FALLTHROUGH_EDGE));
00433 }
00434
00435 mCFG->connect(c, b, TRUE_EDGE);
00436 CFG::NodeLabelListIterator break_iter(*break_statements);
00437 while (break_iter.isValid()) {
00438 exit_nodes.push_back(break_iter.current());
00439 ++break_iter;
00440 }
00441
00442 CFG::NodeLabelListIterator continue_iter(*continue_statements);
00443 while (continue_iter.isValid()) {
00444 x_nodes.push_back(continue_iter.current());
00445 ++continue_iter;
00446 }
00447 } else {
00448 x_nodes.push_back(CFG::NodeLabel(c, TRUE_EDGE));
00449 }
00450
00451
00452 StmtHandle incr = mIR->getLoopIncrement(th);
00453 if (incr) {
00454 OA_ptr<Node> li;
00455 li = new Node(incr);
00456 mCFG->addNode(li);
00457 mCFG->connect(x_nodes, li);
00458 mCFG->connect(li, c, FALLTHROUGH_EDGE);
00459 }
00460 else {
00461 mCFG->connect(x_nodes, c);
00462 }
00463
00464 return LOOP;
00465
00466
00467 }
00468
00469
00470
00493 IRStmtType
00494 ManagerCFGStandard::build_CFG_twoway_branch (OA_ptr<Node> prev_node,
00495 StmtHandle th, std::list<CFG::NodeLabel>& exit_nodes,
00496 OA_ptr<std::list<CFG::NodeLabel> > break_nodes,
00497 OA_ptr<std::list<CFG::NodeLabel> > return_nodes,
00498 OA_ptr<std::list<CFG::NodeLabel> > continue_nodes)
00499 {
00500
00501 if(debug)
00502 {
00503 std::cout << "Inside CFG::build_CFG_twoway_branch" << endl;
00504 }
00505
00506
00507 prev_node->add(th);
00508
00509
00510 OA_ptr<Node> b;
00511 OA_ptr<IRRegionStmtIterator> true_body = mIR->trueBody(th);
00512 if (true_body->isValid() && true_body->current()) {
00513 b = new Node();
00514
00515 if(debug)
00516 {
00517 std::cout << "True branch" << std::endl;
00518 }
00519
00520 if(debug)
00521 {
00522 std::cout << "In CFG addNode" << std::endl;
00523 b->dump(cout , mIR);
00524 }
00525
00526 mCFG->addNode(b);
00527
00528 if(debug)
00529 {
00530 std::cout << "CFG addNode ends" << std::endl;
00531 }
00532
00533
00534 if (build_block(b, true_body, exit_nodes, break_nodes, return_nodes, continue_nodes) == SIMPLE)
00535 exit_nodes.push_back(CFG::NodeLabel(b, FALLTHROUGH_EDGE));
00536
00537 mCFG->connect(prev_node, b, TRUE_EDGE);
00538 }
00539 else {
00540
00541 b = 0;
00542 exit_nodes.push_back(CFG::NodeLabel(prev_node, TRUE_EDGE));
00543 }
00544
00545
00546 OA_ptr<IRRegionStmtIterator> false_body = mIR->elseBody(th);
00547 if (false_body->isValid() && false_body->current()) {
00548 OA_ptr<Node> c_body; c_body = new Node();
00549 if(debug)
00550 {
00551 std::cout << "false branch" << std::endl;
00552 }
00553
00554 if(debug)
00555 {
00556 std::cout << "In CFG addNode" << std::endl;
00557 c_body->dump(cout , mIR);
00558 }
00559
00560 mCFG->addNode(c_body);
00561
00562 if(debug)
00563 {
00564 std::cout << "CFG addNode ends" << std::endl;
00565 }
00566
00567
00568 if (build_block(c_body, false_body, exit_nodes, break_nodes, return_nodes, continue_nodes) == SIMPLE)
00569 exit_nodes.push_back(CFG::NodeLabel(c_body, FALLTHROUGH_EDGE));
00570
00571 mCFG->connect(prev_node, c_body, FALSE_EDGE);
00572 }
00573 else if (!b.ptrEqual(0))
00574 exit_nodes.push_back(CFG::NodeLabel(prev_node, FALSE_EDGE));
00575
00576 return STRUCT_TWOWAY_CONDITIONAL;
00577
00578 if(debug)
00579 {
00580 std::cout << "***** CFG::build_CFG_twoway_branch *****" << endl;
00581 }
00582
00583 }
00584
00585
00586
00608 IRStmtType
00609 ManagerCFGStandard::build_CFG_multiway_branch (OA_ptr<Node> prev_node,
00610 StmtHandle th, std::list<CFG::NodeLabel>& exit_nodes,
00611 OA_ptr<std::list<CFG::NodeLabel> > break_nodes,
00612 OA_ptr<std::list<CFG::NodeLabel> > return_nodes,
00613 OA_ptr<std::list<CFG::NodeLabel> > continue_nodes)
00614 {
00615
00616
00617 prev_node->add(th);
00618
00619 bool direct_drop = false;
00620 bool default_cond = false;
00621
00622
00623 for (int bridx = 0; bridx < mIR->numMultiCases(th); bridx++) {
00624 OA_ptr<IRRegionStmtIterator> body = mIR->multiBody(th, bridx);
00625
00626
00627
00628 if (body->isValid() && body->current()) {
00629 OA_ptr<Node> c; c = new Node();
00630 mCFG->addNode(c);
00631
00632 if(debug)
00633 {
00634 cout << "\n build_CFG_multiway_branch CFG Node";
00635 c->dump(cout , mIR);
00636 cout << "\n";
00637 }
00638
00639
00640 if (build_block(c, body, exit_nodes, break_nodes, return_nodes, continue_nodes) == SIMPLE)
00641 {
00642 exit_nodes.push_back(CFG::NodeLabel(c, FALLTHROUGH_EDGE));
00643 }
00644
00645
00646 if (mIR->isCatchAll(th,bridx)) {
00647 default_cond = true;
00648 mCFG->connect(prev_node, c, MULTIWAY_EDGE);
00649 } else {
00650 ExprHandle multiCond = mIR->getSMultiCondition(th, bridx);
00651 mCFG->connect(prev_node, c, MULTIWAY_EDGE, multiCond);
00652 }
00653
00654
00655 } else {
00656 direct_drop = true;
00657 }
00658
00659 }
00660
00661
00662 if (default_cond == false) {
00663 direct_drop = true;
00664 }
00665
00666
00667 if (direct_drop) {
00668 exit_nodes.push_back(CFG::NodeLabel(prev_node, FALLTHROUGH_EDGE));
00669 }
00670
00671 return STRUCT_MULTIWAY_CONDITIONAL;
00672
00673 }
00674
00675
00676
00677
00678
00679
00697 IRStmtType
00698 ManagerCFGStandard::build_CFG_multiway_branch_with_fallthrough (
00699 OA_ptr<Node> prev_node,
00700 StmtHandle th, std::list<CFG::NodeLabel>& exit_nodes,
00701 OA_ptr<std::list<CFG::NodeLabel> > return_nodes,
00702 OA_ptr<std::list<CFG::NodeLabel> > continue_nodes)
00703 {
00704
00705
00706 prev_node->add(th);
00707
00708
00709 bool empty_cond = false;
00710 bool default_cond = false;
00711
00712
00713
00714
00715 OA_ptr<std::list<CFG::NodeLabel> > break_switch_statements;
00716 break_switch_statements = new std::list<CFG::NodeLabel>;
00717
00718
00719
00720
00721
00722
00723 OA_ptr<Node> prev_case_node;
00724 prev_case_node = 0;
00725 std::list<CFG::NodeLabel> case_exit_nodes;
00726
00727
00728 for (int bridx = 0; bridx < mIR->numMultiCases(th); bridx++) {
00729
00730 OA_ptr<IRRegionStmtIterator> body = mIR->multiBody(th, bridx);
00731
00732 OA_ptr<Node> c; c = new Node();
00733 mCFG->addNode(c);
00734
00735 if(debug)
00736 {
00737 cout << "\n Add CFG multiway branch with_Fallthrough CFG Node";
00738 c->dump(cout , mIR);
00739 cout << "\n";
00740 }
00741
00742
00743
00744 break_switch_statements->clear();
00745
00746
00747 if (!prev_case_node.ptrEqual(NULL)) {
00748 mCFG->connect(case_exit_nodes, c);
00749 case_exit_nodes.clear();
00750 prev_case_node = 0;
00751 }
00752
00753
00754 if (body->isValid() && body->current()) {
00755
00756
00757
00758
00759 IRStmtType prev_case_statement = build_block(c, body, case_exit_nodes,
00760 break_switch_statements,
00761 return_nodes, continue_nodes);
00762
00763
00764 if ( break_switch_statements->size() == 0 ) {
00765 prev_case_node = c;
00766 if (prev_case_statement == SIMPLE) {
00767 case_exit_nodes.push_back(CFG::NodeLabel(prev_case_node, FALLTHROUGH_EDGE));
00768 }
00769
00770
00771 } else {
00772 prev_case_node = 0;
00773
00774
00775 CFG::NodeLabelListIterator
00776 break_stmt_iter(*break_switch_statements);
00777 while (break_stmt_iter.isValid()) {
00778 exit_nodes.push_back(break_stmt_iter.current());
00779 ++break_stmt_iter;
00780 }
00781
00782
00783
00784
00785
00786 }
00787
00788
00789 } else {
00790 prev_case_node = c;
00791 case_exit_nodes.push_back(CFG::NodeLabel(prev_case_node, FALLTHROUGH_EDGE));
00792 }
00793
00794
00795 if (mIR->isCatchAll(th,bridx)) {
00796 default_cond = true;
00797 mCFG->connect(prev_node, c, MULTIWAY_EDGE);
00798 } else {
00799 ExprHandle multiCond = mIR->getSMultiCondition(th, bridx);
00800 mCFG->connect(prev_node, c, MULTIWAY_EDGE, multiCond);
00801 }
00802
00803 }
00804
00805
00806
00807 if (!prev_case_node.ptrEqual(NULL)) {
00808 exit_nodes.push_back(CFG::NodeLabel(prev_case_node, FALLTHROUGH_EDGE));
00809 }
00810
00811
00812 if ( !default_cond || empty_cond ) {
00813 exit_nodes.push_back(CFG::NodeLabel(prev_node, FALLTHROUGH_EDGE));
00814 }
00815
00816 return STRUCT_MULTIWAY_CONDITIONAL;
00817
00818 }
00819
00820
00821
00846 IRStmtType
00847 ManagerCFGStandard::build_CFG_end_tested_loop (OA_ptr<Node> prev_node,
00848 StmtHandle th, std::list<CFG::NodeLabel>& exit_nodes,
00849 OA_ptr<std::list<CFG::NodeLabel> > return_nodes)
00850 {
00851
00852
00853
00854 OA_ptr<Node> b; b = NULL;
00855 OA_ptr<Node> c; c = NULL;
00856
00857
00858 std::list<CFG::NodeLabel> x_nodes;
00859 OA_ptr<IRRegionStmtIterator> body = mIR->loopBody(th);
00860 if (body->isValid() && body->current()) {
00861 if (prev_node->empty()) {
00862 b = prev_node;
00863 } else {
00864 b = new Node();
00865 mCFG->addNode(b);
00866 mCFG->connect(prev_node, b, FALLTHROUGH_EDGE);
00867 }
00868 OA_ptr<std::list<CFG::NodeLabel> > break_statements, continue_statements;
00869 break_statements = new std::list<CFG::NodeLabel>;
00870 continue_statements = new std::list<CFG::NodeLabel>;
00871 if (build_block(b, body, x_nodes, break_statements, return_nodes, continue_statements) == SIMPLE) {
00872 x_nodes.push_back(CFG::NodeLabel(b, FALLTHROUGH_EDGE));
00873 }
00874
00875 CFG::NodeLabelListIterator break_iter(*break_statements);
00876 while (break_iter.isValid()) {
00877 exit_nodes.push_back(break_iter.current());
00878 ++break_iter;
00879 }
00880
00881 CFG::NodeLabelListIterator continue_iter(*continue_statements);
00882 while (continue_iter.isValid()) {
00883 x_nodes.push_back(continue_iter.current());
00884 ++continue_iter;
00885 }
00886 }
00887 else {
00888
00889 x_nodes.push_back(CFG::NodeLabel(c, TRUE_EDGE));
00890 }
00891
00892
00893 c = new Node(th);
00894 mCFG->addNode(c);
00895 exit_nodes.push_back(CFG::NodeLabel(c, FALSE_EDGE));
00896 mCFG->connect(c, b, TRUE_EDGE);
00897 mCFG->connect(x_nodes, c);
00898
00899 return END_TESTED_LOOP;
00900
00901 }
00902
00903 IRStmtType
00904 ManagerCFGStandard::build_CFG_unconditional_jump (
00905 OA_ptr<Node> prev_node,
00906 StmtHandle stmt)
00907 {
00908
00909 StmtLabel lab = mIR->getTargetLabel(stmt, 0);
00910 prev_node->add(stmt);
00911 mCFG->connect(prev_node, mCFG->node_from_label(lab), FALLTHROUGH_EDGE);
00912 return UNCONDITIONAL_JUMP;
00913 }
00914
00915
00916
00936 IRStmtType
00937 ManagerCFGStandard::build_CFG_ustruct_twoway_branch (OA_ptr<Node>
00938 prev_node, StmtHandle stmt, std::list<CFG::NodeLabel>& exit_nodes)
00939 {
00940
00941 StmtLabel lab = mIR->getTargetLabel(stmt, 0);
00942 bool branch_on_true = (mIR->getCFGStmtType(stmt) == USTRUCT_TWOWAY_CONDITIONAL_T);
00943 prev_node->add(stmt);
00944 mCFG->connect(prev_node, mCFG->node_from_label(lab), (branch_on_true ? TRUE_EDGE : FALSE_EDGE));
00945
00946
00947 exit_nodes.push_back(CFG::NodeLabel(prev_node, FALLTHROUGH_EDGE));
00948
00949 return mIR->getCFGStmtType(stmt);
00950 }
00951
00952
00953
00954
00977 IRStmtType
00978 ManagerCFGStandard::build_CFG_unconditional_jump_i (
00979 OA_ptr<Node> prev_node,
00980 StmtHandle stmt)
00981 {
00982
00983
00984
00985 cout << "FIXME: UNCONDITIONAL_JUMP_I not yet implemented" << endl;
00986 assert(0);
00987 return UNCONDITIONAL_JUMP_I;
00988 }
00989
00990
00991
00992
01020 IRStmtType
01021 ManagerCFGStandard::build_CFG_ustruct_multiway_branch (OA_ptr<Node>
01022 prev_node, StmtHandle stmt)
01023 {
01024
01025
01026
01027
01028 prev_node->add(stmt);
01029
01030
01031 for (int br = 0; br < mIR->numUMultiTargets(stmt); br++) {
01032 StmtLabel target_lab = mIR->getUMultiTargetLabel(stmt, br);
01033 ExprHandle cond_expr = mIR->getUMultiCondition(stmt, br);
01034 mCFG->connect(prev_node, mCFG->node_from_label(target_lab),
01035 MULTIWAY_EDGE, cond_expr );
01036 }
01037
01038
01039 StmtLabel default_lab = mIR->getUMultiCatchallLabel(stmt);
01040 if (default_lab) {
01041 mCFG->connect(prev_node, mCFG->node_from_label(default_lab),
01042 MULTIWAY_EDGE );
01043 }
01044
01045 return USTRUCT_MULTIWAY_CONDITIONAL;
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 void
01060 ManagerCFGStandard::HandleDelayedBranches ()
01061 {
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 createBasicCFG();
01076
01077 #if 0 // FIXME: Disabled until its fixed.
01078
01079
01080
01081
01082
01083
01084
01085 Counterlist* emptyCounterList = new Counterlist;
01086 the_worklist->copyCountersToWorklist(Entry(), emptyCounterList);
01087
01088 while (! the_worklist->isEmpty()) {
01089 for (i:NodesIterator nodes_iter(*this);
01090 (bool)nodes_iter && !the_worklist->isEmpty(); ++nodes_iter) {
01091 CFG::Node *node = dynamic_cast<CFG::Node*>((DGraph::Node*)nodes_iter);
01092 processBlock(node);
01093 }
01094 }
01095 #endif
01096 }
01097
01098
01099 void
01100 ManagerCFGStandard::createBasicCFG()
01101 {
01102
01103
01104 std::set<OA_ptr<Node> > block_list;
01105
01106 OA_ptr<DGraph::NodesIteratorInterface> nodes_iter = mCFG->getNodesIterator();
01107 for( ; nodes_iter->isValid(); ++(*nodes_iter))
01108 {
01109 OA_ptr<DGraph::NodeInterface> dnode = nodes_iter->current();
01110 OA_ptr<Node> node = dnode.convert<Node>();
01111
01116 block_list.insert(node);
01117 }
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 while (block_list.size() > 0) {
01129 bool branch_found = false;
01130 int countdown = 0;
01131 StmtHandle stmt = 0;
01132 OA_ptr<Node> node = *block_list.begin();
01133 int numRemoved = block_list.erase(node);
01134 assert(numRemoved > 0);
01135
01136
01137 NodeStatementsIterator si(*node);
01138 for ( ; si.isValid(); ++si) {
01139 stmt = si.current();
01140 IRStmtType ty = mIR->getCFGStmtType(stmt);
01141 assert(ty != UNCONDITIONAL_JUMP_I);
01142 if (ty == USTRUCT_TWOWAY_CONDITIONAL_T
01143 || ty == USTRUCT_TWOWAY_CONDITIONAL_F
01144 || ty == UNCONDITIONAL_JUMP) {
01145 branch_found = true;
01146 countdown = mIR->numberOfDelaySlots(stmt);
01147 break;
01148 }
01149 }
01150
01151
01152
01153
01154
01155 if (branch_found == true && countdown > 0) {
01156
01157 for ( ; si.isValid() && countdown > 0; ++si) {
01158
01159 --countdown;
01160 }
01161
01162
01163 if (countdown == 0) {
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 ++si;
01175 if (1 ) {
01176 StmtHandle val = (si.isValid()) ? si.current() : (StmtHandle)0;
01177 OA_ptr<Node> newnode = mCFG->splitBlock (node, val);
01178 mFallThrough[node] = newnode;
01179 block_list.insert(newnode);
01180 IRStmtType ty = mIR->getCFGStmtType(stmt);
01181 if (ty == USTRUCT_TWOWAY_CONDITIONAL_T
01182 || ty == USTRUCT_TWOWAY_CONDITIONAL_F) {
01183 mCFG->connect(node, mCFG->getLabelBlock(mIR->getTargetLabel(stmt, 0)),
01184 ty == USTRUCT_TWOWAY_CONDITIONAL_T ? TRUE_EDGE : FALSE_EDGE);
01185 mCFG->connect(node, newnode, FALLTHROUGH_EDGE);
01186 } else if (ty == UNCONDITIONAL_JUMP) {
01187 StmtLabel label = mIR->getTargetLabel(stmt, 0);
01188 OA_ptr<Node> nodeTmp = mCFG->getLabelBlock(label);
01189 mCFG->connect(node, nodeTmp, FALLTHROUGH_EDGE);
01190 } else {
01191 assert(0);
01192 }
01193 }
01194 }
01195
01196
01197 }
01198
01199 if (branch_found == false || countdown > 0) {
01200
01201
01202
01203 }
01204
01205
01206 }
01207 }
01208
01209
01210 }
01211 }