mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-24 04:39:10 +02:00
* patch by J. Gareth Moreton: Memory CMP optimisation, resolves #38907
git-svn-id: trunk@49382 -
This commit is contained in:
parent
12a0083c59
commit
6f482952de
@ -2819,24 +2819,73 @@ unit aoptx86;
|
||||
Result:=true;
|
||||
exit;
|
||||
end;
|
||||
if MatchOpType(taicpu(p),top_reg,top_ref) and
|
||||
MatchInstruction(hp1,A_CMP,A_TEST,[taicpu(p).opsize]) and
|
||||
(taicpu(hp1).oper[1]^.typ = top_ref) and
|
||||
RefsEqual(taicpu(p).oper[1]^.ref^, taicpu(hp1).oper[1]^.ref^) then
|
||||
if MatchInstruction(hp1,A_CMP,A_TEST,[taicpu(p).opsize]) then
|
||||
begin
|
||||
{ change
|
||||
mov reg1, mem1
|
||||
test/cmp x, mem1
|
||||
if MatchOpType(taicpu(p),top_reg,top_ref) and
|
||||
(taicpu(hp1).oper[1]^.typ = top_ref) and
|
||||
RefsEqual(taicpu(p).oper[1]^.ref^, taicpu(hp1).oper[1]^.ref^) then
|
||||
begin
|
||||
{ change
|
||||
mov reg1, mem1
|
||||
test/cmp x, mem1
|
||||
|
||||
to
|
||||
to
|
||||
|
||||
mov reg1, mem1
|
||||
test/cmp x, reg1
|
||||
}
|
||||
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
|
||||
DebugMsg(SPeepholeOptimization + 'MovTestCmp2MovTestCmp 1',hp1);
|
||||
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
|
||||
exit;
|
||||
mov reg1, mem1
|
||||
test/cmp x, reg1
|
||||
}
|
||||
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
|
||||
DebugMsg(SPeepholeOptimization + 'MovTestCmp2MovTestCmp 1',hp1);
|
||||
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if MatchOpType(taicpu(p),top_ref,top_reg) and
|
||||
{ The x86 assemblers have difficulty comparing values against absolute addresses }
|
||||
(taicpu(p).oper[0]^.ref^.refaddr in [addr_no, addr_pic, addr_pic_no_got]) and
|
||||
(taicpu(hp1).oper[0]^.typ <> top_ref) and
|
||||
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^.reg) and
|
||||
(
|
||||
(
|
||||
(taicpu(hp1).opcode = A_TEST)
|
||||
) or (
|
||||
(taicpu(hp1).opcode = A_CMP) and
|
||||
{ A sanity check more than anything }
|
||||
not MatchOperand(taicpu(hp1).oper[0]^, taicpu(p).oper[1]^.reg)
|
||||
)
|
||||
) then
|
||||
begin
|
||||
{ change
|
||||
mov mem, %reg
|
||||
cmp/test x, %reg / test %reg,%reg
|
||||
(reg deallocated)
|
||||
|
||||
to
|
||||
|
||||
cmp/test x, mem / cmp 0, mem
|
||||
}
|
||||
TransferUsedRegs(TmpUsedRegs);
|
||||
UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
|
||||
if not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) then
|
||||
begin
|
||||
{ Convert test %reg,%reg or test $-1,%reg to cmp $0,mem }
|
||||
if (taicpu(hp1).opcode = A_TEST) and
|
||||
(
|
||||
MatchOperand(taicpu(hp1).oper[0]^, taicpu(p).oper[1]^.reg) or
|
||||
MatchOperand(taicpu(hp1).oper[0]^, -1)
|
||||
) then
|
||||
begin
|
||||
taicpu(hp1).opcode := A_CMP;
|
||||
taicpu(hp1).loadconst(0, 0);
|
||||
end;
|
||||
taicpu(hp1).loadref(1, taicpu(p).oper[0]^.ref^);
|
||||
DebugMsg(SPeepholeOptimization + 'MOV/CMP -> CMP (memory check)', p);
|
||||
RemoveCurrentP(p, hp1);
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if MatchInstruction(hp1,A_LEA,[S_L{$ifdef x86_64},S_Q{$endif x86_64}]) and
|
||||
|
Loading…
Reference in New Issue
Block a user