From 01937c4630f20652dee29b92dfbb2ab3d58cee8d Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 2 Mar 2021 21:27:43 +0000 Subject: [PATCH] * patch by J. Gareth Moreton: SubMov2LeaSub optimisation improvement, resolves #38555 git-svn-id: trunk@48871 - --- compiler/x86/aoptx86.pas | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index 67bab7a7d7..9bc5dade27 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -7125,7 +7125,7 @@ unit aoptx86; movl/q %reg1,%reg2 To: leal/q $-x(%reg1),%reg2 - subl/q $x,%reg1 + subl/q $x,%reg1 (can be removed if %reg1 or the flags are not used afterwards) Breaks the dependency chain and potentially permits the removal of a CMP instruction if one follows. @@ -7149,12 +7149,26 @@ unit aoptx86; taicpu(hp1).opcode := A_LEA; taicpu(hp1).loadref(0, NewRef); - { Move what is now the LEA instruction to before the SUB instruction } - Asml.Remove(hp1); - Asml.InsertBefore(hp1, p); - AllocRegBetween(taicpu(hp1).oper[1]^.reg, hp1, p, UsedRegs); + TransferUsedRegs(TmpUsedRegs); + UpdateUsedRegs(TmpUsedRegs, tai(p.Next)); + if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or + RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then + begin + { Move what is now the LEA instruction to before the SUB instruction } + Asml.Remove(hp1); + Asml.InsertBefore(hp1, p); + AllocRegBetween(taicpu(hp1).oper[1]^.reg, hp1, p, UsedRegs); + + DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p); + p := hp1; + end + else + begin + { Since %reg1 or the flags aren't used afterwards, we can delete p completely } + RemoveCurrentP(p, hp1); + DebugMsg(SPeepholeOptimization + 'SubMov2Lea', p); + end; - DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p); Result := True; end; end;