CallGraphDFSolver.cpp

Go to the documentation of this file.
00001 
00017 #include "CallGraphDFSolver.hpp"
00018 #include <Utils/Util.hpp>
00019 
00020 namespace OA {
00021   namespace DataFlow {
00022 
00023 static bool debug = false;
00024 
00025 
00026 CallGraphDFSolver::CallGraphDFSolver(CallGraphDirectionType pDirection, CallGraphDFProblem& prob) 
00027       : mDirection(pDirection), mDFProb(prob)
00028 {
00029   OA_DEBUG_CTRL_MACRO("DEBUG_CallGraphDFSolver:ALL", debug);
00030 }       
00031 
00032 
00033 void 
00034 CallGraphDFSolver::solve(OA_ptr<CallGraph::CallGraphInterface> callGraph, 
00035                          DFPImplement algorithm)
00036 {
00037   if (debug) {
00038       /*
00039     std::cout << "CallGraphDFProblem::solve: ";
00040     std::cout << "callgraph = " << std::endl;
00041     callGraph->dump(std::cout,mIR);
00042     */
00043   }
00044 
00045   mTop = mDFProb.initializeTop();
00046 
00047   DataFlow::DGraphSolverDFP::solve(callGraph, 
00048           ((mDirection==TopDown) ? DGraph::DEdgeOrg : DGraph::DEdgeRev),
00049           algorithm);
00050 }
00051 
00052 //========================================================
00053 // implementation of DGraphIterativeDFP callbacks
00054 //========================================================
00055   
00056 //--------------------------------------------------------
00057 // initialization upcall 
00058 //--------------------------------------------------------
00059 void CallGraphDFSolver::initialize(OA_ptr<DGraph::DGraphInterface> dg)
00060 {
00061     OA_ptr<CallGraph::CallGraphInterface> callGraph = dg.convert<CallGraph::CallGraphInterface>();
00062 
00063     // iterate over all nodes and call initialization routine
00064     // that sets up initial DataFlowSets so we know if things have changed
00065     OA_ptr<CallGraph::NodesIteratorInterface> nodeIterPtr;
00066     nodeIterPtr = callGraph->getCallGraphNodesIterator();
00067 
00068     for ( ;nodeIterPtr->isValid(); ++(*nodeIterPtr) ) {
00069         OA_ptr<CallGraph::NodeInterface> node = nodeIterPtr->currentCallGraphNode();
00070         
00071         // In and Out in this context refer to the data-flow direction
00072         // which in the case of bottom-up is in the reverse direction
00073         // of edges in the graph
00074         mNodeInSetMap[node] = mDFProb.initializeTop();
00075         mNodeOutSetMap[node] = mDFProb.initializeNode(node->getProc());
00076     }
00077 
00078     // iterate over all edges and call initialization routine
00079     // that sets up initial DataFlowSets so we know if things have changed
00080     
00081     OA_ptr<CallGraph::EdgesIteratorInterface> edgeIterPtr;
00082     edgeIterPtr = callGraph->getCallGraphEdgesIterator();
00083     for ( ;edgeIterPtr->isValid(); ++(*edgeIterPtr) ) {
00084         OA_ptr<CallGraph::EdgeInterface> edge = edgeIterPtr->currentCallGraphEdge();
00085         
00086         // In is in direction of data-flow
00087         mEdgeInSetMap[edge] = mDFProb.initializeTop();
00088 
00089         // get procedure handle for caller
00090         OA_ptr<CallGraph::NodeInterface> caller = edge->getCallGraphSource();
00091         
00092         // get procedure handle for callee if there is one
00093         OA_ptr<CallGraph::NodeInterface> callee = edge->getCallGraphSink();
00094         
00095         if (callee->isDefined()) {
00096             mEdgeOutSetMap[edge] = mDFProb.initializeEdge(edge->getCallHandle(),
00097                                                   caller->getProc(),
00098                                                   callee->getProc());
00099         } else {
00100             mEdgeOutSetMap[edge] = mDFProb.initializeEdge(edge->getCallHandle(),
00101                                                   caller->getProc(),
00102                                                   callee->getProcSym());
00103         }
00104     }
00105 
00106 }
00107 
00108 //--------------------------------------------------------
00109 // solver upcalls
00110 //--------------------------------------------------------
00111 
00112 bool CallGraphDFSolver::atDGraphEdge( OA_ptr<DGraph::EdgeInterface> pEdge, 
00113                                        DGraph::DGraphEdgeDirection pOrient)
00114 {
00115     if (debug) {
00116       std::cout << "CallGraphDFSolver::atDGraphEdge" << std::endl;
00117     }
00118 
00119     // cast edge to a CallGraph edge
00120     OA_ptr<CallGraph::EdgeInterface> edge 
00121         = pEdge.convert<CallGraph::EdgeInterface>();
00122 
00123     // get procedure handle for caller
00124     OA_ptr<CallGraph::NodeInterface> caller = edge->getCallGraphSource();
00125 
00126     // get procedure handle for callee if there is one
00127     OA_ptr<CallGraph::NodeInterface> callee = edge->getCallGraphSink();
00128 
00129     // get data-flow set for edge based on procedure
00130     // whether getting it from caller or callee depends on 
00131     // the direction of the analysis
00132     OA_ptr<DataFlowSet> edgeIn;
00133     if (pOrient==DGraph::DEdgeOrg) { // top down
00134       edgeIn = mDFProb.nodeToEdge(caller->getProc(), mNodeOutSetMap[caller],
00135                           edge->getCallHandle());
00136     } else { // bottom up
00137       edgeIn = mDFProb.nodeToEdge(callee->getProc(), mNodeOutSetMap[callee],
00138                           edge->getCallHandle());
00139     }
00140 
00141     // do computation at actual call
00142     OA_ptr<DataFlowSet> edgeOut;
00143     if (callee->isDefined()) {
00144       edgeOut = mDFProb.atCallGraphEdge(edgeIn, edge->getCallHandle(),
00145                                         caller->getProc(), callee->getProc());
00146     } else {
00147       edgeOut = mDFProb.atCallGraphEdge(edgeIn, edge->getCallHandle(),
00148                                         caller->getProc(), callee->getProcSym());
00149     }
00150     mEdgeInSetMap[edge] = edgeIn;
00151 
00152     bool changed = false;
00153     // check if a change occured
00154     if (edgeOut != mEdgeOutSetMap[edge]) {
00155       if (debug) { 
00156           std::cout << "%%% CallGraphDFSolver::atDGraphEdge, "
00157                     << "mEdgeOutSetMap != edgeOut" << std::endl;
00158       }
00159       mEdgeOutSetMap[edge] = edgeOut;
00160       changed = true;
00161     } 
00162      
00163     return changed;
00164 }
00165 
00172 bool CallGraphDFSolver::atDGraphNode( 
00173                                        OA_ptr<DGraph::NodeInterface> pNode, 
00174                                        DGraph::DGraphEdgeDirection pOrient)
00175 {
00176     OA_ptr<CallGraph::NodeInterface> node 
00177         = pNode.convert<OA::CallGraph::NodeInterface>();
00178 
00179     if (debug) {
00180         std::cout << "CallGraphDFSolver::atDGraphNode: CallGraph node = ";
00181         std::cout << node->getId() << std::endl;
00182     }
00183 
00184     //-----------------------------------------------------
00185     // for each incoming edge translate edgeOut to nodeIn
00186     // and then do meet of all nodeIns with each other and
00187     // current nodeIn 
00188     //-----------------------------------------------------
00189     OA_ptr<DataFlowSet> nodeInSet = mNodeInSetMap[node]->clone();
00190 
00191     // set up iterator for predecessor nodes
00192     OA_ptr<CallGraph::EdgesIteratorInterface>  it;
00193     if (pOrient==DGraph::DEdgeOrg) {
00194        it = node->getCallGraphIncomingEdgesIterator(); // stupid Sun compiler
00195     } else {
00196        it = node->getCallGraphOutgoingEdgesIterator(); // stupid Sun compiler
00197     }
00198     // iterate over predecessors, translate from edge to node, 
00199     // and do meet operation
00200     for (; it->isValid(); ++(*it)) {
00201       OA_ptr<CallGraph::EdgeInterface> edge = it->currentCallGraphEdge();
00202       OA_ptr<DataFlowSet> temp  = mDFProb.edgeToNode(edge->getCallHandle(),
00203                                                       mEdgeOutSetMap[edge], node->getProc());
00204       nodeInSet = mDFProb.meet(nodeInSet, temp);
00205     }
00206 
00207     if (debug) { 
00208       std::cout << "%%% CallGraphDFSolver::atDGraphNode, ";
00209       std::cout << "nodeInSet = ";
00210       nodeInSet->dump(std::cout);
00211       std::cout << "mNodeInSetMap[node] = ";
00212       mNodeInSetMap[node]->dump(std::cout);
00213     }
00214     // calculate the output data-flow set for this procedure
00215     OA_ptr<DataFlowSet> nodeOutSet;
00216     if (node->getProc() != ProcHandle(0)) {
00217 
00218         nodeOutSet = mDFProb.atCallGraphNode(nodeInSet, node->getProc());
00219     } else {
00220         nodeOutSet = mNodeOutSetMap[node];
00221     }
00222     mNodeInSetMap[node] = nodeInSet;
00223 
00224     // update the out set for this node if has changed
00225     bool changed = false;
00226     if ( mNodeOutSetMap[node] != nodeOutSet ) {
00227         if (debug) { 
00228           std::cout << "%%% CallGraphDFSolver::atDGraphNode, "
00229                     << "mNodeOutSetMap != nodeOutSet" << std::endl;
00230           std::cout << "mNodeOutSetMap = ";
00231           mNodeOutSetMap[node]->dump(std::cout);
00232           std::cout << "nodeOutSet = ";
00233           nodeOutSet->dump(std::cout);
00234         }
00235         mNodeOutSetMap[node] = nodeOutSet;
00236         changed = true;
00237     }
00238     if (debug) { std::cout << "CallGraphDFSolver::atDGraphNode, changed = "
00239                            << changed << std::endl;
00240     }
00241 
00242     return changed;
00243 }
00244 
00245   
00246 //--------------------------------------------------------
00247 // finalization upcalls
00248 //--------------------------------------------------------
00249 void 
00250 CallGraphDFSolver::finalizeNode(
00251     OA_ptr<DGraph::NodeInterface> node)
00252 {
00253 }
00254 
00255 void 
00256 CallGraphDFSolver::finalizeEdge(
00257     OA_ptr<DGraph::EdgeInterface> edge)
00258 {
00259 }
00260 
00261 //--------------------------------------------------------
00262 // debugging upcall 
00263 //--------------------------------------------------------
00264 void CallGraphDFSolver::dump(std::ostream& os, 
00265     OA_ptr<IRHandlesIRInterface> ir)
00266 {
00267 }
00268  
00269 
00270 
00271   } // end of DataFlow namespace
00272 }  // end of OA namespace
00273 

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