On 05/13/2015 06:30 AM, Georg-Johann Lay wrote:


hmmm, it  would actually lead to valid machine code:  The jump table is
actually a dispatch table, i.e. it contains a list of direct jumps to
the case labels.  casesi loads the value of the label associated with
the jump table into a register, adds an offset, and then jumps to that
address (which in turn dispatches to the very cases via a direct jump).
OK.  It's similar to the PA in that regard.



In this specific case cse finds out that the offset (reg 59 below) is
always 0, i.e. the offset computation will always yield the value of the
label associated to the jump table (code_label 84), and then jumps to
that label.
Which is equivalent to jumping to the first entry in the table. OK. Not great, but OK.



Other backends are also using dispatch tables and are jumping into the
table, and internal docs for casesi read: "Instruction to jump through a
dispatch table"...

Wrapping the tablejump's register (reg 60 above) into UNSPEC fixes the
problem, but just because there is no insn to load such an unspec into a
register and hence cse does not perform respective optimization.
That's just avoiding the problem and generating sub-optimal code when you can collapse the switch to a single case that happens to be the first case.


Given the routines from from cfgrtl.c were used:  would it then be legal
to jump to a label which is not contained in any basic block?
I'm not sure offhand -- I'm not real familiar with layoutmode. A quick scan doesn't show a single routine in cfgrtl.c that would do what we want. It may be the case that you'll have to cobble it together.

Conceptually we want to remove all the outgoing edges except the one we care about. If we do that, try_redirect_by_replacing_jump might "just work". It's something you'll need to play a bit with to find the right bits to wire up.

jeff

Reply via email to