* More embarrassing failures to optimize
@ 2003-01-05 10:44 Martin Buchholz
2003-01-05 18:51 ` Zack Weinberg
0 siblings, 1 reply; 4+ messages in thread
From: Martin Buchholz @ 2003-01-05 10:44 UTC (permalink / raw)
To: gcc
One can try creating a typesafe Bool class like this:
class Bool
{
private: const bool val_;
struct Conv { int Dummy; };
public:
Bool (bool val) : val_ (val) {}
operator int Conv::* () const { return val_ ? & Conv::Dummy : 0; }
};
Unfortunately, g++ is less capable of optimizing this than other
obvious Bool classes.
For example,
void f3 ()
{
Bool t (true), f (false);
assert (t); assert (! f);
assert (t); assert (! f);
}
is "optimized" to
xorl %edx, %edx
subl $12, %esp
testb %dl, %dl
jne .L52
addl $12, %esp
ret
.L52:
pushl $_ZZ2f3vE19__PRETTY_FUNCTION__
pushl $42
pushl $.LC0
pushl $.LC2
call __assert_fail
Note that the resulting code contains exactly one branch, not two or
four.
To my eyes it looks like "testb %dl, %dl" always yields constant true;
optimizing this shouldn't be too tough a job.
g++ clearly knows how to optimize "assert (t); assert (! f);" away
completely - but not if it's repeated!
The following alternative Bool classes can be optimized without
problems:
class Bool // "obvious" Bool class
{
private: const bool val_;
public:
Bool (bool val) : val_ (val) {}
operator bool () const { return val_; }
};
class Bool // Note addition of operator!
{
private: const bool val_;
struct Conv { int Dummy; };
public:
Bool (bool val) : val_ (val) {}
operator int Conv::* () const { return val_ ? & Conv::Dummy : 0; }
bool operator! () { return val_ ? 0 : & Conv::Dummy; }
};
A statement that is optimized away completely should not inhibit
optimizations in subsequent statements.
Like other optimization problems I have reported, this "looks" like
"low-hanging fruit".
To repeat: Linux x86, gcc 3.2.1: g++ -O3 -fomit-frame-pointer foo.cc
-----------------------------------------------------------------
#include <cassert>
class Bool1
{
private: const bool val_;
public:
Bool1 (bool val) : val_ (val) {}
operator bool () const { return val_; }
};
class Bool2
{
private: const bool val_;
struct Conv { int Dummy; };
public:
Bool2 (bool val) : val_ (val) {}
operator int Conv::* () const { return val_ ? & Conv::Dummy : 0; }
//bool operator! () { return val_ ? 0 : & Conv::Dummy; }
};
void f1 () // gcc optimizes this
{
Bool1 t (true), f (false);
assert (t); assert (! f);
assert (t); assert (! f);
}
void f2 () // gcc optimizes this
{
Bool2 t (true), f (false);
assert (t); assert (! f);
}
void f3 () // gcc fails to optimize this
{
Bool2 t (true), f (false);
assert (t); assert (! f);
assert (t); assert (! f);
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More embarrassing failures to optimize
2003-01-05 10:44 More embarrassing failures to optimize Martin Buchholz
@ 2003-01-05 18:51 ` Zack Weinberg
2003-01-05 23:01 ` Martin Buchholz
0 siblings, 1 reply; 4+ messages in thread
From: Zack Weinberg @ 2003-01-05 18:51 UTC (permalink / raw)
To: martin; +Cc: gcc
Martin Buchholz <martin@xemacs.org> writes:
> void f3 ()
> {
> Bool t (true), f (false);
>
> assert (t); assert (! f);
> assert (t); assert (! f);
> }
>
> is "optimized" to
>
> xorl %edx, %edx
> subl $12, %esp
> testb %dl, %dl
> jne .L52
> addl $12, %esp
> ret
> .L52:
> pushl $_ZZ2f3vE19__PRETTY_FUNCTION__
> pushl $42
> pushl $.LC0
> pushl $.LC2
> call __assert_fail
>
> Note that the resulting code contains exactly one branch, not two or
> four.
I suspect this is the same underlying problem that causes
gcc.c-torture/execute/builtin-constant.c to fail. This was discussed
at some length in the thread starting at
http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00235.html - it's
nontrivial to fix.
You might want to try these embarrassing failures against the tree-ssa
branch.
zw
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More embarrassing failures to optimize
2003-01-05 18:51 ` Zack Weinberg
@ 2003-01-05 23:01 ` Martin Buchholz
2003-01-05 23:11 ` Zack Weinberg
0 siblings, 1 reply; 4+ messages in thread
From: Martin Buchholz @ 2003-01-05 23:01 UTC (permalink / raw)
To: Zack Weinberg; +Cc: gcc
>>>>> "Z" == Zack Weinberg <zack@codesourcery.com> writes:
Z> I suspect this is the same underlying problem that causes
Z> gcc.c-torture/execute/builtin-constant.c to fail. This was discussed
Z> at some length in the thread starting at
Z> http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00235.html - it's
Z> nontrivial to fix.
Independently of whether it's related to builtin_constant_p, the fact
that the class containing the direct conversion to bool can be
optimized as desired suggests a different approach for improving
optimization:
Make sure that constant pointer expressions used in boolean contexts
can be optimized as well as constant expressions of type bool.
class Bool1 // optimizable
{
private: const bool val_;
public:
Bool1 (bool val) : val_ (val) {}
operator bool () const { return val_; }
};
class Bool2 // less optimizable - Why?
{
private: const bool val_;
struct Conv { int Dummy; };
public:
Bool2 (bool val) : val_ (val) {}
operator int Conv::* () const { return val_ ? & Conv::Dummy : 0; }
};
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More embarrassing failures to optimize
2003-01-05 23:01 ` Martin Buchholz
@ 2003-01-05 23:11 ` Zack Weinberg
0 siblings, 0 replies; 4+ messages in thread
From: Zack Weinberg @ 2003-01-05 23:11 UTC (permalink / raw)
To: martin; +Cc: gcc
Martin Buchholz <martin@xemacs.org> writes:
>>>>>> "Z" == Zack Weinberg <zack@codesourcery.com> writes:
>
> Z> I suspect this is the same underlying problem that causes
> Z> gcc.c-torture/execute/builtin-constant.c to fail. This was discussed
> Z> at some length in the thread starting at
> Z> http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00235.html - it's
> Z> nontrivial to fix.
>
> Independently of whether it's related to builtin_constant_p, the fact
> that the class containing the direct conversion to bool can be
> optimized as desired suggests a different approach for improving
> optimization:
You misunderstand. The problem is a general one, having to do with
calculating common-subexpression information across basic block
boundaries. __builtin_constant_p is a convenient way to turn a
poor-optimization issue into a visible-behavior-change issue.
zw
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-01-05 23:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-05 10:44 More embarrassing failures to optimize Martin Buchholz
2003-01-05 18:51 ` Zack Weinberg
2003-01-05 23:01 ` Martin Buchholz
2003-01-05 23:11 ` Zack Weinberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).