diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-12-03 13:27:48 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-12-03 13:27:48 +0100 |
commit | ff1fe457370d6f33071747b0dfd1b76dff7e247a (patch) | |
tree | 5ba418443623690434ede1e71ba81639b49d733b /gcc/tree-sra.c | |
parent | d5fdc62c3fe523b1104bcccaa3f66f7fa5298d9f (diff) | |
download | gcc-ff1fe457370d6f33071747b0dfd1b76dff7e247a.zip gcc-ff1fe457370d6f33071747b0dfd1b76dff7e247a.tar.gz gcc-ff1fe457370d6f33071747b0dfd1b76dff7e247a.tar.bz2 |
re PR tree-optimization/37716 (ice for legal C++ code with -O2 on 20080926)
PR tree-optimization/37716
* tree-sra.c (sra_build_assignment): For scalar bitfield SRC construct
all the needed operations as trees and gimplify_assign it to dst.
* g++.dg/torture/pr37716.C: New test.
From-SVN: r142392
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 86 |
1 files changed, 25 insertions, 61 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 60330b1..3225d10 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2158,9 +2158,10 @@ sra_build_assignment (tree dst, tree src) if (scalar_bitfield_p (src)) { tree var, shift, width; - tree utype, stype, stmp, utmp, dtmp; + tree utype, stype; bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src)) ? TYPE_UNSIGNED (TREE_TYPE (src)) : true); + struct gimplify_ctx gctx; var = TREE_OPERAND (src, 0); width = TREE_OPERAND (src, 1); @@ -2191,28 +2192,15 @@ sra_build_assignment (tree dst, tree src) else if (!TYPE_UNSIGNED (utype)) utype = unsigned_type_for (utype); - stmp = make_rename_temp (stype, "SR"); - /* Convert the base var of the BIT_FIELD_REF to the scalar type we use for computation if we cannot use it directly. */ - if (!useless_type_conversion_p (stype, TREE_TYPE (var))) - { - if (INTEGRAL_TYPE_P (TREE_TYPE (var))) - stmt = gimple_build_assign (stmp, fold_convert (stype, var)); - else - stmt = gimple_build_assign (stmp, fold_build1 (VIEW_CONVERT_EXPR, - stype, var)); - gimple_seq_add_stmt (&seq, stmt); - var = stmp; - } + if (INTEGRAL_TYPE_P (TREE_TYPE (var))) + var = fold_convert (stype, var); + else + var = fold_build1 (VIEW_CONVERT_EXPR, stype, var); if (!integer_zerop (shift)) - { - stmt = gimple_build_assign (stmp, fold_build2 (RSHIFT_EXPR, stype, - var, shift)); - gimple_seq_add_stmt (&seq, stmt); - var = stmp; - } + var = fold_build2 (RSHIFT_EXPR, stype, var, shift); /* If we need a masking operation, produce one. */ if (TREE_INT_CST_LOW (width) == TYPE_PRECISION (stype)) @@ -2222,24 +2210,11 @@ sra_build_assignment (tree dst, tree src) tree one = build_int_cst_wide (stype, 1, 0); tree mask = int_const_binop (LSHIFT_EXPR, one, width, 0); mask = int_const_binop (MINUS_EXPR, mask, one, 0); - - stmt = gimple_build_assign (stmp, fold_build2 (BIT_AND_EXPR, stype, - var, mask)); - gimple_seq_add_stmt (&seq, stmt); - var = stmp; + var = fold_build2 (BIT_AND_EXPR, stype, var, mask); } /* After shifting and masking, convert to the target type. */ - utmp = stmp; - if (!useless_type_conversion_p (utype, stype)) - { - utmp = make_rename_temp (utype, "SR"); - - stmt = gimple_build_assign (utmp, fold_convert (utype, var)); - gimple_seq_add_stmt (&seq, stmt); - - var = utmp; - } + var = fold_convert (utype, var); /* Perform sign extension, if required. ??? This should never be necessary. */ @@ -2250,40 +2225,29 @@ sra_build_assignment (tree dst, tree src) size_binop (MINUS_EXPR, width, bitsize_int (1)), 0); - stmt = gimple_build_assign (utmp, fold_build2 (BIT_XOR_EXPR, utype, - var, signbit)); - gimple_seq_add_stmt (&seq, stmt); - - stmt = gimple_build_assign (utmp, fold_build2 (MINUS_EXPR, utype, - utmp, signbit)); - gimple_seq_add_stmt (&seq, stmt); - - var = utmp; + var = fold_build2 (BIT_XOR_EXPR, utype, var, signbit); + var = fold_build2 (MINUS_EXPR, utype, var, signbit); } /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast. */ STRIP_NOPS (dst); /* Finally, move and convert to the destination. */ - if (!useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (var))) - { - if (INTEGRAL_TYPE_P (TREE_TYPE (dst))) - var = fold_convert (TREE_TYPE (dst), var); - else - var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var); + if (INTEGRAL_TYPE_P (TREE_TYPE (dst))) + 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 = gimple_build_assign (dtmp, var); - gimple_seq_add_stmt (&seq, stmt); - var = dtmp; - } - } - stmt = gimple_build_assign (dst, var); - gimple_seq_add_stmt (&seq, stmt); + push_gimplify_context (&gctx); + gctx.into_ssa = true; + gctx.allow_rhs_cond_expr = true; + + gimplify_assign (dst, var, &seq); + + if (gimple_referenced_vars (cfun)) + for (var = gctx.temps; var; var = TREE_CHAIN (var)) + add_referenced_var (var); + pop_gimplify_context (NULL); return seq; } |