diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index e4fa4c1fe2..c6fa540760 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -188,14 +188,6 @@ class LLVMBasedICFG ~LLVMBasedICFG() override; - // Re-override getSuccsOf and getPredsOf from LLVMBasedCFG to incorporate - // information about global ctors and globale dtors - [[nodiscard]] std::vector - getPredsOf(const llvm::Instruction *Inst) const override; - - [[nodiscard]] std::vector - getSuccsOf(const llvm::Instruction *Inst) const override; - [[nodiscard]] const llvm::Function *getFirstGlobalCtorOrNull() const; [[nodiscard]] const llvm::Function *getLastGlobalDtorOrNull() const; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp index 96054b614a..5a9b579566 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/Support/Casting.h" #include "nlohmann/json.hpp" @@ -47,47 +48,60 @@ LLVMBasedCFG::getFunctionOf(const llvm::Instruction *Inst) const { vector LLVMBasedCFG::getPredsOf(const llvm::Instruction *I) const { - vector Preds; if (!IgnoreDbgInstructions) { - if (I->getPrevNode()) { - Preds.push_back(I->getPrevNode()); + if (auto *PrevInst = I->getPrevNode()) { + return {PrevInst}; } } else { - if (I->getPrevNonDebugInstruction()) { - Preds.push_back(I->getPrevNonDebugInstruction()); + if (auto *PrevNonDbgInst = + I->getPrevNonDebugInstruction(false /*Only debug instructions*/)) { + return {PrevNonDbgInst}; } } // If we do not have a predecessor yet, look for basic blocks which // lead to our instruction in question! - if (Preds.empty()) { - std::transform(llvm::pred_begin(I->getParent()), - llvm::pred_end(I->getParent()), back_inserter(Preds), - [](const llvm::BasicBlock *BB) { - assert(BB && "BB under analysis was not well formed."); - return BB->getTerminator(); - }); - } + + std::vector Preds; + std::transform(llvm::pred_begin(I->getParent()), + llvm::pred_end(I->getParent()), back_inserter(Preds), + [](const llvm::BasicBlock *BB) { + assert(BB && "BB under analysis was not well formed."); + const llvm::Instruction *Pred = BB->getTerminator(); + if (llvm::isa(Pred)) { + Pred = Pred->getPrevNonDebugInstruction( + false /*Only debug instructions*/); + } + return Pred; + }); + return Preds; } vector LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const { - vector Successors; + std::vector Successors; // case we wish to consider LLVM's debug instructions if (!IgnoreDbgInstructions) { - if (I->getNextNode()) { - Successors.push_back(I->getNextNode()); + if (auto *NextInst = I->getNextNode()) { + return {NextInst}; } } else { - if (I->getNextNonDebugInstruction()) { - Successors.push_back(I->getNextNonDebugInstruction()); + if (auto *NextNonDbgInst = + I->getNextNonDebugInstruction(false /*Only debug instructions*/)) { + Successors.push_back(NextNonDbgInst); } } if (I->isTerminator()) { Successors.reserve(I->getNumSuccessors() + Successors.size()); std::transform(llvm::succ_begin(I), llvm::succ_end(I), - back_inserter(Successors), - [](const llvm::BasicBlock *BB) { return &BB->front(); }); + back_inserter(Successors), [](const llvm::BasicBlock *BB) { + const llvm::Instruction *Succ = &BB->front(); + if (llvm::isa(Succ)) { + Succ = Succ->getNextNonDebugInstruction( + false /*Only debug instructions*/); + } + return Succ; + }); } return Successors; } @@ -135,7 +149,12 @@ LLVMBasedCFG::getStartPointsOf(const llvm::Function *Fun) const { return {}; } if (!Fun->isDeclaration()) { - return {&Fun->front().front()}; + auto *EntryInst = &Fun->front().front(); + if (IgnoreDbgInstructions && llvm::isa(EntryInst)) { + return {EntryInst->getNextNonDebugInstruction( + false /*Only debug instructions*/)}; + } + return {EntryInst}; } else { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Could not get starting points of '" diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 9c26a17392..2280f304ba 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -444,65 +444,6 @@ const llvm::Function *LLVMBasedICFG::getFunction(const string &Fun) const { return IRDB.getFunction(Fun); } -std::vector -LLVMBasedICFG::getPredsOf(const llvm::Instruction *Inst) const { - if (!IgnoreDbgInstructions) { - if (Inst->getPrevNode()) { - return {Inst->getPrevNode()}; - } - } else { - if (Inst->getPrevNonDebugInstruction()) { - return {Inst->getPrevNonDebugInstruction()}; - } - } - // If we do not have a predecessor yet, look for basic blocks which - // lead to our instruction in question! - - vector Preds; - std::transform(llvm::pred_begin(Inst->getParent()), - llvm::pred_end(Inst->getParent()), back_inserter(Preds), - [](const llvm::BasicBlock *BB) { - assert(BB && "BB under analysis was not well formed."); - return BB->getTerminator(); - }); - - /// TODO: Add function-local static variable initialization workaround here - - return Preds; -} - -std::vector -LLVMBasedICFG::getSuccsOf(const llvm::Instruction *Inst) const { - - vector Successors; - // case we wish to consider LLVM's debug instructions - if (!IgnoreDbgInstructions) { - if (Inst->getNextNode()) { - Successors.push_back(Inst->getNextNode()); - } - } else { - if (Inst->getNextNonDebugInstruction()) { - Successors.push_back(Inst->getNextNonDebugInstruction()); - } - } - if (Successors.empty()) { - if (const auto *Branch = llvm::dyn_cast(Inst); - Branch && isStaticVariableLazyInitializationBranch(Branch)) { - // Skip the "already initialized" case, such that the analysis is always - // aware of the initialized value. - Successors.push_back(&Branch->getSuccessor(0)->front()); - - } else { - Successors.reserve(Inst->getNumSuccessors() + Successors.size()); - std::transform(llvm::succ_begin(Inst), llvm::succ_end(Inst), - std::back_inserter(Successors), - [](const llvm::BasicBlock *BB) { return &BB->front(); }); - } - } - - return Successors; -} - const llvm::Function *LLVMBasedICFG::getFirstGlobalCtorOrNull() const { auto it = GlobalCtors.begin(); if (it != GlobalCtors.end()) { @@ -676,11 +617,13 @@ LLVMBasedICFG::getReturnSitesOfCallAt(const llvm::Instruction *N) const { auto *UnwindSucc = &Invoke->getUnwindDest()->front(); if (!IgnoreDbgInstructions && llvm::isa(NormalSucc)) { - NormalSucc = NormalSucc->getNextNonDebugInstruction(); + NormalSucc = NormalSucc->getNextNonDebugInstruction( + false /*Only debug instructions*/); } if (!IgnoreDbgInstructions && llvm::isa(UnwindSucc)) { - UnwindSucc = UnwindSucc->getNextNonDebugInstruction(); + UnwindSucc = UnwindSucc->getNextNonDebugInstruction( + false /*Only debug instructions*/); } if (NormalSucc != nullptr) { ReturnSites.insert(NormalSucc);