Skip to content

Commit

Permalink
Extend DOTGraph Config functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
rleer committed Sep 20, 2019
1 parent a90da93 commit 07fef21
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 28 deletions.
49 changes: 49 additions & 0 deletions config/DOTGraphConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"CFNode": {
"style": "filled",
"shape": "record"
},
"CFIntraEdge": {
},
"CFInterEdge": {
"weight": "1"
},
"FactNode": {
"style": "rounded"
},
"FactIDEdge": {
"style": "dotted",
"arrowhead": "normal",
"fontsize": "11",
"arrowsize": "0.7"
},
"FactCrossEdge": {
"style": "dotted",
"arrowhead": "normal",
"fontsize": "11",
"arrowsize": "0.7"
},
"FactInterEdge": {
"weight": "0.1",
"style": "dashed",
"arrowhead": "normal",
"fontsize": "11",
"arrowsize": "0.7"
},
"LambdaNode": {
"style": "rounded"
},
"LambdaIDEdge": {
"style": "dotted",
"arrowhead": "normal",
"fontsize": "11",
"arrowsize": "0.7"
},
"LambdaInterEdge": {
"weight": "0.1",
"style": "dashed",
"arrowhead": "normal",
"fontsize": "11",
"arrowsize": "0.7"
}
}
1 change: 1 addition & 0 deletions include/phasar/PhasarLLVM/IfdsIde/Solver/IDESolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,7 @@ class IDESolver {
LOG_IF_ENABLE(BOOST_LOG_SEV(lg, DEBUG)
<< "=============================================");
DOTGraph<D> G;
DOTConfig::importDOTConfig();
DOTFunctionSubGraph *FG = nullptr;

// Sort intra-procedural path edges
Expand Down
54 changes: 33 additions & 21 deletions include/phasar/PhasarLLVM/Utils/DOTGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,20 @@ namespace psr {

class DOTConfig {
public:
static const std::string CFNodeAttr() {
return "node [style=filled, shape=record]";
}
static const std::string CFIntraEdgeAttr() { return "edge []"; }
static const std::string CFInterEdgeAttr() { return "edge [weight=0.1]"; }
static const std::string FactNodeAttr() { return "node [style=rounded]"; }
static const std::string FactIdentityEdgeAttr() {
return "edge [style=dotted, arrowhead=normal, " + fontSize + ", " +
arrowSize + ']';
}
static const std::string FactCrossEdgeAttr() {
return FactIdentityEdgeAttr();
}
static const std::string LambdaInterEdgeAttr() {
return "edge[weight=0.1, style=dotted, " + fontSize + ", " + arrowSize +
']';
}
static const std::string FactInterEdgeAttr() {
return "edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize +
']';
}
static const std::string CFNodeAttr() { return CFNode; }
static const std::string CFIntraEdgeAttr() { return CFIntraEdge; }
static const std::string CFInterEdgeAttr() { return CFInterEdge; }

static const std::string FactNodeAttr() { return FactNode; }
static const std::string FactIDEdgeAttr() { return FactIDEdge; }
static const std::string FactCrossEdgeAttr() { return FactCrossEdge; }
static const std::string FactInterEdgeAttr() { return FactInterEdge; }

static const std::string LambdaNodeAttr() { return LambdaNode; }
static const std::string LambdaIDEdgeAttr() { return LambdaIDEdge; }
static const std::string LambdaInterEdgeAttr() { return LambdaInterEdge; }

static void importDOTConfig();

static DOTConfig &getDOTConfig();
~DOTConfig() = default;
Expand All @@ -58,6 +51,25 @@ class DOTConfig {
DOTConfig() = default;
inline static const std::string fontSize = "fontsize=11";
inline static const std::string arrowSize = "arrowsize=0.7";

inline static std::string CFNode = "node [style=filled, shape=record]";
inline static std::string CFIntraEdge = "edge []";
inline static std::string CFInterEdge = "edge [weight=0.1]";
inline static std::string FactNode = "node [style=rounded]";
inline static std::string FactIDEdge =
"edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize +
']';
inline static std::string FactCrossEdge =
"edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize +
']';
inline static std::string FactInterEdge =
"edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']';
inline static std::string LambdaNode = "node [style=rounded]";
inline static std::string LambdaIDEdge =
"edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize +
']';
inline static std::string LambdaInterEdge =
"edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']';
};

struct DOTNode {
Expand Down
77 changes: 70 additions & 7 deletions lib/PhasarLLVM/Utils/DOTGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/

#include <algorithm>
#include <boost/filesystem.hpp>
#include <iterator>
#include <json.hpp>
#include <ostream>

#include <phasar/Config/Configuration.h>
#include <phasar/PhasarLLVM/Utils/DOTGraph.h>

namespace psr {
Expand All @@ -33,8 +36,7 @@ DOTNode::DOTNode(std::string fName, std::string l, std::string sId,
}

std::string DOTNode::str(std::string indent) const {
std::string str =
indent + id + " [label=\"" + label; // + " | SID: " + stmtId + "\"";
std::string str = indent + id + " [label=\"" + label;
if (factId) {
str += " | SID: " + stmtId;
}
Expand Down Expand Up @@ -79,7 +81,7 @@ std::string DOTFactSubGraph::str(std::string indent) const {
}
// Print id edges
str += '\n' + innerIndent + "// Identity edges for this fact\n" +
innerIndent + DOTConfig::FactIdentityEdgeAttr() + '\n';
innerIndent + DOTConfig::FactIDEdgeAttr() + '\n';
for (DOTEdge e : edges) {
str += e.str(innerIndent) + '\n';
}
Expand Down Expand Up @@ -138,14 +140,15 @@ std::string DOTFunctionSubGraph::generateLambdaSG(std::string indent) const {
std::string str = indent + "// Auto-generated lambda nodes and edges\n" +
indent + "subgraph cluster_" + id + "_lambda {\n" +
innerIndent + "style=invis\n" + innerIndent +
"label=\"Λ\"\n" + innerIndent + DOTConfig::FactNodeAttr() +
'\n';
"label=\"Λ\"\n" + innerIndent +
DOTConfig::LambdaNodeAttr() + '\n';
// Print lambda nodes
for (DOTNode stmt : stmts) {
str += innerIndent + id + "_0_" + stmt.stmtId + " [label=\"Λ\"]\n";
str += innerIndent + id + "_0_" + stmt.stmtId +
" [label=\"Λ|SID: " + stmt.stmtId + "\"]\n";
}
// Print lambda edges
str += '\n' + innerIndent + DOTConfig::FactIdentityEdgeAttr() + '\n';
str += '\n' + innerIndent + DOTConfig::LambdaIDEdgeAttr() + '\n';
for (DOTEdge e : intraCFEdges) {
str += innerIndent + id + "_0_" + e.source.stmtId + " -> " + id + "_0_" +
e.target.stmtId;
Expand Down Expand Up @@ -242,4 +245,64 @@ DOTConfig &DOTConfig::getDOTConfig() {
return DC;
}

void DOTConfig::importDOTConfig() {
boost::filesystem::path FilePath(PhasarConfig::PhasarDirectory());
FilePath /= boost::filesystem::path("config/DOTGraphConfig.json");
if (boost::filesystem::exists(FilePath) &&
!boost::filesystem::is_directory(FilePath)) {
std::ifstream ifs(FilePath.string());
if (ifs.is_open()) {
std::stringstream iss;
iss << ifs.rdbuf();
ifs.close();
nlohmann::json jDOTConfig;
iss >> jDOTConfig;
for (auto &el : jDOTConfig.items()) {
std::stringstream attr_str;
if (el.key().find("Node") != std::string::npos) {
attr_str << "node [";
} else {
attr_str << "edge [";
}
for (nlohmann::json::iterator it = el.value().begin();
it != el.value().end(); ++it) {
// using it.value() directly with the << operator adds unnecessary
// quotes
std::string val = it.value();
attr_str << it.key() << "=" << val;
if (std::next(it) != el.value().end()) {
attr_str << ", ";
}
}
attr_str << ']';
if (el.key() == "CFNode") {
DOTConfig::CFNode = attr_str.str();
} else if (el.key() == "CFIntraEdge") {
DOTConfig::CFIntraEdge = attr_str.str();
} else if (el.key() == "CFInterEdge") {
DOTConfig::CFInterEdge = attr_str.str();
} else if (el.key() == "FactNode") {
DOTConfig::FactNode = attr_str.str();
} else if (el.key() == "FactIDEdge") {
DOTConfig::FactIDEdge = attr_str.str();
} else if (el.key() == "FactCrossEdge") {
DOTConfig::FactCrossEdge = attr_str.str();
} else if (el.key() == "FactInterEdge") {
DOTConfig::FactInterEdge = attr_str.str();
} else if (el.key() == "LambdaNode") {
DOTConfig::LambdaNode = attr_str.str();
} else if (el.key() == "LambdaIDEdge") {
DOTConfig::LambdaIDEdge = attr_str.str();
} else if (el.key() == "LambdaInterEdge") {
DOTConfig::LambdaInterEdge = attr_str.str();
}
}
} else {
throw std::ios_base::failure("Could not open file");
}
} else {
throw std::ios_base::failure(FilePath.string() + " is not a valid path");
}
}

} // namespace psr

0 comments on commit 07fef21

Please sign in to comment.