Skip to content

Commit f6ffb9b

Browse files
committed
partial merge
1 parent 09983ec commit f6ffb9b

18 files changed

Lines changed: 405 additions & 181 deletions

File tree

include/phasar/Controller/AnalysisController.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ class AnalysisController {
126126
AnalysisControllerEmitterOptions EmitterOptions,
127127
IFDSIDESolverConfig SolverConfig,
128128
const std::string &ProjectID = "default-phasar-project",
129-
const std::string &OutDirectory = "");
129+
const std::string &OutDirectory = "",
130+
const nlohmann::json &PrecomputedPointsToInfo = {});
130131

131132
~AnalysisController() = default;
132133

include/phasar/DB/ProjectIRDB.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class ProjectIRDB {
174174

175175
[[nodiscard]] std::size_t getNumGlobals() const;
176176

177-
[[nodiscard]] llvm::Instruction *getInstruction(std::size_t Id);
177+
[[nodiscard]] llvm::Instruction *getInstruction(std::size_t Id) const;
178178

179179
[[nodiscard]] static std::size_t getInstructionID(const llvm::Instruction *I);
180180

include/phasar/PhasarLLVM/Pointer/LLVMPointsToSet.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
#include "nlohmann/json.hpp"
1717

18+
#include "llvm/ADT/DenseMap.h"
1819
#include "llvm/ADT/DenseSet.h"
1920

21+
#include "phasar/DB/ProjectIRDB.h"
2022
#include "phasar/PhasarLLVM/Pointer/DynamicPointsToSetPtr.h"
2123
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
2224
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
@@ -80,8 +82,12 @@ class LLVMPointsToSet : public LLVMPointsToInfo {
8082
* UseLazyEvaluation is true, computes points-to-sets for functions that do
8183
* not use global variables on the fly
8284
*/
83-
LLVMPointsToSet(ProjectIRDB &IRDB, bool UseLazyEvaluation = true,
84-
PointerAnalysisType PATy = PointerAnalysisType::CFLAnders);
85+
explicit LLVMPointsToSet(
86+
ProjectIRDB &IRDB, bool UseLazyEvaluation = true,
87+
PointerAnalysisType PATy = PointerAnalysisType::CFLAnders);
88+
89+
explicit LLVMPointsToSet(ProjectIRDB &IRDB,
90+
const nlohmann::json &SerializedPTS);
8591

8692
~LLVMPointsToSet() override = default;
8793

include/phasar/PhasarLLVM/Pointer/PointsToSetOwner.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
#ifndef PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H
1111
#define PHASAR_PHASARLLVM_POINTER_POINTSTOSETOWNER_H
1212

13+
#include <functional>
14+
#include <memory>
1315
#include <memory_resource>
16+
#include <type_traits>
1417

1518
#include "llvm/ADT/DenseSet.h"
1619
#include "llvm/Support/ErrorHandling.h"
@@ -61,6 +64,25 @@ template <typename PointsToSetTy> class PointsToSetOwner {
6164

6265
void reserve(size_t Capacity) { OwnedPTS.reserve(Capacity); }
6366

67+
template <typename CallBackTy,
68+
typename = std::enable_if_t<
69+
std::is_invocable_v<CallBackTy, PointsToSetTy *>>>
70+
void forEachPointsToSet(CallBackTy &&CallBack) {
71+
for (auto &[PTS, Unused] : OwnedPTS) {
72+
std::invoke(std::forward<CallBackTy>(CallBack), PTS);
73+
}
74+
}
75+
76+
template <typename CallBackTy,
77+
typename = std::enable_if_t<
78+
std::is_invocable_v<CallBackTy, const PointsToSetTy *>>>
79+
void forEachPointsToSet(CallBackTy &&CallBack) const {
80+
for (auto &[PTS, Unused] : OwnedPTS) {
81+
std::invoke(std::forward<CallBackTy>(CallBack),
82+
static_cast<const PointsToSetTy *>(PTS));
83+
}
84+
}
85+
6486
private:
6587
std::pmr::polymorphic_allocator<PointsToSetTy> Alloc;
6688
llvm::DenseSet<PointsToSetTy *> OwnedPTS;

include/phasar/Utils/IO.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <memory>
2222
#include <string>
2323

24+
#include "nlohmann/json.hpp"
25+
2426
#include "llvm/Support/MemoryBuffer.h"
2527

2628
namespace psr {
@@ -30,6 +32,9 @@ std::string readTextFile(const std::filesystem::path &Path);
3032
std::unique_ptr<llvm::MemoryBuffer> readFile(const std::filesystem::path &Path);
3133
std::unique_ptr<llvm::MemoryBuffer> readFile(const llvm::Twine &Path);
3234

35+
nlohmann::json readJsonFile(const llvm::Twine &Path);
36+
nlohmann::json readJsonFile(const std::filesystem::path &Path);
37+
3338
void writeTextFile(const std::filesystem::path &Path, llvm::StringRef Content);
3439

3540
} // namespace psr

include/phasar/Utils/LLVMShorthands.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/IR/ModuleSlotTracker.h"
2626
#include "llvm/IR/Value.h"
2727

28+
#include "phasar/DB/ProjectIRDB.h"
2829
#include "phasar/Utils/Utilities.h"
2930

3031
namespace psr {
@@ -94,6 +95,11 @@ globalValuesUsedinFunction(const llvm::Function *F);
9495
*/
9596
std::string getMetaDataID(const llvm::Value *V);
9697

98+
/**
99+
* Revserses the getMetaDataID function
100+
*/
101+
const llvm::Value *fromMetaDataId(const ProjectIRDB &IRDB, llvm::StringRef Id);
102+
97103
/**
98104
* @brief Does less-than comparison based on the annotated ID.
99105
*

lib/Controller/AnalysisController.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ AnalysisController::AnalysisController(
8282
bool AutoGlobalSupport, const std::set<std::string> &EntryPoints,
8383
AnalysisStrategy Strategy, AnalysisControllerEmitterOptions EmitterOptions,
8484
IFDSIDESolverConfig SolverConfig, const std::string &ProjectID,
85-
const std::string &OutDirectory)
86-
: IRDB(IRDB), TH(IRDB), PT(IRDB, !needsToEmitPTA(EmitterOptions), PTATy),
85+
const std::string &OutDirectory,
86+
const nlohmann::json &PrecomputedPointsToInfo)
87+
: IRDB(IRDB), TH(IRDB),
88+
PT(PrecomputedPointsToInfo.empty()
89+
? LLVMPointsToSet(IRDB, !needsToEmitPTA(EmitterOptions), PTATy)
90+
: LLVMPointsToSet(IRDB, PrecomputedPointsToInfo)),
8791
ICF(IRDB, CGTy, EntryPoints, &TH, &PT, SoundnessLevel, AutoGlobalSupport),
8892
DataFlowAnalyses(std::move(DataFlowAnalyses)),
8993
AnalysisConfigs(std::move(AnalysisConfigs)), EntryPoints(EntryPoints),

lib/DB/ProjectIRDB.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,10 @@ std::size_t ProjectIRDB::getNumGlobals() const {
245245
return Ret;
246246
}
247247

248-
llvm::Instruction *ProjectIRDB::getInstruction(std::size_t Id) {
249-
if (IDInstructionMapping.count(Id)) {
250-
return IDInstructionMapping[Id];
248+
llvm::Instruction *ProjectIRDB::getInstruction(std::size_t Id) const {
249+
if (auto It = IDInstructionMapping.find(Id);
250+
It != IDInstructionMapping.end()) {
251+
return It->second;
251252
}
252253
return nullptr;
253254
}

lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ LLVMBasedCFG::getPredsOf(const llvm::Instruction *I) const {
7878

7979
std::vector<const llvm::Instruction *>
8080
LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const {
81-
8281
// case we wish to consider LLVM's debug instructions
8382
if (!IgnoreDbgInstructions) {
8483
if (const auto *NextInst = I->getNextNode()) {
@@ -88,7 +87,6 @@ LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const {
8887
false /*Only debug instructions*/)) {
8988
return {NextNonDbgInst};
9089
}
91-
9290
if (const auto *Branch = llvm::dyn_cast<llvm::BranchInst>(I);
9391
Branch && isStaticVariableLazyInitializationBranch(Branch)) {
9492
// Skip the "already initialized" case, such that the analysis is always
@@ -99,7 +97,6 @@ LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const {
9997
}
10098
return {NextInst};
10199
}
102-
103100
std::vector<const llvm::Instruction *> Successors;
104101
Successors.reserve(I->getNumSuccessors() + Successors.size());
105102
std::transform(

lib/PhasarLLVM/Pointer/LLVMPointsToSet.cpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <algorithm>
1111
#include <cassert>
1212
#include <cstdlib>
13+
#include <iomanip>
1314
#include <iostream>
1415
#include <iterator>
1516
#include <memory>
@@ -34,6 +35,10 @@
3435
#include "llvm/Support/ErrorHandling.h"
3536
#include "llvm/Support/FormatVariadic.h"
3637

38+
#include "boost/log/sources/severity_feature.hpp"
39+
40+
#include "nlohmann/json.hpp"
41+
3742
#include "phasar/DB/ProjectIRDB.h"
3843
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
3944
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
@@ -82,6 +87,61 @@ LLVMPointsToSet::LLVMPointsToSet(ProjectIRDB &IRDB, bool UseLazyEvaluation,
8287
<< "LLVMPointsToSet completed\n");
8388
}
8489

90+
LLVMPointsToSet::LLVMPointsToSet(ProjectIRDB &IRDB,
91+
const nlohmann::json &SerializedPTS)
92+
: PTA(IRDB) {
93+
// Assume, we already have validated the json schema
94+
95+
llvm::outs() << "Load precomputed points-to info from JSON\n";
96+
97+
const auto &Sets = SerializedPTS.at("PointsToSets");
98+
assert(Sets.is_array());
99+
const auto &Fns = SerializedPTS.at("AnalyzedFunctions");
100+
assert(Fns.is_array());
101+
102+
/// Deserialize the PointsToSets - an array of arrays (both are to be
103+
/// interpreted as sets of metadata-ids)
104+
105+
Owner.reserve(Sets.size());
106+
for (const auto &PtsJson : Sets) {
107+
assert(PtsJson.is_array());
108+
auto *PTS = Owner.acquire();
109+
for (auto Alias : PtsJson) {
110+
const auto *Inst = fromMetaDataId(IRDB, Alias.get<std::string>());
111+
if (!Inst) {
112+
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), WARNING)
113+
<< "Invalid Value-Id: " << Alias);
114+
continue;
115+
}
116+
117+
PointsToSets[Inst] = PTS;
118+
PTS->insert(Inst);
119+
}
120+
}
121+
122+
/// Deserialize the AnalyzedFunctions - an array of function-names (to be
123+
/// interpreted as set)
124+
125+
AnalyzedFunctions.reserve(Fns.size());
126+
for (const auto &F : Fns) {
127+
if (!F.is_string()) {
128+
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), WARNING)
129+
<< "Invalid Function Name: " << F);
130+
continue;
131+
}
132+
133+
const auto *IRFn = IRDB.getFunction(F.get<std::string>());
134+
135+
if (!IRFn) {
136+
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), WARNING)
137+
<< "Function: " << F << " not in the IRDB");
138+
continue;
139+
}
140+
141+
AnalyzedFunctions.insert(IRFn);
142+
}
143+
}
144+
85145
void LLVMPointsToSet::computeValuesPointsToSet(const llvm::Value *V) {
86146
if (!isInterestingPointer(V)) {
87147
// don't need to do anything
@@ -631,9 +691,35 @@ void LLVMPointsToSet::introduceAlias(
631691
mergePointsToSets(V1, V2);
632692
}
633693

634-
nlohmann::json LLVMPointsToSet::getAsJson() const { return ""_json; }
694+
nlohmann::json LLVMPointsToSet::getAsJson() const {
695+
nlohmann::json J;
696+
697+
/// Serialize the PointsToSets
698+
auto &Sets = J["PointsToSets"];
699+
Owner.forEachPointsToSet([&Sets](const PointsToSetTy *PTS) {
700+
auto PtsJson = nlohmann::json::array();
701+
for (const auto *Alias : *PTS) {
702+
auto Id = getMetaDataID(Alias);
703+
if (Id != "-1") {
704+
PtsJson.push_back(std::move(Id));
705+
}
706+
}
707+
if (!PtsJson.empty()) {
708+
Sets.push_back(std::move(PtsJson));
709+
}
710+
});
635711

636-
void LLVMPointsToSet::printAsJson(std::ostream &OS) const {}
712+
/// Serialize the AnalyzedFunctions
713+
auto &Fns = J["AnalyzedFunctions"];
714+
for (const auto *F : AnalyzedFunctions) {
715+
Fns.push_back(F->getName().str());
716+
}
717+
return J;
718+
}
719+
720+
void LLVMPointsToSet::printAsJson(std::ostream &OS) const {
721+
OS << std::setw(4) << getAsJson() << std::setw(0);
722+
}
637723

638724
void LLVMPointsToSet::print(std::ostream &OS) const {
639725
for (const auto &[V, PTS] : PointsToSets) {

0 commit comments

Comments
 (0)