I've been converting the Blackfin port to take advantage of the new
lower-subreg pass, which fortunately involves little more than deleting
a few patterns.
One problem is that without an anddi3 expander, we generate poor initial
RTL. optabs knows it can do the operation piecewise, so it could
generate the following sequence for an operation involving one memory
operand:
reg C = (mem:SI symbol+offset)
reg A = reg B + reg C;
reg Z = (mem:SI symbol+offset+4)
reg X = reg Y + reg Z;
It then passes this to emit_no_conflict_block, which is supposed to wrap
it in REG_NO_CONFLICT notes to help the register allocator. This
function pulls out any insns not contributing to the final result, and
emits them first, leading to:
reg C = (mem:SI symbol+offset)
reg Z = (mem:SI symbol+offset+4)
reg A = reg B + reg C;
reg X = reg Y + reg Z;
which has higher register pressure (at least in the usual cases where C
and Z are dead after their use) and causes more spills than the former
sequence on certain testcases. The sad thing is that all the
REG_NO_CONFLICT notes later get removed by lower-subreg as they serve no
purpose, but the suboptimal insn ordering survives until register
allocation.
It would be nice to eliminate REG_NO_CONFLICT altogether, but a quick
experiment with the i386 port showed that this idea is a non-starter for
now (i386 still has insns operating on DImode, hence in some functions
not all DImode registers get lowered, and lack of no_conflict blocks
causes poor register allocation when that happens).
I suppose we could add a target macro to let individual ports turn off
REG_NO_CONFLICT generation? Any other ideas?
Bernd
--
This footer brought to you by insane German lawmakers.
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough