mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 13:09:22 +02:00
* patch by J. Gareth Moreton: Long-range MOV + MOVS/Z optimisation, resolves #37390
git-svn-id: trunk@46346 -
This commit is contained in:
parent
867786c953
commit
8761545848
@ -2611,8 +2611,11 @@ unit aoptx86;
|
|||||||
checking for GetNextInstruction_p }
|
checking for GetNextInstruction_p }
|
||||||
{ GetNextInstructionUsingReg only searches one instruction ahead unless -O3 is specified }
|
{ GetNextInstructionUsingReg only searches one instruction ahead unless -O3 is specified }
|
||||||
GetNextInstructionUsingReg(hp1,hp2,taicpu(p).oper[1]^.reg) and
|
GetNextInstructionUsingReg(hp1,hp2,taicpu(p).oper[1]^.reg) and
|
||||||
MatchInstruction(hp2,A_MOV,[]) and
|
(hp2.typ=ait_instruction) then
|
||||||
MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^) and
|
begin
|
||||||
|
case taicpu(hp2).opcode of
|
||||||
|
A_MOV:
|
||||||
|
if MatchOperand(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^.reg) and
|
||||||
((taicpu(p).oper[0]^.typ=top_const) or
|
((taicpu(p).oper[0]^.typ=top_const) or
|
||||||
((taicpu(p).oper[0]^.typ=top_reg) and
|
((taicpu(p).oper[0]^.typ=top_reg) and
|
||||||
not(RegUsedBetween(taicpu(p).oper[0]^.reg, p, hp2))
|
not(RegUsedBetween(taicpu(p).oper[0]^.reg, p, hp2))
|
||||||
@ -2734,6 +2737,46 @@ unit aoptx86;
|
|||||||
Internalerror(2019103001);
|
Internalerror(2019103001);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
A_MOVZX, A_MOVSX{$ifdef x86_64}, A_MOVSXD{$endif x86_64}:
|
||||||
|
if MatchOpType(taicpu(hp2), top_reg, top_reg) and
|
||||||
|
MatchOperand(taicpu(hp2).oper[0]^, taicpu(p).oper[1]^.reg) and
|
||||||
|
SuperRegistersEqual(taicpu(hp2).oper[1]^.reg, taicpu(p).oper[1]^.reg) then
|
||||||
|
begin
|
||||||
|
{
|
||||||
|
Change from:
|
||||||
|
mov ###, %reg
|
||||||
|
...
|
||||||
|
movs/z %reg,%reg (Same register, just different sizes)
|
||||||
|
|
||||||
|
To:
|
||||||
|
movs/z ###, %reg (Longer version)
|
||||||
|
...
|
||||||
|
(remove)
|
||||||
|
}
|
||||||
|
DebugMsg(SPeepholeOptimization + 'MovMovs/z2Mov/s/z done', p);
|
||||||
|
taicpu(p).oper[1]^.reg := taicpu(hp2).oper[1]^.reg;
|
||||||
|
|
||||||
|
{ Keep the first instruction as mov if ### is a constant }
|
||||||
|
if taicpu(p).oper[0]^.typ = top_const then
|
||||||
|
taicpu(p).opsize := reg2opsize(taicpu(hp2).oper[1]^.reg)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
taicpu(p).opcode := taicpu(hp2).opcode;
|
||||||
|
taicpu(p).opsize := taicpu(hp2).opsize;
|
||||||
|
end;
|
||||||
|
|
||||||
|
DebugMsg(SPeepholeOptimization + 'Removed movs/z instruction and extended earlier write (MovMovs/z2Mov/s/z)', hp2);
|
||||||
|
AllocRegBetween(taicpu(hp2).oper[1]^.reg, p, hp2, UsedRegs);
|
||||||
|
AsmL.Remove(hp2);
|
||||||
|
hp2.Free;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
if (aoc_MovAnd2Mov_3 in OptsToCheck) and
|
if (aoc_MovAnd2Mov_3 in OptsToCheck) and
|
||||||
(taicpu(p).oper[1]^.typ = top_reg) and
|
(taicpu(p).oper[1]^.typ = top_reg) and
|
||||||
|
Loading…
Reference in New Issue
Block a user