/*! * Update call graph for the input indirect callsites */ bool AndersenWaveDiff::updateCallGraph(const CallSiteToFunPtrMap& callsites) { CallEdgeMap newEdges; onTheFlyCallGraphSolve(callsites,newEdges); NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it ) { llvm::CallSite cs = it->first; for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) { consCG->connectCaller2CalleeParams(cs,*cit,cpySrcNodes); } } for(NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it!=eit; ++it) { NodeID src = sccRepNode(it->first); NodeID dst = sccRepNode(it->second); unionPts(dst, src); pushIntoWorklist(dst); } return (!newEdges.empty()); }
static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq, NodePairSet &Ne) { // Don't cache the result for nodes with different hashes. The hash // comparison is fast enough. if (node_hash(N1) != node_hash(N2)) return false; NodePair NP = node_pair(N1, N2); NodePairSet::iterator FEq = Eq.find(NP); if (FEq != Eq.end()) return true; NodePairSet::iterator FNe = Ne.find(NP); if (FNe != Ne.end()) return false; // Not previously compared. bool Root1 = N1->Flags & GepNode::Root; bool Root2 = N2->Flags & GepNode::Root; NodePair P = node_pair(N1, N2); // If the Root flag has different values, the nodes are different. // If both nodes are root nodes, but their base pointers differ, // they are different. if (Root1 != Root2 || (Root1 && N1->BaseVal != N2->BaseVal)) { Ne.insert(P); return false; } // Here the root flags are identical, and for root nodes the // base pointers are equal, so the root nodes are equal. // For non-root nodes, compare their parent nodes. if (Root1 || node_eq(N1->Parent, N2->Parent, Eq, Ne)) { Eq.insert(P); return true; } return false; }
void State::divideTrees(const State& a_other, NodePairSet& a_commonRoots, NodeSet& a_myUniqueRoots, NodeSet& a_otherUniqueRoots) { NodeSet otherRootSet = a_other.getRootSet(); // Copy the entire set a_commonRoots.clear(); a_myUniqueRoots.clear(); a_otherUniqueRoots.clear(); for (NodeSetIter iter = m_rootSet.begin(); iter != m_rootSet.end(); iter++) { bool isUnique = true; string rootName; if (!((*iter)->getUniqueName(rootName))) { error("State::divideTrees - Multiple roots (in this state) with the same name " + rootName + " exist! " + string(*this), true); } for (NodeSetIter otherIter = otherRootSet.begin(); otherIter != otherRootSet.end(); otherIter++) { string otherRootName; if (!((*otherIter)->getUniqueName(otherRootName))) { error("State::divideTrees - Multiple roots (in joined state) with the same name " + otherRootName + " exist! " + string(a_other), true); } if (rootName == otherRootName) { a_commonRoots.insert(make_pair((*iter), (*otherIter))); otherRootSet.erase(otherIter); isUnique = false; break; } } if (isUnique) { a_myUniqueRoots.insert(*iter); } } a_otherUniqueRoots = otherRootSet; }
void State::join(const State& a_otherState) { NodePairSet commonRoots; NodeSet myUniqueRoots; NodeSet otherUniqueRoots; debug("State::join - joining state: " + string(*this)); debug("State::join - with state: " + string(a_otherState)); divideTrees(a_otherState, commonRoots, myUniqueRoots, otherUniqueRoots); m_rootSet.clear(); for (NodePairSetIter iter = commonRoots.begin(); iter != commonRoots.end(); iter++) { TreeNode* myTree = iter->first; TreeNode* otherTree = iter->second; myTree->join(otherTree); m_rootSet.insert(myTree); } for (NodeSetIter iter = myUniqueRoots.begin(); iter != myUniqueRoots.end(); iter++) { m_rootSet.insert(*iter); } for (NodeSetIter iter = otherUniqueRoots.begin(); iter != otherUniqueRoots.end(); iter++) { TreeNode* node = new TreeNode(*(*iter)); m_rootSet.insert(node); } buildVariableMap(); debug("State::join - joined state: " + string(*this)); }