ICFGDFSolver.cpp

Go to the documentation of this file.
00001 
00015 #include "ICFGDFSolver.hpp"
00016 #include <Utils/Util.hpp>
00017 
00018 namespace OA {
00019   namespace DataFlow {
00020 
00021 static bool debug = false;
00022 
00023 ICFGDFSolver::ICFGDFSolver(DFDirectionType pDirection, ICFGDFProblem& prob)
00024     : mDirection(pDirection), mDFProb(prob)
00025 {
00026     OA_DEBUG_CTRL_MACRO("DEBUG_ICFGDFSolver", debug);
00027 }
00028 
00029 void
00030 ICFGDFSolver::solve(OA_ptr<ICFG::ICFGInterface> icfg, DFPImplement algorithm)
00031 {
00032     // remove all mappings of nodes to data flow sets 
00033     mNodeInSetMap.clear();
00034     mNodeOutSetMap.clear();
00035     mNodeInitTransApp.clear();
00036 
00037     mTop = mDFProb.initializeTop();
00038 
00039     DataFlow::DGraphSolverDFP::solve(icfg, 
00040             ((mDirection==Forward) ? DGraph::DEdgeOrg : DGraph::DEdgeRev),
00041             algorithm);
00042 
00043     /*
00044     // if forward then return DataFlowSet for exit
00045     if (mDirection==Forward) {
00046         OA_ptr<ICFG::ICFGStandard::Node> exitnode = icfg->getExit();
00047         return mNodeInSetMap[exitnode];
00048 
00049     // if backward then return DataFlowSet for entry
00050     } else {
00051         OA_ptr<ICFG::ICFGStandard::Node> entrynode = icfg->getEntry();
00052         return mNodeOutSetMap[entrynode];
00053     }
00054     */
00055 }
00056   
00057 //========================================================
00058 // implementation of DGraphIterativeDFP callbacks
00059 //========================================================
00060   
00061 //--------------------------------------------------------
00062 // initialization upcall 
00063 //--------------------------------------------------------
00064 
00065 
00094 void ICFGDFSolver::initialize(OA_ptr<DGraph::DGraphInterface> dg)
00095 {
00096     OA_ptr<ICFG::ICFGInterface> cfg = dg.convert<ICFG::ICFGInterface>();
00097 
00098     // iterate over all nodes and call initialization routine
00099     // that sets up DataFlowSets
00100     OA_ptr<ICFG::NodesIteratorInterface> nodeIterPtr;
00101     nodeIterPtr = cfg->getICFGNodesIterator();
00102     if (debug) {
00103       std::cout << "initializing:  looping over nodes:\n";
00104     }
00105     for ( ;nodeIterPtr->isValid(); ++(*nodeIterPtr) ) {
00106       if (debug) {
00107         std::cout << "\tNode " << (nodeIterPtr->current())->getId()
00108                   << std::endl;
00109       }
00110       OA_ptr<ICFG::NodeInterface> iNode = nodeIterPtr->currentICFGNode();
00111       mNodeInSetMap[iNode]
00112         = mDFProb.initializeNodeIN(iNode);
00113       mNodeOutSetMap[iNode]
00114         = mDFProb.initializeNodeOUT(iNode);
00115       mNodeInitTransApp[iNode] = false;
00116     }
00117 }
00118 
00119 
00120 //--------------------------------------------------------
00121 // solver upcalls
00122 //--------------------------------------------------------
00123 bool ICFGDFSolver::atDGraphNode( OA_ptr<DGraph::NodeInterface> pNode, 
00124                                  DGraph::DGraphEdgeDirection pOrient)
00125 {
00126     bool changed = false;
00127     OA_ptr<ICFG::NodeInterface> node 
00128         = pNode.convert<OA::ICFG::NodeInterface>();
00129 
00130     if (debug) {
00131         std::cout << "ICFGDFSolver::atDGraphNode: ICFG node = ";
00132         std::cout << node->getId() << std::endl;
00133     }
00134 
00135     //-----------------------------------------------------
00136     // do a meet of all out information from nodes that are
00137     // predecessors with current input for this node
00138     // based on the flow direction, edge type,
00139     // and node type
00140     // FIXME: Have to meet with current input for this node because
00141     // of ReachConsts?
00142     //-----------------------------------------------------
00143     OA_ptr<DataFlowSet> meetPartialResult = mTop->clone();
00144     if (pOrient==DGraph::DEdgeOrg) {
00145       meetPartialResult = mDFProb.meet(meetPartialResult,mNodeInSetMap[node]);
00146     } else {
00147       meetPartialResult = mDFProb.meet(meetPartialResult,mNodeOutSetMap[node]);
00148     }
00149 
00150     // set up iterator for predecessor edges
00151     OA_ptr<ICFG::EdgesIteratorInterface> predIterPtr;
00152     if (pOrient==DGraph::DEdgeOrg) {
00153       predIterPtr = node->getICFGIncomingEdgesIterator();
00154     } else {
00155       predIterPtr = node->getICFGOutgoingEdgesIterator();
00156     }
00157     // iterate over predecessors and do meet operation
00158     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
00159       OA_ptr<ICFG::EdgeInterface> predEdge = predIterPtr->currentICFGEdge();
00160       OA_ptr<ICFG::NodeInterface> predNode;
00161       OA_ptr<DataFlowSet> inSet;
00162       if (pOrient==DGraph::DEdgeOrg) {
00163         OA_ptr<ICFG::NodeInterface> predNode = predEdge->getICFGSource();
00164         switch(predEdge->getType()) {
00165             case (ICFG::CALL_EDGE):
00166                 // mNodeInSet because only get to use data-flow set before call
00167                 // in caller
00168                 inSet = mDFProb.callerToCallee(predEdge->getSourceProc(),
00169                             mNodeInSetMap[predNode], predEdge->getCall(),
00170                             predEdge->getSinkProc());
00171                 break;
00172             case (ICFG::RETURN_EDGE):
00173                 inSet = mDFProb.calleeToCaller(predEdge->getSourceProc(),
00174                             mNodeOutSetMap[predNode], predEdge->getCall(),
00175                             predEdge->getSinkProc());
00176                 break;
00177             case (ICFG::CALL_RETURN_EDGE):
00178               // has same parameter order as callerToCallee() for now
00179               // but will need to be changed when callToReturn is 
00180               // revisited.  Currently, only LocDFSet is used.
00181                 inSet = mDFProb.callToReturn(predEdge->getSourceProc(),
00182                             mNodeInSetMap[predNode], predEdge->getCall(),
00183                             predEdge->getSinkProc());
00184                 break;
00185             case (ICFG::CFLOW_EDGE):
00186                 inSet = mNodeOutSetMap[predNode];
00187                 break;
00188         }
00189         if (debug) {
00190           std::cout << "performing forward meet with pred node " 
00191                     << predNode->getId() << std::endl;
00192         }                                              
00193         meetPartialResult = mDFProb.meet(meetPartialResult, inSet);
00194 
00195       // backward flow
00196       } else {
00197         OA_ptr<ICFG::NodeInterface> predNode = predEdge->getICFGSink();
00198         switch(predEdge->getType()) {
00199             case (ICFG::CALL_EDGE):
00200                 inSet = mDFProb.calleeToCaller(predEdge->getSinkProc(),
00201                             mNodeInSetMap[predNode], predEdge->getCall(),
00202                             predEdge->getSourceProc());
00203                 break;
00204             case (ICFG::RETURN_EDGE):
00205                 // use outset for RETURN_NODE in caller
00206                 inSet = mDFProb.callerToCallee(predEdge->getSinkProc(),
00207                             mNodeOutSetMap[predNode], predEdge->getCall(),
00208                             predEdge->getSourceProc());
00209                 break;
00210             case (ICFG::CALL_RETURN_EDGE):
00211               // has same parameter order as callerToCallee() for now
00212               // but will need to be changed when callToReturn is 
00213               // revisited.  Currently, only LocDFSet is used.
00214                 inSet = mDFProb.callToReturn(predEdge->getSinkProc(),
00215                             mNodeOutSetMap[predNode], predEdge->getCall(),
00216                             predEdge->getSourceProc());
00217                 break;
00218             case (ICFG::CFLOW_EDGE):
00219                 inSet = mNodeInSetMap[predNode];
00220                 break;
00221         }
00222         if (debug) {
00223           std::cout << "performing backward meet with succ node " 
00224                     << predNode->getId() << std::endl;
00225         }                                              
00226         meetPartialResult = mDFProb.meet(meetPartialResult, inSet);
00227       }
00228     }
00229 
00230     // update the appropriate set for this node
00231     if (pOrient==DGraph::DEdgeOrg) { // forward
00232       if ( mNodeInSetMap[node] != meetPartialResult ) {
00233         mNodeInSetMap[node] = meetPartialResult;
00234         changed = true;
00235       }
00236     } else { // reverse
00237       if ( mNodeOutSetMap[node] != meetPartialResult ) {
00238         mNodeOutSetMap[node] = meetPartialResult;
00239         changed = true;
00240       }
00241     }
00242 
00243     // if the data flowing into this node has changed or if the
00244     // transfer functions have never been applied, then
00245     // loop through statements in the CFG node/(Basic Block) 
00246     // calculating the new node out
00247     if (debug) {
00248       std::cout << "\tchanged = " << changed << ", mNITA[node]=" 
00249                 << mNodeInitTransApp[node] << std::endl;
00250     }
00251     if (changed || !mNodeInitTransApp[node]) {
00252       changed = false;  // reuse to determine if there is a change based
00253                         // on the block transfer function
00254       mNodeInitTransApp[node] = true;
00255 
00256       // Forward direction
00257       if (pOrient==DGraph::DEdgeOrg) {
00258         OA_ptr<DataFlowSet> prevOut = mNodeInSetMap[node]->clone();
00259 
00260         // call transfer methods based on what kind of node 
00261         if (node->getType()==ICFG::ENTRY_NODE) {
00262             prevOut = mDFProb.entryTransfer(node->getProc(), prevOut);
00263 
00264         // otherwise it is a normal node and should apply regular transfer
00265         // loop through statements in forward order
00266         } else {
00267             OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIterPtr 
00268                 = node->getNodeStatementsIterator();
00269             for (; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00270                 OA::StmtHandle stmt = stmtIterPtr->current();
00271                 prevOut = mDFProb.transfer(node->getProc(), prevOut, stmt);
00272             }
00273         }
00274 
00275         if (prevOut != mNodeOutSetMap[node] ) {
00276           changed = true;
00277           mNodeOutSetMap[node] = prevOut;
00278         }
00279       
00280       // Reverse direction
00281       } else { 
00282         OA_ptr<DataFlowSet> prevIn = mNodeOutSetMap[node]->clone();
00283         
00284         // if it is an exit node call transfer method for exit nodes
00285         if (node->getType()==ICFG::EXIT_NODE) {
00286             prevIn = mDFProb.exitTransfer(node->getProc(), prevIn);
00287 
00288         // otherwise it is a normal node and should apply regular transfer
00289         } else {
00290             // loop through statements in reverse order
00291             OA_ptr<CFG::NodeStatementsRevIteratorInterface> stmtIterPtr 
00292                 = node->getNodeStatementsRevIterator();
00293             if (debug) {
00294               std::cout << "looping through statements in reverse order:\n";
00295             }
00296             for (; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00297                 OA::StmtHandle stmt = stmtIterPtr->current();
00298                 if (debug) {
00299                   std::cout << "\tstmt.hval(" << stmt.hval() << ")\n";
00300                 }
00301                 prevIn = mDFProb.transfer(node->getProc(), prevIn, stmt);
00302                 
00303             }
00304         }
00305 
00306         if (prevIn != mNodeInSetMap[node] ) {
00307           changed = true;
00308           mNodeInSetMap[node] = prevIn;
00309         }
00310       }
00311 
00312     }
00313    
00314     if (debug) {
00315       std::cout << "ICFGDFSolver::atDGraphNode: changed = " << changed 
00316                 << std::endl;
00317     }
00318     return changed;
00319 }
00320   
00321 //--------------------------------------------------------
00322 // finalization upcalls
00323 //--------------------------------------------------------
00324 void 
00325 ICFGDFSolver::finalizeNode(OA_ptr<DGraph::NodeInterface> node)
00326 {
00327 }
00328 
00329 
00330 
00331 //--------------------------------------------------------
00332 // debugging upcall 
00333 //--------------------------------------------------------
00334 void ICFGDFSolver::dump(std::ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00335 {
00336     // iterate over all entries in mNodeInSetMap and mNodeOutSetMap
00337     std::map<OA_ptr<ICFG::NodeInterface>,
00338              OA_ptr<DataFlowSet> >::iterator mapIter;
00339     for (mapIter=mNodeInSetMap.begin(); mapIter!=mNodeInSetMap.end(); mapIter++)
00340     {
00341         OA_ptr<DataFlowSet> dfset = mapIter->second;
00342         os << "Node (" << mapIter->first << ") In: ";
00343         dfset->dump(os,ir);
00344         os << std::endl;
00345     }
00346     for (mapIter=mNodeOutSetMap.begin(); mapIter!=mNodeOutSetMap.end(); mapIter++)
00347     {
00348         OA_ptr<DataFlowSet> dfset = mapIter->second;
00349         os << "Node (" << mapIter->first << ") Out: ";
00350         dfset->dump(os,ir);
00351         os << std::endl;
00352     }
00353 }
00354 
00355   } // end of DataFlow namespace
00356 }  // end of OA namespace
00357 

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