This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: Fix PR2675



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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]