fix jump threading with liveness

Jan Hubicka jh@suse.cz
Sun Mar 3 10:22:00 GMT 2002


Hi,
this patch fixes jump threading when liveness is available.  We are proving equivalenness
of various registers and then and them with live registers forgetting to check whether
the conditional itself is equivalent.

No need to patch branch, as threading is never done with liveness available.

Bootstrapped/regtested i386

	* cfgcleanup.c (mentiones_nonequal_regs): New function.
	(thread_jump): Use it.

*** /egcs2/egcs/gcc/cfgcleanup.c	Fri Mar  1 20:51:33 2002
--- cfgcleanup.c	Sun Mar  3 18:34:58 2002
*************** static edge thread_jump			PARAMS ((int, 
*** 89,94 ****
--- 89,95 ----
  static bool mark_effect			PARAMS ((rtx, bitmap));
  static void notice_new_block		PARAMS ((basic_block));
  static void update_forwarder_flag	PARAMS ((basic_block));
+ static int mentions_nonequal_regs	PARAMS ((rtx *, void *));
  
  /* Set flags for newly created block.  */
  
*************** mark_effect (exp, nonequal)
*** 235,240 ****
--- 236,267 ----
  	return false;
      }
  }
+ 
+ /* Return nonzero if X is an register set in regset DATA.
+    Called via for_each_rtx.  */
+ static int
+ mentions_nonequal_regs (x, data)
+      rtx *x;
+      void *data;
+ {
+   regset nonequal = (regset) data;
+   if (REG_P (*x))
+     {
+       int regno;
+ 
+       regno = REGNO (*x);
+       if (REGNO_REG_SET_P (nonequal, regno))
+ 	return 1;
+       if (regno < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  int n = HARD_REGNO_NREGS (regno, GET_MODE (*x));
+ 	  while (--n > 0)
+ 	    if (REGNO_REG_SET_P (nonequal, regno + n))
+ 	      return 1;
+ 	}
+     }
+   return 0;
+ }
  /* Attempt to prove that the basic block B will have no side effects and
     allways continues in the same edge if reached via E.  Return the edge
     if exist, NULL otherwise.  */
*************** thread_jump (mode, e, b)
*** 338,343 ****
--- 365,375 ----
    if (failed)
      goto failed_exit;
  
+   /* cond2 must not mention any register that is not equal to the
+      former block.  */
+   if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
+     goto failed_exit;
+ 
    /* In case liveness information is available, we need to prove equivalence
       only of the live values.  */
    if (mode & CLEANUP_UPDATE_LIFE)



More information about the Gcc-patches mailing list