Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parser graph generation support for graphs backend #969

Merged
merged 5 commits into from
Oct 30, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
create graph base class, using rectangles in graphs
  • Loading branch information
c3m3gyanesh committed Oct 17, 2017
commit c9975c6ce7acd3862b6661e6f961f2bb52c0dc60
135 changes: 0 additions & 135 deletions backends/graphs/controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,57 +28,6 @@ limitations under the License.

namespace graphs {

class EdgeUnconditional : public EdgeTypeIface {
public:
EdgeUnconditional() = default;
cstring label() const override { return ""; };
};

class EdgeIf : public EdgeTypeIface {
public:
enum class Branch { TRUE, FALSE };
explicit EdgeIf(Branch branch) : branch(branch) { }
cstring label() const override {
switch (branch) {
case Branch::TRUE:
return "TRUE";
case Branch::FALSE:
return "FALSE";
}
BUG("unreachable");
return "";
};

private:
Branch branch;
};

class EdgeSwitch : public EdgeTypeIface {
public:
explicit EdgeSwitch(const IR::Expression *labelExpr)
: labelExpr(labelExpr) { }
cstring label() const override {
std::stringstream sstream;
labelExpr->dbprint(sstream);
return cstring(sstream);
};

private:
const IR::Expression *labelExpr;
};

class EdgeSelect : public EdgeTypeIface {
public:
explicit EdgeSelect(const cstring labelExpr)
: labelExpr(labelExpr) { }
cstring label() const override {
return labelExpr;
};

private:
const cstring labelExpr;
};

using Graph = ControlGraphs::Graph;

Graph *ControlGraphs::ControlStack::pushBack(Graph &currentSubgraph, const cstring &name) {
Expand Down Expand Up @@ -125,90 +74,6 @@ ControlGraphs::ControlGraphs(P4::ReferenceMap *refMap, P4::TypeMap *typeMap,
visitDagOnce = false;
}

vertex_t ControlGraphs::add_vertex(const cstring &name, VertexType type) {
auto v = boost::add_vertex(*g);
boost::put(&Vertex::name, *g, v, name);
boost::put(&Vertex::type, *g, v, type);
return g->local_to_global(v);
}

void ControlGraphs::add_edge(const vertex_t &from, const vertex_t &to, const cstring &name) {
auto ep = boost::add_edge(from, to, g->root());
boost::put(boost::edge_name, g->root(), ep.first, name);
}

boost::optional<vertex_t> ControlGraphs::merge_other_statements_into_vertex() {
if (statementsStack.empty()) return boost::none;
std::stringstream sstream;
if (statementsStack.size() == 1) {
statementsStack[0]->dbprint(sstream);
} else if (statementsStack.size() == 2) {
statementsStack[0]->dbprint(sstream);
sstream << "\n";
statementsStack[1]->dbprint(sstream);
} else {
statementsStack[0]->dbprint(sstream);
sstream << "\n...\n";
statementsStack.back()->dbprint(sstream);
}
auto v = add_vertex(cstring(sstream), VertexType::STATEMENTS);
for (auto parent : parents)
add_edge(parent.first, v, parent.second->label());
parents = {{v, new EdgeUnconditional()}};
statementsStack.clear();
return v;
}

vertex_t ControlGraphs::add_and_connect_vertex(const cstring &name, VertexType type) {
merge_other_statements_into_vertex();
auto v = add_vertex(name, type);
for (auto parent : parents)
add_edge(parent.first, v, parent.second->label());
return v;
}

class ControlGraphs::GraphAttributeSetter {
public:
void operator()(Graph &g) const {
auto vertices = boost::vertices(g);
for (auto vit = vertices.first; vit != vertices.second; ++vit) {
const auto &vinfo = g[*vit];
auto attrs = boost::get(boost::vertex_attribute, g);
attrs[*vit]["label"] = vinfo.name;
attrs[*vit]["style"] = vertexTypeGetStyle(vinfo.type);
attrs[*vit]["shape"] = vertexTypeGetShape(vinfo.type);
}
auto edges = boost::edges(g);
for (auto eit = edges.first; eit != edges.second; ++eit) {
auto attrs = boost::get(boost::edge_attribute, g);
attrs[*eit]["label"] = boost::get(boost::edge_name, g, *eit);
}
}

private:
static cstring vertexTypeGetShape(VertexType type) {
switch (type) {
case VertexType::TABLE:
return "ellipse";
default:
return "rectangle";
}
BUG("unreachable");
return "";
}

static cstring vertexTypeGetStyle(VertexType type) {
switch (type) {
case VertexType::CONTROL:
return "dashed";
default:
return "solid";
}
BUG("unreachable");
return "";
}
};

void ControlGraphs::writeGraphToFile(const Graph &g, const cstring &name) {
auto path = Util::PathName(graphsDir).join(name + ".dot");
auto out = openFile(path.toString(), false);
Expand Down
110 changes: 110 additions & 0 deletions backends/graphs/graphs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,116 @@ MidEnd::MidEnd(CompilerOptions& options) {
});
}

class Graphs::GraphAttributeSetter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally think that the main function for the backend and the Graph methods implementation belong in 2 different files; apart from that it looks ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a new file "p4c-graphs.cpp" to accommodate main funcion.

public:
void operator()(Graph &g) const {
auto vertices = boost::vertices(g);
for (auto vit = vertices.first; vit != vertices.second; ++vit) {
const auto &vinfo = g[*vit];
auto attrs = boost::get(boost::vertex_attribute, g);
attrs[*vit]["label"] = vinfo.name;
attrs[*vit]["style"] = vertexTypeGetStyle(vinfo.type);
attrs[*vit]["shape"] = vertexTypeGetShape(vinfo.type);
attrs[*vit]["margin"] = vertexTypeGetMargin(vinfo.type);
}
auto edges = boost::edges(g);
for (auto eit = edges.first; eit != edges.second; ++eit) {
auto attrs = boost::get(boost::edge_attribute, g);
attrs[*eit]["label"] = boost::get(boost::edge_name, g, *eit);
}
}

private:
static cstring vertexTypeGetShape(VertexType type) {
switch (type) {
case VertexType::TABLE:
return "ellipse";
case VertexType::HEADER:
return "box";
case VertexType::START:
return "circle";
case VertexType::DEFAULT:
return "doublecircle";
default:
return "rectangle";
}
BUG("unreachable");
return "";
}

static cstring vertexTypeGetStyle(VertexType type) {
switch (type) {
case VertexType::CONTROL:
return "dashed";
case VertexType::HEADER:
return "solid";
case VertexType::START:
return "solid";
case VertexType::DEFAULT:
return "solid";
default:
return "solid";
}
BUG("unreachable");
return "";
}

static cstring vertexTypeGetMargin(VertexType type) {
switch (type) {
case VertexType::HEADER:
return "0.05,0";
case VertexType::START:
return "0,0";
case VertexType::DEFAULT:
return "0,0";
default:
return "";
}
}
};

Graphs::vertex_t Graphs::add_vertex(const cstring &name, VertexType type) {
auto v = boost::add_vertex(*g);
boost::put(&Vertex::name, *g, v, name);
boost::put(&Vertex::type, *g, v, type);
return g->local_to_global(v);
}

void Graphs::add_edge(const vertex_t &from, const vertex_t &to, const cstring &name) {
auto ep = boost::add_edge(from, to, g->root());
boost::put(boost::edge_name, g->root(), ep.first, name);
}

boost::optional<Graphs::vertex_t> Graphs::merge_other_statements_into_vertex() {
if (statementsStack.empty()) return boost::none;
std::stringstream sstream;
if (statementsStack.size() == 1) {
statementsStack[0]->dbprint(sstream);
} else if (statementsStack.size() == 2) {
statementsStack[0]->dbprint(sstream);
sstream << "\n";
statementsStack[1]->dbprint(sstream);
} else {
statementsStack[0]->dbprint(sstream);
sstream << "\n...\n";
statementsStack.back()->dbprint(sstream);
}
auto v = add_vertex(cstring(sstream), VertexType::STATEMENTS);
for (auto parent : parents)
add_edge(parent.first, v, parent.second->label());
parents = {{v, new EdgeUnconditional()}};
statementsStack.clear();
return v;
}

Graphs::vertex_t Graphs::add_and_connect_vertex(const cstring &name, VertexType type) {
merge_other_statements_into_vertex();
auto v = add_vertex(name, type);
for (auto parent : parents)
add_edge(parent.first, v, parent.second->label());
return v;
}

class Options : public CompilerOptions {
public:
cstring graphsDir{"."};
Expand Down
Loading