P4C
The P4 Compiler
Loading...
Searching...
No Matches
controlFlowGraph.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef BACKENDS_BMV2_COMMON_CONTROLFLOWGRAPH_H_
9#define BACKENDS_BMV2_COMMON_CONTROLFLOWGRAPH_H_
10
11#include "frontends/common/resolveReferences/referenceMap.h"
12#include "frontends/p4/typeMap.h"
13#include "ir/ir.h"
14#include "lib/castable.h"
15#include "lib/ordered_set.h"
16
17namespace P4::BMV2 {
18
21class CFG final : public IHasDbPrint {
22 public:
23 class Edge;
24 class Node;
25
26 class EdgeSet final : public IHasDbPrint {
27 public:
29
30 EdgeSet() = default;
31 explicit EdgeSet(CFG::Edge *edge) { edges.emplace(edge); }
32 explicit EdgeSet(const EdgeSet *other) { mergeWith(other); }
33
34 void mergeWith(const EdgeSet *other) {
35 edges.insert(other->edges.begin(), other->edges.end());
36 }
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;
48 bool isDestination(const CFG::Node *destination) const;
49 };
50
51 class Node : public IHasDbPrint, public ICastable {
52 protected:
53 friend class CFG;
54
55 static unsigned crtId;
56 EdgeSet predecessors;
57 explicit Node(cstring name) : id(crtId++), name(name) {}
58 Node() : id(crtId++), name("node_" + Util::toString(id)) {}
59 virtual ~Node() {}
60
61 public:
62 const unsigned id;
63 const cstring name;
64 EdgeSet successors;
65
66 void dbprint(std::ostream &out) const override;
67 void addPredecessors(const EdgeSet *set);
68 void computeSuccessors();
69 cstring toString() const { return name; }
70
71 DECLARE_TYPEINFO(Node);
72 };
73
74 public:
75 class TableNode final : public Node {
76 public:
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) {
81 CHECK_NULL(table);
82 CHECK_NULL(invocation);
83 }
84
85 DECLARE_TYPEINFO(TableNode, Node);
86 };
87
88 class IfNode final : public Node {
89 public:
90 const IR::IfStatement *statement;
91 explicit IfNode(const IR::IfStatement *statement) : statement(statement) {
92 CHECK_NULL(statement);
93 }
94
95 DECLARE_TYPEINFO(IfNode, Node);
96 };
97
98 class DummyNode final : public Node {
99 public:
100 explicit DummyNode(cstring name) : Node(name) {}
101
102 DECLARE_TYPEINFO(DummyNode, Node);
103 };
104
105 protected:
106 enum class EdgeType { Unconditional, True, False, Label };
107
108 public:
110 class Edge final {
111 protected:
112 EdgeType type;
113 Edge(Node *node, EdgeType type, cstring label) : type(type), endpoint(node), label(label) {}
114
115 public:
118 cstring label; // only present if type == Label
119
120 explicit Edge(Node *node) : type(EdgeType::Unconditional), endpoint(node) {
121 CHECK_NULL(node);
122 }
123 Edge(Node *node, bool b) : type(b ? EdgeType::True : EdgeType::False), endpoint(node) {
124 CHECK_NULL(node);
125 }
126 Edge(Node *node, cstring label) : type(EdgeType::Label), endpoint(node), label(label) {
127 CHECK_NULL(node);
128 }
129 void dbprint(std::ostream &out) const;
130 Edge *clone(Node *node) const { return new Edge(node, type, label); }
131 Node *getNode() { return endpoint; }
132 bool getBool() {
133 BUG_CHECK(isBool(), "Edge is not Boolean");
134 return type == EdgeType::True;
135 }
136 bool isBool() const { return type == EdgeType::True || type == EdgeType::False; }
137 bool isUnconditional() const { return type == EdgeType::Unconditional; }
138 };
139
140 public:
141 Node *entryPoint;
142 Node *exitPoint;
143 const IR::P4Control *container;
144 ordered_set<Node *> allNodes;
145
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);
150 return result;
151 }
152 Node *makeNode(const IR::IfStatement *statement) {
153 auto result = new IfNode(statement);
154 allNodes.emplace(result);
155 return result;
156 }
157 Node *makeNode(cstring name) {
158 auto result = new DummyNode(name);
159 allNodes.emplace(result);
160 return result;
161 }
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");
165 entryPoint = entry;
166 }
167 void dbprint(std::ostream &out, Node *node, std::set<Node *> &done) const; // helper
168 void dbprint(std::ostream &out) const;
169 void computeSuccessors() {
170 for (auto n : allNodes) n->computeSuccessors();
171 }
174 bool checkImplementable() const;
175
176 private:
177 bool dfs(Node *node, std::set<Node *> &visited, std::set<const IR::P4Table *> &stack) const;
183 bool checkMergeable(std::set<TableNode *> nodes) const;
184};
185
186} // namespace P4::BMV2
187
188#endif /* BACKENDS_BMV2_COMMON_CONTROLFLOWGRAPH_H_ */
Definition controlFlowGraph.h:98
A CFG Edge; can be an in-edge or out-edge.
Definition controlFlowGraph.h:110
Node * endpoint
The destination node of the edge. The source node is not known by the edge.
Definition controlFlowGraph.h:117
Definition controlFlowGraph.h:26
bool checkSame(const EdgeSet &other) const
Definition controlFlowGraph.cpp:104
bool isDestination(const CFG::Node *destination) const
Definition controlFlowGraph.cpp:92
Definition controlFlowGraph.h:88
Definition controlFlowGraph.h:51
Definition controlFlowGraph.h:75
bool checkImplementable() const
Definition controlFlowGraph.cpp:137
Definition castable.h:27
Definition stringify.h:33
Definition cstring.h:85
Definition ordered_set.h:32
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition action.cpp:9