This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

thread_jumps -- am I crazy?



OK, I've been looking at this most of the day, and the conclusion I've
run into is that thread_jumps is badly broken.

In a slightly modified (and slightly old) tree we have the following
hunks of code before the post-loop jump threading pass (ia64 target, though
that's not particularly important).


(code_label 148 142 1218 187 "" "" [1 uses])

(note 1218 148 149 [bb 4] NOTE_INSN_BASIC_BLOCK)

(note 149 1218 152 0x2000000000696780 NOTE_INSN_BLOCK_BEG)

(insn 152 149 154 (set (reg:DI 409)
        (zero_extend:DI (mem/s:HI (reg:DI 811) 394))) -1 (nil)
    (nil))

[ ... ]


(insn 676 674 677 (set (reg:DI 547)
        (mem/s:DI (reg:DI 825) 0)) -1 (nil)
    (nil))

(insn 677 676 678 (set (reg:BI 548)
        (ne:BI (reg:DI 547)
            (reg:DI 815))) -1 (nil)
    (nil))

(jump_insn 678 677 1253 (set (pc)
        (if_then_else (ne (reg:BI 548)
                (const_int 0 [0x0]))
            (label_ref 979)
            (pc))) -1 (nil)
    (nil))

[ ... ]

(code_label 979 1325 1266 186 "" "" [5 uses])

(note 1266 979 984 [bb 46] NOTE_INSN_BASIC_BLOCK)

(insn 984 1266 1293 (set (reg:DI 811)
        (mem/s:DI (reg:DI 825) 0)) -1 (nil)
    (nil))

(note 1293 984 144 NOTE_INSN_LOOP_VTOP)

(insn 144 1293 145 (set (reg/s:BI 406)
        (ne:BI (reg:DI 811)
            (reg:DI 815))) -1 (nil)
    (nil))

(jump_insn 145 144 990 (set (pc)
        (if_then_else (ne (reg/s:BI 406)
                (const_int 0 [0x0]))
            (label_ref 148)
            (pc))) -1 (nil)
    (nil))

An examination of the RTL indicates that the jump at 678 and the jump
at 145 test the same condition and thus the first dominates the second.
Thus, we'd like to thread the first jump so that it jumps to target of
the second jump.  This is precisely what jump threading does.

But wait, that's not safe because we lose the assignment to reg 811 if
thread the jump at 678 and it's taken (reg 811 is *not* dead at insn 144).

It looks like this code is trying to deal with that issue:

          /* If this is the first time we are seeing a register on the `Y'
             side, see if it is the last use.  If not, we can't thread the
             jump, so mark it as not equivalent.  */
          if (REGNO_LAST_UID (REGNO (y)) != INSN_UID (yinsn))
            return 0;

But that's not sufficient because the register may still be live (consider
if the branch at the end of Y is a back branch for a loop, as is the case
in this example).


Am I just on drugs?  Who knows this code well enough to double check my
analysis?


[ It's a little difficult to give a testcase since it requires some mods to
  the SSA code to trigger this failure. ]

jeff



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]