-
Notifications
You must be signed in to change notification settings - Fork 2.6k
[WIP] Support for tracking Exception Sets with ValueNumbers #19284
Conversation
src/jit/valuenum.cpp
Outdated
| if (IsIntZero(v1)) | ||
| { | ||
| *pExcSet = VNExcSetSingleton(VNForFunc(TYP_REF, VNF_DivideByZeroExc)); | ||
| *pExcSet = VNExcSetSingleton(VNForFunc(TYP_REF, VNF_DivideByZeroExc, VNForVoid())); |
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 VNForVoid correct here? The description of VNF_DivideByZeroExc is the divisor value so it seems that here it should the VN of constant 0. Same comment for the next 2 changes bellow.
src/jit/assertionprop.cpp
Outdated
| // ValueNumber indicates that this node evaluates to a constant | ||
|
|
||
| // But we could have an integer division by zero | ||
| if (tree->OperMayThrow(this)) |
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.
Hmm, why is this needed?
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.
Because the Norm value computed for integer division by zero is the constant zero.
It is problematic is serveral places where we think we have a constant but instead we have a divide by 0.
I will look into changing how we ValueNumber a division by zero,.
src/jit/assertionprop.cpp
Outdated
| ValueNum vn = op1->gtVNPair.GetConservative(); | ||
| ValueNum vn = vnStore->VNNormVal(op1->gtVNPair.GetConservative()); | ||
| ValueNum relopVN = vnStore->VNNormVal(relop->gtVNPair.GetConservative()); | ||
| ValueNum op2VN = vnStore->VNNormVal(relop->gtVNPair.GetConservative()); |
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.
relop should be op2
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.
Yes, Thanks
src/jit/assertionprop.cpp
Outdated
| GenTree* op2 = relop->gtGetOp2(); | ||
|
|
||
| ValueNum vn = op1->gtVNPair.GetConservative(); | ||
| ValueNum vn = vnStore->VNNormVal(op1->gtVNPair.GetConservative()); |
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.
Might be nice to rename to op1VN
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 will
src/jit/assertionprop.cpp
Outdated
| // We typically want to use the Normal ValueNumber when checking for constants | ||
| // except for the nodes that might generate an exception like GT_DIV, GT_MOD, etc... | ||
| // | ||
| if (!tree->OperMayThrow(this)) |
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 I guess this is needed because if we have a VN exception set we don't really know if it comes from the node itself or from its children?
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.
Yes that is why I added this,
And Integer Divide is an oper than can Throw
src/jit/assertionprop.cpp
Outdated
|
|
||
| // If the assertion involves "op2" and it is a constant, then check if "op1" also has a constant value. | ||
| if (vnStore->IsVNConstant(op2->gtVNPair.GetConservative())) | ||
| ValueNum vnCns = vnStore->VNNormVal(op2->gtVNPair.GetConservative()); |
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.
There are so many of these VNNormVal that perhaps we should add a shortcut to Compiler - ValueNum Compiler::vnConservativeNormVal(GenTree*);
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.
Yes, I will be adding heper functions:
vnConservativeNormVal
vnLiberalNormVal
src/jit/optcse.cpp
Outdated
| // | ||
| ValueNum vnLibNorm = vnStore->VNNormVal(vnLib); | ||
|
|
||
| // We assign either vnLib or vnLinNorm as the hash key |
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.
vnLinNorm -> vnLibNorm
src/jit/optcse.cpp
Outdated
| // and the parent comma as the CSE use (but with a different exc set) | ||
| // This would prevent us from making any CSE with the comma | ||
| // | ||
| assert(vnLibNorm == vnStore->VNNormVal(vnOp2Lib)); // (We don't need to assert this) |
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 comment after the assert seems strange
| // Afterwards the set of nodes in the 'sideEffectList' are preserved and | ||
| // all other nodes are removed and have their ref counts decremented | ||
| // | ||
| #ifdef DEBUG |
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.
It does not seem useful to introduce this variable for a single use. And the ifdef messes up the comment above.
7058d54 to
ac99312
Compare
Run clang format
Added methods VNConservativeNormVal() and VNLiberalNormVal()
Renamed the local vn to op1VN in optCreateJTrueBoundsAssertion
Other changes:
For optCSE we now use set Union and Intersection and track the full set of exceptions
promised by all defs using defExcSetPromise
Implemented in ValueNum.cpp:
new method VNExcSetIntersection to compute the intersection of two exception sets
new method VNNegOneForType used by the new GT_MOD folding checks.
updated VNExcSetUnion to add checks for ascending order
VNCheckAscending for checking that setys are in ascending order
Changed the value numbering for GT_DIV and GT_MOD, no longer constant fold them when
they are throwing an exception.
Deprecated STR_VN, it is replace with FMT_VN
Added overflowChecking arg for GetVNFuncForOper This method now supports new VNF's for ADD,SUB and MUL with overflow checking Renamed EvalOpIntegral to EvalOpSpecialized has it uses template speclization Moved the template method method to preceed the generic instantiation of T Cleaned up the implementation of EvalOp<T> it now only handles three op GT_ADD, GT_SUB and GT_MUL. We use EvalOPSpecialized to handle GT_DIV and GT_MOD RelOP are handled by EvalComparison and we now have support for unsigned compares as well as unordered flowting point compares. Implemented the floating of compares with NaN's Operations that throw exceptions are not folded to return 0 with an exception set. We now annotated div/Mod with both exceptions VNF_DivideByZeroExc and VNF_ArithmeticExc added supportfow new VNF's: CastOvf, ADD_UN,ADD_OVF and ADD_UN_OVF (also the SUB and MUL versions)
…the INT64 instantiation Fixed an issue with mismatch types when expanding a GT_MUL by 15
5579bfe to
71acf22
Compare
|
@briansull Is this still WIP? Is it ready to be reviewed, or are you still working on it? (btw, it has merge conflicts now) |
|
I decided to stage these changes by checking this stuff using an series of smaller change sets. |
|
Checked in with #20129 |
Added support to create and track Exception sets with ValueNumbers
Some cleanup in ValueNumbering as well.
The Asm Diffs produced are fairly minimal with this set of changes.
Fixes #8648