From e47f44234c68c167b7a6123e56d74a1097ac1869 Mon Sep 17 00:00:00 2001 From: florian Date: Fri, 2 Oct 2020 20:13:17 +0000 Subject: [PATCH] * AVR: MovMov2Mov 2 optimization git-svn-id: trunk@47035 - --- compiler/avr/aoptcpu.pas | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/compiler/avr/aoptcpu.pas b/compiler/avr/aoptcpu.pas index 6295d79fd1..b64a27df71 100644 --- a/compiler/avr/aoptcpu.pas +++ b/compiler/avr/aoptcpu.pas @@ -1101,13 +1101,16 @@ Implementation mov rX,... mov rX,... } - else if GetNextInstruction(p,hp1) and MatchInstruction(hp1,A_MOV) then + else if GetNextInstruction(p,hp1) and MatchInstruction(hp1,A_MOV) and + { test condition here already instead in the while loop only, else MovMov2Mov 2 might be oversight } + MatchInstruction(hp1,A_MOV) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^) then while MatchInstruction(hp1,A_MOV) and MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^) and { don't remove the first mov if the second is a mov rX,rX } not(MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^)) do begin - DebugMsg('Peephole MovMov2Mov performed', p); + DebugMsg('Peephole MovMov2Mov 1 performed', p); RemoveCurrentP(p,hp1); Result := True; @@ -1115,7 +1118,28 @@ Implementation GetNextInstruction(hp1,hp1); if not assigned(hp1) then break; - end; + end + { + This removes the second mov from + mov rX,rY + + ... + + mov rX,rY + + if rX and rY are not modified in-between + } + else if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[1]^.reg) and + MatchInstruction(hp1,A_MOV) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^) and + MatchOperand(taicpu(p).oper[1]^, taicpu(hp1).oper[1]^) and + not(RegModifiedBetween(taicpu(p).oper[0]^.reg,p,hp1)) then + begin + DebugMsg('Peephole MovMov2Mov 2 performed', p); + AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,UsedRegs); + RemoveInstruction(hp1); + Result := True; + end; end; A_SBIC, A_SBIS: