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]

[new-regalloc-branch] combine with precolored regs & rewrite_program



I will not apply this patch without approval.


Tue Jul 31 01:47:59 2001  Denis Chertykov  <denisc@overta.ru>

	* ra.c (combine): combine add_hardregs's of U and V.
	(ok): Restriction for combining a web with a precolored web is
	removed. Check a precolored web for usable_regs.

	(rewrite_program): Since we always call `regclass' if
	`changed' we can emit a new pseudos which will have a new reg
	class preferences.

Index: ra.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/ra.c,v
retrieving revision 1.1.2.26
diff -c -3 -p -r1.1.2.26 ra.c
*** ra.c	2001/07/30 17:31:59	1.1.2.26
--- ra.c	2001/07/30 21:49:26
*************** ok (target, source)
*** 2798,2803 ****
--- 2798,2804 ----
       struct web *target, *source;
  {
    struct conflict_link *wl;
+   int i;
  
    /* Source is PRECOLORED.  We test here, if it isn't one of the fixed
       registers.  In this case we disallow the coalescing.
*************** ok (target, source)
*** 2811,2821 ****
    if (TEST_HARD_REG_BIT (never_use_colors, source->color))
      return 0;
  
!   /* XXX we can't right now combine a web with a hard-reg to a web
!      with a multi-word pseudo, cause we get the conflicts wrong (we forget
!      to add the other hard-regs to the conflicts, and only see the first).  */
!   if (source->add_hardregs != target->add_hardregs)
!     return 0;
  
    for (wl = target->conflict_list; wl; wl = wl->next)
      {
--- 2812,2822 ----
    if (TEST_HARD_REG_BIT (never_use_colors, source->color))
      return 0;
  
!   /* We can't coalesce target with the precolored registers which isn't in
!      usable_regs.  */
!   for (i = target->add_hardregs; i >= 0; --i)
!     if (!TEST_HARD_REG_BIT (usable_regs[target->regclass], source->color + i))
!       return 0;
  
    for (wl = target->conflict_list; wl; wl = wl->next)
      {
*************** combine (u, v)
*** 2926,2955 ****
    u->is_coalesced = 1;
    v->is_coalesced = 1;
    merge_moves (u, v);
!   /* XXX combine add_hardregs's of U and V.  */
!   for (wl = v->conflict_list; wl; wl = wl->next)
      {
!       struct web *pweb = wl->t;
!       if (pweb->type != SELECT && pweb->type != COALESCED)
!         {
! 	  if (wl->sub == NULL)
! 	    record_conflict (u, pweb);
! 	  else
  	    {
! 	      struct sub_conflict *sl;
! 	      /* So, between V and PWEB there are sub_conflicts.  We need
! 		 to relocate those conflicts to be between U and PWEB.
! 		 In the case only a part of V conflicted with (part of) PWEB
! 		 we nevertheless make the new conflict between the whole U and
! 		 the (part of) PWEB.  Later we might try to find in U the
! 		 correct subpart corresponding (by size and offset) to the
! 		 part of V (sl->s) which was the source of the conflict.  */
! 	      for (sl = wl->sub; sl; sl = sl->next)
! 		record_conflict (u, sl->t);
  	    }
! 	  decrement_degree (pweb, 1 + v->add_hardregs);
!         }
      }
    if (u->num_conflicts >= NUM_REGS (u) && u->type == FREEZE)
      {
        remove_list (u->dlink, &freeze_wl);
--- 2927,2990 ----
    u->is_coalesced = 1;
    v->is_coalesced = 1;
    merge_moves (u, v);
!   /* combine add_hardregs's of U and V.  */
!   if (u->type == PRECOLORED)
      {
!       int i;
!       struct web *web;
! 
!       for (i = 0; i <= v->add_hardregs; ++i)
! 	{
! 	  web = hardreg2web [i + u->color];
! 	  for (wl = v->conflict_list; wl; wl = wl->next)
  	    {
! 	      struct web *pweb = wl->t;
! 	      if (pweb->type != SELECT && pweb->type != COALESCED)
! 		{
! 		  if (wl->sub == NULL)
! 		    record_conflict (pweb, web);
! 		  else
! 		    {
! 		      struct sub_conflict *sl;
! 		      for (sl = wl->sub; sl; sl = sl->next)
! 			record_conflict (u, sl->t);
! 		    }
! 		}
  	    }
! 	}
! 
!       for (wl = v->conflict_list; wl; wl = wl->next)
! 	{
! 	  struct web *pweb = wl->t;
! 	  if (pweb->type != SELECT && pweb->type != COALESCED)
! 	    decrement_degree (pweb, 1 + v->add_hardregs);
! 	}
      }
+   else
+     for (wl = v->conflict_list; wl; wl = wl->next)
+       {
+ 	struct web *pweb = wl->t;
+ 	if (pweb->type != SELECT && pweb->type != COALESCED)
+ 	  {
+ 	    if (wl->sub == NULL)
+ 	      record_conflict (u, pweb);
+ 	    else
+ 	      {
+ 		struct sub_conflict *sl;
+ 		/* So, between V and PWEB there are sub_conflicts.  We need
+ 		   to relocate those conflicts to be between U and PWEB.
+ 		   In the case only a part of V conflicted with (part of) PWEB
+ 		   we nevertheless make the new conflict between the whole U
+ 		   and the (part of) PWEB.  Later we might try to find in U the
+ 		   correct subpart corresponding (by size and offset) to the
+ 		   part of V (sl->s) which was the source of the conflict.  */
+ 		for (sl = wl->sub; sl; sl = sl->next)
+ 		  record_conflict (u, sl->t);
+ 	      }
+ 	    decrement_degree (pweb, 1 + v->add_hardregs);
+ 	  }
+       }
+   
    if (u->num_conflicts >= NUM_REGS (u) && u->type == FREEZE)
      {
        remove_list (u->dlink, &freeze_wl);
*************** rewrite_program (void)
*** 3641,3648 ****
  		  dest = gen_rtx_MEM (GET_MODE (source),
  				      plus_constant (XEXP (dest, 0),
  						     SUBREG_BYTE (source)));
  		}
! 	      emit_insn (gen_move_insn (dest, source));
  	      insns = get_insns ();
  	      end_sequence ();
  	      emit_insns_after (insns, insn);
--- 3676,3693 ----
  		  dest = gen_rtx_MEM (GET_MODE (source),
  				      plus_constant (XEXP (dest, 0),
  						     SUBREG_BYTE (source)));
+ 		  emit_insn (gen_move_insn (dest, source));
+ 		}
+ 	      else
+ 		{
+ 		  rtx reg = gen_reg_rtx (GET_MODE (source));
+ 		  if (validate_change (insn, DF_REF_LOC (web->defs[j]),
+ 					reg, 0))
+ 		    emit_insn (gen_move_insn (dest, reg));
+ 		  else
+ 		    emit_insn (gen_move_insn (dest, source));
  		}
! 		
  	      insns = get_insns ();
  	      end_sequence ();
  	      emit_insns_after (insns, insn);
*************** rewrite_program (void)
*** 3703,3710 ****
  		  source = gen_rtx_MEM (GET_MODE (target),
  					plus_constant (XEXP (source, 0),
  						       SUBREG_BYTE (target)));
  		}
! 	      emit_insn (gen_move_insn (target, source));
  	      insns = get_insns ();
  	      end_sequence ();
  	      emit_insns_before (insns, insn);
--- 3748,3766 ----
  		  source = gen_rtx_MEM (GET_MODE (target),
  					plus_constant (XEXP (source, 0),
  						       SUBREG_BYTE (target)));
+ 		  emit_insn (gen_move_insn (target, source));
+ 		}
+ 	      else
+ 		{
+ 		  rtx reg = gen_reg_rtx (GET_MODE (target));
+ 
+ 		  if (validate_change (insn, DF_REF_LOC (web->uses[j]),
+ 					reg, 0))
+ 		    emit_insn (gen_move_insn (reg ,source));
+ 		  else
+ 		    emit_insn (gen_move_insn (target, source));
  		}
! 
  	      insns = get_insns ();
  	      end_sequence ();
  	      emit_insns_before (insns, insn);


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