summaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-22 12:02:11 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-22 12:02:11 +0000
commite1a797ade2cd2dffe3e9ff73826422700f010c84 (patch)
tree69a28087e5d6c8f66821aa2540f8d19983b792eb /gcc/recog.c
parent835b8178b6af49b010c32136c5aa49227d562691 (diff)
downloadgcc-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.c128
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])
{