P4C
The P4 Compiler
Loading...
Searching...
No Matches
remove_action_params.h
1
18
26#ifndef BACKENDS_TOFINO_BF_P4C_MIDEND_REMOVE_ACTION_PARAMS_H_
27#define BACKENDS_TOFINO_BF_P4C_MIDEND_REMOVE_ACTION_PARAMS_H_
28
29#include "frontends/p4/removeParameters.h"
30
31namespace BFN {
32
36class DoRemoveActionParametersTofino : public P4::DoRemoveActionParameters {
37 public:
38 DoRemoveActionParametersTofino(P4::ActionInvocation *inv, P4::TypeMap *typeMap,
39 MinimalNameGenerator *nameGen)
40 : P4::DoRemoveActionParameters(inv, typeMap, nameGen) {}
41
45 bool DoCheckReplaceParam(IR::P4Action *action, const IR::Parameter *p) {
46 int paramUses = 0;
47 int num_mark_to_drop = 0;
48 bool replace = true;
49 for (auto abc : action->body->components) {
50 /* iterate thought all statements, and find the uses of smeta */
51 /* if the only use is in mark_to_drop -- that's not a use! */
52 if (abc->is<IR::BaseAssignmentStatement>()) {
53 auto as = abc->to<IR::BaseAssignmentStatement>();
54 // TODO: Handle assignment statements with expressions
55 if (p->name == as->left->toString())
56 paramUses++;
57 else if (p->name == as->right->toString())
58 paramUses++;
59 } else if (abc->is<IR::MethodCallStatement>()) {
60 auto mcs = abc->to<IR::MethodCallStatement>();
61 auto mc = mcs->methodCall;
62 auto mce = mc->to<IR::MethodCallExpression>();
63 if ("mark_to_drop" == mce->method->toString()) {
64 num_mark_to_drop++;
65 } else {
66 for (auto arg : *(mce->arguments)) {
67 auto *argMem = arg->expression->to<IR::Member>();
68 if (argMem && p->name == argMem->toString()) paramUses++;
69 }
70 }
71 } else {
72 // TODO: Handle block statements
73 LOG3("not handling statement: " << abc);
74 }
75 }
76 if (num_mark_to_drop > 0 && paramUses == 0) {
77 replace = false;
78 }
79 return replace;
80 }
81
82 const IR::Node *postorder(IR::P4Action *action) {
83 LOG1("Visiting " << dbp(action));
84 BUG_CHECK(getParent<IR::P4Control>() || getParent<IR::P4Program>(),
85 "%1%: unexpected parent %2%", getOriginal(), getContext()->node);
86 auto result = new IR::IndexedVector<IR::Declaration>();
87 auto leftParams = new IR::IndexedVector<IR::Parameter>();
88 auto initializers = new IR::IndexedVector<IR::StatOrDecl>();
89 auto postamble = new IR::IndexedVector<IR::StatOrDecl>();
90 auto invocation = getInvocations()->get(getOriginal<IR::P4Action>());
91 if (invocation == nullptr) return action;
92 auto args = invocation->arguments;
93
94 P4::ParameterSubstitution substitution;
95 substitution.populate(action->parameters, args);
96
97 bool removeAll = getInvocations()->removeAllParameters(getOriginal<IR::P4Action>());
98 int numParamsNotReplaced = 0;
99 for (auto p : action->parameters->parameters) {
100 bool replaceParam = DoCheckReplaceParam(action, p);
101 if (p->direction == IR::Direction::None && !removeAll) {
102 leftParams->push_back(p);
103 } else {
104 if (replaceParam) {
105 auto decl = new IR::Declaration_Variable(p->srcInfo, p->name, p->annotations,
106 p->type, nullptr);
107 LOG3("Added declaration " << decl << " annotations " << p->annotations);
108 result->push_back(decl);
109
110 auto arg = substitution.lookup(p);
111 if (arg == nullptr) {
112 error("action %1%: parameter %2% must be bound", invocation, p);
113 continue;
114 }
115
116 if (p->direction == IR::Direction::In || p->direction == IR::Direction::InOut ||
117 p->direction == IR::Direction::None) {
118 auto left = new IR::PathExpression(p->name);
119 auto assign =
120 new IR::AssignmentStatement(arg->srcInfo, left, arg->expression);
121 initializers->push_back(assign);
122 }
123
124 if (p->direction == IR::Direction::Out ||
125 p->direction == IR::Direction::InOut) {
126 auto right = new IR::PathExpression(p->name);
127 auto assign =
128 new IR::AssignmentStatement(arg->srcInfo, arg->expression, right);
129 postamble->push_back(assign);
130 }
131 } else {
132 numParamsNotReplaced++;
133 }
134 }
135 }
136
137 if (result->empty()) {
138 if (numParamsNotReplaced > 0) {
139 for (auto abc : action->body->components) {
140 if (abc->is<IR::MethodCallStatement>()) {
141 auto mcs = abc->to<IR::MethodCallStatement>();
142 auto mc = mcs->methodCall;
143 auto mce = mc->to<IR::MethodCallExpression>();
144 // Add mark_to_drop action component with standard_metadata arg
145 if ("mark_to_drop" == mce->method->toString()) {
146 auto new_mce = new IR::MethodCallExpression(mce->method, args);
147 abc = new IR::MethodCallStatement(new_mce);
148 }
149 }
150 initializers->push_back(abc);
151 }
152 } else {
153 return action;
154 }
155 } else {
156 LOG1("To replace " << dbp(action));
157 initializers->append(action->body->components);
158 initializers->append(*postamble);
159 }
160
161 action->parameters = new IR::ParameterList(action->parameters->srcInfo, *leftParams);
162 action->body = new IR::BlockStatement(action->body->srcInfo, *initializers);
163 result->push_back(action);
164 return result;
165 }
166};
167
173class RemoveActionParameters : public PassManager {
174 public:
175 RemoveActionParameters(P4::ReferenceMap *refMap, P4::TypeMap *typeMap,
176 P4::TypeChecking *tc = nullptr) {
177 setName("RemoveActionParameters");
178 auto ai = new P4::ActionInvocation();
179 // MoveDeclarations() is needed because of this case:
180 // action a(inout x) { x = x + 1 }
181 // bit<32> w;
182 // table t() { actions = a(w); ... }
183 // Without the MoveDeclarations the code would become
184 // action a() { x = w; x = x + 1; w = x; } << w is not yet defined
185 // bit<32> w;
186 // table t() { actions = a(); ... }
187 passes.emplace_back(new P4::MoveDeclarations());
188 if (!tc) tc = new P4::TypeChecking(refMap, typeMap);
189 passes.emplace_back(tc);
190 auto nameGen = new MinimalNameGenerator();
191 passes.emplace_back(new P4::FindActionParameters(typeMap, ai));
192 passes.emplace_back(nameGen);
193 passes.emplace_back(new DoRemoveActionParametersTofino(ai, typeMap, nameGen));
194 passes.emplace_back(new P4::ClearTypeMap(typeMap));
195 }
196};
197
198} // end namespace BFN
199
200#endif /* BACKENDS_TOFINO_BF_P4C_MIDEND_REMOVE_ACTION_PARAMS_H_ */
Definition removeParameters.h:32
Definition typeChecker.h:32
Definition removeParameters.h:115
Definition removeParameters.h:73
Definition indexed_vector.h:40
Definition node.h:53
Definition referenceMap.h:36
Definition moveDeclarations.h:34
Definition parameterSubstitution.h:30
void populate(const IR::ParameterList *params, const IR::Vector< IR::Argument > *args)
Definition parameterSubstitution.cpp:34
Class used to encode maps from paths to declarations.
Definition referenceMap.h:67
Definition typeChecker.h:55
Definition typeMap.h:41
bool DoCheckReplaceParam(IR::P4Action *action, const IR::Parameter *p)
Definition remove_action_params.h:45
Definition remove_action_params.h:36
The namespace encapsulating Barefoot/Intel-specific stuff.
Definition bf-asm/alloc.h:10
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58