From b4ff394c548414d6594170573c1cea89b91968e1 Mon Sep 17 00:00:00 2001 From: Pat Haugen Date: Mon, 7 Nov 2016 15:37:51 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++ gcc/doc/tm.texi | 4 ++ gcc/doc/tm.texi.in | 2 + gcc/ira.c | 135 ++++++++++++++++++++++++--------------------- gcc/target.def | 10 ++++ 5 files changed, 94 insertions(+), 64 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02e05647b7d..c237044b0dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-11-07 Pat Haugen + + * 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 * print-rtl.c (rtx_writer::operand_has_default_value_p): New diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index e2d5e5fe346..81c63b71bff 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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. @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 @section Stack Layout and Calling Conventions @cindex calling conventions diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 102ad71ac01..74e9200f749 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2509,6 +2509,8 @@ value that the middle-end intended. @hook TARGET_CSTORE_MODE +@hook TARGET_COMPUTE_PRESSURE_CLASSES + @node Stack and Calling @section Stack Layout and Calling Conventions @cindex calling conventions diff --git a/gcc/ira.c b/gcc/ira.c index cd640fce589..f453ea9e604 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -792,78 +792,85 @@ setup_pressure_classes (void) HARD_REG_SET temp_hard_regset2; bool insert_p; - n = 0; - for (cl = 0; cl < N_REG_CLASSES; cl++) - { - if (ira_class_hard_regs_num[cl] == 0) - continue; - if (ira_class_hard_regs_num[cl] != 1 - /* 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) + if (targetm.compute_pressure_classes) + n = targetm.compute_pressure_classes (pressure_classes); + else + { + n = 0; + for (cl = 0; cl < N_REG_CLASSES; cl++) { - /* Check that the moves between any hard registers of the - current class are not more expensive for a legal mode - than load/store of the hard registers of the current - class. Such class is a potential candidate to be a - register pressure class. */ - for (m = 0; m < NUM_MACHINE_MODES; m++) + if (ira_class_hard_regs_num[cl] == 0) + continue; + if (ira_class_hard_regs_num[cl] != 1 + /* 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) { - 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)) + /* Check that the moves between any hard registers of the + current class are not more expensive for a legal mode + than load/store of the hard registers of the current + class. Such class is a potential candidate to be a + 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; - 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; - } - curr = 0; - insert_p = true; - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - /* Remove so far added pressure classes which are subset of the - current candidate class. Prefer GENERAL_REGS as a pressure - register class to another class containing the same - allocatable hard registers. We do this because machine - dependent cost hooks might give wrong costs for the latter - 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)) + curr = 0; + insert_p = true; + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + /* Remove so far added pressure classes which are subset of the + current candidate class. Prefer GENERAL_REGS as a pressure + register class to another class containing the same + allocatable hard registers. We do this because machine + dependent cost hooks might give wrong costs for the latter + 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)) + { + 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; - 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; + /* 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; } - /* 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 { diff --git a/gcc/target.def b/gcc/target.def index c9fdfa7b493..bcdbc0e2452 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5039,6 +5039,16 @@ DEFHOOK machine_mode, (enum insn_code icode), 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 be accessed using BLKmode. */ DEFHOOK -- 2.30.2