* UpdateUsedRegsAndOptimize improved to clear aligns that don't have

any live labels after them, and to better handle non-jump labels.
This commit is contained in:
J. Gareth "Curious Kit" Moreton 2023-11-02 12:39:52 +00:00 committed by FPK
parent 90e0b426ef
commit 7080bcc160

View File

@ -1031,7 +1031,7 @@ Unit AoptObj;
repeat repeat
while assigned(p) and while assigned(p) and
((p.typ in (SkipInstr + [ait_align, ait_label] - [ait_RegAlloc])) or ((p.typ in (SkipInstr + [ait_label] - [ait_RegAlloc])) or
((p.typ = ait_marker) and ((p.typ = ait_marker) and
(tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd]))) do (tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd]))) do
begin begin
@ -1074,7 +1074,7 @@ Unit AoptObj;
end; end;
NotFirst := True; NotFirst := True;
until not(assigned(p)) or until not(assigned(p)) or
(not(p.typ in SkipInstr + [ait_align]) and (not(p.typ in SkipInstr) and
not((p.typ = ait_label) and not((p.typ = ait_label) and
labelCanBeSkipped(tai_label(p)))); labelCanBeSkipped(tai_label(p))));
end; end;
@ -1794,6 +1794,7 @@ Unit AoptObj;
tmp, tmpNext: tai; tmp, tmpNext: tai;
hp1: tai; hp1: tai;
CurrentAlign: tai; CurrentAlign: tai;
FoundLabels: Boolean;
begin begin
CurrentAlign := nil; CurrentAlign := nil;
Result := False; Result := False;
@ -1807,26 +1808,33 @@ Unit AoptObj;
case hp1.typ of case hp1.typ of
ait_label: ait_label:
begin begin
{ Set tmp to the next valid entry }
tmp := tai(hp1.Next);
with tai_label(hp1).labsym do with tai_label(hp1).labsym do
if is_used or (bind <> AB_LOCAL) or (labeltype <> alt_jump) then begin
begin if (labeltype <> alt_jump) then
{ Valid label } begin
if Result then { Non-jump label - skip over }
NextValid := hp1; hp1 := tmp;
Continue;
end;
DebugWrite('JUMP DEBUG: Last label in cluster:' + tostr(labelnr)); if is_used or (bind <> AB_LOCAL) then
begin
{ Valid label }
DebugWrite('JUMP DEBUG: Last label in cluster:' + tostr(labelnr));
Exit; Exit;
end; end;
end;
DebugWrite('JUMP DEBUG: Removed label ' + tostr(TAsmLabel(tai_label(hp1).labsym).labelnr)); DebugWrite('JUMP DEBUG: Removed label ' + tostr(TAsmLabel(tai_label(hp1).labsym).labelnr));
{ Set tmp to the next valid entry }
tmp := tai(hp1.Next);
{ Remove label } { Remove label }
AsmL.Remove(hp1); if (NextValid = hp1) then
hp1.Free; NextValid := tmp;
RemoveInstruction(hp1);
hp1 := tmp; hp1 := tmp;
Result := True; Result := True;
@ -1835,6 +1843,9 @@ Unit AoptObj;
{ Also remove the align if it comes before an unused label } { Also remove the align if it comes before an unused label }
ait_align: ait_align:
begin begin
{ Signal that we can possibly delete this align entry }
CurrentAlign := hp1;
tmp := tai(hp1.Next); tmp := tai(hp1.Next);
if tmp = BlockEnd then if tmp = BlockEnd then
{ End of block } { End of block }
@ -1863,8 +1874,7 @@ Unit AoptObj;
end; end;
tmpNext := tai(tmp.Next); tmpNext := tai(tmp.Next);
AsmL.Remove(tmp); RemoveInstruction(tmp);
tmp.Free;
Result := True; Result := True;
tmp := tmpNext; tmp := tmpNext;
end end
@ -1875,28 +1885,30 @@ Unit AoptObj;
end; end;
ait_label: ait_label:
begin begin
{ Signal that we can possibly delete this align entry }
CurrentAlign := hp1;
repeat repeat
with tai_label(tmp).labsym do with tai_label(tmp).labsym do
if is_used or (bind <> AB_LOCAL) or (labeltype <> alt_jump) then begin
begin if (labeltype <> alt_jump) then
{ Valid label } begin
if Result then { Non-jump label - skip over }
NextValid := tmp; tmp := tai(tmp.Next);
Continue;
end;
DebugWrite('JUMP DEBUG: Last label in cluster:' + tostr(labelnr)); if is_used or (bind <> AB_LOCAL) then
begin
{ Valid label }
DebugWrite('JUMP DEBUG: Last label in cluster:' + tostr(labelnr));
Exit; Exit;
end; end;
end;
DebugWrite('JUMP DEBUG: Removed label ' + tostr(TAsmLabel(tai_label(tmp).labsym).labelnr)); DebugWrite('JUMP DEBUG: Removed label ' + tai_label(tmp).labsym.name);
{ Remove label } { Remove label }
tmpNext := tai(tmp.Next); tmpNext := tai(tmp.Next);
AsmL.Remove(tmp); RemoveInstruction(tmp);
tmp.Free;
Result := True; Result := True;
tmp := tmpNext; tmp := tmpNext;
@ -1908,6 +1920,12 @@ Unit AoptObj;
end end
else else
begin begin
if tmp.typ in SkipInstr then
begin
tmp := tai(tmp.Next);
Continue;
end;
{ Set hp1 to the instruction after the align, because the { Set hp1 to the instruction after the align, because the
align might get deleted later and hence set NextValid align might get deleted later and hence set NextValid
to a dangling pointer. [Kit] } to a dangling pointer. [Kit] }
@ -1927,20 +1945,27 @@ Unit AoptObj;
hp1 := tai(hp1.Next); hp1 := tai(hp1.Next);
end; end;
{ hp1 will be the next valid entry } if Assigned(CurrentAlign) then
NextValid := hp1;
{ Remove the alignment field (but only if the next valid entry is not a live label) }
while Assigned(CurrentAlign) and (CurrentAlign.typ = ait_align) do
begin begin
DebugWrite('JUMP DEBUG: Alignment field removed'); { Remember what the first one was }
tmpNext := CurrentAlign;
tmp := tai(CurrentAlign.next); { Remove the alignment field (but only if the next valid entry is not a live label) }
repeat
tmp := tai(CurrentAlign.next);
AsmL.Remove(CurrentAlign); { Any labels found are non-jump labels and will be skipped over }
CurrentAlign.Free; if CurrentAlign.typ = ait_align then
begin
DebugWrite('JUMP DEBUG: Alignment field removed');
RemoveInstruction(CurrentAlign);
end;
CurrentAlign := tmp; CurrentAlign := tmp;
until not Assigned(CurrentAlign) or not (CurrentAlign.typ in [ait_align, ait_label]);
if (NextValid = tmpNext) then
NextValid := tmp;
end; end;
end; end;