Forum > FPC development

[SOLVED] Poor optimization of constant folding

<< < (2/5) > >>

runewalsh:

--- Quote from: 440bx on September 27, 2023, 11:53:55 am ---calculate the value of the constant along with a comment

--- End quote ---

Better to declare a const if you are that distrustful of folding.

lagprogramming:

--- Quote from: 440bx on September 27, 2023, 11:53:55 am ---
--- Quote from: runewalsh on September 27, 2023, 11:42:56 am --- Until the fix in mid-2030s, you can force the folding with parentheses:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---result:=a*((-2)*(-1)*(-1)*(-1)*(-1)*(3));
--- End quote ---
or better yet, calculate the value of the constant along with a comment as to how it was calculated (if necessary for clarity)

--- End quote ---
@runewalsh
Additional parenthesis is a nice trick.

@440bx
:) Reminds me of the following lines in LCL's customdrawnwinapi.inc

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---//lFontSize:= MulDiv(lFontSize,72,ftFont.DPI); // convert points to pixelslFontSize := Round(ftFont.TextHeight(Str) * 0.75);// ToDo: Find out why this 75% factor works:) Most likely a developer precomputed that 0.75 constant value and other developers could not trace the arithmetic to source.
Fpgui has:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TFPGUIWinAPIFont.GetFontSize: integer;begin  Result:=(-FFontHeight * 72) div 96;end;72/96=0.75

Thaddy:
declaring as inline, provided all elements are constant..

ccrause:

--- Quote from: Fibonacci on September 27, 2023, 11:06:49 am ---Its computed at compile time only if whole expression is constant

--- End quote ---
The simplification of constant folding happens in taddnode.simplify (at least the initial simplification).  Here the left and right nodes of an operator are inspected to check if both are constant and of the same type, then the folding is applied. Since this simplification only looks at the immediate left and right nodes of the operand, opportunities farther away is not visible. 

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  b := 10;  a := -1 * b * -1;With -O2 or lower the following code is generated:

--- Code: ASM  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# [9] a := -1 * b *  -1;        movslq  %esi,%rbx        negq    %rbx        negq    %rbx   With -O3 or higher:

--- Code: ASM  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# [9] a := -1 * b *  -1;        movl    $10,%esi   So there is another optimization that can further simplify the expression, although the following example doesn't fold at -O4:

--- Code: ASM  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# [15] a := b * -1 * -1;        movslq  %edi,%rbx        negq    %rbx        negq    %rbx
A workaround is to create sub expressions that can be folded before taddnode.simplify is called:

--- Code: ASM  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---# [18] a := b * (-1 * -1);        movslq  %esi,%rsi
One could perhaps expand the scope of the simplification to search one node wider (deeper?) to cover the above case, but that will then fail to fold the following example:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---a = -1 * b * -1 * b * -1;Note: this example does get simplified all the way to a constant value at -O3.

I think the current situation where seemingly obvious opportunities for constant folding are missed is caused by the fairly simplistic heuristics used by the compiler.  Perhaps someone can come up with a tweak to this heuristic that covers more situations without incurring a significant speed penalty.

440bx:
I doubt what I am going to mention can be applied to FPC without significant effort.  The solution to a large number of expression optimization problems, including constant folding, is to evaluate the expression _symbolically_. 

This not only coalesces all constants (such as the above examples) but allows for the recognition of common algebraic patterns that can be substituted for equivalent but simpler (read faster) patterns.

A little bit of Mathematica in the compiler ;)

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version