Skip to content

[Refactor] New node pruning methods

Summary

This merge request introduces some new methods to help with node tree transformation during the first pass in a bid to improve maintainability and performance:

  • function TUnaryNode.PruneKeepLeft(): TNode; - sets the 'left' node to nil and sets a new 'do not execute' flag on the current node that raises an internal error if it is passed through firstpass again. Returns what 'left' was previously set to.
  • function TBinaryNode.PruneKeepRignt(): TNode; - like PruneKeepLeft, but for the 'right' node instead.
  • function TTertiaryNode.PruneKeepThird(): TNode; - like PruneKeepLeft and PruneKeepRight, but for the 'third' node instead.

To showcase this feature, and the supporting 'do not execute' node, the following node-manipulation code has been refactored in order for the feature to be more closely scrutinised:

  • The x86-specific BZHI and ANDN optimisations from !305 (merged) and !315 (merged) set the nf_do_not_execute flag on nodes that are skipped, so as to trigger an internal error if they are somehow sent through pass_generate_code, where they risk creating vestigial code (e.g. the ANDN optimisation skips over the 'not' node in the tree (since ANDN handles it) and instead processes only its left node).
  • TAddNode.Simplify has two commits that use the new pruning methods:
    • One contains the simple cases of replacing result := right; right := nil; and result := right.getcopy; with result := PruneKeepRight(); (and similar with left).
    • The other contains more complex changes where subnodes are also pruned, but where the benefits of using the functions are more questionable (so this commit can be easily dropped without affecting the simpler cases).

System

  • Processor architecture: All

Additional notes

  • This is a pure refactor; generated code outside of the compiler itself should not change.
  • Cases where result := right.getcopy; are replaced with result := PruneKeepRight(); and similar should see a small performance gain in both speed and memory usage since an entire subtree is no longer duplicated.
  • Unfortunately, the new nf_do_not_execute flag increases the number of unique node flags to 33 and hence the PPU file format had to be changed (version number incremented). I recommend that some type-specific node flags be merged in a future commit, so the size can be possibly reduced to less than 32 bits again.

Merge request reports