ManagerInterSideEffectStandard.cpp

Go to the documentation of this file.
00001 
00019 #include "ManagerInterSideEffectStandard.hpp"
00020 #include <Utils/Util.hpp>
00021 
00022 
00023 namespace OA {
00024   namespace SideEffect {
00025 
00026 static bool debug = false;
00029 ManagerInterSideEffectStandard::ManagerInterSideEffectStandard(
00030   OA_ptr<InterSideEffectIRInterface> _ir) : mIR(_ir)
00031 {
00032   OA_DEBUG_CTRL_MACRO("DEBUG_ManagerInterSideEffectStandard:ALL", debug);
00033   mSolver = new DataFlow::CallGraphDFSolver(DataFlow::CallGraphDFSolver::BottomUp,*this);
00034   
00035 }
00036 
00044 class VisibleVisitor : public virtual LocationVisitor {
00045   private:
00046     std::set<SymHandle> mVisibleSymSet;
00047   public:
00048     bool mVisible;
00049 
00050     VisibleVisitor(std::set<SymHandle> pVisibleSymSet)
00051         : mVisibleSymSet(mVisibleSymSet), mVisible(true) {}
00052     ~VisibleVisitor() {}
00053     void visitNamedLoc(NamedLoc& loc) 
00054       { if (mVisibleSymSet.find(loc.getSymHandle()) != mVisibleSymSet.end())
00055         { mVisible = true; } else { mVisible = false; }
00056       }
00057     void visitUnnamedLoc(UnnamedLoc& loc) { mVisible = true; }
00058     void visitInvisibleLoc(InvisibleLoc& loc) { mVisible = true; }
00059     void visitUnknownLoc(UnknownLoc& loc) { mVisible = true; }
00060     void visitLocSubSet(LocSubSet& loc) { 
00061         // have this visitor visit the base location
00062         OA_ptr<Location> baseLoc = loc.getLoc();
00063         baseLoc->acceptVisitor(*this);
00064     }
00065 };
00066 
00067 
00075 OA_ptr<InterSideEffectStandard> 
00076 ManagerInterSideEffectStandard::performAnalysis(
00077         OA_ptr<CallGraph::CallGraphInterface> callGraph,
00078         OA_ptr<DataFlow::ParamBindings> paramBind,
00079         OA_ptr<Alias::InterAliasInterface> interAlias,
00080         OA_ptr<ManagerSideEffectStandard> intraMan,
00081         DataFlow::DFPImplement algorithm)
00082 {
00083   // create a new (waiting to be filled) InterSideEffectStandard as member
00084   mInterSideEffect = new InterSideEffectStandard();
00085 
00086   // save other things needed for analysis in member variables
00087   mParamBind = paramBind;
00088   mInterAlias = interAlias;
00089   mIntraMan = intraMan;
00090 
00091   // for all functions defined in IR create optimistic intraprocedural
00092   // side-effect results
00093   // NOTE: not using initializeNode because for this analysis we aren't
00094   // using the DataFlowSets being passed around
00095   OA_ptr<CallGraph::NodesIteratorInterface> nodeIterPtr;
00096   nodeIterPtr = callGraph->getCallGraphNodesIterator();
00097   for ( ; nodeIterPtr->isValid(); ++(*nodeIterPtr) ) {
00098       OA_ptr<CallGraph::NodeInterface> node = nodeIterPtr->currentCallGraphNode();
00099       ProcHandle proc = node->getProc();
00100       if (node->isDefined()) {
00101         // use optimistic intra side effect analysis results
00102         OA_ptr<SideEffectStandard> procSideEffect;
00103         procSideEffect= new SideEffectStandard();
00104 
00105         // empty out all the sets
00106         procSideEffect->emptyLMOD();
00107         procSideEffect->emptyMOD();
00108         procSideEffect->emptyLDEF();
00109         procSideEffect->emptyDEF();
00110         procSideEffect->emptyLUSE();
00111         procSideEffect->emptyUSE();
00112         procSideEffect->emptyLREF();
00113         procSideEffect->emptyREF();
00114 
00115         if(debug)
00116         {
00117           std ::cout << "ManagerInterSideEffectStandard:mapProcToSideEffect:proc" << mIR->toString(proc) << std::endl;
00118         }
00119 
00120 
00121         mInterSideEffect->mapProcToSideEffect(proc, procSideEffect);
00122 
00123       } 
00124 
00125   } // loop over nodes in call graph
00126 
00127   // use the CallGraph dataflow solver to visit procedures iteratively
00128   // and solve for side-effect sets for each function call
00129   //DataFlow::CallGraphDFProblemNew::solve(callGraph);
00130   mSolver->solve(callGraph,algorithm);
00131 
00132   return mInterSideEffect;
00133 }
00134 
00135 //========================================================
00136 // implementation of CallGraphDFProblemNew callbacks
00137 //========================================================
00138 //--------------------------------------------------------
00139 // initialization callbacks
00140 //--------------------------------------------------------
00145 OA_ptr<DataFlow::DataFlowSet> ManagerInterSideEffectStandard::initializeTop()
00146 {
00147     OA_ptr<DataFlow::CountDFSet> retval;
00148     retval = new DataFlow::CountDFSet;
00149     return retval;
00150 }
00151 
00154 OA_ptr<DataFlow::DataFlowSet>  
00155 ManagerInterSideEffectStandard::initializeBottom()
00156 {
00157     assert(0);
00158     OA_ptr<DataFlow::CountDFSet> retval;
00159     return retval;
00160 }
00161 
00163 OA_ptr<DataFlow::DataFlowSet> 
00164 ManagerInterSideEffectStandard::initializeNode(ProcHandle proc)
00165 {
00166     return initializeTop();
00167 }
00168 
00169 OA_ptr<DataFlow::DataFlowSet>
00170 ManagerInterSideEffectStandard::initializeNodeIN(OA_ptr<CallGraph::NodeInterface> n)
00171 {
00172 }
00173 
00174 OA_ptr<DataFlow::DataFlowSet>
00175 ManagerInterSideEffectStandard::initializeNodeOUT(OA_ptr<CallGraph::NodeInterface> n)
00176 {
00177 }
00178 
00179 
00182 OA_ptr<DataFlow::DataFlowSet> 
00183 ManagerInterSideEffectStandard::initializeEdge(CallHandle call, 
00184                                                  ProcHandle caller,
00185                                                  ProcHandle callee)
00186 {
00187     return initializeTop();
00188 }
00189 
00193 OA_ptr<DataFlow::DataFlowSet> 
00194 ManagerInterSideEffectStandard::initializeEdge(CallHandle call, 
00195                                                  ProcHandle caller,
00196                                                  SymHandle callee)
00197 {
00198     return initializeTop();
00199 }
00200 
00201 
00202 //--------------------------------------------------------
00203 // solver callbacks
00204 //--------------------------------------------------------
00205 
00208 OA_ptr<DataFlow::DataFlowSet> 
00209 ManagerInterSideEffectStandard::meet(OA_ptr<DataFlow::DataFlowSet> set1, 
00210                       OA_ptr<DataFlow::DataFlowSet> set2)
00211 {
00212     return set1->clone();
00213 }
00214 
00216 OA_ptr<DataFlow::DataFlowSet>
00217 ManagerInterSideEffectStandard::atCallGraphNode(
00218         OA_ptr<DataFlow::DataFlowSet> inSet, 
00219         OA::ProcHandle proc)
00220 {
00221     OA_ptr<DataFlow::CountDFSet> retval;
00222 
00223     if (debug) {
00224         std::cout << "ManagerInterSideEffectStandard::atCallGraphNode: ";
00225         std::cout << "proc = " << mIR->toString(proc) << std::endl;
00226     }
00227 
00228     // do intraprocedural side-effect analysis passing in 
00229     // interprocedural results we have so far
00230     OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(proc);
00231     OA_ptr<SideEffect::SideEffectStandard> sideEffect 
00232         = mIntraMan->performAnalysis(proc, alias, mInterSideEffect); 
00233     mInterSideEffect->mapProcToSideEffect(proc,sideEffect);
00234 
00235     if (debug) {
00236       std::cout << "\tIntra results ---------------" << std::endl;
00237       sideEffect->dump(std::cout,mIR);
00238     }
00239 
00240     // count how many locations are in all sets for this  procedure so we
00241     // can see if any are added
00242     int count = mInterSideEffect->getLocCount(proc);
00243     retval = new DataFlow::CountDFSet(count);
00244 
00245     return retval;
00246 }
00247 
00251 OA_ptr<DataFlow::DataFlowSet>
00252 ManagerInterSideEffectStandard::atCallGraphEdge(
00253         OA_ptr<DataFlow::DataFlowSet> inSet, 
00254         CallHandle call, ProcHandle caller, ProcHandle callee )
00255 {
00256     if (debug) {
00257        std::cout << "atCallGraphEdge::inSet = ";
00258        inSet->dump(std::cout, mIR);
00259     }
00260 
00261     if(debug) {
00262       std::cout << "CallHandle: " << mIR->toString(call) << std::endl; 
00263     }
00264     
00265     // initialize side-effect information for call to have all empty sets
00266     mInterSideEffect->initCallSideEffect(call);
00267 
00268     assert(callee != ProcHandle(0));
00269         
00270     // map callee results to caller results
00271     // iterate through each set of locations for callee and get set
00272     // of locations for call
00273     OA_ptr<DataFlow::CalleeToCallerVisitor> c2cVisitor; 
00274     c2cVisitor = new DataFlow::CalleeToCallerVisitor(callee, call, 
00275                                                      caller, mInterAlias, mParamBind, mIR);
00276     OA_ptr<LocIterator> locIterPtr;
00277     OA_ptr<LocIterator> callLocIterPtr;
00278 
00279     // LMOD
00280     locIterPtr = mInterSideEffect->getLMODIterator(callee);
00281     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00282       OA_ptr<Location> calleeLoc = locIterPtr->current();
00283       calleeLoc->acceptVisitor(*c2cVisitor);
00284       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00285       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00286                OA_ptr<Location> callLoc = callLocIterPtr->current();
00287            // Callee LMOD should go into the Caller MOD set.
00288                mInterSideEffect->insertMOD(call, callLoc);
00289       }
00290     }
00291     // MOD
00292     locIterPtr = mInterSideEffect->getMODIterator(callee);
00293     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00294       OA_ptr<Location> calleeLoc = locIterPtr->current();
00295       if (debug) { 
00296           std::cout << "MOD calleeLoc = ";
00297           calleeLoc->dump(std::cout,mIR);
00298           std::cout << std::endl;
00299       }
00300       calleeLoc->acceptVisitor(*c2cVisitor);
00301       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00302       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00303            OA_ptr<Location> callLoc = callLocIterPtr->current();
00304            mInterSideEffect->insertMOD(call, callLoc);
00305            if (debug) { 
00306                std::cout << "MOD callLoc = ";
00307                callLoc->dump(std::cout,mIR);
00308                std::cout << std::endl;
00309            }
00310       }
00311     }
00312     // LDEF
00313     locIterPtr = mInterSideEffect->getLDEFIterator(callee);
00314     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00315       OA_ptr<Location> calleeLoc = locIterPtr->current();
00316       calleeLoc->acceptVisitor(*c2cVisitor);
00317       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00318       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00319            OA_ptr<Location> callLoc = callLocIterPtr->current();
00320            //Callee LDEF should go into Caller DEF set.
00321            mInterSideEffect->insertDEF(call, callLoc);
00322       }
00323     }
00324     // DEF 
00325     locIterPtr = mInterSideEffect->getDEFIterator(callee);
00326     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00327       OA_ptr<Location> calleeLoc = locIterPtr->current();
00328       calleeLoc->acceptVisitor(*c2cVisitor);
00329       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00330       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00331            OA_ptr<Location> callLoc = callLocIterPtr->current();
00332            mInterSideEffect->insertDEF(call, callLoc);
00333       }
00334     }
00335 
00336     // USE 
00337     locIterPtr = mInterSideEffect->getUSEIterator(callee);
00338     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00339       OA_ptr<Location> calleeLoc = locIterPtr->current();
00340       if (debug) { 
00341           std::cout << "USE calleeLoc = ";
00342           calleeLoc->output(*mIR);
00343           std::cout << std::endl;
00344       }
00345       calleeLoc->acceptVisitor(*c2cVisitor);
00346       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00347       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00348            OA_ptr<Location> callLoc = callLocIterPtr->current();
00349            mInterSideEffect->insertUSE(call, callLoc);
00350            if (debug) { 
00351                std::cout << "USE callLoc = ";
00352                callLoc->output(*mIR);
00353                std::cout << std::endl;
00354            }
00355       }
00356     }
00357     // LUSE
00358     locIterPtr = mInterSideEffect->getLUSEIterator(callee);
00359     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00360       OA_ptr<Location> calleeLoc = locIterPtr->current();
00361       if (debug) { 
00362           std::cout << "LUSE calleeLoc = ";
00363           calleeLoc->output(*mIR);
00364           std::cout << std::endl;
00365       }
00366       calleeLoc->acceptVisitor(*c2cVisitor);
00367       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00368       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00369            OA_ptr<Location> callLoc = callLocIterPtr->current();
00370            if (debug) {
00371                std::cout << "LUSE callLoc = ";
00372                callLoc->output(*mIR);
00373                std::cout << std::endl;
00374            }                  
00375            // Callee LUSE should go into Caller USE set.
00376            mInterSideEffect->insertUSE(call, callLoc);
00377       }
00378     }
00379     // LREF
00380     locIterPtr = mInterSideEffect->getLREFIterator(callee);
00381     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00382       OA_ptr<Location> calleeLoc = locIterPtr->current();
00383       calleeLoc->acceptVisitor(*c2cVisitor);
00384       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00385       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00386            OA_ptr<Location> callLoc = callLocIterPtr->current();
00387            // Callee LREF should go into Caller REF set.
00388            mInterSideEffect->insertREF(call, callLoc);
00389       }
00390     }
00391     // REF
00392     locIterPtr = mInterSideEffect->getREFIterator(callee);
00393     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00394       OA_ptr<Location> calleeLoc = locIterPtr->current();
00395       calleeLoc->acceptVisitor(*c2cVisitor);
00396       callLocIterPtr = c2cVisitor->getCallerLocIterator();
00397       for ( ; callLocIterPtr->isValid(); (*callLocIterPtr)++ ) {
00398            OA_ptr<Location> callLoc = callLocIterPtr->current();
00399            mInterSideEffect->insertREF(call, callLoc);
00400       }
00401     }
00402 
00403     // count how many locations are in all sets for this  procedure so we
00404     // can see if any are added
00405     // FIXME: don't have way to get count for call yet
00406     //int count = mInterSideEffect->getLocCount(caller);
00407     OA_ptr<DataFlow::CountDFSet> retval;
00408     retval = new DataFlow::CountDFSet();
00409 
00410     return retval;
00411 }
00412  
00415 OA_ptr<DataFlow::DataFlowSet>
00416 ManagerInterSideEffectStandard::atCallGraphEdge(
00417         OA_ptr<DataFlow::DataFlowSet> inSet, 
00418         CallHandle call, ProcHandle caller, SymHandle callee )
00419 {
00420     if (debug) {
00421        std::cout << "atCallGraphEdge::inSet = ";
00422        inSet->dump(std::cout, mIR);
00423     }
00424 
00425     if(debug) {
00426       std::cout << "CallHandle: " << mIR->toString(call) << std::endl; 
00427     }
00428     
00429     // initialize side-effect information for call to have all empty sets
00430     mInterSideEffect->initCallSideEffect(call);
00431 
00432     // just insert locations that IR told us about, see comments about
00433     // getSideEffect in InterSideEffectIRInterface
00434     OA_ptr<SideEffect::SideEffectStandard> sideEffect 
00435       = mIR->getSideEffect(caller, callee);
00436     mInterSideEffect->mapCallToSideEffect(call, sideEffect);
00437     
00438     // LMOD
00439     OA_ptr<LocIterator> locIterPtr = sideEffect->getLMODIterator();
00440     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00441       OA_ptr<Location> loc = locIterPtr->current();
00442       mInterSideEffect->insertLMOD(call, loc);
00443     }
00444     // MOD
00445     locIterPtr = sideEffect->getMODIterator();
00446     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00447       OA_ptr<Location> loc = locIterPtr->current();
00448       mInterSideEffect->insertMOD(call, loc);
00449     }
00450     // LDEF
00451     locIterPtr = sideEffect->getLDEFIterator();
00452     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00453       OA_ptr<Location> loc = locIterPtr->current();
00454       mInterSideEffect->insertLDEF(call, loc);
00455     }
00456     // DEF
00457     locIterPtr = sideEffect->getDEFIterator();
00458     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00459       OA_ptr<Location> loc = locIterPtr->current();
00460       mInterSideEffect->insertDEF(call, loc);
00461     }
00462     // LUSE
00463     locIterPtr = sideEffect->getLUSEIterator();
00464     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00465       OA_ptr<Location> loc = locIterPtr->current();
00466       mInterSideEffect->insertLUSE(call, loc);
00467     }
00468     // USE
00469     locIterPtr = sideEffect->getUSEIterator();
00470     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00471       OA_ptr<Location> loc = locIterPtr->current();
00472       mInterSideEffect->insertUSE(call, loc);
00473     }
00474     // LREF
00475     locIterPtr = sideEffect->getLREFIterator();
00476     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00477       OA_ptr<Location> loc = locIterPtr->current();
00478       mInterSideEffect->insertLREF(call, loc);
00479     }
00480     // REF
00481     locIterPtr = sideEffect->getREFIterator();
00482     for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00483       OA_ptr<Location> loc = locIterPtr->current();
00484       mInterSideEffect->insertREF(call, loc);
00485     }
00486     
00487     // count how many locations are in all sets for this  procedure so we
00488     // can see if any are added
00489     // FIXME: don't have way to get count for call yet
00490     //int count = mInterSideEffect->getLocCount(caller);
00491     OA_ptr<DataFlow::CountDFSet> retval;
00492     retval = new DataFlow::CountDFSet();
00493 
00494     return retval;
00495 }
00496 
00497 
00498   } // end of namespace SideEffect
00499 } // end of namespace OA