[fpc-devel] Division nodes
J. Gareth Moreton
gareth at moreton-family.com
Thu May 11 11:04:04 CEST 2023
Hi everyone,
I need to ask a question about how division nodes are set up (I'm
looking at possible optimisation techniques). I've written the
following procedure:
procedure DoDivMod(N, D: Integer; out Q, R: Integer);
begin
Q := N div D;
R := N mod D;
end;
Fairly simple and to the point. However, even before the first node
pass, the following node tree is generated for an integer division
operation:
<statementn pos="24,10">
<ifn resultdef="$void" pos="24,10" flags="nf_internal">
<condition>
<equaln resultdef="Boolean" pos="24,10" flags="nf_internal">
<loadn resultdef="LongInt" pos="24,14">
<symbol>D</symbol>
</loadn>
<ordconstn resultdef="LongInt" pos="24,10" rangecheck="FALSE">
<value>-1</value>
</ordconstn>
</equaln>
</condition>
<then>
<assignn resultdef="$void" pos="24,10" flags="nf_internal">
<temprefn resultdef="LongInt" pos="24,10" flags="nf_write"
id="$7C585E10">
<typedef>LongInt</typedef>
<tempflags>ti_may_be_in_reg</tempflags>
<temptype>tt_persistent</temptype>
</temprefn>
<unaryminusn resultdef="LongInt" pos="24,10">
<loadn resultdef="LongInt" pos="24,8">
<symbol>N</symbol>
</loadn>
</unaryminusn>
</assignn>
</then>
<else>
<assignn resultdef="$void" pos="24,10" flags="nf_internal">
<temprefn resultdef="LongInt" pos="24,10" flags="nf_write"
id="$7C585E10">
<typedef>LongInt</typedef>
<tempflags>ti_may_be_in_reg</tempflags>
<temptype>tt_persistent</temptype>
</temprefn>
<divn resultdef="LongInt" pos="24,10">
<loadn resultdef="LongInt" pos="24,8">
<symbol>N</symbol>
</loadn>
<loadn resultdef="LongInt" pos="24,14">
<symbol>D</symbol>
</loadn>
</divn>
</assignn>
</else>
</ifn>
</statementn>
Something similar is made for "mod" as well. I have to ask though... is
it really necessary to check to see if the divisor is -1 and have a
distinct assignment for it? It's a bit of a rare edge case that usually
just slows things down since it tends to add a comparison and a
conditional jump to the final assembly language. Is there some
anomalous behaviour to a processor's division routine if the divisor is -1?
At the very least, would it be possible to remove the conditional check
when compiling under -Os?
(I intend to see if it's possible to merge "N div D" and "N mod D" on
x86, and possibly other processors that have a combined DIV/MOD operator).
Kit
More information about the fpc-devel
mailing list