diff options
author | Jason Merrill <jason@redhat.com> | 2004-06-11 14:41:47 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2004-06-11 14:41:47 -0400 |
commit | 67c605a553faab6244a1b1d987059798e6c1f9aa (patch) | |
tree | 53b714fbb57b9a4edc2c059014d88e351591041f | |
parent | 67fc0c0f596944a4bc88cb8d8061bf4c8753c03f (diff) | |
download | gcc-67c605a553faab6244a1b1d987059798e6c1f9aa.zip gcc-67c605a553faab6244a1b1d987059798e6c1f9aa.tar.gz gcc-67c605a553faab6244a1b1d987059798e6c1f9aa.tar.bz2 |
i386.h (EXPAND_BUILTIN_VA_ARG): Just abort.
* config/i386/i386.h (EXPAND_BUILTIN_VA_ARG): Just abort.
* config/i386/i386.c (ix86_va_arg): Remove.
* config/rs6000/rs6000.h (EXPAND_BUILTIN_VA_ARG): Just abort.
* config/rs6000/rs6000.c (rs6000_va_arg): Remove.
* config/alpha/alpha.h (EXPAND_BUILTIN_VA_ARG): Just abort.
* config/alpha/alpha.c (alpha_va_arg): Remove.
* config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Just abort.
* config/sparc/sparc.c (sparc_va_arg): Remove.
* tree-ssa-operands.c (get_stmt_operands): Use a V_MAY_DEF if the
assignment might throw.
* tree-eh.c (tree_could_throw_p): Support non-call exceptions in
expressions.
From-SVN: r82992
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 109 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 240 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 3 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 35 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.h | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 223 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 3 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 105 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 3 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 6 | ||||
-rw-r--r-- | gcc/tree-eh.c | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 6 |
14 files changed, 37 insertions, 738 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b56eb1a..c755b36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-06-11 Jason Merrill <jason@redhat.com> + + * config/i386/i386.h (EXPAND_BUILTIN_VA_ARG): Just abort. + * config/i386/i386.c (ix86_va_arg): Remove. + * config/rs6000/rs6000.h (EXPAND_BUILTIN_VA_ARG): Just abort. + * config/rs6000/rs6000.c (rs6000_va_arg): Remove. + * config/alpha/alpha.h (EXPAND_BUILTIN_VA_ARG): Just abort. + * config/alpha/alpha.c (alpha_va_arg): Remove. + * config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Just abort. + * config/sparc/sparc.c (sparc_va_arg): Remove. + + * tree-ssa-operands.c (get_stmt_operands): Use a V_MAY_DEF if the + assignment might throw. + * tree-eh.c (tree_could_throw_p): Support non-call exceptions in + expressions. + 2004-06-11 J"orn Rennecke <joern.rennecke@superh.com> PR 15886: diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 7c9d67d..d4b78d3 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -6291,115 +6291,6 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) } } -rtx -alpha_va_arg (tree valist, tree type) -{ - rtx addr; - tree t, type_size, rounded_size; - tree offset_field, base_field, addr_tree, addend; - tree wide_type, wide_ofs; - int indirect = 0; - - if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK) - return std_expand_builtin_va_arg (valist, type); - - if (type == error_mark_node - || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL - || TREE_OVERFLOW (type_size)) - rounded_size = size_zero_node; - else - rounded_size = fold (build (MULT_EXPR, sizetype, - fold (build (TRUNC_DIV_EXPR, sizetype, - fold (build (PLUS_EXPR, sizetype, - type_size, - size_int (7))), - size_int (8))), - size_int (8))); - - base_field = TYPE_FIELDS (TREE_TYPE (valist)); - offset_field = TREE_CHAIN (base_field); - - base_field = build (COMPONENT_REF, TREE_TYPE (base_field), - valist, base_field); - offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field), - valist, offset_field); - - /* If the type could not be passed in registers, skip the block - reserved for the registers. */ - if (MUST_PASS_IN_STACK (TYPE_MODE (type), type)) - { - t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, - build (MAX_EXPR, TREE_TYPE (offset_field), - offset_field, build_int_2 (6*8, 0))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - wide_type = make_signed_type (64); - wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field)); - - addend = wide_ofs; - - if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode) - { - indirect = 1; - rounded_size = size_int (UNITS_PER_WORD); - } - else if (TREE_CODE (type) == COMPLEX_TYPE) - { - rtx real_part, imag_part, value, tmp; - - real_part = alpha_va_arg (valist, TREE_TYPE (type)); - imag_part = alpha_va_arg (valist, TREE_TYPE (type)); - - /* ??? Most irritatingly, we're not returning the value here, - but the address. Since real_part and imag_part are not - necessarily contiguous, we must copy to local storage. */ - - real_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), real_part); - imag_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), imag_part); - value = gen_rtx_CONCAT (TYPE_MODE (type), real_part, imag_part); - - tmp = assign_temp (type, 0, 1, 0); - emit_move_insn (tmp, value); - - return XEXP (tmp, 0); - } - else if (TREE_CODE (type) == REAL_TYPE) - { - tree fpaddend, cond; - - fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend), - addend, build_int_2 (-6*8, 0))); - - cond = fold (build (LT_EXPR, integer_type_node, - wide_ofs, build_int_2 (6*8, 0))); - - addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond, - fpaddend, addend)); - } - - addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field), - base_field, addend); - - addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); - addr = copy_to_reg (addr); - - t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, - build (PLUS_EXPR, TREE_TYPE (offset_field), - offset_field, rounded_size)); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - - if (indirect) - { - addr = force_reg (Pmode, addr); - addr = gen_rtx_MEM (Pmode, addr); - } - - return addr; -} - static tree alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p, tree *post_p) diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index d59797c..8cc22ca 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1687,8 +1687,7 @@ do { \ alpha_va_start (valist, nextarg) /* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - alpha_va_arg (valist, type) +#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) /* Tell collect that the object format is ECOFF. */ #define OBJECT_FORMAT_COFF diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cffbadf..1f0cfc8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3177,246 +3177,6 @@ ix86_va_start (tree valist, rtx nextarg) } /* Implement va_arg. */ -rtx -ix86_va_arg (tree valist, tree type) -{ - static const int intreg[6] = { 0, 1, 2, 3, 4, 5 }; - tree f_gpr, f_fpr, f_ovf, f_sav; - tree gpr, fpr, ovf, sav, t; - int size, rsize; - rtx lab_false, lab_over = NULL_RTX; - rtx addr_rtx, r; - rtx container; - int indirect_p = 0; - - /* Only 64bit target needs something special. */ - if (!TARGET_64BIT) - { - return std_expand_builtin_va_arg (valist, type); - } - - f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = TREE_CHAIN (f_gpr); - f_ovf = TREE_CHAIN (f_fpr); - f_sav = TREE_CHAIN (f_ovf); - - valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist); - gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr); - fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr); - ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf); - sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav); - - size = int_size_in_bytes (type); - if (size == -1) - { - /* Passed by reference. */ - indirect_p = 1; - type = build_pointer_type (type); - size = int_size_in_bytes (type); - } - rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - - container = construct_container (TYPE_MODE (type), type, 0, - REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0); - /* - * Pull the value out of the saved registers ... - */ - - addr_rtx = gen_reg_rtx (Pmode); - - if (container) - { - rtx int_addr_rtx, sse_addr_rtx; - int needed_intregs, needed_sseregs; - int need_temp; - - lab_over = gen_label_rtx (); - lab_false = gen_label_rtx (); - - examine_argument (TYPE_MODE (type), type, 0, - &needed_intregs, &needed_sseregs); - - - need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64) - || TYPE_ALIGN (type) > 128); - - /* In case we are passing structure, verify that it is consecutive block - on the register save area. If not we need to do moves. */ - if (!need_temp && !REG_P (container)) - { - /* Verify that all registers are strictly consecutive */ - if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0)))) - { - int i; - - for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++) - { - rtx slot = XVECEXP (container, 0, i); - if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i - || INTVAL (XEXP (slot, 1)) != i * 16) - need_temp = 1; - } - } - else - { - int i; - - for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++) - { - rtx slot = XVECEXP (container, 0, i); - if (REGNO (XEXP (slot, 0)) != (unsigned int) i - || INTVAL (XEXP (slot, 1)) != i * 8) - need_temp = 1; - } - } - } - if (!need_temp) - { - int_addr_rtx = addr_rtx; - sse_addr_rtx = addr_rtx; - } - else - { - int_addr_rtx = gen_reg_rtx (Pmode); - sse_addr_rtx = gen_reg_rtx (Pmode); - } - /* First ensure that we fit completely in registers. */ - if (needed_intregs) - { - emit_cmp_and_jump_insns (expand_expr - (gpr, NULL_RTX, SImode, EXPAND_NORMAL), - GEN_INT ((REGPARM_MAX - needed_intregs + - 1) * 8), GE, const1_rtx, SImode, - 1, lab_false); - } - if (needed_sseregs) - { - emit_cmp_and_jump_insns (expand_expr - (fpr, NULL_RTX, SImode, EXPAND_NORMAL), - GEN_INT ((SSE_REGPARM_MAX - - needed_sseregs + 1) * 16 + - REGPARM_MAX * 8), GE, const1_rtx, - SImode, 1, lab_false); - } - - /* Compute index to start of area used for integer regs. */ - if (needed_intregs) - { - t = build (PLUS_EXPR, ptr_type_node, sav, gpr); - r = expand_expr (t, int_addr_rtx, Pmode, EXPAND_NORMAL); - if (r != int_addr_rtx) - emit_move_insn (int_addr_rtx, r); - } - if (needed_sseregs) - { - t = build (PLUS_EXPR, ptr_type_node, sav, fpr); - r = expand_expr (t, sse_addr_rtx, Pmode, EXPAND_NORMAL); - if (r != sse_addr_rtx) - emit_move_insn (sse_addr_rtx, r); - } - if (need_temp) - { - int i; - rtx mem; - rtx x; - - /* Never use the memory itself, as it has the alias set. */ - x = XEXP (assign_temp (type, 0, 1, 0), 0); - mem = gen_rtx_MEM (BLKmode, x); - force_operand (x, addr_rtx); - set_mem_alias_set (mem, get_varargs_alias_set ()); - set_mem_align (mem, BITS_PER_UNIT); - - for (i = 0; i < XVECLEN (container, 0); i++) - { - rtx slot = XVECEXP (container, 0, i); - rtx reg = XEXP (slot, 0); - enum machine_mode mode = GET_MODE (reg); - rtx src_addr; - rtx src_mem; - int src_offset; - rtx dest_mem; - - if (SSE_REGNO_P (REGNO (reg))) - { - src_addr = sse_addr_rtx; - src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16; - } - else - { - src_addr = int_addr_rtx; - src_offset = REGNO (reg) * 8; - } - src_mem = gen_rtx_MEM (mode, src_addr); - set_mem_alias_set (src_mem, get_varargs_alias_set ()); - src_mem = adjust_address (src_mem, mode, src_offset); - dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1))); - emit_move_insn (dest_mem, src_mem); - } - } - - if (needed_intregs) - { - t = - build (PLUS_EXPR, TREE_TYPE (gpr), gpr, - build_int_2 (needed_intregs * 8, 0)); - t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - if (needed_sseregs) - { - t = - build (PLUS_EXPR, TREE_TYPE (fpr), fpr, - build_int_2 (needed_sseregs * 16, 0)); - t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - emit_jump_insn (gen_jump (lab_over)); - emit_barrier (); - emit_label (lab_false); - } - - /* ... otherwise out of the overflow area. */ - - /* Care for on-stack alignment if needed. */ - if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64) - t = ovf; - else - { - HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8; - t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align - 1, 0)); - t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1)); - } - t = save_expr (t); - - r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); - if (r != addr_rtx) - emit_move_insn (addr_rtx, r); - - t = - build (PLUS_EXPR, TREE_TYPE (t), t, - build_int_2 (rsize * UNITS_PER_WORD, 0)); - t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - - if (container) - emit_label (lab_over); - - if (indirect_p) - { - r = gen_rtx_MEM (Pmode, addr_rtx); - set_mem_alias_set (r, get_varargs_alias_set ()); - emit_move_insn (addr_rtx, r); - } - - return addr_rtx; -} - -/* Lower VA_ARG_EXPR at gimplification time. */ tree ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 2cc64d1..61a1f9e 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1790,8 +1790,7 @@ typedef struct ix86_args { ix86_va_start (VALIST, NEXTARG) /* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \ - ix86_va_arg ((VALIST), (TYPE)) +#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) (abort (), NULL_RTX) #define TARGET_ASM_FILE_END ix86_file_end #define NEED_INDICATE_EXEC_STACK 0 diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 519dc05..c29fee4 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -3958,41 +3958,6 @@ ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) /* Implement va_arg. */ -rtx -ia64_va_arg (tree valist, tree type) -{ - tree t; - - /* Variable sized types are passed by reference. */ - if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - { - rtx addr = force_reg (ptr_mode, - std_expand_builtin_va_arg (valist, build_pointer_type (type))); -#ifdef POINTERS_EXTEND_UNSIGNED - addr = convert_memory_address (Pmode, addr); -#endif - return gen_rtx_MEM (ptr_mode, addr); - } - - /* Aggregate arguments with alignment larger than 8 bytes start at - the next even boundary. Integer and floating point arguments - do so if they are larger than 8 bytes, whether or not they are - also aligned larger than 8 bytes. */ - if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE) - ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT) - { - t = build (PLUS_EXPR, TREE_TYPE (valist), valist, - build_int_2 (2 * UNITS_PER_WORD - 1, 0)); - t = build (BIT_AND_EXPR, TREE_TYPE (t), t, - build_int_2 (-2 * UNITS_PER_WORD, -1)); - t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - return std_expand_builtin_va_arg (valist, type); -} - static tree ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index ef57c37..a26a1da 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1403,8 +1403,7 @@ do { \ || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS))) /* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - ia64_va_arg (valist, type) +#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) /* How Scalar Function Values are Returned */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 315cd50..2376fc4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5069,229 +5069,6 @@ rs6000_va_start (tree valist, rtx nextarg) /* Implement va_arg. */ -rtx -rs6000_va_arg (tree valist, tree type) -{ - tree f_gpr, f_fpr, f_res, f_ovf, f_sav; - tree gpr, fpr, ovf, sav, reg, t, u; - int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale; - rtx lab_false, lab_over, addr_rtx, r; - int align; - - if (DEFAULT_ABI != ABI_V4) - { - /* Variable sized types are passed by reference, as are AltiVec - vectors when 32-bit and not using the AltiVec ABI extension. */ - if (int_size_in_bytes (type) < 0 - || (TARGET_32BIT - && !TARGET_ALTIVEC_ABI - && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))) - { - u = build_pointer_type (type); - - /* Args grow upward. */ - t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist, - build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0)); - TREE_SIDE_EFFECTS (t) = 1; - - t = build1 (NOP_EXPR, build_pointer_type (u), t); - TREE_SIDE_EFFECTS (t) = 1; - - t = build1 (INDIRECT_REF, u, t); - TREE_SIDE_EFFECTS (t) = 1; - - return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL); - } - if (targetm.calls.split_complex_arg - && TREE_CODE (type) == COMPLEX_TYPE) - { - tree elem_type = TREE_TYPE (type); - enum machine_mode elem_mode = TYPE_MODE (elem_type); - int elem_size = GET_MODE_SIZE (elem_mode); - - if (elem_size < UNITS_PER_WORD) - { - rtx real_part, imag_part, dest_real, rr; - - real_part = rs6000_va_arg (valist, elem_type); - imag_part = rs6000_va_arg (valist, elem_type); - - /* We're not returning the value here, but the address. - real_part and imag_part are not contiguous, and we know - there is space available to pack real_part next to - imag_part. float _Complex is not promoted to - double _Complex by the default promotion rules that - promote float to double. */ - if (2 * elem_size > UNITS_PER_WORD) - abort (); - - real_part = gen_rtx_MEM (elem_mode, real_part); - imag_part = gen_rtx_MEM (elem_mode, imag_part); - - dest_real = adjust_address (imag_part, elem_mode, -elem_size); - rr = gen_reg_rtx (elem_mode); - emit_move_insn (rr, real_part); - emit_move_insn (dest_real, rr); - - return XEXP (dest_real, 0); - } - } - - return std_expand_builtin_va_arg (valist, type); - } - - f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = TREE_CHAIN (f_gpr); - f_res = TREE_CHAIN (f_fpr); - f_ovf = TREE_CHAIN (f_res); - f_sav = TREE_CHAIN (f_ovf); - - valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist); - gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr); - fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr); - ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf); - sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav); - - size = int_size_in_bytes (type); - rsize = (size + 3) / 4; - align = 1; - - if (AGGREGATE_TYPE_P (type) - || TYPE_MODE (type) == TFmode - || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))) - { - /* Aggregates, long doubles, and AltiVec vectors are passed by - reference. */ - indirect_p = 1; - reg = gpr; - n_reg = 1; - sav_ofs = 0; - sav_scale = 4; - size = 4; - rsize = 1; - } - else if (TARGET_HARD_FLOAT && TARGET_FPRS - && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode)) - { - /* FP args go in FP registers, if present. */ - indirect_p = 0; - reg = fpr; - n_reg = 1; - sav_ofs = 8*4; - sav_scale = 8; - if (TYPE_MODE (type) == DFmode) - align = 8; - } - else - { - /* Otherwise into GP registers. */ - indirect_p = 0; - reg = gpr; - n_reg = rsize; - sav_ofs = 0; - sav_scale = 4; - if (n_reg == 2) - align = 8; - } - - /* Pull the value out of the saved registers.... */ - - lab_over = NULL_RTX; - addr_rtx = gen_reg_rtx (Pmode); - - /* AltiVec vectors never go in registers when -mabi=altivec. */ - if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) - align = 16; - else - { - lab_false = gen_label_rtx (); - lab_over = gen_label_rtx (); - - /* Long long and SPE vectors are aligned in the registers. - As are any other 2 gpr item such as complex int due to a - historical mistake. */ - u = reg; - if (n_reg == 2) - { - u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg, - build_int_2 (n_reg - 1, 0)); - u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u); - TREE_SIDE_EFFECTS (u) = 1; - } - - emit_cmp_and_jump_insns - (expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL), - GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1, - lab_false); - - t = sav; - if (sav_ofs) - t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0)); - - u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, - build_int_2 (n_reg, 0)); - TREE_SIDE_EFFECTS (u) = 1; - - u = build1 (CONVERT_EXPR, integer_type_node, u); - TREE_SIDE_EFFECTS (u) = 1; - - u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0)); - TREE_SIDE_EFFECTS (u) = 1; - - t = build (PLUS_EXPR, ptr_type_node, t, u); - TREE_SIDE_EFFECTS (t) = 1; - - r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); - if (r != addr_rtx) - emit_move_insn (addr_rtx, r); - - emit_jump_insn (gen_jump (lab_over)); - emit_barrier (); - - emit_label (lab_false); - if (n_reg > 2) - { - /* Ensure that we don't find any more args in regs. - Alignment has taken care of the n_reg == 2 case. */ - t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0)); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - } - - /* ... otherwise out of the overflow area. */ - - /* Care for on-stack alignment if needed. */ - t = ovf; - if (align != 1) - { - t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0)); - t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1)); - } - t = save_expr (t); - - r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); - if (r != addr_rtx) - emit_move_insn (addr_rtx, r); - - t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0)); - t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - - if (lab_over) - emit_label (lab_over); - - if (indirect_p) - { - r = gen_rtx_MEM (Pmode, addr_rtx); - set_mem_alias_set (r, get_varargs_alias_set ()); - emit_move_insn (addr_rtx, r); - } - - return addr_rtx; -} - tree rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d08aca9..b3ec7f8 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1760,8 +1760,7 @@ typedef struct rs6000_args rs6000_va_start (valist, nextarg) /* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - rs6000_va_arg (valist, type) +#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) #define PAD_VARARGS_DOWN \ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 5be84c8..2f08388 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -5942,111 +5942,6 @@ sparc_va_start (tree valist, rtx nextarg) /* Implement `va_arg' for stdarg. */ -rtx -sparc_va_arg (tree valist, tree type) -{ - HOST_WIDE_INT size, rsize, align; - tree addr, incr; - rtx addr_rtx; - bool indirect; - - if (function_arg_pass_by_reference (0, TYPE_MODE (type), type, 0)) - { - indirect = true; - size = rsize = UNITS_PER_WORD; - align = 0; - } - else - { - indirect = false; - size = int_size_in_bytes (type); - rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD; - align = 0; - - if (TARGET_ARCH64) - { - /* For SPARC64, objects requiring 16-byte alignment get it. */ - if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD) - align = 2 * UNITS_PER_WORD; - - /* SPARC-V9 ABI states that structures up to 16 bytes in size - are given whole slots as needed. */ - if (AGGREGATE_TYPE_P (type)) - { - if (size == 0) - size = rsize = UNITS_PER_WORD; - else - size = rsize; - } - } - } - - incr = valist; - if (align) - { - incr = fold (build (PLUS_EXPR, ptr_type_node, incr, - build_int_2 (align - 1, 0))); - incr = fold (build (BIT_AND_EXPR, ptr_type_node, incr, - build_int_2 (-align, -1))); - } - - addr = incr = save_expr (incr); - if (BYTES_BIG_ENDIAN && size < rsize) - { - addr = fold (build (PLUS_EXPR, ptr_type_node, incr, - build_int_2 (rsize - size, 0))); - } - incr = fold (build (PLUS_EXPR, ptr_type_node, incr, - build_int_2 (rsize, 0))); - - incr = build (MODIFY_EXPR, ptr_type_node, valist, incr); - TREE_SIDE_EFFECTS (incr) = 1; - expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL); - - addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL); - - /* If the address isn't aligned properly for the type, - we may need to copy to a temporary. - FIXME: This is inefficient. Usually we can do this - in registers. */ - if (align == 0 - && TYPE_ALIGN (type) > BITS_PER_WORD - && !indirect) - { - /* FIXME: We really need to specify that the temporary is live - for the whole function because expand_builtin_va_arg wants - the alias set to be get_varargs_alias_set (), but in this - case the alias set is that for TYPE and if the memory gets - reused it will be reused with alias set TYPE. */ - rtx tmp = assign_temp (type, 0, 1, 0); - rtx dest_addr; - - addr_rtx = force_reg (Pmode, addr_rtx); - addr_rtx = gen_rtx_MEM (BLKmode, addr_rtx); - set_mem_alias_set (addr_rtx, get_varargs_alias_set ()); - set_mem_align (addr_rtx, BITS_PER_WORD); - tmp = shallow_copy_rtx (tmp); - PUT_MODE (tmp, BLKmode); - set_mem_alias_set (tmp, 0); - - dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize), - BLOCK_OP_NORMAL); - if (dest_addr != NULL_RTX) - addr_rtx = dest_addr; - else - addr_rtx = XCEXP (tmp, 0, MEM); - } - - if (indirect) - { - addr_rtx = force_reg (Pmode, addr_rtx); - addr_rtx = gen_rtx_MEM (Pmode, addr_rtx); - set_mem_alias_set (addr_rtx, get_varargs_alias_set ()); - } - - return addr_rtx; -} - tree sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index d1c8049..0b2dceb 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1804,8 +1804,7 @@ do { \ sparc_va_start (valist, nextarg) /* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - sparc_va_arg (valist, type) +#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) /* Generate RTL to flush the register windows so as to make arbitrary frames available. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 0d4d647..70b89f6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3870,11 +3870,15 @@ This hook performs target-specific gimplification of arguments to @code{va_arg}; the latter two are as in @code{gimplify.c:gimplify_expr}. -You only need to define this hook if you also define +You only need to define this hook if you previously defined @code{EXPAND_BUILTIN_VA_ARG}; it is pretty easy to reuse the same code for both. One significant difference is that @code{EXPAND_BUILTIN_VA_ARG} returns an address, whereas this hook produces an expression of type @var{type}, usually an @code{INDIRECT_REF}. + +Once you define this macro, you can change +@code{EXPAND_BUILTIN_VA_ARG} to just abort, as it should never be +called. @end deftypefn @node Scalar Return diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 7d38981..a4a0bc4 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1716,24 +1716,16 @@ tree_could_throw_p (tree t) return false; if (TREE_CODE (t) == MODIFY_EXPR) { - tree sub = TREE_OPERAND (t, 1); - if (TREE_CODE (sub) == CALL_EXPR) - t = sub; - else - { - if (flag_non_call_exceptions) - { - if (tree_could_trap_p (sub)) - return true; - return tree_could_trap_p (TREE_OPERAND (t, 0)); - } - return false; - } + if (flag_non_call_exceptions + && tree_could_trap_p (TREE_OPERAND (t, 0))) + return true; + t = TREE_OPERAND (t, 1); } if (TREE_CODE (t) == CALL_EXPR) return (call_expr_flags (t) & ECF_NOTHROW) == 0; - + if (flag_non_call_exceptions) + return tree_could_trap_p (t); return false; } diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index eae021e..b94a799 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -821,7 +821,11 @@ get_stmt_operands (tree stmt) if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR - || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR) + || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR + /* Use a V_MAY_DEF if the RHS might throw, as the LHS won't be + modified in that case. FIXME we should represent somehow + that it is killed on the fallthrough path. */ + || tree_could_throw_p (TREE_OPERAND (stmt, 1))) get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops); else |