Skip to content

[x86] CheckJumpMovTransferOpt (part of OptPass2JMP) now also copies over register deallocations for better optimisation

Summary

This merge request improves upon the CheckJumpMovTransferOpt optimisation by also copying over register deallocations (and reallocating them after the jump for reasons of consistency) that appear after the distant label. This permits more accurate register tracking and the potential removal of more redundant instructions.

This requires a new support function named GetNextInstructionOrRegAlloc that stops on register allocation on top of anything else that doesn't fall into the SkipInstr collection.

System

  • Processor architecture: i386, x86_64

What is the current bug behavior?

Whenever a jump redirect duplicates assignments (indicated by the debug message "Peephole Optimization: Duplicated 1 assignment(s) and redirected jump" or similar), the end result may include assignments to registers that are no longer in use if you follow the program flow (this is usually caused by other MOV optimisations).

What is the behavior after applying this patch?

More redundant writes are successfully optimised out.

Relevant logs and/or screenshots

In cgbase (x86-64-win64, -O4), before:

	...
.Lj111:
	cmpq	$16,%rcx
	jne	.Lj117
	movb	$5,%dl
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
# Peephole Optimization: %dl = $5; changed to minimise pipeline stall (MovMov2Mov 6b)
	movb	$5,%al
	ret
	.p2align 4,,10
	.p2align 3
.Lj117:
	cmpq	$8,%rcx
	jng	.Lj120
	xorb	%dl,%dl
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
# Peephole Optimization: %dl = $0; changed to minimise pipeline stall (MovMov2Mov 6b)
	xorb	%al,%al
	ret
	...

After:

	...
.Lj111:
	cmpq	$16,%rcx
	jne	.Lj117
# Peephole Optimization: MovMov2Mov 5 done
	movb	$5,%al
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
	ret
	.p2align 4,,10
	.p2align 3
.Lj117:
	cmpq	$8,%rcx
	jng	.Lj120
# Peephole Optimization: MovMov2Mov 5 done
	xorb	%al,%al
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
	ret
	...

Additional notes:

Sometimes, a mov %reg,%reg can appear, such as this example in the System unit - before:

.section .text.n_system_$$_align$qword$qword$$qword,"ax"
	...
	andn	%r9,%rax,%rax
	movq	%rax,%rcx
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
# Peephole Optimization: %rcx = %rax; changed to minimise pipeline stall (MovXXX2MovXXX)
# Peephole Optimization: Mov2Nop 4 done
	ret

After:

.section .text.n_system_$$_align$qword$qword$$qword,"ax"
	...
	andn	%r9,%rax,%rax
# Peephole Optimization: Mov2Nop 3 done
# Peephole Optimization: Duplicated 1 assignment(s) and redirected jump
# Peephole Optimization: %rcx = %rax; changed to minimise pipeline stall (MovXXX2MovXXX)
	movq	%rax,%rax
	ret

In this situation, it's because %rcx was originally copied into %rax, which is the function result. !310 (merged) helps to correct this issue by permitting the FuncMov2Func optimisation to run in Pass 2, which includes an addition to remove mov %reg,%reg which is otherwise only performed in Pass 1.

Merge request reports