* x86: CheckJumpMovTransferOpt now also copies over register deallocations to allow better optimisations

This commit is contained in:
J. Gareth "Curious Kit" Moreton 2022-10-22 22:24:39 +01:00 committed by FPK
parent a49c0f6e0c
commit fb66369a3b
3 changed files with 122 additions and 99 deletions

View File

@ -108,6 +108,8 @@ interface
ait_eabi_attribute
);
taitypes = set of taitype;
taiconst_type = (
aitconst_128bit,
aitconst_64bit,

View File

@ -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

View File

@ -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;