mips.c (mips_canonicalize_move_class): New function.

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.

From-SVN: r141336
This commit is contained in:
Richard Sandiford 2008-10-24 08:04:22 +00:00 committed by Richard Sandiford
parent 887e6178d4
commit aea8cb376b
2 changed files with 134 additions and 47 deletions

View File

@ -1,3 +1,10 @@
2008-10-24 Richard Sandiford <rdsandiford@googlemail.com>
* 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.
2008-10-23 Tobias Grosser <grosser@fim.uni-passau.de>
* graphite.c (graphite_apply_transformations): Check for

View File

@ -9689,62 +9689,142 @@ mips_preferred_reload_class (rtx x, enum reg_class rclass)
return rclass;
}
/* Implement REGISTER_MOVE_COST. */
/* 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 to, enum reg_class from)
enum reg_class from, enum reg_class to)
{
if (TARGET_MIPS16)
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 (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))
if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode))
/* MOV.FMT. */
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. */
if (to == ST_REGS)
/* The sequence generated by mips_expand_fcc_reload. */
return 8;
}
return 12;
/* 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. */