aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2014-11-19 05:30:59 -0800
committerRichard Henderson <rth@gcc.gnu.org>2014-11-19 05:30:59 -0800
commitf2d3d07ee55fa52b41c1ec08e51269831961a772 (patch)
tree7cca5afeed122318032b1af7171e8154c14590df /gcc/calls.c
parentc21df29bcfc04945d3a7be6a0c6e306fc9efc505 (diff)
downloadgcc-f2d3d07ee55fa52b41c1ec08e51269831961a772.zip
gcc-f2d3d07ee55fa52b41c1ec08e51269831961a772.tar.gz
gcc-f2d3d07ee55fa52b41c1ec08e51269831961a772.tar.bz2
Allow the front-end to create calls with a static chain
And, at the same time, allow indirect calls to have a static chain. We'll always eliminate the static chain if we can prove it's unused. * calls.c (prepare_call_address): Allow decl or type for first arg. (expand_call): Pass type to prepare_call_address if no decl. * gimple-fold.c (gimple_fold_call): Eliminate the static chain if the function doesn't use it; fold it otherwise. * gimplify.c (gimplify_call_expr): Gimplify the static chain. * tree-cfg.c (verify_gimple_call): Allow a static chain on indirect function calls. From-SVN: r217770
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 7f55aaf..c64c0eb 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -197,7 +197,7 @@ static void restore_fixed_argument_area (rtx, rtx, int, int);
CALL_INSN_FUNCTION_USAGE information. */
rtx
-prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value,
+prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value,
rtx *call_fusage, int reg_parm_seen, int sibcallp)
{
/* Make a valid memory address and copy constants through pseudo-regs,
@@ -217,12 +217,13 @@ prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value,
#endif
}
- if (static_chain_value != 0)
+ if (static_chain_value != 0
+ && (TREE_CODE (fndecl_or_type) != FUNCTION_DECL
+ || DECL_STATIC_CHAIN (fndecl_or_type)))
{
rtx chain;
- gcc_assert (fndecl);
- chain = targetm.calls.static_chain (fndecl, false);
+ chain = targetm.calls.static_chain (fndecl_or_type, false);
static_chain_value = convert_memory_address (Pmode, static_chain_value);
emit_move_insn (chain, static_chain_value);
@@ -3278,8 +3279,9 @@ expand_call (tree exp, rtx target, int ignore)
}
after_args = get_last_insn ();
- funexp = prepare_call_address (fndecl, funexp, static_chain_value,
- &call_fusage, reg_parm_seen, pass == 0);
+ funexp = prepare_call_address (fndecl ? fndecl : fntype, funexp,
+ static_chain_value, &call_fusage,
+ reg_parm_seen, pass == 0);
load_register_parameters (args, num_actuals, &call_fusage, flags,
pass == 0, &sibcall_failure);