diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-22 12:02:11 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-22 12:02:11 +0000 |
commit | e1a797ade2cd2dffe3e9ff73826422700f010c84 (patch) | |
tree | 69a28087e5d6c8f66821aa2540f8d19983b792eb /gcc/recog.c | |
parent | 835b8178b6af49b010c32136c5aa49227d562691 (diff) | |
download | gcc-e1a797ade2cd2dffe3e9ff73826422700f010c84.tar.gz |
gcc/
* doc/md.texi: Document "preferred_for_size" and "preferred_for_speed"
attributes.
* genattr.c (main): Handle "preferred_for_size" and
"preferred_for_speed" in the same way as "enabled".
* recog.h (bool_attr): New enum.
(target_recog): Replace x_enabled_alternatives with x_bool_attr_masks.
(get_preferred_alternatives, check_bool_attrs): Declare.
* recog.c (have_bool_attr, get_bool_attr, get_bool_attr_mask_uncached)
(get_bool_attr_mask, get_preferred_alternatives, check_bool_attrs):
New functions.
(get_enabled_alternatives): Use get_bool_attr_mask.
* ira-costs.c (record_reg_classes): Use get_preferred_alternatives
instead of recog_data.enabled_alternatives.
* ira.c (ira_setup_alts): Likewise.
* postreload.c (reload_cse_simplify_operands): Likewise.
* config/i386/i386.c (ix86_legitimate_combined_insn): Likewise.
* ira-lives.c (preferred_alternatives): New variable.
(process_bb_node_lives): Set it.
(check_and_make_def_conflict, make_early_clobber_and_input_conflicts)
(single_reg_class, ira_implicitly_set_insn_hard_regs): Use it instead
of recog_data.enabled_alternatives.
* lra-int.h (lra_insn_recog_data): Replace enabled_alternatives
to preferred_alternatives.
* lra-constraints.c (process_alt_operands): Update accordingly.
* lra.c (lra_set_insn_recog_data): Likewise.
(lra_update_insn_recog_data): Assert check_bool_attrs.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216554 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 128 |
1 files changed, 105 insertions, 23 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index 199c7debbf8..afcab998124 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2060,25 +2060,46 @@ mode_dependent_address_p (rtx addr, addr_space_t addrspace) return targetm.mode_dependent_address_p (addr, addrspace); } -/* Return the mask of operand alternatives that are allowed for INSN. - This mask depends only on INSN and on the current target; it does not - depend on things like the values of operands. */ +/* Return true if boolean attribute ATTR is supported. */ -alternative_mask -get_enabled_alternatives (rtx_insn *insn) +static bool +have_bool_attr (bool_attr attr) { - /* Quick exit for asms and for targets that don't use the "enabled" - attribute. */ - int code = INSN_CODE (insn); - if (code < 0 || !HAVE_ATTR_enabled) - return ALL_ALTERNATIVES; + switch (attr) + { + case BA_ENABLED: + return HAVE_ATTR_enabled; + case BA_PREFERRED_FOR_SIZE: + return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size; + case BA_PREFERRED_FOR_SPEED: + return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed; + } + gcc_unreachable (); +} - /* Calling get_attr_enabled can be expensive, so cache the mask - for speed. */ - if (this_target_recog->x_enabled_alternatives[code]) - return this_target_recog->x_enabled_alternatives[code]; +/* Return the value of ATTR for instruction INSN. */ - /* Temporarily install enough information for get_attr_enabled to assume +static bool +get_bool_attr (rtx_insn *insn, bool_attr attr) +{ + switch (attr) + { + case BA_ENABLED: + return get_attr_enabled (insn); + case BA_PREFERRED_FOR_SIZE: + return get_attr_enabled (insn) && get_attr_preferred_for_size (insn); + case BA_PREFERRED_FOR_SPEED: + return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn); + } + gcc_unreachable (); +} + +/* Like get_bool_attr_mask, but don't use the cache. */ + +static alternative_mask +get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr) +{ + /* Temporarily install enough information for get_attr_<foo> to assume that the insn operands are already cached. As above, the attribute mustn't depend on the values of operands, so we don't provide their real values here. */ @@ -2086,20 +2107,81 @@ get_enabled_alternatives (rtx_insn *insn) int old_alternative = which_alternative; recog_data.insn = insn; - alternative_mask enabled = ALL_ALTERNATIVES; - int n_alternatives = insn_data[code].n_alternatives; + alternative_mask mask = ALL_ALTERNATIVES; + int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives; for (int i = 0; i < n_alternatives; i++) { which_alternative = i; - if (!get_attr_enabled (insn)) - enabled &= ~ALTERNATIVE_BIT (i); + if (!get_bool_attr (insn, attr)) + mask &= ~ALTERNATIVE_BIT (i); } recog_data.insn = old_insn; which_alternative = old_alternative; + return mask; +} + +/* Return the mask of operand alternatives that are allowed for INSN + by boolean attribute ATTR. This mask depends only on INSN and on + the current target; it does not depend on things like the values of + operands. */ + +static alternative_mask +get_bool_attr_mask (rtx_insn *insn, bool_attr attr) +{ + /* Quick exit for asms and for targets that don't use these attributes. */ + int code = INSN_CODE (insn); + if (code < 0 || !have_bool_attr (attr)) + return ALL_ALTERNATIVES; - this_target_recog->x_enabled_alternatives[code] = enabled; - return enabled; + /* Calling get_attr_<foo> can be expensive, so cache the mask + for speed. */ + if (!this_target_recog->x_bool_attr_masks[code][attr]) + this_target_recog->x_bool_attr_masks[code][attr] + = get_bool_attr_mask_uncached (insn, attr); + return this_target_recog->x_bool_attr_masks[code][attr]; +} + +/* Return the set of alternatives of INSN that are allowed by the current + target. */ + +alternative_mask +get_enabled_alternatives (rtx_insn *insn) +{ + return get_bool_attr_mask (insn, BA_ENABLED); +} + +/* Return the set of alternatives of INSN that are allowed by the current + target and are preferred for the current size/speed optimization + choice. */ + +alternative_mask +get_preferred_alternatives (rtx_insn *insn) +{ + if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))) + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED); + else + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); +} + +/* Assert that the cached boolean attributes for INSN are still accurate. + The backend is required to define these attributes in a way that only + depends on the current target (rather than operands, compiler phase, + etc.). */ + +bool +check_bool_attrs (rtx_insn *insn) +{ + int code = INSN_CODE (insn); + if (code >= 0) + for (int i = 0; i <= BA_LAST; ++i) + { + enum bool_attr attr = (enum bool_attr) i; + if (this_target_recog->x_bool_attr_masks[code][attr]) + gcc_assert (this_target_recog->x_bool_attr_masks[code][attr] + == get_bool_attr_mask_uncached (insn, attr)); + } + return true; } /* Like extract_insn, but save insn extracted and don't extract again, when @@ -4048,8 +4130,8 @@ recog_init () this_target_recog->x_initialized = true; return; } - memset (this_target_recog->x_enabled_alternatives, 0, - sizeof (this_target_recog->x_enabled_alternatives)); + memset (this_target_recog->x_bool_attr_masks, 0, + sizeof (this_target_recog->x_bool_attr_masks)); for (int i = 0; i < LAST_INSN_CODE; ++i) if (this_target_recog->x_op_alt[i]) { |