aboutsummaryrefslogtreecommitdiff
path: root/gcc/internal-fn.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2015-12-02 09:08:49 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2015-12-02 09:08:49 +0000
commitd95ab70a3cab2998b4671d842e1ad769e75f19a3 (patch)
tree72dd378628c948224552d17ec9c275577e55462a /gcc/internal-fn.c
parent886456e210ef12d77f625ace8f312ab23d208aff (diff)
downloadgcc-d95ab70a3cab2998b4671d842e1ad769e75f19a3.zip
gcc-d95ab70a3cab2998b4671d842e1ad769e75f19a3.tar.gz
gcc-d95ab70a3cab2998b4671d842e1ad769e75f19a3.tar.bz2
PR 68432: Add a target hook to control size/speed optab choices
The problem in the PR is that some i386 optabs FAIL when optimising for size rather than speed. The gimple level generally needs access to this information before calling the generator, so this patch adds a new hook to say whether an optab should be used when optimising for size or speed. It also has a "both" option for cases where we want code that is optimised for both size and speed. I've passed the optab to the target hook because I think in most cases that's more useful than the instruction code. We could pass both if there's a use for it though. At the moment the match-and-simplify code doesn't have direct access to the target block, so for now I've used "both" there. Tested on x86_64-linux-gnu and powerpc64-linux-gnu. gcc/ PR tree-optimization/68432 * coretypes.h (optimization_type): New enum. * doc/tm.texi.in (TARGET_OPTAB_SUPPORTED_P): New hook. * doc/tm.texi: Regenerate. * target.def (optab_supported_p): New hook. * targhooks.h (default_optab_supported_p): Declare. * targhooks.c (default_optab_supported_p): New function. * predict.h (function_optimization_type): Declare. (bb_optimization_type): Likewise. * predict.c (function_optimization_type): New function. (bb_optimization_type): Likewise. * optabs-query.h (convert_optab_handler): Define an overload that takes an optimization type. (direct_optab_handler): Likewise. * optabs-query.c (convert_optab_handler): Likewise. (direct_optab_handler): Likewise. * internal-fn.h (direct_internal_fn_supported_p): Take an optimization_type argument. * internal-fn.c (direct_optab_supported_p): Likewise. (multi_vector_optab_supported_p): Likewise. (direct_internal_fn_supported_p): Likewise. * builtins.c (replacement_internal_fn): Update call to direct_internal_fn_supported_p. * gimple-match-head.c (build_call_internal): Likewise. * tree-vect-patterns.c (vect_recog_pow_pattern): Likewise. * tree-vect-stmts.c (vectorizable_internal_function): Likewise. * tree.c (maybe_build_call_expr_loc): Likewise. * config/i386/i386.c (ix86_optab_supported_p): New function. (TARGET_OPTAB_SUPPORTED_P): Define. * config/i386/i386.md (asinxf2): Remove optimize_insn_for_size_p check. (asin<mode>2, acosxf2, acos<mode>2, log1pxf2, log1p<mode>2) (expNcorexf3, expxf2, exp<mode>2, exp10xf2, exp10<mode>2, exp2xf2) (exp2<mode>2, expm1xf2, expm1<mode>2, ldexpxf3, ldexp<mode>3) (scalbxf3, scalb<mode>3, rint<mode>2, round<mode>2) (<rounding_insn>xf2, <rounding_insn><mode>2): Likewise. gcc/testsuite/ * gcc.target/i386/pr68432-1.c: New test. * gcc.target/i386/pr68432-2.c: Likewise. * gcc.target/i386/pr68432-3.c: Likewise. From-SVN: r231161
Diffstat (limited to 'gcc/internal-fn.c')
-rw-r--r--gcc/internal-fn.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index b15657f..2be2d88 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -2214,23 +2214,30 @@ direct_internal_fn_types (internal_fn fn, gcall *call)
}
/* Return true if OPTAB is supported for TYPES (whose modes should be
- the same). Used for simple direct optabs. */
+ the same) when the optimization type is OPT_TYPE. Used for simple
+ direct optabs. */
static bool
-direct_optab_supported_p (direct_optab optab, tree_pair types)
+direct_optab_supported_p (direct_optab optab, tree_pair types,
+ optimization_type opt_type)
{
machine_mode mode = TYPE_MODE (types.first);
gcc_checking_assert (mode == TYPE_MODE (types.second));
- return direct_optab_handler (optab, mode) != CODE_FOR_nothing;
+ return direct_optab_handler (optab, mode, opt_type) != CODE_FOR_nothing;
}
/* Return true if load/store lanes optab OPTAB is supported for
- array type TYPES.first. */
+ array type TYPES.first when the optimization type is OPT_TYPE. */
static bool
-multi_vector_optab_supported_p (convert_optab optab, tree_pair types)
+multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
+ optimization_type opt_type)
{
- return get_multi_vector_move (types.first, optab) != CODE_FOR_nothing;
+ gcc_assert (TREE_CODE (types.first) == ARRAY_TYPE);
+ machine_mode imode = TYPE_MODE (types.first);
+ machine_mode vmode = TYPE_MODE (TREE_TYPE (types.first));
+ return (convert_optab_handler (optab, imode, vmode, opt_type)
+ != CODE_FOR_nothing);
}
#define direct_unary_optab_supported_p direct_optab_supported_p
@@ -2240,12 +2247,14 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types)
#define direct_mask_store_optab_supported_p direct_optab_supported_p
#define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
-/* Return true if FN is supported for the types in TYPES. The types
- are those associated with the "type0" and "type1" fields of FN's
- direct_internal_fn_info structure. */
+/* Return true if FN is supported for the types in TYPES when the
+ optimization type is OPT_TYPE. The types are those associated with
+ the "type0" and "type1" fields of FN's direct_internal_fn_info
+ structure. */
bool
-direct_internal_fn_supported_p (internal_fn fn, tree_pair types)
+direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
+ optimization_type opt_type)
{
switch (fn)
{
@@ -2253,7 +2262,8 @@ direct_internal_fn_supported_p (internal_fn fn, tree_pair types)
case IFN_##CODE: break;
#define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
case IFN_##CODE: \
- return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types);
+ return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
+ opt_type);
#include "internal-fn.def"
case IFN_LAST:
@@ -2262,16 +2272,17 @@ direct_internal_fn_supported_p (internal_fn fn, tree_pair types)
gcc_unreachable ();
}
-/* Return true if FN is supported for type TYPE. The caller knows that
- the "type0" and "type1" fields of FN's direct_internal_fn_info
- structure are the same. */
+/* Return true if FN is supported for type TYPE when the optimization
+ type is OPT_TYPE. The caller knows that the "type0" and "type1"
+ fields of FN's direct_internal_fn_info structure are the same. */
bool
-direct_internal_fn_supported_p (internal_fn fn, tree type)
+direct_internal_fn_supported_p (internal_fn fn, tree type,
+ optimization_type opt_type)
{
const direct_internal_fn_info &info = direct_internal_fn (fn);
gcc_checking_assert (info.type0 == info.type1);
- return direct_internal_fn_supported_p (fn, tree_pair (type, type));
+ return direct_internal_fn_supported_p (fn, tree_pair (type, type), opt_type);
}
/* Return true if IFN_SET_EDOM is supported. */