P4C
The P4 Compiler
Loading...
Searching...
No Matches
parser_graph.h
1
19#ifndef BACKENDS_TOFINO_BF_P4C_MIDEND_PARSER_GRAPH_H_
20#define BACKENDS_TOFINO_BF_P4C_MIDEND_PARSER_GRAPH_H_
21
22#include <boost/graph/adjacency_list.hpp>
23
24#include "backends/graphs/controls.h"
25#include "backends/graphs/graph_visitor.h"
26#include "backends/graphs/parsers.h"
27
32class P4ParserGraphs : public graphs::ParserGraphs {
33 void postorder(const IR::P4Parser *parser) override {
34 if (dumpDot) {
35 // Create parser dot, that is saved into parserGraphsArray
36 graphs::ParserGraphs::postorder(parser);
37 // Create empty control graphs
38 std::vector<graphs::Graphs::Graph *> emptyControl;
39 // And call graph visitor that actually outputs the graphs from the arrays
40 std::filesystem::path filePath = "";
41 std::filesystem::path empty_path = "";
42 graphs::Graph_visitor gvs(empty_path, true, false, false, filePath);
43 gvs.process(emptyControl, parserGraphsArray);
44 // Clear the array so it won't stay there if another parser is outputted
45 parserGraphsArray.clear();
46 }
47 }
48
49 void end_apply() override {
50 for (auto &kv : transitions) {
51 for (auto *t : kv.second) {
52 auto *src = t->sourceState;
53 auto *dst = t->destState;
54
55 preds[dst->name].insert(src->name);
56 succs[src->name].insert(dst->name);
57 }
58 }
59 }
60
61 bool is_descendant_impl(cstring a, cstring b, std::set<cstring> &visited) const {
62 if (!a || !b || a == b) return false;
63
64 auto inserted = visited.insert(b);
65 if (inserted.second == false) // visited
66 return false;
67
68 if (!succs.count(b)) return false;
69
70 if (succs.at(b).count(a)) return true;
71
72 for (auto succ : succs.at(b))
73 if (is_descendant_impl(a, succ, visited)) return true;
74
75 return false;
76 }
77
78 public:
79 P4ParserGraphs(P4::ReferenceMap *refMap, bool dumpDot)
80 : graphs::ParserGraphs(refMap, ""), dumpDot(dumpDot) {}
81
83 bool is_descendant(cstring a, cstring b) const {
84 std::set<cstring> visited;
85 return is_descendant_impl(a, b, visited);
86 }
87
89 bool is_ancestor(cstring a, cstring b) const { return is_descendant(b, a); }
90
91 const IR::ParserState *get_state(const IR::P4Parser *parser, cstring state) const {
92 for (auto s : states.at(parser)) {
93 if (s->name == state) return s;
94 }
95 return nullptr;
96 }
97
99 const IR::P4Parser *get_parser(const IR::ParserState *state) const {
100 for (auto &kv : states) {
101 for (auto s : kv.second)
102 if (s->name == state->name) return kv.first;
103 }
104
105 return nullptr;
106 }
107
108 ordered_set<const IR::ParserState *> get_all_descendants(const IR::ParserState *state) const {
109 ordered_set<const IR::ParserState *> rv;
110
111 auto parser = get_parser(state);
112
113 for (auto s : states.at(parser)) {
114 if (is_descendant(s->name, state->name)) rv.insert(s);
115 }
116
117 return rv;
118 }
119
120 ordered_set<const IR::ParserState *> get_all_ancestors(const IR::ParserState *state) const {
121 ordered_set<const IR::ParserState *> rv;
122
123 auto parser = get_parser(state);
124
125 for (auto s : states.at(parser)) {
126 if (is_descendant(state->name, s->name)) rv.insert(s);
127 }
128
129 return rv;
130 }
131
132 boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> create_boost_graph(
133 const IR::P4Parser *parser, std::map<int, cstring> &id_to_state) const;
134
135 std::set<std::set<cstring>> compute_strongly_connected_components(
136 const IR::P4Parser *parser) const;
137
138 std::set<std::set<cstring>> compute_loops(const IR::P4Parser *parser) const;
139
140 bool has_loops(const IR::P4Parser *parser) const {
141 auto loops = compute_loops(parser);
142 return !loops.empty();
143 }
144
145 std::vector<cstring> topological_sort(const IR::P4Parser *parser) const;
146
147 std::map<cstring, ordered_set<cstring>> preds, succs;
148
149 bool dumpDot;
150};
151
152#endif /* BACKENDS_TOFINO_BF_P4C_MIDEND_PARSER_GRAPH_H_ */
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
bool is_descendant(cstring a, cstring b) const
Is "a" a descendant of "b"?
Definition parser_graph.h:83
bool is_ancestor(cstring a, cstring b) const
Is "a" an ancestor of "b"?
Definition parser_graph.h:89
std::set< std::set< cstring > > compute_strongly_connected_components(const IR::P4Parser *parser) const
Definition parser_graph.cpp:51
const IR::P4Parser * get_parser(const IR::ParserState *state) const
a kludge due to base class's lack of state -> parser reverse map
Definition parser_graph.h:99
Extends p4c's parser graph with various algorithms.
Definition parser_graph.h:32