This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Combine doesn't update NOTE_INSN_FUNCTION_USAGE
- To: gcc-patches at gcc dot gnu dot org
- Subject: Combine doesn't update NOTE_INSN_FUNCTION_USAGE
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 02 Feb 2001 18:28:00 -0200
- Organization: GCC Team, Red Hat
Remember that port that makes heavy use of by-reference arguments to
libcalls? A relatively large test, from a commercial testsuite, has
exposed a problem in combine. It would ``combine'' the insn in which
a reg was set to the address of the argument into the CALL_INSN. This
would succeed, even though it wouldn't modify the CALL_INSN at all.
And it would end up deleting the insn in which the reg was set, in
case it was not used anywhere else, which happened to be the case.
Then, flow noticed the reg was used in the CALL_INSN_FUNCTION_USAGE
and propagated its liveness up to the beginning of the basic block,
where it was dead before. Crash!
This trivial patch fixes it. Ok to install, if it bootstraps on
i686-pc-linux-gnu and doesn't break previously-working tests in this
new port?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* combine.c (try_combine): Apply substitutions in
CALL_INSN_FUNCTION_USAGE too.
Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.182
diff -u -p -r1.182 combine.c
--- gcc/combine.c 2001/01/30 22:27:44 1.182
+++ gcc/combine.c 2001/02/02 20:21:23
@@ -1496,6 +1496,7 @@ try_combine (i3, i2, i1, new_direct_jump
{
/* New patterns for I3 and I2, respectively. */
rtx newpat, newi2pat = 0;
+ int substed_i2 = 0, substed_i1 = 0;
/* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead. */
int added_sets_1, added_sets_2;
/* Total number of SETs to put into I3. */
@@ -1958,6 +1959,7 @@ try_combine (i3, i2, i1, new_direct_jump
subst_low_cuid = INSN_CUID (i2);
newpat = subst (PATTERN (i3), i2dest, i2src, 0,
! i1_feeds_i3 && i1dest_in_i1src);
+ substed_i2 = 1;
undobuf.previous_undos = undobuf.undos;
/* Record whether i2's body now appears within i3's body. */
@@ -1983,6 +1985,7 @@ try_combine (i3, i2, i1, new_direct_jump
n_occurrences = 0;
subst_low_cuid = INSN_CUID (i1);
newpat = subst (newpat, i1dest, i1src, 0, 0);
+ substed_i1 = 1;
undobuf.previous_undos = undobuf.undos;
}
@@ -2536,6 +2539,23 @@ try_combine (i3, i2, i1, new_direct_jump
INSN_CODE (i3) = insn_code_number;
PATTERN (i3) = newpat;
+
+ if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3))
+ {
+ rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
+
+ reset_used_flags (call_usage);
+ call_usage = copy_rtx_if_shared (call_usage);
+
+ if (substed_i2)
+ replace_rtx (call_usage, i2dest, i2src);
+
+ if (substed_i1)
+ replace_rtx (call_usage, i1dest, i1src);
+
+ CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
+ }
+
if (undobuf.other_insn)
INSN_CODE (undobuf.other_insn) = other_code_number;
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me