-
Notifications
You must be signed in to change notification settings - Fork 463
Generalized array support #5115
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
base: main
Are you sure you want to change the base?
Conversation
74a47dc
to
618c817
Compare
Nice! The test cases look interesting. As usual (unforunately), I haven't attempted to review the C++ implementation code. What is the behavior if you attempt to use an index expression that is not a compile-time known value? I could imagine trying to allow that if the index expression type was |
The frontend/midend won't do anything about it, but I would imaging that many targets would be unable to support non-constant indexes and the backend would reject it. It is not clear what a target that could support non-constant indexes could/should do about out of range indexes. In all of this, an array is the same as a header stack. This really just makes header stacks a special case of arrays -- they support some additional functions that arrays of non-header/header union types do not. |
629eb4e
to
176cee2
Compare
header data_t { | ||
bit<32> f1; | ||
bit<32> f2; | ||
bit<16> h1; | ||
bit<16> h2; | ||
bit<8>[16] arr; | ||
} |
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.
Could you please add positive and/or error test cases similar to the following to demonstrate what is expected when the array type is an array type or contains array types?
struct S {
bit<16> f1;
bit<8>[16] nested_arr;
bit<16> f2;
}
header data_t {
bit<32> f1;
bit<32> f2;
bit<16> h1;
bit<16> h2;
S[16] arr;
}
...
hdr.data.arr[x].nested_arr[y] = ...;
... = hdr.data.arr[z].nested_arr[w];
...
and (if the grammar allows it (I did not look very closely at changes to p4parser.ypp
)):
header data_t {
bit<32> f1;
bit<32> f2;
bit<16> h1;
bit<16> h2;
bit<8>[16][16] arr;
}
...
hdr.data.arr[x][y] = ...;
... = hdr.data.arr[z][w];
...
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.
While these are allowed, perhaps they shouldn't be. They end up running extremely slowly, as the HSIndexSimplifier pass (which replaces non-constant indexes with if trees) winds up replcating this assignment 65536 times (all the possible combinations of indexes for x, y, z, and w) with as many ifs. Not terribly practical.
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.
Explicitly disallowing nested arrays is completely fine with me (as long as it's made clear in the spec).
176cee2
to
01ee268
Compare
struct S { | ||
bit<16> f1; | ||
bit<8>[16] nested_arr; | ||
bit<16> f2; | ||
} | ||
|
||
header data_t { | ||
S[16] arr; | ||
bit<4> w; | ||
bit<4> x; | ||
bit<4> y; | ||
bit<4> z; | ||
} |
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.
Should we also test the other case I mentioned (i.e.
header data_t {
bit<32> f1;
bit<32> f2;
bit<16> h1;
bit<16> h2;
bit<8>[16][16] arr;
}
...
hdr.data.arr[x][y] = ...;
... = hdr.data.arr[z][w];
...
) (assuming that the grammar allows it)?
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 code blows up too much. Even with only 2 indexes in a single statement, it gets 256 variants which expands the memory a lot and takes 5-10 minutes to run the test. Trying to do 3+ really blows up.
There are probably things that could be improved in HSIndexSimplifier pass to not blow up quite as badly, but it is tricky and probably beyond the scope of this change.
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.
Is there a reason we do not want to explicitly disallow this case (by detecting it and emitting an error message)? Is it because not all backends run HSIndexSimplifier
? If that's the case, then why not detect it inside of HSIndexSimplifier
pass, before HSIndexContretizer
(and exit with an error instead of running HSIndexContretizer
if it is detected)?
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.
The same problem can happen even without 2D arrays if they are large enough. The best "quick-fix" for HSIndexSimplifier is probably to put in a limit to the number of branch leaves inserted at 100 or so -- that would avoid any case that had a huge blowup independent of dimensions and such,
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.
Ugh, HSIndexSimplifier
is just broken in how it deals with multiple indexes on arrays/header stacks. It basically goes over things multiple times, hoping everything gets expanded, which may or may not happen (and may create many unneeded duplicates of things).
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.
I've add a limit to the expansion in HSIndexSimplifier -- it now tracks how many additional things it is adding and errors out at an arch-specified limit (defaults to 1000).
I don't like the code of this pass -- it is pretty convoluted and probably broken for some corner cases we don't check. Should be replaced by a simpler pass that does not create and apply sub-passes dynamically and does a better job.
Takeaways from LDWG:
|
01ee268
to
08c5498
Compare
08c5498
to
4150286
Compare
Relax the requirement that IR::Type_Stack element types are headers, which allows using arrays of any type, though non-headers cannot support push/pop/last/next stuff which looks at header valid bits. Signed-off-by: Chris Dodd <[email protected]>
- this allows declaring arrays as in C (eg, `bit<8> data[16];`) rather than in the java style previously required (`bit<8> [16] data;`) Signed-off-by: Chris Dodd <[email protected]>
Signed-off-by: Chris Dodd <[email protected]>
Signed-off-by: Chris Dodd <[email protected]>
- default limit of 1000 extra statements per control (can be changed by arch), generating an error if more than that are needed. - fix FindUninitialized::processHeadersInAssignment to not crash on arrays that are not header stacks. Signed-off-by: Chris Dodd <[email protected]>
First change relaxes frontend checks to allow arrays in general as per p4lang/p4-spec#1320. Non-header arrays only support indexing, not any other header stack operations
Second change adds support for C-style array declarators, with the array size after the name instead of before it.