mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 02:26:20 +02:00
* 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:
parent
47dcc5b05b
commit
2d295a3816
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user