This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
unsharing rtl too early
- To: gcc-patches at gcc dot gnu dot org
- Subject: unsharing rtl too early
- From: Alexandre Oliva <aoliva at cygnus dot com>
- Date: 18 May 2000 14:48:01 -0300
- Organization: Cygnus Solutions, a Red Hat Company
gcc.dg/980816-1.c fails on mn10300 apparently because we're unsharing
RTL too early. Here's a simplified version of the testcase:
int foo(int a) {
int w;
return w/a;
}
% ./cc1 test.c
foo
test.c: In function `foo':
test.c:4: Internal compiler error in `instantiate_virtual_regs_1', at function.c:3903
The insn on which this function crashes is:
(insn 11 8 13 (parallel[
(set (reg:SI 24)
(div:SI (mem/f:SI (plus:SI (reg:SI 19 virtual-stack-vars)
(const_int -4 [0xfffffffffffffffc])) 0)
(mem/f:SI (reg:SI 18 virtual-incoming-args) 0)))
(set (reg:SI 25)
(mod:SI (mem/f:SI (plus:SI (reg:SI 19 virtual-stack-vars)
(const_int -4 [0xfffffffffffffffc])) 0)
(mem/f:SI (reg:SI 18 virtual-incoming-args) 0)))
] ) -1 (nil)
(nil))
The problem is that the first occurrence of (reg:SI 19) is shared with
the declaration of w, so it gets adjusted to use the frame pointer.
However, because instantiate_virtual_regs() is called after
unshare_all_rtl(), the second occurrence is no longer shared, so it's
not adjusted. Then, when we try to instantiate (reg:SI 18), we fail,
because the insn doesn't match (the operands of the mod are dups of
those of the div).
The patch below fixes this problem. Another solution would be to
arrange that unshare_all_rtl unshares declarations too, so that
instantiating them doesn't affect insns, or to instantiate
declarations only after instantiating insns. I preferred to just move
unshare_all_rtl() after instantiate_all_regs(), that should even save
us from doing the work multiple times. Ok to install?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@cygnus.com>
* toplev.c (rest_of_compilation): Unshare rtl after instantiating
virtual registers.
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.338
diff -u -r1.338 toplev.c
--- gcc/toplev.c 2000/05/17 08:15:26 1.338
+++ gcc/toplev.c 2000/05/18 17:09:07
@@ -2807,17 +2807,18 @@
insns = get_insns ();
- /* Copy any shared structure that should not be shared. */
- unshare_all_rtl (current_function_decl, insns);
-
#ifdef SETJMP_VIA_SAVE_AREA
- /* This must be performed before virutal register instantiation. */
+ /* This must be performed before virtual register instantiation. */
if (current_function_calls_alloca)
optimize_save_area_alloca (insns);
#endif
/* Instantiate all virtual registers. */
instantiate_virtual_regs (current_function_decl, insns);
+
+ /* Copy any shared structure that should not be shared. This must
+ be performed after virtual register instantiation. */
+ unshare_all_rtl (current_function_decl, insns);
/* Find all the EH handlers. */
find_exception_handler_labels ();
--
Alexandre Oliva Enjoy Guaranį, see http://www.ic.unicamp.br/~oliva/
Cygnus Solutions, a Red Hat company aoliva@{redhat, cygnus}.com
Free Software Developer and Evangelist CS PhD student at IC-Unicamp
oliva@{lsd.ic.unicamp.br, gnu.org} Write to mailing lists, not to me