Fix detection of new LABEL_REF

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Sun Jul 1 08:54:00 GMT 2001


The code in cse.c that tries to return 1 from cse_main if a new LABEL_REF
is added isn't quite correct in that it doesn't handle the case where a
LABEL_REF is moved from one insn to another and the original insn is
deleted.  The most straightforward way is simply to look for LABEL_REFs in
the insn, which I did.

Bootstrapped on ia32-Linux: the test case comes up bootstrapping GNAT.

Sun Jul  1 11:53:52 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* cse.c (new_label_ref): Variable deleted.
	(insert): Remove set of new_label_ref.
	(check_for_label_ref): New function.
	(cse_basic_block): Don't check new_label_ref; call check_for_label_ref.

*** cse.c	2001/05/17 18:46:57	1.186
--- cse.c	2001/07/01 15:40:15
*************** static int cse_jumps_altered;
*** 387,394 ****
  static int recorded_label_ref;
  
- /* Says which LABEL_REF was put in the hash table.  Used to see if we need
-    to set the above flag.  */
- static rtx new_label_ref;
- 
  /* canon_hash stores 1 in do_not_record
     if it notices a reference to CC0, PC, or some other volatile
--- 387,390 ----
*************** static void cse_set_around_loop	PARAMS (
*** 693,696 ****
--- 689,693 ----
  static rtx cse_basic_block	PARAMS ((rtx, rtx, struct branch_path *, int));
  static void count_reg_usage	PARAMS ((rtx, int *, rtx, int));
+ static int check_for_label_ref	PARAMS ((rtx *, void *));
  extern void dump_class          PARAMS ((struct table_elt*));
  static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
*************** insert (x, classp, hash, mode)
*** 1581,1590 ****
      }
  
-   /* If X is a label, show we recorded it.  */
-   if (GET_CODE (x) == LABEL_REF
-       || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
- 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF))
-     new_label_ref = x;
- 
    /* Put an element for X into the right hash bucket.  */
  
--- 1579,1582 ----
*************** cse_basic_block (from, to, next_branch, 
*** 7291,7304 ****
  	    }
  
- 	  new_label_ref = 0;
  	  cse_insn (insn, libcall_insn);
  
! 	  /* If this insn uses a LABEL_REF and there isn't a REG_LABEL
! 	     note for it, we must rerun jump since it needs to place the
! 	     note.  If this is a LABEL_REF for a CODE_LABEL that isn't in
! 	     the insn chain, don't do this since no REG_LABEL will be added. */
! 	  if (new_label_ref != 0 && INSN_UID (XEXP (new_label_ref, 0)) != 0
! 	      && reg_mentioned_p (new_label_ref, PATTERN (insn))
! 	      && ! find_reg_note (insn, REG_LABEL, XEXP (new_label_ref, 0)))
  	    recorded_label_ref = 1;
  	}
--- 7284,7294 ----
  	    }
  
  	  cse_insn (insn, libcall_insn);
  
! 	  /* If we haven't already found an insn where we added a LABEL_REF,
! 	     check this one.  */
! 	  if (GET_CODE (insn) == INSN && ! recorded_label_ref
! 	      && for_each_rtx (&PATTERN (insn), check_for_label_ref,
! 			       (void *) insn))
  	    recorded_label_ref = 1;
  	}
*************** cse_basic_block (from, to, next_branch, 
*** 7407,7410 ****
--- 7397,7419 ----
  
    return to ? NEXT_INSN (to) : 0;
+ }
+ 
+ /* Called via for_each_rtx to see if an insn is using a LABEL_REF for which
+    there isn't a REG_DEAD note.  Return one if so.  DATA is the insn.  */
+ 
+ static int
+ check_for_label_ref (rtl, data)
+      rtx *rtl;
+      void *data;
+ {
+   rtx insn = (rtx) data;
+ 
+   /* If this insn uses a LABEL_REF and there isn't a REG_LABEL note for it,
+      we must rerun jump since it needs to place the note.  If this is a
+      LABEL_REF for a CODE_LABEL that isn't in the insn chain, don't do this
+      since no REG_LABEL will be added. */
+   return (GET_CODE (*rtl) == LABEL_REF
+ 	  && INSN_UID (XEXP (*rtl, 0)) != 0
+ 	  && ! find_reg_note (insn, REG_LABEL, XEXP (*rtl, 0)));
  }
  



More information about the Gcc-patches mailing list