ReachConstsStandard.hpp

Go to the documentation of this file.
00001 
00016 #ifndef ReachConstsStandard_hpp
00017 #define ReachConstsStandard_hpp
00018 
00019 #include <cassert>
00020 #include <iostream>
00021 #include <map>
00022 #include <set>
00023 #include <vector>
00024 #include <OpenAnalysis/IRInterface/IRHandles.hpp>
00025 #include <OpenAnalysis/Utils/OA_ptr.hpp>
00026 #include <OpenAnalysis/DataFlow/DataFlowSet.hpp>
00027 #include <OpenAnalysis/ReachConsts/Interface.hpp>
00028 #include <OpenAnalysis/IRInterface/ReachConstsIRInterface.hpp>
00029 #include <OpenAnalysis/IRInterface/ConstValBasicInterface.hpp>
00030 #include <OpenAnalysis/Location/Locations.hpp>
00031 #include <OpenAnalysis/OABase/Annotation.hpp>
00032 #include <OpenAnalysis/Utils/GenOutputTool.hpp>
00033 
00034 
00035 namespace OA {
00036   namespace ReachConsts {
00037 
00038 class ConstDef;
00039 class ConstDefSet;
00040 class ConstDefSetIterator;
00041 
00043 // a value if it should be TOP or BOTTOM --> TOP means that the value
00044 // is as it came into the procedure, BOTTOM means that the value cannot
00045 // be determined here due to conflicting defs.
00046 enum ConstDefType {TOP, VALUE, BOTTOM};
00047 
00048 
00050 // Might want to change this to be able to include Top or Bottom
00051 // as the value associated with a location.
00052 // Currently:
00053 //  if constValBasic should be Bottom, constValBasic pointer is null (i.e. 0)
00054 //  if constValBasic should be Top, then Location pointer is not in ConstDefSet
00055 // Added a tag field: TOP,BOTTOM,VALUE
00056 class ConstDef : public virtual Annotation
00057 {
00058 public:
00059   // constructors
00060   ConstDef(OA_ptr<Location> locP, 
00061            OA_ptr<ConstValBasicInterface> cvbP, ConstDefType cdType);
00062   ConstDef(OA_ptr<Location> locP, 
00063            OA_ptr<ConstValBasicInterface> cvbP);
00064   ConstDef(OA_ptr<Location> locP, ConstDefType cdType);
00065   ConstDef(OA_ptr<Location> locP);
00066   ConstDef(ConstDef& other) : mLocPtr(other.mLocPtr), 
00067                               mConstPtr(other.mConstPtr), 
00068                               mCDType(other.mCDType) {}
00069   ConstDef() { }
00070   ~ConstDef() { }
00071 
00072   // access
00073   OA_ptr<Location> getLocPtr() const { return mLocPtr; }
00074   OA_ptr<ConstValBasicInterface> getConstPtr() const { return mConstPtr; }
00075   ConstDefType getConstDefType() const { return mCDType; }
00076 
00077   // relationships
00078   ConstDef& operator= (const ConstDef& other);
00079 
00081   OA_ptr<ConstDef> clone() 
00082       { OA_ptr<ConstDef> retval; retval = new ConstDef(*this);
00083         return retval;
00084       }
00085 
00086   void output(IRHandlesIRInterface& pIR);
00087    
00088 
00090   bool operator== (const ConstDef &other) const ;
00092   bool equiv(const ConstDef& other);
00093 
00094   bool operator!= (const ConstDef &other) const { return !(*this==other); }
00095   bool operator< (const ConstDef &other) const ;
00096   bool sameLoc (const ConstDef &other) const {
00097     if (mLocPtr==(other.getLocPtr())) { 
00098         return true; 
00099     } else {
00100         return false;
00101     }
00102   }
00103 
00104   // debugging
00105   std::string toString(OA_ptr<IRHandlesIRInterface> pIR);
00106   
00107   void dump(std::ostream &os, OA_ptr<IRHandlesIRInterface> pIR) {
00108     os << toString(pIR) << std::endl;
00109   }
00110   
00111 private:
00112 
00113   
00114   OA_ptr<Location> mLocPtr;
00115   OA_ptr<ConstValBasicInterface> mConstPtr;
00116   ConstDefType mCDType;
00117 };
00118 
00120 // members of ReachConstsStandard
00121 class ConstDefSet  : public virtual DataFlow::DataFlowSet,
00122                      public virtual Annotation
00123 {
00124 public:
00125   // construction
00126   //ConstDefSet() { mSet = new std::set<OA_ptr<ConstDef> >; }
00127   //ConstDefSet(const ConstDefSet& other) : mSet(other.mSet) {}
00128   ConstDefSet() : mDefaultType(TOP) { mSet = new std::set<OA_ptr<ConstDef> >; }
00129   ConstDefSet(ConstDefType defaultType) : mDefaultType(defaultType) 
00130     { mSet = new std::set<OA_ptr<ConstDef> >; }
00131   ConstDefSet(const ConstDefSet& other) 
00132       : mDefaultType(other.mDefaultType),mSet(other.mSet) {}
00133   ~ConstDefSet() { }
00134 
00135 
00136   void output(IRHandlesIRInterface& ir);
00137   
00142   ConstDefSet& operator= (const ConstDefSet& other) 
00143       {
00144         mSet = other.mSet;
00145         mDefaultType = other.mDefaultType;
00146         return *this;
00147       }
00148   OA_ptr<DataFlow::DataFlowSet> clone()
00149       { OA_ptr<ConstDefSet> retval;
00150         retval = new ConstDefSet(mDefaultType);
00151         std::set<OA_ptr<ConstDef> >::iterator defIter;
00152         for (defIter=mSet->begin(); defIter!=mSet->end(); defIter++) {
00153           OA_ptr<ConstDef> def = *defIter;
00154           retval->insert(def->clone());
00155         }
00156         return retval;
00157       }
00158 
00159   void insert(OA_ptr<ConstDef> h) { mSet->insert(h); }
00160   void remove(OA_ptr<ConstDef> h) { removeANDtell(h); }
00161   int insertANDtell(OA_ptr<ConstDef> h) 
00162       { return (int)((mSet->insert(h)).second); }
00163   int removeANDtell(OA_ptr<ConstDef> h) { return (mSet->erase(h)); }
00164 
00166   // with ConstDef(locPtr,constPtr,cdType)
00167   // must use this instead of insert because std::set::insert will just see
00168   // that the element with the same locptr is already in the set and then not
00169   // insert the new element
00170   void replace(OA_ptr<Location> locPtr,
00171                OA_ptr<ConstValBasicInterface> constPtr,
00172                ConstDefType cdType);
00173   void replace(OA_ptr<ConstDef> cd);
00174 
00175   // relationship
00176   // param for these can't be const because will have to 
00177   // dynamic cast to specific subclass
00178   bool operator ==(DataFlow::DataFlowSet &other) const;
00179   bool operator !=(DataFlow::DataFlowSet &other) const
00180   { return (!(*this==other)); }
00181 
00183   bool operator==(const ConstDefSet& other) const 
00184   { return ConstDefSet::operator==(const_cast<ConstDefSet&>(other)); }
00185 
00186   bool empty() const { return mSet->empty(); }
00187   
00190   OA_ptr<ConstDef> find(OA_ptr<Location> locPtr) const;
00191 
00192   // debugging
00193   
00194   std::string toString(OA_ptr<IRHandlesIRInterface> pIR);
00195   void dump(std::ostream &os, OA_ptr<IRHandlesIRInterface> pIR)
00196   { os << toString(pIR) << std::endl; }
00197 
00198   void dump(std::ostream &os) {}
00199 
00201   ConstDefType getDefaultConstDef() const { return mDefaultType; }
00203   void setDefaultConstDef(ConstDefType cdt) 
00204   { assert(cdt!=VALUE); mDefaultType = cdt; }
00205 
00206 private:
00207   ConstDefType mDefaultType;  // TOP or BOTTOM
00208 
00209 protected:
00210   
00211   OA_ptr<std::set<OA_ptr<ConstDef> > > mSet;
00212 
00213   friend class ConstDefSetIterator;
00214 };
00215     
00216 
00217   
00219 class ConstDefSetIterator {
00220 public:
00221   ConstDefSetIterator (ConstDefSet& CDSet) : mSet(CDSet.mSet) 
00222       { assert(!mSet.ptrEqual(NULL)); mCDIter = mSet->begin(); }
00223   ~ConstDefSetIterator () {}
00224   
00225   void operator ++ () { if (isValid()) mCDIter++; }
00227   bool isValid() { return (mCDIter != mSet->end()); }
00229   OA_ptr<ConstDef> current() { assert(isValid()); return (*mCDIter); }
00231   void reset() { mCDIter = mSet->begin(); }
00232 
00233 private:
00234   OA_ptr<std::set<OA_ptr<ConstDef> > > mSet;
00235   std::set<OA_ptr<ConstDef> >::iterator mCDIter;
00236 };
00237 
00238 class ReachConstsStandard : public virtual Interface, 
00239                             public virtual Annotation
00240 {
00241   public:
00242     ReachConstsStandard(ProcHandle p) {}
00243     ~ReachConstsStandard() {}
00244 
00246     OA_ptr<ConstDefSet> getReachConsts(StmtHandle s) 
00247     { if (mReachConsts[s].ptrEqual(NULL)) {
00248         mReachConsts[s] = new ConstDefSet;
00249       }
00250       return mReachConsts[s]; 
00251     }
00252 
00256     OA_ptr<ConstValBasicInterface> getReachConst(MemRefHandle h) 
00257     { OA_ptr<ConstValBasicInterface> retval; retval = NULL;
00258       if (mMemRef2ReachConst.find(h)!= mMemRef2ReachConst.end())
00259       { retval= mMemRef2ReachConst[h];}  
00260       return retval; 
00261     }
00262 
00263     void output(IRHandlesIRInterface& ir);
00264 
00265     //*****************************************************************
00266     // Construction methods 
00267     //*****************************************************************
00268 
00270     void insertConstDef(StmtHandle s, OA_ptr<ConstDef> cd, ConstDefType t=TOP)
00271     { if (mReachConsts[s].ptrEqual(NULL)) {
00272         mReachConsts[s] = new ConstDefSet(t);
00273       }
00274       // have to call replace because only compare ConstsDefs by loc
00275       mReachConsts[s]->replace(cd);  
00276     }
00277 
00281     void resetConstDefSet(StmtHandle s, ConstDefType t=TOP)
00282     { mReachConsts[s] = new ConstDefSet(t); }
00283 
00285     void updateReachConst(MemRefHandle ref, 
00286                           OA_ptr<ConstValBasicInterface> cPtr)
00287     { mMemRef2ReachConst[ref]=cPtr; }
00288 
00289     //*****************************************************************
00290     // Output
00291     //*****************************************************************
00292 
00296     void dump(std::ostream& os, OA_ptr<OA::IRHandlesIRInterface> ir);
00297 
00299     OA_ptr<ConstDefSetIterator> getConstDefIterator(StmtHandle s) 
00300     {
00301         OA_ptr<ConstDefSetIterator> retval;
00302         retval = new ConstDefSetIterator(*(mReachConsts[s]));
00303         return retval;
00304     }
00305 
00307     std::string getMemRefConstInfo();
00308 
00309   private:
00310     
00311     // data members
00312     std::map<StmtHandle, OA_ptr<ConstDefSet> > mReachConsts;
00313     std::map<MemRefHandle,OA_ptr<ConstValBasicInterface> > mMemRef2ReachConst;
00314 
00315 };
00316 
00317 
00318   } // end of ReachConsts namespace
00319 } // end of OA namespace
00320 
00321 #endif
00322