This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Combine doesn't update NOTE_INSN_FUNCTION_USAGE


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]