38 using namespace SVFUtil;
56 else assert(
false &&
"BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
63 else assert(
false &&
"BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
71 else assert(
false &&
"BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
77 else assert(
false &&
"BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
84 else assert(
false &&
"BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
86 else assert(
false &&
"no points-to data available");
100 if (names.size() > 1)
101 moduleName = names[names.size() - 1];
106 subtitle =
"Andersen's analysis bitvector";
108 subtitle =
"flow-sensitive analysis bitvector";
110 subtitle =
"CFL analysis bitvector";
112 subtitle =
"Type analysis bitvector";
114 subtitle =
"DDA bitvector";
116 subtitle =
"bitvector";
118 SVFUtil::outs() <<
"\n****Persistent Points-To Cache Statistics: " << subtitle <<
"****\n";
119 SVFUtil::outs() <<
"################ (program : " << moduleName <<
")###############\n";
121 ptCache.printStats(
"bitvector");
122 SVFUtil::outs() <<
"#######################################################" << std::endl;
146 for (
const NodeID o : pts)
162 outs() <<
"Storing ObjVar to '" << filename <<
"'...";
164 std::fstream f(filename.c_str(), std::ios_base::out);
167 outs() <<
" error opening file for writing!\n";
176 if (!isa<ObjVar>(pagNode))
continue;
178 if (NodeIDs.
test(
n))
continue;
205 f << var <<
" -> { ";
226 for(SVFIR::NodeOffsetMap::const_iterator it = gepObjVarMap.begin(), eit = gepObjVarMap.end(); it != eit; it++)
230 f << offsetPair.first <<
" ";
232 f << offsetPair.second <<
" ";
234 f << it->second <<
"\n";
247 outs() <<
"Storing pointer analysis results to '" << filename <<
"'...";
250 std::fstream f(filename.c_str(), std::ios_base::app);
253 outs() <<
" error opening file for writing!\n";
270 if (!isa<ObjVar>(pagNode))
continue;
272 if (NodeIDs.
test(
n))
continue;
294 string delimiter1 =
" -> { ";
295 string delimiter2 =
" }";
296 map<NodeID, string> nodePtsMap;
297 map<string, PointsTo> strPtsMap;
303 if (line.at(0) ==
'[' || line ==
"---VERSIONED---")
continue;
304 if (line ==
"------")
break;
305 size_t pos = line.find(delimiter1);
306 if (pos == string::npos)
break;
307 if (line.back() !=
'}')
break;
310 NodeID var = atoi(line.substr(0, pos).c_str());
313 pos = pos + delimiter1.length();
314 size_t len = line.length() - pos - delimiter2.length();
315 string objs = line.substr(pos, len);
321 nodePtsMap[var] = objs;
322 if (strPtsMap.count(objs))
continue;
324 istringstream ss(objs);
332 strPtsMap[objs] = dstPts;
337 for (
auto t: nodePtsMap)
338 ptD->unionPts(t.first, strPtsMap[t.second]);
349 if (line ==
"------")
break;
351 istringstream ss(line);
355 ss >> base >>
offset >>id;
356 SVFIR::NodeOffsetMap::const_iterator iter = gepObjVarMap.find(std::make_pair(base,
offset));
357 if (iter == gepObjVarMap.end())
360 const MemObj* obj =
nullptr;
361 if (
GepObjVar* gepObjVar = SVFUtil::dyn_cast<GepObjVar>(node))
362 obj = gepObjVar->getMemObj();
363 else if (
FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
364 obj = baseNode->getMemObj();
365 else if (
DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
366 obj = baseNode->getMemObj();
368 assert(
false &&
"new gep obj node kind?");
384 if (line.empty() || line == delimiterStr)
387 istringstream ss(line);
390 ss >> base >> insensitive;
406 outs() <<
"Loading pointer analysis results from '" << filename <<
"'...";
408 ifstream
F(filename.c_str());
411 outs() <<
" error opening file for reading!\n";
442 if (
getPAG()->isValidTopLevelPtr(node))
445 outs() <<
"\nNodeID " << node->
getId() <<
" ";
449 outs() <<
"\t\tPointsTo: {empty}\n\n";
453 outs() <<
"\t\tPointsTo: { ";
456 outs() << *it <<
" ";
474 pagNodes.insert(it->first);
479 outs() <<
"----------------------------------------------\n";
483 outs() <<
"----------------------------------------------\n";
494 for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter)
501 assert(vtbl !=
nullptr);
521 for(CallSiteSet::const_iterator it = tdCallGraph->forksitesBegin(),
522 eit = tdCallGraph->forksitesEnd(); it != eit; ++it)
524 const SVFValue* forkedVal =tdCallGraph->getThreadAPI()->getForkedFun(*it)->getValue();
525 if(SVFUtil::dyn_cast<SVFFunction>(forkedVal) ==
nullptr)
537 if(tdCallGraph->addIndirectForkEdge(*it, svfForkedFun))
538 newForkEdges[*it].insert(svfForkedFun);
557 for (
auto t: memToFieldsMap)
561 assert(memObj &&
"Invalid memobj in memToFieldsMap");
564 for (
NodeID id : t.second)
571 assert(
id == base &&
"Not a GepObj Node or a baseObj Node?");
584 if (!dropNodes.
test(obj))
599 GepObjVarMap.erase(std::make_pair(base, apOffset));
600 memToFieldsMap[base].reset(
n);
virtual void normalizePointsTo()
AliasResult alias(const SVFValue *V1, const SVFValue *V2) override
Interface expose to users of our pointer analysis, given Value infos.
virtual void writeToFile(const std::string &filename)
Interface for analysis result storage on filesystem.
virtual bool readFromFile(const std::string &filename)
virtual void writeObjVarToFile(const std::string &filename)
virtual void clearPts(NodeID id, NodeID element)
Remove element from the points-to set of id.
virtual void readAndSetObjFieldSensitivity(std::ifstream &f, const std::string &delimiterStr)
virtual void writeGepObjVarMapToFile(std::fstream &f)
void finalize() override
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
virtual void writePtsResultToFile(std::fstream &f)
virtual void expandFIObjs(const PointsTo &pts, PointsTo &expandedPts)
Expand FI objects.
void dumpAllPts() override
void remapPointsToSets(void)
Remap all points-to sets to use the current mapping.
virtual void onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newForkEdges)
On the fly thread call graph construction respecting forksite.
PersistentPointsToCache< PointsTo > ptCache
virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
On the fly call graph construction.
virtual bool updateCallGraph(const CallSiteToFunPtrMap &)
Update callgraph. This should be implemented by its subclass.
BVDataPTAImpl(SVFIR *pag, PointerAnalysis::PTATY type, bool alias_check=true)
Constructor.
std::unique_ptr< PTDataTy > ptD
Points-to data.
const PointsTo & getPts(NodeID id) override
void dumpTopLevelPtsTo() override
PTDataTy * getPTDataTy() const
Get points-to data structure.
virtual void readPtsResultFromFile(std::ifstream &f)
virtual bool addPts(NodeID id, NodeID ptd)
PersistentPointsToCache< PointsTo > & getPtCache()
virtual void readGepObjVarMapFromFile(std::ifstream &f)
const SVFVar * getVtablePtr() const
bool isVirtualCall() const
iterator begin()
Iterators.
void removeGNode(NodeType *node)
Delete a node.
NodeType * getGNode(NodeID id) const
Get a node.
IDToNodeMapTy::iterator iterator
Node Iterators.
APOffset getConstantFieldIdx() const
offset of the mem object
NodeID getValueNode(const SVFValue *V)
const SVFValue * getValue() const
Get the reference value to this object.
bool isFieldInsensitive() const
Return true if its field limit is 0.
bool isFunction() const
object attributes methods
static NodeIDAllocator * get(void)
Return (singleton) allocator.
void increaseNumOfObjAndNodes()
static const Option< bool > INCDFPTData
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
static const OptionMap< BVDataPTAImpl::PTBackingType > ptDataBacking
PTData type.
virtual void remapAllPts(void)=0
Remaps all points-to sets to use the current mapping.
PTATY
Pointer analysis type list.
@ Cxt_DDA
context sensitive DDA
@ CFLFICI_WPA
Flow-, context-, insensitive CFL-reachability-based analysis.
@ VFS_WPA
Versioned sparse flow-sensitive WPA.
@ FSCS_WPA
Flow-, context- sensitive WPA.
@ FSDATAFLOW_WPA
Traditional Dataflow-based flow sensitive WPA.
@ AndersenSCD_WPA
Selective cycle detection andersen-style WPA.
@ Andersen_BASE
Base Andersen PTA.
@ FlowS_DDA
Flow sensitive DDA.
@ Andersen_WPA
Andersen PTA.
@ CFLFSCS_WPA
Flow-, context-, CFL-reachability-based analysis.
@ FieldS_DDA
Field sensitive DDA.
@ AndersenWaveDiff_WPA
Diff wave propagation andersen-style WPA.
@ TypeCPP_WPA
Type-based analysis for C++.
@ AndersenSFR_WPA
Stride-based field representation.
@ Steensgaard_WPA
Steensgaard PTA.
@ FSSPARSE_WPA
Sparse flow sensitive WPA.
bool isFieldInsensitive(NodeID id) const
virtual void finalize()
Finalization of a pointer analysis, including checking alias correctness.
virtual void dumpPts(NodeID ptr, const PointsTo &pts)
bool print_stat
User input flags.
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
bool containBlackHoleNode(const PointsTo &pts)
Determine whether a points-to contains a black hole or constant node.
PTAImplTy ptaImplTy
PTA implementation type.
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
virtual void resolveIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve indirect call edges.
virtual void resolveCPPIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve cpp indirect call edges.
@ BVDataImpl
Represents BVDataPTAImpl.
void setObjFieldInsensitive(NodeID id)
PTACallGraph * callgraph
Call graph used for pointer analysis.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
PTATY ptaTy
Pointer analysis Type.
bool empty() const
Returns true if set is empty.
const_iterator end() const
void set(u32_t n)
Inserts n in the set.
NodeBS toNodeBS() const
Returns this points-to set as a NodeBS.
const_iterator begin() const
bool intersects(const PointsTo &rhs) const
Returns true if this set and rhs share any elements.
NodeID getId() const
Get ID.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
const MemObj * getObject(NodeID id) const
std::pair< NodeID, APOffset > NodeOffset
NodeID addGepObjNode(const MemObj *obj, const APOffset &apOffset, const NodeID gepId)
Add a field obj node, this method can only invoked by getGepObjVar.
MemObjToFieldsMap & getMemToFieldsMap()
Return memToFieldsMap.
NodeBS & getAllFieldsObjVars(const MemObj *obj)
Get all fields of an object.
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Map< NodeID, NodeBS > MemObjToFieldsMap
NodeOffsetMap & getGepObjNodeMap()
Return GepObjVarMap.
Map< NodeOffset, NodeID > NodeOffsetMap
const std::string & getModuleIdentifier() const
bool test(unsigned Idx) const
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
std::ostream & outs()
Overwrite llvm::outs()
OrderedSet< NodeID > OrderedNodeSet