This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: inline+sibcall x LEAF_REG_REMAP
On Sep 10, 2000, Richard Henderson <rth@cygnus.com> wrote:
> On Sun, Sep 10, 2000 at 03:41:14AM -0300, Alexandre Oliva wrote:
>> * gcc.c-torture/execute/20000910-1.c: New test.
> Ok.
Ehrm. Not really :-(
Or did you mean to approve just the testcase? :-)
There was another problem situation that hadn't shown up with the
testcase, but that did on bootstrap-O3. I've created another
testcase, included in the new patch below. Ok to install, assuming
bootstrap and testing succeed?
Index: gcc/testsuite/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* gcc.c-torture/execute/20000910-1.c: New test.
* gcc.c-torture/execute/20000910-2.c: Likewise.
Index: gcc/testsuite/gcc.c-torture/execute/20000910-1.c
===================================================================
RCS file: 20000910-1.c
diff -N 20000910-1.c
--- /dev/null Tue May 5 13:32:27 1998
+++ gcc/testsuite/gcc.c-torture/execute/20000910-1.c Sun Sep 10 07:31:53 2000
@@ -0,0 +1,27 @@
+/* Copyright (C) 2000 Free Software Foundation */
+/* by Alexandre Oliva <aoliva@redhat.com> */
+
+#include <stdlib.h>
+
+void bar (int);
+void foo (int *);
+
+int main () {
+ static int a[] = { 0, 1, 2 };
+ int *i = &a[sizeof(a)/sizeof(*a)];
+
+ while (i-- > a)
+ foo (i);
+
+ exit (0);
+}
+
+void baz (int, int);
+
+void bar (int i) { baz (i, i); }
+void foo (int *i) { bar (*i); }
+
+void baz (int i, int j) {
+ if (i != j)
+ abort ();
+}
Index: gcc/testsuite/gcc.c-torture/execute/20000910-2.c
===================================================================
RCS file: 20000910-2.c
diff -N 20000910-2.c
--- /dev/null Tue May 5 13:32:27 1998
+++ gcc/testsuite/gcc.c-torture/execute/20000910-2.c Sun Sep 10 07:31:53 2000
@@ -0,0 +1,28 @@
+/* Copyright (C) 2000 Free Software Foundation */
+/* by Alexandre Oliva <aoliva@redhat.com> */
+
+#include <stdlib.h>
+#include <string.h>
+
+char *list[] = { "*", "e" };
+
+static int bar (const char *fmt) {
+ return (strchr (fmt, '*') != 0);
+}
+
+static void foo () {
+ int i;
+ for (i = 0; i < sizeof (list) / sizeof (*list); i++) {
+ const char *fmt = list[i];
+ if (bar (fmt))
+ continue;
+ if (i == 0)
+ abort ();
+ else
+ exit (0);
+ }
+}
+
+int main () {
+ foo ();
+}
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* print-rtl.c (debug_call_placeholder_verbose): New variable.
(print_rtx) [CALL_PLACEHOLDER]: Dump all call sequences if it is
set.
* integrate.c (copy_rtx_and_substitute): Don't share
LEAF_REG_REMAPpable registers with the inlined function. Don't
share the function value with calling sequences.
Index: gcc/print-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/print-rtl.c,v
retrieving revision 1.58
diff -u -p -r1.58 print-rtl.c
--- gcc/print-rtl.c 2000/08/04 20:28:05 1.58
+++ gcc/print-rtl.c 2000/09/10 14:31:54
@@ -63,6 +63,9 @@ int flag_dump_unnumbered = 0;
/* Nonzero if we are dumping graphical description. */
int dump_for_graph;
+/* Nonzero to dump all call_placeholder alternatives. */
+static int debug_call_placeholder_verbose;
+
/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
static void
@@ -421,6 +424,37 @@ print_rtx (in_rtx)
break;
case CALL_PLACEHOLDER:
+ if (debug_call_placeholder_verbose)
+ {
+ fputs (" (cond [\n (const_string \"normal\") (sequence [", outfile);
+ for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
+ {
+ fputs ("\n ", outfile);
+ print_inline_rtx (outfile, tem, 4);
+ }
+
+ tem = XEXP (in_rtx, 1);
+ if (tem)
+ fputs ("\n ])\n (const_string \"tail_call\") (sequence [", outfile);
+ for (; tem != 0; tem = NEXT_INSN (tem))
+ {
+ fputs ("\n ", outfile);
+ print_inline_rtx (outfile, tem, 4);
+ }
+
+ tem = XEXP (in_rtx, 2);
+ if (tem)
+ fputs ("\n ])\n (const_string \"tail_recursion\") (sequence [", outfile);
+ for (; tem != 0; tem = NEXT_INSN (tem))
+ {
+ fputs ("\n ", outfile);
+ print_inline_rtx (outfile, tem, 4);
+ }
+
+ fputs ("\n ])\n ])", outfile);
+ break;
+ }
+
for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
if (GET_CODE (tem) == CALL_INSN)
{
Index: gcc/integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.113
diff -u -p -r1.113 integrate.c
--- gcc/integrate.c 2000/09/02 02:54:55 1.113
+++ gcc/integrate.c 2000/09/10 14:31:55
@@ -1747,7 +1747,15 @@ copy_rtx_and_substitute (orig, map, for_
{
/* Some hard registers are also mapped,
but others are not translated. */
- if (map->reg_map[regno] != 0)
+ if (map->reg_map[regno] != 0
+ /* We shouldn't usually have reg_map set for return
+ register, but it may happen if we have leaf-register
+ remapping and the return register is used in one of
+ the calling sequences of a call_placeholer. In this
+ case, we'll end up with a reg_map set for this
+ register, but we don't want to use for registers
+ marked as return values. */
+ && ! REG_FUNCTION_VALUE_P (orig))
return map->reg_map[regno];
/* If this is the virtual frame pointer, make space in current
@@ -1758,7 +1766,7 @@ copy_rtx_and_substitute (orig, map, for_
equivalence for it to be the address. This will substitute the
address into insns where it can be substituted and use the new
pseudo where it can't. */
- if (regno == VIRTUAL_STACK_VARS_REGNUM)
+ else if (regno == VIRTUAL_STACK_VARS_REGNUM)
{
rtx loc, seq;
int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
@@ -1845,7 +1853,26 @@ copy_rtx_and_substitute (orig, map, for_
else
return map->inline_target;
}
- return orig;
+#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
+ /* If leaf_renumber_regs_insn() might remap this register to
+ some other number, make sure we don't share it with the
+ inlined function, otherwise delayed optimization of the
+ inlined function may change it in place, breaking our
+ reference to it. We may still shared it within the
+ function, so create an entry for this register in the
+ reg_map. */
+ if (map->integrating && regno < FIRST_PSEUDO_REGISTER
+ && LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
+ {
+ temp = gen_rtx_REG (mode, regno);
+ map->reg_map[regno] = temp;
+ return temp;
+ }
+#endif
+ else
+ return orig;
+
+ abort ();
}
if (map->reg_map[regno] == NULL)
{
--
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