ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, const ProgramState *State, bool* IsNew) { // Profile 'State' to determine if we already have an existing node. llvm::FoldingSetNodeID profile; void *InsertPos = 0; NodeTy::Profile(profile, L, State); NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos); if (!V) { if (freeNodes && !getNodeList(freeNodes)->empty()) { NodeList *nl = getNodeList(freeNodes); V = nl->back(); nl->pop_back(); } else { // Allocate a new node. V = (NodeTy*) getAllocator().Allocate<NodeTy>(); } new (V) NodeTy(L, State); if (reclaimNodes) { if (!recentlyAllocatedNodes) recentlyAllocatedNodes = new NodeList(); getNodeList(recentlyAllocatedNodes)->push_back(V); } // Insert the node into the node set and return it. Nodes.InsertNode(V, InsertPos); ++NumNodes; if (IsNew) *IsNew = true; } else if (IsNew) *IsNew = false; return V; }
void DataFlow::mergeFlow(Graph<NodeDesc>* f,const Graph<NodeDesc>* g, std::map<Node*,Node*>& mapping) { // mapping is g -> f NodeList queue = g->rootNodes(); while (!queue.empty()) { Node* n = queue.back(); queue.pop_back(); // check predecessors bool allSourcesMapped = true; for (LinkListCIt sIt=n->sources().begin();sIt!=n->sources().end();sIt++) { Link* sLink = *sIt; map<Node*,Node*>::iterator findIt=mapping.find(sLink->source); if (findIt==mapping.end()) { allSourcesMapped = false; break; } } if (!allSourcesMapped) { // some sources miss. Ignore current node for now continue; } if (mapping.find(n)==mapping.end()) { // merge node // all sources are merged, merge current node Node* mergedNode(NULL); // first check if identical node already exists in f NodeList candidates; if (n->sources().size()>0) { candidates = mapping.find(n->sources()[0]->source)->second->targetNodes(); } else { candidates = f->rootNodes(); } for (NodeListIt cIt=candidates.begin();cIt!=candidates.end();cIt++) { if ((**cIt==*n) && sources_match(n->sources(),(*cIt)->sources(),mapping)) { // found identical node mergedNode = *cIt; break; } } if (mergedNode==NULL) { // no identical node found. Create node mergedNode = f->createNode(n->v); for (LinkListCIt sIt=n->sources().begin();sIt!=n->sources().end();sIt++) { f->link(mapping.find((*sIt)->source)->second,(*sIt)->sourceOutputPort, mergedNode, (*sIt)->targetInputPort); } } // register mapping mapping[n] = mergedNode; } // add target nodes to queue NodeList targets = n->targetNodes(); queue.insert(queue.end(),targets.begin(),targets.end()); } // merge names for (NameMapCIt gnIt=g->getNames().begin();gnIt!=g->getNames().end();gnIt++) { NameMapCIt fnIt = f->getNames().find(gnIt->first); if (fnIt!=f->getNames().end()) { // check nodes are merged if (mapping[gnIt->second]!=fnIt->second) { cerr << "ERROR: '" << gnIt->first << "' node exists in the two graphs and cannot be merged !" << endl; } } else { // add named node to f f->setNodeName(mapping[gnIt->second], gnIt->first); } } }