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;
}
Пример #2
0
 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);
     }
   }
 }