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