Skip to content

Commit f17594d

Browse files
fabianbs96mxHuber
andauthored
Refactor getAsJson() (#725)
* unresolved ref to F/NToString * compiles * refactored CallGraph::deserialize() * refactored unittests, all fail * all unittests finally pass * code cleanup * refactoring * fixed function with no caller not being serialized * Fix Dependendency Installation (#707) * Do not install phasar's dependencies to the global namespace anymore * fix for in-tree build * out-factor the inclusion of LLVM and clang to a separate cmake file * Make PHASAR_CONFIG_INSTALL_DIR respect the CMAKE_INSTALL_PREFIX, even if that is not set at configure time * Fix in-tree build * backup DIBTH Data * DIBTH serialization code, untested * DIBTHData getDataFromJson Impl * improved de-/serialization impl w/o TypeToVertex * fixed DIBTHData TypeToVertex not compiling * fixed serialization bugs and unittests * DITHS Test fixes, 13 pass, 11 fail * DIBTH Ser Test, 1 failing Test left * GeneralStatisticsAnalysisData impl * LLVMAliasSetData impl * last printAsJson Impls * Final Impls, DIBTH Identifier Impl not working * changes + fixes from meeting * no equality of values DIBTH Test * fixed all bugs, all unittests pass * Fix crash in buildTypeGraph in the presence of typedefs * fixed LLVMAliasSetSerializationTest * Add more aggressive composite type filter * Refactor handling of DI type names * Implicit vertex index * Prioritize type id over type name as the latter may be ambiguous * Adapt DI TH test to identifiers as names * Fix vtable + transitive di th tests * Optimizing deprecation warnings for getAsJson * TypeTrait check current non functioning impl * fixed TypeHierarchySerialization Tests * Optimized deprecation warinings for getAsJson * debug code backup * Fix LLVMBasedTypeHierarchy * added operator<< statistics to printAsJson * Fix GeneralStatistics printAsJson + minor * Add some more deprecations * Fix now failing unittests * Changes from review --------- Co-authored-by: mxHuber <huber.maximilian.leo@gmail.com>
1 parent c1a75ed commit f17594d

41 files changed

Lines changed: 1309 additions & 228 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/phasar/ControlFlow/CFGBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ template <typename Derived> class CFGBase {
131131
void print(ByConstRef<f_t> Fun, llvm::raw_ostream &OS) const {
132132
self().printImpl(Fun, OS);
133133
}
134-
[[nodiscard]] nlohmann::json getAsJson(ByConstRef<f_t> Fun) const {
134+
[[nodiscard, deprecated("Please use printAsJson() instead")]] nlohmann::json
135+
getAsJson(ByConstRef<f_t> Fun) const {
135136
return self().getAsJsonImpl(Fun);
136137
}
137138

include/phasar/ControlFlow/CallGraph.h

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
#define PHASAR_CONTROLFLOW_CALLGRAPH_H
1212

1313
#include "phasar/ControlFlow/CallGraphBase.h"
14+
#include "phasar/ControlFlow/CallGraphData.h"
1415
#include "phasar/Utils/ByRef.h"
1516
#include "phasar/Utils/Logger.h"
1617
#include "phasar/Utils/StableVector.h"
1718
#include "phasar/Utils/Utilities.h"
1819

19-
#include "llvm/ADT/ArrayRef.h"
20-
#include "llvm/ADT/DenseMap.h"
21-
#include "llvm/ADT/STLExtras.h"
20+
#include "llvm/IR/Function.h"
2221

2322
#include "nlohmann/json.hpp"
2423

2524
#include <functional>
25+
#include <string>
2626
#include <utility>
2727
#include <vector>
2828

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

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

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

89+
template <typename FunctionIdGetter, typename InstIdGetter>
90+
void printAsJson(llvm::raw_ostream &OS, FunctionIdGetter GetFunctionId,
91+
InstIdGetter GetInstructionId) const {
92+
CallGraphData CGData;
93+
CGData.FToFunctionVertexTy.reserve(CallersOf.size());
94+
95+
for (const auto &[Fun, Callers] : CallersOf) {
96+
auto &JCallers =
97+
CGData.FToFunctionVertexTy[std::invoke(GetFunctionId, Fun)];
98+
99+
CGData.FToFunctionVertexTy.reserve(Callers->size());
100+
for (const auto &CS : *Callers) {
101+
JCallers.push_back(std::invoke(GetInstructionId, CS));
102+
}
103+
}
104+
105+
CGData.printAsJson(OS);
106+
}
107+
89108
/// Creates a JSON representation of this call-graph suitable for presistent
90109
/// storage.
91110
/// Use the ctor taking a json object for deserialization
92111
template <typename FunctionIdGetter, typename InstIdGetter>
93-
[[nodiscard]] nlohmann::json getAsJson(FunctionIdGetter GetFunctionId,
94-
InstIdGetter GetInstructionId) const {
112+
[[nodiscard]] [[deprecated(
113+
"Please use printAsJson() instead")]] nlohmann::json
114+
getAsJson(FunctionIdGetter GetFunctionId,
115+
InstIdGetter GetInstructionId) const {
95116
nlohmann::json J;
96117

97118
for (const auto &[Fun, Callers] : CallersOf) {
@@ -254,18 +275,13 @@ template <typename N, typename F> class CallGraphBuilder {
254275
template <typename N, typename F>
255276
template <typename FunctionGetter, typename InstructionGetter>
256277
[[nodiscard]] CallGraph<N, F>
257-
CallGraph<N, F>::deserialize(const nlohmann::json &PrecomputedCG,
278+
CallGraph<N, F>::deserialize(const CallGraphData &PrecomputedCG,
258279
FunctionGetter GetFunctionFromName,
259280
InstructionGetter GetInstructionFromId) {
260-
if (!PrecomputedCG.is_object()) {
261-
PHASAR_LOG_LEVEL_CAT(ERROR, "CallGraph", "Invalid Json. Expected object");
262-
return {};
263-
}
264-
265281
CallGraphBuilder<N, F> CGBuilder;
266-
CGBuilder.reserve(PrecomputedCG.size());
282+
CGBuilder.reserve(PrecomputedCG.FToFunctionVertexTy.size());
267283

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

279295
for (const auto &JId : CallerIDs) {
280-
auto Id = JId.get<size_t>();
281-
const auto &CS = std::invoke(GetInstructionFromId, Id);
296+
const auto &CS = std::invoke(GetInstructionFromId, JId);
282297
if (!CS) {
283298
PHASAR_LOG_LEVEL_CAT(WARNING, "CallGraph",
284-
"Invalid CAll-Instruction Id: " << Id);
299+
"Invalid Call-Instruction Id: " << JId);
285300
}
286301

287302
CGBuilder.addCallEdge(CS, Fun);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Maximilian Leo Huber and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
12+
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Support/raw_ostream.h"
15+
16+
#include <string>
17+
#include <unordered_map>
18+
#include <vector>
19+
20+
namespace psr {
21+
struct CallGraphData {
22+
// Mangled FunName --> [CS-IDs]
23+
std::unordered_map<std::string, std::vector<uint32_t>> FToFunctionVertexTy{};
24+
25+
CallGraphData() noexcept = default;
26+
void printAsJson(llvm::raw_ostream &OS);
27+
28+
static CallGraphData deserializeJson(const llvm::Twine &Path);
29+
static CallGraphData loadJsonString(llvm::StringRef JsonAsString);
30+
};
31+
32+
} // namespace psr
33+
34+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H

include/phasar/ControlFlow/ICFGBase.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,16 @@ template <typename Derived> class ICFGBase {
106106
void print(llvm::raw_ostream &OS = llvm::outs()) const {
107107
self().printImpl(OS);
108108
}
109+
110+
/// Prints the underlying call-graph as Json to the given output-stream
111+
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const {
112+
self().printAsJsonImpl(OS);
113+
}
114+
109115
/// Returns the underlying call-graph as JSON
110-
[[nodiscard]] nlohmann::json getAsJson() const {
116+
[[nodiscard]] [[deprecated(
117+
"Please use printAsJson() instead")]] nlohmann::json
118+
getAsJson() const {
111119
return self().getAsJsonImpl();
112120
}
113121

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
4444
using CFGBase::print;
4545
using ICFGBase::print;
4646

47+
using ICFGBase::printAsJson;
48+
4749
using CFGBase::getAsJson;
4850
using ICFGBase::getAsJson;
4951

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

7073
llvm::LLVMContext BackwardRetsCtx;

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
#include "llvm/IR/Value.h"
3434
#include "llvm/Support/raw_ostream.h"
3535

36-
#include "nlohmann/json.hpp"
37-
3836
#include <memory>
3937

4038
namespace psr {
@@ -100,7 +98,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
10098
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB);
10199

102100
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
103-
const nlohmann::json &SerializedCG);
101+
const CallGraphData &SerializedCG);
104102

105103
// Deleter of LLVMTypeHierarchy may be unknown here...
106104
~LLVMBasedICFG();
@@ -141,6 +139,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
141139
using CFGBase::print;
142140
using ICFGBase::print;
143141

142+
using ICFGBase::printAsJson;
143+
144144
using CFGBase::getAsJson;
145145
using ICFGBase::getAsJson;
146146

@@ -155,7 +155,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
155155
[[nodiscard]] llvm::SmallVector<n_t, 2>
156156
getReturnSitesOfCallAtImpl(n_t Inst) const;
157157
void printImpl(llvm::raw_ostream &OS) const;
158-
[[nodiscard]] nlohmann::json getAsJsonImpl() const;
158+
void printAsJsonImpl(llvm::raw_ostream &OS) const;
159+
[[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const;
159160
[[nodiscard]] const CallGraph<n_t, f_t> &getCallGraphImpl() const noexcept {
160161
return CG;
161162
}

include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ struct GeneralStatistics {
176176
"instead")]] const std::set<const llvm::Instruction *> &
177177
getRetResInstructions() const;
178178

179-
[[nodiscard]] nlohmann::json getAsJson() const;
179+
[[nodiscard]] [[deprecated(
180+
"Please use printAsJson() instead")]] nlohmann::json
181+
getAsJson() const;
180182
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
181183
};
182184

include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ struct AliasInfoTraits<LLVMAliasGraph>
5858
*
5959
* @brief Represents the points-to graph of a function.
6060
*/
61-
class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
62-
AliasInfoBaseUtils {
61+
class [[deprecated("Use LLVMAliasSet Instead")]] LLVMAliasGraph
62+
: public AnalysisPropertiesMixin<LLVMAliasGraph>,
63+
AliasInfoBaseUtils {
6364
using traits_t = AliasInfoTraits<LLVMAliasGraph>;
6465

6566
public:
@@ -126,9 +127,9 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
126127
* considered. False, if May and Must Aliases should be
127128
* considered.
128129
*/
129-
explicit LLVMAliasGraph(
130-
LLVMProjectIRDB &IRDB, bool UseLazyEvaluation = true,
131-
AliasAnalysisType PATy = AliasAnalysisType::CFLAnders);
130+
explicit LLVMAliasGraph(LLVMProjectIRDB & IRDB, bool UseLazyEvaluation = true,
131+
AliasAnalysisType PATy =
132+
AliasAnalysisType::CFLAnders);
132133

133134
/**
134135
* @brief Returns true if graph contains 0 nodes.
@@ -162,15 +163,15 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,
162163
* @param F Function pointer
163164
* @return Vector with pointers.
164165
*/
165-
std::vector<const llvm::Value *>
166-
getPointersEscapingThroughReturnsForFunction(const llvm::Function *Fd) const;
166+
std::vector<const llvm::Value *> getPointersEscapingThroughReturnsForFunction(
167+
const llvm::Function *Fd) const;
167168

168169
/**
169170
* @brief Checks if a given value is represented by a vertex in the points-to
170171
* graph.
171172
* @return True, the points-to graph contains the given value.
172173
*/
173-
bool containsValue(llvm::Value *V);
174+
bool containsValue(llvm::Value * V);
174175

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

195-
static inline PointerVertexOrEdgePrinter
196-
makePointerVertexOrEdgePrinter(const graph_t &PAG) {
196+
static inline PointerVertexOrEdgePrinter makePointerVertexOrEdgePrinter(
197+
const graph_t &PAG) {
197198
return {PAG};
198199
}
199200

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

223-
AllocationSiteSetPtrTy
224-
getReachableAllocationSites(const llvm::Value *V, bool IntraProcOnly = false,
225-
const llvm::Instruction *I = nullptr);
224+
AllocationSiteSetPtrTy getReachableAllocationSites(
225+
const llvm::Value *V, bool IntraProcOnly = false,
226+
const llvm::Instruction *I = nullptr);
226227

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

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

254-
void computeAliasGraph(llvm::Function *F);
255+
void computeAliasGraph(llvm::Function * F);
255256

256257
struct AllocationSiteDFSVisitor;
257258
struct ReachabilityDFSVisitor;

include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H
1111
#define PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H
1212

13+
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"
1314
#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h"
1415
#include "phasar/Pointer/AliasInfoBase.h"
1516
#include "phasar/Pointer/AliasInfoTraits.h"
@@ -95,7 +96,11 @@ class LLVMAliasSet : public AnalysisPropertiesMixin<LLVMAliasSet>,
9596

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

98-
[[nodiscard]] nlohmann::json getAsJson() const;
99+
[[nodiscard]] [[deprecated(
100+
"Please use printAsJson() instead")]] nlohmann::json
101+
getAsJson() const;
102+
103+
[[nodiscard]] LLVMAliasSetData getLLVMAliasSetData() const;
99104

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Maximilian Leo Huber and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H
11+
#define PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H
12+
13+
#include "llvm/Support/raw_ostream.h"
14+
15+
#include <string>
16+
17+
namespace psr {
18+
struct LLVMAliasSetData {
19+
std::vector<std::vector<std::string>> AliasSets;
20+
std::vector<std::string> AnalyzedFunctions;
21+
22+
LLVMAliasSetData() noexcept = default;
23+
void printAsJson(llvm::raw_ostream &OS);
24+
25+
static LLVMAliasSetData deserializeJson(const llvm::Twine &Path);
26+
static LLVMAliasSetData loadJsonString(llvm::StringRef JsonAsString);
27+
};
28+
29+
} // namespace psr
30+
31+
#endif // PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H

0 commit comments

Comments
 (0)