avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Link Time Optimization vs __builtin_unreachable() and


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] Link Time Optimization vs __builtin_unreachable() and .signature?
Date: Tue, 19 Jun 2012 01:07:33 +0200
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

Bob Paddock schrieb:
With LTO all the code after __builtin_unreachable(); is gone, breaking
the project.
Code after __builtin_unreachable() is unreachable, thus not needed.
If you claim a function is noreturn but there is a code path that can reach
the end of such a function, your claim is obviously wrong, thus the warning.

Note that the compiler has no knowledge on the magic of RST.CTRL.
I don't know how the macro exactly expands, presumably it's just some
inline assembler and SFR writes. This means that code execution resumes
after the sequence, except you tell so. This is accomplished by
__builtin_unreachable. It means "I never come here, any code after here
is dead".

The issue is one of scope.  I expect the reach of __unreachable() to
be limited to the __noreturn__ function or at least the file that it
is contained in.

It's not. It affects all code after ("after" with respect to code flow)
the builtin.  If that code is not reached otherwise, it is not needed.

With LTO all code after __unreachable() in *all* files linked after it
(guessing about 30) are gone.  Does not seem correct.

Can you be more specific what you mean with "after"?

- after with respect to code flow?
- after with respect to source line?
- after with respect to link order?

I cannot reproduce this:

// foo.c

extern void __attribute__((__noreturn__)) reset2 (void);
extern void bar (char);

static void __attribute__((__noreturn__))
reset1 (void)
{
    __asm volatile ("clh; reset");
    __builtin_unreachable();
}

char volatile a;

int main (void)
{
    bar (1);
    while (1)
    {
        bar (1);
        if (a == 1) reset1();
        if (a == 2) reset2();
    }
}

// bar .c

void __attribute__((__noreturn__))
reset2 (void)
{
    __asm volatile ("seh; reset");
    __builtin_unreachable();
}

char volatile b;

void bar (char a)
{
    b = a;
}

// commands

$ avr-gcc -mmcu=atxmega16a4 foo.c -save-temps -Os -c -flto
$ avr-gcc -mmcu=atxmega16a4 bar.c -save-temps -Os -c -flto
$ avr-gcc -mmcu=atxmega16a4 foo.o bar.o -o foo.elf -Wl,-Map,foo.map -mrelax -Os -save-temps -dp -flto

// foo.elf.ltrans0.o:main

main:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
        ldi r24,lo8(1)   ;  5   movqi_insn/2    [length = 1]
        sts b.1346,r24   ;  6   movqi_insn/3    [length = 2]
        ldi r25,lo8(1)   ;  8   movqi_insn/2    [length = 1]
.L3:
        sts b.1346,r25   ;  9   movqi_insn/3    [length = 2]
        lds r24,a.1345   ;  11  movqi_insn/4    [length = 2]
        cpi r24,lo8(1)   ;  12  *cmpqi/3        [length = 1]
        brne .L2         ;  13  branch  [length = 1]
/* #APP */
 ;  8 "foo.c" 1
        clh; reset
 ;  0 "" 2
/* #NOAPP */
.L2:
        lds r24,a.1345   ;  20  movqi_insn/4    [length = 2]
        cpi r24,lo8(2)   ;  22  *cmpqi/3        [length = 1]
        brne .L3         ;  23  branch  [length = 1]
/* #APP */
 ;  4 "bar.c" 1
        seh; reset
 ;  0 "" 2
/* #NOAPP */

This is completely perfect.

If used code is thrown away: you get a linker error for
undef'd references?

If yes: Is the function in the ltrans dump?
If not: It's not needed (or you betray the compiler).

Johann







reply via email to

[Prev in Thread] Current Thread [Next in Thread]