Uh oh!
There was an error while loading. Please reload this page.
JIT: revise local assertion prop to use bit vectors - #94322
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.
ghost
commented
Nov 2, 2023
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... |
BruceForstall
commented
Nov 3, 2023
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.
AndyAyersMS
commented
Nov 3, 2023
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.