c - What is the difference between assembler generated for functions with and without returns_twice and noreturn? -


i understand noreturn should used functions expected doesn't return control caller, can't find difference in generated assembler codes. know examples generate different codes?

edit: noreturn not generate cleanup code after it.

returns_twice disables gcc optimizations.

as example, in old gcc version have laying around: tail call optimization, global common subexpression elimination, jump bypassing.

returns_twice uses calls_setjmp machinery (all around source tree):

          if (flags & ecf_returns_twice)             cfun->calls_setjmp = true; 

tco (gcc/tree-tailcall.c):

static bool suitable_for_tail_call_opt_p (void) {   [...]   /* function calls setjmp might have longjmp called      called function.  ??? should represent      in cfg needn't special cased.  */   if (cfun->calls_setjmp)     return false; 

gcse (gcc/gcse.c):

static int gcse_main (rtx f attribute_unused) {   [...]   /* not construct accurate cfg in functions call      setjmp, punt safe.  */   if (cfun->calls_setjmp)     return 0; 

jump-bypassing (gcc/gcse.c):

static int bypass_jumps (void) {   [...]   /* not construct accurate cfg in functions call      setjmp, punt safe.  */   if (cfun->calls_setjmp)     return 0; 

the function can neither pure nor const (gcc/ipa-pure-const.c):

/* check parameters of function call call_expr see if    there references in parameters not allowed    pure or const functions.  check see if either    indirect call, call outside compilation unit, or has special    attributes may effect purity.  call_expr node    entire call expression.  */  static void check_call (funct_state local, gimple call) {   [...]       /* when bad things happen bad functions, cannot const          or pure.  */       if (setjmp_call_p (callee_t))         {           local->pure_const_state = ipa_neither;           local->looping = false;         } 

the function cannot inlined (gcc/tree-inline.c):

/* callback walk_gimple_seq handle statements.  returns    non-null iff function can not inlined.  sets reason    why. */  static tree inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,                          struct walk_stmt_info *wip) {   [...]      /* cannot inline functions call setjmp.  */       if (setjmp_call_p (t))         {           inline_forbidden_reason             = g_("function %q+f can never inlined because uses setjmp");           *handled_ops_p = true;           return t;         } 

it affects register save area in function's stack frame.

example(tco):

func.c:

int func(void) {         return 0; } 

tco.c:

extern int func(void)  /*__attribute__((returns_twice))*/;  int main() {         return func(); } 

doesn't return twice:

00000000004003a0 <main>:   4003a0:       e9 0b 01 00 00          jmpq   4004b0 <func>   4003a5:       90                      nop   4003a6:       90                      nop   4003a7:       90                      nop 

returns twice:

00000000004003a0 <main>:   4003a0:       48 83 ec 08             sub    $0x8,%rsp   4003a4:       e8 17 01 00 00          callq  4004c0 <func>   4003a9:       48 83 c4 08             add    $0x8,%rsp   4003ad:       c3                      retq      4003ae:       90                      nop   4003af:       90                      nop 

Comments

Popular posts from this blog

Unable to remove the www from url on https using .htaccess -