From 24c6e72a83976dc43ed28c38f1ad3e86a850d2fe Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 5 Mar 2024 22:05:33 -0600 Subject: [PATCH] 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. --- CGI.pas | 1 + Gen.pas | 10 +++++----- Native.pas | 30 ++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CGI.pas b/CGI.pas index 5d468d5..c37ae6f 100644 --- a/CGI.pas +++ b/CGI.pas @@ -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; diff --git a/Gen.pas b/Gen.pas index 22d919f..579039e 100644 --- a/Gen.pas +++ b/Gen.pas @@ -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} diff --git a/Native.pas b/Native.pas index 483c408..6dba273 100644 --- a/Native.pas +++ b/Native.pas @@ -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 }