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]

Combine versus updating of liveness



Hi,
this cfg-branch crashes in bootstrap after updating to mainline. The purpose
is latent bug in updating liveness after combine.  What happends is an condjump
converted to noop (set (pc) (pc)) on the end of basic block, where given register
is live only on the impossible branching path.

Combine knows how to update liveness in local cases and is happy here - and
correct according to current CFG.  Later delete_noop_moves is called that
should not need updating of cfg, but it detects the dead edge and removes it
via purge_dead_edges causing liveness to be inconsistent.  Later we care
updating the liveness after purge_all_dead_edges, but it is not enought, since
we no longer have this particular dead edge.

Fixing for mainline and branch is probably the attached patch that converts
all three beasts to use BB_DIRTY flags for updating instead of maitaining
their own bitmaps.  The liveness is updated once after all three passes iterate.

Problem is how to fix this porperly for the 3.1 branch?
Unfortunately I don't have testcase that reproduce w/o superblock formation...

Bootstrapped/regtested i386 on mainline, installed to cfg-branch.
OK for mainline?

Honza

Wed Mar  6 18:36:03 CET 2002  Jan Hubicka  <jh@suse.cz>
	* cfgrtl.c (purge_dead_edges): Set BB_DRITY flags if edge has been removed;
	fix return value.
	* combine.c (combine_instructions): Dirtify blocks where we failed to
	update liveness; purge dead edges; use update_life_info_in_dirty_blocks.
	* toplev.c (rest_of_compilation): Do not purge_dead_edges after combine.
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgrtl.c,v
retrieving revision 1.10.2.28
diff -c -3 -p -r1.10.2.28 cfgrtl.c
*** cfgrtl.c	2002/03/06 10:04:34	1.10.2.28
--- cfgrtl.c	2002/03/06 17:03:52
*************** purge_dead_edges (bb)
*** 2153,2158 ****
--- 2153,2159 ----
  	if (e->flags & EDGE_EH)
  	  {
  	    remove_edge (e);
+ 	    bb->flags |= BB_DIRTY;
  	    purged = true;
  	  }
        }
*************** purge_dead_edges (bb)
*** 2166,2172 ****
        if (!any_condjump_p (insn)
  	  && !returnjump_p (insn)
  	  && !simplejump_p (insn))
! 	return false;
  
        /* Branch probability/prediction notes are defined only for
  	 condjumps.  We've possibly turned condjump into simplejump.  */
--- 2167,2173 ----
        if (!any_condjump_p (insn)
  	  && !returnjump_p (insn)
  	  && !simplejump_p (insn))
! 	return purged;
  
        /* Branch probability/prediction notes are defined only for
  	 condjumps.  We've possibly turned condjump into simplejump.  */
*************** purge_dead_edges (bb)
*** 2199,2210 ****
  		   && returnjump_p (insn))
  	    continue;
  
  	  purged = true;
  	  remove_edge (e);
  	}
  
        if (!bb->succ || !purged)
! 	return false;
  
        if (rtl_dump_file)
  	fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
--- 2200,2212 ----
  		   && returnjump_p (insn))
  	    continue;
  
+ 	  bb->flags |= BB_DIRTY;
  	  purged = true;
  	  remove_edge (e);
  	}
  
        if (!bb->succ || !purged)
! 	return purged;
  
        if (rtl_dump_file)
  	fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
*************** purge_dead_edges (bb)
*** 2251,2257 ****
      {
        next = e->succ_next;
        if (!(e->flags & EDGE_FALLTHRU))
! 	remove_edge (e), purged = true;
      }
  
    if (!bb->succ || bb->succ->succ_next)
--- 2253,2263 ----
      {
        next = e->succ_next;
        if (!(e->flags & EDGE_FALLTHRU))
! 	{
! 	  bb->flags |= BB_DIRTY;
! 	  remove_edge (e);
! 	  purged = true;
! 	}
      }
  
    if (!bb->succ || bb->succ->succ_next)
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.241.2.10
diff -c -3 -p -r1.241.2.10 combine.c
*** combine.c	2002/03/05 18:58:04	1.241.2.10
--- combine.c	2002/03/06 17:03:59
*************** combine_instructions (f, nregs)
*** 739,752 ****
  	  ;
  	}
      }
  
    delete_noop_moves (f);
  
!   if (need_refresh)
!     {
!       update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
! 			PROP_DEATH_NOTES);
!     }
  
    /* Clean up.  */
    sbitmap_free (refresh_blocks);
--- 739,754 ----
  	  ;
  	}
      }
+   clear_bb_flags ();
  
+   EXECUTE_IF_SET_IN_SBITMAP (refresh_blocks, 0, this_basic_block,
+ 			     BASIC_BLOCK (this_basic_block)->flags |= BB_DIRTY);
+   new_direct_jump_p |= purge_all_dead_edges (0);
    delete_noop_moves (f);
  
!   update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
! 				    PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
! 				    | PROP_KILL_DEAD_CODE);
  
    /* Clean up.  */
    sbitmap_free (refresh_blocks);
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.537.2.47
diff -c -3 -p -r1.537.2.47 toplev.c
*** toplev.c	2002/03/06 10:04:40	1.537.2.47
--- toplev.c	2002/03/06 17:04:01
*************** rest_of_compilation (decl)
*** 3247,3256 ****
  
        rebuild_jump_labels_after_combine
  	= combine_instructions (insns, max_reg_num ());
- 
-       /* 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
--- 3247,3252 ----


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