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]

Optimization question


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


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