ManagerICFGActive.cpp

Go to the documentation of this file.
00001 
00015 #include <iostream>
00016 #include "ManagerICFGActive.hpp"
00017 #include <Utils/Util.hpp>
00018 
00019 
00020 
00021 namespace OA {
00022   namespace Activity {
00023 
00024 static bool debug = false;
00025 
00026 ManagerICFGActive::ManagerICFGActive(
00027     OA_ptr<Activity::ActivityIRInterface> _ir) : mIR(_ir)
00028 {
00029     OA_DEBUG_CTRL_MACRO("DEBUG_ManagerICFGActive:ALL", debug);
00030     mSolver = new DataFlow::ICFGDFSolver(DataFlow::ICFGDFSolver::Backward,*this);
00031 }
00032 
00039 OA_ptr<InterActive> 
00040 ManagerICFGActive::performAnalysis(
00041         OA_ptr<ICFG::ICFGInterface> icfg,
00042         OA_ptr<DataFlow::ParamBindings> paramBind,
00043         OA_ptr<Alias::InterAliasInterface> interAlias,
00044         OA_ptr<SideEffect::InterSideEffectInterface> interSE,
00045         DataFlow::DFPImplement algorithm)
00046 {
00047   OA_ptr<InterActive> retval;
00048   retval = new InterActive;
00049 
00050   // create a Manager that generates dep information for each statement in
00051   // ICFG
00052   OA_ptr<ManagerICFGDep> depman;
00053   depman = new ManagerICFGDep(mIR);
00054   OA_ptr<ICFGDep> icfgDep = depman->performAnalysis(icfg, paramBind,
00055                                                     interAlias,
00056                                                     algorithm);
00057 
00058   if (debug) { icfgDep->output(*mIR); }
00059 
00060  
00061   if (debug) {
00062       std::cout << "Calling usefulman->performAnalysis() ...\n";
00063       std::cout.flush();
00064   }
00065 
00066   OA_ptr<ManagerICFGUseful> usefulman;
00067   usefulman = new ManagerICFGUseful(mIR);
00068   OA_ptr<InterUseful> 
00069     interUseful = usefulman->performAnalysis(icfg, paramBind, interAlias, 
00070                                              interSE, icfgDep,
00071                                              algorithm);
00072 
00073   retval->setNumIterUseful(interUseful->getNumIter());
00074   if (debug) { interUseful->output(*mIR); }
00075   
00076   // ManagerICFGVaryActive does vary analysis and determines which
00077   // locations are active coming Into a stmt and Outof a stmt
00078   if (debug) {
00079       std::cout << "Calling varyman->performAnalysis() ...\n";
00080       std::cout.flush();
00081   }
00082 
00083   OA_ptr<ManagerICFGVaryActive> varyman;
00084   varyman = new ManagerICFGVaryActive(mIR);
00085   OA_ptr<ActivePerStmt> active = varyman->performAnalysis(icfg, paramBind,
00086           interAlias, icfgDep, interUseful,algorithm);
00087 
00088   retval->setNumIterVary(active->getNumIter());
00089   if (debug) { active->output(*mIR); }
00090   
00091   
00092   //-------------------------------------------------------------
00093   // Do backward dataflow analysis to determine which def memrefs
00094   // and stmts are active
00095   
00096   // store results that will be needed in callbacks
00097   mICFG = icfg;
00098   mParamBind = paramBind;
00099   mICFGDep = icfgDep;
00100   mInterAlias = interAlias;
00101   mActive = active;
00102 
00103   // call iterative data-flow solver for ICFG
00104   mSolver->solve(icfg,algorithm);
00105 
00106   // then iterate over each statement to find active use memrefs
00107 
00185   // For each ICFG node:
00186   OA_ptr<ICFG::NodesIteratorInterface> nodeIter = 
00187     icfg->getICFGNodesIterator();
00188   for ( ; nodeIter->isValid(); (*nodeIter)++) {
00189 
00190     OA_ptr<ICFG::NodeInterface> icfgNode = nodeIter->currentICFGNode();
00191 
00192     // get alias and active results for current procedure
00193     ProcHandle proc = icfgNode->getProc();
00194     OA_ptr<Alias::Interface> alias = interAlias->getAliasResults(proc);
00195     OA_ptr<ActiveStandard> active = mActiveMap[proc];
00196 
00197     // For each stmt in the ICFG node:
00198     OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIter =
00199       icfgNode->getNodeStatementsIterator();
00200     for ( ; stmtIter->isValid(); (*stmtIter)++) {
00201       StmtHandle stmt = stmtIter->current();
00202 
00203       // if this is an active statement, mark all inVaryMemRefs as active
00204       if (active->isActive(stmt)) {
00205 
00206         OA_ptr<MemRefHandleIterator> useIter = mIR->getUseMemRefs(stmt);
00207         for (; useIter->isValid(); (*useIter)++ ) {
00208           MemRefHandle use = useIter->current();
00209           if (debug) {
00210             std::cout << "\tuse = ";
00211             mIR->dump(use,std::cout);
00212           }
00213           
00214           // iterate over locations that are active anywhere
00215           // in procedure, flow-insensitive active locations
00216           OA_ptr<LocIterator> procActiveLocIter 
00217             = active->getActiveLocsIterator();
00218           for ( ; procActiveLocIter->isValid(); (*procActiveLocIter)++ ) {
00219             OA_ptr<Location> activeLoc = procActiveLocIter->current();
00220             if (debug) { 
00221               std::cout << "\t activeLoc = ";
00222               activeLoc->dump(std::cout,mIR);
00223             }
00224             
00225             // iterate over may locs for use
00226             OA_ptr<LocIterator> mayLocIter = alias->getMayLocs(use);
00227             for ( ; mayLocIter->isValid(); (*mayLocIter)++ ) {
00228               OA_ptr<Location> useLoc = mayLocIter->current();
00229               if (debug) { 
00230                 std::cout << "\t\t may loc for use, useLoc = ";
00231                 useLoc->dump(std::cout,mIR);
00232               }
00233               if (activeLoc->mayOverlap(*useLoc)) {
00234                 active->insertMemRef(use);
00235                 if (debug) {
00236                   std::cout << "\t\tinserting active memref use = ";
00237                   mIR->dump(use,std::cout);
00238                   std::cout << std::endl;
00239                 }
00240 
00241               } // if active loc mayOverlap the mayloc of the use memref
00242                 // then use memref is set active
00243 
00244             } // for each mayloc of the use memref
00245 
00246           } // for each active locations anywhere in the procedure
00247 
00248         } // iterate over use memrefs
00249         
00250       } // if active stmt
00251        
00252     } // for each stmt in the icfg node 
00253 
00254   } // for each icfg node
00255 
00256 
00257 
00258 
00259 
00260 
00261   // assign activity results for each procedure into InterActive
00262   std::map<ProcHandle,OA_ptr<ActiveStandard> >::iterator mapIter;
00263   for (mapIter=mActiveMap.begin(); mapIter!=mActiveMap.end(); mapIter++) {
00264     retval->mapProcToActive(mapIter->first,mapIter->second);
00265   }
00266 
00267   // how many iterations did this take?
00268   if (debug) 
00269     {
00270       std::cout << "ICFGActive took " << mSolver->getNumIter()
00271                 << " iterations.\n";
00272     }
00273 
00274   retval->setNumIterActive(mSolver->getNumIter());
00275 
00276   return retval;
00277 }
00278 
00279 //========================================================
00280 // implementation of ICFGDFProblem interface
00281 //========================================================
00282 //--------------------------------------------------------
00283 // initialization callbacks
00284 //--------------------------------------------------------
00285 
00290 OA_ptr<DataFlow::DataFlowSet> ManagerICFGActive::initializeTop()
00291 {
00292   OA_ptr<DataFlow::LocDFSet> retval;
00293   retval = new DataFlow::LocDFSet;
00294   return retval;
00295 }
00296 
00297 OA_ptr<DataFlow::DataFlowSet> 
00298 ManagerICFGActive::initializeNodeIN(OA_ptr<ICFG::NodeInterface> n)
00299 {
00300   OA_ptr<DataFlow::LocDFSet> retval;
00301   retval = new DataFlow::LocDFSet;
00302   return retval;
00303 }
00304 
00305 OA_ptr<DataFlow::DataFlowSet> 
00306 ManagerICFGActive::initializeNodeOUT(OA_ptr<ICFG::NodeInterface> n)
00307 {
00308   OA_ptr<DataFlow::LocDFSet> retval;
00309   retval = new DataFlow::LocDFSet;
00310   return retval;
00311 }
00312 
00313 
00314 //--------------------------------------------------------
00315 // solver callbacks 
00316 //--------------------------------------------------------
00317   
00320 OA_ptr<DataFlow::DataFlowSet> 
00321 ManagerICFGActive::meet(OA_ptr<DataFlow::DataFlowSet> set1, 
00322                       OA_ptr<DataFlow::DataFlowSet> set2)
00323 {
00324     // just return in set
00325     return set1;
00326 }
00327 
00330 OA_ptr<DataFlow::DataFlowSet> 
00331 ManagerICFGActive::transfer(ProcHandle proc,
00332                         OA_ptr<DataFlow::DataFlowSet> out, OA::StmtHandle stmt)
00333 {    
00334   
00335   // ignoring data flow, using outActiveSet from previous analysis
00336     OA_ptr<DataFlow::LocDFSet> outRecast =  mActive->getOutActiveSet(stmt);
00337 
00338     if (debug) {
00339         std::cout << "In transfer, stmt(hval=" << stmt.hval() << ")= ";
00340         mIR->dump(stmt,std::cout);
00341         std::cout << "\toutRecast = ";
00342         outRecast->dump(std::cout,mIR);
00343     }
00344 
00345     // will be storing activity results for stmt and memrefs in
00346     // ActiveStandard for current procedure
00347     if (mActiveMap[proc].ptrEqual(0)) {
00348         mActiveMap[proc] = new ActiveStandard(proc);
00349     }
00350         
00351     // get alias and active results for current procedure
00352     OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(proc);
00353     OA_ptr<ActiveStandard> active = mActiveMap[proc];
00354 
00355     // iterate over def mem refs and if any of them access a location
00356     // that is in the out active set then the mem ref is active and so
00357     // is the stmt
00358     bool activeStmt = false;
00359     OA_ptr<MemRefHandleIterator> defIter = mIR->getDefMemRefs(stmt);
00360     for (; defIter->isValid(); (*defIter)++ ) {
00361         MemRefHandle def = defIter->current();
00362         if (debug) {
00363           std::cout << "\tdef = ";
00364           mIR->dump(def,std::cout);
00365         }
00366 
00367         bool activeMemRef = false;
00368         // loop over may locs for the memref
00369         OA_ptr<LocIterator> locIter = alias->getMayLocs(def);
00370         for ( ; locIter->isValid()&&!activeMemRef; (*locIter)++ ) {
00371           OA_ptr<Location> loc = locIter->current();
00372           if (debug) { 
00373             std::cout << "\t\t mayloc for def = ";
00374             loc->dump(std::cout,mIR);
00375           }
00376 
00377           // if at least one may loc of this def overlaps with
00378           // something in the active set ... then we know
00379           // that this def is active, and we know
00380           // that this stmt is active as well.
00381           if (outRecast->hasOverlapLoc(loc)) {
00382             active->insertMemRef(def);
00383 
00384             // don't need to look at any more mayLocs, since we
00385             // already know that this def is active ... set flag
00386             activeMemRef = true;
00387 
00388             if (!activeStmt) { 
00389               // now we know it is, insert and set flag
00390               active->insertStmt(stmt);
00391               activeStmt = true;
00392             }
00393           }
00394         }
00395     } 
00396 
00397     // since we are ignoring in/out data flow sets, only one iteration
00398     // iterate through all of the active locations that come into this
00399     // statement and insert those locations as active within the
00400     // procedure
00401     OA_ptr<DataFlow::LocDFSet> inActiveSet = mActive->getInActiveSet(stmt);
00402     OA_ptr<LocIterator> locIter = inActiveSet->getLocIterator();
00403     for ( ; locIter->isValid(); (*locIter)++ ) {
00404         active->insertLoc(locIter->current());
00405     } 
00406 
00407     // If we are ignoring the incoming set (see comments at top of transfer)
00408     // upshot:  cuts the iterations by one. (no impact on correct output)
00409     return out;
00410 }
00411 
00416 OA_ptr<DataFlow::DataFlowSet> 
00417 ManagerICFGActive::entryTransfer(ProcHandle proc, OA_ptr<DataFlow::DataFlowSet> in)
00418 {
00419     return in;
00420 }
00421 
00424 OA_ptr<DataFlow::DataFlowSet> 
00425 ManagerICFGActive::exitTransfer(ProcHandle proc, OA_ptr<DataFlow::DataFlowSet> out)
00426 {
00427     return out;
00428 }
00429 
00430 
00432 OA_ptr<DataFlow::DataFlowSet> 
00433 ManagerICFGActive::callerToCallee(ProcHandle caller,
00434     OA_ptr<DataFlow::DataFlowSet> dfset, CallHandle call, ProcHandle callee)
00435 {
00436   // no data flow for this analysis ... returning in set
00437   return dfset;
00438 }
00439   
00441 OA_ptr<DataFlow::DataFlowSet> 
00442 ManagerICFGActive::calleeToCaller(ProcHandle callee,
00443     OA_ptr<DataFlow::DataFlowSet> dfset, CallHandle call, ProcHandle caller)
00444 {
00445   // no data flow for this analysis ... returning in set
00446   return dfset;
00447 }
00448 
00450 OA_ptr<DataFlow::DataFlowSet>
00451 ManagerICFGActive::callToReturn(ProcHandle caller,
00452     OA_ptr<DataFlow::DataFlowSet> dfset, CallHandle call, ProcHandle callee)
00453 {
00454   // no data flow for this analysis ... returning in set
00455   return dfset;
00456 }
00457 
00458   } // end of namespace Activity
00459 } // end of namespace OA