auto_ManagerReachingDefsStandard.cpp

Go to the documentation of this file.
00001 
00002 // ManagerReachingDefsStandard.cpp
00003 
00004 #include "auto_ManagerReachingDefsStandard.hpp"
00005 
00006 using namespace std;
00007 using namespace OA::DataFlow;
00008 using namespace OA::CFG;
00009 using namespace OA::Alias;
00010 using namespace OA::SideEffect;
00011 
00012 namespace OA {
00013   namespace ReachingDefs {
00014 
00015 static bool debug = false;
00016 
00017 
00018 ManagerReachingDefsStandard::ManagerReachingDefsStandard(
00019     OA_ptr<ReachingDefsIRInterface> _ir)
00020     :
00021     mIR(_ir)
00022 {
00023     OA_DEBUG_CTRL_MACRO("DEBUG_ManagerReachingDefsStandard:ALL", debug);
00024     mSolver = new CFGDFSolver(CFGDFSolver::Forward, *this);
00025 }
00026 
00027 
00028 OA_ptr<DataFlowSet> ManagerReachingDefsStandard::initializeTop()
00029 {
00030     OA_ptr<ReachingDefsDFSet> retval;
00031     retval = new ReachingDefsDFSet();
00032     return retval;
00033 }
00034 
00035 
00036 OA_ptr<DataFlowSet> ManagerReachingDefsStandard::initializeBottom()
00037 {
00038     OA_ptr<ReachingDefsDFSet> retval;
00039     retval = new ReachingDefsDFSet();
00040     return retval;
00041 }
00042 
00043 
00044 OA_ptr<DataFlowSet>
00045 ManagerReachingDefsStandard::initializeNodeIN(OA_ptr<NodeInterface> n)
00046 {
00047     OA_ptr<ReachingDefsDFSet> retval;
00048     retval = new ReachingDefsDFSet();
00049     return retval;
00050 }
00051 
00052 
00053 OA_ptr<DataFlowSet>
00054 ManagerReachingDefsStandard::initializeNodeOUT(OA_ptr<NodeInterface> n)
00055 {
00056     OA_ptr<ReachingDefsDFSet> retval;
00057     retval = new ReachingDefsDFSet();
00058     return retval;
00059 }
00060 
00061 
00062 OA_ptr<ReachingDefsStandard> ManagerReachingDefsStandard::performAnalysis(
00063     ProcHandle proc,
00064     OA_ptr<CFGInterface> cfg,
00065     OA_ptr<OA::Alias::Interface> alias,
00066     OA_ptr<InterSideEffectInterface> interSE)
00067 {
00068     if (debug) {
00069         cout << "In ReachingDefs::ManagerReachingDefsStandard::performAnalysis"
00070              << endl;
00071     }
00072 
00073     // create the object we'll store results in
00074     mReachingDefsMap = new ReachingDefsStandard(proc, mIR);
00075 
00076     // store Alias information for use within the transfer function
00077     mAlias = alias;
00078 
00079     {
00080 
00081         // maycode for defs[s]
00082         OA_ptr<IRStmtIterator> stmtIter;
00083         stmtIter = mIR->getStmtIterator(proc);
00084         for(; stmtIter->isValid(); ++(*stmtIter)) {
00085             StmtHandle stmt = stmtIter->current();
00086 
00087             OA_ptr<MemRefHandleIterator> defsIter;
00088             defsIter = mIR->getDefMemRefs(stmt);
00089             for (; defsIter->isValid(); (*defsIter)++) {
00090                 MemRefHandle ref = defsIter->current();
00091 
00092                 OA_ptr<LocIterator> locIter;
00093                 locIter = alias->getMayLocs(ref);
00094                 for (; locIter->isValid(); ++(*locIter)) {
00095                     mStmt2MayDefMap[stmt].insert(locIter->current());
00096                 }
00097             }
00098         }
00099     } {
00100 
00101         // mustcode for defs[s]
00102         OA_ptr<IRStmtIterator> stmtIter;
00103         stmtIter = mIR->getStmtIterator(proc);
00104         for(; stmtIter->isValid(); ++(*stmtIter)) {
00105             StmtHandle stmt = stmtIter->current();
00106 
00107             OA_ptr<MemRefHandleIterator> defsIter;
00108             defsIter = mIR->getDefMemRefs(stmt);
00109             for (; defsIter->isValid(); (*defsIter)++) {
00110                 MemRefHandle ref = defsIter->current();
00111                 OA_ptr<LocIterator> locIter;
00112                 locIter = alias->getMayLocs(ref);
00113                 for (; locIter->isValid(); ++(*locIter)) {
00114                     mStmt2MustDefMap[stmt].insert(locIter->current());
00115                 }
00116             }
00117         }
00118     }
00119 
00120     // use the dataflow solver to get the In and Out sets for the
00121     // basic blocks (BBs).
00122     mSolver->solve(cfg, ITERATIVE);
00123 
00124     // get exit node for CFG and determine what data flow values exit it.
00125     // store these data flow values in the result's exit information.
00126     OA_ptr<NodeInterface> node;
00127     node = cfg->getExit();
00128     OA_ptr<DataFlowSet> x = mSolver->getOutSet(node);
00129     OA_ptr<ReachingDefsDFSet> exitSet =
00130         x.convert<ReachingDefsDFSet>();
00131     for(ReachingDefsDFSet::iterator i = exitSet->begin();
00132         i != exitSet->end(); i++)
00133     {
00134         mReachingDefsMap->insertExit(*i);
00135     }
00136 
00137 
00138     return mReachingDefsMap;
00139 }
00140 
00141 void ManagerReachingDefsStandard::dumpset(OA_ptr<ReachingDefsDFSet> inSet) {
00142     OA_ptr<set<StmtHandle  > > setRecast;
00143     setRecast = inSet.convert<set<StmtHandle  > >();
00144     set<StmtHandle  >::iterator iter;
00145     iter = setRecast->begin();
00146     for(; iter != setRecast->end(); iter++) {
00147         cout << mIR->toString(*iter);
00148     }
00149     cout << endl;
00150 }
00151 
00152 
00153 OA_ptr<DataFlowSet>
00154 ManagerReachingDefsStandard::meet(
00155     OA_ptr<DataFlowSet> set1orig,
00156     OA_ptr<DataFlowSet> set2orig)
00157 {
00158     // convert the incoming sets to sets of the specific flow value.
00159     OA_ptr<ReachingDefsDFSet> set1 = set1orig.convert<ReachingDefsDFSet>();
00160     OA_ptr<ReachingDefsDFSet> set2 = set2orig.convert<ReachingDefsDFSet>();
00161 
00162     if (debug) {
00163         cout << "ManagerReachingDefsStandard::meet" << endl;
00164         cout << "\tset1 = ";
00165         dumpset(set1);
00166         cout << "\tset2 = ";
00167         dumpset(set2);
00168     }
00169 
00170     // perform the meet operator on the left hand set.  It's okay to modify the
00171     // set and return it as a result [since the solver passes a temporary set
00172     // in as set1.  See the CFGDFProblem header for more info.
00173     set1->unionEqu(*set2);
00174 
00175     if (debug) {
00176         cout << endl << "\tcalculated set = ";
00177         dumpset(set1);
00178     }
00179 
00180     return set1;
00181 }
00182 
00183 OA_ptr<DataFlowSet> ManagerReachingDefsStandard::genSet(StmtHandle stmt)
00184 {
00185     OA_ptr<ReachingDefsDFSet> genSet;
00186     genSet =  new ReachingDefsDFSet();
00187 
00188     // Generate GEN code:
00189     OA_ptr<DFAGenDFSet<StmtHandle > > set1;
00190     set1 = new DFAGenDFSet<StmtHandle >();
00191     ReachingDefsDFSet::iterator iter1;
00192     StmtHandle iter1Val;
00193 
00194     {
00195         iter1Val = stmt;
00196         OA_ptr<DFAGenDFSet<OA_ptr<Location> > > set2;
00197         set2 = new DFAGenDFSet<OA_ptr<Location> >(mStmt2MayDefMap[iter1Val]);
00198         bool cond1;
00199         cond1 = !set2->isEmpty();
00200         bool cond;
00201         cond = cond1;
00202         if(cond) {
00203             set1->insert(iter1Val);
00204         }
00205     }
00206     genSet = set1;
00207 
00208     return genSet;
00209 }
00210 
00211 OA_ptr<DataFlowSet> ManagerReachingDefsStandard::killSet(
00212     StmtHandle stmt, OA_ptr<DataFlowSet> xdfset)
00213 {
00214     OA_ptr<ReachingDefsDFSet> x;
00215     x = xdfset.convert<ReachingDefsDFSet>();
00216 
00217     OA_ptr<ReachingDefsDFSet> killSet;
00218     killSet = new ReachingDefsDFSet();
00219 
00220     // Generate KILL code:
00221     OA_ptr<DFAGenDFSet<StmtHandle > > set3;
00222     set3 = new DFAGenDFSet<StmtHandle >();
00223     ReachingDefsDFSet::iterator iter2;
00224     StmtHandle iter2Val;
00225 
00226     for(iter2 = x->begin(); iter2 != x->end(); iter2++) {
00227         iter2Val = *iter2;
00228         OA_ptr<DFAGenDFSet<OA_ptr<Location> > > set4;
00229         set4 = new DFAGenDFSet<OA_ptr<Location> >(mStmt2MayDefMap[iter2Val]);
00230         OA_ptr<DFAGenDFSet<OA_ptr<Location> > > set5;
00231         set5 = new DFAGenDFSet<OA_ptr<Location> >(mStmt2MustDefMap[stmt]);
00232         bool cond2;
00233         cond2 = set4->isSubset(*set5);
00234         bool cond;
00235         cond = cond2;
00236         if(cond) {
00237             set3->insert(iter2Val);
00238         }
00239     }
00240     killSet = set3;
00241 
00242     return killSet;
00243 }
00244 
00245 // Currently the transfer function used by DFAGen is assumed to be:
00246 // Y = gen[n] U (X - kill[n]).
00247 OA_ptr<DataFlowSet>
00248 ManagerReachingDefsStandard::transfer(
00249     OA_ptr<DataFlowSet> xdfset,
00250     StmtHandle stmt)
00251 {
00252     OA_ptr<set<StmtHandle> > xdfgenset;
00253     xdfgenset = xdfset.convert<set<StmtHandle> >();
00254 
00255     OA_ptr<ReachingDefsDFSet> x;
00256     x = new ReachingDefsDFSet(*xdfgenset);
00257 
00258     // if debug mode is on print information about transfer function
00259     if (debug) {
00260         cout << "In transfer: " << endl;
00261         cout << "\t Stmt  = " << mIR->toString(stmt) << endl;
00262         cout << "\t X     = ";
00263         dumpset(x);
00264     }
00265 
00266     OA_ptr<DataFlowSet> genBaseObj = genSet(stmt);
00267     OA_ptr<ReachingDefsDFSet> gen = genBaseObj.convert<ReachingDefsDFSet>();
00268 
00269     OA_ptr<DataFlowSet> killBaseObj = killSet(stmt, x);
00270     OA_ptr<ReachingDefsDFSet> kill = killBaseObj.convert<ReachingDefsDFSet>();
00271 
00272 
00273     // Add gen[n] to Y
00274     ReachingDefsDFSet::iterator genIter = gen->begin();
00275     for(; genIter != gen->end(); ++genIter) {
00276         StmtHandle  genVal;
00277         genVal = *genIter;
00278         mReachingDefsMap->insert(stmt, genVal);
00279     }
00280     // Add X - kill[n] to Y
00281     x->minusEqu(*kill);
00282     ReachingDefsDFSet::iterator xIter = x->begin();
00283     for(; xIter != x->end(); ++xIter) {
00284         StmtHandle  xVal;
00285         xVal = *xIter;
00286         mReachingDefsMap->insert(stmt, xVal);
00287     }
00288 
00289     // if debug mode is on print information about transfer function
00290     if(debug) {
00291         cout << "\t gen  = ";
00292         dumpset(gen);
00293         cout << "\t kill = ";
00294         dumpset(kill);
00295         cout << "\t Y    = ";
00296         dumpset(mReachingDefsMap->getReachingDefsSet(stmt));
00297     }
00298 
00299     return mReachingDefsMap->getReachingDefsSet(stmt);
00300 }
00301 
00302   } // end of namespace ReachingDefs
00303 } // end of namespace OA

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