This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GCC 3.0.3 produces large code



   Hi, I'm the author of a fairly large project which builds in GCC and
Visual C. I noticed that GCC was producing very large files and with a
series of hacks I managed to get the size down, but it's still
considerably larger than Visual C. Here's an example of a function that
doesn't get optimised very well:


#include <stdio.h>
#include <stdlib.h>

class RWL
{
public:
        int a;
};

class AutoRWL
{
public:
        AutoRWL(RWL* pRWL, int foo)
        {
                printf("Lock");
                m_pRWL = pRWL;
                m_foo = foo;
        }
        ~AutoRWL()
        {
                printf("Unlock");
        }
        RWL* m_pRWL;
        int m_foo;
};

class a
{
public:
        int DoOtherThing()
        {
                return rand();
        }
};
class b
{
public:
        b() { m_pa = new a; }
        ~b() { delete m_pa; }
        virtual int DoThing()
        {
                AutoRWL Lock(&m_RWL, 1);
                if( m_pa )
                        return m_pa->DoOtherThing();
                else
                        return 0;
        }
        virtual int DoThing2()
        {
                AutoRWL Lock(&m_RWL, 1);
                return m_pa ? m_pa->DoOtherThing() : 0;
        }
        virtual int DoThing3()
        {
                AutoRWL Lock(&m_RWL, 1);
                int ret = 0;
                if( m_pa ) ret = m_pa->DoOtherThing();
                return ret;
        }
        a* m_pa;
        RWL m_RWL;
};

int main(void)
{
        b bb;
        return bb.DoThing();
}



This is a disassembly of the three DoThing routines:


08048870 <b::DoThing()>:
 8048870:       56                      push   %esi
 8048871:       53                      push   %ebx
 8048872:       83 ec 20                sub    $0x20,%esp
 8048875:       8b 74 24 2c             mov    0x2c(%esp,1),%esi
 8048879:       68 a4 89 04 08          push   $0x80489a4
 804887e:       e8 91 fd ff ff          call   8048614 <_init+0x98>
 8048883:       83 c4 10                add    $0x10,%esp
 8048886:       c7 44 24 0c 01 00 00    movl   $0x1,0xc(%esp,1)
 804888d:       00
 804888e:       8d 5e 08                lea    0x8(%esi),%ebx
 8048891:       89 5c 24 08             mov    %ebx,0x8(%esp,1)
 8048895:       83 7e 04 00             cmpl   $0x0,0x4(%esi)
 8048899:       74 25                   je     80488c0 <b::DoThing()+0x50>
 804889b:       e8 a4 fd ff ff          call   8048644 <_init+0xc8>
 80488a0:       83 ec 0c                sub    $0xc,%esp
 80488a3:       89 c3                   mov    %eax,%ebx
 80488a5:       68 a9 89 04 08          push   $0x80489a9
 80488aa:       e8 65 fd ff ff          call   8048614 <_init+0x98>
 80488af:       83 c4 10                add    $0x10,%esp
 80488b2:       89 d8                   mov    %ebx,%eax
 80488b4:       83 c4 14                add    $0x14,%esp
 80488b7:       5b                      pop    %ebx
 80488b8:       5e                      pop    %esi
 80488b9:       c3                      ret
 80488ba:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
 80488c0:       83 ec 0c                sub    $0xc,%esp
 80488c3:       68 a9 89 04 08          push   $0x80489a9
 80488c8:       e8 47 fd ff ff          call   8048614 <_init+0x98>
 80488cd:       83 c4 10                add    $0x10,%esp
 80488d0:       31 c0                   xor    %eax,%eax
 80488d2:       eb e0                   jmp    80488b4 <b::DoThing()+0x44>
 80488d4:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
 80488da:       8d bf 00 00 00 00       lea    0x0(%edi),%edi

080488e0 <b::DoThing2()>:
 80488e0:       56                      push   %esi
 80488e1:       53                      push   %ebx
 80488e2:       83 ec 20                sub    $0x20,%esp
 80488e5:       8b 74 24 2c             mov    0x2c(%esp,1),%esi
 80488e9:       68 a4 89 04 08          push   $0x80489a4
 80488ee:       e8 21 fd ff ff          call   8048614 <_init+0x98>
 80488f3:       83 c4 10                add    $0x10,%esp
 80488f6:       c7 44 24 0c 01 00 00    movl   $0x1,0xc(%esp,1)
 80488fd:       00
 80488fe:       8d 5e 08                lea    0x8(%esi),%ebx
 8048901:       89 5c 24 08             mov    %ebx,0x8(%esp,1)
 8048905:       83 7e 04 00             cmpl   $0x0,0x4(%esi)
 8048909:       74 1c                   je     8048927 <b::DoThing2()+0x47>
 804890b:       e8 34 fd ff ff          call   8048644 <_init+0xc8>
 8048910:       89 c3                   mov    %eax,%ebx
 8048912:       83 ec 0c                sub    $0xc,%esp
 8048915:       68 a9 89 04 08          push   $0x80489a9
 804891a:       e8 f5 fc ff ff          call   8048614 <_init+0x98>
 804891f:       83 c4 24                add    $0x24,%esp
 8048922:       89 d8                   mov    %ebx,%eax
 8048924:       5b                      pop    %ebx
 8048925:       5e                      pop    %esi
 8048926:       c3                      ret
 8048927:       31 db                   xor    %ebx,%ebx
 8048929:       eb e7                   jmp    8048912 <b::DoThing2()+0x32>
 804892b:       90                      nop
 804892c:       8d 74 26 00             lea    0x0(%esi,1),%esi

08048930 <b::DoThing3()>:
 8048930:       56                      push   %esi
 8048931:       53                      push   %ebx
 8048932:       83 ec 20                sub    $0x20,%esp
 8048935:       8b 74 24 2c             mov    0x2c(%esp,1),%esi
 8048939:       68 a4 89 04 08          push   $0x80489a4
 804893e:       e8 d1 fc ff ff          call   8048614 <_init+0x98>
 8048943:       83 c4 10                add    $0x10,%esp
 8048946:       c7 44 24 0c 01 00 00    movl   $0x1,0xc(%esp,1)
 804894d:       00
 804894e:       8d 5e 08                lea    0x8(%esi),%ebx
 8048951:       89 5c 24 08             mov    %ebx,0x8(%esp,1)
 8048955:       31 db                   xor    %ebx,%ebx
 8048957:       83 7e 04 00             cmpl   $0x0,0x4(%esi)
 804895b:       74 07                   je     8048964 <b::DoThing3()+0x34>
 804895d:       e8 e2 fc ff ff          call   8048644 <_init+0xc8>
 8048962:       89 c3                   mov    %eax,%ebx
 8048964:       83 ec 0c                sub    $0xc,%esp
 8048967:       68 a9 89 04 08          push   $0x80489a9
 804896c:       e8 a3 fc ff ff          call   8048614 <_init+0x98>
 8048971:       83 c4 24                add    $0x24,%esp
 8048974:       89 d8                   mov    %ebx,%eax
 8048976:       5b                      pop    %ebx
 8048977:       5e                      pop    %esi
 8048978:       c3                      ret
 8048979:       8d b4 26 00 00 00 00    lea    0x0(%esi,1),%esi


Here are the sizes:

08048930  w    F .text  00000049              b::DoThing3()
080488e0  w    F .text  0000004b              b::DoThing2()
08048870  w    F .text  00000064              b::DoThing()


   What vexes me is that all three routines do very similar things; in
fact, I have really just done a trivial optimisation by hand in each
case.. but each time this has reduced the code size, in fact quite a lot.
I don't understand why GCC isn't able to do this itself, and I'm still not
sure that the smallest code that I can get it to produce couldn't be made
quite a bit smaller. Here's the commandline by the way:

g++ -Os -fomit-frame-pointer-falign-labels=1 -falign-jumps=1
-fno-exceptions -o test test.cpp

   I chose -Os for obvious reasons... the others are also in an attempt to
get file size down. The version, as mentioned in the subject, is 3.0.3.
Can anyone suggest how to make it compile the code any smaller? And
perhaps the people responsible for optimisations might take note of this.
I can understand maybe why the code needs to be so big with -O3, but with
-Os, it seems to me it could be a lot smaller, and really routines like
this benefit most from being small rather than fast (they'll never really
be all that fast). Maybe the compiler can be super-smart about it, and
automatically optimise small functions for size and large functions for
speed?

   Anyway, I hope someone can improve the situation a bit.


     Thanks,
           Nicholas

   P.S. Other than code size, GCC 3.0.3 seems great.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]