Fold FEnv.h into the implementation

Support headers shouldn't use config.h definitions, and they should never be
undefined like this.

ConstantFolding.cpp was the only user of this facility and already includes
config.h for other math features, so it makes sense to move the checks there at
point of use.

(The implicit config.h was also quite dangerous -- removing the FEnv.h include
would have silently disabled math constant folding without causing any tests to
fail. Need to investigate -Wundef once the cleanup is done.)

This eliminates the last config.h include from LLVM headers, paving the way for
more consistent configuration checks.

llvm-svn: 210483
This commit is contained in:
Alp Toker
2014-06-09 18:28:53 +00:00
parent a8de0de1fe
commit c817d6a5b5
2 changed files with 41 additions and 63 deletions

View File

@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
@@ -31,11 +32,22 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FEnv.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include <cerrno>
#include <cmath>
#ifdef HAVE_FENV_H
#include <fenv.h>
#define USE_FENV
#endif
// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
// fenv.h; see PR6907 for details.
#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
#undef USE_FENV
#endif
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -1314,12 +1326,34 @@ static Constant *GetConstantFoldFPValue(double V, Type *Ty) {
}
namespace {
/// llvm_fenv_clearexcept - Clear the floating-point exception state.
static inline void llvm_fenv_clearexcept() {
#if defined(USE_FENV) && HAVE_DECL_FE_ALL_EXCEPT
feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;
}
/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
static inline bool llvm_fenv_testexcept() {
int errno_val = errno;
if (errno_val == ERANGE || errno_val == EDOM)
return true;
#if defined(USE_FENV) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
return true;
#endif
return false;
}
} // End namespace
static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
Type *Ty) {
sys::llvm_fenv_clearexcept();
llvm_fenv_clearexcept();
V = NativeFP(V);
if (sys::llvm_fenv_testexcept()) {
sys::llvm_fenv_clearexcept();
if (llvm_fenv_testexcept()) {
llvm_fenv_clearexcept();
return nullptr;
}
@@ -1328,10 +1362,10 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
double V, double W, Type *Ty) {
sys::llvm_fenv_clearexcept();
llvm_fenv_clearexcept();
V = NativeFP(V, W);
if (sys::llvm_fenv_testexcept()) {
sys::llvm_fenv_clearexcept();
if (llvm_fenv_testexcept()) {
llvm_fenv_clearexcept();
return nullptr;
}