* x86: PostPeepholeOptCmp and PostPeepholeOptTestOr

now do a final attempt of TrySwapMovCmp to
	 clean up Pass 2 optimisations
This commit is contained in:
J. Gareth "Curious Kit" Moreton 2023-02-16 10:49:17 +00:00 committed by FPK
parent 4d676cd6fa
commit dd7320ec13

View File

@ -15096,8 +15096,46 @@ unit aoptx86;
function TX86AsmOptimizer.PostPeepholeOptCmp(var p : tai) : Boolean;
var
hp1: tai;
begin
Result:=false;
{ Final check to see if CMP/MOV pairs can be changed to MOV/CMP }
while GetNextInstruction(p, hp1) and
TrySwapMovCmp(p, hp1) do
begin
if MatchInstruction(hp1, A_MOV, []) then
begin
if RegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs) then
begin
{ A little hacky, but since CMP doesn't read the flags, only
modify them, it's safe if they get scrambled by MOV -> XOR }
ExcludeRegFromUsedRegs(NR_DEFAULTFLAGS, UsedRegs);
Result := PostPeepholeOptMov(hp1);
{$ifdef x86_64}
if Result and MatchInstruction(hp1, A_XOR, [S_Q]) then
{ Used to shrink instruction size }
PostPeepholeOptXor(hp1);
{$endif x86_64}
IncludeRegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs);
end
else
begin
Result := PostPeepholeOptMov(hp1);
{$ifdef x86_64}
if Result and MatchInstruction(hp1, A_XOR, [S_Q]) then
{ Used to shrink instruction size }
PostPeepholeOptXor(hp1);
{$endif x86_64}
end;
end;
{ Enabling this flag is actually a null operation, but it marks
the code as 'modified' during this pass }
Include(OptsToCheck, aoc_ForceNewIteration);
end;
{ change "cmp $0, %reg" to "test %reg, %reg" }
if MatchOpType(taicpu(p),top_const,top_reg) and
(taicpu(p).oper[0]^.val = 0) then
@ -15116,6 +15154,42 @@ unit aoptx86;
hp1,hp2 : tai;
begin
Result:=false;
{ Final check to see if TEST/MOV pairs can be changed to MOV/TEST }
if (taicpu(p).opcode = A_TEST) then
while GetNextInstruction(p, hp1) and
TrySwapMovCmp(p, hp1) do
begin
if MatchInstruction(hp1, A_MOV, []) then
begin
if RegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs) then
begin
{ A little hacky, but since TEST doesn't read the flags, only
modify them, it's safe if they get scrambled by MOV -> XOR }
ExcludeRegFromUsedRegs(NR_DEFAULTFLAGS, UsedRegs);
Result := PostPeepholeOptMov(hp1);
{$ifdef x86_64}
if Result and MatchInstruction(hp1, A_XOR, [S_Q]) then
{ Used to shrink instruction size }
PostPeepholeOptXor(hp1);
{$endif x86_64}
IncludeRegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs);
end
else
begin
Result := PostPeepholeOptMov(hp1);
{$ifdef x86_64}
if Result and MatchInstruction(hp1, A_XOR, [S_Q]) then
{ Used to shrink instruction size }
PostPeepholeOptXor(hp1);
{$endif x86_64}
end;
end;
{ Enabling this flag is actually a null operation, but it marks
the code as 'modified' during this pass }
Include(OptsToCheck, aoc_ForceNewIteration);
end;
{ If x is a power of 2 (popcnt = 1), change:
or $x, %reg/ref