-
Notifications
You must be signed in to change notification settings - Fork 445
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
constant folding streamlining, bugfixes, and Doxygen comments #541
Conversation
I realized that there are more cases to consider. H[2] h; Also: control c()(bit<32> sz) { H[sz] h; apply {}} |
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 don't see a test case for the failure cases you have described. Please add new test cases in testdata.
Otherwise it looks fine.
frontends/common/constantFolding.h
Outdated
bool typesKnown; | ||
bool warnings; // if true emit warnings | ||
// maps expressions and declarations to their constant values | ||
std::map<const IR::Node*, const IR::Expression*> constants; | ||
std::map<const IR::Declaration_Constant*, const IR::Expression*> constants; |
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.
You have to update the comment above.
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.
Also, please update the reference outputs. This can be done by running each failed test with the -f flag - after you made sure that the produced output is the intended one. For example:
./p4/testdata/p4_16_samples/stack.p4.test -f
will update the output produced by this test.
you should rebase on master, not merge master. |
The GitHub web interface triggers these merges... |
That's why I never trusted GUIs ... |
Yeah. I wish the Github web interface would let you "Update branch" using a rebase instead of a merge. It would save a lot of time. |
|
frontends/common/constantFolding.cpp
Outdated
return expr; | ||
if (expr->is<IR::BoolLiteral>()) | ||
} | ||
if (expr->is<IR::BoolLiteral>()) { |
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.
Seems like this could be just expr->is<IR::Literal>()
to get Constant, BoolLiteral and StringLiteral
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.
String literals are not currently folded, so this would change the logic of the function. Leaving it as-is for now.
frontends/common/constantFolding.cpp
Outdated
if (expr->is<IR::ListExpression>()) { | ||
auto list = expr->to<IR::ListExpression>(); | ||
for (auto e : list->components) | ||
if (getConstant(e) == nullptr) | ||
if (getConstant(e) == nullptr) { |
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.
Our style guidelines do not require braces for this case.
Since @ChrisDodd prefers not to squander vertical space, I have avoided using them; they take 1 extra line.
frontends/common/constantFolding.cpp
Outdated
if (init->is<IR::Constant>()) { | ||
auto cst = init->to<IR::Constant>(); | ||
if (d->type->is<IR::Type_Bits>()) { | ||
if (cst->type->is<IR::Type_InfInt>() || | ||
(cst->type->is<IR::Type_Bits>() && | ||
!(*d->type->to<IR::Type_Bits>() == *cst->type->to<IR::Type_Bits>()))) | ||
!(*d->type->to<IR::Type_Bits>() == *cst->type->to<IR::Type_Bits>()))) |
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.
You should set-up your editor to delete spaces at the end of lines.
frontends/common/constantFolding.cpp
Outdated
} | ||
} | ||
if (init != d->initializer) |
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.
So here no braces?
frontends/common/constantFolding.h
Outdated
bool typesKnown; | ||
bool warnings; // if true emit warnings | ||
// maps expressions and declarations to their constant values | ||
std::map<const IR::Node*, const IR::Expression*> constants; | ||
// maps declaration constants to constant values |
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 comment could have three slashes
@@ -0,0 +1,16 @@ | |||
#include <core.p4> |
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.
How about some of the tests I suggested in comments, e.g.
H[h1.size+1] h2
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.
In principle, this should be possible, but it would be a deeper change based on how the passes are currently organized:
-
We don't fold IR::Members until after type checking.
-
In particular, we need to know the type of the expression to create a constant with the appropriate width.
-
But the type checker requires header stacks to have a compile-time known constant as their size.
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 should be either a positive or a negative test. If it is negative it should have a good error message.
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.
Added stack3.p4 as an error test.
Okay, I think this is finally ready to go. Please let me know if you have more feedback. |
frontends/common/constantFolding.cpp
Outdated
return e; | ||
return v; | ||
if (decl->is<IR::Declaration_Constant>()) { | ||
auto dc = decl->to<IR::Declaration_Constant>(); |
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.
Stylisticly I prefer combining these two lines as
if (auto dc = decl->to<IR::Declaration_Constant>()) {
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.
Done.
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.
Actually, this doesn't compile. So I reverted.
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.
You forgot the =
sign in your code. It would compile.
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.
Mea culpa! I'll push one more time.
frontends/common/constantFolding.cpp
Outdated
d = new IR::Declaration_Constant(d->srcInfo, d->name, d->annotations, d->type, init); | ||
auto orig = getOriginal()->to<IR::Declaration_Constant>(); | ||
BUG_CHECK(orig, "getOriginal() did not return a Declaration_Constant"); | ||
constants.emplace(orig, init); |
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.
These 3 lines could be replaced by
constants.emplace(getOriginal<IR::Declaration_Constant>(), init);
-- the templated version of getOriginal
does the cast and the BUG_CHECK.
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.
Cool. Done.
@@ -0,0 +1,42 @@ | |||
/* |
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.
Where is the output generated by the compiler for this test?
There should be a file stack3.p4-stderr at the very least.
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.
Added.
My fault, I didn't understand the protocol for adding tests that fail to
compile. I'll grab the stderr and stash it in the repo now.
…-N
On Mon, May 8, 2017 at 3:44 PM, Mihai Budiu ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In testdata/p4_16_errors/stack3.p4
<#541 (comment)>:
> @@ -0,0 +1,42 @@
+/*
Where is the output generated by the compiler for this test?
There should be a file stack3.p4-stderr at the very least.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#541 (review)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABwi0gdvCzpBDLl1aJqcznyQ5TNpK0Prks5r35rIgaJpZM4NLvDc>
.
|
In general you should git add everything in testdata after running a test. |
Got it. Thanks!
…On Mon, May 8, 2017 at 3:47 PM, Mihai Budiu ***@***.***> wrote:
In general you should git add everything in testdata after running a test.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#541 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABwi0kxI6GmnZP0ADKumcBXaTqHHT8dfks5r35tygaJpZM4NLvDc>
.
|
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 commit only contains some changes in the control-plane folder, but no files in testdata.
@jnfoster I doubt you meant to update the PI submodule ref pointer (you probably shouldn't) |
Gah. I think this is from pushing the update branch button here and then pushing additional changes from the command line. Let me fix this... |
Okay @sethfowler helped me detangle myself. Morale: don't ever push GitHub's "Update branch" button or follow their command-line instructions! |
../testdata/p4_16_errors/stack3.p4(35): error: header h[]: Size of header stack type should be a constant | ||
h[x] s3; | ||
^^^^ | ||
../testdata/p4_16_errors/stack3.p4(35): error: Could not find type of h[] |
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.
@mbudiu-vmw I'm confused about why the type of h
can't be found. Is this indicating a deeper error?
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.
No, if a sub-expression fails type-checking no type is installed in the typeMap, so all the expressions that involve it as a sub-expression will fail to type-check too. These additional error messages are somewhat redundant, but other compilers are equally confused.
@jnfoster : this code does not build. |
Sorry about that. Clearly I had not run |
* Simplify handling of `constants` map. It is now populated in the visitor for `IR::Declaration_Cosntant` nodes and accessed by the visitor for `IR::PathExpression` nodes. * Make `typeMap` `const`. * Polish and streamline the code.
* Add a new failing test (stack3.p4) * Update test outputs for other tests
Do not merge yet!
Submitting this pull request for comments. More documentation and tidying are needed
The current version of constant folding has two bugs:
constant folding (with type information) yields:
Note that the RHS of the declaration of
s
is not a constant -- it contains the variablet
.The root cause of this behavior is due to the use of auxiliary data structure
constants
: the pass does not ensure that all expressions that are inserted into this map are genuine constants, yet it assumes thatgetConstants
, which returns arbitrary entries fromconstants
, are always a constant. Hence, the current check forDeclaration_Constants
(https://github.com/p4lang/p4c/blob/master/frontends/common/constantFolding.cpp#L76) is not correct.The fix here is to streamline the use of
constants
so it is used in exactly two places:IR::Declaration_Constant
caseIR::PathExpression
(aka variable) casetypeMap
with type information about the newly inserted nodes. However, the types it inserts are not always correct -- e.g., in particular, in theIR::Member
case, when header stack sizes are folded, the type map is updated with `origtype, the type of the expression, but the arbitrary-precision integer may require a cast. Hence, subsequent type-checking passes will rely on the information in the typeMap and assume that no cast is required. However, if the typeMap is ever cleared, then the typeChecker will mutate the node, triggering an error.This error is not triggered by any of our current tests -- in examples like
p4_16_samples/stack.p4
, theIR::Member
is dead code and is eliminated before thetypeMap
is cleared. Hence, the error never manifests. However, a close variant can trigger the error:The solution proposed here is to change the
typeMap
toconst
(which streamlines the constant folding pass) and reconstruct it after type checking. In addition, we statically convert the header stacks length to the appropriate type.