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]
Other format: [Raw text]

[rfc] Make regrename call recog


Hi,

working on a S/390 patch optimizing load/store multiple I've
noticed that regrename replaces registers without calling
recog afterwards. So it happened that a single register out
of a PARALLEL block of SETs gets renamed. Because the
load_multiple patterns only accept SETs with consecutive
registers this insn is invalid after regrename.

The attached patch turns "do_replace" in "try_replace" using
validate_change to replace the register along the def-use chain.

Is this the way to go?

Bye,

-Andreas-

Index: gcc/regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.102
diff -p -c -r1.102 regrename.c
*** gcc/regrename.c	5 Jul 2005 16:20:13 -0000	1.102
--- gcc/regrename.c	25 Aug 2005 12:16:55 -0000
*************** static const char * const scan_actions_n
*** 73,79 ****
  
  static struct obstack rename_obstack;
  
! static void do_replace (struct du_chain *, int);
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type, int);
  static void scan_rtx_address (rtx, rtx *, enum reg_class,
--- 73,79 ----
  
  static struct obstack rename_obstack;
  
! static int try_replace (struct du_chain *, int);
  static void scan_rtx_reg (rtx, rtx *, enum reg_class,
  			  enum scan_actions, enum op_type, int);
  static void scan_rtx_address (rtx, rtx *, enum reg_class,
*************** regrename_optimize (void)
*** 339,350 ****
  	      continue;
  	    }
  
! 	  do_replace (this, best_new_reg);
! 	  tick[best_new_reg] = ++this_tick;
! 	  regs_ever_live[best_new_reg] = 1;
! 
! 	  if (dump_file)
! 	    fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
  	}
  
        obstack_free (&rename_obstack, first_obj);
--- 339,352 ----
  	      continue;
  	    }
  
! 	  if (try_replace (this, best_new_reg))
! 	    {
! 	      tick[best_new_reg] = ++this_tick;
! 	      regs_ever_live[best_new_reg] = 1;
! 	      
! 	      if (dump_file)
! 		fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
! 	    }
  	}
  
        obstack_free (&rename_obstack, first_obj);
*************** regrename_optimize (void)
*** 360,379 ****
  		    PROP_DEATH_NOTES);
  }
  
! static void
! do_replace (struct du_chain *chain, int reg)
  {
    while (chain)
      {
        unsigned int regno = ORIGINAL_REGNO (*chain->loc);
        struct reg_attrs * attr = REG_ATTRS (*chain->loc);
! 
!       *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
        if (regno >= FIRST_PSEUDO_REGISTER)
! 	ORIGINAL_REGNO (*chain->loc) = regno;
!       REG_ATTRS (*chain->loc) = attr;
        chain = chain->next_use;
      }
  }
  
  
--- 362,386 ----
  		    PROP_DEATH_NOTES);
  }
  
! static int
! try_replace (struct du_chain *chain, int reg)
  {
    while (chain)
      {
        unsigned int regno = ORIGINAL_REGNO (*chain->loc);
        struct reg_attrs * attr = REG_ATTRS (*chain->loc);
!       rtx new_reg = gen_raw_REG (GET_MODE (*chain->loc), reg);
!       
        if (regno >= FIRST_PSEUDO_REGISTER)
! 	ORIGINAL_REGNO (new_reg) = regno;
!       REG_ATTRS (new_reg) = attr;
! 
!       validate_change (chain->insn, chain->loc, new_reg, 1);
! 
        chain = chain->next_use;
      }
+ 
+   return apply_change_group ();
  }
  
  


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