ICFG.hpp

Go to the documentation of this file.
00001 
00016 //--------------------------------------------------------------------
00017 //--------------------------------------------------------------------
00018 
00019 #ifndef ICFG_H
00020 #define ICFG_H
00021 
00022 //--------------------------------------------------------------------
00023 // STL headers
00024 #include <list>
00025 #include <map>
00026 
00027 // OpenAnalysis headers
00028 #include <OpenAnalysis/Utils/OA_ptr.hpp>
00029 #include <OpenAnalysis/Utils/DGraph/DGraphImplement.hpp>
00030 #include <OpenAnalysis/Utils/DGraph/DGraphInterface.hpp>
00031 #include <OpenAnalysis/CFG/CFG.hpp>
00032 #include "ICFGInterface.hpp"
00033 
00034 //=================================================================
00035 // ICFG is the special case of CFG and it can access CFG directly
00036 // without using CFGInterface.
00037 //=================================================================
00038 
00039 //--------------------------------------------------------------------
00040 
00041 namespace OA {
00042   namespace ICFG {
00043       
00044 // Changes here must be also reflected in edgeTypeToString 
00045 // and nodeTypeToString.
00046  
00047 //--------------------------------------------------------------------
00053   class Node;
00054   class Edge;
00055 
00056   class NodesIterator;
00057 
00058   class EdgesIterator;
00059   class ICFG;
00060 
00061  
00062   //--------------------------------------------------------
00063   class Node : public virtual NodeInterface,
00064                public virtual DGraph::NodeImplement
00065   {
00066   public:
00067     Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType);
00068     Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType, 
00069           OA_ptr<CFG::NodeInterface> cNode); 
00070     // from MustMayActive branch:
00071     Node (Node& other) ;
00072 
00073     ~Node ();
00074     
00075     //========================================================
00076     // Info specific to ICFG
00077     //========================================================
00078     
00079     NodeType getType() const;
00080 
00081     ProcHandle getProc() const;
00082     
00084     unsigned int size () const;
00085 
00087     OA_ptr<CFG::NodeStatementsIteratorInterface> 
00088         getNodeStatementsIterator() const;
00089 
00091     OA_ptr<CFG::NodeStatementsRevIteratorInterface> 
00092         getNodeStatementsRevIterator() const;
00093 
00094     //========================================================
00095     // Construction Methods
00096     //========================================================
00097 
00098     void addCallEdge(OA_ptr<Edge> e);
00099     void addReturnEdge(OA_ptr<Edge> e);
00100 
00101     // from MustMayActive branch:
00102     void removeCallEdge( OA_ptr<Edge> e);
00103     void removeReturnEdge( OA_ptr<Edge> e);
00104 
00105     /*
00106     //========================================================
00107     // Construction
00108     //========================================================
00109     void addIncomingEdge(OA_ptr<DGraph::EdgeInterface> e);
00110 
00111     void addOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e);
00112 
00113     void removeIncomingEdge(OA_ptr<DGraph::EdgeInterface> e);
00114 
00115     void removeOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e);
00116     */
00117     
00118     // from MustMayActive branch:
00119     //    void removeCallEdge( OA_ptr<Edge> e) { mCallEdges->remove(e); }
00120     //    void removeReturnEdge( OA_ptr<Edge> e) { mReturnEdges->remove(e); }    
00121     //========================================================
00122     // DGraph::Interface::Node interface
00123     //========================================================
00124     
00126     //unsigned int getId() const;
00127     
00128     /*
00130     int num_incoming () const;
00131     
00133     int num_outgoing () const;
00134 
00136     bool isAnEntry() const;
00137 
00139     bool isAnExit() const;
00140 
00141     bool operator==(DGraph::NodeInterface& other);
00142     bool operator<(DGraph::NodeInterface& other);
00143     */
00144    
00145     /*
00146     //===============================================================
00147     // These methods shadow the same named methods in
00148     // the DGraph::Interface class and allow us to return
00149     // the more specific subclass
00150     //========================================================
00151     OA_ptr<DGraph::EdgesIteratorInterface> getIncomingEdgesIterator() const;
00152 
00153     OA_ptr<DGraph::EdgesIteratorInterface> getOutgoingEdgesIterator() const;
00154 
00155     OA_ptr<DGraph::NodesIteratorInterface> getSourceNodesIterator() const;
00156 
00157     OA_ptr<DGraph::NodesIteratorInterface> getSinkNodesIterator() const;
00158     */
00159 
00160     //=====================================================================
00161 
00162     OA_ptr<EdgesIteratorInterface> getICFGIncomingEdgesIterator() const;
00163 
00164     OA_ptr<EdgesIteratorInterface> getICFGOutgoingEdgesIterator() const;
00165 
00166     OA_ptr<NodesIteratorInterface> getICFGSourceNodesIterator() const;
00167 
00168     OA_ptr<NodesIteratorInterface> getICFGSinkNodesIterator() const;
00169 
00170     //========================================================
00171     // Output
00172     //========================================================
00173     void dump(std::ostream& os) {} // for full override
00174     void dumpbase(std::ostream& os) {}
00175     void dump(std::ostream& os, OA_ptr<IRHandlesIRInterface> ir);
00176     void dumpdot(ICFG&,
00177                  std::ostream& os, OA_ptr<IRHandlesIRInterface> ir);
00178 
00179     void longdump(ICFG& icfg, std::ostream& os,
00180                   OA_ptr<IRHandlesIRInterface> ir);
00181 
00182     virtual void output(OA::IRHandlesIRInterface& ir);
00183 
00184 
00185     //------------------------------------------------------------------
00186   
00187 
00188   private:
00189      void Ctor();
00190 
00191     // ========================================================== 
00192     // if we are a ENTRY_Node and have CallEdges then we
00193     // are the entry to a CFG and the CallEdges are incoming
00194     // if we are a EXIT_Node and have ReturnEdges then 
00195     // we are the exit to a CFG and the return edges are outgoing
00196     // if we are a Call node then the call edges are outgoing
00197     // if we are a return node then the call edges are incoming
00198     // ==========================================================
00199     // 
00200     OA_ptr<std::list<OA_ptr<Edge> > > mCallEdges;
00201     OA_ptr<std::list<OA_ptr<Edge> > > mReturnEdges;
00202 
00203 
00204     OA_ptr<ICFG> mICFG;             // enclosing ICFG
00205     ProcHandle mProc;               // enclosing procedure
00206     NodeType mType;                 // node type
00207     OA_ptr<CFG::NodeInterface> mCFGNode;        // corresponding CFG node
00208     //DGraph::NodeImplement mDGNode;  // corresponding DGraph node
00209                                                    // in DGraph that keeps 
00210                                                    // structure
00211 
00212     friend class ICFG;
00213     friend class Edge;
00214   };
00215   
00216   // lt_Node: function object that compares by id.  Useful for sorting.
00217   class lt_Node : public DGraph::lt_NodeInterface {
00218   public:
00219     // return true if n1 < n2; false otherwise
00220     bool operator()(const OA_ptr<DGraph::NodeInterface> n1, 
00221                     const OA_ptr<DGraph::NodeInterface> n2) const ;
00222   };
00223  
00224   /*
00226   OA::OA_ptr<DGraph::Interface::lt_Node> getNodeCompare() const 
00227   { OA::OA_ptr<DGraph::Interface::lt_Node> retval; retval= new lt_Node();  
00228     return retval; 
00229   }
00230  */
00231  
00232   //--------------------------------------------------------
00233   class Edge : public virtual EdgeInterface,
00234                public virtual DGraph::EdgeImplement
00235   {
00236   public:
00237 
00238 
00239     Edge (OA_ptr<ICFG> pICFG,
00240           OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType,
00241           CallHandle call);
00242 
00243 
00244     Edge (OA_ptr<ICFG> pICFG,
00245           OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType);
00246 
00247     
00248     ~Edge ();
00249     
00250     //========================================================
00251     // Info specific to ICFG
00252     //========================================================
00253     
00254     EdgeType getType() const;
00255 
00256     ProcHandle getSourceProc() const;
00257     ProcHandle getSinkProc() const;
00258     
00259     CallHandle getCall() const;
00260 
00261     //========================================================
00262     // DGraph::Interface::Edge interface
00263     //========================================================
00264     
00266     //unsigned int getId() const;
00267 
00268     
00269     /*
00271     OA_ptr<DGraph::NodeInterface> getSource () const;
00272     // FIXME: tail and head should be done like source and sink
00273     // in DGraph::Interface and here
00274     OA_ptr<DGraph::NodeInterface> getTail () const;
00275     
00277     OA_ptr<DGraph::NodeInterface> getSink () const;
00278     OA_ptr<DGraph::NodeInterface> getHead () const;
00279     */
00280 
00281     OA_ptr<NodeInterface> getICFGSource() const;
00282 
00283     OA_ptr<NodeInterface> getICFGSink() const;
00284     
00285     /*
00286     bool operator==(DGraph::EdgeInterface& other);
00287     bool operator<(DGraph::EdgeInterface& other);
00288     */
00289 
00290     void dump (std::ostream& os);
00291     void dumpdot (std::ostream& os);
00292     void dumpbase (std::ostream& os) {}
00293     virtual void output(OA::IRHandlesIRInterface& ir);  
00294 
00295 
00296   private:
00297 
00298     OA_ptr<ICFG> mICFG;
00299     OA_ptr<Node> mNode1, mNode2;
00300     //DGraph::EdgeImplement mDGEdge;
00301 
00302     EdgeType mType;
00303     CallHandle mCall;
00304 
00305     friend class ICFG;
00306     friend class Node;
00307 
00308   }; 
00309   
00310   // lt_Edge: function object that compares by source and sink node
00311   // ids.  Useful for sorting.  Not used to put edges in sets or other
00312   // STL containers.
00313   
00314   class lt_Edge : public DGraph::lt_EdgeInterface {
00315   public:
00316       bool operator()(const OA_ptr<DGraph::EdgeInterface> e1, 
00317                       const OA_ptr<DGraph::EdgeInterface> e2) const;
00318   };
00319 
00320   /*
00321   
00323   OA::OA_ptr<DGraph::Interface::lt_Edge> getEdgeCompare() const 
00324   { OA::OA_ptr<DGraph::Interface::lt_Edge> retval; retval= new lt_Edge();  
00325     return retval; 
00326   }
00327 
00328 */
00329 
00330   //------------------------------------------------------------------
00334   class NodesIterator : public DGraph::NodesIteratorImplement, 
00335                         public virtual NodesIteratorInterface
00336   {
00337   public:
00338     NodesIterator(OA_ptr<DGraph::NodesIteratorInterface> ni);
00339 
00340     OA_ptr<NodeInterface> currentICFGNode() const ;
00341     
00342   };
00343   
00344   //------------------------------------------------------------------
00348   class EdgesIterator : public DGraph::EdgesIteratorImplement,
00349                         public virtual EdgesIteratorInterface
00350   {
00351   public:
00352       
00353      EdgesIterator(OA_ptr<DGraph::EdgesIteratorInterface> ni);
00354 
00355     OA_ptr<EdgeInterface> currentICFGEdge() const;
00356 
00357   };
00358   
00359 
00360 //------------------------------------------------------------------
00361 class ICFG : public virtual ICFGInterface,
00362              public virtual DGraph::DGraphImplement
00363 {
00364   
00365 public:
00366   ICFG (); 
00367   virtual ~ICFG ();
00368 
00369   /*
00370   int getNumNodes();
00371   int getNumEdges();
00372   */      
00373   
00374   //-------------------------------------
00375   // ICFG information access
00376   //-------------------------------------
00377   //OA_ptr<Node> getEntry() { return mEntry; }
00378   //OA_ptr<Node> getExit() { return mExit; }
00379 
00382   /*
00383   OA_ptr<Edge> getICFGEdge(OA_ptr<DGraph::EdgeImplement> dgEdge) const;
00384   */
00387   
00388   /*
00389   OA_ptr<Node> getICFGNode(OA_ptr<DGraph::NodeImplement> dgNode) const;
00390   */
00391   
00392   //========================================================
00393   // Construction
00394   //========================================================
00395   //void addNode(OA_ptr<Node> pNode);
00396   void addEdge(OA_ptr<Edge> pEdge);
00397 
00398   //=======================================================
00399   // From MustMayActive
00400   // =====================================================
00401   // 
00402   void removeEdge(OA_ptr<Edge> e);
00403 
00404   //void removeNode(OA_ptr<DGraph::NodeInterface> n);
00405 
00406   // can't do connect by creating a new edge in a member function
00407   // because edges have to have an OA_ptr to containing ICFG
00408   //void connect(OA_ptr<Node> pNode1, OA_ptr<Node> pNode2,
00409   //             EdgeType pType);
00410 
00411   //========================================================
00412   // Output 
00413   //========================================================
00414   void dump (std::ostream& os, OA_ptr<IRHandlesIRInterface> ir);
00415   void dumpdot (std::ostream& os, OA_ptr<IRHandlesIRInterface> ir);
00416   void dumpbase(std::ostream& os) {}
00417   virtual void output(OA::IRHandlesIRInterface& ir);  
00418 
00419 
00420    //========================================================
00421    // Construction
00422    //========================================================
00423    /*
00424    void addNode(OA_ptr<DGraph::NodeInterface> n);
00425 
00426    void addEdge(OA_ptr<DGraph::EdgeInterface> e);
00427    */
00428 
00429   // =================================================================
00430   // Using trick of imitating covariance when getting all iterators
00431   // so that get an iterator specific to actual subclass
00432   // This is why have these getBlahIterator methods that shadow those
00433   // in DGraph::Interface and also have the protected ones
00434   // that must be defined here which override implementation in 
00435   // DGraph::Interface
00436   //==================================================================
00437   
00438   /*
00439   OA_ptr<DGraph::NodesIteratorInterface> 
00440       getNodesIterator() const;
00441 
00442   OA_ptr<DGraph::NodesIteratorInterface> 
00443       getEntryNodesIterator() const;
00444 
00445   OA_ptr<DGraph::NodesIteratorInterface> 
00446       getExitNodesIterator() const;
00447 
00448   OA_ptr<DGraph::EdgesIteratorInterface> 
00449       getEdgesIterator() const;
00450 
00451   OA_ptr<DGraph::NodesIteratorInterface> 
00452     getReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient);
00453 
00454   OA_ptr<DGraph::NodesIteratorInterface>
00455       getDFSIterator(OA_ptr<DGraph::NodeInterface> n);
00456   */
00457   
00458   OA_ptr<NodesIteratorInterface> 
00459       getICFGNodesIterator() const;
00460 
00461   OA_ptr<EdgesIteratorInterface> 
00462       getICFGEdgesIterator() const;
00463 
00464   OA_ptr<NodesIteratorInterface> 
00465       getICFGEntryNodesIterator() const;
00466 
00467   OA_ptr<NodesIteratorInterface> 
00468       getICFGExitNodesIterator() const;
00469 
00470   OA_ptr<NodesIteratorInterface>
00471     getICFGReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient);
00472 
00473   OA_ptr<NodesIteratorInterface> 
00474       getICFGDFSIterator(OA_ptr<NodeInterface> n);
00475 
00476  private:
00477   OA_ptr<Node> mEntry; 
00478   OA_ptr<Node> mExit;
00479 
00480 
00481 
00482   // dgraph that will store underlying graph structure
00483   //DGraph::DGraphImplement mDGraph;
00484 
00485 
00486   // using lists instead of sets because some of the iterators
00487   // need an ordered list of things and only want to have one
00488   // NodeIterator and EdgesIterator implementation
00489   OA_ptr<std::list<OA_ptr<Node> > > mCallNodes;
00490   OA_ptr<std::list<OA_ptr<Edge> > > mCallEdges;
00491   OA_ptr<std::list<OA_ptr<Node> > > mReturnNodes;
00492   OA_ptr<std::list<OA_ptr<Edge> > > mReturnEdges;
00493 
00494 
00495 };
00496 //--------------------------------------------------------------------
00497 
00498   } // end of ICFG namespace
00499 } // end of OA namespace
00500 
00501 #endif