So progress report on converting "Str(constant, output)"... it's not
easy! Firstly, after the first pass, a call node's parameters can get
reordered so they can be placed into ideal registers or on the stack. I
found a workaround for that by adding a new field that records their
original right-to-left ordering. Despite the headache, I managed to
consistently change it to an assignment of a string literal to the
output variable. Success, right? Wrong! The first pass converts such
an assignment to another call node!
<calln resultdef="$void" pos="12,3" flags="nf_pass1_done" complexity="255">
<procname>$fpc_shortstr_to_shortstr(out OpenString;<const
Int64>;const ShortString);</procname>
<callparan resultdef="ShortString" pos="12,3">
<stringconstn resultdef="ShortString" pos="12,3"
flags="nf_pass1_done" complexity="1">
<stringtype>shortstring</stringtype>
<length>1</length>
<value>5</value>
</stringconstn>
</callparan>
<callparan resultdef="OpenString" pos="12,3">
<loadn resultdef="ShortString" pos="12,3"
flags="nf_pass1_done,nf_write" complexity="1">
<symbol>OUTPUT</symbol>
</loadn>
</callparan>
<callparan resultdef="Int64" pos="12,3">
<ordconstn resultdef="Int64" pos="12,3"
flags="nf_pass1_done,nf_explicit" complexity="0" rangecheck="TRUE">
<value>255</value>
</ordconstn>
</callparan>
</calln>
(The third "255" parameter seems to be some kind of encoding parameter)
Here, the original line of code was "Str(5, Output);". This is actually
pretty difficult to solve.
It might be that I have to find a way to perform purity analysis without
ever calling firstpass on the node tree, which is currently needed for
processing nested pure and inline functions... granted, I can possibly
do that selectively using "foreachnode" or "foreachnodestatic".
Kit
On 14/12/2022 12:21, J. Gareth Moreton via fpc-devel wrote:
So it turns out that an "inlinen" node is created initially, but it is
transmuted into a "calln" node by the typecheck pass almost as soon as
it is created. I think the reason it is transmuted so soon is because
differently-named internal procedures have to be called depending on
the input types. I think the easiest way I can handle this is to add
a new optional field to indicate which class of internal functions the
node was generated from, and pass_1 can perform unique processing on
it if certain criteria are met... and if they are not met, or the
field is set to a value the compiler doesn't recognise, it just falls
back to regular call-node handling.
Kit
On 14/12/2022 11:39, J. Gareth Moreton via fpc-devel wrote:
On 14/12/2022 10:18, Sven Barth via fpc-devel wrote:
Wouldn't it make more sense to ensure that the Str() and Val()
intrinsic work correctly inside "pure" functions? After all the
compiler can then simply evaluate the inlinen nodes and does not
have to "interpret" a ton of other code as well.
So I just tried a simple test with "System.Str(5, Output);" (with
Output defined as a string), and it produced the following nodes:
<calln resultdef="$void" pos="12,3">
...<procname>$fpc_shortstr_sint(Int64;Int64;out OpenString;<const
Int64>);</procname>
...<callparan resultdef="Int64" pos="12,3">
......<ordconstn resultdef="Int64" pos="12,3" flags="nf_explicit"
rangecheck="TRUE">
.........<value>255</value>
......</ordconstn>
...</callparan>
...<callparan resultdef="OpenString" pos="12,23">
......<loadn resultdef="ShortString" pos="12,23" flags="nf_write">
.........<symbol>OUTPUT</symbol>
......</loadn>
...</callparan>
...<callparan resultdef="Int64" pos="12,3">
......<ordconstn resultdef="Int64" pos="12,3" rangecheck="FALSE">
.........<value>-1</value>
......</ordconstn>
...</callparan>
...<callparan resultdef="Int64" pos="12,15">
......<ordconstn resultdef="Int64" pos="12,15" rangecheck="FALSE">
.........<value>5</value>
......</ordconstn>
...</callparan>
</calln>
This is before the first pass, so the parser immediately replaces it
with a call to the internal compiler procedure.
How should I handle this? There are a few problems I need to
consider. If I use a new kind of inline node that expands into a
regular call after the first pass, I'll still need to handle the case
where it is a call node because there are situations during purity
analysis where nested pure functions are not analysed because their
actual parameters haven't yet been fully calculated (usually requires
another found of constant propagation and inline simplification). It
may be that I need to add some kind of field to the TCallNode to
indicate which internal function it's referring to.
I'll try to do a new merge request soon so Str and Val can be
simplified at the node level, as this can easily have benefits
outside of pure functions.
Kit
_______________________________________________
fpc-devel maillist -fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
fpc-devel maillist -fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel