This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix PR2675
- To: gcc-patches at gcc dot gnu dot org, Phil Edwards <pedwards at jaj dot com>, Richard Henderson <rth at cygnus dot com>
- Subject: PATCH: Fix PR2675
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 02 May 2001 15:06:57 -0700
- Organization: CodeSourcery, LLC
This patch fixes a regression from GCC 2.95.x on SPARCs. However, I'm
not 100% sure it's correct, and I don't have a SPARC to play with at
the moment, so I'm hoping Phil will help out again by bootstrapping
this patch and running the testsuite. Phil, please make sure that:
gcc.c-torture/execute/20000910-1.c
gcc.c-torture/execute/20000910-2.c
still pass with the patch applied. Phil, if you don't have time to do
this, please let me know so that I can "volunteer" someone else. :-)
Richard, if you have time to look at the patch (in between the EH
stuff), that would be great too -- I could be going down another weird
rathole like I did with that `asm' stuff.
This bug is a lingering problem from the sibcall code, interacting
with the old inliner. (Someday, everyone will use the tree-based
inliner, and then we'll do sibcalls on trees, and thousands of lines
of code will go away.)
Alexandre tried to fix this problem in this thread:
http://gcc.gnu.org/ml/gcc-patches/2000-09/msg00324.html
called "inline+sibcall x LEAF_REG_REMAP", but didn't fully
succeed. :-(
Alexandre realized that we have to remap leaf registers when inlining,
and so he stored them in the `reg_map' field of an `inline_remap'.
However, leaf registers (unlike pseudos) sometimes appear in multiple
modes, which is what happenned in the test-case indicated by the PR.
So, we ended up substituting `(reg:DF 24 %i0)' for an SImode
equivalent, leading to later disasters when trying to recognize the
(now-mutant) instruction.
Fixed by keeping a table for the leaf registers, indexed by mode as
well as register number, separately from teh rest of the register map.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.c,v
retrieving revision 1.126.4.5
diff -c -p -r1.126.4.5 integrate.c
*** integrate.c 2001/03/27 04:41:15 1.126.4.5
--- integrate.c 2001/05/02 21:58:25
*************** expand_inline_function (fndecl, parms, t
*** 766,772 ****
/* Allocate the structures we use to remap things. */
! map = (struct inline_remap *) xmalloc (sizeof (struct inline_remap));
map->fndecl = fndecl;
VARRAY_TREE_INIT (map->block_map, 10, "block_map");
--- 766,772 ----
/* Allocate the structures we use to remap things. */
! map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap));
map->fndecl = fndecl;
VARRAY_TREE_INIT (map->block_map, 10, "block_map");
*************** copy_rtx_and_substitute (orig, map, for_
*** 1748,1762 ****
{
/* Some hard registers are also mapped,
but others are not translated. */
! if (map->reg_map[regno] != 0
! /* We shouldn't usually have reg_map set for return
! register, but it may happen if we have leaf-register
! remapping and the return register is used in one of
! the calling sequences of a call_placeholer. In this
! case, we'll end up with a reg_map set for this
! register, but we don't want to use for registers
! marked as return values. */
! && ! REG_FUNCTION_VALUE_P (orig))
return map->reg_map[regno];
/* If this is the virtual frame pointer, make space in current
--- 1748,1754 ----
{
/* Some hard registers are also mapped,
but others are not translated. */
! if (map->reg_map[regno] != 0)
return map->reg_map[regno];
/* If this is the virtual frame pointer, make space in current
*************** copy_rtx_and_substitute (orig, map, for_
*** 1874,1882 ****
if (map->integrating && regno < FIRST_PSEUDO_REGISTER
&& LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
{
! temp = gen_rtx_REG (mode, regno);
! map->reg_map[regno] = temp;
! return temp;
}
#endif
else
--- 1866,1874 ----
if (map->integrating && regno < FIRST_PSEUDO_REGISTER
&& LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
{
! if (!map->leaf_reg_map[regno][mode])
! map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno);
! return map->leaf_reg_map[regno][mode];
}
#endif
else
Index: integrate.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.h,v
retrieving revision 1.16
diff -c -p -r1.16 integrate.h
*** integrate.h 2001/01/23 18:36:06 1.16
--- integrate.h 2001/05/02 21:58:25
***************
*** 1,5 ****
/* Function integration definitions for GNU C-Compiler
! Copyright (C) 1990, 1995, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
--- 1,5 ----
/* Function integration definitions for GNU C-Compiler
! Copyright (C) 1990, 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
*************** struct inline_remap
*** 47,52 ****
--- 47,56 ----
/* Mapping from old registers to new registers.
It is allocated and deallocated in `expand_inline_function' */
rtx *reg_map;
+ #if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
+ /* Mapping from old leaf registers to new leaf registers. */
+ rtx leaf_reg_map[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
+ #endif
/* Mapping from old code-labels to new code-labels.
The first element of this map is label_map[min_labelno]. */
rtx *label_map;