Skip to content

Commit

Permalink
Merge pull request #1295 from jumormt/opaque
Browse files Browse the repository at this point in the history
remove some opaque pointer dependencies
  • Loading branch information
yuleisui committed Dec 22, 2023
2 parents 6cc6277 + 5034678 commit dee5caa
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 15 deletions.
1 change: 1 addition & 0 deletions svf-llvm/include/SVF-LLVM/BasicTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ typedef llvm::VAStartInst VAStartInst;
typedef llvm::BinaryOperator BinaryOperator;
typedef llvm::UnaryOperator UnaryOperator;
typedef llvm::UndefValue UndefValue;
typedef llvm::GEPOperator GEPOperator;

// Related to Switch Case
typedef std::pair<const BasicBlock*, const ConstantInt*> SuccBBAndCondValPair;
Expand Down
6 changes: 6 additions & 0 deletions svf-llvm/include/SVF-LLVM/LLVMUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ static inline Type* getPtrElementType(const PointerType* pty)
#endif
}

/// Infer type based on llvm value, this is for the migration to opaque pointer
/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions
Type *getPointeeType(const Value *value);

/// Get the reference type of heap/static object from an allocation site.
//@{
inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallBase* cs)
Expand All @@ -139,6 +143,7 @@ inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallBase* cs)
int argPos = SVFUtil::getHeapAllocHoldingArgPosition(svfcs);
const Value* arg = cs->getArgOperand(argPos);
if (const PointerType *argType = SVFUtil::dyn_cast<PointerType>(arg->getType()))
// TODO: getPtrElementType need type inference
refType = SVFUtil::dyn_cast<PointerType>(getPtrElementType(argType));
}
// Case 2: heap object held by return value.
Expand Down Expand Up @@ -389,6 +394,7 @@ inline u32_t SVFType2ByteSize(const SVFType* type)
const llvm::Type* llvm_rhs = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(type);
const llvm::PointerType* llvm_rhs_ptr = SVFUtil::dyn_cast<PointerType>(llvm_rhs);
assert(llvm_rhs_ptr && "not a pointer type?");
// TODO: getPtrElementType need type inference
const Type *ptrElementType = getPtrElementType(llvm_rhs_ptr);
u32_t llvm_rhs_size = LLVMUtil::getTypeSizeInBytes(ptrElementType);
u32_t llvm_elem_size = -1;
Expand Down
1 change: 1 addition & 0 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,7 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
//cast svftype to SVFPointerType
SVFPointerType* svfPtrType = SVFUtil::dyn_cast<SVFPointerType>(svftype);
assert(svfPtrType && "this is not SVFPointerType");
// TODO: getPtrElementType to be removed
svfPtrType->setPtrElementType(getSVFType(LLVMUtil::getPtrElementType(pt)));
}

Expand Down
50 changes: 50 additions & 0 deletions svf-llvm/lib/LLVMUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,51 @@ const Value* LLVMUtil::stripConstantCasts(const Value* val)
return val;
}

/// Infer type based on llvm value, this is for the migration to opaque pointer
/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions
Type *LLVMUtil::getPointeeType(const Value *value) {
assert(value && "value cannot be nullptr!");
if (const LoadInst *loadInst = SVFUtil::dyn_cast<LoadInst>(value)) {
// get the pointee type of rhs based on lhs
// e.g., for `%lhs = load i64, ptr %rhs`, we return i64
return loadInst->getType();
} else if (const StoreInst *storeInst = SVFUtil::dyn_cast<StoreInst>(value)) {
// get the pointee type of op1 based on op0
// e.g., for `store i64 %op0, ptr %op1`, we return i64
return storeInst->getValueOperand()->getType();
} else if (const GetElementPtrInst *gepInst = SVFUtil::dyn_cast<GetElementPtrInst>(value)) {
// get the source element type of a gep instruction
// e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo
return gepInst->getSourceElementType();
} else if (const GEPOperator* gepOperator = SVFUtil::dyn_cast<GEPOperator>(value)) {
// get the source element type of a gep instruction
// e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo
return gepOperator->getSourceElementType();
} else if (const CallInst *callInst = SVFUtil::dyn_cast<CallInst>(value)) {
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return callInst->getFunctionType();
} else if (const CallBase *callBase = SVFUtil::dyn_cast<CallBase>(value)) {
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return callBase->getFunctionType();
} else if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(value)) {
// get the type of the allocated memory
// e.g., for `%retval = alloca i64, align 4`, we return i64
return allocaInst->getAllocatedType();
} else if (const GlobalVariable *globalVar = SVFUtil::dyn_cast<GlobalVariable>(value)) {
// get the pointee type of the global pointer
return globalVar->getValueType();
} else if (const Function* func = SVFUtil::dyn_cast<Function>(value)) {
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return func->getFunctionType();
} else {
assert(false && (LLVMUtil::dumpValue(value) + "Unknown llvm Type, cannot get Ptr Element Type").c_str());
abort();
}
}

void LLVMUtil::viewCFG(const Function* fun)
{
if (fun != nullptr)
Expand Down Expand Up @@ -351,6 +396,7 @@ const Value* LLVMUtil::getFirstUseViaCastInst(const Value* val)
const PointerType * type = SVFUtil::dyn_cast<PointerType>(val->getType());
assert(type && "this value should be a pointer type!");
/// If type is void* (i8*) and val is immediately used at a bitcast instruction
// TODO: getPtrElementType to be removed
if (IntegerType *IT = SVFUtil::dyn_cast<IntegerType>(getPtrElementType(type)))
{
if (IT->getBitWidth() == 8)
Expand Down Expand Up @@ -397,6 +443,7 @@ const Type* LLVMUtil::getTypeOfHeapAlloc(const Instruction *inst)
}

assert(type && "not a pointer type?");
// TODO: getPtrElementType need type inference
return getPtrElementType(type);
}

Expand Down Expand Up @@ -922,6 +969,7 @@ bool LLVMUtil::isLoadVtblInst(const LoadInst* loadInst)
const Type* elemTy = valTy;
for (u32_t i = 0; i < 3; ++i)
{
// TODO: getPtrElementType to be removed
if (const PointerType* ptrTy = SVFUtil::dyn_cast<PointerType>(elemTy))
elemTy = LLVMUtil::getPtrElementType(ptrTy);
else
Expand All @@ -933,6 +981,7 @@ bool LLVMUtil::isLoadVtblInst(const LoadInst* loadInst)
std::string className = "";
if(const PointerType* ptrTy = SVFUtil::dyn_cast<PointerType>(paramty))
{
// TODO: getPtrElementType need type inference
if(const StructType* st = SVFUtil::dyn_cast<StructType>(getPtrElementType(ptrTy)))
className = LLVMUtil::getClassNameFromType(st);
}
Expand Down Expand Up @@ -1198,6 +1247,7 @@ std::string LLVMUtil::getClassNameOfThisPtr(const CallBase* inst)
{
const Value* thisPtr = LLVMUtil::getVCallThisPtr(inst);
if(const PointerType* ptrTy = SVFUtil::dyn_cast<PointerType>(thisPtr->getType()))
// TODO: getPtrElementType need type inference
if(const StructType* st = SVFUtil::dyn_cast<StructType>(getPtrElementType(ptrTy)))
thisPtrClassName = getClassNameFromType(st);
}
Expand Down
3 changes: 2 additions & 1 deletion svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,9 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
// If it's a non-constant offset access
// If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
// If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
if(!op && gepTy->isPointerTy() && getPtrElementType(SVFUtil::dyn_cast<PointerType>(gepTy))->isSingleValueType())
if(!op && gepTy->isPointerTy() && LLVMUtil::getPointeeType(V)->isSingleValueType()) {
isConst = false;
}

// The actual index
//s32_t idx = op->getSExtValue();
Expand Down
5 changes: 4 additions & 1 deletion svf-llvm/lib/SymbolTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ void SymbolTableBuilder::collectSVFTypeInfo(const Value* val)
(void)getOrAddSVFTypeInfo(val->getType());
if (const PointerType * ptrType = SVFUtil::dyn_cast<PointerType>(val->getType()))
{
// TODO: getPtrElementType to be removed
const Type* objtype = LLVMUtil::getPtrElementType(ptrType);
(void)getOrAddSVFTypeInfo(objtype);
}
Expand Down Expand Up @@ -575,6 +576,7 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant* C)
*/
ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val)
{
/// TODO: getPtrElementType to be removed
const PointerType* refTy = nullptr;

const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
Expand Down Expand Up @@ -627,7 +629,8 @@ void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val)

const PointerType* refty = SVFUtil::dyn_cast<PointerType>(val->getType());
assert(refty && "this value should be a pointer type!");
Type* elemTy = getPtrElementType(refty);
// TODO: getPtrElementType need type inference
Type *elemTy = getPtrElementType(refty);
bool isPtrObj = false;
// Find the inter nested array element
while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
Expand Down
4 changes: 2 additions & 2 deletions svf/include/MemoryModel/AccessPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class AccessPath
AccessPath(const AccessPath& ap)
: fldIdx(ap.fldIdx),
idxOperandPairs(ap.getIdxOperandPairVec()),
gepPointeeType(ap.getGepPointeeType())
gepPointeeType(ap.gepSrcPointeeType())
{
}

Expand Down Expand Up @@ -109,7 +109,7 @@ class AccessPath
{
return idxOperandPairs;
}
inline const SVFType* getGepPointeeType() const
inline const SVFType* gepSrcPointeeType() const
{
return gepPointeeType;
}
Expand Down
4 changes: 2 additions & 2 deletions svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,9 @@ std::pair<s32_t, s32_t> SVFIR2ConsExeState::getGepOffset(const SVF::GepStmt *gep
continue;
}

if (const SVFPointerType *pty = SVFUtil::dyn_cast<SVFPointerType>(type))
if (SVFUtil::isa<SVFPointerType>(type))
{
offset = offset * gep->getAccessPath().getElementNum(pty->getPtrElementType());
offset = offset * gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType());
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ IntervalValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep)
u32_t elemByteSize = 1;
if (const SVFArrayType* arrOperandType = SVFUtil::dyn_cast<SVFArrayType>(idxOperandType))
elemByteSize = arrOperandType->getTypeOfElement()->getByteSize();
else if (const SVFPointerType* ptrOperandType = SVFUtil::dyn_cast<SVFPointerType>(idxOperandType))
elemByteSize = ptrOperandType->getPtrElementType()->getByteSize();
else if (SVFUtil::isa<SVFPointerType>(idxOperandType))
elemByteSize = gep->getAccessPath().gepSrcPointeeType()->getByteSize();
else
assert(false && "idxOperandType must be ArrType or PtrType");
if (const SVFConstantInt *op = SVFUtil::dyn_cast<SVFConstantInt>(idxOperandVar->getValue()))
Expand Down Expand Up @@ -364,9 +364,9 @@ IntervalValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep)
}
}
// for pointer type, flattened index = elemNum * idx
if (const SVFPointerType *pty = SVFUtil::dyn_cast<SVFPointerType>(type))
if (SVFUtil::isa<SVFPointerType>(type))
{
u32_t elemNum = gep->getAccessPath().getElementNum(pty->getPtrElementType());
u32_t elemNum = gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType());
idxLb = (double)Options::MaxFieldLimit() / elemNum < idxLb? Options::MaxFieldLimit(): idxLb * elemNum;
idxUb = (double)Options::MaxFieldLimit() / elemNum < idxUb? Options::MaxFieldLimit(): idxUb * elemNum;
}
Expand Down
11 changes: 6 additions & 5 deletions svf/lib/MemoryModel/AccessPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ u32_t AccessPath::getElementNum(const SVFType* type) const
else if (type->isSingleValueType())
{
/// This is a pointer arithmetic
// TODO: getPtrElementType to be removed
if(const SVFPointerType* pty = SVFUtil::dyn_cast<SVFPointerType>(type))
return getElementNum(pty->getPtrElementType());
else
Expand Down Expand Up @@ -122,11 +123,11 @@ APOffset AccessPath::computeConstantByteOffset() const
/// for (2) i = 1, arrType: [10 x i8], type2 = i8
type2 = arrType->getTypeOfElement();
}
else if (const SVFPointerType* ptrType = SVFUtil::dyn_cast<SVFPointerType>(type))
else if (SVFUtil::isa<SVFPointerType>(type))
{
/// for (1) i = 0, ptrType: %struct.DEST*, type2: %struct.DEST
/// for (2) i = 0, ptrType: [10 x i8]*, type2 = [10 x i8]
type2 = ptrType->getPtrElementType();
type2 = gepSrcPointeeType();
}

const SVFConstantInt* op = SVFUtil::dyn_cast<SVFConstantInt>(value);
Expand Down Expand Up @@ -227,8 +228,8 @@ APOffset AccessPath::computeConstantOffset() const
continue;
}

if(const SVFPointerType* pty = SVFUtil::dyn_cast<SVFPointerType>(type))
totalConstOffset += op->getSExtValue() * getElementNum(pty->getPtrElementType());
if(SVFUtil::isa<SVFPointerType>(type))
totalConstOffset += op->getSExtValue() * getElementNum(gepPointeeType);
else
{
APOffset offset = op->getSExtValue();
Expand Down Expand Up @@ -268,7 +269,7 @@ NodeBS AccessPath::computeAllLocations() const

AccessPath AccessPath::operator+(const AccessPath& rhs) const
{
assert(gepPointeeType == rhs.getGepPointeeType() && "source element type not match");
assert(gepPointeeType == rhs.gepSrcPointeeType() && "source element type not match");
AccessPath ap(rhs);
ap.fldIdx += getConstantStructFldIdx();
for (auto &p : ap.getIdxOperandPairVec())
Expand Down
1 change: 1 addition & 0 deletions svf/lib/MemoryModel/PointerAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ void PointerAnalysis::dumpAllTypes()

const SVFType* type = node->getValue()->getType();
pag->getSymbolInfo()->printFlattenFields(type);
// TODO: getPtrElementType to be removed
if (const SVFPointerType* ptType = SVFUtil::dyn_cast<SVFPointerType>(type))
pag->getSymbolInfo()->printFlattenFields(ptType->getPtrElementType());
}
Expand Down
1 change: 1 addition & 0 deletions svf/lib/SVFIR/SVFType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ std::ostream& operator<<(std::ostream& os, const SVFType& type)

void SVFPointerType::print(std::ostream& os) const
{
// TODO: getPtrElementType to be removed
os << *getPtrElementType() << '*';
}

Expand Down
1 change: 1 addition & 0 deletions svf/lib/SVFIR/SymbolTableInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ void SymbolTableInfo::printFlattenFields(const SVFType* type)
}
else if (const SVFPointerType* pt= SVFUtil::dyn_cast<SVFPointerType>(type))
{
// TODO: getPtrElementType to be removed
u32_t eSize = getNumOfFlattenElements(pt->getPtrElementType());
outs() << " {Type: " << *pt << "}\n"
<< "\t [target size = " << eSize << "]\n"
Expand Down

0 comments on commit dee5caa

Please sign in to comment.