This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA] emit_group_load()
- To: gcc-patches at gcc dot gnu dot org
- Subject: [RFA] emit_group_load()
- From: David Edelsohn <dje at watson dot ibm dot com>
- Date: Fri, 23 Feb 2001 16:42:14 -0500
- cc: Richard Henderson <rth at redhat dot com>, Mark Mitchell <mark at codesourcery dot com>
The following patch is an attempt to fix the emit_group_load() bug
introduced in August 2000 which I reported earlier. This bug causes
c-torture/compile/960829-1.c to fail on PowerPC.
The change to emit_group_load() optimized some cases but assumed
that all constants could be loaded into registers directly or via
extract_bit_field(). extract_bit_field() falls back to change_address()
which does not work on a constant.
The patch moves the test for an intermediate pseudo into the loop
for each destination. I extended the test for constants when creating
pseudos so that pseudos are created if the modes do not match and I
removed the extra tests for constants in the later assignment.
This new patch may go too far to undo the earlier patch. For
example, maybe pseudos only should be used when the MODE_CLASS does not
match (not for all MODE mismatches) and extract_bit_field() should be used
for the same class.
* expr.c (emit_group_load): Determine need for intermediate pseudo
individually for each destination. Assign all constants directly.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.295
diff -c -p -r1.295 expr.c
*** expr.c 2001/02/04 22:43:59 1.295
--- expr.c 2001/02/23 21:04:14
*************** emit_group_load (dst, orig_src, ssize, a
*** 1948,1965 ****
tmps = (rtx *) alloca (sizeof (rtx) * XVECLEN (dst, 0));
- /* If we won't be loading directly from memory, protect the real source
- from strange tricks we might play. */
- src = orig_src;
- if (GET_CODE (src) != MEM && ! CONSTANT_P (src))
- {
- if (GET_MODE (src) == VOIDmode)
- src = gen_reg_rtx (GET_MODE (dst));
- else
- src = gen_reg_rtx (GET_MODE (orig_src));
- emit_move_insn (src, orig_src);
- }
-
/* Process the pieces. */
for (i = start; i < XVECLEN (dst, 0); i++)
{
--- 1948,1953 ----
*************** emit_group_load (dst, orig_src, ssize, a
*** 1977,1982 ****
--- 1965,1984 ----
abort ();
}
+ /* If we won't be loading directly from memory, protect the real source
+ from strange tricks we might play; but make sure that the source can
+ be loaded directly into the destination. */
+ src = orig_src;
+ if (GET_CODE (src) != MEM
+ && (!CONSTANT_P (src) || GET_MODE (src) != mode))
+ {
+ if (GET_MODE (src) == VOIDmode)
+ src = gen_reg_rtx (GET_MODE (dst));
+ else
+ src = gen_reg_rtx (GET_MODE (orig_src));
+ emit_move_insn (src, orig_src);
+ }
+
/* Optimize the access just a bit. */
if (GET_CODE (src) == MEM
&& align >= GET_MODE_ALIGNMENT (mode)
*************** emit_group_load (dst, orig_src, ssize, a
*** 2000,2008 ****
else
abort ();
}
! else if ((CONSTANT_P (src)
! && (GET_MODE (src) == VOIDmode || GET_MODE (src) == mode))
! || (GET_CODE (src) == REG && GET_MODE (src) == mode))
tmps[i] = src;
else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
--- 2002,2008 ----
else
abort ();
}
! else if (CONSTANT_P (src))
tmps[i] = src;
else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,