From 66ee4402d0a421b10aaccf570bfde101f744772d Mon Sep 17 00:00:00 2001 From: James Zern Date: Fri, 6 Jan 2017 17:59:50 -0800 Subject: [PATCH] aom_encoder: enable floating point exceptions with --enable-debug (CONFIG_DEBUG) when available BUG=aomedia:388 Change-Id: I5dd0718d6bd0ba17bc1b52d5842e250244d2d1d8 --- aom/src/aom_encoder.c | 53 ++++++++++++++++++++------- build/cmake/aom_config.h.cmake | 1 + build/cmake/aom_config_defaults.cmake | 1 + build/cmake/aom_configure.cmake | 11 ++++++ build/cmake/compiler_tests.cmake | 10 +++++ configure | 7 ++++ 6 files changed, 69 insertions(+), 14 deletions(-) diff --git a/aom/src/aom_encoder.c b/aom/src/aom_encoder.c index 41c70ef1b..ac84c888a 100644 --- a/aom/src/aom_encoder.c +++ b/aom/src/aom_encoder.c @@ -13,9 +13,15 @@ * \brief Provides the high level interface to wrap encoder algorithms. * */ +#include "./aom_config.h" + +#if HAVE_FEXCEPT +#define _GNU_SOURCE +#include +#endif + #include #include -#include "aom_config.h" #include "aom/internal/aom_codec_internal.h" #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var) @@ -168,23 +174,42 @@ aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface, return res; } +/* clang-format off */ +#define FLOATING_POINT_BEGIN_SCOPE do { +#define FLOATING_POINT_END_SCOPE } while (0); +/* clang-format on */ + #if ARCH_X86 || ARCH_X86_64 /* On X86, disable the x87 unit's internal 80 bit precision for better * consistency with the SSE unit's 64 bit precision. */ #include "aom_ports/x86.h" -#define FLOATING_POINT_INIT() \ - do { \ - unsigned short x87_orig_mode = x87_set_double_precision(); -#define FLOATING_POINT_RESTORE() \ - x87_set_control_word(x87_orig_mode); \ - } \ - while (0) - +#define FLOATING_POINT_SET_PRECISION \ + unsigned short x87_orig_mode = x87_set_double_precision(); +#define FLOATING_POINT_RESTORE_PRECISION x87_set_control_word(x87_orig_mode); #else -static void FLOATING_POINT_INIT() {} -static void FLOATING_POINT_RESTORE() {} -#endif +#define FLOATING_POINT_SET_PRECISION +#define FLOATING_POINT_RESTORE_PRECISION +#endif // ARCH_X86 || ARCH_X86_64 + +#if HAVE_FEXCEPT && CONFIG_DEBUG +#define FLOATING_POINT_SET_EXCEPTIONS \ + const int float_excepts = feenableexcept(FE_DIVBYZERO); +#define FLOATING_POINT_RESTORE_EXCEPTIONS feenableexcept(float_excepts); +#else +#define FLOATING_POINT_SET_EXCEPTIONS +#define FLOATING_POINT_RESTORE_EXCEPTIONS +#endif // HAVE_FEXCEPT && CONFIG_DEBUG + +#define FLOATING_POINT_INIT \ + FLOATING_POINT_BEGIN_SCOPE \ + FLOATING_POINT_SET_PRECISION \ + FLOATING_POINT_SET_EXCEPTIONS + +#define FLOATING_POINT_RESTORE \ + FLOATING_POINT_RESTORE_EXCEPTIONS \ + FLOATING_POINT_RESTORE_PRECISION \ + FLOATING_POINT_END_SCOPE aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, aom_codec_pts_t pts, unsigned long duration, @@ -204,7 +229,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, /* Execute in a normalized floating point environment, if the platform * requires it. */ - FLOATING_POINT_INIT(); + FLOATING_POINT_INIT if (num_enc == 1) res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags, @@ -231,7 +256,7 @@ aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, ctx++; } - FLOATING_POINT_RESTORE(); + FLOATING_POINT_RESTORE } return SAVE_STATUS(ctx, res); diff --git a/build/cmake/aom_config.h.cmake b/build/cmake/aom_config.h.cmake index d5655594f..2e95e23fd 100644 --- a/build/cmake/aom_config.h.cmake +++ b/build/cmake/aom_config.h.cmake @@ -36,6 +36,7 @@ #define HAVE_AVX ${HAVE_AVX} #define HAVE_AVX2 ${HAVE_AVX2} #define HAVE_AOM_PORTS ${HAVE_AOM_PORTS} +#define HAVE_FEXCEPT ${HAVE_FEXCEPT} #define HAVE_PTHREAD_H ${HAVE_PTHREAD_H} #define HAVE_UNISTD_H ${HAVE_UNISTD_H} #define CONFIG_DEPENDENCY_TRACKING ${CONFIG_DEPENDENCY_TRACKING} diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake index d457e5823..441bdf396 100644 --- a/build/cmake/aom_config_defaults.cmake +++ b/build/cmake/aom_config_defaults.cmake @@ -36,6 +36,7 @@ set(HAVE_SSE4_1 0 CACHE BOOL "Enables SSE 4.1 optimizations.") set(HAVE_AVX 0 CACHE BOOL "Enables AVX optimizations.") set(HAVE_AVX2 0 CACHE BOOL "Enables AVX2 optimizations.") set(HAVE_AOM_PORTS 0 CACHE BOOL "Internal flag, deprecated.") +set(HAVE_FEXCEPT 0 CACHE BOOL "Internal flag, GNU fenv.h present for target.") set(HAVE_PTHREAD_H 0 CACHE BOOL "Internal flag, target pthread support.") set(HAVE_UNISTD_H 0 CACHE BOOL "Internal flag, unistd.h present for target.") set(CONFIG_DEPENDENCY_TRACKING 1 CACHE BOOL "Internal flag.") diff --git a/build/cmake/aom_configure.cmake b/build/cmake/aom_configure.cmake index 34e014244..31f826e97 100644 --- a/build/cmake/aom_configure.cmake +++ b/build/cmake/aom_configure.cmake @@ -158,6 +158,17 @@ if (CONFIG_ANS AND CONFIG_DAALA_EC) "CONFIG_ANS and CONFIG_DAALA_EC cannot be enabled together.") endif () +if (NOT MSVC) + aom_push_var(CMAKE_REQUIRED_LIBRARIES "m") + aom_check_c_compiles("fenv_check" + "#define _GNU_SOURCE + #include + void unused(void) { + (void)feenableexcept(FE_DIVBYZERO | FE_INVALID); + }" HAVE_FEXCEPT) + aom_pop_var(CMAKE_REQUIRED_LIBRARIES) +endif() + # TODO(tomfinegan): consume trailing whitespace after configure_file() when # target platform check produces empty INLINE and RESTRICT values (aka empty # values require special casing). diff --git a/build/cmake/compiler_tests.cmake b/build/cmake/compiler_tests.cmake index e3c0e9abe..e763597a2 100644 --- a/build/cmake/compiler_tests.cmake +++ b/build/cmake/compiler_tests.cmake @@ -21,6 +21,16 @@ set(AOM_C_FAILED_TESTS) set(AOM_CXX_PASSED_TESTS) set(AOM_CXX_FAILED_TESTS) +function(aom_push_var var new_value) + set(SAVED_${var} ${var} PARENT_SCOPE) + set(${var} ${new_value} PARENT_SCOPE) +endfunction () + +function(aom_pop_var var) + set(var ${SAVED_${var}} PARENT_SCOPE) + unset(SAVED_${var} PARENT_SCOPE) +endfunction () + # Confirms $test_source compiles and stores $test_name in one of # $AOM_C_PASSED_TESTS or $AOM_C_FAILED_TESTS depending on out come. When the # test passes $result_var is set to 1. When it fails $result_var is unset. diff --git a/configure b/configure index 5a24bed1a..ad240ba81 100755 --- a/configure +++ b/configure @@ -238,6 +238,7 @@ ARCH_EXT_LIST=" HAVE_LIST=" ${ARCH_EXT_LIST} aom_ports + fexcept pthread_h unistd_h wxwidgets @@ -649,6 +650,12 @@ EOF check_header unistd.h # for sysconf(3) and friends. check_header aom/aom_integer.h -I${source_path} && enable_feature aom_ports + + check_ld < +int main(void) { (void)feenableexcept(FE_DIVBYZERO | FE_INVALID); return 0; } +EOF } process_toolchain() { -- GitLab