>>> 2012-05-10 Vladimir Makarov<vmaka...@redhat.com> >>> >>> PR rtl-optimization/53125 >>> * ira.c (ira): Call find_moveable_pseudos and >>> move_unallocated_pseudos if only ira_conflicts_p is true.
And the attached patch fixes the reginfo slowness. The reginfo pass was doing: for each bb: for each insn in bb, from BB_END(bb) to BB_HEAD(bb): for each reg that died between BB_END(bb) and insn: // i.e. register is live at insn REG_LIVE_LENGTH(reg)++ With very large basic blocks, and the kind of code for the test case of the PR results in many live registers for SPARC (for x86_64 there are far fewer live registers). For SPARC, there are O(1e5) insns and O(1e4) registers live for most of the basic block. That is effectively almost quadratic behavior in the number of insns per basic block. But the above loop is a bit silly. It is much easier and computationally cheaper to just remember at what insn reg died (last used), and add to REG_LIVE_LENGTH the distance from the insn that sets reg to the insn that used reg. It turns out that (before or after the patch) partial or conditional sets never kill a register, so that REG_LIVE_LENGTH for registers set by partial or conditional stores is not very accurate. I have a few ideas for how to improve that situation a bit, but I'm not sure if it's worth the trouble. I also think that the computation of REG_FREQ and REG_FREQ_CALLS_CROSSED has been wrong for some time. The maximum REG_FREQ is REG_FREQ_MAX (see regs.h) but regstat.c just accumulates REG_FREQ_FROM_BB. I've added a few lines to limit the REG_FREQ to REG_FREQ_MAX, e.g.: REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb); + REG_FREQ (dregno) = + MIN (REG_FREQ (dregno), REG_FREQ_MAX); With this patch, the reginfo pass disappears from the time report for the test case attached to PR53125, compiled at -O0. Bootstrapped and tested on x86_64-unknown-linux-gnu, and I verified for a few simple test cases that the computed REG_LIVE_LENGHTs are unchanged. OK for trunk? Ciao! Steven