Пример #1
0
int get_max_key(std::multimap<u_int,record> map, std::set<u_int> keys) {
	std::set<u_int>::iterator it = keys.begin();
	u_int max = *it;
        for(;it != keys.end(); ++it){
		if (map.count(*it) > map.count(max))
			max = *it;
	}
	return max; 
}
void CZMQAbstractPublishNotifier::Shutdown()
{
    assert(psocket);

    int count = mapPublishNotifiers.count(address);

    // remove this notifier from the list of publishers using this address
    typedef std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator iterator;
    std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address);

    for (iterator it = iterpair.first; it != iterpair.second; ++it)
    {
        if (it->second==this)
        {
            mapPublishNotifiers.erase(it);
            break;
        }
    }

    if (count == 1)
    {
        LogPrint("zmq", "Close socket at address %s\n", address);
        int linger = 0;
        zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger));
        zmq_close(psocket);
    }

    psocket = 0;
}
std::vector<CIMSettings> InterwovenServers::GetDuplicateEntries(const std::map<CStdString, CIMSettings>& uniqueIntewovenServers, const std::multimap<CStdString, CIMSettings>& duplicateIntewovenServers)
{
	LOG_WS_FUNCTION_SCOPE();
	
	std::vector<CIMSettings> duplications;
	
	if(uniqueIntewovenServers.size() == duplicateIntewovenServers.size())
	{
		return duplications;
	}

	for(std::map<CStdString, CIMSettings>::const_iterator it = uniqueIntewovenServers.begin(); it != uniqueIntewovenServers.end(); ++it)
	{
		CStdString key = it->first;		
		
		if(duplicateIntewovenServers.count(key) == 1)
		{
			continue;
		}

		pair<multimap<CStdString, CIMSettings>::const_iterator, multimap<CStdString, CIMSettings>::const_iterator> equalRange = duplicateIntewovenServers.equal_range(key);
		for(multimap<CStdString, CIMSettings>::const_iterator it = equalRange.first; it != equalRange.second; ++it)
		{
			CIMSettings wsServer = it->second;
			wsServer.SetActionType(CIMSettings::REGISTRATION_ACTION_REMOVE);
			duplications.push_back(wsServer);		
		}
	}
	
	return duplications;
}
Пример #4
0
void AMQPAbstractPublishNotifier::Shutdown()
{
    LogPrint("amqp", "amqp: Shutdown notifier %s at %s\n", GetType(), GetAddress());

    int count = mapPublishNotifiers.count(address);

    // remove this notifier from the list of publishers using this address
    typedef std::multimap<std::string, AMQPAbstractPublishNotifier*>::iterator iterator;
    std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address);

    for (iterator it = iterpair.first; it != iterpair.second; ++it) {
        if (it->second == this) {
            mapPublishNotifiers.erase(it);
            break;
        }
    }

    // terminate the connection if this is the last publisher using this address
    if (count == 1) {
        handler_->terminate();
        if (thread_.get() != nullptr) {
            if (thread_->joinable()) {
                thread_->join();
            }
        }
    }
}
Пример #5
0
void getAverageNormal(
	PackedVertexWithTangents2 & packed,
	std::multimap<PackedVertexWithTangents2,unsigned int> & vertexToOutIndex,
	PackedVertexWithTangents2 & result)
{
	result.position = packed.position;
	result.uv = packed.uv;
	std::multimap<PackedVertexWithTangents2,unsigned int>::iterator it;
	int count = vertexToOutIndex.count(packed);

	for(it = vertexToOutIndex.equal_range(packed).first; it != vertexToOutIndex.equal_range(packed).second; ++it)
	{
		result.normal += it->first.normal;
		result.tangent += it->first.tangent;
		result.biTangent += it->first.biTangent;
	}

	result.normal = glm::normalize(result.normal);
	result.biTangent = glm::normalize(result.biTangent);
	result.tangent = glm::normalize(result.tangent);
}
Пример #6
0
/*
 * dissect/print packet
 */
void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{

	static int count = 1;                   /* packet counter */
	
	/* declare pointers to packet headers */
	const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
	const struct sniff_ip *ip;              /* The IP header */
	const struct sniff_tcp *tcp;            /* The TCP header */
	//const char *payload;                    /* Packet payload */
	//const u_char *payload;

	int size_ip;
	int size_tcp;
	int size_payload;
	
	//printf("\nPacket number %d:\n", count);
	count++;
	
	/* define ethernet header */
	ethernet = (struct sniff_ethernet*)(packet);
	
	/* define/compute ip header offset */
	ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
	size_ip = IP_HL(ip)*4;
	if (size_ip < 20) {
		printf("   * Invalid IP header length: %u bytes\n", size_ip);
		return;
	}

	/* print source and destination IP addresses */
	//printf("       From: %s\n", inet_ntoa(ip->ip_src));
	//printf("         To: %s\n", inet_ntoa(ip->ip_dst));
	
	/* determine protocol */	
	switch(ip->ip_p) {
		case IPPROTO_TCP:
			//printf("   Protocol: TCP\n");
			break;
		case IPPROTO_UDP:
			printf("   Protocol: UDP\n");
			return;
		case IPPROTO_ICMP:
			printf("   Protocol: ICMP\n");
			return;
		case IPPROTO_IP:
			printf("   Protocol: IP\n");
			return;
		default:
			printf("   Protocol: unknown\n");
			return;
	}

	
	/* define/compute tcp header offset */
	tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
	size_tcp = TH_OFF(tcp)*4;
	if (size_tcp < 20) {
		printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
		return;
	}
	std::string flags;
	if (tcp->th_flags & TH_FIN) 
		flags = flags + "F";
	if (tcp->th_flags & TH_SYN) 
                flags = flags + "S";
	if (tcp->th_flags & TH_RST) 
                flags = flags + "R";
	if (tcp->th_flags & TH_ACK) 
                flags = flags + "A";
	if (tcp->th_flags & TH_URG) 
                flags = flags + "U";
	if (tcp->th_flags & TH_ECE) 
                flags = flags + "E";
	if (tcp->th_flags & TH_CWR) 
                flags = flags + "C";

	chars v;
	chars buffer;
	std::multimap<u_int,chars> temp_map; //to sort

	std::cout << "Packet# " << count << " S " << ntohl(tcp->th_seq) << " A " << ntohl(tcp->th_ack) << " Flags " << flags <<"\n";

	if ((tcp->th_flags & TH_ACK) != 0) {
		const u_char *payload = (const u_char *) (packet + SIZE_ETHERNET + size_ip + size_tcp);
		size_payload = ntohs(ip->ip_len)- (size_ip + size_tcp);
		std::copy(payload, payload + size_payload, std::back_inserter(v));
		//std::reverse(v.begin(),v.end()); // byte order thing
		std::pair<u_int,chars> temp(ntohl(tcp->th_seq),v); // create record
		dict.insert(std::pair<u_int,record>(ntohl(tcp->th_ack),temp));
		//std::cout << "Packet# " << count << " " << ntohl(tcp->th_seq) << "\n";
		//std::cout << "Packet# " << count << " " << inet_ntoa(ip->ip_src) << "\n";
	}

	  if (((tcp->th_flags & TH_FIN) != 0) && ((tcp->th_flags & TH_ACK) != 0)) {
		std::set<u_int> temp = get_keys(dict);
		u_int last_key = ntohl(tcp->th_ack);
		std::cout << "*********************************************\n";
		std::set<u_int>::iterator it = temp.begin();
		for(;it != temp.end(); ++it)
			std::cout << "Key " << *it << " Count " << dict.count(*it) <<"\n";
		u_int image_key = get_max_key(dict,temp);
		std::cout << "Image key " << image_key << "\n";

		std::multimap<u_int,record>::iterator itt;
		std::cout << "*********************************************\n";
		for(itt=dict.begin(); itt!= dict.end(); ++itt) {
			if ((*itt).first == image_key) {
				std::pair<u_int,chars> temp_record = (*itt).second;
				temp_map.insert(std::pair<u_int,chars>(temp_record.first,temp_record.second));
			}
		}

		std::multimap<u_int,chars>::iterator ittt;
		for(ittt = temp_map.begin(); ittt!=temp_map.end(); ++ittt) {
			buffer.insert(buffer.end(), (*ittt).second.begin(), (*ittt).second.end());
		}

		std::ofstream myfile;
		myfile.open("image.jpg", std::ios::out | std::ios::binary);
		myfile.write(&buffer[0], buffer.size());
		std::cout << buffer.size() << "\n";
		std::cout << "For FIN packet " << "S: " << ntohl(tcp->th_seq) << " A: " << ntohl(tcp->th_ack) << "\n";
		dict.clear();
		conn.set("server_ip",inet_ntoa(ip->ip_src));
		//exit(0);
	}
return;
}
Пример #7
0
bool  ConvertXML2PO(std::string LangDir, std::string LCode, int nPlurals,
                    std::string PluralForm, bool bIsForeignLang)
{
  int contextCount = 0;
  int stringCountSource = 0;
  int stringCountForeign = 0;
  std::string  OutputPOFilename;

  OutputPOFilename = LangDir + "strings.po";

  // Initalize the output po document
  pPOTFile = fopen (OutputPOFilename.c_str(),"wb");
  if (pPOTFile == NULL)
  {
    printf("Error opening output file: %s\n", OutputPOFilename.c_str());
    return false;
  }
  printf("%s\t\t", LCode.c_str()); 

  fprintf(pPOTFile,
    "# XBMC Media Center language file\n"
    "msgid \"\"\n"
    "msgstr \"\"\n"
    "\"Project-Id-Version: %s-%s\\n\"\n"
    "\"Report-Msgid-Bugs-To: [email protected]\\n\"\n"
    "\"POT-Creation-Date: %s\\n\"\n"
    "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n"
    "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n"
    "\"Language-Team: LANGUAGE\\n\"\n"
    "\"MIME-Version: 1.0\\n\"\n"
    "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
    "\"Content-Transfer-Encoding: 8bit\\n\"\n"
    "\"Language: %s\\n\"\n"
    "\"Plural-Forms: nplurals=%i; plural=%s\\n\"\n\n",
    (pProjectName != NULL) ? pProjectName : "xbmc-unnamed",
    (pVersionNumber != NULL) ?  pVersionNumber : "rev_unknown",
    GetCurrTime().c_str(),
    (!LCode.empty()) ? LCode.c_str() : "LANGUAGE",
    nPlurals, PluralForm.c_str());

  int previd = -1;
  bool bCommentWritten = false;
  for (itSourceXmlId = mapSourceXmlId.begin(); itSourceXmlId != mapSourceXmlId.end(); itSourceXmlId++)
  {
    int id = itSourceXmlId->first;
    std::string value = itSourceXmlId->second;

    //create comment lines, if empty string id or ids found and
    //re-create original xml comments between entries. Only for the source language
    bCommentWritten = false;
    if (!bIsForeignLang) bCommentWritten = WriteComments(previd, true);

    if ((id-previd >= 2) && !bIsForeignLang)
    {
      if (id-previd == 2 && previd > -1)
        fprintf(pPOTFile,"#empty string with id %i\n", id-1);
      if (id-previd > 2 && previd > -1)
        fprintf(pPOTFile,"#empty strings from id %i to %i\n", previd+1, id-1);
      bCommentWritten = true;
    }
    if (bCommentWritten) fprintf(pPOTFile, "\n");

    //create comment, including string id
    fprintf(pPOTFile,"#: id:%i\n", id);

    //write comment originally placed next to the string entry
    //convert it into #. style gettext comment
    if (!bIsForeignLang) WriteComments(id, false);

    if (multimapSourceXmlStrings.count(value) > 1) // if we have multiple IDs for the same string value
    {
      //create autogenerated context message for multiple msgid entries
      fprintf(pPOTFile,"msgctxt \"Auto context with id %i\"\n", id);
      contextCount++;
    }
    //create msgid and msgstr lines
    WriteStrLine("msgid ", value.c_str(), sourceXMLEncoding);
    if (bIsForeignLang)
    {
      itForeignXmlId = mapForeignXmlId.find(id);
      if (itForeignXmlId != mapForeignXmlId.end())
      {
        stringCountForeign++;
        WriteStrLine("msgstr ", itForeignXmlId->second.c_str(), foreignXMLEncoding);
        fprintf(pPOTFile,"\n");
      }
      else fprintf(pPOTFile,"msgstr \"\"\n\n");
    }
    else fprintf(pPOTFile,"msgstr \"\"\n\n");

    stringCountSource++;
    previd =id;
  }
  fclose(pPOTFile);

  printf("%i\t\t", bIsForeignLang ? stringCountForeign : stringCountSource);
  printf("%i\t\t", contextCount);
  printf("%s\n", OutputPOFilename.erase(0,WorkingDir.length()).c_str());

  mapForeignXmlId.clear();
  return true;
}
Пример #8
0
void generateProlog()
{
  int total_cycles;
  int regi_prolog_cycles = prolog_size/(X*Y);
  int init_cycles = maxMemoryOperations*3;
  int noop_cycles=0;
  if(init_cycles%II != 0)
  {
    noop_cycles = II - (init_cycles%II);
  }
  total_cycles = init_cycles + noop_cycles + regi_prolog_cycles;

  final_prolog_size = total_cycles * X * Y;

  final_prolog = new unsigned int[final_prolog_size];

  CGRA_Instruction noop_ins = generateNOOP();
  unsigned int noop_decoded = noop_ins.DecodeInstruction(&noop_ins);

  //populate the final_prolog array with init instructions

  //FOR EACH PE
  for(int i=0; i<(X*Y); ++i)
  {   
    //FOR EACH MEM OPERATION
    if(initInstructions.count(i) > 0)
    {
      std::pair <std::multimap<int,std::vector<CGRA_Instruction> >::iterator, std::multimap<int,std::vector<CGRA_Instruction> >::iterator> ret;
      ret = initInstructions.equal_range(i);
      int j=0;

      //FOR EACH LD_IMM OPERATION
      for (std::multimap<int,std::vector<CGRA_Instruction> >::iterator it=ret.first; it!=ret.second; ++it)
      {
        std::vector<CGRA_Instruction> LDI_ins = it->second;
        for(int k = 0;k<LDI_ins.size(); ++k)
        {
          final_prolog[i + (X*Y)*j] = LDI_ins[k].DecodeInstruction(&LDI_ins[k]);
          j++;
        }
      }

      //fill the rest of init cycles with noops
      if(j < init_cycles)
      {
        while(j< init_cycles)
        {
          final_prolog[i + (X*Y)*j] = noop_decoded;
          j++;
        }
      }


    }

    //fll with only noops
    else
    {
      for(int j = 0;j<init_cycles;++j)
        final_prolog[i + (X*Y)*j] = noop_decoded;
    }
  }

  //populate the final_prolog array with dummy noop instructions

  if(noop_cycles > 0)
  {
    for(int i = 0; i< (X*Y); ++i)
    {
      for (int j = init_cycles; j < (init_cycles + noop_cycles) ; ++j)
      {
        final_prolog[i + (X*Y)*j] = noop_decoded;
      }
    }
  }

  int prolog_start = (init_cycles + noop_cycles) * (X*Y);

  for(int i =0; i<prolog_size; ++i)
  {
    if(prolog[i] == -1)
    {   
      final_prolog[prolog_start++] = noop_decoded;
    }
    else
    {
      CGRA_Instruction temp = nodeid_instruction[prolog[i]];
      final_prolog[prolog_start++] = temp.DecodeInstruction(&temp);
    }
  }

  cout<<"*******PROLOG*********\n";

  for(int i =0; i<final_prolog_size; ++i)
    printf("%d: %x\n",i,final_prolog[i]);
}
Пример #9
0
/// visitGraph - Visit the functions in the specified graph, updating the
/// specified lattice values for all of their uses.
///
void StructureFieldVisitorBase::
visitGraph(DSGraph &DSG, std::multimap<DSNode*, LatticeValue*> &NodeLVs) {
  assert(!NodeLVs.empty() && "No lattice values to compute!");

  // To visit a graph, first step, we visit the instruction making up each
  // function in the graph, but ignore calls when processing them.  We handle
  // call nodes explicitly by looking at call nodes in the graph if needed.  We
  // handle instructions before calls to avoid interprocedural analysis if we
  // can drive lattice values to bottom early.
  //
  SFVInstVisitor IV(DSG, Callbacks, NodeLVs);

  for (DSGraph::retnodes_iterator FI = DSG.retnodes_begin(),
         E = DSG.retnodes_end(); FI != E; ++FI)
    for (Function::iterator BB = FI->first->begin(), E = FI->first->end();
         BB != E; ++BB)
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
        if (IV.visit(*I) && NodeLVs.empty())
          return;  // Nothing left to analyze.

  // Keep track of which actual direct callees are handled.
  std::set<Function*> CalleesHandled;

  // Once we have visited all of the instructions in the function bodies, if
  // there are lattice values that have not been driven to bottom, see if any of
  // the nodes involved are passed into function calls.  If so, we potentially
  // have to recursively traverse the call graph.
  for (DSGraph::fc_iterator CS = DSG.fc_begin(), E = DSG.fc_end();
       CS != E; ++CS) {
    // Figure out the mapping from a node in the caller (potentially several)
    // nodes in the callee.
    DSGraph::NodeMapTy CallNodeMap;

    Instruction *TheCall = CS->getCallSite().getInstruction();

    // If this is an indirect function call, assume nothing gets passed through
    // it. FIXME: THIS IS BROKEN!  Just get the ECG for the fn ptr if it's not
    // direct.
    if (CS->isIndirectCall())
      continue;

    // If this is an external function call, it cannot be involved with this
    // node, because otherwise the node would be marked incomplete!
    if (CS->getCalleeFunc()->isExternal())
      continue;

    // If we can handle this function call, remove it from the set of direct
    // calls found by the visitor.
    CalleesHandled.insert(CS->getCalleeFunc());

    std::vector<DSNodeHandle> Args;

    DSGraph *CG = &ECG.getDSGraph(*CS->getCalleeFunc());
    CG->getFunctionArgumentsForCall(CS->getCalleeFunc(), Args);

    if (!CS->getRetVal().isNull())
      DSGraph::computeNodeMapping(Args[0], CS->getRetVal(), CallNodeMap);
    for (unsigned i = 0, e = CS->getNumPtrArgs(); i != e; ++i) {
      if (i == Args.size()-1) break;
      DSGraph::computeNodeMapping(Args[i+1], CS->getPtrArg(i), CallNodeMap);
    }
    Args.clear();

    // The mapping we just computed maps from nodes in the callee to nodes in
    // the caller, so we can't query it efficiently.  Instead of going through
    // the trouble of inverting the map to do this (linear time with the size of
    // the mapping), we just do a linear search to see if any affected nodes are
    // passed into this call.
    bool CallCanModifyDataFlow = false;
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI)
      if (NodeLVs.count(MI->second.getNode()))
        // Okay, the node is passed in, check to see if the call might do
        // something interesting to it (i.e. if analyzing the call can produce
        // anything other than "top").
        if ((CallCanModifyDataFlow = NodeCanPossiblyBeInteresting(MI->first,
                                                                  Callbacks)))
          break;

    // If this function call cannot impact the analysis (either because the
    // nodes we are tracking are not passed into the call, or the DSGraph for
    // the callee tells us that analysis of the callee can't provide interesting
    // information), ignore it.
    if (!CallCanModifyDataFlow)
      continue;

    // Okay, either compute analysis results for the callee function, or reuse
    // results previously computed.
    std::multimap<DSNode*, LatticeValue*> &CalleeFacts = getCalleeFacts(*CG);

    // Merge all of the facts for the callee into the facts for the caller.  If
    // this reduces anything in the caller to 'bottom', remove them.
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI) {
      // If we have Lattice facts in the caller for this node in the callee,
      // merge any information from the callee into the caller.

      // If the node is not accessed in the callee at all, don't update.
      if (MI->first->getType() == Type::VoidTy)
        continue;

      // If there are no data-flow facts live in the caller for this node, don't
      // both processing it.
      std::multimap<DSNode*, LatticeValue*>::iterator NLVI =
        NodeLVs.find(MI->second.getNode());
      if (NLVI == NodeLVs.end()) continue;
          
          
      // Iterate over all of the lattice values that have corresponding fields
      // in the callee, merging in information as we go.  Be careful about the
      // fact that the callee may get passed the address of a substructure and
      // other funny games.
      //if (CalleeFacts.count(const_cast<DSNode*>(MI->first)) == 0) {

      DSNode *CalleeNode = const_cast<DSNode*>(MI->first);

      unsigned CalleeNodeOffset = MI->second.getOffset();
      while (NLVI->first == MI->second.getNode()) {
        // Figure out what offset in the callee this field would land.
        unsigned FieldOff = NLVI->second->getFieldOffset()+CalleeNodeOffset;

        // If the field is not within the callee node, ignore it.
        if (FieldOff >= CalleeNode->getSize()) {
          ++NLVI;
          continue;
        }

        // Okay, check to see if we have a lattice value for the field at offset
        // FieldOff in the callee node.
        const LatticeValue *CalleeLV = 0;

        std::multimap<DSNode*, LatticeValue*>::iterator CFI = 
          CalleeFacts.lower_bound(CalleeNode);
        for (; CFI != CalleeFacts.end() && CFI->first == CalleeNode; ++CFI)
          if (CFI->second->getFieldOffset() == FieldOff) {
            CalleeLV = CFI->second;   // Found it!
            break;
          }
        
        // If we don't, the lattice value hit bottom and we should remove the
        // lattice value in the caller.
        if (!CalleeLV) {
          delete NLVI->second;   // The lattice value hit bottom.
          NodeLVs.erase(NLVI++);
          continue;
        }

        // Finally, if we did find a corresponding entry, merge the information
        // into the caller's lattice value and keep going.
        if (NLVI->second->mergeInValue(CalleeLV)) {
          // Okay, merging these two caused the caller value to hit bottom.
          // Remove it.
          delete NLVI->second;   // The lattice value hit bottom.
          NodeLVs.erase(NLVI++);
        }

        ++NLVI;  // We successfully merged in some information!
      }

      // If we ran out of facts to prove, just exit.
      if (NodeLVs.empty()) return;
    }
  }

  // The local analysis pass inconveniently discards many local function calls
  // from the graph if they are to known functions.  Loop over direct function
  // calls not handled above and visit them as appropriate.
  while (!IV.DirectCallSites.empty()) {
    Instruction *Call = *IV.DirectCallSites.begin();
    IV.DirectCallSites.erase(IV.DirectCallSites.begin());

    // Is this one actually handled by DSA?
    if (CalleesHandled.count(cast<Function>(Call->getOperand(0))))
      continue;

    // Collect the pointers involved in this call.    
    std::vector<Value*> Pointers;
    if (isa<PointerType>(Call->getType()))
      Pointers.push_back(Call);
    for (unsigned i = 1, e = Call->getNumOperands(); i != e; ++i)
      if (isa<PointerType>(Call->getOperand(i)->getType()))
        Pointers.push_back(Call->getOperand(i));

    // If this is an intrinsic function call, figure out which one.
    unsigned IID = cast<Function>(Call->getOperand(0))->getIntrinsicID();

    for (unsigned i = 0, e = Pointers.size(); i != e; ++i) {
      // If any of our lattice values are passed into this call, which is
      // specially handled by the local analyzer, inform the lattice function.
      DSNode *N = DSG.getNodeForValue(Pointers[i]).getNode();
      for (std::multimap<DSNode*, LatticeValue*>::iterator LVI =
             NodeLVs.lower_bound(N); LVI != NodeLVs.end() && LVI->first == N;) {
        bool AtBottom = false;
        switch (IID) {
        default:
          AtBottom = LVI->second->visitRecognizedCall(*Call);
          break;
        case Intrinsic::memset:
          if (Callbacks & Visit::Stores)
            AtBottom = LVI->second->visitMemSet(*cast<CallInst>(Call));
          break;
        }

        if (AtBottom) {
          delete LVI->second;
          NodeLVs.erase(LVI++);
        } else {
          ++LVI;
        }
      }
    }
  }
}