Port IsRedundantMov to xarch#54075
Conversation
|
CC. @AndyAyersMS |
|
Linking to my earlier attempt, which I abandoned once we'd improved LSRA preferencing: dotnet/coreclr#21959 because |
AndyAyersMS
left a comment
There was a problem hiding this comment.
LGTM. Left some suggestions for comments / naming.
src/coreclr/jit/emitxarch.cpp
Outdated
| // size - Operand size of current instruction | ||
| // dst - The current destination | ||
| // src - The current source | ||
| // canSkip - The move can be skipped as it doesn't represent special semantics |
There was a problem hiding this comment.
Consider renaming this to better convey what it means, something like canIgnoreSideEffects?
There was a problem hiding this comment.
I've renamed this in IsRedundantMov but not everywhere else (as /* canSkip */ value is used for almost every call to emitIns_Mov).
| case INS_movd: | ||
| case INS_movdqa: | ||
| case INS_movdqu: | ||
| case INS_movsd: |
There was a problem hiding this comment.
Since you're removing movsd perhaps leave a comment describing why other "move-like" instructions aren't included here?
There was a problem hiding this comment.
Also commenting nit: can you add a return value comment?
There was a problem hiding this comment.
Added a return value and remarks comment covering why this doesn't cover all "move like" instructions:
//
// Return Value:
// true if the instruction is a qualifying move instruction; otherwise, false
//
// Remarks:
// This methods covers most kinds of two operand move instructions that copy a
// value between two registers. It does not cover all move-like instructions
// and so doesn't currently cover things like movsb/movsw/movsd/movsq or cmovcc
// and doesn't currently cover cases where a value is read/written from memory.
//
// The reason it doesn't cover all instructions was namely to limit the scope
// of the initial change to that which was impactful to move elision so that
// it could be centrally managed and optimized. It may be beneficial to support
// the other move instructions in the future but that may require more extensive
// changes to ensure relevant codegen/emit paths flow and check things correctly.
There was a problem hiding this comment.
The TL;DR is just that it was only covering the move instructions that were impactful to move elision initially. Other move instructions have side effects (like being non-temporal or dealing with memory) and so weren't necessary to cover.
This ports the
emitter::IsRedundantMovmethod that exists for Arm64 to also exist for x86/x64.The PMI diff reports are below and this namely impacts two cases.
First, the following looks to occur in most
IL_STUB_PInvokemethods:movzx rax, al - movzx rax, alSecond, this resolves #49535 by avoiding the shuffle back/forth:
mov rsi, rax - mov rax, rsiThere are a couple
TODO-CQ-XArchleft in the comments as we should be able to utilizeAreUpper32BitsZeroand an equivalent method forSIMDinstructions to elide a few additional variations.jit-diff diff --diff --pmi --frameworks
jit-diff diff --diff --pmi --benchmarks
jit-diff diff --diff --pmi --tests