This is the mail archive of the gcc-help@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]

problems with optimisation


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<char *>(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<int v>
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:

   0:	ba 03 00 00 00       	mov    $0x3,%edx
   5:	be 01 00 00 00       	mov    $0x1,%esi
   a:	ec                   	in     (%dx),%al
   b:	b2 05                	mov    $0x5,%dl
   d:	41 88 c0             	mov    %al,%r8b
  10:	ec                   	in     (%dx),%al
  11:	b2 06                	mov    $0x6,%dl
  13:	40 88 c7             	mov    %al,%dil
  16:	ec                   	in     (%dx),%al
  17:	b2 07                	mov    $0x7,%dl
  19:	88 c1                	mov    %al,%cl
  1b:	ec                   	in     (%dx),%al
  1c:	b2 08                	mov    $0x8,%dl
  1e:	41 88 c1             	mov    %al,%r9b
  21:	c0 e9 04             	shr    $0x4,%cl
  24:	ec                   	in     (%dx),%al
  25:	c0 e8 04             	shr    $0x4,%al
  28:	41 01 f9             	add    %edi,%r9d
  2b:	83 e1 01             	and    $0x1,%ecx
  2e:	21 c6                	and    %eax,%esi
  30:	42 8d 04 07          	lea    (%rdi,%r8,1),%eax
  34:	44 01 ce             	add    %r9d,%esi
  37:	01 c8                	add    %ecx,%eax
  39:	40 0f be f6          	movsbl %sil,%esi
  3d:	0f be c0             	movsbl %al,%eax
  40:	29 f0                	sub    %esi,%eax
  42:	c3                   	retq   


but when I uncomment "//r += p[0]? 1: 0; " in foo(), the code becomes 
unexpectly large and unclear:

0000000000000000 <_ZNK12_GLOBAL__N_13BitcvbEv>:
   0:	48 8b 07             	mov    (%rdi),%rax
   3:	8b 4f 08             	mov    0x8(%rdi),%ecx
   6:	be 01 00 00 00       	mov    $0x1,%esi
   b:	8b 10                	mov    (%rax),%edx
   d:	d3 e6                	shl    %cl,%esi
   f:	ec                   	in     (%dx),%al
  10:	0f be c0             	movsbl %al,%eax
  13:	85 f0                	test   %esi,%eax
  15:	0f 9f c0             	setg   %al
  18:	c3                   	retq   

0000000000000019 <_Z3barv>:
  19:	53                   	push   %rbx
  1a:	e8 00 00 00 00       	callq  1f <_Z3barv+0x6>
  1f:	88 c3                	mov    %al,%bl
  21:	e8 00 00 00 00       	callq  26 <_Z3barv+0xd>
  26:	0f be d3             	movsbl %bl,%edx
  29:	0f be c0             	movsbl %al,%eax
  2c:	29 c2                	sub    %eax,%edx
  2e:	88 d0                	mov    %dl,%al
  30:	5b                   	pop    %rbx
  31:	c3                   	retq   

Disassembly of section .text._Z3fooILi4EEcv:

0000000000000000 <_Z3fooILi4EEcv>:
   0:	41 54                	push   %r12
   2:	ba 03 00 00 00       	mov    $0x3,%edx
   7:	ec                   	in     (%dx),%al
   8:	55                   	push   %rbp
   9:	b2 05                	mov    $0x5,%dl
   b:	40 88 c5             	mov    %al,%bpl
   e:	ec                   	in     (%dx),%al
   f:	53                   	push   %rbx
  10:	41 88 c4             	mov    %al,%r12b
  13:	41 8d 1c 2c          	lea    (%r12,%rbp,1),%ebx
  17:	48 83 ec 20          	sub    $0x20,%rsp
  1b:	48 8d 04 24          	lea    (%rsp),%rax
  1f:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi
  24:	c7 04 24 04 00 00 00 	movl   $0x4,(%rsp)
  2b:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%rsp)
  32:	00 
  33:	c7 44 24 08 06 00 00 	movl   $0x6,0x8(%rsp)
  3a:	00 
  3b:	0f be db             	movsbl %bl,%ebx
  3e:	c7 44 24 0c 05 00 00 	movl   $0x5,0xc(%rsp)
  45:	00 
  46:	48 89 44 24 10       	mov    %rax,0x10(%rsp)
  4b:	c7 44 24 18 00 00 00 	movl   $0x0,0x18(%rsp)
  52:	00 
  53:	e8 00 00 00 00       	callq  58 <_Z3fooILi4EEcv+0x58>
  58:	0f b6 c0             	movzbl %al,%eax
  5b:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi
  60:	c7 44 24 18 04 00 00 	movl   $0x4,0x18(%rsp)
  67:	00 
  68:	01 c3                	add    %eax,%ebx
  6a:	48 8d 44 24 08       	lea    0x8(%rsp),%rax
  6f:	0f be db             	movsbl %bl,%ebx
  72:	48 89 44 24 10       	mov    %rax,0x10(%rsp)
  77:	e8 00 00 00 00       	callq  7c <_Z3fooILi4EEcv+0x7c>
  7c:	48 83 c4 20          	add    $0x20,%rsp
  80:	0f b6 c0             	movzbl %al,%eax
  83:	01 d8                	add    %ebx,%eax
  85:	5b                   	pop    %rbx
  86:	5d                   	pop    %rbp
  87:	41 5c                	pop    %r12
  89:	c3                   	retq   

Disassembly of section .text._Z3fooILi6EEcv:

0000000000000000 <_Z3fooILi6EEcv>:
   0:	41 54                	push   %r12
   2:	ba 05 00 00 00       	mov    $0x5,%edx
   7:	ec                   	in     (%dx),%al
   8:	55                   	push   %rbp
   9:	b2 07                	mov    $0x7,%dl
   b:	40 88 c5             	mov    %al,%bpl
   e:	ec                   	in     (%dx),%al
   f:	53                   	push   %rbx
  10:	41 88 c4             	mov    %al,%r12b
  13:	41 8d 1c 2c          	lea    (%r12,%rbp,1),%ebx
  17:	48 83 ec 20          	sub    $0x20,%rsp
  1b:	48 8d 04 24          	lea    (%rsp),%rax
  1f:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi
  24:	c7 04 24 06 00 00 00 	movl   $0x6,(%rsp)
  2b:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%rsp)
  32:	00 
  33:	c7 44 24 08 08 00 00 	movl   $0x8,0x8(%rsp)
  3a:	00 
  3b:	0f be db             	movsbl %bl,%ebx
  3e:	c7 44 24 0c 07 00 00 	movl   $0x7,0xc(%rsp)
  45:	00 
  46:	48 89 44 24 10       	mov    %rax,0x10(%rsp)
  4b:	c7 44 24 18 00 00 00 	movl   $0x0,0x18(%rsp)
  52:	00 
  53:	e8 00 00 00 00       	callq  58 <_Z3fooILi6EEcv+0x58>
  58:	0f b6 c0             	movzbl %al,%eax
  5b:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi
  60:	c7 44 24 18 04 00 00 	movl   $0x4,0x18(%rsp)
  67:	00 
  68:	01 c3                	add    %eax,%ebx
  6a:	48 8d 44 24 08       	lea    0x8(%rsp),%rax
  6f:	0f be db             	movsbl %bl,%ebx
  72:	48 89 44 24 10       	mov    %rax,0x10(%rsp)
  77:	e8 00 00 00 00       	callq  7c <_Z3fooILi6EEcv+0x7c>
  7c:	48 83 c4 20          	add    $0x20,%rsp
  80:	0f b6 c0             	movzbl %al,%eax
  83:	01 d8                	add    %ebx,%eax
  85:	5b                   	pop    %rbx
  86:	5d                   	pop    %rbp
  87:	41 5c                	pop    %r12
  89:	c3                   	retq   


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?


regards

-- 
MichaÅ Walenciak
gmail.com kicer86
http://kicer.sileman.net.pl
gg: 3729519


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