This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Unshare insns after splitting
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: rth at redhat dot com, Kenneth Zadeck <zadeck at naturalbridge dot com>
- Date: Sun, 29 Apr 2007 17:03:54 +0200
- Subject: [patch] Unshare insns after splitting
Hi,
On the dataflow problem we ran into a problem where the DF verifier
bombed on shared RTL introduced by insn splitting. This was caught
after regrename did a valid replacement in one inss. Because of
the shared RTL the replacement affected other insns, which triggers
the DF verifier.
After a bit of googling, I found out that this has been discussed
before (http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00113.html)
but this previous discussion was never followed up with a patch and
the problem remained latent.
For the DF branch we have to fix this. But since it's broken on the
trunk also, I'd like to see this patch go into the trunk as well.
Bootstrapped and tested on {i686,x86_64,ia64}-unknown-linux-gnu with
the trunk and on {x86_64,ia64}-unknown-linux-gnu with the dataflow
branch. This patch fixes a bootstrap error with java on the dataflow
branch.
OK for the trunk and for the branch?
Thanks,
Gr.
Steven
* emit-rtl.c (try_split): Unshare RTL sequences produced by splitters.
Index: emit-rtl.c
===================================================================
--- emit-rtl.c (revision 124273)
+++ emit-rtl.c (working copy)
@@ -3155,6 +3155,13 @@
split_branch_probability = INTVAL (XEXP (note, 0));
probability = split_branch_probability;
+ /* Cleanup the USED bits in TRIAL, so that we can unshare the insns
+ generated by a splitter. */
+ reset_used_flags (PATTERN (trial));
+ reset_used_flags (REG_NOTES (trial));
+ set_used_flags (PATTERN (trial));
+ set_used_flags (REG_NOTES (trial));
+
seq = split_insns (pat, trial);
split_branch_probability = -1;
@@ -3183,6 +3190,10 @@
insn_last = NEXT_INSN (insn_last);
}
+ /* We will be adding the new sequence to the function. The splitters
+ may have introduced invalid RTL sharing, so unshare the sequence now. */
+ unshare_all_rtl_in_chain (seq);
+
/* Mark labels. */
for (insn = insn_last; insn ; insn = PREV_INSN (insn))
{