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

Fixup/cleanup IR::Type::width_bits() #4858

Merged
merged 1 commit into from
Aug 11, 2024
Merged

Conversation

ChrisDodd
Copy link
Contributor

This method is used by backends to get the size of a type, and should only be used for Types for which the concept of `size in bits' makes sense. Having it return 0 for types that it should not be called for adds to the confusion and possible bugs when it gets called when it shouldn't. It is suprising to me that having it return 0 for stacks and serializable enums hasn't caused problems before -- bugs waiting to happen.

The existence of this method goes back to the very earliest days of the compiler -- it can be argued that this does not belong here, and it really should be target specific, but the fact that almost all targets will have the same sizes for many things, plus the inability to do multiple dispatch in C++ is what caused it to be implements as a IR::Type virtual method.

@fruffy fruffy added the core Topics concerning the core segments of the compiler (frontend, midend, parser) label Aug 9, 2024
Copy link
Collaborator

@fruffy fruffy left a comment

Choose a reason for hiding this comment

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

P4Testgen fails because it calls width_bits on Type_String. Why, I do not quite remember but it should be a benign issue when serializing a test.

backends/bmv2/psa_switch/psaSwitch.h Show resolved Hide resolved
@ChrisDodd
Copy link
Contributor Author

P4Testgen fails because it calls width_bits on Type_String. Why, I do not quite remember but it should be a benign issues when serializing a test.

Looks like the code is calling type->width_bits() unconditionally, even thought the value it gets back only matters when type happens to be Type::Bits. Swapping the order of the clauses is the if avoids the problem (and is more efficient too)

Copy link
Collaborator

@fruffy fruffy left a comment

Choose a reason for hiding this comment

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

P4Testgen fails because it calls width_bits on Type_String. Why, I do not quite remember but it should be a benign issues when serializing a test.

Looks like the code is calling type->width_bits() unconditionally, even thought the value it gets back only matters when type happens to be Type::Bits. Swapping the order of the clauses is the if avoids the problem (and is more efficient too)

Makes sense, this was part of a cache implementation based on bit-width. I think there is also code like this in lib/expression.cpp.

@kfcripps kfcripps added the breaking-change This change may break assumptions of compiler back ends. label Aug 9, 2024
@@ -321,7 +321,7 @@ class TypeNameExpression : Expression {
dbprint{ out << typeName; }
toString { return typeName->toString(); }
validate { BUG_CHECK(typeName->is<Type_Name>() || typeName->is<Type_Specialized>(),
"%1 unexpected type in TypeNameExpression", typeName); }
"%1% unexpected type in TypeNameExpression", typeName); }
Copy link
Contributor

Choose a reason for hiding this comment

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

the sooner we migrate out of boost::format, the better. The format strings should be checked statically at compile time as much as possible :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So we should use C printf instead so we can use __attribute__((__format__ to get compile time checking? I'm not aware of any way to get the C++ formatting stuff (either boost or std::fmt) to check things at compile time.

Copy link
Contributor

@asl asl Aug 10, 2024

Choose a reason for hiding this comment

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

abseil does this. fmtlib does as well. Actually, the places where we do use abseil formatting routines already perform compile-time checking (e.g. SourceCodeBuilder::appendFormat) and it takes some jumps to disable this checking (e.g. in error_reporter)

@ChrisDodd ChrisDodd force-pushed the cdodd-misc branch 2 times, most recently from c33e8bf to ec73f2f Compare August 10, 2024 04:47
@ChrisDodd ChrisDodd force-pushed the cdodd-misc branch 2 times, most recently from fae4103 to 1e75aec Compare August 10, 2024 08:34
- this method is used by backends to get the size of a type, and should
  only be used for Types for which the concept of `size in bits' makes
  sense

Signed-off-by: Chris Dodd <cdodd@nvidia.com>
@ChrisDodd ChrisDodd added this pull request to the merge queue Aug 10, 2024
Merged via the queue into p4lang:main with commit 0e2a7d6 Aug 11, 2024
18 checks passed
@ChrisDodd ChrisDodd deleted the cdodd-misc branch August 11, 2024 00:12
@@ -268,6 +269,7 @@ class Type_InfInt : Type, ITypeVar {
return true; /* ignore declid */
}
const Type* getP4Type() const override { return this; }
int width_bits() const override { return 0; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, is this a good idea? with_bits fails for some types which don't have defined width, yet here it returns 0 as a "don't know" value (even though 0 can also be a perfectly valid with of bit<0>).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it would be better to remove this, but there are many places in that seem to depend on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sadly, there are more cases that someone could have relied on (whether deliberately or as a bug, e.g. void and unknown). Ultimately I think the BUG makes sense though (and to me it would make sense for int too).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A common case that hits this is code that is converting constants to strings of some kind (eg, json or other output). It generally just calls width_bits() on the constant type and if it returns 0 ouputs a constant with no specific size (if >0, it outputs some size indications). This happens to be what you want, but relies on InfInt::width_bits() returning 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change This change may break assumptions of compiler back ends. core Topics concerning the core segments of the compiler (frontend, midend, parser)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants