Skip to content

Commit fef6e5d

Browse files
author
Mihai Budiu
authored
Allow named arguments in calls; first step: types and grammar (#1222)
* Allow named arguments in calls; first step: types and grammar
1 parent 2cb9fd5 commit fef6e5d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+481
-331
lines changed

backends/bmv2/action.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ ConvertActions::convertActionBody(const IR::Vector<IR::StatOrDecl>* body, Util::
7676
prim = "remove_header";
7777
} else if (builtin->name == IR::Type_Stack::push_front) {
7878
BUG_CHECK(mc->arguments->size() == 1, "Expected 1 argument for %1%", mc);
79-
auto arg = conv->convert(mc->arguments->at(0));
79+
auto arg = conv->convert(mc->arguments->at(0)->expression);
8080
prim = "push";
8181
parameters->append(arg);
8282
} else if (builtin->name == IR::Type_Stack::pop_front) {
8383
BUG_CHECK(mc->arguments->size() == 1, "Expected 1 argument for %1%", mc);
84-
auto arg = conv->convert(mc->arguments->at(0));
84+
auto arg = conv->convert(mc->arguments->at(0)->expression);
8585
prim = "pop";
8686
parameters->append(arg);
8787
} else {

backends/bmv2/control.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ void ControlConverter::convertTableEntries(const IR::P4Table *table,
114114
action->emplace("action_id", id);
115115
auto actionData = mkArrayField(action, "action_data");
116116
for (auto arg : *actionCall->arguments) {
117-
actionData->append(stringRepr(arg->to<IR::Constant>()->value, 0));
117+
actionData->append(stringRepr(arg->expression->to<IR::Constant>()->value, 0));
118118
}
119119
entry->emplace("action_entry", action);
120120

@@ -199,7 +199,7 @@ ControlConverter::handleTableImplementation(const IR::Property* implementation,
199199
// TBD what about the else if cases below?
200200

201201
auto add_size = [&action_profile, &arguments](size_t arg_index) {
202-
auto size_expr = arguments->at(arg_index);
202+
auto size_expr = arguments->at(arg_index)->expression;
203203
int size;
204204
if (!size_expr->is<IR::Constant>()) {
205205
::error("%1% must be a constant", size_expr);
@@ -216,7 +216,7 @@ ControlConverter::handleTableImplementation(const IR::Property* implementation,
216216
table->emplace("type", "indirect_ws");
217217
action_profile->emplace("selector", selector);
218218
add_size(1);
219-
auto hash = arguments->at(0);
219+
auto hash = arguments->at(0)->expression;
220220
auto ei = P4::EnumInstance::resolve(hash, typeMap);
221221
if (ei == nullptr) {
222222
::error("%1%: must be a constant on this target", hash);
@@ -594,7 +594,7 @@ ControlConverter::convertTable(const CFG::TableNode* node,
594594
}
595595
auto expr = defact->value->to<IR::ExpressionValue>()->expression;
596596
const IR::P4Action* action = nullptr;
597-
const IR::Vector<IR::Expression>* args = nullptr;
597+
const IR::Vector<IR::Argument>* args = nullptr;
598598

599599
if (expr->is<IR::PathExpression>()) {
600600
auto path = expr->to<IR::PathExpression>()->path;
@@ -618,9 +618,10 @@ ControlConverter::convertTable(const CFG::TableNode* node,
618618
entry->emplace("action_const", defact->isConstant);
619619
auto fields = mkArrayField(entry, "action_data");
620620
if (args != nullptr) {
621+
// TODO: use argument names
621622
for (auto a : *args) {
622-
if (a->is<IR::Constant>()) {
623-
cstring repr = stringRepr(a->to<IR::Constant>()->value);
623+
if (a->expression->is<IR::Constant>()) {
624+
cstring repr = stringRepr(a->expression->to<IR::Constant>()->value);
624625
fields->append(repr);
625626
} else {
626627
::error("%1%: argument must evaluate to a constant integer", a);

backends/bmv2/deparser.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void ConvertDeparser::convertDeparserBody(const IR::Vector<IR::StatOrDecl>* body
4747
// arrays are expanded into elements.
4848
int size = type->to<IR::Type_Stack>()->getSize();
4949
for (int i=0; i < size; i++) {
50-
auto j = conv->convert(arg);
50+
auto j = conv->convert(arg->expression);
5151
auto e = j->to<Util::JsonObject>()->get("value");
5252
BUG_CHECK(e->is<Util::JsonValue>(),
5353
"%1%: Expected a Json value", e->toString());
@@ -56,7 +56,7 @@ void ConvertDeparser::convertDeparserBody(const IR::Vector<IR::StatOrDecl>* body
5656
result->append(ref);
5757
}
5858
} else if (type->is<IR::Type_Header>()) {
59-
auto j = conv->convert(arg);
59+
auto j = conv->convert(arg->expression);
6060
auto val = j->to<Util::JsonObject>()->get("value");
6161
result->append(val);
6262
} else {

backends/bmv2/extern.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,9 @@ Extern::addExternAttributes(const IR::Declaration_Instance*, // TODO: Unused pa
3535
}
3636
} else if (pVal->is<IR::Declaration_ID>()) {
3737
auto declId = pVal->to<IR::Declaration_ID>();
38-
json->add_extern_attribute(name, "string", declId->name, attributes);
39-
} else if (pVal->is<IR::Type_Enum>()) {
40-
json->add_extern_attribute(name, "string", pVal->toString(), attributes);
38+
json->add_extern_attribute(name, "string", declId->toString(), attributes);
4139
} else {
42-
BUG("%1%: unknown constructor param type", p->type);
40+
BUG("%1%: unexpected constructor argument", pVal);
4341
}
4442
}
4543
return attributes;

backends/bmv2/lower.cpp

+50-28
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,47 @@ RemoveComplexExpressions::createTemporary(const IR::Expression* expression) {
163163
auto decl = new IR::Declaration_Variable(IR::ID(name), type->getP4Type());
164164
newDecls.push_back(decl);
165165
typeMap->setType(decl, type);
166-
auto assign = new IR::AssignmentStatement(new IR::PathExpression(name), expression);
166+
auto assign = new IR::AssignmentStatement(
167+
expression->srcInfo, new IR::PathExpression(name), expression);
167168
assignments.push_back(assign);
168-
return new IR::PathExpression(name);
169+
return new IR::PathExpression(expression->srcInfo, new IR::Path(name));
170+
}
171+
172+
const IR::Vector<IR::Argument>*
173+
RemoveComplexExpressions::simplifyExpressions(const IR::Vector<IR::Argument>* args) {
174+
bool changes = true;
175+
auto result = new IR::Vector<IR::Argument>();
176+
for (auto arg : *args) {
177+
auto r = simplifyExpression(arg->expression, false);
178+
if (r != arg->expression) {
179+
changes = true;
180+
result->push_back(new IR::Argument(arg->srcInfo, arg->name, r));
181+
} else {
182+
result->push_back(arg);
183+
}
184+
}
185+
if (changes)
186+
return result;
187+
return args;
188+
}
189+
190+
const IR::Expression*
191+
RemoveComplexExpressions::simplifyExpression(const IR::Expression* expression, bool force) {
192+
if (expression->is<IR::ListExpression>()) {
193+
auto list = expression->to<IR::ListExpression>();
194+
auto simpl = simplifyExpressions(&list->components);
195+
if (simpl != &list->components)
196+
return new IR::ListExpression(expression->srcInfo, *simpl);
197+
return expression;
198+
} else {
199+
ComplexExpression ce;
200+
(void)expression->apply(ce);
201+
if (force || ce.isComplex) {
202+
LOG3("Moved into temporary " << dbp(expression));
203+
return createTemporary(expression);
204+
}
205+
return expression;
206+
}
169207
}
170208

171209
const IR::Vector<IR::Expression>*
@@ -178,28 +216,10 @@ RemoveComplexExpressions::simplifyExpressions(const IR::Vector<IR::Expression>*
178216
bool changes = true;
179217
auto result = new IR::Vector<IR::Expression>();
180218
for (auto e : *vec) {
181-
if (e->is<IR::ListExpression>()) {
182-
auto list = e->to<IR::ListExpression>();
183-
auto simpl = simplifyExpressions(&list->components);
184-
if (simpl != &list->components) {
185-
changes = true;
186-
auto l = new IR::ListExpression(e->srcInfo, *simpl);
187-
result->push_back(l);
188-
} else {
189-
result->push_back(e);
190-
}
191-
} else {
192-
ComplexExpression ce;
193-
(void)e->apply(ce);
194-
if (force || ce.isComplex) {
195-
changes = true;
196-
LOG3("Moved into temporary " << dbp(e));
197-
auto tmp = createTemporary(e);
198-
result->push_back(tmp);
199-
} else {
200-
result->push_back(e);
201-
}
202-
}
219+
auto r = simplifyExpression(e, force);
220+
if (r != e)
221+
changes = true;
222+
result->push_back(r);
203223
}
204224
if (changes)
205225
return result;
@@ -247,17 +267,19 @@ RemoveComplexExpressions::postorder(IR::MethodCallExpression* expression) {
247267
::error("%1% expected 2 arguments", expression);
248268
return expression;
249269
}
250-
auto vec = new IR::Vector<IR::Expression>();
270+
auto vec = new IR::Vector<IR::Argument>();
251271
// Digest has two arguments, we have to save the second one.
252272
// It should be a list expression.
253273
vec->push_back(expression->arguments->at(0));
254-
auto arg1 = expression->arguments->at(1);
274+
auto arg1 = expression->arguments->at(1)->expression;
255275
if (arg1->is<IR::ListExpression>()) {
256276
auto list = simplifyExpressions(&arg1->to<IR::ListExpression>()->components, true);
257277
arg1 = new IR::ListExpression(arg1->srcInfo, *list);
258-
vec->push_back(arg1);
278+
vec->push_back(new IR::Argument(arg1));
259279
} else {
260-
auto tmp = createTemporary(expression->arguments->at(1));
280+
auto tmp = new IR::Argument(
281+
expression->arguments->at(1)->srcInfo,
282+
createTemporary(expression->arguments->at(1)->expression));
261283
vec->push_back(tmp);
262284
}
263285
expression->arguments = vec;

backends/bmv2/lower.h

+3
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ class RemoveComplexExpressions : public Transform {
7676
IR::IndexedVector<IR::StatOrDecl> assignments;
7777

7878
const IR::PathExpression* createTemporary(const IR::Expression* expression);
79+
const IR::Expression* simplifyExpression(const IR::Expression* expression, bool force);
7980
const IR::Vector<IR::Expression>* simplifyExpressions(
8081
const IR::Vector<IR::Expression>* vec, bool force = false);
82+
const IR::Vector<IR::Argument>* simplifyExpressions(
83+
const IR::Vector<IR::Argument>* vec);
8184

8285
public:
8386
RemoveComplexExpressions(P4::ReferenceMap* refMap, P4::TypeMap* typeMap,

backends/bmv2/parser.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Util::IJson* ParserConverter::convertParserStatement(const IR::StatOrDecl* stat)
5555
cstring ename = argCount == 1 ? "extract" : "extract_VL";
5656
result->emplace("op", ename);
5757
auto arg = mce->arguments->at(0);
58-
auto argtype = typeMap->getType(arg, true);
58+
auto argtype = typeMap->getType(arg->expression, true);
5959
if (!argtype->is<IR::Type_Header>()) {
6060
::error("%1%: extract only accepts arguments with header types, not %2%",
6161
arg, argtype);
@@ -66,8 +66,8 @@ Util::IJson* ParserConverter::convertParserStatement(const IR::StatOrDecl* stat)
6666
cstring type;
6767
Util::IJson* j = nullptr;
6868

69-
if (arg->is<IR::Member>()) {
70-
auto mem = arg->to<IR::Member>();
69+
if (arg->expression->is<IR::Member>()) {
70+
auto mem = arg->expression->to<IR::Member>();
7171
auto baseType = typeMap->getType(mem->expr, true);
7272
if (baseType->is<IR::Type_Stack>()) {
7373
if (mem->member == IR::Type_Stack::next) {
@@ -80,15 +80,15 @@ Util::IJson* ParserConverter::convertParserStatement(const IR::StatOrDecl* stat)
8080
}
8181
if (j == nullptr) {
8282
type = "regular";
83-
j = conv->convert(arg);
83+
j = conv->convert(arg->expression);
8484
}
8585
auto value = j->to<Util::JsonObject>()->get("value");
8686
param->emplace("type", type);
8787
param->emplace("value", value);
8888

8989
if (argCount == 2) {
9090
auto arg2 = mce->arguments->at(1);
91-
auto jexpr = conv->convert(arg2, true, false);
91+
auto jexpr = conv->convert(arg2->expression, true, false);
9292
auto rwrap = new Util::JsonObject();
9393
// The spec says that this must always be wrapped in an expression
9494
rwrap->emplace("type", "expression");
@@ -107,14 +107,14 @@ Util::IJson* ParserConverter::convertParserStatement(const IR::StatOrDecl* stat)
107107
auto cond = mce->arguments->at(0);
108108
// false means don't wrap in an outer expression object, which is not needed
109109
// here
110-
auto jexpr = conv->convert(cond, true, false);
110+
auto jexpr = conv->convert(cond->expression, true, false);
111111
params->append(jexpr);
112112
}
113113
{
114114
auto error = mce->arguments->at(1);
115115
// false means don't wrap in an outer expression object, which is not needed
116116
// here
117-
auto jexpr = conv->convert(error, true, false);
117+
auto jexpr = conv->convert(error->expression, true, false);
118118
params->append(jexpr);
119119
}
120120
return result;
@@ -153,7 +153,7 @@ Util::IJson* ParserConverter::convertParserStatement(const IR::StatOrDecl* stat)
153153
primitive = "pop";
154154

155155
BUG_CHECK(mce->arguments->size() == 1, "Expected 1 argument for %1%", mce);
156-
auto arg = conv->convert(mce->arguments->at(0));
156+
auto arg = conv->convert(mce->arguments->at(0)->expression);
157157
pp->append(arg);
158158
} else {
159159
BUG("%1%: Unexpected built-in method", bi->name);

0 commit comments

Comments
 (0)