P4C
The P4 Compiler
Loading...
Searching...
No Matches
localizeActions.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 FRONTENDS_P4_LOCALIZEACTIONS_H_
18#define FRONTENDS_P4_LOCALIZEACTIONS_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/common/resolveReferences/resolveReferences.h"
22#include "frontends/p4/callGraph.h"
23#include "frontends/p4/typeChecking/typeChecker.h"
24#include "frontends/p4/unusedDeclarations.h"
25#include "ir/ir.h"
26#include "lib/ordered_set.h"
27
28namespace P4 {
29
31 public:
32 // For each control that uses an action and for each each global action
33 // we create a replacement.
34 std::map<const IR::P4Control *, ordered_map<const IR::P4Action *, const IR::P4Action *> *> repl;
35
36 const IR::P4Action *getReplacement(const IR::P4Action *action,
37 const IR::P4Control *control) const {
38 auto map = ::P4::get(repl, control);
39 if (map == nullptr) return nullptr;
40 if (map->find(action) != map->end()) return (*map)[action];
41 return nullptr;
42 }
43 void addReplacement(const IR::P4Action *action, const IR::P4Control *control,
44 const IR::P4Action *replacement) {
45 LOG1("Cloning global " << dbp(action) << " into " << dbp(replacement) << " for "
46 << dbp(control));
47 if (repl.find(control) == repl.end())
49 (*repl[control])[action] = replacement;
50 }
51};
52
53// Find global (i.e., declared at toplevel) actions and who uses them.
57 std::set<const IR::P4Action *> globalActions;
58
59 public:
60 explicit FindGlobalActionUses(GlobalActionReplacements *repl) : repl(repl) {
61 CHECK_NULL(repl);
62 setName("FindGlobalActionUses");
63 }
64 bool preorder(const IR::PathExpression *path) override;
65 bool preorder(const IR::P4Action *action) override;
66 profile_t init_apply(const IR::Node *node) override;
67};
68
69// Global actions are cloned into actions local to the
70// control using them. One action can produce many copies.
73
74 public:
75 explicit LocalizeActions(GlobalActionReplacements *repl) : repl(repl) {
76 visitDagOnce = false;
77 CHECK_NULL(repl);
78 setName("LocalizeActions");
79 }
80 const IR::Node *postorder(IR::P4Control *control) override;
81 const IR::Node *postorder(IR::PathExpression *expression) override;
82};
83
85 public:
86 // For each action and each user the replacement action to use.
87 // Node is either a P4Table or MethodCallExpression.
88 std::map<const IR::P4Action *, ordered_map<const IR::Node *, const IR::P4Action *> *> toInsert;
89 std::map<const IR::PathExpression *, const IR::P4Action *> repl;
90 // For each action all replacements to insert
91
92 const IR::P4Action *getActionUser(const IR::P4Action *action, const IR::Node *user) {
93 if (toInsert.find(action) == toInsert.end()) return nullptr;
94 auto map = toInsert[action];
95 CHECK_NULL(map);
96 if (map->find(user) == map->end()) return nullptr;
97 return (*map)[user];
98 }
99 void createReplacement(const IR::P4Action *original, const IR::Node *user,
100 const IR::P4Action *replacement) {
101 auto map = toInsert[original];
102 if (map == nullptr) {
104 toInsert[original] = map;
105 }
106 (*map)[user] = replacement;
107 }
108 // In the specified path replace the original with the replacement
109 void setRefReplacement(const IR::PathExpression *path, const IR::P4Action *replacement) {
110 LOG1("Adding replacement " << dbp(replacement) << " used by " << dbp(path));
111 repl[path] = replacement;
112 }
113};
114
115// Find actions that are invoked in multiple places; create a new
116// copy for each invocation and store it in the repl map. Ignores
117// actions that are not in a control.
119 MinimalNameGenerator nameGen;
120 ActionReplacement *repl;
121
122 public:
123 explicit FindRepeatedActionUses(ActionReplacement *repl) : repl(repl) {
124 CHECK_NULL(repl);
125 setName("FindRepeatedActionUses");
126 }
127 bool preorder(const IR::PathExpression *expression) override;
128 profile_t init_apply(const IR::Node *node) override;
129};
130
131// Replicates actions for each different user.
132// Should be run after LocalizeActions.
134 ActionReplacement *repl;
135
136 public:
137 explicit DuplicateActions(ActionReplacement *repl) : repl(repl) {
138 visitDagOnce = false;
139 CHECK_NULL(repl);
140 setName("DuplicateActions");
141 }
142 const IR::Node *postorder(IR::PathExpression *expression) override;
143 const IR::Node *postorder(IR::P4Control *control) override;
144};
145
146// Add a @name annotation on each global action that does not have one
148 public:
149 TagGlobalActions() { setName("TagGlobalActions"); }
150 const IR::Node *preorder(IR::P4Action *action) override;
151 const IR::Node *preorder(IR::P4Parser *parser) override {
152 prune();
153 return parser;
154 }
155 const IR::Node *preorder(IR::P4Control *control) override {
156 prune();
157 return control;
158 }
159};
160
167 GlobalActionReplacements globalReplacements;
168 ActionReplacement localReplacements;
169
170 public:
171 explicit LocalizeAllActions(ReferenceMap *refMap, const RemoveUnusedPolicy &policy) {
172 passes.emplace_back(new TagGlobalActions());
173 passes.emplace_back(new PassRepeated{
174 new FindGlobalActionUses(&globalReplacements),
175 new LocalizeActions(&globalReplacements),
176 });
177 passes.emplace_back(new FindRepeatedActionUses(&localReplacements));
178 passes.emplace_back(new DuplicateActions(&localReplacements));
179 passes.emplace_back(new ResolveReferences(refMap));
180 passes.emplace_back(new RemoveAllUnusedDeclarations(refMap, policy));
181 setName("LocalizeAllActions");
182 }
183};
184
185} // namespace P4
186
187#endif /* FRONTENDS_P4_LOCALIZEACTIONS_H_ */
Definition localizeActions.h:84
Definition localizeActions.h:133
Definition localizeActions.h:54
Definition localizeActions.h:118
Definition localizeActions.h:30
Definition node.h:95
Definition visitor.h:400
Definition localizeActions.h:71
Definition localizeActions.h:166
Definition referenceMap.h:36
Definition pass_manager.h:40
Definition pass_manager.h:145
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Iterates RemoveUnusedDeclarations until convergence.
Definition unusedDeclarations.h:146
Definition unusedDeclarations.h:28
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:33
Definition resolveReferences.h:121
Definition localizeActions.h:147
Definition visitor.h:424
Definition visitor.h:78
Definition ordered_map.h:32
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24