00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define LP 1
00011 #define PERFDEBUG 0
00012
00013 #ifdef _OPENMP
00014 #include <omp.h>
00015 #endif
00016 #include <boost/regex.hpp>
00017 #include <iostream>
00018 #include <fstream>
00019 #include <string>
00020 #include <assert.h>
00021 #include <staticCFG.h>
00022
00054 #include <boost/graph/adjacency_list.hpp>
00055 #include <boost/bind.hpp>
00056 #include <boost/foreach.hpp>
00057 #include <boost/tuple/tuple.hpp>
00058 #include <boost/graph/graphviz.hpp>
00059 #include <boost/graph/dominator_tree.hpp>
00060 #include <boost/graph/reverse_graph.hpp>
00061 #include <boost/graph/transpose_graph.hpp>
00062 #include <boost/algorithm/string.hpp>
00063
00064
00065
00066 #include <vector>
00067 #include <algorithm>
00068 #include <utility>
00069 #include <iostream>
00070 #include <sys/time.h>
00071 #include <sys/resource.h>
00072 #include <sys/time.h>
00073
00074
00075
00076
00077
00078
00079 template <class CFG>
00080 class SgGraphTraversal
00081 {
00082 public:
00083
00084 typedef typename boost::graph_traits<CFG>::vertex_descriptor Vertex;
00085 typedef typename boost::graph_traits<CFG>:: edge_descriptor Edge;
00086
00087 void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true);
00088 virtual void analyzePath(std::vector<Vertex>& pth) = 0;
00089 std::vector<int> getInEdges(int& node, CFG*& g);
00090 std::vector<int> getOutEdges(int& node, CFG*& g);
00091 int getTarget(int& n, CFG*& g);
00092 int getSource(int& n, CFG*& g);
00093 std::map<Vertex, int> vertintmap;
00094 std::map<Edge, int> edgeintmap;
00095 std::map<int, Vertex> intvertmap;
00096 std::map<int, Edge> intedgemap;
00097 SgGraphTraversal();
00098 virtual ~SgGraphTraversal();
00099 SgGraphTraversal( SgGraphTraversal &);
00100 SgGraphTraversal &operator=( SgGraphTraversal &);
00101 int pathnum;
00102
00103
00104 void firstPrepGraph(CFG*& g);
00105
00106 private:
00107
00108 int normals;
00109 int abnormals;
00110 bool needssafety;
00111 int recursed;
00112 int checkedfound;
00113
00114
00115
00116
00117 void prepareGraph(CFG*& g);
00118 void findClosuresAndMarkersAndEnumerate(CFG*& g);
00119
00120
00121
00122 int stoppedpaths;
00123 std::set<std::vector<int> > traversePath(int begin, int end, CFG*& g, bool loop=false);
00124 std::set<std::vector<int> > uTraversePath(int begin, int end, CFG*& g, bool loop, std::map<int, std::vector<std::vector<int> > >& localLoops);
00125 std::vector<std::vector<int> > bfsTraversePath(int begin, int end, CFG*& g, bool loop=false);
00126 std::vector<int> unzipPath(std::vector<int>& path, CFG*& g, int start, int end);
00127 std::vector<int> zipPath(std::vector<int>& path, CFG*& g, int start, int end);
00128 std::vector<int> zipPath2(std::vector<int>& path, CFG*& g);
00129 void printCFGNode(int& cf, std::ofstream& o);
00130 void printCFGNodeGeneric(int& cf, std::string prop, std::ofstream& o);
00131 void printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o);
00132 void printHotness(CFG*& g);
00133 void printPathDot(CFG*& g);
00134 void computeOrder(CFG*& g, const int& begin);
00135 void computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential);
00136
00137
00138 std::vector<int> sources;
00139 std::vector<int> sinks;
00140 std::vector<int> recursiveLoops;
00141 std::vector<int> recurses;
00142 std::map<int, int> ptsNum;
00143 bool borrowed;
00144 std::set<int> badloop;
00145 std::map<int, std::vector<std::vector<int> > > totalLoops;
00146
00147 std::map<int, std::string> nodeStrings;
00148 int sourcenum;
00149 unsigned long long evaledpaths;
00150 int badpaths;
00151 int workingthreadnum;
00152 bool workingthread;
00153 std::map<int, std::set<std::vector<int> > > loopStore;
00154 std::vector<std::vector<int> > pathStore;
00155 std::map<int, std::vector<int> > subpathglobal;
00156 std::map<std::vector<int>, int> subpathglobalinv;
00157 int nextsubpath;
00158 std::vector<int> orderOfNodes;
00159
00160
00161
00162
00163 std::vector<std::map<Vertex, Vertex> > SubGraphGraphMap;
00164 std::vector<std::map<Vertex, Vertex> > GraphSubGraphMap;
00165 std::vector<CFG*> subGraphVector;
00166 void getVertexPath(std::vector<int> path, CFG*& g, std::vector<Vertex>& vertexPath );
00167 void storeCompact(std::vector<int> path);
00168 int nextNode;
00169 int nextEdge;
00170 std::vector<int> markers;
00171 std::vector<int> closures;
00172 std::map<int, int> markerIndex;
00173 std::map<int, std::vector<int> > pathsAtMarkers;
00174 typedef typename boost::graph_traits<CFG>::vertex_iterator vertex_iterator;
00175 typedef typename boost::graph_traits<CFG>::out_edge_iterator out_edge_iterator;
00176 typedef typename boost::graph_traits<CFG>::in_edge_iterator in_edge_iterator;
00177 typedef typename boost::graph_traits<CFG>::edge_iterator edge_iterator;
00178 bool bound;
00179
00180
00181
00182
00183
00184
00185 };
00186
00187
00188 template<class CFG>
00189 SgGraphTraversal<CFG>::
00190 SgGraphTraversal()
00191 {
00192 }
00193
00194
00195
00196 template<class CFG>
00197 SgGraphTraversal<CFG> &
00198 SgGraphTraversal<CFG>::
00199 operator=( SgGraphTraversal &other)
00200 {
00201 return *this;
00202 }
00203
00204 #ifndef SWIG
00205
00206 template<class CFG>
00207 SgGraphTraversal<CFG>::
00208 ~SgGraphTraversal()
00209 {
00210 }
00211
00212 #endif
00213
00221 template<class CFG>
00222 inline int
00223 SgGraphTraversal<CFG>::
00224 getSource(int& edge, CFG*& g)
00225 {
00226 Edge e = intedgemap[edge];
00227 Vertex v = boost::source(e, *g);
00228 return(vertintmap[v]);
00229 }
00230
00240 template<class CFG>
00241 inline int
00242 SgGraphTraversal<CFG>::
00243 getTarget(int& edge, CFG*& g)
00244 {
00245 Edge e = intedgemap[edge];
00246 Vertex v = boost::target(e, *g);
00247 return(vertintmap[v]);
00248 }
00249
00258 template<class CFG>
00259 std::vector<int>
00260 SgGraphTraversal<CFG>::
00261 getInEdges(int& node, CFG*& g)
00262 {
00263 Vertex getIns = intvertmap[node];
00264 std::vector<int> inedges;
00265 in_edge_iterator i, j;
00266 for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i)
00267 {
00268 inedges.push_back(edgeintmap[*i]);
00269 }
00270 return inedges;
00271 }
00272
00283 template<class CFG>
00284 std::vector<int>
00285 SgGraphTraversal<CFG>::
00286 getOutEdges(int &node, CFG*& g)
00287 {
00288 Vertex getOuts = intvertmap[node];
00289 std::vector<int> outedges;
00290 out_edge_iterator i, j;
00291 for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i)
00292 {
00293 outedges.push_back(edgeintmap[*i]);
00294 }
00295 return outedges;
00296 }
00297
00307 template<class CFG>
00308 inline
00309 std::vector<int>
00310 SgGraphTraversal<CFG>::
00311 zipPath2(std::vector<int>& pth, CFG*& g) {
00312 std::vector<int> npth;
00313 npth.push_back(pth[0]);
00314 for (int i = 1; i < pth.size()-1; i++) {
00315 if (find(closures.begin(), closures.end(), pth[i]) != closures.end()) {
00316 npth.push_back(pth[i]);
00317 }
00318 }
00319 npth.push_back(pth.back());
00320 return npth;
00321 }
00322
00334 template<class CFG>
00335 std::vector<int>
00336 SgGraphTraversal<CFG>::
00337 zipPath(std::vector<int>& pth, CFG*& g, int start, int end) {
00338 std::vector<int> subpath;
00339 std::vector<int> movepath;
00340 movepath.push_back(pth.front());
00341 movepath.push_back(pth.back());
00342 for (unsigned int qw = 0; qw < pth.size()-1; qw++) {
00343 if (find(markers.begin(), markers.end(), pth[qw]) != markers.end()) {
00344 std::vector<int> oeds = getOutEdges(pth[qw], g);
00345 for (unsigned int i = 0; i < oeds.size(); i++) {
00346 if (getTarget(oeds[i], g) == pth[qw+1]) {
00347 movepath.push_back(oeds[i]);
00348 }
00349 }
00350 }
00351 }
00352 return movepath;
00353 }
00354
00355
00356
00357
00358
00359
00370 template<class CFG>
00371 std::vector<int>
00372 SgGraphTraversal<CFG>::
00373 unzipPath(std::vector<int>& pzipped, CFG*& g, int start, int end) {
00374 ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1));
00375 std::vector<int> zipped;
00376 for (unsigned int i = 2; i < pzipped.size(); i++) {
00377 zipped.push_back(pzipped[i]);
00378 }
00379 std::vector<int> unzipped;
00380 unzipped.push_back(start);
00381 std::vector<int> oeds = getOutEdges(start, g);
00382 if (oeds.size() == 0) {
00383 return unzipped;
00384 }
00385 for (unsigned int i = 0; i < zipped.size(); i++) {
00386 oeds = getOutEdges(unzipped.back(), g);
00387 while (oeds.size() == 1) {
00388 if (getTarget(oeds[0], g) == end && unzipped.size() != 1) {
00389 unzipped.push_back(end);
00390 return unzipped;
00391 }
00392 unzipped.push_back(getTarget(oeds[0], g));
00393 oeds = getOutEdges(unzipped.back(), g);
00394 }
00395 if (oeds.size() == 0) {
00396 return unzipped;
00397 }
00398 if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) {
00399 ROSE_ASSERT(getSource(zipped[i], g) == unzipped.back());
00400 unzipped.push_back(getTarget(zipped[i], g));
00401 }
00402
00403 }
00404 std::vector<int> oeds2 = getOutEdges(unzipped.back(), g);
00405 if (unzipped.back() != end && oeds2.size() != 0) {
00406 while (oeds2.size() == 1 && unzipped.back() != end) {
00407 unzipped.push_back(getTarget(oeds2[0], g));
00408 oeds2 = getOutEdges(unzipped.back(), g);
00409 }
00410 }
00411 return unzipped;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00439 template<class CFG>
00440 std::vector<std::vector<int> >
00441 SgGraphTraversal<CFG>::
00442 bfsTraversePath(int begin, int end, CFG*& g, bool loop) {
00443
00444 #ifdef PERFDEBUG
00445 timeval tim;
00446 gettimeofday(&tim, NULL);
00447 double tim1 = tim.tv_sec+(tim.tv_usec/1000000.0);
00448 #endif
00449 bool recursedloop = loop;
00450 std::map<int, std::vector<std::vector<int> > > PtP;
00451 std::set<int> nodes;
00452 std::vector<std::vector<int> > pathContainer;
00453
00454 std::vector<int> completedLoops;
00455 std::vector<std::vector<int> > npc;
00456 std::vector<int> bgpath;
00457 bgpath.push_back(begin);
00458 pathContainer.push_back(bgpath);
00459 std::vector<std::vector<int> > newPathContainer;
00460 std::vector<std::vector<int> > paths;
00461 std::vector<int> localLoops;
00462 std::map<int, std::vector<std::vector<int> > > globalLoopPaths;
00463
00464
00465 while (pathContainer.size() != 0 ) {
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 for (unsigned int i = 0; i < pathContainer.size(); i++) {
00496 std::vector<int> npth = pathContainer[i];
00497 std::vector<int> oeds = getOutEdges(npth.back(), g);
00498 std::vector<int> ieds = getInEdges(npth.back(), g);
00499
00500 npth = pathContainer[i];
00501 oeds = getOutEdges(npth.back(), g);
00502
00503 if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) {
00504 std::vector<int> newpth;
00505 newpth = (pathContainer[i]);
00506 std::vector<int> movepath = newpth;
00507 if (recursedloop && newpth.back() == end && newpth.size() != 1) {
00508 paths.push_back(movepath);
00509 }
00510 else if (!recursedloop) {
00511 if (bound && newpth.size() != 1 && newpth.back() == end) {
00512 paths.push_back(movepath);
00513 }
00514 else if (!bound) {
00515 paths.push_back(movepath);
00516 }
00517 }
00518
00519 }
00520 else {
00521 std::vector<int> oeds = getOutEdges(pathContainer[i].back(), g);
00522
00523 for (unsigned int j = 0; j < oeds.size(); j++) {
00524
00525
00526 int tg = getTarget(oeds[j], g);
00527
00528
00529 std::vector<int> newpath = (pathContainer[i]);
00530
00531
00532 if (nodes.find(tg) != nodes.end() && find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) {
00533 if (PtP.find(tg) == PtP.end()) {
00534 std::vector<int> nv;
00535 nv.push_back(tg);
00536 newPathContainer.push_back(nv);
00537 PtP[tg].push_back(newpath);
00538 }
00539 else {
00540 PtP[tg].push_back(newpath);
00541 }
00542 }
00543 else if (find(newpath.begin(), newpath.end(), getTarget(oeds[j], g)) == newpath.end() || getTarget(oeds[j], g) == end) {
00544 newpath.push_back(tg);
00545 std::vector<int> ieds = getInEdges(tg, g);
00546 if (ieds.size() > 1) {
00547 nodes.insert(tg);
00548 }
00549 newPathContainer.push_back(newpath);
00550 }
00551 else if (tg == end && recursedloop) {
00552 newpath.push_back(tg);
00553 newPathContainer.push_back(newpath);
00554 }
00555 else {
00556 std::vector<int> ieds = getInEdges(tg, g);
00557 if (ieds.size() > 1 && find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() && find(recurses.begin(), recurses.end(), tg) == recurses.end()) {
00558 localLoops.push_back(tg);
00559 nodes.insert(tg);
00560 }
00561
00562
00563 }
00564
00565
00566
00567
00568 }
00569 }
00570 }
00571 pathContainer = newPathContainer;
00572 newPathContainer.clear();
00573 }
00574
00575 pathContainer.clear();
00576 std::vector<std::vector<int> > finnpts;
00577 std::vector<std::vector<int> > npts;
00578 while (true) {
00579 if (paths.size() > 1000000) {
00580 std::cout << "too many paths, consider a subgraph" << std::endl;
00581 ROSE_ASSERT(false);
00582 }
00583
00584 for (unsigned int qq = 0; qq < paths.size(); qq++) {
00585 std::vector<int> pq = paths[qq];
00586 std::vector<int> qp;
00587 int ppf = paths[qq].front();
00588 if (PtP.find(ppf) != PtP.end()) {
00589 for (unsigned int kk = 0; kk < PtP[ppf].size(); kk++) {
00590 std::vector<int> newpath = PtP[ppf][kk];
00591 bool good = true;
00592 if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) {
00593 good = false;
00594 }
00595 else {
00596
00597
00598
00599
00600
00601
00602
00603 for (unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) {
00604
00605
00606
00607
00608
00609
00610 if (find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) {
00611 good = false;
00612 break;
00613
00614 }
00615 }
00616
00617 }
00618 if (good) {
00619 newpath.insert(newpath.end(), pq.begin(), pq.end());
00620 #pragma omp critical
00621 {
00622 npts.push_back(newpath);
00623 }
00624 }
00625 }
00626 }
00627 else {
00628 std::vector<int> ppq = pq;
00629 #pragma omp critical
00630 {
00631 finnpts.push_back(ppq);
00632 }
00633 }
00634 }
00635 if (npts.size() == 0) {
00636 break;
00637 }
00638 else {
00639 paths = npts;
00640 npts.clear();
00641 }
00642 }
00643 paths = finnpts;
00644 finnpts.clear();
00645 for (unsigned int k = 0; k < localLoops.size(); k++) {
00646 int lk = localLoops[k];
00647 std::vector<std::vector<int> > loopp;
00648 if (loopStore.find(localLoops[k]) != loopStore.end()) {
00649 loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end());
00650 }
00651 else {
00652 std::map<int, std::vector<std::vector<int> > > localLoopPaths;
00653 completedLoops.push_back(lk);
00654 recurses.push_back(lk);
00655 loopp = bfsTraversePath(lk, lk, g, true);
00656 recurses.pop_back();
00657 }
00658 for (unsigned int ik = 0; ik < loopp.size(); ik++) {
00659
00660 if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) {
00661 globalLoopPaths[localLoops[k]].push_back(loopp[ik]);
00662 }
00663 }
00664
00665
00666
00667 }
00668 borrowed = true;
00669 std::vector<std::vector<int> > lps2;
00670 unsigned int maxpaths = 1000;
00671 unsigned int pathdivisor = 1;
00672
00673
00674 pathdivisor = 1;
00675 maxpaths = paths.size();
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 pathStore = paths;
00694 paths.clear();
00695 if (!recursedloop) {
00696 uTraversePath(begin, end, g, false, globalLoopPaths);
00697 }
00698 else {
00699 recursed++;
00700
00701 std::set<std::vector<int> > lps = uTraversePath(begin, end, g, true, globalLoopPaths);
00702 recursed--;
00703 for (std::set<std::vector<int> >::iterator ij = lps.begin(); ij != lps.end(); ij++) {
00704 std::vector<int> ijk = (*ij);
00705
00706 lps2.push_back(*ij);
00707 }
00708 }
00709
00710 #ifdef PERFDEBUG
00711
00712
00713 gettimeofday(&tim, NULL);
00714 double tim2 = tim.tv_sec+(tim.tv_usec/1000000);
00715 double timeRet = tim2 - tim1;
00716
00717 #endif
00718 return lps2;
00719
00720 }
00721
00722
00734 template<class CFG>
00735 std::set<std::vector<int> >
00736 SgGraphTraversal<CFG>::
00737 uTraversePath(int begin, int end, CFG*& g, bool loop, std::map<int, std::vector<std::vector<int> > >& globalLoopPaths) {
00738
00739 int doubledpaths = 0;
00740 int newmil = 1;
00741
00742
00743
00744
00745
00746 #ifdef PERFDEBUG
00747 timeval tim;
00748 gettimeofday(&tim, NULL);
00749 double t1 = tim.tv_sec+(tim.tv_usec/1000000);
00750 #endif
00751 std::set<std::vector<int> > newpaths;
00752 std::set<std::vector<int> > npaths;
00753 pathnum = 0;
00754 std::vector<int> path;
00755 std::vector<std::vector<int> > paths;
00756 int truepaths = 0;
00757 std::vector<std::vector<int> > checkpaths;
00758 std::vector<std::vector<int> > npathchecker;
00759 std::map<int, int> currents;
00760
00761 std::set<std::vector<int> > loopPaths;
00762
00763 bool done = false;
00764 std::set<std::vector<int> > fts;
00765 double ttfors = 0;
00766 double tperms = 0;
00767 while (true) {
00768
00769 if (paths.size() > 1000000) {
00770 std::cout << "nearly 1 million paths with no loops, stopping" << std::endl;
00771 return loopPaths;
00772 std::cout << "ended early" << std::endl;
00773 }
00774 if (done || borrowed) {
00775
00776 if (borrowed) {
00777 paths = pathStore;
00778 pathStore.clear();
00779 }
00780
00781 if (paths.size() != 0) {
00782 }
00783 else {
00784 return loopPaths;
00785 }
00786
00787
00788
00789 #pragma omp parallel for schedule(guided)
00790 for (unsigned int qqq = 0; qqq < paths.size(); qqq++) {
00791
00792 int pathevals = 0;
00793
00794
00795 std::set<std::vector<int> > movepaths;
00796 std::vector<int> path;
00797 path = paths[qqq];
00798 truepaths++;
00799 int permnums = 1;
00800 std::vector<int> perms;
00801 std::vector<unsigned int> qs;
00802 std::map<int, std::vector<std::vector<int> > > localLoops;
00803 std::vector<int> takenLoops;
00804 takenLoops.push_back(path[0]);
00805 bool taken = false;
00806 timeval timfor;
00807 int lost = 0;
00808 gettimeofday(&timfor, NULL);
00809 double t1for = timfor.tv_sec + (timfor.tv_usec/1000000);
00810 for (unsigned int q = 1; q < path.size()-1; q++) {
00811
00812 if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() && globalLoopPaths[path[q]].size() != 0 ) {
00813 for (unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) {
00814
00815 std::vector<int> gp = globalLoopPaths[path[q]][qp1];
00816
00817 for (unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) {
00818 if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) {
00819 taken = true;
00820 }
00821 }
00822
00823 if (!taken) {
00824 localLoops[path[q]].push_back(gp);
00825 }
00826 else {
00827 lost++;
00828 taken = false;
00829 }
00830 }
00831 if (localLoops[path[q]].size() != 0) {
00832 takenLoops.push_back(path[q]);
00833 permnums *= (localLoops[path[q]].size()+1);
00834 perms.push_back(permnums);
00835 qs.push_back(path[q]);
00836 }
00837 }
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 gettimeofday(&timfor, NULL);
00851 double t2for = timfor.tv_sec + (timfor.tv_usec/1000000);
00852 double ttfor = t2for - t1for;
00853
00854
00855
00856
00857 std::set<std::vector<int> > movepathscheck;
00858 timeval timperms;
00859 gettimeofday(&timperms, NULL);
00860 double t1perm = timperms.tv_sec + (timperms.tv_usec/1000000);
00861 std::vector<int> nvec;
00862 std::vector<std::vector<int> > boxpaths(permnums, nvec);
00863
00864 for (int i = 1; i <= permnums; i++) {
00865
00866 std::vector<int> loopsTaken;
00867
00868 unsigned int j = 0;
00869 std::vector<int> npath;
00870 while (true) {
00871 if (j == perms.size() || perms[j] > i) {
00872 break;
00873 }
00874 else {
00875 j++;
00876 }
00877 }
00878 int pn = i;
00879 std::vector<int> pL;
00880 for (unsigned int j1 = 0; j1 <= j; j1++) {
00881 pL.push_back(-1);
00882 }
00883 for (unsigned int k = j; k > 0; k--) {
00884 int l = 1;
00885 while (perms[k-1]*l < pn) {
00886 l++;
00887 }
00888 pL[k] = l-2;
00889 pn -= (perms[k-1]*(l-1));
00890 }
00891 pL[0] = pn-2;
00892
00893 unsigned int q2 = 0;
00894 for (unsigned int q1 = 0; q1 < path.size(); q1++) {
00895 if (q2 < qs.size()) {
00896 if (qs.size() != 0 && path[q1] == qs[q2] && q2 != pL.size()) {
00897 if (pL[q2] == -1) {
00898 npath.push_back(path[q1]);
00899 }
00900 else {
00901
00902 npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(), localLoops[path[q1]][pL[q2]].end());
00903
00904 }
00905 q2++;
00906 }
00907 else {
00908 npath.push_back(path[q1]);
00909 }
00910 }
00911 else {
00912 npath.push_back(path[q1]);
00913 }
00914
00915 }
00916 #ifdef FULLDEBUG
00917 std::cout << "path: " << std::endl;
00918 for (int qe = 0; qe < npath.size(); qe++) {
00919 std::cout << ", " << npath[qe];
00920 }
00921 std::cout << std::endl;
00922 std::cout << "permnum: " << i << std::endl;
00923 #endif
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 boxpaths[i-1] = npath;
00969
00970
00971
00972 }
00973
00974 evaledpaths += boxpaths.size();
00975 if (evaledpaths > newmil*100000) {
00976
00977 newmil++;
00978 }
00979
00980
00981 if (!loop) {
00982 for (std::vector<std::vector<int> >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) {
00983 std::vector<Vertex> verts;
00984 getVertexPath((*box), g, verts);
00985 #pragma omp critical
00986 {
00987 analyzePath(verts);
00988 }
00989 }
00990 }
00991 else {
00992 #pragma omp critical
00993 {
00994 loopPaths.insert(boxpaths.begin(), boxpaths.end());;
00995 }
00996 }
00997 }
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 #ifdef PERFDEBUG
01059 gettimeofday(&tim, NULL);
01060
01061
01062
01063
01064
01065
01066
01067
01068 #endif
01069 #ifdef LP
01070 if (loop) {
01071 #ifdef PERFDEBUG
01072
01073 #endif
01074 loopStore[begin] = loopPaths;
01075 }
01076 #endif
01077 return loopPaths;
01078
01079 }
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01100 template<class CFG>
01101 void
01102 SgGraphTraversal<CFG>::
01103 constructPathAnalyzer(CFG* g, bool unbounded, Vertex begin, Vertex end, bool ns) {
01104 abnormals = 0;
01105 normals = 0;
01106 if (ns) {
01107 needssafety = true;
01108 }
01109 else {
01110 needssafety = false;
01111 }
01112 checkedfound = 0;
01113 recursed = 0;
01114 nextsubpath = 0;
01115 borrowed = true;
01116 stoppedpaths = 0;
01117 evaledpaths = 0;
01118 badpaths = 0;
01119 sourcenum = 0;
01120 prepareGraph(g);
01121 workingthread = false;
01122 workingthreadnum = -1;
01123
01124
01125
01126
01127
01128 bool subgraph = false;
01129 if (!subgraph) {
01130 if (!unbounded) {
01131 bound = true;
01132 recursiveLoops.clear();
01133 recurses.clear();
01134 std::vector<std::vector<int> > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g);
01135
01136 }
01137 else {
01138 std::set<int> usedsources;
01139 bound = false;
01140 std::vector<int> localLps;
01141 for (unsigned int j = 0; j < sources.size(); j++) {
01142 sourcenum = sources[j];
01143 recursiveLoops.clear();
01144 recurses.clear();
01145 std::vector<std::vector<int> > spaths = bfsTraversePath(sources[j], -1, g);
01146
01147
01148 }
01149 }
01150 }
01151
01152 printHotness(g);
01153 }
01154
01165 template<class CFG>
01166 void
01167 SgGraphTraversal<CFG>::
01168 computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential) {
01169 int minDepth = 0;
01170 int maxDepth = minDepth + depthDifferential;
01171 int currSubGraph = 0;
01172 CFG* subGraph;
01173 std::set<int> foundNodes;
01174 while (true) {
01175 Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]);
01176 GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin];
01177 SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]];
01178 for (int i = minDepth; i <= maxDepth; i++) {
01179 Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]];
01180 std::vector<int> outEdges = getOutEdges(orderOfNodes[i], g);
01181 for (unsigned int j = 0; j < outEdges.size(); j++) {
01182 Vertex u;
01183 if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) {
01184 u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]];
01185 }
01186 else {
01187 u = boost::add_vertex(*subGraphVector[currSubGraph]);
01188 foundNodes.insert(getTarget(outEdges[j], g));
01189 SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)];
01190 GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u;
01191
01192 }
01193 Edge edge;
01194 bool ok;
01195 boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]);
01196 }
01197 }
01198 minDepth = maxDepth;
01199 if ((unsigned int) minDepth == orderOfNodes.size()-1) {
01200 break;
01201 }
01202 maxDepth += depthDifferential;
01203 if ((unsigned int) maxDepth > orderOfNodes.size()-1)
01204 {
01205 maxDepth = orderOfNodes.size()-1;
01206 }
01207 CFG* newSubGraph;
01208 subGraphVector.push_back(newSubGraph);
01209 currSubGraph++;
01210 }
01211 return;
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221 template<class CFG>
01222 void
01223 SgGraphTraversal<CFG>::
01224 printCFGNodeGeneric(int &cf, std::string prop, std::ofstream& o) {
01225 std::string nodeColor = "black";
01226 o << cf << " [label=\"" << " num:" << cf << " prop: " << prop << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n";
01227 }
01228
01229 template<class CFG>
01230 void
01231 SgGraphTraversal<CFG>::
01232 printCFGNode(int& cf, std::ofstream& o)
01233 {
01234 #ifdef FULLDEBUG
01235 int pts = ptsNum[cf];
01236 std::string nodeColor = "black";
01237 o << cf << " [label=\"" << " pts: " << pts << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n";
01238 #endif
01239 #ifndef FULLDEBUG
01240 std::string nodeColor = "black";
01241 o << cf << " [label=\"" << " num:" << cf << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n";
01242 #endif
01243
01244 }
01245
01246 template<class CFG>
01247 void
01248 SgGraphTraversal<CFG>::
01249 printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o)
01250 {
01251 int src = getSource(cf, cfg);
01252 int tar = getTarget(cf, cfg);
01253 o << src << " -> " << tar << " [label=\"" << src << " " << tar << "\", style=\"" << "solid" << "\"];\n";
01254 }
01255
01256 template<class CFG>
01257 void
01258 SgGraphTraversal<CFG>::
01259 printHotness(CFG*& g)
01260 {
01261 const CFG* gc = g;
01262 int currhot = 0;
01263 std::ofstream mf;
01264 std::stringstream filenam;
01265 filenam << "hotness" << currhot << ".dot";
01266 currhot++;
01267 std::string fn = filenam.str();
01268 mf.open(fn.c_str());
01269
01270 mf << "digraph defaultName { \n";
01271 vertex_iterator v, vend;
01272 edge_iterator e, eend;
01273 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
01274 {
01275 printCFGNode(vertintmap[*v], mf);
01276 }
01277 for (tie(e, eend) = edges(*gc); e != eend; ++e)
01278 {
01279 printCFGEdge(edgeintmap[*e], g, mf);
01280 }
01281 mf.close();
01282 }
01283 template<class CFG>
01284 void
01285 SgGraphTraversal<CFG>::
01286 printPathDot(CFG*& g)
01287 {
01288 const CFG* gc = g;
01289 std::ofstream mf;
01290 std::stringstream filenam;
01291 filenam << "pathnums.dot";
01292 std::string fn = filenam.str();
01293 mf.open(fn.c_str());
01294
01295 mf << "digraph defaultName { \n";
01296 vertex_iterator v, vend;
01297 edge_iterator e, eend;
01298 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
01299 {
01300 if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) {
01301 int nn = vertintmap[*v];
01302 printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf);
01303 }
01304 else {
01305 printCFGNodeGeneric(vertintmap[*v], "noprop", mf);
01306 }
01307 }
01308 for (tie(e, eend) = edges(*gc); e != eend; ++e)
01309 {
01310 printCFGEdge(edgeintmap[*e], g, mf);
01311 }
01312
01313 mf.close();
01314 }
01315
01316
01317
01327 template<class CFG>
01328 void
01329 SgGraphTraversal<CFG>::
01330 prepareGraph(CFG*& g) {
01331 nextNode = 1;
01332 nextEdge = 1;
01333 findClosuresAndMarkersAndEnumerate(g);
01334 }
01335
01336
01348 template<class CFG>
01349 void
01350 SgGraphTraversal<CFG>::
01351 firstPrepGraph(CFG*& g) {
01352 nextNode = 1;
01353 nextEdge = 1;
01354 findClosuresAndMarkersAndEnumerate(g);
01355 }
01356
01368 template<class CFG>
01369 void
01370 SgGraphTraversal<CFG>::
01371 findClosuresAndMarkersAndEnumerate(CFG*& g)
01372 {
01373 edge_iterator e, eend;
01374 for (tie(e, eend) = edges(*g); e != eend; ++e) {
01375 intedgemap[nextEdge] = *e;
01376 edgeintmap[*e] = nextEdge;
01377 nextEdge++;
01378 }
01379 vertex_iterator v1, vend1;
01380 for (tie(v1, vend1) = vertices(*g); v1 != vend1; ++v1)
01381 {
01382 vertintmap[*v1] = nextNode;
01383 intvertmap[nextNode] = *v1;
01384 nextNode++;
01385 }
01386 vertex_iterator v, vend;
01387 for (tie(v, vend) = vertices(*g); v != vend; ++v) {
01388 std::vector<int> outs = getOutEdges(vertintmap[*v], g);
01389 std::vector<int> ins = getInEdges(vertintmap[*v], g);
01390 if (outs.size() > 1)
01391 {
01392 markers.push_back(vertintmap[*v]);
01393
01394 markerIndex[vertintmap[*v]] = markers.size()-1;
01395 for (unsigned int i = 0; i < outs.size(); i++) {
01396 pathsAtMarkers[vertintmap[*v]].push_back(getTarget(outs[i], g));
01397 }
01398 }
01399 if (ins.size() > 1)
01400 {
01401 closures.push_back(vertintmap[*v]);
01402 }
01403 if (outs.size() == 0) {
01404 sinks.push_back(vertintmap[*v]);
01405 }
01406 if (ins.size() == 0) {
01407 sources.push_back(vertintmap[*v]);
01408 }
01409 }
01410 return;
01411 }
01412
01413
01414
01421 template<class CFG>
01422 void
01423 SgGraphTraversal<CFG>::
01424 computeOrder(CFG*& g, const int& begin) {
01425 std::vector<int> currentNodes;
01426 std::vector<int> newCurrentNodes;
01427 currentNodes.push_back(begin);
01428 std::map<int, int> reverseCurrents;
01429 orderOfNodes.push_back(begin);
01430 std::set<int> heldBackNodes;
01431 while (currentNodes.size() != 0) {
01432 for (unsigned int j = 0; j < currentNodes.size(); j++) {
01433
01434 std::vector<int> inEdges = getInEdges(currentNodes[j], g);
01435 if (inEdges.size() > 1) {
01436 if (reverseCurrents.find(currentNodes[j]) == reverseCurrents.end()) {
01437 reverseCurrents[currentNodes[j]] = 0;
01438 }
01439 if ((unsigned int) reverseCurrents[currentNodes[j]] == inEdges.size() - 1) {
01440 heldBackNodes.erase(currentNodes[j]);
01441 reverseCurrents[currentNodes[j]]++;
01442 std::vector<int> outEdges = getOutEdges(currentNodes[j], g);
01443 for (unsigned int k = 0; k < outEdges.size(); k++) {
01444 newCurrentNodes.push_back(getTarget(outEdges[k], g));
01445 orderOfNodes.push_back(getTarget(outEdges[k], g));
01446 }
01447 }
01448 else if (reverseCurrents[currentNodes[j]] < reverseCurrents.size()) {
01449 reverseCurrents[currentNodes[j]]++;
01450 if (heldBackNodes.find(currentNodes[j]) == heldBackNodes.end()) {
01451 heldBackNodes.insert(currentNodes[j]);
01452 }
01453 }
01454 }
01455 else {
01456 std::vector<int> outEdges = getOutEdges(currentNodes[j], g);
01457 for (unsigned int k = 0; k < outEdges.size(); k++) {
01458 newCurrentNodes.push_back(getTarget(outEdges[k], g));
01459 orderOfNodes.push_back(getTarget(outEdges[k], g));
01460
01461 }
01462 }
01463 }
01464 if (newCurrentNodes.size() == 0 && heldBackNodes.size() != 0) {
01465 for (std::set<int>::iterator q = heldBackNodes.begin(); q != heldBackNodes.end(); q++) {
01466 int qint = *q;
01467 std::vector<int> heldBackOutEdges = getOutEdges(qint, g);
01468 for (unsigned int p = 0; p < heldBackOutEdges.size(); p++) {
01469 newCurrentNodes.push_back(getTarget(heldBackOutEdges[p], g));
01470 }
01471 }
01472 heldBackNodes.clear();
01473 }
01474 currentNodes = newCurrentNodes;
01475 newCurrentNodes.clear();
01476 }
01477 return;
01478 }
01479
01489 template<class CFG>
01490 void
01491 SgGraphTraversal<CFG>::
01492 getVertexPath(std::vector<int> path, CFG*& g, std::vector<Vertex>& vertexPath) {
01493 for (unsigned int i = 0; i < path.size(); i++) {
01494 vertexPath.push_back(intvertmap[path[i]]);
01495 }
01496
01497
01498
01499 }
01500
01507 template<class CFG>
01508 void
01509 SgGraphTraversal<CFG>::
01510 storeCompact(std::vector<int> compactPath) {
01511 return;
01512 }
01513
01514
01515
01516
01517