Index: llvm/include/llvm/ADT/APFloat.h =================================================================== --- llvm/include/llvm/ADT/APFloat.h +++ llvm/include/llvm/ADT/APFloat.h @@ -21,6 +21,15 @@ #include "llvm/Support/ErrorHandling.h" #include +#define APFLOAT_SINGLE_DISPATCH(METHOD_CALL) \ + do { \ + if (usesLayout(getSemantics())) \ + return U.IEEE.METHOD_CALL; \ + if (usesLayout(getSemantics())) \ + return U.Double.METHOD_CALL; \ + llvm_unreachable("Unexpected semantics"); \ + } while (false) + namespace llvm { struct fltSemantics; @@ -771,76 +780,20 @@ llvm_unreachable("Unexpected semantics"); } - void makeZero(bool Neg) { - if (usesLayout(getSemantics())) { - U.IEEE.makeZero(Neg); - return; - } - if (usesLayout(getSemantics())) { - U.Double.makeZero(Neg); - return; - } - llvm_unreachable("Unexpected semantics"); - } + void makeZero(bool Neg) { APFLOAT_SINGLE_DISPATCH(makeZero(Neg)); } - void makeInf(bool Neg) { - if (usesLayout(*U.semantics)) { - U.IEEE.makeInf(Neg); - return; - } - if (usesLayout(*U.semantics)) { - U.Double.makeInf(Neg); - return; - } - llvm_unreachable("Unexpected semantics"); - } + void makeInf(bool Neg) { APFLOAT_SINGLE_DISPATCH(makeInf(Neg)); } void makeNaN(bool SNaN, bool Neg, const APInt *fill) { - if (usesLayout(getSemantics())) { - U.IEEE.makeNaN(SNaN, Neg, fill); - return; - } - if (usesLayout(getSemantics())) { - return U.Double.makeNaN(SNaN, Neg, fill); - return; - } - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(makeNaN(SNaN, Neg, fill)); } - void makeLargest(bool Neg) { - if (usesLayout(getSemantics())) { - U.IEEE.makeLargest(Neg); - return; - } - if (usesLayout(getSemantics())) { - U.Double.makeLargest(Neg); - return; - } - llvm_unreachable("Unexpected semantics"); - } + void makeLargest(bool Neg) { APFLOAT_SINGLE_DISPATCH(makeLargest(Neg)); } - void makeSmallest(bool Neg) { - if (usesLayout(getSemantics())) { - U.IEEE.makeSmallest(Neg); - return; - } - if (usesLayout(getSemantics())) { - U.Double.makeSmallest(Neg); - return; - } - llvm_unreachable("Unexpected semantics"); - } + void makeSmallest(bool Neg) { APFLOAT_SINGLE_DISPATCH(makeSmallest(Neg)); } void makeSmallestNormalized(bool Neg) { - if (usesLayout(getSemantics())) { - U.IEEE.makeSmallestNormalized(Neg); - return; - } - if (usesLayout(getSemantics())) { - U.Double.makeSmallestNormalized(Neg); - return; - } - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(makeSmallestNormalized(Neg)); } // FIXME: This is due to clang 3.3 (or older version) always checks for the @@ -879,13 +832,7 @@ ~APFloat() = default; - bool needsCleanup() const { - if (usesLayout(getSemantics())) - return U.IEEE.needsCleanup(); - if (usesLayout(getSemantics())) - return U.Double.needsCleanup(); - llvm_unreachable("Unexpected semantics"); - } + bool needsCleanup() const { APFLOAT_SINGLE_DISPATCH(needsCleanup()); } /// Factory for Positive and Negative Zero. /// @@ -1044,22 +991,12 @@ llvm_unreachable("Unexpected semantics"); } opStatus roundToIntegral(roundingMode RM) { - if (usesLayout(getSemantics())) - return U.IEEE.roundToIntegral(RM); - if (usesLayout(getSemantics())) - return U.Double.roundToIntegral(RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(roundToIntegral(RM)); } // TODO: bool parameters are not readable and a source of bugs. // Do something. - opStatus next(bool nextDown) { - if (usesLayout(getSemantics())) - return U.IEEE.next(nextDown); - if (usesLayout(getSemantics())) - return U.Double.next(nextDown); - llvm_unreachable("Unexpected semantics"); - } + opStatus next(bool nextDown) { APFLOAT_SINGLE_DISPATCH(next(nextDown)); } /// Add two APFloats, rounding ties to the nearest even. /// No error checking. @@ -1093,17 +1030,7 @@ return Result; } - void changeSign() { - if (usesLayout(getSemantics())) { - U.IEEE.changeSign(); - return; - } - if (usesLayout(getSemantics())) { - U.Double.changeSign(); - return; - } - llvm_unreachable("Unexpected semantics"); - } + void changeSign() { APFLOAT_SINGLE_DISPATCH(changeSign()); } void clearSign() { if (isNegative()) changeSign(); @@ -1125,52 +1052,29 @@ opStatus convertToInteger(integerPart *Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const { - if (usesLayout(getSemantics())) - return U.IEEE.convertToInteger(Input, Width, IsSigned, RM, IsExact); - if (usesLayout(getSemantics())) - return U.Double.convertToInteger(Input, Width, IsSigned, RM, IsExact); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH( + convertToInteger(Input, Width, IsSigned, RM, IsExact)); } opStatus convertToInteger(APSInt &Result, roundingMode RM, bool *IsExact) const; opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM) { - if (usesLayout(getSemantics())) - return U.IEEE.convertFromAPInt(Input, IsSigned, RM); - if (usesLayout(getSemantics())) - return U.Double.convertFromAPInt(Input, IsSigned, RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(convertFromAPInt(Input, IsSigned, RM)); } opStatus convertFromSignExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM) { - if (usesLayout(getSemantics())) - return U.IEEE.convertFromSignExtendedInteger(Input, InputSize, IsSigned, - RM); - if (usesLayout(getSemantics())) - return U.Double.convertFromSignExtendedInteger(Input, InputSize, IsSigned, - RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH( + convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM)); } opStatus convertFromZeroExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM) { - if (usesLayout(getSemantics())) - return U.IEEE.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, - RM); - if (usesLayout(getSemantics())) - return U.Double.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, - RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH( + convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM)); } opStatus convertFromString(StringRef, roundingMode); - APInt bitcastToAPInt() const { - if (usesLayout(getSemantics())) - return U.IEEE.bitcastToAPInt(); - if (usesLayout(getSemantics())) - return U.Double.bitcastToAPInt(); - llvm_unreachable("Unexpected semantics"); - } + APInt bitcastToAPInt() const { APFLOAT_SINGLE_DISPATCH(bitcastToAPInt()); } double convertToDouble() const { return getIEEE().convertToDouble(); } float convertToFloat() const { return getIEEE().convertToFloat(); } @@ -1198,11 +1102,7 @@ unsigned int convertToHexString(char *DST, unsigned int HexDigits, bool UpperCase, roundingMode RM) const { - if (usesLayout(getSemantics())) - return U.IEEE.convertToHexString(DST, HexDigits, UpperCase, RM); - if (usesLayout(getSemantics())) - return U.Double.convertToHexString(DST, HexDigits, UpperCase, RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(convertToHexString(DST, HexDigits, UpperCase, RM)); } bool isZero() const { return getCategory() == fcZero; } @@ -1210,13 +1110,7 @@ bool isNaN() const { return getCategory() == fcNaN; } bool isNegative() const { return getIEEE().isNegative(); } - bool isDenormal() const { - if (usesLayout(getSemantics())) - return U.IEEE.isDenormal(); - if (usesLayout(getSemantics())) - return U.Double.isDenormal(); - llvm_unreachable("Unexpected semantics"); - } + bool isDenormal() const { APFLOAT_SINGLE_DISPATCH(isDenormal()); } bool isSignaling() const { return getIEEE().isSignaling(); } bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } @@ -1228,53 +1122,23 @@ bool isFiniteNonZero() const { return isFinite() && !isZero(); } bool isPosZero() const { return isZero() && !isNegative(); } bool isNegZero() const { return isZero() && isNegative(); } - bool isSmallest() const { - if (usesLayout(getSemantics())) - return U.IEEE.isSmallest(); - if (usesLayout(getSemantics())) - return U.Double.isSmallest(); - llvm_unreachable("Unexpected semantics"); - } - bool isLargest() const { - if (usesLayout(getSemantics())) - return U.IEEE.isLargest(); - if (usesLayout(getSemantics())) - return U.Double.isLargest(); - llvm_unreachable("Unexpected semantics"); - } - bool isInteger() const { - if (usesLayout(getSemantics())) - return U.IEEE.isInteger(); - if (usesLayout(getSemantics())) - return U.Double.isInteger(); - llvm_unreachable("Unexpected semantics"); - } + bool isSmallest() const { APFLOAT_SINGLE_DISPATCH(isSmallest()); } + bool isLargest() const { APFLOAT_SINGLE_DISPATCH(isLargest()); } + bool isInteger() const { APFLOAT_SINGLE_DISPATCH(isInteger()); } APFloat &operator=(const APFloat &RHS) = default; APFloat &operator=(APFloat &&RHS) = default; void toString(SmallVectorImpl &Str, unsigned FormatPrecision = 0, unsigned FormatMaxPadding = 3) const { - if (usesLayout(getSemantics())) { - U.IEEE.toString(Str, FormatPrecision, FormatMaxPadding); - return; - } - if (usesLayout(getSemantics())) { - U.Double.toString(Str, FormatPrecision, FormatMaxPadding); - return; - } - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(toString(Str, FormatPrecision, FormatMaxPadding)); } void print(raw_ostream &) const; void dump() const; bool getExactInverse(APFloat *inv) const { - if (usesLayout(getSemantics())) - return U.IEEE.getExactInverse(inv); - if (usesLayout(getSemantics())) - return U.Double.getExactInverse(inv); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(getExactInverse(inv)); } friend hash_code hash_value(const APFloat &Arg); @@ -1345,4 +1209,5 @@ } // namespace llvm +#undef APFLOAT_SINGLE_DISPATCH #endif // LLVM_ADT_APFLOAT_H Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -26,6 +26,15 @@ #include #include +#define APFLOAT_SINGLE_DISPATCH(METHOD_CALL) \ + do { \ + if (usesLayout(getSemantics())) \ + return U.IEEE.METHOD_CALL; \ + if (usesLayout(getSemantics())) \ + return U.Double.METHOD_CALL; \ + llvm_unreachable("Unexpected semantics"); \ + } while (false) + using namespace llvm; /// A macro used to combine two fcCategory enums into one key which can be used @@ -4418,11 +4427,7 @@ } APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) { - if (usesLayout(getSemantics())) - return U.IEEE.convertFromString(Str, RM); - if (usesLayout(getSemantics())) - return U.Double.convertFromString(Str, RM); - llvm_unreachable("Unexpected semantics"); + APFLOAT_SINGLE_DISPATCH(convertFromString(Str, RM)); } hash_code hash_value(const APFloat &Arg) { @@ -4512,3 +4517,5 @@ } } // End llvm namespace + +#undef APFLOAT_SINGLE_DISPATCH