problems with optimisation
Kicer
kicer86@gmail.com
Fri Dec 28 10:25:00 GMT 2012
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
More information about the Gcc-help
mailing list