JIT: revise local assertion prop to use bit vectors#94322
JIT: revise local assertion prop to use bit vectors#94322AndyAyersMS merged 1 commit intodotnet:mainfrom
Conversation
…n tracking Track the set of active local assertions via a bit vector, rather than assuming all entries in the table are live. Doing so required a number of changes in assertion prop to ensure the vector is consulted before deciding an assertion is valid. This will (eventually) allow us to propagate assertions cross-block. For now we reset the bit vector and assertion table back to empty at the start of each block so nothing propagates past the end of a block. The table can fill and cause the JIT to miss assertions in very large blocks as morph will no longer remove assertions while processing a block. Previously this would happen if there were more than 64 live assertions in a block, and now it can happen if there are more than 64 assertions in block (so somewhat more frequently). Contributes to dotnet#93246.
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsTrack the set of active local assertions via a bit vector, rather than assuming all entries in the table are live. Doing so required a number of changes in assertion prop to ensure the vector is consulted before deciding an assertion is valid. This will (eventually) allow us to propagate assertions cross-block. For now we reset the bit vector and assertion table back to empty at the start of each block so nothing propagates past the end of a block. The table can fill and cause the JIT to miss assertions in very large blocks as morph will no longer remove assertions while processing a block. Previously this would happen if there were more than 64 live assertions in a block, and now it can happen if there are more than 64 assertions in block (so somewhat more frequently). Contributes to #93246.
|
|
@jakobbotsch PTAL Should cause a few hundred diffs, mainly in test code. Two RWC methods with big diffs; the next stage of this work may or may not help here as I will have to make the table larger.... Local TP impact looks good; let's see what the lab says. Not sure what to make of the linux TP numbers... |
clang is not as good as MSVC at bit vector manipulation? |
There was a problem hiding this comment.
LGTM. I took the liberty of collecting a details TP diff on Linux, since I had a readily available setup to do that:
Base: 20039267461, Diff: 20129180266, +0.4487%
Compiler::fgMorphTreeDone(GenTree*, bool, bool) : 92335191 : NA : 70.82% : +0.4608%
Compiler::fgMorphBlock(BasicBlock*) : 7141209 : NA : 5.48% : +0.0356%
Compiler::fgMorphSmpOp(GenTree*, Compiler::MorphAddrContext*, bool*) : 5377091 : +1.72% : 4.12% : +0.0268%
Compiler::optLocalAssertionIsEqualOrNotEqual(Compiler::optOp1Kind, unsigned int, Compiler::optOp2Kind, long, unsigned long* const&) : 1507878 : +16.46% : 1.16% : +0.0075%
Compiler::fgAssertionGen(GenTree*) : 1198394 : NA : 0.92% : +0.0060%
Compiler::fgKillDependentAssertions(unsigned int) : 671692 : +22.10% : 0.52% : +0.0034%
GenTree::DefinesLocal(Compiler*, GenTreeLclVarCommon**, bool*, long*, unsigned int*) : 404001 : +0.61% : 0.31% : +0.0020%
Compiler::optAssertionProp(unsigned long* const&, GenTree*, Statement*, BasicBlock*) : 343019 : +0.46% : 0.26% : +0.0017%
Compiler::fgKillDependentAssertionsSingle(unsigned int) : 316623 : +10.81% : 0.24% : +0.0016%
Compiler::optAssertionIsNonNullInternal(GenTree*, unsigned long* const&) : 255071 : +1.88% : 0.20% : +0.0013%
Compiler::AssertionDsc::Equals(Compiler::AssertionDsc*, bool) : 146167 : +0.39% : 0.11% : +0.0007%
Compiler::optGetAssertion(unsigned short) : -309470 : -4.31% : 0.24% : -0.0015%
Compiler::optAssertionProp_LclVar(unsigned long* const&, GenTreeLclVarCommon*, Statement*) : -331995 : -0.50% : 0.25% : -0.0017%
Compiler::optAssertionInit(bool) : -378584 : -6.98% : 0.29% : -0.0019%
Compiler::optAssertionGen(GenTree*) : -562997 : -0.53% : 0.43% : -0.0028%
Compiler::GetAssertionDep(unsigned int) : -731197 : -2.90% : 0.56% : -0.0036%
Compiler::optAssertionReset(unsigned short) : -974712 : -8.89% : 0.75% : -0.0049%
Compiler::optAssertionIsSubrange(GenTree*, IntegralRange, unsigned long* const&) : -1347642 : -17.08% : 1.03% : -0.0067%
Compiler::fgMorphBlocks() : -2362170 : -40.42% : 1.81% : -0.0118%
Compiler::fgMorphLeafLocal(GenTreeLclVarCommon*) : -3832890 : -11.77% : 2.94% : -0.0191%
Compiler::fgMorphTree(GenTree*, Compiler::MorphAddrContext*) : -8915512 : -4.80% : 6.84% : -0.0445%Looks like Clang at least stopped inlining fgMorphTreeDone somewhere.
|
Yeah |
Track the set of active local assertions via a bit vector, rather than assuming all entries in the table are live.
Doing so required a number of changes in assertion prop to ensure the vector is consulted before deciding an assertion is valid.
This will (eventually) allow us to propagate assertions cross-block. For now we reset the bit vector and assertion table back to empty at the start of each block so nothing propagates past the end of a block.
The table can fill and cause the JIT to miss assertions in very large blocks as morph will no longer remove assertions while processing a block. Previously this would happen if there were more than 64 live assertions in a block, and now it can happen if there are more than 64 assertions in block (so somewhat more frequently).
Contributes to #93246.