X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftree-sra.c;h=45142e8e14cd07bef93c94b6b23f9231c9282183;hp=ba1db90a9962148f156e325d07d36ba3bab4835a;hb=35ba59f55d9a948599b1bce3a68d199ad580661d;hpb=8ca26bddc3c40df69f7b9446b99e6a3aa9404ed8 diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index ba1db90a996..45142e8e14c 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1162,17 +1162,18 @@ scan_function (void) static const struct sra_walk_fns fns = { scan_use, scan_copy, scan_init, scan_ldst, true }; + bitmap_iterator bi; sra_walk_function (&fns); if (dump_file && (dump_flags & TDF_DETAILS)) { - referenced_var_iterator ri; - tree var; + unsigned i; fputs ("\nScan results:\n", dump_file); - FOR_EACH_REFERENCED_VAR_IN_BITMAP (sra_candidates, var, ri) + EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi) { + tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); if (elt) scan_dump (elt); @@ -1279,9 +1280,6 @@ instantiate_element (struct sra_elt *elt) TYPE_SIZE (elt->type), DECL_SIZE (var)) : bitsize_int (0)); - if (!INTEGRAL_TYPE_P (elt->type) - || TYPE_UNSIGNED (elt->type)) - BIT_FIELD_REF_UNSIGNED (elt->replacement) = 1; } /* For vectors, if used on the left hand side with BIT_FIELD_REF, @@ -1676,12 +1674,17 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) /* Create the field group as a single variable. */ - type = lang_hooks.types.type_for_mode (mode, 1); + /* We used to create a type for the mode above, but size turns + to be out not of mode-size. As we need a matching type + to build a BIT_FIELD_REF, use a nonstandard integer type as + fallback. */ + type = lang_hooks.types.type_for_size (size, 1); + if (!type || TYPE_PRECISION (type) != size) + type = build_nonstandard_integer_type (size, 1); gcc_assert (type); var = build3 (BIT_FIELD_REF, type, NULL_TREE, bitsize_int (size), bitsize_int (bit)); - BIT_FIELD_REF_UNSIGNED (var) = 1; block = instantiate_missing_elements_1 (elt, var, type); gcc_assert (block && block->is_scalar); @@ -1695,7 +1698,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) TREE_TYPE (block->element), var, bitsize_int (size), bitsize_int (bit & ~alchk)); - BIT_FIELD_REF_UNSIGNED (block->replacement) = 1; } block->in_bitfld_block = 2; @@ -1718,7 +1720,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) + (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f)))) & ~alchk)); - BIT_FIELD_REF_UNSIGNED (fld->replacement) = TYPE_UNSIGNED (field_type); fld->in_bitfld_block = 1; } @@ -1949,18 +1950,19 @@ decide_block_copy (struct sra_elt *elt) static void decide_instantiations (void) { + unsigned int i; bool cleared_any; bitmap_head done_head; - referenced_var_iterator ri; - tree var; + bitmap_iterator bi; /* We cannot clear bits from a bitmap we're iterating over, so save up all the bits to clear until the end. */ bitmap_initialize (&done_head, &bitmap_default_obstack); cleared_any = false; - FOR_EACH_REFERENCED_VAR_IN_BITMAP (sra_candidates, var, ri) + EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi) { + tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); if (elt) { @@ -1970,7 +1972,7 @@ decide_instantiations (void) } if (!elt) { - bitmap_set_bit (&done_head, DECL_UID (var)); + bitmap_set_bit (&done_head, i); cleared_any = true; } } @@ -2137,9 +2139,10 @@ sra_build_assignment (tree dst, tree src) if (scalar_bitfield_p (src)) { tree var, shift, width; - tree utype, stype, stmp, utmp; + tree utype, stype, stmp, utmp, dtmp; tree list, stmt; - bool unsignedp = BIT_FIELD_REF_UNSIGNED (src); + bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src)) + ? TYPE_UNSIGNED (TREE_TYPE (src)) : true); var = TREE_OPERAND (src, 0); width = TREE_OPERAND (src, 1); @@ -2254,6 +2257,16 @@ sra_build_assignment (tree dst, tree src) var = fold_convert (TREE_TYPE (dst), var); else var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var); + + /* If the destination is not a register the conversion needs + to be a separate statement. */ + if (!is_gimple_reg (dst)) + { + dtmp = make_rename_temp (TREE_TYPE (dst), "SR"); + stmt = build_gimple_modify_stmt (dtmp, var); + append_to_statement_list (stmt, &list); + var = dtmp; + } } stmt = build_gimple_modify_stmt (dst, var); append_to_statement_list (stmt, &list); @@ -2479,6 +2492,7 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src) if (elt->in_bitfld_block == 2 && TREE_CODE (src) == BIT_FIELD_REF) { + tmp = src; cst = TYPE_SIZE (TREE_TYPE (var)); cst2 = size_binop (MINUS_EXPR, TREE_OPERAND (src, 2), TREE_OPERAND (dst, 2)); @@ -2524,8 +2538,7 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src) } else { - src = fold_build3 (BIT_FIELD_REF, TREE_TYPE (var), src, cst, cst2); - BIT_FIELD_REF_UNSIGNED (src) = 1; + src = fold_convert (TREE_TYPE (var), tmp); } return sra_build_assignment (var, src); @@ -3002,6 +3015,8 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, type = TREE_TYPE (infld); if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen)) type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (flen), 1); + else + type = unsigned_type_for (type); if (TREE_CODE (infld) == BIT_FIELD_REF) { @@ -3019,7 +3034,6 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, } infld = fold_build3 (BIT_FIELD_REF, type, infld, flen, fpos); - BIT_FIELD_REF_UNSIGNED (infld) = 1; invar = size_binop (MINUS_EXPR, flp.field_pos, bpos); if (flp.overlap_pos) @@ -3027,7 +3041,6 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var, invar = size_binop (PLUS_EXPR, invar, vpos); invar = fold_build3 (BIT_FIELD_REF, type, var, flen, invar); - BIT_FIELD_REF_UNSIGNED (invar) = 1; if (to_var) st = sra_build_bf_assignment (invar, infld); @@ -3530,11 +3543,12 @@ static void scalarize_parms (void) { tree list = NULL; - referenced_var_iterator ri; - tree var; + unsigned i; + bitmap_iterator bi; - FOR_EACH_REFERENCED_VAR_IN_BITMAP (needs_copy_in, var, ri) + EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i, bi) { + tree var = referenced_var (i); struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT); generate_copy_inout (elt, true, var, &list); }