Hi, I've used this patch in the past for another port, and now again for rs6000, and I think it is generally useful. It prints very verbose information to the dump file about how ivopts comes up with its costs for various forms of memory accesses, which tends to show problems in the target's address cost functions and the legitimize functions.
In this patch it is disabled by default -- it is very chatty. It also shows that the LAST_VIRTUAL_REGISTER trickery ivopts does does not work (legitimize_address can create new registers, so now a) we have new registers anyway, and b) we use some for multiple purposes. Oops). Is this okay for trunk? Bootstrapped and tested on powerpc64-linux. Segher 2015-08-18 Segher Boessenkool <seg...@kernel.crashing.org> * tree-ssa-loop-ivopts.c (IVOPTS_DEBUG_COSTS): New define. (get_address_cost): Add address cost debug code. --- gcc/tree-ssa-loop-ivopts.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 6bce3a1..ae29a6f 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +/* Define to 1 to debug how this pass comes up with its cost estimates. */ +#define IVOPTS_DEBUG_COSTS 0 + /* This pass tries to find the optimal set of induction variables for the loop. It optimizes just the basic linear induction variables (although adding support for other types should not be too hard). It includes the @@ -3743,8 +3746,51 @@ get_address_cost (bool symbol_present, bool var_present, seq = get_insns (); end_sequence (); - acost = seq_cost (seq, speed); - acost += address_cost (addr, mem_mode, as, speed); + unsigned acost1 = seq_cost (seq, speed); + unsigned acost2 = address_cost (addr, mem_mode, as, speed); + + if (dump_file && IVOPTS_DEBUG_COSTS) + { + fprintf (dump_file, "======= sequence generated for "); + if (sym_p) + fprintf (dump_file, "sym + "); + if (var_p) + fprintf (dump_file, "var + "); + if (off_p) + fprintf (dump_file, "cst + "); + if (rat_p) + fprintf (dump_file, "rat * "); + fprintf (dump_file, "index:\n"); + + print_rtl (dump_file, seq); + + fprintf (dump_file, "\n cost of seq is %u", acost1); + + if (seq && NEXT_INSN (seq)) + { + fprintf (dump_file, " (namely,"); + + for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) + { + unsigned cost; + rtx set = single_set (insn); + if (set) + cost = set_rtx_cost (set, speed); + else + cost = 1; + fprintf (dump_file, " %u", cost); + } + + fprintf (dump_file, ")"); + } + + fprintf (dump_file, "\n\nremaining address is:\n"); + print_rtl_single (dump_file, addr); + + fprintf (dump_file, "\n cost of that address is %u\n\n", acost2); + } + + acost = acost1 + acost2; if (!acost) acost = 1; -- 1.8.1.4