diff options
Diffstat (limited to 'include/llvm/ADT')
26 files changed, 1664 insertions, 1202 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 14bcaef6d1656..43a78660bf186 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -6,461 +6,575 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file declares a class to represent arbitrary precision floating -// point values and provide a variety of arithmetic operations on them. -// +/// +/// \file +/// \brief +/// This file declares a class to represent arbitrary precision floating point +/// values and provide a variety of arithmetic operations on them. +/// //===----------------------------------------------------------------------===// -/* A self-contained host- and target-independent arbitrary-precision - floating-point software implementation. It uses bignum integer - arithmetic as provided by static functions in the APInt class. - The library will work with bignum integers whose parts are any - unsigned type at least 16 bits wide, but 64 bits is recommended. +#ifndef LLVM_ADT_APFLOAT_H +#define LLVM_ADT_APFLOAT_H - Written for clarity rather than speed, in particular with a view - to use in the front-end of a cross compiler so that target - arithmetic can be correctly performed on the host. Performance - should nonetheless be reasonable, particularly for its intended - use. It may be useful as a base implementation for a run-time - library during development of a faster target-specific one. +#include "llvm/ADT/APInt.h" - All 5 rounding modes in the IEEE-754R draft are handled correctly - for all implemented operations. Currently implemented operations - are add, subtract, multiply, divide, fused-multiply-add, - conversion-to-float, conversion-to-integer and - conversion-from-integer. New rounding modes (e.g. away from zero) - can be added with three or four lines of code. +namespace llvm { - Four formats are built-in: IEEE single precision, double - precision, quadruple precision, and x87 80-bit extended double - (when operating with full extended precision). Adding a new - format that obeys IEEE semantics only requires adding two lines of - code: a declaration and definition of the format. +struct fltSemantics; +class APSInt; +class StringRef; - All operations return the status of that operation as an exception - bit-mask, so multiple operations can be done consecutively with - their results or-ed together. The returned status can be useful - for compiler diagnostics; e.g., inexact, underflow and overflow - can be easily diagnosed on constant folding, and compiler - optimizers can determine what exceptions would be raised by - folding operations and optimize, or perhaps not optimize, - accordingly. +/// Enum that represents what fraction of the LSB truncated bits of an fp number +/// represent. +/// +/// This essentially combines the roles of guard and sticky bits. +enum lostFraction { // Example of truncated bits: + lfExactlyZero, // 000000 + lfLessThanHalf, // 0xxxxx x's not all zero + lfExactlyHalf, // 100000 + lfMoreThanHalf // 1xxxxx x's not all zero +}; - At present, underflow tininess is detected after rounding; it - should be straight forward to add support for the before-rounding - case too. +/// \brief A self-contained host- and target-independent arbitrary-precision +/// floating-point software implementation. +/// +/// APFloat uses bignum integer arithmetic as provided by static functions in +/// the APInt class. The library will work with bignum integers whose parts are +/// any unsigned type at least 16 bits wide, but 64 bits is recommended. +/// +/// Written for clarity rather than speed, in particular with a view to use in +/// the front-end of a cross compiler so that target arithmetic can be correctly +/// performed on the host. Performance should nonetheless be reasonable, +/// particularly for its intended use. It may be useful as a base +/// implementation for a run-time library during development of a faster +/// target-specific one. +/// +/// All 5 rounding modes in the IEEE-754R draft are handled correctly for all +/// implemented operations. Currently implemented operations are add, subtract, +/// multiply, divide, fused-multiply-add, conversion-to-float, +/// conversion-to-integer and conversion-from-integer. New rounding modes +/// (e.g. away from zero) can be added with three or four lines of code. +/// +/// Four formats are built-in: IEEE single precision, double precision, +/// quadruple precision, and x87 80-bit extended double (when operating with +/// full extended precision). Adding a new format that obeys IEEE semantics +/// only requires adding two lines of code: a declaration and definition of the +/// format. +/// +/// All operations return the status of that operation as an exception bit-mask, +/// so multiple operations can be done consecutively with their results or-ed +/// together. The returned status can be useful for compiler diagnostics; e.g., +/// inexact, underflow and overflow can be easily diagnosed on constant folding, +/// and compiler optimizers can determine what exceptions would be raised by +/// folding operations and optimize, or perhaps not optimize, accordingly. +/// +/// At present, underflow tininess is detected after rounding; it should be +/// straight forward to add support for the before-rounding case too. +/// +/// The library reads hexadecimal floating point numbers as per C99, and +/// correctly rounds if necessary according to the specified rounding mode. +/// Syntax is required to have been validated by the caller. It also converts +/// floating point numbers to hexadecimal text as per the C99 %a and %A +/// conversions. The output precision (or alternatively the natural minimal +/// precision) can be specified; if the requested precision is less than the +/// natural precision the output is correctly rounded for the specified rounding +/// mode. +/// +/// It also reads decimal floating point numbers and correctly rounds according +/// to the specified rounding mode. +/// +/// Conversion to decimal text is not currently implemented. +/// +/// Non-zero finite numbers are represented internally as a sign bit, a 16-bit +/// signed exponent, and the significand as an array of integer parts. After +/// normalization of a number of precision P the exponent is within the range of +/// the format, and if the number is not denormal the P-th bit of the +/// significand is set as an explicit integer bit. For denormals the most +/// significant bit is shifted right so that the exponent is maintained at the +/// format's minimum, so that the smallest denormal has just the least +/// significant bit of the significand set. The sign of zeroes and infinities +/// is significant; the exponent and significand of such numbers is not stored, +/// but has a known implicit (deterministic) value: 0 for the significands, 0 +/// for zero exponent, all 1 bits for infinity exponent. For NaNs the sign and +/// significand are deterministic, although not really meaningful, and preserved +/// in non-conversion operations. The exponent is implicitly all 1 bits. +/// +/// APFloat does not provide any exception handling beyond default exception +/// handling. We represent Signaling NaNs via IEEE-754R 2008 6.2.1 should clause +/// by encoding Signaling NaNs with the first bit of its trailing significand as +/// 0. +/// +/// TODO +/// ==== +/// +/// Some features that may or may not be worth adding: +/// +/// Binary to decimal conversion (hard). +/// +/// Optional ability to detect underflow tininess before rounding. +/// +/// New formats: x87 in single and double precision mode (IEEE apart from +/// extended exponent range) (hard). +/// +/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward. +/// +class APFloat { +public: - The library reads hexadecimal floating point numbers as per C99, - and correctly rounds if necessary according to the specified - rounding mode. Syntax is required to have been validated by the - caller. It also converts floating point numbers to hexadecimal - text as per the C99 %a and %A conversions. The output precision - (or alternatively the natural minimal precision) can be specified; - if the requested precision is less than the natural precision the - output is correctly rounded for the specified rounding mode. + /// A signed type to represent a floating point numbers unbiased exponent. + typedef signed short ExponentType; - It also reads decimal floating point numbers and correctly rounds - according to the specified rounding mode. + /// \name Floating Point Semantics. + /// @{ - Conversion to decimal text is not currently implemented. + static const fltSemantics IEEEhalf; + static const fltSemantics IEEEsingle; + static const fltSemantics IEEEdouble; + static const fltSemantics IEEEquad; + static const fltSemantics PPCDoubleDouble; + static const fltSemantics x87DoubleExtended; - Non-zero finite numbers are represented internally as a sign bit, - a 16-bit signed exponent, and the significand as an array of - integer parts. After normalization of a number of precision P the - exponent is within the range of the format, and if the number is - not denormal the P-th bit of the significand is set as an explicit - integer bit. For denormals the most significant bit is shifted - right so that the exponent is maintained at the format's minimum, - so that the smallest denormal has just the least significant bit - of the significand set. The sign of zeroes and infinities is - significant; the exponent and significand of such numbers is not - stored, but has a known implicit (deterministic) value: 0 for the - significands, 0 for zero exponent, all 1 bits for infinity - exponent. For NaNs the sign and significand are deterministic, - although not really meaningful, and preserved in non-conversion - operations. The exponent is implicitly all 1 bits. + /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with + /// anything real. + static const fltSemantics Bogus; - TODO - ==== + /// @} - Some features that may or may not be worth adding: + static unsigned int semanticsPrecision(const fltSemantics &); - Binary to decimal conversion (hard). + /// IEEE-754R 5.11: Floating Point Comparison Relations. + enum cmpResult { + cmpLessThan, + cmpEqual, + cmpGreaterThan, + cmpUnordered + }; - Optional ability to detect underflow tininess before rounding. + /// IEEE-754R 4.3: Rounding-direction attributes. + enum roundingMode { + rmNearestTiesToEven, + rmTowardPositive, + rmTowardNegative, + rmTowardZero, + rmNearestTiesToAway + }; - New formats: x87 in single and double precision mode (IEEE apart - from extended exponent range) (hard). + /// IEEE-754R 7: Default exception handling. + /// + /// opUnderflow or opOverflow are always returned or-ed with opInexact. + enum opStatus { + opOK = 0x00, + opInvalidOp = 0x01, + opDivByZero = 0x02, + opOverflow = 0x04, + opUnderflow = 0x08, + opInexact = 0x10 + }; - New operations: sqrt, IEEE remainder, C90 fmod, nextafter, - nexttoward. -*/ + /// Category of internally-represented number. + enum fltCategory { + fcInfinity, + fcNaN, + fcNormal, + fcZero + }; -#ifndef LLVM_ADT_APFLOAT_H -#define LLVM_ADT_APFLOAT_H + /// Convenience enum used to construct an uninitialized APFloat. + enum uninitializedTag { + uninitialized + }; -// APInt contains static functions implementing bignum arithmetic. -#include "llvm/ADT/APInt.h" + /// \name Constructors + /// @{ -namespace llvm { + APFloat(const fltSemantics &); // Default construct to 0.0 + APFloat(const fltSemantics &, StringRef); + APFloat(const fltSemantics &, integerPart); + APFloat(const fltSemantics &, uninitializedTag); + APFloat(const fltSemantics &, const APInt &); + explicit APFloat(double d); + explicit APFloat(float f); + APFloat(const APFloat &); + ~APFloat(); - /* Exponents are stored as signed numbers. */ - typedef signed short exponent_t; + /// @} - struct fltSemantics; - class APSInt; - class StringRef; + /// \brief Returns whether this instance allocated memory. + bool needsCleanup() const { return partCount() > 1; } - /* When bits of a floating point number are truncated, this enum is - used to indicate what fraction of the LSB those bits represented. - It essentially combines the roles of guard and sticky bits. */ - enum lostFraction { // Example of truncated bits: - lfExactlyZero, // 000000 - lfLessThanHalf, // 0xxxxx x's not all zero - lfExactlyHalf, // 100000 - lfMoreThanHalf // 1xxxxx x's not all zero - }; + /// \name Convenience "constructors" + /// @{ - class APFloat { - public: + /// Factory for Positive and Negative Zero. + /// + /// \param Negative True iff the number should be negative. + static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { + APFloat Val(Sem, uninitialized); + Val.makeZero(Negative); + return Val; + } - /* We support the following floating point semantics. */ - static const fltSemantics IEEEhalf; - static const fltSemantics IEEEsingle; - static const fltSemantics IEEEdouble; - static const fltSemantics IEEEquad; - static const fltSemantics PPCDoubleDouble; - static const fltSemantics x87DoubleExtended; - /* And this pseudo, used to construct APFloats that cannot - conflict with anything real. */ - static const fltSemantics Bogus; + /// Factory for Positive and Negative Infinity. + /// + /// \param Negative True iff the number should be negative. + static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { + APFloat Val(Sem, uninitialized); + Val.makeInf(Negative); + return Val; + } - static unsigned int semanticsPrecision(const fltSemantics &); + /// Factory for QNaN values. + /// + /// \param Negative - True iff the NaN generated should be negative. + /// \param type - The unspecified fill bits for creating the NaN, 0 by + /// default. The value is truncated as necessary. + static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, + unsigned type = 0) { + if (type) { + APInt fill(64, type); + return getQNaN(Sem, Negative, &fill); + } else { + return getQNaN(Sem, Negative, 0); + } + } - /* Floating point numbers have a four-state comparison relation. */ - enum cmpResult { - cmpLessThan, - cmpEqual, - cmpGreaterThan, - cmpUnordered - }; + /// Factory for QNaN values. + static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, false, Negative, payload); + } - /* IEEE-754R gives five rounding modes. */ - enum roundingMode { - rmNearestTiesToEven, - rmTowardPositive, - rmTowardNegative, - rmTowardZero, - rmNearestTiesToAway - }; + /// Factory for SNaN values. + static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, true, Negative, payload); + } - // Operation status. opUnderflow or opOverflow are always returned - // or-ed with opInexact. - enum opStatus { - opOK = 0x00, - opInvalidOp = 0x01, - opDivByZero = 0x02, - opOverflow = 0x04, - opUnderflow = 0x08, - opInexact = 0x10 - }; + /// Returns the largest finite number in the given semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getLargest(const fltSemantics &Sem, bool Negative = false); - // Category of internally-represented number. - enum fltCategory { - fcInfinity, - fcNaN, - fcNormal, - fcZero - }; + /// Returns the smallest (by magnitude) finite number in the given semantics. + /// Might be denormalized, which implies a relative loss of precision. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false); - enum uninitializedTag { - uninitialized - }; + /// Returns the smallest (by magnitude) normalized finite number in the given + /// semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallestNormalized(const fltSemantics &Sem, + bool Negative = false); - // Constructors. - APFloat(const fltSemantics &); // Default construct to 0.0 - APFloat(const fltSemantics &, StringRef); - APFloat(const fltSemantics &, integerPart); - APFloat(const fltSemantics &, fltCategory, bool negative); - APFloat(const fltSemantics &, uninitializedTag); - APFloat(const fltSemantics &, const APInt &); - explicit APFloat(double d); - explicit APFloat(float f); - APFloat(const APFloat &); - ~APFloat(); + /// Returns a float which is bitcasted from an all one value int. + /// + /// \param BitWidth - Select float type + /// \param isIEEE - If 128 bit number, select between PPC and IEEE + static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); - // Convenience "constructors" - static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { - return APFloat(Sem, fcZero, Negative); - } - static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { - return APFloat(Sem, fcInfinity, Negative); - } + /// @} - /// getNaN - Factory for QNaN values. - /// - /// \param Negative - True iff the NaN generated should be negative. - /// \param type - The unspecified fill bits for creating the NaN, 0 by - /// default. The value is truncated as necessary. - static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, - unsigned type = 0) { - if (type) { - APInt fill(64, type); - return getQNaN(Sem, Negative, &fill); - } else { - return getQNaN(Sem, Negative, 0); - } - } + /// Used to insert APFloat objects, or objects that contain APFloat objects, + /// into FoldingSets. + void Profile(FoldingSetNodeID &NID) const; - /// getQNan - Factory for QNaN values. - static APFloat getQNaN(const fltSemantics &Sem, - bool Negative = false, - const APInt *payload = 0) { - return makeNaN(Sem, false, Negative, payload); - } + /// \brief Used by the Bitcode serializer to emit APInts to Bitcode. + void Emit(Serializer &S) const; - /// getSNan - Factory for SNaN values. - static APFloat getSNaN(const fltSemantics &Sem, - bool Negative = false, - const APInt *payload = 0) { - return makeNaN(Sem, true, Negative, payload); - } + /// \brief Used by the Bitcode deserializer to deserialize APInts. + static APFloat ReadVal(Deserializer &D); - /// getLargest - Returns the largest finite number in the given - /// semantics. - /// - /// \param Negative - True iff the number should be negative - static APFloat getLargest(const fltSemantics &Sem, bool Negative = false); + /// \name Arithmetic + /// @{ - /// getSmallest - Returns the smallest (by magnitude) finite number - /// in the given semantics. Might be denormalized, which implies a - /// relative loss of precision. - /// - /// \param Negative - True iff the number should be negative - static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false); + opStatus add(const APFloat &, roundingMode); + opStatus subtract(const APFloat &, roundingMode); + opStatus multiply(const APFloat &, roundingMode); + opStatus divide(const APFloat &, roundingMode); + /// IEEE remainder. + opStatus remainder(const APFloat &); + /// C fmod, or llvm frem. + opStatus mod(const APFloat &, roundingMode); + opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); + opStatus roundToIntegral(roundingMode); + /// IEEE-754R 5.3.1: nextUp/nextDown. + opStatus next(bool nextDown); - /// getSmallestNormalized - Returns the smallest (by magnitude) - /// normalized finite number in the given semantics. - /// - /// \param Negative - True iff the number should be negative - static APFloat getSmallestNormalized(const fltSemantics &Sem, - bool Negative = false); + /// @} - /// getAllOnesValue - Returns a float which is bitcasted from - /// an all one value int. - /// - /// \param BitWidth - Select float type - /// \param isIEEE - If 128 bit number, select between PPC and IEEE - static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); + /// \name Sign operations. + /// @{ - /// Profile - Used to insert APFloat objects, or objects that contain - /// APFloat objects, into FoldingSets. - void Profile(FoldingSetNodeID& NID) const; + void changeSign(); + void clearSign(); + void copySign(const APFloat &); - /// @brief Used by the Bitcode serializer to emit APInts to Bitcode. - void Emit(Serializer& S) const; + /// @} - /// @brief Used by the Bitcode deserializer to deserialize APInts. - static APFloat ReadVal(Deserializer& D); + /// \name Conversions + /// @{ - /* Arithmetic. */ - opStatus add(const APFloat &, roundingMode); - opStatus subtract(const APFloat &, roundingMode); - opStatus multiply(const APFloat &, roundingMode); - opStatus divide(const APFloat &, roundingMode); - /* IEEE remainder. */ - opStatus remainder(const APFloat &); - /* C fmod, or llvm frem. */ - opStatus mod(const APFloat &, roundingMode); - opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); - opStatus roundToIntegral(roundingMode); + opStatus convert(const fltSemantics &, roundingMode, bool *); + opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode, + bool *) const; + opStatus convertToInteger(APSInt &, roundingMode, bool *) const; + opStatus convertFromAPInt(const APInt &, bool, roundingMode); + opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int, + bool, roundingMode); + opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int, + bool, roundingMode); + opStatus convertFromString(StringRef, roundingMode); + APInt bitcastToAPInt() const; + double convertToDouble() const; + float convertToFloat() const; - /* Sign operations. */ - void changeSign(); - void clearSign(); - void copySign(const APFloat &); + /// @} - /* Conversions. */ - opStatus convert(const fltSemantics &, roundingMode, bool *); - opStatus convertToInteger(integerPart *, unsigned int, bool, - roundingMode, bool *) const; - opStatus convertToInteger(APSInt&, roundingMode, bool *) const; - opStatus convertFromAPInt(const APInt &, - bool, roundingMode); - opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int, - bool, roundingMode); - opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int, - bool, roundingMode); - opStatus convertFromString(StringRef, roundingMode); - APInt bitcastToAPInt() const; - double convertToDouble() const; - float convertToFloat() const; + /// The definition of equality is not straightforward for floating point, so + /// we won't use operator==. Use one of the following, or write whatever it + /// is you really mean. + bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION; - /* The definition of equality is not straightforward for floating point, - so we won't use operator==. Use one of the following, or write - whatever it is you really mean. */ - bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION; + /// IEEE comparison with another floating point number (NaNs compare + /// unordered, 0==-0). + cmpResult compare(const APFloat &) const; - /* IEEE comparison with another floating point number (NaNs - compare unordered, 0==-0). */ - cmpResult compare(const APFloat &) const; + /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0). + bool bitwiseIsEqual(const APFloat &) const; - /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ - bool bitwiseIsEqual(const APFloat &) const; + /// Write out a hexadecimal representation of the floating point value to DST, + /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d. + /// Return the number of characters written, excluding the terminating NUL. + unsigned int convertToHexString(char *dst, unsigned int hexDigits, + bool upperCase, roundingMode) const; - /* Write out a hexadecimal representation of the floating point - value to DST, which must be of sufficient size, in the C99 form - [-]0xh.hhhhp[+-]d. Return the number of characters written, - excluding the terminating NUL. */ - unsigned int convertToHexString(char *dst, unsigned int hexDigits, - bool upperCase, roundingMode) const; + /// \name IEEE-754R 5.7.2 General operations. + /// @{ - /* Simple queries. */ - fltCategory getCategory() const { return category; } - const fltSemantics &getSemantics() const { return *semantics; } - bool isZero() const { return category == fcZero; } - bool isNonZero() const { return category != fcZero; } - bool isNormal() const { return category == fcNormal; } - bool isNaN() const { return category == fcNaN; } - bool isInfinity() const { return category == fcInfinity; } - bool isNegative() const { return sign; } - bool isPosZero() const { return isZero() && !isNegative(); } - bool isNegZero() const { return isZero() && isNegative(); } - bool isDenormal() const; + /// IEEE-754R isSignMinus: Returns true if and only if the current value is + /// negative. + /// + /// This applies to zeros and NaNs as well. + bool isNegative() const { return sign; } - APFloat& operator=(const APFloat &); + /// IEEE-754R isNormal: Returns true if and only if the current value is normal. + /// + /// This implies that the current value of the float is not zero, subnormal, + /// infinite, or NaN following the definition of normality from IEEE-754R. + bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } - /// \brief Overload to compute a hash code for an APFloat value. - /// - /// Note that the use of hash codes for floating point values is in general - /// frought with peril. Equality is hard to define for these values. For - /// example, should negative and positive zero hash to different codes? Are - /// they equal or not? This hash value implementation specifically - /// emphasizes producing different codes for different inputs in order to - /// be used in canonicalization and memoization. As such, equality is - /// bitwiseIsEqual, and 0 != -0. - friend hash_code hash_value(const APFloat &Arg); + /// Returns true if and only if the current value is zero, subnormal, or + /// normal. + /// + /// This means that the value is not infinite or NaN. + bool isFinite() const { return !isNaN() && !isInfinity(); } - /// Converts this value into a decimal string. - /// - /// \param FormatPrecision The maximum number of digits of - /// precision to output. If there are fewer digits available, - /// zero padding will not be used unless the value is - /// integral and small enough to be expressed in - /// FormatPrecision digits. 0 means to use the natural - /// precision of the number. - /// \param FormatMaxPadding The maximum number of zeros to - /// consider inserting before falling back to scientific - /// notation. 0 means to always use scientific notation. - /// - /// Number Precision MaxPadding Result - /// ------ --------- ---------- ------ - /// 1.01E+4 5 2 10100 - /// 1.01E+4 4 2 1.01E+4 - /// 1.01E+4 5 1 1.01E+4 - /// 1.01E-2 5 2 0.0101 - /// 1.01E-2 4 2 0.0101 - /// 1.01E-2 4 1 1.01E-2 - void toString(SmallVectorImpl<char> &Str, - unsigned FormatPrecision = 0, - unsigned FormatMaxPadding = 3) const; + /// Returns true if and only if the float is plus or minus zero. + bool isZero() const { return category == fcZero; } - /// getExactInverse - If this value has an exact multiplicative inverse, - /// store it in inv and return true. - bool getExactInverse(APFloat *inv) const; + /// IEEE-754R isSubnormal(): Returns true if and only if the float is a + /// denormal. + bool isDenormal() const; - private: + /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity. + bool isInfinity() const { return category == fcInfinity; } - /* Trivial queries. */ - integerPart *significandParts(); - const integerPart *significandParts() const; - unsigned int partCount() const; + /// Returns true if and only if the float is a quiet or signaling NaN. + bool isNaN() const { return category == fcNaN; } - /* Significand operations. */ - integerPart addSignificand(const APFloat &); - integerPart subtractSignificand(const APFloat &, integerPart); - lostFraction addOrSubtractSignificand(const APFloat &, bool subtract); - lostFraction multiplySignificand(const APFloat &, const APFloat *); - lostFraction divideSignificand(const APFloat &); - void incrementSignificand(); - void initialize(const fltSemantics *); - void shiftSignificandLeft(unsigned int); - lostFraction shiftSignificandRight(unsigned int); - unsigned int significandLSB() const; - unsigned int significandMSB() const; - void zeroSignificand(); + /// Returns true if and only if the float is a signaling NaN. + bool isSignaling() const; - /* Arithmetic on special values. */ - opStatus addOrSubtractSpecials(const APFloat &, bool subtract); - opStatus divideSpecials(const APFloat &); - opStatus multiplySpecials(const APFloat &); - opStatus modSpecials(const APFloat &); + /// @} - /* Miscellany. */ - static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, - const APInt *fill); - void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0); - opStatus normalize(roundingMode, lostFraction); - opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); - cmpResult compareAbsoluteValue(const APFloat &) const; - opStatus handleOverflow(roundingMode); - bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; - opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool, - roundingMode, bool *) const; - opStatus convertFromUnsignedParts(const integerPart *, unsigned int, - roundingMode); - opStatus convertFromHexadecimalString(StringRef, roundingMode); - opStatus convertFromDecimalString(StringRef, roundingMode); - char *convertNormalToHexString(char *, unsigned int, bool, - roundingMode) const; - opStatus roundSignificandWithExponent(const integerPart *, unsigned int, - int, roundingMode); + /// \name Simple Queries + /// @{ - APInt convertHalfAPFloatToAPInt() const; - APInt convertFloatAPFloatToAPInt() const; - APInt convertDoubleAPFloatToAPInt() const; - APInt convertQuadrupleAPFloatToAPInt() const; - APInt convertF80LongDoubleAPFloatToAPInt() const; - APInt convertPPCDoubleDoubleAPFloatToAPInt() const; - void initFromAPInt(const fltSemantics *Sem, const APInt& api); - void initFromHalfAPInt(const APInt& api); - void initFromFloatAPInt(const APInt& api); - void initFromDoubleAPInt(const APInt& api); - void initFromQuadrupleAPInt(const APInt &api); - void initFromF80LongDoubleAPInt(const APInt& api); - void initFromPPCDoubleDoubleAPInt(const APInt& api); + fltCategory getCategory() const { return category; } + const fltSemantics &getSemantics() const { return *semantics; } + bool isNonZero() const { return category != fcZero; } + bool isFiniteNonZero() const { return isFinite() && !isZero(); } + bool isPosZero() const { return isZero() && !isNegative(); } + bool isNegZero() const { return isZero() && isNegative(); } - void assign(const APFloat &); - void copySignificand(const APFloat &); - void freeSignificand(); + /// Returns true if and only if the number has the smallest possible non-zero + /// magnitude in the current semantics. + bool isSmallest() const; - /* What kind of semantics does this value obey? */ - const fltSemantics *semantics; + /// Returns true if and only if the number has the largest possible finite + /// magnitude in the current semantics. + bool isLargest() const; - /* Significand - the fraction with an explicit integer bit. Must be - at least one bit wider than the target precision. */ - union Significand - { - integerPart part; - integerPart *parts; - } significand; + /// @} - /* The exponent - a signed number. */ - exponent_t exponent; + APFloat &operator=(const APFloat &); - /* What kind of floating point number this is. */ - /* Only 2 bits are required, but VisualStudio incorrectly sign extends - it. Using the extra bit keeps it from failing under VisualStudio */ - fltCategory category: 3; + /// \brief Overload to compute a hash code for an APFloat value. + /// + /// Note that the use of hash codes for floating point values is in general + /// frought with peril. Equality is hard to define for these values. For + /// example, should negative and positive zero hash to different codes? Are + /// they equal or not? This hash value implementation specifically + /// emphasizes producing different codes for different inputs in order to + /// be used in canonicalization and memoization. As such, equality is + /// bitwiseIsEqual, and 0 != -0. + friend hash_code hash_value(const APFloat &Arg); - /* The sign bit of this number. */ - unsigned int sign: 1; - }; + /// Converts this value into a decimal string. + /// + /// \param FormatPrecision The maximum number of digits of + /// precision to output. If there are fewer digits available, + /// zero padding will not be used unless the value is + /// integral and small enough to be expressed in + /// FormatPrecision digits. 0 means to use the natural + /// precision of the number. + /// \param FormatMaxPadding The maximum number of zeros to + /// consider inserting before falling back to scientific + /// notation. 0 means to always use scientific notation. + /// + /// Number Precision MaxPadding Result + /// ------ --------- ---------- ------ + /// 1.01E+4 5 2 10100 + /// 1.01E+4 4 2 1.01E+4 + /// 1.01E+4 5 1 1.01E+4 + /// 1.01E-2 5 2 0.0101 + /// 1.01E-2 4 2 0.0101 + /// 1.01E-2 4 1 1.01E-2 + void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0, + unsigned FormatMaxPadding = 3) const; + + /// If this value has an exact multiplicative inverse, store it in inv and + /// return true. + bool getExactInverse(APFloat *inv) const; + +private: + + /// \name Simple Queries + /// @{ + + integerPart *significandParts(); + const integerPart *significandParts() const; + unsigned int partCount() const; + + /// @} + + /// \name Significand operations. + /// @{ + + integerPart addSignificand(const APFloat &); + integerPart subtractSignificand(const APFloat &, integerPart); + lostFraction addOrSubtractSignificand(const APFloat &, bool subtract); + lostFraction multiplySignificand(const APFloat &, const APFloat *); + lostFraction divideSignificand(const APFloat &); + void incrementSignificand(); + void initialize(const fltSemantics *); + void shiftSignificandLeft(unsigned int); + lostFraction shiftSignificandRight(unsigned int); + unsigned int significandLSB() const; + unsigned int significandMSB() const; + void zeroSignificand(); + /// Return true if the significand excluding the integral bit is all ones. + bool isSignificandAllOnes() const; + /// Return true if the significand excluding the integral bit is all zeros. + bool isSignificandAllZeros() const; + + /// @} + + /// \name Arithmetic on special values. + /// @{ + + opStatus addOrSubtractSpecials(const APFloat &, bool subtract); + opStatus divideSpecials(const APFloat &); + opStatus multiplySpecials(const APFloat &); + opStatus modSpecials(const APFloat &); + + /// @} + + /// \name Special value setters. + /// @{ + + void makeLargest(bool Neg = false); + void makeSmallest(bool Neg = false); + void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0); + static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill); + void makeInf(bool Neg = false); + void makeZero(bool Neg = false); + + /// @} + + /// \name Miscellany + /// @{ + + bool convertFromStringSpecials(StringRef str); + opStatus normalize(roundingMode, lostFraction); + opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); + cmpResult compareAbsoluteValue(const APFloat &) const; + opStatus handleOverflow(roundingMode); + bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; + opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool, + roundingMode, bool *) const; + opStatus convertFromUnsignedParts(const integerPart *, unsigned int, + roundingMode); + opStatus convertFromHexadecimalString(StringRef, roundingMode); + opStatus convertFromDecimalString(StringRef, roundingMode); + char *convertNormalToHexString(char *, unsigned int, bool, + roundingMode) const; + opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int, + roundingMode); + + /// @} + + APInt convertHalfAPFloatToAPInt() const; + APInt convertFloatAPFloatToAPInt() const; + APInt convertDoubleAPFloatToAPInt() const; + APInt convertQuadrupleAPFloatToAPInt() const; + APInt convertF80LongDoubleAPFloatToAPInt() const; + APInt convertPPCDoubleDoubleAPFloatToAPInt() const; + void initFromAPInt(const fltSemantics *Sem, const APInt &api); + void initFromHalfAPInt(const APInt &api); + void initFromFloatAPInt(const APInt &api); + void initFromDoubleAPInt(const APInt &api); + void initFromQuadrupleAPInt(const APInt &api); + void initFromF80LongDoubleAPInt(const APInt &api); + void initFromPPCDoubleDoubleAPInt(const APInt &api); + + void assign(const APFloat &); + void copySignificand(const APFloat &); + void freeSignificand(); + + /// The semantics that this value obeys. + const fltSemantics *semantics; + + /// A binary fraction with an explicit integer bit. + /// + /// The significand must be at least one bit wider than the target precision. + union Significand { + integerPart part; + integerPart *parts; + } significand; + + /// The signed unbiased exponent of the value. + ExponentType exponent; + + /// What kind of floating point number this is. + /// + /// Only 2 bits are required, but VisualStudio incorrectly sign extends it. + /// Using the extra bit keeps it from failing under VisualStudio. + fltCategory category : 3; + + /// Sign bit of the number. + unsigned int sign : 1; +}; - // See friend declaration above. This additional declaration is required in - // order to compile LLVM with IBM xlC compiler. - hash_code hash_value(const APFloat &Arg); -} /* namespace llvm */ +/// See friend declaration above. +/// +/// This additional declaration is required in order to compile LLVM with IBM +/// xlC compiler. +hash_code hash_value(const APFloat &Arg); +} // namespace llvm -#endif /* LLVM_ADT_APFLOAT_H */ +#endif // LLVM_ADT_APFLOAT_H diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 3d8b72d9aaf4d..d494ad25351bd 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -6,10 +6,11 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements a class to represent arbitrary precision integral -// constant values and operations on them. -// +/// +/// \file +/// \brief This file implements a class to represent arbitrary precision +/// integral constant values and operations on them. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_APINT_H @@ -24,30 +25,30 @@ #include <string> namespace llvm { - class Deserializer; - class FoldingSetNodeID; - class Serializer; - class StringRef; - class hash_code; - class raw_ostream; +class Deserializer; +class FoldingSetNodeID; +class Serializer; +class StringRef; +class hash_code; +class raw_ostream; - template<typename T> - class SmallVectorImpl; +template <typename T> class SmallVectorImpl; - // An unsigned host type used as a single part of a multi-part - // bignum. - typedef uint64_t integerPart; +// An unsigned host type used as a single part of a multi-part +// bignum. +typedef uint64_t integerPart; - const unsigned int host_char_bit = 8; - const unsigned int integerPartWidth = host_char_bit * - static_cast<unsigned int>(sizeof(integerPart)); +const unsigned int host_char_bit = 8; +const unsigned int integerPartWidth = + host_char_bit * static_cast<unsigned int>(sizeof(integerPart)); //===----------------------------------------------------------------------===// // APInt Class //===----------------------------------------------------------------------===// -/// APInt - This class represents arbitrary precision constant integral values. -/// It is a functional replacement for common case unsigned integer type like +/// \brief Class for arbitrary precision integers. +/// +/// APInt is a functional replacement for common case unsigned integer type like /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width /// integer sizes and large integer value types such as 3-bits, 15-bits, or more /// than 64-bits of precision. APInt provides a variety of arithmetic operators @@ -71,65 +72,68 @@ namespace llvm { /// * In general, the class tries to follow the style of computation that LLVM /// uses in its IR. This simplifies its use for LLVM. /// -/// @brief Class for arbitrary precision integers. class APInt { - unsigned BitWidth; ///< The number of bits in this APInt. + unsigned BitWidth; ///< The number of bits in this APInt. /// This union is used to store the integer value. When the /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. union { - uint64_t VAL; ///< Used to store the <= 64 bits integer value. - uint64_t *pVal; ///< Used to store the >64 bits integer value. + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t *pVal; ///< Used to store the >64 bits integer value. }; /// This enum is used to hold the constants we needed for APInt. enum { /// Bits in a word - APINT_BITS_PER_WORD = static_cast<unsigned int>(sizeof(uint64_t)) * - CHAR_BIT, + APINT_BITS_PER_WORD = + static_cast<unsigned int>(sizeof(uint64_t)) * CHAR_BIT, /// Byte size of a word APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t)) }; + /// \brief Fast internal constructor + /// /// This constructor is used only internally for speed of construction of /// temporaries. It is unsafe for general use so it is not public. - /// @brief Fast internal constructor - APInt(uint64_t* val, unsigned bits) : BitWidth(bits), pVal(val) { } + APInt(uint64_t *val, unsigned bits) : BitWidth(bits), pVal(val) {} - /// @returns true if the number of bits <= 64, false otherwise. - /// @brief Determine if this APInt just has one word to store value. - bool isSingleWord() const { - return BitWidth <= APINT_BITS_PER_WORD; - } + /// \brief Determine if this APInt just has one word to store value. + /// + /// \returns true if the number of bits <= 64, false otherwise. + bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; } - /// @returns the word position for the specified bit position. - /// @brief Determine which word a bit is in. + /// \brief Determine which word a bit is in. + /// + /// \returns the word position for the specified bit position. static unsigned whichWord(unsigned bitPosition) { return bitPosition / APINT_BITS_PER_WORD; } - /// @returns the bit position in a word for the specified bit position + /// \brief Determine which bit in a word a bit is in. + /// + /// \returns the bit position in a word for the specified bit position /// in the APInt. - /// @brief Determine which bit in a word a bit is in. static unsigned whichBit(unsigned bitPosition) { return bitPosition % APINT_BITS_PER_WORD; } + /// \brief Get a single bit mask. + /// + /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set /// This method generates and returns a uint64_t (word) mask for a single /// bit at a specific bit position. This is used to mask the bit in the /// corresponding word. - /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set - /// @brief Get a single bit mask. static uint64_t maskBit(unsigned bitPosition) { return 1ULL << whichBit(bitPosition); } + /// \brief Clear unused high order bits + /// /// This method is used internally to clear the to "N" bits in the high order /// word that are not used by the APInt. This is needed after the most /// significant word is assigned a value to ensure that those bits are /// zero'd out. - /// @brief Clear unused high order bits - APInt& clearUnusedBits() { + APInt &clearUnusedBits() { // Compute how many bits are used in the final word unsigned wordBits = BitWidth % APINT_BITS_PER_WORD; if (wordBits == 0) @@ -147,12 +151,15 @@ class APInt { return *this; } - /// @returns the corresponding word for the specified bit position. - /// @brief Get the word corresponding to a bit position + /// \brief Get the word corresponding to a bit position + /// \returns the corresponding word for the specified bit position. uint64_t getWord(unsigned bitPosition) const { return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } + /// \brief Convert a char array into an APInt + /// + /// \param radix 2, 8, 10, 16, or 36 /// Converts a string into a number. The string must be non-empty /// and well-formed as a number of the given base. The bit-width /// must be sufficient to hold the result. @@ -162,19 +169,16 @@ class APInt { /// StringRef::getAsInteger is superficially similar but (1) does /// not assume that the string is well-formed and (2) grows the /// result to hold the input. - /// - /// @param radix 2, 8, 10, 16, or 36 - /// @brief Convert a char array into an APInt void fromString(unsigned numBits, StringRef str, uint8_t radix); + /// \brief An internal division function for dividing APInts. + /// /// This is used by the toString method to divide by the radix. It simply /// provides a more convenient form of divide for internal use since KnuthDiv /// has specific constraints on its inputs. If those constraints are not met /// then it provides a simpler form of divide. - /// @brief An internal division function for dividing APInts. - static void divide(const APInt LHS, unsigned lhsWords, - const APInt &RHS, unsigned rhsWords, - APInt *Quotient, APInt *Remainder); + static void divide(const APInt LHS, unsigned lhsWords, const APInt &RHS, + unsigned rhsWords, APInt *Quotient, APInt *Remainder); /// out-of-line slow case for inline constructor void initSlowCase(unsigned numBits, uint64_t val, bool isSigned); @@ -183,25 +187,25 @@ class APInt { void initFromArray(ArrayRef<uint64_t> array); /// out-of-line slow case for inline copy constructor - void initSlowCase(const APInt& that); + void initSlowCase(const APInt &that); /// out-of-line slow case for shl APInt shlSlowCase(unsigned shiftAmt) const; /// out-of-line slow case for operator& - APInt AndSlowCase(const APInt& RHS) const; + APInt AndSlowCase(const APInt &RHS) const; /// out-of-line slow case for operator| - APInt OrSlowCase(const APInt& RHS) const; + APInt OrSlowCase(const APInt &RHS) const; /// out-of-line slow case for operator^ - APInt XorSlowCase(const APInt& RHS) const; + APInt XorSlowCase(const APInt &RHS) const; /// out-of-line slow case for operator= - APInt& AssignSlowCase(const APInt& RHS); + APInt &AssignSlowCase(const APInt &RHS); /// out-of-line slow case for operator== - bool EqualSlowCase(const APInt& RHS) const; + bool EqualSlowCase(const APInt &RHS) const; /// out-of-line slow case for operator== bool EqualSlowCase(uint64_t Val) const; @@ -216,18 +220,21 @@ class APInt { unsigned countPopulationSlowCase() const; public: - /// @name Constructors + /// \name Constructors /// @{ + + /// \brief Create a new APInt of numBits width, initialized as val. + /// /// If isSigned is true then val is treated as if it were a signed value /// (i.e. as an int64_t) and the appropriate sign extension to the bit width /// will be done. Otherwise, no sign extension occurs (high order bits beyond /// the range of val are zero filled). - /// @param numBits the bit width of the constructed APInt - /// @param val the initial value of the APInt - /// @param isSigned how to treat signedness of val - /// @brief Create a new APInt of numBits width, initialized as val. + /// + /// \param numBits the bit width of the constructed APInt + /// \param val the initial value of the APInt + /// \param isSigned how to treat signedness of val APInt(unsigned numBits, uint64_t val, bool isSigned = false) - : BitWidth(numBits), VAL(0) { + : BitWidth(numBits), VAL(0) { assert(BitWidth && "bitwidth too small"); if (isSingleWord()) VAL = val; @@ -236,12 +243,15 @@ public: clearUnusedBits(); } + /// \brief Construct an APInt of numBits width, initialized as bigVal[]. + /// /// Note that bigVal.size() can be smaller or larger than the corresponding /// bit width but any extraneous bits will be dropped. - /// @param numBits the bit width of the constructed APInt - /// @param bigVal a sequence of words to form the initial value of the APInt - /// @brief Construct an APInt of numBits width, initialized as bigVal[]. + /// + /// \param numBits the bit width of the constructed APInt + /// \param bigVal a sequence of words to form the initial value of the APInt APInt(unsigned numBits, ArrayRef<uint64_t> bigVal); + /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but /// deprecated because this constructor is prone to ambiguity with the /// APInt(unsigned, uint64_t, bool) constructor. @@ -251,22 +261,22 @@ public: /// constructor. APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]); + /// \brief Construct an APInt from a string representation. + /// /// This constructor interprets the string \p str in the given radix. The /// interpretation stops when the first character that is not suitable for the /// radix is encountered, or the end of the string. Acceptable radix values - /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the + /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the /// string to require more bits than numBits. /// - /// @param numBits the bit width of the constructed APInt - /// @param str the string to be interpreted - /// @param radix the radix to use for the conversion - /// @brief Construct an APInt from a string representation. + /// \param numBits the bit width of the constructed APInt + /// \param str the string to be interpreted + /// \param radix the radix to use for the conversion APInt(unsigned numBits, StringRef str, uint8_t radix); /// Simply makes *this a copy of that. /// @brief Copy Constructor. - APInt(const APInt& that) - : BitWidth(that.BitWidth), VAL(0) { + APInt(const APInt &that) : BitWidth(that.BitWidth), VAL(0) { assert(BitWidth && "bitwidth too small"); if (isSingleWord()) VAL = that.VAL; @@ -275,207 +285,228 @@ public: } #if LLVM_HAS_RVALUE_REFERENCES - /// @brief Move Constructor. - APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) { + /// \brief Move Constructor. + APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) { that.BitWidth = 0; } #endif - /// @brief Destructor. + /// \brief Destructor. ~APInt() { - if (!isSingleWord()) - delete [] pVal; + if (needsCleanup()) + delete[] pVal; } - /// Default constructor that creates an uninitialized APInt. This is useful - /// for object deserialization (pair this with the static method Read). + /// \brief Default constructor that creates an uninitialized APInt. + /// + /// This is useful for object deserialization (pair this with the static + /// method Read). explicit APInt() : BitWidth(1) {} - /// Profile - Used to insert APInt objects, or objects that contain APInt - /// objects, into FoldingSets. - void Profile(FoldingSetNodeID& id) const; + /// \brief Returns whether this instance allocated memory. + bool needsCleanup() const { return !isSingleWord(); } + + /// Used to insert APInt objects, or objects that contain APInt objects, into + /// FoldingSets. + void Profile(FoldingSetNodeID &id) const; /// @} - /// @name Value Tests + /// \name Value Tests /// @{ + + /// \brief Determine sign of this APInt. + /// /// This tests the high bit of this APInt to determine if it is set. - /// @returns true if this APInt is negative, false otherwise - /// @brief Determine sign of this APInt. - bool isNegative() const { - return (*this)[BitWidth - 1]; - } + /// + /// \returns true if this APInt is negative, false otherwise + bool isNegative() const { return (*this)[BitWidth - 1]; } + /// \brief Determine if this APInt Value is non-negative (>= 0) + /// /// This tests the high bit of the APInt to determine if it is unset. - /// @brief Determine if this APInt Value is non-negative (>= 0) - bool isNonNegative() const { - return !isNegative(); - } + bool isNonNegative() const { return !isNegative(); } + /// \brief Determine if this APInt Value is positive. + /// /// This tests if the value of this APInt is positive (> 0). Note /// that 0 is not a positive value. - /// @returns true if this APInt is positive. - /// @brief Determine if this APInt Value is positive. - bool isStrictlyPositive() const { - return isNonNegative() && !!*this; - } + /// + /// \returns true if this APInt is positive. + bool isStrictlyPositive() const { return isNonNegative() && !!*this; } + /// \brief Determine if all bits are set + /// /// This checks to see if the value has all bits of the APInt are set or not. - /// @brief Determine if all bits are set bool isAllOnesValue() const { - return countPopulation() == BitWidth; + if (isSingleWord()) + return VAL == ~integerPart(0) >> (APINT_BITS_PER_WORD - BitWidth); + return countPopulationSlowCase() == BitWidth; } + /// \brief Determine if this is the largest unsigned value. + /// /// This checks to see if the value of this APInt is the maximum unsigned /// value for the APInt's bit width. - /// @brief Determine if this is the largest unsigned value. - bool isMaxValue() const { - return countPopulation() == BitWidth; - } + bool isMaxValue() const { return isAllOnesValue(); } + /// \brief Determine if this is the largest signed value. + /// /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. - /// @brief Determine if this is the largest signed value. bool isMaxSignedValue() const { - return BitWidth == 1 ? VAL == 0 : - !isNegative() && countPopulation() == BitWidth - 1; + return BitWidth == 1 ? VAL == 0 + : !isNegative() && countPopulation() == BitWidth - 1; } + /// \brief Determine if this is the smallest unsigned value. + /// /// This checks to see if the value of this APInt is the minimum unsigned /// value for the APInt's bit width. - /// @brief Determine if this is the smallest unsigned value. - bool isMinValue() const { - return !*this; - } + bool isMinValue() const { return !*this; } + /// \brief Determine if this is the smallest signed value. + /// /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. - /// @brief Determine if this is the smallest signed value. bool isMinSignedValue() const { return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2(); } - /// @brief Check if this APInt has an N-bits unsigned integer value. + /// \brief Check if this APInt has an N-bits unsigned integer value. bool isIntN(unsigned N) const { assert(N && "N == 0 ???"); return getActiveBits() <= N; } - /// @brief Check if this APInt has an N-bits signed integer value. + /// \brief Check if this APInt has an N-bits signed integer value. bool isSignedIntN(unsigned N) const { assert(N && "N == 0 ???"); return getMinSignedBits() <= N; } - /// @returns true if the argument APInt value is a power of two > 0. + /// \brief Check if this APInt's value is a power of two greater than zero. + /// + /// \returns true if the argument APInt value is a power of two > 0. bool isPowerOf2() const { if (isSingleWord()) return isPowerOf2_64(VAL); return countPopulationSlowCase() == 1; } - /// isSignBit - Return true if this is the value returned by getSignBit. + /// \brief Check if the APInt's value is returned by getSignBit. + /// + /// \returns true if this is the value returned by getSignBit. bool isSignBit() const { return isMinSignedValue(); } + /// \brief Convert APInt to a boolean value. + /// /// This converts the APInt to a boolean value as a test against zero. - /// @brief Boolean conversion function. - bool getBoolValue() const { - return !!*this; - } + bool getBoolValue() const { return !!*this; } - /// getLimitedValue - If this value is smaller than the specified limit, - /// return it, otherwise return the limit value. This causes the value - /// to saturate to the limit. + /// If this value is smaller than the specified limit, return it, otherwise + /// return the limit value. This causes the value to saturate to the limit. uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const { - return (getActiveBits() > 64 || getZExtValue() > Limit) ? - Limit : getZExtValue(); + return (getActiveBits() > 64 || getZExtValue() > Limit) ? Limit + : getZExtValue(); } /// @} - /// @name Value Generators + /// \name Value Generators /// @{ - /// @brief Gets maximum unsigned value of APInt for specific bit width. + + /// \brief Gets maximum unsigned value of APInt for specific bit width. static APInt getMaxValue(unsigned numBits) { return getAllOnesValue(numBits); } - /// @brief Gets maximum signed value of APInt for a specific bit width. + /// \brief Gets maximum signed value of APInt for a specific bit width. static APInt getSignedMaxValue(unsigned numBits) { APInt API = getAllOnesValue(numBits); API.clearBit(numBits - 1); return API; } - /// @brief Gets minimum unsigned value of APInt for a specific bit width. - static APInt getMinValue(unsigned numBits) { - return APInt(numBits, 0); - } + /// \brief Gets minimum unsigned value of APInt for a specific bit width. + static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); } - /// @brief Gets minimum signed value of APInt for a specific bit width. + /// \brief Gets minimum signed value of APInt for a specific bit width. static APInt getSignedMinValue(unsigned numBits) { APInt API(numBits, 0); API.setBit(numBits - 1); return API; } - /// getSignBit - This is just a wrapper function of getSignedMinValue(), and - /// it helps code readability when we want to get a SignBit. - /// @brief Get the SignBit for a specific bit width. + /// \brief Get the SignBit for a specific bit width. + /// + /// This is just a wrapper function of getSignedMinValue(), and it helps code + /// readability when we want to get a SignBit. static APInt getSignBit(unsigned BitWidth) { return getSignedMinValue(BitWidth); } - /// @returns the all-ones value for an APInt of the specified bit-width. - /// @brief Get the all-ones value. + /// \brief Get the all-ones value. + /// + /// \returns the all-ones value for an APInt of the specified bit-width. static APInt getAllOnesValue(unsigned numBits) { return APInt(numBits, UINT64_MAX, true); } - /// @returns the '0' value for an APInt of the specified bit-width. - /// @brief Get the '0' value. - static APInt getNullValue(unsigned numBits) { - return APInt(numBits, 0); - } + /// \brief Get the '0' value. + /// + /// \returns the '0' value for an APInt of the specified bit-width. + static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); } + /// \brief Compute an APInt containing numBits highbits from this APInt. + /// /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the low bits and right shift to the least significant bit. - /// @returns the high "numBits" bits of this APInt. + /// + /// \returns the high "numBits" bits of this APInt. APInt getHiBits(unsigned numBits) const; + /// \brief Compute an APInt containing numBits lowbits from this APInt. + /// /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the high bits. - /// @returns the low "numBits" bits of this APInt. + /// + /// \returns the low "numBits" bits of this APInt. APInt getLoBits(unsigned numBits) const; - /// getOneBitSet - Return an APInt with exactly one bit set in the result. + /// \brief Return an APInt with exactly one bit set in the result. static APInt getOneBitSet(unsigned numBits, unsigned BitNo) { APInt Res(numBits, 0); Res.setBit(BitNo); return Res; } - + + /// \brief Get a value with a block of bits set. + /// /// Constructs an APInt value that has a contiguous range of bits set. The /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other /// bits will be zero. For example, with parameters(32, 0, 16) you would get /// 0x0000FFFF. If hiBit is less than loBit then the set bits "wrap". For /// example, with parameters (32, 28, 4), you would get 0xF000000F. - /// @param numBits the intended bit width of the result - /// @param loBit the index of the lowest bit set. - /// @param hiBit the index of the highest bit set. - /// @returns An APInt value with the requested bits set. - /// @brief Get a value with a block of bits set. + /// + /// \param numBits the intended bit width of the result + /// \param loBit the index of the lowest bit set. + /// \param hiBit the index of the highest bit set. + /// + /// \returns An APInt value with the requested bits set. static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) { assert(hiBit <= numBits && "hiBit out of range"); assert(loBit < numBits && "loBit out of range"); if (hiBit < loBit) return getLowBitsSet(numBits, hiBit) | - getHighBitsSet(numBits, numBits-loBit); - return getLowBitsSet(numBits, hiBit-loBit).shl(loBit); + getHighBitsSet(numBits, numBits - loBit); + return getLowBitsSet(numBits, hiBit - loBit).shl(loBit); } + /// \brief Get a value with high bits set + /// /// Constructs an APInt value that has the top hiBitsSet bits set. - /// @param numBits the bitwidth of the result - /// @param hiBitsSet the number of high-order bits set in the result. - /// @brief Get a value with high bits set + /// + /// \param numBits the bitwidth of the result + /// \param hiBitsSet the number of high-order bits set in the result. static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) { assert(hiBitsSet <= numBits && "Too many bits to set!"); // Handle a degenerate case, to avoid shifting by word size @@ -488,10 +519,12 @@ public: return getAllOnesValue(numBits).shl(shiftAmt); } + /// \brief Get a value with low bits set + /// /// Constructs an APInt value that has the bottom loBitsSet bits set. - /// @param numBits the bitwidth of the result - /// @param loBitsSet the number of low-order bits set in the result. - /// @brief Get a value with low bits set + /// + /// \param numBits the bitwidth of the result + /// \param loBitsSet the number of low-order bits set in the result. static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) { assert(loBitsSet <= numBits && "Too many bits to set!"); // Handle a degenerate case, to avoid shifting by word size @@ -527,65 +560,74 @@ public: return I1.zext(I2.getBitWidth()) == I2; } - + /// \brief Overload to compute a hash_code for an APInt value. friend hash_code hash_value(const APInt &Arg); /// This function returns a pointer to the internal storage of the APInt. /// This is useful for writing out the APInt in binary form without any /// conversions. - const uint64_t* getRawData() const { + const uint64_t *getRawData() const { if (isSingleWord()) return &VAL; return &pVal[0]; } /// @} - /// @name Unary Operators + /// \name Unary Operators /// @{ - /// @returns a new APInt value representing *this incremented by one - /// @brief Postfix increment operator. + + /// \brief Postfix increment operator. + /// + /// \returns a new APInt value representing *this incremented by one const APInt operator++(int) { APInt API(*this); ++(*this); return API; } - /// @returns *this incremented by one - /// @brief Prefix increment operator. - APInt& operator++(); + /// \brief Prefix increment operator. + /// + /// \returns *this incremented by one + APInt &operator++(); - /// @returns a new APInt representing *this decremented by one. - /// @brief Postfix decrement operator. + /// \brief Postfix decrement operator. + /// + /// \returns a new APInt representing *this decremented by one. const APInt operator--(int) { APInt API(*this); --(*this); return API; } - /// @returns *this decremented by one. - /// @brief Prefix decrement operator. - APInt& operator--(); + /// \brief Prefix decrement operator. + /// + /// \returns *this decremented by one. + APInt &operator--(); + /// \brief Unary bitwise complement operator. + /// /// Performs a bitwise complement operation on this APInt. - /// @returns an APInt that is the bitwise complement of *this - /// @brief Unary bitwise complement operator. + /// + /// \returns an APInt that is the bitwise complement of *this APInt operator~() const { APInt Result(*this); Result.flipAllBits(); return Result; } + /// \brief Unary negation operator + /// /// Negates *this using two's complement logic. - /// @returns An APInt value representing the negation of *this. - /// @brief Unary negation operator - APInt operator-() const { - return APInt(BitWidth, 0) - (*this); - } + /// + /// \returns An APInt value representing the negation of *this. + APInt operator-() const { return APInt(BitWidth, 0) - (*this); } + /// \brief Logical negation operator. + /// /// Performs logical negation operation on this APInt. - /// @returns true if *this is zero, false otherwise. - /// @brief Logical negation operator. + /// + /// \returns true if *this is zero, false otherwise. bool operator!() const { if (isSingleWord()) return !VAL; @@ -597,11 +639,13 @@ public: } /// @} - /// @name Assignment Operators + /// \name Assignment Operators /// @{ - /// @returns *this after assignment of RHS. - /// @brief Copy assignment operator. - APInt& operator=(const APInt& RHS) { + + /// \brief Copy assignment operator. + /// + /// \returns *this after assignment of RHS. + APInt &operator=(const APInt &RHS) { // If the bitwidths are the same, we can avoid mucking with memory if (isSingleWord() && RHS.isSingleWord()) { VAL = RHS.VAL; @@ -614,9 +658,9 @@ public: #if LLVM_HAS_RVALUE_REFERENCES /// @brief Move assignment operator. - APInt& operator=(APInt&& that) { + APInt &operator=(APInt &&that) { if (!isSingleWord()) - delete [] pVal; + delete[] pVal; BitWidth = that.BitWidth; VAL = that.VAL; @@ -627,31 +671,37 @@ public: } #endif + /// \brief Assignment operator. + /// /// The RHS value is assigned to *this. If the significant bits in RHS exceed /// the bit width, the excess bits are truncated. If the bit width is larger /// than 64, the value is zero filled in the unspecified high order bits. - /// @returns *this after assignment of RHS value. - /// @brief Assignment operator. - APInt& operator=(uint64_t RHS); + /// + /// \returns *this after assignment of RHS value. + APInt &operator=(uint64_t RHS); + /// \brief Bitwise AND assignment operator. + /// /// Performs a bitwise AND operation on this APInt and RHS. The result is /// assigned to *this. - /// @returns *this after ANDing with RHS. - /// @brief Bitwise AND assignment operator. - APInt& operator&=(const APInt& RHS); + /// + /// \returns *this after ANDing with RHS. + APInt &operator&=(const APInt &RHS); + /// \brief Bitwise OR assignment operator. + /// /// Performs a bitwise OR operation on this APInt and RHS. The result is /// assigned *this; - /// @returns *this after ORing with RHS. - /// @brief Bitwise OR assignment operator. - APInt& operator|=(const APInt& RHS); + /// + /// \returns *this after ORing with RHS. + APInt &operator|=(const APInt &RHS); + /// \brief Bitwise OR assignment operator. + /// /// Performs a bitwise OR operation on this APInt and RHS. RHS is /// logically zero-extended or truncated to match the bit-width of /// the LHS. - /// - /// @brief Bitwise OR assignment operator. - APInt& operator|=(uint64_t RHS) { + APInt &operator|=(uint64_t RHS) { if (isSingleWord()) { VAL |= RHS; clearUnusedBits(); @@ -661,114 +711,149 @@ public: return *this; } + /// \brief Bitwise XOR assignment operator. + /// /// Performs a bitwise XOR operation on this APInt and RHS. The result is /// assigned to *this. - /// @returns *this after XORing with RHS. - /// @brief Bitwise XOR assignment operator. - APInt& operator^=(const APInt& RHS); + /// + /// \returns *this after XORing with RHS. + APInt &operator^=(const APInt &RHS); + /// \brief Multiplication assignment operator. + /// /// Multiplies this APInt by RHS and assigns the result to *this. - /// @returns *this - /// @brief Multiplication assignment operator. - APInt& operator*=(const APInt& RHS); + /// + /// \returns *this + APInt &operator*=(const APInt &RHS); + /// \brief Addition assignment operator. + /// /// Adds RHS to *this and assigns the result to *this. - /// @returns *this - /// @brief Addition assignment operator. - APInt& operator+=(const APInt& RHS); + /// + /// \returns *this + APInt &operator+=(const APInt &RHS); + /// \brief Subtraction assignment operator. + /// /// Subtracts RHS from *this and assigns the result to *this. - /// @returns *this - /// @brief Subtraction assignment operator. - APInt& operator-=(const APInt& RHS); + /// + /// \returns *this + APInt &operator-=(const APInt &RHS); + /// \brief Left-shift assignment function. + /// /// Shifts *this left by shiftAmt and assigns the result to *this. - /// @returns *this after shifting left by shiftAmt - /// @brief Left-shift assignment function. - APInt& operator<<=(unsigned shiftAmt) { + /// + /// \returns *this after shifting left by shiftAmt + APInt &operator<<=(unsigned shiftAmt) { *this = shl(shiftAmt); return *this; } /// @} - /// @name Binary Operators + /// \name Binary Operators /// @{ + + /// \brief Bitwise AND operator. + /// /// Performs a bitwise AND operation on *this and RHS. - /// @returns An APInt value representing the bitwise AND of *this and RHS. - /// @brief Bitwise AND operator. - APInt operator&(const APInt& RHS) const { + /// + /// \returns An APInt value representing the bitwise AND of *this and RHS. + APInt operator&(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) return APInt(getBitWidth(), VAL & RHS.VAL); return AndSlowCase(RHS); } - APInt And(const APInt& RHS) const { + APInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APInt &RHS) const { return this->operator&(RHS); } + /// \brief Bitwise OR operator. + /// /// Performs a bitwise OR operation on *this and RHS. - /// @returns An APInt value representing the bitwise OR of *this and RHS. - /// @brief Bitwise OR operator. - APInt operator|(const APInt& RHS) const { + /// + /// \returns An APInt value representing the bitwise OR of *this and RHS. + APInt operator|(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) return APInt(getBitWidth(), VAL | RHS.VAL); return OrSlowCase(RHS); } - APInt Or(const APInt& RHS) const { + + /// \brief Bitwise OR function. + /// + /// Performs a bitwise or on *this and RHS. This is implemented bny simply + /// calling operator|. + /// + /// \returns An APInt value representing the bitwise OR of *this and RHS. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APInt &RHS) const { return this->operator|(RHS); } + /// \brief Bitwise XOR operator. + /// /// Performs a bitwise XOR operation on *this and RHS. - /// @returns An APInt value representing the bitwise XOR of *this and RHS. - /// @brief Bitwise XOR operator. - APInt operator^(const APInt& RHS) const { + /// + /// \returns An APInt value representing the bitwise XOR of *this and RHS. + APInt operator^(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) return APInt(BitWidth, VAL ^ RHS.VAL); return XorSlowCase(RHS); } - APInt Xor(const APInt& RHS) const { + + /// \brief Bitwise XOR function. + /// + /// Performs a bitwise XOR operation on *this and RHS. This is implemented + /// through the usage of operator^. + /// + /// \returns An APInt value representing the bitwise XOR of *this and RHS. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APInt &RHS) const { return this->operator^(RHS); } + /// \brief Multiplication operator. + /// /// Multiplies this APInt by RHS and returns the result. - /// @brief Multiplication operator. - APInt operator*(const APInt& RHS) const; + APInt operator*(const APInt &RHS) const; + /// \brief Addition operator. + /// /// Adds RHS to this APInt and returns the result. - /// @brief Addition operator. - APInt operator+(const APInt& RHS) const; - APInt operator+(uint64_t RHS) const { - return (*this) + APInt(BitWidth, RHS); - } + APInt operator+(const APInt &RHS) const; + APInt operator+(uint64_t RHS) const { return (*this) + APInt(BitWidth, RHS); } + /// \brief Subtraction operator. + /// /// Subtracts RHS from this APInt and returns the result. - /// @brief Subtraction operator. - APInt operator-(const APInt& RHS) const; - APInt operator-(uint64_t RHS) const { - return (*this) - APInt(BitWidth, RHS); - } + APInt operator-(const APInt &RHS) const; + APInt operator-(uint64_t RHS) const { return (*this) - APInt(BitWidth, RHS); } - APInt operator<<(unsigned Bits) const { - return shl(Bits); - } + /// \brief Left logical shift operator. + /// + /// Shifts this APInt left by \p Bits and returns the result. + APInt operator<<(unsigned Bits) const { return shl(Bits); } - APInt operator<<(const APInt &Bits) const { - return shl(Bits); - } + /// \brief Left logical shift operator. + /// + /// Shifts this APInt left by \p Bits and returns the result. + APInt operator<<(const APInt &Bits) const { return shl(Bits); } + /// \brief Arithmetic right-shift function. + /// /// Arithmetic right-shift this APInt by shiftAmt. - /// @brief Arithmetic right-shift function. - APInt ashr(unsigned shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(unsigned shiftAmt) const; + /// \brief Logical right-shift function. + /// /// Logical right-shift this APInt by shiftAmt. - /// @brief Logical right-shift function. - APInt lshr(unsigned shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(unsigned shiftAmt) const; + /// \brief Left-shift function. + /// /// Left-shift this APInt by shiftAmt. - /// @brief Left-shift function. - APInt shl(unsigned shiftAmt) const { + APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(unsigned shiftAmt) const { assert(shiftAmt <= BitWidth && "Invalid shift amount"); if (isSingleWord()) { if (shiftAmt >= BitWidth) @@ -778,65 +863,74 @@ public: return shlSlowCase(shiftAmt); } - /// @brief Rotate left by rotateAmt. - APInt rotl(unsigned rotateAmt) const; + /// \brief Rotate left by rotateAmt. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(unsigned rotateAmt) const; - /// @brief Rotate right by rotateAmt. - APInt rotr(unsigned rotateAmt) const; + /// \brief Rotate right by rotateAmt. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(unsigned rotateAmt) const; + /// \brief Arithmetic right-shift function. + /// /// Arithmetic right-shift this APInt by shiftAmt. - /// @brief Arithmetic right-shift function. - APInt ashr(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(const APInt &shiftAmt) const; + /// \brief Logical right-shift function. + /// /// Logical right-shift this APInt by shiftAmt. - /// @brief Logical right-shift function. - APInt lshr(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(const APInt &shiftAmt) const; + /// \brief Left-shift function. + /// /// Left-shift this APInt by shiftAmt. - /// @brief Left-shift function. - APInt shl(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(const APInt &shiftAmt) const; - /// @brief Rotate left by rotateAmt. - APInt rotl(const APInt &rotateAmt) const; + /// \brief Rotate left by rotateAmt. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(const APInt &rotateAmt) const; - /// @brief Rotate right by rotateAmt. - APInt rotr(const APInt &rotateAmt) const; + /// \brief Rotate right by rotateAmt. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(const APInt &rotateAmt) const; + /// \brief Unsigned division operation. + /// /// Perform an unsigned divide operation on this APInt by RHS. Both this and /// RHS are treated as unsigned quantities for purposes of this division. - /// @returns a new APInt value containing the division result - /// @brief Unsigned division operation. - APInt udiv(const APInt &RHS) const; + /// + /// \returns a new APInt value containing the division result + APInt LLVM_ATTRIBUTE_UNUSED_RESULT udiv(const APInt &RHS) const; + /// \brief Signed division function for APInt. + /// /// Signed divide this APInt by APInt RHS. - /// @brief Signed division function for APInt. - APInt sdiv(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const; + /// \brief Unsigned remainder operation. + /// /// Perform an unsigned remainder operation on this APInt with RHS being the /// divisor. Both this and RHS are treated as unsigned quantities for purposes - /// of this operation. Note that this is a true remainder operation and not - /// a modulo operation because the sign follows the sign of the dividend - /// which is *this. - /// @returns a new APInt value containing the remainder result - /// @brief Unsigned remainder operation. - APInt urem(const APInt &RHS) const; + /// of this operation. Note that this is a true remainder operation and not a + /// modulo operation because the sign follows the sign of the dividend which + /// is *this. + /// + /// \returns a new APInt value containing the remainder result + APInt LLVM_ATTRIBUTE_UNUSED_RESULT urem(const APInt &RHS) const; + /// \brief Function for signed remainder operation. + /// /// Signed remainder operation on APInt. - /// @brief Function for signed remainder operation. - APInt srem(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT srem(const APInt &RHS) const; + /// \brief Dual division/remainder interface. + /// /// Sometimes it is convenient to divide two APInt values and obtain both the /// quotient and remainder. This function does both operations in the same /// computation making it a little more efficient. The pair of input arguments /// may overlap with the pair of output arguments. It is safe to call /// udivrem(X, Y, X, Y), for example. - /// @brief Dual division/remainder interface. - static void udivrem(const APInt &LHS, const APInt &RHS, - APInt &Quotient, APInt &Remainder); - - static void sdivrem(const APInt &LHS, const APInt &RHS, - APInt &Quotient, APInt &Remainder); + static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, + APInt &Remainder); + static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, + APInt &Remainder); // Operations that return overflow indicators. APInt sadd_ov(const APInt &RHS, bool &Overflow) const; @@ -848,247 +942,261 @@ public: APInt umul_ov(const APInt &RHS, bool &Overflow) const; APInt sshl_ov(unsigned Amt, bool &Overflow) const; - /// @returns the bit value at bitPosition - /// @brief Array-indexing support. + /// \brief Array-indexing support. + /// + /// \returns the bit value at bitPosition bool operator[](unsigned bitPosition) const { assert(bitPosition < getBitWidth() && "Bit position out of bounds!"); return (maskBit(bitPosition) & - (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) != 0; + (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) != + 0; } /// @} - /// @name Comparison Operators + /// \name Comparison Operators /// @{ + + /// \brief Equality operator. + /// /// Compares this APInt with RHS for the validity of the equality /// relationship. - /// @brief Equality operator. - bool operator==(const APInt& RHS) const { + bool operator==(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths"); if (isSingleWord()) return VAL == RHS.VAL; return EqualSlowCase(RHS); } + /// \brief Equality operator. + /// /// Compares this APInt with a uint64_t for the validity of the equality /// relationship. - /// @returns true if *this == Val - /// @brief Equality operator. + /// + /// \returns true if *this == Val bool operator==(uint64_t Val) const { if (isSingleWord()) return VAL == Val; return EqualSlowCase(Val); } + /// \brief Equality comparison. + /// /// Compares this APInt with RHS for the validity of the equality /// relationship. - /// @returns true if *this == Val - /// @brief Equality comparison. - bool eq(const APInt &RHS) const { - return (*this) == RHS; - } + /// + /// \returns true if *this == Val + bool eq(const APInt &RHS) const { return (*this) == RHS; } + /// \brief Inequality operator. + /// /// Compares this APInt with RHS for the validity of the inequality /// relationship. - /// @returns true if *this != Val - /// @brief Inequality operator. - bool operator!=(const APInt& RHS) const { - return !((*this) == RHS); - } + /// + /// \returns true if *this != Val + bool operator!=(const APInt &RHS) const { return !((*this) == RHS); } + /// \brief Inequality operator. + /// /// Compares this APInt with a uint64_t for the validity of the inequality /// relationship. - /// @returns true if *this != Val - /// @brief Inequality operator. - bool operator!=(uint64_t Val) const { - return !((*this) == Val); - } + /// + /// \returns true if *this != Val + bool operator!=(uint64_t Val) const { return !((*this) == Val); } + /// \brief Inequality comparison + /// /// Compares this APInt with RHS for the validity of the inequality /// relationship. - /// @returns true if *this != Val - /// @brief Inequality comparison - bool ne(const APInt &RHS) const { - return !((*this) == RHS); - } + /// + /// \returns true if *this != Val + bool ne(const APInt &RHS) const { return !((*this) == RHS); } + /// \brief Unsigned less than comparison + /// /// Regards both *this and RHS as unsigned quantities and compares them for /// the validity of the less-than relationship. - /// @returns true if *this < RHS when both are considered unsigned. - /// @brief Unsigned less than comparison + /// + /// \returns true if *this < RHS when both are considered unsigned. bool ult(const APInt &RHS) const; + /// \brief Unsigned less than comparison + /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the less-than relationship. - /// @returns true if *this < RHS when considered unsigned. - /// @brief Unsigned less than comparison - bool ult(uint64_t RHS) const { - return ult(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this < RHS when considered unsigned. + bool ult(uint64_t RHS) const { return ult(APInt(getBitWidth(), RHS)); } + /// \brief Signed less than comparison + /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-than relationship. - /// @returns true if *this < RHS when both are considered signed. - /// @brief Signed less than comparison - bool slt(const APInt& RHS) const; + /// + /// \returns true if *this < RHS when both are considered signed. + bool slt(const APInt &RHS) const; + /// \brief Signed less than comparison + /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the less-than relationship. - /// @returns true if *this < RHS when considered signed. - /// @brief Signed less than comparison - bool slt(uint64_t RHS) const { - return slt(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this < RHS when considered signed. + bool slt(uint64_t RHS) const { return slt(APInt(getBitWidth(), RHS)); } + /// \brief Unsigned less or equal comparison + /// /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the less-or-equal relationship. - /// @returns true if *this <= RHS when both are considered unsigned. - /// @brief Unsigned less or equal comparison - bool ule(const APInt& RHS) const { - return ult(RHS) || eq(RHS); - } + /// + /// \returns true if *this <= RHS when both are considered unsigned. + bool ule(const APInt &RHS) const { return ult(RHS) || eq(RHS); } + /// \brief Unsigned less or equal comparison + /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the less-or-equal relationship. - /// @returns true if *this <= RHS when considered unsigned. - /// @brief Unsigned less or equal comparison - bool ule(uint64_t RHS) const { - return ule(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this <= RHS when considered unsigned. + bool ule(uint64_t RHS) const { return ule(APInt(getBitWidth(), RHS)); } + /// \brief Signed less or equal comparison + /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-or-equal relationship. - /// @returns true if *this <= RHS when both are considered signed. - /// @brief Signed less or equal comparison - bool sle(const APInt& RHS) const { - return slt(RHS) || eq(RHS); - } + /// + /// \returns true if *this <= RHS when both are considered signed. + bool sle(const APInt &RHS) const { return slt(RHS) || eq(RHS); } - /// Regards both *this as a signed quantity and compares it with RHS for - /// the validity of the less-or-equal relationship. - /// @returns true if *this <= RHS when considered signed. - /// @brief Signed less or equal comparison - bool sle(uint64_t RHS) const { - return sle(APInt(getBitWidth(), RHS)); - } + /// \brief Signed less or equal comparison + /// + /// Regards both *this as a signed quantity and compares it with RHS for the + /// validity of the less-or-equal relationship. + /// + /// \returns true if *this <= RHS when considered signed. + bool sle(uint64_t RHS) const { return sle(APInt(getBitWidth(), RHS)); } + /// \brief Unsigned greather than comparison + /// /// Regards both *this and RHS as unsigned quantities and compares them for /// the validity of the greater-than relationship. - /// @returns true if *this > RHS when both are considered unsigned. - /// @brief Unsigned greather than comparison - bool ugt(const APInt& RHS) const { - return !ult(RHS) && !eq(RHS); - } + /// + /// \returns true if *this > RHS when both are considered unsigned. + bool ugt(const APInt &RHS) const { return !ult(RHS) && !eq(RHS); } + /// \brief Unsigned greater than comparison + /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the greater-than relationship. - /// @returns true if *this > RHS when considered unsigned. - /// @brief Unsigned greater than comparison - bool ugt(uint64_t RHS) const { - return ugt(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this > RHS when considered unsigned. + bool ugt(uint64_t RHS) const { return ugt(APInt(getBitWidth(), RHS)); } - /// Regards both *this and RHS as signed quantities and compares them for - /// the validity of the greater-than relationship. - /// @returns true if *this > RHS when both are considered signed. - /// @brief Signed greather than comparison - bool sgt(const APInt& RHS) const { - return !slt(RHS) && !eq(RHS); - } + /// \brief Signed greather than comparison + /// + /// Regards both *this and RHS as signed quantities and compares them for the + /// validity of the greater-than relationship. + /// + /// \returns true if *this > RHS when both are considered signed. + bool sgt(const APInt &RHS) const { return !slt(RHS) && !eq(RHS); } + /// \brief Signed greater than comparison + /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the greater-than relationship. - /// @returns true if *this > RHS when considered signed. - /// @brief Signed greater than comparison - bool sgt(uint64_t RHS) const { - return sgt(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this > RHS when considered signed. + bool sgt(uint64_t RHS) const { return sgt(APInt(getBitWidth(), RHS)); } + /// \brief Unsigned greater or equal comparison + /// /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the greater-or-equal relationship. - /// @returns true if *this >= RHS when both are considered unsigned. - /// @brief Unsigned greater or equal comparison - bool uge(const APInt& RHS) const { - return !ult(RHS); - } + /// + /// \returns true if *this >= RHS when both are considered unsigned. + bool uge(const APInt &RHS) const { return !ult(RHS); } + /// \brief Unsigned greater or equal comparison + /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the greater-or-equal relationship. - /// @returns true if *this >= RHS when considered unsigned. - /// @brief Unsigned greater or equal comparison - bool uge(uint64_t RHS) const { - return uge(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this >= RHS when considered unsigned. + bool uge(uint64_t RHS) const { return uge(APInt(getBitWidth(), RHS)); } + /// \brief Signed greather or equal comparison + /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the greater-or-equal relationship. - /// @returns true if *this >= RHS when both are considered signed. - /// @brief Signed greather or equal comparison - bool sge(const APInt& RHS) const { - return !slt(RHS); - } + /// + /// \returns true if *this >= RHS when both are considered signed. + bool sge(const APInt &RHS) const { return !slt(RHS); } + /// \brief Signed greater or equal comparison + /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the greater-or-equal relationship. - /// @returns true if *this >= RHS when considered signed. - /// @brief Signed greater or equal comparison - bool sge(uint64_t RHS) const { - return sge(APInt(getBitWidth(), RHS)); - } + /// + /// \returns true if *this >= RHS when considered signed. + bool sge(uint64_t RHS) const { return sge(APInt(getBitWidth(), RHS)); } - - - /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. - bool intersects(const APInt &RHS) const { - return (*this & RHS) != 0; - } + bool intersects(const APInt &RHS) const { return (*this & RHS) != 0; } /// @} - /// @name Resizing Operators + /// \name Resizing Operators /// @{ + + /// \brief Truncate to new width. + /// /// Truncate the APInt to a specified width. It is an error to specify a width /// that is greater than or equal to the current width. - /// @brief Truncate to new width. - APInt trunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(unsigned width) const; + /// \brief Sign extend to a new width. + /// /// This operation sign extends the APInt to a new width. If the high order /// bit is set, the fill on the left will be done with 1 bits, otherwise zero. /// It is an error to specify a width that is less than or equal to the /// current width. - /// @brief Sign extend to a new width. - APInt sext(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sext(unsigned width) const; + /// \brief Zero extend to a new width. + /// /// This operation zero extends the APInt to a new width. The high order bits /// are filled with 0 bits. It is an error to specify a width that is less /// than or equal to the current width. - /// @brief Zero extend to a new width. - APInt zext(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zext(unsigned width) const; + /// \brief Sign extend or truncate to width + /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, truncated, or left alone to make it that width. - /// @brief Sign extend or truncate to width - APInt sextOrTrunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrTrunc(unsigned width) const; + /// \brief Zero extend or truncate to width + /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, truncated, or left alone to make it that width. - /// @brief Zero extend or truncate to width - APInt zextOrTrunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrTrunc(unsigned width) const; + /// \brief Sign extend or truncate to width + /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, or left alone to make it that width. - /// @brief Sign extend or truncate to width - APInt sextOrSelf(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrSelf(unsigned width) const; + /// \brief Zero extend or truncate to width + /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, or left alone to make it that width. - /// @brief Zero extend or truncate to width - APInt zextOrSelf(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrSelf(unsigned width) const; /// @} - /// @name Bit Manipulation Operators + /// \name Bit Manipulation Operators /// @{ - /// @brief Set every bit to 1. + + /// \brief Set every bit to 1. void setAllBits() { if (isSingleWord()) VAL = UINT64_MAX; @@ -1101,11 +1209,12 @@ public: clearUnusedBits(); } + /// \brief Set a given bit to 1. + /// /// Set the given bit to 1 whose position is given as "bitPosition". - /// @brief Set a given bit to 1. void setBit(unsigned bitPosition); - /// @brief Set every bit to 0. + /// \brief Set every bit to 0. void clearAllBits() { if (isSingleWord()) VAL = 0; @@ -1113,11 +1222,12 @@ public: memset(pVal, 0, getNumWords() * APINT_WORD_SIZE); } + /// \brief Set a given bit to 0. + /// /// Set the given bit to 0 whose position is given as "bitPosition". - /// @brief Set a given bit to 0. void clearBit(unsigned bitPosition); - /// @brief Toggle every bit to its opposite value. + /// \brief Toggle every bit to its opposite value. void flipAllBits() { if (isSingleWord()) VAL ^= UINT64_MAX; @@ -1128,68 +1238,71 @@ public: clearUnusedBits(); } + /// \brief Toggles a given bit to its opposite value. + /// /// Toggle a given bit to its opposite value whose position is given /// as "bitPosition". - /// @brief Toggles a given bit to its opposite value. void flipBit(unsigned bitPosition); /// @} - /// @name Value Characterization Functions + /// \name Value Characterization Functions /// @{ - /// @returns the total number of bits. - unsigned getBitWidth() const { - return BitWidth; - } + /// \brief Return the number of bits in the APInt. + unsigned getBitWidth() const { return BitWidth; } + /// \brief Get the number of words. + /// /// Here one word's bitwidth equals to that of uint64_t. - /// @returns the number of words to hold the integer value of this APInt. - /// @brief Get the number of words. - unsigned getNumWords() const { - return getNumWords(BitWidth); - } + /// + /// \returns the number of words to hold the integer value of this APInt. + unsigned getNumWords() const { return getNumWords(BitWidth); } - /// Here one word's bitwidth equals to that of uint64_t. - /// @returns the number of words to hold the integer value with a - /// given bit width. - /// @brief Get the number of words. + /// \brief Get the number of words. + /// + /// *NOTE* Here one word's bitwidth equals to that of uint64_t. + /// + /// \returns the number of words to hold the integer value with a given bit + /// width. static unsigned getNumWords(unsigned BitWidth) { return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; } + /// \brief Compute the number of active bits in the value + /// /// This function returns the number of active bits which is defined as the /// bit width minus the number of leading zeros. This is used in several /// computations to see how "wide" the value is. - /// @brief Compute the number of active bits in the value - unsigned getActiveBits() const { - return BitWidth - countLeadingZeros(); - } + unsigned getActiveBits() const { return BitWidth - countLeadingZeros(); } - /// This function returns the number of active words in the value of this - /// APInt. This is used in conjunction with getActiveData to extract the raw - /// value of the APInt. + /// \brief Compute the number of active words in the value of this APInt. + /// + /// This is used in conjunction with getActiveData to extract the raw value of + /// the APInt. unsigned getActiveWords() const { unsigned numActiveBits = getActiveBits(); return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1; } - /// Computes the minimum bit width for this APInt while considering it to be - /// a signed (and probably negative) value. If the value is not negative, - /// this function returns the same value as getActiveBits()+1. Otherwise, it + /// \brief Get the minimum bit size for this signed APInt + /// + /// Computes the minimum bit width for this APInt while considering it to be a + /// signed (and probably negative) value. If the value is not negative, this + /// function returns the same value as getActiveBits()+1. Otherwise, it /// returns the smallest bit width that will retain the negative value. For /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so /// for -1, this function will always return 1. - /// @brief Get the minimum bit size for this signed APInt unsigned getMinSignedBits() const { if (isNegative()) return BitWidth - countLeadingOnes() + 1; - return getActiveBits()+1; + return getActiveBits() + 1; } + /// \brief Get zero extended value + /// /// This method attempts to return the value of this APInt as a zero extended /// uint64_t. The bitwidth must be <= 64 or the value must fit within a /// uint64_t. Otherwise an assertion will result. - /// @brief Get zero extended value uint64_t getZExtValue() const { if (isSingleWord()) return VAL; @@ -1197,43 +1310,49 @@ public: return pVal[0]; } + /// \brief Get sign extended value + /// /// This method attempts to return the value of this APInt as a sign extended /// int64_t. The bit width must be <= 64 or the value must fit within an /// int64_t. Otherwise an assertion will result. - /// @brief Get sign extended value int64_t getSExtValue() const { if (isSingleWord()) return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >> - (APINT_BITS_PER_WORD - BitWidth); + (APINT_BITS_PER_WORD - BitWidth); assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); return int64_t(pVal[0]); } + /// \brief Get bits required for string value. + /// /// This method determines how many bits are required to hold the APInt /// equivalent of the string given by \p str. - /// @brief Get bits required for string value. static unsigned getBitsNeeded(StringRef str, uint8_t radix); - /// countLeadingZeros - This function is an APInt version of the - /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number - /// of zeros from the most significant bit to the first one bit. - /// @returns BitWidth if the value is zero, otherwise - /// returns the number of zeros from the most significant bit to the first - /// one bits. + /// \brief The APInt version of the countLeadingZeros functions in + /// MathExtras.h. + /// + /// It counts the number of zeros from the most significant bit to the first + /// one bit. + /// + /// \returns BitWidth if the value is zero, otherwise returns the number of + /// zeros from the most significant bit to the first one bits. unsigned countLeadingZeros() const { if (isSingleWord()) { unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth; - return CountLeadingZeros_64(VAL) - unusedBits; + return llvm::countLeadingZeros(VAL) - unusedBits; } return countLeadingZerosSlowCase(); } - /// countLeadingOnes - This function is an APInt version of the - /// countLeadingOnes_{32,64} functions in MathExtras.h. It counts the number - /// of ones from the most significant bit to the first zero bit. - /// @returns 0 if the high order bit is not set, otherwise - /// returns the number of 1 bits from the most significant to the least - /// @brief Count the number of leading one bits. + /// \brief Count the number of leading one bits. + /// + /// This function is an APInt version of the countLeadingOnes_{32,64} + /// functions in MathExtras.h. It counts the number of ones from the most + /// significant bit to the first zero bit. + /// + /// \returns 0 if the high order bit is not set, otherwise returns the number + /// of 1 bits from the most significant to the least unsigned countLeadingOnes() const; /// Computes the number of leading bits of this APInt that are equal to its @@ -1242,34 +1361,36 @@ public: return isNegative() ? countLeadingOnes() : countLeadingZeros(); } - /// countTrailingZeros - This function is an APInt version of the - /// countTrailingZeros_{32,64} functions in MathExtras.h. It counts - /// the number of zeros from the least significant bit to the first set bit. - /// @returns BitWidth if the value is zero, otherwise - /// returns the number of zeros from the least significant bit to the first - /// one bit. - /// @brief Count the number of trailing zero bits. + /// \brief Count the number of trailing zero bits. + /// + /// This function is an APInt version of the countTrailingZeros_{32,64} + /// functions in MathExtras.h. It counts the number of zeros from the least + /// significant bit to the first set bit. + /// + /// \returns BitWidth if the value is zero, otherwise returns the number of + /// zeros from the least significant bit to the first one bit. unsigned countTrailingZeros() const; - /// countTrailingOnes - This function is an APInt version of the - /// countTrailingOnes_{32,64} functions in MathExtras.h. It counts - /// the number of ones from the least significant bit to the first zero bit. - /// @returns BitWidth if the value is all ones, otherwise - /// returns the number of ones from the least significant bit to the first - /// zero bit. - /// @brief Count the number of trailing one bits. + /// \brief Count the number of trailing one bits. + /// + /// This function is an APInt version of the countTrailingOnes_{32,64} + /// functions in MathExtras.h. It counts the number of ones from the least + /// significant bit to the first zero bit. + /// + /// \returns BitWidth if the value is all ones, otherwise returns the number + /// of ones from the least significant bit to the first zero bit. unsigned countTrailingOnes() const { if (isSingleWord()) return CountTrailingOnes_64(VAL); return countTrailingOnesSlowCase(); } - /// countPopulation - This function is an APInt version of the - /// countPopulation_{32,64} functions in MathExtras.h. It counts the number - /// of 1 bits in the APInt value. - /// @returns 0 if the value is zero, otherwise returns the number of set - /// bits. - /// @brief Count the number of bits set. + /// \brief Count the number of bits set. + /// + /// This function is an APInt version of the countPopulation_{32,64} functions + /// in MathExtras.h. It counts the number of 1 bits in the APInt value. + /// + /// \returns 0 if the value is zero, otherwise returns the number of set bits. unsigned countPopulation() const { if (isSingleWord()) return CountPopulation_64(VAL); @@ -1277,12 +1398,12 @@ public: } /// @} - /// @name Conversion Functions + /// \name Conversion Functions /// @{ void print(raw_ostream &OS, bool isSigned) const; - /// toString - Converts an APInt to a string and append it to Str. Str is - /// commonly a SmallString. + /// Converts an APInt to a string and append it to Str. Str is commonly a + /// SmallString. void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed, bool formatAsCLiteral = false) const; @@ -1298,32 +1419,30 @@ public: toString(Str, Radix, true, false); } - /// toString - This returns the APInt as a std::string. Note that this is an - /// inefficient method. It is better to pass in a SmallVector/SmallString - /// to the methods above to avoid thrashing the heap for the string. + /// \brief Return the APInt as a std::string. + /// + /// Note that this is an inefficient method. It is better to pass in a + /// SmallVector/SmallString to the methods above to avoid thrashing the heap + /// for the string. std::string toString(unsigned Radix, bool Signed) const; + /// \returns a byte-swapped representation of this APInt Value. + APInt LLVM_ATTRIBUTE_UNUSED_RESULT byteSwap() const; - /// @returns a byte-swapped representation of this APInt Value. - APInt byteSwap() const; - - /// @brief Converts this APInt to a double value. + /// \brief Converts this APInt to a double value. double roundToDouble(bool isSigned) const; - /// @brief Converts this unsigned APInt to a double value. - double roundToDouble() const { - return roundToDouble(false); - } + /// \brief Converts this unsigned APInt to a double value. + double roundToDouble() const { return roundToDouble(false); } - /// @brief Converts this signed APInt to a double value. - double signedRoundToDouble() const { - return roundToDouble(true); - } + /// \brief Converts this signed APInt to a double value. + double signedRoundToDouble() const { return roundToDouble(true); } + /// \brief Converts APInt bits to a double + /// /// The conversion does not do a translation from integer to double, it just /// re-interprets the bits as a double. Note that it is valid to do this on /// any bit width. Exactly 64 bits will be translated. - /// @brief Converts APInt bits to a double double bitsToDouble() const { union { uint64_t I; @@ -1333,10 +1452,11 @@ public: return T.D; } + /// \brief Converts APInt bits to a double + /// /// The conversion does not do a translation from integer to float, it just /// re-interprets the bits as a float. Note that it is valid to do this on /// any bit width. Exactly 32 bits will be translated. - /// @brief Converts APInt bits to a double float bitsToFloat() const { union { unsigned I; @@ -1346,10 +1466,11 @@ public: return T.F; } + /// \brief Converts a double to APInt bits. + /// /// The conversion does not do a translation from double to integer, it just /// re-interprets the bits of the double. - /// @brief Converts a double to APInt bits. - static APInt doubleToBits(double V) { + static APInt LLVM_ATTRIBUTE_UNUSED_RESULT doubleToBits(double V) { union { uint64_t I; double D; @@ -1358,10 +1479,11 @@ public: return APInt(sizeof T * CHAR_BIT, T.I); } + /// \brief Converts a float to APInt bits. + /// /// The conversion does not do a translation from float to integer, it just /// re-interprets the bits of the float. - /// @brief Converts a float to APInt bits. - static APInt floatToBits(float V) { + static APInt LLVM_ATTRIBUTE_UNUSED_RESULT floatToBits(float V) { union { unsigned I; float F; @@ -1371,20 +1493,18 @@ public: } /// @} - /// @name Mathematics Operations + /// \name Mathematics Operations /// @{ - /// @returns the floor log base 2 of this APInt. - unsigned logBase2() const { - return BitWidth - 1 - countLeadingZeros(); - } + /// \returns the floor log base 2 of this APInt. + unsigned logBase2() const { return BitWidth - 1 - countLeadingZeros(); } - /// @returns the ceil log base 2 of this APInt. + /// \returns the ceil log base 2 of this APInt. unsigned ceilLogBase2() const { return BitWidth - (*this - 1).countLeadingZeros(); } - /// @returns the log base 2 of this APInt if its an exact power of two, -1 + /// \returns the log base 2 of this APInt if its an exact power of two, -1 /// otherwise int32_t exactLogBase2() const { if (!isPowerOf2()) @@ -1392,22 +1512,23 @@ public: return logBase2(); } - /// @brief Compute the square root - APInt sqrt() const; + /// \brief Compute the square root + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sqrt() const; + /// \brief Get the absolute value; + /// /// If *this is < 0 then return -(*this), otherwise *this; - /// @brief Get the absolute value; - APInt abs() const { + APInt LLVM_ATTRIBUTE_UNUSED_RESULT abs() const { if (isNegative()) return -(*this); return *this; } - /// @returns the multiplicative inverse for a given modulo. - APInt multiplicativeInverse(const APInt& modulo) const; + /// \returns the multiplicative inverse for a given modulo. + APInt multiplicativeInverse(const APInt &modulo) const; /// @} - /// @name Support for division by constant + /// \name Support for division by constant /// @{ /// Calculate the magic number for signed division by a constant. @@ -1419,18 +1540,17 @@ public: mu magicu(unsigned LeadingZeros = 0) const; /// @} - /// @name Building-block Operations for APInt and APFloat + /// \name Building-block Operations for APInt and APFloat /// @{ - // These building block operations operate on a representation of - // arbitrary precision, two's-complement, bignum integer values. - // They should be sufficient to implement APInt and APFloat bignum - // requirements. Inputs are generally a pointer to the base of an - // array of integer parts, representing an unsigned bignum, and a - // count of how many parts there are. + // These building block operations operate on a representation of arbitrary + // precision, two's-complement, bignum integer values. They should be + // sufficient to implement APInt and APFloat bignum requirements. Inputs are + // generally a pointer to the base of an array of integer parts, representing + // an unsigned bignum, and a count of how many parts there are. - /// Sets the least significant part of a bignum to the input value, - /// and zeroes out higher parts. */ + /// Sets the least significant part of a bignum to the input value, and zeroes + /// out higher parts. static void tcSet(integerPart *, integerPart, unsigned int); /// Assign one bignum to another. @@ -1442,13 +1562,13 @@ public: /// Extract the given bit of a bignum; returns 0 or 1. Zero-based. static int tcExtractBit(const integerPart *, unsigned int bit); - /// Copy the bit vector of width srcBITS from SRC, starting at bit - /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB - /// becomes the least significant bit of DST. All high bits above - /// srcBITS in DST are zero-filled. + /// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to + /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least + /// significant bit of DST. All high bits above srcBITS in DST are + /// zero-filled. static void tcExtract(integerPart *, unsigned int dstCount, - const integerPart *, - unsigned int srcBits, unsigned int srcLSB); + const integerPart *, unsigned int srcBits, + unsigned int srcLSB); /// Set the given bit of a bignum. Zero-based. static void tcSetBit(integerPart *, unsigned int bit); @@ -1456,76 +1576,70 @@ public: /// Clear the given bit of a bignum. Zero-based. static void tcClearBit(integerPart *, unsigned int bit); - /// Returns the bit number of the least or most significant set bit - /// of a number. If the input number has no bits set -1U is - /// returned. + /// Returns the bit number of the least or most significant set bit of a + /// number. If the input number has no bits set -1U is returned. static unsigned int tcLSB(const integerPart *, unsigned int); static unsigned int tcMSB(const integerPart *parts, unsigned int n); /// Negate a bignum in-place. static void tcNegate(integerPart *, unsigned int); - /// DST += RHS + CARRY where CARRY is zero or one. Returns the - /// carry flag. + /// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag. static integerPart tcAdd(integerPart *, const integerPart *, integerPart carry, unsigned); - /// DST -= RHS + CARRY where CARRY is zero or one. Returns the - /// carry flag. + /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag. static integerPart tcSubtract(integerPart *, const integerPart *, integerPart carry, unsigned); - /// DST += SRC * MULTIPLIER + PART if add is true - /// DST = SRC * MULTIPLIER + PART if add is false + /// DST += SRC * MULTIPLIER + PART if add is true + /// DST = SRC * MULTIPLIER + PART if add is false /// - /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC - /// they must start at the same point, i.e. DST == SRC. + /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC they must + /// start at the same point, i.e. DST == SRC. /// - /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is - /// returned. Otherwise DST is filled with the least significant - /// DSTPARTS parts of the result, and if all of the omitted higher - /// parts were zero return zero, otherwise overflow occurred and - /// return one. + /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is returned. + /// Otherwise DST is filled with the least significant DSTPARTS parts of the + /// result, and if all of the omitted higher parts were zero return zero, + /// otherwise overflow occurred and return one. static int tcMultiplyPart(integerPart *dst, const integerPart *src, integerPart multiplier, integerPart carry, unsigned int srcParts, unsigned int dstParts, bool add); - /// DST = LHS * RHS, where DST has the same width as the operands - /// and is filled with the least significant parts of the result. - /// Returns one if overflow occurred, otherwise zero. DST must be - /// disjoint from both operands. - static int tcMultiply(integerPart *, const integerPart *, - const integerPart *, unsigned); + /// DST = LHS * RHS, where DST has the same width as the operands and is + /// filled with the least significant parts of the result. Returns one if + /// overflow occurred, otherwise zero. DST must be disjoint from both + /// operands. + static int tcMultiply(integerPart *, const integerPart *, const integerPart *, + unsigned); - /// DST = LHS * RHS, where DST has width the sum of the widths of - /// the operands. No overflow occurs. DST must be disjoint from - /// both operands. Returns the number of parts required to hold the - /// result. + /// DST = LHS * RHS, where DST has width the sum of the widths of the + /// operands. No overflow occurs. DST must be disjoint from both + /// operands. Returns the number of parts required to hold the result. static unsigned int tcFullMultiply(integerPart *, const integerPart *, const integerPart *, unsigned, unsigned); /// If RHS is zero LHS and REMAINDER are left unchanged, return one. - /// Otherwise set LHS to LHS / RHS with the fractional part - /// discarded, set REMAINDER to the remainder, return zero. i.e. + /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set + /// REMAINDER to the remainder, return zero. i.e. /// /// OLD_LHS = RHS * LHS + REMAINDER /// - /// SCRATCH is a bignum of the same size as the operands and result - /// for use by the routine; its contents need not be initialized - /// and are destroyed. LHS, REMAINDER and SCRATCH must be - /// distinct. + /// SCRATCH is a bignum of the same size as the operands and result for use by + /// the routine; its contents need not be initialized and are destroyed. LHS, + /// REMAINDER and SCRATCH must be distinct. static int tcDivide(integerPart *lhs, const integerPart *rhs, integerPart *remainder, integerPart *scratch, unsigned int parts); - /// Shift a bignum left COUNT bits. Shifted in bits are zero. - /// There are no restrictions on COUNT. + /// Shift a bignum left COUNT bits. Shifted in bits are zero. There are no + /// restrictions on COUNT. static void tcShiftLeft(integerPart *, unsigned int parts, unsigned int count); - /// Shift a bignum right COUNT bits. Shifted in bits are zero. - /// There are no restrictions on COUNT. + /// Shift a bignum right COUNT bits. Shifted in bits are zero. There are no + /// restrictions on COUNT. static void tcShiftRight(integerPart *, unsigned int parts, unsigned int count); @@ -1536,17 +1650,19 @@ public: static void tcComplement(integerPart *, unsigned int); /// Comparison (unsigned) of two bignums. - static int tcCompare(const integerPart *, const integerPart *, - unsigned int); + static int tcCompare(const integerPart *, const integerPart *, unsigned int); /// Increment a bignum in-place. Return the carry flag. static integerPart tcIncrement(integerPart *, unsigned int); + /// Decrement a bignum in-place. Return the borrow flag. + static integerPart tcDecrement(integerPart *, unsigned int); + /// Set the least significant BITS and clear the rest. static void tcSetLeastSignificantBits(integerPart *, unsigned int, unsigned int bits); - /// @brief debug method + /// \brief debug method void dump() const; /// @} @@ -1554,24 +1670,20 @@ public: /// Magic data for optimising signed division by a constant. struct APInt::ms { - APInt m; ///< magic number - unsigned s; ///< shift amount + APInt m; ///< magic number + unsigned s; ///< shift amount }; /// Magic data for optimising unsigned division by a constant. struct APInt::mu { - APInt m; ///< magic number - bool a; ///< add indicator - unsigned s; ///< shift amount + APInt m; ///< magic number + bool a; ///< add indicator + unsigned s; ///< shift amount }; -inline bool operator==(uint64_t V1, const APInt& V2) { - return V2 == V1; -} +inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; } -inline bool operator!=(uint64_t V1, const APInt& V2) { - return V2 != V1; -} +inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; } inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) { I.print(OS, true); @@ -1580,188 +1692,173 @@ inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) { namespace APIntOps { -/// @brief Determine the smaller of two APInts considered to be signed. -inline APInt smin(const APInt &A, const APInt &B) { - return A.slt(B) ? A : B; -} +/// \brief Determine the smaller of two APInts considered to be signed. +inline APInt smin(const APInt &A, const APInt &B) { return A.slt(B) ? A : B; } -/// @brief Determine the larger of two APInts considered to be signed. -inline APInt smax(const APInt &A, const APInt &B) { - return A.sgt(B) ? A : B; -} +/// \brief Determine the larger of two APInts considered to be signed. +inline APInt smax(const APInt &A, const APInt &B) { return A.sgt(B) ? A : B; } -/// @brief Determine the smaller of two APInts considered to be signed. -inline APInt umin(const APInt &A, const APInt &B) { - return A.ult(B) ? A : B; -} +/// \brief Determine the smaller of two APInts considered to be signed. +inline APInt umin(const APInt &A, const APInt &B) { return A.ult(B) ? A : B; } -/// @brief Determine the larger of two APInts considered to be unsigned. -inline APInt umax(const APInt &A, const APInt &B) { - return A.ugt(B) ? A : B; -} +/// \brief Determine the larger of two APInts considered to be unsigned. +inline APInt umax(const APInt &A, const APInt &B) { return A.ugt(B) ? A : B; } -/// @brief Check if the specified APInt has a N-bits unsigned integer value. -inline bool isIntN(unsigned N, const APInt& APIVal) { - return APIVal.isIntN(N); -} +/// \brief Check if the specified APInt has a N-bits unsigned integer value. +inline bool isIntN(unsigned N, const APInt &APIVal) { return APIVal.isIntN(N); } -/// @brief Check if the specified APInt has a N-bits signed integer value. -inline bool isSignedIntN(unsigned N, const APInt& APIVal) { +/// \brief Check if the specified APInt has a N-bits signed integer value. +inline bool isSignedIntN(unsigned N, const APInt &APIVal) { return APIVal.isSignedIntN(N); } -/// @returns true if the argument APInt value is a sequence of ones -/// starting at the least significant bit with the remainder zero. -inline bool isMask(unsigned numBits, const APInt& APIVal) { +/// \returns true if the argument APInt value is a sequence of ones starting at +/// the least significant bit with the remainder zero. +inline bool isMask(unsigned numBits, const APInt &APIVal) { return numBits <= APIVal.getBitWidth() && - APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits); + APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits); } -/// @returns true if the argument APInt value contains a sequence of ones +/// \brief Return true if the argument APInt value contains a sequence of ones /// with the remainder zero. -inline bool isShiftedMask(unsigned numBits, const APInt& APIVal) { - return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal); +inline bool isShiftedMask(unsigned numBits, const APInt &APIVal) { + return isMask(numBits, (APIVal - APInt(numBits, 1)) | APIVal); } -/// @returns a byte-swapped representation of the specified APInt Value. -inline APInt byteSwap(const APInt& APIVal) { - return APIVal.byteSwap(); -} +/// \brief Returns a byte-swapped representation of the specified APInt Value. +inline APInt byteSwap(const APInt &APIVal) { return APIVal.byteSwap(); } -/// @returns the floor log base 2 of the specified APInt value. -inline unsigned logBase2(const APInt& APIVal) { - return APIVal.logBase2(); -} +/// \brief Returns the floor log base 2 of the specified APInt value. +inline unsigned logBase2(const APInt &APIVal) { return APIVal.logBase2(); } -/// GreatestCommonDivisor - This function returns the greatest common -/// divisor of the two APInt values using Euclid's algorithm. -/// @returns the greatest common divisor of Val1 and Val2 -/// @brief Compute GCD of two APInt values. -APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2); +/// \brief Compute GCD of two APInt values. +/// +/// This function returns the greatest common divisor of the two APInt values +/// using Euclid's algorithm. +/// +/// \returns the greatest common divisor of Val1 and Val2 +APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2); +/// \brief Converts the given APInt to a double value. +/// /// Treats the APInt as an unsigned value for conversion purposes. -/// @brief Converts the given APInt to a double value. -inline double RoundAPIntToDouble(const APInt& APIVal) { +inline double RoundAPIntToDouble(const APInt &APIVal) { return APIVal.roundToDouble(); } +/// \brief Converts the given APInt to a double value. +/// /// Treats the APInt as a signed value for conversion purposes. -/// @brief Converts the given APInt to a double value. -inline double RoundSignedAPIntToDouble(const APInt& APIVal) { +inline double RoundSignedAPIntToDouble(const APInt &APIVal) { return APIVal.signedRoundToDouble(); } -/// @brief Converts the given APInt to a float vlalue. -inline float RoundAPIntToFloat(const APInt& APIVal) { +/// \brief Converts the given APInt to a float vlalue. +inline float RoundAPIntToFloat(const APInt &APIVal) { return float(RoundAPIntToDouble(APIVal)); } +/// \brief Converts the given APInt to a float value. +/// /// Treast the APInt as a signed value for conversion purposes. -/// @brief Converts the given APInt to a float value. -inline float RoundSignedAPIntToFloat(const APInt& APIVal) { +inline float RoundSignedAPIntToFloat(const APInt &APIVal) { return float(APIVal.signedRoundToDouble()); } -/// RoundDoubleToAPInt - This function convert a double value to an APInt value. -/// @brief Converts the given double value into a APInt. +/// \brief Converts the given double value into a APInt. +/// +/// This function convert a double value to an APInt value. APInt RoundDoubleToAPInt(double Double, unsigned width); -/// RoundFloatToAPInt - Converts a float value into an APInt value. -/// @brief Converts a float value into a APInt. +/// \brief Converts a float value into a APInt. +/// +/// Converts a float value into an APInt value. inline APInt RoundFloatToAPInt(float Float, unsigned width) { return RoundDoubleToAPInt(double(Float), width); } +/// \brief Arithmetic right-shift function. +/// /// Arithmetic right-shift the APInt by shiftAmt. -/// @brief Arithmetic right-shift function. -inline APInt ashr(const APInt& LHS, unsigned shiftAmt) { +inline APInt ashr(const APInt &LHS, unsigned shiftAmt) { return LHS.ashr(shiftAmt); } +/// \brief Logical right-shift function. +/// /// Logical right-shift the APInt by shiftAmt. -/// @brief Logical right-shift function. -inline APInt lshr(const APInt& LHS, unsigned shiftAmt) { +inline APInt lshr(const APInt &LHS, unsigned shiftAmt) { return LHS.lshr(shiftAmt); } +/// \brief Left-shift function. +/// /// Left-shift the APInt by shiftAmt. -/// @brief Left-shift function. -inline APInt shl(const APInt& LHS, unsigned shiftAmt) { +inline APInt shl(const APInt &LHS, unsigned shiftAmt) { return LHS.shl(shiftAmt); } +/// \brief Signed division function for APInt. +/// /// Signed divide APInt LHS by APInt RHS. -/// @brief Signed division function for APInt. -inline APInt sdiv(const APInt& LHS, const APInt& RHS) { - return LHS.sdiv(RHS); -} +inline APInt sdiv(const APInt &LHS, const APInt &RHS) { return LHS.sdiv(RHS); } +/// \brief Unsigned division function for APInt. +/// /// Unsigned divide APInt LHS by APInt RHS. -/// @brief Unsigned division function for APInt. -inline APInt udiv(const APInt& LHS, const APInt& RHS) { - return LHS.udiv(RHS); -} +inline APInt udiv(const APInt &LHS, const APInt &RHS) { return LHS.udiv(RHS); } +/// \brief Function for signed remainder operation. +/// /// Signed remainder operation on APInt. -/// @brief Function for signed remainder operation. -inline APInt srem(const APInt& LHS, const APInt& RHS) { - return LHS.srem(RHS); -} +inline APInt srem(const APInt &LHS, const APInt &RHS) { return LHS.srem(RHS); } +/// \brief Function for unsigned remainder operation. +/// /// Unsigned remainder operation on APInt. -/// @brief Function for unsigned remainder operation. -inline APInt urem(const APInt& LHS, const APInt& RHS) { - return LHS.urem(RHS); -} +inline APInt urem(const APInt &LHS, const APInt &RHS) { return LHS.urem(RHS); } +/// \brief Function for multiplication operation. +/// /// Performs multiplication on APInt values. -/// @brief Function for multiplication operation. -inline APInt mul(const APInt& LHS, const APInt& RHS) { - return LHS * RHS; -} +inline APInt mul(const APInt &LHS, const APInt &RHS) { return LHS * RHS; } +/// \brief Function for addition operation. +/// /// Performs addition on APInt values. -/// @brief Function for addition operation. -inline APInt add(const APInt& LHS, const APInt& RHS) { - return LHS + RHS; -} +inline APInt add(const APInt &LHS, const APInt &RHS) { return LHS + RHS; } +/// \brief Function for subtraction operation. +/// /// Performs subtraction on APInt values. -/// @brief Function for subtraction operation. -inline APInt sub(const APInt& LHS, const APInt& RHS) { - return LHS - RHS; -} +inline APInt sub(const APInt &LHS, const APInt &RHS) { return LHS - RHS; } +/// \brief Bitwise AND function for APInt. +/// /// Performs bitwise AND operation on APInt LHS and /// APInt RHS. -/// @brief Bitwise AND function for APInt. -inline APInt And(const APInt& LHS, const APInt& RHS) { - return LHS & RHS; -} +inline APInt And(const APInt &LHS, const APInt &RHS) { return LHS & RHS; } +/// \brief Bitwise OR function for APInt. +/// /// Performs bitwise OR operation on APInt LHS and APInt RHS. -/// @brief Bitwise OR function for APInt. -inline APInt Or(const APInt& LHS, const APInt& RHS) { - return LHS | RHS; -} +inline APInt Or(const APInt &LHS, const APInt &RHS) { return LHS | RHS; } +/// \brief Bitwise XOR function for APInt. +/// /// Performs bitwise XOR operation on APInt. -/// @brief Bitwise XOR function for APInt. -inline APInt Xor(const APInt& LHS, const APInt& RHS) { - return LHS ^ RHS; -} +inline APInt Xor(const APInt &LHS, const APInt &RHS) { return LHS ^ RHS; } +/// \brief Bitwise complement function. +/// /// Performs a bitwise complement operation on APInt. -/// @brief Bitwise complement function. -inline APInt Not(const APInt& APIVal) { - return ~APIVal; -} +inline APInt Not(const APInt &APIVal) { return ~APIVal; } } // End of APIntOps namespace - // See friend declaration above. This additional declaration is required in - // order to compile LLVM with IBM xlC compiler. - hash_code hash_value(const APInt &Arg); +// See friend declaration above. This additional declaration is required in +// order to compile LLVM with IBM xlC compiler. +hash_code hash_value(const APInt &Arg); } // End of llvm namespace #endif diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 11be4c513e2c3..ad035a7c30df4 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -68,18 +68,18 @@ public: } using APInt::toString; - APSInt trunc(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const { return APSInt(APInt::trunc(width), IsUnsigned); } - APSInt extend(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extend(uint32_t width) const { if (IsUnsigned) return APSInt(zext(width), IsUnsigned); else return APSInt(sext(width), IsUnsigned); } - APSInt extOrTrunc(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extOrTrunc(uint32_t width) const { if (IsUnsigned) return APSInt(zextOrTrunc(width), IsUnsigned); else @@ -212,7 +212,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); } - APSInt And(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APSInt& RHS) const { return this->operator&(RHS); } @@ -220,7 +220,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); } - APSInt Or(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APSInt& RHS) const { return this->operator|(RHS); } @@ -229,7 +229,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); } - APSInt Xor(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APSInt& RHS) const { return this->operator^(RHS); } diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index d4152ec727b13..e5562c3683098 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -80,9 +80,16 @@ namespace llvm { /// Construct an ArrayRef from a C array. template <size_t N> - /*implicit*/ ArrayRef(const T (&Arr)[N]) + /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {} +#if LLVM_HAS_INITIALIZER_LISTS + /// Construct an ArrayRef from a std::initializer_list. + /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec) + : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()), + Length(Vec.size()) {} +#endif + /// @} /// @name Simple Operations /// @{ @@ -178,6 +185,8 @@ namespace llvm { public: typedef T *iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + /// Construct an empty MutableArrayRef. /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} @@ -212,6 +221,9 @@ namespace llvm { iterator begin() const { return data(); } iterator end() const { return data() + this->size(); } + reverse_iterator rbegin() const { return reverse_iterator(end()); } + reverse_iterator rend() const { return reverse_iterator(begin()); } + /// front - Get the first element. T &front() const { assert(!this->empty()); diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 82cfdf437d4e7..8fb538f68fcf5 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -138,8 +138,15 @@ public: /// all - Returns true if all bits are set. bool all() const { - // TODO: Optimize this. - return count() == size(); + for (unsigned i = 0; i < Size / BITWORD_SIZE; ++i) + if (Bits[i] != ~0UL) + return false; + + // If bits remain check that they are ones. The unused bits are always zero. + if (unsigned Remainder = Size % BITWORD_SIZE) + return Bits[Size / BITWORD_SIZE] == (1UL << Remainder) - 1; + + return true; } /// none - Returns true if none of the bits are set. @@ -153,9 +160,9 @@ public: for (unsigned i = 0; i < NumBitWords(size()); ++i) if (Bits[i] != 0) { if (sizeof(BitWord) == 4) - return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]); if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); llvm_unreachable("Unsupported!"); } return -1; @@ -176,9 +183,9 @@ public: if (Copy != 0) { if (sizeof(BitWord) == 4) - return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy); + return WordPos * BITWORD_SIZE + countTrailingZeros((uint32_t)Copy); if (sizeof(BitWord) == 8) - return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); + return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); llvm_unreachable("Unsupported!"); } @@ -186,9 +193,9 @@ public: for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i) if (Bits[i] != 0) { if (sizeof(BitWord) == 4) - return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]); if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); llvm_unreachable("Unsupported!"); } return -1; diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 31fd6d899daec..ce322cce4e0b4 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -64,7 +64,9 @@ public: return const_iterator(getBucketsEnd(), getBucketsEnd(), true); } - bool empty() const { return getNumEntries() == 0; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { + return getNumEntries() == 0; + } unsigned size() const { return getNumEntries(); } /// Grow the densemap so that it has at least Size buckets. Does not shrink @@ -222,11 +224,11 @@ public: if (LookupBucketFor(Key, TheBucket)) return *TheBucket; - return *InsertIntoBucket(Key, ValueT(), TheBucket); + return *InsertIntoBucket(std::move(Key), ValueT(), TheBucket); } ValueT &operator[](KeyT &&Key) { - return FindAndConstruct(Key).second; + return FindAndConstruct(std::move(Key)).second; } #endif @@ -436,9 +438,8 @@ private: this->grow(NumBuckets * 2); LookupBucketFor(Key, TheBucket); NumBuckets = getNumBuckets(); - } - if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) { - this->grow(NumBuckets * 2); + } else if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) { + this->grow(NumBuckets); LookupBucketFor(Key, TheBucket); } assert(TheBucket); @@ -713,13 +714,13 @@ public: init(NumInitBuckets); } - SmallDenseMap(const SmallDenseMap &other) { + SmallDenseMap(const SmallDenseMap &other) : BaseT() { init(0); copyFrom(other); } #if LLVM_HAS_RVALUE_REFERENCES - SmallDenseMap(SmallDenseMap &&other) { + SmallDenseMap(SmallDenseMap &&other) : BaseT() { init(0); swap(other); } diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 91794dea69819..1b2c94c35f84e 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -352,7 +352,8 @@ template<class T> class FoldingSetBucketIterator; template<typename T> inline bool DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID, - unsigned IDHash, FoldingSetNodeID &TempID) { + unsigned /*IDHash*/, + FoldingSetNodeID &TempID) { FoldingSetTrait<T>::Profile(X, TempID); return TempID == ID; } @@ -366,7 +367,7 @@ template<typename T, typename Ctx> inline bool DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X, const FoldingSetNodeID &ID, - unsigned IDHash, + unsigned /*IDHash*/, FoldingSetNodeID &TempID, Ctx Context) { ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context); diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index a667479a4d176..8f8fb98770405 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -211,6 +211,7 @@ public: friend class ImmutableMap; public: + typedef ptrdiff_t difference_type; typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type; typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference; typedef typename iterator::value_type *pointer; diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index fbdf066e61ab6..ad349699e2a11 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -851,6 +851,18 @@ PROFILE_INTEGER_INFO(unsigned long long) #undef PROFILE_INTEGER_INFO +/// Profile traits for booleans. +template <> +struct ImutProfileInfo<bool> { + typedef const bool value_type; + typedef const bool& value_type_ref; + + static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + ID.AddBoolean(X); + } +}; + + /// Generic profile trait for pointer types. We treat pointers as /// references to unique objects. template <typename T> @@ -1060,6 +1072,7 @@ public: friend class ImmutableSet<ValT,ValInfo>; public: + typedef ptrdiff_t difference_type; typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; typedef typename iterator::value_type *pointer; diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index c4083eed6a993..1ca3288a350ab 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -496,7 +496,7 @@ public: NodeRef() {} /// operator bool - Detect a null ref. - operator bool() const { return pip.getOpaqueValue(); } + LLVM_EXPLICIT operator bool() const { return pip.getOpaqueValue(); } /// NodeRef - Create a reference to the node p with n elements. template <typename NodeT> @@ -612,7 +612,7 @@ public: /// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as /// possible. This may cause the node to grow by 1, or it may cause the node /// to shrink because of coalescing. -/// @param i Starting index = insertFrom(0, size, a) +/// @param Pos Starting index = insertFrom(0, size, a) /// @param Size Number of elements in node. /// @param a Interval start. /// @param b Interval stop. @@ -1956,7 +1956,7 @@ iterator::eraseNode(unsigned Level) { /// overflow - Distribute entries of the current node evenly among /// its siblings and ensure that the current node is not full. /// This may require allocating a new node. -/// @param NodeT The type of node at Level (Leaf or Branch). +/// @tparam NodeT The type of node at Level (Leaf or Branch). /// @param Level path index of the overflowing node. /// @return True when the tree height was changed. template <typename KeyT, typename ValT, unsigned N, typename Traits> diff --git a/include/llvm/ADT/NullablePtr.h b/include/llvm/ADT/NullablePtr.h deleted file mode 100644 index 8ddfd5d20abdc..0000000000000 --- a/include/llvm/ADT/NullablePtr.h +++ /dev/null @@ -1,52 +0,0 @@ -//===- llvm/ADT/NullablePtr.h - A pointer that allows null ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines and implements the NullablePtr class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_NULLABLEPTR_H -#define LLVM_ADT_NULLABLEPTR_H - -#include <cassert> -#include <cstddef> - -namespace llvm { -/// NullablePtr pointer wrapper - NullablePtr is used for APIs where a -/// potentially-null pointer gets passed around that must be explicitly handled -/// in lots of places. By putting a wrapper around the null pointer, it makes -/// it more likely that the null pointer case will be handled correctly. -template<class T> -class NullablePtr { - T *Ptr; -public: - NullablePtr(T *P = 0) : Ptr(P) {} - - bool isNull() const { return Ptr == 0; } - bool isNonNull() const { return Ptr != 0; } - - /// get - Return the pointer if it is non-null. - const T *get() const { - assert(Ptr && "Pointer wasn't checked for null!"); - return Ptr; - } - - /// get - Return the pointer if it is non-null. - T *get() { - assert(Ptr && "Pointer wasn't checked for null!"); - return Ptr; - } - - T *getPtrOrNull() { return Ptr; } - const T *getPtrOrNull() const { return Ptr; } -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h index 86f9feee2cb4c..6b9e42eaec0f1 100644 --- a/include/llvm/ADT/OwningPtr.h +++ b/include/llvm/ADT/OwningPtr.h @@ -70,8 +70,9 @@ public: T *operator->() const { return Ptr; } T *get() const { return Ptr; } - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } bool operator!() const { return Ptr == 0; } + bool isValid() const { return Ptr != 0; } void swap(OwningPtr &RHS) { T *Tmp = RHS.Ptr; @@ -132,7 +133,7 @@ public: } T *get() const { return Ptr; } - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } bool operator!() const { return Ptr == 0; } void swap(OwningArrayPtr &RHS) { diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 0299a83c4411c..0cfd470003af7 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_POINTERINTPAIR_H #define LLVM_ADT_POINTERINTPAIR_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> @@ -40,7 +41,7 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned, typename PtrTraits = PointerLikeTypeTraits<PointerTy> > class PointerIntPair { intptr_t Value; - enum { + enum LLVM_ENUM_INT_TYPE(uintptr_t) { /// PointerBitMask - The bits that come from the pointer. PointerBitMask = ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1), diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index f42515ac77a74..05d362feab22b 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -15,6 +15,7 @@ #ifndef LLVM_ADT_POINTERUNION_H #define LLVM_ADT_POINTERUNION_H +#include "llvm/Support/Compiler.h" #include "llvm/ADT/PointerIntPair.h" namespace llvm { @@ -71,7 +72,7 @@ namespace llvm { /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0" /// X = P.get<int*>(); // ok. /// Y = P.get<float*>(); // runtime assertion failure. - /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag) + /// Z = P.get<double*>(); // compile time failure. /// P = (float*)0; /// Y = P.get<float*>(); // ok. /// X = P.get<int*>(); // runtime assertion failure. @@ -109,7 +110,7 @@ namespace llvm { // we recursively strip off low bits if we have a nested PointerUnion. return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer()); } - operator bool() const { return !isNull(); } + LLVM_EXPLICIT operator bool() const { return !isNull(); } /// is<T>() return true if the Union currently holds the type matching T. template<typename T> @@ -174,7 +175,19 @@ namespace llvm { return V; } }; - + + template<typename PT1, typename PT2> + static bool operator==(PointerUnion<PT1, PT2> lhs, + PointerUnion<PT1, PT2> rhs) { + return lhs.getOpaqueValue() == rhs.getOpaqueValue(); + } + + template<typename PT1, typename PT2> + static bool operator!=(PointerUnion<PT1, PT2> lhs, + PointerUnion<PT1, PT2> rhs) { + return lhs.getOpaqueValue() != rhs.getOpaqueValue(); + } + // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. template<typename PT1, typename PT2> @@ -251,7 +264,7 @@ namespace llvm { /// isNull - Return true if the pointer held in the union is null, /// regardless of which type it is. bool isNull() const { return Val.isNull(); } - operator bool() const { return !isNull(); } + LLVM_EXPLICIT operator bool() const { return !isNull(); } /// is<T>() return true if the Union currently holds the type matching T. template<typename T> @@ -359,7 +372,7 @@ namespace llvm { /// isNull - Return true if the pointer held in the union is null, /// regardless of which type it is. bool isNull() const { return Val.isNull(); } - operator bool() const { return !isNull(); } + LLVM_EXPLICIT operator bool() const { return !isNull(); } /// is<T>() return true if the Union currently holds the type matching T. template<typename T> diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index dacda36521290..3aa8183353215 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -217,6 +217,22 @@ inline tier<T1, T2> tie(T1& f, T2& s) { return tier<T1, T2>(f, s); } +/// \brief Function object to check whether the first component of a std::pair +/// compares less than the first component of another std::pair. +struct less_first { + template <typename T> bool operator()(const T &lhs, const T &rhs) const { + return lhs.first < rhs.first; + } +}; + +/// \brief Function object to check whether the second component of a std::pair +/// compares less than the second component of another std::pair. +struct less_second { + template <typename T> bool operator()(const T &lhs, const T &rhs) const { + return lhs.second < rhs.second; + } +}; + //===----------------------------------------------------------------------===// // Extra additions for arrays //===----------------------------------------------------------------------===// @@ -277,12 +293,16 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) { get_array_pod_sort_comparator(*Start)); } -template<class IteratorTy> -inline void array_pod_sort(IteratorTy Start, IteratorTy End, - int (*Compare)(const void*, const void*)) { +template <class IteratorTy> +inline void array_pod_sort( + IteratorTy Start, IteratorTy End, + int (*Compare)( + const typename std::iterator_traits<IteratorTy>::value_type *, + const typename std::iterator_traits<IteratorTy>::value_type *)) { // Don't dereference start iterator of empty sequence. if (Start == End) return; - qsort(&*Start, End-Start, sizeof(*Start), Compare); + qsort(&*Start, End - Start, sizeof(*Start), + reinterpret_cast<int (*)(const void *, const void *)>(Compare)); } //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index d2f7286c2596d..5eda37c675fee 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -170,7 +170,7 @@ public: vector_.pop_back(); } - T pop_back_val() { + T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { T Ret = back(); pop_back(); return Ret; diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 652492a1538cb..86949b2ae3420 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -216,9 +216,9 @@ public: if (Bits == 0) return -1; if (NumBaseBits == 32) - return CountTrailingZeros_32(Bits); + return countTrailingZeros(Bits); if (NumBaseBits == 64) - return CountTrailingZeros_64(Bits); + return countTrailingZeros(Bits); llvm_unreachable("Unsupported!"); } return getPointer()->find_first(); @@ -234,9 +234,9 @@ public: if (Bits == 0 || Prev + 1 >= getSmallSize()) return -1; if (NumBaseBits == 32) - return CountTrailingZeros_32(Bits); + return countTrailingZeros(Bits); if (NumBaseBits == 64) - return CountTrailingZeros_64(Bits); + return countTrailingZeros(Bits); llvm_unreachable("Unsupported!"); } return getPointer()->find_next(Prev); @@ -426,6 +426,40 @@ public: return *this; } + /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS. + SmallBitVector &reset(const SmallBitVector &RHS) { + if (isSmall() && RHS.isSmall()) + setSmallBits(getSmallBits() & ~RHS.getSmallBits()); + else if (!isSmall() && !RHS.isSmall()) + getPointer()->reset(*RHS.getPointer()); + else + for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) + if (RHS.test(i)) + reset(i); + + return *this; + } + + /// test - Check if (This - RHS) is zero. + /// This is the same as reset(RHS) and any(). + bool test(const SmallBitVector &RHS) const { + if (isSmall() && RHS.isSmall()) + return (getSmallBits() & ~RHS.getSmallBits()) != 0; + if (!isSmall() && !RHS.isSmall()) + return getPointer()->test(*RHS.getPointer()); + + unsigned i, e; + for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i) + if (test(i) && !RHS.test(i)) + return true; + + for (e = size(); i != e; ++i) + if (test(i)) + return true; + + return false; + } + SmallBitVector &operator|=(const SmallBitVector &RHS) { resize(std::max(size(), RHS.size())); if (isSmall()) diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 8c7304197f34f..bd0d8838ef02b 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -71,7 +71,7 @@ protected: ~SmallPtrSetImpl(); public: - bool empty() const { return size() == 0; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; } unsigned size() const { return NumElements; } void clear() { diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 7ba0a714bfc76..505aa8d8ae618 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -53,7 +53,7 @@ public: return size_t((char*)CapacityX - (char*)BeginX); } - bool empty() const { return BeginX == EndX; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; } }; template <typename T, unsigned N> struct SmallVectorStorage; @@ -427,7 +427,7 @@ public: this->grow(N); } - T pop_back_val() { + T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { #if LLVM_HAS_RVALUE_REFERENCES T Result = ::std::move(this->back()); #else diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index 306e92832f0b0..7a10f857044d6 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -137,9 +137,9 @@ public: for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) if (Bits[i] != 0) { if (sizeof(BitWord) == 4) - return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); llvm_unreachable("Unsupported!"); } llvm_unreachable("Illegal empty element"); @@ -162,9 +162,9 @@ public: if (Copy != 0) { if (sizeof(BitWord) == 4) - return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy); + return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); if (sizeof(BitWord) == 8) - return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); + return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); llvm_unreachable("Unsupported!"); } @@ -172,9 +172,9 @@ public: for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i) if (Bits[i] != 0) { if (sizeof(BitWord) == 4) - return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); if (sizeof(BitWord) == 8) - return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); + return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); llvm_unreachable("Unsupported!"); } return -1; diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index d2887c5c2c56f..56dbb5b806899 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H +#include <iterator> #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -159,6 +160,48 @@ static inline StringRef getOrdinalSuffix(unsigned Val) { } } +template <typename IteratorT> +inline std::string join_impl(IteratorT Begin, IteratorT End, + StringRef Separator, std::input_iterator_tag) { + std::string S; + if (Begin == End) + return S; + + S += (*Begin); + while (++Begin != End) { + S += Separator; + S += (*Begin); + } + return S; +} + +template <typename IteratorT> +inline std::string join_impl(IteratorT Begin, IteratorT End, + StringRef Separator, std::forward_iterator_tag) { + std::string S; + if (Begin == End) + return S; + + size_t Len = (std::distance(Begin, End) - 1) * Separator.size(); + for (IteratorT I = Begin; I != End; ++I) + Len += (*Begin).size(); + S.reserve(Len); + S += (*Begin); + while (++Begin != End) { + S += Separator; + S += (*Begin); + } + return S; +} + +/// Joins the strings in the range [Begin, End), adding Separator between +/// the elements. +template <typename IteratorT> +inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) { + typedef typename std::iterator_traits<IteratorT>::iterator_category tag; + return join_impl(Begin, End, Separator, tag()); +} + } // End llvm namespace #endif diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index d01437b61c2bb..0838ebe91f1ba 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -102,6 +102,13 @@ public: bool empty() const { return NumItems == 0; } unsigned size() const { return NumItems; } + + void swap(StringMapImpl &Other) { + std::swap(TheTable, Other.TheTable); + std::swap(NumBuckets, Other.NumBuckets); + std::swap(NumItems, Other.NumItems); + std::swap(NumTombstones, Other.NumTombstones); + } }; /// StringMapEntry - This is used to represent one value that is inserted into @@ -109,6 +116,7 @@ public: /// and data. template<typename ValueTy> class StringMapEntry : public StringMapEntryBase { + StringMapEntry(StringMapEntry &E) LLVM_DELETED_FUNCTION; public: ValueTy second; @@ -409,6 +417,8 @@ protected: public: typedef StringMapEntry<ValueTy> value_type; + StringMapConstIterator() : Ptr(0) { } + explicit StringMapConstIterator(StringMapEntryBase **Bucket, bool NoAdvance = false) : Ptr(Bucket) { @@ -448,6 +458,7 @@ private: template<typename ValueTy> class StringMapIterator : public StringMapConstIterator<ValueTy> { public: + StringMapIterator() {} explicit StringMapIterator(StringMapEntryBase **Bucket, bool NoAdvance = false) : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) { diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index d013d05623252..ec0c2849f37ef 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -19,7 +19,7 @@ #include <utility> namespace llvm { - template<typename T> + template <typename T> class SmallVectorImpl; class APInt; class hash_code; @@ -175,7 +175,7 @@ namespace llvm { /// transform one of the given strings into the other. If zero, /// the strings are identical. unsigned edit_distance(StringRef Other, bool AllowReplacements = true, - unsigned MaxEditDistance = 0); + unsigned MaxEditDistance = 0) const; /// str - Get the contents as an std::string. std::string str() const { @@ -210,12 +210,18 @@ namespace llvm { compareMemory(Data, Prefix.Data, Prefix.Length) == 0; } + /// Check if this string starts with the given \p Prefix, ignoring case. + bool startswith_lower(StringRef Prefix) const; + /// Check if this string ends with the given \p Suffix. bool endswith(StringRef Suffix) const { return Length >= Suffix.Length && compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; } + /// Check if this string ends with the given \p Suffix, ignoring case. + bool endswith_lower(StringRef Suffix) const; + /// @} /// @name String Searching /// @{ @@ -548,6 +554,10 @@ namespace llvm { template <typename T> struct isPodLike; template <> struct isPodLike<StringRef> { static const bool value = true; }; + /// Construct a string ref from a boolean. + inline StringRef toStringRef(bool B) { + return StringRef(B ? "true" : "false"); + } } #endif diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 3a72e8704f61d..84e0b29d1fe06 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -14,30 +14,33 @@ // Some system headers or GCC predefined macros conflict with identifiers in // this file. Undefine them here. +#undef NetBSD #undef mips #undef sparc namespace llvm { -/// Triple - Helper class for working with target triples. +/// Triple - Helper class for working with autoconf configuration names. For +/// historical reasons, we also call these 'triples' (they used to contain +/// exactly three fields). /// -/// Target triples are strings in the canonical form: +/// Configuration names are strings in the canonical form: /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM /// or /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT /// /// This class is used for clients which want to support arbitrary -/// target triples, but also want to implement certain special -/// behavior for particular targets. This class isolates the mapping -/// from the components of the target triple to well known IDs. +/// configuration names, but also want to implement certain special +/// behavior for particular configurations. This class isolates the mapping +/// from the components of the configuration name to well known IDs. /// /// At its core the Triple class is designed to be a wrapper for a triple /// string; the constructor does not change or normalize the triple string. /// Clients that need to handle the non-canonical triples that users often /// specify should use the normalize method. /// -/// See autoconf/config.guess for a glimpse into what triples look like in -/// practice. +/// See autoconf/config.guess for a glimpse into what configuration names +/// look like in practice. class Triple { public: enum ArchType { @@ -53,6 +56,7 @@ public: msp430, // MSP430: msp430 ppc, // PPC: powerpc ppc64, // PPC64: powerpc64, ppu + ppc64le, // PPC64LE: powerpc64le r600, // R600: AMD GPUs HD2XXX - HD6XXX sparc, // Sparc: sparc sparcv9, // Sparcv9: Sparcv9 @@ -62,7 +66,6 @@ public: x86, // X86: i[3-9]86 x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore - mblaze, // MBlaze: mblaze nvptx, // NVPTX: 32-bit nvptx64, // NVPTX: 64-bit le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) @@ -79,7 +82,8 @@ public: BGP, BGQ, Freescale, - IBM + IBM, + NVIDIA }; enum OSType { UnknownOS, @@ -105,7 +109,9 @@ public: NaCl, // Native Client CNK, // BG/P Compute-Node Kernel Bitrig, - AIX + AIX, + CUDA, // NVIDIA CUDA + NVCL // NVIDIA OpenCL }; enum EnvironmentType { UnknownEnvironment, @@ -313,7 +319,12 @@ public: return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; } - /// isOSWindows - Is this a "Windows" OS. + /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment. + bool isOSMSVCRT() const { + return getOS() == Triple::Win32 || getOS() == Triple::MinGW32; + } + + /// \brief Tests whether the OS is Windows. bool isOSWindows() const { return getOS() == Triple::Win32 || isOSCygMing(); } @@ -323,6 +334,11 @@ public: return getOS() == Triple::NaCl; } + /// \brief Tests whether the OS is Linux. + bool isOSLinux() const { + return getOS() == Triple::Linux; + } + /// \brief Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return !isOSDarwin() && !isOSWindows(); diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 71dab2ef551c7..6aeaa91f1b167 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -382,7 +382,9 @@ public: // Miscellaneous inspection routines. size_type max_size() const { return size_type(-1); } - bool empty() const { return Head == 0 || Head == getTail(); } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { + return Head == 0 || Head == getTail(); + } // Front and back accessor functions... reference front() { @@ -534,7 +536,7 @@ public: // Functionality derived from other functions defined above... // - size_type size() const { + size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const { if (Head == 0) return 0; // Don't require construction of sentinel if empty. return std::distance(begin(), end()); } diff --git a/include/llvm/ADT/polymorphic_ptr.h b/include/llvm/ADT/polymorphic_ptr.h new file mode 100644 index 0000000000000..b8d8d71238e3c --- /dev/null +++ b/include/llvm/ADT/polymorphic_ptr.h @@ -0,0 +1,117 @@ +//===- llvm/ADT/polymorphic_ptr.h - Smart copyable owned ptr ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides a polymorphic_ptr class template. See the class comments +/// for details about this API, its intended use cases, etc. +/// +/// The primary motivation here is to work around the necessity of copy +/// semantics in C++98. This is typically used where any actual copies are +/// incidental or unnecessary. As a consequence, it is expected to cease to be +/// useful and be removed when we can directly rely on move-only types. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_POLYMORPHIC_PTR_H +#define LLVM_ADT_POLYMORPHIC_PTR_H + +#include "llvm/Support/Compiler.h" + +namespace llvm { + +/// \brief An owning, copyable polymorphic smart pointer. +/// +/// This pointer exists to provide copyable owned smart pointer. Rather than +/// shared ownership semantics, it has unique ownership semantics and deep copy +/// semantics. It is copyable by requiring that the underlying type exposes +/// a method which can produce a (heap allocated) clone. +/// +/// Note that in almost all scenarios use of this could be avoided if we could +/// build move-only containers of a std::unique_ptr, but until then this +/// provides an effective way to place polymorphic objects in a container. +template <typename T> class polymorphic_ptr { + T *ptr; + +public: + polymorphic_ptr(T *ptr = 0) : ptr(ptr) {} + polymorphic_ptr(const polymorphic_ptr &arg) : ptr(arg ? arg->clone() : 0) {} +#if LLVM_HAS_RVALUE_REFERENCES + polymorphic_ptr(polymorphic_ptr &&arg) : ptr(arg.take()) {} +#endif + ~polymorphic_ptr() { delete ptr; } + + polymorphic_ptr &operator=(polymorphic_ptr arg) { + swap(arg); + return *this; + } + polymorphic_ptr &operator=(T *arg) { + if (arg != ptr) { + delete ptr; + ptr = arg; + } + return *this; + } + + T &operator*() const { return *ptr; } + T *operator->() const { return ptr; } + LLVM_EXPLICIT operator bool() const { return ptr != 0; } + bool operator!() const { return ptr == 0; } + + T *get() const { return ptr; } + + T *take() { + T *tmp = ptr; + ptr = 0; + return tmp; + } + + void swap(polymorphic_ptr &arg) { + T *tmp = ptr; + ptr = arg.ptr; + arg.ptr = tmp; + } +}; + +template <typename T> +void swap(polymorphic_ptr<T> &lhs, polymorphic_ptr<T> &rhs) { + lhs.swap(rhs); +} + +template <typename T, typename U> +bool operator==(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) { + return lhs.get() == rhs.get(); +} + +template <typename T, typename U> +bool operator!=(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) { + return lhs.get() != rhs.get(); +} + +template <typename T, typename U> +bool operator==(const polymorphic_ptr<T> &lhs, U *rhs) { + return lhs.get() == rhs; +} + +template <typename T, typename U> +bool operator!=(const polymorphic_ptr<T> &lhs, U *rhs) { + return lhs.get() != rhs; +} + +template <typename T, typename U> +bool operator==(T *lhs, const polymorphic_ptr<U> &rhs) { + return lhs == rhs.get(); +} + +template <typename T, typename U> +bool operator!=(T *lhs, const polymorphic_ptr<U> &rhs) { + return lhs != rhs.get(); +} + +} + +#endif |
