CallGraph.cpp

Go to the documentation of this file.
00001 
00020 //--------------------------------------------------------------------
00021 //--------------------------------------------------------------------
00022 
00023 // standard headers
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; // For compatibility with non-std C headers
00034 #endif
00035 
00036 #include <iostream>
00037 using std::ostream;
00038 using std::endl;
00039 using std::cout;
00040 using std::cerr;
00041 
00042 // Mint headers
00043 #include "CallGraph.hpp"
00044 
00045 namespace OA {
00046   namespace CallGraph {
00047 
00048 static bool debug = false;
00049 
00050 //--------------------------------------------------------------------
00051 
00052 //--------------------------------------------------------------------
00053 // must be updated any time CallGraph::Interface::EdgeType changes
00054 static const char *sEdgeTypeToString[] = { 
00055   "NORMAL_EDGE" // FIXME (make CFG's version static)
00056 };
00057 
00058 
00059 //--------------------------------------------------------------------
00060 
00061 CallGraphCalleeProcIter::CallGraphCalleeProcIter(OA_ptr<std::set<ProcHandle> > pSet)
00062         : IRHandleSetIterator<ProcHandle>(pSet)  {}
00063 
00064 CallGraphCalleeProcIter::~CallGraphCalleeProcIter() {}
00065 
00066 void CallGraphCalleeProcIter::operator++() { IRHandleSetIterator<ProcHandle>::operator++(); }
00067 
00068 
00069 bool CallGraphCalleeProcIter::isValid() const
00070       { return IRHandleSetIterator<ProcHandle>::isValid(); }
00071 
00072 ProcHandle CallGraphCalleeProcIter::current() const
00073       { return IRHandleSetIterator<ProcHandle>::current(); }
00074 
00075 
00076 void CallGraphCalleeProcIter::reset() { IRHandleSetIterator<ProcHandle>::current(); }
00077 
00078 
00079 NodesIterator::NodesIterator(OA_ptr<DGraph::NodesIteratorInterface> ni)
00080         : DGraph::NodesIteratorImplement(ni) {}
00081 
00082 EdgesIterator::EdgesIterator(OA_ptr<DGraph::EdgesIteratorInterface> ni)
00083     : DGraph::EdgesIteratorImplement(ni) {}
00084 
00085 Node::Node() : mSym(0), mProc(0) {  }
00086 
00087 Node::Node(SymHandle s) : mSym(s), mProc(0)
00088         {  }
00089 
00090 Node::~Node () { }
00091 
00092 bool Node::isDefined() const { return (mProc.hval() != 0); }
00093 
00094 bool Node::isCalled() const { return (mCalls.size() != 0); }
00095 
00096 ProcHandle Node::getProc() const { return mProc; }
00097 
00098 SymHandle Node::getProcSym() const { return mSym; }
00099 
00100 void Node::add_def(ProcHandle h) { mProc = h; }
00101 
00102 void Node::add_call(CallHandle h) { mCalls.push_back(h); }
00103 
00104 Edge::Edge(OA_ptr<DGraph::NodeInterface> source,
00105              OA_ptr<DGraph::NodeInterface> sink, EdgeType _type,
00106              OA::CallHandle call) : DGraph::EdgeImplement (source, sink), mType(_type), mCallsiteExpr(call)
00107 {
00108 }
00109 
00110 /*
00111 Edge::Edge(OA_ptr<DGraph::NodeInterface> source,
00112              OA_ptr<DGraph::NodeInterface> sink, EdgeType _type,
00113              CallHandle call) : DGraph::EdgeImplement (source, sink), mType(_type), mCallsiteExpr(call)         {
00114             }
00115 */
00116 
00117 Edge::~Edge () {}
00118 
00119 /*
00120 unsigned int Edge::getId() const { return mDGEdge.getId(); }
00121 */
00122 
00123 EdgeType Edge::getType() const { return mType; }
00124 
00125 CallHandle Edge::getCallHandle() const { return mCallsiteExpr; }
00126 
00127 /*
00128 OA_ptr<DGraph::NodeInterface> Edge::getSource () const
00129         {
00130 
00131             return mDGEdge.getSource();
00132         }
00133 
00134 OA_ptr<DGraph::NodeInterface> Edge::getSink () const
00135         {
00136 
00137 
00138 
00139             return mDGEdge.getSink();
00140         }
00141 */
00142 
00143 OA_ptr<NodeInterface> Edge::getCallGraphSource() const
00144 {
00145            return getSource().convert<NodeInterface>();
00146 
00147 }
00148 
00149 OA_ptr<NodeInterface> Edge::getCallGraphSink() const
00150 {
00151            return getSink().convert<NodeInterface>();
00152 }
00153 
00154 /*
00155 bool Edge::operator== (DGraph::EdgeInterface& other)
00156 {
00157     return mDGEdge.operator==(other);
00158 }
00159 
00160 bool Edge::operator< (DGraph::EdgeInterface& other)
00161 {
00162     return mDGEdge.operator<(other);
00163 }
00164 */
00165 
00166 /*
00167 int CallGraph::getNumNodes() { return mDGraph.getNumNodes(); }
00168 
00169 int CallGraph::getNumEdges() { return mDGraph.getNumEdges(); }
00170 */
00171 
00172 CallGraph::CallGraph(const SymHandle name) 
00173   : mName(name)
00174 {
00175     OA_DEBUG_CTRL_MACRO("DEBUG_CallGraph:ALL", debug);
00176 }
00177 
00178 CallGraph::CallGraph() 
00179   : mName(SymHandle(0))
00180 {
00181 }
00182 
00183 
00184 CallGraph::~CallGraph()
00185 {
00186 }
00187 
00188 /*
00189 void CallGraph::addNode(OA_ptr<DGraph::NodeInterface> n)
00190 {
00191   mDGraph.addNode(n);
00192 }
00193 
00194 void CallGraph::addEdge(OA_ptr<DGraph::EdgeInterface> e)
00195 {
00196 
00197    mDGraph.addEdge(e);
00198 }
00199 
00200 
00201 void CallGraph::removeEdge(OA_ptr<DGraph::EdgeInterface> e)
00202     {
00203         mDGraph.removeEdge(e);
00204     }
00205 
00206 void CallGraph::removeNode(OA_ptr<DGraph::NodeInterface> n)
00207     {
00208         mDGraph.removeNode(n);
00209     }
00210 */
00211 
00212 
00213 OA_ptr<ProcHandleIterator> CallGraph::getCalleeProcIter(CallHandle call)
00214     {
00215       OA_ptr<ProcHandleIterator> retIter;
00216       OA_ptr<std::set<ProcHandle> > procSet;
00217       procSet = mCallToCalleeProcSetMap[call];
00218       if (procSet.ptrEqual(NULL)) {
00219         procSet = new std::set<ProcHandle>;
00220       }
00221       retIter = new CallGraphCalleeProcIter(procSet);
00222       return retIter;
00223     }
00224 
00225 
00226 
00227 //--------------------------------------------------------------------
00228 OA_ptr<NodeInterface> NodesIterator::currentCallGraphNode() const {
00229    return current().convert<Node>();
00230 }
00231 
00232 OA_ptr<EdgeInterface> EdgesIterator::currentCallGraphEdge() const {
00233    return current().convert<Edge>();
00234 }
00235 
00236 /*
00237 unsigned int Node::getId() const { return mDGNode.getId(); }
00238 
00239 int Node::num_incoming () const
00240 {
00241     return mDGNode.num_incoming();
00242 }
00243 
00244 int Node::num_outgoing () const
00245 {
00246     return mDGNode.num_outgoing();
00247 }
00248 
00249 bool Node::isAnEntry() const
00250 {
00251     return mDGNode.isAnEntry();
00252 }
00253 
00254 bool Node::isAnExit() const
00255 {
00256     return mDGNode.isAnExit();
00257 }
00258 
00259 
00260 bool Node::operator== (DGraph::NodeInterface& other)
00261 {
00262     return mDGNode.operator==(other);
00263 }
00264 
00265 bool Node::operator< (DGraph::NodeInterface& other)
00266 {
00267     return mDGNode.operator<(other);
00268 }
00269 
00270 void Node::addIncomingEdge(OA_ptr<DGraph::EdgeInterface> e)
00271 {
00272     mDGNode.addIncomingEdge(e);
00273 }
00274 
00275 void Node::addOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e)
00276 {
00277      mDGNode.addOutgoingEdge(e);
00278 }
00279 
00280 void Node::removeIncomingEdge(OA_ptr<DGraph::EdgeInterface> e)
00281 {
00282     mDGNode.removeIncomingEdge(e);
00283 }
00284 
00285 void Node::removeOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e)
00286 {
00287      mDGNode.removeOutgoingEdge(e);
00288 }
00289 
00290 
00291 OA_ptr<DGraph::EdgesIteratorInterface> Node::getIncomingEdgesIterator() const
00292       {
00293          return mDGNode.getIncomingEdgesIterator();
00294       }
00295 
00296 
00297 OA_ptr<DGraph::EdgesIteratorInterface> Node::getOutgoingEdgesIterator() const
00298       {
00299          return mDGNode.getOutgoingEdgesIterator();
00300       }
00301 
00302 OA_ptr<DGraph::NodesIteratorInterface> Node::getSourceNodesIterator() const
00303       {
00304          return mDGNode.getSourceNodesIterator();
00305       }
00306 
00307 OA_ptr<DGraph::NodesIteratorInterface> Node::getSinkNodesIterator() const
00308       {
00309          return mDGNode.getSinkNodesIterator();
00310       }
00311 */
00312 
00313 OA_ptr<EdgesIteratorInterface> Node::getCallGraphIncomingEdgesIterator() const
00314       {
00315          OA_ptr<EdgesIterator> retval;
00316          retval = new EdgesIterator(getIncomingEdgesIterator());
00317          return retval;
00318 
00319       }
00320 
00321 OA_ptr<EdgesIteratorInterface> Node::getCallGraphOutgoingEdgesIterator() const
00322       {
00323          OA_ptr<EdgesIterator> retval;
00324          retval = new EdgesIterator(getOutgoingEdgesIterator());
00325          return retval;
00326 
00327       }
00328 
00329 OA_ptr<NodesIteratorInterface> Node::getCallGraphSourceNodesIterator() const
00330       {
00331          OA_ptr<NodesIterator> retval;
00332          retval = new NodesIterator(getSourceNodesIterator());
00333          return retval;
00334       }
00335 
00336 
00337 OA_ptr<NodesIteratorInterface> Node::getCallGraphSinkNodesIterator() const
00338       {
00339          OA_ptr<NodesIterator> retval;
00340          retval = new NodesIterator(getSinkNodesIterator());
00341          return retval;
00342 
00343       }
00344 
00345 
00346 //--------------------------------------------------------------------
00347 
00348 
00349 void Edge::dump(ostream& os)
00350 {
00351   os << sEdgeTypeToString[mType];
00352 }
00353 
00354 void Edge::output(IRHandlesIRInterface& ir)
00355 {
00356     // always get NORMAL_EDGE so it just clutters things
00357     //sOutBuild->outputString(  sEdgeTypeToString[mType] );
00358   
00359   sOutBuild->outputString( ir.toString(mCallsiteExpr) );
00360 }
00361 
00362 //--------------------------------------------------------------------
00363 
00364 void CallGraph::connect (OA_ptr<NodeInterface> src, 
00365               OA_ptr<NodeInterface> dst, 
00366               EdgeType type, CallHandle call) 
00367 {
00368     OA_ptr<Edge> e; e = new Edge (src, dst, type, call);
00369 
00370     addEdge (e);
00371 }
00372 
00373 
00374 void CallGraph::disconnect (OA_ptr<EdgeInterface> e)
00375 {
00376     removeEdge(e);
00377 }
00378 
00379 
00380 OA_ptr<Node> 
00381 CallGraph::findOrAddNode(SymHandle sym)
00382 {
00383   OA_ptr<Node> node; node = NULL;
00384 
00385   SymToNodeMapType::iterator it = mSymToNodeMap.find(sym);
00386   if (it == mSymToNodeMap.end()) {
00387     node = new Node(sym);
00388     addNode(node);
00389     mSymToNodeMap.insert(SymToNodeMapType::value_type(sym, node));
00390   } else {
00391     node = (*it).second;
00392   }
00393   assert(!node.ptrEqual(NULL));
00394   
00395   return node;
00396 }
00397 
00398 //--------------------------------------------------------------------
00399 
00400 void CallGraph::addToCallProcSetMap(CallHandle call, ProcHandle proc) 
00401 {
00402   OA_ptr<std::set<ProcHandle> > procSet;  procSet = NULL;
00403 
00404   std::map<CallHandle, OA_ptr<std::set<ProcHandle> > >::iterator it;
00405   it = mCallToCalleeProcSetMap.find(call);
00406   if (it == mCallToCalleeProcSetMap.end()) {
00407     procSet = new std::set<ProcHandle>;
00408     mCallToCalleeProcSetMap.insert(std::map<CallHandle, 
00409                   OA_ptr<std::set<ProcHandle> > >::value_type(call,procSet));
00410   }
00411   mCallToCalleeProcSetMap[call]->insert(proc);
00412 
00413   // checking (keeping this here to test on UseOA-Rose -- BK
00414   if (debug) {
00415     it = mCallToCalleeProcSetMap.find(call);
00416     if (it == mCallToCalleeProcSetMap.end()) {
00417       std::cout << "++++++ map insert failed (cannot even find call)\n\n";
00418     } else {
00419       procSet = (*it).second;
00420       std::set<ProcHandle>::iterator psit;
00421       bool found = false;
00422       for (psit = procSet->begin(); psit != procSet->end(); (psit++) ) {
00423         if ((*psit)==proc) {
00424           found = true;
00425         }
00426       }
00427       if (found) {
00428         std::cout << "++++++ map insert succeeded\n\n";
00429       } else {
00430         std::cout << "++++++ map insert failed (found call, but not proc)\n\n";
00431       }
00432     }
00433   }
00434 
00435 }
00436 
00437 
00438 
00439 
00440 /*
00441 OA_ptr<DGraph::NodesIteratorInterface> CallGraph::getNodesIterator() const
00442   {
00443       return mDGraph.getNodesIterator();
00444   }
00445 
00446 
00447 OA_ptr<DGraph::EdgesIteratorInterface> CallGraph::getEdgesIterator() const
00448   {
00449       return mDGraph.getEdgesIterator();
00450   }
00451 
00452 
00453 OA_ptr<DGraph::NodesIteratorInterface>
00454       CallGraph::getReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient)
00455     {
00456         return mDGraph.getReversePostDFSIterator(pOrient);
00457     }
00458 
00459 
00460 OA_ptr<DGraph::NodesIteratorInterface>
00461       CallGraph::getDFSIterator(OA_ptr<DGraph::NodeInterface> n){
00462 
00463           return mDGraph.getDFSIterator(n);
00464       }
00465 
00466 
00467 
00468 OA_ptr<DGraph::NodesIteratorInterface> CallGraph::getEntryNodesIterator() const
00469 {
00470    return mDGraph.getEntryNodesIterator();
00471 }
00472 
00473 
00474 OA_ptr<DGraph::NodesIteratorInterface> CallGraph::getExitNodesIterator() const
00475 {
00476  return mDGraph.getExitNodesIterator();
00477 }
00478 */
00479 
00480 
00481 OA_ptr<NodesIteratorInterface> CallGraph::getCallGraphNodesIterator() const
00482   {
00483        OA_ptr<NodesIterator> retval;
00484        retval = new NodesIterator(getNodesIterator());
00485        return retval;
00486 
00487   }
00488 
00489 
00490 OA_ptr<EdgesIteratorInterface> CallGraph::getCallGraphEdgesIterator() const
00491   {
00492        OA_ptr<EdgesIterator> retval;
00493        retval = new EdgesIterator(getEdgesIterator());
00494        return retval;
00495 
00496   }
00497 
00498 
00499 OA_ptr<NodesIteratorInterface>
00500       CallGraph::getCallGraphReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient)
00501     {
00502          OA_ptr<NodesIterator> retval;
00503          retval = new NodesIterator(getReversePostDFSIterator(pOrient));
00504          return retval;
00505 
00506     }
00507 
00508 
00509 OA_ptr<NodesIteratorInterface>
00510      CallGraph::getCallGraphDFSIterator(OA_ptr<NodeInterface> n)
00511 {
00512      OA_ptr<NodesIterator> retval;
00513      retval = new NodesIterator(getDFSIterator(n));
00514      return retval;
00515 
00516 }
00517 
00518 
00519 OA_ptr<NodesIteratorInterface> CallGraph::getCallGraphEntryNodesIterator() const
00520 {
00521      OA_ptr<NodesIterator> retval;
00522      retval = new NodesIterator(getEntryNodesIterator());
00523      return retval;
00524 
00525 }
00526 
00527 
00528 OA_ptr<NodesIteratorInterface> CallGraph::getCallGraphExitNodesIterator() const
00529 {
00530      OA_ptr<NodesIterator> retval;
00531      retval = new NodesIterator(getExitNodesIterator());
00532      return retval;
00533 
00534 }
00535 
00536 
00537 
00538 //--------------------------------------------------------------------
00539 void
00540 CallGraph::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00541 {
00556 }
00557 //--------------------------------------------------------------------
00558 
00559 void CallGraph::output(OA::IRHandlesIRInterface& ir) {
00560 
00561   // perform output from superclass
00562   //mDGraph.output(ir);
00563   
00564 
00565   DGraph::DGraphImplement::output(ir);
00566 
00567   // now output map info:  CallHandle to ProcHandle set
00568   sOutBuild->mapStart("mCallToCalleeProcSetMap", "CallHandle", 
00569                       "OA_ptr<std::set<ProcHandle> > ");
00570   std::map<CallHandle, OA_ptr<std::set<ProcHandle> > >::iterator mapIter;
00571 
00572   mapIter = mCallToCalleeProcSetMap.begin();
00573 
00574   for (; 
00575        mapIter != mCallToCalleeProcSetMap.end(); mapIter++) {
00576 
00577     CallHandle call = mapIter->first;
00578     if (call==CallHandle(0)) continue;
00579 
00580     sOutBuild->mapEntryStart();
00581     sOutBuild->mapKey(ir.toString(call));
00582     sOutBuild->mapValueStart();
00583 
00584     OA_ptr<std::set<ProcHandle> > procSet;
00585     procSet = mapIter->second;
00586     if (!procSet.ptrEqual(0)) {
00587 
00588       sOutBuild->listStart();
00589       CallGraphCalleeProcIter procIter(procSet);
00590       for (; procIter.isValid(); ++procIter) {
00591         ProcHandle proc = procIter.current();
00592         sOutBuild->listItemStart();
00593         sOutBuild->outputString( ir.toString(proc) );
00594         sOutBuild->listItemEnd();
00595       }
00596       sOutBuild->listEnd();
00597     }
00598 
00599     sOutBuild->mapValueEnd();
00600     sOutBuild->mapEntryEnd();
00601   }
00602 
00603   sOutBuild->mapEnd("mCallToCalleeProcSetMap");
00604 
00605 }
00606 
00607 //--------------------------------------------------------------------
00608 void
00609 Node::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00610 {
00611   if (mSym.hval() == 0) {
00612     os << "<no-symbol>";
00613   } else {
00614     os << ir->toString(mSym);
00615   }
00616   os << " " << (isDefined() ? "[defined]" : "[referenced]");
00617 }
00618 
00619 void
00620 Node::output(OA::IRHandlesIRInterface& ir)
00621 {
00622     std::stringstream label;
00623     if (mSym.hval() == 0) {
00624       label << "<no-symbol>";
00625     } else {
00626       label << ir.toString(mSym);
00627     }
00628     label << " " << (isDefined() ? "[defined]" : "[referenced]");
00629     sOutBuild->outputString(label.str());
00630 }
00631 
00632 void
00633 Node::longdump ( ostream& os, 
00634                                    OA_ptr<IRHandlesIRInterface> ir)
00635 {
00678 }
00679 
00680 //--------------------------------------------------------------------
00681 
00682   } // end namespace CallGraph
00683 } // end namespace OA

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