[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 throughpass_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;
andresult := right.getcopy;
withresult := PruneKeepRight();
(and similar withleft
). - 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).
- One contains the simple cases of replacing
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 withresult := 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.