106 &&
"TBHC: original object not set for clone?");
122 assert(baseNode &&
"TBHC: given bad base node?");
124 assert(baseObj &&
"TBHC: non-object given for base?");
149 assert(node &&
"TBHC: base object node does not exist.");
151 assert(baseNode &&
"TBHC: base \"object\" node is not an object.");
155 unsigned totalOffset = offset;
156 if (
const GepObjPN *baseGep = SVFUtil::dyn_cast<GepObjPN>(baseNode))
158 totalOffset += baseGep->getLocationSet().getOffset();
166 if (offset == 0 && baseType->getTag() != dwarf::DW_TAG_array_type)
183 for (
NodeID gep : gepObjs)
186 assert(node &&
"TBHC: expected gep node doesn't exist.");
187 assert((SVFUtil::isa<GepObjPN>(node) || SVFUtil::isa<FIObjPN>(node))
188 &&
"TBHC: expected a GEP or FI object.");
190 if (
GepObjPN *gepNode = SVFUtil::dyn_cast<GepObjPN>(node))
192 if (gepNode->getLocationSet().getOffset() == totalOffset)
230 gep->setBaseNode(base);
234 const DIType *newGepType =
nullptr;
235 if (baseType->getTag() == dwarf::DW_TAG_array_type || baseType->getTag() == dwarf::DW_TAG_pointer_type)
237 if (
const DICompositeType *arrayType = SVFUtil::dyn_cast<DICompositeType>(baseType))
240 newGepType = arrayType->getBaseType();
242 else if (
const DIDerivedType *ptrType = SVFUtil::dyn_cast<DIDerivedType>(baseType))
245 newGepType = ptrType->getBaseType();
247 assert(newGepType &&
"TBHC: newGepType is neither DIComposite nor DIDerived");
274 bool changed =
false;
284 if (filterSet.test(o))
continue;
287 assert(obj &&
"TBHC: pointee object does not exist in PAG?");
293 bool fieldInsensitive =
false;
294 std::vector<const DIType *> fieldTypes;
297 fieldInsensitive = obj->getMemObj()->isFieldInsensitive();
298 if (tp !=
nullptr && (tp->getTag() == dwarf::DW_TAG_structure_type
299 || tp->getTag() == dwarf::DW_TAG_class_type))
314 assert(!
isGep(obj) &&
"TBHC: GEP object is untyped!");
319 else if (fieldInsensitive && tp &&
dchg->
isFieldOf(tildet, tp))
326 else if (gep && aggs.find(tildet) != aggs.end())
339 else if (
isBase(tp, tildet) && tp != tildet
354 else if (
isBase(tildet, tp))
361 else if (tildet != tp && reuse)
386 if (gep && aggs.find(tildet) != aggs.end())
415 if (
const GepObjPN *gepObj = SVFUtil::dyn_cast<GepObjPN>(obj))
419 for (
NodeID clone : clones)
430 addGepToObj(clone, gepObj->getBaseNode(), gepObj->getLocationSet().getOffset());
441 else if (SVFUtil::isa<FIObjPN>(obj) || SVFUtil::isa<DummyObjPN>(obj))
446 for (
NodeID clone : clones)
454 if (
const FIObjPN *fiObj = SVFUtil::dyn_cast<FIObjPN>(obj))
471 assert(
false &&
"FSTBHC: trying to clone unhandled object");
485 assert(v !=
nullptr &&
"TBHC: trying to get metadata from nullptr!");
487 const MDNode *mdNode =
nullptr;
488 if (
const Instruction *inst = SVFUtil::dyn_cast<Instruction>(v))
492 else if (
const GlobalObject *go = SVFUtil::dyn_cast<GlobalObject>(v))
521 assert(v !=
nullptr &&
"TBHC: trying to get type from nullptr!");
524 if (mdNode ==
nullptr)
541 assert(n !=
nullptr &&
"TBHC: testing if null is a GEP object!");
542 return SVFUtil::isa<GepObjPN>(n);
580 const StoreInst *ps =
nullptr, *qs =
nullptr;
588 if (
const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
590 std::string calledFnName = ci->getCalledFunction()->getName().str();
594 assert(si &&
"TBHC: validation macro not producing stores?");
601 currInst = currInst->getNextNonDebugInstruction();
603 while (currInst !=
nullptr);
606 while (currInst !=
nullptr)
611 currInst = currInst->getNextNonDebugInstruction();
613 if (
const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
615 std::string calledFnName = ci->getCalledFunction()->getName().str();
619 assert(si &&
"TBHC: validation macro not producing stores?");
626 assert(ps !=
nullptr && qs !=
nullptr &&
"TBHC: malformed alias test?");
633 PointsTo pPtsFiltered, qPtsFiltered;
651 assert(bvpta &&
"TBHC: need a BVDataPTAImpl for TBHC alias testing.");
655 std::string testName =
"";
659 passed = res == llvm::MayAlias || res == llvm::MustAlias;
665 passed = res == llvm::NoAlias;
671 passed = res == llvm::MustAlias || res == llvm::MayAlias;
677 passed = res == llvm::MayAlias || res == llvm::PartialAlias;
683 passed = res != llvm::MayAlias && res != llvm::MustAlias && res != llvm::PartialAlias;
689 passed = res != llvm::NoAlias;
697 <<
" check <id:" << p <<
", id:" << q <<
"> " 700 assert(
false &&
"test case failed!");
702 if (pPtsFiltered.empty())
705 <<
" : pts(" << p <<
") is empty\n";
708 if (qPtsFiltered.empty())
711 <<
" : pts(" << q <<
") is empty\n";
717 <<
" : MUSTALIAS tests are actually MAYALIAS tests\n";
723 <<
" : PARTIALALIAS tests are actually MAYALIAS tests\n";
738 SVFUtil::outs() << indent <<
"=== Original objects to clones ===\n";
740 unsigned totalClones = 0;
745 if (clones.count() == 0)
continue;
747 totalClones += clones.count();
750 <<
"(" << clones.count() <<
")" 773 <<
" (" << totalClones <<
" clones)\n";
774 SVFUtil::outs() << indent <<
"==================================\n";
void setOriginalObj(NodeID c, NodeID o)
static bool isAliasTestFunction(std::string name)
Returns true if the function name matches MAYALIAS, NOALIAS, etc.
static std::string diTypeToStr(const DIType *)
Returns a human-readable version of the DIType.
const std::vector< const DIType * > & getFieldTypes(const DIType *base)
Returns a vector of the types of all fields in base.
virtual void clearFullPts(NodeID id)
Clear points-to set of id.
llvm::StoreInst StoreInst
NodeID getValueNode(const Value *V)
Get PAG Node according to LLVM value.
virtual void backPropagate(NodeID clone)=0
static const std::string derefFnName
deref function for TBHC alias tests.
bool isBlkObjOrConstantObj(NodeID id) const
const MemObj * getMemObj() const
Return memory object.
llvm::raw_ostream raw_ostream
LLVM outputs.
static const std::string aliasTestFailMayAliasMangled
TypeBasedHeapCloning(BVDataPTAImpl *pta)
Constructor. pta is the pointer analysis using this object (i.e. that which is extending).
static const std::string aliasTestNoAlias
const NodeBS & getGepObjs(NodeID base)
Map< NodeID, const DIType * > objToType
Object -> its type.
void setBaseNode(NodeID base)
Set the base object from which this GEP node came from.
Map< NodeID, PointsTo > locToFilterSet
Maps nodes (a location like a PAG node or SVFG node) to their filter set.
raw_ostream & errs()
Overwrite llvm::errs()
void setType(NodeID o, const DIType *t)
Sets the type (in objToType) of o.
Map< NodeID, NodeBS > objToGeps
Maps objects to the GEP nodes beneath them.
NodeID addCloneFIObjNode(const MemObj *mem)
Add clone FI object node to PAG.
bool isBlkObjOrConstantObj(NodeID o) const
void setFldIdx(Size_t idx)
NodeID addObjNode(const Value *val, NodeID i)
Add a memory obj node.
bool isFieldInsensitive() const
Return true if its field limit is 0.
NodeID addCloneGepObjNode(const MemObj *mem, const LocationSet &l)
Add clone GEP object node to PAG.
CallBase * getInstruction() const
std::string getSourceLoc(const Value *val)
Return source code including line number and file name from debug information.
virtual bool unionPts(NodeID id, const PointsTo &target)
llvm::DICompositeType DICompositeType
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
Size_t getFieldObjNodeNum() const
std::string sucMsg(std::string msg)
Returns successful message by converting a string into green string output.
static std::string indent(size_t n)
llvm::GlobalObject GlobalObject
const Set< const DIType * > & getAggs(const DIType *base)
Returns all the aggregates contained (transitively) in base.
u32_t getModuleNum() const
static const DIType * undefType
The undefined type (•); void.
const std::string derefMDName
BVDataPTAImpl * pta
PTA extending this class.
Map< NodeID, NodeID > objToAllocation
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
static bool isAgg(const DIType *t)
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
static const std::string aliasTestMayAliasMangled
const NodeBS getObjsWithClones(void)
Returns objects that have clones (any key in objToClones).
static const std::string aliasTestFailNoAlias
void setPAG(PAG *pag)
PAG must be set by extending class once the PAG is available.
const Value * getRefVal() const
Get the reference value to this object.
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
virtual const PointsTo & getPts(NodeID id)
llvm::Instruction Instruction
NodeID getGepObjNode(const MemObj *obj, const LocationSet &ls)
Get a field PAG Object node according to base mem obj and offset.
llvm::DIDerivedType DIDerivedType
virtual bool isFieldOf(const DIType *f, const DIType *b)
Returns true if f is a field of b (fields from getFieldTypes).
static const std::string mangledDerefFnName
deref function (mangled) for TBHC alias tests.
NodeID cloneObject(NodeID o, const DIType *type, bool reuse)
void setDCHG(DCHGraph *dchg)
DCHG must be set by extending class once the DCHG is available.
void dumpStats(void)
Dump some statistics we tracked.
void validateTBHCTests(SVFModule *svfMod)
static const std::string aliasTestMustAliasMangled
static const std::string aliasTestNoAliasMangled
Set< const CallBlockNode * > CallSiteSet
Size_t getObjectNodeNum() const
static const std::string aliasTestMayAlias
const NodeBS & getGepObjsFromMemObj(const MemObj *memObj, unsigned offset)
static const std::string aliasTestMustAlias
NodeID getAllocationSite(NodeID o) const
Returns the allocation site (from objToAllocation) of o. Asserts existence.
static const MDNode * getRawCTirMetadata(const Value *)
Returns raw ctir metadata of a Value. Returns null if it doesn't exist.
raw_ostream & outs()
Overwrite llvm::outs()
static const std::string aliasTestPartialAlias
bool isBase(const DIType *a, const DIType *b) const
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.
Function * getCalledFunction() const
void setAllocationSite(NodeID o, NodeID site)
Sets the allocation site (in objToAllocation) of o.
const DIType * getFieldType(const DIType *base, unsigned idx)
Returns the type of field number idx (flattened) in base.
const DIType * getCanonicalType(const DIType *t)
virtual bool isBase(const DIType *a, const DIType *b, bool firstField)
static LLVMModuleSet * getLLVMModuleSet()
CallSite getLLVMCallSite(const Instruction *inst)
Return LLVM callsite given a instruction.
static const std::string aliasTestFailNoAliasMangled
Map< NodeID, NodeID > cloneToOriginalObj
(Clone) object -> original object (opposite of objToclones).
static NodeIDAllocator * get(void)
Return (singleton) allocator.
bool isClone(NodeID o) const
Returns true if o is a clone.
llvm::SparseBitVector NodeBS
const NodeBS & getClones(NodeID o)
Returns all the clones of o.
PointsTo & getFilterSet(NodeID loc)
Returns the filter set of a location. Not const; could create empty PointsTo.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isGep(const PAGNode *n) const
Test whether object is a GEP object. For convenience.
NodeID addCloneDummyObjNode(const MemObj *mem)
Add clone dummy object node to PAG.
const DIType * getTypeFromCTirMetadata(const Value *)
static const std::string aliasTestPartialAliasMangled
Map< NodeID, NodeBS > objToClones
(Original) object -> set of its clones.
std::string wrnMsg(std::string msg)
Returns warning message by converting a string into yellow string output.
const NodeBS getGepObjClones(NodeID base, unsigned offset)
Map< const MemObj *, Map< unsigned, NodeBS > > memObjToGeps
Maps memory objects to their GEP objects. (memobj -> (fieldidx -> geps))
void addClone(NodeID o, NodeID c)
Add a clone c to object o.
bool init(NodeID loc, NodeID p, const DIType *tildet, bool reuse, bool gep=false)
std::string errMsg(std::string msg)
Print error message by converting a string into red string output.
bool isFirstField(const DIType *f, const DIType *b)
virtual const std::string PTAName() const
Return PTA name.
const CallSiteSet & getCallSiteSet() const
NodeID getOriginalObj(NodeID c) const
Returns the original object c is cloned from. If c is not a clone, returns itself.
static const std::string aliasTestFailMayAlias
virtual AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
Interface expose to users of our pointer analysis, given Location infos.
void addGepToObj(NodeID gep, NodeID base, unsigned offset)
Associates gep with base (through objToGeps and memObjToGeps).
llvm::AliasResult AliasResult