P4C
The P4 Compiler
Loading...
Searching...
No Matches
uniqueNames.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 FRONTENDS_P4_UNIQUENAMES_H_
9#define FRONTENDS_P4_UNIQUENAMES_H_
10
11#include "frontends/common/resolveReferences/referenceMap.h"
12#include "frontends/common/resolveReferences/resolveReferences.h"
13#include "frontends/p4/typeMap.h"
14#include "ir/ir.h"
15#include "ir/pass_manager.h"
16#include "ir/visitor.h"
17
18namespace P4 {
19
20class RenameMap {
22 std::map<const IR::IDeclaration *, cstring> newName;
24 std::map<const IR::MethodCallExpression *, const IR::P4Action *> actionCall;
25
26 public:
30 void setNewName(const IR::IDeclaration *decl, cstring name, bool allowOverride = false);
31
33 cstring getName(const IR::IDeclaration *decl) const {
34 auto n = get(decl);
35 BUG_CHECK(n.has_value(), "%1%: no new name", decl);
36 return *n;
37 }
38
40 bool toRename(const IR::IDeclaration *decl) const {
41 CHECK_NULL(decl);
42 return newName.find(decl) != newName.end();
43 }
44
46 std::optional<cstring> get(const IR::IDeclaration *decl) const {
47 CHECK_NULL(decl);
48 if (auto it = newName.find(decl); it != newName.end()) {
49 return it->second;
50 }
51 return {};
52 }
53
54 void foundInTable(const IR::P4Action *action);
55 void markActionCall(const IR::P4Action *action, const IR::MethodCallExpression *call);
56 const IR::P4Action *actionCalled(const IR::MethodCallExpression *expression) const;
57};
58
61class UniqueNames : public PassManager {
62 private:
63 RenameMap *renameMap;
64
65 public:
66 UniqueNames();
67};
68
72class FindSymbols : public Inspector {
73 MinimalNameGenerator nameGen; // used to generate new names
74 RenameMap *renameMap;
75
76 public:
77 bool isTopLevel() const {
78 return !isInContext<IR::P4Parser>() && !isInContext<IR::P4Control>();
79 }
80 explicit FindSymbols(RenameMap *renameMap) : renameMap(renameMap) {
81 CHECK_NULL(renameMap);
82 setName("FindSymbols");
83 }
84 profile_t init_apply(const IR::Node *node) override {
85 auto rv = Inspector::init_apply(node);
86 node->apply(nameGen);
87 return rv;
88 }
89
90 void doDecl(const IR::Declaration *decl) {
91 cstring newName = nameGen.newName(decl->getName().string_view());
92 renameMap->setNewName(decl, newName);
93 }
94 void postorder(const IR::Declaration_Variable *decl) override { doDecl(decl); }
95 void postorder(const IR::Declaration_Constant *decl) override {
96 // Skip toplevel constants with names like __
97 // We assume that these do not clash and no new symbols with
98 // these names will be added.
99 if (decl->getName().name.startsWith("__") && getParent<IR::P4Program>()) return;
100 doDecl(decl);
101 }
102 void postorder(const IR::Declaration_Instance *decl) override {
103 if (!isTopLevel()) doDecl(decl);
104 }
105 void postorder(const IR::P4Table *decl) override { doDecl(decl); }
106 void postorder(const IR::P4Action *decl) override {
107 if (!isTopLevel()) doDecl(decl);
108 }
109 void postorder(const IR::P4ValueSet *decl) override {
110 if (!isTopLevel()) doDecl(decl);
111 }
112};
113
114class RenameSymbols : public Transform, public ResolutionContext {
115 protected:
116 RenameMap *renameMap;
117
119 IR::ID *getName() const;
122 IR::ID *getName(const IR::IDeclaration *decl) const;
123
126 template <typename D>
127 const IR::Node *renameDeclWithNameAnnotation(D *decl) {
128 auto name = getName();
129 if (name != nullptr && *name != decl->name) {
130 decl->addAnnotationIfNew(IR::Annotation::nameAnnotation,
131 new IR::StringLiteral(decl->name));
132 decl->name = *name;
133 }
134 return decl;
135 }
136
137 public:
138 explicit RenameSymbols(RenameMap *renameMap) : renameMap(renameMap) {
139 CHECK_NULL(renameMap);
140 visitDagOnce = false;
141 setName("RenameSymbols");
142 }
143 const IR::Node *postorder(IR::Declaration_Variable *decl) override;
144 const IR::Node *postorder(IR::Declaration_Constant *decl) override;
145 const IR::Node *postorder(IR::PathExpression *expression) override;
146 const IR::Node *postorder(IR::Declaration_Instance *decl) override;
147 const IR::Node *postorder(IR::P4Table *decl) override;
148 const IR::Node *postorder(IR::P4Action *decl) override;
149 const IR::Node *postorder(IR::P4ValueSet *decl) override;
150 const IR::Node *postorder(IR::Parameter *param) override;
151 const IR::Node *postorder(IR::Argument *argument) override;
152};
153
155class FindParameters : public Inspector {
156 MinimalNameGenerator nameGen;
157 RenameMap *renameMap;
158
159 void doParameters(const IR::ParameterList *pl) {
160 for (auto p : pl->parameters) {
161 cstring newName = nameGen.newName(p->name.string_view());
162 renameMap->setNewName(p, newName);
163 }
164 }
165
166 public:
167 explicit FindParameters(RenameMap *renameMap) : renameMap(renameMap) {
168 CHECK_NULL(renameMap);
169 setName("FindParameters");
170 }
171 void postorder(const IR::P4Action *action) override { doParameters(action->parameters); }
172 profile_t init_apply(const IR::Node *node) override;
173};
174
177class UniqueParameters : public PassManager {
178 private:
179 RenameMap *renameMap;
180
181 public:
182 explicit UniqueParameters(TypeMap *typeMap);
183};
184
185} // namespace P4
186
187#endif /* FRONTENDS_P4_UNIQUENAMES_H_ */
The Declaration interface, representing objects with names.
Definition declaration.h:17
Definition node.h:53
Definition visitor.h:418
Definition referenceMap.h:36
Definition uniqueNames.h:20
void setNewName(const IR::IDeclaration *decl, cstring name, bool allowOverride=false)
Add rename entry for the declaration to be named with the given name.
Definition uniqueNames.cpp:14
std::optional< cstring > get(const IR::IDeclaration *decl) const
Get new name for the declaration (wrapped in optional), or std::nullopt if there is none.
Definition uniqueNames.h:46
cstring getName(const IR::IDeclaration *decl) const
Get new name for the declaration, fails if none exists.
Definition uniqueNames.h:33
bool toRename(const IR::IDeclaration *decl) const
Definition uniqueNames.h:40
IR::ID * getName() const
Get new name of the current declaration or nullptr if the declaration is not to be renamed.
Definition uniqueNames.cpp:81
Definition visitor.h:442
Definition typeMap.h:32
Definition visitor.h:78
Definition cstring.h:85
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Definition id.h:28