X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flower-subreg.c;h=3563cee0824e8da863409dc084290171398b5705;hb=54c0191177db8bc27fb599a7d0d7a5866c5046fb;hp=3301a9db18c8bc22d7bc77974b6717ea7283874a;hpb=da7a04f1ae5b3db6d7165379c62aac7d1269ae1e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 3301a9db18c..3563cee0824 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "recog.h" #include "bitmap.h" +#include "dce.h" #include "expr.h" #include "except.h" #include "regs.h" @@ -63,6 +64,12 @@ static bitmap decomposable_context; which it can not be decomposed. */ static bitmap non_decomposable_context; +/* Bit N in this bitmap is set if regno N is used in a subreg + which changes the mode but not the size. This typically happens + when the register accessed as a floating-point value; we want to + avoid generating accesses to its subwords in integer modes. */ +static bitmap subreg_context; + /* Bit N in the bitmap in element M of this array is set if there is a copy from reg M to reg N. */ static VEC(bitmap,heap) *reg_copy_graph; @@ -289,6 +296,7 @@ find_decomposable_subregs (rtx *px, void *data) && !MODES_TIEABLE_P (GET_MODE (x), GET_MODE (inner))) { bitmap_set_bit (non_decomposable_context, regno); + bitmap_set_bit (subreg_context, regno); return -1; } } @@ -388,7 +396,7 @@ simplify_subreg_concatn (enum machine_mode outermode, rtx op, unsigned int byte) { unsigned int inner_size; - enum machine_mode innermode; + enum machine_mode innermode, partmode; rtx part; unsigned int final_offset; @@ -401,11 +409,24 @@ simplify_subreg_concatn (enum machine_mode outermode, rtx op, inner_size = GET_MODE_SIZE (innermode) / XVECLEN (op, 0); part = XVECEXP (op, 0, byte / inner_size); + partmode = GET_MODE (part); + + /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of + regular CONST_VECTORs. They have vector or integer modes, depending + on the capabilities of the target. Cope with them. */ + if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) + partmode = GET_MODE_INNER (innermode); + else if (partmode == VOIDmode) + { + enum mode_class mclass = GET_MODE_CLASS (innermode); + partmode = mode_for_size (inner_size * BITS_PER_UNIT, mclass, 0); + } + final_offset = byte % inner_size; if (final_offset + GET_MODE_SIZE (outermode) > inner_size) return NULL_RTX; - return simplify_gen_subreg (outermode, part, GET_MODE (part), final_offset); + return simplify_gen_subreg (outermode, part, partmode, final_offset); } /* Wrapper around simplify_gen_subreg which handles CONCATN. */ @@ -616,7 +637,7 @@ can_decompose_p (rtx x) return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD) && HARD_REGNO_MODE_OK (regno, word_mode)); else - return !bitmap_bit_p (non_decomposable_context, regno); + return !bitmap_bit_p (subreg_context, regno); } return true; @@ -1000,13 +1021,6 @@ resolve_shift_zext (rtx insn) offset2 = UNITS_PER_WORD * (1 - dest_reg_num); src_offset = UNITS_PER_WORD * src_reg_num; - if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN) - { - offset1 += UNITS_PER_WORD - 1; - offset2 += UNITS_PER_WORD - 1; - src_offset += UNITS_PER_WORD - 1; - } - start_sequence (); dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set), @@ -1084,6 +1098,9 @@ decompose_multiword_subregs (void) return; } + if (df) + run_word_dce (); + /* FIXME: When the dataflow branch is merged, we can change this code to look for each multi-word pseudo-register and to find each insn which sets or uses that register. That should be faster @@ -1091,6 +1108,7 @@ decompose_multiword_subregs (void) decomposable_context = BITMAP_ALLOC (NULL); non_decomposable_context = BITMAP_ALLOC (NULL); + subreg_context = BITMAP_ALLOC (NULL); reg_copy_graph = VEC_alloc (bitmap, heap, max); VEC_safe_grow (bitmap, heap, reg_copy_graph, max); @@ -1212,7 +1230,7 @@ decompose_multiword_subregs (void) basic block and still produce the correct control flow graph for it. */ gcc_assert (!cfi - || (flag_non_call_exceptions + || (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))); insn = resolve_simple_move (set, insn); @@ -1300,7 +1318,7 @@ decompose_multiword_subregs (void) unsigned int i; bitmap b; - for (i = 0; VEC_iterate (bitmap, reg_copy_graph, i, b); ++i) + FOR_EACH_VEC_ELT (bitmap, reg_copy_graph, i, b) if (b) BITMAP_FREE (b); } @@ -1309,6 +1327,7 @@ decompose_multiword_subregs (void) BITMAP_FREE (decomposable_context); BITMAP_FREE (non_decomposable_context); + BITMAP_FREE (subreg_context); } /* Gate function for lower subreg pass. */