ManagerReachDefsStandard.cpp

Go to the documentation of this file.
00001 
00017 #include "ManagerReachDefsStandard.hpp"
00018 
00019 
00020 namespace OA {
00021   namespace ReachDefs {
00022 
00023 static bool debug = false;
00024 
00025 
00028 ManagerReachDefsStandard::ManagerReachDefsStandard(OA_ptr<ReachDefsIRInterface> _ir) 
00029     : mIR(_ir)
00030 {
00031    mSolver = new DataFlow::CFGDFSolver(DataFlow::CFGDFSolver::Forward,*this);
00032 }
00033 
00034 OA_ptr<DataFlow::DataFlowSet> ManagerReachDefsStandard::initializeTop()
00035 {
00036     OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> >  retval;
00037     retval = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00038     return retval;
00039 }
00040 
00041 OA_ptr<DataFlow::DataFlowSet> ManagerReachDefsStandard::initializeBottom()
00042 {
00043     OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> >  retval;
00044     retval = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00045     return retval;
00046 }
00047 
00055 OA_ptr<ReachDefsStandard> ManagerReachDefsStandard::performAnalysis(ProcHandle proc, 
00056     OA_ptr<CFG::CFGInterface> cfg, OA_ptr<Alias::Interface> alias,
00057     OA_ptr<SideEffect::InterSideEffectInterface> interSE,
00058     DataFlow::DFPImplement algorithm)
00059 {
00060   if (debug) {
00061     std::cout << "In ReachDefs::ManagerReachDefsStandard::performAnalysis" << std::endl;
00062   }
00063   mReachDefMap = new ReachDefsStandard(proc);
00064 
00065   // store Alias information for use within the transfer function
00066   mAlias = alias;
00067 
00068   // get mapping of statements to locations they may and must define
00069   OA_ptr<OA::IRStmtIterator> sIt = mIR->getStmtIterator(proc);
00070   for ( ; sIt->isValid(); (*sIt)++) {
00071     OA::StmtHandle stmt = sIt->current();
00072     if (debug) {
00073       std::cout<< "\tstmt (" << stmt.hval() << ") = ";
00074       mIR->dump(stmt,std::cout);
00075     } 
00076     
00077     // initialize each stmt to define an empty set of locations
00078     mStmtMustDefMap[stmt];
00079     mStmtMayDefMap[stmt];
00080 
00081     // locations that each statement may or must def
00082     OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(stmt);
00083     for (; defIterPtr->isValid(); (*defIterPtr)++) {
00084         MemRefHandle ref = defIterPtr->current();
00085         if (debug) {
00086           std::cout << "\t\tdef ref (" << ref.hval() << ") = ";
00087           mIR->dump(ref,std::cout);
00088         }
00089 
00090         OA_ptr<LocIterator> locIterPtr = alias->getMustLocs(ref);
00091         for (; locIterPtr->isValid(); ++(*locIterPtr)) {
00092             mStmtMustDefMap[stmt].insert(locIterPtr->current());
00093         }
00094 
00095         locIterPtr = alias->getMayLocs(ref);
00096         for (; locIterPtr->isValid(); ++(*locIterPtr)) {
00097             mStmtMayDefMap[stmt].insert(locIterPtr->current());
00098         }
00099     }
00100  
00101     // must or may defines from procedure calls
00102     OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(stmt);
00103     for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00104       CallHandle expr = callsiteItPtr->current();
00105 
00106       OA_ptr<LocIterator> locIterPtr;
00107       
00108       // MOD
00109       locIterPtr = interSE->getMODIterator(expr);
00110       for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00111           OA_ptr<Location> modLocPtr = locIterPtr->current();
00112           mStmtMayDefMap[stmt].insert(modLocPtr);
00113       }
00114       
00115       // DEF
00116       locIterPtr = interSE->getDEFIterator(expr);
00117       for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00118           OA_ptr<Location> defLocPtr = locIterPtr->current();
00119           mStmtMustDefMap[stmt].insert(defLocPtr);
00120       }
00121     }
00122 
00123   } // loop over statements
00124 
00125   // use the dataflow solver to get the In and Out sets for the BBs
00126   //DataFlow::CFGDFProblem::solve(cfg);
00127   //
00128   mSolver->solve(cfg,algorithm);  
00129   
00130   // get exit node for CFG and determine what definitions reach that node
00131   OA_ptr<CFG::NodeInterface> node;
00132   
00133   node = cfg->getExit();
00134 
00135   OA_ptr<DataFlow::DataFlowSet> x = mSolver->getOutSet(node);
00136       //mNodeInSetMap[node];
00137   OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> > inSet 
00138     = x.convert<DataFlow::IRHandleDataFlowSet<StmtHandle> >();
00139 
00140   DataFlow::IRHandleIterator<StmtHandle> rdIter(inSet);
00141   for (; rdIter.isValid(); ++rdIter) {
00142       StmtHandle reachDef = rdIter.current();
00143       mReachDefMap->insertExitReachDef(reachDef);
00144   }
00145   return mReachDefMap;
00146 
00147 }
00148 
00149 //------------------------------------------------------------------
00150 // Implementing the callbacks for CFGDFProblem
00151 //------------------------------------------------------------------
00152 /*void ManagerReachDefsStandard::initializeNode(OA_ptr<CFG::Interface::Node> n)
00153 {
00154     mNodeInSetMap[n] = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00155     mNodeOutSetMap[n] = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00156 }
00157 */
00158 
00162 OA_ptr<DataFlow::DataFlowSet>
00163 ManagerReachDefsStandard::initializeNodeIN(OA_ptr<CFG::NodeInterface> n)
00164 {
00165      OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> >  retval;
00166      retval = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00167      return retval;
00168 }
00169 
00170 OA_ptr<DataFlow::DataFlowSet>
00171 ManagerReachDefsStandard::initializeNodeOUT(OA_ptr<CFG::NodeInterface> n)
00172 {
00173      OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> >  retval;
00174      retval = new DataFlow::IRHandleDataFlowSet<StmtHandle>;
00175      return retval;
00176 }
00177 
00178 
00179 
00180 OA_ptr<DataFlow::DataFlowSet> 
00181 ManagerReachDefsStandard::meet (OA_ptr<DataFlow::DataFlowSet> set1orig, 
00182                        OA_ptr<DataFlow::DataFlowSet> set2orig)
00183 {
00184     OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> > set1
00185         = set1orig.convert<DataFlow::IRHandleDataFlowSet<StmtHandle> >();
00186     if (debug) {
00187         std::cout << "ManagerReachDefsStandard::meet" << std::endl;
00188         std::cout << "\tset1 = ";
00189         set1->dump(std::cout,mIR);
00190         std::cout << ", set2 = ";
00191         set2orig->dump(std::cout,mIR);
00192     }
00193        
00194     DataFlow::IRHandleDataFlowSet<StmtHandle> retval 
00195         = set1->setUnion(*set2orig);
00196     if (debug) {
00197         std::cout << std::endl << "\tretval set = ";
00198         retval.dump(std::cout,mIR);
00199         std::cout << std::endl;
00200     }
00201        
00202     return retval.clone();
00203 }
00204 
00215 OA_ptr<DataFlow::DataFlowSet> 
00216 ManagerReachDefsStandard::transfer(OA_ptr<DataFlow::DataFlowSet> in, OA::StmtHandle stmt) 
00217 {
00218     OA_ptr<DataFlow::IRHandleDataFlowSet<StmtHandle> > inRecast 
00219         = in.convert<DataFlow::IRHandleDataFlowSet<StmtHandle> >();
00220 
00221     if (debug) {
00222         std::cout << "In transfer, stmt(hval=" << stmt.hval() << ")= ";
00223         mIR->dump(stmt,std::cout);
00224     }
00225         
00226     
00227     // KILL: will kill all statements that may have defined 
00228     // locations that this statement must defines
00229          
00230     // for each stmt that is a reaching definition
00231     DataFlow::IRHandleIterator<StmtHandle> inIter(inRecast);
00232     for (; inIter.isValid(); ) {
00233         StmtHandle reachdef = inIter.current();
00234         if (debug) {
00235           std::cout << "\treachdef in Inset = ";
00236           mIR->dump(reachdef,std::cout);
00237         }
00238 
00239         // insert reachDef into results
00240         mReachDefMap->insertReachDef(stmt,reachdef);
00241 
00242         // get set of locations that were may defed in reaching definition
00243         // and are must defed in the current stmt
00244         OA_ptr<std::set<OA_ptr<Location> > > killLocSetPtr 
00245             = intersectLocSets(mStmtMayDefMap[reachdef],
00246                                          mStmtMustDefMap[stmt]);
00247 
00248         if (debug) {
00249           std::cout << "\tMayDefs for reachdef = ";
00250           dumpLocSet(mStmtMayDefMap[reachdef],std::cout,mIR);
00251           std::cout << "\tMustDefs for stmt(hval=" << stmt.hval() << ")= ";
00252           dumpLocSet(mStmtMustDefMap[stmt],std::cout,mIR);
00253           std::cout << "\tkillLocSet for stmt(hval=" << stmt.hval() << "(= ";
00254           dumpLocSet(*killLocSetPtr,std::cout,mIR);
00255         }
00256 
00257         // if that set is nonempty and a superset of all the 
00258         // may defs in the reaching definition then we will go 
00259         // ahead and kill the reach def
00260         if ( !killLocSetPtr->empty() 
00261              && subSetOf(mStmtMayDefMap[reachdef],*killLocSetPtr) ) 
00262         {
00263             ++inIter ;
00264             if (debug) {
00265               std::cout << "\tStmt in Kill set: ";
00266               mIR->dump(reachdef,std::cout);
00267             }
00268             // delete statement that is in the kill subset
00269             inRecast->remove(reachdef);
00270         } else {
00271             ++inIter;
00272         }
00273     }
00274 
00275     // DEF: if this statement has any defs then it is put into the
00276     //      set of reaching definitions
00277 
00278     if (!mStmtMayDefMap[stmt].empty()) {
00279         // put into dataflow set as a reaching definition
00280         inRecast->insert(stmt);
00281         if (debug) {
00282           std::cout << "\tStmt in Def set: ";
00283           mIR->dump(stmt,std::cout);
00284         }
00285     }
00286 
00287     return inRecast;
00288 }
00289 
00290   } // end of namespace ReachDefs
00291 } // end of namespace OA