00001 #ifndef wali_graph__INTRA_GRAPH_H
00002 #define wali_graph__INTRA_GRAPH_H
00003
00004 #include "wali/SemElem.hpp"
00005
00006 #include "wali/graph/RegExp.hpp"
00007 #include "wali/graph/GraphCommon.hpp"
00008
00009 #include <map>
00010
00011 namespace wali {
00012
00013 namespace graph {
00014
00015 enum node_type {None, SuperSource, Source, OutNode};
00016
00017 struct IntraGraphStats {
00018 int nstar;
00019 int ncombine;
00020 int nextend;
00021 int nnodes;
00022 int nedges;
00023 int nupdatable;
00024 int ncutset;
00025 int nget_weight;
00026 int ndom_sequence;
00027 int ndom_componentsize;
00028 int ndom_components;
00029 int ndom_componentcutset;
00030 clock_t t1,t2,t3,t4,t5;
00031
00032 IntraGraphStats() {
00033 nstar = nextend = ncombine = 0;
00034 nnodes = 0;
00035 nupdatable = 0;
00036 ncutset = 0;
00037 nedges = 0;
00038 ndom_sequence = ndom_componentsize = ndom_components = 0;
00039 ndom_componentcutset = 0;
00040 nget_weight = 0;
00041 t1 = t2 = t3 = t4 = t5 = 0;
00042 }
00043 };
00044 ostream &operator << (ostream &out, const IntraGraphStats &s);
00045
00046 class IntraGraphEdge {
00047 public:
00048 int src, tgt;
00049 sem_elem_t weight;
00050 bool updatable;
00051 int updatable_no;
00052 reg_exp_t regexp;
00053 IntraGraphEdge(int s, int t, sem_elem_t w, bool u, int uno = 0) : src(s), tgt(t), weight(w), updatable(u), updatable_no(uno) {
00054 if(updatable)
00055 regexp = RegExp::updatable(uno, weight);
00056 else
00057 regexp = RegExp::constant(weight);
00058 }
00059 void set(int s, int t, sem_elem_t w, bool u, int uno = 0) {
00060 src = s;
00061 tgt = t;
00062 weight = w;
00063 updatable = u;
00064 updatable_no = uno;
00065 if(updatable)
00066 regexp = RegExp::updatable(uno, weight);
00067 else
00068 regexp = RegExp::constant(weight);
00069 }
00070 IntraGraphEdge() : src(-1), tgt(-1) { }
00071 IntraGraphEdge(const IntraGraphEdge &e) {
00072 src = e.src;
00073 tgt = e.tgt;
00074 weight = e.weight;
00075 updatable = e.updatable;
00076 updatable_no = e.updatable_no;
00077 regexp = e.regexp;
00078 }
00079 };
00080
00081 struct PathSequence {
00082 reg_exp_t regexp;
00083 int src, tgt;
00084 PathSequence(reg_exp_t r, int s, int t) : regexp(r), src(s), tgt(t) {}
00085 };
00086
00087 struct EvaluatedPathSequence {
00088 sem_elem_t value;
00089 int src, tgt;
00090 EvaluatedPathSequence(sem_elem_t v, int s, int t) : value(v), src(s), tgt(t) {}
00091 };
00092
00093 class IntraGraphNode {
00094 public:
00095 Transition trans;
00096 int node_no;
00097 node_type type;
00098 list<int> outgoing;
00099 list<int> incoming;
00100 reg_exp_t regexp;
00101
00102 bool iscutset;
00103 int visited;
00104 int scc_number;
00105
00106 IntraGraphNode() : trans(0,0,0), node_no(-1), type(None) { }
00107 IntraGraphNode(int nno, node_type ty = None) : trans(0,0,0), node_no(nno), type(ty), iscutset(false), visited(0), scc_number(0) {}
00108 IntraGraphNode(const IntraGraphNode &n) : trans(n.trans), node_no(n.node_no), type(n.type), outgoing(n.outgoing), incoming(n.incoming),
00109 regexp(n.regexp), iscutset(n.iscutset), visited(n.visited), scc_number(n.scc_number) {
00110 }
00111 void set(int nno, node_type ty = None) {
00112 trans = Transition(0,0,0);
00113 node_no = nno;
00114 type = ty;
00115 iscutset = false;
00116 visited = 0;
00117 scc_number = 0;
00118 }
00119 };
00120
00121 class InterGraph;
00122
00123
00124 typedef map<Transition, int, TransitionCmp> transition_map_t;
00125
00126
00127 class update_t {
00128 public:
00129 int node;
00130 sem_elem_t wt;
00131 int uno;
00132 update_t(int _node, int _uno) : node(_node), wt(NULL), uno(_uno) { }
00133 update_t(int _node, sem_elem_t _wt) : node(_node), wt(_wt), uno(-1) { }
00134 update_t(const update_t &it) : node(it.node), wt(it.wt), uno(it.uno) { }
00135 };
00136
00137 class IntraGraph {
00138 friend class InterGraph;
00139 friend class SummaryGraph;
00140 private:
00141 typedef ostream & (*PRINT_OP)(ostream &, int);
00142
00143 vector<IntraGraphNode> nodes;
00144 vector<IntraGraphEdge> edges;
00145 int nnodes;
00146 int nedges;
00147 list<int> *out_nodes_intra;
00148 list<int> *out_nodes_inter;
00149
00150 bool running_prestar;
00151
00152 set<IntraGraph *> calls;
00153 vector<PathSequence> path_sequence;
00154 vector<EvaluatedPathSequence> evaluated_path_sequence;
00155 list<update_t> updates;
00156 vector<sem_elem_t> node_weight;
00157 vector<sem_elem_t> node_pop_weight;
00158 sem_elem_t **apsp;
00159
00160 list<int> topsort_list;
00161 vector<int> cutset_list;
00162
00163 bool visited;
00164 unsigned int scc_number;
00165 unsigned int bfs_number;
00166
00167 vector<int> updatable_edges;
00168 IntraGraphStats stats;
00169 static sem_elem_t se;
00170 #ifdef STATIC_MEMORY
00171 static int * intraGraphBuffer;
00172 static set<int> *childrenBuffer;
00173 static reg_exp_t *regBuffer;
00174 static int intraGraphBufferSize;
00175 #endif
00176 static ostream &defaultPrintOp(ostream &out, int a) {
00177 out << a;
00178 return out;
00179 }
00180 public:
00181 IntraGraph(bool pre, sem_elem_t _se) :nodes(50), edges(50) {
00182 visited = false;
00183 scc_number = 0;
00184 bfs_number = 0;
00185 nodes[0].set(0, SuperSource);
00186 nnodes = 1;
00187 nedges = 0;
00188 out_nodes_intra = new list<int>;
00189 out_nodes_inter = new list<int>;
00190 running_prestar = pre;
00191 se = _se;
00192 apsp = NULL;
00193 }
00194
00195 ~IntraGraph() {
00196 delete out_nodes_intra;
00197 delete out_nodes_inter;
00198 if(apsp != NULL) {
00199 int i;
00200 for(i=0;i<nnodes;i++)
00201 delete [] apsp[i];
00202 delete [] apsp;
00203 apsp = NULL;
00204 }
00205 }
00206 list<int> *getOutTransitions() {
00207 return out_nodes_inter;
00208 }
00209 IntraGraphStats get_stats();
00210 int getSize() {
00211 return nnodes;
00212 }
00213 #ifdef STATIC_MEMORY
00214 static void addStaticBuffer(int s) {
00215 intraGraphBuffer = new int[5*s];
00216 childrenBuffer = new set<int>[s];
00217 regBuffer = new reg_exp_t[s];
00218 intraGraphBufferSize = s;
00219 }
00220 static void clearStaticBuffer() {
00221 delete [] intraGraphBuffer;
00222 delete [] childrenBuffer;
00223 delete [] regBuffer;
00224
00225 intraGraphBuffer = 0;
00226 childrenBuffer = 0;
00227 regBuffer = 0;
00228
00229 intraGraphBufferSize = 0;
00230 }
00231 #endif
00232 int makeNode(Transition t) {
00233 create_node(t, nnodes);
00234 return (nnodes-1);
00235 }
00236 int makeNode() {
00237 Transition t(0,0,0);
00238 return makeNode(t);
00239 }
00240 void addEdge(int src, int tgt, sem_elem_t se, bool updatable = false);
00241 void setSource(int t, sem_elem_t se);
00242 void setOutNode(int t, int inter_t);
00243 void addCallEdge(IntraGraph *next);
00244 void updateWeight(int node, sem_elem_t wt);
00245 void updateWeight(int node, int uno);
00246 void assignUpdates();
00247 void clearUpdates();
00248
00249 bool updateEdgeWeight(int src, int tgt, sem_elem_t se);
00250 void setupIntraSolution(bool compress_regexp = false);
00251 sem_elem_t get_weight(int outnode);
00252 ostream &print(ostream &out, PRINT_OP pop = defaultPrintOp);
00253 static ostream &print_trans(Transition &t, ostream &out, PRINT_OP pop = defaultPrintOp);
00254 void resetUpdatable();
00255
00256 void solveSummarySolution(list<WTransition> &change);
00257 void preSolveSummarySolution(list<WTransition> &change);
00258 void setupSummarySolution();
00259
00260 private:
00261
00262 void create_node(Transition &t, int n);
00263 void create_node(int n);
00264 int edgeno(int s, int t);
00265 sem_elem_t extend(sem_elem_t w1, sem_elem_t w2);
00266 void dfs(int v, set<int> &, set<int> &, set<int> &);
00267 void topSort(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int,
00268 list<int> &ts, vector<int> &cs, bool no_outgoing, bool no_updatable);
00269 int SCC(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int);
00270 void buildCutsetRegExp(list<int> &ts, vector<int> &cs, vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int);
00271 void compressGraph(list<int> &ts, vector<int> &cs, list<int> &nts, vector<int> &ncs,
00272 vector<IntraGraphNode> &cnodes, vector<IntraGraphEdge> &cedges,
00273 map<int,int> &orig_to_compress);
00274 void compressGraphAggressive(list<int> &ts, vector<int> &cs, list<int> &nts, vector<int> &ncs,
00275 vector<IntraGraphNode> &cnodes, vector<IntraGraphEdge> &cedges,
00276 map<int,int> &orig_to_compress);
00277 void basicRegExp(bool compress_regexp);
00278 int *computeDominators(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int, int *buffer, set<int> *bucket_buffer);
00279 void dfsDominators(vector<IntraGraphNode> &cnodes, vector<IntraGraphEdge> &cedges, int v, int *parent, int *semi, int *vertex, int &n);
00280 void setupDomRegExp(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int,
00281 int *dom, int *number, int *vertex, int *tree, set<int> *children);
00282 void numberNodes(int v, int *number, int *vertex, set<int> *children, int &count);
00283 void compress_and_sequence(vector<IntraGraphNode> &cnodes, vector<IntraGraphEdge> &cedges,
00284 int h, int *ancestor, vector<PathSequence> &sequence);
00285 reg_exp_t eval_and_sequence(vector<IntraGraphNode> &cnodes, vector<IntraGraphEdge> &cedges,
00286 int e, int *ancestor, vector<PathSequence> &sequence);
00287 void domRegExp(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int, vector<PathSequence> &seq);
00288 void buildRegExp(vector<PathSequence> &seq);
00289 void computePathSequence(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int, vector<PathSequence> &sequence, bool use_cutset = false);
00290 void computePathSequenceCutset(vector<IntraGraphNode> &cnodes, int, vector<IntraGraphEdge> &cedges, int, vector<PathSequence> &sequence);
00291
00292 sem_elem_t popWeight(int nno);
00293 void calculatePopWeights(int eps_nno);
00294
00295 void solveRegSummarySolution();
00296 void preSolveRegSummarySolution();
00297
00298 };
00299
00300 }
00301
00302 }
00303
00304 #endif // wali_graph__INTRA_GRAPH_H