InterGraph.hpp

Go to the documentation of this file.
00001 #ifndef wali_graph_INTER_GRAPH_GUARD
00002 #define wali_graph_INTER_GRAPH_GUARD 1
00003 
00004 #include "wali/Countable.hpp"
00005 #include "wali/ref_ptr.hpp"
00006 #include "wali/MergeFn.hpp"
00007 
00008 #include "wali/graph/GraphCommon.hpp"
00009 
00010 #include <list>
00011 #include <vector>
00012 #include <iostream>
00013 #include <map>
00014 #include <set>
00015 
00016 namespace wali {
00017 
00018     namespace graph {
00019 
00020         class IntraGraph;
00021         class InterGraph;
00022 
00023         class UnionFind {
00024             friend class InterGraph;
00025             int *arr;
00026             int n;
00027             public:
00028             UnionFind(int len);
00029             ~UnionFind();
00030             void reset();
00031             int find(int a);
00032             void takeUnion(int a, int b);
00033         };
00034 
00035 
00036         struct InterGraphStats {
00037             int nnodes;
00038             int nedges;
00039             int nhyperedges;
00040             int ncombine;
00041             int nextend;
00042             int nstar;
00043             int ngraphs;
00044             int nupdatable;
00045             int ncutset;
00046             int nget_weight;
00047             int niter;
00048             int ncomponents;
00049             int ndom_sequence;
00050             int ndom_componentsize;
00051             int ndom_components;
00052             int ndom_componentcutset;
00053 
00054             InterGraphStats() {
00055                 nnodes = nedges = nhyperedges = 0;
00056                 ncombine = nextend = nstar = 0;
00057                 ngraphs = nupdatable = ncutset = 0;
00058                 niter = 0;
00059                 ncomponents = 0;
00060                 ndom_sequence = 0;
00061                 ndom_componentsize = 0;
00062                 ndom_components = 0;
00063                 ndom_componentcutset = 0;
00064                 nget_weight = 0;
00065                 //WIN(intra_saturation = inter_saturation = setup_time = 0);
00066                 //WIN(t1 = t2 = t3 = 0);
00067             }
00068         };
00069 
00070        /* For call site to (mid-state) return site transition */
00071        class ETransHandler {
00072 
00073          friend class InterGraph;
00074          friend class SummaryGraph;
00075          
00076        private:
00077          typedef std::pair<int, sem_elem_t> Dependency; 
00078          typedef std::map<int, Dependency> EdgeMap;
00079          
00080          ETransHandler() {}
00081          bool exists(int ret);
00082          void addEdge(int call, int ret, sem_elem_t wtCallRule);
00083          sem_elem_t get_dependency(int ret, int &call);
00084 
00085        private:
00086          EdgeMap edgeMap;
00087 
00088        };
00089 
00090         class HyperEdge {
00091             public:
00092                 int src1, src2, tgt;
00093                 sem_elem_t weight;
00094                 wali::merge_fn_t mf;
00095                 HyperEdge(int s1, int s2, int t, sem_elem_t se) : src1(s1), src2(s2), tgt(t), weight(se), mf(0) {}
00096                 HyperEdge(int s1, int s2, int t, wali::merge_fn_t f) : src1(s1), src2(s2), tgt(t), weight(0), mf(f) {}
00097                 HyperEdge(const HyperEdge &h) : src1(h.src1), src2(h.src2), tgt(h.tgt), weight(h.weight), mf(h.mf) {}
00098         };
00099 
00100         class GraphEdge {
00101             public:
00102                 int src, tgt;
00103                 sem_elem_t weight;
00104                 GraphEdge(int s, int t, sem_elem_t w) : src(s), tgt(t), weight(w) {}
00105                 GraphEdge(const GraphEdge &e) {
00106                     src = e.src;
00107                     tgt = e.tgt;
00108                     weight = e.weight;
00109                 }
00110         };
00111 
00112         enum inter_node_t {InterNone = 0, InterSource = 1, InterOutNode = 2, InterSourceOutNode = 3};
00113 
00114         class GraphNode {
00115             public:
00116                 Transition trans;
00117                 int intra_nodeno;
00118                 inter_node_t type;
00119                 sem_elem_t weight;
00120                 IntraGraph *gr;
00121                 std::list<int> outgoing;
00122                 std::list<int> incoming;
00123                 std::list<int> out_hyper_edges;
00124                 bool visited;
00125                 GraphNode(Transition tr, inter_node_t ty = InterNone) : trans(tr), intra_nodeno(-1), type(ty), weight(0), gr(NULL) {}
00126                 GraphNode(const GraphNode &g) : trans(g.trans), intra_nodeno(g.intra_nodeno), type(g.type), weight(g.weight), 
00127                 gr(g.gr), outgoing(g.outgoing), incoming(g.incoming),
00128                 out_hyper_edges(g.out_hyper_edges), visited(g.visited) {}
00129         };
00130 
00131       class InterGraph : public Countable {
00132             public:
00133                 typedef std::ostream & (*PRINT_OP)(std::ostream &, int);
00134 
00135             private:
00136                 friend class SummaryGraph;
00137 
00138                 typedef std::map<Transition, int, TransitionCmp> TransMap;
00139                 typedef bool (*WT_CHECK)(SemElem *);
00140                 typedef SemElem *(*WT_CORRECT)(SemElem *);
00141                 typedef std::pair<int,int> tup;
00142                 typedef std::pair<int, int> call_edge_t;
00143 
00144                 std::vector<GraphNode> nodes;
00145                 std::vector<GraphEdge> intra_edges;
00146                 std::vector<HyperEdge> inter_edges;
00147                 std::vector<call_edge_t> call_edges;
00148                 int max_scc_computed;
00149 
00150                 UnionFind *intra_graph_uf;
00151                 std::list<IntraGraph *> gr_list;
00152 
00153                 ETransHandler eHandler;
00154                 //map<int,IntraGraph*> intra_graph_map;
00155 
00156                 TransMap node_number;
00157                 sem_elem_t sem; 
00158                 bool running_ewpds;
00159                 bool running_prestar;
00160                 InterGraphStats stats;
00161 
00162                 static std::ostream &defaultPrintOp(std::ostream &out, int a) {
00163                     out << a;
00164                     return out;
00165                 }
00166 
00167             public:
00168                 InterGraph(wali::sem_elem_t s, bool e, bool pre) {
00169                     sem = s;
00170                     intra_graph_uf = NULL;
00171                     running_ewpds = e;
00172                     running_prestar = pre;
00173                     max_scc_computed = 0;
00174                     count = 0;
00175                 }
00176                 ~InterGraph();
00177                 void addEdge(Transition src, Transition tgt, wali::sem_elem_t se);
00178                 void addEdge(Transition src1, Transition src2, Transition tgt, wali::sem_elem_t se);
00179                 void addEdge(Transition src1, Transition src2, Transition tgt, wali::merge_fn_t mf);
00180                 void addCallRetEdge(Transition src, Transition tgt, wali::sem_elem_t se);
00181 
00182                 void addCallEdge(Transition src1, Transition src2);
00183 
00184                 void setSource(Transition t, wali::sem_elem_t se);
00185                 void setESource(Transition t, wali::sem_elem_t wtAtCall, wali::sem_elem_t wtAfterCall);
00186 
00187                 void setupInterSolution(std::list<Transition> *wt_required = NULL);
00188 
00189                 sem_elem_t get_weight(Transition t);
00190                 sem_elem_t get_call_weight(Transition t);
00191 
00192                 void update_all_weights();
00193 
00194                 bool exists(int state, int stack, WT_CHECK op);
00195 
00196                 std::ostream &print(std::ostream &out, PRINT_OP pop = defaultPrintOp);
00197 
00198                 std::ostream &print_stats(std::ostream &out); 
00199 
00200                 bool path_summary(int state, int stack, int accept, WT_CORRECT correct, WT_CHECK op);
00201 
00202                 bool exists(Transition &t);
00203 
00204                 int nGraphs() {
00205                     return (int)gr_list.size();
00206                 }
00207             private:
00208                 int nodeno(Transition &t);
00209 
00210                 int intra_edgeno(Transition &src, Transition &tgt);
00211 
00212                 int inter_edgeno(Transition &src1, Transition &src2, Transition &tgt);
00213 
00214                 void dfsIntraForward(IntraGraph *gr, 
00215                         std::list<IntraGraph *> &finished, 
00216                         std::map<IntraGraph *, 
00217                         std::list<IntraGraph *> > &rev_edges);
00218 
00219                 void bfsIntra(IntraGraph *start, unsigned int scc_number);
00220 
00221                 unsigned SCC(std::list<IntraGraph *> &grlist, std::list<IntraGraph *> &grsorted);
00222 
00223                 void saturate(std::multiset<tup> &worklist, unsigned scc_n);
00224 
00225                 void setup_worklist(std::list<IntraGraph *> &gr_sorted, 
00226                         std::list<IntraGraph *>::iterator &gr_it, 
00227                         unsigned int scc_n,
00228                         std::multiset<tup> &worklist);
00229 
00230                 void resetSCCedges(IntraGraph *gr, unsigned int scc_number);
00231         };
00232 
00233         typedef ref_ptr<InterGraph> InterGraphPtr;
00234     } // namespace graph
00235 
00236 } // namespace wali
00237 
00238 
00239 #endif // wali_graph_INTER_GRAPH_GUARD 
00240