This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Help: How to update dataflow info after splitting ?
- From: Nick Clifton <nickc at redhat dot com>
- To: gcc-bugs at gcc dot gnu dot org
- Cc: pocmatos at gmail dot com
- Date: Thu, 06 Oct 2011 17:35:28 +0100
- Subject: Help: How to update dataflow info after splitting ?
Hi Guys,
I am stuck on a dataflow problem. PR 49801 is reported against the RX
toolchain, but I believe it to be a generic problem.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49801
The issue I think is the split2 pass which is converting this:
(set (pc) (if_then_else (geu (reg r1)
(reg r2))
(label_ref 13)
(pc)))
into this:
(set (reg:CC cc) (compare:CC (reg r1)
(reg r2)))
(set (pc) (if_then_else (geu (reg cc)
(const_int 0))
(label_ref 13)
(pc)))
This new pair of insns introduces a definition and use of the
condition code register (reg cc), but the dataflow information is not
updated to reflect this. This causes the following pass (compare
eliminate) to ICE with a dataflow checking failure if checking is
enabled:
shift.c:7:1: internal compiler error: in df_live_verify_transfer_functions, at df-problems.c:1816
The dataflow information for the basic block looks like this:
;; Start of basic block ( 0) -> 2
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(0){ }}
;; lr in 0 [r0] 1 [r1] 2 [r2]
;; lr use 0 [r0] 1 [r1] 2 [r2]
;; lr def
;; live in 0 [r0] 1 [r1] 2 [r2]
;; live gen
;; live kill
;; End of basic block 2 -> ( 3 4)
;; lr out 0 [r0] 1 [r1] 2 [r2]
;; live out 0 [r0] 1 [r1] 2 [r2]
Ie no mention of the condition code register (register 16).
The issue I have is that I do not know how to fix this. I thought
that adding a call to df_insn_rescan for the newly created insns would
work, like this:
Index: gcc/recog.c
===================================================================
--- gcc/recog.c (revision 179611)
+++ gcc/recog.c (working copy)
@@ -2841,7 +2841,10 @@
for (;;)
{
if (INSN_P (first))
- cleanup_subreg_operands (first);
+ {
+ cleanup_subreg_operands (first);
+ df_insn_rescan (first);
+ }
if (first == last)
break;
first = NEXT_INSN (first);
But this made no difference. :-( I have considered adding a
"(set (reg cc)..)" in parallel to the original jump pattern, but I am
loath to do so because I have found that gcc tends to have issues with
jump insns that contain parallels.
Any suggestions ?
Cheers
Nick