Commit b4ff394c by Pat Haugen Committed by Pat Haugen

target.def (compute_pressure_classes): New target hook.

	* target.def (compute_pressure_classes): New target hook.
	* doc/tm.texi.in: Document it.
	* doc/tm.texi: Regenerate.
	* ira.c (setup_pressure_classes): Call target hook if defined.

From-SVN: r241911
parent c939044a
2016-11-07 Pat Haugen <pthaugen@us.ibm.com>
* target.def (compute_pressure_classes): New target hook.
* doc/tm.texi.in: Document it.
* doc/tm.texi: Regenerate.
* ira.c (setup_pressure_classes): Call target hook if defined.
2016-11-07 David Malcolm <dmalcolm@redhat.com> 2016-11-07 David Malcolm <dmalcolm@redhat.com>
* print-rtl.c (rtx_writer::operand_has_default_value_p): New * print-rtl.c (rtx_writer::operand_has_default_value_p): New
...@@ -2903,6 +2903,10 @@ This hook defines a class of registers which could be used for spilling pseudos ...@@ -2903,6 +2903,10 @@ This hook defines a class of registers which could be used for spilling pseudos
This hook defines the machine mode to use for the boolean result of conditional store patterns. The ICODE argument is the instruction code for the cstore being performed. Not definiting this hook is the same as accepting the mode encoded into operand 0 of the cstore expander patterns. This hook defines the machine mode to use for the boolean result of conditional store patterns. The ICODE argument is the instruction code for the cstore being performed. Not definiting this hook is the same as accepting the mode encoded into operand 0 of the cstore expander patterns.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} int TARGET_COMPUTE_PRESSURE_CLASSES (enum reg_class *@var{pressure_classes})
A target hook which lets a backend compute the set of pressure classes to be used by those optimization passes which take register pressure into account, as opposed to letting IRA compute them. It returns the number of register classes stored in the array @var{pressure_classes}.
@end deftypefn
@node Stack and Calling @node Stack and Calling
@section Stack Layout and Calling Conventions @section Stack Layout and Calling Conventions
@cindex calling conventions @cindex calling conventions
......
...@@ -2509,6 +2509,8 @@ value that the middle-end intended. ...@@ -2509,6 +2509,8 @@ value that the middle-end intended.
@hook TARGET_CSTORE_MODE @hook TARGET_CSTORE_MODE
@hook TARGET_COMPUTE_PRESSURE_CLASSES
@node Stack and Calling @node Stack and Calling
@section Stack Layout and Calling Conventions @section Stack Layout and Calling Conventions
@cindex calling conventions @cindex calling conventions
......
...@@ -792,78 +792,85 @@ setup_pressure_classes (void) ...@@ -792,78 +792,85 @@ setup_pressure_classes (void)
HARD_REG_SET temp_hard_regset2; HARD_REG_SET temp_hard_regset2;
bool insert_p; bool insert_p;
n = 0; if (targetm.compute_pressure_classes)
for (cl = 0; cl < N_REG_CLASSES; cl++) n = targetm.compute_pressure_classes (pressure_classes);
{ else
if (ira_class_hard_regs_num[cl] == 0) {
continue; n = 0;
if (ira_class_hard_regs_num[cl] != 1 for (cl = 0; cl < N_REG_CLASSES; cl++)
/* A register class without subclasses may contain a few
hard registers and movement between them is costly
(e.g. SPARC FPCC registers). We still should consider it
as a candidate for a pressure class. */
&& alloc_reg_class_subclasses[cl][0] < cl)
{ {
/* Check that the moves between any hard registers of the if (ira_class_hard_regs_num[cl] == 0)
current class are not more expensive for a legal mode continue;
than load/store of the hard registers of the current if (ira_class_hard_regs_num[cl] != 1
class. Such class is a potential candidate to be a /* A register class without subclasses may contain a few
register pressure class. */ hard registers and movement between them is costly
for (m = 0; m < NUM_MACHINE_MODES; m++) (e.g. SPARC FPCC registers). We still should consider it
as a candidate for a pressure class. */
&& alloc_reg_class_subclasses[cl][0] < cl)
{ {
COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); /* Check that the moves between any hard registers of the
AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); current class are not more expensive for a legal mode
AND_COMPL_HARD_REG_SET (temp_hard_regset, than load/store of the hard registers of the current
ira_prohibited_class_mode_regs[cl][m]); class. Such class is a potential candidate to be a
if (hard_reg_set_empty_p (temp_hard_regset)) register pressure class. */
for (m = 0; m < NUM_MACHINE_MODES; m++)
{
COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
AND_COMPL_HARD_REG_SET (temp_hard_regset,
ira_prohibited_class_mode_regs[cl][m]);
if (hard_reg_set_empty_p (temp_hard_regset))
continue;
ira_init_register_move_cost_if_necessary ((machine_mode) m);
cost = ira_register_move_cost[m][cl][cl];
if (cost <= ira_max_memory_move_cost[m][cl][1]
|| cost <= ira_max_memory_move_cost[m][cl][0])
break;
}
if (m >= NUM_MACHINE_MODES)
continue; continue;
ira_init_register_move_cost_if_necessary ((machine_mode) m);
cost = ira_register_move_cost[m][cl][cl];
if (cost <= ira_max_memory_move_cost[m][cl][1]
|| cost <= ira_max_memory_move_cost[m][cl][0])
break;
} }
if (m >= NUM_MACHINE_MODES) curr = 0;
continue; insert_p = true;
} COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
curr = 0; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
insert_p = true; /* Remove so far added pressure classes which are subset of the
COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); current candidate class. Prefer GENERAL_REGS as a pressure
AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); register class to another class containing the same
/* Remove so far added pressure classes which are subset of the allocatable hard registers. We do this because machine
current candidate class. Prefer GENERAL_REGS as a pressure dependent cost hooks might give wrong costs for the latter
register class to another class containing the same class but always give the right cost for the former class
allocatable hard registers. We do this because machine (GENERAL_REGS). */
dependent cost hooks might give wrong costs for the latter for (i = 0; i < n; i++)
class but always give the right cost for the former class
(GENERAL_REGS). */
for (i = 0; i < n; i++)
{
cl2 = pressure_classes[i];
COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl2]);
AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
if (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)
&& (! hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2)
|| cl2 == (int) GENERAL_REGS))
{ {
cl2 = pressure_classes[i];
COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl2]);
AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
if (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)
&& (! hard_reg_set_equal_p (temp_hard_regset,
temp_hard_regset2)
|| cl2 == (int) GENERAL_REGS))
{
pressure_classes[curr++] = (enum reg_class) cl2;
insert_p = false;
continue;
}
if (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset)
&& (! hard_reg_set_equal_p (temp_hard_regset2,
temp_hard_regset)
|| cl == (int) GENERAL_REGS))
continue;
if (hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset))
insert_p = false;
pressure_classes[curr++] = (enum reg_class) cl2; pressure_classes[curr++] = (enum reg_class) cl2;
insert_p = false;
continue;
} }
if (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset) /* If the current candidate is a subset of a so far added
&& (! hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset) pressure class, don't add it to the list of the pressure
|| cl == (int) GENERAL_REGS)) classes. */
continue; if (insert_p)
if (hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset)) pressure_classes[curr++] = (enum reg_class) cl;
insert_p = false; n = curr;
pressure_classes[curr++] = (enum reg_class) cl2;
} }
/* If the current candidate is a subset of a so far added
pressure class, don't add it to the list of the pressure
classes. */
if (insert_p)
pressure_classes[curr++] = (enum reg_class) cl;
n = curr;
} }
#ifdef ENABLE_IRA_CHECKING #ifdef ENABLE_IRA_CHECKING
{ {
......
...@@ -5039,6 +5039,16 @@ DEFHOOK ...@@ -5039,6 +5039,16 @@ DEFHOOK
machine_mode, (enum insn_code icode), machine_mode, (enum insn_code icode),
default_cstore_mode) default_cstore_mode)
/* This target hook allows the backend to compute the register pressure
classes to use. */
DEFHOOK
(compute_pressure_classes,
"A target hook which lets a backend compute the set of pressure classes to\
be used by those optimization passes which take register pressure into\
account, as opposed to letting IRA compute them. It returns the number of\
register classes stored in the array @var{pressure_classes}.",
int, (enum reg_class *pressure_classes), NULL)
/* True if a structure, union or array with MODE containing FIELD should /* True if a structure, union or array with MODE containing FIELD should
be accessed using BLKmode. */ be accessed using BLKmode. */
DEFHOOK DEFHOOK
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment