42 assert(dchg !=
nullptr &&
"FSTBHC: DCHGraph required!");
66 assert(cloneObj &&
"FSTBHC: clone does not exist in PAG?");
68 assert(cloneObj &&
"FSTBHC: original object does not exist in PAG?");
71 if (SVFUtil::isa<CloneGepObjPN>(cloneObj) || SVFUtil::isa<GepObjPN>(originalObj))
75 for (
NodeID r : retrievers)
80 else if (SVFUtil::isa<CloneFIObjPN>(cloneObj) || SVFUtil::isa<CloneDummyObjPN>(cloneObj))
86 assert(
false &&
"FSTBHC: unexpected object type?");
109 bool isStore =
false;
110 const DIType *tildet =
nullptr;
112 if (
const StoreSVFGNode *store = SVFUtil::dyn_cast<StoreSVFGNode>(src))
116 storePts =
getPts(store->getPAGDstNodeID());
122 if (!filterSet.test(o))
124 edgePtsAndClones.set(o);
131 if (!filterSet.test(c))
133 edgePtsAndClones.set(c);
138 if (storePts.test(c) && !filterSet.test(c))
140 edgePtsAndClones.set(c);
152 if (!isStore || gepType ||
isBase(tildet, gepType))
154 if (!filterSet.test(g))
156 edgePtsAndClones.set(g);
163 for (
NodeID o : edgePtsAndClones)
172 for (
NodeID f : allFields)
186 bool changed =
false;
194 if (!ap->getParam()->isPointer())
return false;
199 if (!fp->getRet()->isPointer())
return false;
258 changed =
addPts(dstID, c) || changed;
272 bool changed =
false;
280 changed =
init(gep->
getId(), q, tildet, reuse,
true);
293 if (filterSet.test(oq))
continue;
301 if (SVFUtil::isa<VariantGepPE>(gep->
getPAGEdge()))
306 if (t && (t->getTag() == dwarf::DW_TAG_array_type || t->getTag() == dwarf::DW_TAG_pointer_type))
309 for (
NodeID fc : fieldClones)
321 if (baseType ==
nullptr)
325 tmpDstPts.set(fiObj);
329 if (
DCHGraph::isAgg(baseType) && baseType->getTag() != dwarf::DW_TAG_array_type
345 for (
NodeID fc : fieldClones)
354 assert(
false &&
"FSTBHC: new gep edge?");
370 bool changed =
false;
392 if (filterSet.test(s))
continue;
397 for (
NodeID ptd : srcOriginalObjs)
408 for (
NodeID f : allFields)
425 bool changed =
false;
460 if (filterSet.test(ptd))
continue;
507 if (copy->
getInst() ==
nullptr)
return nullptr;
511 if (mdNode ==
nullptr)
return nullptr;
514 assert(type !=
nullptr &&
"TBHC: bad ctir.vt.init metadata");
521 bool changed =
false;
522 if (vtInitType !=
nullptr)
581 if (
const StmtSVFGNode *gep = SVFUtil::dyn_cast<GepSVFGNode>(svfgNode))
587 for (
const SVFGEdge *e : gep->getOutEdges())
592 if (gep == dst)
continue;
594 if (!SVFUtil::isa<LoadSVFGNode>(dst))
618 if (
const StmtSVFGNode *stmt = SVFUtil::dyn_cast<StmtSVFGNode>(s))
620 const Value *v = stmt->getInst() ? stmt->getInst() : stmt->getPAGEdge()->getValue();
632 if (
const StmtSVFGNode *stmt = SVFUtil::dyn_cast<StmtSVFGNode>(s))
634 const Value *v = stmt->getInst();
653 o = gepObj->getBaseNode();
661 for (std::pair<NodeID, NodeID> locP : cmp)
665 PointsTo &ptsFiltered = filteredPts[locP];
669 if (filterSet.test(o))
continue;
674 for (std::pair<NodeID, NodeID> locPA : cmp)
676 const PointsTo &aPts = filteredPts[locPA];
677 for (std::pair<NodeID, NodeID> locPB : cmp)
679 if (locPB == locPA)
continue;
680 const PointsTo &bPts = filteredPts[locPB];
682 switch (
alias(aPts, bPts))
691 assert(
"Not May/NoAlias?");
virtual void finalize() override
Finalize analysis.
unsigned getNumFields(const DIType *base)
iterator begin()
Iterators.
virtual bool propagateFromAPToFP(const ActualParmSVFGNode *ap, const SVFGNode *dst)
const std::string vtInitMDName
virtual void pushIntoWorklist(NodeID id)
NodeID getPAGDstNodeID() const
double loadTime
time of load edges
virtual bool processPhi(const PHISVFGNode *phi) override
const Instruction * getInst() const
double addrTime
time of handling address edges
virtual bool processCopy(const CopySVFGNode *copy)
SVFG * buildFullSVFG(BVDataPTAImpl *pta)
const NodeBS & getGepObjs(NodeID base)
virtual const NodeBS & getAllFieldsObjNode(NodeID id) override
bool isNonPointerObj(NodeID id) const
bool isStrongUpdate(const SVFGNode *node, NodeID &singleton)
Return TRUE if this is a strong update STORE statement.
bool storeReuse
Whether to allow for reuse at stores.
void setType(NodeID o, const DIType *t)
Sets the type (in objToType) of o.
virtual bool processCopy(const CopySVFGNode *copy) override
void determineWhichGepsAreLoads(void)
bool isBlkObjOrConstantObj(NodeID o) const
virtual void analyze()
Flow sensitive analysis.
virtual void initialize() override
Initialize analysis.
virtual void finalize()
Finalize analysis.
SVFModule * svfMod
Module.
virtual bool unionPts(NodeID id, const PointsTo &target)
virtual bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
const PAGEdge * getPAGEdge() const
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
bool isPTAEdge() const
Whether src and dst nodes are both of pointer type.
virtual bool propAlongDirectEdge(const DirectSVFGEdge *edge) override
Propagate points-to information along a DIRECT SVFG edge.
virtual void expandFIObjs(const PointsTo &pts, PointsTo &expandedPts) override
Expand FI objects.
friend class FlowSensitiveStat
static const DIType * undefType
The undefined type (•); void.
virtual void backPropagate(NodeID clone) override
virtual bool weakUpdateOutFromIn(const SVFGNode *node)
Handle weak updates.
NodeBS loadGeps
Maps whether a (SVFG) GEP node is a load or not.
bool isConstantObj(NodeID id) const
virtual bool processLoad(const LoadSVFGNode *load) override
virtual bool processStore(const StoreSVFGNode *store) override
static const llvm::cl::opt< bool > TBHCStoreReuse
Whether we allow reuse for TBHC.
static bool isAgg(const DIType *t)
virtual bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates)=0
For each variable var in IN at loc, do updateDFOutFromIn(loc, var, loc, var).
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
bool gepIsLoad(NodeID gep)
IDToNodeMapTy::iterator iterator
Node Iterators.
static const llvm::cl::opt< bool > TBHCAllReuse
virtual bool propAlongIndirectEdge(const IndirectSVFGEdge *edge) override
Propagate points-to information along an INDIRECT SVFG edge.
void setPAG(PAG *pag)
PAG must be set by extending class once the PAG is available.
NodeType * getDstNode() const
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
virtual bool addPts(NodeID id, NodeID ptd)
virtual void countAliases(Set< std::pair< NodeID, NodeID >> cmp, unsigned *mayAliases, unsigned *noAliases) override
Fills may/noAliases for the location/pointer pairs in cmp.
virtual bool processGep(const GepSVFGNode *gep) override
void setGraph(GraphType g)
virtual bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar)=0
Update points-to set of top-level pointers with IN[srcLoc:srcVar].
virtual bool processAddr(const AddrSVFGNode *addr)
virtual const PointsTo & getPts(NodeID id)
virtual void analyze() override
Flow sensitive analysis with FSTBHC.
llvm::Instruction Instruction
const DIType * getTypeFromCTirMetadata(const SVFGNode *)
void setObjFieldInsensitive(NodeID id)
void setDCHG(DCHGraph *dchg)
DCHG must be set by extending class once the DCHG is available.
virtual bool unionPtsFromIn(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar) override
void dumpStats(void)
Dump some statistics we tracked.
void validateTBHCTests(SVFModule *svfMod)
NodeID getPAGSrcNodeID() const
virtual bool processAddr(const AddrSVFGNode *addr) override
CommonCHGraph * getCHGraph() const
get CHGraph
static AndersenWaveDiff * createAndersenWaveDiff(PAG *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
const NodeBS & getGepObjsFromMemObj(const MemObj *memObj, unsigned offset)
const PointsTo & getPointsTo() const
PTAStat * stat
Statistics.
NodeID getAllocationSite(NodeID o) const
Returns the allocation site (from objToAllocation) of o. Asserts existence.
virtual bool propDFOutToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar) override
NodeType * getSrcNode() const
static const MDNode * getRawCTirMetadata(const Value *)
Returns raw ctir metadata of a Value. Returns null if it doesn't exist.
virtual bool updateATVPts(const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Update address-taken variables OUT[dstLoc:dstVar] with points-to of top-level pointers.
bool isBase(const DIType *a, const DIType *b) const
virtual bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc:dstVar], OUT[srcLoc:srcVar]).
double directPropaTime
time of points-to propagation of address-taken objects
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
bool isHeapMemObj(NodeID id) const
Whether this object is heap or array.
void setAllocationSite(NodeID o, NodeID site)
Sets the allocation site (in objToAllocation) of o.
virtual bool processPhi(const PHISVFGNode *phi)
virtual bool unionPtsFromTop(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar) override
const DIType * getCanonicalType(const DIType *t)
virtual bool propDFInToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar) override
bool isPTANode() const
Whether this phi node is of pointer type (used for pointer analysis).
static const MDNode * getRawCTirMetadata(const SVFGNode *)
static double getClk(bool mark=false)
bool isFIObjNode(NodeID id) const
NodeID getId() const
Get ID.
llvm::SparseBitVector NodeBS
FlowSensitiveTBHC(PAG *_pag, PTATY type=FSTBHC_WPA)
Constructor.
const NodeBS & getClones(NodeID o)
Returns all the clones of o.
Map< NodeID, NodeBS > gepToSVFGRetrievers
Maps GEP objects to the SVFG nodes that retrieved them with getGepObjClones.
PointsTo & getFilterSet(NodeID loc)
Returns the filter set of a location. Not const; could create empty PointsTo.
virtual bool updateInFromOut(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar) override
virtual bool updateAllDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc::dstVar], IN[srcLoc:srcVar]. There is no flag check, unlike the above.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual bool updateAllDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar)=0
Union (IN[dstLoc::dstVar], OUT[srcLoc:srcVar]. There is no flag check, unlike the above...
virtual bool propVarPtsFromSrcToDst(NodeID var, const SVFGNode *src, const SVFGNode *dst)
Propagate points-to information of a certain variable from src to dst.
const DIType * getTypeFromCTirMetadata(const Value *)
PTATY
Pointer analysis type list.
double storeTime
time of store edges
static const DIType * getVTInitType(const CopySVFGNode *copy, DCHGraph *dchg)
bool print_stat
User input flags.
const NodeBS getGepObjClones(NodeID base, unsigned offset)
double gepTime
time of handling gep edges
virtual bool strongUpdateOutFromIn(const SVFGNode *node, NodeID singleton)
Handle strong updates.
bool init(NodeID loc, NodeID p, const DIType *tildet, bool reuse, bool gep=false)
NodeID getOriginalObj(NodeID c) const
Returns the original object c is cloned from. If c is not a clone, returns itself.
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and PAG etc.
virtual bool updateInFromIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar) override
DFPTDataTy * getDFPTDataTy() const
double updateTime
time of strong/weak updates.
virtual AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
Interface expose to users of our pointer analysis, given Location infos.
virtual bool propagateFromFRToAR(const FormalRetSVFGNode *fr, const SVFGNode *dst)