Commit 28ed065e by Michael Matz Committed by Michael Matz

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
parent 2f6924a4
2009-09-01 Michael Matz <matz@suse.de>
* 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.
2009-09-02 Vladimir Makarov <vmakarov@redhat.com> 2009-09-02 Vladimir Makarov <vmakarov@redhat.com>
* doc/invoke.texi (-fsched-pressure): Document it. * doc/invoke.texi (-fsched-pressure): Document it.
......
...@@ -2284,7 +2284,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \ ...@@ -2284,7 +2284,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \
$(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) \ $(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) \
$(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \ $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \
$(DBGCNT_H) $(DBGCNT_H) tree-scalar-evolution.h
tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) $(CFGLOOP_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) $(CFGLOOP_H) \
...@@ -2675,7 +2675,7 @@ statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -2675,7 +2675,7 @@ statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
libfuncs.h $(EXCEPT_H) $(RECOG_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \ libfuncs.h $(EXCEPT_H) $(RECOG_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \
langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H) $(MACHMODE_H) \ langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H) gimple.h $(MACHMODE_H) \
$(REGS_H) alloc-pool.h $(REGS_H) alloc-pool.h
except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) libfuncs.h \ $(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) libfuncs.h \
......
...@@ -6235,7 +6235,7 @@ expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp, ...@@ -6235,7 +6235,7 @@ expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
static void static void
expand_builtin_synchronize (void) expand_builtin_synchronize (void)
{ {
tree x; gimple x;
#ifdef HAVE_memory_barrier #ifdef HAVE_memory_barrier
if (HAVE_memory_barrier) if (HAVE_memory_barrier)
...@@ -6253,10 +6253,10 @@ expand_builtin_synchronize (void) ...@@ -6253,10 +6253,10 @@ expand_builtin_synchronize (void)
/* If no explicit memory barrier instruction is available, create an /* If no explicit memory barrier instruction is available, create an
empty asm stmt with a memory clobber. */ empty asm stmt with a memory clobber. */
x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL, x = gimple_build_asm ("", 0, 0, 1,
tree_cons (NULL, build_string (6, "memory"), NULL)); tree_cons (NULL, build_string (6, "memory"), NULL));
ASM_VOLATILE_P (x) = 1; gimple_asm_set_volatile (x, true);
expand_asm_expr (x); expand_asm_stmt (x);
} }
/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */ /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
......
...@@ -238,7 +238,7 @@ prepare_call_address (rtx funexp, rtx static_chain_value, ...@@ -238,7 +238,7 @@ prepare_call_address (rtx funexp, rtx static_chain_value,
denote registers used by the called function. */ denote registers used by the called function. */
static void 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, tree funtype ATTRIBUTE_UNUSED,
HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED, HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
HOST_WIDE_INT rounded_stack_size, HOST_WIDE_INT rounded_stack_size,
...@@ -380,15 +380,6 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED, ...@@ -380,15 +380,6 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
effect. */ effect. */
if (ecf_flags & ECF_NOTHROW) if (ecf_flags & ECF_NOTHROW)
add_reg_note (call_insn, REG_EH_REGION, const0_rtx); 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) if (ecf_flags & ECF_NORETURN)
add_reg_note (call_insn, REG_NORETURN, const0_rtx); add_reg_note (call_insn, REG_NORETURN, const0_rtx);
...@@ -1927,6 +1918,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -1927,6 +1918,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Data type of the function. */ /* Data type of the function. */
tree funtype; tree funtype;
tree type_arg_types; tree type_arg_types;
tree rettype;
/* Declaration of the function being called, /* Declaration of the function being called,
or 0 if the function is computed (not known by name). */ or 0 if the function is computed (not known by name). */
tree fndecl = 0; tree fndecl = 0;
...@@ -2022,7 +2014,6 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2022,7 +2014,6 @@ expand_call (tree exp, rtx target, int ignore)
int old_stack_pointer_delta = 0; int old_stack_pointer_delta = 0;
rtx call_fusage; rtx call_fusage;
tree p = CALL_EXPR_FN (exp);
tree addr = CALL_EXPR_FN (exp); tree addr = CALL_EXPR_FN (exp);
int i; int i;
/* The alignment of the stack, in bits. */ /* The alignment of the stack, in bits. */
...@@ -2045,15 +2036,16 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2045,15 +2036,16 @@ expand_call (tree exp, rtx target, int ignore)
} }
else else
{ {
fntype = TREE_TYPE (TREE_TYPE (p)); fntype = TREE_TYPE (TREE_TYPE (addr));
flags |= flags_from_decl_or_type (fntype); flags |= flags_from_decl_or_type (fntype);
} }
rettype = TREE_TYPE (exp);
struct_value = targetm.calls.struct_value_rtx (fntype, 0); struct_value = targetm.calls.struct_value_rtx (fntype, 0);
/* Warn if this value is an aggregate type, /* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */ 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"); warning (OPT_Waggregate_return, "function call has aggregate value");
/* If the result of a non looping pure or const function call is /* 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) ...@@ -2063,7 +2055,7 @@ expand_call (tree exp, rtx target, int ignore)
if ((flags & (ECF_CONST | ECF_PURE)) if ((flags & (ECF_CONST | ECF_PURE))
&& (!(flags & ECF_LOOPING_CONST_OR_PURE)) && (!(flags & ECF_LOOPING_CONST_OR_PURE))
&& (ignore || target == const0_rtx && (ignore || target == const0_rtx
|| TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)) || TYPE_MODE (rettype) == VOIDmode))
{ {
bool volatilep = false; bool volatilep = false;
tree arg; tree arg;
...@@ -2106,7 +2098,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2106,7 +2098,7 @@ expand_call (tree exp, rtx target, int ignore)
} }
#else /* not PCC_STATIC_STRUCT_RETURN */ #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)) if (target && MEM_P (target) && CALL_EXPR_RETURN_SLOT_OPT (exp))
structure_value_addr = XEXP (target, 0); structure_value_addr = XEXP (target, 0);
...@@ -2115,7 +2107,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2115,7 +2107,7 @@ expand_call (tree exp, rtx target, int ignore)
/* For variable-sized objects, we must be called with a target /* For variable-sized objects, we must be called with a target
specified. If we were to allocate space on the stack here, specified. If we were to allocate space on the stack here,
we would have no way of knowing when to free it. */ 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); mark_temp_addr_taken (d);
structure_value_addr = XEXP (d, 0); structure_value_addr = XEXP (d, 0);
...@@ -2286,7 +2278,6 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2286,7 +2278,6 @@ expand_call (tree exp, rtx target, int ignore)
if (currently_expanding_call++ != 0 if (currently_expanding_call++ != 0
|| !flag_optimize_sibling_calls || !flag_optimize_sibling_calls
|| args_size.var || args_size.var
|| lookup_expr_eh_region (exp) >= 0
|| dbg_cnt (tail_call) == false) || dbg_cnt (tail_call) == false)
try_tail_call = 0; try_tail_call = 0;
...@@ -2693,14 +2684,14 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2693,14 +2684,14 @@ expand_call (tree exp, rtx target, int ignore)
/* Figure out the register where the value, if any, will come back. */ /* Figure out the register where the value, if any, will come back. */
valreg = 0; valreg = 0;
if (TYPE_MODE (TREE_TYPE (exp)) != VOIDmode if (TYPE_MODE (rettype) != VOIDmode
&& ! structure_value_addr) && ! structure_value_addr)
{ {
if (pcc_struct_value) 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)); fndecl, NULL, (pass == 0));
else else
valreg = hard_function_value (TREE_TYPE (exp), fndecl, fntype, valreg = hard_function_value (rettype, fndecl, fntype,
(pass == 0)); (pass == 0));
/* If VALREG is a PARALLEL whose first member has a zero /* If VALREG is a PARALLEL whose first member has a zero
...@@ -2865,12 +2856,12 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2865,12 +2856,12 @@ expand_call (tree exp, rtx target, int ignore)
group load/store machinery below. */ group load/store machinery below. */
if (!structure_value_addr if (!structure_value_addr
&& !pcc_struct_value && !pcc_struct_value
&& TYPE_MODE (TREE_TYPE (exp)) != BLKmode && TYPE_MODE (rettype) != BLKmode
&& targetm.calls.return_in_msb (TREE_TYPE (exp))) && 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; 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)) if (pass && (flags & ECF_MALLOC))
...@@ -2879,7 +2870,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2879,7 +2870,7 @@ expand_call (tree exp, rtx target, int ignore)
rtx last, insns; rtx last, insns;
/* The return value from a malloc-like function is a pointer. */ /* 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); mark_reg_pointer (temp, BIGGEST_ALIGNMENT);
emit_move_insn (temp, valreg); emit_move_insn (temp, valreg);
...@@ -2929,7 +2920,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2929,7 +2920,7 @@ expand_call (tree exp, rtx target, int ignore)
/* If value type not void, return an rtx for the value. */ /* If value type not void, return an rtx for the value. */
if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode if (TYPE_MODE (rettype) == VOIDmode
|| ignore) || ignore)
target = const0_rtx; target = const0_rtx;
else if (structure_value_addr) else if (structure_value_addr)
...@@ -2937,10 +2928,10 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2937,10 +2928,10 @@ expand_call (tree exp, rtx target, int ignore)
if (target == 0 || !MEM_P (target)) if (target == 0 || !MEM_P (target))
{ {
target target
= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), = gen_rtx_MEM (TYPE_MODE (rettype),
memory_address (TYPE_MODE (TREE_TYPE (exp)), memory_address (TYPE_MODE (rettype),
structure_value_addr)); structure_value_addr));
set_mem_attributes (target, exp, 1); set_mem_attributes (target, rettype, 1);
} }
} }
else if (pcc_struct_value) else if (pcc_struct_value)
...@@ -2948,9 +2939,9 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2948,9 +2939,9 @@ expand_call (tree exp, rtx target, int ignore)
/* This is the special C++ case where we need to /* This is the special C++ case where we need to
know what the true target was. We take care to know what the true target was. We take care to
never use this value more than once in one expression. */ 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)); 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. /* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */ The Irix 6 ABI has examples of this. */
...@@ -2959,22 +2950,22 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2959,22 +2950,22 @@ expand_call (tree exp, rtx target, int ignore)
if (target == 0) if (target == 0)
{ {
/* This will only be assigned once, so it can be readonly. */ /* This will only be assigned once, so it can be readonly. */
tree nt = build_qualified_type (TREE_TYPE (exp), tree nt = build_qualified_type (rettype,
(TYPE_QUALS (TREE_TYPE (exp)) (TYPE_QUALS (rettype)
| TYPE_QUAL_CONST)); | TYPE_QUAL_CONST));
target = assign_temp (nt, 0, 1, 1); target = assign_temp (nt, 0, 1, 1);
} }
if (! rtx_equal_p (target, valreg)) if (! rtx_equal_p (target, valreg))
emit_group_store (target, valreg, TREE_TYPE (exp), emit_group_store (target, valreg, rettype,
int_size_in_bytes (TREE_TYPE (exp))); int_size_in_bytes (rettype));
/* We can not support sibling calls for this case. */ /* We can not support sibling calls for this case. */
sibcall_failure = 1; sibcall_failure = 1;
} }
else if (target else if (target
&& GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp)) && GET_MODE (target) == TYPE_MODE (rettype)
&& GET_MODE (target) == GET_MODE (valreg)) && GET_MODE (target) == GET_MODE (valreg))
{ {
bool may_overlap = false; bool may_overlap = false;
...@@ -3019,9 +3010,9 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -3019,9 +3010,9 @@ expand_call (tree exp, rtx target, int ignore)
sibcall_failure = 1; 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. */ /* We can not support sibling calls for this case. */
sibcall_failure = 1; sibcall_failure = 1;
...@@ -3032,10 +3023,10 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -3032,10 +3023,10 @@ expand_call (tree exp, rtx target, int ignore)
/* If we promoted this return value, make the proper SUBREG. /* If we promoted this return value, make the proper SUBREG.
TARGET might be const0_rtx here, so be careful. */ TARGET might be const0_rtx here, so be careful. */
if (REG_P (target) if (REG_P (target)
&& TYPE_MODE (TREE_TYPE (exp)) != BLKmode && TYPE_MODE (rettype) != BLKmode
&& GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp))) && GET_MODE (target) != TYPE_MODE (rettype))
{ {
tree type = TREE_TYPE (exp); tree type = rettype;
int unsignedp = TYPE_UNSIGNED (type); int unsignedp = TYPE_UNSIGNED (type);
int offset = 0; int offset = 0;
enum machine_mode pmode; enum machine_mode pmode;
......
...@@ -437,9 +437,9 @@ set_eh_region_tree_label (struct eh_region_d *region, tree lab) ...@@ -437,9 +437,9 @@ set_eh_region_tree_label (struct eh_region_d *region, tree lab)
} }
void void
expand_resx_expr (tree exp) expand_resx_stmt (gimple stmt)
{ {
int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)); int region_nr = gimple_resx_region (stmt);
rtx insn; rtx insn;
struct eh_region_d *reg = VEC_index (eh_region, struct eh_region_d *reg = VEC_index (eh_region,
cfun->eh->region_array, region_nr); cfun->eh->region_array, region_nr);
......
...@@ -198,7 +198,7 @@ extern void foreach_reachable_handler (int, bool, bool, ...@@ -198,7 +198,7 @@ extern void foreach_reachable_handler (int, bool, bool,
void *); void *);
extern void collect_eh_region_array (void); extern void collect_eh_region_array (void);
extern void expand_resx_expr (tree); extern void expand_resx_stmt (gimple);
extern void verify_eh_tree (struct function *); extern void verify_eh_tree (struct function *);
extern void dump_eh_tree (FILE *, struct function *); extern void dump_eh_tree (FILE *, struct function *);
void debug_eh_tree (struct function *); void debug_eh_tree (struct function *);
......
...@@ -4435,7 +4435,7 @@ expand_assignment (tree to, tree from, bool nontemporal) ...@@ -4435,7 +4435,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
/* Emits nontemporal store insn that moves FROM to TO. Returns true if this /* Emits nontemporal store insn that moves FROM to TO. Returns true if this
succeeded, false otherwise. */ succeeded, false otherwise. */
static bool bool
emit_storent_insn (rtx to, rtx from) emit_storent_insn (rtx to, rtx from)
{ {
enum machine_mode mode = GET_MODE (to), imode; enum machine_mode mode = GET_MODE (to), imode;
...@@ -4485,7 +4485,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) ...@@ -4485,7 +4485,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
{ {
rtx temp; rtx temp;
rtx alt_rtl = NULL_RTX; rtx alt_rtl = NULL_RTX;
int dont_return_target = 0;
location_t loc = EXPR_LOCATION (exp); location_t loc = EXPR_LOCATION (exp);
if (VOID_TYPE_P (TREE_TYPE (exp))) if (VOID_TYPE_P (TREE_TYPE (exp)))
...@@ -4646,19 +4645,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) ...@@ -4646,19 +4645,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
(call_param_p (call_param_p
? EXPAND_STACK_PARM : EXPAND_NORMAL), ? EXPAND_STACK_PARM : EXPAND_NORMAL),
&alt_rtl); &alt_rtl);
/* Return TARGET if it's a specified hardware register.
If TARGET is a volatile mem ref, either return TARGET
or return a reg copied *from* TARGET; ANSI requires this.
Otherwise, if TEMP is not TARGET, return TEMP
if it is constant (for efficiency),
or if we really want the correct value. */
if (!(target && REG_P (target)
&& REGNO (target) < FIRST_PSEUDO_REGISTER)
&& !(MEM_P (target) && MEM_VOLATILE_P (target))
&& ! rtx_equal_p (temp, target)
&& CONSTANT_P (temp))
dont_return_target = 1;
} }
/* If TEMP is a VOIDmode constant and the mode of the type of EXP is not /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
...@@ -4707,15 +4693,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) ...@@ -4707,15 +4693,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
&& GET_MODE (temp) != VOIDmode) && GET_MODE (temp) != VOIDmode)
{ {
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp)); int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
if (dont_return_target) if (GET_MODE (target) == BLKmode
{
/* In this case, we will return TEMP,
so make sure it has the proper mode.
But don't forget to store the value into TARGET. */
temp = convert_to_mode (GET_MODE (target), temp, unsignedp);
emit_move_insn (target, temp);
}
else if (GET_MODE (target) == BLKmode
|| GET_MODE (temp) == BLKmode) || GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp), emit_block_move (target, temp, expr_size (exp),
(call_param_p (call_param_p
...@@ -7128,9 +7106,6 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, ...@@ -7128,9 +7106,6 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
recursively. */ recursively. */
static rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *);
rtx rtx
expand_expr_real (tree exp, rtx target, enum machine_mode tmode, expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl) enum expand_modifier modifier, rtx *alt_rtl)
...@@ -7203,7 +7178,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, ...@@ -7203,7 +7178,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
return ret; return ret;
} }
static rtx rtx
expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
enum expand_modifier modifier) enum expand_modifier modifier)
{ {
...@@ -8251,7 +8226,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, ...@@ -8251,7 +8226,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
} }
#undef REDUCE_BIT_FIELD #undef REDUCE_BIT_FIELD
static rtx rtx
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl) enum expand_modifier modifier, rtx *alt_rtl)
{ {
...@@ -8611,12 +8586,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -8611,12 +8586,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return ret; return ret;
} }
case GOTO_EXPR:
if (TREE_CODE (treeop0) == LABEL_DECL)
expand_goto (treeop0);
else
expand_computed_goto (treeop0);
return const0_rtx;
case CONSTRUCTOR: case CONSTRUCTOR:
/* If we don't need the result, just ensure we evaluate any /* If we don't need the result, just ensure we evaluate any
...@@ -9505,13 +9474,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9505,13 +9474,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return const0_rtx; return const0_rtx;
} }
case RETURN_EXPR:
if (!treeop0)
expand_null_return ();
else
expand_return (treeop0);
return const0_rtx;
case ADDR_EXPR: case ADDR_EXPR:
return expand_expr_addr_expr (exp, target, tmode, modifier); return expand_expr_addr_expr (exp, target, tmode, modifier);
...@@ -9523,9 +9485,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9523,9 +9485,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
op0 = expand_normal (treeop0); op0 = expand_normal (treeop0);
return read_complex_part (op0, true); return read_complex_part (op0, true);
case RETURN_EXPR:
case LABEL_EXPR:
case GOTO_EXPR:
case SWITCH_EXPR:
case ASM_EXPR:
case RESX_EXPR: case RESX_EXPR:
expand_resx_expr (exp); /* Expanded in cfgexpand.c. */
return const0_rtx; gcc_unreachable ();
case TRY_CATCH_EXPR: case TRY_CATCH_EXPR:
case CATCH_EXPR: case CATCH_EXPR:
...@@ -9563,18 +9530,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -9563,18 +9530,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
initialization constants, and should not be expanded. */ initialization constants, and should not be expanded. */
gcc_unreachable (); gcc_unreachable ();
case SWITCH_EXPR:
expand_case (exp);
return const0_rtx;
case LABEL_EXPR:
expand_label (treeop0);
return const0_rtx;
case ASM_EXPR:
expand_asm_expr (exp);
return const0_rtx;
case WITH_SIZE_EXPR: case WITH_SIZE_EXPR:
/* WITH_SIZE_EXPR expands to its first argument. The caller should /* WITH_SIZE_EXPR expands to its first argument. The caller should
have pulled out the size to use in whatever context it needed. */ have pulled out the size to use in whatever context it needed. */
......
...@@ -426,6 +426,7 @@ extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods); ...@@ -426,6 +426,7 @@ extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
extern rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool); extern rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods, extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods,
unsigned int, HOST_WIDE_INT); unsigned int, HOST_WIDE_INT);
extern bool emit_storent_insn (rtx to, rtx from);
/* Copy all or part of a value X into registers starting at REGNO. /* Copy all or part of a value X into registers starting at REGNO.
The number of registers to be filled is NREGS. */ The number of registers to be filled is NREGS. */
...@@ -539,9 +540,13 @@ extern rtx store_expr (tree, rtx, int, bool); ...@@ -539,9 +540,13 @@ extern rtx store_expr (tree, rtx, int, bool);
Useful after calling expand_expr with 1 as sum_ok. */ Useful after calling expand_expr with 1 as sum_ok. */
extern rtx force_operand (rtx, rtx); extern rtx force_operand (rtx, rtx);
/* Work horse for expand_expr. */ /* Work horses for expand_expr. */
extern rtx expand_expr_real (tree, rtx, enum machine_mode, extern rtx expand_expr_real (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *); enum expand_modifier, rtx *);
extern rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *);
extern rtx expand_expr_real_2 (sepops, rtx, enum machine_mode,
enum expand_modifier);
/* Generate code for computing expression EXP. /* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null. An rtx for the computed value is returned. The value is never null.
......
...@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "predict.h" #include "predict.h"
#include "optabs.h" #include "optabs.h"
#include "target.h" #include "target.h"
#include "gimple.h"
#include "regs.h" #include "regs.h"
#include "alloc-pool.h" #include "alloc-pool.h"
#include "pretty-print.h" #include "pretty-print.h"
...@@ -1075,20 +1076,65 @@ expand_asm_operands (tree string, tree outputs, tree inputs, ...@@ -1075,20 +1076,65 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
} }
void void
expand_asm_expr (tree exp) expand_asm_stmt (gimple stmt)
{ {
int noutputs, i; int noutputs;
tree outputs, tail; tree outputs, tail, t;
tree *o; tree *o;
size_t i, n;
const char *s;
tree str, out, in, cl;
/* Meh... convert the gimple asm operands into real tree lists.
Eventually we should make all routines work on the vectors instead
of relying on TREE_CHAIN. */
out = NULL_TREE;
n = gimple_asm_noutputs (stmt);
if (n > 0)
{
t = out = gimple_asm_output_op (stmt, 0);
for (i = 1; i < n; i++)
{
TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
t = gimple_asm_output_op (stmt, i);
}
}
in = NULL_TREE;
n = gimple_asm_ninputs (stmt);
if (n > 0)
{
t = in = gimple_asm_input_op (stmt, 0);
for (i = 1; i < n; i++)
{
TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
t = gimple_asm_input_op (stmt, i);
}
}
cl = NULL_TREE;
n = gimple_asm_nclobbers (stmt);
if (n > 0)
{
t = cl = gimple_asm_clobber_op (stmt, 0);
for (i = 1; i < n; i++)
{
TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
t = gimple_asm_clobber_op (stmt, i);
}
}
if (ASM_INPUT_P (exp)) s = gimple_asm_string (stmt);
str = build_string (strlen (s), s);
if (gimple_asm_input_p (stmt))
{ {
expand_asm_loc (ASM_STRING (exp), ASM_VOLATILE_P (exp), input_location); expand_asm_loc (str, gimple_asm_volatile_p (stmt), input_location);
return; return;
} }
outputs = ASM_OUTPUTS (exp); outputs = out;
noutputs = list_length (outputs); noutputs = gimple_asm_noutputs (stmt);
/* o[I] is the place that output number I should be written. */ /* o[I] is the place that output number I should be written. */
o = (tree *) alloca (noutputs * sizeof (tree)); o = (tree *) alloca (noutputs * sizeof (tree));
...@@ -1098,8 +1144,7 @@ expand_asm_expr (tree exp) ...@@ -1098,8 +1144,7 @@ expand_asm_expr (tree exp)
/* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
OUTPUTS some trees for where the values were actually stored. */ OUTPUTS some trees for where the values were actually stored. */
expand_asm_operands (ASM_STRING (exp), outputs, ASM_INPUTS (exp), expand_asm_operands (str, outputs, in, cl, gimple_asm_volatile_p (stmt),
ASM_CLOBBERS (exp), ASM_VOLATILE_P (exp),
input_location); input_location);
/* Copy all the intermediate outputs into the specified outputs. */ /* Copy all the intermediate outputs into the specified outputs. */
...@@ -2154,7 +2199,7 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval, ...@@ -2154,7 +2199,7 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
Generate the code to test it and jump to the right place. */ Generate the code to test it and jump to the right place. */
void void
expand_case (tree exp) expand_case (gimple stmt)
{ {
tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE; tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
rtx default_label = 0; rtx default_label = 0;
...@@ -2167,9 +2212,7 @@ expand_case (tree exp) ...@@ -2167,9 +2212,7 @@ expand_case (tree exp)
int i; int i;
rtx before_case, end, lab; rtx before_case, end, lab;
tree vec = SWITCH_LABELS (exp); tree index_expr = gimple_switch_index (stmt);
tree orig_type = TREE_TYPE (exp);
tree index_expr = SWITCH_COND (exp);
tree index_type = TREE_TYPE (index_expr); tree index_type = TREE_TYPE (index_expr);
int unsignedp = TYPE_UNSIGNED (index_type); int unsignedp = TYPE_UNSIGNED (index_type);
...@@ -2188,11 +2231,6 @@ expand_case (tree exp) ...@@ -2188,11 +2231,6 @@ expand_case (tree exp)
sizeof (struct case_node), sizeof (struct case_node),
100); 100);
/* The switch body is lowered in gimplify.c, we should never have
switches with a non-NULL SWITCH_BODY here. */
gcc_assert (!SWITCH_BODY (exp));
gcc_assert (SWITCH_LABELS (exp));
do_pending_stack_adjust (); do_pending_stack_adjust ();
/* An ERROR_MARK occurs for various reasons including invalid data type. */ /* An ERROR_MARK occurs for various reasons including invalid data type. */
...@@ -2200,24 +2238,24 @@ expand_case (tree exp) ...@@ -2200,24 +2238,24 @@ expand_case (tree exp)
{ {
tree elt; tree elt;
bitmap label_bitmap; bitmap label_bitmap;
int vl = TREE_VEC_LENGTH (vec); int stopi = 0;
/* cleanup_tree_cfg removes all SWITCH_EXPR with their index /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
expressions being INTEGER_CST. */ expressions being INTEGER_CST. */
gcc_assert (TREE_CODE (index_expr) != INTEGER_CST); gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
/* The default case, if ever taken, is at the end of TREE_VEC. */ /* The default case, if ever taken, is the first element. */
elt = TREE_VEC_ELT (vec, vl - 1); elt = gimple_switch_label (stmt, 0);
if (!CASE_LOW (elt) && !CASE_HIGH (elt)) if (!CASE_LOW (elt) && !CASE_HIGH (elt))
{ {
default_label_decl = CASE_LABEL (elt); default_label_decl = CASE_LABEL (elt);
--vl; stopi = 1;
} }
for (i = vl - 1; i >= 0; --i) for (i = gimple_switch_num_labels (stmt) - 1; i >= stopi; --i)
{ {
tree low, high; tree low, high;
elt = TREE_VEC_ELT (vec, i); elt = gimple_switch_label (stmt, i);
low = CASE_LOW (elt); low = CASE_LOW (elt);
gcc_assert (low); gcc_assert (low);
...@@ -2371,9 +2409,7 @@ expand_case (tree exp) ...@@ -2371,9 +2409,7 @@ expand_case (tree exp)
decision tree an unconditional jump to the decision tree an unconditional jump to the
default code is emitted. */ default code is emitted. */
use_cost_table use_cost_table = estimate_case_costs (case_list);
= (TREE_CODE (orig_type) != ENUMERAL_TYPE
&& estimate_case_costs (case_list));
balance_case_nodes (&case_list, NULL); balance_case_nodes (&case_list, NULL);
emit_case_nodes (index, case_list, default_label, index_type); emit_case_nodes (index, case_list, default_label, index_type);
if (default_label) if (default_label)
......
...@@ -5054,9 +5054,9 @@ extern bool parse_output_constraint (const char **, int, int, int, ...@@ -5054,9 +5054,9 @@ extern bool parse_output_constraint (const char **, int, int, int,
bool *, bool *, bool *); bool *, bool *, bool *);
extern bool parse_input_constraint (const char **, int, int, int, int, extern bool parse_input_constraint (const char **, int, int, int, int,
const char * const *, bool *, bool *); const char * const *, bool *, bool *);
extern void expand_asm_expr (tree); extern void expand_asm_stmt (gimple);
extern tree resolve_asm_operand_names (tree, tree, tree); extern tree resolve_asm_operand_names (tree, tree, tree);
extern void expand_case (tree); extern void expand_case (gimple);
extern void expand_decl (tree); extern void expand_decl (tree);
#ifdef HARD_CONST #ifdef HARD_CONST
/* Silly ifdef to avoid having all includers depend on hard-reg-set.h. */ /* Silly ifdef to avoid having all includers depend on hard-reg-set.h. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment