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

Support for [lsb+:width] slices #4917

Merged
merged 1 commit into from
Oct 3, 2024
Merged

Conversation

ChrisDodd
Copy link
Contributor

Initial support for Verilog-style [lsb+:width] slices, allowing variable index slices with a constant width.

Most backends will probably require that these be strength-reduced to constant (normal) indexes, which will happen with eg. unrolled loops where the index depends on the loop index.

@ChrisDodd ChrisDodd force-pushed the cdodd-slice branch 2 times, most recently from 4a72192 to 422673f Compare September 17, 2024 01:34
@fruffy fruffy added the p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/). label Sep 17, 2024
@ChrisDodd ChrisDodd force-pushed the cdodd-slice branch 6 times, most recently from 7ad797d to b7579c6 Compare September 20, 2024 08:03
ir/expression.def Outdated Show resolved Hide resolved
ir/expression.def Outdated Show resolved Hide resolved
ir/expression.def Outdated Show resolved Hide resolved
@ChrisDodd ChrisDodd force-pushed the cdodd-slice branch 4 times, most recently from 623c388 to 1149526 Compare September 30, 2024 01:24
@ChrisDodd ChrisDodd force-pushed the cdodd-slice branch 2 times, most recently from f07c9d6 to bdba4e7 Compare October 2, 2024 03:07
Copy link
Contributor

@asl asl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

Copy link
Contributor

@jafingerhut jafingerhut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I have only reviewed the new test program, but it is very cool to see that it exercises the ability of p4c to unroll a loop, and use the loop variable in a bit slice. Nice!

- allows for non-const lsb slices (width must still be const)

Signed-off-by: Chris Dodd <cdodd@nvidia.com>
@ChrisDodd ChrisDodd added this pull request to the merge queue Oct 3, 2024
Merged via the queue into p4lang:main with commit b07a695 Oct 3, 2024
18 checks passed
@ChrisDodd ChrisDodd deleted the cdodd-slice branch October 3, 2024 07:42
Comment on lines 1395 to 1401
bool save = lhs;
lhs = false; // slices on the LHS also read the data
visit(expression->e0);
visit(expression->e1); // this might not be a constant (for a PlusSlice)
LOG3("FU Returned from " << expression);
auto storage = getReads(expression->e0, true);
reads(expression, storage); // true even in LHS
Copy link
Contributor

@kfcripps kfcripps Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChrisDodd Shouldn't expression also read expression->e1 if expression is a IR::PlusSlice? Something like this:

        bool save = lhs;
        lhs = false;  // slices on the LHS also read the data
        visit(expression->e0);
        auto storage = getReads(expression->e0, true);

        if (expression->is<IR::PlusSlice>()) {
            visit(expression->e1);  // this might not be a constant (for a PlusSlice)
            auto idxStorage = getReads(expression->e1);
            reads(expression, storage->join(idxStorage));
        } else {
            reads(expression, storage);  // true even in LHS
        }
        LOG3("FU Returned from " << expression);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, unrelated to this PR, but do you know why expression reads expression->e0? I'm not sure I understand how, in a slice assignment such as x[hi:lo] = rhs;, x[hi:lo] "reads" x.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not entirely clear to me exactly how this pass works and what it expects for its invariants, but I based this (ie, just setting reads(expression... from expression->e0 and not ->e1) on what is done in the ArrayIndex code a few lines after this. In particular no compound expression ever calls storage->join to create a union of its children.

Overall, a lot of things in this pass seem confusingly misnamed. reads is just setting an element in an Expression* -> LocationSet map which generally just maps some expressions to the locations they read, but not all. So an expression like a[b] the PathExpressions will be in the map, and the arrayIndex will just refer to a, not b. Whereas for a+b, again the PathExpressions will be in the map, but the Add will not. The main (only?) purpose of this map is to print warnings in FindUninitialized::registerUses about potentially uninitialized things.

That gets into why (lvalue) slices "read" the storage location they are writing to -- the slice only writes part of the location, so previous writes are still "live". It seems likely this may cause spurious warnings though (if you have a variable that you write to with multiple slices that cover the whole thing, but you never write to it as a whole, you will probably get a warning about a subsequent read of the whole thing).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not entirely clear to me exactly how this pass works and what it expects for its invariants, but I based this (ie, just setting reads(expression... from expression->e0 and not ->e1) on what is done in the ArrayIndex code a few lines after this. In particular no compound expression ever calls storage->join to create a union of its children.

I noticed the ArrayIndex code too, and it also looks suspicious to me, although I don't know what the consequences are of not handling this case like I would expect it to be handled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants