On 02/17/14 02:28, Eric Botcazou wrote:
So, the code has this structure
if (looks safe)
emit in existing order
else if (reverse order looks safe)
emit in reversed order
else
undo_all
In this specific case, the existing order is never going to look safe
because set1 uses (sp) as an input argument and use_crosses_set_p is
very conservative when the value is the stack pointer on a PUSH_ROUNDING
machine (such as the m68k)
What a bummer, it seems all things are aligned so as to block the optimization
here... It is a bit of a shame, as this is a powerful combination that would
eliminate a branch if it succeeded. The combination of the 3 insns yields the
(set (pc) (pc)) pattern and it's only because added_sets_1 is true that the
annoying PARALLEL is created.
Yea. As I mentioned before, I actually considered peeking inside the
vector for a (set (pc) (pc)) and simplifying vector (possibly back down
to a single set). I really like eliminating branches ;-0
But I couldn't convince myself it'd be worth the effort.
So we could put the verification code that both I3 and I2 are INSNs in
the else if (reverse order looks safe) clause. That would mean for
this testcase, we ultimately undo_all. But I consider that reasonable
given the only reason this instance bled into RTL land was -O1 instead
of -O2 compilation.
Although it's probably time to concede defeat in this particular case, I don't
think we should use the NONJUMP_INSN_P big hammer because we want to eliminate
branches if possible. So I'd just add the minimal test to the two existing
conditions so as to prevent the invalid RTL from being created, e.g.
&& (!JUMP_P (i3) || SET_DEST (set[01]) == pc_rtx)
OK. I'll give that a spin.
jeff