ManagerCallGraph.cpp

Go to the documentation of this file.
00001 
00015 // standard headers
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; // For compatibility with non-std C headers
00026 #endif
00027 
00028 #include <iostream>
00029 
00030 #include "ManagerCallGraph.hpp"
00031 
00032 namespace OA {
00033   namespace CallGraph {
00034 
00035 static bool debug = false;
00036 
00037 ManagerCallGraphStandard::ManagerCallGraphStandard(OA_ptr<CallGraphIRInterface> _ir) : mIR(_ir)
00038 {
00039     OA_DEBUG_CTRL_MACRO("DEBUG_ManagerCallGraph:ALL", debug);
00040 }
00041 
00042 //--------------------------------------------------------------------
00043 OA_ptr<CallGraph> ManagerCallGraphStandard::performAnalysis (
00044         OA_ptr<IRProcIterator> procIter, 
00045         OA_ptr<Alias::InterAliasInterface> interAlias 
00046 ) 
00047 {
00048   mCallGraph = new CallGraph();
00049   mInterAlias = interAlias;
00050 
00051   build_graph(procIter);
00052 
00053   // document CallHandle to ProcHandle Set Map
00054 
00055   OA_ptr<EdgesIteratorInterface> edgeIter;
00056   edgeIter = mCallGraph->getCallGraphEdgesIterator();
00057   for (; edgeIter->isValid(); edgeIter->operator++()) {
00058     OA_ptr<EdgeInterface> edge = edgeIter->currentCallGraphEdge();
00059     CallHandle call = edge->getCallHandle();
00060     OA_ptr<NodeInterface> dest = edge->getCallGraphSink();
00061     ProcHandle proc = dest->getProc();
00062     
00063     if (debug) {
00064       std::cout << "Inserting call:'" << mIR->toString(call) << "'"
00065                 << " to proc:'" << mIR->toString(proc) << "'\n";
00066     }
00067 
00068     mCallGraph->addToCallProcSetMap(call, proc);
00069   }
00070 
00071 
00072   return mCallGraph;
00073 }
00074 
00075 //--------------------------------------------------------------------
00076 void
00077 ManagerCallGraphStandard::build_graph(OA_ptr<IRProcIterator> procIter)
00078 {
00079   // Iterate over all the procedures in the program
00080   for ( procIter->reset(); procIter->isValid(); ++(*procIter)) { 
00081     
00082     // Create a node for this procedure
00083     ProcHandle currProc = procIter->current();
00084     SymHandle currProcSym = mIR->getProcSymHandle(currProc);
00085     if (debug) {
00086       std::cout << "currProc = " << mIR->toString(currProc);
00087       std::cout << ", currProcSym = " << mIR->toString(currProcSym) 
00088                 << std::endl;
00089     }
00090 
00091     OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(currProc);
00092 
00093     OA_ptr<Node> currProcNode 
00094       = mCallGraph->findOrAddNode(currProcSym);
00095     currProcNode->add_def(currProc); 
00096 
00097   if (debug) {
00098       std::cout << "After currProc = " << mIR->toString(currProc);
00099       std::cout << ", After currProcSym = " << mIR->toString(currProcSym)
00100                 << std::endl;
00101     }
00102 
00103     
00104     // Iterate over the statements of this procedure
00105     OA_ptr<IRStmtIterator> stmtIterPtr = mIR->getStmtIterator(currProc);
00106     // Iterate over the statements of this block adding procedure references
00107     for ( ; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00108       StmtHandle stmt = stmtIterPtr->current();
00109 
00110       // Iterate over procedure calls of a statement
00111       OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(stmt);
00112       if (debug) {
00113         if (callsiteItPtr->isValid()) {
00114           std::cout << "\n***\n  Call Statement:\n     <'";
00115           std::cout << mIR->toString(stmt) << "'>";
00116         }
00117       }
00118       for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00119         CallHandle call = callsiteItPtr->current();
00120 
00121         if (debug) {
00122           std::cout << "\n        Call: ["
00123                     << mIR->toString(call) << "]";
00124         }
00125         // get the mre for the function call (eg. NamedRef('foo'))
00126         OA_ptr<MemRefExpr> callMRE = mIR->getCallMemRefExpr(call);
00127 
00128         // iterate over the may locs for this callMRE
00129         OA_ptr<LocIterator> mayCallItPtr = alias->getMayLocs(*callMRE,
00130                                                               currProc);
00131         for(mayCallItPtr->reset(); mayCallItPtr->isValid(); ++(*mayCallItPtr)) {
00132            OA_ptr<Location> loc = mayCallItPtr->current();
00133 
00134            if (loc->isaNamed()) {
00135              OA_ptr<NamedLoc> namedProc;
00136              namedProc = loc.convert<NamedLoc>();
00137 
00138              // get the symbol for the function
00139              SymHandle sym = namedProc->getSymHandle();
00140 
00141              // Add a node (if nonexistent) and edge
00142              OA_ptr<Node> node
00143                = mCallGraph->findOrAddNode(sym);
00144              node->add_call(call);
00145 
00146              if(debug)
00147              {
00148                  std::cout << "ManagerCallGraphStandard currProcNode";
00149                  std::cout << currProcNode->getId();
00150                  std::cout << std::endl;
00151              }
00152             
00153              if(debug)
00154              {
00155                  std::cout << "ManagerCallGraphStandard Node";
00156                  std::cout << node->getId();
00157                  std::cout << std::endl;
00158              }
00159 
00160              
00161              mCallGraph->connect(currProcNode, node,
00162                                  NORMAL_EDGE, call);
00163 
00164            } // if may loc isaNamed()
00165 
00166         } // iterating over may locs for the callMRE
00167 
00168       } // iterating over calls of a statement
00169 
00170       if (debug) {
00171         callsiteItPtr->reset();
00172         if (callsiteItPtr->isValid()) {
00173           std::cout << "\n***\n";
00174         }
00175       }
00176 
00177     } // iterating over statements
00178 
00179   } // iterating over procedures
00180 
00181 }
00182 
00183   } // end CallGraph namespace
00184 } // end OA namespace

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