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]

Fix alpha/sparc failure


> On Sat, Oct 27, 2001 at 08:19:10PM +0200, Jan Hubicka wrote:
> > I am just testing following fix.  The problem is that function in question
> > swaps meaning of a and b in the middle and I do the setting too early :(
> 
> This doesn't fix the Alpha abort Toon reported.  Preprocessed
> source attached.

Hi,
the problem has been caused by the fact that liveness has been already
broken when entering cfg_cleanup.  This is caused by combine that turned
some conditionals to noop moves and updated life info. After that it
purged the dead edges that caused life info to be pesimistic, that caused
us to fail few passes later.

I solve the problem by avoiding the edge purging from delete_noop_moves, instead
I purge the edges at once after combine and update life information.

The patch also fixes two minor bugs in merge_blocks I found during proofreading.

Bootstrapped/regtested i386, sparc bootstrap in progress.

OK?
Honza

Sat Oct 27 22:08:52 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* basic-block.h (purge_all_dead_edges): Add life_ok argument.
	* cfgcleanup.c (merge_blocks): Update the life flag after merging;
	fix warning.
	* cfgrtl.c (purge_all_dead_edges): Allow updating of liveness.
	(life_analysis): call purge_all_dead_edges after deleting noops.
	(delete_noop_move): Do not purge CFG.
	* toplev.c (rest_of_compilation): Update purge_all_dead_edges call.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.126
diff -c -3 -p -r1.126 basic-block.h
*** basic-block.h	2001/10/26 07:49:34	1.126
--- basic-block.h	2001/10/27 20:05:51
*************** extern basic_block force_nonfallthru	PAR
*** 638,644 ****
  extern bool redirect_edge_and_branch	PARAMS ((edge, basic_block));
  extern rtx block_label			PARAMS ((basic_block));
  extern bool forwarder_block_p		PARAMS ((basic_block));
! extern bool purge_all_dead_edges	PARAMS ((void));
  extern bool purge_dead_edges		PARAMS ((basic_block));
  extern void find_sub_basic_blocks	PARAMS ((basic_block));
  extern void find_many_sub_basic_blocks	PARAMS ((sbitmap));
--- 638,644 ----
  extern bool redirect_edge_and_branch	PARAMS ((edge, basic_block));
  extern rtx block_label			PARAMS ((basic_block));
  extern bool forwarder_block_p		PARAMS ((basic_block));
! extern bool purge_all_dead_edges	PARAMS ((bool));
  extern bool purge_dead_edges		PARAMS ((basic_block));
  extern void find_sub_basic_blocks	PARAMS ((basic_block));
  extern void find_many_sub_basic_blocks	PARAMS ((sbitmap));
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgcleanup.c,v
retrieving revision 1.13
diff -c -3 -p -r1.13 cfgcleanup.c
*** cfgcleanup.c	2001/10/27 10:17:44	1.13
--- cfgcleanup.c	2001/10/27 20:05:51
*************** merge_blocks (e, b, c, mode)
*** 430,438 ****
        && tail_recursion_label_p (c->head))
      return false;
  
    /* If B has a fallthru edge to C, no need to move anything.  */
    if (e->flags & EDGE_FALLTHRU)
      {
        merge_blocks_nomove (b, c);
        update_forwarder_flag (b);
  
--- 430,444 ----
        && tail_recursion_label_p (c->head))
      return false;
  
!   /* If B has a fallthru edge to C, no need to move anything.  */
    if (e->flags & EDGE_FALLTHRU)
      {
+       /* We need to update liveness in case C already has broken liveness
+ 	 or B ends by conditional jump to next instructions that will be
+ 	 removed.  */
+       if ((BB_FLAGS (c) & BB_UPDATE_LIFE)
+ 	  || GET_CODE (b->end) == JUMP_INSN)
+ 	BB_SET_FLAG (b, BB_UPDATE_LIFE);
        merge_blocks_nomove (b, c);
        update_forwarder_flag (b);
  
*************** merge_blocks (e, b, c, mode)
*** 490,496 ****
  
        if (b_has_incoming_fallthru)
  	{
! 	  rtx bb;
  	  if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
  	    return false;
  	  bb = force_nonfallthru (b_fallthru_edge);
--- 499,505 ----
  
        if (b_has_incoming_fallthru)
  	{
! 	  basic_block bb;
  	  if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
  	    return false;
  	  bb = force_nonfallthru (b_fallthru_edge);
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgrtl.c,v
retrieving revision 1.5
diff -c -3 -p -r1.5 cfgrtl.c
*** cfgrtl.c	2001/10/27 10:17:44	1.5
--- cfgrtl.c	2001/10/27 20:05:52
*************** purge_dead_edges (bb)
*** 1923,1932 ****
   */
  
  bool
! purge_all_dead_edges ()
  {
    int i, purged = false;
    for (i = 0; i < n_basic_blocks; i++)
!     purged |= purge_dead_edges (BASIC_BLOCK (i));
    return purged;
  }
--- 1923,1952 ----
   */
  
  bool
! purge_all_dead_edges (life_ok)
!      bool life_ok;
  {
    int i, purged = false;
+   sbitmap blocks;
+ 
+   if (life_ok)
+     {
+       blocks = sbitmap_alloc (n_basic_blocks);
+       sbitmap_zero (blocks);
+     }
    for (i = 0; i < n_basic_blocks; i++)
!     {
!       bool purged_here;
!       purged_here = purge_dead_edges (BASIC_BLOCK (i));
!       purged |= purged_here;
!       if (purged_here && life_ok)
! 	SET_BIT (blocks, i);
!     }
!   if (life_ok && purged)
!     update_life_info (blocks, UPDATE_LIFE_GLOBAL,
! 		      PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
! 		      | PROP_KILL_DEAD_CODE);
!   if (life_ok)
!     sbitmap_free (blocks);
    return purged;
  }
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.487
diff -c -3 -p -r1.487 flow.c
*** flow.c	2001/10/26 09:20:01	1.487
--- flow.c	2001/10/27 20:05:55
*************** life_analysis (f, file, flags)
*** 456,461 ****
--- 456,462 ----
    /* Always remove no-op moves.  Do this before other processing so
       that we don't have to keep re-scanning them.  */
    delete_noop_moves (f);
+   purge_all_dead_edges (false);
  
    /* Some targets can emit simpler epilogues if they know that sp was
       not ever modified during the function.  After reload, of course,
*************** delete_noop_moves (f)
*** 803,810 ****
  	      PUT_CODE (insn, NOTE);
  	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  	      NOTE_SOURCE_FILE (insn) = 0;
- 	      if (insn == bb->end)
- 		purge_dead_edges (bb);
  	    }
  	}
      }
--- 804,809 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.526
diff -c -3 -p -r1.526 toplev.c
*** toplev.c	2001/10/25 17:56:51	1.526
--- toplev.c	2001/10/27 20:05:56
*************** rest_of_compilation (decl)
*** 3297,3303 ****
  
        /* Always purge dead edges, as we may eliminate an insn throwing
           exception.  */
!       rebuild_jump_labels_after_combine |= purge_all_dead_edges ();
  
        /* Combining insns may have turned an indirect jump into a
  	 direct jump.  Rebuid the JUMP_LABEL fields of jumping
--- 3297,3303 ----
  
        /* Always purge dead edges, as we may eliminate an insn throwing
           exception.  */
!       rebuild_jump_labels_after_combine |= purge_all_dead_edges (true);
  
        /* Combining insns may have turned an indirect jump into a
  	 direct jump.  Rebuid the JUMP_LABEL fields of jumping


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