This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

Re: [Patch] Remove workaround for copy_backward


Phil Edwards <phil@jaj.com> writes:

| This is a side comment unrelated to the patches proposed.
| 
| 
| On Sat, Sep 27, 2003 at 07:43:35PM +0200, Gabriel Dos Reis wrote:
| > Basically, what is happening is that the last argument (either a
| > __true_type or a __false_type) which we know is a compile-time
| > constant is "shifted" into an explicit template argument for the class
| > dispatcher, so one uses less function arguments or registers. 
| 
| Or /registers/?

Yes.

| Is the compiler really allocating registers for arguments which it knows
| are unused (because they don't have formal names)? 

well, being unnamed is insufficient for the compiler to determine that
a particular argument won't be used.  But, in the particular case
we're considering, the compiler should know that it is an object, whose
type is an empty class, passed by value that can't possibly be used in any
meaningful way that would look at its value. 

| That would suck...
| I don't know off the top of my head how to test this.

I did that some time ago my looking at the assembly generated.
You may also look at build_call, its expansions, particularly that of
EMPTY_CLASS_EXPR (which is already a kind of optimization).

I just tried with the following sample on a sparc:

    dromion% cat t.C
    struct A { };

    struct B { };

    extern void f(A, B, int);

    void g(int i)
    {
       f(A(), B(), i);
    }

    dromion% g++ -O2 -S t.C && cat 
    [...]
    _Z1gi:                                      ! void g()
    .LLFB3:
            !#PROLOGUE# 0
            save    %sp, -120, %sp
    .LLCFI0:
            !#PROLOGUE# 1
            mov     %i0, %o2                    ! move "i" to the 3rd reg
            add     %fp, -18, %o1               ! pass address-of t2 = B()
            call    _Z1f1A1Bi, 0                ! call f
            add     %fp, -17, %o0               ! pass address-of t1 = A()
            nop
            ret
            restore

As you can see, the compiler uses the first two registers to pass "A()"
and "B()" by address (on the stack) and the third register for "i".

The compiler should know, that A and B being empty classes, there is
no point in passing them (either by value or by reference), and thus
not allocating registers for them.

Use of empty classes are sufficiently common idioms in C++ so that the
middle-end and the back-ends should be aware of EMPTY_CLASS_EXPR and
optimize them appropriately.  If "C++ linkage" or "calling convention"
has any meaning, it should at least include that uses of empty
classes.

-- Gaby


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