/*! * Collect cycle information */ void AndersenStat::collectCycleInfo(ConstraintGraph* consCG) { _NumOfCycles = 0; _NumOfPWCCycles = 0; _NumOfNodesInCycles = 0; std::set<NodeID> repNodes; repNodes.clear(); for(ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it!=eit; ++it) { // sub nodes have been removed from the constraint graph, only rep nodes are left. NodeID repNode = consCG->sccRepNode(it->first); NodeBS& subNodes = pta->sccSubNodes(repNode); NodeBS clone = subNodes; for (NodeBS::iterator it = subNodes.begin(), eit = subNodes.end(); it != eit; ++it) { NodeID nodeId = *it; PAGNode* pagNode = pta->getPAG()->getPAGNode(nodeId); if (isa<ObjPN>(pagNode) && consCG->isFieldInsensitiveObj(nodeId)) { NodeID baseId = consCG->getBaseObjNode(nodeId); clone.reset(nodeId); clone.set(baseId); } } u32_t num = clone.count(); if (num > 1) { if(repNodes.insert(repNode).second) { _NumOfNodesInCycles += num; if(consCG->isPWCNode(repNode)) _NumOfPWCCycles ++; } if( num > _MaxNumOfNodesInSCC) _MaxNumOfNodesInSCC = num; } } _NumOfCycles += repNodes.size(); }
void MRGenerator::getGlobalsAndHeapFromPts(NodeBS& globs, const NodeBS& pts) { for(NodeBS::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it) { const MemObj* obj = pta->getPAG()->getObject(*it); assert(obj && "object not found!!"); if(obj->isGlobalObj() || obj->isHeap()) globs.set(*it); } }
/*! * Get all fields object nodes of an object * If this object is collapsed into one field insensitive object * Then only return this field insensitive object */ NodeBS PAG::getFieldsAfterCollapse(NodeID id) { const PAGNode* node = pag->getPAGNode(id); assert(llvm::isa<ObjPN>(node) && "need an object node"); const MemObj* mem = llvm::cast<ObjPN>(node)->getMemObj(); if(mem->isFieldInsensitive()) { NodeBS bs; bs.set(getFIObjNode(mem)); return bs; } else return getAllFieldsObjNode(mem); }
/*! * Add indirect def an memory object in the function */ bool MRGenerator::addModSideEffectOfCallSite(llvm::CallSite cs, const NodeBS& mods) { if(!mods.empty()) { NodeBS modset = mods; modset &= getCallSitePts(cs); getGlobalsAndHeapFromPts(modset,mods); addModSideEffectOfFunction(cs.getCaller(),modset); return csToModsMap[cs] |= modset; } return false; }
/*! * Add indirect uses an memory object in the function */ bool MRGenerator::addRefSideEffectOfCallSite(llvm::CallSite cs, const NodeBS& refs) { if(!refs.empty()) { NodeBS refset = refs; refset &= getCallSitePts(cs); getGlobalsAndHeapFromPts(refset,refs); addRefSideEffectOfFunction(cs.getCaller(),refset); return csToRefsMap[cs] |= refset; } return false; }
bool PTACallGraphNode::isReachableFromProgEntry() const { std::stack<const PTACallGraphNode*> nodeStack; NodeBS visitedNodes; nodeStack.push(this); visitedNodes.set(getId()); while (nodeStack.empty() == false) { PTACallGraphNode* node = const_cast<PTACallGraphNode*>(nodeStack.top()); nodeStack.pop(); if (analysisUtil::isProgEntryFunction(node->getFunction())) return true; for (const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) { PTACallGraphEdge* edge = *it; if (visitedNodes.test_and_set(edge->getSrcID())) nodeStack.push(edge->getSrcNode()); } } return false; }
/*! * Add indirect def an memory object in the function */ void MRGenerator::addModSideEffectOfFunction(const llvm::Function* fun, const NodeBS& mods) { for(NodeBS::iterator it = mods.begin(), eit = mods.end(); it!=eit; ++it) { if(isNonLocalObject(*it,fun)) funToModsMap[fun].set(*it); } }