std::pair<GraphNode*, int> llvm::Graph::getNearestDependency(llvm::Value* sink, std::set<llvm::Value*> sources, bool skipMemoryNodes) { std::pair<llvm::GraphNode*, int> result; result.first = NULL; result.second = -1; if (GraphNode* startNode = findNode(sink)) { std::set<GraphNode*> sourceNodes = findNodes(sources); std::map<GraphNode*, int> nodeColor; std::list<std::pair<GraphNode*, int> > workList; for (std::set<GraphNode*>::iterator Nit = nodes.begin(), Nend = nodes.end(); Nit != Nend; Nit++) { if (skipMemoryNodes && isa<MemNode> (*Nit)) nodeColor[*Nit] = 1; else nodeColor[*Nit] = 0; } workList.push_back(pair<GraphNode*, int> (startNode, 0)); /* * we will do a breadth search on the predecessors of each node, * until we find one of the sources. If we don't find any, then the * sink doesn't depend on any source. */ while (workList.size()) { GraphNode* workNode = workList.front().first; int currentDistance = workList.front().second; nodeColor[workNode] = 1; workList.pop_front(); if (sourceNodes.count(workNode)) { result.first = workNode; result.second = currentDistance; break; } std::map<GraphNode*, edgeType> preds = workNode->getPredecessors(); for (std::map<GraphNode*, edgeType>::iterator pred = preds.begin(), pend = preds.end(); pred != pend; pred++) { if (nodeColor[pred->first] == 0) { // the node hasn't been processed yet nodeColor[pred->first] = 1; workList.push_back( pair<GraphNode*, int> (pred->first, currentDistance + 1)); } } } } return result; }
std::map<GraphNode*, std::vector<GraphNode*> > llvm::Graph::getEveryDependency( llvm::Value* sink, std::set<llvm::Value*> sources, bool skipMemoryNodes) { std::map<llvm::GraphNode*, std::vector<GraphNode*> > result; DenseMap<GraphNode*, GraphNode*> parent; std::vector<GraphNode*> path; // errs() << "--- Get every dep --- \n"; if (GraphNode* startNode = findNode(sink)) { // errs() << "found sink\n"; // errs() << "Starting search from " << startNode->getLabel() << "\n"; std::set<GraphNode*> sourceNodes = findNodes(sources); std::map<GraphNode*, int> nodeColor; std::list<GraphNode*> workList; // int size = 0; for (std::set<GraphNode*>::iterator Nit = nodes.begin(), Nend = nodes.end(); Nit != Nend; Nit++) { // size++; if (skipMemoryNodes && isa<MemNode> (*Nit)) nodeColor[*Nit] = 1; else nodeColor[*Nit] = 0; } workList.push_back(startNode); nodeColor[startNode] = 1; /* * we will do a breadth search on the predecessors of each node, * until we find one of the sources. If we don't find any, then the * sink doesn't depend on any source. */ // int pb = 1; while (!workList.empty()) { GraphNode* workNode = workList.front(); workList.pop_front(); if (sourceNodes.count(workNode)) { //Retrieve path path.clear(); GraphNode* n = workNode; path.push_back(n); while (parent.count(n)) { path.push_back(parent[n]); n = parent[n]; } // std::reverse(path.begin(), path.end()); // errs() << "Path: "; // for (std::vector<GraphNode*>::iterator i = path.begin(), e = path.end(); i != e; ++i) { // errs() << (*i)->getLabel() << " | "; // } // errs() << "\n"; result[workNode] = path; } std::map<GraphNode*, edgeType> preds = workNode->getPredecessors(); for (std::map<GraphNode*, edgeType>::iterator pred = preds.begin(), pend = preds.end(); pred != pend; pred++) { if (nodeColor[pred->first] == 0) { // the node hasn't been processed yet nodeColor[pred->first] = 1; workList.push_back(pred->first); // pb++; parent[pred->first] = workNode; } } // errs() << pb << "/" << size << "\n"; } } return result; }
/* * method fixPointIteration * * Implements a worklist algorithm that updates the abstract states * of the nodes of the graph until a fixed point is reached. * * The LatticeOperation lo determines if the operation will be a widening * or narrowing analysis. */ void llvm::RangeAnalysis::fixPointIteration(int SCCid, LatticeOperation lo) { SCC_Iterator it(depGraph, SCCid); std::set<GraphNode*> worklist; std::list<GraphNode*> currentSCC; while(it.hasNext()){ GraphNode* node = it.getNext(); //Things to do in the first fixPoint iteration (growth analysis) if (lo == loJoin) { currentSCC.push_back(node); //Initialize abstract state out_state[node] = getInitialState(node); widening_count[node] = 0; narrowing_count[node] = 0; } std::map<GraphNode*, edgeType> preds = node->getPredecessors(); if (preds.size() == 0) { worklist.insert(node); } else { //Add the Sigma Nodes to the worklist of the narrowing, //even if they do not receive data from outside the SCC if (lo == loMeet) { if(SigmaOpNode* Sigma = dyn_cast<SigmaOpNode>(node)){ worklist.insert(Sigma); } } else { //Look for nodes that receive information from outside the SCC for(std::map<GraphNode*, edgeType>::iterator pred = preds.begin(), pred_end = preds.end(); pred != pred_end; pred++){ //Only data dependence edges if(pred->second != etData) continue; if(depGraph->getSCCID(pred->first) != SCCid) { worklist.insert(node); break; } } } } } while(worklist.size() > 0){ GraphNode* currentNode = *(worklist.begin()); worklist.erase(currentNode); computeNode(currentNode, worklist, lo); } if (lo == loJoin){ //Statistic: size of SCCs unsigned int current_size = currentSCC.size(); if (current_size == 1) numAloneSCCs++; else if (current_size > sizeMaxSCC) sizeMaxSCC = current_size; for(std::list<GraphNode*>::iterator it = currentSCC.begin(), iend = currentSCC.end(); it != iend; it++){ GraphNode* currentNode = *it; if(out_state[currentNode].isUnknown()){ out_state[currentNode] = Range(Min, Max); } } } }