Optimization of nested procedures and functions lazarus / 64-FPC development ---------------------------------------------------------------------- lagprogramming · 2022-07-16 10:17 According to the documentation: QuoteWhen a routine is declared within the scope of a procedure or function, it is said to be nested. In this case, an additional invisible parameter is passed to the nested routine. This additional parameter is the frame pointer address of the parent routine. This permits the nested routine to access the local variables and parameters of the calling routine. In the situation when the nested routine doesn't access any parameter or local variable of the calling routine, would there be a problem if the produced code would be as if the routine was not nested? The frame pointer parameter occupies space with no benefit and it looks like it might block a useful CPU register(look at variable "f" in the following nested_yes and nested_no functions). Here is an example where function1 and function2 do the same thing except for the fact that one of them calls a nested routine and the other one doesn't: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; function nested_no(a,b,c,d,e,f:sizeint):sizeint;begin  if a+b+c+d+e+f>0 then result:=-1 else result:=0;end; function function1(a,b,c,d,e,f:sizeint):sizeint;begin  result:=nested_no(a,b,a,b,a,b);end; function function2(a,b,c,d,e,f:sizeint):sizeint;  function nested_yes(a,b,c,d,e,f:sizeint):sizeint;  begin    if a+b+c+d+e+f>0 then result:=-1 else result:=0;  end;begin  result:=nested_yes(a,b,a,b ,a,b);end; beginwriteln(function1(round(random),round(random),round(ra ndom),round(random),round(random),round(random)));writeln(function2(ro und(random),round(random),round(random),round(random),round(random),ro und(random)));end. I attach FPC's produced code(look at variable "f" in the following nested_yes and nested_no functions) ---------------------------------------------------------------------- marcov · 2022-07-16 10:56 If you mark nested_no as "inline", the assembler looks like Code: [Select]pushl %ebp .Lc9: .Lc10: # Var a located in register eax # Var b located in register edx # Var c located in register ecx # Var d located in stack [ebp+16] # Var e located in stack [ebp+12] # Var f located in stack [ebp+8] .Ll6: # [10] result:=nested_no(a,b,a,b,a,b); leal (%eax,%edx),%ecx addl %eax,%ecx addl %edx,%ecx addl %ecx,%eax addl %edx,%eax testl %eax,%eax jng .Lj11 movl $-1,%eax jmp .Lj12 .p2align 4,,10 .p2align 3 .Lj11: xorl %eax,%eax .Lj12: # Var $result located in register eax .Lc11: .Lc12: .Ll7: # [11] end; popl %ebp ret $12 AND for function2: .Ll10: # [19] result:=nested_yes(a,b,a,b,a,b); leal (%eax,%edx),%ecx addl %eax,%ecx addl %edx,%ecx addl %ecx,%eax addl %edx,%eax testl %eax,%eax jng .Lj18 movl $-1,%eax jmp .Lj19 .p2align 4,,10 .p2align 3 .Lj18: xorl %eax,%eax Which doesn't call nested_no. So mark the nested functions you want to inline with the inline directive like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function nested_no(a,b,c,d,e,f:sizeint):sizeint; inline; // and  function nested_yes(a,b,c,d,e,f:sizeint):sizeint; inline; Note that inlining very large functions does not always produce a better result. But ---------------------------------------------------------------------- PascalDragon · 2022-07-16 14:34 Quote from: lagprogramming on July 16, 2022, 12:17:20 pmIn the situation when the nested routine doesn't access any parameter or local variable of the calling routine, would there be a problem if the produced code would be as if the routine was not nested? The frame pointer parameter occupies space with no benefit and it looks like it might block a useful CPU register(look at variable "f" in the following nested_yes and nested_no functions). FPC main contains the UnusedPara optimization which removes the parent framepointer parameter in your example.