Crossjumping of tablejumps
Josef Zlomek
zlomj9am@artax.karlin.mff.cuni.cz
Tue Mar 11 23:22:00 GMT 2003
> > * cfgcleanup.c (outgoing_edges_match): Compare the jump tables.
> > (try_crossjump_to_edge): Replace refereces to one jump table by
> > references to identical jump table.
>
> This breaks s390, apparently because it doesn't cope correctly with the
> case where the jump table label is stored in the literal pool.
I'll look at it tomorrow.
Josef
> In my test case, this sequence
>
> ;; Start of basic block 4, registers live: 15 [%r15] 43 57
> (note 185 75 76 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
>
> (insn 76 185 77 4 0x401ab0c0 (set (reg:SI 3 %r3 [orig:57 kt ] [57])
> (ashift:SI (reg:SI 3 %r3 [orig:57 kt ] [57])
> (const_int 2 [0x2]))) 246 {ashlsi3} (nil)
> (nil))
>
> (insn 77 76 78 4 0x401ab0c0 (set (reg/f:SI 1 %r1 [58])
> (mem/u/f:SI (symbol_ref/u:SI ("*.LC2")) [3 S4 A32])) 56 {*movsi} (nil)
> (insn_list:REG_LABEL 80 (expr_list:REG_EQUIV (label_ref:SI 80)
> (nil))))
>
> (insn 78 77 79 4 0x401ab0c0 (set (reg:SI 2 %r2 [59])
> (mem:SI (plus:SI (reg/f:SI 1 %r1 [58])
> (reg:SI 3 %r3 [orig:57 kt ] [57])) [0 S4 A8])) 56 {*movsi} (insn_list 77 (insn_list 76 (nil)))
> (nil))
>
> (jump_insn 79 78 80 4 0x401ab0c0 (parallel [
> (set (pc)
> (reg:SI 2 %r2 [59]))
> (use (label_ref 80))
> ]) 265 {casesi_jump} (insn_list:REG_DEP_ANTI 76 (insn_list:REG_DEP_ANTI 77 (insn_list 78 (nil))))
> (nil))
> ;; End of basic block 4, registers live:
> 11 [%r11] 15 [%r15] 32 [%ap] 34 [%fp] 43
>
> ;; Insn is not within a basic block
> (code_label/s 80 79 81 10 "" [3 uses])
>
> ;; Insn is not within a basic block
> (jump_insn 81 80 82 (nil) (addr_vec:SI [
> (label_ref:SI 18)
> (label_ref:SI 30)
> (label_ref:SI 40)
> (label_ref:SI 52)
> ]) -1 (nil)
> (nil))
>
> (barrier 82 81 18)
>
>
> is replaced by
>
> ;; Start of basic block 4, registers live: 3 [%r3] 4 [%r4] 5 [%r5] 15 [%r15]
> (note 185 75 76 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
>
> (insn 76 185 77 4 0x401ab0c0 (set (reg:SI 3 %r3 [orig:57 kt ] [57])
> (ashift:SI (reg:SI 3 %r3 [orig:57 kt ] [57])
> (const_int 2 [0x2]))) 246 {ashlsi3} (nil)
> (nil))
>
> (insn 77 76 282 4 0x401ab0c0 (set (reg/f:SI 1 %r1 [58])
> (mem/u/f:SI (symbol_ref/u:SI ("*.LC2")) [3 S4 A32])) 56 {*movsi} (nil)
> (insn_list:REG_LABEL 80 (expr_list:REG_EQUIV (label_ref:SI 153)
> (nil))))
>
> (jump_insn 282 77 283 4 (nil) (set (pc)
> (label_ref 281)) -1 (nil)
> (nil))
> ;; End of basic block 4, registers live:
> 1 [%r1] 3 [%r3] 4 [%r4] 5 [%r5] 15 [%r15]
>
> (barrier 283 282 80)
>
> (note/s 80 283 19 "" NOTE_INSN_DELETED_LABEL 10)
>
>
> This is broken, because the literal pool entry .LC2 still contains
> a reference to the now-deleted label 10. This causes the label to
> be emitted at some random point in the code stream, and the target
> of the redirected jump:
>
> ;; Start of basic block 31, registers live: 1 [%r1] 3 [%r3] 4 [%r4] 5 [%r5] 15 [%r15]
> (code_label 281 150 279 31 23 "" [1 uses])
>
> (note 279 281 151 31 [bb 31] NOTE_INSN_BASIC_BLOCK)
>
> (insn 151 279 152 31 0x401ab0c0 (set (reg:SI 2 %r2 [74])
> (mem:SI (plus:SI (reg/f:SI 1 %r1 [73])
> (reg:SI 3 %r3 [orig:72 kt ] [72])) [0 S4 A8])) 56 {*movsi} (nil)
> (expr_list:REG_DEAD (reg/f:SI 1 %r1 [73])
> (expr_list:REG_DEAD (reg:SI 3 %r3 [orig:72 kt ] [72])
> (nil))))
>
> (jump_insn 152 151 153 31 0x401ab0c0 (parallel [
> (set (pc)
> (reg:SI 2 %r2 [74]))
> (use (label_ref 153))
> ]) 265 {casesi_jump} (insn_list 151 (nil))
> (expr_list:REG_DEAD (reg:SI 2 %r2 [74])
> (nil)))
>
> uses this piece of code as jump table and jumps to some random
> location ...
>
>
> Bye,
> Ulrich
>
> --
> Dr. Ulrich Weigand
> weigand@informatik.uni-erlangen.de
--
Josef Zlomek
zlomek@users.sf.net
zlomj9am@artax.karlin.mff.cuni.cz
http://zlomek.matfyz.cz/
http://artax.karlin.mff.cuni.cz/~zlomj9am/
More information about the Gcc-patches
mailing list