From 74bc50f6ea09b779e55c17e9d267fdbe6700dc7e Mon Sep 17 00:00:00 2001 From: shuangxiang kan <18550887212@163.com> Date: Fri, 28 Jul 2023 12:56:40 +1000 Subject: [PATCH] Code Simplification --- CMakeLists.txt | 15 +-- svf-llvm/include/SVF-LLVM/LLVMUtil.h | 127 +++-------------------- svf-llvm/include/SVF-LLVM/SVFIRBuilder.h | 2 +- svf-llvm/lib/LLVMModule.cpp | 47 +++------ svf-llvm/lib/LLVMUtil.cpp | 95 +++++++++++++++++ 5 files changed, 123 insertions(+), 163 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89ae384a4..808945309 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,17 +89,8 @@ install( PATTERN "**/*.h") # Compile extapi.c to extapi.bc -string(REGEX REPLACE "/lib/cmake/llvm$" "" LLVM_DIR "${LLVM_DIR}") -add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/include/Util/extapi.bc - COMMAND ${LLVM_DIR}/bin/clang -w -S -c -Xclang -disable-O0-optnone -fno-discard-value-names -emit-llvm ${PROJECT_SOURCE_DIR}/svf/lib/Util/extapi.c -o ${PROJECT_BINARY_DIR}/include/Util/extapi.bc +find_path(LLVM_CLANG_DIR NAMES clang PATH_SUFFIXES bin) +add_custom_target(extapi_ir ALL + COMMAND ${LLVM_CLANG_DIR}/clang -w -S -c -Xclang -disable-O0-optnone -fno-discard-value-names -emit-llvm ${PROJECT_SOURCE_DIR}/svf/lib/Util/extapi.c -o ${PROJECT_BINARY_DIR}/include/Util/extapi.bc DEPENDS ${PROJECT_SOURCE_DIR}/svf/lib/Util/extapi.c -) - -add_custom_target(extapi_ir ALL DEPENDS ${PROJECT_BINARY_DIR}/include/Util/extapi.bc) - -install( - FILES ${PROJECT_BINARY_DIR}/include/Util/extapi.bc - COMPONENT devel - DESTINATION include/svf/Util ) \ No newline at end of file diff --git a/svf-llvm/include/SVF-LLVM/LLVMUtil.h b/svf-llvm/include/SVF-LLVM/LLVMUtil.h index 8acc2c851..2e49db186 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMUtil.h +++ b/svf-llvm/include/SVF-LLVM/LLVMUtil.h @@ -98,121 +98,6 @@ inline const Function* getProgFunction(const std::string& funName) return nullptr; } -inline std::vector getFunAnnotations(const Function* fun) -{ - std::vector annotations; - // Get annotation variable - GlobalVariable *glob = fun->getParent()->getGlobalVariable("llvm.global.annotations"); - if (glob == nullptr) - return annotations; - - ConstantArray *ca = SVFUtil::dyn_cast(glob->getInitializer()); - if (ca == nullptr) - return annotations; - - for (unsigned i = 0; i < ca->getNumOperands(); ++i) - { - ConstantStruct *structAn = SVFUtil::dyn_cast(ca->getOperand(i)); - if (structAn == nullptr) - continue; - - ConstantExpr *expr = SVFUtil::dyn_cast(structAn->getOperand(0)); - if (expr == nullptr) - continue; - - if (expr->getOpcode() != Instruction::BitCast || expr->getOperand(0) != fun) - continue; - - ConstantExpr *note = SVFUtil::cast(structAn->getOperand(1)); - if (note->getOpcode() != Instruction::GetElementPtr) - continue; - - GlobalVariable *annotateStr = SVFUtil::dyn_cast(note->getOperand(0)); - if (annotateStr == nullptr) - continue; - - ConstantDataSequential *data = SVFUtil::dyn_cast(annotateStr->getInitializer()); - if (data == nullptr) - continue; - - if (data->isString()) { - std::string annotation = data->getAsString().str(); - if (!annotation.empty()) { - annotations.push_back(annotation); - } - } - } - return annotations; -} - -inline void removeFunAnnotations(const std::vector& removedFuncList) { - if (removedFuncList.empty()) { - return; // No functions to remove annotations in extapi.bc module - } - - Module* module = removedFuncList[0]->getParent(); - GlobalVariable* glob = module->getGlobalVariable("llvm.global.annotations"); - - if (glob == nullptr) { - return; // No annotations to remove - } - - ConstantArray* ca = SVFUtil::dyn_cast(glob->getInitializer()); - if (ca == nullptr) { - return; // Invalid annotations format - } - - std::vector newAnnotations; - - for (unsigned i = 0; i < ca->getNumOperands(); ++i) { - ConstantStruct* structAn = SVFUtil::dyn_cast(ca->getOperand(i)); - if (structAn == nullptr) { - continue; - } - - ConstantExpr* expr = SVFUtil::dyn_cast(structAn->getOperand(0)); - if (expr == nullptr || expr->getOpcode() != Instruction::BitCast) { - // Keep the annotation if it's not created using BitCast - newAnnotations.push_back(structAn); - continue; - } - - Function* annotatedFunc = SVFUtil::dyn_cast(expr->getOperand(0)); - if (annotatedFunc == nullptr || std::find(removedFuncList.begin(), removedFuncList.end(), annotatedFunc) != removedFuncList.end()) { - // Skip this annotation as it belongs to one of the functions in removedFuncList - continue; - } - - // Keep the annotation for all other functions - newAnnotations.push_back(structAn); - } - - if (newAnnotations.size() == ca->getNumOperands()) { - return; // No annotations to remove - } - - ArrayType* annotationsType = ArrayType::get(ca->getType()->getElementType(), newAnnotations.size()); - Constant* newCA = ConstantArray::get(annotationsType, newAnnotations); - - // Check if a global variable with the name llvm.global.annotations already exists - GlobalVariable* existingGlobal = module->getGlobalVariable("llvm.global.annotations"); - if (existingGlobal) { - // Rename the existing llvm.global.annotations to llvm.global.annotations_old - existingGlobal->setName("llvm.global.annotations_old"); - } - - // Create a new global variable with the updated annotations - GlobalVariable* newGlobal = new GlobalVariable(*module, newCA->getType(), glob->isConstant(), - glob->getLinkage(), newCA, "llvm.global.annotations", glob, glob->getThreadLocalMode()); - - // Copy other properties from the old global variable to the new one - newGlobal->setSection(glob->getSection()); - newGlobal->setAlignment(llvm::MaybeAlign(glob->getAlignment())); - - // Remove the old global variable - glob->eraseFromParent(); -} - /// Check whether a function is an entry function (i.e., main) inline bool isProgEntryFunction(const Function* fun) { @@ -487,6 +372,18 @@ const std::string getSourceLocOfFunction(const Function* F); bool isIntrinsicInst(const Instruction* inst); bool isIntrinsicFun(const Function* func); +std::vector getFunAnnotations(const Function* fun); +void removeFunAnnotations(std::vector& removedFuncList); + +inline void removeUnusedFuncsAndAnnotations(std::vector removedFuncList) +{ + /// Remove unused function annotations in extapi.bc + LLVMUtil::removeFunAnnotations(removedFuncList); + /// Remove unused function in extapi.bc + for (Function* func : removedFuncList) + func->eraseFromParent(); +} + /// Get the corresponding Function based on its name inline const SVFFunction* getFunction(const std::string& name) { diff --git a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h index db15a39be..b3d846598 100644 --- a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h @@ -278,7 +278,7 @@ class SVFIRBuilder: public llvm::InstVisitor return nullPtr; } - NodeID getGepValVar(const Value* val, const AccessPath& ls, const SVFType* elementType); + NodeID getGepValVar(const Value* val, const AccessPath& ap, const SVFType* elementType); void setCurrentBBAndValueForPAGEdge(PAGEdge* edge); diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 19df13b70..782dd1c2c 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -154,51 +154,29 @@ void LLVMModuleSet::createSVFDataStructure() { getSVFType(IntegerType::getInt8Ty(getContext())); // Functions need to be retrieved in the order of insertion - std::vector candidateDecls; - std::vector candidateDefs; - + std::vector candidateFuncs; for (Module& mod : modules) { std::vector removedFuncList; /// Function for (Function& func : mod.functions()) { - if (func.isDeclaration() && (FunDefToDeclsMap.find(&func) != FunDefToDeclsMap.end() || mod.getName().str() != Options::ExtAPIInput())) + /// Remove unused function in extapi.bc module + /// if this function func defined in extapi.bc but never used in application code (without any corresponding declared functions). + if (mod.getName().str() == Options::ExtAPIInput() && FunDefToDeclsMap.find(&func) == FunDefToDeclsMap.end() && func.getName().str() != "svf__main") { - /// if this function is declaration - candidateDecls.push_back(&func); + removedFuncList.push_back(&func); + continue; } else { - /// if this function is definition - if (mod.getName().str() == Options::ExtAPIInput() && FunDefToDeclsMap.find(&func) == FunDefToDeclsMap.end() && func.getName().str() != "svf__main") - { - /// if this function func defined in ExtAPI but never used in application code (without any corresponding declared functions). - removedFuncList.push_back(&func); - continue; - } - else - { - /// if this function is in app bc, any def func should be added. - /// if this function is in ext bc, only functions which have declarations(should be used by app bc) can be inserted. - candidateDefs.push_back(&func); - } + candidateFuncs.push_back(&func); } } - // Remove unused function annotations in extapi.bc - LLVMUtil::removeFunAnnotations(removedFuncList); - // Remove unused function in extapi.bc - for (Function* func : removedFuncList) - { - func->eraseFromParent(); - } - } - for (const Function* func: candidateDefs) - { - createSVFFunction(func); + /// Remove unused functions and annotations in extapi.bc + LLVMUtil::removeUnusedFuncsAndAnnotations(removedFuncList); } - - for (const Function* func: candidateDecls) + for (const Function* func: candidateFuncs) { createSVFFunction(func); } @@ -557,9 +535,8 @@ void LLVMModuleSet::loadExtAPIModules() Err.print("SVFModuleLoader", llvm::errs()); abort(); } - // The module of ext.bc needs to be imported before other modules. - // Otherwise, when overwriting the app function with SVF extern function, - // the corresponding SVFFunction of the extern function will not be found. + // The module of extapi.bc needs to be inserted before applications modules, like std::vector> modules{extapi_module, app_module}. + // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found. modules.insert(modules.begin(), *mod); owned_modules.insert(owned_modules.begin(),std::move(mod)); } diff --git a/svf-llvm/lib/LLVMUtil.cpp b/svf-llvm/lib/LLVMUtil.cpp index fdbb3e0ea..57b5c9859 100644 --- a/svf-llvm/lib/LLVMUtil.cpp +++ b/svf-llvm/lib/LLVMUtil.cpp @@ -443,6 +443,101 @@ void LLVMUtil::processArguments(int argc, char **argv, int &arg_num, char **arg_ } } +std::vector LLVMUtil::getFunAnnotations(const Function* fun) +{ + std::vector annotations; + // Get annotation variable + GlobalVariable *glob = fun->getParent()->getGlobalVariable("llvm.global.annotations"); + if (glob == nullptr || !glob->hasInitializer()) + return annotations; + + ConstantArray *ca = SVFUtil::dyn_cast(glob->getInitializer()); + for (unsigned i = 0; i < ca->getNumOperands(); ++i) + { + ConstantStruct *structAn = SVFUtil::dyn_cast(ca->getOperand(i)); + if (structAn == nullptr) + continue; + + ConstantExpr *expr = SVFUtil::dyn_cast(structAn->getOperand(0)); + if (expr == nullptr || expr->getOpcode() != Instruction::BitCast || expr->getOperand(0) != fun) + continue; + + ConstantExpr *note = SVFUtil::cast(structAn->getOperand(1)); + if (note->getOpcode() != Instruction::GetElementPtr) + continue; + + GlobalVariable *annotateStr = SVFUtil::dyn_cast(note->getOperand(0)); + if (annotateStr == nullptr || !annotateStr->hasInitializer()) + continue; + + ConstantDataSequential *data = SVFUtil::dyn_cast(annotateStr->getInitializer()); + if (data->isString()) + { + std::string annotation = data->getAsString().str(); + if (!annotation.empty()) + annotations.push_back(annotation); + } + } + return annotations; +} + +void LLVMUtil::removeFunAnnotations(std::vector& removedFuncList) +{ + if (removedFuncList.empty()) + return; // No functions to remove annotations in extapi.bc module + + Module* module = removedFuncList[0]->getParent(); + GlobalVariable* glob = module->getGlobalVariable("llvm.global.annotations"); + if (glob == nullptr || !glob->hasInitializer()) + return; + + ConstantArray* ca = SVFUtil::dyn_cast(glob->getInitializer()); + std::vector newAnnotations; + for (unsigned i = 0; i < ca->getNumOperands(); ++i) + { + ConstantStruct* structAn = SVFUtil::dyn_cast(ca->getOperand(i)); + if (structAn == nullptr) + continue; + + ConstantExpr* expr = SVFUtil::dyn_cast(structAn->getOperand(0)); + if (expr == nullptr || expr->getOpcode() != Instruction::BitCast) + { + // Keep the annotation if it's not created using BitCast + newAnnotations.push_back(structAn); + continue; + } + + Function* annotatedFunc = SVFUtil::dyn_cast(expr->getOperand(0)); + if (annotatedFunc == nullptr || std::find(removedFuncList.begin(), removedFuncList.end(), annotatedFunc) != removedFuncList.end()) + continue; + + // Keep the annotation for all other functions + newAnnotations.push_back(structAn); + } + + if (newAnnotations.size() == ca->getNumOperands()) + return; // No annotations to remove + + ArrayType* annotationsType = ArrayType::get(ca->getType()->getElementType(), newAnnotations.size()); + Constant* newCA = ConstantArray::get(annotationsType, newAnnotations); + + // Check if a global variable with the name llvm.global.annotations already exists + GlobalVariable* existingGlobal = module->getGlobalVariable("llvm.global.annotations"); + if (existingGlobal) + // Rename the existing llvm.global.annotations to llvm.global.annotations_old + existingGlobal->setName("llvm.global.annotations_old"); + + // Create a new global variable with the updated annotations + GlobalVariable* newGlobal = new GlobalVariable(*module, newCA->getType(), glob->isConstant(), + glob->getLinkage(), newCA, "llvm.global.annotations", glob, glob->getThreadLocalMode()); + + // Copy other properties from the old global variable to the new one + newGlobal->setSection(glob->getSection()); + newGlobal->setAlignment(llvm::MaybeAlign(glob->getAlignment())); + + // Remove the old global variable + glob->eraseFromParent(); +} u32_t LLVMUtil::getTypeSizeInBytes(const Type* type) {