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]

fix latent bug in crossjuping


Hi,
the trace scheduling on cfgbranch uncovered another latent problem in crossjumping.
WHen we merge two blocks, one containing clobber, it is necesary to remove the clobber in order to avoid
the other computation patch from loosing the computation.
It may be better to move the clobber to the edge but that can futher complicate
flowgraph and I don't think liveness in functions just prtially returning value
is that important.

Bootstrapped/regtested rtlopt branch.  OK for mainline?
Tue Dec 31 17:20:47 CET 2002  Jan Hubicka  <jh@suse.cz>
	* cfgcleanup.c (try_crossjump_to_edge):  Remove bohus clobbers.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.63.2.6
diff -c -3 -p -r1.63.2.6 cfgcleanup.c
*** cfgcleanup.c	18 Dec 2002 10:35:02 -0000	1.63.2.6
--- cfgcleanup.c	31 Dec 2002 16:25:14 -0000
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1348,1353 ****
--- 1348,1354 ----
    basic_block redirect_to, redirect_from, to_remove;
    rtx newpos1, newpos2;
    edge s;
+   rtx insn;
  
    /* Search backward through forwarder blocks.  We don't need to worry
       about multiple entry or chained forwarders, as they will be optimized
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1480,1485 ****
--- 1481,1512 ----
    to_remove = redirect_from->succ->dest;
  
    redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
+ 
+   /*  The redirect_to may contain clobbers missing in to_remove.  This
+       is commonly the case when return value is undefined in some paths.
+       We must wallk trought the clobbers and remove these that clobber values
+       live in beggining of to_remove and not in the beggining of redirect_to.
+ 
+       If needed the same trick can be done without liveness information by
+       comparing clobbers and uses present in both blocks.  */
+   if (!(mode & CLEANUP_POST_REGSTACK))
+     {
+       if (!(mode & CLEANUP_UPDATE_LIFE))
+ 	abort ();
+       for (insn = redirect_to->head; insn != NEXT_INSN (redirect_to->end);
+ 	   insn = NEXT_INSN (insn))
+ 	if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == CLOBBER
+ 	    && REG_P (XEXP (PATTERN (insn), 0)))
+ 	  {
+ 	    unsigned int regno = REGNO (XEXP (PATTERN (insn), 0));
+ 	    if (REGNO_REG_SET_P (to_remove->global_live_at_start, regno)
+ 		&& !REGNO_REG_SET_P (redirect_to->global_live_at_start, regno))
+ 	      delete_insn (insn);
+ 	  }
+       IOR_REG_SET (redirect_to->global_live_at_start, 
+ 		   to_remove->global_live_at_start);
+     }
+ 
    flow_delete_block (to_remove);
  
    update_forwarder_flag (redirect_from);


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