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]

Re: PR17340 - disable accurate live analysis for now?


Richard Henderson wrote:

On Tue, Dec 14, 2004 at 11:48:04AM -0500, Vladimir Makarov wrote:


* global.c (bb_info, allocate_bb_info, free_bb_info,
modify_reg_pav, make_accurate_live_analysis). Rename pavin,
pavout to live_pavin, live_pavout.
(modify_bb_reg_pav): Ditto. Use live information to calculate
live_pavin, live_pavout.
(temp_bitmap): New variable.
(calculate_reg_pav): Allocate/deallocate temp_bitmap.



Ok.


Further improvement: Move this loop,

         FOR_EACH_EDGE (e, ei, bb->preds)
           changed_p = modify_bb_reg_pav (bb, e->src, changed_p);



bb_info = BB_INFO (bb);
! bb_live_pavin = bb_info->live_pavin;
! bb_live_pavout = bb_info->live_pavout;
if (pred->index != ENTRY_BLOCK)
! {
! bitmap_ior_into (bb_live_pavin, BB_INFO (pred)->live_pavout);
! bitmap_and_into (bb_live_pavin, bb->global_live_at_start);
! }


It was consequence that the function was a generic one (could be used for any forward propagation solution of equations). Therefore I've missed that modify_bb_reg_pav can be inlined and sped up.

Here the final patch which I commited few minutes ago. The patch was tested again on x86, x86-64.

2004-12-15  Vladimir Makarov  <vmakarov@redhat.com>
           Steven Bosscher  <stevenb@suse.de>
	PR middle end/17340

	* global.c: Update comments in a few places.
	(check_earlyclobber): Return true if there are early clobber
	classes.
       (calculate_local_reg_bb_info): Do not try to mark earlyclobber
	regs if there are none.
	(bb_info, allocate_bb_info, free_bb_info, modify_reg_pav,
	make_accurate_live_analysis): Rename pavin, pavout to live_pavin,
	live_pavout.
	(modify_bb_reg_pav): Remove.
	(calculate_reg_pav): Use code from modify_bb_reg_pav.
	(temp_bitmap): New variable.
	(calculate_reg_pav): Allocate/deallocate temp_bitmap.




Vlad





Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.118
diff -c -p -r1.118 global.c
*** global.c	25 Nov 2004 09:30:03 -0000	1.118
--- global.c	15 Dec 2004 17:25:14 -0000
*************** static void reg_dies (int, enum machine_
*** 308,321 ****
  
  static void allocate_bb_info (void);
  static void free_bb_info (void);
! static void check_earlyclobber (rtx);
  static bool regclass_intersect (enum reg_class, enum reg_class);
  static void mark_reg_use_for_earlyclobber_1 (rtx *, void *);
  static int mark_reg_use_for_earlyclobber (rtx *, void *);
  static void calculate_local_reg_bb_info (void);
  static void set_up_bb_rts_numbers (void);
  static int rpost_cmp (const void *, const void *);
- static bool modify_bb_reg_pav (basic_block, basic_block, bool);
  static void calculate_reg_pav (void);
  static void modify_reg_pav (void);
  static void make_accurate_live_analysis (void);
--- 308,320 ----
  
  static void allocate_bb_info (void);
  static void free_bb_info (void);
! static bool check_earlyclobber (rtx);
  static bool regclass_intersect (enum reg_class, enum reg_class);
  static void mark_reg_use_for_earlyclobber_1 (rtx *, void *);
  static int mark_reg_use_for_earlyclobber (rtx *, void *);
  static void calculate_local_reg_bb_info (void);
  static void set_up_bb_rts_numbers (void);
  static int rpost_cmp (const void *, const void *);
  static void calculate_reg_pav (void);
  static void modify_reg_pav (void);
  static void make_accurate_live_analysis (void);
*************** struct bb_info
*** 2011,2019 ****
    /* Registers correspondingly killed (clobbered) and defined but not
       killed afterward in the basic block.  */
    bitmap killed, avloc;
!   /* Registers partially available correspondingly at the start and
!      end of the basic block.  */
!   bitmap pavin, pavout;
  };
  
  /* Macros for accessing data flow information of basic blocks.  */
--- 2010,2019 ----
    /* Registers correspondingly killed (clobbered) and defined but not
       killed afterward in the basic block.  */
    bitmap killed, avloc;
!   /* Registers partially available and living (in other words whose
!      values were calclualted and used) correspondingly at the start
!      and end of the basic block.  */
!   bitmap live_pavin, live_pavout;
  };
  
  /* Macros for accessing data flow information of basic blocks.  */
*************** struct bb_info
*** 2022,2029 ****
  #define BB_INFO_BY_INDEX(N) BB_INFO (BASIC_BLOCK(N))
  
  /* The function allocates the info structures of each basic block.  It
!    also initialized PAVIN and PAVOUT as if all hard registers were
!    partially available.  */
  
  static void
  allocate_bb_info (void)
--- 2022,2029 ----
  #define BB_INFO_BY_INDEX(N) BB_INFO (BASIC_BLOCK(N))
  
  /* The function allocates the info structures of each basic block.  It
!    also initialized LIVE_PAVIN and LIVE_PAVOUT as if all hard
!    registers were partially available.  */
  
  static void
  allocate_bb_info (void)
*************** allocate_bb_info (void)
*** 2043,2052 ****
        bb_info->earlyclobber = BITMAP_XMALLOC ();
        bb_info->avloc = BITMAP_XMALLOC ();
        bb_info->killed = BITMAP_XMALLOC ();
!       bb_info->pavin = BITMAP_XMALLOC ();
!       bb_info->pavout = BITMAP_XMALLOC ();
!       bitmap_copy (bb_info->pavin, init);
!       bitmap_copy (bb_info->pavout, init);
      }
    BITMAP_XFREE (init);
  }
--- 2043,2052 ----
        bb_info->earlyclobber = BITMAP_XMALLOC ();
        bb_info->avloc = BITMAP_XMALLOC ();
        bb_info->killed = BITMAP_XMALLOC ();
!       bb_info->live_pavin = BITMAP_XMALLOC ();
!       bb_info->live_pavout = BITMAP_XMALLOC ();
!       bitmap_copy (bb_info->live_pavin, init);
!       bitmap_copy (bb_info->live_pavout, init);
      }
    BITMAP_XFREE (init);
  }
*************** free_bb_info (void)
*** 2062,2069 ****
    FOR_EACH_BB (bb)
      {
        bb_info = BB_INFO (bb);
!       BITMAP_XFREE (bb_info->pavout);
!       BITMAP_XFREE (bb_info->pavin);
        BITMAP_XFREE (bb_info->killed);
        BITMAP_XFREE (bb_info->avloc);
        BITMAP_XFREE (bb_info->earlyclobber);
--- 2062,2069 ----
    FOR_EACH_BB (bb)
      {
        bb_info = BB_INFO (bb);
!       BITMAP_XFREE (bb_info->live_pavout);
!       BITMAP_XFREE (bb_info->live_pavin);
        BITMAP_XFREE (bb_info->killed);
        BITMAP_XFREE (bb_info->avloc);
        BITMAP_XFREE (bb_info->earlyclobber);
*************** mark_reg_change (rtx reg, rtx setter, vo
*** 2101,2113 ****
  
  static varray_type earlyclobber_regclass;
  
! /* The function stores classes of registers which could be early
!    clobbered in INSN.  */
  
! static void
  check_earlyclobber (rtx insn)
  {
    int opno;
  
    extract_insn (insn);
  
--- 2101,2115 ----
  
  static varray_type earlyclobber_regclass;
  
! /* This function finds and stores register classes that could be early
!    clobbered in INSN.  If any earlyclobber classes are found, the function
!    returns TRUE, in all other cases it returns FALSE.  */
  
! static bool
  check_earlyclobber (rtx insn)
  {
    int opno;
+   bool found = false;
  
    extract_insn (insn);
  
*************** check_earlyclobber (rtx insn)
*** 2148,2153 ****
--- 2150,2156 ----
  	    case ',':
  	      if (amp_p && class != NO_REGS)
  		{
+ 		  found = true;
  		  for (i = VARRAY_ACTIVE_SIZE (earlyclobber_regclass) - 1;
  		       i >= 0; i--)
  		    if (VARRAY_INT (earlyclobber_regclass, i) == (int) class)
*************** check_earlyclobber (rtx insn)
*** 2173,2178 ****
--- 2176,2183 ----
  	  p += CONSTRAINT_LEN (c, p);
  	}
      }
+ 
+   return found;
  }
  
  /* The function returns true if register classes C1 and C2 intersect.  */
*************** regclass_intersect (enum reg_class c1, e
*** 2193,2199 ****
  
  /* The function checks that pseudo-register *X has a class
     intersecting with the class of pseudo-register could be early
!    clobbered in the same insn.  */
  
  static int
  mark_reg_use_for_earlyclobber (rtx *x, void *data ATTRIBUTE_UNUSED)
--- 2198,2205 ----
  
  /* The function checks that pseudo-register *X has a class
     intersecting with the class of pseudo-register could be early
!    clobbered in the same insn.
!    This function is a no-op if earlyclobber_regclass is empty.  */
  
  static int
  mark_reg_use_for_earlyclobber (rtx *x, void *data ATTRIBUTE_UNUSED)
*************** calculate_local_reg_bb_info (void)
*** 2251,2258 ****
  	if (INSN_P (insn))
  	  {
  	    note_stores (PATTERN (insn), mark_reg_change, bb);
! 	    check_earlyclobber (insn);
! 	    note_uses (&PATTERN (insn), mark_reg_use_for_earlyclobber_1, bb);
  	  }
      }
  }
--- 2257,2264 ----
  	if (INSN_P (insn))
  	  {
  	    note_stores (PATTERN (insn), mark_reg_change, bb);
! 	    if (check_earlyclobber (insn))
! 	      note_uses (&PATTERN (insn), mark_reg_use_for_earlyclobber_1, bb);
  	  }
      }
  }
*************** rpost_cmp (const void *bb1, const void *
*** 2283,2322 ****
    return BB_INFO (b2)->rts_number - BB_INFO (b1)->rts_number;
  }
  
! /* The function calculates partial availability of registers.  The
!    function calculates partial availability at the end of basic block
!    BB by propagating partial availability at end of predecessor basic
!    block PRED.  The function returns true if the partial availability
!    at the end of BB has been changed or if CHANGED_P.  We have the
!    following equations:
  
!      bb.pavin = empty for entry block | union (pavout of predecessors)
!      bb.pavout = union (bb.pavin - b.killed, bb.avloc)  */
  
! static bool
! modify_bb_reg_pav (basic_block bb, basic_block pred, bool changed_p)
! {
!   struct bb_info *bb_info;
!   bitmap bb_pavin, bb_pavout;
! 
!   bb_info = BB_INFO (bb);
!   bb_pavin = bb_info->pavin;
!   bb_pavout = bb_info->pavout;
!   if (pred->index != ENTRY_BLOCK)
!     bitmap_ior_into (bb_pavin, BB_INFO (pred)->pavout);
!   changed_p |= bitmap_ior_and_compl (bb_pavout, bb_info->avloc,
! 				     bb_pavin, bb_info->killed);
!   return changed_p;
! }
! 
! /* The function calculates partial register availability.  */
  
  static void
  calculate_reg_pav (void)
  {
    basic_block bb, succ;
    edge e;
-   bool changed_p;
    int i, nel;
    varray_type bbs, new_bbs, temp;
    basic_block *bb_array;
--- 2289,2311 ----
    return BB_INFO (b2)->rts_number - BB_INFO (b1)->rts_number;
  }
  
! /* Temporary bitmap used for live_pavin, live_pavout calculation.  */
! static bitmap temp_bitmap;
  
! /* The function calculates partial register availability according to
!    the following equations:
  
!      bb.live_pavin
!        = empty for entry block
!          | union (live_pavout of predecessors) & global_live_at_start
!      bb.live_pavout = union (bb.live_pavin - bb.killed, bb.avloc)
!                       & global_live_at_end  */
  
  static void
  calculate_reg_pav (void)
  {
    basic_block bb, succ;
    edge e;
    int i, nel;
    varray_type bbs, new_bbs, temp;
    basic_block *bb_array;
*************** calculate_reg_pav (void)
*** 2324,2329 ****
--- 2313,2319 ----
  
    VARRAY_BB_INIT (bbs, n_basic_blocks, "basic blocks");
    VARRAY_BB_INIT (new_bbs, n_basic_blocks, "basic blocks for the next iter.");
+   temp_bitmap = BITMAP_XMALLOC ();
    FOR_EACH_BB (bb)
      {
        VARRAY_PUSH_BB (bbs, bb);
*************** calculate_reg_pav (void)
*** 2338,2358 ****
        for (i = 0; i < nel; i++)
  	{
  	  edge_iterator ei;
! 
  	  bb = bb_array [i];
! 	  changed_p = 0;
  	  FOR_EACH_EDGE (e, ei, bb->preds)
! 	    changed_p = modify_bb_reg_pav (bb, e->src, changed_p);
! 	  if (changed_p)
! 	    FOR_EACH_EDGE (e, ei, bb->succs)
! 	      {
! 		succ = e->dest;
! 		if (succ->index != EXIT_BLOCK && !TEST_BIT (wset, succ->index))
! 		  {
! 		    SET_BIT (wset, succ->index);
! 		    VARRAY_PUSH_BB (new_bbs, succ);
! 		  }
! 	      }
  	}
        temp = bbs;
        bbs = new_bbs;
--- 2328,2365 ----
        for (i = 0; i < nel; i++)
  	{
  	  edge_iterator ei;
! 	  struct bb_info *bb_info;
! 	  bitmap bb_live_pavin, bb_live_pavout;
! 	      
  	  bb = bb_array [i];
! 	  bb_info = BB_INFO (bb);
! 	  bb_live_pavin = bb_info->live_pavin;
! 	  bb_live_pavout = bb_info->live_pavout;
  	  FOR_EACH_EDGE (e, ei, bb->preds)
! 	    {
! 	      basic_block pred = e->src;
! 
! 	      if (pred->index != ENTRY_BLOCK)
! 		bitmap_ior_into (bb_live_pavin, BB_INFO (pred)->live_pavout);
! 	    }
! 	  bitmap_and_into (bb_live_pavin, bb->global_live_at_start);
! 	  bitmap_ior_and_compl (temp_bitmap, bb_info->avloc,
! 				bb_live_pavin, bb_info->killed);
! 	  bitmap_and_into (temp_bitmap, bb->global_live_at_end);
! 	  if (! bitmap_equal_p (temp_bitmap, bb_live_pavout))
! 	    {
! 	      bitmap_copy (bb_live_pavout, temp_bitmap);
! 	      FOR_EACH_EDGE (e, ei, bb->succs)
! 		{
! 		  succ = e->dest;
! 		  if (succ->index != EXIT_BLOCK
! 		      && !TEST_BIT (wset, succ->index))
! 		    {
! 		      SET_BIT (wset, succ->index);
! 		      VARRAY_PUSH_BB (new_bbs, succ);
! 		    }
! 		}
! 	    }
  	}
        temp = bbs;
        bbs = new_bbs;
*************** calculate_reg_pav (void)
*** 2360,2365 ****
--- 2367,2373 ----
        VARRAY_POP_ALL (new_bbs);
      }
    sbitmap_free (wset);
+   BITMAP_XFREE (temp_bitmap);
  }
  
  /* The function modifies partial availability information for two
*************** modify_reg_pav (void)
*** 2402,2415 ****
  	 insn if the pseudo-register is used first time in given BB
  	 and not lived at the BB start.  To prevent this we don't
  	 change life information for such pseudo-registers.  */
!       bitmap_ior_into (bb_info->pavin, bb_info->earlyclobber);
  #ifdef STACK_REGS
        /* We can not use the same stack register for uninitialized
  	 pseudo-register and another living pseudo-register because if the
  	 uninitialized pseudo-register dies, subsequent pass reg-stack
  	 will be confused (it will believe that the other register
  	 dies).  */
!       bitmap_ior_into (bb_info->pavin, stack_regs);
  #endif
      }
  #ifdef STACK_REGS
--- 2410,2423 ----
  	 insn if the pseudo-register is used first time in given BB
  	 and not lived at the BB start.  To prevent this we don't
  	 change life information for such pseudo-registers.  */
!       bitmap_ior_into (bb_info->live_pavin, bb_info->earlyclobber);
  #ifdef STACK_REGS
        /* We can not use the same stack register for uninitialized
  	 pseudo-register and another living pseudo-register because if the
  	 uninitialized pseudo-register dies, subsequent pass reg-stack
  	 will be confused (it will believe that the other register
  	 dies).  */
!       bitmap_ior_into (bb_info->live_pavin, stack_regs);
  #endif
      }
  #ifdef STACK_REGS
*************** modify_reg_pav (void)
*** 2419,2428 ****
  
  /* The following function makes live information more accurate by
     modifying global_live_at_start and global_live_at_end of basic
!    blocks.  After the function call a register lives at a program
!    point only if it is initialized on a path from CFG entry to the
!    program point.  The standard GCC life analysis permits registers to
!    live uninitialized.  */
  
  static void
  make_accurate_live_analysis (void)
--- 2427,2451 ----
  
  /* The following function makes live information more accurate by
     modifying global_live_at_start and global_live_at_end of basic
!    blocks.
! 
!    The standard GCC life analysis permits registers to live
!    uninitialized, for example:
! 
!        R is never used
!        .....
!        Loop:
!          R is defined
!        ...
!        R is used.
! 
!    With normal life_analysis, R would be live before "Loop:".
!    The result is that R causes many interferences that do not
!    serve any purpose.
! 
!    After the function call a register lives at a program point
!    only if it is initialized on a path from CFG entry to the
!    program point.  */
  
  static void
  make_accurate_live_analysis (void)
*************** make_accurate_live_analysis (void)
*** 2441,2448 ****
      {
        bb_info = BB_INFO (bb);
        
!       bitmap_and_into (bb->global_live_at_start, bb_info->pavin);
!       bitmap_and_into (bb->global_live_at_end, bb_info->pavout);
      }
    free_bb_info ();
  }
--- 2464,2471 ----
      {
        bb_info = BB_INFO (bb);
        
!       bitmap_and_into (bb->global_live_at_start, bb_info->live_pavin);
!       bitmap_and_into (bb->global_live_at_end, bb_info->live_pavout);
      }
    free_bb_info ();
  }

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