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