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