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]

[Committed] Minor clean-up of reg-stack.c


The following patch is a very minor reorganization of reg-stack.c
that should have absolutely no functionality change.  I've a few
ideas for improving things in reg-stack.c, but thought it would
be nice to make three minor clean-ups before starting to change
things.

The first change is that result of convert_regs is never used, so the
return type of the function can be made "void".  With this change,
I noticed that I'd also need to update convert_regs' protototype at
the top of the file, as the functions in this file are strangely
ordered.  Moving the external API point, reg_to_stack to the bottom
of the source file, allows most functions to be defined before their
first use, allowing the prototypes to be removed.

The final change is a small conceptual reorganization.  There are
currently two loops used to initialize the aux information that we
associate with each basic block.  The first in the top-level
reg_to_stack where we allocate and free the aux info.  And the
second, at the top of convert_regs_entry.  It turns out that not
only is this second loop slightly out of place, but it executes
immediately after the first loop (reg_to_stack calls convert_regs
which immediately calls convert_regs_entry).  This patch moves all
of the basic block initialization into the single top-level loop,
leaving convert_regs_entry to handle entry edges in exactly the
same way that convert_regs_exit only handles exit edges.

I suspect this strange code structuring is a historical
artifact from the days when reg-stack.c used to attempt its own
data-flow analysis.  Now that register liveness is calculated
for us, "setting up the problem" is much simpler.


The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.

Committed to mainline CVS.


2005-05-26  Roger Sayle  <roger@eyesopen.com>

	* reg-stack.c (convert_regs_entry, convert_regs_exit,
	convert_regs_1, convert_regs_2, convert_regs): Delete prototypes.
	(reg_to_stack): Move to end of the file.  Initialize the per
	basic block information here, instead of...
	(convert_regs_entry): Here.
	(convert_regs): Change unused return type to void.


Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.177
diff -c -3 -p -r1.177 reg-stack.c
*** reg-stack.c	14 Apr 2005 11:31:02 -0000	1.177
--- reg-stack.c	26 May 2005 21:04:07 -0000
*************** static bool subst_stack_regs_pat (rtx, s
*** 259,269 ****
  static void subst_asm_stack_regs (rtx, stack);
  static bool subst_stack_regs (rtx, stack);
  static void change_stack (rtx, stack, stack, enum emit_where);
- static int convert_regs_entry (void);
- static void convert_regs_exit (void);
- static int convert_regs_1 (FILE *, basic_block);
- static int convert_regs_2 (FILE *, basic_block);
- static int convert_regs (FILE *);
  static void print_stack (FILE *, stack);
  static rtx next_flags_user (rtx);
  static bool compensate_edge (edge, FILE *);
--- 259,264 ----
*************** pop_stack (stack regstack, int regno)
*** 398,498 ****
      }
  }

- /* Convert register usage from "flat" register file usage to a "stack
-    register file.  FILE is the dump file, if used.
-
-    Construct a CFG and run life analysis.  Then convert each insn one
-    by one.  Run a last cleanup_cfg pass, if optimizing, to eliminate
-    code duplication created when the converter inserts pop insns on
-    the edges.  */
-
- bool
- reg_to_stack (FILE *file)
- {
-   basic_block bb;
-   int i;
-   int max_uid;
-
-   /* Clean up previous run.  */
-   stack_regs_mentioned_data = 0;
-
-   /* See if there is something to do.  Flow analysis is quite
-      expensive so we might save some compilation time.  */
-   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
-     if (regs_ever_live[i])
-       break;
-   if (i > LAST_STACK_REG)
-     return false;
-
-   /* Ok, floating point instructions exist.  If not optimizing,
-      build the CFG and run life analysis.
-      Also need to rebuild life when superblock scheduling is done
-      as it don't update liveness yet.  */
-   if (!optimize
-       || (flag_sched2_use_superblocks
- 	  && flag_schedule_insns_after_reload))
-     {
-       count_or_remove_death_notes (NULL, 1);
-       life_analysis (file, PROP_DEATH_NOTES);
-     }
-   mark_dfs_back_edges ();
-
-   /* Set up block info for each basic block.  */
-   alloc_aux_for_blocks (sizeof (struct block_info_def));
-   FOR_EACH_BB_REVERSE (bb)
-     {
-       edge e;
-       edge_iterator ei;
-
-       FOR_EACH_EDGE (e, ei, bb->preds)
- 	if (!(e->flags & EDGE_DFS_BACK)
- 	    && e->src != ENTRY_BLOCK_PTR)
- 	  BLOCK_INFO (bb)->predecessors++;
-     }
-
-   /* Create the replacement registers up front.  */
-   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
-     {
-       enum machine_mode mode;
-       for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
- 	   mode != VOIDmode;
- 	   mode = GET_MODE_WIDER_MODE (mode))
- 	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
-       for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
- 	   mode != VOIDmode;
- 	   mode = GET_MODE_WIDER_MODE (mode))
- 	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
-     }
-
-   ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
-
-   /* A QNaN for initializing uninitialized variables.
-
-      ??? We can't load from constant memory in PIC mode, because
-      we're inserting these instructions before the prologue and
-      the PIC register hasn't been set up.  In that case, fall back
-      on zero, which we can get from `ldz'.  */
-
-   if (flag_pic)
-     not_a_num = CONST0_RTX (SFmode);
-   else
-     {
-       not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
-       not_a_num = force_const_mem (SFmode, not_a_num);
-     }
-
-   /* Allocate a cache for stack_regs_mentioned.  */
-   max_uid = get_max_uid ();
-   VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
- 		    "stack_regs_mentioned cache");
-
-   convert_regs (file);
-
-   free_aux_for_blocks ();
-   return true;
- }
-
-
  /* Return a pointer to the REG expression within PAT.  If PAT is not a
     REG, possible enclosed by a conversion rtx, return the inner part of
     PAT that stopped the search.  */
--- 393,398 ----
*************** convert_regs_entry (void)
*** 2604,2628 ****
    int inserted = 0;
    edge e;
    edge_iterator ei;
-   basic_block block;
-
-   FOR_EACH_BB_REVERSE (block)
-     {
-       block_info bi = BLOCK_INFO (block);
-       int reg;
-
-       /* Set current register status at last instruction `uninitialized'.  */
-       bi->stack_in.top = -2;
-
-       /* Copy live_at_end and live_at_start into temporaries.  */
-       for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
- 	{
- 	  if (REGNO_REG_SET_P (block->global_live_at_end, reg))
- 	    SET_HARD_REG_BIT (bi->out_reg_set, reg);
- 	  if (REGNO_REG_SET_P (block->global_live_at_start, reg))
- 	    SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
- 	}
-     }

    /* Load something into each stack register live at function entry.
       Such live registers can be caused by uninitialized variables or
--- 2504,2509 ----
*************** convert_regs_2 (FILE *file, basic_block
*** 3078,3084 ****
     references in each insn from the "flat" register file that gcc uses,
     to the stack-like registers the 387 uses.  */

! static int
  convert_regs (FILE *file)
  {
    int inserted;
--- 2959,2965 ----
     references in each insn from the "flat" register file that gcc uses,
     to the stack-like registers the 387 uses.  */

! static void
  convert_regs (FILE *file)
  {
    int inserted;
*************** convert_regs (FILE *file)
*** 3118,3126 ****

    if (file)
      fputc ('\n', file);

!   return inserted;
  }
  #endif /* STACK_REGS */

  #include "gt-reg-stack.h"
--- 2999,3114 ----

    if (file)
      fputc ('\n', file);
+ }
+
+ /* Convert register usage from "flat" register file usage to a "stack
+    register file.  FILE is the dump file, if used.

!    Construct a CFG and run life analysis.  Then convert each insn one
!    by one.  Run a last cleanup_cfg pass, if optimizing, to eliminate
!    code duplication created when the converter inserts pop insns on
!    the edges.  */
!
! bool
! reg_to_stack (FILE *file)
! {
!   basic_block bb;
!   int i;
!   int max_uid;
!
!   /* Clean up previous run.  */
!   stack_regs_mentioned_data = 0;
!
!   /* See if there is something to do.  Flow analysis is quite
!      expensive so we might save some compilation time.  */
!   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
!     if (regs_ever_live[i])
!       break;
!   if (i > LAST_STACK_REG)
!     return false;
!
!   /* Ok, floating point instructions exist.  If not optimizing,
!      build the CFG and run life analysis.
!      Also need to rebuild life when superblock scheduling is done
!      as it don't update liveness yet.  */
!   if (!optimize
!       || (flag_sched2_use_superblocks
! 	  && flag_schedule_insns_after_reload))
!     {
!       count_or_remove_death_notes (NULL, 1);
!       life_analysis (file, PROP_DEATH_NOTES);
!     }
!   mark_dfs_back_edges ();
!
!   /* Set up block info for each basic block.  */
!   alloc_aux_for_blocks (sizeof (struct block_info_def));
!   FOR_EACH_BB_REVERSE (bb)
!     {
!       block_info bi = BLOCK_INFO (bb);
!       edge_iterator ei;
!       edge e;
!       int reg;
!
!       FOR_EACH_EDGE (e, ei, bb->preds)
! 	if (!(e->flags & EDGE_DFS_BACK)
! 	    && e->src != ENTRY_BLOCK_PTR)
! 	  bi->predecessors++;
!
!       /* Set current register status at last instruction `uninitialized'.  */
!       bi->stack_in.top = -2;
!
!       /* Copy live_at_end and live_at_start into temporaries.  */
!       for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
! 	{
! 	  if (REGNO_REG_SET_P (bb->global_live_at_end, reg))
! 	    SET_HARD_REG_BIT (bi->out_reg_set, reg);
! 	  if (REGNO_REG_SET_P (bb->global_live_at_start, reg))
! 	    SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
! 	}
!     }
!
!   /* Create the replacement registers up front.  */
!   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
!     {
!       enum machine_mode mode;
!       for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
! 	   mode != VOIDmode;
! 	   mode = GET_MODE_WIDER_MODE (mode))
! 	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
!       for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
! 	   mode != VOIDmode;
! 	   mode = GET_MODE_WIDER_MODE (mode))
! 	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
!     }
!
!   ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
!
!   /* A QNaN for initializing uninitialized variables.
!
!      ??? We can't load from constant memory in PIC mode, because
!      we're inserting these instructions before the prologue and
!      the PIC register hasn't been set up.  In that case, fall back
!      on zero, which we can get from `ldz'.  */
!
!   if (flag_pic)
!     not_a_num = CONST0_RTX (SFmode);
!   else
!     {
!       not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
!       not_a_num = force_const_mem (SFmode, not_a_num);
!     }
!
!   /* Allocate a cache for stack_regs_mentioned.  */
!   max_uid = get_max_uid ();
!   VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
! 		    "stack_regs_mentioned cache");
!
!   convert_regs (file);
!
!   free_aux_for_blocks ();
!   return true;
  }
  #endif /* STACK_REGS */


Roger
--


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