diff --git a/BreakingChanges.md b/BreakingChanges.md index 477de93b7..514c97a24 100644 --- a/BreakingChanges.md +++ b/BreakingChanges.md @@ -2,6 +2,7 @@ ## Development HEAD +- Removed the CLI options `--alias-analysis` and `-P`. PhASAR now only supports the default alias analysis pipeline from LLVM consisting of TBAA, ScopedNoAliasAA and BasicAA. - Default build mode is no longer `SHARED` but `STATIC`. To build in shared mode, use the cmake option `BUILD_SHARED_LIBS` which we don't recommend anymore. Consider using `PHASAR_BUILD_DYNLIB` instead to build one big libphasar.so. ## v0323 diff --git a/include/phasar/PhasarLLVM/HelperAnalyses.h b/include/phasar/PhasarLLVM/HelperAnalyses.h index 39a06ddf9..8aa215e36 100644 --- a/include/phasar/PhasarLLVM/HelperAnalyses.h +++ b/include/phasar/PhasarLLVM/HelperAnalyses.h @@ -31,7 +31,7 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions) public: explicit HelperAnalyses(std::string IRFile, std::optional PrecomputedPTS, - AliasAnalysisType PTATy, bool AllowLazyPTS, + bool AllowLazyPTS, std::vector EntryPoints, std::optional PrecomputedCG, CallGraphAnalysisType CGTy, Soundness SoundnessLevel, @@ -66,7 +66,6 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions) // PTS std::optional PrecomputedPTS; - AliasAnalysisType PTATy{}; bool AllowLazyPTS{}; // ICF diff --git a/include/phasar/PhasarLLVM/HelperAnalysisConfig.h b/include/phasar/PhasarLLVM/HelperAnalysisConfig.h index 4fbd87c62..634846458 100644 --- a/include/phasar/PhasarLLVM/HelperAnalysisConfig.h +++ b/include/phasar/PhasarLLVM/HelperAnalysisConfig.h @@ -11,7 +11,6 @@ #define PHASAR_PHASARLLVM_HELPERANALYSISCONFIG_H #include "phasar/ControlFlow/CallGraphAnalysisType.h" -#include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Utils/Soundness.h" #include "nlohmann/json.hpp" @@ -22,7 +21,6 @@ namespace psr { struct HelperAnalysisConfig { std::optional PrecomputedPTS = std::nullopt; std::optional PrecomputedCG = std::nullopt; - AliasAnalysisType PTATy = AliasAnalysisType::CFLAnders; CallGraphAnalysisType CGTy = CallGraphAnalysisType::OTF; Soundness SoundnessLevel = Soundness::Soundy; bool AutoGlobalSupport = true; diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h index c266980b1..4b50f2740 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h @@ -126,9 +126,7 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin, * considered. False, if May and Must Aliases should be * considered. */ - explicit LLVMAliasGraph( - LLVMProjectIRDB &IRDB, bool UseLazyEvaluation = true, - AliasAnalysisType PATy = AliasAnalysisType::CFLAnders); + explicit LLVMAliasGraph(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation = true); /** * @brief Returns true if graph contains 0 nodes. @@ -212,8 +210,6 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin, [[nodiscard]] bool isInterProcedural() const noexcept; - [[nodiscard]] AliasAnalysisType getAliasAnalysisType() const noexcept; - AliasResult alias(const llvm::Value *V1, const llvm::Value *V2, const llvm::Instruction *I = nullptr); diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h index 0775e98d2..713b92dfc 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h @@ -30,6 +30,8 @@ class Value; class Instruction; class GlobalVariable; class Function; +class GlobalObject; +class DataLayout; } // namespace llvm namespace psr { @@ -58,8 +60,7 @@ class LLVMAliasSet : public AnalysisPropertiesMixin, * UseLazyEvaluation is true, computes points-to-sets for functions that do * not use global variables on the fly */ - explicit LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation = true, - AliasAnalysisType PATy = AliasAnalysisType::CFLAnders); + explicit LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation = true); explicit LLVMAliasSet(LLVMProjectIRDB *IRDB, const nlohmann::json &SerializedPTS); @@ -68,10 +69,6 @@ class LLVMAliasSet : public AnalysisPropertiesMixin, return false; }; - [[nodiscard]] inline AliasAnalysisType getAliasAnalysisType() const noexcept { - return PTA.getPointerAnalysisType(); - }; - [[nodiscard]] AliasResult alias(const llvm::Value *V1, const llvm::Value *V2, const llvm::Instruction *I = nullptr); @@ -158,6 +155,19 @@ class LLVMAliasSet : public AnalysisPropertiesMixin, }; static_assert(IsAliasInfo); +using TTTT = decltype(detail::testAliasInfo( + std::declval(), std::declval())); + +using TTTT2 = std::void_t< + decltype(std::declval().print(llvm::outs())), + decltype(std::declval().printAsJson(llvm::outs())), + decltype(std::declval().mergeWith( + std::declval())), + decltype(std::declval().introduceAlias( + std::declval::v_t>(), + std::declval::v_t>(), + std::declval::n_t>(), + AliasResult{}))>; } // namespace psr diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h b/include/phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h index c37cfda21..60be8335f 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h @@ -10,14 +10,16 @@ #ifndef PHASAR_PHASARLLVM_POINTER_LLVMBASEDALIASANALYSIS_H_ #define PHASAR_PHASARLLVM_POINTER_LLVMBASEDALIASANALYSIS_H_ -#include "phasar/Pointer/AliasAnalysisType.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/raw_ostream.h" -#include "llvm/Analysis/AliasAnalysis.h" +#include namespace llvm { class Value; class Function; class Instruction; +class AAResults; } // namespace llvm namespace psr { @@ -25,11 +27,8 @@ namespace psr { class LLVMProjectIRDB; class LLVMBasedAliasAnalysis { - public: - explicit LLVMBasedAliasAnalysis( - LLVMProjectIRDB &IRDB, bool UseLazyEvaluation, - AliasAnalysisType PATy = AliasAnalysisType::Basic); + LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation = true); LLVMBasedAliasAnalysis(LLVMBasedAliasAnalysis &&) noexcept = default; LLVMBasedAliasAnalysis & @@ -37,9 +36,8 @@ class LLVMBasedAliasAnalysis { LLVMBasedAliasAnalysis(const LLVMBasedAliasAnalysis &) = delete; LLVMBasedAliasAnalysis &operator=(const LLVMBasedAliasAnalysis &) = delete; - ~LLVMBasedAliasAnalysis(); - void print(llvm::raw_ostream &OS = llvm::outs()) const; + ~LLVMBasedAliasAnalysis(); [[nodiscard]] inline llvm::AAResults *getAAResults(llvm::Function *F) { if (!hasAliasInfo(*F)) { @@ -52,11 +50,6 @@ class LLVMBasedAliasAnalysis { void clear() noexcept; - [[nodiscard]] inline AliasAnalysisType - getPointerAnalysisType() const noexcept { - return PATy; - }; - private: [[nodiscard]] bool hasAliasInfo(const llvm::Function &Fun) const; @@ -66,7 +59,6 @@ class LLVMBasedAliasAnalysis { struct Impl; std::unique_ptr PImpl; - AliasAnalysisType PATy; llvm::DenseMap AAInfos; }; diff --git a/include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h b/include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h index 4ec3570b5..18c3c962f 100644 --- a/include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h +++ b/include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h @@ -21,17 +21,17 @@ namespace llvm { class Function; class BasicBlock; class Instruction; -class DominatorTree; } // namespace llvm namespace psr { class DefaultDominatorTreeAnalysis { - llvm::DenseMap> - Dom; - public: llvm::DominatorTree &operator()(const llvm::Function *F); + +private: + llvm::DenseMap> + Dom{}; }; /// Provides a simple partial ordering of BasicBlocks based on LLVM's diff --git a/include/phasar/Pointer.h b/include/phasar/Pointer.h index def25c239..2e1de5f34 100644 --- a/include/phasar/Pointer.h +++ b/include/phasar/Pointer.h @@ -10,7 +10,6 @@ #ifndef PHASAR_POINTER_H #define PHASAR_POINTER_H -#include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Pointer/AliasInfo.h" #include "phasar/Pointer/AliasInfoBase.h" #include "phasar/Pointer/AliasInfoTraits.h" diff --git a/include/phasar/Pointer/AliasAnalysisType.def b/include/phasar/Pointer/AliasAnalysisType.def deleted file mode 100644 index 93c3599d7..000000000 --- a/include/phasar/Pointer/AliasAnalysisType.def +++ /dev/null @@ -1,19 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2022 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -#ifndef ALIAS_ANALYSIS_TYPE -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, DESC) -#endif - -ALIAS_ANALYSIS_TYPE(Basic, "basic", "Basic LLVM alias resolving based on simple, local properties") -ALIAS_ANALYSIS_TYPE(CFLSteens, "cflsteens", "Steensgaard-style alias analysis (equality-based)") -ALIAS_ANALYSIS_TYPE(CFLAnders, "cflanders", "Andersen-style alias analysis (subset-based) (default)") -ALIAS_ANALYSIS_TYPE(PointsTo, "points-to", "Alias-information based on (external) points-to information") - -#undef ALIAS_ANALYSIS_TYPE diff --git a/include/phasar/Pointer/AliasAnalysisType.h b/include/phasar/Pointer/AliasAnalysisType.h deleted file mode 100644 index 7e8fb61b1..000000000 --- a/include/phasar/Pointer/AliasAnalysisType.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef PHASAR_POINTER_ALIASANALYSISTYPE_H -#define PHASAR_POINTER_ALIASANALYSISTYPE_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" - -#include - -namespace psr { -enum class AliasAnalysisType { -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, TYPE) NAME, -#include "phasar/Pointer/AliasAnalysisType.def" - Invalid -}; - -std::string toString(AliasAnalysisType PA); - -AliasAnalysisType toAliasAnalysisType(llvm::StringRef S); - -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, AliasAnalysisType PA); -} // namespace psr - -#endif // PHASAR_POINTER_ALIASANALYSISTYPE_H diff --git a/include/phasar/Pointer/AliasInfo.h b/include/phasar/Pointer/AliasInfo.h index ba9fa480f..3438e20a4 100644 --- a/include/phasar/Pointer/AliasInfo.h +++ b/include/phasar/Pointer/AliasInfo.h @@ -32,7 +32,6 @@ class Instruction; } // namespace llvm namespace psr { -enum class AliasAnalysisType; template class AliasInfoRef; template class AliasInfo; @@ -97,10 +96,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { assert(VT != nullptr); return VT->IsInterProcedural(AA); } - [[nodiscard]] AliasAnalysisType getAliasAnalysisType() const noexcept { - assert(VT != nullptr); - return VT->GetAliasAnalysisType(AA); - } [[nodiscard]] AliasResult alias(ByConstRef Pointer1, ByConstRef Pointer2, @@ -189,7 +184,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { private: struct VTable { bool (*IsInterProcedural)(const void *) noexcept; - AliasAnalysisType (*GetAliasAnalysisType)(const void *) noexcept; AliasResult (*Alias)(void *, ByConstRef, ByConstRef, ByConstRef); AliasSetPtrTy (*GetAliasSet)(void *, ByConstRef, ByConstRef); @@ -215,9 +209,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { [](const void *AA) noexcept { return static_cast(AA)->isInterProcedural(); }, - [](const void *AA) noexcept { - return static_cast(AA)->getAliasAnalysisType(); - }, [](void *AA, ByConstRef Pointer1, ByConstRef Pointer2, ByConstRef AtInstruction) { return static_cast(AA)->alias(Pointer1, Pointer2, diff --git a/include/phasar/Pointer/AliasInfoBase.h b/include/phasar/Pointer/AliasInfoBase.h index b3bb828c1..0a1f62c8a 100644 --- a/include/phasar/Pointer/AliasInfoBase.h +++ b/include/phasar/Pointer/AliasInfoBase.h @@ -28,7 +28,6 @@ class Value; namespace psr { -enum class AliasAnalysisType; enum class AnalysisProperties; enum class AliasResult; @@ -45,8 +44,8 @@ auto testAliasInfo( const std::optional::n_t> &NT = {}, const std::optional::v_t> &VT = {}) -> decltype(std::make_tuple( - CAI.isInterProcedural(), CAI.getAliasAnalysisType(), - AI.alias(*VT, *VT, *NT), AI.getAliasSet(*VT, *NT), + CAI.isInterProcedural(), AI.alias(*VT, *VT, *NT), + AI.getAliasSet(*VT, *NT), AI.getReachableAllocationSites(*VT, true, *NT), AI.isInReachableAllocationSites(*VT, *VT, true, *NT), CAI.getAsJson(), CAI.getAnalysisProperties(), CAI.isContextSensitive(), @@ -65,7 +64,7 @@ struct IsAliasInfo< std::declval::n_t>(), AliasResult{}))>, std::enable_if_t::AliasSetPtrTy, typename AliasInfoTraits::AllocationSiteSetPtrTy, bool, nlohmann::json, AnalysisProperties, bool, bool, bool>, diff --git a/lib/PhasarLLVM/HelperAnalyses.cpp b/lib/PhasarLLVM/HelperAnalyses.cpp index e0d13925e..f012f547d 100644 --- a/lib/PhasarLLVM/HelperAnalyses.cpp +++ b/lib/PhasarLLVM/HelperAnalyses.cpp @@ -9,17 +9,13 @@ #include namespace psr { -HelperAnalyses::HelperAnalyses(std::string IRFile, - std::optional PrecomputedPTS, - AliasAnalysisType PTATy, bool AllowLazyPTS, - std::vector EntryPoints, - std::optional PrecomputedCG, - CallGraphAnalysisType CGTy, - Soundness SoundnessLevel, - bool AutoGlobalSupport) noexcept +HelperAnalyses::HelperAnalyses( + std::string IRFile, std::optional PrecomputedPTS, + bool AllowLazyPTS, std::vector EntryPoints, + std::optional PrecomputedCG, CallGraphAnalysisType CGTy, + Soundness SoundnessLevel, bool AutoGlobalSupport) noexcept : IRFile(std::move(IRFile)), PrecomputedPTS(std::move(PrecomputedPTS)), - PTATy(PTATy), AllowLazyPTS(AllowLazyPTS), - PrecomputedCG(std::move(PrecomputedCG)), + AllowLazyPTS(AllowLazyPTS), PrecomputedCG(std::move(PrecomputedCG)), EntryPoints(std::move(EntryPoints)), CGTy(CGTy), SoundnessLevel(SoundnessLevel), AutoGlobalSupport(AutoGlobalSupport) {} @@ -27,7 +23,7 @@ HelperAnalyses::HelperAnalyses(std::string IRFile, std::vector EntryPoints, HelperAnalysisConfig Config) noexcept : IRFile(std::move(IRFile)), - PrecomputedPTS(std::move(Config.PrecomputedPTS)), PTATy(Config.PTATy), + PrecomputedPTS(std::move(Config.PrecomputedPTS)), AllowLazyPTS(Config.AllowLazyPTS), PrecomputedCG(std::move(Config.PrecomputedCG)), EntryPoints(std::move(EntryPoints)), CGTy(Config.CGTy), @@ -58,8 +54,7 @@ LLVMAliasSet &HelperAnalyses::getAliasInfo() { if (PrecomputedPTS.has_value()) { PT = std::make_unique(&getProjectIRDB(), *PrecomputedPTS); } else { - PT = std::make_unique(&getProjectIRDB(), AllowLazyPTS, - PTATy); + PT = std::make_unique(&getProjectIRDB(), AllowLazyPTS); } } return *PT; diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp index 5d217fb44..0201d7139 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp @@ -134,9 +134,8 @@ std::string LLVMAliasGraph::EdgeProperties::getValueAsString() const { // points-to graph stuff -LLVMAliasGraph::LLVMAliasGraph(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation, - AliasAnalysisType PATy) - : PTA(IRDB, UseLazyEvaluation, PATy) {} +LLVMAliasGraph::LLVMAliasGraph(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation) + : PTA(IRDB, UseLazyEvaluation) {} void LLVMAliasGraph::computeAliasGraph(const llvm::Value *V) { // FIXME when fixed in LLVM @@ -244,10 +243,6 @@ void LLVMAliasGraph::computeAliasGraph(llvm::Function *F) { bool LLVMAliasGraph::isInterProcedural() const noexcept { return false; } -AliasAnalysisType LLVMAliasGraph::getAliasAnalysisType() const noexcept { - return PTA.getPointerAnalysisType(); -} - AliasResult LLVMAliasGraph::alias(const llvm::Value *V1, const llvm::Value *V2, const llvm::Instruction * /*I*/) { computeAliasGraph(V1); diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index 07902f06c..28a11a3eb 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -13,7 +13,6 @@ #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" #include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Utils/BoxedPointer.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/NlohmannLogging.h" @@ -55,9 +54,8 @@ template class BoxedPtr; template class BoxedConstPtr; template class AliasSetOwner; -LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation, - AliasAnalysisType PATy) - : PTA(*IRDB, UseLazyEvaluation, PATy) { +LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation) + : PTA(*IRDB, UseLazyEvaluation) { assert(IRDB != nullptr); auto NumGlobals = IRDB->getNumGlobals(); @@ -463,6 +461,7 @@ void LLVMAliasSet::computeFunctionsAliasSet(llvm::Function *F) { llvm::DenseSet UsedGlobals; for (auto &Inst : llvm::instructions(F)) { + if (Inst.getType()->isPointerTy()) { // Add all pointer instructions. addPointer(&Inst, Pointers); diff --git a/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp b/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp index 319dbc4b7..e85413f9b 100644 --- a/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp @@ -11,15 +11,12 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h" -#include "phasar/Pointer/AliasAnalysisType.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" -#include "llvm/Analysis/CFLAndersAliasAnalysis.h" -#include "llvm/Analysis/CFLSteensAliasAnalysis.h" #include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/IR/Argument.h" @@ -29,11 +26,8 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Value.h" -#include "llvm/IR/Verifier.h" #include "llvm/Passes/PassBuilder.h" -using namespace psr; - namespace psr { struct LLVMBasedAliasAnalysis::Impl { @@ -42,56 +36,6 @@ struct LLVMBasedAliasAnalysis::Impl { llvm::FunctionPassManager FPM{}; }; -static void printResults(llvm::AliasResult AR, bool P, const llvm::Value *V1, - const llvm::Value *V2, const llvm::Module *M) { - if (P) { - std::string O1; - - std::string O2; - { - llvm::raw_string_ostream OS1(O1); - - llvm::raw_string_ostream OS2(O2); - V1->printAsOperand(OS1, true, M); - V2->printAsOperand(OS2, true, M); - } - - if (O2 < O1) { - std::swap(O1, O2); - } - llvm::errs() << " " << AR << ":\t" << O1 << ", " << O2 << "\n"; - } -} - -static inline void printModRefResults(const char *Msg, bool P, - const llvm::Instruction *I, - const llvm::Value *Ptr, - const llvm::Module *M) { - if (P) { - llvm::errs() << " " << Msg << ": Ptr: "; - Ptr->printAsOperand(llvm::errs(), true, M); - llvm::errs() << "\t<->" << *I << '\n'; - } -} - -static inline void printModRefResults(const char *Msg, bool P, - const llvm::CallBase *CallA, - const llvm::CallBase *CallB, - const llvm::Module * /*M*/) { - if (P) { - llvm::errs() << " " << Msg << ": " << *CallA << " <-> " << *CallB << '\n'; - } -} - -static inline void printLoadStoreResults(llvm::AliasResult AR, bool P, - const llvm::Value *V1, - const llvm::Value *V2, - const llvm::Module * /*M*/) { - if (P) { - llvm::errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n'; - } -} - bool LLVMBasedAliasAnalysis::hasAliasInfo(const llvm::Function &Fun) const { return AAInfos.find(&Fun) != AAInfos.end(); } @@ -116,28 +60,12 @@ void LLVMBasedAliasAnalysis::clear() noexcept { } LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, - bool UseLazyEvaluation, - AliasAnalysisType PATy) - : PImpl(new Impl{}), PATy(PATy) { + bool UseLazyEvaluation) + : PImpl(new Impl{}) { PImpl->FAM.registerPass([&] { llvm::AAManager AA; - switch (PATy) { - case AliasAnalysisType::CFLAnders: - AA.registerFunctionAnalysis(); - break; - case AliasAnalysisType::CFLSteens: - AA.registerFunctionAnalysis(); - break; - case AliasAnalysisType::Basic: - [[fallthrough]]; - default: - break; - } - // Note: The order of the alias analyses is important. See LLVM's source - // code for reference (e.g. registerAAAnalyses() in - // llvm/CodeGen/CodeGenPassBuilder.h) - // + // Note: The order of the alias analyses is important AA.registerFunctionAnalysis(); AA.registerFunctionAnalysis(); AA.registerFunctionAnalysis(); @@ -156,258 +84,4 @@ LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, LLVMBasedAliasAnalysis::~LLVMBasedAliasAnalysis() = default; -void LLVMBasedAliasAnalysis::print(llvm::raw_ostream &OS) const { - OS << "Points-to Info:\n"; - for (const auto &[Fn, AA] : AAInfos) { - bool PrintAll = true; - bool PrintNoAlias = true; - bool PrintMayAlias = true; - bool PrintPartialAlias = true; - bool PrintMustAlias = true; - bool EvalAAMD = true; - bool PrintNoModRef = true; - bool PrintMod = true; - bool PrintRef = true; - bool PrintModRef = true; - bool PrintMust = true; - bool PrintMustMod = true; - bool PrintMustRef = true; - bool PrintMustModRef = true; - - // taken from llvm/Analysis/AliasAnalysisEvaluator.cpp - const llvm::DataLayout &DL = Fn->getParent()->getDataLayout(); - - llvm::SetVector Pointers; - llvm::SmallSetVector Calls; - llvm::SetVector Loads; - llvm::SetVector Stores; - - for (const auto &I : Fn->args()) { - if (I.getType()->isPointerTy()) { // Add all pointer arguments. - Pointers.insert(&I); - } - } - - for (llvm::const_inst_iterator I = inst_begin(*Fn), E = inst_end(*Fn); - I != E; ++I) { - if (I->getType()->isPointerTy()) { // Add all pointer instructions. - Pointers.insert(&*I); - } - if (EvalAAMD && llvm::isa(&*I)) { - Loads.insert(&*I); - } - if (EvalAAMD && llvm::isa(&*I)) { - Stores.insert(&*I); - } - const llvm::Instruction &Inst = *I; - if (const auto *Call = llvm::dyn_cast(&Inst)) { - llvm::Value *Callee = Call->getCalledOperand(); - // Skip actual functions for direct function calls. - if (!llvm::isa(Callee) && - isInterestingPointer(Callee)) { - Pointers.insert(Callee); - } - // Consider formals. - for (const llvm::Use &DataOp : Call->data_ops()) { - if (isInterestingPointer(DataOp)) { - Pointers.insert(DataOp); - } - } - Calls.insert(Call); - } else { - // Consider all operands. - for (llvm::Instruction::const_op_iterator OI = Inst.op_begin(), - OE = Inst.op_end(); - OI != OE; ++OI) { - if (isInterestingPointer(*OI)) { - Pointers.insert(*OI); - } - } - } - } - - if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias || - PrintMustAlias || PrintNoModRef || PrintMod || PrintRef || - PrintModRef) { - OS << "Function: " << Fn->getName() << ": " << Pointers.size() - << " pointers, " << Calls.size() << " call sites\n"; - } - - // iterate over the worklist, and run the full (n^2)/2 disambiguations - for (auto I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { - auto I1Size = llvm::LocationSize::beforeOrAfterPointer(); - llvm::Type *I1ElTy = - llvm::cast((*I1)->getType())->getElementType(); - if (I1ElTy->isSized()) { - I1Size = llvm::LocationSize::precise(DL.getTypeStoreSize(I1ElTy)); - } - for (auto I2 = Pointers.begin(); I2 != I1; ++I2) { - auto I2Size = llvm::LocationSize::beforeOrAfterPointer(); - llvm::Type *I2ElTy = - llvm::cast((*I2)->getType())->getElementType(); - if (I2ElTy->isSized()) { - I2Size = llvm::LocationSize::precise(DL.getTypeStoreSize(I2ElTy)); - } - llvm::AliasResult AR = AA->alias(*I1, I1Size, *I2, I2Size); - switch (AR) { - case llvm::AliasResult::NoAlias: - printResults(AR, PrintNoAlias, *I1, *I2, Fn->getParent()); - break; - case llvm::AliasResult::MayAlias: - printResults(AR, PrintMayAlias, *I1, *I2, Fn->getParent()); - break; - case llvm::AliasResult::PartialAlias: - printResults(AR, PrintPartialAlias, *I1, *I2, Fn->getParent()); - break; - case llvm::AliasResult::MustAlias: - printResults(AR, PrintMustAlias, *I1, *I2, Fn->getParent()); - break; - } - } - } - - if (EvalAAMD) { - // iterate over all pairs of load, store - for (const llvm::Value *Load : Loads) { - for (const llvm::Value *Store : Stores) { - llvm::AliasResult AR = AA->alias( - llvm::MemoryLocation::get(llvm::cast(Load)), - llvm::MemoryLocation::get(llvm::cast(Store))); - switch (AR) { - case llvm::AliasResult::NoAlias: - printLoadStoreResults(AR, PrintNoAlias, Load, Store, - Fn->getParent()); - break; - case llvm::AliasResult::MayAlias: - printLoadStoreResults(AR, PrintMayAlias, Load, Store, - Fn->getParent()); - break; - case llvm::AliasResult::PartialAlias: - printLoadStoreResults(AR, PrintPartialAlias, Load, Store, - Fn->getParent()); - break; - case llvm::AliasResult::MustAlias: - printLoadStoreResults(AR, PrintMustAlias, Load, Store, - Fn->getParent()); - break; - } - } - } - - // iterate over all pairs of store, store - for (auto I1 = Stores.begin(), E = Stores.end(); I1 != E; ++I1) { - for (auto I2 = Stores.begin(); I2 != I1; ++I2) { - llvm::AliasResult AR = AA->alias( - llvm::MemoryLocation::get(llvm::cast(*I1)), - llvm::MemoryLocation::get(llvm::cast(*I2))); - switch (AR) { - case llvm::AliasResult::NoAlias: - printLoadStoreResults(AR, PrintNoAlias, *I1, *I2, Fn->getParent()); - break; - case llvm::AliasResult::MayAlias: - printLoadStoreResults(AR, PrintMayAlias, *I1, *I2, Fn->getParent()); - break; - case llvm::AliasResult::PartialAlias: - printLoadStoreResults(AR, PrintPartialAlias, *I1, *I2, - Fn->getParent()); - break; - case llvm::AliasResult::MustAlias: - printLoadStoreResults(AR, PrintMustAlias, *I1, *I2, - Fn->getParent()); - break; - } - } - } - } - - // Mod/ref alias analysis: compare all pairs of calls and values - for (const llvm::CallBase *Call : Calls) { - for (const auto *Pointer : Pointers) { - auto Size = llvm::LocationSize::beforeOrAfterPointer(); - llvm::Type *ElTy = - llvm::cast(Pointer->getType())->getElementType(); - if (ElTy->isSized()) { - Size = llvm::LocationSize::precise(DL.getTypeStoreSize(ElTy)); - } - - switch (AA->getModRefInfo(Call, Pointer, Size)) { - case llvm::ModRefInfo::NoModRef: - printModRefResults("NoModRef", PrintNoModRef, Call, Pointer, - Fn->getParent()); - break; - case llvm::ModRefInfo::Mod: - printModRefResults("Just Mod", PrintMod, Call, Pointer, - Fn->getParent()); - break; - case llvm::ModRefInfo::Ref: - printModRefResults("Just Ref", PrintRef, Call, Pointer, - Fn->getParent()); - break; - case llvm::ModRefInfo::ModRef: - printModRefResults("Both ModRef", PrintModRef, Call, Pointer, - Fn->getParent()); - break; - case llvm::ModRefInfo::Must: - printModRefResults("Must", PrintMust, Call, Pointer, Fn->getParent()); - break; - case llvm::ModRefInfo::MustMod: - printModRefResults("Just Mod (MustAlias)", PrintMustMod, Call, - Pointer, Fn->getParent()); - break; - case llvm::ModRefInfo::MustRef: - printModRefResults("Just Ref (MustAlias)", PrintMustRef, Call, - Pointer, Fn->getParent()); - break; - case llvm::ModRefInfo::MustModRef: - printModRefResults("Both ModRef (MustAlias)", PrintMustModRef, Call, - Pointer, Fn->getParent()); - break; - } - } - } - - // Mod/ref alias analysis: compare all pairs of calls - for (const llvm::CallBase *CallA : Calls) { - for (const llvm::CallBase *CallB : Calls) { - if (CallA == CallB) { - continue; - } - switch (AA->getModRefInfo(CallA, CallB)) { - case llvm::ModRefInfo::NoModRef: - printModRefResults("NoModRef", PrintNoModRef, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::Mod: - printModRefResults("Just Mod", PrintMod, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::Ref: - printModRefResults("Just Ref", PrintRef, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::ModRef: - printModRefResults("Both ModRef", PrintModRef, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::Must: - printModRefResults("Must", PrintMust, CallA, CallB, Fn->getParent()); - break; - case llvm::ModRefInfo::MustMod: - printModRefResults("Just Mod (MustAlias)", PrintMustMod, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::MustRef: - printModRefResults("Just Ref (MustAlias)", PrintMustRef, CallA, CallB, - Fn->getParent()); - break; - case llvm::ModRefInfo::MustModRef: - printModRefResults("Both ModRef (MustAlias)", PrintMustModRef, CallA, - CallB, Fn->getParent()); - break; - } - } - } - } -} - } // namespace psr diff --git a/lib/Pointer/AliasAnalysisType.cpp b/lib/Pointer/AliasAnalysisType.cpp deleted file mode 100644 index d958fae7b..000000000 --- a/lib/Pointer/AliasAnalysisType.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "phasar/Pointer/AliasAnalysisType.h" - -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSwitch.h" - -std::string psr::toString(AliasAnalysisType PA) { - switch (PA) { - default: -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, DESC) \ - case AliasAnalysisType::NAME: \ - return #NAME; -#include "phasar/Pointer/AliasAnalysisType.def" - case AliasAnalysisType::Invalid: - return "Invalid"; - } -} - -psr::AliasAnalysisType psr::toAliasAnalysisType(llvm::StringRef S) { - AliasAnalysisType Type = llvm::StringSwitch(S) -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, TYPE) \ - .Case(#NAME, AliasAnalysisType::NAME) -#include "phasar/Pointer/AliasAnalysisType.def" - .Default(AliasAnalysisType::Invalid); - if (Type == AliasAnalysisType::Invalid) { - Type = llvm::StringSwitch(S) -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, TYPE) \ - .Case(CMDFLAG, AliasAnalysisType::NAME) -#include "phasar/Pointer/AliasAnalysisType.def" - .Default(AliasAnalysisType::Invalid); - } - return Type; -} - -llvm::raw_ostream &psr::operator<<(llvm::raw_ostream &OS, - AliasAnalysisType PA) { - return OS << toString(PA); -} diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp index ef221b8cd..c5e27a758 100644 --- a/tools/phasar-cli/phasar-cli.cpp +++ b/tools/phasar-cli/phasar-cli.cpp @@ -16,7 +16,6 @@ #include "phasar/PhasarLLVM/HelperAnalyses.h" #include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" -#include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Utils/IO.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Soundness.h" @@ -97,21 +96,6 @@ cl::opt AnalysisConfigOpt( cl::desc("Set the analysis's configuration (if required)"), cl::cat(PsrCat)); -cl::opt AliasTypeOpt( - "alias-analysis", - cl::desc("Set the alias analysis to be used (CFLSteens, " - "CFLAnders). CFLSteens is ~O(N) but inaccurate while " - "CFLAnders O(N^3) but more accurate."), - cl::values( -#define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, DESC) \ - clEnumValN(AliasAnalysisType::NAME, CMDFLAG, DESC), -#include "phasar/Pointer/AliasAnalysisType.def" - clEnumValN(AliasAnalysisType::Invalid, "invalid", "invalid")), - cl::init(AliasAnalysisType::CFLAnders), cl::cat(PsrCat)); -cl::alias AliasTypeAlias("P", cl::aliasopt(AliasTypeOpt), - cl::desc("Alias for --alias-analysis"), - cl::cat(PsrCat)); - cl::opt CGTypeOpt( "call-graph-analysis", cl::desc("Set the call-graph algorithm to be used"), cl::values( @@ -275,13 +259,6 @@ void validateParamOutput() { } } -void validateParamPointerAnalysis() { - if (AliasTypeOpt == AliasAnalysisType::Invalid) { - llvm::errs() << "'Invalid' is not a valid pointer analysis!\n"; - exit(1); - } -} - void validateParamCallGraphAnalysis() { if (CGTypeOpt == CallGraphAnalysisType::Invalid) { llvm::errs() << "'Invalid' is not a valid call-graph analysis!\n"; @@ -360,7 +337,6 @@ int main(int Argc, const char **Argv) { validateParamModule(); validateParamOutput(); - validateParamPointerAnalysis(); validateParamCallGraphAnalysis(); validateSoundnessFlag(); validateParamAnalysisConfig(); @@ -448,11 +424,10 @@ int main(int Argc, const char **Argv) { } // setup IRDB as source code manager - HelperAnalyses HA(std::move(ModuleOpt.getValue()), - std::move(PrecomputedAliasSet), AliasTypeOpt, - !AnalysisController::needsToEmitPTA(EmitterOptions), - EntryOpt, std::move(PrecomputedCallGraph), CGTypeOpt, - SoundnessOpt, AutoGlobalsOpt); + HelperAnalyses HA( + std::move(ModuleOpt.getValue()), std::move(PrecomputedAliasSet), + !AnalysisController::needsToEmitPTA(EmitterOptions), EntryOpt, + std::move(PrecomputedCallGraph), CGTypeOpt, SoundnessOpt, AutoGlobalsOpt); AnalysisController Controller( HA, DataFlowAnalysisOpt, {AnalysisConfigOpt.getValue()}, EntryOpt, diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp index 77f858c30..56d86f08f 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp @@ -156,6 +156,8 @@ TEST_F(IFDSConstAnalysisTest, HandlePointerTest_01) { } TEST_F(IFDSConstAnalysisTest, HandlePointerTest_02) { + GTEST_SKIP() << "The Alias Analysis does not know anymore that i and p do " + "not alias..."; initialize({PathToLlFiles + "pointer/pointer_02_cpp_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve();