Skip to content

Commit

Permalink
[APFloat] Reduce some dispatch boilerplates. NFC.
Browse files Browse the repository at this point in the history
Summary: This is an attempt to reduce the verbose manual dispatching code in APFloat. This doesn't handle multiple dispatch on single discriminator (e.g. APFloat::add(const APFloat&)), nor handles multiple dispatch on multiple discriminators (e.g. APFloat::convert()).

Reviewers: hfinkel, echristo, jlebar

Subscribers: mehdi_amini, llvm-commits

Differential Revision: https://reviews.llvm.org/D29161

llvm-svn: 293255
  • Loading branch information
timshen91 committed Jan 27, 2017
1 parent c5b2e00 commit 601ba8c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 167 deletions.
199 changes: 37 additions & 162 deletions llvm/include/llvm/ADT/APFloat.h
Expand Up @@ -21,6 +21,15 @@
#include "llvm/Support/ErrorHandling.h"
#include <memory>

#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
do { \
if (usesLayout<IEEEFloat>(getSemantics())) \
return U.IEEE.METHOD_CALL; \
if (usesLayout<DoubleAPFloat>(getSemantics())) \
return U.Double.METHOD_CALL; \
llvm_unreachable("Unexpected semantics"); \
} while (false)

namespace llvm {

struct fltSemantics;
Expand Down Expand Up @@ -771,76 +780,24 @@ class APFloat : public APFloatBase {
llvm_unreachable("Unexpected semantics");
}

void makeZero(bool Neg) {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.makeZero(Neg);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.makeZero(Neg);
return;
}
llvm_unreachable("Unexpected semantics");
}
void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); }

void makeInf(bool Neg) {
if (usesLayout<IEEEFloat>(*U.semantics)) {
U.IEEE.makeInf(Neg);
return;
}
if (usesLayout<DoubleAPFloat>(*U.semantics)) {
U.Double.makeInf(Neg);
return;
}
llvm_unreachable("Unexpected semantics");
}
void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); }

void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.makeNaN(SNaN, Neg, fill);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
return U.Double.makeNaN(SNaN, Neg, fill);
return;
}
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill));
}

void makeLargest(bool Neg) {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.makeLargest(Neg);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.makeLargest(Neg);
return;
}
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg));
}

void makeSmallest(bool Neg) {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.makeSmallest(Neg);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.makeSmallest(Neg);
return;
}
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg));
}

void makeSmallestNormalized(bool Neg) {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.makeSmallestNormalized(Neg);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.makeSmallestNormalized(Neg);
return;
}
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg));
}

// FIXME: This is due to clang 3.3 (or older version) always checks for the
Expand Down Expand Up @@ -879,13 +836,7 @@ class APFloat : public APFloatBase {

~APFloat() = default;

bool needsCleanup() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.needsCleanup();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.needsCleanup();
llvm_unreachable("Unexpected semantics");
}
bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); }

/// Factory for Positive and Negative Zero.
///
Expand Down Expand Up @@ -1044,21 +995,13 @@ class APFloat : public APFloatBase {
llvm_unreachable("Unexpected semantics");
}
opStatus roundToIntegral(roundingMode RM) {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.roundToIntegral(RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.roundToIntegral(RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM));
}

// TODO: bool parameters are not readable and a source of bugs.
// Do something.
opStatus next(bool nextDown) {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.next(nextDown);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.next(nextDown);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
}

/// Add two APFloats, rounding ties to the nearest even.
Expand Down Expand Up @@ -1093,17 +1036,7 @@ class APFloat : public APFloatBase {
return Result;
}

void changeSign() {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.changeSign();
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.changeSign();
return;
}
llvm_unreachable("Unexpected semantics");
}
void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); }
void clearSign() {
if (isNegative())
changeSign();
Expand All @@ -1125,51 +1058,30 @@ class APFloat : public APFloatBase {
opStatus convertToInteger(integerPart *Input, unsigned int Width,
bool IsSigned, roundingMode RM,
bool *IsExact) const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.convertToInteger(Input, Width, IsSigned, RM, IsExact);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertToInteger(Input, Width, IsSigned, RM, IsExact);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(
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<IEEEFloat>(getSemantics()))
return U.IEEE.convertFromAPInt(Input, IsSigned, RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertFromAPInt(Input, IsSigned, RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
}
opStatus convertFromSignExtendedInteger(const integerPart *Input,
unsigned int InputSize, bool IsSigned,
roundingMode RM) {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.convertFromSignExtendedInteger(Input, InputSize, IsSigned,
RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertFromSignExtendedInteger(Input, InputSize, IsSigned,
RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(
convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
}
opStatus convertFromZeroExtendedInteger(const integerPart *Input,
unsigned int InputSize, bool IsSigned,
roundingMode RM) {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertFromZeroExtendedInteger(Input, InputSize, IsSigned,
RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(
convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
}
opStatus convertFromString(StringRef, roundingMode);
APInt bitcastToAPInt() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.bitcastToAPInt();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.bitcastToAPInt();
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
}
double convertToDouble() const { return getIEEE().convertToDouble(); }
float convertToFloat() const { return getIEEE().convertToFloat(); }
Expand Down Expand Up @@ -1198,25 +1110,16 @@ class APFloat : public APFloatBase {

unsigned int convertToHexString(char *DST, unsigned int HexDigits,
bool UpperCase, roundingMode RM) const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.convertToHexString(DST, HexDigits, UpperCase, RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertToHexString(DST, HexDigits, UpperCase, RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(
convertToHexString(DST, HexDigits, UpperCase, RM));
}

bool isZero() const { return getCategory() == fcZero; }
bool isInfinity() const { return getCategory() == fcInfinity; }
bool isNaN() const { return getCategory() == fcNaN; }

bool isNegative() const { return getIEEE().isNegative(); }
bool isDenormal() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.isDenormal();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.isDenormal();
llvm_unreachable("Unexpected semantics");
}
bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); }
bool isSignaling() const { return getIEEE().isSignaling(); }

bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
Expand All @@ -1228,53 +1131,24 @@ class APFloat : public APFloatBase {
bool isFiniteNonZero() const { return isFinite() && !isZero(); }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
bool isSmallest() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.isSmallest();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.isSmallest();
llvm_unreachable("Unexpected semantics");
}
bool isLargest() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.isLargest();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.isLargest();
llvm_unreachable("Unexpected semantics");
}
bool isInteger() const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.isInteger();
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.isInteger();
llvm_unreachable("Unexpected semantics");
}
bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }

APFloat &operator=(const APFloat &RHS) = default;
APFloat &operator=(APFloat &&RHS) = default;

void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
unsigned FormatMaxPadding = 3) const {
if (usesLayout<IEEEFloat>(getSemantics())) {
U.IEEE.toString(Str, FormatPrecision, FormatMaxPadding);
return;
}
if (usesLayout<DoubleAPFloat>(getSemantics())) {
U.Double.toString(Str, FormatPrecision, FormatMaxPadding);
return;
}
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(
toString(Str, FormatPrecision, FormatMaxPadding));
}

void print(raw_ostream &) const;
void dump() const;

bool getExactInverse(APFloat *inv) const {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.getExactInverse(inv);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.getExactInverse(inv);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
}

friend hash_code hash_value(const APFloat &Arg);
Expand Down Expand Up @@ -1345,4 +1219,5 @@ inline APFloat maxnum(const APFloat &A, const APFloat &B) {

} // namespace llvm

#undef APFLOAT_DISPATCH_ON_SEMANTICS
#endif // LLVM_ADT_APFLOAT_H
17 changes: 12 additions & 5 deletions llvm/lib/Support/APFloat.cpp
Expand Up @@ -26,6 +26,15 @@
#include <cstring>
#include <limits.h>

#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
do { \
if (usesLayout<IEEEFloat>(getSemantics())) \
return U.IEEE.METHOD_CALL; \
if (usesLayout<DoubleAPFloat>(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
Expand Down Expand Up @@ -4418,11 +4427,7 @@ APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
}

APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
if (usesLayout<IEEEFloat>(getSemantics()))
return U.IEEE.convertFromString(Str, RM);
if (usesLayout<DoubleAPFloat>(getSemantics()))
return U.Double.convertFromString(Str, RM);
llvm_unreachable("Unexpected semantics");
APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
}

hash_code hash_value(const APFloat &Arg) {
Expand Down Expand Up @@ -4512,3 +4517,5 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result,
}

} // End llvm namespace

#undef APFLOAT_DISPATCH_ON_SEMANTICS

0 comments on commit 601ba8c

Please sign in to comment.