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
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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 }
00056
00057
00058
00059
00060
00061
00062
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
00099
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
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
00137
00138
00139
00140
00141
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
00151 OA_ptr<ICFG::EdgesIteratorInterface> predIterPtr;
00152 if (pOrient==DGraph::DEdgeOrg) {
00153 predIterPtr = node->getICFGIncomingEdgesIterator();
00154 } else {
00155 predIterPtr = node->getICFGOutgoingEdgesIterator();
00156 }
00157
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
00167
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
00179
00180
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
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
00206 inSet = mDFProb.callerToCallee(predEdge->getSinkProc(),
00207 mNodeOutSetMap[predNode], predEdge->getCall(),
00208 predEdge->getSourceProc());
00209 break;
00210 case (ICFG::CALL_RETURN_EDGE):
00211
00212
00213
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
00231 if (pOrient==DGraph::DEdgeOrg) {
00232 if ( mNodeInSetMap[node] != meetPartialResult ) {
00233 mNodeInSetMap[node] = meetPartialResult;
00234 changed = true;
00235 }
00236 } else {
00237 if ( mNodeOutSetMap[node] != meetPartialResult ) {
00238 mNodeOutSetMap[node] = meetPartialResult;
00239 changed = true;
00240 }
00241 }
00242
00243
00244
00245
00246
00247 if (debug) {
00248 std::cout << "\tchanged = " << changed << ", mNITA[node]="
00249 << mNodeInitTransApp[node] << std::endl;
00250 }
00251 if (changed || !mNodeInitTransApp[node]) {
00252 changed = false;
00253
00254 mNodeInitTransApp[node] = true;
00255
00256
00257 if (pOrient==DGraph::DEdgeOrg) {
00258 OA_ptr<DataFlowSet> prevOut = mNodeInSetMap[node]->clone();
00259
00260
00261 if (node->getType()==ICFG::ENTRY_NODE) {
00262 prevOut = mDFProb.entryTransfer(node->getProc(), prevOut);
00263
00264
00265
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
00281 } else {
00282 OA_ptr<DataFlowSet> prevIn = mNodeOutSetMap[node]->clone();
00283
00284
00285 if (node->getType()==ICFG::EXIT_NODE) {
00286 prevIn = mDFProb.exitTransfer(node->getProc(), prevIn);
00287
00288
00289 } else {
00290
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
00323
00324 void
00325 ICFGDFSolver::finalizeNode(OA_ptr<DGraph::NodeInterface> node)
00326 {
00327 }
00328
00329
00330
00331
00332
00333
00334 void ICFGDFSolver::dump(std::ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00335 {
00336
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 }
00356 }
00357