Skip to content

Commit

Permalink
Merge branch 'development' into f-SplitLLVMBasedICFG
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbs96 committed Oct 22, 2024
2 parents 3e68f04 + f17594d commit 2e4b276
Show file tree
Hide file tree
Showing 41 changed files with 1,310 additions and 239 deletions.
3 changes: 2 additions & 1 deletion include/phasar/ControlFlow/CFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ template <typename Derived> class CFGBase {
void print(ByConstRef<f_t> Fun, llvm::raw_ostream &OS) const {
self().printImpl(Fun, OS);
}
[[nodiscard]] nlohmann::json getAsJson(ByConstRef<f_t> Fun) const {
[[nodiscard, deprecated("Please use printAsJson() instead")]] nlohmann::json
getAsJson(ByConstRef<f_t> Fun) const {
return self().getAsJsonImpl(Fun);
}

Expand Down
49 changes: 32 additions & 17 deletions include/phasar/ControlFlow/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
#define PHASAR_CONTROLFLOW_CALLGRAPH_H

#include "phasar/ControlFlow/CallGraphBase.h"
#include "phasar/ControlFlow/CallGraphData.h"
#include "phasar/Utils/ByRef.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/StableVector.h"
#include "phasar/Utils/Utilities.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Function.h"

#include "nlohmann/json.hpp"

#include <functional>
#include <string>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -58,7 +58,7 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
/// Deserializes a previously computed call-graph
template <typename FunctionGetter, typename InstructionGetter>
[[nodiscard]] static CallGraph
deserialize(const nlohmann::json &PrecomputedCG,
deserialize(const CallGraphData &PrecomputedCG,
FunctionGetter GetFunctionFromName,
InstructionGetter GetInstructionFromId);

Expand Down Expand Up @@ -86,12 +86,33 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {

[[nodiscard]] bool empty() const noexcept { return CallersOf.empty(); }

template <typename FunctionIdGetter, typename InstIdGetter>
void printAsJson(llvm::raw_ostream &OS, FunctionIdGetter GetFunctionId,
InstIdGetter GetInstructionId) const {
CallGraphData CGData;
CGData.FToFunctionVertexTy.reserve(CallersOf.size());

for (const auto &[Fun, Callers] : CallersOf) {
auto &JCallers =
CGData.FToFunctionVertexTy[std::invoke(GetFunctionId, Fun)];

CGData.FToFunctionVertexTy.reserve(Callers->size());
for (const auto &CS : *Callers) {
JCallers.push_back(std::invoke(GetInstructionId, CS));
}
}

CGData.printAsJson(OS);
}

/// Creates a JSON representation of this call-graph suitable for presistent
/// storage.
/// Use the ctor taking a json object for deserialization
template <typename FunctionIdGetter, typename InstIdGetter>
[[nodiscard]] nlohmann::json getAsJson(FunctionIdGetter GetFunctionId,
InstIdGetter GetInstructionId) const {
[[nodiscard]] [[deprecated(
"Please use printAsJson() instead")]] nlohmann::json
getAsJson(FunctionIdGetter GetFunctionId,
InstIdGetter GetInstructionId) const {
nlohmann::json J;

for (const auto &[Fun, Callers] : CallersOf) {
Expand Down Expand Up @@ -254,18 +275,13 @@ template <typename N, typename F> class CallGraphBuilder {
template <typename N, typename F>
template <typename FunctionGetter, typename InstructionGetter>
[[nodiscard]] CallGraph<N, F>
CallGraph<N, F>::deserialize(const nlohmann::json &PrecomputedCG,
CallGraph<N, F>::deserialize(const CallGraphData &PrecomputedCG,
FunctionGetter GetFunctionFromName,
InstructionGetter GetInstructionFromId) {
if (!PrecomputedCG.is_object()) {
PHASAR_LOG_LEVEL_CAT(ERROR, "CallGraph", "Invalid Json. Expected object");
return {};
}

CallGraphBuilder<N, F> CGBuilder;
CGBuilder.reserve(PrecomputedCG.size());
CGBuilder.reserve(PrecomputedCG.FToFunctionVertexTy.size());

for (const auto &[FunName, CallerIDs] : PrecomputedCG.items()) {
for (const auto &[FunName, CallerIDs] : PrecomputedCG.FToFunctionVertexTy) {
const auto &Fun = std::invoke(GetFunctionFromName, FunName);
if (!Fun) {
PHASAR_LOG_LEVEL_CAT(WARNING, "CallGraph",
Expand All @@ -277,11 +293,10 @@ CallGraph<N, F>::deserialize(const nlohmann::json &PrecomputedCG,
CEdges->reserve(CallerIDs.size());

for (const auto &JId : CallerIDs) {
auto Id = JId.get<size_t>();
const auto &CS = std::invoke(GetInstructionFromId, Id);
const auto &CS = std::invoke(GetInstructionFromId, JId);
if (!CS) {
PHASAR_LOG_LEVEL_CAT(WARNING, "CallGraph",
"Invalid CAll-Instruction Id: " << Id);
"Invalid Call-Instruction Id: " << JId);
}

CGBuilder.addCallEdge(CS, Fun);
Expand Down
34 changes: 34 additions & 0 deletions include/phasar/ControlFlow/CallGraphData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Maximilian Leo Huber and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"

#include <string>
#include <unordered_map>
#include <vector>

namespace psr {
struct CallGraphData {
// Mangled FunName --> [CS-IDs]
std::unordered_map<std::string, std::vector<uint32_t>> FToFunctionVertexTy{};

CallGraphData() noexcept = default;
void printAsJson(llvm::raw_ostream &OS);

static CallGraphData deserializeJson(const llvm::Twine &Path);
static CallGraphData loadJsonString(llvm::StringRef JsonAsString);
};

} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
10 changes: 9 additions & 1 deletion include/phasar/ControlFlow/ICFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ template <typename Derived> class ICFGBase {
void print(llvm::raw_ostream &OS = llvm::outs()) const {
self().printImpl(OS);
}

/// Prints the underlying call-graph as Json to the given output-stream
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const {
self().printAsJsonImpl(OS);
}

/// Returns the underlying call-graph as JSON
[[nodiscard]] nlohmann::json getAsJson() const {
[[nodiscard]] [[deprecated(
"Please use printAsJson() instead")]] nlohmann::json
getAsJson() const {
return self().getAsJsonImpl();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
using CFGBase::print;
using ICFGBase::print;

using ICFGBase::printAsJson;

using CFGBase::getAsJson;
using ICFGBase::getAsJson;

Expand All @@ -64,7 +66,8 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
[[nodiscard]] llvm::SmallVector<n_t, 2>
getReturnSitesOfCallAtImpl(n_t Inst) const;
void printImpl(llvm::raw_ostream &OS) const;
[[nodiscard]] nlohmann::json getAsJsonImpl() const;
void printAsJsonImpl(llvm::raw_ostream &OS) const;
[[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const;
[[nodiscard]] const CallGraph<n_t, f_t> &getCallGraphImpl() const noexcept;

llvm::LLVMContext BackwardRetsCtx;
Expand Down
16 changes: 6 additions & 10 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
#include "llvm/IR/Value.h"
#include "llvm/Support/raw_ostream.h"

#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include <memory>

namespace psr {
class LLVMTypeHierarchy;
Expand Down Expand Up @@ -92,13 +91,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, const LLVMProjectIRDB *IRDB);

explicit LLVMBasedICFG(const LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG);
// To avoid ambiguity with the first ctor (json implicitly converts to
// CallGraphAnalysisType for whatever reason)
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG)
: LLVMBasedICFG(static_cast<const LLVMProjectIRDB *>(IRDB),
SerializedCG) {}
const CallGraphData &SerializedCG);

// Deleter of LLVMTypeHierarchy may be unknown here...
~LLVMBasedICFG();
Expand Down Expand Up @@ -142,6 +135,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
using CFGBase::print;
using ICFGBase::print;

using ICFGBase::printAsJson;

using CFGBase::getAsJson;
using ICFGBase::getAsJson;

Expand All @@ -156,7 +151,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
[[nodiscard]] llvm::SmallVector<n_t, 2>
getReturnSitesOfCallAtImpl(n_t Inst) const;
void printImpl(llvm::raw_ostream &OS) const;
[[nodiscard]] nlohmann::json getAsJsonImpl() const;
void printAsJsonImpl(llvm::raw_ostream &OS) const;
[[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const;
[[nodiscard]] const LLVMBasedCallGraph &getCallGraphImpl() const noexcept {
return CG;
}
Expand Down
4 changes: 3 additions & 1 deletion include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ struct GeneralStatistics {
"instead")]] const std::set<const llvm::Instruction *> &
getRetResInstructions() const;

[[nodiscard]] nlohmann::json getAsJson() const;
[[nodiscard]] [[deprecated(
"Please use printAsJson() instead")]] nlohmann::json
getAsJson() const;
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
};

Expand Down
29 changes: 15 additions & 14 deletions include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ struct AliasInfoTraits<LLVMAliasGraph>
*
* @brief Represents the points-to graph of a function.
*/
class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
AliasInfoBaseUtils {
class [[deprecated("Use LLVMAliasSet Instead")]] LLVMAliasGraph
: public AnalysisPropertiesMixin<LLVMAliasGraph>,
AliasInfoBaseUtils {
using traits_t = AliasInfoTraits<LLVMAliasGraph>;

public:
Expand Down Expand Up @@ -126,9 +127,9 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
* 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,
AliasAnalysisType PATy =
AliasAnalysisType::CFLAnders);

/**
* @brief Returns true if graph contains 0 nodes.
Expand Down Expand Up @@ -162,15 +163,15 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
* @param F Function pointer
* @return Vector with pointers.
*/
std::vector<const llvm::Value *>
getPointersEscapingThroughReturnsForFunction(const llvm::Function *Fd) const;
std::vector<const llvm::Value *> getPointersEscapingThroughReturnsForFunction(
const llvm::Function *Fd) const;

/**
* @brief Checks if a given value is represented by a vertex in the points-to
* graph.
* @return True, the points-to graph contains the given value.
*/
bool containsValue(llvm::Value *V);
bool containsValue(llvm::Value * V);

/**
* The value-vertex-map maps each Value of the points-to graph to
Expand All @@ -192,8 +193,8 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
const graph_t &PAG;
};

static inline PointerVertexOrEdgePrinter
makePointerVertexOrEdgePrinter(const graph_t &PAG) {
static inline PointerVertexOrEdgePrinter makePointerVertexOrEdgePrinter(
const graph_t &PAG) {
return {PAG};
}

Expand All @@ -220,9 +221,9 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
AliasSetPtrTy getAliasSet(const llvm::Value *V,
const llvm::Instruction *I = nullptr);

AllocationSiteSetPtrTy
getReachableAllocationSites(const llvm::Value *V, bool IntraProcOnly = false,
const llvm::Instruction *I = nullptr);
AllocationSiteSetPtrTy getReachableAllocationSites(
const llvm::Value *V, bool IntraProcOnly = false,
const llvm::Instruction *I = nullptr);

[[nodiscard]] bool isInReachableAllocationSites(
const llvm::Value *V, const llvm::Value *PotentialValue,
Expand Down Expand Up @@ -251,7 +252,7 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,

void computeAliasGraph(const llvm::Value *V);

void computeAliasGraph(llvm::Function *F);
void computeAliasGraph(llvm::Function * F);

struct AllocationSiteDFSVisitor;
struct ReachabilityDFSVisitor;
Expand Down
7 changes: 6 additions & 1 deletion include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H
#define PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H

#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"
#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h"
#include "phasar/Pointer/AliasInfoBase.h"
#include "phasar/Pointer/AliasInfoTraits.h"
Expand Down Expand Up @@ -95,7 +96,11 @@ class LLVMAliasSet : public AnalysisPropertiesMixin<LLVMAliasSet>,

void print(llvm::raw_ostream &OS = llvm::outs()) const;

[[nodiscard]] nlohmann::json getAsJson() const;
[[nodiscard]] [[deprecated(
"Please use printAsJson() instead")]] nlohmann::json
getAsJson() const;

[[nodiscard]] LLVMAliasSetData getLLVMAliasSetData() const;

void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;

Expand Down
31 changes: 31 additions & 0 deletions include/phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Maximilian Leo Huber and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H
#define PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H

#include "llvm/Support/raw_ostream.h"

#include <string>

namespace psr {
struct LLVMAliasSetData {
std::vector<std::vector<std::string>> AliasSets;
std::vector<std::string> AnalyzedFunctions;

LLVMAliasSetData() noexcept = default;
void printAsJson(llvm::raw_ostream &OS);

static LLVMAliasSetData deserializeJson(const llvm::Twine &Path);
static LLVMAliasSetData loadJsonString(llvm::StringRef JsonAsString);
};

} // namespace psr

#endif // PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H
Loading

0 comments on commit 2e4b276

Please sign in to comment.