public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* noreturn function attribute and ret asm instruction
@ 2003-08-23 16:33 Kristis Makris
  2003-08-25 20:30 ` Jim Wilson
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-08-23 16:33 UTC (permalink / raw)
  To: gcc-bugs

Hello, 

I have also send this to gcc-help but got no response.

$ gcc --version 
gcc (GCC) 3.3 (Debian) 

I am trying to create a C function that does not return and I have 
implemented it like this: 

void __attribute__((always_inline)) __attribute__((noreturn))
dynreplace_branch(void *address) 
{ 
  __asm__ __volatile__ ( "jmp *%0" 
: /* output */ 
: "m" (address) /* input */ 
); 
} 


This produces the following asm code: 

$ objdump -d -z -r arch/i386/kernel/dynreplace.o 

arch/i386/kernel/dynreplace.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <dynreplace_branch>: 
   0:   ff 64 24 04             jmp    *0x4(%esp,1) 
   4:   c3                      ret    

The problem I have with this is the ret instruction that gets generated,
while I'm trying to do just a jmp. 

Is a #defined version of the function or simply writing this in assembly
instead of C the only way I can produce only the jmp without the ret ? I
would assume noreturn would imply that no ret instruction would be
emmitted but that does not seem to be the case. I was able to get the
just the jump when I #define the function as:


#define dynreplace_branch(address) \
  __asm__ __volatile__ ( "jmp *%0" \
                         : /* output */ \
                         : "m" (address) /* input */ \
                         );

But then I lose the type checking feature if I use a macro, plus I am
stuck havind to add "\"s at the end of each line so I can't write too
much code in a legible way, plus I can't really memcpy during runtime
the code produced by this macro, the way I would if this was a function.
Conceptually I should be able to just define the function in C. Is this
noreturn behaviour expected ? Shouldn't the "ret" be missing from the
code produced here (is this a bug)? Is there another attribute that
won't produce that "ret" instruction ?

Thanks, 
Kristis



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-08-23 16:33 noreturn function attribute and ret asm instruction Kristis Makris
@ 2003-08-25 20:30 ` Jim Wilson
  2003-08-26  6:51   ` Kristis Makris
  0 siblings, 1 reply; 22+ messages in thread
From: Jim Wilson @ 2003-08-25 20:30 UTC (permalink / raw)
  To: Kristis Makris; +Cc: gcc-bugs

An extended asm isn't allowed to change the flow of control.  So this is 
an invalid asm.

noreturn does not suppress the ret instruction at the end of a function. 
   What it does is tell the compiler that if we call a function defined 
as noreturn, then the call won't return.  There is no function call at 
the end of your function, so it can't be a noreturn function.  If you 
compile with -Wall, it will tell you this.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-08-25 20:30 ` Jim Wilson
@ 2003-08-26  6:51   ` Kristis Makris
  2003-08-26  7:05     ` Zack Weinberg
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-08-26  6:51 UTC (permalink / raw)
  To: Jim Wilson; +Cc: gcc-bugs

Thanks for the reply and your insight Jim. I have some questions though.

On Mon, 2003-08-25 at 13:30, Jim Wilson wrote:
> An extended asm isn't allowed to change the flow of control.  So this is 
> an invalid asm.

Why is it not allowed to change the flow of control ? Define "invalid".
I tried using this asm syntax in a function and I was able to change the
flow of control.

> noreturn does not suppress the ret instruction at the end of a function. 

Why not ? Shouldn't it ? Of what use is that extra "ret" then ? 

>    What it does is tell the compiler that if we call a function defined 
> as noreturn, then the call won't return.  There is no function call at

What does "the call won't return" really mean then ?

The question I have is what happens to the stack when function A makes a
call to function B (which is flagged noreturn) ? Is a return address
pushed on the stack ? I would assume one should not, since the function
called (B) will not return, thus this would not be a "call" but a "jmp".
And then the extra "ret" would be of no use if the function won't
return; and it gets in the way in what I'm trying to do. Setting a stack
frame with "enter" and having to "leave" at the end of the function is
something I'm trying to avoid also.
 
> the end of your function, so it can't be a noreturn function.  If you 
> compile with -Wall, it will tell you this.

There is no call at the end of my noreturn function, but I am trying to
call this noreturn function from another noreturn function.

In effect, what I am trying to accomplish is write a C function that can
be called without pushing a return address on the stack. And that can be
accomplished if the function is either jmp'ed to, or flagged to be
inlined. Inlined won't work for me as I need to be able to memcpy during
runtime the code generated for this function, and that may be impossible
to do if the function is inlined and further optimized differently per
case where it is inlined.

Perhaps I'm looking at the wrong direction. How do I generate "a chunk
of code" with no ret instruction at the end if I want to write that code
in C ?

Regardless, gcc should be able to see that a function flagged as
noreturn does not return if there's a jmp instruction in it that
branches somewhere else. Try running this, uncommenting only one
function at the time from main. None of A,B,C are flagged to return, but
you only get warnings for A and B when you compile it. There's no ret
instruction generated in funC, only because it calls exit(), which gcc
knows about as mentioned in the info page. How can I accomplish the same
effect when trying to write a function of my own ?

Also why does funD crash ? If funD crashes because it is flagged as
noreturn while it does return, then why is only a warning reported here
by gcc instead of an error ?


/* $ gcc -g -Wall test3.c
test3.c: In function `funA':
test3.c:14: warning: `noreturn' function does return
test3.c: In function `funB':
test3.c:23: warning: `noreturn' function does return
test3.c: In function `funD':
test3.c:40: warning: `noreturn' function does return
   $ objdump -z -d -r a.out |more
*/
#include <stdio.h>
#include <stdlib.h>

void __attribute__((noreturn)) funA (void *address)
{
  printf("funA\n");
  __asm__ __volatile__ ( "jmp *%0" 
			 : /* output */ 
			 : "m" (address) /* input */ 
			 );
}

void __attribute__((noreturn)) funB(void)
{
  printf("funB\n");
  __asm__ __volatile__ ( "jmp *%0" 
			 : /* output */ 
			 : "m" (&funB) /* input */ 
			 );
}

void __attribute__((noreturn)) funC(void)
{
  printf("funC\n");
  exit(0);
}

void funD_help()
{
  printf("funD_help\n");
}

void __attribute__((noreturn)) funD(void)
{
  printf("funD\n");
  funD_help();
}

void funE_help()
{
  printf("funE_help\n");
}

void funE()
{
  printf("funE\n");
  funE_help();
}

int main()
{
  /* This should be an infinite loop */
  //funA(&main);

  /* And so should this */
  //funB();

  /* This is not */
  //funC();

  /* Nor is this; this should not be an warning, but an error. It
crashes. */
  //funD();

  /* This is a regular function */
  //funE();
}



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-08-26  6:51   ` Kristis Makris
@ 2003-08-26  7:05     ` Zack Weinberg
  2003-08-30  0:09       ` Kristis Makris
  0 siblings, 1 reply; 22+ messages in thread
From: Zack Weinberg @ 2003-08-26  7:05 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Jim Wilson, gcc-bugs

Kristis Makris <kristis.makris@asu.edu> writes:

> Thanks for the reply and your insight Jim. I have some questions though.
>
> On Mon, 2003-08-25 at 13:30, Jim Wilson wrote:
>> An extended asm isn't allowed to change the flow of control.  So this is 
>> an invalid asm.
>
> Why is it not allowed to change the flow of control ? Define "invalid".
> I tried using this asm syntax in a function and I was able to change the
> flow of control.

The optimizer does not know what you are doing, and *will*
mis-optimize the function.

It is currently impossible to do what you want.  (I once proposed that
clobbering "pc" in an asm() should indicate that control did not pass
beyond that asm(), but it got shot down.)

>> noreturn does not suppress the ret instruction at the end of a function. 
>
> Why not ?

Because attribute noreturn has no effect on code generation of the
function it is applied to.  Its effect is to allow better optimization
of the places where that function is called, and that's all it does.

> The question I have is what happens to the stack when function A makes a
> call to function B (which is flagged noreturn) ? Is a return address
> pushed on the stack ? I would assume one should not, since the function
> called (B) will not return, thus this would not be a "call" but a "jmp".

Depending on the platform ABI and the skill of the optimizer, the
instruction generated may be either "jmp" or "call"; you cannot count
on either.

> In effect, what I am trying to accomplish is write a C function that can
> be called without pushing a return address on the stack. And that can be
> accomplished if the function is either jmp'ed to, or flagged to be
> inlined. Inlined won't work for me as I need to be able to memcpy during
> runtime the code generated for this function, and that may be impossible
> to do if the function is inlined and further optimized differently per
> case where it is inlined.

It begins to sound like you should be writing raw assembly language in
an .s file.

> Perhaps I'm looking at the wrong direction. How do I generate "a chunk
> of code" with no ret instruction at the end if I want to write that code
> in C ?

There is no way to do this for arbitrary code.  The optimizer *may*
notice that the epilogue is unreachable and not bother generating code
for it but you cannot rely on that.

> Regardless, gcc should be able to see that a function flagged as
> noreturn does not return if there's a jmp instruction in it that
> branches somewhere else.

gcc does not know what your asm() statement means, other than what you
tell it with input and output constraints and clobbers.

zw


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-08-26  7:05     ` Zack Weinberg
@ 2003-08-30  0:09       ` Kristis Makris
  2003-09-02 21:17         ` Jim Wilson
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-08-30  0:09 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Jim Wilson, gcc-bugs

Thanks for the reply Zack.

> It is currently impossible to do what you want.  (I once proposed that
> clobbering "pc" in an asm() should indicate that control did not pass
> beyond that asm(), but it got shot down.)

Interesting.

> Because attribute noreturn has no effect on code generation of the
> function it is applied to.  Its effect is to allow better optimization
> of the places where that function is called, and that's all it does.

> It begins to sound like you should be writing raw assembly language in
> an .s file.

That's what I ended up doing. Still, conceptually one shouldn't have to
do that. I should be able to generate "a chunk of code" by writing that
in C, with no "ret" at the end as if it where a function. 

Would it be acceptable if an extra function attribute was added that
allowed generation of code without assuming that it is a function (hence
no "ret" at the end) ? How do gcc developers feel about that ? Is this
something I should add in bugzilla as a feature request or should I
forward it to a different list ?

Thanks,
Kristis



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-08-30  0:09       ` Kristis Makris
@ 2003-09-02 21:17         ` Jim Wilson
  2003-09-02 21:57           ` Zack Weinberg
  2003-10-01  5:59           ` Hans-Peter Nilsson
  0 siblings, 2 replies; 22+ messages in thread
From: Jim Wilson @ 2003-09-02 21:17 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Zack Weinberg, gcc-bugs

On Fri, 2003-08-29 at 17:09, Kristis Makris wrote:
> Would it be acceptable if an extra function attribute was added that
> allowed generation of code without assuming that it is a function (hence
> no "ret" at the end) ?

I don't see any point to this.  The compiler optimizes away the ret if
control flow does not reach the end of the function.  There is no need
for a function attribute for this.

The real problem here is that we have no support for asms that change
flow of control.  Adding a function attribute to suppress the ret does
not fix this.  Letting asms change flow of control would require syntax
and semantic changes.  This would be a major change, and it isn't clear
if it is a good idea.  It might impede optimization so much that it
hurts more than it helps.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-02 21:17         ` Jim Wilson
@ 2003-09-02 21:57           ` Zack Weinberg
  2003-09-02 22:02             ` Joseph S. Myers
                               ` (2 more replies)
  2003-10-01  5:59           ` Hans-Peter Nilsson
  1 sibling, 3 replies; 22+ messages in thread
From: Zack Weinberg @ 2003-09-02 21:57 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Kristis Makris, gcc-bugs

Jim Wilson <wilson@tuliptree.org> writes:

> On Fri, 2003-08-29 at 17:09, Kristis Makris wrote:
>> Would it be acceptable if an extra function attribute was added that
>> allowed generation of code without assuming that it is a function (hence
>> no "ret" at the end) ?
>
> I don't see any point to this.  The compiler optimizes away the ret if
> control flow does not reach the end of the function.  There is no need
> for a function attribute for this.
>
> The real problem here is that we have no support for asms that change
> flow of control.  Adding a function attribute to suppress the ret does
> not fix this.  Letting asms change flow of control would require syntax
> and semantic changes.  This would be a major change, and it isn't clear
> if it is a good idea.  It might impede optimization so much that it
> hurts more than it helps.

I think that the very limited concept of 'this asm() constitutes a
control barrier' could be safely and usefully added.  The canonical
example is the BUG() macro from Linux: a typical definition is

#define BUG()                           \
 __asm__ __volatile__(  "ud2\n"         \
                        "\t.word %c0\n" \
                        "\t.long %c1\n" \
                         : : "i" (__LINE__), "i" (__FILE__))

(ud2 is the i386 opcode guaranteed to raise an illegal instruction
exception.)  When used e.g. as

void foo(void) { BUG(); }

the assembly you get is

foo:
#APP
        ud2
        .word 7
        .long .LC0

#NO_APP
        ret

The 'ret' is unnecessary, control transfers from the ud2 to the
illegal instruction trap handler and never comes back.  But the
compiler doesn't know that.  The optimization benefits are more
significant in the usual case where BUG() is conditional.

My old suggestion was to express this by clobbering "pc", which
currently has no meaning.  This would require no syntax change.
The objection I remember is "use __builtin_trap()", but that is
not flexible enough to replace the above, nor is it universally
implemented.

zw


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-02 21:57           ` Zack Weinberg
@ 2003-09-02 22:02             ` Joseph S. Myers
  2003-09-03  2:19             ` Kristis Makris
  2003-09-12  1:29             ` Kristis Makris
  2 siblings, 0 replies; 22+ messages in thread
From: Joseph S. Myers @ 2003-09-02 22:02 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Jim Wilson, Kristis Makris, gcc-bugs

On Tue, 2 Sep 2003, Zack Weinberg wrote:

> The objection I remember is "use __builtin_trap()", but that is
> not flexible enough to replace the above, nor is it universally
> implemented.

How about a more general __builtin_unreached(), telling the compiler to
assume (without generating any trap for safety, so potentially allowing
more optimization) that a particular point in the code (e.g., the end of a
function here) can never be reached?

-- 
Joseph S. Myers
jsm@polyomino.org.uk


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-02 21:57           ` Zack Weinberg
  2003-09-02 22:02             ` Joseph S. Myers
@ 2003-09-03  2:19             ` Kristis Makris
  2003-09-12  1:29             ` Kristis Makris
  2 siblings, 0 replies; 22+ messages in thread
From: Kristis Makris @ 2003-09-03  2:19 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Jim Wilson, gcc-bugs

I am sorry, I obviously have no undrestanding of gcc internals. For
whatever it's worth, I have added a feature request for this in the GCC
bugzilla (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12118), with a
link that points back to this thread.

> > The real problem here is that we have no support for asms that change
> > flow of control.  Adding a function attribute to suppress the ret does

> My old suggestion was to express this by clobbering "pc", which
> currently has no meaning.  This would require no syntax change.
> The objection I remember is "use __builtin_trap()", but that is
> not flexible enough to replace the above, nor is it universally
> implemented.

I couldn't find any history on that discussion anywhere on bugzilla or
the mailing lists. Thank's for the comments though.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-02 21:57           ` Zack Weinberg
  2003-09-02 22:02             ` Joseph S. Myers
  2003-09-03  2:19             ` Kristis Makris
@ 2003-09-12  1:29             ` Kristis Makris
  2003-09-12  7:10               ` Jim Wilson
  2 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-09-12  1:29 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Jim Wilson, gcc-bugs

On Tue, 2003-09-02 at 14:56, Zack Weinberg wrote: 
> Jim Wilson <wilson@tuliptree.org> writes:
> > The real problem here is that we have no support for asms that change
> > flow of control.  Adding a function attribute to suppress the ret does
> > not fix this.  Letting asms change flow of control would require syntax
> > and semantic changes.  This would be a major change, and it isn't clear
> > if it is a good idea.  It might impede optimization so much that it
> > hurts more than it helps.

On the same note, is there any way to tell gcc that it should create
code for a function that will leave the state of the registers exactly
as it was originally when the function was entered ? Is there some
function attribute for that ? So if the caller was already using certain
registers, can the responsibility of preserving those be somehow
offloaded to the callee ? Can I generate "a chunk of code" that does not
mess with the state of the processor, just like I would if the same code
was written in asm ?

I don't know if gcc was meant not to do that by design.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-12  1:29             ` Kristis Makris
@ 2003-09-12  7:10               ` Jim Wilson
  2003-09-12 18:16                 ` Kristis Makris
  0 siblings, 1 reply; 22+ messages in thread
From: Jim Wilson @ 2003-09-12  7:10 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Zack Weinberg, gcc-bugs

On Thu, 2003-09-11 at 18:29, Kristis Makris wrote:
> On the same note, is there any way to tell gcc that it should create
> code for a function that will leave the state of the registers exactly
> as it was originally when the function was entered ?

No.  If you are trying to write assembly language code, then write
assembly language code not C code with asms.

Some targets have an "interrupt" attribute that can be used to write
functions called by interrupt handlers.  They work a bit like this, in
that they have to save/restore all of the call clobbered registers. 
This doesn't necessarily do what you want though, for instance, you will
get a return from interrupt instruction at the end of the function
instead of a normal return instruction.  And your target may not have
support for this attribute.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-12  7:10               ` Jim Wilson
@ 2003-09-12 18:16                 ` Kristis Makris
  2003-09-13  3:41                   ` Jim Wilson
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-09-12 18:16 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Zack Weinberg, gcc-bugs

> No.  If you are trying to write assembly language code, then write
> assembly language code not C code with asms.

I am not trying to inject asms in C code this time, even though I see
your point given that the optimizer does not know if the flow was
changed by an asm.

This time I am referring to this example:

int a = 8;
int c = 5;

void test3()
{
  c = a + c;
}

Dump of assembler code for function test3:
0x80483cc <test3>:      push   %ebp
0x80483cd <test3+1>:    mov    %esp,%ebp
0x80483cf <test3+3>:    mov    0x80494f4,%eax
0x80483d4 <test3+8>:    add    %eax,0x80494f8
0x80483da <test3+14>:   leave  
0x80483db <test3+15>:   ret    
End of assembler dump.


Here %eax is used and it's previous value is not preserved. Again
conceptually I should be able to write in a high-level language such as
C with the option to tell gcc to preserve the registers it will end up
using on its own. Agreed, writing intuitively in asm would solve the
problem of preserving the registers, but not the problem of trying to
write in a high-level language.

Should this feature be implemented for gcc, would it be accepted ? What
would be the best way to implement it ? As a function attribute ?

Please excuse once again my inexperience with gcc internals.

> Some targets have an "interrupt" attribute that can be used to write

I am familiar with it. 

> get a return from interrupt instruction at the end of the function

And this is their only pitfall. Otherwise the state of clobbered
registers is preserved. Well pointed out.

Thanks,
Kristis



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-12 18:16                 ` Kristis Makris
@ 2003-09-13  3:41                   ` Jim Wilson
  2003-09-14 17:31                     ` Kristis Makris
  0 siblings, 1 reply; 22+ messages in thread
From: Jim Wilson @ 2003-09-13  3:41 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Zack Weinberg, gcc-bugs

On Fri, 2003-09-12 at 10:14, Kristis Makris wrote:
> Here %eax is used and it's previous value is not preserved. Again
> conceptually I should be able to write in a high-level language such as
> C with the option to tell gcc to preserve the registers it will end up
> using on its own.

You haven't given any justification for why you want this feature.  We
aren't going to add features that have no known use.  Maybe if you
explained what you are trying to do, we could offer a better
alternative, or give reasons why what you want to do won't work.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-13  3:41                   ` Jim Wilson
@ 2003-09-14 17:31                     ` Kristis Makris
  2003-09-14 20:22                       ` Jim Wilson
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-09-14 17:31 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Zack Weinberg, gcc-bugs

On Fri, 2003-09-12 at 18:25, Jim Wilson wrote:
> On Fri, 2003-09-12 at 10:14, Kristis Makris wrote:
> > Here %eax is used and it's previous value is not preserved. Again
> > conceptually I should be able to write in a high-level language such as
> > C with the option to tell gcc to preserve the registers it will end up
> > using on its own.
> 
> You haven't given any justification for why you want this feature.  We
> aren't going to add features that have no known use.  Maybe if you
> explained what you are trying to do, we could offer a better
> alternative, or give reasons why what you want to do won't work.

I'm sorry Jim. Let me provide some more information.

I am working on a framework with which functions that were compiled for
the linux kernel can be replaced with newer revisions of them during
runtime. As part of the redirection mechanism of a function call, the
original function image is overwritten with a trampoline that jumps to a
separate portion in memory (the handler of the redirection) where after
some bookeeping work a jump to the newer revision of the function is
made. At the time the newer function is jumped to, the processor state
should be the same as when the original version of the function was
called, with all the parameters it might have been passed on the stack,
and any register values unchanged. Conceptually I should be able to
write a complex handler in a high-level language without explicit calls
to the SAVE_ALL and RESTORE_ALL macros in linux that push *all* the
registers instead of only the ones that might be clobbered. The compiler
should be able to generate such C code. The handler itself is
dynamically genarated and customized per function image for better
performance, so I memcpy a handler template currently written in asm as
the actual handler of a function after replacing in it some jump and
variable addresses used. As more functionality needs to be added in the
handler (or conditionally compiled in it), the asm implementation
becomes uneccessarily complex, for what could be a more readable
implementation in C.

It just appears to me that one should never have to write anything in
assembly, unless using architecture dependent features such as using the
%cr2 register in x86 for paging. If I'm trying to add up two numbers or
grab a lock, I should be able to write that in C. I see this as a useful
feature, but gcc developers might look at this from a different angle. I
welcome your feedback.




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-14 17:31                     ` Kristis Makris
@ 2003-09-14 20:22                       ` Jim Wilson
  2003-09-15 18:21                         ` Kristis Makris
  0 siblings, 1 reply; 22+ messages in thread
From: Jim Wilson @ 2003-09-14 20:22 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Zack Weinberg, gcc-bugs

On Sun, 2003-09-14 at 10:18, Kristis Makris wrote:
> I am working on a framework with which functions that were compiled for
> the linux kernel can be replaced with newer revisions of them during
> runtime.

OK.  I see what you are trying to do.  This is outside the scope of the
ISO C language standard, and all ABI standards I know of.  However, it
does sound like a reasonable thing for the linux developers to ask from
gcc.

There will need to be some definition work here.  Do you really need all
registers preserved?  The ABI only requires that call-saved registers
and function arguments be preserved.  (And for gcc, global register
variables are preserved.)  It should be safe to clobber any
call-clobbered register, unless perhaps linux is passing info via them
that is hidden to the compiler.  Letting gcc clobber call-clobbered
registers means a bit better performance in the handler.  Preserving
call-clobbered registers means you get the same ABI as an interrupt
handler, which means we can perhaps share some code.  Instead of having
an rte at the end of the function, we would have essentially a sibling
(tail) call.

There will be implementation work needed for all targets that are
supported by linux.  I am not volunteering for this work.  This is
probably the killer part, because you would have to find a volunteer to
do all of this work.  You would need someone familiar with each target,
or willing to learn each target, which makes this quite a bit of work.

The Objective C language needs a somewhat similar feature.  It is
implemented via builtin_save_args and builtin_apply_all.  These are
inefficient features that save and restore lots of register arguments
and stack arguments.  Perhaps this same feature could be used to improve
Objective C support.  I am not familiar enough with Objective C to know
for sure whether this makes any sense though.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-14 20:22                       ` Jim Wilson
@ 2003-09-15 18:21                         ` Kristis Makris
  2003-09-15 20:15                           ` Jim Wilson
  0 siblings, 1 reply; 22+ messages in thread
From: Kristis Makris @ 2003-09-15 18:21 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Zack Weinberg, gcc-bugs

I just formally requested this feature in bugzilla:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12284

> OK.  I see what you are trying to do.  This is outside the scope of the
> ISO C language standard, and all ABI standards I know of.  However, it
> does sound like a reasonable thing for the linux developers to ask from
> gcc.

Its just me working on this framework right now...but I see value in
such a gcc feature.

> There will need to be some definition work here.  Do you really need all
> registers preserved?  The ABI only requires that call-saved registers

Absolutely not. In my naive terminology, I need a "preserve_as_needed"
function attribute to tell gcc to preserve only the registers it will
decide to use as temporary placeholders (which only gcc will know which
those are). I can see use for a "preserve_all" attribute as well though.

If you read the bug entry in Bugzilla, Andrew Pinska recommended use of
the -fcall-used-<register> flag. It didn't appear to me as the same
feature I'm asking. After reading this:

http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Code-Gen-Options.html#Code%20Gen%20Options

it appeared to be the opposite actually. Maybe he meant
-fcall-save-register, but still I don't know which register gcc will use
internally.

> and function arguments be preserved.  (And for gcc, global register
> variables are preserved.)  It should be safe to clobber any
> call-clobbered register, unless perhaps linux is passing info via them
> that is hidden to the compiler.  Letting gcc clobber call-clobbered
> registers means a bit better performance in the handler.  Preserving
> call-clobbered registers means you get the same ABI as an interrupt
> handler, which means we can perhaps share some code.  Instead of having
> an rte at the end of the function, we would have essentially a sibling
> (tail) call.
> 
> There will be implementation work needed for all targets that are
> supported by linux.  I am not volunteering for this work.  This is
> probably the killer part, because you would have to find a volunteer to
> do all of this work.  You would need someone familiar with each target,
> or willing to learn each target, which makes this quite a bit of work.

I'm willing to have a look if pointed to where in the sources target
specific work should be done.

> The Objective C language needs a somewhat similar feature.  It is
> implemented via builtin_save_args and builtin_apply_all.  These are
> inefficient features that save and restore lots of register arguments
> and stack arguments.  Perhaps this same feature could be used to improve
> Objective C support.  I am not familiar enough with Objective C to know
> for sure whether this makes any sense though.

I'm clueless when it comes to gcc internal but wouldn't mind having a
look. Thanks for the insight Jim.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-15 18:21                         ` Kristis Makris
@ 2003-09-15 20:15                           ` Jim Wilson
  0 siblings, 0 replies; 22+ messages in thread
From: Jim Wilson @ 2003-09-15 20:15 UTC (permalink / raw)
  To: Kristis Makris; +Cc: Zack Weinberg, gcc-bugs

On Mon, 2003-09-15 at 10:46, Kristis Makris wrote:
> I'm willing to have a look if pointed to where in the sources target
> specific work should be done.

It is the target specific prologue/epilogue code that would need
modifying.  There are different ways that this code can be written, but
if you search for prologue in the target directory you should be able to
find it.  It is common to have an expand_prologue function that calls a
compute_frame_size function which computes which registers need saving. 
This would have to save different registers in your case.  Looking at
targets that already support an interrupt attribute should be
instructive.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-09-02 21:17         ` Jim Wilson
  2003-09-02 21:57           ` Zack Weinberg
@ 2003-10-01  5:59           ` Hans-Peter Nilsson
  2003-10-01  7:00             ` Zack Weinberg
  1 sibling, 1 reply; 22+ messages in thread
From: Hans-Peter Nilsson @ 2003-10-01  5:59 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Kristis Makris, Zack Weinberg, gcc-bugs

On 2 Sep 2003, Jim Wilson wrote:
> The real problem here is that we have no support for asms that change
> flow of control.  Adding a function attribute to suppress the ret does
> not fix this.  Letting asms change flow of control would require syntax
> and semantic changes.  This would be a major change, and it isn't clear
> if it is a good idea.  It might impede optimization so much that it
> hurts more than it helps.

Though an attribute on the asm would be simpler syntax-wise,
and without optimization impediments when it's not used, no?

 __asm__ ("xyzzy") __attribute__ ((__noreturn__));

Using an asm to terminate a function is common in kernel-like
code so the request seems reasonable.  (But still not trivial to
implement, flow-wise.)

brgds, H-P


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-10-01  5:59           ` Hans-Peter Nilsson
@ 2003-10-01  7:00             ` Zack Weinberg
  2003-10-01  7:26               ` Hans-Peter Nilsson
  2003-10-01 16:21               ` Richard Henderson
  0 siblings, 2 replies; 22+ messages in thread
From: Zack Weinberg @ 2003-10-01  7:00 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: Jim Wilson, Kristis Makris, gcc-bugs

Hans-Peter Nilsson <hp@bitrange.com> writes:

> On 2 Sep 2003, Jim Wilson wrote:
>> The real problem here is that we have no support for asms that change
>> flow of control.  Adding a function attribute to suppress the ret does
>> not fix this.  Letting asms change flow of control would require syntax
>> and semantic changes.  This would be a major change, and it isn't clear
>> if it is a good idea.  It might impede optimization so much that it
>> hurts more than it helps.
>
> Though an attribute on the asm would be simpler syntax-wise,

I dunno.  Attribute handling is one of the hairiest parts of the
syntax.

> Using an asm to terminate a function is common in kernel-like
> code so the request seems reasonable.  (But still not trivial to
> implement, flow-wise.)

It really is trivial at the RTL level - I know, I implemented it.
(You just emit a BARRIER insn right after the ASM_OPERANDS insn.)
It might be harder at the tree level; I'm not sure how noreturn is
being represented in tree-ssa.

zw


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-10-01  7:00             ` Zack Weinberg
@ 2003-10-01  7:26               ` Hans-Peter Nilsson
  2003-10-01 16:21               ` Richard Henderson
  1 sibling, 0 replies; 22+ messages in thread
From: Hans-Peter Nilsson @ 2003-10-01  7:26 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Jim Wilson, Kristis Makris, gcc-bugs

On Wed, 1 Oct 2003, Zack Weinberg wrote:
> Hans-Peter Nilsson <hp@bitrange.com> writes:
> > Though an attribute on the asm would be simpler syntax-wise,
>
> I dunno.  Attribute handling is one of the hairiest parts of the
> syntax.

For variables and functions, but surely not for statement asms?
For the "stmt" rule, there's nothing between ')' and ';', so we
can't intrude on previous syntax.

> > Using an asm to terminate a function is common in kernel-like
> > code so the request seems reasonable.  (But still not trivial to
> > implement, flow-wise.)
>
> It really is trivial at the RTL level - I know, I implemented it.
> (You just emit a BARRIER insn right after the ASM_OPERANDS insn.)

Ah, right you are.  Cool.  Good news.  Maybe this would be a
nice beginner's project?  Perhaps I can volunteer someone to
actually do it.

> It might be harder at the tree level; I'm not sure how noreturn is
> being represented in tree-ssa.

Bah! :-)

(Seriously, this will have to be considered before such a change.)

brgds, H-P


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-10-01  7:00             ` Zack Weinberg
  2003-10-01  7:26               ` Hans-Peter Nilsson
@ 2003-10-01 16:21               ` Richard Henderson
  2003-10-01 17:57                 ` Zack Weinberg
  1 sibling, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2003-10-01 16:21 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Hans-Peter Nilsson, Jim Wilson, Kristis Makris, gcc-bugs

On Wed, Oct 01, 2003 at 12:00:22AM -0700, Zack Weinberg wrote:
> It might be harder at the tree level; I'm not sure how noreturn is
> being represented in tree-ssa.

Only in the CFG.  If there's no edge to exit, then there's
no flow to exit.  You'd have to find a way to represent the
noreturn attribute in the ASM_EXPR so that it survives until
the CFG is created.


r~


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: noreturn function attribute and ret asm instruction
  2003-10-01 16:21               ` Richard Henderson
@ 2003-10-01 17:57                 ` Zack Weinberg
  0 siblings, 0 replies; 22+ messages in thread
From: Zack Weinberg @ 2003-10-01 17:57 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Hans-Peter Nilsson, Jim Wilson, Kristis Makris, gcc-bugs

Richard Henderson <rth@redhat.com> writes:

> On Wed, Oct 01, 2003 at 12:00:22AM -0700, Zack Weinberg wrote:
>> It might be harder at the tree level; I'm not sure how noreturn is
>> being represented in tree-ssa.
>
> Only in the CFG.  If there's no edge to exit, then there's
> no flow to exit.  You'd have to find a way to represent the
> noreturn attribute in the ASM_EXPR so that it survives until
> the CFG is created.

In the original implementation of this, back in 2000
[http://gcc.gnu.org/ml/gcc-patches/2000-01/msg00190.html]
it was done by putting "pc" in the clobbers list, which should be
preserved fine; one would need to make the CFG creator aware of this
convention.

zw


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2003-10-01 17:57 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-23 16:33 noreturn function attribute and ret asm instruction Kristis Makris
2003-08-25 20:30 ` Jim Wilson
2003-08-26  6:51   ` Kristis Makris
2003-08-26  7:05     ` Zack Weinberg
2003-08-30  0:09       ` Kristis Makris
2003-09-02 21:17         ` Jim Wilson
2003-09-02 21:57           ` Zack Weinberg
2003-09-02 22:02             ` Joseph S. Myers
2003-09-03  2:19             ` Kristis Makris
2003-09-12  1:29             ` Kristis Makris
2003-09-12  7:10               ` Jim Wilson
2003-09-12 18:16                 ` Kristis Makris
2003-09-13  3:41                   ` Jim Wilson
2003-09-14 17:31                     ` Kristis Makris
2003-09-14 20:22                       ` Jim Wilson
2003-09-15 18:21                         ` Kristis Makris
2003-09-15 20:15                           ` Jim Wilson
2003-10-01  5:59           ` Hans-Peter Nilsson
2003-10-01  7:00             ` Zack Weinberg
2003-10-01  7:26               ` Hans-Peter Nilsson
2003-10-01 16:21               ` Richard Henderson
2003-10-01 17:57                 ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).