public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [new-regalloc] is_death/subregs patch
@ 2002-07-29 12:03 Denis Chertykov
  0 siblings, 0 replies; only message in thread
From: Denis Chertykov @ 2002-07-29 12:03 UTC (permalink / raw)
  To: Michael Matz; +Cc: gcc-patches, denisc


2002-07-29  Denis Chertykov  <denisc@overta.ru>

	* ra-rewrite.c (set_web_live, reset_web_live, is_partly_dead): New
	functions.
	(is_partly_live): Walk only on one subweb or all subwebs of super web.
	(emit_loads): Use set_web_live, reset_web_live.
	(detect_deaths_in_bb): Likewise.
	(reloads_to_loads): Use is_partly_dead instead of is_death ....
	Use set_web_live, reset_web_live.
	(rewrite_program2): Likewise.

Index: ra-rewrite.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra-rewrite.c,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 ra-rewrite.c
*** ra-rewrite.c	16 Jul 2002 19:52:44 -0000	1.1.2.3
--- ra-rewrite.c	29 Jul 2002 18:24:02 -0000
*************** static void detect_web_parts_to_rebuild 
*** 69,74 ****
--- 69,77 ----
  static void delete_useless_defs PARAMS ((void));
  static void detect_non_changed_webs PARAMS ((void));
  static void reset_changed_flag PARAMS ((void));
+ static void set_web_live PARAMS ((sbitmap, struct web *));
+ static void reset_web_live PARAMS ((sbitmap, struct web *));
+ static int is_partly_dead PARAMS ((sbitmap, struct web *));
  
  /* For tracking some statistics, we count the number (and cost)
     of deleted move insns.  */
*************** is_partly_live_1 (live, web)
*** 809,816 ****
  }
  
  /* Fast version in case WEB has no subwebs.  */
! #define is_partly_live(live, web) ((!web->subreg_next)	\
! 				   ? TEST_BIT (live, web->id)	\
  				   : is_partly_live_1 (live, web))
  
  /* Change the set of currently IN_USE colors according to
--- 812,819 ----
  }
  
  /* Fast version in case WEB has no subwebs.  */
! #define is_partly_live(live, web) ((!web->subreg_next || web->parent_web) \
! 				   ? TEST_BIT (live, web->id)		  \
  				   : is_partly_live_1 (live, web))
  
  /* Change the set of currently IN_USE colors according to
*************** emit_loads (ri, nl_first_reload, last_bl
*** 918,923 ****
--- 921,927 ----
        struct web *supweb;
        struct web *aweb;
        rtx ni, slot, reg;
+       enum machine_mode innermode;
        rtx before = NULL_RTX, after = NULL_RTX;
        basic_block bb;
        /* When spilltemps were spilled for the last insns, their
*************** emit_loads (ri, nl_first_reload, last_bl
*** 941,947 ****
  	}
        web->in_load = 0;
        /* The adding of reloads doesn't depend on liveness.  */
!       if (j < nl_first_reload && !TEST_BIT (ri->live, web->id))
  	continue;
        aweb = alias (supweb);
        aweb->changed = 1;
--- 945,951 ----
  	}
        web->in_load = 0;
        /* The adding of reloads doesn't depend on liveness.  */
!       if (j < nl_first_reload && !is_partly_live (ri->live, web))
  	continue;
        aweb = alias (supweb);
        aweb->changed = 1;
*************** emit_loads (ri, nl_first_reload, last_bl
*** 956,982 ****
  	  if (aweb != supweb)
  	    abort ();
  	  slot = copy_rtx (supweb->pattern);
! 	  reg = copy_rtx (supweb->orig_x);
! 	  /* Sanity check.  orig_x should be a REG rtx, which should be
! 	     shared over all RTL, so copy_rtx should have no effect.  */
! 	  if (reg != supweb->orig_x)
! 	    abort ();
  	}
        else
  	{
  	  allocate_spill_web (aweb);
  	  slot = aweb->stack_slot;
! 
! 	  /* If we don't copy the RTL there might be some SUBREG
! 	     rtx shared in the next iteration although being in
! 	     different webs, which leads to wrong code.  */
! 	  reg = copy_rtx (web->orig_x);
! 	  if (GET_CODE (reg) == SUBREG)
! 	    /*slot = adjust_address (slot, GET_MODE (reg), SUBREG_BYTE
! 	       (reg));*/
! 	    slot = simplify_gen_subreg (GET_MODE (reg), slot, GET_MODE (slot),
! 					SUBREG_BYTE (reg));
  	}
        ra_emit_move_insn (reg, slot);
        ni = get_insns ();
        end_sequence ();
--- 960,980 ----
  	  if (aweb != supweb)
  	    abort ();
  	  slot = copy_rtx (supweb->pattern);
! 	  innermode = GET_MODE (supweb->orig_x);
  	}
        else
  	{
  	  allocate_spill_web (aweb);
  	  slot = aweb->stack_slot;
! 	  innermode = GET_MODE (slot);
  	}
+       /* If we don't copy the RTL there might be some SUBREG
+ 	 rtx shared in the next iteration although being in
+ 	 different webs, which leads to wrong code.  */
+       reg = copy_rtx (web->orig_x);
+       if (GET_CODE (reg) == SUBREG)
+ 	slot = simplify_gen_subreg (GET_MODE (reg), slot, innermode,
+ 				    SUBREG_BYTE (reg));
        ra_emit_move_insn (reg, slot);
        ni = get_insns ();
        end_sequence ();
*************** emit_loads (ri, nl_first_reload, last_bl
*** 1025,1031 ****
  	  emitted_spill_loads++;
  	  spill_load_cost += bb->frequency + 1;
  	}
!       RESET_BIT (ri->live, web->id);
        /* In the special case documented above only emit the reloads and
  	 one load.  */
        if (ri->need_load == 2 && j < nl_first_reload)
--- 1023,1029 ----
  	  emitted_spill_loads++;
  	  spill_load_cost += bb->frequency + 1;
  	}
!       reset_web_live (ri->live, web);
        /* In the special case documented above only emit the reloads and
  	 one load.  */
        if (ri->need_load == 2 && j < nl_first_reload)
*************** detect_bbs_for_rewrite (changed_bbs)
*** 1053,1058 ****
--- 1051,1104 ----
        }
  }
  
+ /* Test LIVE for partial WEB live.  */
+ static int
+ is_partly_dead (live, web)
+      sbitmap live;
+      struct web *web;
+ {
+   struct web *sweb;
+   
+   if (web->subreg_next && !web->parent_web)
+     {
+       for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+ 	if (!TEST_BIT (live, sweb->id))
+ 	  return 1;
+       return 0;
+     }
+   return !TEST_BIT (live, web->id);
+ }
+ 
+ /* Set live bit in LIVE for WEB or all his subwebs.  */
+ static void
+ set_web_live (live, web)
+      sbitmap live;
+      struct web *web;
+ {
+   struct web *sweb;
+ 
+   if (web->subreg_next && !web->parent_web)
+     for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+       SET_BIT (live, sweb->id);
+   else
+     SET_BIT (live, web->id);
+ }
+ 
+ /* Reset live bit in LIVE for WEB or all his subwebs.  */
+ static void
+ reset_web_live (live, web)
+      sbitmap live;
+      struct web *web;
+ {
+   struct web *sweb;
+ 
+   if (web->subreg_next && !web->parent_web)
+     for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+       RESET_BIT (live, sweb->id);
+   else
+     RESET_BIT (live, web->id);
+ }
+ 
  /* Fast version of rewrite_program2() for one basic block, where
     no spill code is necessary.  We detect here only insns with deaths.  */
  static void
*************** detect_deaths_in_bb (bb, live, new_death
*** 1094,1111 ****
        info = insn_df[INSN_UID (insn)];
        for (n = 0; n < info.num_defs; n++)
  	{
  	  struct ref *ref = info.defs[n];
  	  struct web *web = def2web[DF_REF_ID (ref)];
! 	  rtx reg = DF_REF_REG (ref);
  	  int is_non_def = 0;
- 	  unsigned int n2;
  
- 	  web = find_web_for_subweb (web);
  	  /* Detect rmw webs.  */
  	  for (n2 = 0; n2 < info.num_uses; n2++)
  	    {
  	      struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
! 	      if (web == find_web_for_subweb (web2))
  		{
  		  is_non_def = 1;
  		  break;
--- 1140,1156 ----
        info = insn_df[INSN_UID (insn)];
        for (n = 0; n < info.num_defs; n++)
  	{
+ 	  unsigned int n2;
  	  struct ref *ref = info.defs[n];
  	  struct web *web = def2web[DF_REF_ID (ref)];
! 	  struct web *supweb = find_web_for_subweb (web);
  	  int is_non_def = 0;
  
  	  /* Detect rmw webs.  */
  	  for (n2 = 0; n2 < info.num_uses; n2++)
  	    {
  	      struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
! 	      if (supweb == find_web_for_subweb (web2))
  		{
  		  is_non_def = 1;
  		  break;
*************** detect_deaths_in_bb (bb, live, new_death
*** 1114,1145 ****
  	  if (is_non_def)
  	    continue;
  
! 	  if (!is_partly_live (live, web))
  	    bitmap_set_bit (useless_defs, DF_REF_ID (ref));
  
! 	  if (GET_CODE (reg) == SUBREG)
! 	    {
! 	      struct web *sweb;
! 	      sweb = find_subweb (web, reg);
! 	      RESET_BIT (live, sweb->id);
! 	    }
! 	  else
! 	    {
! 	      struct web *sweb;
! 	      RESET_BIT (live, web->id);
! 	      for (sweb = web->subreg_next; sweb;
! 		   sweb = sweb->subreg_next)
! 		RESET_BIT (live, sweb->id);
! 	    }
  	}
  
        for (n = 0; n < info.num_uses; n++)
  	{
  	  struct web *web = use2web[DF_REF_ID (info.uses[n])];
! 	  struct web *supweb = find_web_for_subweb (web);
! 	  int is_death = !TEST_BIT (live, supweb->id);
! 	  is_death &= !TEST_BIT (live, web->id);
! 	  if (is_death)
  	    {
  	      bitmap_set_bit (new_deaths, INSN_UID (insn));
  	      break;
--- 1159,1174 ----
  	  if (is_non_def)
  	    continue;
  
! 	  if (!is_partly_live (live, supweb))
  	    bitmap_set_bit (useless_defs, DF_REF_ID (ref));
  
! 	  reset_web_live (live, web);
  	}
  
        for (n = 0; n < info.num_uses; n++)
  	{
  	  struct web *web = use2web[DF_REF_ID (info.uses[n])];
! 	  if (is_partly_dead (live, web))
  	    {
  	      bitmap_set_bit (new_deaths, INSN_UID (insn));
  	      break;
*************** detect_deaths_in_bb (bb, live, new_death
*** 1149,1155 ****
        for (n = 0; n < info.num_uses; n++)
  	{
  	  struct web *web = use2web[DF_REF_ID (info.uses[n])];
! 	  SET_BIT (live, web->id);
  	}
      }
  }
--- 1178,1184 ----
        for (n = 0; n < info.num_uses; n++)
  	{
  	  struct web *web = use2web[DF_REF_ID (info.uses[n])];
! 	  set_web_live (live, web);
  	}
      }
  }
*************** reloads_to_loads (ri, refs, num_refs, re
*** 1174,1180 ****
      {
        struct web *web = ref2web[DF_REF_ID (refs[n])];
        struct web *supweb = find_web_for_subweb (web);
-       int is_death;
        int j;
        /* Only emit reloads when entering their interference
  	 region.  A use of a spilled web never opens an
--- 1203,1208 ----
*************** reloads_to_loads (ri, refs, num_refs, re
*** 1185,1195 ****
  	  && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
  	continue;
        /* Note, that if web (and supweb) are DEFs, we already cleared
! 	 the corresponding bits in live.  I.e. is_death becomes true, which
! 	 is what we want.  */
!       is_death = !TEST_BIT (ri->live, supweb->id);
!       is_death &= !TEST_BIT (ri->live, web->id);
!       if (is_death)
  	{
  	  int old_num_r = num_reloads;
  	  bitmap_clear (ri->scratch);
--- 1213,1221 ----
  	  && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
  	continue;
        /* Note, that if web (and supweb) are DEFs, we already cleared
! 	 the corresponding bits in live.  I.e. is_partly_dead becomes true,
! 	 which is what we want.  */
!       if (is_partly_dead (ri->live, web))
  	{
  	  int old_num_r = num_reloads;
  	  bitmap_clear (ri->scratch);
*************** rewrite_program2 (new_deaths)
*** 1294,1300 ****
  	     Remember to not add to colors_in_use in that case.  */
  	  if (aweb->type != SPILLED /*|| aweb->color >= 0*/)
  	    {
! 	      SET_BIT (ri.live, web->id);
  	      if (aweb->type != SPILLED)
  	        update_spill_colors (&(ri.colors_in_use), web, 1);
  	    }
--- 1320,1326 ----
  	     Remember to not add to colors_in_use in that case.  */
  	  if (aweb->type != SPILLED /*|| aweb->color >= 0*/)
  	    {
! 	      set_web_live (ri.live, web);
  	      if (aweb->type != SPILLED)
  	        update_spill_colors (&(ri.colors_in_use), web, 1);
  	    }
*************** rewrite_program2 (new_deaths)
*** 1343,1349 ****
  		  struct web *aweb = alias (find_web_for_subweb (web));
  		  if (aweb->type != SPILLED)
  		    {
! 		      SET_BIT (ri.live, web->id);
  		      update_spill_colors (&(ri.colors_in_use), web, 1);
  		    }
  		});
--- 1369,1375 ----
  		  struct web *aweb = alias (find_web_for_subweb (web));
  		  if (aweb->type != SPILLED)
  		    {
! 		      set_web_live (ri.live, web);
  		      update_spill_colors (&(ri.colors_in_use), web, 1);
  		    }
  		});
*************** rewrite_program2 (new_deaths)
*** 1407,1413 ****
  		if (!is_partly_live (ri.live, supweb))
  		  bitmap_set_bit (useless_defs, DF_REF_ID (ref));
  
! 		RESET_BIT (ri.live, web->id);
  		if (bitmap_bit_p (ri.need_reload, web->id))
  		  {
  		    ri.num_reloads--;
--- 1433,1439 ----
  		if (!is_partly_live (ri.live, supweb))
  		  bitmap_set_bit (useless_defs, DF_REF_ID (ref));
  
! 		reset_web_live (ri.live, web);
  		if (bitmap_bit_p (ri.need_reload, web->id))
  		  {
  		    ri.num_reloads--;
*************** rewrite_program2 (new_deaths)
*** 1436,1442 ****
  		    for (sweb = supweb->subreg_next; sweb;
  			 sweb = sweb->subreg_next)
  		      {
- 		        RESET_BIT (ri.live, sweb->id);
  			if (bitmap_bit_p (ri.need_reload, sweb->id))
  			  {
  		            ri.num_reloads--;
--- 1462,1467 ----
*************** rewrite_program2 (new_deaths)
*** 1462,1474 ****
  	      {
  		struct web *web = use2web[DF_REF_ID (info.uses[n])];
  		struct web *supweb = find_web_for_subweb (web);
- 		int is_death;
  		if (supweb->type == PRECOLORED
  		    && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
  		  continue;
! 		is_death = !TEST_BIT (ri.live, supweb->id);
! 		is_death &= !TEST_BIT (ri.live, web->id);
! 		if (is_death)
  		  {
  		    ri.need_load = 1;
  		    bitmap_set_bit (new_deaths, INSN_UID (insn));
--- 1487,1496 ----
  	      {
  		struct web *web = use2web[DF_REF_ID (info.uses[n])];
  		struct web *supweb = find_web_for_subweb (web);
  		if (supweb->type == PRECOLORED
  		    && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
  		  continue;
! 		if (is_partly_dead (ri.live, web))
  		  {
  		    ri.need_load = 1;
  		    bitmap_set_bit (new_deaths, INSN_UID (insn));
*************** rewrite_program2 (new_deaths)
*** 1514,1520 ****
  		struct web *web = use2web[DF_REF_ID (info.uses[n])];
  		struct web *supweb = find_web_for_subweb (web);
  		struct web *aweb = alias (supweb);
! 		SET_BIT (ri.live, web->id);
  		if (aweb->type != SPILLED)
  		  continue;
  		if (supweb->spill_temp)
--- 1536,1542 ----
  		struct web *web = use2web[DF_REF_ID (info.uses[n])];
  		struct web *supweb = find_web_for_subweb (web);
  		struct web *aweb = alias (supweb);
! 		set_web_live (ri.live, web);
  		if (aweb->type != SPILLED)
  		  continue;
  		if (supweb->spill_temp)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-07-29 18:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-29 12:03 [new-regalloc] is_death/subregs patch Denis Chertykov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).