P4C
The P4 Compiler
Loading...
Searching...
No Matches
graphs.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef BACKENDS_GRAPHS_GRAPHS_H_
18#define BACKENDS_GRAPHS_GRAPHS_H_
19
20#include "config.h"
21#include "lib/cstring.h"
22
25#ifndef HAVE_LIBBOOST_GRAPH
26#error "This backend requires the boost graph headers, which could not be found"
27#endif
28
29#include <map>
30#include <optional>
31#include <utility> // std::pair
32#include <vector>
33
34#include <boost/graph/adjacency_list.hpp>
35#include <boost/graph/graph_traits.hpp>
36#include <boost/graph/graphviz.hpp>
37
38#include "frontends/p4/parserCallGraph.h"
39#include "ir/ir.h"
40#include "ir/visitor.h"
41
42namespace P4 {
43
44class ReferenceMap;
45class TypeMap;
46
47} // namespace P4
48
49namespace P4::graphs {
50
51using namespace P4::literals;
52
54 public:
55 virtual ~EdgeTypeIface() {}
56 virtual cstring label() const = 0;
57};
58
60 public:
61 EdgeUnconditional() = default;
62 cstring label() const override { return cstring::empty; };
63};
64
65class EdgeIf : public EdgeTypeIface {
66 public:
67 enum class Branch { TRUE, FALSE };
68 explicit EdgeIf(Branch branch) : branch(branch) {}
69 cstring label() const override {
70 switch (branch) {
71 case Branch::TRUE:
72 return "TRUE"_cs;
73 case Branch::FALSE:
74 return "FALSE"_cs;
75 }
76 BUG("unreachable");
77 return cstring::empty;
78 };
79
80 private:
81 Branch branch;
82};
83
84class EdgeSwitch : public EdgeTypeIface {
85 public:
86 explicit EdgeSwitch(const IR::Expression *labelExpr) : labelExpr(labelExpr) {}
87 cstring label() const override {
88 std::stringstream sstream;
89 labelExpr->dbprint(sstream);
90 return cstring(sstream);
91 };
92
93 private:
94 const IR::Expression *labelExpr;
95};
96
97class Graphs : public Inspector {
98 public:
99 enum class VertexType {
100 TABLE,
101 KEY,
102 ACTION,
103 CONDITION,
104 SWITCH,
105 STATEMENTS,
106 CONTROL,
107 OTHER,
108 STATE,
109 EMPTY
110 };
111 struct Vertex {
112 cstring name;
113 VertexType type;
114 };
115
121 using GraphvizAttributes = std::map<cstring, cstring>;
122 using vertexProperties = boost::property<boost::vertex_attribute_t, GraphvizAttributes, Vertex>;
123 using edgeProperties = boost::property<
124 boost::edge_attribute_t, GraphvizAttributes,
125 boost::property<boost::edge_name_t, cstring, boost::property<boost::edge_index_t, int>>>;
126 using graphProperties = boost::property<
127 boost::graph_name_t, std::string,
128 boost::property<
129 boost::graph_graph_attribute_t, GraphvizAttributes,
130 boost::property<boost::graph_vertex_attribute_t, GraphvizAttributes,
131 boost::property<boost::graph_edge_attribute_t, GraphvizAttributes>>>>;
132 using Graph_ = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
133 vertexProperties, edgeProperties, graphProperties>;
134 using Graph = boost::subgraph<Graph_>;
135 using vertex_t = boost::graph_traits<Graph>::vertex_descriptor;
136
137 using Parents = std::vector<std::pair<vertex_t, EdgeTypeIface *>>;
138
141 std::optional<vertex_t> merge_other_statements_into_vertex();
142
143 vertex_t add_vertex(const cstring &name, VertexType type);
144 vertex_t add_and_connect_vertex(const cstring &name, VertexType type);
145 void add_edge(const vertex_t &from, const vertex_t &to, const cstring &name);
152 void add_edge(const vertex_t &from, const vertex_t &to, const cstring &name,
153 unsigned cluster_id);
154
156 public:
157 void operator()(Graph &g) const {
158 auto vertices = boost::vertices(g);
159 for (auto &vit = vertices.first; vit != vertices.second; ++vit) {
160 const auto &vinfo = g[*vit];
161 auto attrs = boost::get(boost::vertex_attribute, g);
162 attrs[*vit]["label"_cs] = vinfo.name;
163 attrs[*vit]["style"_cs] = vertexTypeGetStyle(vinfo.type);
164 attrs[*vit]["shape"_cs] = vertexTypeGetShape(vinfo.type);
165 attrs[*vit]["margin"_cs] = vertexTypeGetMargin(vinfo.type);
166 }
167 auto edges = boost::edges(g);
168 for (auto &eit = edges.first; eit != edges.second; ++eit) {
169 auto attrs = boost::get(boost::edge_attribute, g);
170 attrs[*eit]["label"_cs] = boost::get(boost::edge_name, g, *eit);
171 }
172 }
173
174 private:
175 static cstring vertexTypeGetShape(VertexType type) {
176 switch (type) {
177 case VertexType::TABLE:
178 case VertexType::ACTION:
179 return "ellipse"_cs;
180 default:
181 return "rectangle"_cs;
182 }
183 BUG("unreachable");
184 return cstring::empty;
185 }
186
187 static cstring vertexTypeGetStyle(VertexType type) {
188 switch (type) {
189 case VertexType::CONTROL:
190 return "dashed"_cs;
191 case VertexType::EMPTY:
192 return "invis"_cs;
193 case VertexType::KEY:
194 case VertexType::CONDITION:
195 case VertexType::SWITCH:
196 return "rounded"_cs;
197 default:
198 return "solid"_cs;
199 }
200 BUG("unreachable");
201 return cstring::empty;
202 }
203
204 static cstring vertexTypeGetMargin(VertexType type) {
205 switch (type) {
206 default:
207 return cstring::empty;
208 }
209 }
210 }; // end class GraphAttributeSetter
211
212 protected:
213 Graph *g{nullptr};
214 vertex_t start_v{};
215 vertex_t exit_v{};
216 Parents parents{};
217 std::vector<const IR::Statement *> statementsStack{};
218
219 private:
224 void limitStringSize(std::stringstream &sstream, std::stringstream &helper_sstream);
225};
226
227} // namespace P4::graphs
228
229#endif /* BACKENDS_GRAPHS_GRAPHS_H_ */
Definition visitor.h:400
Definition cstring.h:85
Definition graphs.h:65
Definition graphs.h:84
Definition graphs.h:53
Definition graphs.h:59
Definition graphs.h:97
std::optional< vertex_t > merge_other_statements_into_vertex()
Definition graphs.cpp:61
std::map< cstring, cstring > GraphvizAttributes
Definition graphs.h:121
Definition graphs.h:111
Definition controls.cpp:30
Definition cstring.h:80
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24