diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d1122a2688..9f4d052e60d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2002-05-09 David S. Miller + + * rtl.h (struct rtx_def): Document unchanging and in_struct flags + more accurately. + (INSN_ANNULLED_BRANCH_P): Only valid for JUMP_INSN and CALL_INSN, fix + comment. + (INSN_FROM_TARGET_P): Valid also for CALL_INSN. + * doc/rtl.texi: Document these macros more accurately. + * recog.c (whole file): Only mess with INSN_ANNULLED_BRANCH_P for + JUMP_INSNs and CALL_INSNs. + * resource.c (whole file): Only mess with INSN_ANNULLED_BRANCH_P + or INSN_FROM_TARGET_P if the code is appropriate. + 2002-05-10 Marek Michalkiewicz * config/avr/avr.c (print_operand): Check that addr is a SYMBOL_REF diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index f537f394df1..23994fdf286 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -395,15 +395,13 @@ indicates that the insn represents a call to a const or pure function. Stored in the @code{unchanging} field and printed as @samp{/u}. @findex INSN_ANNULLED_BRANCH_P -@cindex @code{insn} and @samp{/u} @cindex @code{jump_insn} and @samp{/u} -@cindex @code{unchanging}, in @code{insn} and @code{jump_insn} +@cindex @code{call_insn} and @samp{/u} +@cindex @code{unchanging}, in @code{jump_insn} and @code{call_insn} @item INSN_ANNULLED_BRANCH_P (@var{x}) -In an @code{insn} or @code{jump_insn} in the delay slot of a branch insn, -indicates that an -annulling branch should be used. See the discussion under -@code{sequence} below. Stored in the @code{unchanging} field and printed -as @samp{/u}. +In a @code{jump_insn} or @code{call_insn} indicates that the branch is +an annulling one. See the discussion under @code{sequence} below. +Stored in the @code{unchanging} field and printed as @samp{/u}. @findex INSN_DEAD_CODE_P @cindex @code{insn} and @samp{/s} @@ -430,10 +428,11 @@ nonzero if the insn has been deleted. Stored in the @findex INSN_FROM_TARGET_P @cindex @code{insn} and @samp{/s} @cindex @code{jump_insn} and @samp{/s} -@cindex @code{in_struct}, in @code{insn} and @code{jump_insn} +@cindex @code{call_insn} and @samp{/s} +@cindex @code{in_struct}, in @code{insn} and @code{jump_insn} and @code{call_insn} @item INSN_FROM_TARGET_P (@var{x}) -In an @code{insn} or @code{jump_insn} in a delay slot of a branch, -indicates that the insn +In an @code{insn} or @code{jump_insn} or @code{call_insn} in a delay +slot of a branch, indicates that the insn is from the target of the branch. If the branch insn has @code{INSN_ANNULLED_BRANCH_P} set, this insn will only be executed if the branch is taken. For annulled branches with diff --git a/gcc/reorg.c b/gcc/reorg.c index 659fc007590..e6793ed8bba 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -617,7 +617,8 @@ delete_from_delay_slot (insn) annul flag. */ if (delay_list) trial = emit_delay_sequence (trial, delay_list, XVECLEN (seq, 0) - 2); - else + else if (GET_CODE (trial) == JUMP_INSN + || GET_CODE (trial) == CALL_INSN) INSN_ANNULLED_BRANCH_P (trial) = 0; INSN_FROM_TARGET_P (insn) = 0; @@ -3628,7 +3629,9 @@ dbr_schedule (first, file) { rtx target; - INSN_ANNULLED_BRANCH_P (insn) = 0; + if (GET_CODE (insn) == JUMP_INSN + || GET_CODE (insn) == CALL_INSN) + INSN_ANNULLED_BRANCH_P (insn) = 0; INSN_FROM_TARGET_P (insn) = 0; /* Skip vector tables. We can't get attributes for them. */ diff --git a/gcc/resource.c b/gcc/resource.c index e890f8799e6..c6b75705ee3 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -175,10 +175,21 @@ next_insn_no_annul (insn) { /* If INSN is an annulled branch, skip any insns from the target of the branch. */ - if (INSN_ANNULLED_BRANCH_P (insn) + if (GET_CODE (insn) == JUMP_INSN + && INSN_ANNULLED_BRANCH_P (insn) && NEXT_INSN (PREV_INSN (insn)) != insn) - while (INSN_FROM_TARGET_P (NEXT_INSN (insn))) - insn = NEXT_INSN (insn); + { + rtx next = NEXT_INSN (insn); + enum rtx_code code = GET_CODE (next); + + while ((code == INSN || code == JUMP_INSN || code == CALL_INSN) + && INSN_FROM_TARGET_P (next)) + { + insn = next; + next = NEXT_INSN (insn); + code = GET_CODE (next); + } + } insn = NEXT_INSN (insn); if (insn && GET_CODE (insn) == INSN @@ -1007,16 +1018,18 @@ mark_target_live_regs (insns, target, res) { rtx link; rtx real_insn = insn; + enum rtx_code code = GET_CODE (insn); /* If this insn is from the target of a branch, it isn't going to be used in the sequel. If it is used in both cases, this test will not be true. */ - if (INSN_FROM_TARGET_P (insn)) + if ((code == INSN || code == JUMP_INSN || code == CALL_INSN) + && INSN_FROM_TARGET_P (insn)) continue; /* If this insn is a USE made by update_block, we care about the underlying insn. */ - if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE + if (code == INSN && GET_CODE (PATTERN (insn)) == USE && INSN_P (XEXP (PATTERN (insn), 0))) real_insn = XEXP (PATTERN (insn), 0); diff --git a/gcc/rtl.h b/gcc/rtl.h index 2406b73d966..f83ac8200a1 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -140,8 +140,7 @@ struct rtx_def 1 in a SYMBOL_REF if it addresses something in the per-function constants pool. 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call. - 1 in an INSN in the delay slot of a branch insn if an annulling branch - should be used. */ + 1 in a JUMP_INSN or CALL_INSN of an annulling branch. */ unsigned int unchanging : 1; /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile. 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE @@ -168,7 +167,6 @@ struct rtx_def 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and from the target of a branch. Valid from reorg until end of compilation; cleared before used. - 1 in an INSN in a delay slot that is the target of a branch, during reorg. 1 in an INSN or related rtx if this insn is dead code. Valid only during dead-code elimination phase; cleared before use. */ unsigned int in_struct : 1; @@ -539,11 +537,9 @@ do { \ #define SIBLING_CALL_P(RTX) \ (RTL_FLAG_CHECK1("SIBLING_CALL_P", (RTX), CALL_INSN)->jump) -/* 1 if RTX is an insn in the delay slot of a branch insn for which an - annulling branch should be used. */ +/* 1 if RTX is an insn that is an annulling branch. */ #define INSN_ANNULLED_BRANCH_P(RTX) \ - (RTL_FLAG_CHECK2("INSN_ANNULLED_BRANCH_P", (RTX), INSN, \ - JUMP_INSN)->unchanging) + (RTL_FLAG_CHECK2("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN, CALL_INSN)->unchanging) /* 1 if RTX is an insn that is dead code. Valid only for dead-code elimination phase. */ @@ -555,7 +551,7 @@ do { \ executed if the branch is taken. For annulled branches with this bit clear, the insn should be executed only if the branch is not taken. */ #define INSN_FROM_TARGET_P(RTX) \ - (RTL_FLAG_CHECK2("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN)->in_struct) + (RTL_FLAG_CHECK3("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN, CALL_INSN)->in_struct) #define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4)