public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).