Simplify some conditional branches.

This affects certain places where code like the following could be generated:

	bCC lab2
lab1	brl ...
lab2 ...

If lab1 is no longer referenced due to previous optimizations, it can be removed. This then allows the bCC+brl combination to be shortened to a single conditional branch, if the target is close enough.

This introduces a flag for tracking and potentially removing labels that are only used as the target of one branch. This could be used more widely, but currently it is only used for the specific code sequences shown above. Using it in other places could potentially open up possibilities for invalid native-code optimizations that were previously blocked due to the presence of the label.
This commit is contained in:
Stephen Heumann 2024-03-05 22:05:33 -06:00
parent 0f18fa63b5
commit 24c6e72a83
3 changed files with 34 additions and 7 deletions

View File

@ -48,6 +48,7 @@ const
forFlags = 256; {instruction used for effect on flags only}
subtract1 = 512; {subtract 1 from address operand}
shiftLeft8 = 1024; {shift operand left 8 bits}
labelUsedOnce = 2048; {only one branch targets this label}
m_adc_abs = $6D; {op code #s for 65816 instructions}
m_adc_dir = $65;

10
Gen.pas
View File

@ -1121,7 +1121,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
end; {if}
GenNative(m_bpl, relative, lab1, nil, 0);
if num <> 0 then
GenLab(lab2);
GenLabUsedOnce(lab2);
GenNative(m_brl, longrelative, lb, nil, 0);
GenLab(lab1);
end {if (num >= 0) and (num < 3)}
@ -1134,7 +1134,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
GenNative(m_cmp_imm, immediate, num, nil, 0);
GenNative(m_bcs, relative, lab2, nil, 0);
if num > 0 then begin
GenLab(lab1);
GenLabUsedOnce(lab1);
GenNative(m_brl, longrelative, lb, nil, 0);
GenLab(lab2);
end {if}
@ -1184,7 +1184,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
GenLab(lab1);
end {if}
else begin
GenLab(lab1);
GenLabUsedOnce(lab1);
GenNative(m_brl, longrelative, lb, nil, 0);
GenLab(lab2);
end; {else}
@ -1282,7 +1282,7 @@ else
else
GenNative(m_bcs, relative, lab2, nil, 0);
if op^.opcode = pc_grt then
GenLab(lab3);
GenLabUsedOnce(lab3);
GenNative(m_brl, longrelative, lb, nil, 0);
GenLab(lab2);
end {if}
@ -6531,7 +6531,7 @@ procedure GenTree {op: icptr};
if op^.opcode = pc_lor then begin
lab2 := GenLabel;
GenNative(m_beq, relative, lab2, nil, 0);
GenLab(lab1);
GenLabUsedOnce(lab1);
GenNative(m_brl, longrelative, lab3, nil, 0);
GenLab(lab2);
end {if}

View File

@ -110,6 +110,14 @@ procedure GenLab (lnum: integer);
{ lnum - label number }
procedure GenLabUsedOnce (lnum: integer);
{ generate a label that is only targeted by one branch }
{ }
{ parameters: }
{ lnum - label number }
procedure InitFile (keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean);
{ Set up the object file }
@ -1674,14 +1682,20 @@ var
opcode := m_bmi;
end {else if m_bra}
else if npeep[ns+3].opcode in [m_bra,m_brl] then
if Short(ns,npeep[ns+3].operand) then
if Short(ns,npeep[ns+3].operand) then begin
operand := npeep[ns+3].operand;
if (npeep[ns+2].flags & labelUsedOnce) <> 0 then
Remove(ns+2);
end; {if}
end {if}
else if npeep[ns+3].opcode = d_lab then
if npeep[ns+3].operand = operand then
if npeep[ns+4].opcode in [m_bra,m_brl] then
if Short(ns,npeep[ns+4].operand) then
if Short(ns,npeep[ns+4].operand) then begin
operand := npeep[ns+4].operand;
if (npeep[ns+3].flags & labelUsedOnce) <> 0 then
Remove(ns+3);
end; {if}
m_brl:
if Short(ns,operand) then begin
@ -2307,6 +2321,18 @@ GenNative(d_lab, gnrlabel, lnum, nil, 0);
end; {GenLab}
procedure GenLabUsedOnce {lnum: integer};
{ generate a label that is only targeted by one branch }
{ }
{ parameters: }
{ lnum - label number }
begin {GenLabUsedOnce}
GenNative(d_lab, gnrlabel, lnum, nil, labelUsedOnce);
end; {GenLabUsedOnce}
procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean};
{ Set up the object file }