This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH RFC: Don't simply discard libcall REG_EQUAL notes
- From: Ian Lance Taylor <ian at wasabisystems dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 21 Oct 2003 13:28:26 -0700
- Subject: PATCH RFC: Don't simply discard libcall REG_EQUAL notes
With the current sources, for a target with software floating point,
this test case:
extern void bar (void);
float
foo (void)
{
float d = 1.0;
float e = 1.0;
int i;
for (i = 0; i < 1; i++)
bar ();
return d * e;
}
generates a call to __mulsf3 to compute d * e. For example, compiling
this for the i386 with -O2 -msoft-float produces this:
foo:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
call bar
movl $0x3f800000, 4(%esp)
movl $0x3f800000, (%esp)
call __mulsf3
leave
ret
Calling __mulsf3 with constant arguments is pointless.
gcc generates a call to __mulsf3 in the RTL, and puts a REG_EQUAL note
on the insn which assigns the result to a pseudo-register. The
REG_EQUAL says that the result is equal to mult:SF of two registers.
The problem is that the gcse pass simplifies the note one register at
a time. gcse first sees that one of the registers can be replaced by
a constant. It then sees a multiplication by 1.0, and simplifies the
note into a simple REG_EQUAL of the other register. gcse then detects
the case of a REG_EQUAL of another register, and discards the note
before it can take advantage of the information.
This patch moves the check for REG_EQUAL of another register to later
in the code, so that the note can be fully simplified. When it sees
such a case, it also tries to replace a single set with a set simply
to the other register, before it discards the note. Later passes
should be able to take advantage of this.
With this patch, the above test case becomes this with -O2
-msoft-float:
foo:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
call bar
leave
fld1
ret
I'm having some trouble doing a full bootstrap and test with the
current sources, for unrelated reasons. Right now I'd like to hear
whether anybody thinks this is the wrong approach.
Ian
2003-10-21 Ian Lance Taylor <ian@wasabisystems.com>
* gcse.c (try_replace_reg): Don't delete a REG_EQUAL note
simplified to a register here.
(cprop_insn): If we find a REG_EQUAL note which has been
simplified to a single register, try to replace SET_SRC of a
simple set, and remove the note.
(local_cprop_pass): Likewise.
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.277
diff -u -p -r1.277 gcse.c
--- gcse.c 17 Oct 2003 16:16:44 -0000 1.277
+++ gcse.c 21 Oct 2003 20:12:44 -0000
@@ -3911,13 +3911,6 @@ try_replace_reg (rtx from, rtx to, rtx i
note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src));
}
- /* REG_EQUAL may get simplified into register.
- We don't allow that. Remove that note. This code ought
- not to happen, because previous code ought to synthesize
- reg-reg move, but be on the safe side. */
- if (note && REG_P (XEXP (note, 0)))
- remove_note (insn, note);
-
return success;
}
@@ -4223,6 +4216,20 @@ cprop_insn (rtx insn, int alter_jumps)
}
}
+ /* REG_EQUAL may get simplified into register. We don't allow that.
+ Remove such a note. */
+ note = find_reg_equal_equiv_note (insn);
+ if (note && REG_P (XEXP (note, 0)))
+ {
+ rtx set;
+
+ /* Before removing the note, try to simplify. */
+ set = single_set (insn);
+ if (set && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
+ changed = 1;
+ remove_note (insn, note);
+ }
+
return changed;
}
@@ -4435,6 +4442,21 @@ local_cprop_pass (int alter_jumps)
break;
}
while (reg_use_count);
+
+ /* REG_EQUAL may get simplified into register. We don't
+ allow that. Remove such a note. */
+ note = find_reg_equal_equiv_note (insn);
+ if (note && REG_P (XEXP (note, 0)))
+ {
+ rtx set;
+
+ /* Before removing the note, try to simplify. */
+ set = single_set (insn);
+ if (set
+ && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
+ changed = true;
+ remove_note (insn, note);
+ }
}
cselib_process_insn (insn);
}