119 void prepareGraph(CFG*& g);
120 void findClosuresAndMarkersAndEnumerate(CFG*& g);
125 std::set<std::vector<int> > traversePath(
int begin,
int end, CFG*& g,
bool loop=
false);
126 std::set<std::vector<int> > uTraversePath(
int begin,
int end, CFG*& g,
bool loop, std::map<
int, std::vector<std::vector<int> > >& localLoops);
127 std::vector<std::vector<int> > bfsTraversePath(
int begin,
int end, CFG*& g,
bool loop=
false);
128 std::vector<int> unzipPath(std::vector<int>& path, CFG*& g,
int start,
int end);
129 std::vector<int> zipPath(std::vector<int>& path, CFG*& g,
int start,
int end);
130 std::vector<int> zipPath2(std::vector<int>& path, CFG*& g);
131 void printCFGNode(
int& cf, std::ofstream& o);
132 void printCFGNodeGeneric(
int& cf, std::string prop, std::ofstream& o);
133 void printCFGEdge(
int& cf, CFG*& cfg, std::ofstream& o);
134 void printHotness(CFG*& g);
135 void printPathDot(CFG*& g);
136 void computeOrder(CFG*& g,
const int& begin);
137 void computeSubGraphs(
const int& begin,
const int &end, CFG*& g,
int depthDifferential);
140 std::vector<int> sources;
141 std::vector<int> sinks;
142 std::vector<int> recursiveLoops;
143 std::vector<int> recurses;
144 std::map<int, int> ptsNum;
146 std::set<int> badloop;
147 std::map<int, std::vector<std::vector<int> > > totalLoops;
149 std::map<int, std::string> nodeStrings;
151 unsigned long long evaledpaths;
153 int workingthreadnum;
155 std::map<int, std::set<std::vector<int> > > loopStore;
156 std::vector<std::vector<int> > pathStore;
157 std::map<int, std::vector<int> > subpathglobal;
158 std::map<std::vector<int>,
int> subpathglobalinv;
160 std::vector<int> orderOfNodes;
165 std::vector<std::map<Vertex, Vertex> > SubGraphGraphMap;
166 std::vector<std::map<Vertex, Vertex> > GraphSubGraphMap;
167 std::vector<CFG*> subGraphVector;
168 void getVertexPath(std::vector<int> path, CFG*& g, std::vector<Vertex>& vertexPath );
169 void storeCompact(std::vector<int> path);
172 std::vector<int> markers;
173 std::vector<int> closures;
174 std::map<int, int> markerIndex;
175 std::map<int, std::vector<int> > pathsAtMarkers;
176 typedef typename boost::graph_traits<CFG>::vertex_iterator vertex_iterator;
177 typedef typename boost::graph_traits<CFG>::out_edge_iterator out_edge_iterator;
178 typedef typename boost::graph_traits<CFG>::in_edge_iterator in_edge_iterator;
179 typedef typename boost::graph_traits<CFG>::edge_iterator edge_iterator;
228 Edge e = intedgemap[edge];
229 Vertex v = boost::source(e, *g);
230 return(vertintmap[v]);
247 Edge e = intedgemap[edge];
248 Vertex v = boost::target(e, *g);
249 return(vertintmap[v]);
265 Vertex getIns = intvertmap[node];
266 std::vector<int> inedges;
269 in_edge_iterator i, j;
272 in_edge_iterator i = inedges.begin();
273 in_edge_iterator j = i;
275 for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i)
277 inedges.push_back(edgeintmap[*i]);
297 Vertex getOuts = intvertmap[node];
298 std::vector<int> outedges;
301 out_edge_iterator i, j;
304 out_edge_iterator i = outedges.begin();
305 out_edge_iterator j = i;
307 for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i)
309 outedges.push_back(edgeintmap[*i]);
327zipPath2(std::vector<int>& pth, CFG*& g) {
328 std::vector<int> npth;
329 npth.push_back(pth[0]);
330 for (
int i = 1; i < pth.size()-1; i++) {
331 if (find(closures.begin(), closures.end(), pth[i]) != closures.end()) {
332 npth.push_back(pth[i]);
335 npth.push_back(pth.back());
353zipPath(std::vector<int>& pth, CFG*& g,
int start,
int end) {
354 std::vector<int> subpath;
355 std::vector<int> movepath;
356 movepath.push_back(pth.front());
357 movepath.push_back(pth.back());
358 for (
unsigned int qw = 0; qw < pth.size()-1; qw++) {
359 if (find(markers.begin(), markers.end(), pth[qw]) != markers.end()) {
360 std::vector<int> oeds = getOutEdges(pth[qw], g);
361 for (
unsigned int i = 0; i < oeds.size(); i++) {
362 if (getTarget(oeds[i], g) == pth[qw+1]) {
363 movepath.push_back(oeds[i]);
389unzipPath(std::vector<int>& pzipped, CFG*& g,
int start,
int end) {
390 ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1));
391 std::vector<int> zipped;
392 for (
unsigned int i = 2; i < pzipped.size(); i++) {
393 zipped.push_back(pzipped[i]);
395 std::vector<int> unzipped;
396 unzipped.push_back(start);
397 std::vector<int> oeds = getOutEdges(start, g);
398 if (oeds.size() == 0) {
401 for (
unsigned int i = 0; i < zipped.size(); i++) {
402 oeds = getOutEdges(unzipped.back(), g);
403 while (oeds.size() == 1) {
404 if (getTarget(oeds[0], g) == end && unzipped.size() != 1) {
405 unzipped.push_back(end);
408 unzipped.push_back(getTarget(oeds[0], g));
409 oeds = getOutEdges(unzipped.back(), g);
411 if (oeds.size() == 0) {
414 if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) {
415 ROSE_ASSERT(getSource(zipped[i], g) == unzipped.back());
416 unzipped.push_back(getTarget(zipped[i], g));
420 std::vector<int> oeds2 = getOutEdges(unzipped.back(), g);
421 if (unzipped.back() != end && oeds2.size() != 0) {
422 while (oeds2.size() == 1 && unzipped.back() != end) {
423 unzipped.push_back(getTarget(oeds2[0], g));
424 oeds2 = getOutEdges(unzipped.back(), g);
456std::vector<std::vector<int> >
465 bool recursedloop = loop;
466 std::map<int, std::vector<std::vector<int> > > PtP;
468 std::vector<std::vector<int> > pathContainer;
470 std::vector<int> completedLoops;
471 std::vector<std::vector<int> > npc;
472 std::vector<int> bgpath;
473 bgpath.push_back(begin);
474 pathContainer.push_back(bgpath);
475 std::vector<std::vector<int> > newPathContainer;
476 std::vector<std::vector<int> > paths;
477 std::vector<int> localLoops;
478 std::map<int, std::vector<std::vector<int> > > globalLoopPaths;
481 while (pathContainer.size() != 0 ) {
511 for (
unsigned int i = 0; i < pathContainer.size(); i++) {
512 std::vector<int> npth = pathContainer[i];
513 std::vector<int> oeds = getOutEdges(npth.back(), g);
514 std::vector<int> ieds = getInEdges(npth.back(), g);
516 npth = pathContainer[i];
517 oeds = getOutEdges(npth.back(), g);
519 if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) {
520 std::vector<int> newpth;
521 newpth = (pathContainer[i]);
522 std::vector<int> movepath = newpth;
523 if (recursedloop && newpth.back() == end && newpth.size() != 1) {
524 paths.push_back(movepath);
526 else if (!recursedloop) {
527 if (bound && newpth.size() != 1 && newpth.back() == end) {
528 paths.push_back(movepath);
531 paths.push_back(movepath);
537std::vector<int> oeds = getOutEdges(pathContainer[i].back(), g);
539 for (
unsigned int j = 0; j < oeds.size(); j++) {
542int tg = getTarget(oeds[j], g);
545 std::vector<int> newpath = (pathContainer[i]);
548 if (nodes.find(tg) != nodes.end() && find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) {
549 if (PtP.find(tg) == PtP.end()) {
552 newPathContainer.push_back(nv);
553 PtP[tg].push_back(newpath);
556 PtP[tg].push_back(newpath);
559 else if (find(newpath.begin(), newpath.end(), getTarget(oeds[j], g)) == newpath.end() || getTarget(oeds[j], g) == end) {
560 newpath.push_back(tg);
561 std::vector<int> ieds = getInEdges(tg, g);
562 if (ieds.size() > 1) {
565 newPathContainer.push_back(newpath);
567 else if (tg == end && recursedloop) {
568 newpath.push_back(tg);
569 newPathContainer.push_back(newpath);
572 std::vector<int> ieds = getInEdges(tg, g);
573 if (ieds.size() > 1 && find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() && find(recurses.begin(), recurses.end(), tg) == recurses.end()) {
574 localLoops.push_back(tg);
587 pathContainer = newPathContainer;
588 newPathContainer.clear();
591 pathContainer.clear();
592 std::vector<std::vector<int> > finnpts;
593 std::vector<std::vector<int> > npts;
595 if (paths.size() > 1000000) {
596 std::cout <<
"too many paths, consider a subgraph" << std::endl;
600 for (
unsigned int qq = 0; qq < paths.size(); qq++) {
601 std::vector<int> pq = paths[qq];
603 int ppf = paths[qq].front();
604 if (PtP.find(ppf) != PtP.end()) {
605 for (
unsigned int kk = 0; kk < PtP[ppf].size(); kk++) {
606 std::vector<int> newpath = PtP[ppf][kk];
608 if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) {
619 for (
unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) {
626if (find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) {
635 newpath.insert(newpath.end(), pq.begin(), pq.end());
640 npts.push_back(newpath);
646 std::vector<int> ppq = pq;
651 finnpts.push_back(ppq);
655 if (npts.size() == 0) {
665 for (
unsigned int k = 0; k < localLoops.size(); k++) {
666 int lk = localLoops[k];
667 std::vector<std::vector<int> > loopp;
668 if (loopStore.find(localLoops[k]) != loopStore.end()) {
669 loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end());
672 std::map<int, std::vector<std::vector<int> > > localLoopPaths;
673 completedLoops.push_back(lk);
674 recurses.push_back(lk);
675 loopp = bfsTraversePath(lk, lk, g,
true);
678 for (
unsigned int ik = 0; ik < loopp.size(); ik++) {
680 if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) {
681 globalLoopPaths[localLoops[k]].push_back(loopp[ik]);
689 std::vector<std::vector<int> > lps2;
716 uTraversePath(begin, end, g,
false, globalLoopPaths);
721 std::set<std::vector<int> > lps = uTraversePath(begin, end, g,
true, globalLoopPaths);
723 for (std::set<std::vector<int> >::iterator ij = lps.begin(); ij != lps.end(); ij++) {
724 std::vector<int> ijk = (*ij);
755std::set<std::vector<int> >
757uTraversePath(
int begin,
int , CFG*& g,
bool loop, std::map<
int, std::vector<std::vector<int> > >& globalLoopPaths) {
771 std::set<std::vector<int> > newpaths;
772 std::set<std::vector<int> > npaths;
774 std::vector<int> path;
775 std::vector<std::vector<int> > paths;
777 std::vector<std::vector<int> > checkpaths;
778 std::vector<std::vector<int> > npathchecker;
779 std::map<int, int> currents;
781 std::set<std::vector<int> > loopPaths;
784 std::set<std::vector<int> > fts;
789 if (paths.size() > 1000000) {
790 std::cout <<
"nearly 1 million paths with no loops, stopping" << std::endl;
792 std::cout <<
"ended early" << std::endl;
794 if (done || borrowed) {
801 if (paths.size() != 0) {
810 #pragma omp parallel for schedule(guided)
812 for (
unsigned int qqq = 0; qqq < paths.size(); qqq++) {
817 std::set<std::vector<int> > movepaths;
818 std::vector<int> path;
822 std::vector<int> perms;
823 std::vector<unsigned int> qs;
824 std::map<int, std::vector<std::vector<int> > > localLoops;
825 std::vector<int> takenLoops;
826 takenLoops.push_back(path[0]);
832 for (
unsigned int q = 1; q < path.size()-1; q++) {
834 if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() && globalLoopPaths[path[q]].size() != 0 ) {
835 for (
unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) {
837 std::vector<int> gp = globalLoopPaths[path[q]][qp1];
839 for (
unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) {
840 if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) {
846 localLoops[path[q]].push_back(gp);
853 if (localLoops[path[q]].size() != 0) {
854 takenLoops.push_back(path[q]);
855 permnums *= (localLoops[path[q]].size()+1);
856 perms.push_back(permnums);
857 qs.push_back(path[q]);
879 std::set<std::vector<int> > movepathscheck;
883 std::vector<int> nvec;
884 std::vector<std::vector<int> > boxpaths(permnums, nvec);
886 for (
int i = 1; i <= permnums; i++) {
888 std::vector<int> loopsTaken;
891 std::vector<int> npath;
893 if (j == perms.size() || perms[j] > i) {
902 for (
unsigned int j1 = 0; j1 <= j; j1++) {
905 for (
unsigned int k = j; k > 0; k--) {
907 while (perms[k-1]*l < pn) {
911 pn -= (perms[k-1]*(l-1));
916 for (
unsigned int q1 = 0; q1 < path.size(); q1++) {
917 if (q2 < qs.size()) {
918 if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (
size_t)q2 != pL.size()) {
920 npath.push_back(path[q1]);
924 npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(),
925 localLoops[path[q1]][pL[q2]].end());
931 npath.push_back(path[q1]);
935 npath.push_back(path[q1]);
939 std::cout <<
"path: " << std::endl;
940 for (
int qe = 0; qe < npath.size(); qe++) {
941 std::cout <<
", " << npath[qe];
943 std::cout << std::endl;
944 std::cout <<
"permnum: " << i << std::endl;
990 boxpaths[i-1] = npath;
996 evaledpaths += boxpaths.size();
997 if (evaledpaths > newmil*100000ull) {
1004 for (std::vector<std::vector<int> >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) {
1005 std::vector<Vertex> verts;
1006 getVertexPath((*box), g, verts);
1008 #pragma omp critical
1017 #pragma omp critical
1020 loopPaths.insert(boxpaths.begin(), boxpaths.end());;
1100 loopStore[begin] = loopPaths;
1136 needssafety =
false;
1147 workingthread =
false;
1148 workingthreadnum = -1;
1154 bool subgraph =
false;
1158 recursiveLoops.clear();
1160 std::vector<std::vector<int> > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g);
1164 std::set<int> usedsources;
1166 std::vector<int> localLps;
1167 for (
unsigned int j = 0; j < sources.size(); j++) {
1168 sourcenum = sources[j];
1169 recursiveLoops.clear();
1171 std::vector<std::vector<int> > spaths = bfsTraversePath(sources[j], -1, g);
1194computeSubGraphs(
const int& begin,
const int &end, CFG*& g,
int depthDifferential) {
1196 int maxDepth = minDepth + depthDifferential;
1197 int currSubGraph = 0;
1199 std::set<int> foundNodes;
1201 Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]);
1202 GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin];
1203 SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]];
1204 for (
int i = minDepth; i <= maxDepth; i++) {
1205 Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]];
1206 std::vector<int> outEdges = getOutEdges(orderOfNodes[i], g);
1207 for (
unsigned int j = 0; j < outEdges.size(); j++) {
1209 if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) {
1210 u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]];
1213 u = boost::add_vertex(*subGraphVector[currSubGraph]);
1214 foundNodes.insert(getTarget(outEdges[j], g));
1215 SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)];
1216 GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u;
1221 boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]);
1224 minDepth = maxDepth;
1225 if ((
unsigned int) minDepth == orderOfNodes.size()-1) {
1228 maxDepth += depthDifferential;
1229 if ((
unsigned int) maxDepth > orderOfNodes.size()-1)
1231 maxDepth = orderOfNodes.size()-1;
1234 subGraphVector.push_back(newSubGraph);
1251 std::string nodeColor =
"black";
1252 o << cf <<
" [label=\"" <<
" num:" << cf <<
" prop: " << prop <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1261 int pts = ptsNum[cf];
1262 std::string nodeColor =
"black";
1263 o << cf <<
" [label=\"" <<
" pts: " << pts <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1266 std::string nodeColor =
"black";
1267 o << cf <<
" [label=\"" <<
" num:" << cf <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1277 int src = getSource(cf, cfg);
1278 int tar = getTarget(cf, cfg);
1279 o << src <<
" -> " << tar <<
" [label=\"" << src <<
" " << tar <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1290 std::stringstream filenam;
1291 filenam <<
"hotness" << currhot <<
".dot";
1293 std::string fn = filenam.str();
1294 mf.open(fn.c_str());
1296 mf <<
"digraph defaultName { \n";
1299 vertex_iterator v, vend;
1300 edge_iterator e, eend;
1303 vertex_iterator v = vertices(*gc).begin();
1304 vertex_iterator vend = v;
1305 edge_iterator e = edges(*gc).begin();
1306 edge_iterator eend = e;
1308 for (boost::tie(v, vend) = vertices(*gc); v != vend; ++v)
1310 printCFGNode(vertintmap[*v], mf);
1312 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1314 printCFGEdge(edgeintmap[*e], g, mf);
1325 std::stringstream filenam;
1326 filenam <<
"pathnums.dot";
1327 std::string fn = filenam.str();
1328 mf.open(fn.c_str());
1330 mf <<
"digraph defaultName { \n";
1331 vertex_iterator v, vend;
1332 edge_iterator e, eend;
1333 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
1335 if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) {
1336 int nn = vertintmap[*v];
1337 printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf);
1340 printCFGNodeGeneric(vertintmap[*v],
"noprop", mf);
1343 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1345 printCFGEdge(edgeintmap[*e], g, mf);
1368 findClosuresAndMarkersAndEnumerate(g);
1389 findClosuresAndMarkersAndEnumerate(g);