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());
638 npts.push_back(newpath);
644 std::vector<int> ppq = pq;
647 finnpts.push_back(ppq);
651 if (npts.size() == 0) {
661 for (
unsigned int k = 0; k < localLoops.size(); k++) {
662 int lk = localLoops[k];
663 std::vector<std::vector<int> > loopp;
664 if (loopStore.find(localLoops[k]) != loopStore.end()) {
665 loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end());
668 std::map<int, std::vector<std::vector<int> > > localLoopPaths;
669 completedLoops.push_back(lk);
670 recurses.push_back(lk);
671 loopp = bfsTraversePath(lk, lk, g,
true);
674 for (
unsigned int ik = 0; ik < loopp.size(); ik++) {
676 if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) {
677 globalLoopPaths[localLoops[k]].push_back(loopp[ik]);
685 std::vector<std::vector<int> > lps2;
712 uTraversePath(begin, end, g,
false, globalLoopPaths);
717 std::set<std::vector<int> > lps = uTraversePath(begin, end, g,
true, globalLoopPaths);
719 for (std::set<std::vector<int> >::iterator ij = lps.begin(); ij != lps.end(); ij++) {
720 std::vector<int> ijk = (*ij);
751std::set<std::vector<int> >
753uTraversePath(
int begin,
int end, CFG*& g,
bool loop, std::map<
int, std::vector<std::vector<int> > >& globalLoopPaths) {
767 std::set<std::vector<int> > newpaths;
768 std::set<std::vector<int> > npaths;
770 std::vector<int> path;
771 std::vector<std::vector<int> > paths;
773 std::vector<std::vector<int> > checkpaths;
774 std::vector<std::vector<int> > npathchecker;
775 std::map<int, int> currents;
777 std::set<std::vector<int> > loopPaths;
780 std::set<std::vector<int> > fts;
785 if (paths.size() > 1000000) {
786 std::cout <<
"nearly 1 million paths with no loops, stopping" << std::endl;
788 std::cout <<
"ended early" << std::endl;
790 if (done || borrowed) {
797 if (paths.size() != 0) {
805 #pragma omp parallel for schedule(guided)
806 for (
unsigned int qqq = 0; qqq < paths.size(); qqq++) {
811 std::set<std::vector<int> > movepaths;
812 std::vector<int> path;
816 std::vector<int> perms;
817 std::vector<unsigned int> qs;
818 std::map<int, std::vector<std::vector<int> > > localLoops;
819 std::vector<int> takenLoops;
820 takenLoops.push_back(path[0]);
826 for (
unsigned int q = 1; q < path.size()-1; q++) {
828 if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() && globalLoopPaths[path[q]].size() != 0 ) {
829 for (
unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) {
831 std::vector<int> gp = globalLoopPaths[path[q]][qp1];
833 for (
unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) {
834 if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) {
840 localLoops[path[q]].push_back(gp);
847 if (localLoops[path[q]].size() != 0) {
848 takenLoops.push_back(path[q]);
849 permnums *= (localLoops[path[q]].size()+1);
850 perms.push_back(permnums);
851 qs.push_back(path[q]);
873 std::set<std::vector<int> > movepathscheck;
877 std::vector<int> nvec;
878 std::vector<std::vector<int> > boxpaths(permnums, nvec);
880 for (
int i = 1; i <= permnums; i++) {
882 std::vector<int> loopsTaken;
885 std::vector<int> npath;
887 if (j == perms.size() || perms[j] > i) {
896 for (
unsigned int j1 = 0; j1 <= j; j1++) {
899 for (
unsigned int k = j; k > 0; k--) {
901 while (perms[k-1]*l < pn) {
905 pn -= (perms[k-1]*(l-1));
910 for (
unsigned int q1 = 0; q1 < path.size(); q1++) {
911 if (q2 < qs.size()) {
912 if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (
size_t)q2 != pL.size()) {
914 npath.push_back(path[q1]);
918 npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(),
919 localLoops[path[q1]][pL[q2]].end());
925 npath.push_back(path[q1]);
929 npath.push_back(path[q1]);
933 std::cout <<
"path: " << std::endl;
934 for (
int qe = 0; qe < npath.size(); qe++) {
935 std::cout <<
", " << npath[qe];
937 std::cout << std::endl;
938 std::cout <<
"permnum: " << i << std::endl;
984 boxpaths[i-1] = npath;
990 evaledpaths += boxpaths.size();
991 if (evaledpaths > newmil*100000ull) {
998 for (std::vector<std::vector<int> >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) {
999 std::vector<Vertex> verts;
1000 getVertexPath((*box), g, verts);
1001 #pragma omp critical
1008 #pragma omp critical
1010 loopPaths.insert(boxpaths.begin(), boxpaths.end());;
1090 loopStore[begin] = loopPaths;
1126 needssafety =
false;
1137 workingthread =
false;
1138 workingthreadnum = -1;
1144 bool subgraph =
false;
1148 recursiveLoops.clear();
1150 std::vector<std::vector<int> > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g);
1154 std::set<int> usedsources;
1156 std::vector<int> localLps;
1157 for (
unsigned int j = 0; j < sources.size(); j++) {
1158 sourcenum = sources[j];
1159 recursiveLoops.clear();
1161 std::vector<std::vector<int> > spaths = bfsTraversePath(sources[j], -1, g);
1184computeSubGraphs(
const int& begin,
const int &end, CFG*& g,
int depthDifferential) {
1186 int maxDepth = minDepth + depthDifferential;
1187 int currSubGraph = 0;
1189 std::set<int> foundNodes;
1191 Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]);
1192 GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin];
1193 SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]];
1194 for (
int i = minDepth; i <= maxDepth; i++) {
1195 Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]];
1196 std::vector<int> outEdges = getOutEdges(orderOfNodes[i], g);
1197 for (
unsigned int j = 0; j < outEdges.size(); j++) {
1199 if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) {
1200 u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]];
1203 u = boost::add_vertex(*subGraphVector[currSubGraph]);
1204 foundNodes.insert(getTarget(outEdges[j], g));
1205 SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)];
1206 GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u;
1211 boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]);
1214 minDepth = maxDepth;
1215 if ((
unsigned int) minDepth == orderOfNodes.size()-1) {
1218 maxDepth += depthDifferential;
1219 if ((
unsigned int) maxDepth > orderOfNodes.size()-1)
1221 maxDepth = orderOfNodes.size()-1;
1224 subGraphVector.push_back(newSubGraph);
1241 std::string nodeColor =
"black";
1242 o << cf <<
" [label=\"" <<
" num:" << cf <<
" prop: " << prop <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1251 int pts = ptsNum[cf];
1252 std::string nodeColor =
"black";
1253 o << cf <<
" [label=\"" <<
" pts: " << pts <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1256 std::string nodeColor =
"black";
1257 o << cf <<
" [label=\"" <<
" num:" << cf <<
"\", color=\"" << nodeColor <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1267 int src = getSource(cf, cfg);
1268 int tar = getTarget(cf, cfg);
1269 o << src <<
" -> " << tar <<
" [label=\"" << src <<
" " << tar <<
"\", style=\"" <<
"solid" <<
"\"];\n";
1280 std::stringstream filenam;
1281 filenam <<
"hotness" << currhot <<
".dot";
1283 std::string fn = filenam.str();
1284 mf.open(fn.c_str());
1286 mf <<
"digraph defaultName { \n";
1289 vertex_iterator v, vend;
1290 edge_iterator e, eend;
1293 vertex_iterator v = vertices(*gc).begin();
1294 vertex_iterator vend = v;
1295 edge_iterator e = edges(*gc).begin();
1296 edge_iterator eend = e;
1298 for (boost::tie(v, vend) = vertices(*gc); v != vend; ++v)
1300 printCFGNode(vertintmap[*v], mf);
1302 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1304 printCFGEdge(edgeintmap[*e], g, mf);
1315 std::stringstream filenam;
1316 filenam <<
"pathnums.dot";
1317 std::string fn = filenam.str();
1318 mf.open(fn.c_str());
1320 mf <<
"digraph defaultName { \n";
1321 vertex_iterator v, vend;
1322 edge_iterator e, eend;
1323 for (tie(v, vend) = vertices(*gc); v != vend; ++v)
1325 if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) {
1326 int nn = vertintmap[*v];
1327 printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf);
1330 printCFGNodeGeneric(vertintmap[*v],
"noprop", mf);
1333 for (tie(e, eend) = edges(*gc); e != eend; ++e)
1335 printCFGEdge(edgeintmap[*e], g, mf);
1358 findClosuresAndMarkersAndEnumerate(g);
1379 findClosuresAndMarkersAndEnumerate(g);