[Refactor] Node traversal optimisation
Summary
This merge request makes some speed optimisations to the compiler by updating the foreachnode
and foreachnodestatic
calls:
- The versions of
foreachnode
andforeachnodestatic
that don't have a process order parameter are now inlined, since these simply call the versions with the order parameter aspm_postprocess
, passing through the other parameters unmodified. - If
foreachnode
andforeachnodetatic
are called with a process order ofpm_postandagain
, the root node is not processed again if theprocess_children
function returns False, since if the root node wasn't changed the first time (or even if it was), it shouldn't change again if the children weren't changed. As a side-effect, the return value of this 'again' call can be discarded because Result is always True at this point, thus removing acase
block.
Especially with the second point, it reduces the number of times the nodes are unnecessarily traversed, although currently only the constant propagation code uses pm_postandagain
traversals.
System
- Processor architecture: Cross-platform
What is the current bug behavior?
N/A
What is the behavior after applying this patch?
The compiler should gain a small speed boost, especially if constant propagation is enabled (which uses pm_postandagain).
Relevant logs and/or screenshots
Places where the inlined foreachnode
and foreachnodestatic
functions are called gain an extra line of code, but in compensation, there is one fewer procedure jump in the chain. For example, for the nbas unit under aarch64-linux - before:
.section .text.n_nbas_$$_no_exit_statement_in_block$tnode$$boolean,"ax"
.balign 8
.globl NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN
.hidden NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN
.type NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN,@function
NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN:
...
adrp x1,:got:NBAS_$$_IS_EXIT_STATEMENT$TNODE$POINTER$$FOREACHNODERESULT
ldr x1,[x1, :got_lo12:NBAS_$$_IS_EXIT_STATEMENT$TNODE$POINTER$$FOREACHNODERESULT]
mov x0,sp
movz x2,#0
bl NUTILS_$$_FOREACHNODESTATIC$TNODE$STATICFOREACHNODEFUNCTION$POINTER$$BOOLEAN
After:
.section .text.n_nbas_$$_no_exit_statement_in_block$tnode$$boolean,"ax"
.balign 8
.globl NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN
.hidden NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN
.type NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN,@function
NBAS_$$_NO_EXIT_STATEMENT_IN_BLOCK$TNODE$$BOOLEAN:
...
adrp x2,:got:NBAS_$$_IS_EXIT_STATEMENT$TNODE$POINTER$$FOREACHNODERESULT
ldr x2,[x2, :got_lo12:NBAS_$$_IS_EXIT_STATEMENT$TNODE$POINTER$$FOREACHNODERESULT]
mov x1,sp
movz x3,#0
movz w0,#1 ; <-- Corresponds to pm_postprocess
bl NUTILS_$$_FOREACHNODESTATIC$hYWSyYihGjGH```