This is the mail archive of the
mailing list for the GCC project.
Re: Question about gcse.c vs cc0
Steven Bosscher <firstname.lastname@example.org> writes:
> In gcse.c:insert_insn_end_basic_block() I found the following code:
> #ifdef HAVE_cc0
> /* FIXME: 'twould be nice to call prev_cc0_setter here but it aborts
> if cc0 isn't set. */
> note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
> if (note)
> insn = XEXP (note, 0);
> rtx maybe_cc0_setter = prev_nonnote_insn (insn);
> if (maybe_cc0_setter
> && INSN_P (maybe_cc0_setter)
> && sets_cc0_p (PATTERN (maybe_cc0_setter)))
> insn = maybe_cc0_setter;
> How can this work? As far as grep understands, only link_cc0_insns
> creates REG_CC_SETTER notes, but that function is only called from
> reorg.c (and even then, only if it makes a transformation). So NOTE
> will always be NULL.
> Are REG_CC_SETTER/REG_CC_USER notes supposed to exist before dbr_sched?
Looking at the code, it's fairly clear that it is simply an inlined copy
of prev_cc0_setter which does not require that the insn use cc0. I
expect that it was never useful to check for a REG_CC_SETTER note, and
the code could be simplified to
rtx maybe_cc0_setter = prev_nonnote_insn (insn);
&& INSN_P (maybe_cc0_setter)
&& sets_cc0_p (PATTERN (maybe_cc0_setter)))
insn = maybe_cc0_setter;
> P.S. The code goes on to use prev_nonnote_insn, which may cross basic
> block boundaries, so prev_nonnote_insn_bb should be used instead.
As Jeff alluded to, RTL does not permit the CC0 setter and CC0 user to
be in different basic blocks before reorg. In fact, the whole point of
this code is to keep the CC0 setter and user adjacent.