-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Propagate assertions for more checked bounds #11521
Conversation
@briansull, @AndyAyersMS PTAL This addresses #10050 with the exception that the value-number update that happens for compare nodes when one of their arguments is an array length that gets CSE'd does not apply in as many cases to spans, because we don't have the CSE candidate occurrence lists collected yet when we build the The
No other diffs from this change (spans aren't used much in our test corpus) |
src/jit/assertionprop.cpp
Outdated
// Cases where op1 holds the condition bound and op2 is 0. | ||
// Loop condition like: "i < len == 0" | ||
// Assertion: "i < len == false" | ||
else if (vnStore->IsVNCompareCheckedBound(vn) && |
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 block reads better like this:
// Cases where op1 holds the upper bound and op2 is 0.
// Loop condition like: "i < bnd == 0"
// Assertion: "i < bnd == false"
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.
If you change this also change the previous comment block to match.
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.
And a few more below...
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.
Looks good overall. Just some nits on comments and use of locals to cache things.
src/jit/optcse.cpp
Outdated
{ | ||
// Found an arrayLen feeding a compare that is a tracatable function of it; | ||
// record this in the map so we can update the compare VN if the array length | ||
// Found a checked bound feeding a compare that is a tracatable function of it; |
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 as well fix this typo while you're at it: tracatable
-> tractable
src/jit/optcse.cpp
Outdated
ValueNumStore::ArrLenArithBoundInfo info; | ||
ValueNum newCmpArgVN; | ||
if (vnStore->IsVNArrLenBound(oldCmpVN)) | ||
ValueNumStore* vnStore = m_pCompiler->vnStore; |
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.
Can you hoist the vnStore
local defn up a few lines and use it in the new code you added above?
src/jit/rangecheck.cpp
Outdated
@@ -96,44 +95,35 @@ bool RangeCheck::BetweenBounds(Range& range, int lower, GenTreePtr upper) | |||
else if (m_pCompiler->vnStore->IsVNArrLen(uLimitVN)) | |||
{ | |||
// Get the array reference from the length. | |||
arrRefVN = m_pCompiler->vnStore->GetArrForLenVn(uLimitVN); | |||
ValueNum arrRefVN = m_pCompiler->vnStore->GetArrForLenVn(uLimitVN); |
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.
Maybe introduce a local for m_pCompiler->vnStore
(up above somewhere suitable), it is used a dozen or more times below and would both make the code more readable and run a tiny bit faster.
src/jit/assertionprop.cpp
Outdated
// Cases where op1 holds the condition bound and op2 is 0. | ||
// Loop condition like: "i < len == 0" | ||
// Assertion: "i < len == false" | ||
else if (vnStore->IsVNCompareCheckedBound(vn) && |
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.
If you change this also change the previous comment block to match.
src/jit/assertionprop.cpp
Outdated
// Cases where op1 holds the condition bound and op2 is 0. | ||
// Loop condition like: "i < len == 0" | ||
// Assertion: "i < len == false" | ||
else if (vnStore->IsVNCompareCheckedBound(vn) && |
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.
And a few more below...
src/jit/valuenum.cpp
Outdated
@@ -7028,6 +7062,14 @@ void Compiler::fgValueNumberTree(GenTreePtr tree, bool evalAsgLhsInd) | |||
excSet = vnStore->VNPExcSetUnion(excSet, vnStore->VNPExcVal(tree->AsBoundsChk()->gtArrLen->gtVNPair)); | |||
|
|||
tree->gtVNPair = vnStore->VNPWithExc(vnStore->VNPForVoid(), excSet); | |||
|
|||
// Record non-constant value numbers that are used a the length argument to bounds checks, so that |
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.
are used as the length
b80e270
to
0a95122
Compare
- Add default key infos for int/unsigned - Call compGetMem through a forward-declared wrapper to avoid circular dependency problems if Compiler itself (or one of its dependencies) uses a SmallHashTable
0a95122
to
da3e151
Compare
Generalize (and rename) the assertion/limit code for tracking array lengths (which have until now been recognized by the VNFunc being GT_ARR_LENGTH) to track all values that appear in the function as length arguments to bounds chcks nodes. Add a hashtable to identify that set of value numbers, `m_checkedBoundVNs` to the VNStore object, and populate it during value-numbering. Wherever names were adjusted, the generalization of "array length" is called "checked bound". This allows the array bound check removal machinery to operate on span bound checks as well.
da3e151
to
72e126a
Compare
Updated per feedback (and to fix build issue) |
Perf lab run came back, the indexer tests with diffs do indeed show improvement:
|
@dotnet-bot test this please |
Generalize (and rename) the assertion/limit code for tracking array
lengths (which have until now been recognized by the VNFunc being
GT_ARR_LENGTH) to track all values that appear in the function as
length arguments to bounds chcks nodes. Add a hashtable to identify that
set of value numbers,
m_checkedBoundVNs
to the VNStore object, andpopulate it during value-numbering. Wherever names were adjusted, the
generalization of "array length" is called "checked bound".
This allows the array bound check removal machinery to operate on span
bound checks as well.