31 explicit EdgeSet(
CFG::Edge *edge) { edges.emplace(edge); }
32 explicit EdgeSet(
const EdgeSet *other) { mergeWith(other); }
34 void mergeWith(
const EdgeSet *other) {
35 edges.insert(other->edges.begin(), other->edges.end());
37 void dbprint(std::ostream &out)
const;
38 void emplace(
CFG::Edge *edge) { edges.emplace(edge); }
39 size_t size()
const {
return edges.size(); }
43 bool checkSame(
const EdgeSet &other)
const;
55 static unsigned crtId;
57 explicit Node(
cstring name) : id(crtId++), name(name) {}
58 Node() : id(crtId++), name(
"node_" + Util::toString(
id)) {}
66 void dbprint(std::ostream &out)
const override;
67 void addPredecessors(
const EdgeSet *set);
68 void computeSuccessors();
69 cstring toString()
const {
return name; }
71 DECLARE_TYPEINFO(Node);
75 class TableNode final :
public Node {
77 const IR::P4Table *table;
78 const IR::Expression *invocation;
79 explicit TableNode(
const IR::P4Table *table,
const IR::Expression *invocation)
80 : Node(table->controlPlaneName()), table(table), invocation(invocation) {
82 CHECK_NULL(invocation);
85 DECLARE_TYPEINFO(TableNode, Node);
88 class IfNode final :
public Node {
90 const IR::IfStatement *statement;
91 explicit IfNode(
const IR::IfStatement *statement) : statement(statement) {
92 CHECK_NULL(statement);
95 DECLARE_TYPEINFO(IfNode, Node);
98 class DummyNode final :
public Node {
100 explicit DummyNode(
cstring name) : Node(name) {}
102 DECLARE_TYPEINFO(DummyNode, Node);
106 enum class EdgeType { Unconditional, True, False, Label };
113 Edge(
Node *node, EdgeType type,
cstring label) : type(type),
endpoint(node), label(label) {}
120 explicit Edge(
Node *node) : type(EdgeType::Unconditional),
endpoint(node) {
123 Edge(
Node *node,
bool b) : type(b ? EdgeType::True : EdgeType::False),
endpoint(node) {
126 Edge(Node *node,
cstring label) : type(EdgeType::Label),
endpoint(node), label(label) {
129 void dbprint(std::ostream &out)
const;
130 Edge *clone(Node *node)
const {
return new Edge(node, type, label); }
131 Node *getNode() {
return endpoint; }
133 BUG_CHECK(isBool(),
"Edge is not Boolean");
134 return type == EdgeType::True;
136 bool isBool()
const {
return type == EdgeType::True || type == EdgeType::False; }
137 bool isUnconditional()
const {
return type == EdgeType::Unconditional; }
143 const IR::P4Control *container;
144 ordered_set<Node *> allNodes;
146 CFG() : entryPoint(nullptr), exitPoint(nullptr), container(nullptr) {}
147 Node *makeNode(
const IR::P4Table *table,
const IR::Expression *invocation) {
148 auto result =
new TableNode(table, invocation);
149 allNodes.emplace(result);
152 Node *makeNode(
const IR::IfStatement *statement) {
153 auto result =
new IfNode(statement);
154 allNodes.emplace(result);
157 Node *makeNode(cstring name) {
159 allNodes.emplace(result);
162 void build(
const IR::P4Control *cc, P4::ReferenceMap *refMap, P4::TypeMap *typeMap);
163 void setEntry(
Node *entry) {
164 BUG_CHECK(entryPoint ==
nullptr,
"Entry already set");
167 void dbprint(std::ostream &out,
Node *node, std::set<Node *> &done)
const;
168 void dbprint(std::ostream &out)
const;
169 void computeSuccessors() {
170 for (
auto n : allNodes) n->computeSuccessors();
177 bool dfs(
Node *node, std::set<Node *> &visited, std::set<const IR::P4Table *> &stack)
const;
183 bool checkMergeable(std::set<TableNode *> nodes)
const;