P4C
The P4 Compiler
Loading...
Searching...
No Matches
p4RuntimeSymbolTable.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 CONTROL_PLANE_P4RUNTIMESYMBOLTABLE_H_
18#define CONTROL_PLANE_P4RUNTIMESYMBOLTABLE_H_
19
20#include "lib/cstring.h"
21#include "p4RuntimeArchHandler.h"
22#include "typeSpecConverter.h"
23
24namespace p4 {
25namespace config {
26namespace v1 {
27class P4Info;
28} // namespace v1
29} // namespace config
30namespace v1 {
31class WriteRequest;
32} // namespace v1
33} // namespace p4
34
35namespace P4::IR {
36class P4Program;
37} // namespace P4::IR
38
39namespace P4 {
40
41namespace ControlPlaneAPI {
42
43const p4rt_id_t INVALID_ID = ::p4::config::v1::P4Ids::UNSPECIFIED;
44
46bool isControllerHeader(const IR::Type_Header *type);
47
49bool isHidden(const IR::IAnnotated *node);
50
53std::optional<p4rt_id_t> getIdAnnotation(const IR::IAnnotated *node);
54
63 void addSymbol(const cstring &symbol);
64
65 cstring shortestUniqueSuffix(const cstring &symbol) const;
66
67 private:
68 // All symbols in the set. We store these separately to make sure that no
69 // symbol is added to the tree of suffixes more than once.
70 std::set<cstring> symbols;
71
72 // A node in the tree of suffixes. The tree of suffixes is a directed graph
73 // of path components, with the edges pointing from the each component to
74 // its predecessor, so that every suffix of every symbol corresponds to a
75 // path through the tree. For example, "foo.bar[1].baz" would be represented
76 // as "baz" -> "bar[1]" -> "foo".
77 struct SuffixNode {
78 // How many suffixes pass through this node? This includes suffixes that
79 // terminate at this node.
80 unsigned instances = 0;
81
82 // Outgoing edges from this node. The SuffixNode should never be null.
83 std::map<cstring, SuffixNode *> edges;
84 };
85
86 // The root of our tree of suffixes. Note that this is *not* the data
87 // structure known as a suffix tree.
88 SuffixNode *suffixesRoot = new SuffixNode;
89};
90
94 public:
108 template <typename Func>
109 static P4RuntimeSymbolTable *create(Func function) {
110 // Create and initialize the symbol table. At this stage, ids aren't
111 // available, because computing ids requires global knowledge of all the
112 // P4Runtime symbols in the program.
113 auto *symbols = new P4RuntimeSymbolTable();
114 function(*symbols);
115
116 // Now that the symbol table is initialized, we can compute ids.
117 for (auto &table : symbols->symbolTables) {
118 symbols->computeIdsForSymbols(table.first);
119 }
120
121 return symbols;
122 }
123
124 static P4RuntimeSymbolTable *generateSymbols(const IR::P4Program *program,
125 const IR::ToplevelBlock *evaluatedProgram,
126 ReferenceMap *refMap, TypeMap *typeMap,
127 P4RuntimeArchHandlerIface *archHandler);
128
130 void add(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) override;
131
133 void add(P4RuntimeSymbolType type, cstring name,
134 std::optional<p4rt_id_t> id = std::nullopt) override;
135
138 p4rt_id_t getId(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) const override;
139
141 p4rt_id_t getId(P4RuntimeSymbolType type, cstring name) const override;
142
147 cstring getAlias(cstring name) const override;
148
149 private:
150 // Rather than call this constructor, use P4RuntimeSymbolTable::create().
151 P4RuntimeSymbolTable() = default;
152
156 p4rt_id_t tryToAssignId(std::optional<p4rt_id_t> id);
157
163 void computeIdsForSymbols(P4RuntimeSymbolType type);
164
176 template <typename ConstructIdFunc>
177 std::optional<p4rt_id_t> probeForId(const uint32_t sourceValue, ConstructIdFunc constructId) {
178 uint32_t value = sourceValue;
179 while (assignedIds.find(constructId(value)) != assignedIds.end()) {
180 ++value;
181 if (value == sourceValue) {
182 return std::nullopt; // We wrapped around; there's no unassigned
183 // id left.
184 }
185 }
186
187 return constructId(value);
188 }
189
190 // The hash function used for resource names.
191 // Taken from: https://en.wikipedia.org/wiki/Jenkins_hash_function
192 static uint32_t jenkinsOneAtATimeHash(const char *key, size_t length);
193
194 // All the ids we've assigned so far. Used to avoid id collisions; this is
195 // especially crucial since ids can be set manually via the '@id'
196 // annotation.
197 std::set<p4rt_id_t> assignedIds;
198
199 // Symbol tables, mapping symbols to P4Runtime ids.
200 using SymbolTable = std::map<cstring, p4rt_id_t>;
201 std::map<P4RuntimeSymbolType, SymbolTable> symbolTables{};
202
203 // A set which contains all the symbols in the program. It's used to compute
204 // the shortest unique suffix of each symbol, which is the default alias we
205 // use for P4Runtime objects.
206 P4SymbolSuffixSet suffixSet;
207};
208
209void collectControlSymbols(P4RuntimeSymbolTable &symbols, P4RuntimeArchHandlerIface *archHandler,
210 const IR::ControlBlock *controlBlock, ReferenceMap *refMap,
211 TypeMap *typeMap);
212
213void collectExternSymbols(P4RuntimeSymbolTable &symbols, P4RuntimeArchHandlerIface *archHandler,
214 const IR::ExternBlock *externBlock);
215
216void collectTableSymbols(P4RuntimeSymbolTable &symbols, P4RuntimeArchHandlerIface *archHandler,
217 const IR::TableBlock *tableBlock);
218
219void collectParserSymbols(P4RuntimeSymbolTable &symbols, const IR::ParserBlock *parserBlock);
220
221} // namespace ControlPlaneAPI
222
223} // namespace P4
224
225#endif /* CONTROL_PLANE_P4RUNTIMESYMBOLTABLE_H_ */
Definition p4RuntimeArchHandler.h:139
Definition p4RuntimeSymbolTable.h:93
p4rt_id_t getId(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) const override
Definition p4RuntimeSymbolTable.cpp:197
void add(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) override
Add a @type symbol, extracting the name and id from @declaration.
Definition p4RuntimeSymbolTable.cpp:180
cstring getAlias(cstring name) const override
Definition p4RuntimeSymbolTable.cpp:217
static P4RuntimeSymbolTable * create(Func function)
Definition p4RuntimeSymbolTable.h:109
Definition p4RuntimeArchHandler.h:109
Definition p4RuntimeArchHandler.h:63
The Declaration interface, representing objects with names.
Definition declaration.h:26
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeMap.h:41
Definition cstring.h:85
std::optional< p4rt_id_t > getIdAnnotation(const IR::IAnnotated *node)
Definition p4RuntimeSymbolTable.cpp:39
bool isControllerHeader(const IR::Type_Header *type)
Definition p4RuntimeSymbolTable.cpp:31
bool isHidden(const IR::IAnnotated *node)
Definition p4RuntimeSymbolTable.cpp:35
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition p4RuntimeSymbolTable.h:61
void addSymbol(const cstring &symbol)
Adds @symbol's suffixes to the set if it's not already present.
Definition p4RuntimeSymbolTable.cpp:338