Hi! I've noticed that for the side-effects that adjust_insn emits as extra sets in the PARALLEL we don't transform the SET_SRC parts through adjust_mems. This means that a typical i?86 push is seen by var-tracking as: [(set (mem:SI ((plus:SI (reg:SI argp) (const_int -64)))) (something:SI)) (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -4)))] while with this patch as: [(set (mem:SI ((plus:SI (reg:SI argp) (const_int -64)))) (something:SI)) (set (reg:SI sp) (plus:SI (reg:SI argp) (const_int -64)))] While we have for some time code to increase sharing of VALUEs for the typical stack pointer adjustments by constant, still it means that every bb new VALUEs need to be created for every offset from the stack pointer base that is seen in the code. By using the argp (cfa) + offset instead we can just share the VALUEs across the whole function.
This patch helps a lot the attached testcase (see the PR for exact numbers), unfortunately it didn't seem to help insn-recog.c compilation time as much as I hoped (though, the i686-linux bootstrap as whole took about 20 minutes less than the last bootstrap). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-01-30 Jakub Jelinek <ja...@redhat.com> PR debug/59992 * var-tracking.c (adjust_mems): Before adding a SET to amd->side_effects, adjust it's SET_SRC using simplify_replace_fn_rtx. * gcc.dg/pr59992.c: New test. --- gcc/var-tracking.c.jj 2014-01-29 10:21:11.000000000 +0100 +++ gcc/var-tracking.c 2014-01-30 11:01:01.779089299 +0100 @@ -1067,10 +1067,13 @@ adjust_mems (rtx loc, const_rtx old_rtx, ? GET_MODE_SIZE (amd->mem_mode) : -GET_MODE_SIZE (amd->mem_mode), GET_MODE (loc))); + store_save = amd->store; + amd->store = false; + tem = simplify_replace_fn_rtx (tem, old_rtx, adjust_mems, data); + amd->store = store_save; amd->side_effects = alloc_EXPR_LIST (0, gen_rtx_SET (VOIDmode, - XEXP (loc, 0), - tem), + XEXP (loc, 0), tem), amd->side_effects); return addr; case PRE_MODIFY: @@ -1080,10 +1083,14 @@ adjust_mems (rtx loc, const_rtx old_rtx, addr = XEXP (loc, 0); gcc_assert (amd->mem_mode != VOIDmode); addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data); + store_save = amd->store; + amd->store = false; + tem = simplify_replace_fn_rtx (XEXP (loc, 1), old_rtx, + adjust_mems, data); + amd->store = store_save; amd->side_effects = alloc_EXPR_LIST (0, gen_rtx_SET (VOIDmode, - XEXP (loc, 0), - XEXP (loc, 1)), + XEXP (loc, 0), tem), amd->side_effects); return addr; case SUBREG: --- gcc/testsuite/gcc.dg/pr59992.c.jj 2014-01-30 11:43:55.323795812 +0100 +++ gcc/testsuite/gcc.dg/pr59992.c 2014-01-30 11:38:57.000000000 +0100 @@ -0,0 +1,17 @@ +/* PR debug/59992 */ +/* { dg-do compile } */ +/* { dg-require-effective-target run_expensive_tests } */ +/* { dg-options "-O2 -g" } */ +/* { dg-timeout-factor 16.0 } */ + +#define A(n) if (p[n]) { extern void foo##n (int, int, double, int, int); foo##n (p[n], 5, 8.0, p[n] + p[n + 1], 9); return; } +#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) +#define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) +#define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n##5) C(n##6) C(n##7) C(n##8) C(n##9) +#define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n##5) D(n##6) D(n##7) D(n##8) D(n##9) + +void +foo (int *p) +{ + E(1) +} Jakub