-
Notifications
You must be signed in to change notification settings - Fork 452
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
Fix expansion of signed ranges to masks #3212
Changes from 1 commit
8fa2514
be08558
34a3ffb
eff90ee
5681bfc
80f68b9
9444809
a2c8f65
1a9a2d9
a62a610
aad48f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,9 @@ class DoReplaceSelectRange : public Transform { | |
// Each case is a key set expression. | ||
const uint MAX_CASES; | ||
bool inSelect = false; | ||
// Collects select indices which will need to be replaced with bitcast of | ||
// the original value to unsigned. This is needed if we encounter a range | ||
// over a signed value at the given index. | ||
std::set<int> signedIndicesToReplace; | ||
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. why not a set of size_t or unsigned values? 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. (Because old habits die hard.) Changed to size_t. As for the comment, sure, except that we need to replace it any time the value is signed, not only when it crosses over zero. Masks are only defined for |
||
|
||
explicit DoReplaceSelectRange(uint max) : MAX_CASES(max) { | ||
|
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 think it's actually nicer to return a list of vectors for the result.
one in the common case, two if the range contains 0.
the keyIndex and signedIndicesToReplace make the data flow much harder to understand.
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 agree that
signedIndicesToReplace
does make the flow harder to understand. But this is mainly because it is indeed complex -- the indices are detected when range is expanded, but they are used in the corresponding select through which we backtrack later (making use ofpostorder
). This needs to be done this way as at the time we encounter the select first, we don't know which values will contain ranges and when working with ranges we cannot replace a parent node (at least I don't think so, I could be wrong since I am a beginner to p4c). The only alternative to indices I see would be to remember the actual corresponding select expressions, but that in my opinion improves nothing and could lead to danger in case of some weird select with duplicated keys:In this (rather pathological) case, we need to insert the bitcast only to the first occurence of
foo.a
not to both instances offoo.a
expression in select.As for the vector-of-vectors. I don't think this is a good idea as returning a vector of vectors implies that there can be any number of vectors, including 0 and more than 2. Therefore I think that would be bad design of the function as the type would allow too many invalid possibilities. It could make sense to return pair (isSigned, vectors) and resolve the index one level up in the postorder of mask.
For now, I have just added a comment about the indices into the class.