[Refactor] Firstpass efficiency (minimising "getcopy")
Summary
This merge request makes a minor change to typecheckpass_internal_loop
and firstpass
that permits TNode.simplify
to safely return Self (in the trunk, doing so would create a dangling pointer), indicating that the node branch was transformed in some way but the root node hasn't changed. This provides some small gains in memory conservation by potentially reducing the number of calls to getcopy
in particular circumstances.
Howevrer, TNode.pass_1
is not allowed to return Self
(doing so will now raise an internal error) because this would very likely cause an infinite loop, since there should be no logical reason to pass a node through pass_1
more than once without transforming it in some way in between calls (e.g. via simplify
).
To showcase this, a couple of optimisations in TAddNode.Simplify
that utilised result:=getcopy;
calls have been modified to return result:=Self;
instead.
An instance of result:=getcopy;
also appears in the nmat
unit, but this couldn't be changed to Result:=Self;
because the final return value is a new TTypeConvNode
object that encapsulates the original node. Nevertheless, it was modified slightly to avoid unnecessary duplication of its children.
System
- Processor architecture: All
What is the current bug behavior?
N/A
What is the behavior after applying this patch?
The compiler's memory footpoint will be slightly less in some circumstances, as well as potential performance gains with some code examples (The dateutil.inc
unit in packages/rtl-objpas
is a notable example).
Relevant logs and/or screenshots
This is a pure refactor and resultant binaries and assembly dumps should not change (except in pass_1
, nadd
and nmat
).
Future development
One possible extension of this merge request is to introduce a new nf_preserve
flag that tells pass_1
etc. to not delete the original node if a branch is transformed (although it will clear the flag), and to introduce a new TNode
method named reuse
which returns Self but sets the nf_preserve
flag at the same time. This would be useful for the TModDivNode.simplify
example above, since it would allow the original node to be used inside the new TTypeConvNode
node without having to call getcopy
or do gymnastics with the node's children to stop them from being pruned.