[fpc-devel] Kit's development progress and research
J. Gareth Moreton
gareth at moreton-family.com
Tue Jun 2 05:31:00 CEST 2020
Admittedly I haven't paid much attention to pass 2 yet, and the binary
output of test programs, including Lazarus, shows that the generated
binary is identical. Granted, so far I haven't reached the point where
I feel confident in reusing nodes because of things like directly
modifying nodes as you describe (such as type conversions changing
resultdefs). Because my current time saving is only 1%, I'm putting
this particular bit of exploration on the backburner - however, there
are some things I can scavenge out of this that are useful:
- Fixing up "right:=right.simplify(False);", so it frees the original
'right' and raises an internal error if simplify's result is nil (since
the code expects it not to be).
- Removing superfluous calls to "firstpass(result);" in some nodes'
"pass_1" routines, since the routine that calls "pass_1" in the first
place will automatically call "firstpass" on the result. While it will
exit immediately because the result node has already been processed, it
is a waste of a call that increases stack depth. In some cases, the
extra call to "firstpass(result)" is justified - comments usually
explain why - but if the routine exits immediately afterwards, it can be
removed without harm.
- Constructs such as "result := getcopy;" being changed so it doesn't go
through the wasteful process of creating a copy of the node tree at that
point and deleting the original (which 'firstpass' automatically does if
the result is not nil). I introduced a method named "ProtectAndReuse"
(an alias for "AddRef"), which increments the reference count and is
named as such to show the intent that you intend to reuse this node and
don't want it to be deleted, and making a new method called "Release"
that decrements the reference count and only destroys the node if it
falls to zero. In this case, the code would be "result :=
ProtectAndReuse;" (it returns Self), then firstpass calls "p.Release;"
instead of "p.Free;", since 'result' and 'p' will be identical.
Thanks for warning me about pass 2 though - I think it was just dumb
luck that I haven't fallen foul of it yet since I haven't developed
anything that caused the nodes to get a reference count of 2 for more
than a split second. The experimentation is mostly for my own benefit,
but I like to think I'm getting a better understanding of the compiler
as a result and may find and create something useful in the future.
Gareth aka. Kit
On 01/06/2020 11:47, Jonas Maebe wrote:
> On 01/06/2020 07:57, J. Gareth Moreton wrote:
>> Well, I haven't managed to get much of a saving yet, probably due to how
>> good FPC's memory manager is as well as the "nf_pass1_done" flag that
>> minimises needless parsing of the nodes even when they're copied.
>> Ultimately it's not worth showcasing just yet, although I might be able
>> to pick out a couple of things like removing memory leaks, and avoiding
>> the use of copying nodes does save on memory, which might be good for
>> platforms that are a bit more constrained.
> If you use reference counting, how do you handle
> 1) node.location being different in pass 2 for identical nodes, since
> the result of nodes will often end up in different virtual registers
> 2) cases in the compiler where existing nodes are directly modified.
> This is mostly in ncnv, e.g. lines 2509 - 2511
>
> While you are correct that the existing node juggling is error-prone in
> terms of memory leaks and other mistakes, I'm afraid reference counting
> may make it worse rather than better.
>
>
> Jonas
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
>
--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
More information about the fpc-devel
mailing list