16 #include <boost/regex.hpp>
54 #include <boost/graph/adjacency_list.hpp>
55 #include <boost/bind.hpp>
56 #include <boost/foreach.hpp>
57 #include <boost/tuple/tuple.hpp>
58 #include <boost/graph/graphviz.hpp>
59 #include <boost/graph/dominator_tree.hpp>
60 #include <boost/graph/reverse_graph.hpp>
61 #include <boost/graph/transpose_graph.hpp>
62 #include <boost/algorithm/string.hpp>
71 #include <sys/resource.h>
84 typedef typename boost::graph_traits<CFG>::vertex_descriptor
Vertex;
85 typedef typename boost::graph_traits<CFG>:: edge_descriptor
Edge;
88 virtual void analyzePath(std::vector<Vertex>& pth) = 0;
89 std::vector<int>
getInEdges(
int& node, CFG*& g);
123 std::set<std::vector<int> >
traversePath(
int begin,
int end, CFG*& g,
bool loop=
false);
124 std::set<std::vector<int> >
uTraversePath(
int begin,
int end, CFG*& g,
bool loop, std::map<
int, std::vector<std::vector<int> > >& localLoops);
125 std::vector<std::vector<int> >
bfsTraversePath(
int begin,
int end, CFG*& g,
bool loop=
false);
126 std::vector<int>
unzipPath(std::vector<int>& path, CFG*& g,
int start,
int end);
127 std::vector<int>
zipPath(std::vector<int>& path, CFG*& g,
int start,
int end);
128 std::vector<int>
zipPath2(std::vector<int>& path, CFG*& g);
135 void computeSubGraphs(
const int& begin,
const int &end, CFG*& g,
int depthDifferential);
166 void getVertexPath(std::vector<int> path, CFG*& g, std::vector<Vertex>& vertexPath );
227 Vertex v = boost::source(e, *g);
228 return(vertintmap[v]);
246 Vertex v = boost::target(e, *g);
247 return(vertintmap[v]);
263 Vertex getIns = intvertmap[node];
264 std::vector<int> inedges;
266 for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i)
288 Vertex getOuts = intvertmap[node];
289 std::vector<int> outedges;
291 for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i)
312 std::vector<int> npth;
313 npth.push_back(pth[0]);
314 for (
int i = 1; i < pth.size()-1; i++) {
315 if (
find(closures.begin(), closures.end(), pth[i]) != closures.end()) {
316 npth.push_back(pth[i]);
319 npth.push_back(pth.back());
337 zipPath(std::vector<int>& pth, CFG*& g,
int start,
int end) {
338 std::vector<int> subpath;
339 std::vector<int> movepath;
340 movepath.push_back(pth.front());
341 movepath.push_back(pth.back());
342 for (
unsigned int qw = 0; qw < pth.size()-1; qw++) {
343 if (
find(markers.begin(), markers.end(), pth[qw]) != markers.end()) {
344 std::vector<int> oeds = getOutEdges(pth[qw], g);
345 for (
unsigned int i = 0; i < oeds.size(); i++) {
346 if (
getTarget(oeds[i], g) == pth[qw+1]) {
347 movepath.push_back(oeds[i]);
373 unzipPath(std::vector<int>& pzipped, CFG*& g,
int start,
int end) {
374 ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1));
375 std::vector<int> zipped;
376 for (
unsigned int i = 2; i < pzipped.size(); i++) {
377 zipped.push_back(pzipped[i]);
379 std::vector<int> unzipped;
380 unzipped.push_back(start);
381 std::vector<int> oeds = getOutEdges(start, g);
382 if (oeds.size() == 0) {
385 for (
unsigned int i = 0; i < zipped.size(); i++) {
386 oeds = getOutEdges(unzipped.back(), g);
387 while (oeds.size() == 1) {
388 if (
getTarget(oeds[0], g) == end && unzipped.size() != 1) {
389 unzipped.push_back(end);
392 unzipped.push_back(
getTarget(oeds[0], g));
393 oeds = getOutEdges(unzipped.back(), g);
395 if (oeds.size() == 0) {
398 if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) {
399 ROSE_ASSERT(
getSource(zipped[i], g) == unzipped.back());
400 unzipped.push_back(
getTarget(zipped[i], g));
404 std::vector<int> oeds2 = getOutEdges(unzipped.back(), g);
405 if (unzipped.back() != end && oeds2.size() != 0) {
406 while (oeds2.size() == 1 && unzipped.back() != end) {
407 unzipped.push_back(
getTarget(oeds2[0], g));
408 oeds2 = getOutEdges(unzipped.back(), g);
440 std::vector<std::vector<int> >
449 bool recursedloop = loop;
450 std::map<int, std::vector<std::vector<int> > > PtP;
452 std::vector<std::vector<int> > pathContainer;
454 std::vector<int> completedLoops;
455 std::vector<std::vector<int> > npc;
456 std::vector<int> bgpath;
457 bgpath.push_back(begin);
458 pathContainer.push_back(bgpath);
459 std::vector<std::vector<int> > newPathContainer;
460 std::vector<std::vector<int> >
paths;
461 std::vector<int> localLoops;
462 std::map<int, std::vector<std::vector<int> > > globalLoopPaths;
465 while (pathContainer.size() != 0 ) {
495 for (
unsigned int i = 0; i < pathContainer.size(); i++) {
496 std::vector<int> npth = pathContainer[i];
497 std::vector<int> oeds = getOutEdges(npth.back(), g);
498 std::vector<int> ieds = getInEdges(npth.back(), g);
500 npth = pathContainer[i];
501 oeds = getOutEdges(npth.back(), g);
503 if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) {
504 std::vector<int> newpth;
505 newpth = (pathContainer[i]);
506 std::vector<int> movepath = newpth;
507 if (recursedloop && newpth.back() == end && newpth.size() != 1) {
508 paths.push_back(movepath);
510 else if (!recursedloop) {
511 if (bound && newpth.size() != 1 && newpth.back() == end) {
512 paths.push_back(movepath);
515 paths.push_back(movepath);
521 std::vector<int> oeds = getOutEdges(pathContainer[i].back(), g);
523 for (
unsigned int j = 0; j < oeds.size(); j++) {
529 std::vector<int> newpath = (pathContainer[i]);
532 if (nodes.find(tg) != nodes.end() &&
find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) {
533 if (PtP.find(tg) == PtP.end()) {
536 newPathContainer.push_back(nv);
537 PtP[tg].push_back(newpath);
540 PtP[tg].push_back(newpath);
543 else if (
find(newpath.begin(), newpath.end(),
getTarget(oeds[j], g)) == newpath.end() ||
getTarget(oeds[j], g) == end) {
544 newpath.push_back(tg);
545 std::vector<int> ieds = getInEdges(tg, g);
546 if (ieds.size() > 1) {
549 newPathContainer.push_back(newpath);
551 else if (tg == end && recursedloop) {
552 newpath.push_back(tg);
553 newPathContainer.push_back(newpath);
556 std::vector<int> ieds = getInEdges(tg, g);
557 if (ieds.size() > 1 &&
find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() &&
find(recurses.begin(), recurses.end(), tg) == recurses.end()) {
558 localLoops.push_back(tg);
571 pathContainer = newPathContainer;
572 newPathContainer.clear();
575 pathContainer.clear();
576 std::vector<std::vector<int> > finnpts;
577 std::vector<std::vector<int> > npts;
579 if (paths.size() > 1000000) {
580 std::cout <<
"too many paths, consider a subgraph" << std::endl;
584 for (
unsigned int qq = 0; qq < paths.size(); qq++) {
585 std::vector<int> pq = paths[qq];
587 int ppf = paths[qq].front();
588 if (PtP.find(ppf) != PtP.end()) {
589 for (
unsigned int kk = 0; kk < PtP[ppf].size(); kk++) {
590 std::vector<int> newpath = PtP[ppf][kk];
592 if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) {
603 for (
unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) {
610 if (
find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) {
619 newpath.insert(newpath.end(), pq.begin(), pq.end());
622 npts.push_back(newpath);
628 std::vector<int> ppq = pq;
631 finnpts.push_back(ppq);
635 if (npts.size() == 0) {
645 for (
unsigned int k = 0; k < localLoops.size(); k++) {
646 int lk = localLoops[k];
647 std::vector<std::vector<int> > loopp;
648 if (loopStore.find(localLoops[k]) != loopStore.end()) {
649 loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end());
652 std::map<int, std::vector<std::vector<int> > > localLoopPaths;
653 completedLoops.push_back(lk);
654 recurses.push_back(lk);
655 loopp = bfsTraversePath(lk, lk, g,
true);
658 for (
unsigned int ik = 0; ik < loopp.size(); ik++) {
660 if (
find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) {
661 globalLoopPaths[localLoops[k]].push_back(loopp[ik]);
669 std::vector<std::vector<int> > lps2;
670 unsigned int maxpaths = 1000;
671 unsigned int pathdivisor = 1;
675 maxpaths = paths.size();
696 uTraversePath(begin, end, g,
false, globalLoopPaths);
701 std::set<std::vector<int> > lps = uTraversePath(begin, end, g,
true, globalLoopPaths);
703 for (std::set<std::vector<int> >::
iterator ij = lps.
begin(); ij != lps.
end(); ij++) {
704 std::vector<int> ijk = (*ij);
735 std::set<std::vector<int> >
737 uTraversePath(
int begin,
int end, CFG*& g,
bool loop, std::map<
int, std::vector<std::vector<int> > >& globalLoopPaths) {
751 std::set<std::vector<int> > newpaths;
752 std::set<std::vector<int> > npaths;
754 std::vector<int> path;
755 std::vector<std::vector<int> >
paths;
757 std::vector<std::vector<int> > checkpaths;
758 std::vector<std::vector<int> > npathchecker;
759 std::map<int, int> currents;
761 std::set<std::vector<int> > loopPaths;
764 std::set<std::vector<int> > fts;
769 if (paths.size() > 1000000) {
770 std::cout <<
"nearly 1 million paths with no loops, stopping" << std::endl;
772 std::cout <<
"ended early" << std::endl;
774 if (done || borrowed) {
781 if (paths.size() != 0) {
789 #pragma omp parallel for schedule(guided)
790 for (
unsigned int qqq = 0; qqq < paths.size(); qqq++) {
795 std::set<std::vector<int> > movepaths;
796 std::vector<int> path;
800 std::vector<int> perms;
801 std::vector<unsigned int> qs;
802 std::map<int, std::vector<std::vector<int> > > localLoops;
803 std::vector<int> takenLoops;
804 takenLoops.push_back(path[0]);
810 for (
unsigned int q = 1; q < path.size()-1; q++) {
812 if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() && globalLoopPaths[path[q]].size() != 0 ) {
813 for (
unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) {
815 std::vector<int> gp = globalLoopPaths[path[q]][qp1];
817 for (
unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) {
818 if (
find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) {
824 localLoops[path[q]].push_back(gp);
831 if (localLoops[path[q]].size() != 0) {
832 takenLoops.push_back(path[q]);
833 permnums *= (localLoops[path[q]].size()+1);
834 perms.push_back(permnums);
835 qs.push_back(path[q]);
857 std::set<std::vector<int> > movepathscheck;
861 std::vector<int> nvec;
862 std::vector<std::vector<int> > boxpaths(permnums, nvec);
864 for (
int i = 1; i <= permnums; i++) {
866 std::vector<int> loopsTaken;
869 std::vector<int> npath;
871 if (j == perms.size() || perms[j] > i) {
880 for (
unsigned int j1 = 0; j1 <= j; j1++) {
883 for (
unsigned int k = j; k > 0; k--) {
885 while (perms[k-1]*l < pn) {
889 pn -= (perms[k-1]*(l-1));
894 for (
unsigned int q1 = 0; q1 < path.size(); q1++) {
895 if (q2 < qs.size()) {
896 if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (
size_t)q2 != pL.size()) {
898 npath.push_back(path[q1]);
902 npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(),
903 localLoops[path[q1]][pL[q2]].end());
909 npath.push_back(path[q1]);
913 npath.push_back(path[q1]);
917 std::cout <<
"path: " << std::endl;
918 for (
int qe = 0; qe < npath.size(); qe++) {
919 std::cout <<
", " << npath[qe];
921 std::cout << std::endl;
922 std::cout <<
"permnum: " << i << std::endl;
968 boxpaths[i-1] = npath;
974 evaledpaths += boxpaths.size();
975 if (evaledpaths > newmil*100000ull) {
982 for (std::vector<std::vector<int> >::
iterator box = boxpaths.
begin(); box != boxpaths.
end(); box++) {
983 std::vector<Vertex> verts;
984 getVertexPath((*box), g, verts);
994 loopPaths.insert(boxpaths.begin(), boxpaths.end());;
1074 loopStore[begin] = loopPaths;
1110 needssafety =
false;
1121 workingthread =
false;
1122 workingthreadnum = -1;
1128 bool subgraph =
false;
1132 recursiveLoops.clear();
1134 std::vector<std::vector<int> > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g);
1138 std::set<int> usedsources;
1140 std::vector<int> localLps;
1141 for (
unsigned int j = 0; j < sources.size(); j++) {
1142 sourcenum = sources[j];
1143 recursiveLoops.clear();
1145 std::vector<std::vector<int> > spaths = bfsTraversePath(sources[j], -1, g);
1170 int maxDepth = minDepth + depthDifferential;
1171 int currSubGraph = 0;
1173 std::set<int> foundNodes;
1175 Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]);
1176 GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin];
1177 SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]];
1178 for (
int i = minDepth; i <= maxDepth; i++) {
1179 Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]];
1180 std::vector<int>
outEdges = getOutEdges(orderOfNodes[i], g);
1181 for (
unsigned int j = 0; j < outEdges.size(); j++) {
1183 if (foundNodes.find(
getTarget(outEdges[j], g)) == foundNodes.end()) {
1184 u = GraphSubGraphMap[currSubGraph][intvertmap[
getTarget(outEdges[j], g)]];
1187 u = boost::add_vertex(*subGraphVector[currSubGraph]);
1188 foundNodes.insert(
getTarget(outEdges[j], g));
1189 SubGraphGraphMap[currSubGraph][u] = intvertmap[
getTarget(outEdges[j], g)];
1190 GraphSubGraphMap[currSubGraph][intvertmap[
getTarget(outEdges[j], g)]] = u;
1195 boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]);
1198 minDepth = maxDepth;
1199 if ((
unsigned int) minDepth == orderOfNodes.size()-1) {
1202 maxDepth += depthDifferential;
1203 if ((
unsigned int) maxDepth > orderOfNodes.size()-1)
1205 maxDepth = orderOfNodes.size()-1;
1208 subGraphVector.push_back(newSubGraph);
1225 std::string nodeColor =
"black";
1226 o << cf <<
" [label=\"" <<
" num:" << cf <<
" prop: " << prop <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1235 int pts = ptsNum[cf];
1236 std::string nodeColor =
"black";
1237 o << cf <<
" [label=\"" <<
" pts: " << pts <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1240 std::string nodeColor =
"black";
1241 o << cf <<
" [label=\"" <<
" num:" << cf <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1253 o << src <<
" -> " << tar <<
" [label=\"" << src <<
" " << tar <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1264 std::stringstream filenam;
1265 filenam <<
"hotness" << currhot <<
".dot";
1267 std::string fn = filenam.str();
1268 mf.open(fn.c_str());
1270 mf <<
"digraph defaultName { \n";
1273 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
1275 printCFGNode(vertintmap[*v], mf);
1277 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1290 std::stringstream filenam;
1291 filenam <<
"pathnums.dot";
1292 std::string fn = filenam.str();
1293 mf.open(fn.c_str());
1295 mf <<
"digraph defaultName { \n";
1298 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
1300 if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) {
1301 int nn = vertintmap[*v];
1302 printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf);
1305 printCFGNodeGeneric(vertintmap[*v],
"noprop", mf);
1308 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1333 findClosuresAndMarkersAndEnumerate(g);
1354 findClosuresAndMarkersAndEnumerate(g);
1374 for (tie(e, eend) = edges(*g); e != eend; ++e) {
1380 for (tie(v1, vend1) = vertices(*g); v1 != vend1; ++v1)
1382 vertintmap[*v1] = nextNode;
1383 intvertmap[nextNode] = *v1;
1387 for (tie(v, vend) = vertices(*g); v != vend; ++v) {
1388 std::vector<int> outs = getOutEdges(vertintmap[*v], g);
1389 std::vector<int> ins = getInEdges(vertintmap[*v], g);
1390 if (outs.size() > 1)
1392 markers.push_back(vertintmap[*v]);
1394 markerIndex[vertintmap[*v]] = markers.size()-1;
1395 for (
unsigned int i = 0; i < outs.size(); i++) {
1396 pathsAtMarkers[vertintmap[*v]].push_back(
getTarget(outs[i], g));
1401 closures.push_back(vertintmap[*v]);
1403 if (outs.size() == 0) {
1404 sinks.push_back(vertintmap[*v]);
1406 if (ins.size() == 0) {
1407 sources.push_back(vertintmap[*v]);
1425 std::vector<int> currentNodes;
1426 std::vector<int> newCurrentNodes;
1427 currentNodes.push_back(begin);
1428 std::map<int, int> reverseCurrents;
1429 orderOfNodes.push_back(begin);
1430 std::set<int> heldBackNodes;
1431 while (currentNodes.size() != 0) {
1432 for (
unsigned int j = 0; j < currentNodes.size(); j++) {
1434 std::vector<int>
inEdges = getInEdges(currentNodes[j], g);
1435 if (inEdges.size() > 1) {
1436 if (reverseCurrents.find(currentNodes[j]) == reverseCurrents.end()) {
1437 reverseCurrents[currentNodes[j]] = 0;
1439 if ((
unsigned int) reverseCurrents[currentNodes[j]] == inEdges.size() - 1) {
1440 heldBackNodes.erase(currentNodes[j]);
1441 reverseCurrents[currentNodes[j]]++;
1442 std::vector<int>
outEdges = getOutEdges(currentNodes[j], g);
1443 for (
unsigned int k = 0; k < outEdges.size(); k++) {
1444 newCurrentNodes.push_back(
getTarget(outEdges[k], g));
1445 orderOfNodes.push_back(
getTarget(outEdges[k], g));
1448 else if (reverseCurrents[currentNodes[j]] < reverseCurrents.size()) {
1449 reverseCurrents[currentNodes[j]]++;
1450 if (heldBackNodes.find(currentNodes[j]) == heldBackNodes.end()) {
1451 heldBackNodes.insert(currentNodes[j]);
1456 std::vector<int>
outEdges = getOutEdges(currentNodes[j], g);
1457 for (
unsigned int k = 0; k < outEdges.size(); k++) {
1458 newCurrentNodes.push_back(
getTarget(outEdges[k], g));
1459 orderOfNodes.push_back(
getTarget(outEdges[k], g));
1464 if (newCurrentNodes.size() == 0 && heldBackNodes.size() != 0) {
1465 for (std::set<int>::iterator q = heldBackNodes.begin(); q != heldBackNodes.end(); q++) {
1467 std::vector<int> heldBackOutEdges = getOutEdges(qint, g);
1468 for (
unsigned int p = 0; p < heldBackOutEdges.size(); p++) {
1469 newCurrentNodes.push_back(
getTarget(heldBackOutEdges[p], g));
1472 heldBackNodes.clear();
1474 currentNodes = newCurrentNodes;
1475 newCurrentNodes.clear();
1492 getVertexPath(std::vector<int> path, CFG*& g, std::vector<Vertex>& vertexPath) {
1493 for (
unsigned int i = 0; i < path.size(); i++) {
1494 vertexPath.push_back(intvertmap[path[i]]);