Exemple #1
0
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;
}
Exemple #2
0
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);
			}

		}
	}

}