summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-02 09:08:49 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-02 09:08:49 +0000
commitacdfe9e04a79209c5e0d8c0a220ba62af46abcb6 (patch)
tree72dd378628c948224552d17ec9c275577e55462a /gcc/config
parent592e7d6945e8de8562ca5f52fc5a6362c77d3f42 (diff)
downloadgcc-acdfe9e04a79209c5e0d8c0a220ba62af46abcb6.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231161 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c46
-rw-r--r--gcc/config/i386/i386.md69
2 files changed, 47 insertions, 68 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 23a42734007..05e7fe6d39a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -54100,6 +54100,49 @@ ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
return true;
}
+/* Implement the TARGET_OPTAB_SUPPORTED_P hook. */
+
+static bool
+ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
+ optimization_type opt_type)
+{
+ switch (op)
+ {
+ case asin_optab:
+ case acos_optab:
+ case log1p_optab:
+ case exp_optab:
+ case exp10_optab:
+ case exp2_optab:
+ case expm1_optab:
+ case ldexp_optab:
+ case scalb_optab:
+ case round_optab:
+ return opt_type == OPTIMIZE_FOR_SPEED;
+
+ case rint_optab:
+ if (SSE_FLOAT_MODE_P (mode1)
+ && TARGET_SSE_MATH
+ && !flag_trapping_math
+ && !TARGET_ROUND)
+ return opt_type == OPTIMIZE_FOR_SPEED;
+ return true;
+
+ case floor_optab:
+ case ceil_optab:
+ case btrunc_optab:
+ if (SSE_FLOAT_MODE_P (mode1)
+ && TARGET_SSE_MATH
+ && !flag_trapping_math
+ && TARGET_ROUND)
+ return true;
+ return opt_type == OPTIMIZE_FOR_SPEED;
+
+ default:
+ return true;
+ }
+}
+
/* Address space support.
This is not "far pointers" in the 16-bit sense, but an easy way
@@ -54645,6 +54688,9 @@ ix86_addr_space_zero_address_valid (addr_space_t as)
#undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
#define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
+#undef TARGET_OPTAB_SUPPORTED_P
+#define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index cbb9ffd86af..e8c5f061331 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14726,9 +14726,6 @@
{
int i;
- if (optimize_insn_for_size_p ())
- FAIL;
-
for (i = 2; i < 6; i++)
operands[i] = gen_reg_rtx (XFmode);
@@ -14746,9 +14743,6 @@
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- if (optimize_insn_for_size_p ())
- FAIL;
-
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_asinxf2 (op0, op1));
emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
@@ -14770,9 +14764,6 @@
{
int i;
- if (optimize_insn_for_size_p ())
- FAIL;
-
for (i = 2; i < 6; i++)
operands[i] = gen_reg_rtx (XFmode);
@@ -14790,9 +14781,6 @@
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- if (optimize_insn_for_size_p ())
- FAIL;
-
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_acosxf2 (op0, op1));
emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
@@ -14953,9 +14941,6 @@
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
{
- if (optimize_insn_for_size_p ())
- FAIL;
-
ix86_emit_i387_log1p (operands[0], operands[1]);
DONE;
})
@@ -14970,9 +14955,6 @@
{
rtx op0;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
@@ -15121,9 +15103,6 @@
{
int i;
- if (optimize_insn_for_size_p ())
- FAIL;
-
for (i = 3; i < 10; i++)
operands[i] = gen_reg_rtx (XFmode);
@@ -15138,9 +15117,6 @@
{
rtx op2;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op2 = gen_reg_rtx (XFmode);
emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
@@ -15158,9 +15134,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
@@ -15178,9 +15151,6 @@
{
rtx op2;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op2 = gen_reg_rtx (XFmode);
emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
@@ -15198,9 +15168,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
@@ -15218,9 +15185,6 @@
{
rtx op2;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op2 = gen_reg_rtx (XFmode);
emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
@@ -15238,9 +15202,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
@@ -15278,9 +15239,6 @@
{
int i;
- if (optimize_insn_for_size_p ())
- FAIL;
-
for (i = 2; i < 13; i++)
operands[i] = gen_reg_rtx (XFmode);
@@ -15300,9 +15258,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
@@ -15320,8 +15275,6 @@
&& flag_unsafe_math_optimizations"
{
rtx tmp1, tmp2;
- if (optimize_insn_for_size_p ())
- FAIL;
tmp1 = gen_reg_rtx (XFmode);
tmp2 = gen_reg_rtx (XFmode);
@@ -15343,9 +15296,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
@@ -15366,9 +15316,6 @@
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
{
- if (optimize_insn_for_size_p ())
- FAIL;
-
operands[3] = gen_reg_rtx (XFmode);
})
@@ -15383,9 +15330,6 @@
{
rtx op0, op1, op2;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
op2 = gen_reg_rtx (XFmode);
@@ -15463,8 +15407,6 @@
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
(operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
- else if (optimize_insn_for_size_p ())
- FAIL;
else
ix86_expand_rint (operands[0], operands[1]);
}
@@ -15491,9 +15433,6 @@
|| (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& !flag_trapping_math && !flag_rounding_math)"
{
- if (optimize_insn_for_size_p ())
- FAIL;
-
if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& !flag_trapping_math && !flag_rounding_math)
{
@@ -15747,8 +15686,7 @@
FRNDINT_ROUNDING))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && !optimize_insn_for_size_p ()")
+ && flag_unsafe_math_optimizations")
(define_expand "<rounding_insn><mode>2"
[(parallel [(set (match_operand:MODEF 0 "register_operand")
@@ -15768,8 +15706,6 @@
if (TARGET_ROUND)
emit_insn (gen_sse4_1_round<mode>2
(operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
- else if (optimize_insn_for_size_p ())
- FAIL;
else if (TARGET_64BIT || (<MODE>mode != DFmode))
{
if (ROUND_<ROUNDING> == ROUND_FLOOR)
@@ -15797,9 +15733,6 @@
{
rtx op0, op1;
- if (optimize_insn_for_size_p ())
- FAIL;
-
op0 = gen_reg_rtx (XFmode);
op1 = gen_reg_rtx (XFmode);
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));