|
10 | 10 | #include <algorithm> |
11 | 11 | #include <cassert> |
12 | 12 | #include <cstdlib> |
| 13 | +#include <iomanip> |
13 | 14 | #include <iostream> |
14 | 15 | #include <iterator> |
15 | 16 | #include <memory> |
|
34 | 35 | #include "llvm/Support/ErrorHandling.h" |
35 | 36 | #include "llvm/Support/FormatVariadic.h" |
36 | 37 |
|
| 38 | +#include "boost/log/sources/severity_feature.hpp" |
| 39 | + |
| 40 | +#include "nlohmann/json.hpp" |
| 41 | + |
37 | 42 | #include "phasar/DB/ProjectIRDB.h" |
38 | 43 | #include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h" |
39 | 44 | #include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h" |
@@ -82,6 +87,61 @@ LLVMPointsToSet::LLVMPointsToSet(ProjectIRDB &IRDB, bool UseLazyEvaluation, |
82 | 87 | << "LLVMPointsToSet completed\n"); |
83 | 88 | } |
84 | 89 |
|
| 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 | + |
85 | 145 | void LLVMPointsToSet::computeValuesPointsToSet(const llvm::Value *V) { |
86 | 146 | if (!isInterestingPointer(V)) { |
87 | 147 | // don't need to do anything |
@@ -631,9 +691,35 @@ void LLVMPointsToSet::introduceAlias( |
631 | 691 | mergePointsToSets(V1, V2); |
632 | 692 | } |
633 | 693 |
|
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 | + }); |
635 | 711 |
|
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 | +} |
637 | 723 |
|
638 | 724 | void LLVMPointsToSet::print(std::ostream &OS) const { |
639 | 725 | for (const auto &[V, PTS] : PointsToSets) { |
|
0 commit comments