From: Richard Henderson Date: Fri, 16 Jul 2004 23:25:51 +0000 (-0700) Subject: builtins.c (std_expand_builtin_va_arg): Remove. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=77c9db7751b8239833f152701b7cde02569859e0;p=gcc.git builtins.c (std_expand_builtin_va_arg): Remove. * builtins.c (std_expand_builtin_va_arg): Remove. (expand_builtin_va_arg): Remove. * expr.h: Don't declare them. * gimplify.c (mark_decls_volatile_r): Remove. (copy_if_shared_r): Don't call it. * target-def.h: Don't test EXPAND_BUILTIN_VA_ARG. * expr.c (expand_expr_real_1): Don't handle VA_ARG_EXPR. * gimple-low.c (lower_stmt): Likewise. * tree-cfg.c (cfg_remove_useless_stmts_bb): Likewise. * tree-gimple.c (is_gimple_tmp_rhs, is_gimple_stmt): Likewise. * tree-ssa-operands.c (get_expr_operands): Likewise. * doc/tm.texi (TARGET_GIMPLIFY_VA_ARG_EXPR): Don't mention EXPAND_BUILTIN_VA_ARG. * system.h (EXPAND_BUILTIN_VA_ARG): Poison. * config/alpha/alpha.h, config/alpha/unicosmk.h, config/i386/i386.h, config/ia64/ia64.h, config/rs6000/rs6000.h, config/s390/s390.h, config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Remove. From-SVN: r84842 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a89927f3f14..34dfd963b07 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2004-07-16 Richard Henderson + + * builtins.c (std_expand_builtin_va_arg): Remove. + (expand_builtin_va_arg): Remove. + * expr.h: Don't declare them. + * gimplify.c (mark_decls_volatile_r): Remove. + (copy_if_shared_r): Don't call it. + * target-def.h: Don't test EXPAND_BUILTIN_VA_ARG. + * expr.c (expand_expr_real_1): Don't handle VA_ARG_EXPR. + * gimple-low.c (lower_stmt): Likewise. + * tree-cfg.c (cfg_remove_useless_stmts_bb): Likewise. + * tree-gimple.c (is_gimple_tmp_rhs, is_gimple_stmt): Likewise. + * tree-ssa-operands.c (get_expr_operands): Likewise. + * doc/tm.texi (TARGET_GIMPLIFY_VA_ARG_EXPR): Don't mention + EXPAND_BUILTIN_VA_ARG. + * system.h (EXPAND_BUILTIN_VA_ARG): Poison. + * config/alpha/alpha.h, config/alpha/unicosmk.h, config/i386/i386.h, + config/ia64/ia64.h, config/rs6000/rs6000.h, config/s390/s390.h, + config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Remove. + 2004-07-16 Daniel Berlin * tree-ssa-pre.c (insert_aux): Break out if we hit diff --git a/gcc/builtins.c b/gcc/builtins.c index d83b0de27de..de2cca6de17 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4288,186 +4288,6 @@ expand_builtin_va_start (tree arglist) /* The "standard" implementation of va_arg: read the value from the current (padded) address and increment by the (padded) size. */ -rtx -std_expand_builtin_va_arg (tree valist, tree type) -{ - tree addr_tree, t, type_size = NULL; - tree align, alignm1; - tree rounded_size; - rtx addr; - HOST_WIDE_INT boundary; - - /* Compute the rounded size of the type. */ - align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); - alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); - boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); - - /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually - requires greater alignment, we must perform dynamic alignment. */ - - if (boundary > PARM_BOUNDARY) - { - if (!PAD_VARARGS_DOWN) - { - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, - build2 (PLUS_EXPR, TREE_TYPE (valist), valist, - build_int_2 (boundary / BITS_PER_UNIT - 1, 0))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, - build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist, - build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - 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 (build2 (PLUS_EXPR, sizetype, type_size, alignm1)); - rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype, - rounded_size, align)); - rounded_size = fold (build2 (MULT_EXPR, sizetype, - rounded_size, align)); - } - - /* Get AP. */ - addr_tree = valist; - if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size)) - { - /* Small args are padded downward. */ - addr_tree = fold (build2 (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, - fold (build3 (COND_EXPR, sizetype, - fold (build2 (GT_EXPR, sizetype, - rounded_size, - align)), - size_zero_node, - fold (build2 (MINUS_EXPR, - sizetype, - rounded_size, - type_size)))))); - } - - addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); - addr = copy_to_reg (addr); - - /* Compute new value for AP. */ - if (! integer_zerop (rounded_size)) - { - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, - build2 (PLUS_EXPR, TREE_TYPE (valist), valist, - rounded_size)); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - return addr; -} - -/* Expand __builtin_va_arg, which is not really a builtin function, but - a very special sort of operator. */ - -rtx -expand_builtin_va_arg (tree valist, tree type) -{ - rtx addr, result; - tree promoted_type, want_va_type, have_va_type; - - /* Verify that valist is of the proper type. */ - - want_va_type = va_list_type_node; - have_va_type = TREE_TYPE (valist); - if (TREE_CODE (want_va_type) == ARRAY_TYPE) - { - /* If va_list is an array type, the argument may have decayed - to a pointer type, e.g. by being passed to another function. - In that case, unwrap both types so that we can compare the - underlying records. */ - if (TREE_CODE (have_va_type) == ARRAY_TYPE - || TREE_CODE (have_va_type) == POINTER_TYPE) - { - want_va_type = TREE_TYPE (want_va_type); - have_va_type = TREE_TYPE (have_va_type); - } - } - if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type)) - { - error ("first argument to `va_arg' not of type `va_list'"); - addr = const0_rtx; - } - - /* Generate a diagnostic for requesting data of a type that cannot - be passed through `...' due to type promotion at the call site. */ - else if ((promoted_type = lang_hooks.types.type_promotes_to (type)) - != type) - { - const char *name = "", *pname = 0; - static bool gave_help; - - if (TYPE_NAME (type)) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type))) - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - if (TYPE_NAME (promoted_type)) - { - if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE) - pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type)); - else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (promoted_type))) - pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type))); - } - - /* Unfortunately, this is merely undefined, rather than a constraint - violation, so we cannot make this an error. If this call is never - executed, the program is still strictly conforming. */ - warning ("`%s' is promoted to `%s' when passed through `...'", - name, pname); - if (! gave_help) - { - gave_help = true; - warning ("(so you should pass `%s' not `%s' to `va_arg')", - pname, name); - } - - /* We can, however, treat "undefined" any way we please. - Call abort to encourage the user to fix the program. */ - inform ("if this code is reached, the program will abort"); - expand_builtin_trap (); - - /* This is dead code, but go ahead and finish so that the - mode of the result comes out right. */ - addr = const0_rtx; - } - else - { - /* Make it easier for the backends by protecting the valist argument - from multiple evaluations. */ - valist = stabilize_va_list (valist, 0); - -#ifdef EXPAND_BUILTIN_VA_ARG - addr = EXPAND_BUILTIN_VA_ARG (valist, type); -#else - addr = std_expand_builtin_va_arg (valist, type); -#endif - } - - addr = convert_memory_address (Pmode, addr); - - result = gen_rtx_MEM (TYPE_MODE (type), addr); - set_mem_alias_set (result, get_varargs_alias_set ()); - - return result; -} - -/* Like std_expand_builtin_va_arg, but gimplify instead of expanding. */ - tree std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) { @@ -4550,7 +4370,8 @@ dummy_object (tree type) return build1 (INDIRECT_REF, type, t); } -/* Like expand_builtin_va_arg, but gimplify instead of expanding. */ +/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a + builtin function, but a very special sort of operator. */ enum gimplify_status gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index b77a9bce290..15b3a09d7a8 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1675,9 +1675,6 @@ do { \ /* Implement `va_start' for varargs and stdarg. */ #define EXPAND_BUILTIN_VA_START(valist, nextarg) \ alpha_va_start (valist, nextarg) - -/* Implement `va_arg'. */ -#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/alpha/unicosmk.h b/gcc/config/alpha/unicosmk.h index 7c9a6073fa6..c0aac5330e8 100644 --- a/gcc/config/alpha/unicosmk.h +++ b/gcc/config/alpha/unicosmk.h @@ -483,6 +483,5 @@ ssib_section (void) \ #define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma" #undef EXPAND_BUILTIN_VA_START -#undef EXPAND_BUILTIN_VA_ARG #define EH_FRAME_IN_DATA_SECTION 1 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index c85c8892893..da73bfefcd9 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1769,9 +1769,6 @@ typedef struct ix86_args { #define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \ ix86_va_start (VALIST, NEXTARG) -/* Implement `va_arg'. */ -#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.h b/gcc/config/ia64/ia64.h index a0ff4806594..d2a9ca3769f 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1386,9 +1386,6 @@ do { \ (((REGNO) >= AR_ARG_FIRST && (REGNO) < (AR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \ || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS))) -/* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) - /* How Scalar Function Values are Returned */ /* A C expression to create an RTX representing the place where a function diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index fdf3d4afef9..f69b10cc3c0 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1754,9 +1754,6 @@ typedef struct rs6000_args #define EXPAND_BUILTIN_VA_START(valist, nextarg) \ rs6000_va_start (valist, nextarg) -/* Implement `va_arg'. */ -#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/s390/s390.h b/gcc/config/s390/s390.h index 3c32f0c1588..f4d91fa13bb 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -704,10 +704,6 @@ CUMULATIVE_ARGS; #define EXPAND_BUILTIN_VA_START(valist, nextarg) \ s390_va_start (valist, nextarg) -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - (abort (), NULL_RTX) - - /* Trampolines for nested functions. */ #define TRAMPOLINE_SIZE (TARGET_64BIT ? 36 : 20) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 4b073377869..db72f351111 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1860,9 +1860,6 @@ do { \ #define EXPAND_BUILTIN_VA_START(valist, nextarg) \ sparc_va_start (valist, nextarg) -/* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX) - /* Generate RTL to flush the register windows so as to make arbitrary frames available. */ #define SETUP_FRAME_ADDRESSES() \ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index dad9e9a8a50..30c58d6511e 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3882,16 +3882,6 @@ This hook performs target-specific gimplification of @code{VA_ARG_EXPR}. The first two parameters correspond to the 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 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/expr.c b/gcc/expr.c index dd1aad9cc32..417f69cfccc 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8541,12 +8541,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case WITH_CLEANUP_EXPR: case CLEANUP_POINT_EXPR: case TARGET_EXPR: + case VA_ARG_EXPR: /* Lowered by gimplify.c. */ abort (); - case VA_ARG_EXPR: - return expand_builtin_va_arg (TREE_OPERAND (exp, 0), type); - case EXC_PTR_EXPR: return get_exception_pointer (cfun); diff --git a/gcc/expr.h b/gcc/expr.h index ebd30c3b6f9..d3fab31fb4a 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -351,8 +351,6 @@ extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx); extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int); extern tree std_build_builtin_va_list (void); extern void std_expand_builtin_va_start (tree, rtx); -extern rtx std_expand_builtin_va_arg (tree, tree); -extern rtx expand_builtin_va_arg (tree, tree); extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int); extern void expand_builtin_setjmp_setup (rtx, rtx); extern void expand_builtin_setjmp_receiver (rtx); diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index b3b6af71ab8..f164bd92ef1 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -195,7 +195,6 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) case CALL_EXPR: case GOTO_EXPR: case LABEL_EXPR: - case VA_ARG_EXPR: case SWITCH_EXPR: break; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 6cf5d486b3f..34f1b3e4dc2 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -608,20 +608,6 @@ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } -/* Mark all the _DECL nodes under *TP as volatile. FIXME: This must die - after VA_ARG_EXPRs are properly lowered. */ - -static tree -mark_decls_volatile_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) -{ - if (SSA_VAR_P (*tp)) - TREE_THIS_VOLATILE (*tp) = 1; - - return NULL_TREE; -} - - /* Callback for walk_tree to unshare most of the shared trees rooted at *TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1), then *TP is deep copied by calling copy_tree_r. @@ -662,23 +648,7 @@ copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, /* Otherwise, mark the tree as visited and keep looking. */ else - { - TREE_VISITED (t) = 1; - if (TREE_CODE (*tp) == VA_ARG_EXPR - && targetm.gimplify_va_arg_expr == NULL) - { - /* Mark any _DECL inside the operand as volatile to avoid - the optimizers messing around with it. We have to do this - early, otherwise we might mark a variable as volatile - after we gimplify other statements that use the variable - assuming it's not volatile. */ - - /* FIXME once most targets define the above hook, this should - go away (perhaps along with the #include "target.h"). */ - walk_tree (&TREE_OPERAND (*tp, 0), mark_decls_volatile_r, - NULL, NULL); - } - } + TREE_VISITED (t) = 1; return NULL_TREE; } diff --git a/gcc/system.h b/gcc/system.h index 26dccf4c70a..dfc8b089c71 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -623,7 +623,7 @@ extern int snprintf (char *, size_t, const char *, ...); DBX_OUTPUT_STANDARD_TYPES BUILTIN_SETJMP_FRAME_VALUE \ SUNOS4_SHARED_LIBRARIES PROMOTE_FOR_CALL_ONLY \ SPACE_AFTER_L_OPTION NO_RECURSIVE_FUNCTION_CSE \ - DEFAULT_MAIN_RETURN TARGET_MEM_FUNCTIONS + DEFAULT_MAIN_RETURN TARGET_MEM_FUNCTIONS EXPAND_BUILTIN_VA_ARG /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ diff --git a/gcc/target-def.h b/gcc/target-def.h index 4cf40b5b8c6..242d5351d34 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -359,13 +359,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. default_pretend_outgoing_varargs_named #define TARGET_SPLIT_COMPLEX_ARG NULL -#ifdef EXPAND_BUILTIN_VA_ARG -/* If there's a target-specific va_arg expander, there needs to be a - target-specific gimplifier. */ -#define TARGET_GIMPLIFY_VA_ARG_EXPR NULL -#else #define TARGET_GIMPLIFY_VA_ARG_EXPR std_gimplify_va_arg_expr -#endif #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_false diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f6bb8e01b60..f3df4e2c221 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1734,11 +1734,8 @@ cfg_remove_useless_stmts_bb (basic_block bb) /* Invalidate the var if we encounter something that could modify it. */ if (TREE_CODE (stmt) == ASM_EXPR - || TREE_CODE (stmt) == VA_ARG_EXPR || (TREE_CODE (stmt) == MODIFY_EXPR - && (TREE_OPERAND (stmt, 0) == var - || TREE_OPERAND (stmt, 0) == val - || TREE_CODE (TREE_OPERAND (stmt, 1)) == VA_ARG_EXPR))) + && TREE_OPERAND (stmt, 0) == var)) return; bsi_next (&bsi); diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index c081b5aabae..488173fb620 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -219,8 +219,6 @@ is_gimple_tmp_rhs (tree t) case CALL_EXPR: case CONSTRUCTOR: case COMPLEX_EXPR: - /* FIXME lower VA_ARG_EXPR. */ - case VA_ARG_EXPR: case INTEGER_CST: case REAL_CST: case STRING_CST: @@ -389,10 +387,6 @@ is_gimple_stmt (tree t) /* These are always void. */ return true; - case VA_ARG_EXPR: - /* FIXME this should be lowered. */ - return true; - case CALL_EXPR: case MODIFY_EXPR: /* These are valid regardless of their type. */ diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 9b2974136a8..c1c967a53a9 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -808,8 +808,8 @@ get_stmt_operands (tree stmt) default: /* Notice that if get_expr_operands tries to use &STMT as the operand pointer (which may only happen for USE operands), we will abort in - append_use. This default will handle statements like empty statements, - CALL_EXPRs or VA_ARG_EXPRs that may appear on the RHS of a statement + append_use. This default will handle statements like empty + statements, or CALL_EXPRs that may appear on the RHS of a statement or as statements themselves. */ get_expr_operands (stmt, &stmt, opf_none, &prev_vops); break; @@ -964,13 +964,6 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) return; } - case VA_ARG_EXPR: - /* Mark VA_ARG_EXPR nodes as making volatile references. FIXME, - this is needed because we currently do not gimplify VA_ARG_EXPR - properly. */ - stmt_ann (stmt)->has_volatile_ops = true; - return; - case CONSTRUCTOR: { /* General aggregate CONSTRUCTORs have been decomposed, but they