* [committed] Improve MIPS register move costs (for IRA)
@ 2008-10-24 8:54 Richard Sandiford
0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2008-10-24 8:54 UTC (permalink / raw)
To: gcc-patches
This patch improves the register move costs for MIPS. It's part of
fixing the dspr2-MULT{,U}.c problems that Chao-Ying and Adam noticed.
The MIPS implementation of REGISTER_MOVE_COST has traditionally
returned:
- a specific value for moves that can be done directly
- 4 for MIPS16 moves between non-MIPS16 GPRs
- 12 for everything else
Returning 12 is flawed for two reasons:
- It overestimates the costs of some moves that can be done with
secondary reloads. E.g. MD_REGS->FPR_REGS involves a GPR scratch,
and is actually cheaper than 12.
- More importantly, it means that we return 12 for all moves
involving union classes. The cost of such moves should really
be the maximum of the move costs for the constituent classes.
E.g. the maximum cost of GR_AND_ACC_REGS->GR_REGS is the maximum
of GR_REGS->GR_REGS and ACC_REGS->GR_REGS. regclass already knows
this, and actually sets the move cost to the maximum of:
REGISTER_MOVE_COST (MODE, GR_REGS, GR_REGS)
REGISTER_MOVE_COST (MODE, ACC_REGS, GR_REGS)
...
REGISTER_MOVE_COST (MODE, GR_AND_ACC_REGS, GR_REGS)
But MIPS screws up the calculation by making the last value 12.
It should return 0 instead and let regclass do the right thing.
Overestimating the cost didn't hurt too much with the old RA,
but it can convince IRA that spilling to memory is more profitable
than using an accumulator register.
As I've said before, the basic consituent costs aren't right for all
MIPS processors, and ought to be part of the costs structure. I haven't
changed that here. Instead, the idea is to keep the same constituent
costs but to make the values derived from them more accurate.
The CSiBE results are as follows:
-Os -EB -mips16 -mabi=32 -mhard-float 2840801 2840753 : 100.00%
-Os -EB -mips16 -mabi=32 -msoft-float 2823197 2823149 : 100.00%
-Os -EB -mips16 -mabi=o64 -mhard-float 2855585 2855493 : 100.00%
-Os -EB -mips16 -mabi=o64 -msoft-float 2837037 2836977 : 100.00%
-Os -EB -mno-mips16 -mabi=32 -mhard-float 3502597 3501041 : 99.96%
-Os -EB -mno-mips16 -mabi=32 -msoft-float 3974577 3973149 : 99.96%
-Os -EB -mno-mips16 -mabi=o64 -mhard-float 3503329 3501693 : 99.95%
-Os -EB -mno-mips16 -mabi=o64 -msoft-float 3766561 3765197 : 99.96%
-Os -EL -mips16 -mabi=32 -mhard-float 2840325 2840293 : 100.00%
-Os -EL -mips16 -mabi=32 -msoft-float 2822353 2822321 : 100.00%
-Os -EL -mips16 -mabi=o64 -mhard-float 2855409 2855333 : 100.00%
-Os -EL -mips16 -mabi=o64 -msoft-float 2836861 2836801 : 100.00%
-Os -EL -mno-mips16 -mabi=32 -mhard-float 3501989 3500529 : 99.96%
-Os -EL -mno-mips16 -mabi=32 -msoft-float 3971089 3970013 : 99.97%
-Os -EL -mno-mips16 -mabi=o64 -mhard-float 3502561 3500925 : 99.95%
-Os -EL -mno-mips16 -mabi=o64 -msoft-float 3765777 3764397 : 99.96%
Regression-tested on mipsisa64-elfoabi and applied.
The DSP tests aren't fixed by this patch alone. They need another
couple of changes that I'm still working on.
Richard
gcc/
* config/mips/mips.c (mips_canonicalize_move_class): New function.
(mips_move_to_gpr_cost): Likewise.
(mips_move_from_gpr_cost): Likewise.
(mips_register_move_cost): Make more fine-grained.
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c 2008-10-23 20:11:19.000000000 +0100
--- gcc/config/mips/mips.c 2008-10-23 21:24:39.000000000 +0100
*************** mips_preferred_reload_class (rtx x, enum
*** 9689,9750 ****
return rclass;
}
! /* Implement REGISTER_MOVE_COST. */
! int
! mips_register_move_cost (enum machine_mode mode,
! enum reg_class to, enum reg_class from)
{
! if (TARGET_MIPS16)
! {
! if (reg_class_subset_p (from, GENERAL_REGS)
! && reg_class_subset_p (to, GENERAL_REGS))
! {
! if (reg_class_subset_p (from, M16_REGS)
! || reg_class_subset_p (to, M16_REGS))
! return 2;
! /* Two MOVEs. */
! return 4;
! }
! }
! else if (reg_class_subset_p (from, GENERAL_REGS))
{
! if (reg_class_subset_p (to, GENERAL_REGS))
! return 2;
! if (reg_class_subset_p (to, FP_REGS))
! return 4;
! if (reg_class_subset_p (to, COP0_REGS)
! || reg_class_subset_p (to, COP2_REGS)
! || reg_class_subset_p (to, COP3_REGS))
! return 5;
! if (reg_class_subset_p (to, ACC_REGS))
! return 6;
}
! else if (reg_class_subset_p (to, GENERAL_REGS))
{
! if (reg_class_subset_p (from, FP_REGS))
! return 4;
! if (reg_class_subset_p (from, ST_REGS))
! /* LUI followed by MOVF. */
! return 4;
! if (reg_class_subset_p (from, COP0_REGS)
! || reg_class_subset_p (from, COP2_REGS)
! || reg_class_subset_p (from, COP3_REGS))
! return 5;
! if (reg_class_subset_p (from, ACC_REGS))
! return 6;
}
! else if (reg_class_subset_p (from, FP_REGS))
{
! if (reg_class_subset_p (to, FP_REGS)
! && mips_mode_ok_for_mov_fmt_p (mode))
return 4;
! if (reg_class_subset_p (to, ST_REGS))
! /* An expensive sequence. */
return 8;
}
! return 12;
}
/* Implement TARGET_IRA_COVER_CLASSES. */
--- 9689,9830 ----
return rclass;
}
! /* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
! Return a "canonical" class to represent it in later calculations. */
! static enum reg_class
! mips_canonicalize_move_class (enum reg_class rclass)
{
! /* All moves involving accumulator registers have the same cost. */
! if (reg_class_subset_p (rclass, ACC_REGS))
! rclass = ACC_REGS;
!
! /* Likewise promote subclasses of general registers to the most
! interesting containing class. */
! if (TARGET_MIPS16 && reg_class_subset_p (rclass, M16_REGS))
! rclass = M16_REGS;
! else if (reg_class_subset_p (rclass, GENERAL_REGS))
! rclass = GENERAL_REGS;
!
! return rclass;
! }
!
! /* Return the cost of moving a value of mode MODE from a register of
! class FROM to a GPR. Return 0 for classes that are unions of other
! classes handled by this function. */
!
! static int
! mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
! enum reg_class from)
! {
! switch (from)
{
! case GENERAL_REGS:
! /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
! return 2;
!
! case ACC_REGS:
! /* MFLO and MFHI. */
! return 6;
!
! case FP_REGS:
! /* MFC1, etc. */
! return 4;
!
! case ST_REGS:
! /* LUI followed by MOVF. */
! return 4;
!
! case COP0_REGS:
! case COP2_REGS:
! case COP3_REGS:
! /* This choice of value is historical. */
! return 5;
!
! default:
! return 0;
}
! }
!
! /* Return the cost of moving a value of mode MODE from a GPR to a
! register of class TO. Return 0 for classes that are unions of
! other classes handled by this function. */
!
! static int
! mips_move_from_gpr_cost (enum machine_mode mode, enum reg_class to)
! {
! switch (to)
{
! case GENERAL_REGS:
! /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */
! return 2;
!
! case ACC_REGS:
! /* MTLO and MTHI. */
! return 6;
!
! case FP_REGS:
! /* MTC1, etc. */
! return 4;
!
! case ST_REGS:
! /* A secondary reload through an FPR scratch. */
! return (mips_register_move_cost (mode, GENERAL_REGS, FP_REGS)
! + mips_register_move_cost (mode, FP_REGS, ST_REGS));
!
! case COP0_REGS:
! case COP2_REGS:
! case COP3_REGS:
! /* This choice of value is historical. */
! return 5;
!
! default:
! return 0;
}
! }
!
! /* Implement REGISTER_MOVE_COST. Return 0 for classes that are the
! maximum of the move costs for subclasses; regclass will work out
! the maximum for us. */
!
! int
! mips_register_move_cost (enum machine_mode mode,
! enum reg_class from, enum reg_class to)
! {
! enum reg_class dregs;
! int cost1, cost2;
!
! from = mips_canonicalize_move_class (from);
! to = mips_canonicalize_move_class (to);
!
! /* Handle moves that can be done without using general-purpose registers. */
! if (from == FP_REGS)
{
! if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode))
! /* MOV.FMT. */
return 4;
! if (to == ST_REGS)
! /* The sequence generated by mips_expand_fcc_reload. */
return 8;
}
! /* Handle cases in which only one class deviates from the ideal. */
! dregs = TARGET_MIPS16 ? M16_REGS : GENERAL_REGS;
! if (from == dregs)
! return mips_move_from_gpr_cost (mode, to);
! if (to == dregs)
! return mips_move_to_gpr_cost (mode, from);
!
! /* Handles cases that require a GPR temporary. */
! cost1 = mips_move_to_gpr_cost (mode, from);
! if (cost1 != 0)
! {
! cost2 = mips_move_from_gpr_cost (mode, to);
! if (cost2 != 0)
! return cost1 + cost2;
! }
!
! return 0;
}
/* Implement TARGET_IRA_COVER_CLASSES. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-10-24 8:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-24 8:54 [committed] Improve MIPS register move costs (for IRA) Richard Sandiford
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).