x86: DeepMOVOpt Improvements
Summary
This merge request makes a number of improvements to the DeepMOVOpt method and supporting functions:
- ReplaceRegisterInInstruction now replaces registers in references that are written to (since the registers themselves won't change)
- RegModifiedByInstruction will no longer return True for a register that appears in a reference that's written to (for the same reason as above) - special operations like MOVSS (the 0-operand version) aren't affected.
- DeepMOVOpt returning True will now always set the Result of OptPass1MOV to True even though p wasn't directly modified, since this often caused missed optimisations.
- Some of the speed-ups in the patch from #32916 have also been applied in order to make the general DeepMOVOpt run faster, notably it tries to avoid calling UpdateUsedRegs where possible.
System
- Operating system: All x86 platforms
- Processor architecture: i386, x86_64
What is the current bug behavior?
N/A
What is the behavior after applying this patch?
Note significant size and speed savings on compiled code. In the compiler itself for x86_64-win64, it is reduced in size by 1,024 bytes due to the additional optimisations applied to itself.
Relevant logs and/or screenshots
The changes make a wealth of savings to many subroutines in the RTL and the compiler. In aasmcnst, for example, before:
.section .text.n_aasmcnst$_$tai_aggregatetypedconst_$_tadeenumerator_$__$$_reset,"ax"
.balign 16,0x90
.globl AASMCNST$_$TAI_AGGREGATETYPEDCONST_$_TADEENUMERATOR_$__$$_RESET
AASMCNST$_$TAI_AGGREGATETYPEDCONST_$_TADEENUMERATOR_$__$$_RESET:
movq %rcx,%rax
movl $0,16(%rax)
ret
After:
.section .text.n_aasmcnst$_$tai_aggregatetypedconst_$_tadeenumerator_$__$$_reset,"ax"
.balign 16,0x90
.globl AASMCNST$_$TAI_AGGREGATETYPEDCONST_$_TADEENUMERATOR_$__$$_RESET
AASMCNST$_$TAI_AGGREGATETYPEDCONST_$_TADEENUMERATOR_$__$$_RESET:
movl $0,16(%rcx)
ret
These simple savings that save a cycle appear very frequently, but even if an instruction isn't removed, pipeline stalls are minimised further.
Other
The change to IsRefSafe was an accidental modification that belonged to a different branch, but it otherwise just removes the "Inline" directive since it has a number of conditions that will likely require conditional jumps.