// Iterate through all possible paths in the dag void LSTMStaticEstimatorPass::calculatePaths(BLInstrumentationDag* dag) { unsigned nPaths = dag->getNumberOfPaths(); errs() << "There are " << nPaths << " paths\n"; int stride = nPaths / MAX_PATHS; if (stride <= 1) stride = 1; errs() << "Using stride " << stride << "\n"; Function* fn = dag->getRoot()->getBlock()->getParent(); PI->setCurrentFunction(fn); unsigned nPathsRun = PI->pathsRun(); if (nPathsRun == 0) { errs() << "This function is never run in profiling! Skipping...\n"; } else { int n_extracted = 0; // Enumerate all paths in this function for (int i=0; i<nPaths; i++) { // Show progress for large values if (i % 10000000 == 0 && i != 0) { errs() << "Computed for " << i << "/" << nPaths << " paths\n"; } ProfilePath* curPath = PI->getPath(i); unsigned n_real_count = 0; if (curPath) { n_real_count = curPath->getCount(); } // We need to subsample the paths, but only if this isn't a pos example bool extract = false; if (n_real_count == 0) { if (i % stride == 0) { extract = true; } } else { extract = true; } if (extract) { //compute the exact path std::vector<BasicBlock*> path = computePath(dag, i); // Extract features FeatureExtractor* features = new FeatureExtractor(path); std::string fnName = fn->getName(); ofs << fnName << " " << i << " " // Function ID << n_real_count << " " // Ground truth << path.size() << "\n" // Number of BB to follow << features->getFeaturesLSTM(); // BBs and features delete features; n_extracted++; } } errs() << "Extracted " << n_extracted << " paths for this function\n\n"; } }
// the verifier iterates through each path to gather the total // number of edge frequencies bool PathProfileVerifier::runOnModule (Module &M) { PathProfileInfo& pathProfileInfo = getAnalysis<PathProfileInfo>(); // setup a data structure to map path edges which index an // array of edge counters NestedBlockToIndexMap arrayMap; unsigned i = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; arrayMap[0][F->begin()][0] = i++; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { TerminatorInst *TI = BB->getTerminator(); unsigned duplicate = 0; BasicBlock* prev = 0; for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; prev = TI->getSuccessor(s), ++s) { if (prev == TI->getSuccessor(s)) duplicate++; else duplicate = 0; arrayMap[BB][TI->getSuccessor(s)][duplicate] = i++; } } } std::vector<unsigned> edgeArray(i); // iterate through each path and increment the edge counters as needed for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; pathProfileInfo.setCurrentFunction(F); DEBUG(dbgs() << "function '" << F->getName() << "' ran " << pathProfileInfo.pathsRun() << "/" << pathProfileInfo.getPotentialPathCount() << " potential paths\n"); for( ProfilePathIterator nextPath = pathProfileInfo.pathBegin(), endPath = pathProfileInfo.pathEnd(); nextPath != endPath; nextPath++ ) { ProfilePath* currentPath = nextPath->second; ProfilePathEdgeVector* pev = currentPath->getPathEdges(); DEBUG(dbgs () << "path #" << currentPath->getNumber() << ": " << currentPath->getCount() << "\n"); // setup the entry edge (normally path profiling doesn't care about this) if (currentPath->getFirstBlockInPath() == &F->getEntryBlock()) edgeArray[arrayMap[0][currentPath->getFirstBlockInPath()][0]] += currentPath->getCount(); for( ProfilePathEdgeIterator nextEdge = pev->begin(), endEdge = pev->end(); nextEdge != endEdge; nextEdge++ ) { if (nextEdge != pev->begin()) DEBUG(dbgs() << " :: "); BasicBlock* source = nextEdge->getSource(); BasicBlock* target = nextEdge->getTarget(); unsigned duplicateNumber = nextEdge->getDuplicateNumber(); DEBUG(dbgs() << source->getName() << " --{" << duplicateNumber << "}--> " << target->getName()); // Ensure all the referenced edges exist // TODO: make this a separate function if( !arrayMap.count(source) ) { errs() << " error [" << F->getName() << "()]: source '" << source->getName() << "' does not exist in the array map.\n"; } else if( !arrayMap[source].count(target) ) { errs() << " error [" << F->getName() << "()]: target '" << target->getName() << "' does not exist in the array map.\n"; } else if( !arrayMap[source][target].count(duplicateNumber) ) { errs() << " error [" << F->getName() << "()]: edge " << source->getName() << " -> " << target->getName() << " duplicate number " << duplicateNumber << " does not exist in the array map.\n"; } else { edgeArray[arrayMap[source][target][duplicateNumber]] += currentPath->getCount(); } } DEBUG(errs() << "\n"); delete pev; } } std::string errorInfo; std::string filename = EdgeProfileFilename; // Open a handle to the file FILE* edgeFile = fopen(filename.c_str(),"wb"); if (!edgeFile) { errs() << "error: unable to open file '" << filename << "' for output.\n"; return false; } errs() << "Generating edge profile '" << filename << "' ...\n"; // write argument info unsigned type = ArgumentInfo; unsigned num = pathProfileInfo.argList.size(); int zeros = 0; fwrite(&type,sizeof(unsigned),1,edgeFile); fwrite(&num,sizeof(unsigned),1,edgeFile); fwrite(pathProfileInfo.argList.c_str(),1,num,edgeFile); if (num&3) fwrite(&zeros, 1, 4-(num&3), edgeFile); type = EdgeInfo; num = edgeArray.size(); fwrite(&type,sizeof(unsigned),1,edgeFile); fwrite(&num,sizeof(unsigned),1,edgeFile); // write each edge to the file for( std::vector<unsigned>::iterator s = edgeArray.begin(), e = edgeArray.end(); s != e; s++) fwrite(&*s, sizeof (unsigned), 1, edgeFile); fclose (edgeFile); return true; }