This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
2.95: Some additional patches
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: 2.95: Some additional patches
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Thu, 25 Jan 2001 13:01:56 +0000 (GMT)
Unfortunately, some bugs showed up while testing the last 2.95.3 test
release, and a few additional patches are necessary.
Bernd
* varasm.c (force_const_mem): When putting a LABEL_REF into the
constant pool, also put it on forced_labels list so that it won't
be deleted.
This fixes the hpux bootstrap problem when using the native assembler.
We'd end up with a constant pool referencing a label that got deleted.
This patch may be necessary for the mainline as well; I'm not entirely
sure.
2000-05-25 Alexandre Oliva <aoliva@cygnus.com>
* emit-rtl.c (reset_used_decls): New function.
(unshare_all_rtl_again): Call it.
2000-05-24 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* emit-rtl.c (unshare_all_decls): New function.
(unshare_all_rtl): Call it.
2000-05-20 Alexandre Oliva <aoliva@cygnus.com>
* emit-rtl.c (unshare_all_rtl): Store the copied rtx.
2000-04-15 Richard Earnshaw (rearnsah@arm.com)
* emit-rtl.c (unshare_all_rtl_again): Unmark everything, then
call unshare_all_rtl.
2000-01-27 Geoffrey Keating <geoffk@cygnus.com>
* emit-rtl.c (unshare_all_rtl): Unshare virtual parameters too.
Use unshare_all_rtl_1.
(unshare_all_rtl_again): New function.
(unshare_all_rtl_1): New function split out of unshare_all_rtl.
* function.c (purge_addressof_1): Use unshare_all_rtl_again
rather than resetting the 'used' flags ourself.
* toplev.c (rest_of_compilation): Add current_function_decl
to the unshare_all_rtl call.
* tree.h: Prototype unshare_all_rtl.
* rtl.h: Prototype unshare_all_rtl_again here.
This set is taken from Franz Sirl's patchkit. I didn't apply it before
since it wasn't entirely clear what it fixed, and it seemed like a rather
large change. Testing on m68k-linux has now revealed at least one problem:
the DECL_RTL of local variables can be shared with the rtl for the function,
and if the DECL_RTL is processed in instantiate_virtual_regs, some insn
patterns can suddenly cease to be valid. We'd get compilation failures,
apparently whenever the m68k divmod pattern was used.
This problem was exposed by another bugfix installed on the branch.
Bernd
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.59.4.6
diff -u -p -r1.59.4.6 emit-rtl.c
--- emit-rtl.c 2000/12/18 14:37:37 1.59.4.6
+++ emit-rtl.c 2001/01/25 12:54:00
@@ -248,6 +248,9 @@ extern int emit_lineno;
static rtx make_jump_insn_raw PROTO((rtx));
static rtx make_call_insn_raw PROTO((rtx));
static rtx find_line_note PROTO((rtx));
+static void unshare_all_rtl_1 PROTO((rtx));
+static void unshare_all_decls PROTO((tree));
+static void reset_used_decls PROTO((tree));
rtx
gen_rtx_CONST_INT (mode, arg)
@@ -1767,23 +1770,29 @@ restore_emit_status (p)
free_insn = 0;
}
-/* Go through all the RTL insn bodies and copy any invalid shared structure.
- It does not work to do this twice, because the mark bits set here
- are not cleared afterwards. */
+/* Go through all the RTL insn bodies and copy any invalid shared
+ structure. This routine should only be called once. */
void
-unshare_all_rtl (insn)
- register rtx insn;
+unshare_all_rtl (fndecl, insn)
+ tree fndecl;
+ rtx insn;
{
- for (; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
- || GET_CODE (insn) == CALL_INSN)
- {
- PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
- REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
- LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
- }
+ tree decl;
+ /* Make sure that virtual stack slots are not shared. */
+ reset_used_decls (DECL_INITIAL (current_function_decl));
+
+ /* Make sure that virtual parameters are not shared. */
+ for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
+ DECL_RTL (decl) = copy_rtx_if_shared (DECL_RTL (decl));
+
+ /* Make sure that virtual stack slots are not shared. */
+ unshare_all_decls (DECL_INITIAL (fndecl));
+
+ /* Unshare just about everything else. */
+ unshare_all_rtl_1 (insn);
+
/* Make sure the addresses of stack slots found outside the insn chain
(such as, in DECL_RTL of a variable) are not shared
with the insn chain.
@@ -1791,8 +1800,76 @@ unshare_all_rtl (insn)
This special care is necessary when the stack slot MEM does not
actually appear in the insn chain. If it does appear, its address
is unshared from all else at that point. */
+ stack_slot_list = copy_rtx_if_shared (stack_slot_list);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared
+ structure, again. This is a fairly expensive thing to do so it
+ should be done sparingly. */
+
+void
+unshare_all_rtl_again (insn)
+ rtx insn;
+{
+ rtx p;
+ for (p = insn; p; p = NEXT_INSN (p))
+ if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
+ {
+ reset_used_flags (PATTERN (p));
+ reset_used_flags (REG_NOTES (p));
+ reset_used_flags (LOG_LINKS (p));
+ }
+ unshare_all_rtl_1 (insn);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared structure.
+ Assumes the mark bits are cleared at entry. */
+
+static void
+unshare_all_rtl_1 (insn)
+ rtx insn;
+{
+ for (; insn; insn = NEXT_INSN (insn))
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ {
+ PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
+ REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
+ LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
+ }
+}
- copy_rtx_if_shared (stack_slot_list);
+/* Go through all virtual stack slots of a function and copy any
+ shared structure. */
+static void
+unshare_all_decls (blk)
+ tree blk;
+{
+ tree t;
+
+ /* Copy shared decls. */
+ for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+ DECL_RTL (t) = copy_rtx_if_shared (DECL_RTL (t));
+
+ /* Now process sub-blocks. */
+ for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+ unshare_all_decls (t);
+}
+
+/* Go through all virtual stack slots of a function and mark them as
+ not shared. */
+static void
+reset_used_decls (blk)
+ tree blk;
+{
+ tree t;
+
+ /* Mark decls. */
+ for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+ reset_used_flags (DECL_RTL (t));
+
+ /* Now process sub-blocks. */
+ for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+ reset_used_decls (t);
}
/* Mark ORIG as in use, and return a copy of it if it was already in use.
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.90.4.4
diff -u -p -r1.90.4.4 function.c
--- function.c 2000/12/22 14:19:57 1.90.4.4
+++ function.c 2001/01/25 12:54:02
@@ -3221,13 +3221,7 @@ purge_addressof_1 (loc, insn, force, sto
/* Make sure to unshare any shared rtl that store_bit_field
might have created. */
- for (p = get_insns(); p; p = NEXT_INSN (p))
- {
- reset_used_flags (PATTERN (p));
- reset_used_flags (REG_NOTES (p));
- reset_used_flags (LOG_LINKS (p));
- }
- unshare_all_rtl (get_insns ());
+ unshare_all_rtl_again (get_insns ());
seq = gen_sequence ();
end_sequence ();
@@ -3479,6 +3473,20 @@ purge_addressof (insns)
hash_table_free (&ht);
purge_bitfield_addressof_replacements = 0;
purge_addressof_replacements = 0;
+
+ /* REGs are shared. purge_addressof will destructively replace a REG
+ with a MEM, which creates shared MEMs.
+
+ Unfortunately, the children of put_reg_into_stack assume that MEMs
+ referring to the same stack slot are shared (fixup_var_refs and
+ the associated hash table code).
+
+ So, we have to do another unsharing pass after we have flushed any
+ REGs that had their address taken into the stack.
+
+ It may be worth tracking whether or not we converted any REGs into
+ MEMs to avoid this overhead when it is not needed. */
+ unshare_all_rtl_again (get_insns ());
}
/* Pass through the INSNS of function FNDECL and convert virtual register
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.105.4.1
diff -u -p -r1.105.4.1 rtl.h
--- rtl.h 2000/12/20 13:52:59 1.105.4.1
+++ rtl.h 2001/01/25 12:54:03
@@ -1391,7 +1391,7 @@ extern int subreg_realpart_p PROTO ((r
extern void reverse_comparison PROTO ((rtx));
extern void set_new_first_and_last_insn PROTO ((rtx, rtx));
extern void set_new_first_and_last_label_num PROTO ((int, int));
-extern void unshare_all_rtl PROTO ((rtx));
+extern void unshare_all_rtl_again PROTO ((rtx));
extern void set_last_insn PROTO ((rtx));
extern void link_cc0_insns PROTO ((rtx));
extern void add_insn PROTO ((rtx));
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.185.4.5
diff -u -p -r1.185.4.5 toplev.c
--- toplev.c 2000/12/18 14:13:25 1.185.4.5
+++ toplev.c 2001/01/25 12:54:05
@@ -3816,7 +3816,7 @@ rest_of_compilation (decl)
/* Copy any shared structure that should not be shared. */
- unshare_all_rtl (insns);
+ unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
/* This must be performed before virutal register instantiation. */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.71
diff -u -p -r1.71 tree.h
--- tree.h 1999/05/02 17:43:32 1.71
+++ tree.h 2001/01/25 12:54:06
@@ -2207,6 +2207,7 @@ extern tree reorder_blocks PROTO ((tree
struct rtx_def *));
extern void free_temps_for_rtl_expr PROTO ((tree));
extern void instantiate_virtual_regs PROTO ((tree, struct rtx_def *));
+extern void unshare_all_rtl PROTO ((tree, struct rtx_def *));
extern int max_parm_reg_num PROTO ((void));
extern void push_function_context PROTO ((void));
extern void pop_function_context PROTO ((void));
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.4
diff -u -p -r1.59.4.4 varasm.c
--- varasm.c 1999/06/09 12:13:49 1.59.4.4
+++ varasm.c 2001/01/25 12:54:07
@@ -3493,6 +3493,18 @@ force_const_mem (mode, x)
pop_obstacks ();
}
+ if (GET_CODE (x) == LABEL_REF)
+ {
+ extern rtx forced_labels;
+
+ push_obstacks_nochange ();
+ rtl_in_saveable_obstack ();
+
+ forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
+ XEXP (x, 0),
+ forced_labels);
+ pop_obstacks ();
+ }
/* Allocate a pool constant descriptor, fill it in, and chain it in. */