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>
* doc/invoke.texi (-fsched-pressure): Document it.
......
......@@ -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 \
$(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) \
$(DBGCNT_H)
$(DBGCNT_H) tree-scalar-evolution.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) \
$(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 \
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) \
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
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 \
......
......@@ -6235,7 +6235,7 @@ expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
static void
expand_builtin_synchronize (void)
{
tree x;
gimple x;
#ifdef HAVE_memory_barrier
if (HAVE_memory_barrier)
......@@ -6253,10 +6253,10 @@ expand_builtin_synchronize (void)
/* If no explicit memory barrier instruction is available, create an
empty asm stmt with a memory clobber. */
x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
tree_cons (NULL, build_string (6, "memory"), NULL));
ASM_VOLATILE_P (x) = 1;
expand_asm_expr (x);
x = gimple_build_asm ("", 0, 0, 1,
tree_cons (NULL, build_string (6, "memory"), NULL));
gimple_asm_set_volatile (x, true);
expand_asm_stmt (x);
}
/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
......
......@@ -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;
......
......@@ -437,9 +437,9 @@ set_eh_region_tree_label (struct eh_region_d *region, tree lab)
}
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;
struct eh_region_d *reg = VEC_index (eh_region,
cfun->eh->region_array, region_nr);
......
......@@ -198,7 +198,7 @@ extern void foreach_reachable_handler (int, bool, bool,
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 dump_eh_tree (FILE *, struct function *);
void debug_eh_tree (struct function *);
......
......@@ -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
succeeded, false otherwise. */
static bool
bool
emit_storent_insn (rtx to, rtx from)
{
enum machine_mode mode = GET_MODE (to), imode;
......@@ -4485,7 +4485,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
{
rtx temp;
rtx alt_rtl = NULL_RTX;
int dont_return_target = 0;
location_t loc = EXPR_LOCATION (exp);
if (VOID_TYPE_P (TREE_TYPE (exp)))
......@@ -4646,19 +4645,6 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
(call_param_p
? EXPAND_STACK_PARM : EXPAND_NORMAL),
&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
......@@ -4707,15 +4693,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
&& GET_MODE (temp) != VOIDmode)
{
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
if (dont_return_target)
{
/* 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
if (GET_MODE (target) == BLKmode
|| GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
(call_param_p
......@@ -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
recursively. */
static rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *);
rtx
expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl)
......@@ -7203,7 +7178,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
return ret;
}
static rtx
rtx
expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
enum expand_modifier modifier)
{
......@@ -8251,7 +8226,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
}
#undef REDUCE_BIT_FIELD
static rtx
rtx
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl)
{
......@@ -8611,12 +8586,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return ret;
}
case GOTO_EXPR:
if (TREE_CODE (treeop0) == LABEL_DECL)
expand_goto (treeop0);
else
expand_computed_goto (treeop0);
return const0_rtx;
case CONSTRUCTOR:
/* 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,
return const0_rtx;
}
case RETURN_EXPR:
if (!treeop0)
expand_null_return ();
else
expand_return (treeop0);
return const0_rtx;
case ADDR_EXPR:
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,
op0 = expand_normal (treeop0);
return read_complex_part (op0, true);
case RETURN_EXPR:
case LABEL_EXPR:
case GOTO_EXPR:
case SWITCH_EXPR:
case ASM_EXPR:
case RESX_EXPR:
expand_resx_expr (exp);
return const0_rtx;
/* Expanded in cfgexpand.c. */
gcc_unreachable ();
case TRY_CATCH_EXPR:
case CATCH_EXPR:
......@@ -9563,18 +9530,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
initialization constants, and should not be expanded. */
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:
/* WITH_SIZE_EXPR expands to its first argument. The caller should
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);
extern rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods,
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.
The number of registers to be filled is NREGS. */
......@@ -539,9 +540,13 @@ extern rtx store_expr (tree, rtx, int, bool);
Useful after calling expand_expr with 1 as sum_ok. */
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,
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.
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
#include "predict.h"
#include "optabs.h"
#include "target.h"
#include "gimple.h"
#include "regs.h"
#include "alloc-pool.h"
#include "pretty-print.h"
......@@ -1075,20 +1076,65 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
}
void
expand_asm_expr (tree exp)
expand_asm_stmt (gimple stmt)
{
int noutputs, i;
tree outputs, tail;
int noutputs;
tree outputs, tail, t;
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;
}
outputs = ASM_OUTPUTS (exp);
noutputs = list_length (outputs);
outputs = out;
noutputs = gimple_asm_noutputs (stmt);
/* o[I] is the place that output number I should be written. */
o = (tree *) alloca (noutputs * sizeof (tree));
......@@ -1098,8 +1144,7 @@ expand_asm_expr (tree exp)
/* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
OUTPUTS some trees for where the values were actually stored. */
expand_asm_operands (ASM_STRING (exp), outputs, ASM_INPUTS (exp),
ASM_CLOBBERS (exp), ASM_VOLATILE_P (exp),
expand_asm_operands (str, outputs, in, cl, gimple_asm_volatile_p (stmt),
input_location);
/* 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,
Generate the code to test it and jump to the right place. */
void
expand_case (tree exp)
expand_case (gimple stmt)
{
tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
rtx default_label = 0;
......@@ -2167,9 +2212,7 @@ expand_case (tree exp)
int i;
rtx before_case, end, lab;
tree vec = SWITCH_LABELS (exp);
tree orig_type = TREE_TYPE (exp);
tree index_expr = SWITCH_COND (exp);
tree index_expr = gimple_switch_index (stmt);
tree index_type = TREE_TYPE (index_expr);
int unsignedp = TYPE_UNSIGNED (index_type);
......@@ -2188,11 +2231,6 @@ expand_case (tree exp)
sizeof (struct case_node),
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 ();
/* An ERROR_MARK occurs for various reasons including invalid data type. */
......@@ -2200,24 +2238,24 @@ expand_case (tree exp)
{
tree elt;
bitmap label_bitmap;
int vl = TREE_VEC_LENGTH (vec);
int stopi = 0;
/* cleanup_tree_cfg removes all SWITCH_EXPR with their index
expressions being INTEGER_CST. */
gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
/* The default case, if ever taken, is at the end of TREE_VEC. */
elt = TREE_VEC_ELT (vec, vl - 1);
/* The default case, if ever taken, is the first element. */
elt = gimple_switch_label (stmt, 0);
if (!CASE_LOW (elt) && !CASE_HIGH (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;
elt = TREE_VEC_ELT (vec, i);
elt = gimple_switch_label (stmt, i);
low = CASE_LOW (elt);
gcc_assert (low);
......@@ -2371,9 +2409,7 @@ expand_case (tree exp)
decision tree an unconditional jump to the
default code is emitted. */
use_cost_table
= (TREE_CODE (orig_type) != ENUMERAL_TYPE
&& estimate_case_costs (case_list));
use_cost_table = estimate_case_costs (case_list);
balance_case_nodes (&case_list, NULL);
emit_case_nodes (index, case_list, default_label, index_type);
if (default_label)
......
......@@ -5054,9 +5054,9 @@ extern bool parse_output_constraint (const char **, int, int, int,
bool *, bool *, bool *);
extern bool parse_input_constraint (const char **, int, int, int, int,
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 void expand_case (tree);
extern void expand_case (gimple);
extern void expand_decl (tree);
#ifdef HARD_CONST
/* 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