* patch by J. Gareth Moreton, issue #36271, part 2: x86 specific rework of the jump optimizer

git-svn-id: trunk@43440 -
This commit is contained in:
florian 2019-11-10 16:11:39 +00:00
parent 47dcc5b05b
commit 2d295a3816

View File

@ -3318,49 +3318,44 @@ unit aoptx86;
end; end;
end; end;
if ((hp1.typ = ait_label) and (symbol = tai_label(hp1).labsym)) { Detect the following:
or ((hp1.typ = ait_align) and GetNextInstruction(hp1, hp2) and (hp2.typ = ait_label) and (symbol = tai_label(hp2).labsym)) then jmp<cond> @Lbl1
jmp @Lbl2
...
@Lbl1:
ret
Change to:
jmp<inv_cond> @Lbl2
ret
}
if MatchInstruction(hp1, A_JMP, []) then
begin begin
{ If Jcc is immediately followed by the label that it's supposed to jump to, remove it } hp2 := getlabelwithsym(TAsmLabel(symbol));
DebugMsg(SPeepholeOptimization + 'Removed conditional jump whose destination was immediately after it', p); if Assigned(hp2) and SkipLabels(hp2,hp2) and
UpdateUsedRegs(hp1); MatchInstruction(hp2,A_RET,[S_NO]) then
TAsmLabel(symbol).decrefs;
{ if the label refs. reach zero, remove any alignment before the label }
if (hp1.typ = ait_align) then
begin begin
UpdateUsedRegs(hp2); taicpu(p).condition := inverse_cond(taicpu(p).condition);
if (TAsmLabel(symbol).getrefs = 0) then
begin { Change label address to that of the unconditional jump }
asml.Remove(hp1); taicpu(p).loadoper(0, taicpu(hp1).oper[0]^);
hp1.Free;
TAsmLabel(symbol).DecRefs;
taicpu(hp1).opcode := A_RET;
taicpu(hp1).is_jmp := false;
taicpu(hp1).ops := taicpu(hp2).ops;
case taicpu(hp2).ops of
0:
taicpu(hp1).clearop(0);
1:
taicpu(hp1).loadconst(0,taicpu(hp2).oper[0]^.val);
else
internalerror(2016041302);
end; end;
hp1 := hp2; { Set hp1 to the label }
end; end;
asml.remove(p);
p.free;
if (TAsmLabel(symbol).getrefs = 0) then
begin
GetNextInstruction(hp1, p); { Instruction following the label }
asml.remove(hp1);
hp1.free;
UpdateUsedRegs(p);
Result := True;
end
else
begin
{ We don't need to set the result to True because we know hp1
is a label and won't trigger any optimisation routines. [Kit] }
p := hp1;
end;
Exit;
end; end;
end; end;
{$ifndef i8086} {$ifndef i8086}
if CPUX86_HAS_CMOV in cpu_capabilities[current_settings.cputype] then if CPUX86_HAS_CMOV in cpu_capabilities[current_settings.cputype] then
begin begin
@ -3415,24 +3410,29 @@ unit aoptx86;
else else
hp2 := hp1; hp2 := hp1;
if not Assigned(hp2) then { Remember what the first hp2 is in case there's multiple aligns and labels to get rid of }
InternalError(2018062910); hp3 := hp2;
repeat
if not Assigned(hp2) then
InternalError(2018062910);
if (hp2.typ <> ait_label) then case hp2.typ of
begin ait_label:
{ There's something other than CMOVs here. Move the original jump { What we expected - break out of the loop (it won't be a dead label at the top of
to right before this point, then break out. a cluster because that was optimised at an earlier stage) }
Break;
Originally this was part of the above internal error, but it got ait_align:
triggered on the bootstrapping process sometimes. Investigate. [Kit] } { Go to the next entry until a label is found (may be multiple aligns before it) }
asml.remove(p); begin
asml.insertbefore(p, hp2); hp2 := tai(hp2.Next);
DebugMsg('Jcc/CMOVcc drop-out', p); Continue;
UpdateUsedRegs(p); end;
Result := True; else
Exit; InternalError(2018062911);
end; end;
until False;
{ Now we can safely decrement the reference count } { Now we can safely decrement the reference count }
tasmlabel(symbol).decrefs; tasmlabel(symbol).decrefs;
@ -3444,10 +3444,7 @@ unit aoptx86;
{ Remove the label if this is its final reference } { Remove the label if this is its final reference }
if (tasmlabel(symbol).getrefs=0) then if (tasmlabel(symbol).getrefs=0) then
begin StripLabelFast(hp3);
asml.remove(hp2);
hp2.free;
end;
if Assigned(p) then if Assigned(p) then
begin begin
@ -3541,16 +3538,7 @@ unit aoptx86;
hp1.free; hp1.free;
{ Remove label xxx (it will have a ref of zero due to the initial check } { Remove label xxx (it will have a ref of zero due to the initial check }
if (hp4.typ = ait_align) then StripLabelFast(hp4);
begin
{ Account for alignment as well }
GetNextInstruction(hp4, hp1);
asml.remove(hp1);
hp1.free;
end;
asml.remove(hp4);
hp4.free;
{ Now we can safely decrement it } { Now we can safely decrement it }
tasmlabel(symbol).decrefs; tasmlabel(symbol).decrefs;
@ -3561,23 +3549,12 @@ unit aoptx86;
asml.remove(hp2); asml.remove(hp2);
hp2.free; hp2.free;
{ Remove label yyy (and the optional alignment) if its reference will fall to zero } { As before, now we can safely decrement it }
if tasmlabel(symbol).getrefs = 1 then tasmlabel(symbol).decrefs;
begin
if (hp3.typ = ait_align) then
begin
{ Account for alignment as well }
GetNextInstruction(hp3, hp1);
asml.remove(hp1);
hp1.free;
end;
asml.remove(hp3); { Remove label yyy (and the optional alignment) if its reference falls to zero }
hp3.free; if tasmlabel(symbol).getrefs = 0 then
StripLabelFast(hp3);
{ As before, now we can safely decrement it }
tasmlabel(symbol).decrefs;
end;
if Assigned(p) then if Assigned(p) then
begin begin