00001
00023
00024
00025 #ifdef NO_STD_CHEADERS
00026 # include <stdlib.h>
00027 # include <string.h>
00028 # include <assert.h>
00029 #else
00030 # include <cstdlib>
00031 # include <cstring>
00032 # include <cassert>
00033 using namespace std;
00034 #endif
00035
00036 #include <iostream>
00037 using std::ostream;
00038 using std::endl;
00039 using std::cout;
00040 using std::cerr;
00041
00042
00043 #include "CFG.hpp"
00044
00045 namespace OA {
00046 namespace CFG {
00047
00048
00049
00050 NodesIterator::NodesIterator(OA_ptr<DGraph::NodesIteratorInterface> ni)
00051 : DGraph::NodesIteratorImplement(ni) {
00052 }
00053
00054
00055
00056 CFG::CFG()
00057 {
00058 }
00059
00060 OA_ptr<NodeInterface> NodesIterator::currentCFGNode() const
00061 {
00062 return current().convert<Node>();
00063 }
00064
00065 OA_ptr<EdgeInterface> EdgesIterator::currentCFGEdge() const
00066 {
00067 return current().convert<Edge>();
00068 }
00069
00070 Node::~Node()
00071 {
00072 mStmt_list->clear();
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 unsigned int Node::size() const
00133 {
00134 return mStmt_list->size();
00135 }
00136
00137 void Node::add(StmtHandle h)
00138 {
00139 mStmt_list->push_back(h);
00140 }
00141
00142 void Node::add_front(StmtHandle h)
00143 {
00144 mStmt_list->push_front(h);
00145 }
00146
00151 StmtHandle Node::erase(StmtHandle h)
00152 {
00153 std::list<StmtHandle>::iterator it;
00154 for (it = mStmt_list->begin(); (it != mStmt_list->end()); ++it) {
00155 StmtHandle stmt = *it;
00156 if (stmt == h) {
00157 mStmt_list->erase(it);
00158 return h;
00159 }
00160 }
00161 return 0;
00162 }
00163
00164
00165 bool Node::empty() const
00166 {
00167 return mStmt_list->empty();
00168 }
00169
00170
00171 OA_ptr<NodeStatementsIteratorInterface>
00172 Node::getNodeStatementsIterator() const
00173 {
00174 OA_ptr<NodeStatementsIterator> retval;
00175 retval = new NodeStatementsIterator(*this);
00176 return retval;
00177 }
00178
00179
00180
00181 OA_ptr<NodeStatementsRevIteratorInterface>
00182 Node::getNodeStatementsRevIterator() const
00183 {
00184 OA_ptr<NodeStatementsRevIterator> retval;
00185 retval = new NodeStatementsRevIterator(*this);
00186 return retval;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 OA_ptr<EdgesIteratorInterface> Node::getCFGIncomingEdgesIterator() const
00222 {
00223 OA_ptr<EdgesIterator> retval;
00224 retval = new EdgesIterator(getIncomingEdgesIterator());
00225 return retval;
00226
00227 }
00228
00229 OA_ptr<EdgesIteratorInterface> Node::getCFGOutgoingEdgesIterator() const
00230 {
00231 OA_ptr<EdgesIterator> retval;
00232 retval = new EdgesIterator(getOutgoingEdgesIterator());
00233 return retval;
00234
00235 }
00236
00237 OA_ptr<NodesIteratorInterface> Node::getCFGSourceNodesIterator() const
00238 {
00239 OA_ptr<NodesIterator> retval;
00240 retval = new NodesIterator(getSourceNodesIterator());
00241 return retval;
00242
00243 }
00244
00245 OA_ptr<NodesIteratorInterface> Node::getCFGSinkNodesIterator() const
00246 {
00247 OA_ptr<NodesIterator> retval;
00248 retval = new NodesIterator(getSinkNodesIterator());
00249 return retval;
00250
00251 }
00252
00253
00254 OA_ptr<NodesIteratorInterface> Node::getCFGPredNodesIterator() const
00255 {
00256 OA_ptr<NodesIterator> retval;
00257 retval = new NodesIterator(getSourceNodesIterator());
00258 return retval;
00259
00260 }
00261
00262 OA_ptr<NodesIteratorInterface> Node::getCFGSuccNodesIterator() const
00263 {
00264 OA_ptr<NodesIterator> retval;
00265 retval = new NodesIterator(getSinkNodesIterator());
00266 return retval;
00267
00268 }
00269
00270
00271 Node::Node() { Ctor(); }
00272
00273 Node::Node(StmtHandle n)
00274 { Ctor(); mStmt_list->push_back(n); }
00275
00276
00277 void Node::dump(std::ostream& os) {
00278
00279
00280
00281
00282
00283
00284 }
00285
00286
00287
00288 void Node::Ctor()
00289 {
00290
00291 mStmt_list = new std::list<StmtHandle>;
00292 }
00293
00294
00295 std::list<StmtHandle>::iterator Node::getStmtListBegin ()
00296 {
00297 return mStmt_list->begin();
00298 }
00299
00300 std::list<StmtHandle>::iterator Node::getStmtListEnd ()
00301 {
00302 return mStmt_list->end();
00303 }
00304
00305 std::list<StmtHandle>::reverse_iterator Node::getStmtListRBegin ()
00306 {
00307 return mStmt_list->rbegin();
00308 }
00309
00310 std::list<StmtHandle>::reverse_iterator Node::getStmtListREnd ()
00311 {
00312 return mStmt_list->rend();
00313 }
00314
00317 Edge::Edge(OA_ptr<DGraph::NodeInterface> source,
00318 OA_ptr<DGraph::NodeInterface> sink, EdgeType _type,
00319 OA::ExprHandle _expr) : DGraph::EdgeImplement (source, sink), mType(_type), mExpr(_expr)
00320 {
00321 }
00322
00323
00324 Edge::~Edge()
00325 {
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 OA_ptr<NodeInterface> Edge::getCFGSource() const
00341 {
00342 return getSource().convert<NodeInterface>();
00343 }
00344
00345 OA_ptr<NodeInterface> Edge::getCFGSink() const
00346 {
00347 return getSink().convert<NodeInterface>();
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 EdgeType Edge::getType() const
00368 {
00369 return mType;
00370 }
00371
00372 ExprHandle Edge::getExpr() const
00373 {
00374 return mExpr;
00375 }
00376
00377
00378 const char *Edge::sEdgeTypeToString[] = {
00379 "TRUE_EDGE", "FALLTHROUGH_EDGE", "FALSE_EDGE",
00380 "BACK_EDGE", "MULTIWAY_EDGE", "BREAK_EDGE",
00381 "CONTINUE_EDGE", "RETURN_EDGE"
00382 };
00383
00384
00385
00386
00387
00388
00389
00390 void Edge::setType(EdgeType type)
00391 {
00392 mType = type;
00393 }
00394
00395 void Edge::setExpr(ExprHandle expr)
00396 {
00397 mExpr = expr;
00398 }
00399
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 OA_ptr<NodeInterface> CFG::getEntry() const
00411 {
00412 return mEntry;
00413 }
00414
00415 OA_ptr<NodeInterface> CFG::getExit() const
00416 {
00417 return mExit;
00418 }
00419
00420 SymHandle CFG::getName() const
00421 {
00422 return mName;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 OA_ptr<NodesIteratorInterface> CFG::getCFGNodesIterator() const
00463 {
00464 OA_ptr<NodesIterator> retval;
00465 retval = new NodesIterator(getNodesIterator());
00466 return retval;
00467 }
00468
00469
00470 OA_ptr<EdgesIteratorInterface> CFG::getCFGEdgesIterator() const
00471 {
00472 OA_ptr<EdgesIterator> retval;
00473 retval = new EdgesIterator(getEdgesIterator());
00474 return retval;
00475 }
00476
00477
00478 OA_ptr<NodesIteratorInterface> CFG::getCFGEntryNodesIterator() const
00479 {
00480 OA_ptr<NodesIterator> retval;
00481 retval = new NodesIterator(getEntryNodesIterator());
00482 return retval;
00483 }
00484
00485 OA_ptr<NodesIteratorInterface> CFG::getCFGExitNodesIterator() const
00486 {
00487 OA_ptr<NodesIterator> retval;
00488 retval = new NodesIterator(getExitNodesIterator());
00489 return retval;
00490 }
00491
00492 OA_ptr<NodesIteratorInterface>
00493 CFG::getCFGReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient)
00494 {
00495 OA_ptr<NodesIterator> retval;
00496 retval = new NodesIterator(getReversePostDFSIterator(pOrient));
00497 return retval;
00498 }
00499
00500
00501 OA_ptr<NodesIteratorInterface> CFG::getCFGDFSIterator(OA_ptr<NodeInterface> n)
00502 {
00503 OA_ptr<NodesIterator> retval;
00504 retval = new NodesIterator(getDFSIterator(n));
00505 return retval;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 void CFG::setEntry(OA_ptr<Node> n)
00529 {
00530 mEntry = n;
00531 }
00532
00533 void CFG::setExit(OA_ptr<Node> n)
00534 {
00535 mExit = n;
00536 }
00537
00538
00539 OA_ptr<Edge> CFG::connect(OA_ptr<NodeInterface> src,
00540 OA_ptr<NodeInterface> dst,
00541 EdgeType type)
00542 {
00543 OA_ptr<Edge> e;
00544 e = new Edge (src, dst, type, 0);
00545 addEdge (e);
00546 return e;
00547 }
00548
00549 OA_ptr<Edge> CFG::connect(OA_ptr<NodeInterface> src,
00550 OA_ptr<NodeInterface> dst,
00551 EdgeType type, ExprHandle expr)
00552 {
00553 OA_ptr<Edge> e;
00554 e = new Edge (src, dst, type, expr);
00555 addEdge (e);
00556 return e;
00557 }
00558
00559 void CFG::disconnect(OA_ptr<EdgeInterface> e)
00560 {
00561 removeEdge(e);
00562 }
00563
00564 void CFG::disconnect(OA_ptr<NodeInterface> n)
00565 {
00566 removeNode(n);
00567 }
00568
00569 void CFG::mapLabelToNode(OA::StmtLabel lab, OA_ptr<Node> n)
00570 {
00571 mlabel_to_node_map[lab] = n;
00572 }
00573
00574
00576 bool CFG::isLabelMappedToNode(StmtLabel lab)
00577 {
00578 return (mlabel_to_node_map.find(lab) != mlabel_to_node_map.end()) ? true: false;
00579 }
00580
00581 void NodeStatementsIterator::operator++()
00582 {
00583 if (mIter != mList->end())
00584 {
00585 mIter++;
00586 }
00587 }
00588
00589 void NodeStatementsIterator::operator++(int)
00590 {
00591 ++*this;
00592 }
00593
00594
00595 bool NodeStatementsIterator::isValid() const
00596 {
00597 return (mIter != mList->end());
00598 }
00599
00600
00601 StmtHandle NodeStatementsIterator::current() const
00602 {
00603 return *mIter;
00604 }
00605
00606 void NodeStatementsIterator::reset()
00607 {
00608 mIter = mList->begin();
00609 }
00610
00611 void NodeStatementsRevIterator::operator++()
00612 {
00613 if (mRevIter != mList->rend())
00614 ++mRevIter;
00615 }
00616
00617 void NodeStatementsRevIterator::operator++(int)
00618 {
00619 ++*this;
00620 }
00621
00622
00623 bool NodeStatementsRevIterator::isValid() const
00624 {
00625 return (mRevIter != mList->rend());
00626 }
00627
00628
00629 StmtHandle NodeStatementsRevIterator::current() const
00630 {
00631 return *mRevIter;
00632 }
00633
00634
00635 void NodeStatementsRevIterator::reset()
00636 {
00637 mRevIter = mList->rbegin();
00638 }
00639
00640 OA_ptr<Node> CFG::NodeLabel::getNode()
00641 {
00642 return mN;
00643 }
00644
00645 EdgeType CFG::NodeLabel::getEdgeType()
00646 {
00647 return mEt;
00648 }
00649
00650 OA::ExprHandle CFG::NodeLabel::getExpr()
00651 {
00652 return mEh;
00653 }
00654
00655 void CFG::NodeLabelListIterator::operator++()
00656 {
00657 if (mIter != mList.end()) ++mIter;
00658 }
00659
00660 void CFG::NodeLabelListIterator::operator++(int)
00661 {
00662 ++*this;
00663 }
00664
00665 bool CFG::NodeLabelListIterator::isValid() const
00666 {
00667 return (mIter != mList.end());
00668 }
00669
00670 CFG::NodeLabel CFG::CFG::NodeLabelListIterator::current() const
00671 {
00672 return *mIter;
00673 }
00674
00675
00676
00677
00678
00679 const char* Edge::edgeTypeToString(EdgeType et) const
00680 {
00681 return sEdgeTypeToString[et];
00682 }
00683
00684 void Edge::dump (ostream& os)
00685 {
00692 }
00693
00694 void Edge::output(IRHandlesIRInterface& ir)
00695 {
00696 std::ostringstream label;
00697 label << "{ "
00698 << edgeTypeToString(mType) << " "
00699 << mExpr << " }";
00700 sOutBuild->outputString( label.str() );
00701 }
00702
00703
00712
00713
00714
00715
00716 CFG::~CFG()
00720 {
00721
00722
00723 mEntry = NULL;
00724 mExit = NULL;
00725 mlabel_to_node_map.clear();
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00744
00745
00746
00747
00748
00749
00750
00751
00752
00758 OA_ptr<Node> CFG::getLabelBlock(OA::StmtLabel lab)
00759 {
00760 OA_ptr<Node> retval; retval = 0;
00761
00762 if (mlabel_to_node_map.find(lab) != mlabel_to_node_map.end()) {
00763 retval = mlabel_to_node_map[lab];
00764 }
00765 return retval;
00766 }
00767
00768
00774 OA_ptr<Node> CFG::node_from_label (OA::StmtLabel lab)
00775 {
00776 OA_ptr<Node> node; node = 0;
00777 if (mlabel_to_node_map.find(lab) != mlabel_to_node_map.end()) {
00778
00779 node = mlabel_to_node_map[lab];
00780 }
00781 else {
00782
00783 node = new Node();
00784 addNode(node);
00785 mlabel_to_node_map[lab] = node;
00786 }
00787 return node;
00788 }
00789
00790
00791
00792
00797 void Node::split(OA::StmtHandle splitPoint, OA_ptr<Node> newBlock)
00798 {
00799 std::list<StmtHandle>::iterator splitPointIter;
00800 std::list<StmtHandle> tempList;
00801 std::list<StmtHandle>::iterator tempIter;
00802
00803 for (splitPointIter = mStmt_list->begin();
00804 (splitPointIter != mStmt_list->end() && *splitPointIter != splitPoint);
00805 ++splitPointIter) {
00806 }
00807
00808
00809
00810 tempList.splice(tempList.end(), *mStmt_list, splitPointIter, mStmt_list->end());
00811
00812
00813
00814 for (tempIter=tempList.begin(); tempIter != tempList.end(); tempIter++) {
00815 newBlock->add(*tempIter);
00816 }
00817 }
00818
00819
00830 OA_ptr<Node>
00831 CFG::splitBlock (OA_ptr<Node> block, StmtHandle splitPoint)
00832 {
00833
00834
00835
00836 OA_ptr<Node> newBlock; newBlock = new Node;
00837 addNode(newBlock);
00838
00839
00840
00841 block->split((StmtHandle)splitPoint, newBlock);
00842
00843
00844 std::list<OA_ptr<EdgeInterface> > del_list;
00845
00846
00847 for (OA_ptr<EdgesIteratorInterface> ei = block->getCFGOutgoingEdgesIterator();
00848 ei->isValid(); ++(*ei))
00849 {
00850
00851 OA_ptr<EdgeInterface> edge
00852 = ei->currentCFGEdge();
00853 OA_ptr<NodeInterface> targBlock
00854 = edge->getCFGSink();
00855
00856 connect(newBlock, targBlock, edge->getType(), edge->getExpr());
00857 del_list.push_back(edge);
00858
00859
00860
00861 }
00862
00863
00864 std::list<OA_ptr<EdgeInterface> >::iterator dli = del_list.begin();
00865 for ( ; dli != del_list.end(); dli++) {
00866 disconnect(*dli);
00867 }
00868
00869 #if 0 // FIXME: Splitting won't change any label's block??
00870
00871 for (NodeStatementsIterator si(newBlock); (StmtHandle)si; ++si) {
00872 StmtHandle stmt = (StmtHandle)si;
00873 if (ir->GetLabel(stmt) != 0) {
00874 label_to_node_map.erase(ir->GetLabel(stmt));
00875 label_to_node_map[ir->GetLabel(stmt)] = newBlock;
00876 }
00877 }
00878 #endif
00879
00880 return newBlock;
00881 }
00882
00883
00885 void
00886 CFG::connect (OA_ptr<NodeInterface> src,
00887 CFG::NodeLabelList& dst_list)
00888 {
00889 CFG::NodeLabelListIterator dst_list_iter(dst_list);
00890 while (dst_list_iter.isValid()) {
00891 NodeLabel nl = dst_list_iter.current();
00892 connect(src, nl.getNode(), nl.getEdgeType(), nl.getExpr());
00893 ++dst_list_iter;
00894 }
00895 }
00896
00897
00899 void
00900 CFG::connect (CFG::NodeLabelList& src_list,
00901 OA_ptr<NodeInterface> dst)
00902 {
00903 NodeLabelListIterator src_list_iter(src_list);
00904 while (src_list_iter.isValid()) {
00905 NodeLabel nl = src_list_iter.current();
00906 connect(nl.getNode(), dst, nl.getEdgeType(), nl.getExpr());
00907 ++src_list_iter;
00908 }
00909 }
00910
00912 void
00913 CFG::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00914 {
00933 }
00934
00935 void
00936 Node::dump (ostream& os, OA_ptr<IRHandlesIRInterface> rir)
00937 {
00977 }
00978
00979
00980
00981
00982
00983
01044
01045
01046
01047
01048
01069
01070
01071
01072
01073
01074
01075
01096
01097
01098
01099 void Node::output(OA::IRHandlesIRInterface& ir)
01100 {
01101 std::ostringstream label;
01102
01103 label << "====== CFG node " << getId() << " ======\n";
01104
01105
01106
01107 NodeStatementsIterator stmtIt(*this);
01108 for ( ; stmtIt.isValid(); ++stmtIt) {
01109 StmtHandle s = stmtIt.current();
01110 label << ir.toString(s) + "\n";
01111 }
01112
01113 sOutBuild->outputString(label.str());
01114 }
01115
01116 void Edge::dumpdot(ostream& os, OA_ptr<IRHandlesIRInterface> ir)
01117 {
01122 }
01123
01124
01125
01126 }
01127 }