aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/calls.cc')
-rw-r--r--gcc/calls.cc22
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;
}