40 explicit EdgeSet(
CFG::Edge *edge) { edges.emplace(edge); }
41 explicit EdgeSet(
const EdgeSet *other) { mergeWith(other); }
43 void mergeWith(
const EdgeSet *other) {
44 edges.insert(other->edges.begin(), other->edges.end());
46 void dbprint(std::ostream &out)
const;
47 void emplace(
CFG::Edge *edge) { edges.emplace(edge); }
48 size_t size()
const {
return edges.size(); }
52 bool checkSame(
const EdgeSet &other)
const;
64 static unsigned crtId;
66 explicit Node(
cstring name) : id(crtId++), name(name) {}
67 Node() : id(crtId++), name(
"node_" + Util::toString(
id)) {}
75 void dbprint(std::ostream &out)
const override;
76 void addPredecessors(
const EdgeSet *set);
77 void computeSuccessors();
78 cstring toString()
const {
return name; }
80 DECLARE_TYPEINFO(Node);
84 class TableNode final :
public Node {
86 const IR::P4Table *table;
87 const IR::Expression *invocation;
88 explicit TableNode(
const IR::P4Table *table,
const IR::Expression *invocation)
89 : Node(table->controlPlaneName()), table(table), invocation(invocation) {
91 CHECK_NULL(invocation);
94 DECLARE_TYPEINFO(TableNode, Node);
97 class IfNode final :
public Node {
99 const IR::IfStatement *statement;
100 explicit IfNode(
const IR::IfStatement *statement) : statement(statement) {
101 CHECK_NULL(statement);
104 DECLARE_TYPEINFO(IfNode, Node);
107 class DummyNode final :
public Node {
109 explicit DummyNode(
cstring name) : Node(name) {}
111 DECLARE_TYPEINFO(DummyNode, Node);
115 enum class EdgeType { Unconditional, True, False, Label };
122 Edge(
Node *node, EdgeType type,
cstring label) : type(type),
endpoint(node), label(label) {}
129 explicit Edge(
Node *node) : type(EdgeType::Unconditional),
endpoint(node) {
132 Edge(
Node *node,
bool b) : type(b ? EdgeType::True : EdgeType::False),
endpoint(node) {
135 Edge(Node *node,
cstring label) : type(EdgeType::Label),
endpoint(node), label(label) {
138 void dbprint(std::ostream &out)
const;
139 Edge *clone(Node *node)
const {
return new Edge(node, type, label); }
140 Node *getNode() {
return endpoint; }
142 BUG_CHECK(isBool(),
"Edge is not Boolean");
143 return type == EdgeType::True;
145 bool isBool()
const {
return type == EdgeType::True || type == EdgeType::False; }
146 bool isUnconditional()
const {
return type == EdgeType::Unconditional; }
152 const IR::P4Control *container;
153 ordered_set<Node *> allNodes;
155 CFG() : entryPoint(nullptr), exitPoint(nullptr), container(nullptr) {}
156 Node *makeNode(
const IR::P4Table *table,
const IR::Expression *invocation) {
157 auto result =
new TableNode(table, invocation);
158 allNodes.emplace(result);
161 Node *makeNode(
const IR::IfStatement *statement) {
162 auto result =
new IfNode(statement);
163 allNodes.emplace(result);
166 Node *makeNode(cstring name) {
168 allNodes.emplace(result);
171 void build(
const IR::P4Control *cc, P4::ReferenceMap *refMap, P4::TypeMap *typeMap);
172 void setEntry(
Node *entry) {
173 BUG_CHECK(entryPoint ==
nullptr,
"Entry already set");
176 void dbprint(std::ostream &out,
Node *node, std::set<Node *> &done)
const;
177 void dbprint(std::ostream &out)
const;
178 void computeSuccessors() {
179 for (
auto n : allNodes) n->computeSuccessors();
186 bool dfs(
Node *node, std::set<Node *> &visited, std::set<const IR::P4Table *> &stack)
const;
192 bool checkMergeable(std::set<TableNode *> nodes)
const;