Skip to content

Commit 8851fe9

Browse files
committed
optimized pag's vertex and edge properties
1 parent 184e9a3 commit 8851fe9

10 files changed

Lines changed: 83 additions & 70 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class LLVMBasedBackwardsICFG
9898

9999
void printAsDot(std::ostream &OS) const;
100100

101-
void printInternalPTGAsDot(const std::string &filename);
101+
void printInternalPTGAsDot(std::ostream &OS) const;
102102

103103
using LLVMBasedBackwardCFG::getAsJson; // tell the compiler we wish to have
104104
// both prints

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class LLVMBasedICFG
7575
const llvm::Function *F = nullptr;
7676
VertexProperties() = default;
7777
VertexProperties(const llvm::Function *F);
78-
std::string getFunctionName() const;
78+
std::string getFunctionName() const;
7979
};
8080

8181
// The EdgeProperties for our call-graph.
@@ -160,7 +160,7 @@ class LLVMBasedICFG
160160
using LLVMBasedCFG::print; // tell the compiler we wish to have both prints
161161
void print(std::ostream &OS = std::cout) const override;
162162

163-
// provide a VertexPropertyWrite to tell boost how to write a vertex
163+
// provide a VertexPropertyWrite to tell boost how to write a vertex
164164
class CallGraphVertexWriter {
165165
public:
166166
CallGraphVertexWriter(const bidigraph_t &CGraph) : CGraph(CGraph) {}
@@ -193,14 +193,13 @@ class LLVMBasedICFG
193193
};
194194

195195
// a function to conveniently create the edge writer
196-
CallGraphEdgeWriter
197-
makeCallGraphEdgeWriter(const bidigraph_t &CGraph) const {
196+
CallGraphEdgeWriter makeCallGraphEdgeWriter(const bidigraph_t &CGraph) const {
198197
return CallGraphEdgeWriter(CGraph);
199198
}
200199

201200
void printAsDot(std::ostream &OS = std::cout) const;
202201

203-
void printInternalPTGAsDot(const std::string &filename);
202+
void printInternalPTGAsDot(std::ostream &OS = std::cout) const;
204203

205204
using LLVMBasedCFG::getAsJson; // tell the compiler we wish to have both
206205
// prints

include/phasar/PhasarLLVM/Pointer/LLVMPointsToGraph.h

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,20 @@ class PointsToGraph {
7474
* Variable or a formal Argument.
7575
*/
7676
const llvm::Value *V = nullptr;
77-
/// Holds the llvm IR code for that vertex.
78-
std::string IR;
79-
8077
VertexProperties() = default;
8178
VertexProperties(const llvm::Value *v);
79+
std::string getValueAsString() const;
8280
};
8381

8482
/**
8583
* @brief Holds the information of an edge in the points-to graph.
8684
*/
8785
struct EdgeProperties {
88-
/// This might be an Instruction, in particular a Call Instruction.
86+
/// This may contain a call or invoke instruction.
8987
const llvm::Value *V = nullptr;
90-
/// Holds the llvm IR code for that edge.
91-
std::string IR;
92-
9388
EdgeProperties() = default;
9489
EdgeProperties(const llvm::Value *v);
90+
std::string getValueAsString() const;
9591
};
9692

9793
/// Data structure for holding the points-to graph.
@@ -106,9 +102,9 @@ class PointsToGraph {
106102
typedef boost::graph_traits<graph_t>::edge_descriptor edge_t;
107103

108104
/// The type for a vertex iterator.
109-
typedef boost::graph_traits<graph_t>::vertex_iterator vertex_iterator_t;
110-
typedef boost::graph_traits<graph_t>::out_edge_iterator out_edge_iterator_t;
111-
typedef boost::graph_traits<graph_t>::in_edge_iterator in_edge_iterator_t;
105+
typedef boost::graph_traits<graph_t>::vertex_iterator vertex_iterator;
106+
typedef boost::graph_traits<graph_t>::out_edge_iterator out_edge_iterator;
107+
typedef boost::graph_traits<graph_t>::in_edge_iterator in_edge_iterator;
112108

113109
/// Set of functions that allocate heap memory, e.g. new, new[], malloc.
114110
inline const static std::set<std::string> HeapAllocationFunctions = {
@@ -236,11 +232,29 @@ class PointsToGraph {
236232
*/
237233
void print(std::ostream &OS = std::cout) const;
238234

235+
class PointerVertexOrEdgePrinter {
236+
public:
237+
PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(PAG) {}
238+
template <class VertexOrEdge>
239+
void operator()(std::ostream &out, const VertexOrEdge &v) const {
240+
out << "[label=\"" << PAG[v].getValueAsString() << "\"]";
241+
}
242+
243+
private:
244+
const graph_t &PAG;
245+
};
246+
247+
static inline PointerVertexOrEdgePrinter
248+
makePointerVertexOrEdgePrinter(const graph_t &PAG) {
249+
return PointerVertexOrEdgePrinter(PAG);
250+
}
251+
239252
/**
240-
* @brief Prints the points-to graph as a .dot file.
241-
* @param filename Filename of the .dot file.
253+
* @brief Prints the points-to graph in .dot format to the given output
254+
* stream.
255+
* @param outputstream.
242256
*/
243-
void printAsDot(const std::string &filename);
257+
void printAsDot(std::ostream &OS = std::cout) const;
244258

245259
size_t getNumVertices() const;
246260

include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ class LLVMTypeHierarchy
8383
typedef boost::graph_traits<bidigraph_t>::edge_descriptor edge_t;
8484
// Let us have some further handy typedefs.
8585
typedef boost::graph_traits<bidigraph_t>::vertex_iterator vertex_iterator;
86-
typedef boost::graph_traits<bidigraph_t>::out_edge_iterator
87-
out_edge_iterator;
86+
typedef boost::graph_traits<bidigraph_t>::out_edge_iterator out_edge_iterator;
8887
typedef boost::graph_traits<bidigraph_t>::in_edge_iterator in_edge_iterator;
8988

9089
private:

lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,8 @@ void LLVMBasedBackwardsICFG::printAsDot(std::ostream &OS) const {
153153
ForwardICFG.printAsDot(OS);
154154
}
155155

156-
void LLVMBasedBackwardsICFG::printInternalPTGAsDot(
157-
const std::string &filename) {
158-
ForwardICFG.printInternalPTGAsDot(filename);
156+
void LLVMBasedBackwardsICFG::printInternalPTGAsDot(std::ostream &OS) const {
157+
ForwardICFG.printInternalPTGAsDot(OS);
159158
}
160159

161160
nlohmann::json LLVMBasedBackwardsICFG::getAsJson() const {

lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#include <phasar/DB/ProjectIRDB.h>
4848

49+
#include <phasar/PhasarLLVM/Pointer/LLVMPointsToGraph.h>
4950
#include <phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h>
5051

5152
#include <phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h>
@@ -525,14 +526,11 @@ void LLVMBasedICFG::printAsDot(std::ostream &OS) const {
525526
makeCallGraphEdgeWriter(CallGraph));
526527
}
527528

528-
void LLVMBasedICFG::printInternalPTGAsDot(const string &filename) {
529-
ofstream ofs(filename);
529+
void LLVMBasedICFG::printInternalPTGAsDot(std::ostream &OS) const {
530530
boost::write_graphviz(
531-
ofs, WholeModulePTG.PAG,
532-
boost::make_label_writer(
533-
boost::get(&PointsToGraph::VertexProperties::IR, WholeModulePTG.PAG)),
534-
boost::make_label_writer(
535-
boost::get(&PointsToGraph::EdgeProperties::IR, WholeModulePTG.PAG)));
531+
OS, WholeModulePTG.PAG,
532+
PointsToGraph::makePointerVertexOrEdgePrinter(WholeModulePTG.PAG),
533+
PointsToGraph::makePointerVertexOrEdgePrinter(WholeModulePTG.PAG));
536534
}
537535

538536
nlohmann::json LLVMBasedICFG::getAsJson() const {

lib/PhasarLLVM/Plugins/ICFGTestPlugin.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ std::string ICFGTestPlugin::getFunctionName(ICFGTestPlugin::m_t fun) const {
9999

100100
void ICFGTestPlugin::print(ICFGTestPlugin::m_t F, std::ostream &OS) const {}
101101

102-
nlohmann::json ICFGTestPlugin::getAsJson(ICFGTestPlugin::m_t F) const { return ""; }
102+
nlohmann::json ICFGTestPlugin::getAsJson(ICFGTestPlugin::m_t F) const {
103+
return "";
104+
}
103105

104106
// ICFG parts
105107

lib/PhasarLLVM/Pointer/LLVMPointsToGraph.cpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,16 @@ struct PointsToGraph::ReachabilityDFSVisitor : boost::default_dfs_visitor {
117117
// points-to graph internal stuff
118118

119119
PointsToGraph::VertexProperties::VertexProperties(const llvm::Value *V)
120-
: V(V), IR(llvmIRToString(V)) {
121-
// WARNING: equivalent to llvmIRToString
122-
// WARNING 2 : really really really slow (yes it is)
120+
: V(V) {}
121+
122+
std::string PointsToGraph::VertexProperties::getValueAsString() const {
123+
return llvmIRToString(V);
123124
}
124125

125-
PointsToGraph::EdgeProperties::EdgeProperties(const llvm::Value *V)
126-
: V(V), IR(llvmIRToString(V)) {
127-
// WARNING: equivalent to llvmIRToString
128-
// WARNING 2 : really really really slow (yes it is)
126+
PointsToGraph::EdgeProperties::EdgeProperties(const llvm::Value *V) : V(V) {}
127+
128+
std::string PointsToGraph::EdgeProperties::getValueAsString() const {
129+
return llvmIRToString(V);
129130
}
130131

131132
// points-to graph stuff
@@ -235,7 +236,7 @@ PointsToGraph::PointsToGraph(llvm::Function *F, llvm::AAResults &AA) {
235236
vector<pair<unsigned, const llvm::Value *>>
236237
PointsToGraph::getPointersEscapingThroughParams() {
237238
vector<pair<unsigned, const llvm::Value *>> escaping_pointers;
238-
for (pair<vertex_iterator_t, vertex_iterator_t> vp = boost::vertices(PAG);
239+
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
239240
vp.first != vp.second; ++vp.first) {
240241
if (const llvm::Argument *arg =
241242
llvm::dyn_cast<llvm::Argument>(PAG[*vp.first].V)) {
@@ -248,7 +249,7 @@ PointsToGraph::getPointersEscapingThroughParams() {
248249
vector<const llvm::Value *>
249250
PointsToGraph::getPointersEscapingThroughReturns() const {
250251
vector<const llvm::Value *> escaping_pointers;
251-
for (pair<vertex_iterator_t, vertex_iterator_t> vp = boost::vertices(PAG);
252+
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
252253
vp.first != vp.second; ++vp.first) {
253254
for (auto user : PAG[*vp.first].V->users()) {
254255
if (llvm::isa<llvm::ReturnInst>(user)) {
@@ -263,7 +264,7 @@ vector<const llvm::Value *>
263264
PointsToGraph::getPointersEscapingThroughReturnsForFunction(
264265
const llvm::Function *F) const {
265266
vector<const llvm::Value *> escaping_pointers;
266-
for (pair<vertex_iterator_t, vertex_iterator_t> vp = boost::vertices(PAG);
267+
for (pair<vertex_iterator, vertex_iterator> vp = boost::vertices(PAG);
267268
vp.first != vp.second; ++vp.first) {
268269
for (auto user : PAG[*vp.first].V->users()) {
269270
if (auto R = llvm::dyn_cast<llvm::ReturnInst>(user)) {
@@ -289,7 +290,7 @@ set<const llvm::Value *> PointsToGraph::getReachableAllocationSites(
289290
}
290291

291292
bool PointsToGraph::containsValue(llvm::Value *V) {
292-
pair<vertex_iterator_t, vertex_iterator_t> vp;
293+
pair<vertex_iterator, vertex_iterator> vp;
293294
for (vp = boost::vertices(PAG); vp.first != vp.second; ++vp.first)
294295
if (PAG[*vp.first].V == V)
295296
return true;
@@ -353,33 +354,37 @@ bool PointsToGraph::representsSingleFunction() {
353354
void PointsToGraph::print(std::ostream &OS) const {
354355
for (const auto &Fn : ContainedFunctions) {
355356
cout << "PointsToGraph for " << Fn << ":\n";
356-
boost::print_graph(
357-
PAG, boost::get(&PointsToGraph::VertexProperties::IR, PAG), OS);
357+
vertex_iterator ui, ui_end;
358+
for (boost::tie(ui, ui_end) = boost::vertices(PAG); ui != ui_end; ++ui) {
359+
OS << PAG[*ui].getValueAsString() << " <--> ";
360+
out_edge_iterator ei, ei_end;
361+
for (boost::tie(ei, ei_end) = boost::out_edges(*ui, PAG); ei != ei_end;
362+
++ei) {
363+
OS << PAG[target(*ei, PAG)].getValueAsString() << " ";
364+
}
365+
OS << '\n';
366+
}
358367
}
359368
}
360369

361-
void PointsToGraph::printAsDot(const string &filename) {
362-
ofstream ofs(filename);
363-
boost::write_graphviz(ofs, PAG,
364-
boost::make_label_writer(boost::get(
365-
&PointsToGraph::VertexProperties::IR, PAG)),
366-
boost::make_label_writer(boost::get(
367-
&PointsToGraph::EdgeProperties::IR, PAG)));
370+
void PointsToGraph::printAsDot(std::ostream &OS) const {
371+
boost::write_graphviz(OS, PAG, makePointerVertexOrEdgePrinter(PAG),
372+
makePointerVertexOrEdgePrinter(PAG));
368373
}
369374

370375
nlohmann::json PointsToGraph::getAsJson() {
371376
nlohmann::json J;
372-
vertex_iterator_t vi_v, vi_v_end;
373-
out_edge_iterator_t ei, ei_end;
377+
vertex_iterator vi_v, vi_v_end;
378+
out_edge_iterator ei, ei_end;
374379
// iterate all graph vertices
375380
for (boost::tie(vi_v, vi_v_end) = boost::vertices(PAG); vi_v != vi_v_end;
376381
++vi_v) {
377-
J[PhasarConfig::JsonPointToGraphID()][llvmIRToString(PAG[*vi_v].V)];
382+
J[PhasarConfig::JsonPointToGraphID()][PAG[*vi_v].getValueAsString()];
378383
// iterate all out edges of vertex vi_v
379384
for (boost::tie(ei, ei_end) = boost::out_edges(*vi_v, PAG); ei != ei_end;
380385
++ei) {
381-
J[PhasarConfig::JsonPointToGraphID()][llvmIRToString(PAG[*vi_v].V)] +=
382-
llvmIRToString(PAG[boost::target(*ei, PAG)].V);
386+
J[PhasarConfig::JsonPointToGraphID()][PAG[*vi_v].getValueAsString()] +=
387+
PAG[boost::target(*ei, PAG)].getValueAsString();
383388
}
384389
}
385390
return J;
@@ -398,7 +403,7 @@ void PointsToGraph::mergeWith(const PointsToGraph *Other,
398403
copy_graph<PointsToGraph::graph_t, PointsToGraph::vertex_t>(PAG,
399404
Other->PAG);
400405
ValueVertexMap.clear();
401-
vertex_iterator_t vi, vi_end;
406+
vertex_iterator vi, vi_end;
402407
for (boost::tie(vi, vi_end) = boost::vertices(PAG); vi != vi_end; ++vi) {
403408
ValueVertexMap.insert(make_pair(PAG[*vi].V, *vi));
404409
}
@@ -447,7 +452,7 @@ void PointsToGraph::mergeWith(
447452
PointsToGraph::EdgeProperties, const llvm::Instruction *>(
448453
PAG, Other.PAG, v_in_g1_u_in_g2);
449454
ValueVertexMap.clear();
450-
vertex_iterator_t vi, vi_end;
455+
vertex_iterator vi, vi_end;
451456
for (boost::tie(vi, vi_end) = boost::vertices(PAG); vi != vi_end; ++vi) {
452457
ValueVertexMap.insert(make_pair(PAG[*vi].V, *vi));
453458
}
@@ -478,10 +483,9 @@ void PointsToGraph::mergeWith(PointsToGraph *Other, llvm::ImmutableCallSite CS,
478483
}
479484
} else {
480485
ContainedFunctions.insert(F->getName().str());
481-
// TODO this function has to check if F's points-to graph is already merged
482-
// into the 'this' points-to graph. If so, is is not allowed to copy it a
483-
// second
484-
// time into 'this' PAG.
486+
// TODO this function has to check if F's points-to graph is already
487+
// merged into the 'this' points-to graph. If so, is is not allowed to
488+
// copy it a second time into 'this' PAG.
485489
vector<pair<PointsToGraph::vertex_t, PointsToGraph::vertex_t>>
486490
v_in_g1_u_in_g2;
487491
for (unsigned i = 0; i < CS.getNumArgOperands(); ++i) {
@@ -509,8 +513,8 @@ void PointsToGraph::mergeWith(PointsToGraph *Other, llvm::ImmutableCallSite CS,
509513
typename std::vector<PointsToGraph::vertex_t>::iterator, index_map_t,
510514
PointsToGraph::vertex_t, PointsToGraph::vertex_t &>
511515
IsoMap;
512-
// for more generic graphs, one can try typedef std::map<vertex_t, vertex_t>
513-
// IsoMap;
516+
// for more generic graphs, one can try typedef std::map<vertex_t,
517+
// vertex_t> IsoMap;
514518
vector<PointsToGraph::vertex_t> orig2copy_data(
515519
boost::num_vertices(Other->PAG));
516520
IsoMap mapV = boost::make_iterator_property_map(
@@ -523,7 +527,7 @@ void PointsToGraph::mergeWith(PointsToGraph *Other, llvm::ImmutableCallSite CS,
523527
}
524528
}
525529
ValueVertexMap.clear();
526-
vertex_iterator_t vi, vi_end;
530+
vertex_iterator vi, vi_end;
527531
for (boost::tie(vi, vi_end) = boost::vertices(PAG); vi != vi_end; ++vi) {
528532
ValueVertexMap.insert(make_pair(PAG[*vi].V, *vi));
529533
}

tools/example-tool/myphasartool.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ int main(int argc, const char **argv) {
5050
LLVMBasedICFG I(DB, CallGraphAnalysisType::OTF, {"main"}, &H, &P);
5151
// print inter-procedural control-flow graph
5252
I.print();
53-
std::ofstream ofs("cg.dot");
54-
I.printAsDot(ofs);
5553
// IFDS template parametrization test
5654
std::cout << "Testing IFDS:\n";
5755
IFDSLinearConstantAnalysis L(&DB, &H, &I, &P, {"main"});

unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ TEST_F(LLVMBasedICFG_OTFTest, VirtualCallSite_7) {
5151
// LLVMPointsToInfo PT(IRDB);
5252
// LLVMBasedICFG ICFG(IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT);
5353
// const llvm::Function *F = IRDB.getFunctionDefinition("main");
54-
// const llvm::Function *FooC = IRDB.getFunctionDefinition("_ZZ4mainEN1C3fooEv");
55-
// ASSERT_TRUE(F);
54+
// const llvm::Function *FooC =
55+
// IRDB.getFunctionDefinition("_ZZ4mainEN1C3fooEv"); ASSERT_TRUE(F);
5656
// ASSERT_TRUE(FooC);
5757

5858
// auto CS1 = getNthInstruction(F, 15);

0 commit comments

Comments
 (0)