This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos 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: mbox compiler warning fix


>>>>> "jifl" == Jonathan Larmour <jifl@jifvik.org> writes:

    jifl> Andrew Lunn wrote:
    >> Hi
    >> 
    >> This patch fixes a compiler warnings in the mbox code with
    >> recent versions of gcc.

    jifl> We should avoid this for time-sensitive code. It should be
    jifl> tagged with __attribute__((unused)) (aka
    jifl> CYGBLD_ATTRIB_UNUSED) instead. In fact all uninitialised
    jifl> variable warnings should be treated this way.

Since we now know attributes do not work for this problem, I have been
thinking about another approach.

Reminder: the basic issue is for code like Cyg_Mbox::get():

void *
Cyg_Mbox::get()
{
    void * p;
    if ( ! m.get( p ) )
        return NULL;
    return p;
}

The compiler does not know about any linkage between the m.get()
return value and the setting of p, so issues a warning that p may get
used before being set. This can be avoided by explicitly initializing
p, but that initialization adds to code size and cpu cycles without
fixing any real problem.

Instead consider the following attempt at a generic solution for this
kind of problem:

#define CYG_FAKE_USE(_a_)       \
    CYG_MACRO_START             \
    asm ( "" : "=g" ( _a_ ) );  \
    CYG_MACRO_END

void *
Cyg_Mbox::get()
{
    void * p;
    
    CYG_FAKE_USE(p) ;
    if ( ! m.get( p ) )
        return NULL;
    return p;
}

In theory this marks p as initialized by the asm, even though there is
no assembler code as such. The use of an =g output constraint means
that the compiler can use any memory or register operand, so it can
just use the current location of p irrespective of where it has been
allocated. The macro would have to be used with a bit of care: as I
understand it an asm output constraint says that the variable will be
updated by the assembler code, not that it may be updated, so the
compiler can eliminate off any previous assignments.

When building for the synthetic target CYG_FAKE_USE() silences the
compiler warnings as expected. Further, for Cyg_Mbox::get() and
Cyg_Mbox::tryget() the compiler generates exactly the same code
whether the CYG_FAKE_USE() macro is present or absent, i.e. code
generation is not affected. So far so good.

Unfortunately for Cyg_Mbox::get(cyg_tick_count timeout) the compiler
does generate different code. I have not fully analyzed what is going
on, but it looks like for some reason the compiler decides to flush a
variable to the stack instead of keeping it in a register. The net
result is bigger code, cancelling out any gains from using the
CYG_FAKE_USE() macro.

I do not have time to pursue this any further, but I thought I would
post my current findings in case somebody else wants to take this idea
further.

Bart

-- 
Bart Veer                                 eCos Configuration Architect
http://www.ecoscentric.com/               The eCos and RedBoot experts
Besuchen Sie uns vom 13.-15.02.07 auf der Embedded World 2007, Stand 11-336
Visit us at Embedded World 2007, Nürnberg, Germany, 13-15 Feb, Stand 11-336


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