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

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).