[Committed] PR25474: Enable CSE of compressed constant pool entries

Roger Sayle roger@eyesopen.com
Sun Apr 16 23:35:00 GMT 2006

The following minor patch resolves PR middle-end/25474.  When placing
constants in a function's constant pool, the middle-end considers storing
the value in a narrower (compressed) mode if possible and extending after
loading if from the pool.  For example, the DFmode constant 1.0, may be
stored in a function's constant pool as 1.0f and extended to a double for

Currently, the initial RTL we generate for such compressed constants
performs the load from memory and extension as a single instruction,
such as "(set (reg:DF) (float_extend:DF (mem:SF ...))".

The tweaks below is to call force_reg to split this sequence into two
instructions, the first to perform the load from memory and the second
to perform the float extension, i.e.

	(set (reg:SF) (mem:SF ...))
	(set (reg:DF) (float_extend:DF (reg:SF)))

Conceptually, at the abstract RTL level these sequences are identical,
and combine will reconstitute a single instruction that performs the
load and extension if this is supported by the target.  The benefit
is that CSE can now see the loads from the constant pool, allowing the
load of a DFmode 1.0 and a SFmode 1.0f to be reuse a single load.

Unfortunately, there are still issues with GCC's register allocation
(really?), which currently doesn't allow two different pseudos with
different modes to both be live in the same hard register simultaneously.
Hence, in the powerpc testcase for 25474, only have a single "load",
but an unnecessary register to register move.

The following patch has been tested on both i686-pc-linux-gnu and
powerpc-apple-darwin7.9.0 with a full "make bootstrap", all default
languages and regression tested with a top-level "make -k check"
with no new failures.

Let me know if you encounter an unanticipated pessimization on your
favorite platform.

Committed to mainline as 112991.

2006-04-16  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/25474
	* expr.c (compress_float_constant): Copy the narrow constant into
	a new pseudo before extending it to its final width.

Index: expr.c
*** expr.c	(revision 112731)
--- expr.c	(working copy)
*************** compress_float_constant (rtx x, rtx y)
*** 3346,3352 ****
        emit_unop_insn (ic, x, trunc_y, UNKNOWN);
        last_insn = get_last_insn ();

--- 3346,3356 ----
!       /* For CSE's benefit, force the compressed constant pool entry
! 	 into a new pseudo.  This constant may be used in different modes,
! 	 and if not, combine will put things back together for us.  */
!       trunc_y = force_reg (srcmode, trunc_y);
        emit_unop_insn (ic, x, trunc_y, UNKNOWN);
        last_insn = get_last_insn ();


More information about the Gcc-patches mailing list