mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 17:26:35 +02:00
* Fixed general peephole optimization of conditional jumps after r30446. It has been broken, since r30446 had added some IsJumpToLabel() checks, which tests for unconditional jump, but the optimization code expects also conditional jumps.
- Renamed IsJumpToLabel() to IsJumpToLabelUncond() to avoid confusions. - Added IsJumpToLabel() to check for any jump to a label. - Added comments. git-svn-id: trunk@32114 -
This commit is contained in:
parent
3d2919acae
commit
5771073e0b
@ -1174,7 +1174,9 @@ Unit AoptObj;
|
|||||||
end;
|
end;
|
||||||
{$pop}
|
{$pop}
|
||||||
|
|
||||||
function IsJumpToLabel(hp: taicpu): boolean;
|
|
||||||
|
{ Returns True if hp is an unconditional jump to a label }
|
||||||
|
function IsJumpToLabelUncond(hp: taicpu): boolean;
|
||||||
begin
|
begin
|
||||||
{$if defined(avr)}
|
{$if defined(avr)}
|
||||||
result:=(hp.opcode in aopt_uncondjmp) and
|
result:=(hp.opcode in aopt_uncondjmp) and
|
||||||
@ -1190,6 +1192,16 @@ Unit AoptObj;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ Returns True if hp is any jump to a label }
|
||||||
|
function IsJumpToLabel(hp: taicpu): boolean;
|
||||||
|
begin
|
||||||
|
result:=hp.is_jmp and
|
||||||
|
(hp.ops>0) and
|
||||||
|
(JumpTargetOp(hp)^.typ = top_ref) and
|
||||||
|
(JumpTargetOp(hp)^.ref^.symbol is TAsmLabel);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TAOptObj.RemoveDelaySlot(hp1:tai);
|
procedure TAOptObj.RemoveDelaySlot(hp1:tai);
|
||||||
var
|
var
|
||||||
hp2: tai;
|
hp2: tai;
|
||||||
@ -1239,7 +1251,7 @@ Unit AoptObj;
|
|||||||
(taicpu(p1).is_jmp) then
|
(taicpu(p1).is_jmp) then
|
||||||
if { the next instruction after the label where the jump hp arrives}
|
if { the next instruction after the label where the jump hp arrives}
|
||||||
{ is unconditional or of the same type as hp, so continue }
|
{ is unconditional or of the same type as hp, so continue }
|
||||||
IsJumpToLabel(taicpu(p1))
|
IsJumpToLabelUncond(taicpu(p1))
|
||||||
{$if not defined(MIPS) and not defined(JVM)}
|
{$if not defined(MIPS) and not defined(JVM)}
|
||||||
{ for MIPS, it isn't enough to check the condition; first operands must be same, too. }
|
{ for MIPS, it isn't enough to check the condition; first operands must be same, too. }
|
||||||
or
|
or
|
||||||
@ -1254,7 +1266,7 @@ Unit AoptObj;
|
|||||||
SkipLabels(p1,p2) and
|
SkipLabels(p1,p2) and
|
||||||
(p2.typ = ait_instruction) and
|
(p2.typ = ait_instruction) and
|
||||||
(taicpu(p2).is_jmp) and
|
(taicpu(p2).is_jmp) and
|
||||||
(IsJumpToLabel(taicpu(p2)) or
|
(IsJumpToLabelUncond(taicpu(p2)) or
|
||||||
(conditions_equal(taicpu(p2).condition,hp.condition))) and
|
(conditions_equal(taicpu(p2).condition,hp.condition))) and
|
||||||
SkipLabels(p1,p1))
|
SkipLabels(p1,p1))
|
||||||
{$endif not MIPS and not JVM}
|
{$endif not MIPS and not JVM}
|
||||||
@ -1354,7 +1366,7 @@ Unit AoptObj;
|
|||||||
{ the following if-block removes all code between a jmp and the next label,
|
{ the following if-block removes all code between a jmp and the next label,
|
||||||
because it can never be executed
|
because it can never be executed
|
||||||
}
|
}
|
||||||
if IsJumpToLabel(taicpu(p)) then
|
if IsJumpToLabelUncond(taicpu(p)) then
|
||||||
begin
|
begin
|
||||||
hp2:=p;
|
hp2:=p;
|
||||||
while GetNextInstruction(hp2, hp1) and
|
while GetNextInstruction(hp2, hp1) and
|
||||||
@ -1387,11 +1399,11 @@ Unit AoptObj;
|
|||||||
end
|
end
|
||||||
else break;
|
else break;
|
||||||
end;
|
end;
|
||||||
{ remove jumps to a label coming right after them }
|
|
||||||
if GetNextInstruction(p, hp1) then
|
if GetNextInstruction(p, hp1) then
|
||||||
begin
|
begin
|
||||||
SkipEntryExitMarker(hp1,hp1);
|
SkipEntryExitMarker(hp1,hp1);
|
||||||
if IsJumpToLabel(taicpu(p)) and
|
{ remove unconditional jumps to a label coming right after them }
|
||||||
|
if IsJumpToLabelUncond(taicpu(p)) and
|
||||||
FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp1) and
|
FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp1) and
|
||||||
{ TODO: FIXME removing the first instruction fails}
|
{ TODO: FIXME removing the first instruction fails}
|
||||||
(p<>blockstart) then
|
(p<>blockstart) then
|
||||||
@ -1409,10 +1421,17 @@ Unit AoptObj;
|
|||||||
end
|
end
|
||||||
else if assigned(hp1) then
|
else if assigned(hp1) then
|
||||||
begin
|
begin
|
||||||
|
{ change the following jumps:
|
||||||
|
jmp<cond> lab_1 jmp<cond_inverted> lab_2
|
||||||
|
jmp lab_2 >>> <code>
|
||||||
|
lab_1: lab_2:
|
||||||
|
<code>
|
||||||
|
lab_2:
|
||||||
|
}
|
||||||
if hp1.typ = ait_label then
|
if hp1.typ = ait_label then
|
||||||
SkipLabels(hp1,hp1);
|
SkipLabels(hp1,hp1);
|
||||||
if (tai(hp1).typ=ait_instruction) and
|
if (tai(hp1).typ=ait_instruction) and
|
||||||
IsJumpToLabel(taicpu(hp1)) and
|
IsJumpToLabelUncond(taicpu(hp1)) and
|
||||||
GetNextInstruction(hp1, hp2) and
|
GetNextInstruction(hp1, hp2) and
|
||||||
IsJumpToLabel(taicpu(p)) and
|
IsJumpToLabel(taicpu(p)) and
|
||||||
FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp2) then
|
FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp2) then
|
||||||
|
Loading…
Reference in New Issue
Block a user