Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Type_Dontcare for _ expressions in table entries #3444

Merged
merged 1 commit into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1914,8 +1914,6 @@ const IR::Node* TypeInference::postorder(IR::Key* key) {
}
LOG2("Setting key type to " << dbp(keyTuple));
setType(key, keyTuple);
// installing also for the original because we cannot tell which one will survive in the ir
LOG2("Setting key type to " << dbp(getOriginal()));
setType(getOriginal(), keyTuple);
return key;
}
Expand Down Expand Up @@ -1975,14 +1973,22 @@ const IR::Node* TypeInference::postorder(IR::Entry* entry) {
auto entryKeyType = getType(entry->keys);
if (entryKeyType == nullptr)
return entry;
if (entryKeyType->is<IR::Type_Set>())
entryKeyType = entryKeyType->to<IR::Type_Set>()->elementType;
if (auto ts = entryKeyType->to<IR::Type_Set>())
entryKeyType = ts->elementType;
if (entry->singleton) {
if (auto tl = entryKeyType->to<IR::Type_BaseList>()) {
// An entry of _ does not have type Tuple<Type_Dontcare>, but rather Type_Dontcare
if (tl->getSize() == 1 && tl->components.at(0)->is<IR::Type_Dontcare>())
entryKeyType = tl->components.at(0);
}
}

auto keyset = entry->getKeys();
if (keyset == nullptr || !(keyset->is<IR::ListExpression>())) {
typeError("%1%: key expression must be tuple", keyset);
return entry;
} else if (keyset->components.size() < key->keyElements.size()) {
}
if (keyset->components.size() < key->keyElements.size()) {
typeError("%1%: Size of entry keyset must match the table key set size", keyset);
return entry;
}
Expand All @@ -2009,7 +2015,7 @@ const IR::Node* TypeInference::postorder(IR::Entry* entry) {

if (ks != keyset)
entry = new IR::Entry(entry->srcInfo, entry->annotations,
ks->to<IR::ListExpression>(), entry->action);
ks->to<IR::ListExpression>(), entry->action, entry->singleton);

auto actionRef = entry->getAction();
auto ale = validateActionInitializer(actionRef, table);
Expand Down
4 changes: 2 additions & 2 deletions frontends/parsers/p4/p4parser.ypp
Original file line number Diff line number Diff line change
Expand Up @@ -1296,12 +1296,12 @@ actionRef
entry
: keysetExpression ":" actionRef optAnnotations ";"
{ if (auto l = $1->to<IR::ListExpression>())
$$ = new IR::Entry(@1+@4, $4, l, $3);
$$ = new IR::Entry(@1+@4, $4, l, $3, false);
else { // if not a tuple, make it a list of 1
IR::Vector<IR::Expression> le($1);
$$ = new IR::Entry(@1+@4, $4,
new IR::ListExpression(@1, le),
$3);
$3, true);
}
}
;
Expand Down
1 change: 1 addition & 0 deletions ir/ir.def
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ class Entry : IAnnotated {
ListExpression keys; /// must be a tuple expression
Expression action; /// typically a MethodCallExpression.
/// The action must be defined in action list
bool singleton; /// True if the entry is not a list.

Annotations getAnnotations() const override { return annotations; }
ListExpression getKeys() const { return keys; }
Expand Down
3 changes: 2 additions & 1 deletion midend/eliminateSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ const IR::Node* DoEliminateSwitch::postorder(IR::SwitchStatement* statement) {

for (auto lab : pendingLabels) {
if (!lab->is<IR::DefaultExpression>()) {
auto entry = new IR::Entry(scSrc, new IR::ListExpression({lab}), actionCall);
auto entry = new IR::Entry(scSrc, new IR::ListExpression({lab}),
actionCall, false);
entries.push_back(entry);
}
}
Expand Down
20 changes: 20 additions & 0 deletions testdata/p4_16_samples/issue3442.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <core.p4>

control c();
package p(c c);

control myc () {
action a() { }
action b() { }
table t {
key = {}
actions = { a; }
const entries = {
_ : a();
}
}
apply {
t.apply();
}
}
p(myc ()) main;
28 changes: 28 additions & 0 deletions testdata/p4_16_samples_outputs/issue3442-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <core.p4>

control c();
package p(c c);
control myc() {
action a() {
}
action b() {
}
table t {
key = {
}
actions = {
a();
@defaultonly NoAction();
}
const entries = {
default : a();
}
default_action = NoAction();
}
apply {
t.apply();
}
}

p(myc()) main;

28 changes: 28 additions & 0 deletions testdata/p4_16_samples_outputs/issue3442-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <core.p4>

control c();
package p(c c);
control myc() {
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("myc.a") action a() {
}
@name("myc.t") table t_0 {
key = {
}
actions = {
a();
@defaultonly NoAction_1();
}
const entries = {
default : a();
}
default_action = NoAction_1();
}
apply {
t_0.apply();
}
}

p(myc()) main;

28 changes: 28 additions & 0 deletions testdata/p4_16_samples_outputs/issue3442-midend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <core.p4>

control c();
package p(c c);
control myc() {
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("myc.a") action a() {
}
@name("myc.t") table t_0 {
key = {
}
actions = {
a();
@defaultonly NoAction_1();
}
const entries = {
default : a();
}
default_action = NoAction_1();
}
apply {
t_0.apply();
}
}

p(myc()) main;

26 changes: 26 additions & 0 deletions testdata/p4_16_samples_outputs/issue3442.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <core.p4>

control c();
package p(c c);
control myc() {
action a() {
}
action b() {
}
table t {
key = {
}
actions = {
a;
}
const entries = {
default : a();
}
}
apply {
t.apply();
}
}

p(myc()) main;

Empty file.