RTL_FLAG_CHECK patch
David S. Miller
davem@redhat.com
Fri May 10 05:57:00 GMT 2002
From: Janis Johnson <janis187@us.ibm.com>
Date: Wed, 8 May 2002 16:41:54 -0700
Can one of you familiar with targets that use these macros determine
the right list of RTL codes to use with INSN_ANNULLED_BRANCH_P and
INSN_FROM_TARGET_P and submit the appropriate patches to rtl.h and
doc/rtl.texi? In the meantime if you need to work around this you
can turn off the new rtlflag checks (--enable-checking=misc,tree,gc).
Ok, I took a stab at this, here is what I installed.
It makes Sparc work, though it is possible some other platform
with delay slots might trigger something.
2002-05-09 David S. Miller <davem@redhat.com>
* 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.
--- ./doc/rtl.texi.~1~ Wed May 8 22:46:18 2002
+++ ./doc/rtl.texi Thu May 9 04:34:42 2002
@@ -395,15 +395,13 @@ indicates that the insn represents a cal
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. S
@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
--- ./resource.c.~1~ Wed May 8 22:46:13 2002
+++ ./resource.c Thu May 9 07:50:06 2002
@@ -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, re
{
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);
--- ./rtl.h.~1~ Wed May 8 22:46:13 2002
+++ ./rtl.h Fri May 10 05:18:49 2002
@@ -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;
@@ -337,7 +335,7 @@ extern void rtvec_check_failed_bounds PA
/* Access an individual rtx flag, with no checking of any kind. */
#define RTX_FLAG(RTX, FLAG) ((RTX)->FLAG)
-#if defined ENABLE_RTL_FLAG_CHECKING
+#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION >= 2007)
#define RTL_FLAG_CHECK1(NAME, RTX, C1) __extension__ \
({ rtx const _rtx = (RTX); \
if (GET_CODE(_rtx) != C1) \
@@ -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)
--- ./reorg.c.~1~ Fri Apr 26 17:03:58 2002
+++ ./reorg.c Thu May 9 04:36:03 2002
@@ -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. */
More information about the Gcc-bugs
mailing list