diff --git a/include/MemoryModel/ConsG.h b/include/MemoryModel/ConsG.h index 09462dc0c..9fcd3a7da 100644 --- a/include/MemoryModel/ConsG.h +++ b/include/MemoryModel/ConsG.h @@ -130,7 +130,7 @@ class ConstraintGraph : public GenericGraph { /// Add Copy edge bool addCopyCGEdge(NodeID src, NodeID dst); /// Add Gep edge - bool addNormalGepCGEdge(NodeID src, NodeID dst, const LocationSet& ls); + bool addNormalGepCGEdge(NodeID src, NodeID dst, const NormalGepPE* gepPE); bool addVariantGepCGEdge(NodeID src, NodeID dst); /// Add Load edge bool addLoadCGEdge(NodeID src, NodeID dst); @@ -255,8 +255,8 @@ class ConstraintGraph : public GenericGraph { return (mem->getMaxFieldOffsetLimit() == 1); } /// Get a field of a memory object - inline NodeID getGepObjNode(NodeID id, const LocationSet& ls) { - NodeID gep = pag->getGepObjNode(id,ls); + inline NodeID getGepObjNode(NodeID id, const NormalGepCGEdge* gepEdge) { + NodeID gep = pag->getGepObjNode(id,gepEdge->getGepPE()); /// Create a node when it is (1) not exist on graph and (2) not merged if(sccRepNode(gep)==gep && hasConstraintNode(gep)==false) addConstraintNode(new ConstraintNode(gep),gep); diff --git a/include/MemoryModel/ConsGEdge.h b/include/MemoryModel/ConsGEdge.h index c004f334a..6d4daa5df 100644 --- a/include/MemoryModel/ConsGEdge.h +++ b/include/MemoryModel/ConsGEdge.h @@ -239,7 +239,7 @@ class NormalGepCGEdge : public GepCGEdge { NormalGepCGEdge(const NormalGepCGEdge &); ///< place holder void operator=(const NormalGepCGEdge &); ///< place holder - LocationSet ls; ///< location set of the gep edge + const NormalGepPE* gepPE; ///< PAG Gep Edge public: /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -259,18 +259,23 @@ class NormalGepCGEdge : public GepCGEdge { //@} /// Constructor - NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const LocationSet& l, EdgeID id) - : GepCGEdge(s,d,NormalGep,id), ls(l) + NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const NormalGepPE* gep, EdgeID id) + : GepCGEdge(s,d,NormalGep,id), gepPE(gep) {} /// Get location set of the gep edge inline const LocationSet& getLocationSet() const { - return ls; + return gepPE->getLocationSet(); } /// Get location set of the gep edge inline const u32_t getOffset() const { - return ls.getOffset(); + return gepPE->getLocationSet().getOffset(); + } + + /// Get location set of the gep edge + inline const NormalGepPE* getGepPE() const { + return gepPE; } }; diff --git a/include/MemoryModel/MemModel.h b/include/MemoryModel/MemModel.h index 6417546a7..744692156 100644 --- a/include/MemoryModel/MemModel.h +++ b/include/MemoryModel/MemModel.h @@ -671,7 +671,8 @@ class SymbolTableInfo { const inline std::vector& getFlattenFieldInfoVec(const llvm::Type *T) { return getStructInfoIter(T)->second->getFlattenFieldInfoVec(); } - const inline llvm::Type* getSubType(const llvm::Type* baseType, u32_t fieldIndex){ + /// Get a subType of a type of a base object (all its subtypes are flattened) + const inline llvm::Type* getFlattenSubType(const llvm::Type* baseType, u32_t fieldIndex){ const std::vector &fieldinfo = getFlattenFieldInfoVec(baseType); const llvm::Type *subtype = fieldinfo[fieldIndex].getFlattenElemTy(); return subtype; diff --git a/include/MemoryModel/PAG.h b/include/MemoryModel/PAG.h index 4cf3560c0..6b792debd 100644 --- a/include/MemoryModel/PAG.h +++ b/include/MemoryModel/PAG.h @@ -403,9 +403,9 @@ class PAG : public GenericGraph { /// Get a field PAG Value node according to base value and offset NodeID getGepValNode(const llvm::Value* val, const LocationSet& ls, const llvm::Type *baseType, u32_t fieldidx); /// Get a field PAG Object node according to base mem obj and offset - NodeID getGepObjNode(const MemObj* obj, const LocationSet& ls); + NodeID getGepObjNode(const MemObj* obj, const NormalGepPE* gepEdge, const LocationSet& ls); /// Get a field obj PAG node according to a mem obj and a given offset - NodeID getGepObjNode(NodeID id, const LocationSet& ls) ; + NodeID getGepObjNode(NodeID id, const NormalGepPE* gepEdge) ; /// Get a field-insensitive obj PAG node according to a mem obj //@{ inline NodeID getFIObjNode(const MemObj* obj) const { @@ -532,7 +532,7 @@ class PAG : public GenericGraph { /// Add a temp field value node, this method can only invoked by getGepValNode NodeID addGepValNode(const llvm::Value* val, const LocationSet& ls, NodeID i, const llvm::Type *type, u32_t fieldidx); /// Add a field obj node, this method can only invoked by getGepObjNode - NodeID addGepObjNode(const MemObj* obj, const LocationSet& ls, NodeID i); + NodeID addGepObjNode(const MemObj* obj, const NormalGepPE* gepEdge, const LocationSet& ls); /// Add a field-insensitive node, this method can only invoked by getFIGepObjNode NodeID addFIObjNode(const MemObj* obj); //@} diff --git a/include/MemoryModel/PAGNode.h b/include/MemoryModel/PAGNode.h index 1d578d10e..8428bad24 100644 --- a/include/MemoryModel/PAGNode.h +++ b/include/MemoryModel/PAGNode.h @@ -369,8 +369,7 @@ class GepValPN: public ValPN { class GepObjPN: public ObjPN { private: LocationSet ls; - const llvm::Type* gepObjType; - + const NormalGepPE* gepPE; public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ @@ -389,8 +388,8 @@ class GepObjPN: public ObjPN { //@} /// Constructor - GepObjPN(const MemObj* mem, const llvm::Type* type, NodeID i, const LocationSet& l) : - ObjPN(mem->getRefVal(), i, mem, GepObjNode), ls(l), gepObjType(type) { + GepObjPN(const MemObj* mem, const NormalGepPE* gep, NodeID i, const LocationSet& l) : + ObjPN(mem->getRefVal(), i, mem, GepObjNode), ls(l), gepPE(gep) { } /// offset of the mem object @@ -398,16 +397,17 @@ class GepObjPN: public ObjPN { return ls; } + /// offset of the mem object + inline const NormalGepPE* getGepPE() const { + return gepPE; + } + /// Return name of a LLVM value inline const std::string getValueName() const { if (value && value->hasName()) return value->getName().str() + "_" + llvm::itostr(ls.getOffset()); return "offset_" + llvm::itostr(ls.getOffset()); } - /// Return type of this gep object - inline const llvm::Type* getType() const { - return gepObjType; - } }; /* diff --git a/include/MemoryModel/PointerAnalysis.h b/include/MemoryModel/PointerAnalysis.h index f9ba68634..2c582d2ee 100644 --- a/include/MemoryModel/PointerAnalysis.h +++ b/include/MemoryModel/PointerAnalysis.h @@ -269,8 +269,8 @@ class PointerAnalysis { inline NodeID getFIObjNode(NodeID id) { return pag->getFIObjNode(id); } - inline NodeID getGepObjNode(NodeID id, const LocationSet& ls) { - return pag->getGepObjNode(id,ls); + inline NodeID getGepObjNode(NodeID id, const NormalGepPE* gepEdge) { + return pag->getGepObjNode(id,gepEdge); } inline const NodeBS& getAllFieldsObjNode(NodeID id) { return pag->getAllFieldsObjNode(id); diff --git a/lib/MemoryModel/ConsG.cpp b/lib/MemoryModel/ConsG.cpp index d995160b7..dbf96debf 100644 --- a/lib/MemoryModel/ConsG.cpp +++ b/lib/MemoryModel/ConsG.cpp @@ -96,7 +96,7 @@ void ConstraintGraph::buildCG() { for (PAGEdge::PAGEdgeSetTy::iterator iter = ngeps.begin(), eiter = ngeps.end(); iter != eiter; ++iter) { NormalGepPE* edge = cast(*iter); - addNormalGepCGEdge(edge->getSrcID(),edge->getDstID(),edge->getLocationSet()); + addNormalGepCGEdge(edge->getSrcID(),edge->getDstID(),edge); } PAGEdge::PAGEdgeSetTy& vgeps = pag->getEdgeSet(PAGEdge::VariantGep); @@ -177,13 +177,13 @@ bool ConstraintGraph::addCopyCGEdge(NodeID src, NodeID dst) { /*! * Add Gep edge */ -bool ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const LocationSet& ls) { +bool ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const NormalGepPE* gepPE) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); if(hasEdge(srcNode,dstNode,ConstraintEdge::NormalGep)) return false; - NormalGepCGEdge* edge = new NormalGepCGEdge(srcNode, dstNode,ls, edgeIndex++); + NormalGepCGEdge* edge = new NormalGepCGEdge(srcNode, dstNode, gepPE, edgeIndex++); bool added = directEdgeSet.insert(edge).second; assert(added && "not added??"); srcNode->addOutgoingGepEdge(edge); @@ -266,9 +266,8 @@ void ConstraintGraph::reTargetDstOfEdge(ConstraintEdge* edge, ConstraintNode* ne addCopyCGEdge(srcId,newDstNodeID); } else if(NormalGepCGEdge* gep = dyn_cast(edge)) { - const LocationSet ls = gep->getLocationSet(); removeDirectEdge(gep); - addNormalGepCGEdge(srcId,newDstNodeID,ls); + addNormalGepCGEdge(srcId,newDstNodeID,gep->getGepPE()); } else if(VariantGepCGEdge* gep = dyn_cast(edge)) { removeDirectEdge(gep); @@ -306,9 +305,8 @@ void ConstraintGraph::reTargetSrcOfEdge(ConstraintEdge* edge, ConstraintNode* ne addCopyCGEdge(newSrcNodeID,dstId); } else if(NormalGepCGEdge* gep = dyn_cast(edge)) { - const LocationSet ls = gep->getLocationSet(); removeDirectEdge(gep); - addNormalGepCGEdge(newSrcNodeID,dstId,ls); + addNormalGepCGEdge(newSrcNodeID,dstId,gep->getGepPE()); } else if(VariantGepCGEdge* gep = dyn_cast(edge)) { removeDirectEdge(gep); diff --git a/lib/MemoryModel/PAG.cpp b/lib/MemoryModel/PAG.cpp index b0de6cb72..8789c46f0 100644 --- a/lib/MemoryModel/PAG.cpp +++ b/lib/MemoryModel/PAG.cpp @@ -273,12 +273,12 @@ NodeID PAG::addGepValNode(const llvm::Value* gepVal, const LocationSet& ls, Node /*! * Given an object node, find its field object node */ -NodeID PAG::getGepObjNode(NodeID id, const LocationSet& ls) { +NodeID PAG::getGepObjNode(NodeID id, const NormalGepPE* gepEdge) { PAGNode* node = pag->getPAGNode(id); if (GepObjPN* gepNode = dyn_cast(node)) - return getGepObjNode(gepNode->getMemObj(), gepNode->getLocationSet() + ls); + return getGepObjNode(gepNode->getMemObj(), gepEdge, gepNode->getLocationSet() + gepEdge->getLocationSet()); else if (FIObjPN* baseNode = dyn_cast(node)) - return getGepObjNode(baseNode->getMemObj(), ls); + return getGepObjNode(baseNode->getMemObj(), gepEdge, gepEdge->getLocationSet()); else { assert(false && "new gep obj node kind?"); return id; @@ -291,7 +291,7 @@ NodeID PAG::getGepObjNode(NodeID id, const LocationSet& ls) { * offset = offset % obj->getMaxFieldOffsetLimit() to create limited number of mem objects * maximum number of field object creation is obj->getMaxFieldOffsetLimit() */ -NodeID PAG::getGepObjNode(const MemObj* obj, const LocationSet& ls) { +NodeID PAG::getGepObjNode(const MemObj* obj, const NormalGepPE* gepEdge, const LocationSet& ls) { NodeID base = getObjectNode(obj); /// if this obj is field-insensitive, just return the field-insensitive node. @@ -301,29 +301,25 @@ NodeID PAG::getGepObjNode(const MemObj* obj, const LocationSet& ls) { LocationSet newLS = SymbolTableInfo::Symbolnfo()->getModulusOffset(obj->getTypeInfo(),ls); NodeLocationSetMap::iterator iter = GepObjNodeMap.find(std::make_pair(base, newLS)); - if (iter == GepObjNodeMap.end()) { - NodeID gepNode= addGepObjNode(obj,newLS,nodeNum); - return gepNode; - } else - return iter->second; + if (iter == GepObjNodeMap.end()) + return addGepObjNode(obj, gepEdge, newLS); + else + return iter->second; } /*! * Add a field obj node, this method can only invoked by getGepObjNode */ -NodeID PAG::addGepObjNode(const MemObj* obj, const LocationSet& ls, NodeID i) { +NodeID PAG::addGepObjNode(const MemObj* obj, const NormalGepPE* gepEdge, const LocationSet& ls) { //assert(findPAGNode(i) == false && "this node should not be created before"); NodeID base = getObjectNode(obj); assert(0==GepObjNodeMap.count(std::make_pair(base, ls)) && "this node should not be created before"); - GepObjNodeMap[std::make_pair(base, ls)] = i; - const Type* gepObjType = NULL; - if (obj->getRefVal()) - gepObjType = symInfo->getSubType(obj->getRefVal()->getType(), ls.getOffset()); - GepObjPN *node = new GepObjPN(obj, gepObjType, i, ls); - memToFieldsMap[base].set(i); - return addObjNode(obj->getRefVal(), node, i); + GepObjNodeMap[std::make_pair(base, ls)] = nodeNum; + GepObjPN *node = new GepObjPN(obj, gepEdge, nodeNum, ls); + memToFieldsMap[base].set(nodeNum); + return addObjNode(obj->getRefVal(), node, nodeNum); } /*! diff --git a/lib/MemoryModel/PointerAnalysis.cpp b/lib/MemoryModel/PointerAnalysis.cpp index 68c057dde..dd70014c5 100644 --- a/lib/MemoryModel/PointerAnalysis.cpp +++ b/lib/MemoryModel/PointerAnalysis.cpp @@ -443,7 +443,7 @@ bool BVDataPTAImpl::readFromFile(const string& filename) { size_t offset; ss >> id >> base >> offset; - NodeID n = pag->getGepObjNode(pag->getObject(base), LocationSet(offset)); + NodeID n = pag->getGepObjNode(pag->getObject(base), NULL, LocationSet(offset)); assert(id == n && "Error adding GepObjNode into PAG!"); getline(F, line); diff --git a/lib/WPA/Andersen.cpp b/lib/WPA/Andersen.cpp index bb1716ab5..52a634e0f 100644 --- a/lib/WPA/Andersen.cpp +++ b/lib/WPA/Andersen.cpp @@ -281,7 +281,7 @@ void Andersen::processGepPts(PointsTo& pts, const GepCGEdge* edge) else if (const NormalGepCGEdge* normalGepEdge = dyn_cast(edge)) { if (!matchType(edge->getSrcID(), ptd, normalGepEdge)) continue; - NodeID fieldSrcPtdNode = consCG->getGepObjNode(ptd, normalGepEdge->getLocationSet()); + NodeID fieldSrcPtdNode = consCG->getGepObjNode(ptd, normalGepEdge); tmpDstPts.set(fieldSrcPtdNode); addTypeForGepObjNode(fieldSrcPtdNode, normalGepEdge); // Any points-to passed to an FIObj also pass to its first field diff --git a/lib/WPA/FlowSensitive.cpp b/lib/WPA/FlowSensitive.cpp index e81dbf9c7..7a4b65b62 100644 --- a/lib/WPA/FlowSensitive.cpp +++ b/lib/WPA/FlowSensitive.cpp @@ -387,7 +387,7 @@ bool FlowSensitive::processGep(const GepSVFGNode* edge) { tmpDstPts.set(getFIObjNode(ptd)); } else if (const NormalGepPE* normalGep = dyn_cast(edge->getPAGEdge())) { - NodeID fieldSrcPtdNode = getGepObjNode(ptd, normalGep->getLocationSet()); + NodeID fieldSrcPtdNode = getGepObjNode(ptd, normalGep); tmpDstPts.set(fieldSrcPtdNode); } else