mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-07 00:18:45 +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;
|
Result:=true;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if MatchOpType(taicpu(p),top_reg,top_ref) and
|
if MatchInstruction(hp1,A_CMP,A_TEST,[taicpu(p).opsize]) then
|
||||||
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
|
|
||||||
begin
|
begin
|
||||||
{ change
|
if MatchOpType(taicpu(p),top_reg,top_ref) and
|
||||||
mov reg1, mem1
|
(taicpu(hp1).oper[1]^.typ = top_ref) and
|
||||||
test/cmp x, mem1
|
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
|
mov reg1, mem1
|
||||||
test/cmp x, reg1
|
test/cmp x, reg1
|
||||||
}
|
}
|
||||||
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
|
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
|
||||||
DebugMsg(SPeepholeOptimization + 'MovTestCmp2MovTestCmp 1',hp1);
|
DebugMsg(SPeepholeOptimization + 'MovTestCmp2MovTestCmp 1',hp1);
|
||||||
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
|
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
|
||||||
exit;
|
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;
|
end;
|
||||||
|
|
||||||
if MatchInstruction(hp1,A_LEA,[S_L{$ifdef x86_64},S_Q{$endif x86_64}]) and
|
if MatchInstruction(hp1,A_LEA,[S_L{$ifdef x86_64},S_Q{$endif x86_64}]) and
|
||||||
|
Loading…
Reference in New Issue
Block a user