aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/calls.cc')
-rw-r--r--gcc/calls.cc107
1 files changed, 56 insertions, 51 deletions
diff --git a/gcc/calls.cc b/gcc/calls.cc
index b3dccd8..e16190c 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -1273,11 +1273,19 @@ void
maybe_complain_about_tail_call (tree call_expr, const char *reason)
{
gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
- if (!CALL_EXPR_MUST_TAIL_CALL (call_expr))
- return;
-
- error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
- CALL_EXPR_MUST_TAIL_CALL (call_expr) = 0;
+ if (CALL_EXPR_TAILCALL (call_expr)
+ && dump_file
+ && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, ";; Cannot tail-call: %s: ", reason);
+ print_generic_expr (dump_file, call_expr, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ if (CALL_EXPR_MUST_TAIL_CALL (call_expr))
+ {
+ error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
+ CALL_EXPR_MUST_TAIL_CALL (call_expr) = 0;
+ }
}
/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
@@ -1374,6 +1382,11 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
}
}
+ bool promote_p
+ = targetm.calls.promote_prototypes (fndecl
+ ? TREE_TYPE (fndecl)
+ : fntype);
+
/* I counts args in order (to be) pushed; ARGPOS counts in order written. */
for (argpos = 0; argpos < num_actuals; i--, argpos++)
{
@@ -1383,6 +1396,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
/* Replace erroneous argument with constant zero. */
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
args[i].tree_value = integer_zero_node, type = integer_type_node;
+ else if (promote_p
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ type = integer_type_node;
/* If TYPE is a transparent union or record, pass things the way
we would pass the first field of the union or record. We have
@@ -1447,10 +1464,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
if (!call_from_thunk_p && DECL_P (base) && !TREE_STATIC (base))
{
*may_tailcall = false;
- maybe_complain_about_tail_call (exp,
- _("a callee-copied argument is"
- " stored in the current"
- " function's frame"));
+ maybe_complain_about_tail_call (exp, _("a callee-copied "
+ "argument is stored "
+ "in the current "
+ "function's frame"));
}
args[i].tree_value = build_fold_addr_expr_loc (loc,
@@ -2534,10 +2551,9 @@ can_implement_as_sibling_call_p (tree exp,
if (!targetm.have_sibcall_epilogue ()
&& !targetm.emit_epilogue_for_sibcall)
{
- maybe_complain_about_tail_call
- (exp,
- _("machine description does not have"
- " a sibcall_epilogue instruction pattern"));
+ maybe_complain_about_tail_call (exp, _("machine description does not "
+ "have a sibcall_epilogue "
+ "instruction pattern"));
return false;
}
@@ -2555,9 +2571,8 @@ can_implement_as_sibling_call_p (tree exp,
into a sibcall. */
if (!targetm.function_ok_for_sibcall (fndecl, exp))
{
- maybe_complain_about_tail_call (exp,
- _("target is not able to optimize the"
- " call into a sibling call"));
+ maybe_complain_about_tail_call (exp, _("target is not able to optimize "
+ "the call into a sibling call"));
return false;
}
@@ -2606,9 +2621,8 @@ can_implement_as_sibling_call_p (tree exp,
if (maybe_gt (args_size.constant,
crtl->args.size - crtl->args.pretend_args_size))
{
- maybe_complain_about_tail_call (exp,
- _("callee required more stack slots"
- " than the caller"));
+ maybe_complain_about_tail_call (exp, _("callee required more stack "
+ "slots than the caller"));
return false;
}
@@ -2621,9 +2635,8 @@ can_implement_as_sibling_call_p (tree exp,
(current_function_decl),
crtl->args.size)))
{
- maybe_complain_about_tail_call (exp,
- _("inconsistent number of"
- " popped arguments"));
+ maybe_complain_about_tail_call (exp, _("inconsistent number of"
+ " popped arguments"));
return false;
}
@@ -2685,7 +2698,7 @@ expand_call (tree exp, rtx target, int ignore)
so this shouldn't really happen unless the
the musttail pass gave up walking before finding the call. */
if (!try_tail_call)
- maybe_complain_about_tail_call (exp, _("other reasons"));
+ maybe_complain_about_tail_call (exp, _("other reasons"));
int pass;
/* Register in which non-BLKmode value will be returned,
@@ -3092,8 +3105,9 @@ expand_call (tree exp, rtx target, int ignore)
if (MEM_P (*iter))
{
try_tail_call = 0;
- maybe_complain_about_tail_call (exp,
- _("hidden string length argument passed on stack"));
+ maybe_complain_about_tail_call (exp, _("hidden string length "
+ "argument passed on "
+ "stack"));
break;
}
}
@@ -3140,10 +3154,9 @@ expand_call (tree exp, rtx target, int ignore)
|| partial_subreg_p (caller_mode, callee_mode)))))
{
try_tail_call = 0;
- maybe_complain_about_tail_call (exp,
- _("caller and callee disagree in"
- " promotion of function"
- " return value"));
+ maybe_complain_about_tail_call (exp, _("caller and callee disagree "
+ "in promotion of function "
+ "return value"));
}
}
@@ -3723,19 +3736,16 @@ expand_call (tree exp, rtx target, int ignore)
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags, args_so_far);
- if (flag_ipa_ra)
+ rtx_call_insn *last;
+ rtx datum = NULL_RTX;
+ if (fndecl != NULL_TREE)
{
- rtx_call_insn *last;
- rtx datum = NULL_RTX;
- if (fndecl != NULL_TREE)
- {
- datum = XEXP (DECL_RTL (fndecl), 0);
- gcc_assert (datum != NULL_RTX
- && GET_CODE (datum) == SYMBOL_REF);
- }
- last = last_call_insn ();
- add_reg_note (last, REG_CALL_DECL, datum);
+ datum = XEXP (DECL_RTL (fndecl), 0);
+ gcc_assert (datum != NULL_RTX
+ && GET_CODE (datum) == SYMBOL_REF);
}
+ last = last_call_insn ();
+ add_reg_note (last, REG_CALL_DECL, datum);
/* If the call setup or the call itself overlaps with anything
of the argument setup we probably clobbered our call address.
@@ -3777,8 +3787,7 @@ expand_call (tree exp, rtx target, int ignore)
add_reg_note (last, REG_NOALIAS, temp);
/* Write out the sequence. */
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_insn (insns);
valreg = temp;
}
@@ -3994,8 +4003,7 @@ expand_call (tree exp, rtx target, int ignore)
targetm.calls.end_call_args (args_so_far);
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
if (pass == 0)
{
@@ -4793,13 +4801,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
struct_value_size, call_cookie, valreg,
old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
- if (flag_ipa_ra)
- {
- rtx datum = orgfun;
- gcc_assert (GET_CODE (datum) == SYMBOL_REF);
- rtx_call_insn *last = last_call_insn ();
- add_reg_note (last, REG_CALL_DECL, datum);
- }
+ rtx datum = orgfun;
+ gcc_assert (GET_CODE (datum) == SYMBOL_REF);
+ rtx_call_insn *last = last_call_insn ();
+ add_reg_note (last, REG_CALL_DECL, datum);
/* Right-shift returned value if necessary. */
if (!pcc_struct_value