Bug 39810 - gcc-c++-2.96-81 inadequate optimization
gcc-c++-2.96-81 inadequate optimization
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
David Lawrence
: FutureFeature
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-05-09 02:35 EDT by Omnifarious
Modified: 2007-04-18 12:33 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-05-09 06:21:44 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
This is an example C++ source file that compiles with bloated initializers (267 bytes, text/plain)
2001-05-09 02:36 EDT, Omnifarious
no flags Details

  None (edit)
Description Omnifarious 2001-05-09 02:35:44 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux 2.4.3 i686; en-US; 0.8.1) Gecko/20010421

Description of problem:
Static initializers are optimized very poorly.  Jump optimization seems not
to be performed, and when the initializers have a result that can be
verified as static at compile time, they are not removed and simply set up
as constant values in the .rodata or .data section.


How reproducible:
Always

Steps to Reproduce:
1.g++ -pipe -march=athlon -O2 -S example.cpp

2.Examine example.s.	

Actual Results:  	.file	"example.cpp"
	.version	"01.01"
gcc2_compiled.:
.globl abarney
.bss
	.align 4
	.type	 abarney,@object
	.size	 abarney,8
abarney:
	.zero	8
.globl afred
	.align 4
	.type	 afred,@object
	.size	 afred,4
afred:
	.zero	4
.text
	.align 16
	.type	 __static_initialization_and_destruction_0,@function
__static_initialization_and_destruction_0:
.LFB1:
	pushl	%ebp
.LCFI0:
	movl	%esp, %ebp
.LCFI1:
	movl	12(%ebp), %eax
	movl	8(%ebp), %edx
	cmpl	$65535, %eax
	jne	.L3
	cmpl	$1, %edx
	jne	.L3
	movl	$5, abarney
	movl	$6, abarney+4
.L3:
	cmpl	$65535, %eax
	jne	.L11
	decl	%edx
	jne	.L11
	movl	$2, afred
.L11:
	popl	%ebp
	ret
.LFE1:
.Lfe1:
	.size	
__static_initialization_and_destruction_0,.Lfe1-__static_initialization_and_destruction_0
	.align 16
	.type	 _GLOBAL_.I.abarney,@function
_GLOBAL_.I.abarney:
.LFB2:
	pushl	%ebp
.LCFI2:
	movl	%esp, %ebp
.LCFI3:
	subl	$16, %esp
.LCFI4:
	pushl	$65535
	pushl	$1
.LCFI5:
	call	__static_initialization_and_destruction_0
	addl	$16, %esp
	leave
	ret
.LFE2:
.Lfe2:
	.size	 _GLOBAL_.I.abarney,.Lfe2-_GLOBAL_.I.abarney
		.section	.ctors,"aw"
	.long	 _GLOBAL_.I.abarney
	.ident	"GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-81)"



Expected Results:  	.file	"example2.cpp"
	.version	"01.01"
gcc2_compiled.:
.globl abarney
		.section	.rodata
	.align 4
	.type	 abarney,@object
	.size	 abarney,8
abarney:
	.long	5
	.long	6
.globl afred
	.align 4
	.type	 afred,@object
	.size	 afred,4
afred:
	.long	2
	.ident	"GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-81)"



Additional info:

example.cpp:
class Fred {
   public:
      Fred(int x) : x_(x) { }

   private:
      int x_;
};

class Barney : public Fred {
   public:
      Barney(int x, int y) : Fred(x), y_(y) { }

   private:
      int y_;
};

extern const Barney abarney(5, 6);
extern const Fred afred(2);
------------
The results of all these initializers can be statically determined at
compile time.  There is no reason I can think of they should be stuck in
the .rodata section.  If they were not const, they could be stuck in the
.data section.

Even if the initializer is run, the initializer itself will make repeated
comparisons of %eax against $65535 instead of simply jumping to the end if
the first such comparison registers as being equal.  This situation is also
easily determined by simple analysis, and jump optimization in ordinary
code would catch it.
Comment 1 Omnifarious 2001-05-09 02:36:59 EDT
Created attachment 17827 [details]
This is an example C++ source file that compiles with bloated initializers
Comment 2 Jakub Jelinek 2001-05-09 06:21:39 EDT
As for eliminating the static initializers, ATM none of g++ 2.95.x, 2.96-RH,
3.0-branch or 3.1-head do this. It would be probably better if you requested
this enhancement on @gnu.org lists (it is too late for 3.0, but for 3.1 it could be doable).
As for the jump to test+jump not being optimized out, I'll look at what's going
on. It seems that gcc 3.0 and 3.1 behave the same way, have reproduced it
on C code as well:
int abarney[2];
int afred[1];

void foo(int edx, int eax)
{
  if (eax == 65535)
    {
      if (edx == 1)
        {
          abarney[0] = 5;
          abarney[1] = 6;
        }
    }
  if (eax == 65535)
    {
      if (--edx == 0)
        afred[0] = 2;
    }
}
Comment 3 Jakub Jelinek 2001-06-07 09:07:42 EDT
Jump threading should be fixed in gcc-2.96-86, likewise it will generate
better code for __static_initialization_and_destruction_0 (which even
jump threading is not able to cope with).
Comment 4 Omnifarious 2001-06-27 02:18:41 EDT
Thanks, in gcc-c++-2.96-88, this is now lots better than it was.  :-)

I still say the constructors can be done away with completely and the constant
initial values moved into the .bss segment, but I imagine that's kind of hard to do.

It would solve a major class of problems dealing with order of static
intialization though.  I wouldn't have to worry about initialization order for
many types of global constants.

Note You need to log in before you can comment on or make changes to this bug.