From 49deff3c86dbe5c40e9b0178a8b241af0ebca1a1 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 14 Mar 2023 21:32:20 -0500 Subject: [PATCH] Generate more efficient code for certain conditionals. This will change a "jump if true" to "jump if false" (or vice versa) and logically negate the condition in certain cases where that generates better code. An assembly peephole optimization for certain "branch to branch" instructions is also added. (Certain conditionals could generate these.) --- Gen.pas | 37 ++++++++++++++++++++++++++----------- Native.pas | 5 ++++- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Gen.pas b/Gen.pas index ec629de..9ad9e16 100644 --- a/Gen.pas +++ b/Gen.pas @@ -1051,6 +1051,28 @@ var op^.right := nd; end; {Switch} + + procedure ReverseConditional; + + { Change tjp to an equivalent fjp, or vice versa. } + { } + { Note: assumes opcode is pc_geq or pc_grt. } + + begin {ReverseConditional} + if rOpcode in [pc_tjp,pc_fjp] then begin + if op^.opcode = pc_geq then + op^.opcode := pc_grt + else + op^.opcode := pc_geq; + if rOpcode = pc_tjp then + rOpcode := pc_fjp + else + rOpcode := pc_tjp; + Switch; + end; {if} + end; {ReverseConditional} + + begin {GenCmp} {To reduct the number of possibilities that must be handled, pc_les } {and pc_leq compares are reduced to their equivalent pc_grt and } @@ -1068,17 +1090,7 @@ else if op^.opcode = pc_leq then begin {for a tjp or fjp with a constant left operand. } if op^.optype in [cgByte,cgUByte,cgWord,cgUWord] then if op^.left^.opcode = pc_ldc then - if rOpcode in [pc_tjp,pc_fjp] then begin - if op^.opcode = pc_geq then - op^.opcode := pc_grt - else - op^.opcode := pc_geq; - if rOpcode = pc_tjp then - rOpcode := pc_fjp - else - rOpcode := pc_tjp; - Switch; - end; {if} + ReverseConditional; {Short cuts are available for single-word operands where the } {right operand is a constant. } @@ -1222,6 +1234,9 @@ else case op^.optype of cgByte,cgUByte,cgWord,cgUWord: begin + if ((op^.opcode = pc_grt) and (Complex(op^.left) <= Complex(op^.right))) + or (Complex(op^.right) and not Complex(op^.left)) then + ReverseConditional; if Complex(op^.right) then begin GenTree(op^.right); if Complex(op^.left) then begin diff --git a/Native.pas b/Native.pas index f919fa7..54a4cdc 100644 --- a/Native.pas +++ b/Native.pas @@ -1670,7 +1670,10 @@ var opcode := m_bcs else opcode := m_bmi; - end; {else if m_bra} + 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 + operand := npeep[ns+3].operand; m_brl: if Short(ns,operand) then begin