Skip to content

[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.

Merge request reports