Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@briansull
Copy link

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

if (IsIntZero(v1))
{
*pExcSet = VNExcSetSingleton(VNForFunc(TYP_REF, VNF_DivideByZeroExc));
*pExcSet = VNExcSetSingleton(VNForFunc(TYP_REF, VNF_DivideByZeroExc, VNForVoid()));
Copy link

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.

// ValueNumber indicates that this node evaluates to a constant

// But we could have an integer division by zero
if (tree->OperMayThrow(this))
Copy link

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?

Copy link
Author

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,.

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());
Copy link

Choose a reason for hiding this comment

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

relop should be op2

Copy link
Author

Choose a reason for hiding this comment

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

Yes, Thanks

GenTree* op2 = relop->gtGetOp2();

ValueNum vn = op1->gtVNPair.GetConservative();
ValueNum vn = vnStore->VNNormVal(op1->gtVNPair.GetConservative());
Copy link

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

Copy link
Author

Choose a reason for hiding this comment

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

I will

// 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))
Copy link

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?

Copy link
Author

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


// 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());
Copy link

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*);

Copy link
Author

@briansull briansull Aug 14, 2018

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

//
ValueNum vnLibNorm = vnStore->VNNormVal(vnLib);

// We assign either vnLib or vnLinNorm as the hash key
Copy link

Choose a reason for hiding this comment

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

vnLinNorm -> vnLibNorm

// 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)
Copy link

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
Copy link

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.

@briansull briansull force-pushed the vn-except-support branch 2 times, most recently from 7058d54 to ac99312 Compare August 17, 2018 19:49
    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
@BruceForstall
Copy link

@briansull Is this still WIP? Is it ready to be reviewed, or are you still working on it? (btw, it has merge conflicts now)

@briansull
Copy link
Author

briansull commented Sep 5, 2018

I decided to stage these changes by checking this stuff using an series of smaller change sets.
Currently I have this part our for review: #19720

@briansull
Copy link
Author

Checked in with #20129

@briansull briansull closed this Oct 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants