Program Listing for File nodeState.h

Program Listing for File nodeState.h#

Return to documentation for file (src/midend/programAnalysis/genericDataflow/state/nodeState.h)

#include <featureTests.h>
#ifdef ROSE_ENABLE_SOURCE_ANALYSIS

#ifndef NODE_STATE_H
#define NODE_STATE_H

#include "DataflowCFG.h"
class NodeFact;
class NodeState;

#include "lattice.h"
#include "analysis.h"
#include <map>
#include <vector>
#include <string>
#include <set>

#ifdef THREADED
#include "tbb/concurrent_hash_map.h"
#include "tbb/atomic.h"
#endif


//template<class factType>
/************************************************
 ***               NodeFact                   ***
 *** A fact associated with a CFG node by     ***
 *** some analysis thatis not evolved as part ***
 *** of a dataflow analysis (i.e. it should   ***
 *** stay constant throughout the analysis).  ***
 ************************************************/
// A fact associated with a CFG node that is not part of a dataflow analysis. In other words,
// it is not a lattice and is not meant to evolve during the course of a dataflow analysis.
class NodeFact: public printable
{
        public:

        // The string that represents this object.
        // Every line of this string must be prefixed by indent.
        // The last character of the returned string must not be '\n', even if it is a multi-line string.
        //virtual string str(string indent="")=0;

                // returns a copy of this node fact
        virtual NodeFact* copy() const=0;

/*      void* fact;

        public:
        NodeFact(void* fact)
        {
                this->fact = fact;
        }

        NodeFact(factType* fact)
        {
                this->fact = *fact;
        }

        void* getFact()
        {
                return fact;
        }*/
};


/**********************************************
 ***               NodeState                ***
 *** The state of all the Lattice elements  ***
 *** associated by dataflow analyses with a ***
 *** given node. This state will evolve as  ***
 *** a result of the dataflow analysis.     ***
 **********************************************/
#ifdef THREADED
class NodeStateHashCompare
{
        public:
        NodeStateHashCompare() {}
        NodeStateHashCompare(const NodeStateHashCompare & that) {}

        ~NodeStateHashCompare(){}

        static bool equal(const Analysis* & j, const Analysis* & k )
        { return j==k; }

        static bool equal(const Analysis* const & j, const Analysis* const & k )
        { return j==k; }

        static size_t hash( const Analysis* k ) { return (size_t) k; }
};
#endif

class NodeState
{
        #ifdef THREADED
        typedef tbb::concurrent_hash_map <Analysis*, std::vector<Lattice*>, NodeStateHashCompare > LatticeMap;
        //typedef tbb::concurrent_hash_map <Analysis*, map <int, NodeFact*>, NodeStateHashCompare > NodeFactMap;
        typedef tbb::concurrent_hash_map <Analysis*, std::vector<NodeFact*>, NodeStateHashCompare > NodeFactMap;
        typedef tbb::concurrent_hash_map <Analysis*, bool, NodeStateHashCompare  > BoolMap;
        #else
        typedef std::map<Analysis*, std::vector<Lattice*> > LatticeMap;
        //typedef std::map<Analysis*, std::map<int, NodeFact*> > NodeFactMap;
        typedef std::map<Analysis*, std::vector<NodeFact*> > NodeFactMap;
        typedef std::map<Analysis*, bool > BoolMap;
        #endif

        // the dataflow information Above the node, for each analysis that
        // may be interested in the current node
        LatticeMap dfInfoAbove;

        // the Analysis information Below the node, for each analysis that
        // may be interested in the current node
        LatticeMap dfInfoBelow;

        // the facts that are true at this node, for each analysis that
        // may be interested in the current node
        NodeFactMap facts;

        // Contains all the Analyses that have initialized their state at this node. It is a map because
        // TBB doesn't provide a concurrent set.
        BoolMap initializedAnalyses;

        // the dataflow node that this NodeState object corresponds to
        //DataflowNode parentNode;

        public:
        /*NodeState(DataflowNode& parentNode) : parentNode(parentNode)
        {}

        NodeState(CFGNode& parentNode) : parentNode(parentNode)
        {}

        NodeState(CFGNode parentNode) : parentNode(parentNode)
        {}*/

        NodeState()
        {}

/*      void initialize(Analysis* analysis, int latticeName)
        {
                initDfMap(dfInfoAbove);
                initDfMap(dfInfoBelow);
        }

        private:
        // initializes the given lattice owned by the given analysis in the given map
        // dfMap may be either dfInfoAbove or dfInfoBelow
        void initDfMap(std::map<Analysis*, std::vector<Lattice*> >& dfMap)
        {
                std::map<Analysis*, std::vector<Lattice*> >::iterator dfLattices;
                // if this analysis has registered some Lattices at this node
                if((dfLattices = dfMap.find(analysis)) != dfInfoAbove.end())
                {
                        std::map<int, Lattice>::iterator it;
                        // if the given lattice name was registered by this analysis
                        if((it = (*dfLattices).find(latticeName) != (*dfLattices).end())
                        {
                                (*it)->initialize();
                        }
                        else
                        {
                                (*dfLattices)[latticeName] = new Lattice();
                        }
                }
                else
                {
                        std::map<int, Lattice> newMap;
                        Lattice newLattice;
                        newMap[latticeName] = newLattice;
                        dfMap[analysis] = newMap;
                }
        }*/

        public:
        // Records that this analysis has initializedAnalyses its state at this node
        void initialized(Analysis* analysis);

        // Returns true if this analysis has initialized its state at this node and false otherwise
        bool isInitialized(Analysis* analysis);

        // adds the given lattice, organizing it under the given analysis and lattice name
        //void addLattice(const Analysis* analysis, int latticeName, Lattice* l);


        // Set this node's lattices for this analysis (possibly above or below only, replacing previous mappings)
        // These methods take ownership of the pointed-to lattices.
        void setLattices(const Analysis* analysis, std::vector<Lattice*>& lattices);
        void setLatticeAbove(const Analysis* analysis, std::vector<Lattice*>& lattices);
        void setLatticeBelow(const Analysis* analysis, std::vector<Lattice*>& lattices);

        // returns the given lattice from above the node that is owned by the given analysis
        Lattice* getLatticeAbove(const Analysis* analysis, int latticeName) const;
        // returns the given lattice from below the node that is owned by the given analysis
        Lattice* getLatticeBelow(const Analysis* analysis, int latticeName) const;

        // (read-only access)
        static const std::vector<Lattice*>& getLatticeAbove(const Analysis* analysis, SgNode* n, unsigned int index ) ;

        // returns all the lattices from below the CFG node (corresponding to SgNode and an CFG index) that are owned by the given analysis
        // (read-only access)
        static const std::vector<Lattice*>& getLatticeBelow(const Analysis* analysis, SgNode* n, unsigned int index) ;


        // returns the map containing all the lattices from above the node that are owned by the given analysis
        // (read-only access)
        const std::vector<Lattice*>& getLatticeAbove(const Analysis* analysis) const;
        // returns the map containing all the lattices from below the node that are owned by the given analysis
        // (read-only access)
        const std::vector<Lattice*>& getLatticeBelow(const Analysis* analysis) const;

        // returns the map containing all the lattices from above the node that are owned by the given analysis
        // (read/write access)
        std::vector<Lattice*>& getLatticeAboveMod(const Analysis* analysis);
        // returns the map containing all the lattices from below the node that are owned by the given analysis
        // (read/write access)
        std::vector<Lattice*>& getLatticeBelowMod(const Analysis* analysis);

        // deletes all lattices above this node associated with the given analysis
        void deleteLatticeAbove(const Analysis* analysis);

        // deletes all lattices below this node associated with the given analysis
        void deleteLatticeBelow(const Analysis* analysis);

        // returns true if the two lattices vectors are the same and false otherwise
        static bool eqLattices(const std::vector<Lattice*>& latticesA,
                               const std::vector<Lattice*>& latticesB);

        // Creates a copy of all the dataflow state (Lattices and Facts) associated with
        // analysis srcA and associates this copied state with analysis tgtA.
        void cloneAnalysisState(const Analysis* srcA, const Analysis* tgtA);

        // Given a set of analyses, one of which is designated as a master, unions together the
        // lattices associated with each of these analyses. The results are associated on each
        // CFG node with the master analysis.
        void unionLattices(std::set<Analysis*>& unionSet, const Analysis* master);

        //void removeLattice(const Analysis* analysis, int latticeName);

        private:
        /*// adds the given lattice to the given dfInfo structure (dfInfoAbove or dfInfoBelow),
        // organizing it under the given analysis and lattice name
        void addLattice_ex(std::map<Analysis*, std::vector<Lattice*> >& dfMap,
                          const  Analysis* analysis, int latticeName, Lattice* l);
        */
        // returns the given lattice, which owned by the given analysis
        Lattice* getLattice_ex(const LatticeMap& dfMap,
                          const Analysis* analysis, int latticeName) const;

        /*// removes the given lattice, owned by the given analysis
        // returns true if the given lattice was found and removed and false if it was not found
        bool removeLattice_ex(LatticeMap& dfMap,
                              const Analysis* analysis, int latticeName);
        */
        public:
        // associates the given analysis/fact name with the given NodeFact,
        // deleting any previous association (the previous NodeFact is freed)
        void addFact(const Analysis* analysis, int factName, NodeFact* f);

        // associates the given analysis with the given map of fact names to NodeFacts,
        // deleting any previous association (the previous NodeFacts are freed). This call
        // takes the actual provided facts and does not make a copy of them.
        //void setFacts(const Analysis* analysis, const std::map<int, NodeFact*>& newFacts);
        void setFacts(const Analysis* analysis, const std::vector<NodeFact*>& newFacts);

        // returns the given fact, which owned by the given analysis
        NodeFact* getFact(const Analysis* analysis, int factName) const ;

        // returns the map of all the facts owned by the given analysis at this NodeState
        // (read-only access)
        //const std::map<int, NodeFact*>& getFacts(const Analysis* analysis) const;
        const std::vector<NodeFact*>& getFacts(const Analysis* analysis) const;

        // returns the map of all the facts owned by the given analysis at this NodeState
        // (read/write access)
        //std::map<int, NodeFact*>& getFactsMod(const Analysis* analysis);
        std::vector<NodeFact*>& getFactsMod(const Analysis* analysis);

        // removes the given fact, owned by the given analysis
        // returns true if the given fact was found and removed and false if it was not found
        //bool removeFact(const Analysis* analysis, int factName);

        // deletes all facts at this node associated with the given analysis
        void deleteFacts(const Analysis* analysis);

        // delete all state at this node associated with the given analysis
        void deleteState(const Analysis* analysis);

        // ====== STATIC ======
        private:
        static std::map<DataflowNode, std::vector<NodeState*> > nodeStateMap;
        static bool nodeStateMapInit;

        public:
        // returns the NodeState object associated with the given dataflow node.
        // index is used when multiple NodeState objects are associated with a given node
        // (ex: SgFunctionCallExp has 3 NodeStates: entry, function body, exit)
        static NodeState* getNodeState(const DataflowNode& n, int index=0);


        //returns the NodeState object associated with a given SgNode
        //index is used when multiple Control flow nodes (and consequently multiple NodeStates) are associated with a given node
        static NodeState* getNodeState(SgNode * n, int index=0);

        // returns a vector of NodeState objects associated with the given dataflow node.
        static const std::vector<NodeState*> getNodeStates(const DataflowNode& n);

        // returns the number of NodeStates associated with the given DataflowNode
        static int numNodeStates(DataflowNode& n);

        private:
        // initializes the nodeStateMap
        static void initNodeStateMap(bool (*filter) (CFGNode cfgn));

        public:
        /*// copies the facts from that to this
        void copyFacts(NodeState &that);

        // copies the dfInfoBelow lattices from that to this
        void copyLatticesBelow(NodeState &that);

        // copies the dfInfoAbove lattices from the given map to this
        void copyLatticesAbove(const LatticeMap& thatInfo);

        // copies the dfInfoBelow lattices from the given map to this
        void copyLatticesBelow(const LatticeMap& thatInfo);

        protected:
        // copies the dfInfoAbove or dfInfoBelow lattices from that to this
        void copyLattices(const LatticeMap& dfInfo,
                          const LatticeMap& thatInfo);
        */

        // copies from's above lattices for the given analysis to to's above lattices for the same analysis
        static void copyLattices_aEQa(Analysis* analysis, NodeState& to, const NodeState& from);

        // copies from's above lattices for analysisA to to's above lattices for analysisB
        static void copyLattices_aEQa(Analysis* analysisA, NodeState& to, Analysis* analysisB, const NodeState& from);

        // copies from's above lattices for the given analysis to to's below lattices for the same analysis
        static void copyLattices_bEQa(Analysis* analysis, NodeState& to, const NodeState& from);

        // copies from's above lattices for analysisA to to's below lattices for analysisB
        static void copyLattices_bEQa(Analysis* analysisA, NodeState& to, Analysis* analysisB, const NodeState& from);

        // copies from's below lattices for the given analysis to to's below lattices for the same analysis
        static void copyLattices_bEQb(Analysis* analysis, NodeState& to, const NodeState& from);

        // copies from's below lattices for the given analysis to to's above lattices for the same analysis
        static void copyLattices_aEQb(Analysis* analysis, NodeState& to, const NodeState& from);

        protected:
        // makes dfInfoX a copy of dfInfoY
        static void copyLattices(std::vector<Lattice*>& dfInfoX, const std::vector<Lattice*>& dfInfoY);

        /*public:
        void operator=(NodeState& that);*/
        public:
        std::string str(Analysis* analysis, std::string indent="") const;
};

#endif
#endif