From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30541 invoked by alias); 28 Dec 2012 15:19:28 -0000 Received: (qmail 30486 invoked by uid 22791); 28 Dec 2012 15:19:26 -0000 X-SWARE-Spam-Status: No, hits=-7.1 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_OV,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 28 Dec 2012 15:19:21 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBSFJKVP023993 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 28 Dec 2012 10:19:21 -0500 Received: from zebedee.pink (ovpn-113-25.phx2.redhat.com [10.3.113.25]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qBSFJJpb001917; Fri, 28 Dec 2012 10:19:20 -0500 Message-ID: <50DDB877.9000806@redhat.com> Date: Fri, 28 Dec 2012 15:19:00 -0000 From: Andrew Haley User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120911 Thunderbird/15.0.1 MIME-Version: 1.0 To: Kicer CC: gcc-help@gcc.gnu.org Subject: Re: problems with optimisation References: <3594412.lfrBexjLtS@kicer> In-Reply-To: <3594412.lfrBexjLtS@kicer> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2012-12/txt/msg00145.txt.bz2 On 12/28/2012 10:25 AM, Kicer wrote: > Hi all > > > Last days I've found a problem with some certain code optimisations: > > > namespace > { > > struct Base; > > struct Bit > { > const Base &m_p; > const int m_pos; > > constexpr Bit(const Base &p, const int pos): m_p(p), m_pos(pos) > { > } > > operator bool() const; > }; > > struct Base > { > const int m_port; > constexpr Base(int p): m_port(p) > { > } > > operator char () const > { > char result; > > asm( > "in %%dx, %%al\n" > :"=a"(result) > :"d"(m_port) > ); > > //result = *(reinterpret_cast(m_port+32)); > > return result; > } > > Bit operator[] (int p) const > { > Bit r(*this, p); > return r; > } > > }; > > > Bit::operator bool() const > { > const char v = m_p; > const bool r = (v & (1 << m_pos)) > 0; > > return r; > } > > struct Anc: public Base > { > const Base m_in; > constexpr Anc(int o): Base(o), m_in(o - 1) > { > } > > const Base& getIn() const > { > return m_in; > } > > }; > > } > > template > char foo() > { > Anc p(v), p2(v+2); > char r = p.getIn() + p2.getIn(); > > //r += p[0]? 1: 0; //commented out at first step > r += p2[4]? 1 : 0; > > return r; > } > > > char bar() > { > char r = foo<4>(); > > r-= foo<6>(); > > return r; > } > > there are 3 structs which looks more complex than the code they generate. > foo() and bar() are just ising those structs. > For the code above output is short and clear as expected: > > but when I uncomment "//r += p[0]? 1: 0; " in foo(), the code becomes > unexpectly large and unclear: > > > compilation flags: > g++ -Os test.cpp -c -o test.o -std=c++11 > > > this may seem to be a less important problem for x86 archs, but I'm affected > with this problem on avr arch where memory is very limited. Can I somehow > figure out why gcc resigns from generation clean code in second example? With -O2 there's much less difference: bar(): bar(): .LFB14: .LFB14: .cfi_startproc .cfi_startproc movl $3, %edx movl $3, %edx in %dx, %al in %dx, %al movb $6, %dl | movb $4, %dl movl %eax, %ecx movl %eax, %ecx in %dx, %al in %dx, %al > movb $6, %dl > movl %eax, %edi > in %dx, %al > movb $7, %dl movb $7, %dl movl %eax, %esi movl %eax, %esi > andl $1, %edi in %dx, %al in %dx, %al movl %eax, %edi | movl %eax, %r8d > movsbl %sil, %esi movb $8, %dl movb $8, %dl subb %dil, %cl | subb %r8b, %cl in %dx, %al in %dx, %al andl $16, %esi | addl %edi, %ecx > testb $16, %sil setne %dl setne %dl > andl $1, %esi addl %edx, %ecx addl %edx, %ecx > subb %sil, %cl testb $16, %al testb $16, %al setne %al setne %al subb %al, %cl subb %al, %cl movl %ecx, %eax movl %ecx, %eax ret ret Without inlining GCC can't tell what your program is doing, and by using -Os you're preventing GCC from inlining. Andrew.