Skip to content

Commit

Permalink
Merge branch 'development' into f-OptionalEFComposeJoin
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbs96 authored Oct 22, 2024
2 parents cad8c02 + bb86c25 commit a452156
Show file tree
Hide file tree
Showing 61 changed files with 2,001 additions and 657 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
1 change: 1 addition & 0 deletions include/phasar/PhasarLLVM/ControlFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_H

#include "phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
Expand Down
31 changes: 31 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.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:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
#define PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H

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

#include <string>
#include <vector>

namespace psr {
class LLVMProjectIRDB;

[[nodiscard]] std::vector<const llvm::Function *>
getEntryFunctions(const LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> EntryPoints);

[[nodiscard]] std::vector<llvm::Function *>
getEntryFunctionsMut(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> EntryPoints);
} // namespace psr

#endif // PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
45 changes: 45 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H

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

namespace psr {
class LLVMProjectIRDB;

class GlobalCtorsDtorsModel {
public:
static constexpr llvm::StringLiteral ModelName =
"__psrCRuntimeGlobalCtorsModel";

static constexpr llvm::StringLiteral DtorModelName =
"__psrCRuntimeGlobalDtorsModel";

static constexpr llvm::StringLiteral DtorsCallerName =
"__psrGlobalDtorsCaller";

static constexpr llvm::StringLiteral UserEntrySelectorName =
"__psrCRuntimeUserEntrySelector";

static llvm::Function *
buildModel(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<llvm::Function *> UserEntryPoints);
static llvm::Function *
buildModel(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> UserEntryPoints);

/// Returns true, if a function was generated by phasar.
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &F) noexcept;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
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
25 changes: 25 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H

#include "phasar/ControlFlow/CallGraph.h"

namespace llvm {
class Instruction;
class Function;
} // namespace llvm

namespace psr {
using LLVMBasedCallGraph =
CallGraph<const llvm::Instruction *, const llvm::Function *>;
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
49 changes: 49 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H

#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/Utils/Soundness.h"

namespace psr {
class LLVMProjectIRDB;
enum class CallGraphAnalysisType;
class LLVMTypeHierarchy;
class LLVMVFTableProvider;
class Resolver;

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
Soundness S = Soundness::Soundy);
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
Loading

0 comments on commit a452156

Please sign in to comment.