aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2009-09-02 21:13:34 +0000
committerMichael Matz <matz@gcc.gnu.org>2009-09-02 21:13:34 +0000
commit28ed065ef9f3450c5c7f7fe53a3aff66c1721a6d (patch)
treedcf22487df72f428cf2839f64e5d177bc055f7b3 /gcc/calls.c
parent2f6924a4846fdb6e9fb51c5fca7d0f7e6336145d (diff)
downloadgcc-28ed065ef9f3450c5c7f7fe53a3aff66c1721a6d.zip
gcc-28ed065ef9f3450c5c7f7fe53a3aff66c1721a6d.tar.gz
gcc-28ed065ef9f3450c5c7f7fe53a3aff66c1721a6d.tar.bz2
expr.h (emit_storent_insn, [...]): Declare.
* expr.h (emit_storent_insn, expand_expr_real_1, expand_expr_real_2): Declare. * expr.c (emit_storent_insn, expand_expr_real_1, expand_expr_real_2): Export. (store_expr): Setting and evaluating dont_return_target is useless. (expand_expr_real_1, <case GOTO_EXPR, RETURN_EXPR, SWITCH_EXPR, LABEL_EXPR and ASM_EXPR>): Move to gcc_unreachable. * except.c (expand_resx_expr): Rename to ... (expand_resx_stmt): ... this. Rewrite to take gimple statement. * except.h (expand_resx_stmt): Declare. * stmt.c: Add include gimple.h (expand_asm_expr): Rename to ... (expand_asm_stmt): ... this. Rewrite to take gimple statement. (expand_case): Rewrite to take gimple statement. * tree.h (expand_asm_stmt): Declare. (expand_case): Change prototype. * Makefile.in (stmt.o): Depend on gimple.h. * builtins.c (expand_builtin_synchronize): Build gimple asm statement, not an ASM_EXPR. * cfgexpand.c (gimple_cond_pred_to_tree, set_expr_location_r, gimple_to_tree, release_stmt_tree): Remove. (expand_gimple_cond): Don't call gimple_cond_pred_to_tree or ggc_free, but hold comparison code and operands separately. Call jumpif_1 and jumpifnot_1 instead of jumpif and jumpifnot. (expand_call_stmt, expand_gimple_stmt_1, expand_gimple_stmt): New helpers. (expand_gimple_tailcall): Don't call gimple_to_tree, expand_expr_stmt, release_stmt_tree. Call expand_gimple_stmt instead. (expand_gimple_basic_block): Ditto. * calls.c (emit_call_1): Don't look at EH regions here, make fntree parameter useless. (expand_call): New local rettype for TREE_TYPE(exp), use it throughout. Remove local p, use addr instead. Don't look at EH regions here. From-SVN: r151350
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index cdb934a..2063909 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -238,7 +238,7 @@ prepare_call_address (rtx funexp, rtx static_chain_value,
denote registers used by the called function. */
static void
-emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
+emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNUSED,
tree funtype ATTRIBUTE_UNUSED,
HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
HOST_WIDE_INT rounded_stack_size,
@@ -380,15 +380,6 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
effect. */
if (ecf_flags & ECF_NOTHROW)
add_reg_note (call_insn, REG_EH_REGION, const0_rtx);
- else
- {
- int rn = lookup_expr_eh_region (fntree);
-
- /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't
- throw, which we already took care of. */
- if (rn > 0)
- add_reg_note (call_insn, REG_EH_REGION, GEN_INT (rn));
- }
if (ecf_flags & ECF_NORETURN)
add_reg_note (call_insn, REG_NORETURN, const0_rtx);
@@ -1927,6 +1918,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Data type of the function. */
tree funtype;
tree type_arg_types;
+ tree rettype;
/* Declaration of the function being called,
or 0 if the function is computed (not known by name). */
tree fndecl = 0;
@@ -2022,7 +2014,6 @@ expand_call (tree exp, rtx target, int ignore)
int old_stack_pointer_delta = 0;
rtx call_fusage;
- tree p = CALL_EXPR_FN (exp);
tree addr = CALL_EXPR_FN (exp);
int i;
/* The alignment of the stack, in bits. */
@@ -2045,15 +2036,16 @@ expand_call (tree exp, rtx target, int ignore)
}
else
{
- fntype = TREE_TYPE (TREE_TYPE (p));
+ fntype = TREE_TYPE (TREE_TYPE (addr));
flags |= flags_from_decl_or_type (fntype);
}
+ rettype = TREE_TYPE (exp);
struct_value = targetm.calls.struct_value_rtx (fntype, 0);
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
- if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ if (AGGREGATE_TYPE_P (rettype))
warning (OPT_Waggregate_return, "function call has aggregate value");
/* If the result of a non looping pure or const function call is
@@ -2063,7 +2055,7 @@ expand_call (tree exp, rtx target, int ignore)
if ((flags & (ECF_CONST | ECF_PURE))
&& (!(flags & ECF_LOOPING_CONST_OR_PURE))
&& (ignore || target == const0_rtx
- || TYPE_MODE (TREE_TYPE (exp)) == VOIDmode))
+ || TYPE_MODE (rettype) == VOIDmode))
{
bool volatilep = false;
tree arg;
@@ -2106,7 +2098,7 @@ expand_call (tree exp, rtx target, int ignore)
}
#else /* not PCC_STATIC_STRUCT_RETURN */
{
- struct_value_size = int_size_in_bytes (TREE_TYPE (exp));
+ struct_value_size = int_size_in_bytes (rettype);
if (target && MEM_P (target) && CALL_EXPR_RETURN_SLOT_OPT (exp))
structure_value_addr = XEXP (target, 0);
@@ -2115,7 +2107,7 @@ expand_call (tree exp, rtx target, int ignore)
/* For variable-sized objects, we must be called with a target
specified. If we were to allocate space on the stack here,
we would have no way of knowing when to free it. */
- rtx d = assign_temp (TREE_TYPE (exp), 0, 1, 1);
+ rtx d = assign_temp (rettype, 0, 1, 1);
mark_temp_addr_taken (d);
structure_value_addr = XEXP (d, 0);
@@ -2286,7 +2278,6 @@ expand_call (tree exp, rtx target, int ignore)
if (currently_expanding_call++ != 0
|| !flag_optimize_sibling_calls
|| args_size.var
- || lookup_expr_eh_region (exp) >= 0
|| dbg_cnt (tail_call) == false)
try_tail_call = 0;
@@ -2693,14 +2684,14 @@ expand_call (tree exp, rtx target, int ignore)
/* Figure out the register where the value, if any, will come back. */
valreg = 0;
- if (TYPE_MODE (TREE_TYPE (exp)) != VOIDmode
+ if (TYPE_MODE (rettype) != VOIDmode
&& ! structure_value_addr)
{
if (pcc_struct_value)
- valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)),
+ valreg = hard_function_value (build_pointer_type (rettype),
fndecl, NULL, (pass == 0));
else
- valreg = hard_function_value (TREE_TYPE (exp), fndecl, fntype,
+ valreg = hard_function_value (rettype, fndecl, fntype,
(pass == 0));
/* If VALREG is a PARALLEL whose first member has a zero
@@ -2865,12 +2856,12 @@ expand_call (tree exp, rtx target, int ignore)
group load/store machinery below. */
if (!structure_value_addr
&& !pcc_struct_value
- && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
- && targetm.calls.return_in_msb (TREE_TYPE (exp)))
+ && TYPE_MODE (rettype) != BLKmode
+ && targetm.calls.return_in_msb (rettype))
{
- if (shift_return_value (TYPE_MODE (TREE_TYPE (exp)), false, valreg))
+ if (shift_return_value (TYPE_MODE (rettype), false, valreg))
sibcall_failure = 1;
- valreg = gen_rtx_REG (TYPE_MODE (TREE_TYPE (exp)), REGNO (valreg));
+ valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg));
}
if (pass && (flags & ECF_MALLOC))
@@ -2879,7 +2870,7 @@ expand_call (tree exp, rtx target, int ignore)
rtx last, insns;
/* The return value from a malloc-like function is a pointer. */
- if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
+ if (TREE_CODE (rettype) == POINTER_TYPE)
mark_reg_pointer (temp, BIGGEST_ALIGNMENT);
emit_move_insn (temp, valreg);
@@ -2929,7 +2920,7 @@ expand_call (tree exp, rtx target, int ignore)
/* If value type not void, return an rtx for the value. */
- if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode
+ if (TYPE_MODE (rettype) == VOIDmode
|| ignore)
target = const0_rtx;
else if (structure_value_addr)
@@ -2937,10 +2928,10 @@ expand_call (tree exp, rtx target, int ignore)
if (target == 0 || !MEM_P (target))
{
target
- = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
- memory_address (TYPE_MODE (TREE_TYPE (exp)),
+ = gen_rtx_MEM (TYPE_MODE (rettype),
+ memory_address (TYPE_MODE (rettype),
structure_value_addr));
- set_mem_attributes (target, exp, 1);
+ set_mem_attributes (target, rettype, 1);
}
}
else if (pcc_struct_value)
@@ -2948,9 +2939,9 @@ expand_call (tree exp, rtx target, int ignore)
/* This is the special C++ case where we need to
know what the true target was. We take care to
never use this value more than once in one expression. */
- target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
+ target = gen_rtx_MEM (TYPE_MODE (rettype),
copy_to_reg (valreg));
- set_mem_attributes (target, exp, 1);
+ set_mem_attributes (target, rettype, 1);
}
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
@@ -2959,22 +2950,22 @@ expand_call (tree exp, rtx target, int ignore)
if (target == 0)
{
/* This will only be assigned once, so it can be readonly. */
- tree nt = build_qualified_type (TREE_TYPE (exp),
- (TYPE_QUALS (TREE_TYPE (exp))
+ tree nt = build_qualified_type (rettype,
+ (TYPE_QUALS (rettype)
| TYPE_QUAL_CONST));
target = assign_temp (nt, 0, 1, 1);
}
if (! rtx_equal_p (target, valreg))
- emit_group_store (target, valreg, TREE_TYPE (exp),
- int_size_in_bytes (TREE_TYPE (exp)));
+ emit_group_store (target, valreg, rettype,
+ int_size_in_bytes (rettype));
/* We can not support sibling calls for this case. */
sibcall_failure = 1;
}
else if (target
- && GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
+ && GET_MODE (target) == TYPE_MODE (rettype)
&& GET_MODE (target) == GET_MODE (valreg))
{
bool may_overlap = false;
@@ -3019,9 +3010,9 @@ expand_call (tree exp, rtx target, int ignore)
sibcall_failure = 1;
}
}
- else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
+ else if (TYPE_MODE (rettype) == BLKmode)
{
- target = copy_blkmode_from_reg (target, valreg, TREE_TYPE (exp));
+ target = copy_blkmode_from_reg (target, valreg, rettype);
/* We can not support sibling calls for this case. */
sibcall_failure = 1;
@@ -3032,10 +3023,10 @@ expand_call (tree exp, rtx target, int ignore)
/* If we promoted this return value, make the proper SUBREG.
TARGET might be const0_rtx here, so be careful. */
if (REG_P (target)
- && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
- && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
+ && TYPE_MODE (rettype) != BLKmode
+ && GET_MODE (target) != TYPE_MODE (rettype))
{
- tree type = TREE_TYPE (exp);
+ tree type = rettype;
int unsignedp = TYPE_UNSIGNED (type);
int offset = 0;
enum machine_mode pmode;