optimization/9016: Failure to consistently constant fold "constant" C++ objects
martin@xemacs.org
martin@xemacs.org
Thu Dec 19 21:36:00 GMT 2002
>Number: 9016
>Category: optimization
>Synopsis: Failure to consistently constant fold "constant" C++ objects
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: unassigned
>State: open
>Class: pessimizes-code
>Submitter-Id: net
>Arrival-Date: Thu Dec 19 21:36:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: martin@xemacs.org
>Release: gcc-3.2.1
>Organization:
>Environment:
Linux x86
>Description:
Let's look at some code, a simple wrapper around "double"
static struct X {} x;
static struct Y {} y;
struct Double
{
double d_;
Double (double d) : d_ (d) {}
Double (const X&) : d_ (1.2) {}
Double (const Y&) : d_ (3.4) {}
operator double () { return d_; }
inline friend Double operator/ (Double d1, Double d2)
{ return Double (double (d1) / double (d2)); }
};
double f1 () { return Double (1.2) / Double (3.4); }
double f2 () { return Double (1.2) / Double (y ); }
double f3 () { return Double (x ) / Double (3.4); }
double f4 () { return Double (x ) / Double (y ); }
It's obvious that all the Double objects above are
compile-time constant objects, and thus can be
constant-folded.
All the functions f1 f2 f3 f4 return the same constant value.
Of course, g++ can optimize f1 to
fldl .LC2
ret
f2 and f3 are optimized to the only slightly inferior
subl $12, %esp
fldl .LC5
addl $12, %esp
ret
This shows that g++ "knows" that Double (x) and Double (y)
are both compile-time constants, else they could not be
folded. Then why can g++ not optimize f4 as well?
subl $20, %esp
movl $858993459, (%esp)
movl $1074475827, 4(%esp)
fldl (%esp)
movl $858993459, 8(%esp)
movl $1072902963, 12(%esp)
fdivrl 8(%esp)
addl $20, %esp
ret
f4 compiles to a run-time division.
Even at the assembly language level it is relatively
easy to do constant folding of the division here.
What confuses me about this is that g++ can clearly
constant fold Double (x) and Double (y), but only when combined with an "even more constant" Double (1.2),
not with each other.
>How-To-Repeat:
g++ -Wall -O3 -S -fomit-frame-pointer
and look at the resulting .s file
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-prs
mailing list