diff options
Diffstat (limited to 'gcc/calls.cc')
-rw-r--r-- | gcc/calls.cc | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/gcc/calls.cc b/gcc/calls.cc index e16190c..bb8a6d0 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -2589,7 +2589,8 @@ can_implement_as_sibling_call_p (tree exp, return false; } - if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))) + if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) + && !CALL_EXPR_MUST_TAIL_CALL (exp)) { maybe_complain_about_tail_call (exp, _("volatile function type")); return false; @@ -3234,11 +3235,6 @@ expand_call (tree exp, rtx target, int ignore) if (pass) precompute_arguments (num_actuals, args); - /* Now we are about to start emitting insns that can be deleted - if a libcall is deleted. */ - if (pass && (flags & ECF_MALLOC)) - start_sequence (); - /* Check the canary value for sibcall or function which doesn't return and could throw. */ if ((pass == 0 @@ -3770,25 +3766,23 @@ expand_call (tree exp, rtx target, int ignore) valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg)); } - if (pass && (flags & ECF_MALLOC)) + /* If the return register exists, for malloc like + function calls, mark the return register with the + alignment and noalias reg note. */ + if (pass && (flags & ECF_MALLOC) && valreg) { rtx temp = gen_reg_rtx (GET_MODE (valreg)); - rtx_insn *last, *insns; + rtx_insn *last; /* The return value from a malloc-like function is a pointer. */ if (TREE_CODE (rettype) == POINTER_TYPE) mark_reg_pointer (temp, MALLOC_ABI_ALIGNMENT); - emit_move_insn (temp, valreg); + last = emit_move_insn (temp, valreg); /* The return value from a malloc-like function cannot alias anything else. */ - last = get_last_insn (); add_reg_note (last, REG_NOALIAS, temp); - - /* Write out the sequence. */ - insns = end_sequence (); - emit_insn (insns); valreg = temp; } |