-
Notifications
You must be signed in to change notification settings - Fork 441
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
Bug fix in typechecker: fixes #1937 #1948
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
Copyright 2019 Cisco Systems, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { bit<8> f1; bit<8> f2; } | ||
struct headers_t { h1_t h1; } | ||
struct metadata_t { } | ||
|
||
action foo (out bit<8> x, in bit<8> y = 5) { | ||
x = (y >> 2); | ||
} | ||
|
||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
foo(hdr.h1.f1, hdr.h1.f1); | ||
foo(hdr.h1.f2); | ||
} | ||
} | ||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { state start { transition accept; } } | ||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { apply { } } | ||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control deparserImpl(packet_out packet, in headers_t hdr) { apply { } } | ||
V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
Copyright 2019 Cisco Systems, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { bit<8> f1; bit<8> f2; } | ||
struct headers_t { h1_t h1; } | ||
struct metadata_t { } | ||
|
||
parser foo (out bit<8> x, in bit<8> y = 5) { | ||
state start { | ||
x = (y >> 2); | ||
transition accept; | ||
} | ||
} | ||
|
||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
state start { | ||
foo.apply(hdr.h1.f1, hdr.h1.f1); | ||
foo.apply(hdr.h1.f2); | ||
transition accept; | ||
} | ||
} | ||
|
||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { apply { } } | ||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { apply { } } | ||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control deparserImpl(packet_out packet, in headers_t hdr) { apply { } } | ||
V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
Copyright 2019 Cisco Systems, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { bit<8> f1; bit<8> f2; } | ||
struct headers_t { h1_t h1; } | ||
struct metadata_t { } | ||
|
||
control foo (out bit<8> x, in bit<8> y = 5) { | ||
apply { | ||
x = (y >> 2); | ||
} | ||
} | ||
|
||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
foo.apply(hdr.h1.f1, hdr.h1.f1); | ||
foo.apply(hdr.h1.f2); | ||
} | ||
} | ||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { state start { transition accept; } } | ||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { apply { } } | ||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { apply { } } | ||
control deparserImpl(packet_out packet, in headers_t hdr) { apply { } } | ||
V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#include <core.p4> | ||
|
||
header h1_t { bit<8> f1; bit<8> f2; } | ||
|
||
parser foo (out bit<8> x, in bit<8> y = 5) { | ||
state start { | ||
x = (y >> 2); | ||
transition accept; | ||
} | ||
} | ||
|
||
parser parserImpl(out h1_t hdr) { | ||
state start { | ||
foo.apply(hdr.f1, hdr.f1); | ||
foo.apply(hdr.f2); | ||
transition accept; | ||
} | ||
} | ||
|
||
parser p<T>(out T h); | ||
package top<T>(p<T> p); | ||
|
||
top(parserImpl()) main; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { | ||
bit<8> f1; | ||
bit<8> f2; | ||
} | ||
|
||
struct headers_t { | ||
h1_t h1; | ||
} | ||
|
||
struct metadata_t { | ||
} | ||
|
||
action foo(out bit<8> x, in bit<8> y=5) { | ||
x = y >> 2; | ||
} | ||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
foo(hdr.h1.f1, hdr.h1.f1); | ||
foo(x = hdr.h1.f2, y = 8w5); | ||
} | ||
} | ||
|
||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
state start { | ||
transition accept; | ||
} | ||
} | ||
|
||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
} | ||
} | ||
|
||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control deparserImpl(packet_out packet, in headers_t hdr) { | ||
apply { | ||
} | ||
} | ||
|
||
V1Switch<headers_t, metadata_t>(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { | ||
bit<8> f1; | ||
bit<8> f2; | ||
} | ||
|
||
struct headers_t { | ||
h1_t h1; | ||
} | ||
|
||
struct metadata_t { | ||
} | ||
|
||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
@name(".foo") action foo(out bit<8> x, in bit<8> y=5) { | ||
x = y >> 2; | ||
} | ||
@name(".foo") action foo_0(out bit<8> x_1, in bit<8> y_1=5) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having two actions with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense that the compiler is taking one action, and creating two separate actions from it? Why is that useful? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code makes sure that each action is used in a single table. For some targets there is no action reuse anyway; if you have the same code you have to implement it twice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not an error, you can have multiple actions with the same name; the control-plane disambiguates them through the tables that invoke them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are both invoked by the same table, so no such through-the-table disambiguation is possible here, is it? |
||
x_1 = y_1 >> 2; | ||
} | ||
bit<8> tmp; | ||
bit<8> tmp_0; | ||
apply { | ||
tmp_0 = hdr.h1.f1; | ||
foo(tmp, tmp_0); | ||
hdr.h1.f1 = tmp; | ||
foo_0(x_1 = hdr.h1.f2, y_1 = 8w5); | ||
} | ||
} | ||
|
||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
state start { | ||
transition accept; | ||
} | ||
} | ||
|
||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
} | ||
} | ||
|
||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control deparserImpl(packet_out packet, in headers_t hdr) { | ||
apply { | ||
} | ||
} | ||
|
||
V1Switch<headers_t, metadata_t>(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
header h1_t { | ||
bit<8> f1; | ||
bit<8> f2; | ||
} | ||
|
||
struct headers_t { | ||
h1_t h1; | ||
} | ||
|
||
struct metadata_t { | ||
} | ||
|
||
control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
bit<8> tmp; | ||
bit<8> tmp_0; | ||
@name(".foo") action foo() { | ||
tmp = tmp_0 >> 2; | ||
} | ||
@name(".foo") action foo_0() { | ||
hdr.h1.f2 = 8w1; | ||
} | ||
@hidden action act() { | ||
tmp_0 = hdr.h1.f1; | ||
} | ||
@hidden action act_0() { | ||
hdr.h1.f1 = tmp; | ||
} | ||
@hidden table tbl_act { | ||
actions = { | ||
act(); | ||
} | ||
const default_action = act(); | ||
} | ||
@hidden table tbl_foo { | ||
actions = { | ||
foo(); | ||
} | ||
const default_action = foo(); | ||
} | ||
@hidden table tbl_act_0 { | ||
actions = { | ||
act_0(); | ||
} | ||
const default_action = act_0(); | ||
} | ||
@hidden table tbl_foo_0 { | ||
actions = { | ||
foo_0(); | ||
} | ||
const default_action = foo_0(); | ||
} | ||
apply { | ||
tbl_act.apply(); | ||
tbl_foo.apply(); | ||
tbl_act_0.apply(); | ||
tbl_foo_0.apply(); | ||
} | ||
} | ||
|
||
parser parserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
state start { | ||
transition accept; | ||
} | ||
} | ||
|
||
control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { | ||
apply { | ||
} | ||
} | ||
|
||
control updateChecksum(inout headers_t hdr, inout metadata_t meta) { | ||
apply { | ||
} | ||
} | ||
|
||
control deparserImpl(packet_out packet, in headers_t hdr) { | ||
apply { | ||
} | ||
} | ||
|
||
V1Switch<headers_t, metadata_t>(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This applying a clone and ignoring the return value just to update the typeMap still bugs me -- its a symptom of the messiness of having the typeMap separate from the type field(s) in the IR that I really would like to clean up eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the referenceMap should be easier.
The typechecking pass has grown quite complicated. Some of the complications are probably unnecessary - like maintaining canonical types. But I don't see how you can maintain such a complicated graph of types without an auxiliary data structure.
The most annoying thing about type checking is that it needs to run over and over, any time the graph changes. But I think that the alternative of having each pass compute types on its own is worse. At least this way the type checking is centralized in a single pass.