mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-14 00:49:09 +02:00
* x86: CheckJumpMovTransferOpt now also copies over register deallocations to allow better optimisations
This commit is contained in:
parent
a49c0f6e0c
commit
fb66369a3b
@ -108,6 +108,8 @@ interface
|
||||
ait_eabi_attribute
|
||||
);
|
||||
|
||||
taitypes = set of taitype;
|
||||
|
||||
taiconst_type = (
|
||||
aitconst_128bit,
|
||||
aitconst_64bit,
|
||||
|
@ -60,12 +60,15 @@ unit aoptbase;
|
||||
|
||||
{ gets the next tai object after current that contains info relevant }
|
||||
{ to the optimizer in p1. If there is none, it returns false and }
|
||||
{ sets p1 to nil }
|
||||
class function GetNextInstruction(Current: tai; out Next: tai): Boolean; static;
|
||||
{ sets p1 to nil. If AlsoStopOn is set, it will also stop on these }
|
||||
{ object types that are normally skipped over. }
|
||||
class function GetNextInstruction(Current: tai; out Next: tai; AlsoStopOn: taitypes = []): Boolean; static;
|
||||
|
||||
{ gets the previous tai object after current that contains info }
|
||||
{ relevant to the optimizer in last. If there is none, it returns }
|
||||
{ false and sets last to nil }
|
||||
class function GetLastInstruction(Current: tai; out Last: tai): Boolean; static;
|
||||
{ false and sets last to nil. If AlsoStopOn is set, it will also }
|
||||
{ stop on these object types that are normally skipped over. }
|
||||
class function GetLastInstruction(Current: tai; out Last: tai; AlsoStopOn: taitypes = []): Boolean; static;
|
||||
|
||||
class function SkipEntryExitMarker(current: tai; out next: tai): boolean; static;
|
||||
|
||||
@ -185,12 +188,12 @@ unit aoptbase;
|
||||
end;
|
||||
|
||||
|
||||
class function TAOptBase.GetNextInstruction(Current: tai; out Next: tai): Boolean;
|
||||
class function TAOptBase.GetNextInstruction(Current: tai; out Next: tai; AlsoStopOn: taitypes): Boolean;
|
||||
Begin
|
||||
Repeat
|
||||
Current := tai(Current.Next);
|
||||
While Assigned(Current) And
|
||||
((Current.typ In SkipInstr) or
|
||||
((Current.typ In SkipInstr - AlsoStopOn) or
|
||||
{$ifdef cpudelayslot}
|
||||
((Current.typ=ait_instruction) and
|
||||
(taicpu(Current).opcode=A_NOP)
|
||||
@ -223,7 +226,7 @@ unit aoptbase;
|
||||
(Tai_Marker(Current).Kind <> mark_NoPropInfoEnd);
|
||||
Next := Current;
|
||||
If Assigned(Current) And
|
||||
Not((Current.typ In SkipInstr) or
|
||||
Not((Current.typ In SkipInstr - AlsoStopOn) or
|
||||
((Current.typ = ait_label) And
|
||||
labelCanBeSkipped(Tai_Label(Current))))
|
||||
Then GetNextInstruction := True
|
||||
@ -234,14 +237,15 @@ unit aoptbase;
|
||||
End;
|
||||
End;
|
||||
|
||||
class function TAOptBase.GetLastInstruction(Current: tai; out Last: tai): Boolean;
|
||||
|
||||
class function TAOptBase.GetLastInstruction(Current: tai; out Last: tai; AlsoStopOn: taitypes): Boolean;
|
||||
Begin
|
||||
Repeat
|
||||
Current := Tai(Current.previous);
|
||||
While Assigned(Current) And
|
||||
(((Current.typ = ait_Marker) And
|
||||
Not(Tai_Marker(Current).Kind in [mark_AsmBlockEnd{,mark_NoPropInfoEnd}])) or
|
||||
(Current.typ In SkipInstr) or
|
||||
(Current.typ In SkipInstr - AlsoStopOn) or
|
||||
((Current.typ = ait_label) And
|
||||
labelCanBeSkipped(Tai_Label(Current)))) Do
|
||||
Current := Tai(Current.previous);
|
||||
@ -258,7 +262,7 @@ unit aoptbase;
|
||||
(Current.typ <> ait_Marker) Or
|
||||
not(tai_Marker(current).Kind in [mark_NoPropInfoStart,mark_NoPropInfoEnd]);
|
||||
If Not(Assigned(Current)) or
|
||||
(Current.typ In SkipInstr) or
|
||||
(Current.typ In SkipInstr - AlsoStopOn) or
|
||||
((Current.typ = ait_label) And
|
||||
labelCanBeSkipped(Tai_Label(Current))) or
|
||||
((Current.typ = ait_Marker) And
|
||||
|
@ -9226,9 +9226,24 @@ unit aoptx86;
|
||||
if Assigned(hp1) and (hp1.typ = ait_label) then
|
||||
SkipLabels(hp1,hp1);
|
||||
|
||||
if (hp1.typ <> ait_instruction) then
|
||||
InternalError(2021040720);
|
||||
case hp1.typ of
|
||||
ait_regalloc:
|
||||
if tai_regalloc(hp1).ratype = ra_dealloc then
|
||||
begin
|
||||
{ Duplicate the register deallocation... }
|
||||
hp3:=tai(hp1.getcopy);
|
||||
if first_assignment = nil then
|
||||
first_assignment := hp3;
|
||||
|
||||
asml.InsertBefore(hp3, p);
|
||||
|
||||
{ ... but also reallocate it after the jump }
|
||||
hp3:=tai(hp1.getcopy);
|
||||
tai_regalloc(hp3).ratype := ra_alloc;
|
||||
|
||||
asml.InsertAfter(hp3, p);
|
||||
end;
|
||||
ait_instruction:
|
||||
case taicpu(hp1).opcode of
|
||||
A_JMP:
|
||||
begin
|
||||
@ -9262,6 +9277,8 @@ unit aoptx86;
|
||||
begin
|
||||
{ Duplicate the MOV instruction }
|
||||
hp3:=tai(hp1.getcopy);
|
||||
if first_assignment = nil then
|
||||
first_assignment := hp3;
|
||||
|
||||
asml.InsertBefore(hp3, p);
|
||||
|
||||
@ -9317,13 +9334,13 @@ unit aoptx86;
|
||||
;
|
||||
end;
|
||||
end;
|
||||
|
||||
if first_assignment = nil then
|
||||
first_assignment := hp3;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
InternalError(2021040720);
|
||||
end;
|
||||
|
||||
if not GetNextInstruction(hp1, hp1) then
|
||||
if not GetNextInstruction(hp1, hp1, [ait_regalloc]) then
|
||||
{ Should have dropped out earlier }
|
||||
InternalError(2021040710);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user