Skip to content

Commit 5ee184e

Browse files
committed
optimized type hierarchy's vertex properties
1 parent da6dffa commit 5ee184e

3 files changed

Lines changed: 50 additions & 23 deletions

File tree

include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@
1818
#define PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMTYPEHIERARCHY_H_
1919

2020
#include <iostream>
21+
#include <optional>
2122
#include <set>
2223
#include <string>
2324
#include <unordered_map>
2425
#include <unordered_set>
2526
#include <vector>
2627

27-
#include <gtest/gtest_prod.h>
28-
2928
#include <boost/graph/adjacency_list.hpp>
3029
#include <boost/graph/graph_traits.hpp>
3130

31+
#include <llvm/ADT/StringRef.h>
32+
33+
#include <gtest/gtest_prod.h>
34+
3235
#include <json.hpp>
3336

3437
#include <phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h>
@@ -38,6 +41,7 @@ namespace llvm {
3841
class Module;
3942
class StructType;
4043
class Function;
44+
class GlobalVariable;
4145
} // namespace llvm
4246

4347
namespace psr {
@@ -57,9 +61,9 @@ class LLVMTypeHierarchy
5761
VertexProperties() = default;
5862
VertexProperties(const llvm::StructType *Type);
5963
const llvm::StructType *Type = nullptr;
60-
std::string TypeName = "";
61-
LLVMVFTable VFT;
64+
std::optional<LLVMVFTable> VFT;
6265
std::set<const llvm::StructType *> ReachableTypes;
66+
std::string getTypeName() const;
6367
};
6468

6569
/// Edges in the class hierarchy graph doesn't hold any additional
@@ -203,6 +207,25 @@ class LLVMTypeHierarchy
203207
*/
204208
void printTransitiveClosure(std::ostream &OS = std::cout) const;
205209

210+
// provide a VertexPropertyWrite to tell boost how to write a vertex
211+
class TypeHierarchyVertexWriter {
212+
public:
213+
TypeHierarchyVertexWriter(const bidigraph_t &TyGraph) : TyGraph(TyGraph) {}
214+
template <class VertexOrEdge>
215+
void operator()(std::ostream &out, const VertexOrEdge &v) const {
216+
out << "[label=\"" << TyGraph[v].getTypeName() << "\"]";
217+
}
218+
219+
private:
220+
const bidigraph_t &TyGraph;
221+
};
222+
223+
// a function to conveniently create this writer
224+
TypeHierarchyVertexWriter
225+
makeTypeHierarchyVertexWriter(const bidigraph_t &TyGraph) const {
226+
return TypeHierarchyVertexWriter(TyGraph);
227+
}
228+
206229
/**
207230
* @brief Prints the class hierarchy to an ostream in dot format.
208231
* @param an outputstream

lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <llvm/IR/Constants.h>
3232
#include <llvm/IR/Function.h>
33+
#include <llvm/IR/GlobalVariable.h>
3334
#include <llvm/IR/InstIterator.h>
3435
#include <llvm/IR/Instructions.h>
3536
#include <llvm/IR/Module.h>
@@ -61,8 +62,11 @@ const std::string LLVMTypeHierarchy::TypeInfoPrefixDemang = "typeinfo for ";
6162

6263
LLVMTypeHierarchy::VertexProperties::VertexProperties(
6364
const llvm::StructType *Type)
64-
: Type(Type), TypeName(Type->getStructName().str()), VFT(),
65-
ReachableTypes({Type}) {}
65+
: Type(Type), ReachableTypes({Type}) {}
66+
67+
std::string LLVMTypeHierarchy::VertexProperties::getTypeName() const {
68+
return Type->getStructName().str();
69+
}
6670

6771
LLVMTypeHierarchy::LLVMTypeHierarchy(ProjectIRDB &IRDB) {
6872
PAMM_GET_INSTANCE;
@@ -337,18 +341,16 @@ bool LLVMTypeHierarchy::empty() const { return size() == 0; }
337341

338342
void LLVMTypeHierarchy::print(std::ostream &OS) const {
339343
OS << "Type Hierarchy:\n";
340-
boost::print_graph(TypeGraph,
341-
boost::get(&VertexProperties::TypeName, TypeGraph), OS);
342-
// vertex_iterator_t ui, ui_end;
343-
// for (boost::tie(ui, ui_end) = boost::vertices(TypeGraph); ui != ui_end;
344-
// ++ui) {
345-
// OS << TypeGraph[*ui].TypeName << " --> ";
346-
// out_edge_iterator_t ei, ei_end;
347-
// for (boost::tie(ei, ei_end) = boost::out_edges(*ui, TypeGraph); ei !=
348-
// ei_end; ++ei)
349-
// OS << TypeGraph[target(*ei, TypeGraph)].TypeName << " ";
350-
// OS << '\n';
351-
// }
344+
vertex_iterator_t ui, ui_end;
345+
for (boost::tie(ui, ui_end) = boost::vertices(TypeGraph); ui != ui_end;
346+
++ui) {
347+
OS << TypeGraph[*ui].getTypeName() << " --> ";
348+
out_edge_iterator_t ei, ei_end;
349+
for (boost::tie(ei, ei_end) = boost::out_edges(*ui, TypeGraph);
350+
ei != ei_end; ++ei)
351+
OS << TypeGraph[target(*ei, TypeGraph)].getTypeName() << " ";
352+
OS << '\n';
353+
}
352354
OS << "VFTables:\n";
353355
for (const auto &[Ty, VFT] : TypeVFTMap) {
354356
OS << "Virtual function table for: " << Ty->getName().str() << '\n';
@@ -365,12 +367,12 @@ nlohmann::json LLVMTypeHierarchy::getAsJson() const {
365367
// iterate all graph vertices
366368
for (boost::tie(vi_v, vi_v_end) = boost::vertices(TypeGraph);
367369
vi_v != vi_v_end; ++vi_v) {
368-
J[PhasarConfig::JsonTypeHierarchyID()][TypeGraph[*vi_v].TypeName];
370+
J[PhasarConfig::JsonTypeHierarchyID()][TypeGraph[*vi_v].getTypeName()];
369371
// iterate all out edges of vertex vi_v
370372
for (boost::tie(ei, ei_end) = boost::out_edges(*vi_v, TypeGraph);
371373
ei != ei_end; ++ei) {
372-
J[PhasarConfig::JsonTypeHierarchyID()][TypeGraph[*vi_v].TypeName] +=
373-
TypeGraph[boost::target(*ei, TypeGraph)].TypeName;
374+
J[PhasarConfig::JsonTypeHierarchyID()][TypeGraph[*vi_v].getTypeName()] +=
375+
TypeGraph[boost::target(*ei, TypeGraph)].getTypeName();
374376
}
375377
}
376378
return J;
@@ -424,8 +426,7 @@ nlohmann::json LLVMTypeHierarchy::getAsJson() const {
424426

425427
void LLVMTypeHierarchy::printAsDot(std::ostream &OS) const {
426428
boost::write_graphviz(OS, TypeGraph,
427-
boost::make_label_writer(boost::get(
428-
&VertexProperties::TypeName, TypeGraph)));
429+
makeTypeHierarchyVertexWriter(TypeGraph));
429430
}
430431

431432
// void LLVMTypeHierarchy::printGraphAsDot(ostream &out) {

tools/example-tool/myphasartool.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*****************************************************************************/
99

1010
#include <iostream>
11+
#include <fstream>
1112

1213
#include <boost/filesystem/operations.hpp>
1314

@@ -49,6 +50,8 @@ int main(int argc, const char **argv) {
4950
LLVMBasedICFG I(DB, CallGraphAnalysisType::OTF, {"main"}, &H, &P);
5051
// print inter-procedural control-flow graph
5152
I.print();
53+
std::ofstream ofs("cg.dot");
54+
I.printAsDot(ofs);
5255
// IFDS template parametrization test
5356
std::cout << "Testing IFDS:\n";
5457
IFDSLinearConstantAnalysis L(&DB, &H, &I, &P, {"main"});

0 commit comments

Comments
 (0)