Skip to content

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.

Edited by J. Gareth "Kit" Moreton

Merge request reports