ManagerICFGReachConsts.cpp

Go to the documentation of this file.
00001 
00015 #include "ManagerICFGReachConsts.hpp"
00016 
00017 
00018 namespace OA {
00019   namespace ReachConsts {
00020 
00021 static bool debug = false;
00022 
00025 ManagerICFGReachConsts::ManagerICFGReachConsts( 
00026     OA_ptr<ReachConstsIRInterface> _ir) : mIR(_ir)
00027 {
00028     OA_DEBUG_CTRL_MACRO("DEBUG_ManagerICFGReachConsts:ALL", debug);
00029     mSolver = new DataFlow::ICFGDFSolver(DataFlow::ICFGDFSolver::Forward,*this);
00030 }
00031 
00032 OA_ptr<InterReachConsts> 
00033 ManagerICFGReachConsts::performAnalysis(
00034         OA_ptr<ICFG::ICFGInterface> icfg,
00035         OA_ptr<DataFlow::ParamBindings> paramBind,
00036         OA_ptr<Alias::InterAliasInterface> interAlias,
00037         OA_ptr<SideEffect::InterSideEffectInterface> interSE,
00038         DataFlow::DFPImplement algorithm)
00039 {
00040   // store results that will be needed in callbacks
00041   mICFG = icfg;
00042   mParamBind = paramBind;
00043   mInterAlias = interAlias;
00044   mInterSE = interSE;
00045 
00046   // create an empty InterReachConsts
00047   mInterReachConsts = new InterReachConsts();
00048 
00049   // call iterative data-flow solver for ICFG
00050   mSolver->solve(icfg,algorithm);
00051     
00052   // assign results for each procedure into InterReachConsts
00053   std::map<ProcHandle,OA_ptr<ReachConstsStandard> >::iterator mapIter;
00054   for (mapIter=mReachConstsMap.begin(); mapIter!=mReachConstsMap.end(); 
00055        mapIter++) 
00056   {
00057     mInterReachConsts->mapProcToReachConsts(mapIter->first,mapIter->second);
00058   }
00059 
00060   return mInterReachConsts;
00061 }
00062 
00063 //========================================================
00064 // implementation of ICFGDFProblem interface
00065 //========================================================
00066 //--------------------------------------------------------
00067 // initialization callbacks
00068 //--------------------------------------------------------
00069 
00074 OA_ptr<DataFlow::DataFlowSet> ManagerICFGReachConsts::initializeTop()
00075 {
00076     OA_ptr<ConstDefSet> retval;
00077     retval = new ConstDefSet(TOP);
00078     return retval;
00079 }
00080 
00081 OA_ptr<DataFlow::DataFlowSet> 
00082 ManagerICFGReachConsts::initializeNodeIN(OA_ptr<ICFG::NodeInterface> n)
00083 {
00084     OA_ptr<ConstDefSet> retval;
00085     
00086     // if node is entry node for whole ICFG
00087     // FIXME: the size thing is a hack to get around the weird
00088     // return nodes
00089     if (n->isAnEntry() && (n->size()==0)) {
00090         retval  = new ConstDefSet(BOTTOM);
00091     } else {
00092         retval = new ConstDefSet(TOP);
00093     }
00094     return retval;
00095 }
00096 
00097 OA_ptr<DataFlow::DataFlowSet> 
00098 ManagerICFGReachConsts::initializeNodeOUT(OA_ptr<ICFG::NodeInterface> n)
00099 {
00100     return initializeTop();
00101  }
00102 
00103 
00104 //--------------------------------------------------------
00105 // solver callbacks 
00106 //--------------------------------------------------------
00107   
00110 OA_ptr<DataFlow::DataFlowSet> 
00111 ManagerICFGReachConsts::meet(OA_ptr<DataFlow::DataFlowSet> set1, 
00112                              OA_ptr<DataFlow::DataFlowSet> set2)
00113 {
00114   OA_ptr<DataFlow::DataFlowSet> set1clone = set1->clone(); 
00115   OA_ptr<DataFlow::DataFlowSet> set2clone = set2->clone(); 
00116   OA_ptr<ConstDefSet> cdset1 = set1clone.convert<ConstDefSet>();
00117   OA_ptr<ConstDefSet> cdset2 = set2clone.convert<ConstDefSet>();
00118   // needed to clone them, as we change their contents during meet
00119     
00120   if (debug) {
00121     std::cout << "--------- ManagerICFGReachConsts::meet" << std::endl;
00122     std::cout << "\tcdset1 = ";
00123     cdset1->dump(std::cout, mIR);
00124     std::cout << "\tcdset2 = ";
00125     cdset2->dump(std::cout, mIR);
00126   }
00127   
00128   /*********************** now done after while loop
00129   // if either has a default constant value of BOTTOM then
00130   // the result will have a default constant value of BOTTOM
00131   // for all locations
00132   OA_ptr<ConstDefSet> retval; 
00133   if ((cdset1->getDefaultConstDef() == BOTTOM)
00134       || (cdset2->getDefaultConstDef() == BOTTOM) ) {
00135     retval = new ConstDefSet(BOTTOM);
00136   } else {
00137     retval = new ConstDefSet(TOP);
00138   }
00139   ***********************/
00140   
00141   bool changeOccurred = true; // set to true to enable initial pass
00142   // need to loop over two sets multiple times because there might be locations
00143   // A and B in set one that overlap each other and only A overlaps location
00144   // C that is in set two?
00145   while (changeOccurred) {
00146     changeOccurred = false; 
00147     
00148     // loop through all assignments of locations to lattice values 
00149     // (either a constant, top, or bottom) in the first set
00150     for (int i=1; i<=2; i++) {
00151       OA_ptr<ConstDefSet> set1ptr, set2ptr;
00152       if (i==1) {
00153         set1ptr = cdset1; set2ptr = cdset2;
00154       } else {
00155         set1ptr = cdset2; set2ptr = cdset1;
00156       }
00157       
00158       ConstDefSetIterator set1Iter(*set1ptr);
00159       ConstDefSetIterator set2Iter(*set2ptr);
00160       
00161       ConstDefSet killSet1;
00162       ConstDefSet genSet1;
00163       
00164       // for each ConstDefLoc in Set1
00165       for (set1Iter.reset(); set1Iter.isValid(); ++(set1Iter)) {
00166         OA_ptr<ConstDef> constDef1 = set1Iter.current();
00167         OA_ptr<Location> cdLocPtr1 = constDef1->getLocPtr();
00168         OA_ptr<ConstValBasicInterface> cdConstPtr1 
00169           = constDef1->getConstPtr();
00170         ConstDefType cdType1 = constDef1->getConstDefType();
00171         
00172         // did we find at least one overlap
00173         bool overlapfound = false;
00174         OA_ptr<ConstValBasicInterface> nullVal;
00175         
00176         ConstDefType defaultVal2 = set2ptr->getDefaultConstDef();
00177         // conservatively assume that it could mayOverlap with  
00178         // anything in the second set
00179         if ((cdType1==BOTTOM) && (defaultVal2 != BOTTOM)) {
00180           defaultVal2 = BOTTOM;
00181           set2ptr->setDefaultConstDef(BOTTOM);
00182           changeOccurred = true;
00183         }
00184 
00185         // for each ConstDefLoc in Set2
00186         for (set2Iter.reset(); set2Iter.isValid(); ++(set2Iter)) {
00187           OA_ptr<ConstDef> constDef2 = set2Iter.current();
00188           OA_ptr<Location> cdLocPtr2 = constDef2->getLocPtr();
00189           OA_ptr<ConstValBasicInterface> cdConstPtr2 
00190             = constDef2->getConstPtr();
00191           ConstDefType cdType2 = constDef2->getConstDefType();
00192           
00193           // find all the locations that must overlap with this location
00194           // in the second set and perform meets
00195           if (cdLocPtr1->mustOverlap(*cdLocPtr2)) {
00196             overlapfound = true;
00197             if ((cdType1==BOTTOM) || (cdType2==BOTTOM)) {
00198               cdType1 = BOTTOM; cdConstPtr1 = nullVal;
00199             } else if ((cdType1==TOP) && (cdType2==TOP)) {
00200               cdType1 = TOP; cdConstPtr1 = nullVal;
00201             } else if ((cdType1==TOP) && (cdType2==VALUE)) {
00202               cdType1 = VALUE;  cdConstPtr1 = cdConstPtr2;
00203             } else if ((cdType1==VALUE) && (cdType2==TOP)) {
00204               cdType1 = VALUE;  
00205             } else if ((cdType1==VALUE) && (cdType2==VALUE)) {
00206               if (cdConstPtr1 != cdConstPtr2) {
00207                 cdType1 = BOTTOM; cdConstPtr1 = nullVal;
00208               } // needed else cdType1 can continue as is, no changes
00209             }
00210           }
00211           
00212           /****************** doing something different here.  
00213           // if there are any locations that only may overlap, do a meet
00214           // with their value and the default value for set 2
00215           // only do this if didn't already find a must overlap
00216           if (!overlapfound && cdLocPtr1->mayOverlap(*cdLocPtr2)) {
00217             overlapfound = true;
00218             if ((cdType1==BOTTOM) || (cdType2==BOTTOM) 
00219                 || (defaultVal2==BOTTOM)) 
00220               {
00221                 cdType1 = BOTTOM; cdConstPtr1 = nullVal;
00222               } else if ((cdType1==TOP) && (cdType2==TOP) && 
00223                          (defaultVal2==TOP)) {
00224               cdType1 = TOP; cdConstPtr1 = nullVal;
00225               
00226               // if neither of the above are true then defaultVal2==TOP
00227               // and can be ignored
00228             } else if ((cdType1==TOP) && (cdType2==VALUE)) {
00229               cdType1 = TOP;  cdConstPtr1 = nullVal;
00230             } else if ((cdType1==VALUE) && (cdType2==TOP)) {
00231               cdType1 = VALUE;  
00232             } 
00233           }
00234           *********************/
00235 
00236 
00237         } // iterating over set 2
00238         
00239         // if there are no locations that may or must overlap, do a meet
00240         // with the default value for set 2
00241         if (!overlapfound && defaultVal2==TOP) {
00242           cdType1 = cdType1;
00243         } else if (!overlapfound && defaultVal2==BOTTOM) {
00244           cdType1 = BOTTOM;  cdConstPtr1 = nullVal;
00245         }
00246 
00247         /****************** replaced with above
00248         if (!overlapfound) {
00249           if ((cdType1==BOTTOM) || (defaultVal2==BOTTOM))  {
00250             cdType1 = BOTTOM; cdConstPtr1 = nullVal;
00251           }
00252           // other possibilities result in no changes to cd1
00253         }
00254         ******************/
00255         
00256         // Check for changes
00257         if (cdType1 != constDef1->getConstDefType()) {
00258           changeOccurred = true;
00259           killSet1.insert(constDef1);
00260           OA_ptr<ConstDef> cd;
00261           cd = new ConstDef(cdLocPtr1,cdConstPtr1,cdType1);
00262           genSet1.insert(cd);
00263         }
00264 
00265         /*********************** handled below, after while loop
00266         if (((cdType1==BOTTOM) && (retval->getDefaultConstDef()==BOTTOM))
00267             || ((cdType1==TOP) && (retval->getDefaultConstDef()==TOP)) )
00268           {
00269             // do nothing
00270           } else {
00271           // insert the const def
00272           OA_ptr<ConstDef> cd; 
00273           cd = new ConstDef(cdLocPtr1, cdConstPtr1, cdType1);
00274           retval->insert(cd);
00275         }
00276         ***********************/
00277 
00278       } // iterating over set 1
00279 
00280       // Update set1
00281       // Apply Kills
00282       ConstDefSetIterator setIter(killSet1);
00283       for (; setIter.isValid(); ++(setIter)) {
00284         OA_ptr<ConstDef> constDef = setIter.current();
00285         if (i==1) { // set 1 == cdset1
00286           if (debug) {
00287             int k = cdset1->removeANDtell(constDef);
00288             std::cout << "MEET: killed "<<k<<" from set1: (cd "
00289                       << constDef->toString(mIR) << ")" << std::endl;
00290           } else {
00291             cdset1->remove(constDef);
00292           }
00293         } else { // i==2 means set 1 == cdset2
00294           if (debug) {
00295             int k = cdset2->removeANDtell(constDef);
00296             std::cout << "MEET: killed "<<k<<" from set2: (cd "
00297                       << constDef->toString(mIR) << ")" << std::endl;
00298           } else {
00299             cdset2->remove(constDef);
00300           }
00301         }
00302       } // end of Apply Kills
00303 
00304       // Apply Gens
00305       ConstDefSetIterator vsetIter(genSet1);
00306       for (; vsetIter.isValid(); ++(vsetIter)) {
00307         OA_ptr<ConstDef> constDef = vsetIter.current();
00308         if (i==1) { // set 1 == cdset1
00309           cdset1->replace(constDef->getLocPtr(),constDef->getConstPtr(),
00310                           constDef->getConstDefType());
00311           if (debug) {
00312             std::cout << "MEET: Val replacement in set1: (cd "
00313                       << constDef->toString(mIR) << ")" << std::endl;
00314           }
00315         } else { // i==2, set 1 == cdset2
00316           cdset2->replace(constDef->getLocPtr(),constDef->getConstPtr(),
00317                           constDef->getConstDefType());
00318           if (debug) {
00319             std::cout << "MEET: Val replacement in set2: (cd "
00320                       << constDef->toString(mIR) << ")" << std::endl;
00321           }
00322         }
00323       } // end of Apply Gens
00324       
00325     } // doing the comparison both directions
00326 
00327   } // while(changeOccurred)
00328 
00329   // compose retval
00330 
00331   // if either has a default constant value of BOTTOM then
00332   // the result will have a default constant value of BOTTOM
00333   // for all locations
00334   OA_ptr<ConstDefSet> retval;
00335   ConstDefType retDefaultVal;
00336   if ((cdset1->getDefaultConstDef() == BOTTOM)
00337       || (cdset2->getDefaultConstDef() == BOTTOM) ) {
00338     retDefaultVal = BOTTOM;
00339   } else {
00340     retDefaultVal = TOP;
00341   }
00342   retval = new ConstDefSet(retDefaultVal);
00343 
00344   // insert cdset1
00345   ConstDefSetIterator set1Iter(*cdset1);
00346   for (set1Iter.reset(); set1Iter.isValid(); ++(set1Iter)) {
00347     OA_ptr<ConstDef> constDef1 = set1Iter.current();
00348     if (constDef1->getConstDefType() == retDefaultVal) {
00349       // do nothing
00350     } else {
00351       // insert into retval
00352       OA_ptr<ConstDef> cd; 
00353       cd = new ConstDef(constDef1->getLocPtr(), 
00354                         constDef1->getConstPtr(), 
00355                         constDef1->getConstDefType());
00356       retval->insert(cd);
00357     }
00358   }    
00359   
00360   // insert cdset2 (if we insert a ConstDef with the same Location that
00361   //                already exists in retval, the original remains.
00362   //                This should not be a problem, as any ConstDefs between
00363   //                cdset1 and cdset2 with the same Location would
00364   //                eventually get to the same value in while loop above
00365   ConstDefSetIterator set2Iter(*cdset2);
00366   for (set2Iter.reset(); set2Iter.isValid(); ++(set2Iter)) {
00367     OA_ptr<ConstDef> constDef2 = set2Iter.current();
00368     if (constDef2->getConstDefType() == retDefaultVal) {
00369       // do nothing
00370     } else {
00371       // insert into retval
00372       OA_ptr<ConstDef> cd; 
00373       cd = new ConstDef(constDef2->getLocPtr(), 
00374                         constDef2->getConstPtr(), 
00375                         constDef2->getConstDefType());
00376       retval->insert(cd);
00377     }
00378   }
00379   
00380   if (debug) {
00381     std::cout << "\tretval = ";
00382     retval->dump(std::cout, mIR);
00383   }
00384   return retval;
00385 }
00386 
00406 OA_ptr<DataFlow::DataFlowSet> 
00407 ManagerICFGReachConsts::transfer(ProcHandle proc,
00408                           OA_ptr<DataFlow::DataFlowSet> in, OA::StmtHandle stmt)
00409 {    
00410   // if there isn't a ReachConsts for this proc then make one
00411   if (mReachConstsMap.find(proc)==mReachConstsMap.end()) {
00412       mReachConstsMap[proc] = new ReachConstsStandard(proc);
00413   }
00414 
00415   // get alias results for procedure
00416   OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(proc);
00417 
00418   ConstDefSet killSet;
00419   ConstDefSet replaceSet;
00420   ConstDefSet genSet;
00421   OA_ptr<DataFlow::DataFlowSet> inclone = in->clone();
00422   OA_ptr<ConstDefSet> inRecast = inclone.convert<ConstDefSet>();
00423   // need another copy because can't iterate over set and update it at same time
00424   inclone = in->clone();  // need this or get segfault
00425   OA_ptr<ConstDefSet> inRecastCopy = inclone.convert<ConstDefSet>();
00426 
00427   // set the constant defs for this stmt
00428   // first remove any old defs
00429   mReachConstsMap[proc]->resetConstDefSet(stmt,
00430                                           inRecastCopy->getDefaultConstDef());
00431   ConstDefSetIterator cdIter(*inRecast);
00432   for (; cdIter.isValid(); ++(cdIter)) {
00433     OA_ptr<ConstDef> constDef = cdIter.current();
00434     mReachConstsMap[proc]->insertConstDef(stmt,constDef,
00435                                           inRecastCopy->getDefaultConstDef());
00436   }
00437 
00438   if (debug) {
00439     std::cout << "--- --- --- --- --- Top of Transfer " << std::endl;
00440   }
00441 
00442   // 1) Update mapping for all use memrefs for this statement
00443   setUseMemRef2Const(proc, stmt, *inRecastCopy);
00444 
00445   if (debug) {
00446       std::cout << "------------------------------------------------"
00447                 << std::endl;
00448       std::cout << "transfer: stmt = (" << stmt.hval() << ": "
00449                 << mIR->toString(stmt) << ") :" << std::endl;
00450       std::cout << "\tConstDefsIn: ";
00451       inRecast->dump(std::cout,mIR);
00452       std::cout.flush();
00453   }
00454 
00455   // KILLSET construction algorithm (incl. KILLSET application)
00456   //--------------------------------
00457   // for each MemRefHandle of the DefMemRefs for this stmt:
00458   //   for each MayLoc of this MemRefHandle: 
00459   //     if the Loc of a ConstDef in inSet MayOverlap the MayLoc:
00460   //       replace ConstDef in the inSet with 
00461   //               (ConstDef.getLocPtr(),BOTTOM)
00462   //--------------------------------
00463     
00464   { // beginning of KILLSET creation/application 
00465     
00466     // for each def mem ref for this statement
00467     OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(stmt);
00468     for (; defIterPtr->isValid(); (*defIterPtr)++) {
00469         MemRefHandle memref = defIterPtr->current();
00470         
00471         // for each mayLoc for this mem ref
00472         OA_ptr<LocIterator> locIterPtr = alias->getMayLocs(memref);
00473         for (; locIterPtr->isValid(); ++(*locIterPtr)) {
00474           OA_ptr<Location> mayLocPtr = locIterPtr->current();
00475           
00476           // for each ConstDefLoc in inSet
00477           OA_ptr<ConstDefSetIterator> inIter;
00478           inIter = new ConstDefSetIterator(*inRecastCopy);
00479           for (; inIter->isValid(); ++(*inIter)) {
00480             OA_ptr<ConstDef> constDef = inIter->current();
00481             OA_ptr<Location> cdLocPtr = constDef->getLocPtr();
00482             
00483             // if Loc mayOverLap MayLoc, replace any constDef with cdLocPtr
00484             // with ConstDef(cdLocPtr,BOTTOM)
00485             if (cdLocPtr->mayOverlap(*mayLocPtr)) {
00486               OA_ptr<ConstValBasicInterface> nullVal; nullVal = 0;
00487               if (inRecast->getDefaultConstDef()!=BOTTOM) {
00488                 inRecast->replace(cdLocPtr,nullVal,BOTTOM);
00489               } else {
00490                 // just remove it
00491                 inRecast->remove(constDef);
00492               }
00493             }
00494           }
00495         }
00496     }
00497 
00498     // loop through all func calls in this statement and what they MOD
00499     OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(stmt);
00500     for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00501       CallHandle expr = callsiteItPtr->current();
00502 
00503       OA_ptr<LocIterator> locIterPtr;
00504       // MOD
00505       locIterPtr = mInterSE->getMODIterator(expr);
00506       for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00507           OA_ptr<Location> modLocPtr = locIterPtr->current();
00508           
00509           // for each ConstDefLoc in inSet
00510           OA_ptr<ConstDefSetIterator> inIter;
00511           inIter = new ConstDefSetIterator(*inRecastCopy);
00512           for (; inIter->isValid(); ++(*inIter)) {
00513             OA_ptr<ConstDef> constDef = inIter->current();
00514             OA_ptr<Location> cdLocPtr = constDef->getLocPtr();
00515             
00516             // if Loc mayOverLap modLoc, replace any constDef with cdLocPtr
00517             // with ConstDef(cdLocPtr,BOTTOM)
00518             if (cdLocPtr->mayOverlap(*modLocPtr)) {
00519               OA_ptr<ConstValBasicInterface> nullVal; nullVal = 0;
00520               if (inRecast->getDefaultConstDef()!=BOTTOM) {
00521                 inRecast->replace(cdLocPtr,nullVal,BOTTOM);
00522               } else {
00523                 // just remove it
00524                 inRecast->remove(constDef);
00525               }
00526             }
00527           }
00528        } 
00529 
00530     }
00531  
00532   } // end of KILLSET creation/application 
00533 
00534 
00535   // 3) Generate GEN set
00536   // GENSET construction/application algorithm for EXPR_STMT
00537   //--------------------------------
00538   // for each AssignPair -- <MemRefHandle,ExprTree> -- for this stmt:
00539   //   get ExprConst from ExprTree if it exists
00540   //   if ExprConst exists:
00541   //     for each MustLoc of the MemRefHandle
00542   //       replace any ConstDef(MustLoc) in inSet with
00543   //                   ConstDef(MustLoc,ExprConst,VALUE)
00544   //--------------------------------
00545  
00546   OA_ptr<AssignPairIterator> espIterPtr 
00547         = mIR->getAssignPairIterator(stmt);
00548   for ( ; espIterPtr->isValid(); (*espIterPtr)++) {
00549      // unbundle pair
00550      MemRefHandle mref = espIterPtr->currentTarget();
00551      ExprHandle expr = espIterPtr->currentSource();
00552         
00553      // getConstValBasic if possible
00554      OA_ptr<ConstValBasicInterface> cvbiPtr; cvbiPtr = 0;
00555      OA_ptr<ExprTree> eTreePtr = mIR->getExprTree(expr);
00556 
00557      // get ConstValBasicInterface by evaluating expression tree
00558      EvalToConstVisitor evalVisitor(mIR,mReachConstsMap[proc]);
00559      eTreePtr->acceptVisitor(evalVisitor);
00560      cvbiPtr = evalVisitor.getConstVal();
00561 
00562      if (!cvbiPtr.ptrEqual(NULL)) { // GEN a constant value
00563        if (debug) {
00564         std::cout << "After expr eval, cvbiPtr = (" << cvbiPtr <<")"<<std::endl;
00565         std::cout.flush();
00566         std::cout << "           *cvbiPTr = (" << cvbiPtr->toString()
00567                   << ") found for memRefHandle = <" 
00568                   << mIR->toString(mref) << ">"
00569                   << std::endl;
00570         std::cout.flush();
00571        }
00572           
00573        // for each MustLoc, replace any ConstDef(MustLoc,...) in inSet
00574        //     with new constant value: ConstDef(MustLoc,cvbiPtr,VALUE)
00575        OA_ptr<LocIterator> lIterPtr = alias->getMustLocs(mref);
00576        if (debug) {
00577           if (!lIterPtr->isValid()) {
00578             std::cout << "\n:( :( :( But no MustLocs found! :( :(\n\n";
00579           }
00580        }
00581        
00582        for ( ; lIterPtr->isValid() ; ++(*lIterPtr)) {
00583           OA_ptr<Location> lPtr = lIterPtr->current();
00584           inRecast->replace(lPtr,cvbiPtr,VALUE); 
00585        }
00586      } // end of "if we have a usable const val"
00587   } // end of loop over AssignPairList
00588  
00589       
00590   // 4) update reach consts for all mayLocs(???) of the DefMemRefs(stmt)
00591   setDefMemRef2Const(proc, stmt, *inRecast);
00592   
00593   if (debug) {
00594     std::cout << "\tConstDefsOut: ";
00595     inRecast->dump(std::cout,mIR);
00596   }
00597   
00598   return inRecast;
00599 }
00600 
00602 OA_ptr<DataFlow::DataFlowSet> 
00603 ManagerICFGReachConsts::callerToCallee(ProcHandle caller,
00604     OA_ptr<DataFlow::DataFlowSet> dfset, CallHandle call, ProcHandle callee)
00605 {
00606     OA_ptr<ConstDefSet> inRecast = dfset.convert<ConstDefSet>();
00607     OA_ptr<ConstDefSet> retval;
00608     // if the call node in the caller hasn't been visited yet, inRecast
00609     // will be TOP and we don't want to prematurely set the output to BOTTOM
00610     if (inRecast->getDefaultConstDef()==TOP) {
00611         retval = new ConstDefSet(TOP);
00612     } else {
00613         retval = new ConstDefSet(BOTTOM);
00614     }
00615 
00616     if (debug) {
00617         std::cout << "-------- ManagerICFGReachConsts::callerToCallee" 
00618                   << "\n\tinRecast = ";
00619         inRecast->dump(std::cout, mIR);
00620         std::cout << "\n\tcall = <" << mIR->toString(call) << ">\n\n";
00621     }
00622 
00623     // get alias results for caller procedure
00624     OA_ptr<Alias::Interface> callerAlias;
00625     callerAlias = mInterAlias->getAliasResults(caller);
00626     // get alias results for callee procedure
00627     OA_ptr<Alias::Interface> calleeAlias;
00628     calleeAlias = mInterAlias->getAliasResults(callee);
00629     
00630     // iterate over all the formal parameters for the call
00631     // (because we cannot go from exprHandle to symHandle, just the other
00632     //  direction)
00633     OA_ptr<SymHandleIterator> formalIter;
00634     formalIter = mParamBind->getFormalIterator(callee);
00635     for (; formalIter->isValid(); (*formalIter)++) {
00636       SymHandle formal = formalIter->current();
00637       ExprHandle actual = mParamBind->getActualExprHandle(call,formal);
00638       OA_ptr<ExprTree> etree = mParamBind->getActualExprTree(actual);
00639       
00640       if (debug) {
00641         std::cout << "\tformal = " << mIR->toString(formal) << "\n";
00642         std::cout << "\nactual = " << mIR->toString(actual) << "\n";
00643         std::cout << "\teTree = ";
00644         etree->output(*mIR);
00645       }
00646       
00647       // get ConstValBasicInterface by evaluating expression tree
00648       OA_ptr<ConstValBasicInterface> constVal; 
00649       EvalToConstVisitor evalVisitor(mIR,mReachConstsMap[caller]);
00650       etree->acceptVisitor(evalVisitor);
00651       constVal = evalVisitor.getConstVal();
00652       
00653       // if the actual parameter evaluates to a constant value
00654       if (!constVal.ptrEqual(NULL)) {          
00655         OA_ptr<Location> nloc;
00656         nloc = new NamedLoc(formal,true);
00657         OA_ptr<ConstDef> cd; 
00658         cd = new ConstDef(nloc, constVal, VALUE);
00659         retval->insert(cd);
00660         if (debug) {
00661           std::cout << "\nloc = ";
00662           nloc->dump(std::cout, mIR);
00663           std::cout << "\tconstVal = " << constVal->toString() 
00664                     << std::endl;
00665         }
00666       } else {
00667         // if there is a MemRefHandle at the top of this ExprTree
00668         MemRefHandle memref;
00669         EvalToMemRefVisitor evalVisitor;
00670         etree->acceptVisitor(evalVisitor);
00671         if (debug) { 
00672           etree->output(*mIR); 
00673         }
00674         if ( evalVisitor.isMemRef() ) {
00675           memref = evalVisitor.getMemRef();
00676           if (debug) {
00677             std::cout << "        MemRef: "
00678                       << mIR->toString(memref)
00679                       << std::endl;
00680           }
00681         } else {
00682           if (debug) {
00683             std::cout << "        No MemRef at top of ExprTree\n";
00684           }
00685           continue;
00686         }
00687         
00688         // check for isAddrOf locations with constant values ...
00689 
00690         // for each MemRefExpr of this MemRefHandle
00691         OA_ptr<MemRefExprIterator> mreIter;
00692         mreIter = mIR->getMemRefExprIterator(memref);
00693         for (; mreIter->isValid(); (*mreIter)++) {
00694           OA_ptr<MemRefExpr> mre_actual = mreIter->current();
00695           
00696           // prime the pump
00697           OA_ptr<MemRefExpr> deref_mre = mre_actual->clone();
00698           bool found_locs = true;
00699           int numDerefs = 0;
00700           
00701           // loop to find all locations (on the caller side) that may overlap
00702           // with this actual mre (from the caller side)
00703           while (found_locs) {
00704             found_locs = false;
00705             
00706             // Deref mre
00707             OA_ptr<MemRefExpr> nullmre;
00708             OA_ptr<Deref> deref;
00709             //deref = new Deref(false,true,MemRefExpr::USE,nullmre,1); 
00710             
00711             /* PLM 1/23/07
00712             deref = new Deref(true,MemRefExpr::USE,nullmre,1);
00713             */
00714 
00715             deref = new Deref(MemRefExpr::USE,nullmre,1);
00716             deref_mre = deref->composeWith(deref_mre);
00717             numDerefs++;
00718 
00719             if (debug) {
00720               std::cout << "\t\tgetting maylocs from caller for deref_mre = ";
00721               deref_mre->output(*mIR);
00722               std::cout << std::endl;
00723             }
00724             // query the alias analysis of Caller for maylocs of deref_mre  
00725             OA_ptr<LocIterator> mayLocIter;
00726             mayLocIter = callerAlias->getMayLocs(*deref_mre,caller);
00727 
00728             // continue if there are no maylocs
00729             if (!mayLocIter->isValid()) {
00730               continue;
00731             }
00732             found_locs = true;
00733 
00734             // see if all of these mayLocs have the same constant values
00735             bool allValuesAgree = true;
00736 
00737             // treat first mayLoc separately
00738             OA_ptr<Location> loc = mayLocIter->current();
00739             OA_ptr<ConstDef> cdPtr = inRecast->find(loc);
00740             (*mayLocIter)++;
00741 
00742             if (cdPtr.ptrEqual(NULL)) {
00743               // must be TOP or BOTTOM
00744               allValuesAgree = false; // first location not found in inSet
00745               if (debug) {
00746                 std::cout << "deref'd mre (";
00747                 deref_mre->output(*mIR);
00748                 std::cout << ") "
00749                   << "missing ConstDef for first mayLoc ( "
00750                   << loc->toString(mIR) << ")" << std::endl;
00751                 std::cout.flush();
00752               }
00753             } else if (cdPtr->getConstDefType() != VALUE) {
00754               allValuesAgree = false;
00755               // first value of mayLoc for this deref memref is not a value
00756             } 
00757 
00758             // Now check that all other mayLocs agree
00759             for (; (allValuesAgree) && (mayLocIter->isValid()); 
00760                  ++(*mayLocIter)) {
00761               loc = mayLocIter->current();
00762               OA_ptr<ConstDef> cdNextPtr = inRecast->find(loc);
00763               if (cdPtr.ptrEqual(NULL)) {
00764                 allValuesAgree = false; // next location not found in inSet
00765               } else if (!((*cdPtr).equiv(*cdNextPtr))) {
00766                 allValuesAgree = false; // next location not equiv to previous
00767               }
00768             }
00769             if (allValuesAgree) {
00770               // create similar deref depth on formal parameter
00771               // get mre_formal for mre_actual
00772               OA_ptr<MemRefExpr> mre_final;
00773               OA_ptr<NamedRef> mre_formal;
00774               //mre_formal = new NamedRef(false,true,MemRefExpr::USE,formal);
00775 
00776               
00777               /* PLM 1/23/07 deprecated accuracy 
00778               mre_formal = new NamedRef(true,MemRefExpr::USE,formal);
00779               */
00780 
00781               mre_formal = new NamedRef(MemRefExpr::USE,formal);
00782               mre_final = mre_formal->clone();
00783               
00784               // duplicate number of derefs on callee side as on caller side
00785               for (int i = 0; i < numDerefs; i++) {
00786                 // Deref mre
00787                 OA_ptr<MemRefExpr> nullmre;
00788                 OA_ptr<Deref> deref;
00789                 //deref = new Deref(false,true,MemRefExpr::USE,nullmre,1); 
00790 
00791                 /* PLM 1/23/07
00792                 deref = new Deref(true,MemRefExpr::USE,nullmre,1);
00793                 */
00794 
00795                 deref = new Deref(MemRefExpr::USE,nullmre,1);
00796                 mre_final = deref->composeWith(mre_final);
00797               }
00798               
00799               if (debug) {
00800                 std::cout << "\t\tquerying callee with mre_final = ";
00801                 mre_final->output(*mIR);
00802                 std::cout << std::endl;
00803               }
00804 
00805               // query the alias analysis of Callee for maylocs of mre_final 
00806               OA_ptr<LocIterator> mayLocIter;
00807               mayLocIter = calleeAlias->getMayLocs(*mre_final,callee);
00808               for (; mayLocIter->isValid(); (*mayLocIter)++) { 
00809                 OA_ptr<Location> mayloc = mayLocIter->current();
00810                 if (debug) {
00811                   std::cout << "\t\tmayloc for mre_final, loc = ";
00812                   mayloc->output(*mIR);
00813                 }
00814                 // record the value in cdPtr to mapping for this formal
00815                 OA_ptr<ConstDef> cd;
00816                 cd = new ConstDef(mayloc, cdPtr->getConstPtr(), VALUE);
00817                 retval->insert(cd);
00818                 if (debug) {
00819                   std::cout << "\tconstVal = " 
00820                             << (cdPtr->getConstPtr())->toString() 
00821                             << std::endl;
00822                 }
00823               } // end mayLocs in callee
00824             } // end if all values agree
00825           } // end while found locs
00826         } // end mre loop
00827       } // end else check for addrOf MemRef at top of ExprTree
00828     } // end formal parameter loop
00829 
00830 
00831     //commented out previous MustMayActive treatment for above. BK 8/06
00832     /*    
00833     OA_ptr<ExprHandleIterator> paramIter 
00834         = mParamBind->getActualExprHandleIterator(call);
00835     for (; paramIter->isValid(); (*paramIter)++ ) {
00836       ExprHandle param = paramIter->current();
00837       OA_ptr<ExprTree> etree = mParamBind->getActualExprTree(param);
00838       if (debug) { 
00839           std::cout << "\teTree = ";
00840           etree->dump(std::cout, mIR);
00841       }
00842       
00843       // get ConstValBasicInterface by evaluating expression tree
00844       OA_ptr<ConstValBasicInterface> constVal; 
00845       EvalToConstVisitor evalVisitor(mIR,mReachConstsMap[caller]);
00846       etree->acceptVisitor(evalVisitor);
00847       constVal = evalVisitor.getConstVal();
00848 
00849       // if the parameter evaluates to a constant value
00850       if (!constVal.ptrEqual(NULL)) { 
00851           SymHandle sym = mParamBind->getCalleeFormal(call,param);
00852           OA_ptr<Location> nloc;
00853           nloc = new NamedLoc(sym,true);
00854           OA_ptr<ConstDef> cd; 
00855           cd = new ConstDef(nloc, constVal, VALUE);
00856           retval->insert(cd);
00857           if (debug) {
00858               std::cout << "\nloc = ";
00859               nloc->dump(std::cout, mIR);
00860               std::cout << "\tconstVal = " << constVal->toString() 
00861               << std::endl;
00862           }
00863       }
00864     } 
00865 
00866     // loop over all locations in incoming set and pass through those
00867     // that are not local
00868     ConstDefSetIterator setIter(*inRecast);
00869     
00870     // for each ConstDefLoc in Set1
00871     for (setIter.reset(); setIter.isValid(); ++(setIter)) {
00872         OA_ptr<ConstDef> constDef = setIter.current();
00873         OA_ptr<Location> cdLocPtr = constDef->getLocPtr();
00874         OA_ptr<ConstValBasicInterface> cdConstPtr = constDef->getConstPtr();
00875         ConstDefType cdType = constDef->getConstDefType();
00876 
00877         if (cdLocPtr->isLocal()==false) {
00878           if (debug) {
00879               std::cout << "\tinserting non-local = ";
00880               cdLocPtr->dump(std::cout,mIR);
00881           }
00882           OA_ptr<ConstDef> cd; 
00883           cd = new ConstDef(*constDef);
00884           retval->insert(cd);
00885         }
00886     }
00887  
00888     */
00889     // probably will want to eventually do something with the non-locals, but
00890     // current, new alias analysis breaks with non-locals coming through.
00891     // so results are currently more conservative than they might have been
00892     // in the MustMayActive CVS branch.  BK 8/06
00893 
00894     if (debug) {
00895         std::cout << "\tretval = ";
00896         retval->dump(std::cout, mIR);
00897     }
00898     return retval;
00899 }
00900   
00902 
00907 OA_ptr<DataFlow::DataFlowSet> 
00908 ManagerICFGReachConsts::calleeToCaller(ProcHandle callee,
00909     OA_ptr<DataFlow::DataFlowSet> dfset, CallHandle call, ProcHandle caller)
00910 {
00911     OA_ptr<ConstDefSet> inRecast = dfset.convert<ConstDefSet>();
00912     if (debug) {
00913         std::cout << "-------- ManagerICFGReachConsts::calleeToCaller" 
00914                   << std::endl;
00915         std::cout << "\tinRecast = ";
00916         inRecast->dump(std::cout, mIR);
00917     }
00918     OA_ptr<ConstDefSet> calleeRetVal;
00919     // default will be top
00920     calleeRetVal = new ConstDefSet(TOP);
00921 
00922     // set all locations that are modified by the callee indirectly
00923     // or directly to BOTTOM
00924     OA_ptr<LocIterator> locIterPtr = mInterSE->getMODIterator(callee);
00925     for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00926       OA_ptr<Location> modLocPtr = locIterPtr->current();
00927       OA_ptr<ConstDef> cd;
00928       OA_ptr<ConstValBasicInterface> cdConstPtr;
00929       cd = new ConstDef(modLocPtr, cdConstPtr, BOTTOM);
00930       calleeRetVal->insert(cd);
00931     }
00932 
00933     // Then pick up any constant assignments (they can over-ride the BOTTOMs)
00934     ConstDefSetIterator inIter(*inRecast);
00935     for (inIter.reset(); inIter.isValid(); ++(inIter)) {
00936       OA_ptr<ConstDef> constDef = inIter.current();
00937       calleeRetVal->replace(constDef);
00938     }
00939 
00940     // have visitor convert all locations into aliased locations in
00941     // the caller
00942     OA_ptr<DataFlow::CalleeToCallerVisitor> locVisitor; 
00943     locVisitor = new DataFlow::CalleeToCallerVisitor(callee, call, 
00944                               caller, mInterAlias, mParamBind, mIR);
00945     
00946     OA_ptr<ConstDefSet> retval;
00947     // default will be top
00948     retval = new ConstDefSet(TOP);
00949 
00950     // loop over all locations in calleeRetVal, xform them into aliased
00951     // locations in the caller, to make retval set
00952     ConstDefSetIterator setIter(*calleeRetVal);
00953     for (setIter.reset(); setIter.isValid(); ++(setIter)) {
00954         OA_ptr<ConstDef> constDef = setIter.current();
00955         OA_ptr<Location> cdLocPtr = constDef->getLocPtr();
00956         OA_ptr<ConstValBasicInterface> cdConstPtr = constDef->getConstPtr();
00957         ConstDefType cdType = constDef->getConstDefType();
00958         if (debug) {
00959             std::cout << "\tcallee constDef = ";
00960             constDef->output(*mIR);
00961         }
00962 
00963         cdLocPtr->acceptVisitor(*locVisitor);
00964         OA_ptr<LocIterator> callerLoc = locVisitor->getCallerLocIterator();
00965         for ( ; callerLoc->isValid(); (*callerLoc)++ ) {
00966             if (debug) {
00967               std::cout << "\tGOT a callerLoc = ";
00968               (callerLoc->current())->output(*mIR);
00969               std::cout << std::endl;
00970             }
00971             if (cdType!=retval->getDefaultConstDef()) {
00972                 OA_ptr<ConstDef> cd; 
00973                 cd = new ConstDef(callerLoc->current(), cdConstPtr, cdType);
00974                 retval->insert(cd);
00975             }
00976         }
00977     }
00978 
00979 
00980     if (debug) {
00981         std::cout << "\tretval = ";
00982         retval->dump(std::cout, mIR);
00983     }
00984     return retval;
00985 }
00986 
00989 void 
00990 ManagerICFGReachConsts::setUseMemRef2Const(ProcHandle proc, StmtHandle stmt, 
00991         const ConstDefSet& in) 
00992 {
00993 
00994   // get alias results for procedure
00995   OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(proc);
00996   if (debug) {
00997     std::cout << "in setUseMemRef2Const: using alias for "
00998               << mIR->toString(proc) << "\n";
00999   }
01000 
01001 
01002   // commenting out old code from MustMayActive branch
01003   // replacing with current technique found in ManagerReachConstsStandard
01004   // BK 8/06
01005   /*
01006   // for each use mem ref in this statement
01007   OA_ptr<MemRefHandleIterator> useIterPtr = mIR->getUseMemRefs(stmt);
01008   for (; useIterPtr->isValid(); (*useIterPtr)++) {
01009     MemRefHandle ref = useIterPtr->current();
01010 
01011     // only use must location for this mem ref to determine if
01012     // it is a constant
01013     OA_ptr<LocIterator> locIterPtr = alias->getMustLocs(ref);
01014     
01015     // get first location info
01016     if (! locIterPtr->isValid()) { continue; }
01017     OA_ptr<Location> loc = locIterPtr->current();
01018     // if there are more than one must locs then just conservatively move on
01019     (*locIterPtr)++;  if (locIterPtr->isValid()) { continue; }
01020     OA_ptr<ConstDef> cdPtr = in.find(loc);
01021 
01022     if (cdPtr.ptrEqual(NULL) || (cdPtr->getConstDefType() != VALUE)) {
01023       if (debug) {
01024         std::cout << "a useMemRef (" << mIR->toString(ref) << ") "
01025                   << "missing ConstDef for loc ( "
01026                   << loc->toString(mIR) << ")" << std::endl;
01027         std::cout.flush();
01028       }
01029       // record no constant value for this memref
01030       OA_ptr<ConstValBasicInterface> nullVal;  nullVal = 0;
01031       mReachConstsMap[proc]->updateReachConst(ref,nullVal);
01032 
01033     // it does have a constant value
01034     } else {
01035       mReachConstsMap[proc]->updateReachConst(ref,cdPtr->getConstPtr());
01036     }
01037 
01038   } // end of useMemRef loop
01039 
01040   */
01041 
01042   // for each use mem ref in this statement
01043   OA_ptr<MemRefHandleIterator> useIterPtr = mIR->getUseMemRefs(stmt);
01044   for (; useIterPtr->isValid(); (*useIterPtr)++) {
01045     MemRefHandle ref = useIterPtr->current();
01046 
01047     // get all may locations for this mem ref
01048     OA_ptr<LocIterator> locIterPtr = alias->getMayLocs(ref);
01049    
01050     if (!locIterPtr->isValid()) {
01051       continue; // actual parameters (isAddrOf==1) do not have mayLocs
01052     }
01053 
01054     // set up first location info
01055     OA_ptr<Location> loc = locIterPtr->current();
01056     if (debug) {
01057       std::cout << "First may location (" << loc->toString(mIR) << ")" 
01058                 << std::endl;
01059       std::cout.flush();
01060     }
01061 
01062     OA_ptr<ConstDef> cdPtr = in.find(loc);
01063 
01064     // keep track of useful info for this memref
01065     bool allValuesAgree = true;
01066     if (cdPtr.ptrEqual(NULL)) {
01067       // first location not found in inSet ==> must be TOP or BOTTOM
01068       allValuesAgree = false;
01069     } else if (cdPtr->getConstDefType() != VALUE) {
01070       allValuesAgree = false;
01071       // first value of mayLoc for this memref is not a value
01072     } 
01073 
01074     // Now check that all other mayLocs agree
01075     for (; (allValuesAgree) && (locIterPtr->isValid()); ++(*locIterPtr)) {
01076       OA_ptr<Location> loc = locIterPtr->current();
01077       OA_ptr<ConstDef> cdNextPtr = in.find(loc);
01078       if (cdNextPtr.ptrEqual(NULL)) {
01079         allValuesAgree = false; // next location not found in inSet
01080       } else if (!((*cdPtr).equiv(*cdNextPtr))) {
01081         allValuesAgree = false; // next location not equiv to previous
01082       }
01083     }
01084     if (allValuesAgree) {
01085       // record the value in cdPtr to mapping for this memref
01086       mReachConstsMap[proc]->updateReachConst(ref,cdPtr->getConstPtr());
01087     } else {
01088       // record no constant value for this memref
01089       OA_ptr<ConstValBasicInterface> nullVal;  nullVal = 0;
01090       mReachConstsMap[proc]->updateReachConst(ref,nullVal);
01091     }
01092   } // end of useMemRef loop
01093 
01094 
01095   if (debug) {
01096     OA_ptr<MemRefHandleIterator> useIterPtr = mIR->getUseMemRefs(stmt);
01097     for (; useIterPtr->isValid(); (*useIterPtr)++) {
01098       MemRefHandle ref = useIterPtr->current();
01099       OA_ptr<ConstValBasicInterface> cvbiPtr 
01100           = mReachConstsMap[proc]->getReachConst(ref);
01101       std::cout << "useMemRef(" << mIR->toString(ref) ;
01102       if (cvbiPtr.ptrEqual(NULL)) {
01103         std::cout << ") has no constant value." << std::endl;
01104       } else {
01105         std::cout  << ") maps to VALUE="
01106                    << cvbiPtr->toString() << std::endl;
01107       }
01108     }
01109   }
01110 } // end of setUseMemRef2Const()
01111 
01112 
01115 void 
01116 ManagerICFGReachConsts::setDefMemRef2Const(ProcHandle proc, StmtHandle stmt, 
01117         const ConstDefSet& in) 
01118 {
01119 
01120   // get alias results for procedure
01121   OA_ptr<Alias::Interface> alias = mInterAlias->getAliasResults(proc);
01122 
01123   // update mReachConstsMap for all mayLocs(???) of the DefMemRefs(stmt)
01124   OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(stmt);
01125   for (; defIterPtr->isValid(); (*defIterPtr)++) {
01126     MemRefHandle ref = defIterPtr->current();
01127     
01128     // get all may locations for this mem ref
01129     OA_ptr<LocIterator> locIterPtr = alias->getMayLocs(ref);
01130     
01131     // set up first location info
01132     OA_ptr<Location> loc = locIterPtr->current();
01133     if (debug) {
01134       std::cout << "Finding def location (" << loc->toString(mIR) << ")" 
01135                 << std::endl;
01136       std::cout.flush();
01137     }
01138     
01139     OA_ptr<ConstDef> cdPtr = in.find(loc);
01140     
01141     // keep track of useful info for this memref
01142     bool allValuesAgree = true;
01143     if (cdPtr.ptrEqual(NULL)) {
01144       allValuesAgree = false; // first location not found in inSet
01145       if (debug) {
01146         std::cout << "a defMemRef (" << mIR->toString(ref) << ") "
01147                   << "missing ConstDef for first mayLoc ( "
01148                   << loc->toString(mIR) << ")" << std::endl;
01149         std::cout.flush();
01150       }
01151     } else if (cdPtr->getConstDefType() != VALUE) {
01152       allValuesAgree = false;
01153       // first value of mayLoc for this memref is not a value
01154     } 
01155     
01156     // Now check that all other mayLocs agree
01157     for (; (allValuesAgree) && (locIterPtr->isValid()); ++(*locIterPtr)) {
01158       OA_ptr<Location> loc = locIterPtr->current();
01159       OA_ptr<ConstDef> cdNextPtr = in.find(loc);
01160       if (cdNextPtr.ptrEqual(NULL)) {
01161         allValuesAgree = false; // next location not found in inSet
01162       } else if (!((*cdPtr).equiv(*cdNextPtr))) {
01163         allValuesAgree = false; // next location not equiv to previous
01164       }
01165     }
01166     if (allValuesAgree) {
01167       // record the value in cdPtr to mapping for this memref
01168       mReachConstsMap[proc]->updateReachConst(ref,cdPtr->getConstPtr());
01169     } else {
01170       // record no constant value for this memref
01171       OA_ptr<ConstValBasicInterface> nullValue; nullValue = NULL;
01172       mReachConstsMap[proc]->updateReachConst(ref,nullValue);
01173     }
01174   } // end of defMemRef loop
01175   
01176   if (debug) {
01177     OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(stmt);
01178     for (; defIterPtr->isValid(); (*defIterPtr)++) {
01179       MemRefHandle ref = defIterPtr->current();
01180       OA_ptr<ConstValBasicInterface> cvbiPtr;
01181       cvbiPtr = mReachConstsMap[proc]->getReachConst(ref);
01182       std::cout << "defMemRef(" << mIR->toString(ref);
01183       if (cvbiPtr.ptrEqual(NULL)) {
01184         std::cout << ") has no constant value." << std::cout;
01185       } else {
01186         std::cout << ") maps to VALUE="
01187                   << (mReachConstsMap[proc]->getReachConst(ref))->toString() 
01188                   << std::endl;
01189       }
01190     }
01191   }
01192 } // end of setDefMemRef2Const()
01193 
01196 OA_ptr<DataFlow::DataFlowSet> 
01197 ManagerICFGReachConsts::exitTransfer(ProcHandle proc, 
01198                                      OA_ptr<DataFlow::DataFlowSet> out)
01199 {
01200     return out;
01201 }
01202 
01203 OA_ptr<DataFlow::DataFlowSet> 
01204 ManagerICFGReachConsts::entryTransfer(ProcHandle proc, 
01205                                       OA_ptr<DataFlow::DataFlowSet> in)
01206 {
01207     return in;
01208 }
01209 
01211 OA_ptr<DataFlow::DataFlowSet> 
01212 ManagerICFGReachConsts::callToReturn(ProcHandle caller,
01213                                      OA_ptr<DataFlow::DataFlowSet> dfset, 
01214                                      CallHandle call, ProcHandle callee)
01215 {
01216   if (debug) {
01217     std::cout << "-------- ManagerICFGReachConsts::callToReturn" << std::endl;
01218   }
01219   // When this was a C_FLOW_EDGE, we just used the dfset
01220   // so, just return a clone of the dfset
01221   
01222   // BK:  not sure reasoning above is correct.  The whole reason we added
01223   //      a CALL_RETURN edge was so that it would NOT be treated as a
01224   //      C_FLOW edge.  
01225   
01226   // stopped here BK XXXXX
01227   
01228   // create a default TOP set
01229   //OA_ptr<ConstDefSet> retval;
01230   //retval = new ConstDefSet(TOP);
01231   
01232   // pass on a copy of input
01233   return dfset->clone();
01234   
01235   // why don't we have to do something like (BK): // haven't really looked
01236   /*
01237   // create retval as copy of dfset
01238   OA_ptr<ConstDefSet> remapdfset = dfset.convert<ConstDefSet>();
01239   OA_ptr<ConstDefSet> retval;
01240   OA_ptr<DataFlow::DataFlowSet> temp = remapdfset->clone();
01241   retval = temp.convert<ConstDefSet>();
01242   return retval;
01243   */
01244 
01245 }
01246 
01247 
01248   } // end of namespace ReachConsts
01249 } // end of namespace OA