Hi, the following patch improves LRA spilling general reg pseduos into vector regs.
Before the patch only *regular* spilled pseudos of general regs class are assigned to vector regs on the LRA spill sub-pass. The patch improves this by assigning vector regs to *inheritance* pseudos on LRA assign sub-pass (it should be done here as if an inheritance pseudo does not get a hard reg on the sub-pass, it is removed right after the sub-pass). As the result on a big benchmark (about 500K lines of fortran code), LRA assigns about 25% more spilled pseudos of general regs class to vector regs (6123 vs. 4827) in 64-bit mode and about 85% in 32-bit mode (22691 vs 12171). The patch also fixes a bug in spilling pseudos into vector regs which might result in LRA cycling. The fix is in i386.c which wrongly returned SSE_REGS class for NO_REGS pseudos. Pseudos denoting secondary memory have such class and they might get vector regs and it results in secondary memory transformation again and again. The fix is pretty obvious so I am checking it in without an approval. The patch was bootstrapped and tested on x86-64 with switching on spilling general reg pseudos into vector regs. Committed as rev. 211655. 2014-06-13 Vladimir Makarov <vmaka...@redhat.com> * lra-assign.c (assign_by_spills): Add code to assign vector regs to inheritance pseudos. * config/i386/i386.c (ix86_spill_class): Add check on NO_REGS.
Index: lra-assigns.c =================================================================== --- lra-assigns.c (revision 211654) +++ lra-assigns.c (working copy) @@ -1420,6 +1420,31 @@ assign_by_spills (void) alternatives of insns containing the pseudo. */ bitmap_set_bit (&changed_pseudo_bitmap, regno); } + else + { + enum reg_class rclass = lra_get_allocno_class (regno); + enum reg_class spill_class; + + if (lra_reg_info[regno].restore_regno < 0 + || ! bitmap_bit_p (&lra_inheritance_pseudos, regno) + || (spill_class + = ((enum reg_class) + targetm.spill_class + ((reg_class_t) rclass, + PSEUDO_REGNO_MODE (regno)))) == NO_REGS) + continue; + regno_allocno_class_array[regno] = spill_class; + hard_regno = find_hard_regno_for (regno, &cost, -1, false); + if (hard_regno < 0) + regno_allocno_class_array[regno] = rclass; + else + { + setup_reg_classes + (regno, spill_class, spill_class, spill_class); + assign_hard_regno (hard_regno, regno); + bitmap_set_bit (&changed_pseudo_bitmap, regno); + } + } } } free (update_hard_regno_preference_check); Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 211654) +++ config/i386/i386.c (working copy) @@ -46502,7 +46502,7 @@ ix86_spill_class (reg_class_t rclass, en { if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX && (mode == SImode || (TARGET_64BIT && mode == DImode)) - && INTEGER_CLASS_P (rclass)) + && rclass != NO_REGS && INTEGER_CLASS_P (rclass)) return ALL_SSE_REGS; return NO_REGS; }