It seems that in a typical -O0 compile the amount of rtl that
starts out as needed but becomes garbage is only slightly less than
half of the total amount created. One of the big offenders is the
vregs pass, which creates new PLUSes when instanstiating a virtual
register + a constant and which creates new MEMs when instantiating
an address involving a virtual register. This happens a lot in -O0
code because all variables live on the stack.
The instantiation walk is fundamentally in-place: every other part
of the pattern is modified without copying. And rtl sharing rules
guarantee that we can do the same for PLUSes of registers and MEMs.
The patch does this by adding "inplace" arguments to plus_constant and
replace_equiv_address. In a -O0 compile of an oldish fold-const.ii
(where no GC takes place) it reduces the amount of used GC memory
from 169M to 166M. The average max RSS goes down by just over 1%.
Compile time seems to decrease slightly, but probably in the noise range.
There might be other callers than can use the new interfaces too.
Tested on x86_64-linux-gnu. Also tested by comparing the asm output
for various parts of the testsuite before and after the patch.
The only changes were that some "sym+0"s becamse plain "syms"
(i.e. (plus X (const_int 0)) became X) because of the plus_constant
change.
OK to install?
Thanks,
Richard
gcc/
* emit-rtl.h (replace_equiv_address, replace_equiv_address_nv): Add an
inplace argument. Store the new address in the original MEM when true.
* emit-rtl.c (change_address_1): Likewise.
(adjust_address_1, adjust_automodify_address_1, offset_address):
Update accordingly.
* rtl.h (plus_constant): Add an inplace argument.
* explow.c (plus_constant): Likewise. Try to reuse the original PLUS
when true. Avoid generating (plus X (const_int 0)).
* function.c (instantiate_virtual_regs_in_rtx): Adjust the PLUS
in-place. Pass true to plus_constant.
(instantiate_virtual_regs_in_insn): Pass true to replace_equiv_address.
Index: gcc/emit-rtl.h
===================================================================
--- gcc/emit-rtl.h 2014-05-15 11:27:06.000259353 +0100
+++ gcc/emit-rtl.h 2014-05-16 09:11:42.479556294 +0100
@@ -52,10 +52,10 @@ extern tree get_spill_slot_decl (bool);
ADDR. The caller is asserting that the actual piece of memory pointed
to is the same, just the form of the address is being changed, such as
by putting something into a register. */
-extern rtx replace_equiv_address (rtx, rtx);
+extern rtx replace_equiv_address (rtx, rtx, bool = false);
/* Likewise, but the reference is not required to be valid. */
-extern rtx replace_equiv_address_nv (rtx, rtx);
+extern rtx replace_equiv_address_nv (rtx, rtx, bool = false);