From patchwork Wed Jul 14 14:57:53 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: A few simple DImode improvements Date: Wed, 14 Jul 2010 04:57:53 -0000 From: Bernd Schmidt X-Patchwork-Id: 58909 Message-Id: <4C3DD071.6040707@codesourcery.com> To: Ian Lance Taylor Cc: Eric Botcazou , gcc-patches@gcc.gnu.org, "Vladimir N. Makarov" On 06/29/2010 01:34 AM, Bernd Schmidt wrote: > On 06/29/2010 01:03 AM, Ian Lance Taylor wrote: >> I see what you're getting at. It's unlikely, but it does happen in code >> which examines the bits of a floating point number via a union or using >> -fno-strict-aliasing and a type cast. So if that code works correctly >> if perhaps less efficiently, then I agree that checking that the mode >> class is MODE_INT should work OK here. > > Hmm. Looking at this again now, aren't we already doing that? > (resolve_reg_p checks whether DEST is a CONCAT) > > if (!can_decompose_p (dest) > || (side_effects_p (dest) && !pushing) > || (!SCALAR_INT_MODE_P (dest_mode) > && !resolve_reg_p (dest) > && !resolve_subreg_p (dest))) In other words, how about the following patch? Bootstrapped and regression tested on i686-linux. Bernd * lower-subreg.c (subreg_context): New static bitmap. (decompose_multiword_subregs): Allocate and free it. (find_decomposable_subregs): Set a bit in it for a register that occurs in a subreg that changes mode but not size. (can_decompose_p): Test it instead of non_decomposable_context. Index: lower-subreg.c =================================================================== --- lower-subreg.c (revision 162146) +++ lower-subreg.c (working copy) @@ -63,6 +63,10 @@ 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. */ +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 +293,7 @@ find_decomposable_subregs (rtx *px, void && !MODES_TIEABLE_P (GET_MODE (x), GET_MODE (inner))) { bitmap_set_bit (non_decomposable_context, regno); + bitmap_set_bit (subreg_context, regno); return -1; } } @@ -616,7 +621,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; @@ -1091,6 +1096,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); @@ -1309,6 +1315,7 @@ decompose_multiword_subregs (void) BITMAP_FREE (decomposable_context); BITMAP_FREE (non_decomposable_context); + BITMAP_FREE (subreg_context); } /* Gate function for lower subreg pass. */