combine: Do not combine moves from hard registers
authorSegher Boessenkool <segher@kernel.crashing.org>
Mon, 22 Oct 2018 20:23:39 +0000 (22:23 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Mon, 22 Oct 2018 20:23:39 +0000 (22:23 +0200)
commit8d2d39587d941a40f25ea0144cceb677df115040
tree2f6a7fb98a24d7e9e26b2519b4f4ae5c355579b6
parentf3b13f46fa6b9e28859e26ec2201bc6017cda0c1
combine: Do not combine moves from hard registers

On most targets every function starts with moves from the parameter
passing (hard) registers into pseudos.  Similarly, after every call
there is a move from the return register into a pseudo.  These moves
usually combine with later instructions (leaving pretty much the same
instruction, just with a hard reg instead of a pseudo).

This isn't a good idea.  Register allocation can get rid of unnecessary
moves just fine, and moving the parameter passing registers into many
later instructions tends to prevent good register allocation.  This
patch disallows combining moves from a hard (non-fixed) register.

This also avoid the problem mentioned in PR87600 #c3 (combining hard
registers into inline assembler is problematic).

Because the register move can often be combined with other instructions
*itself*, for example for setting some condition code, this patch adds
extra copies via new pseudos after every copy-from-hard-reg.

On some targets this reduces average code size.  On others it increases
it a bit, 0.1% or 0.2% or so.  (I tested this on all *-linux targets).

PR rtl-optimization/87600
* combine.c: Add include of expr.h.
(cant_combine_insn_p): Do not combine moves from any hard non-fixed
register to a pseudo.
(make_more_copies): New function, add a copy to a new pseudo after
the moves from hard registers into pseudos.
(rest_of_handle_combine): Declare rebuild_jump_labels_after_combine
later.  Call make_more_copies.

From-SVN: r265398
gcc/ChangeLog
gcc/combine.c