ICFG.cpp

Go to the documentation of this file.
00001 
00015 //--------------------------------------------------------------------
00016 //--------------------------------------------------------------------
00017 
00018 // standard headers
00019 
00020 #ifdef NO_STD_CHEADERS
00021 # include <stdlib.h>
00022 # include <string.h>
00023 # include <assert.h>
00024 #else
00025 # include <cstdlib>
00026 # include <cstring>
00027 # include <cassert>
00028 using namespace std; // For compatibility with non-std C headers
00029 #endif
00030 
00031 #include <iostream>
00032 using std::ostream;
00033 using std::endl;
00034 using std::cout;
00035 using std::cerr;
00036 
00037 #include "ICFG.hpp"
00038 
00039 namespace OA {
00040   namespace ICFG {
00041 
00042 static bool debug = false;
00043 
00044 //--------------------------------------------------------------------
00045 
00046 //--------------------------------------------------------------------
00047 // must be updated any time ICFG::Interface::EdgeType changes
00048 static const char *sEdgeTypeToString[] = { 
00049   "CFLOW_EDGE",
00050   "CALL_EDGE",
00051   "RETURN_EDGE",
00052   "CALL_RETURN_EDGE"
00053 };
00054 // must be updated any time ICFG::Interface::EdgeType changes
00055 static const char *sNodeTypeToString[] = { 
00056   "CFLOW_NODE",
00057   "CALL_NODE",
00058   "RETURN_NODE",
00059   "ENTRY_NODE",
00060   "EXIT_NODE"
00061 };
00062 
00063 //--------------------------------------------------------------------
00067 Node::Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType)
00068         : DGraph::NodeImplement(), mICFG(pICFG), mProc(proc), mType(pType) { Ctor(); }
00069 
00070 
00071 Node::Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType,
00072           OA_ptr<CFG::NodeInterface> cNode)
00073         : DGraph::NodeImplement(), mICFG(pICFG), mProc(proc), mType(pType), mCFGNode(cNode) { Ctor(); }
00074 
00075 Node::Node (Node& other)
00076       : DGraph::NodeImplement(), mICFG(other.mICFG), mProc(other.mProc),
00077         mType(other.mType), mCFGNode(other.mCFGNode) { Ctor(); }
00078 
00079 Node::~Node () { }
00080 
00081 NodeType Node::getType() const { return mType; }
00082 
00083 ProcHandle Node::getProc() const { return mProc; }
00084 
00085 
00086 void Node::addCallEdge(OA_ptr<Edge> e) { mCallEdges->push_back(e); }
00087 
00088 void Node::addReturnEdge(OA_ptr<Edge> e) { mReturnEdges->push_back(e); }
00089 
00090 void Node::removeCallEdge( OA_ptr<Edge> e) { mCallEdges->remove(e); }
00091 
00092 void Node::removeReturnEdge( OA_ptr<Edge> e) { mReturnEdges->remove(e); }
00093 
00094 /*
00095 unsigned int Node::getId() const { return mDGNode.getId(); }
00096 
00097 int Node::num_incoming () const { return mDGNode.num_incoming(); }
00098 
00099 int Node::num_outgoing () const { return mDGNode.num_outgoing(); }
00100 
00101 bool Node::isAnEntry() const { return mDGNode.isAnEntry(); }
00102 
00103 bool Node::isAnExit() const { return mDGNode.isAnExit(); }
00104 */
00105 
00106 void Node::Ctor() { 
00107     mCallEdges = new std::list<OA_ptr<Edge> >;
00108     mReturnEdges = new std::list<OA_ptr<Edge> >;
00109 }
00110 
00112 unsigned int Node::size () const
00113 {
00114     return mCFGNode->size(); 
00115 }
00116 
00118 OA_ptr<CFG::NodeStatementsIteratorInterface> 
00119 Node::getNodeStatementsIterator() const
00120 {
00121     return mCFGNode->getNodeStatementsIterator();
00122 }
00123 
00125 OA_ptr<CFG::NodeStatementsRevIteratorInterface> 
00126 Node::getNodeStatementsRevIterator() const
00127 {
00128     return mCFGNode->getNodeStatementsRevIterator();
00129 }
00130 
00131 
00132 //--------------------------------------------------------------------
00133 void
00134 Node::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00135 {
00136   os << sNodeTypeToString[mType] << std::endl;
00137 //  mCFGNode->dump(os,ir);
00138 }
00139 
00140 /*
00141 bool Node::operator==(DGraph::NodeInterface& other) 
00142 { 
00143     return mDGNode.operator==(other);
00144 }
00145 
00146 bool Node::operator<(DGraph::NodeInterface& other) 
00147 {
00148     return mDGNode.operator<(other);
00149 }
00150 */
00151 
00152 void
00153 Node::longdump (ICFG& icfg, 
00154                               ostream& os, 
00155                               OA_ptr<IRHandlesIRInterface> ir)
00156 {
00157     /*
00158   // print the node ID
00159   os << "ICFGStandard Node: ";
00160   dump(os,ir);
00161   
00162   if (isAnEntry()) {
00163     os << " (ENTRY)";
00164   } else if (isAnExit()) {
00165     os << " (EXIT)"; 
00166   }
00167   os << endl;
00168   
00169   // print the source(s)
00170   unsigned int count = 0;
00171   OA_ptr<NodesIteratorInterface> srcIter = getICFGSourceNodesIterator();
00172   for ( ; srcIter->isValid(); ++(*srcIter), ++count) {
00173     OA_ptr<NodeInterface> node = srcIter->currentICFGNode();
00174     if (count == 0) { os << " <-- ("; }
00175     else            { os << ", "; }
00176 
00177     node->dump(os,ir);
00178   }
00179   if (count > 0) { os << ")" << endl; }
00180   
00181   // print the sink(s)
00182   count = 0;
00183   OA_ptr<NodesIterator> outIter = getICFGSinkNodesIterator();
00184   for ( ; outIter->isValid(); ++(*outIter), ++count) {
00185     OA_ptr<Node> node = outIter->current();
00186     if (count == 0) { os << " --> ("; } 
00187     else            { os << ", "; }
00188     
00189     node->dump(os,ir);
00190   }
00191   if (count > 0) { os << ")" << endl; }
00192   */
00193 }
00194 
00195 
00196 void
00197 Node::dumpdot (ICFG &currcfg, ostream& os, 
00198                              OA_ptr<IRHandlesIRInterface> ir)
00199 {
00200     /*
00201   // print the node
00202   os << getId() << " [ label=\"==  ICFG ";
00203   os << sNodeTypeToString[getType()] << " " << getId() << " ==";
00204   
00205   if (isAnEntry()) {
00206     os << " (entry)";
00207   } 
00208   else if (isAnExit()) {
00209     os << " (exit)"; 
00210   }
00211   os << "\\n"; 
00212 
00213   // print the node contents
00214   OA_ptr<CFG::Interface::NodeStatementsIterator> stmtIter 
00215       = getNodeStatementsIterator();
00216 
00217 //  for ( ; stmtIter->isValid(); ++(*stmtIter)) {
00218 //    StmtHandle s = stmtIter->current();
00219 //    os << std::endl << ir->toString(s) << "\\n";
00220 //  }
00221 
00222   if (stmtIter->isValid()) {
00223     os << "\\n"; // internal dot line break
00224   }
00225   for ( ; stmtIter->isValid(); ++(*stmtIter)) {
00226     StmtHandle s = stmtIter->current();
00227     std::string st = ir->toString(s);
00228 
00229     // replace any '\"' in fortran code with '\''
00230     // because it messes up the dot files
00231     // (could replace each '\"' with two characters: '\\' '\"' )
00232     char * cst;
00233     cst = (char *)malloc(strlen(st.c_str()) + 1);
00234     strcpy(cst, st.c_str());
00235     for (unsigned int j = 0; j < strlen(cst); j++) {
00236       if (cst[j]=='\"') {
00237         cst[j]='\'';
00238       }
00239     }
00240 
00241     os << cst << "\\n";
00242   }
00243 
00244   os << "\" ];" << endl;
00245   os.flush();
00246   */
00247 }
00248 
00249 void Node::output(OA::IRHandlesIRInterface& ir) {
00250 
00251     std::ostringstream label;
00252 
00253     label <<  "==  ICFG ";
00254     label << sNodeTypeToString[getType()] << " " << getId() << " ==";
00255     if (isAnEntry()) {
00256       label << " (entry)";
00257     } 
00258     else if (isAnExit()) {
00259       label << " (exit)";
00260     }
00261     label << "\n";
00262 
00263     // print the node contents
00264     OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIter 
00265       = getNodeStatementsIterator();
00266     for ( ; stmtIter->isValid(); ++(*stmtIter)) {
00267         StmtHandle s = stmtIter->current();
00268         std::string st = ir.toString(s);
00269         
00270         // replace any '\"' in fortran code with '\''
00271         // because it messes up the dot files
00272         // (could replace each '\"' with two characters: '\\' '\"' )
00273         char * cst;
00274         cst = (char *)malloc(strlen(st.c_str()) + 1);
00275         strcpy(cst, st.c_str());
00276         for (unsigned int j = 0; j < strlen(cst); j++) {
00277           if (cst[j]=='\"') {
00278             cst[j]='\'';
00279           }
00280         }
00281         label << cst << "\n";
00282     }
00283 
00284     sOutBuild->outputString(label.str());
00285 
00286 }
00287 
00288 
00289 /*
00290 void Node::addIncomingEdge(OA_ptr<DGraph::EdgeInterface> e)
00291 {
00292     mDGNode.addIncomingEdge(e);
00293 }
00294 
00295 void Node::addOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e)
00296 {
00297      mDGNode.addOutgoingEdge(e);
00298 }
00299 
00300 void Node::removeIncomingEdge(OA_ptr<DGraph::EdgeInterface> e)
00301 {
00302     mDGNode.removeIncomingEdge(e);
00303 }
00304 
00305 void Node::removeOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e)
00306 {
00307     mDGNode.removeOutgoingEdge(e);
00308 }
00309 */
00310 
00311 
00312 
00313 //--------------------------------------------------------------------
00314 
00315 /*
00316 OA_ptr<DGraph::EdgesIteratorInterface> 
00317     Node::getIncomingEdgesIterator() const
00318 {
00319     
00320     return mDGNode.getIncomingEdgesIterator();
00321 }
00322 
00323 OA_ptr<DGraph::EdgesIteratorInterface> 
00324     Node::getOutgoingEdgesIterator() const
00325 {
00326     return mDGNode.getOutgoingEdgesIterator();
00327 }
00328 
00329 OA_ptr<DGraph::NodesIteratorInterface> 
00330     Node::getSourceNodesIterator() const
00331 {
00332     return mDGNode.getSourceNodesIterator();
00333 }
00334 
00335 OA_ptr<DGraph::NodesIteratorInterface> 
00336     Node::getSinkNodesIterator() const
00337 {
00338     return mDGNode.getSinkNodesIterator();
00339 }
00340 */
00341 
00342 //-------------------------------------------------------------------
00343 
00344 OA_ptr<EdgesIteratorInterface>
00345     Node::getICFGIncomingEdgesIterator() const
00346 {
00347    OA_ptr<EdgesIterator> retval;
00348    retval = new EdgesIterator(getIncomingEdgesIterator());
00349    return retval;
00350 
00351 }
00352 
00353 OA_ptr<EdgesIteratorInterface>
00354     Node::getICFGOutgoingEdgesIterator() const
00355 {
00356    OA_ptr<EdgesIterator> retval;
00357    retval = new EdgesIterator(getOutgoingEdgesIterator());
00358    return retval;
00359 
00360 }
00361 
00362 
00363 bool lt_Node::operator()(const OA_ptr<DGraph::NodeInterface> n1,
00364                     const OA_ptr<DGraph::NodeInterface> n2) const {
00365       return (n1->getId() < n2->getId());
00366     }
00367 
00368 
00369 
00370 bool lt_Edge::operator()(const OA_ptr<DGraph::EdgeInterface> e1,
00371                       const OA_ptr<DGraph::EdgeInterface> e2) const
00372 {
00373     unsigned int src1 = e1->getSource()->getId();
00374     unsigned int src2 = e2->getSource()->getId();
00375     if (src1 == src2) {
00376         return (e1->getSink()->getId() < e2->getSink()->getId());
00377     } else {
00378         return (src1 < src2);
00379     }
00380 }
00381 
00382 
00383 
00384 OA_ptr<NodesIteratorInterface>
00385     Node::getICFGSourceNodesIterator() const
00386 {
00387    OA_ptr<NodesIterator> retval;
00388    retval = new NodesIterator(getSourceNodesIterator());
00389    return retval;
00390 
00391 }
00392 
00393 OA_ptr<NodesIteratorInterface>
00394     Node::getICFGSinkNodesIterator() const
00395 {
00396    OA_ptr<NodesIterator> retval;
00397    retval = new NodesIterator(getSinkNodesIterator());
00398    return retval;
00399 
00400 }
00401 
00402 // -----------------------------------------------------------------
00403 
00404 Edge::Edge (OA_ptr<ICFG> pICFG,
00405           OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType,
00406           CallHandle call)
00407     : DGraph::EdgeImplement (pNode1, pNode2), mICFG(pICFG), mNode1(pNode1.convert<Node>()), mNode2(pNode2.convert<Node>()), mType(pType), mCall(call)
00408     {
00409     }
00410 
00411 
00412 
00413 Edge::Edge (OA_ptr<ICFG> pICFG,
00414           OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType)
00415     : DGraph::EdgeImplement (pNode1, pNode2), mICFG(pICFG), mNode1(pNode1.convert<Node>()), mNode2(pNode2.convert<Node>()), mType(pType), mCall(CallHandle(0))
00416     {
00417     }
00418 
00419 
00420 
00421 Edge::~Edge () {}
00422 
00423 EdgeType Edge::getType() const { return mType; }
00424 
00425 ProcHandle Edge::getSourceProc() const { return mNode1->getProc(); }
00426 
00427 ProcHandle Edge::getSinkProc() const { return mNode2->getProc(); }
00428 
00429 CallHandle Edge::getCall() const { return mCall; }
00430 
00431 /*
00432 unsigned int Edge::getId() const { return mDGEdge.getId(); }
00433 
00434 OA_ptr<DGraph::NodeInterface> Edge::getSource () const { return mDGEdge.getSource(); }
00435 
00436 OA_ptr<DGraph::NodeInterface> Edge::getTail () const { return mDGEdge.getSource(); }
00437 
00438 OA_ptr<DGraph::NodeInterface> Edge::getSink () const { return mDGEdge.getSink(); }
00439 
00440 OA_ptr<DGraph::NodeInterface> Edge::getHead () const { return mDGEdge.getSink(); }
00441 */
00442 
00443  OA_ptr<NodeInterface> Edge::getICFGSource() const
00444     {
00445         return getSource().convert<Node>();
00446     }
00447 
00448     OA_ptr<NodeInterface> Edge::getICFGSink() const
00449     {
00450         return getSink().convert<Node>();
00451     }
00452 
00453 
00454 /*
00455 bool Edge::operator==(DGraph::EdgeInterface& other) 
00456 {
00458     //Edge& recastOther = dynamic_cast<Edge&>(other);
00459     //return mDGEdge == recastOther.mDGEdge; 
00460     
00461     return mDGEdge.operator==(other);
00462 }
00463 
00464 bool Edge::operator<(DGraph::EdgeInterface& other) 
00465 { 
00466     return mDGEdge.operator<(other);
00467 }
00468 */
00469 
00470 
00471 void Edge::dump(ostream& os)
00472 {
00473   os << sEdgeTypeToString[mType];
00474 }
00475 
00476 void Edge::dumpdot(ostream& os)
00477 {
00478     os << getSource()->getId() << " -> " << getSink()->getId(); 
00479     switch(mType) {
00480         case (CALL_EDGE):
00481             os << " [label=\"CALL_EDGE\", style=dashed,color=red];" 
00482                << std::endl;
00483             break;
00484         case (RETURN_EDGE):
00485             os << " [label=\"RETURN_EDGE\", style=dashed,color=blue];" 
00486                << std::endl;
00487             break;
00488         case (CFLOW_EDGE):
00489             os << ";" << std::endl;
00490             break;
00491          case (CALL_RETURN_EDGE):
00492            os << " [label=\"CALL_RETURN_EDGE\", style=dashed];" << std::endl;
00493     }
00494 
00495     os.flush();
00496 }
00497 
00498 void Edge::output(OA::IRHandlesIRInterface& ir) {
00499 
00500     std::ostringstream label;
00501 
00502     if (debug) {
00503       label << "<Edge_" << getId() << ":" << getSource()->getId()
00504             << "==>" << getSink()->getId() << "> "; 
00505     }
00506 
00507     switch(mType) {
00508         case (CALL_EDGE):
00509           label << "CALL_(" << ir.toString(mCall) << ")";
00510             break;
00511         case (RETURN_EDGE):
00512           label << "RETURN_(" << ir.toString(mCall) << ")";
00513             break;
00514         case (CFLOW_EDGE):
00515             break;
00516         case (CALL_RETURN_EDGE):
00517           label << "CALL_RETURN";
00518             break;
00519     }
00520 
00521     sOutBuild->outputString( label.str() );
00522 }
00523 
00524  NodesIterator::NodesIterator(OA_ptr<DGraph::NodesIteratorInterface> ni)
00525         : DGraph::NodesIteratorImplement(ni) {}
00526 
00527 
00528 EdgesIterator::EdgesIterator(OA_ptr<DGraph::EdgesIteratorInterface> ni)
00529        : DGraph::EdgesIteratorImplement(ni) {}
00530 
00531 
00532    OA_ptr<EdgeInterface> EdgesIterator::currentICFGEdge() const
00533       {
00534          return current().convert<Edge>();
00535       }
00536 
00537 
00538 
00539    OA_ptr<NodeInterface> NodesIterator::currentICFGNode() const
00540       {
00541            return current().convert<Node>();
00542       }
00543 
00544 
00545 
00546 //--------------------------------------------------------------------
00547 //--------------------------------------------------------------------
00548 /*
00549  int ICFG::getNumNodes() { return mDGraph.getNumNodes(); }
00550   int ICFG::getNumEdges() { return mDGraph.getNumEdges(); }
00551 */
00552 
00553 
00554 
00555 ICFG::ICFG() 
00556 {
00557   OA_DEBUG_CTRL_MACRO("DEBUG_ICFG", debug);
00558 
00559   mEntry = mExit = NULL;
00560   mCallNodes = new std::list<OA_ptr<Node> >;
00561   mReturnNodes = new std::list<OA_ptr<Node> >;
00562   mCallEdges = new std::list<OA_ptr<Edge> >;
00563   mReturnEdges = new std::list<OA_ptr<Edge> >;
00564 
00565 }
00566 
00567 
00568 ICFG::~ICFG()
00569 {
00570   mEntry = NULL;
00571   mExit = NULL;
00572 }
00573 
00574 //--------------------------------------------------------------------
00575 // ICFG Methods
00576 //--------------------------------------------------------------------
00577 /*
00578 OA_ptr<Edge> 
00579 ICFG::getICFGEdge(
00580         const OA_ptr<DGraph::EdgeImplement> dgEdge) const
00581 {
00582   OA_ptr<Edge> retval;
00583 
00584   return retval;  
00585 }
00586 
00587 OA_ptr<Node> 
00588 ICFG::getICFGNode(
00589         const OA_ptr<DGraph::NodeImplement> dgNode) const
00590 {
00591   OA_ptr<Node> retval;
00592 
00593   return retval;
00594 }
00595 */
00596 
00597 void ICFG::addEdge(OA_ptr<Edge> pEdge)
00598 {
00599   assert(!pEdge.ptrEqual(0));
00600 
00601   // add associated DGraph edge to underlying DGraph
00602   DGraph::DGraphImplement::addEdge(pEdge);
00603 
00604   // add to complete list of edges
00605 
00606   OA_ptr<Node> pNode1, pNode2;
00607   switch (pEdge->getType()) {
00608       // a call edge
00609       case CALL_EDGE:
00610           {
00611         // put in set of call edges for pNode1 and pNode2
00612         OA_ptr<DGraph::NodeInterface> dNode1 = pEdge->getSource();
00613         pNode1 = dNode1.convert<Node>();
00614         pNode1->addCallEdge(pEdge);
00615         OA_ptr<DGraph::NodeInterface> dNode2 = pEdge->getSource();
00616         pNode2 = dNode2.convert<Node>();
00617         pNode2->addCallEdge(pEdge);
00618 
00619         // store in call edge set
00620         mCallEdges->push_back(pEdge);
00621         break;
00622           }
00623       // a return edge
00624       case RETURN_EDGE:
00625           {
00626         // put in set of return edges for pNode1 and pNode2
00627         OA_ptr<DGraph::NodeInterface> dNode1 = pEdge->getSource();
00628         pNode1 = dNode1.convert<Node>();
00629         pNode1->addReturnEdge(pEdge);
00630         OA_ptr<DGraph::NodeInterface> dNode2 = pEdge->getSource();
00631         pNode2 = dNode2.convert<Node>();
00632         pNode2->addReturnEdge(pEdge);
00633 
00634         // store in return edge set
00635         mReturnEdges->push_back(pEdge);
00636         break;
00637           }
00638       default:
00639         break;
00640   }
00641 
00642 }
00643 
00644 /*
00645 void ICFG::addNode(OA_ptr<Node> pNode)
00646 {
00648     //if ( pNode->mDGNode.ptrEqual(0) ) {
00649     //    assert(0);
00650     //} else {
00651     //    mDGNodeToICFGNode[pNode->mDGNode] = pNode;
00652     //}
00653 
00654     //mDGraph->addNode(pNode->mDGNode);
00655     
00656     mDGraph.addNode(pNode);
00657     
00658     // add to complete list of edges
00659 
00660 }
00661 */
00662 
00663     // from MustMayActive branch:
00664 //void ICFG::removeEdge(OA_ptr<DGraph::EdgeInterface> pEdge)
00665 void ICFG::removeEdge(OA_ptr<Edge> pEdge)
00666 {
00667   assert(!pEdge.ptrEqual(0));
00668 
00669   // erase the entry for the associated DGEdge 
00670 //  mDGEdgeToICFGEdge.erase(pEdge->mDGEdge);
00671 
00672   // remove associated DGraph edge to underlying DGraph
00673   //mDGraph->removeEdge(pEdge->mDGEdge);
00674   DGraph::DGraphImplement::removeEdge(pEdge);
00675 
00676   // add to complete list of edges
00677   //mEdges->remove(pEdge);
00678 
00679   OA_ptr<Node> pNode1, pNode2;
00680   OA_ptr<DGraph::NodeInterface> dpNode1, dpNode2;
00681   switch (pEdge->getType()) {
00682       // a call edge
00683       case CALL_EDGE:
00684         // remove from set of call edges for pNode1 and pNode2
00685         dpNode1 = pEdge->getSource();
00686         pNode1 = dpNode1.convert<Node>();
00687         pNode1->removeCallEdge(pEdge);
00688         dpNode2 = pEdge->getSource();
00689         pNode2 = dpNode2.convert<Node>();
00690         pNode2->removeCallEdge(pEdge);
00691 
00692         // remove from call edge set
00693         mCallEdges->remove(pEdge);
00694         break;
00695 
00696       // a return edge
00697       case RETURN_EDGE:
00698         // remove from set of return edges for pNode1 and pNode2
00699         dpNode1 = pEdge->getSource();
00700         pNode1 = dpNode1.convert<Node>();
00701         pNode1->removeReturnEdge(pEdge);
00702         dpNode2 = pEdge->getSource();
00703         pNode2 = dpNode2.convert<Node>();
00704         pNode2->removeReturnEdge(pEdge);
00705 
00706         // remove from return edge set
00707         mReturnEdges->remove(pEdge);
00708         break;
00709 
00710       default:
00711         break;
00712   }
00713 
00714 }
00715 
00716 /*
00717      //from MustMayActive branch:
00718 void ICFG::removeNode(OA_ptr<DGraph::NodeInterface> pNode)
00719 {
00720     //assert(! pNode->mDGNode.ptrEqual(0) );
00721     //assert(! pNode.ptrEqual(0));
00722 
00723     // remove the associated DGNode from map
00724 //    mDGNodeToICFGNode.erase(pNode->mDGNode);
00725 
00726     //mDGraph->removeNode(pNode->mDGNode);
00727     //mDGraph.removeNode(pNode);
00728     
00729     // remove from complete list of edges
00730     //mNodes->remove(pNode);
00731 }
00732 */
00733 
00734 
00735 /*
00736 OA_ptr<DGraph::NodesIteratorInterface> ICFG::getNodesIterator() const
00737 {
00738   return mDGraph.getNodesIterator(); 
00739 }
00740 
00741 
00742 OA_ptr<DGraph::NodesIteratorInterface>
00743 ICFG::getEntryNodesIterator( ) const
00744 {
00745   return mDGraph.getEntryNodesIterator();
00746 }
00747 
00748 OA_ptr<DGraph::NodesIteratorInterface>
00749 ICFG::getExitNodesIterator( ) const
00750 {
00751    return mDGraph.getExitNodesIterator();
00752 }
00753 
00754 OA_ptr<DGraph::EdgesIteratorInterface> ICFG::getEdgesIterator() const
00755 { 
00756    return mDGraph.getEdgesIterator();    
00757 }
00758 
00759 
00760 OA_ptr<DGraph::NodesIteratorInterface>
00761 ICFG::getReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
00762 {
00763    return mDGraph.getReversePostDFSIterator(pOrient);
00764 }
00765 
00766 
00767 OA_ptr<DGraph::NodesIteratorInterface> 
00768       ICFG::getDFSIterator(OA_ptr<DGraph::NodeInterface> n)
00769 {
00770    return mDGraph.getDFSIterator(n);
00771 }
00772 */
00773 
00774 
00775 // -----------------------------------------------------------------
00776 
00777 OA_ptr<NodesIteratorInterface> ICFG::getICFGNodesIterator() const
00778 {
00779    OA_ptr<NodesIterator> retval;
00780    retval = new NodesIterator(getNodesIterator());
00781    return retval;
00782 
00783 }
00784 
00785 
00786 OA_ptr<NodesIteratorInterface>
00787 ICFG::getICFGEntryNodesIterator( ) const
00788 {
00789  OA_ptr<NodesIterator> retval;
00790    retval = new NodesIterator(getEntryNodesIterator());
00791    return retval;
00792 
00793 
00794 }
00795 
00796 OA_ptr<NodesIteratorInterface>
00797 ICFG::getICFGExitNodesIterator( ) const
00798 {
00799  OA_ptr<NodesIterator> retval;
00800    retval = new NodesIterator(getExitNodesIterator());
00801    return retval;
00802 
00803 
00804 }
00805 
00806 OA_ptr<EdgesIteratorInterface> ICFG::getICFGEdgesIterator() const
00807 {
00808  OA_ptr<EdgesIterator> retval;
00809    retval = new EdgesIterator(getEdgesIterator());
00810    return retval;
00811 
00812 
00813 }
00814 
00815 
00816 OA_ptr<NodesIteratorInterface>
00817 ICFG::getICFGReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
00818 {
00819  OA_ptr<NodesIterator> retval;
00820    retval = new NodesIterator(getReversePostDFSIterator(pOrient));
00821    return retval;
00822 
00823 
00824 }
00825 
00826 
00827 OA_ptr<NodesIteratorInterface>
00828       ICFG::getICFGDFSIterator(OA_ptr<NodeInterface> n)
00829 {
00830  OA_ptr<NodesIterator> retval;
00831    retval = new NodesIterator(getDFSIterator(n));
00832    return retval;
00833 
00834 
00835 }
00836 
00837 
00838 
00839 void
00840 ICFG::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00841 {
00842   os << "===== ICFG: =====\n"
00843      << endl;
00844   
00845   // print the contents of all the nodes
00846   OA_ptr<DGraph::NodesIteratorInterface> nodeIter = getNodesIterator();
00847   for ( ; nodeIter->isValid(); ++(*nodeIter)) {
00848     OA_ptr<DGraph::NodeInterface> dnode = nodeIter->current();
00849     OA_ptr<Node> node = dnode.convert<Node>();
00850     node->longdump(*this,os, ir);
00851     os << endl;
00852   }
00853   
00854   os << "====================" << endl;
00855 
00856 }
00857 
00858 void
00859 ICFG::dumpdot(ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00860 {
00861   os << "digraph OA_ICFG {" << endl;
00862   os << "node [shape=rectangle];" << endl;
00863 
00864   // print the contents of all the nodes 
00865   // first sort group nodes by procedure
00866   std::map<ProcHandle,std::set<OA_ptr<Node> > > procNodeSet;
00867   OA_ptr<DGraph::NodesIteratorInterface> nodesIterPtr = getNodesIterator();
00868   for ( ; nodesIterPtr->isValid(); ++(*nodesIterPtr) ) {
00869     OA_ptr<DGraph::NodeInterface> dnode = nodesIterPtr->current();
00870     OA_ptr<Node> node = dnode.convert<Node>();
00871     ProcHandle proc = node->getProc();
00872     procNodeSet[proc].insert(node);
00873   }
00874 
00875   // sort edges by procedure, call and return edges will be put in 
00876   // a separate set
00877   std::set<OA_ptr<Edge> > sepSet;
00878   std::map<ProcHandle,std::set<OA_ptr<Edge> > > procEdgeSet;
00879   OA_ptr<DGraph::EdgesIteratorInterface> edgeIterPtr = getEdgesIterator();
00880   for ( ; edgeIterPtr->isValid(); ++(*edgeIterPtr) ) {
00881     OA_ptr<DGraph::EdgeInterface> dedge = edgeIterPtr->current();
00882     OA_ptr<Edge> edge = dedge.convert<Edge>();
00883     if (edge->getSinkProc() == edge->getSourceProc()) {
00884         procEdgeSet[edge->getSinkProc()].insert(edge);
00885     } else {
00886         sepSet.insert(edge);
00887     }
00888   }
00889 
00890   int procNum = 0; // for labeling each proc uniquely
00891   // then output nodes and edges by procedure
00892   std::map<ProcHandle,std::set<OA_ptr<Node> > >::iterator mapIter;
00893   for (mapIter=procNodeSet.begin(); mapIter!=procNodeSet.end(); mapIter++ ) {
00894     // subgraph
00895     std::ostringstream label;
00896     label << ir->toString(mapIter->first) << "_" << procNum++;
00897     os << "subgraph cluster_" << label.str() << " {" << std::endl;
00898     os << "    label=\"" << label.str() << "\"" << std::endl;
00899       
00900     // set of nodes
00901     std::set<OA_ptr<Node> > nodeSet = mapIter->second;
00902     std::set<OA_ptr<Node> >::iterator nodeIter;
00903     for (nodeIter=nodeSet.begin(); nodeIter!=nodeSet.end(); nodeIter++ ) {
00904       (*nodeIter)->dumpdot(*this,os,ir);
00905     }
00906     
00907     // set of edges
00908     std::set<OA_ptr<Edge> > edgeSet = procEdgeSet[mapIter->first];
00909     std::set<OA_ptr<Edge> >::iterator edgeIter;
00910     for (edgeIter=edgeSet.begin(); edgeIter!=edgeSet.end(); edgeIter++ ) {
00911       (*edgeIter)->dumpdot(os);
00912     }
00913     os << "}" << endl;
00914   }
00915 
00916   // print rest of edges
00917   std::set<OA_ptr<Edge> >::iterator edgeIter;
00918   for (edgeIter=sepSet.begin(); edgeIter!=sepSet.end(); edgeIter++ ) {
00919       (*edgeIter)->dumpdot(os);
00920   }
00921   
00922   os << "}" << endl;
00923   os.flush();
00924 }
00925 
00926 void ICFG::output(OA::IRHandlesIRInterface& ir) {
00927 
00928   // output the contents of the ICFG
00929   // first sort group nodes by procedure
00930   std::map<ProcHandle,std::set<OA_ptr<Node> > > procNodeSet;
00931   OA_ptr<DGraph::NodesIteratorInterface> nodesIterPtr = getNodesIterator();
00932   for ( ; nodesIterPtr->isValid(); ++(*nodesIterPtr) ) {
00933     OA_ptr<DGraph::NodeInterface> dnode = nodesIterPtr->current();
00934     OA_ptr<Node> node = dnode.convert<Node>();
00935     ProcHandle proc = node->getProc();
00936     procNodeSet[proc].insert(node);
00937   }
00938 
00939   // then sort edges by procedure:
00940   // call and return edges will be put in a separate set
00941   std::set<OA_ptr<Edge> > sepSet;
00942   std::map<ProcHandle,std::set<OA_ptr<Edge> > > procEdgeSet;
00943   OA_ptr<DGraph::EdgesIteratorInterface> edgeIterPtr = getEdgesIterator();
00944   for ( ; edgeIterPtr->isValid(); ++(*edgeIterPtr) ) {
00945     OA_ptr<DGraph::EdgeInterface> dedge = edgeIterPtr->current();
00946     OA_ptr<Edge> edge = dedge.convert<Edge>();
00947     if (edge->getSinkProc() == edge->getSourceProc()) {
00948         procEdgeSet[edge->getSinkProc()].insert(edge);
00949     } else {
00950         sepSet.insert(edge);
00951     }
00952   }
00953 
00954   
00955 
00956   int procNum = 0; // numbering subgraphs in case we have duplicate names
00957   sOutBuild->graphStart("ICFG");
00958 
00959   // then output nodes and edges by procedure
00960   std::map<ProcHandle,std::set<OA_ptr<Node> > >::iterator mapIter;
00961   for (mapIter=procNodeSet.begin(); mapIter!=procNodeSet.end(); mapIter++ ) {
00962 
00963     // subgraph
00964     std::ostringstream label;
00965     label << ir.toString(mapIter->first) << "_" << procNum++;
00966 
00967     sOutBuild->graphSubStart( label.str() );
00968     
00969     // set of nodes
00970     std::set<OA_ptr<Node> > nodeSet = mapIter->second;
00971     std::set<OA_ptr<Node> >::iterator nodeIter;
00972     for (nodeIter=nodeSet.begin(); nodeIter!=nodeSet.end(); nodeIter++ ) {
00973       OA_ptr<Node> node = (*nodeIter);
00974       sOutBuild->graphNodeStart(node->getId());
00975          sOutBuild->graphNodeLabelStart();
00976             node->output(ir);
00977          sOutBuild->graphNodeLabelEnd();
00978       sOutBuild->graphNodeEnd();
00979     }
00980     
00981     // set of edges
00982     std::set<OA_ptr<Edge> > edgeSet = procEdgeSet[mapIter->first];
00983     std::set<OA_ptr<Edge> >::iterator edgeIter;
00984     for (edgeIter=edgeSet.begin(); edgeIter!=edgeSet.end(); edgeIter++ ) {
00985       OA_ptr<Edge> edge = (*edgeIter);
00986       OA_ptr<DGraph::NodeInterface> dsourceNode = edge->getSource();
00987       OA_ptr<Node> sourceNode = dsourceNode.convert<Node>();
00988       OA_ptr<DGraph::NodeInterface> dsinkNode   = edge->getSink();
00989       OA_ptr<Node> sinkNode = dsinkNode.convert<Node>();
00990       
00991       sOutBuild->graphEdgeStart();
00992          sOutBuild->graphEdgeSourceNode(sourceNode->getId());
00993          sOutBuild->graphEdgeSinkNode(sinkNode->getId());
00994          sOutBuild->graphEdgeLabelStart();
00995             edge->output(ir);
00996          sOutBuild->graphEdgeLabelEnd();
00997          std::ostringstream extras;
00998          switch(edge->mType) {
00999          case (CALL_EDGE):
01000            extras << ",style=dashed,color=red";
01001            break;
01002          case (RETURN_EDGE):
01003            extras << ",style=dashed,color=blue";
01004            break;
01005          case (CFLOW_EDGE):
01006            break;
01007          }
01008          sOutBuild->outputString( extras.str() );
01009       sOutBuild->graphEdgeEnd();
01010     }
01011 
01012     sOutBuild->graphSubEnd( label.str() );
01013   }
01014 
01015   // print rest of edges
01016   std::set<OA_ptr<Edge> >::iterator edgeIter;
01017   for (edgeIter=sepSet.begin(); edgeIter!=sepSet.end(); edgeIter++ ) {
01018       OA_ptr<Edge> edge = (*edgeIter);
01019       OA_ptr<DGraph::NodeInterface> dsourceNode = edge->getSource();
01020       OA_ptr<Node> sourceNode = dsourceNode.convert<Node>();
01021       OA_ptr<DGraph::NodeInterface> dsinkNode   = edge->getSink();
01022       OA_ptr<Node> sinkNode = dsinkNode.convert<Node>();
01023       
01024       sOutBuild->graphEdgeStart();
01025          sOutBuild->graphEdgeSourceNode(sourceNode->getId());
01026          sOutBuild->graphEdgeSinkNode(sinkNode->getId());
01027          sOutBuild->graphEdgeLabelStart();
01028             edge->output(ir);
01029          sOutBuild->graphEdgeLabelEnd();
01030          std::ostringstream extras;
01031          switch(edge->mType) {
01032          case (CALL_EDGE):
01033            extras << ",style=dashed,color=red";
01034            break;
01035          case (RETURN_EDGE):
01036            extras << ",style=dashed,color=blue";
01037            break;
01038          case (CFLOW_EDGE):
01039            break;
01040          }
01041          sOutBuild->outputString( extras.str() );
01042       sOutBuild->graphEdgeEnd();
01043   }
01044 
01045 //      mDGraph->output(ir);
01046   
01047   sOutBuild->graphEnd("ICFG");
01048 }
01049 
01050 /*
01051 void ICFG::addNode(OA_ptr<DGraph::NodeInterface> n)
01052 {
01053    mDGraph.addNode(n); 
01054 }
01055 
01056 void ICFG::addEdge(OA_ptr<DGraph::EdgeInterface> e)
01057 {
01058 
01059    mDGraph.addEdge(e);
01060 }
01061 */
01062 
01063 
01064   } // end namespace ICFG
01065 } // end namespace OA

Generated on Sat Oct 31 05:21:21 2009 for OpenAnalysis by  doxygen 1.6.1