This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Optimization question
- From: "Piotr Wyderski" <piotr dot wyderski at wp dot pl>
- To: <gcc at gcc dot gnu dot org>
- Date: Sun, 8 Aug 2004 15:53:10 +0200
- Subject: Optimization question
- Organization: Faculty of Computer Science, University of Wroclaw
Hello,
I've implemented a flexible generic list (in this example it's
unidirectional), below are some important snippets:
// ----------------8<---------------
template <typename traits> unsigned int list<traits>::length() const
throw() {
// Compute the number of items in the list
unsigned int len = 0;
for(iterator i = get_head(); i.is_valid(); ++i)
++len;
return len;
}
template <typename traits> class iterator {
[...]
// Define basic types
typedef typename traits::object_type object_type;
// Current object
object_type* m_Object;
iterator& operator ++() {
m_Object = traits::get_next(m_Object);
return *this;
}
bool is_valid() const throw() {
return (m_Object != NULL);
}
}
template <typename S> struct simple_traits<S,false> : public
list_traits_base {
[...]
BASE_INLINE static object_type* get_next(object_type* const p) {
return p->m_Next;
}
};
BASE_INLINE is a portable wrapper for __attribute__((__always_inline__)).
// ----------------8<---------------
Now, if I have a list L of some objects, GCC 3.4 .0 with options:
-O3 -funit-at-a-time -fomit-frame-pointer -fstrength-reduce
-fmerge-constants -fregmove -fmove-all-movables -freorder-blocks
-fexpensive-optimizations -fschedule-insns -fschedule-insns2
-fno-common -falign-loops=2 -falign-jumps=2 -falign-functions=4
generates the following code for
L.length();
// ----------------8<---------------
00046f90 <__ZNK4base4listIN3mdl23declaration_list_traitsEE6lengthEv>:
46f90: 83 ec 1c sub $0x1c,%esp <=== HERE
46f93: 31 d2 xor %edx,%edx
46f95: 8b 44 24 20 mov 0x20(%esp,1),%eax
46f99: 8b 00 mov (%eax),%eax
46f9b: eb 05 jmp 46fa2
<__ZNK4base4listIN3mdl23declaration_list_traitsEE6lengthEv+0x12>
46f9d: 90 nop
46f9e: 8b 40 14 mov 0x14(%eax),%eax
46fa1: 42 inc %edx
46fa2: 89 04 24 mov %eax,(%esp,1) <=== HERE
46fa5: 85 c0 test %eax,%eax
46fa7: 75 f5 jne 46f9e
<__ZNK4base4listIN3mdl23declaration_list_traitsEE6lengthEv+0xe>
46fa9: 89 d0 mov %edx,%eax
46fab: 83 c4 1c add $0x1c,%esp <=== HERE
46fae: c3 ret
// ----------------8<---------------
Why does it generate the instructions pointed to by (<=== HERE)?
The most mysterious one is at 46fa2: the value is never used.
If it were eliminated, the stack frame management code would be
useless too. Where's the source of such artifacts and how can
I avoid them?
Best regards
Piotr Wyderski