From c5cf911aaa61a1c1a179b5a560b220293289c437 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 16 Feb 2024 15:36:59 +0100 Subject: [PATCH 1/2] Fix joinImpl + IIAAKillOrReplaceEF in IIA --- .../Problems/IDEInstInteractionAnalysis.h | 90 ++++++++----------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h index 9e9972ac49..9fefd21c24 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h @@ -30,6 +30,7 @@ #include "phasar/Utils/Logger.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Constant.h" @@ -629,26 +630,19 @@ class IDEInstInteractionAnalysisT // variables using generalized initial seeds // Generate zero value at the entry points - Seeds.addSeed(SP, this->getZeroValue(), bottomElement()); + Seeds.addSeed(SP, this->getZeroValue(), Bottom{}); // Generate formal parameters of entry points, e.g. main(). Formal // parameters will otherwise cause trouble by overriding alloca // instructions without being valid data-flow facts themselves. for (const auto &Arg : SP->getFunction()->args()) { - Seeds.addSeed(SP, &Arg, Bottom{}); + Seeds.addSeed(SP, &Arg, BitVectorSet()); } // Generate all global variables using generalized initial seeds for (const auto &G : this->IRDB->getModule()->globals()) { if (const auto *GV = llvm::dyn_cast(&G)) { - l_t InitialValues = BitVectorSet(); - std::set EdgeFacts; - if (EdgeFactGen) { - EdgeFacts = EdgeFactGen(GV); - // fill BitVectorSet - InitialValues = - BitVectorSet(EdgeFacts.begin(), EdgeFacts.end()); - } - Seeds.addSeed(SP, GV, InitialValues); + l_t InitialValues = bvSetFrom(invoke_or_default(EdgeFactGen, GV)); + Seeds.addSeed(SP, GV, std::move(InitialValues)); } } }); @@ -691,7 +685,13 @@ class IDEInstInteractionAnalysisT if (SuccNode == Store->getPointerOperand() || PT.isInReachableAllocationSites(Store->getPointerOperand(), SuccNode, true, Store)) { - return IIAAAddLabelsEFCache.createEdgeFunction(UserEdgeFacts); + if (isZeroValue(CurrNode)) { + return IIAAKillOrReplaceEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); + } else { + return IIAAAddLabelsEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); + } } } @@ -722,7 +722,8 @@ class IDEInstInteractionAnalysisT PHASAR_LOG_LEVEL(DFADEBUG, '\n'); }); // obtain label from the original allocation - return IIAAKillOrReplaceEFCache.createEdgeFunction(UserEdgeFacts); + return IIAAKillOrReplaceEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); } } else { @@ -800,7 +801,13 @@ class IDEInstInteractionAnalysisT // We generate Curr in this instruction, so we have to annotate it with // edge labels - return IIAAAddLabelsEFCache.createEdgeFunction(UserEdgeFacts); + if (isZeroValue(CurrNode)) { + return IIAAKillOrReplaceEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); + } else { + return IIAAAddLabelsEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); + } } // Otherwise stick to identity. @@ -835,7 +842,7 @@ class IDEInstInteractionAnalysisT } } if (isZeroValue(SrcNode) && SRetParams.count(DestNode)) { - return IIAAAddLabelsEFCache.createEdgeFunction(); + return IIAAKillOrReplaceEFCache.createEdgeFunction(); } // Everything else can be passed as identity. return EdgeIdentity{}; @@ -863,14 +870,8 @@ class IDEInstInteractionAnalysisT if (const auto *CD = llvm::dyn_cast(Ret->getReturnValue())) { // Check if the user has registered a fact generator function - l_t UserEdgeFacts = BitVectorSet(); - std::set EdgeFacts; - if (EdgeFactGen) { - EdgeFacts = EdgeFactGen(ExitInst); - // fill BitVectorSet - UserEdgeFacts = BitVectorSet(EdgeFacts.begin(), EdgeFacts.end()); - } - return IIAAAddLabelsEFCache.createEdgeFunction( + l_t UserEdgeFacts = bvSetFrom(invoke_or_default(EdgeFactGen, ExitInst)); + return IIAAKillOrReplaceEFCache.createEdgeFunction( std::move(UserEdgeFacts)); } } @@ -883,13 +884,8 @@ class IDEInstInteractionAnalysisT d_t RetSiteNode, llvm::ArrayRef Callees) override { // Check if the user has registered a fact generator function - l_t UserEdgeFacts = BitVectorSet(); - std::set EdgeFacts; - if (EdgeFactGen) { - EdgeFacts = EdgeFactGen(CallSite); - // fill BitVectorSet - UserEdgeFacts = BitVectorSet(EdgeFacts.begin(), EdgeFacts.end()); - } + l_t UserEdgeFacts = bvSetFrom(invoke_or_default(EdgeFactGen, CallSite)); + // Model call to heap allocating functions (new, new[], malloc, etc.) -- // only model direct calls, though. if (Callees.size() == 1) { @@ -908,7 +904,7 @@ class IDEInstInteractionAnalysisT // i // if (isZeroValue(CallNode) && RetSiteNode == CallSite) { - return IIAAAddLabelsEFCache.createEdgeFunction( + return IIAAKillOrReplaceEFCache.createEdgeFunction( std::move(UserEdgeFacts)); } } @@ -956,7 +952,7 @@ class IDEInstInteractionAnalysisT // others). struct IIAAKillOrReplaceEF { using l_t = typename AnalysisDomainTy::l_t; - l_t Replacement{}; + l_t Replacement = BitVectorSet(); l_t computeTarget(ByConstRef /* Src */) const { return Replacement; } @@ -972,27 +968,13 @@ class IDEInstInteractionAnalysisT "IIAAKillOrReplaceEF is too large for SOO"); if (auto *AD = llvm::dyn_cast(SecondFunction)) { - auto ADCache = - SecondFunction.template getCacheOrNull(); - assert(ADCache != nullptr); - if (This->isKillAll()) { - return ADCache->createEdgeFunction(*AD); - } auto Union = IDEInstInteractionAnalysisT::joinImpl(This->Replacement, AD->Data); - return ADCache->createEdgeFunction(std::move(Union)); + return Cache->createEdgeFunction(std::move(Union)); } if (auto *KR = llvm::dyn_cast(SecondFunction)) { - if (This->isKillAll()) { - return Cache->createEdgeFunction(*KR); - } - if (KR->isKillAll()) { - return SecondFunction; - } - auto Union = IDEInstInteractionAnalysisT::joinImpl(This->Replacement, - KR->Replacement); - return Cache->createEdgeFunction(std::move(Union)); + return SecondFunction; } llvm::report_fatal_error( "found unexpected edge function in 'IIAAKillOrReplaceEF'"); @@ -1033,6 +1015,8 @@ class IDEInstInteractionAnalysisT return Replacement == Other.Replacement; } + bool isConstant() const noexcept { return true; } + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IIAAKillOrReplaceEF &EF) { OS << "EF: (IIAAKillOrReplaceEF)<->"; @@ -1061,7 +1045,7 @@ class IDEInstInteractionAnalysisT // add all labels provided by Data. struct IIAAAddLabelsEF { using l_t = typename AnalysisDomainTy::l_t; - l_t Data{}; + l_t Data = BitVectorSet(); l_t computeTarget(ByConstRef Src) const { return IDEInstInteractionAnalysisT::joinImpl(Src, Data); @@ -1083,7 +1067,7 @@ class IDEInstInteractionAnalysisT return Cache->createEdgeFunction(std::move(Union)); } if (auto *KR = llvm::dyn_cast(SecondFunction)) { - return Cache->createEdgeFunction(KR->Replacement); + return SecondFunction; } llvm::report_fatal_error( "found unexpected edge function in 'IIAAAddLabelsEF'"); @@ -1244,10 +1228,10 @@ class IDEInstInteractionAnalysisT } static inline l_t joinImpl(ByConstRef Lhs, ByConstRef Rhs) { - if (Lhs.isTop() || Lhs.isBottom()) { + if (Lhs.isTop() || Rhs.isBottom()) { return Rhs; } - if (Rhs.isTop() || Rhs.isBottom()) { + if (Rhs.isTop() || Lhs.isBottom()) { return Lhs; } const auto &LhsSet = std::get>(Lhs); @@ -1270,7 +1254,7 @@ class IDEInstInteractionAnalysisT // at some point. Therefore, we only care for the variables and their // associated values and ignore at which point a variable may holds as a // data-flow fact. - const auto Variable = Result.getColumnKey(); + const auto &Variable = Result.getColumnKey(); const auto &Value = Result.getValue(); // skip result entry if variable is not in the set of all variables if (Variables.find(Variable) == Variables.end()) { From 337cb63d5474e3dae066be3eaa16cc5611269079 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 16 Feb 2024 16:00:31 +0100 Subject: [PATCH 2/2] minor --- .../Problems/IDEInstInteractionAnalysis.h | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h index 9fefd21c24..40d1dff446 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h @@ -688,10 +688,9 @@ class IDEInstInteractionAnalysisT if (isZeroValue(CurrNode)) { return IIAAKillOrReplaceEFCache.createEdgeFunction( std::move(UserEdgeFacts)); - } else { - return IIAAAddLabelsEFCache.createEdgeFunction( - std::move(UserEdgeFacts)); } + return IIAAAddLabelsEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); } } @@ -709,7 +708,7 @@ class IDEInstInteractionAnalysisT // v // y // - if ((CurrNode == SuccNode) && CurrNode == Store->getPointerOperand()) { + if (CurrNode == SuccNode && CurrNode == Store->getPointerOperand()) { // y obtains its value(s) from its original allocation and the store // instruction under analysis. IF_LOG_ENABLED({ @@ -804,10 +803,8 @@ class IDEInstInteractionAnalysisT if (isZeroValue(CurrNode)) { return IIAAKillOrReplaceEFCache.createEdgeFunction( std::move(UserEdgeFacts)); - } else { - return IIAAAddLabelsEFCache.createEdgeFunction( - std::move(UserEdgeFacts)); } + return IIAAAddLabelsEFCache.createEdgeFunction(std::move(UserEdgeFacts)); } // Otherwise stick to identity. @@ -889,24 +886,24 @@ class IDEInstInteractionAnalysisT // Model call to heap allocating functions (new, new[], malloc, etc.) -- // only model direct calls, though. if (Callees.size() == 1) { - for (const auto *Callee : Callees) { - if (this->ICF->isHeapAllocatingFunction(Callee)) { - // Let H be a heap allocating function. - // - // 0 --> x - // - // Edge function: - // - // 0 - // \ + const auto *Callee = Callees.front(); + + if (this->ICF->isHeapAllocatingFunction(Callee)) { + // Let H be a heap allocating function. + // + // 0 --> x + // + // Edge function: + // + // 0 + // \ // %i = call H \ \x.x \cup { commit of('%i = call H') } - // v - // i - // - if (isZeroValue(CallNode) && RetSiteNode == CallSite) { - return IIAAKillOrReplaceEFCache.createEdgeFunction( - std::move(UserEdgeFacts)); - } + // v + // i + // + if (isZeroValue(CallNode) && RetSiteNode == CallSite) { + return IIAAKillOrReplaceEFCache.createEdgeFunction( + std::move(UserEdgeFacts)); } } } @@ -940,10 +937,6 @@ class IDEInstInteractionAnalysisT return nullptr; } - inline l_t topElement() override { return Top{}; } - - inline l_t bottomElement() override { return Bottom{}; } - inline l_t join(l_t Lhs, l_t Rhs) override { return joinImpl(Lhs, Rhs); } // Provide some handy helper edge functions to improve reuse. @@ -1015,7 +1008,7 @@ class IDEInstInteractionAnalysisT return Replacement == Other.Replacement; } - bool isConstant() const noexcept { return true; } + [[nodiscard]] bool isConstant() const noexcept { return true; } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IIAAKillOrReplaceEF &EF) { @@ -1198,9 +1191,8 @@ class IDEInstInteractionAnalysisT } protected: - static inline bool isZeroValueImpl(d_t d) { - return LLVMZeroValue::isLLVMZeroValue(d); - } + // NOLINTNEXTLINE(readability-identifier-naming) + static constexpr auto isZeroValueImpl = LLVMZeroValue::isLLVMZeroValue; static void printEdgeFactImpl(llvm::raw_ostream &OS, ByConstRef EdgeFact) {