- else
- /* Vectors do not have domains; look up the domain of
- the array embedded in the debug representation type.
- FIXME Would probably be more efficient to treat vectors
- separately from arrays. */
- {
- domain = TYPE_DEBUG_REPRESENTATION_TYPE (type);
- domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain)));
- if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target)))
- {
- enum machine_mode mode = GET_MODE (target);
-
- icode = (int) vec_init_optab->handlers[mode].insn_code;
- if (icode != CODE_FOR_nothing)
- {
- unsigned int i;
-
- elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
- n_elts = (GET_MODE_SIZE (mode) / elt_size);
- vector = alloca (n_elts);
- for (i = 0; i < n_elts; i++)
- vector [i] = CONST0_RTX (GET_MODE_INNER (mode));
- }
- }
- }
-
- const_bounds_p = (TYPE_MIN_VALUE (domain)
- && TYPE_MAX_VALUE (domain)
- && host_integerp (TYPE_MIN_VALUE (domain), 0)
- && host_integerp (TYPE_MAX_VALUE (domain), 0));
-
- /* If we have constant bounds for the range of the type, get them. */
- if (const_bounds_p)
- {
- minelt = tree_low_cst (TYPE_MIN_VALUE (domain), 0);
- maxelt = tree_low_cst (TYPE_MAX_VALUE (domain), 0);
- }
-
- /* If the constructor has fewer elements than the array,
- clear the whole array first. Similarly if this is
- static constructor of a non-BLKmode object. */
- if (cleared || (REG_P (target) && TREE_STATIC (exp)))
- need_to_clear = 1;
- else
- {
- HOST_WIDE_INT count = 0, zero_count = 0;
- need_to_clear = ! const_bounds_p;
-
- /* This loop is a more accurate version of the loop in
- mostly_zeros_p (it handles RANGE_EXPR in an index).
- It is also needed to check for missing elements. */
- for (elt = CONSTRUCTOR_ELTS (exp);
- elt != NULL_TREE && ! need_to_clear;
- elt = TREE_CHAIN (elt))
- {
- tree index = TREE_PURPOSE (elt);
- HOST_WIDE_INT this_node_count;
-
- if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
- {
- tree lo_index = TREE_OPERAND (index, 0);
- tree hi_index = TREE_OPERAND (index, 1);
-
- if (! host_integerp (lo_index, 1)
- || ! host_integerp (hi_index, 1))
- {
- need_to_clear = 1;
- break;
- }
-
- this_node_count = (tree_low_cst (hi_index, 1)
- - tree_low_cst (lo_index, 1) + 1);
- }
- else
- this_node_count = 1;
-
- count += this_node_count;
- if (mostly_zeros_p (TREE_VALUE (elt)))
- zero_count += this_node_count;
- }
-
- /* Clear the entire array first if there are any missing elements,
- or if the incidence of zero elements is >= 75%. */
- if (! need_to_clear
- && (count < maxelt - minelt + 1 || 4 * zero_count >= 3 * count))
- need_to_clear = 1;
- }
-
- if (need_to_clear && size > 0 && !vector)
- {
- if (! cleared)
- {
- if (REG_P (target))
- emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
- else
- clear_storage (target, GEN_INT (size));
- }
- cleared = 1;
- }
- else if (REG_P (target))
- /* Inform later passes that the old value is dead. */
- emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-
- /* Store each element of the constructor into
- the corresponding element of TARGET, determined
- by counting the elements. */
- for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
- elt;
- elt = TREE_CHAIN (elt), i++)
- {
- enum machine_mode mode;
- HOST_WIDE_INT bitsize;
- HOST_WIDE_INT bitpos;
- int unsignedp;
- tree value = TREE_VALUE (elt);
- tree index = TREE_PURPOSE (elt);
- rtx xtarget = target;
-
- if (cleared && initializer_zerop (value))
- continue;
-
- unsignedp = TYPE_UNSIGNED (elttype);
- mode = TYPE_MODE (elttype);
- if (mode == BLKmode)
- bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
- ? tree_low_cst (TYPE_SIZE (elttype), 1)
- : -1);
- else
- bitsize = GET_MODE_BITSIZE (mode);
-
- if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
- {
- tree lo_index = TREE_OPERAND (index, 0);
- tree hi_index = TREE_OPERAND (index, 1);
- rtx index_r, pos_rtx;
- HOST_WIDE_INT lo, hi, count;
- tree position;
-
- if (vector)
- abort ();
-
- /* If the range is constant and "small", unroll the loop. */
- if (const_bounds_p
- && host_integerp (lo_index, 0)
- && host_integerp (hi_index, 0)
- && (lo = tree_low_cst (lo_index, 0),
- hi = tree_low_cst (hi_index, 0),
- count = hi - lo + 1,
- (!MEM_P (target)
- || count <= 2
- || (host_integerp (TYPE_SIZE (elttype), 1)
- && (tree_low_cst (TYPE_SIZE (elttype), 1) * count
- <= 40 * 8)))))
- {
- lo -= minelt; hi -= minelt;
- for (; lo <= hi; lo++)
- {
- bitpos = lo * tree_low_cst (TYPE_SIZE (elttype), 0);
-
- if (MEM_P (target)
- && !MEM_KEEP_ALIAS_SET_P (target)
- && TREE_CODE (type) == ARRAY_TYPE
- && TYPE_NONALIASED_COMPONENT (type))
- {
- target = copy_rtx (target);
- MEM_KEEP_ALIAS_SET_P (target) = 1;
- }
-
- store_constructor_field
- (target, bitsize, bitpos, mode, value, type, cleared,
- get_alias_set (elttype));
- }
- }
- else
- {
- rtx loop_start = gen_label_rtx ();
- rtx loop_end = gen_label_rtx ();
- tree exit_cond;
-
- expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
- unsignedp = TYPE_UNSIGNED (domain);
-
- index = build_decl (VAR_DECL, NULL_TREE, domain);
-
- index_r
- = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
- &unsignedp, 0));
- SET_DECL_RTL (index, index_r);
- store_expr (lo_index, index_r, 0);
-
- /* Build the head of the loop. */
- do_pending_stack_adjust ();
- emit_queue ();
- emit_label (loop_start);
-
- /* Assign value to element index. */
- position
- = convert (ssizetype,
- fold (build (MINUS_EXPR, TREE_TYPE (index),
- index, TYPE_MIN_VALUE (domain))));
- position = size_binop (MULT_EXPR, position,
- convert (ssizetype,
- TYPE_SIZE_UNIT (elttype)));
-
- pos_rtx = expand_expr (position, 0, VOIDmode, 0);
- xtarget = offset_address (target, pos_rtx,
- highest_pow2_factor (position));
- xtarget = adjust_address (xtarget, mode, 0);
- if (TREE_CODE (value) == CONSTRUCTOR)
- store_constructor (value, xtarget, cleared,
- bitsize / BITS_PER_UNIT);
- else
- store_expr (value, xtarget, 0);
-
- /* Generate a conditional jump to exit the loop. */
- exit_cond = build (LT_EXPR, integer_type_node,
- index, hi_index);
- jumpif (exit_cond, loop_end);
-
- /* Update the loop counter, and jump to the head of
- the loop. */
- expand_increment (build (PREINCREMENT_EXPR,
- TREE_TYPE (index),
- index, integer_one_node), 0, 0);
- emit_jump (loop_start);
-
- /* Build the end of the loop. */
- emit_label (loop_end);
- }
- }
- else if ((index != 0 && ! host_integerp (index, 0))
- || ! host_integerp (TYPE_SIZE (elttype), 1))
- {
- tree position;
-
- if (vector)
- abort ();
-
- if (index == 0)
- index = ssize_int (1);
-
- if (minelt)
- index = convert (ssizetype,
- fold (build (MINUS_EXPR, index,
- TYPE_MIN_VALUE (domain))));
-
- position = size_binop (MULT_EXPR, index,
- convert (ssizetype,
- TYPE_SIZE_UNIT (elttype)));
- xtarget = offset_address (target,
- expand_expr (position, 0, VOIDmode, 0),
- highest_pow2_factor (position));
- xtarget = adjust_address (xtarget, mode, 0);
- store_expr (value, xtarget, 0);
- }
- else if (vector)
- {
- int pos;
-
- if (index != 0)
- pos = tree_low_cst (index, 0) - minelt;
- else
- pos = i;
- vector[pos] = expand_expr (value, NULL_RTX, VOIDmode, 0);
- }
- else
- {
- if (index != 0)
- bitpos = ((tree_low_cst (index, 0) - minelt)
- * tree_low_cst (TYPE_SIZE (elttype), 1));
- else
- bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1));
-
- if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
- && TREE_CODE (type) == ARRAY_TYPE
- && TYPE_NONALIASED_COMPONENT (type))
- {
- target = copy_rtx (target);
- MEM_KEEP_ALIAS_SET_P (target) = 1;
- }
- store_constructor_field (target, bitsize, bitpos, mode, value,
- type, cleared, get_alias_set (elttype));
- }
- }
- if (vector)
- {
- emit_insn (GEN_FCN (icode) (target,
- gen_rtx_PARALLEL (GET_MODE (target),
- gen_rtvec_v (n_elts, vector))));
- }
- }