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