Now that all ports that use the "enabled", "preferred_for_size" and "preferred_for_speed" attributes have been converted to use "code,alternative", we can use them for the bool_attr code in recog.
The patch also exports the new form of get_bool_attr_mask for use by patch 21. Tested as described in the covering note. gcc/ * doc/md.texi: Require enabled, preferred_for_size and preferred_for_speed to be code,alternative attributes. * genattr.c (main): Use hook_int_int_int_1 as the default for get_attr_enabled, get_attr_preferred_for_size and get_attr_preferred_for_speed. * hooks.h (hook_int_int_int_1): Declare. * hooks.c (hook_int_int_int_1): New function. * recog.h (get_bool_attr_mask): Declare. * recog.c (get_bool_attr): Take an icode and alternative instead of an rtx_insn *. (get_bool_attr_mask_uncached): Take an icode instead of an rtx_insn *. Update call to get_bool_attr. (get_bool_attr_mask): Take an icode instead of an rtx_insn *. Update call to get_bool_attr_mask_uncached. Make public. (get_enabled_alternatives): Update accordingly. (get_preferred_alternatives): Likewise. (check_bool_attrs): Likewise. diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 5d3736c..fb0e7fb 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4226,11 +4226,11 @@ optimized for speed. @end table All these attributes should use @code{(const_int 1)} to allow an alternative -or @code{(const_int 0)} to disallow it. The attributes must be a static -property of the subtarget; they cannot for example depend on the -current operands, on the current optimization level, on the location -of the insn within the body of a loop, on whether register allocation -has finished, or on the current compiler pass. +or @code{(const_int 0)} to disallow it. The attributes must have +type @code{code,alternative} and be a static property of the +subtarget; they cannot for example depend on the current operands, on +the current optimization level, on whether register allocation has +finished, or on the current compiler pass. The @code{enabled} attribute is a correctness property. It tells GCC to act as though the disabled alternatives were never defined in the first place. @@ -4295,14 +4295,16 @@ with the @code{enabled} attribute defined like this: @smallexample -(define_attr "cpu_facility" "standard,new" (const_string "standard")) +(define_attr "cpu_facility" "standard,new" (const_string "standard") + "code,alternative") (define_attr "enabled" "" (cond [(eq_attr "cpu_facility" "standard") (const_int 1) (and (eq_attr "cpu_facility" "new") (ne (symbol_ref "TARGET_NEW") (const_int 0))) (const_int 1)] - (const_int 0))) + (const_int 0)) + "code,alternative") @end smallexample @@ -8173,7 +8175,8 @@ distances. @xref{Insn Lengths}. @item enabled The @code{enabled} attribute can be defined to prevent certain alternatives of an insn definition from being used during code -generation. @xref{Disable Insn Alternatives}. +generation. @xref{Disable Insn Alternatives}. This attribute must +have type @code{code,alternative}. @item mnemonic The @code{mnemonic} attribute can be defined to implement instruction diff --git a/gcc/genattr.c b/gcc/genattr.c index c08c4af..3be3e38 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -355,15 +355,15 @@ main (int argc, char **argv) "#define insn_current_length hook_int_rtx_insn_unreachable\n" "#include \"insn-addr.h\"\n" "#endif\n" - "extern int hook_int_rtx_1 (rtx);\n" + "extern int hook_int_int_int_1 (int, int);\n" "#if !HAVE_ATTR_enabled\n" - "#define get_attr_enabled hook_int_rtx_1\n" + "#define get_attr_enabled hook_int_int_int_1\n" "#endif\n" "#if !HAVE_ATTR_preferred_for_size\n" - "#define get_attr_preferred_for_size hook_int_rtx_1\n" + "#define get_attr_preferred_for_size hook_int_int_int_1\n" "#endif\n" "#if !HAVE_ATTR_preferred_for_speed\n" - "#define get_attr_preferred_for_speed hook_int_rtx_1\n" + "#define get_attr_preferred_for_speed hook_int_int_int_1\n" "#endif\n"); /* Output flag masks for use by reorg. diff --git a/gcc/hooks.c b/gcc/hooks.c index 0fb9add..6b02b6f 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -191,6 +191,12 @@ default_can_output_mi_thunk_no_vcall (const_tree a ATTRIBUTE_UNUSED, } int +hook_int_int_int_1 (int, int) +{ + return 1; +} + +int hook_int_uint_mode_1 (unsigned int a ATTRIBUTE_UNUSED, machine_mode b ATTRIBUTE_UNUSED) { diff --git a/gcc/hooks.h b/gcc/hooks.h index c3d4bd3..15bede9 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -77,6 +77,7 @@ extern void hook_void_tree_treeptr (tree, tree *); extern void hook_void_int_int (int, int); extern void hook_void_gcc_optionsp (struct gcc_options *); +extern int hook_int_int_int_1 (int, int); extern int hook_int_uint_mode_1 (unsigned int, machine_mode); extern int hook_int_const_tree_0 (const_tree); extern int hook_int_const_tree_const_tree_1 (const_tree, const_tree); diff --git a/gcc/recog.c b/gcc/recog.c index 04228f8..c42f82f 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2042,19 +2042,22 @@ have_bool_attr (bool_attr attr) gcc_unreachable (); } -/* Return the value of ATTR for instruction INSN. */ +/* Return the value of ATTR for alternative ALTERNATIVE of the instruction + with code ICODE. */ static bool -get_bool_attr (rtx_insn *insn, bool_attr attr) +get_bool_attr (int icode, int alternative, bool_attr attr) { switch (attr) { case BA_ENABLED: - return get_attr_enabled (insn); + return get_attr_enabled (icode, alternative); case BA_PREFERRED_FOR_SIZE: - return get_attr_enabled (insn) && get_attr_preferred_for_size (insn); + return (get_attr_enabled (icode, alternative) + && get_attr_preferred_for_size (icode, alternative)); case BA_PREFERRED_FOR_SPEED: - return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn); + return (get_attr_enabled (icode, alternative) + && get_attr_preferred_for_speed (icode, alternative)); } gcc_unreachable (); } @@ -2062,49 +2065,35 @@ get_bool_attr (rtx_insn *insn, bool_attr attr) /* 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) +get_bool_attr_mask_uncached (int icode, 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. */ - rtx_insn *old_insn = recog_data.insn; - int old_alternative = cached_which_alternative; - - recog_data.insn = insn; alternative_mask mask = ALL_ALTERNATIVES; - int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives; + int n_alternatives = MAX (insn_data[icode].n_alternatives, 1); for (int i = 0; i < n_alternatives; i++) { - cached_which_alternative = i; - if (!get_bool_attr (insn, attr)) + if (!get_bool_attr (icode, i, attr)) mask &= ~ALTERNATIVE_BIT (i); } - recog_data.insn = old_insn; - cached_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. */ +/* Return the mask of operand alternatives that are allowed for instruction + code ICODE by boolean attribute ATTR. */ -static alternative_mask -get_bool_attr_mask (rtx_insn *insn, bool_attr attr) +alternative_mask +get_bool_attr_mask (int icode, 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)) + if (icode < 0 || !have_bool_attr (attr)) return ALL_ALTERNATIVES; /* 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]; + if (!this_target_recog->x_bool_attr_masks[icode][attr]) + this_target_recog->x_bool_attr_masks[icode][attr] + = get_bool_attr_mask_uncached (icode, attr); + return this_target_recog->x_bool_attr_masks[icode][attr]; } /* Return the set of alternatives of INSN that are allowed by the current @@ -2113,7 +2102,7 @@ get_bool_attr_mask (rtx_insn *insn, bool_attr attr) alternative_mask get_enabled_alternatives (rtx_insn *insn) { - return get_bool_attr_mask (insn, BA_ENABLED); + return get_bool_attr_mask (INSN_CODE (insn), BA_ENABLED); } /* Return the set of alternatives of INSN that are allowed by the current @@ -2124,9 +2113,9 @@ 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); + return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SPEED); else - return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); + return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SIZE); } /* Return the set of alternatives of INSN that are allowed by the current @@ -2139,9 +2128,9 @@ alternative_mask get_preferred_alternatives (rtx_insn *insn, basic_block bb) { if (optimize_bb_for_speed_p (bb)) - return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED); + return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SPEED); else - return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); + return get_bool_attr_mask (INSN_CODE (insn), BA_PREFERRED_FOR_SIZE); } /* Assert that the cached boolean attributes for INSN are still accurate. @@ -2159,7 +2148,7 @@ check_bool_attrs (rtx_insn *insn) 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)); + == get_bool_attr_mask_uncached (code, attr)); } return true; } diff --git a/gcc/recog.h b/gcc/recog.h index b15140b..c8422f5 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -399,6 +399,7 @@ extern struct target_recog *this_target_recog; #define this_target_recog (&default_target_recog) #endif +alternative_mask get_bool_attr_mask (int, bool_attr); alternative_mask get_enabled_alternatives (rtx_insn *); alternative_mask get_preferred_alternatives (rtx_insn *); alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);