Removed trailing whitespace.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62000 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Misha Brukman
2009-01-09 19:25:42 +00:00
parent 6e7a1617ac
commit 3a54b3dc87
30 changed files with 924 additions and 924 deletions

View File

@@ -191,14 +191,14 @@ namespace llvm {
static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) { static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) {
return APFloat(Sem, fcNaN, Negative); return APFloat(Sem, fcNaN, Negative);
} }
/// Profile - Used to insert APFloat objects, or objects that contain /// Profile - Used to insert APFloat objects, or objects that contain
/// APFloat objects, into FoldingSets. /// APFloat objects, into FoldingSets.
void Profile(FoldingSetNodeID& NID) const; void Profile(FoldingSetNodeID& NID) const;
/// @brief Used by the Bitcode serializer to emit APInts to Bitcode. /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
void Emit(Serializer& S) const; void Emit(Serializer& S) const;
/// @brief Used by the Bitcode deserializer to deserialize APInts. /// @brief Used by the Bitcode deserializer to deserialize APInts.
static APFloat ReadVal(Deserializer& D); static APFloat ReadVal(Deserializer& D);

View File

@@ -26,10 +26,10 @@ namespace llvm {
class Deserializer; class Deserializer;
class FoldingSetNodeID; class FoldingSetNodeID;
class raw_ostream; class raw_ostream;
template<typename T> template<typename T>
class SmallVectorImpl; class SmallVectorImpl;
/* An unsigned host type used as a single part of a multi-part /* An unsigned host type used as a single part of a multi-part
bignum. */ bignum. */
typedef uint64_t integerPart; typedef uint64_t integerPart;
@@ -43,20 +43,20 @@ namespace llvm {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// APInt - This class represents arbitrary precision constant integral values. /// APInt - This class represents arbitrary precision constant integral values.
/// It is a functional replacement for common case unsigned integer type like /// It is a functional replacement for common case unsigned integer type like
/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width /// "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 /// 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 /// than 64-bits of precision. APInt provides a variety of arithmetic operators
/// and methods to manipulate integer values of any bit-width. It supports both /// and methods to manipulate integer values of any bit-width. It supports both
/// the typical integer arithmetic and comparison operations as well as bitwise /// the typical integer arithmetic and comparison operations as well as bitwise
/// manipulation. /// manipulation.
/// ///
/// The class has several invariants worth noting: /// The class has several invariants worth noting:
/// * All bit, byte, and word positions are zero-based. /// * All bit, byte, and word positions are zero-based.
/// * Once the bit width is set, it doesn't change except by the Truncate, /// * Once the bit width is set, it doesn't change except by the Truncate,
/// SignExtend, or ZeroExtend operations. /// SignExtend, or ZeroExtend operations.
/// * All binary operators must be on APInt instances of the same bit width. /// * All binary operators must be on APInt instances of the same bit width.
/// Attempting to use these operators on instances with different bit /// Attempting to use these operators on instances with different bit
/// widths will yield an assertion. /// widths will yield an assertion.
/// * The value is stored canonically as an unsigned value. For operations /// * The value is stored canonically as an unsigned value. For operations
/// where it makes a difference, there are both signed and unsigned variants /// where it makes a difference, there are both signed and unsigned variants
@@ -93,35 +93,35 @@ class APInt {
/// @returns true if the number of bits <= 64, false otherwise. /// @returns true if the number of bits <= 64, false otherwise.
/// @brief Determine if this APInt just has one word to store value. /// @brief Determine if this APInt just has one word to store value.
bool isSingleWord() const { bool isSingleWord() const {
return BitWidth <= APINT_BITS_PER_WORD; return BitWidth <= APINT_BITS_PER_WORD;
} }
/// @returns the word position for the specified bit position. /// @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.
static uint32_t whichWord(uint32_t bitPosition) { static uint32_t whichWord(uint32_t bitPosition) {
return bitPosition / APINT_BITS_PER_WORD; return bitPosition / APINT_BITS_PER_WORD;
} }
/// @returns the bit position in a word for the specified bit position /// @returns the bit position in a word for the specified bit position
/// in the APInt. /// in the APInt.
/// @brief Determine which bit in a word a bit is in. /// @brief Determine which bit in a word a bit is in.
static uint32_t whichBit(uint32_t bitPosition) { static uint32_t whichBit(uint32_t bitPosition) {
return bitPosition % APINT_BITS_PER_WORD; return bitPosition % APINT_BITS_PER_WORD;
} }
/// This method generates and returns a uint64_t (word) mask for a single /// 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 /// bit at a specific bit position. This is used to mask the bit in the
/// corresponding word. /// corresponding word.
/// @returns a uint64_t with only bit at "whichBit(bitPosition)" set /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set
/// @brief Get a single bit mask. /// @brief Get a single bit mask.
static uint64_t maskBit(uint32_t bitPosition) { static uint64_t maskBit(uint32_t bitPosition) {
return 1ULL << whichBit(bitPosition); return 1ULL << whichBit(bitPosition);
} }
/// This method is used internally to clear the to "N" bits in the high order /// 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 /// 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 /// significant word is assigned a value to ensure that those bits are
/// zero'd out. /// zero'd out.
/// @brief Clear unused high order bits /// @brief Clear unused high order bits
APInt& clearUnusedBits() { APInt& clearUnusedBits() {
@@ -144,13 +144,13 @@ class APInt {
/// @returns the corresponding word for the specified bit position. /// @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
uint64_t getWord(uint32_t bitPosition) const { uint64_t getWord(uint32_t bitPosition) const {
return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
} }
/// This is used by the constructors that take string arguments. /// This is used by the constructors that take string arguments.
/// @brief Convert a char array into an APInt /// @brief Convert a char array into an APInt
void fromString(uint32_t numBits, const char *strStart, uint32_t slen, void fromString(uint32_t numBits, const char *strStart, uint32_t slen,
uint8_t radix); uint8_t radix);
/// This is used by the toString method to divide by the radix. It simply /// This is used by the toString method to divide by the radix. It simply
@@ -158,7 +158,7 @@ class APInt {
/// has specific constraints on its inputs. If those constraints are not met /// has specific constraints on its inputs. If those constraints are not met
/// then it provides a simpler form of divide. /// then it provides a simpler form of divide.
/// @brief An internal division function for dividing APInts. /// @brief An internal division function for dividing APInts.
static void divide(const APInt LHS, uint32_t lhsWords, static void divide(const APInt LHS, uint32_t lhsWords,
const APInt &RHS, uint32_t rhsWords, const APInt &RHS, uint32_t rhsWords,
APInt *Quotient, APInt *Remainder); APInt *Quotient, APInt *Remainder);
@@ -228,7 +228,7 @@ public:
APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[]); APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[]);
/// This constructor interprets the slen characters starting at StrStart as /// This constructor interprets the slen characters starting at StrStart as
/// a string in the given radix. The interpretation stops when the first /// a string in the given radix. The interpretation stops when the first
/// character that is not suitable for the radix is encountered. Acceptable /// character that is not suitable for the radix is encountered. Acceptable
/// radix values are 2, 8, 10 and 16. It is an error for the value implied by /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
/// the string to require more bits than numBits. /// the string to require more bits than numBits.
@@ -244,7 +244,7 @@ public:
APInt(const APInt& that) APInt(const APInt& that)
: BitWidth(that.BitWidth), VAL(0) { : BitWidth(that.BitWidth), VAL(0) {
assert(BitWidth && "bitwidth too small"); assert(BitWidth && "bitwidth too small");
if (isSingleWord()) if (isSingleWord())
VAL = that.VAL; VAL = that.VAL;
else else
initSlowCase(that); initSlowCase(that);
@@ -252,21 +252,21 @@ public:
/// @brief Destructor. /// @brief Destructor.
~APInt() { ~APInt() {
if (!isSingleWord()) if (!isSingleWord())
delete [] pVal; delete [] pVal;
} }
/// Default constructor that creates an uninitialized APInt. This is useful /// Default constructor that creates an uninitialized APInt. This is useful
/// for object deserialization (pair this with the static method Read). /// for object deserialization (pair this with the static method Read).
explicit APInt() : BitWidth(1) {} explicit APInt() : BitWidth(1) {}
/// Profile - Used to insert APInt objects, or objects that contain APInt /// Profile - Used to insert APInt objects, or objects that contain APInt
/// objects, into FoldingSets. /// objects, into FoldingSets.
void Profile(FoldingSetNodeID& id) const; void Profile(FoldingSetNodeID& id) const;
/// @brief Used by the Bitcode serializer to emit APInts to Bitcode. /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
void Emit(Serializer& S) const; void Emit(Serializer& S) const;
/// @brief Used by the Bitcode deserializer to deserialize APInts. /// @brief Used by the Bitcode deserializer to deserialize APInts.
void Read(Deserializer& D); void Read(Deserializer& D);
@@ -335,7 +335,7 @@ public:
assert(N && "N == 0 ???"); assert(N && "N == 0 ???");
if (N >= getBitWidth()) if (N >= getBitWidth())
return true; return true;
if (isSingleWord()) if (isSingleWord())
return VAL == (VAL & (~0ULL >> (64 - N))); return VAL == (VAL & (~0ULL >> (64 - N)));
APInt Tmp(N, getNumWords(), pVal); APInt Tmp(N, getNumWords(), pVal);
@@ -350,13 +350,13 @@ public:
} }
/// @returns true if the argument APInt value is a power of two > 0. /// @returns true if the argument APInt value is a power of two > 0.
bool isPowerOf2() const; bool isPowerOf2() const;
/// isSignBit - Return true if this is the value returned by getSignBit. /// isSignBit - Return true if this is the value returned by getSignBit.
bool isSignBit() const { return isMinSignedValue(); } bool isSignBit() const { return isMinSignedValue(); }
/// This converts the APInt to a boolean value as a test against zero. /// This converts the APInt to a boolean value as a test against zero.
/// @brief Boolean conversion function. /// @brief Boolean conversion function.
bool getBoolValue() const { bool getBoolValue() const {
return *this != 0; return *this != 0;
} }
@@ -425,7 +425,7 @@ public:
/// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other /// 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 /// 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 /// 0x0000FFFF. If hiBit is less than loBit then the set bits "wrap". For
/// example, with parameters (32, 28, 4), you would get 0xF000000F. /// example, with parameters (32, 28, 4), you would get 0xF000000F.
/// @param numBits the intended bit width of the result /// @param numBits the intended bit width of the result
/// @param loBit the index of the lowest bit set. /// @param loBit the index of the lowest bit set.
/// @param hiBit the index of the highest bit set. /// @param hiBit the index of the highest bit set.
@@ -478,7 +478,7 @@ public:
/// @brief Get a hash value based on this APInt /// @brief Get a hash value based on this APInt
uint64_t getHashValue() const; uint64_t getHashValue() const;
/// This function returns a pointer to the internal storage of the APInt. /// 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 /// This is useful for writing out the APInt in binary form without any
/// conversions. /// conversions.
const uint64_t* getRawData() const { const uint64_t* getRawData() const {
@@ -503,7 +503,7 @@ public:
APInt& operator++(); APInt& operator++();
/// @returns a new APInt representing *this decremented by one. /// @returns a new APInt representing *this decremented by one.
/// @brief Postfix decrement operator. /// @brief Postfix decrement operator.
const APInt operator--(int) { const APInt operator--(int) {
APInt API(*this); APInt API(*this);
--(*this); --(*this);
@@ -511,12 +511,12 @@ public:
} }
/// @returns *this decremented by one. /// @returns *this decremented by one.
/// @brief Prefix decrement operator. /// @brief Prefix decrement operator.
APInt& operator--(); APInt& operator--();
/// Performs a bitwise complement operation on this APInt. /// Performs a bitwise complement operation on this APInt.
/// @returns an APInt that is the bitwise complement of *this /// @returns an APInt that is the bitwise complement of *this
/// @brief Unary bitwise complement operator. /// @brief Unary bitwise complement operator.
APInt operator~() const { APInt operator~() const {
APInt Result(*this); APInt Result(*this);
Result.flip(); Result.flip();
@@ -532,14 +532,14 @@ public:
/// Performs logical negation operation on this APInt. /// Performs logical negation operation on this APInt.
/// @returns true if *this is zero, false otherwise. /// @returns true if *this is zero, false otherwise.
/// @brief Logical negation operator. /// @brief Logical negation operator.
bool operator!() const; bool operator!() const;
/// @} /// @}
/// @name Assignment Operators /// @name Assignment Operators
/// @{ /// @{
/// @returns *this after assignment of RHS. /// @returns *this after assignment of RHS.
/// @brief Copy assignment operator. /// @brief Copy assignment operator.
APInt& operator=(const APInt& RHS) { APInt& operator=(const APInt& RHS) {
// If the bitwidths are the same, we can avoid mucking with memory // If the bitwidths are the same, we can avoid mucking with memory
if (isSingleWord() && RHS.isSingleWord()) { if (isSingleWord() && RHS.isSingleWord()) {
@@ -555,40 +555,40 @@ public:
/// the bit width, the excess bits are truncated. If the bit width is larger /// 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. /// than 64, the value is zero filled in the unspecified high order bits.
/// @returns *this after assignment of RHS value. /// @returns *this after assignment of RHS value.
/// @brief Assignment operator. /// @brief Assignment operator.
APInt& operator=(uint64_t RHS); APInt& operator=(uint64_t RHS);
/// Performs a bitwise AND operation on this APInt and RHS. The result is /// Performs a bitwise AND operation on this APInt and RHS. The result is
/// assigned to *this. /// assigned to *this.
/// @returns *this after ANDing with RHS. /// @returns *this after ANDing with RHS.
/// @brief Bitwise AND assignment operator. /// @brief Bitwise AND assignment operator.
APInt& operator&=(const APInt& RHS); APInt& operator&=(const APInt& RHS);
/// Performs a bitwise OR operation on this APInt and RHS. The result is /// Performs a bitwise OR operation on this APInt and RHS. The result is
/// assigned *this; /// assigned *this;
/// @returns *this after ORing with RHS. /// @returns *this after ORing with RHS.
/// @brief Bitwise OR assignment operator. /// @brief Bitwise OR assignment operator.
APInt& operator|=(const APInt& RHS); APInt& operator|=(const APInt& RHS);
/// Performs a bitwise XOR operation on this APInt and RHS. The result is /// Performs a bitwise XOR operation on this APInt and RHS. The result is
/// assigned to *this. /// assigned to *this.
/// @returns *this after XORing with RHS. /// @returns *this after XORing with RHS.
/// @brief Bitwise XOR assignment operator. /// @brief Bitwise XOR assignment operator.
APInt& operator^=(const APInt& RHS); APInt& operator^=(const APInt& RHS);
/// Multiplies this APInt by RHS and assigns the result to *this. /// Multiplies this APInt by RHS and assigns the result to *this.
/// @returns *this /// @returns *this
/// @brief Multiplication assignment operator. /// @brief Multiplication assignment operator.
APInt& operator*=(const APInt& RHS); APInt& operator*=(const APInt& RHS);
/// Adds RHS to *this and assigns the result to *this. /// Adds RHS to *this and assigns the result to *this.
/// @returns *this /// @returns *this
/// @brief Addition assignment operator. /// @brief Addition assignment operator.
APInt& operator+=(const APInt& RHS); APInt& operator+=(const APInt& RHS);
/// Subtracts RHS from *this and assigns the result to *this. /// Subtracts RHS from *this and assigns the result to *this.
/// @returns *this /// @returns *this
/// @brief Subtraction assignment operator. /// @brief Subtraction assignment operator.
APInt& operator-=(const APInt& RHS); APInt& operator-=(const APInt& RHS);
/// Shifts *this left by shiftAmt and assigns the result to *this. /// Shifts *this left by shiftAmt and assigns the result to *this.
@@ -604,7 +604,7 @@ public:
/// @{ /// @{
/// Performs a bitwise AND operation on *this and RHS. /// Performs a bitwise AND operation on *this and RHS.
/// @returns An APInt value representing the bitwise AND of *this and RHS. /// @returns An APInt value representing the bitwise AND of *this and RHS.
/// @brief Bitwise AND operator. /// @brief Bitwise AND operator.
APInt operator&(const APInt& RHS) const { APInt operator&(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) if (isSingleWord())
@@ -617,7 +617,7 @@ public:
/// Performs a bitwise OR operation on *this and RHS. /// Performs a bitwise OR operation on *this and RHS.
/// @returns An APInt value representing the bitwise OR of *this and RHS. /// @returns An APInt value representing the bitwise OR of *this and RHS.
/// @brief Bitwise OR operator. /// @brief Bitwise OR operator.
APInt operator|(const APInt& RHS) const { APInt operator|(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) if (isSingleWord())
@@ -630,7 +630,7 @@ public:
/// Performs a bitwise XOR operation on *this and RHS. /// Performs a bitwise XOR operation on *this and RHS.
/// @returns An APInt value representing the bitwise XOR of *this and RHS. /// @returns An APInt value representing the bitwise XOR of *this and RHS.
/// @brief Bitwise XOR operator. /// @brief Bitwise XOR operator.
APInt operator^(const APInt& RHS) const { APInt operator^(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) if (isSingleWord())
@@ -642,23 +642,23 @@ public:
} }
/// Multiplies this APInt by RHS and returns the result. /// Multiplies this APInt by RHS and returns the result.
/// @brief Multiplication operator. /// @brief Multiplication operator.
APInt operator*(const APInt& RHS) const; APInt operator*(const APInt& RHS) const;
/// Adds RHS to this APInt and returns the result. /// Adds RHS to this APInt and returns the result.
/// @brief Addition operator. /// @brief Addition operator.
APInt operator+(const APInt& RHS) const; APInt operator+(const APInt& RHS) const;
APInt operator+(uint64_t RHS) const { APInt operator+(uint64_t RHS) const {
return (*this) + APInt(BitWidth, RHS); return (*this) + APInt(BitWidth, RHS);
} }
/// Subtracts RHS from this APInt and returns the result. /// Subtracts RHS from this APInt and returns the result.
/// @brief Subtraction operator. /// @brief Subtraction operator.
APInt operator-(const APInt& RHS) const; APInt operator-(const APInt& RHS) const;
APInt operator-(uint64_t RHS) const { APInt operator-(uint64_t RHS) const {
return (*this) - APInt(BitWidth, RHS); return (*this) - APInt(BitWidth, RHS);
} }
APInt operator<<(unsigned Bits) const { APInt operator<<(unsigned Bits) const {
return shl(Bits); return shl(Bits);
} }
@@ -758,7 +758,7 @@ public:
/// may overlap with the pair of output arguments. It is safe to call /// may overlap with the pair of output arguments. It is safe to call
/// udivrem(X, Y, X, Y), for example. /// udivrem(X, Y, X, Y), for example.
/// @brief Dual division/remainder interface. /// @brief Dual division/remainder interface.
static void udivrem(const APInt &LHS, const APInt &RHS, static void udivrem(const APInt &LHS, const APInt &RHS,
APInt &Quotient, APInt &Remainder); APInt &Quotient, APInt &Remainder);
static void sdivrem(const APInt &LHS, const APInt &RHS, static void sdivrem(const APInt &LHS, const APInt &RHS,
@@ -788,7 +788,7 @@ public:
/// @{ /// @{
/// Compares this APInt with RHS for the validity of the equality /// Compares this APInt with RHS for the validity of the equality
/// relationship. /// relationship.
/// @brief Equality operator. /// @brief Equality operator.
bool operator==(const APInt& RHS) const { bool operator==(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths"); assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
if (isSingleWord()) if (isSingleWord())
@@ -796,7 +796,7 @@ public:
return EqualSlowCase(RHS); return EqualSlowCase(RHS);
} }
/// Compares this APInt with a uint64_t for the validity of the equality /// Compares this APInt with a uint64_t for the validity of the equality
/// relationship. /// relationship.
/// @returns true if *this == Val /// @returns true if *this == Val
/// @brief Equality operator. /// @brief Equality operator.
@@ -811,25 +811,25 @@ public:
/// @returns true if *this == Val /// @returns true if *this == Val
/// @brief Equality comparison. /// @brief Equality comparison.
bool eq(const APInt &RHS) const { bool eq(const APInt &RHS) const {
return (*this) == RHS; return (*this) == RHS;
} }
/// Compares this APInt with RHS for the validity of the inequality /// Compares this APInt with RHS for the validity of the inequality
/// relationship. /// relationship.
/// @returns true if *this != Val /// @returns true if *this != Val
/// @brief Inequality operator. /// @brief Inequality operator.
bool operator!=(const APInt& RHS) const { bool operator!=(const APInt& RHS) const {
return !((*this) == RHS); return !((*this) == RHS);
} }
/// Compares this APInt with a uint64_t for the validity of the inequality /// Compares this APInt with a uint64_t for the validity of the inequality
/// relationship. /// relationship.
/// @returns true if *this != Val /// @returns true if *this != Val
/// @brief Inequality operator. /// @brief Inequality operator.
bool operator!=(uint64_t Val) const { bool operator!=(uint64_t Val) const {
return !((*this) == Val); return !((*this) == Val);
} }
/// Compares this APInt with RHS for the validity of the inequality /// Compares this APInt with RHS for the validity of the inequality
/// relationship. /// relationship.
/// @returns true if *this != Val /// @returns true if *this != Val
@@ -908,19 +908,19 @@ public:
/// @name Resizing Operators /// @name Resizing Operators
/// @{ /// @{
/// Truncate the APInt to a specified width. It is an error to specify a 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. /// that is greater than or equal to the current width.
/// @brief Truncate to new width. /// @brief Truncate to new width.
APInt &trunc(uint32_t width); APInt &trunc(uint32_t width);
/// This operation sign extends the APInt to a new width. If the high order /// 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. /// 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 /// It is an error to specify a width that is less than or equal to the
/// current width. /// current width.
/// @brief Sign extend to a new width. /// @brief Sign extend to a new width.
APInt &sext(uint32_t width); APInt &sext(uint32_t width);
/// This operation zero extends the APInt to a new width. The high order bits /// 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 /// are filled with 0 bits. It is an error to specify a width that is less
/// than or equal to the current width. /// than or equal to the current width.
/// @brief Zero extend to a new width. /// @brief Zero extend to a new width.
APInt &zext(uint32_t width); APInt &zext(uint32_t width);
@@ -958,9 +958,9 @@ public:
/// @brief Set every bit to 0. /// @brief Set every bit to 0.
APInt& clear() { APInt& clear() {
if (isSingleWord()) if (isSingleWord())
VAL = 0; VAL = 0;
else else
memset(pVal, 0, getNumWords() * APINT_WORD_SIZE); memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
return *this; return *this;
} }
@@ -980,7 +980,7 @@ public:
return clearUnusedBits(); return clearUnusedBits();
} }
/// Toggle a given bit to its opposite value whose position is given /// Toggle a given bit to its opposite value whose position is given
/// as "bitPosition". /// as "bitPosition".
/// @brief Toggles a given bit to its opposite value. /// @brief Toggles a given bit to its opposite value.
APInt& flip(uint32_t bitPosition); APInt& flip(uint32_t bitPosition);
@@ -990,8 +990,8 @@ public:
/// @{ /// @{
/// @returns the total number of bits. /// @returns the total number of bits.
uint32_t getBitWidth() const { uint32_t getBitWidth() const {
return BitWidth; return BitWidth;
} }
/// Here one word's bitwidth equals to that of uint64_t. /// Here one word's bitwidth equals to that of uint64_t.
@@ -1017,12 +1017,12 @@ public:
} }
/// Computes the minimum bit width for this APInt while considering it to be /// 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, /// a signed (and probably negative) value. If the value is not negative,
/// this function returns the same value as getActiveBits()+1. Otherwise, it /// this function returns the same value as getActiveBits()+1. Otherwise, it
/// returns the smallest bit width that will retain the negative value. For /// 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 /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
/// for -1, this function will always return 1. /// for -1, this function will always return 1.
/// @brief Get the minimum bit size for this signed APInt /// @brief Get the minimum bit size for this signed APInt
uint32_t getMinSignedBits() const { uint32_t getMinSignedBits() const {
if (isNegative()) if (isNegative())
return BitWidth - countLeadingOnes() + 1; return BitWidth - countLeadingOnes() + 1;
@@ -1046,7 +1046,7 @@ public:
/// @brief Get sign extended value /// @brief Get sign extended value
int64_t getSExtValue() const { int64_t getSExtValue() const {
if (isSingleWord()) if (isSingleWord())
return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >> 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"); assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
return int64_t(pVal[0]); return int64_t(pVal[0]);
@@ -1079,8 +1079,8 @@ public:
/// @brief Count the number of leading one bits. /// @brief Count the number of leading one bits.
uint32_t countLeadingOnes() const; uint32_t countLeadingOnes() const;
/// countTrailingZeros - This function is an APInt version of the /// countTrailingZeros - This function is an APInt version of the
/// countTrailingZeros_{32,64} functions in MathExtras.h. It counts /// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first set bit. /// the number of zeros from the least significant bit to the first set bit.
/// @returns BitWidth if the value is zero. /// @returns BitWidth if the value is zero.
/// @returns the number of zeros from the least significant bit to the first /// @returns the number of zeros from the least significant bit to the first
@@ -1088,8 +1088,8 @@ public:
/// @brief Count the number of trailing zero bits. /// @brief Count the number of trailing zero bits.
uint32_t countTrailingZeros() const; uint32_t countTrailingZeros() const;
/// countTrailingOnes - This function is an APInt version of the /// countTrailingOnes - This function is an APInt version of the
/// countTrailingOnes_{32,64} functions in MathExtras.h. It counts /// countTrailingOnes_{32,64} functions in MathExtras.h. It counts
/// the number of ones from the least significant bit to the first zero bit. /// the number of ones from the least significant bit to the first zero bit.
/// @returns BitWidth if the value is all ones. /// @returns BitWidth if the value is all ones.
/// @returns the number of ones from the least significant bit to the first /// @returns the number of ones from the least significant bit to the first
@@ -1103,7 +1103,7 @@ public:
/// countPopulation - This function is an APInt version of the /// countPopulation - This function is an APInt version of the
/// countPopulation_{32,64} functions in MathExtras.h. It counts the number /// countPopulation_{32,64} functions in MathExtras.h. It counts the number
/// of 1 bits in the APInt value. /// of 1 bits in the APInt value.
/// @returns 0 if the value is zero. /// @returns 0 if the value is zero.
/// @returns the number of set bits. /// @returns the number of set bits.
/// @brief Count the number of bits set. /// @brief Count the number of bits set.
@@ -1117,7 +1117,7 @@ public:
/// @name Conversion Functions /// @name Conversion Functions
/// @{ /// @{
void print(raw_ostream &OS, bool isSigned) const; void print(raw_ostream &OS, bool isSigned) const;
/// toString - Converts an APInt to a string and append it to Str. Str is /// toString - Converts an APInt to a string and append it to Str. Str is
/// commonly a SmallString. /// commonly a SmallString.
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const; void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const;
@@ -1133,12 +1133,12 @@ public:
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
return toString(Str, Radix, true); return toString(Str, Radix, true);
} }
/// toString - This returns the APInt as a std::string. Note that this is an /// 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 /// inefficient method. It is better to pass in a SmallVector/SmallString
/// to the methods above to avoid thrashing the heap for the string. /// to the methods above to avoid thrashing the heap for the string.
std::string toString(unsigned Radix, bool Signed) const; std::string toString(unsigned Radix, bool Signed) const;
/// @returns a byte-swapped representation of this APInt Value. /// @returns a byte-swapped representation of this APInt Value.
APInt byteSwap() const; APInt byteSwap() const;
@@ -1359,7 +1359,7 @@ public:
static void tcOr(integerPart *, const integerPart *, unsigned int); static void tcOr(integerPart *, const integerPart *, unsigned int);
static void tcXor(integerPart *, const integerPart *, unsigned int); static void tcXor(integerPart *, const integerPart *, unsigned int);
static void tcComplement(integerPart *, unsigned int); static void tcComplement(integerPart *, unsigned int);
/// Comparison (unsigned) of two bignums. /// Comparison (unsigned) of two bignums.
static int tcCompare(const integerPart *, const integerPart *, static int tcCompare(const integerPart *, const integerPart *,
unsigned int); unsigned int);
@@ -1389,7 +1389,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
I.print(OS, true); I.print(OS, true);
return OS; return OS;
} }
namespace APIntOps { namespace APIntOps {
/// @brief Determine the smaller of two APInts considered to be signed. /// @brief Determine the smaller of two APInts considered to be signed.
@@ -1442,7 +1442,7 @@ inline APInt byteSwap(const APInt& APIVal) {
/// @returns the floor log base 2 of the specified APInt value. /// @returns the floor log base 2 of the specified APInt value.
inline uint32_t logBase2(const APInt& APIVal) { inline uint32_t logBase2(const APInt& APIVal) {
return APIVal.logBase2(); return APIVal.logBase2();
} }
/// GreatestCommonDivisor - This function returns the greatest common /// GreatestCommonDivisor - This function returns the greatest common
@@ -1544,7 +1544,7 @@ inline APInt sub(const APInt& LHS, const APInt& RHS) {
return LHS - RHS; return LHS - RHS;
} }
/// Performs bitwise AND operation on APInt LHS and /// Performs bitwise AND operation on APInt LHS and
/// APInt RHS. /// APInt RHS.
/// @brief Bitwise AND function for APInt. /// @brief Bitwise AND function for APInt.
inline APInt And(const APInt& LHS, const APInt& RHS) { inline APInt And(const APInt& LHS, const APInt& RHS) {
@@ -1552,7 +1552,7 @@ inline APInt And(const APInt& LHS, const APInt& RHS) {
} }
/// Performs bitwise OR operation on APInt LHS and APInt RHS. /// Performs bitwise OR operation on APInt LHS and APInt RHS.
/// @brief Bitwise OR function for APInt. /// @brief Bitwise OR function for APInt.
inline APInt Or(const APInt& LHS, const APInt& RHS) { inline APInt Or(const APInt& LHS, const APInt& RHS) {
return LHS | RHS; return LHS | RHS;
} }
@@ -1561,10 +1561,10 @@ inline APInt Or(const APInt& LHS, const APInt& RHS) {
/// @brief Bitwise XOR function for APInt. /// @brief Bitwise XOR function for APInt.
inline APInt Xor(const APInt& LHS, const APInt& RHS) { inline APInt Xor(const APInt& LHS, const APInt& RHS) {
return LHS ^ RHS; return LHS ^ RHS;
} }
/// Performs a bitwise complement operation on APInt. /// Performs a bitwise complement operation on APInt.
/// @brief Bitwise complement function. /// @brief Bitwise complement function.
inline APInt Not(const APInt& APIVal) { inline APInt Not(const APInt& APIVal) {
return ~APIVal; return ~APIVal;
} }

View File

@@ -18,7 +18,7 @@
#include "llvm/ADT/APInt.h" #include "llvm/ADT/APInt.h"
namespace llvm { namespace llvm {
class APSInt : public APInt { class APSInt : public APInt {
bool IsUnsigned; bool IsUnsigned;
public: public:
@@ -27,27 +27,27 @@ public:
/// APSInt ctor - Create an APSInt with the specified width, default to /// APSInt ctor - Create an APSInt with the specified width, default to
/// unsigned. /// unsigned.
explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
: APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
explicit APSInt(const APInt &I, bool isUnsigned = true) explicit APSInt(const APInt &I, bool isUnsigned = true)
: APInt(I), IsUnsigned(isUnsigned) {} : APInt(I), IsUnsigned(isUnsigned) {}
APSInt &operator=(const APSInt &RHS) { APSInt &operator=(const APSInt &RHS) {
APInt::operator=(RHS); APInt::operator=(RHS);
IsUnsigned = RHS.IsUnsigned; IsUnsigned = RHS.IsUnsigned;
return *this; return *this;
} }
APSInt &operator=(const APInt &RHS) { APSInt &operator=(const APInt &RHS) {
// Retain our current sign. // Retain our current sign.
APInt::operator=(RHS); APInt::operator=(RHS);
return *this; return *this;
} }
APSInt &operator=(uint64_t RHS) { APSInt &operator=(uint64_t RHS) {
// Retain our current sign. // Retain our current sign.
APInt::operator=(RHS); APInt::operator=(RHS);
return *this; return *this;
} }
@@ -56,7 +56,7 @@ public:
bool isUnsigned() const { return IsUnsigned; } bool isUnsigned() const { return IsUnsigned; }
void setIsUnsigned(bool Val) { IsUnsigned = Val; } void setIsUnsigned(bool Val) { IsUnsigned = Val; }
void setIsSigned(bool Val) { IsUnsigned = !Val; } void setIsSigned(bool Val) { IsUnsigned = !Val; }
/// toString - Append this APSInt to the specified SmallString. /// toString - Append this APSInt to the specified SmallString.
void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const { void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
return APInt::toString(Str, Radix, isSigned()); return APInt::toString(Str, Radix, isSigned());
@@ -67,7 +67,7 @@ public:
return APInt::toString(Radix, isSigned()); return APInt::toString(Radix, isSigned());
} }
using APInt::toString; using APInt::toString;
APSInt& extend(uint32_t width) { APSInt& extend(uint32_t width) {
if (IsUnsigned) if (IsUnsigned)
zext(width); zext(width);
@@ -75,7 +75,7 @@ public:
sext(width); sext(width);
return *this; return *this;
} }
APSInt& extOrTrunc(uint32_t width) { APSInt& extOrTrunc(uint32_t width) {
if (IsUnsigned) if (IsUnsigned)
zextOrTrunc(width); zextOrTrunc(width);
@@ -83,7 +83,7 @@ public:
sextOrTrunc(width); sextOrTrunc(width);
return *this; return *this;
} }
const APSInt &operator%=(const APSInt &RHS) { const APSInt &operator%=(const APSInt &RHS) {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
if (IsUnsigned) if (IsUnsigned)
@@ -108,7 +108,7 @@ public:
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false); return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
} }
APSInt operator>>(unsigned Amt) const { APSInt operator>>(unsigned Amt) const {
return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
} }
@@ -116,7 +116,7 @@ public:
*this = *this >> Amt; *this = *this >> Amt;
return *this; return *this;
} }
inline bool operator<(const APSInt& RHS) const { inline bool operator<(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return IsUnsigned ? ult(RHS) : slt(RHS); return IsUnsigned ? ult(RHS) : slt(RHS);
@@ -133,18 +133,18 @@ public:
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return IsUnsigned ? uge(RHS) : sge(RHS); return IsUnsigned ? uge(RHS) : sge(RHS);
} }
// The remaining operators just wrap the logic of APInt, but retain the // The remaining operators just wrap the logic of APInt, but retain the
// signedness information. // signedness information.
APSInt operator<<(unsigned Bits) const { APSInt operator<<(unsigned Bits) const {
return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
} }
APSInt& operator<<=(unsigned Amt) { APSInt& operator<<=(unsigned Amt) {
*this = *this << Amt; *this = *this << Amt;
return *this; return *this;
} }
APSInt& operator++() { APSInt& operator++() {
static_cast<APInt&>(*this)++; static_cast<APInt&>(*this)++;
return *this; return *this;
@@ -158,20 +158,20 @@ public:
} }
APSInt operator--(int) { APSInt operator--(int) {
return APSInt(--static_cast<APInt&>(*this), IsUnsigned); return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
} }
APSInt operator-() const { APSInt operator-() const {
return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
} }
APSInt& operator+=(const APSInt& RHS) { APSInt& operator+=(const APSInt& RHS) {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
static_cast<APInt&>(*this) += RHS; static_cast<APInt&>(*this) += RHS;
return *this; return *this;
} }
APSInt& operator-=(const APSInt& RHS) { APSInt& operator-=(const APSInt& RHS) {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
static_cast<APInt&>(*this) -= RHS; static_cast<APInt&>(*this) -= RHS;
return *this; return *this;
} }
APSInt& operator*=(const APSInt& RHS) { APSInt& operator*=(const APSInt& RHS) {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
static_cast<APInt&>(*this) *= RHS; static_cast<APInt&>(*this) *= RHS;
@@ -193,36 +193,36 @@ public:
return *this; return *this;
} }
APSInt operator&(const APSInt& RHS) const { APSInt operator&(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
} }
APSInt And(const APSInt& RHS) const { APSInt And(const APSInt& RHS) const {
return this->operator&(RHS); return this->operator&(RHS);
} }
APSInt operator|(const APSInt& RHS) const { APSInt operator|(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
} }
APSInt Or(const APSInt& RHS) const { APSInt Or(const APSInt& RHS) const {
return this->operator|(RHS); return this->operator|(RHS);
} }
APSInt operator^(const APSInt& RHS) const { APSInt operator^(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
} }
APSInt Xor(const APSInt& RHS) const { APSInt Xor(const APSInt& RHS) const {
return this->operator^(RHS); return this->operator^(RHS);
} }
APSInt operator*(const APSInt& RHS) const { APSInt operator*(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
} }
APSInt operator+(const APSInt& RHS) const { APSInt operator+(const APSInt& RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
} }
@@ -230,35 +230,35 @@ public:
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned); return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
} }
APSInt operator~() const { APSInt operator~() const {
return APSInt(~static_cast<const APInt&>(*this), IsUnsigned); return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
} }
/// getMaxValue - Return the APSInt representing the maximum integer value /// getMaxValue - Return the APSInt representing the maximum integer value
/// with the given bit width and signedness. /// with the given bit width and signedness.
static APSInt getMaxValue(uint32_t numBits, bool Signed) { static APSInt getMaxValue(uint32_t numBits, bool Signed) {
return APSInt(Signed ? APInt::getSignedMaxValue(numBits) return APSInt(Signed ? APInt::getSignedMaxValue(numBits)
: APInt::getMaxValue(numBits), Signed); : APInt::getMaxValue(numBits), Signed);
} }
/// getMinValue - Return the APSInt representing the minimum integer value /// getMinValue - Return the APSInt representing the minimum integer value
/// with the given bit width and signedness. /// with the given bit width and signedness.
static APSInt getMinValue(uint32_t numBits, bool Signed) { static APSInt getMinValue(uint32_t numBits, bool Signed) {
return APSInt(Signed ? APInt::getSignedMinValue(numBits) return APSInt(Signed ? APInt::getSignedMinValue(numBits)
: APInt::getMinValue(numBits), Signed); : APInt::getMinValue(numBits), Signed);
} }
/// Profile - Used to insert APSInt objects, or objects that contain APSInt /// Profile - Used to insert APSInt objects, or objects that contain APSInt
/// objects, into FoldingSets. /// objects, into FoldingSets.
void Profile(FoldingSetNodeID& ID) const; void Profile(FoldingSetNodeID& ID) const;
}; };
inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) { inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
I.print(OS, I.isSigned()); I.print(OS, I.isSigned());
return OS; return OS;
} }
} // end namespace llvm } // end namespace llvm
#endif #endif

View File

@@ -26,7 +26,7 @@ class BitVector {
enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * 8 }; enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * 8 };
BitWord *Bits; // Actual bits. BitWord *Bits; // Actual bits.
unsigned Size; // Size of bitvector in bits. unsigned Size; // Size of bitvector in bits.
unsigned Capacity; // Size of allocated memory in BitWord. unsigned Capacity; // Size of allocated memory in BitWord.
@@ -89,7 +89,7 @@ public:
Bits = new BitWord[Capacity]; Bits = new BitWord[Capacity];
std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits); std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
} }
~BitVector() { ~BitVector() {
delete[] Bits; delete[] Bits;
} }
@@ -185,13 +185,13 @@ public:
grow(N); grow(N);
init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t); init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
} }
// Set any old unused bits that are now included in the BitVector. This // Set any old unused bits that are now included in the BitVector. This
// may set bits that are not included in the new vector, but we will clear // may set bits that are not included in the new vector, but we will clear
// them back out below. // them back out below.
if (N > Size) if (N > Size)
set_unused_bits(t); set_unused_bits(t);
// Update the size, and clear out any bits that are now unused // Update the size, and clear out any bits that are now unused
unsigned OldSize = Size; unsigned OldSize = Size;
Size = N; Size = N;
@@ -250,7 +250,7 @@ public:
} }
bool operator[](unsigned Idx) const { bool operator[](unsigned Idx) const {
assert (Idx < Size && "Out-of-bounds Bit access."); assert (Idx < Size && "Out-of-bounds Bit access.");
BitWord Mask = 1L << (Idx % BITWORD_SIZE); BitWord Mask = 1L << (Idx % BITWORD_SIZE);
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0; return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
} }
@@ -267,7 +267,7 @@ public:
for (i = 0; i != std::min(ThisWords, RHSWords); ++i) for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
if (Bits[i] != RHS.Bits[i]) if (Bits[i] != RHS.Bits[i])
return false; return false;
// Verify that any extra words are all zeros. // Verify that any extra words are all zeros.
if (i != ThisWords) { if (i != ThisWords) {
for (; i != ThisWords; ++i) for (; i != ThisWords; ++i)
@@ -292,13 +292,13 @@ public:
unsigned i; unsigned i;
for (i = 0; i != std::min(ThisWords, RHSWords); ++i) for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
Bits[i] &= RHS.Bits[i]; Bits[i] &= RHS.Bits[i];
// Any bits that are just in this bitvector become zero, because they aren't // Any bits that are just in this bitvector become zero, because they aren't
// in the RHS bit vector. Any words only in RHS are ignored because they // in the RHS bit vector. Any words only in RHS are ignored because they
// are already zero in the LHS. // are already zero in the LHS.
for (; i != ThisWords; ++i) for (; i != ThisWords; ++i)
Bits[i] = 0; Bits[i] = 0;
return *this; return *this;
} }
@@ -315,7 +315,7 @@ public:
Bits[i] ^= RHS.Bits[i]; Bits[i] ^= RHS.Bits[i];
return *this; return *this;
} }
// Assignment operator. // Assignment operator.
const BitVector &operator=(const BitVector &RHS) { const BitVector &operator=(const BitVector &RHS) {
if (this == &RHS) return *this; if (this == &RHS) return *this;
@@ -327,7 +327,7 @@ public:
clear_unused_bits(); clear_unused_bits();
return *this; return *this;
} }
// Grow the bitvector to have enough elements. // Grow the bitvector to have enough elements.
Capacity = RHSWords; Capacity = RHSWords;
BitWord *NewBits = new BitWord[Capacity]; BitWord *NewBits = new BitWord[Capacity];
@@ -344,14 +344,14 @@ private:
unsigned NumBitWords(unsigned S) const { unsigned NumBitWords(unsigned S) const {
return (S + BITWORD_SIZE-1) / BITWORD_SIZE; return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
} }
// Set the unused bits in the high words. // Set the unused bits in the high words.
void set_unused_bits(bool t = true) { void set_unused_bits(bool t = true) {
// Set high words first. // Set high words first.
unsigned UsedWords = NumBitWords(Size); unsigned UsedWords = NumBitWords(Size);
if (Capacity > UsedWords) if (Capacity > UsedWords)
init_words(&Bits[UsedWords], (Capacity-UsedWords), t); init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
// Then set any stray high bits of the last used word. // Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE; unsigned ExtraBits = Size % BITWORD_SIZE;
if (ExtraBits) { if (ExtraBits) {
@@ -377,13 +377,13 @@ private:
// Destroy the old bits. // Destroy the old bits.
delete[] Bits; delete[] Bits;
Bits = NewBits; Bits = NewBits;
clear_unused_bits(); clear_unused_bits();
} }
void init_words(BitWord *B, unsigned NumWords, bool t) { void init_words(BitWord *B, unsigned NumWords, bool t) {
memset(B, 0 - (int)t, NumWords*sizeof(BitWord)); memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
} }
}; };
inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) { inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
@@ -403,6 +403,6 @@ inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
Result ^= RHS; Result ^= RHS;
return Result; return Result;
} }
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@@ -20,7 +20,7 @@
#include <utility> #include <utility>
namespace llvm { namespace llvm {
template<typename T> template<typename T>
struct DenseMapInfo { struct DenseMapInfo {
//static inline T getEmptyKey(); //static inline T getEmptyKey();
@@ -36,7 +36,7 @@ struct DenseMapInfo<T*> {
static inline T* getEmptyKey() { return reinterpret_cast<T*>(-1); } static inline T* getEmptyKey() { return reinterpret_cast<T*>(-1); }
static inline T* getTombstoneKey() { return reinterpret_cast<T*>(-2); } static inline T* getTombstoneKey() { return reinterpret_cast<T*>(-2); }
static unsigned getHashValue(const T *PtrVal) { static unsigned getHashValue(const T *PtrVal) {
return (unsigned((uintptr_t)PtrVal) >> 4) ^ return (unsigned((uintptr_t)PtrVal) >> 4) ^
(unsigned((uintptr_t)PtrVal) >> 9); (unsigned((uintptr_t)PtrVal) >> 9);
} }
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
@@ -61,12 +61,12 @@ struct DenseMapInfo<std::pair<T, U> > {
typedef DenseMapInfo<T> FirstInfo; typedef DenseMapInfo<T> FirstInfo;
typedef DenseMapInfo<U> SecondInfo; typedef DenseMapInfo<U> SecondInfo;
static inline Pair getEmptyKey() { static inline Pair getEmptyKey() {
return std::make_pair(FirstInfo::getEmptyKey(), return std::make_pair(FirstInfo::getEmptyKey(),
SecondInfo::getEmptyKey()); SecondInfo::getEmptyKey());
} }
static inline Pair getTombstoneKey() { static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(), return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getEmptyKey()); SecondInfo::getEmptyKey());
} }
static unsigned getHashValue(const Pair& PairVal) { static unsigned getHashValue(const Pair& PairVal) {
@@ -86,7 +86,7 @@ struct DenseMapInfo<std::pair<T, U> > {
static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); } static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); }
}; };
template<typename KeyT, typename ValueT, template<typename KeyT, typename ValueT,
typename KeyInfoT = DenseMapInfo<KeyT>, typename KeyInfoT = DenseMapInfo<KeyT>,
typename ValueInfoT = DenseMapInfo<ValueT> > typename ValueInfoT = DenseMapInfo<ValueT> >
class DenseMapIterator; class DenseMapIterator;
@@ -102,23 +102,23 @@ class DenseMap {
typedef std::pair<KeyT, ValueT> BucketT; typedef std::pair<KeyT, ValueT> BucketT;
unsigned NumBuckets; unsigned NumBuckets;
BucketT *Buckets; BucketT *Buckets;
unsigned NumEntries; unsigned NumEntries;
unsigned NumTombstones; unsigned NumTombstones;
public: public:
typedef KeyT key_type; typedef KeyT key_type;
typedef ValueT mapped_type; typedef ValueT mapped_type;
typedef BucketT value_type; typedef BucketT value_type;
DenseMap(const DenseMap& other) { DenseMap(const DenseMap& other) {
NumBuckets = 0; NumBuckets = 0;
CopyFrom(other); CopyFrom(other);
} }
explicit DenseMap(unsigned NumInitBuckets = 64) { explicit DenseMap(unsigned NumInitBuckets = 64) {
init(NumInitBuckets); init(NumInitBuckets);
} }
~DenseMap() { ~DenseMap() {
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
@@ -129,7 +129,7 @@ public:
} }
operator delete(Buckets); operator delete(Buckets);
} }
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator; typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator; typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator;
inline iterator begin() { inline iterator begin() {
@@ -144,13 +144,13 @@ public:
inline const_iterator end() const { inline const_iterator end() const {
return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets); return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
} }
bool empty() const { return NumEntries == 0; } bool empty() const { return NumEntries == 0; }
unsigned size() const { return NumEntries; } unsigned size() const { return NumEntries; }
/// Grow the densemap so that it has at least Size buckets. Does not shrink /// Grow the densemap so that it has at least Size buckets. Does not shrink
void resize(size_t Size) { grow(Size); } void resize(size_t Size) { grow(Size); }
void clear() { void clear() {
// If the capacity of the array is huge, and the # elements used is small, // If the capacity of the array is huge, and the # elements used is small,
// shrink the array. // shrink the array.
@@ -158,7 +158,7 @@ public:
shrink_and_clear(); shrink_and_clear();
return; return;
} }
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
if (!KeyInfoT::isEqual(P->first, EmptyKey)) { if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
@@ -178,7 +178,7 @@ public:
BucketT *TheBucket; BucketT *TheBucket;
return LookupBucketFor(Val, TheBucket); return LookupBucketFor(Val, TheBucket);
} }
iterator find(const KeyT &Val) { iterator find(const KeyT &Val) {
BucketT *TheBucket; BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket)) if (LookupBucketFor(Val, TheBucket))
@@ -191,7 +191,7 @@ public:
return const_iterator(TheBucket, Buckets+NumBuckets); return const_iterator(TheBucket, Buckets+NumBuckets);
return end(); return end();
} }
/// lookup - Return the entry for the specified key, or a default /// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists. /// constructed value if no such entry exists.
ValueT lookup(const KeyT &Val) const { ValueT lookup(const KeyT &Val) const {
@@ -206,13 +206,13 @@ public:
if (LookupBucketFor(KV.first, TheBucket)) if (LookupBucketFor(KV.first, TheBucket))
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets), return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
false); // Already in map. false); // Already in map.
// Otherwise, insert the new element. // Otherwise, insert the new element.
TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets), return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
true); true);
} }
/// insert - Range insertion of pairs. /// insert - Range insertion of pairs.
template<typename InputIt> template<typename InputIt>
void insert(InputIt I, InputIt E) { void insert(InputIt I, InputIt E) {
@@ -220,7 +220,7 @@ public:
insert(*I); insert(*I);
} }
bool erase(const KeyT &Val) { bool erase(const KeyT &Val) {
BucketT *TheBucket; BucketT *TheBucket;
if (!LookupBucketFor(Val, TheBucket)) if (!LookupBucketFor(Val, TheBucket))
@@ -245,19 +245,19 @@ public:
BucketT *TheBucket; BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket)) if (LookupBucketFor(Key, TheBucket))
return *TheBucket; return *TheBucket;
return *InsertIntoBucket(Key, ValueT(), TheBucket); return *InsertIntoBucket(Key, ValueT(), TheBucket);
} }
ValueT &operator[](const KeyT &Key) { ValueT &operator[](const KeyT &Key) {
return FindAndConstruct(Key).second; return FindAndConstruct(Key).second;
} }
DenseMap& operator=(const DenseMap& other) { DenseMap& operator=(const DenseMap& other) {
CopyFrom(other); CopyFrom(other);
return *this; return *this;
} }
private: private:
void CopyFrom(const DenseMap& other) { void CopyFrom(const DenseMap& other) {
if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) { if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) {
@@ -269,15 +269,15 @@ private:
P->first.~KeyT(); P->first.~KeyT();
} }
} }
NumEntries = other.NumEntries; NumEntries = other.NumEntries;
NumTombstones = other.NumTombstones; NumTombstones = other.NumTombstones;
if (NumBuckets) if (NumBuckets)
operator delete(Buckets); operator delete(Buckets);
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
other.NumBuckets)); other.NumBuckets));
if (KeyInfoT::isPod() && ValueInfoT::isPod()) if (KeyInfoT::isPod() && ValueInfoT::isPod())
memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT)); memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
else else
@@ -289,7 +289,7 @@ private:
} }
NumBuckets = other.NumBuckets; NumBuckets = other.NumBuckets;
} }
BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
BucketT *TheBucket) { BucketT *TheBucket) {
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
@@ -302,16 +302,16 @@ private:
// table completely filled with tombstones, no lookup would ever succeed, // table completely filled with tombstones, no lookup would ever succeed,
// causing infinite loops in lookup. // causing infinite loops in lookup.
if (NumEntries*4 >= NumBuckets*3 || if (NumEntries*4 >= NumBuckets*3 ||
NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
this->grow(NumBuckets * 2); this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket); LookupBucketFor(Key, TheBucket);
} }
++NumEntries; ++NumEntries;
// If we are writing over a tombstone, remember this. // If we are writing over a tombstone, remember this.
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
--NumTombstones; --NumTombstones;
TheBucket->first = Key; TheBucket->first = Key;
new (&TheBucket->second) ValueT(Value); new (&TheBucket->second) ValueT(Value);
return TheBucket; return TheBucket;
@@ -326,7 +326,7 @@ private:
static const KeyT getTombstoneKey() { static const KeyT getTombstoneKey() {
return KeyInfoT::getTombstoneKey(); return KeyInfoT::getTombstoneKey();
} }
/// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
/// FoundBucket. If the bucket contains the key and a value, this returns /// FoundBucket. If the bucket contains the key and a value, this returns
/// true, otherwise it returns a bucket with an empty marker or tombstone and /// true, otherwise it returns a bucket with an empty marker or tombstone and
@@ -335,7 +335,7 @@ private:
unsigned BucketNo = getHashValue(Val); unsigned BucketNo = getHashValue(Val);
unsigned ProbeAmt = 1; unsigned ProbeAmt = 1;
BucketT *BucketsPtr = Buckets; BucketT *BucketsPtr = Buckets;
// FoundTombstone - Keep track of whether we find a tombstone while probing. // FoundTombstone - Keep track of whether we find a tombstone while probing.
BucketT *FoundTombstone = 0; BucketT *FoundTombstone = 0;
const KeyT EmptyKey = getEmptyKey(); const KeyT EmptyKey = getEmptyKey();
@@ -343,7 +343,7 @@ private:
assert(!KeyInfoT::isEqual(Val, EmptyKey) && assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
!KeyInfoT::isEqual(Val, TombstoneKey) && !KeyInfoT::isEqual(Val, TombstoneKey) &&
"Empty/Tombstone value shouldn't be inserted into map!"); "Empty/Tombstone value shouldn't be inserted into map!");
while (1) { while (1) {
BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1)); BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
// Found Val's bucket? If so, return it. // Found Val's bucket? If so, return it.
@@ -351,7 +351,7 @@ private:
FoundBucket = ThisBucket; FoundBucket = ThisBucket;
return true; return true;
} }
// If we found an empty bucket, the key doesn't exist in the set. // If we found an empty bucket, the key doesn't exist in the set.
// Insert it and return the default value. // Insert it and return the default value.
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) { if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
@@ -361,12 +361,12 @@ private:
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
return false; return false;
} }
// If this is a tombstone, remember it. If Val ends up not in the map, we // If this is a tombstone, remember it. If Val ends up not in the map, we
// prefer to return it than something that would require more probing. // prefer to return it than something that would require more probing.
if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone) if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
FoundTombstone = ThisBucket; // Remember the first tombstone found. FoundTombstone = ThisBucket; // Remember the first tombstone found.
// Otherwise, it's a hash collision or a tombstone, continue quadratic // Otherwise, it's a hash collision or a tombstone, continue quadratic
// probing. // probing.
BucketNo += ProbeAmt++; BucketNo += ProbeAmt++;
@@ -385,11 +385,11 @@ private:
for (unsigned i = 0; i != InitBuckets; ++i) for (unsigned i = 0; i != InitBuckets; ++i)
new (&Buckets[i].first) KeyT(EmptyKey); new (&Buckets[i].first) KeyT(EmptyKey);
} }
void grow(unsigned AtLeast) { void grow(unsigned AtLeast) {
unsigned OldNumBuckets = NumBuckets; unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets; BucketT *OldBuckets = Buckets;
// Double the number of buckets. // Double the number of buckets.
while (NumBuckets <= AtLeast) while (NumBuckets <= AtLeast)
NumBuckets <<= 1; NumBuckets <<= 1;
@@ -413,21 +413,21 @@ private:
assert(!FoundVal && "Key already in new map?"); assert(!FoundVal && "Key already in new map?");
DestBucket->first = B->first; DestBucket->first = B->first;
new (&DestBucket->second) ValueT(B->second); new (&DestBucket->second) ValueT(B->second);
// Free the value. // Free the value.
B->second.~ValueT(); B->second.~ValueT();
} }
B->first.~KeyT(); B->first.~KeyT();
} }
// Free the old table. // Free the old table.
operator delete(OldBuckets); operator delete(OldBuckets);
} }
void shrink_and_clear() { void shrink_and_clear() {
unsigned OldNumBuckets = NumBuckets; unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets; BucketT *OldBuckets = Buckets;
// Reduce the number of buckets. // Reduce the number of buckets.
NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1) NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
: 64; : 64;
@@ -449,10 +449,10 @@ private:
} }
B->first.~KeyT(); B->first.~KeyT();
} }
// Free the old table. // Free the old table.
operator delete(OldBuckets); operator delete(OldBuckets);
NumEntries = 0; NumEntries = 0;
} }
}; };
@@ -468,21 +468,21 @@ public:
DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) { DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
AdvancePastEmptyBuckets(); AdvancePastEmptyBuckets();
} }
std::pair<KeyT, ValueT> &operator*() const { std::pair<KeyT, ValueT> &operator*() const {
return *const_cast<BucketT*>(Ptr); return *const_cast<BucketT*>(Ptr);
} }
std::pair<KeyT, ValueT> *operator->() const { std::pair<KeyT, ValueT> *operator->() const {
return const_cast<BucketT*>(Ptr); return const_cast<BucketT*>(Ptr);
} }
bool operator==(const DenseMapIterator &RHS) const { bool operator==(const DenseMapIterator &RHS) const {
return Ptr == RHS.Ptr; return Ptr == RHS.Ptr;
} }
bool operator!=(const DenseMapIterator &RHS) const { bool operator!=(const DenseMapIterator &RHS) const {
return Ptr != RHS.Ptr; return Ptr != RHS.Ptr;
} }
inline DenseMapIterator& operator++() { // Preincrement inline DenseMapIterator& operator++() { // Preincrement
++Ptr; ++Ptr;
AdvancePastEmptyBuckets(); AdvancePastEmptyBuckets();
@@ -491,13 +491,13 @@ public:
DenseMapIterator operator++(int) { // Postincrement DenseMapIterator operator++(int) { // Postincrement
DenseMapIterator tmp = *this; ++*this; return tmp; DenseMapIterator tmp = *this; ++*this; return tmp;
} }
private: private:
void AdvancePastEmptyBuckets() { void AdvancePastEmptyBuckets() {
const KeyT Empty = KeyInfoT::getEmptyKey(); const KeyT Empty = KeyInfoT::getEmptyKey();
const KeyT Tombstone = KeyInfoT::getTombstoneKey(); const KeyT Tombstone = KeyInfoT::getTombstoneKey();
while (Ptr != End && while (Ptr != End &&
(KeyInfoT::isEqual(Ptr->first, Empty) || (KeyInfoT::isEqual(Ptr->first, Empty) ||
KeyInfoT::isEqual(Ptr->first, Tombstone))) KeyInfoT::isEqual(Ptr->first, Tombstone)))
++Ptr; ++Ptr;

View File

@@ -29,61 +29,61 @@ class DenseSet {
public: public:
DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {} DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {} explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); } bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); } unsigned size() const { return TheMap.size(); }
void clear() { void clear() {
TheMap.clear(); TheMap.clear();
} }
bool count(const ValueT &V) const { bool count(const ValueT &V) const {
return TheMap.count(V); return TheMap.count(V);
} }
void erase(const ValueT &V) { void erase(const ValueT &V) {
TheMap.erase(V); TheMap.erase(V);
} }
DenseSet &operator=(const DenseSet &RHS) { DenseSet &operator=(const DenseSet &RHS) {
TheMap = RHS.TheMap; TheMap = RHS.TheMap;
return *this; return *this;
} }
// Iterators. // Iterators.
class Iterator { class Iterator {
typename MapTy::iterator I; typename MapTy::iterator I;
public: public:
Iterator(const typename MapTy::iterator &i) : I(i) {} Iterator(const typename MapTy::iterator &i) : I(i) {}
ValueT& operator*() { return I->first; } ValueT& operator*() { return I->first; }
ValueT* operator->() { return &I->first; } ValueT* operator->() { return &I->first; }
Iterator& operator++() { ++I; return *this; }; Iterator& operator++() { ++I; return *this; };
bool operator==(const Iterator& X) const { return I == X.I; } bool operator==(const Iterator& X) const { return I == X.I; }
bool operator!=(const Iterator& X) const { return I != X.I; } bool operator!=(const Iterator& X) const { return I != X.I; }
}; };
class ConstIterator { class ConstIterator {
typename MapTy::const_iterator I; typename MapTy::const_iterator I;
public: public:
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {} ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
const ValueT& operator*() { return I->first; } const ValueT& operator*() { return I->first; }
const ValueT* operator->() { return &I->first; } const ValueT* operator->() { return &I->first; }
ConstIterator& operator++() { ++I; return *this; }; ConstIterator& operator++() { ++I; return *this; };
bool operator==(const ConstIterator& X) const { return I == X.I; } bool operator==(const ConstIterator& X) const { return I == X.I; }
bool operator!=(const ConstIterator& X) const { return I != X.I; } bool operator!=(const ConstIterator& X) const { return I != X.I; }
}; };
typedef Iterator iterator; typedef Iterator iterator;
typedef ConstIterator const_iterator; typedef ConstIterator const_iterator;
iterator begin() { return Iterator(TheMap.begin()); } iterator begin() { return Iterator(TheMap.begin()); }
iterator end() { return Iterator(TheMap.end()); } iterator end() { return Iterator(TheMap.end()); }
const_iterator begin() const { return ConstIterator(TheMap.begin()); } const_iterator begin() const { return ConstIterator(TheMap.begin()); }
const_iterator end() const { return ConstIterator(TheMap.end()); } const_iterator end() const { return ConstIterator(TheMap.end()); }

View File

@@ -29,7 +29,7 @@ namespace llvm {
/// instance of the node in the set. If the node already exists, return /// instance of the node in the set. If the node already exists, return
/// it, otherwise return the bucket it should be inserted into. /// it, otherwise return the bucket it should be inserted into.
/// 2. Given a node that has already been created, remove it from the set. /// 2. Given a node that has already been created, remove it from the set.
/// ///
/// This class is implemented as a single-link chained hash table, where the /// This class is implemented as a single-link chained hash table, where the
/// "buckets" are actually the nodes themselves (the next pointer is in the /// "buckets" are actually the nodes themselves (the next pointer is in the
/// node). The last node points back to the bucket to simplify node removal. /// node). The last node points back to the bucket to simplify node removal.
@@ -37,7 +37,7 @@ namespace llvm {
/// Any node that is to be included in the folding set must be a subclass of /// Any node that is to be included in the folding set must be a subclass of
/// FoldingSetNode. The node class must also define a Profile method used to /// FoldingSetNode. The node class must also define a Profile method used to
/// establish the unique bits of data for the node. The Profile method is /// establish the unique bits of data for the node. The Profile method is
/// passed a FoldingSetNodeID object which is used to gather the bits. Just /// passed a FoldingSetNodeID object which is used to gather the bits. Just
/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class. /// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
/// NOTE: That the folding set does not own the nodes and it is the /// NOTE: That the folding set does not own the nodes and it is the
/// responsibility of the user to dispose of the nodes. /// responsibility of the user to dispose of the nodes.
@@ -62,7 +62,7 @@ namespace llvm {
/// Eg. /// Eg.
/// FoldingSet<MyNode> MyFoldingSet; /// FoldingSet<MyNode> MyFoldingSet;
/// ///
/// Four public methods are available to manipulate the folding set; /// Four public methods are available to manipulate the folding set;
/// ///
/// 1) If you have an existing node that you want add to the set but unsure /// 1) If you have an existing node that you want add to the set but unsure
/// that the node might already exist then call; /// that the node might already exist then call;
@@ -97,34 +97,34 @@ namespace llvm {
/// bool WasRemoved = RemoveNode(N); /// bool WasRemoved = RemoveNode(N);
/// ///
/// The result indicates whether the node existed in the folding set. /// The result indicates whether the node existed in the folding set.
class FoldingSetNodeID; class FoldingSetNodeID;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetImpl - Implements the folding set functionality. The main /// FoldingSetImpl - Implements the folding set functionality. The main
/// structure is an array of buckets. Each bucket is indexed by the hash of /// structure is an array of buckets. Each bucket is indexed by the hash of
/// the nodes it contains. The bucket itself points to the nodes contained /// the nodes it contains. The bucket itself points to the nodes contained
/// in the bucket via a singly linked list. The last node in the list points /// in the bucket via a singly linked list. The last node in the list points
/// back to the bucket to facilitate node removal. /// back to the bucket to facilitate node removal.
/// ///
class FoldingSetImpl { class FoldingSetImpl {
protected: protected:
/// Buckets - Array of bucket chains. /// Buckets - Array of bucket chains.
/// ///
void **Buckets; void **Buckets;
/// NumBuckets - Length of the Buckets array. Always a power of 2. /// NumBuckets - Length of the Buckets array. Always a power of 2.
/// ///
unsigned NumBuckets; unsigned NumBuckets;
/// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
/// is greater than twice the number of buckets. /// is greater than twice the number of buckets.
unsigned NumNodes; unsigned NumNodes;
public: public:
explicit FoldingSetImpl(unsigned Log2InitSize = 6); explicit FoldingSetImpl(unsigned Log2InitSize = 6);
virtual ~FoldingSetImpl(); virtual ~FoldingSetImpl();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// Node - This class is used to maintain the singly linked bucket list in /// Node - This class is used to maintain the singly linked bucket list in
/// a folding set. /// a folding set.
@@ -133,11 +133,11 @@ public:
private: private:
// NextInFoldingSetBucket - next link in the bucket list. // NextInFoldingSetBucket - next link in the bucket list.
void *NextInFoldingSetBucket; void *NextInFoldingSetBucket;
public: public:
Node() : NextInFoldingSetBucket(0) {} Node() : NextInFoldingSetBucket(0) {}
// Accessors // Accessors
void *getNextInBucket() const { return NextInFoldingSetBucket; } void *getNextInBucket() const { return NextInFoldingSetBucket; }
void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; } void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
@@ -149,34 +149,34 @@ public:
/// RemoveNode - Remove a node from the folding set, returning true if one /// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set. /// was removed or false if the node was not in the folding set.
bool RemoveNode(Node *N); bool RemoveNode(Node *N);
/// GetOrInsertNode - If there is an existing simple Node exactly /// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and return /// equal to the specified node, return it. Otherwise, insert 'N' and return
/// it instead. /// it instead.
Node *GetOrInsertNode(Node *N); Node *GetOrInsertNode(Node *N);
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists, /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion /// return it. If not, return the insertion token that will make insertion
/// faster. /// faster.
Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos); Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
/// InsertNode - Insert the specified node into the folding set, knowing that /// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from /// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos. /// FindNodeOrInsertPos.
void InsertNode(Node *N, void *InsertPos); void InsertNode(Node *N, void *InsertPos);
/// size - Returns the number of nodes in the folding set. /// size - Returns the number of nodes in the folding set.
unsigned size() const { return NumNodes; } unsigned size() const { return NumNodes; }
/// empty - Returns true if there are no nodes in the folding set. /// empty - Returns true if there are no nodes in the folding set.
bool empty() const { return NumNodes == 0; } bool empty() const { return NumNodes == 0; }
private: private:
/// GrowHashTable - Double the size of the hash table and rehash everything. /// GrowHashTable - Double the size of the hash table and rehash everything.
/// ///
void GrowHashTable(); void GrowHashTable();
protected: protected:
/// GetNodeProfile - Instantiations of the FoldingSet template implement /// GetNodeProfile - Instantiations of the FoldingSet template implement
@@ -196,26 +196,26 @@ template<typename T> struct FoldingSetTrait {
static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);} static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);}
static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); } static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
}; };
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// FoldingSetNodeID - This class is used to gather all the unique data bits of /// FoldingSetNodeID - This class is used to gather all the unique data bits of
/// a node. When all the bits are gathered this class is used to produce a /// a node. When all the bits are gathered this class is used to produce a
/// hash value for the node. /// hash value for the node.
/// ///
class FoldingSetNodeID { class FoldingSetNodeID {
/// Bits - Vector of all the data bits that make the node unique. /// Bits - Vector of all the data bits that make the node unique.
/// Use a SmallVector to avoid a heap allocation in the common case. /// Use a SmallVector to avoid a heap allocation in the common case.
SmallVector<unsigned, 32> Bits; SmallVector<unsigned, 32> Bits;
public: public:
FoldingSetNodeID() {} FoldingSetNodeID() {}
/// getRawData - Return the ith entry in the Bits data. /// getRawData - Return the ith entry in the Bits data.
/// ///
unsigned getRawData(unsigned i) const { unsigned getRawData(unsigned i) const {
return Bits[i]; return Bits[i];
} }
/// Add* - Add various data types to Bit data. /// Add* - Add various data types to Bit data.
/// ///
void AddPointer(const void *Ptr); void AddPointer(const void *Ptr);
@@ -229,31 +229,31 @@ public:
void AddDouble(double D); void AddDouble(double D);
void AddString(const std::string &String); void AddString(const std::string &String);
void AddString(const char* String); void AddString(const char* String);
template <typename T> template <typename T>
inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); } inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); }
/// clear - Clear the accumulated profile, allowing this FoldingSetNodeID /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
/// object to be used to compute a new profile. /// object to be used to compute a new profile.
inline void clear() { Bits.clear(); } inline void clear() { Bits.clear(); }
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
/// to lookup the node in the FoldingSetImpl. /// to lookup the node in the FoldingSetImpl.
unsigned ComputeHash() const; unsigned ComputeHash() const;
/// operator== - Used to compare two nodes to each other. /// operator== - Used to compare two nodes to each other.
/// ///
bool operator==(const FoldingSetNodeID &RHS) const; bool operator==(const FoldingSetNodeID &RHS) const;
}; };
// Convenience type to hide the implementation of the folding set. // Convenience type to hide the implementation of the folding set.
typedef FoldingSetImpl::Node FoldingSetNode; typedef FoldingSetImpl::Node FoldingSetNode;
template<class T> class FoldingSetIterator; template<class T> class FoldingSetIterator;
template<class T> class FoldingSetBucketIterator; template<class T> class FoldingSetBucketIterator;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSet - This template class is used to instantiate a specialized /// FoldingSet - This template class is used to instantiate a specialized
/// implementation of the folding set to the node class T. T must be a /// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function. /// subclass of FoldingSetNode and implement a Profile function.
/// ///
template<class T> class FoldingSet : public FoldingSetImpl { template<class T> class FoldingSet : public FoldingSetImpl {
@@ -264,12 +264,12 @@ private:
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
FoldingSetTrait<T>::Profile(*TN,ID); FoldingSetTrait<T>::Profile(*TN,ID);
} }
public: public:
explicit FoldingSet(unsigned Log2InitSize = 6) explicit FoldingSet(unsigned Log2InitSize = 6)
: FoldingSetImpl(Log2InitSize) : FoldingSetImpl(Log2InitSize)
{} {}
typedef FoldingSetIterator<T> iterator; typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); } iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); } iterator end() { return iterator(Buckets+NumBuckets); }
@@ -278,23 +278,23 @@ public:
const_iterator begin() const { return const_iterator(Buckets); } const_iterator begin() const { return const_iterator(Buckets); }
const_iterator end() const { return const_iterator(Buckets+NumBuckets); } const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
typedef FoldingSetBucketIterator<T> bucket_iterator; typedef FoldingSetBucketIterator<T> bucket_iterator;
bucket_iterator bucket_begin(unsigned hash) { bucket_iterator bucket_begin(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1))); return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
} }
bucket_iterator bucket_end(unsigned hash) { bucket_iterator bucket_end(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true); return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
} }
/// GetOrInsertNode - If there is an existing simple Node exactly /// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and /// equal to the specified node, return it. Otherwise, insert 'N' and
/// return it instead. /// return it instead.
T *GetOrInsertNode(Node *N) { T *GetOrInsertNode(Node *N) {
return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N)); return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
} }
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists, /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion /// return it. If not, return the insertion token that will make insertion
/// faster. /// faster.
@@ -311,7 +311,7 @@ protected:
FoldingSetNode *NodePtr; FoldingSetNode *NodePtr;
FoldingSetIteratorImpl(void **Bucket); FoldingSetIteratorImpl(void **Bucket);
void advance(); void advance();
public: public:
bool operator==(const FoldingSetIteratorImpl &RHS) const { bool operator==(const FoldingSetIteratorImpl &RHS) const {
return NodePtr == RHS.NodePtr; return NodePtr == RHS.NodePtr;
@@ -326,15 +326,15 @@ template<class T>
class FoldingSetIterator : public FoldingSetIteratorImpl { class FoldingSetIterator : public FoldingSetIteratorImpl {
public: public:
explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {} explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
T &operator*() const { T &operator*() const {
return *static_cast<T*>(NodePtr); return *static_cast<T*>(NodePtr);
} }
T *operator->() const { T *operator->() const {
return static_cast<T*>(NodePtr); return static_cast<T*>(NodePtr);
} }
inline FoldingSetIterator& operator++() { // Preincrement inline FoldingSetIterator& operator++() { // Preincrement
advance(); advance();
return *this; return *this;
@@ -343,18 +343,18 @@ public:
FoldingSetIterator tmp = *this; ++*this; return tmp; FoldingSetIterator tmp = *this; ++*this; return tmp;
} }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support /// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
/// shared by all folding sets, which knows how to walk a particular bucket /// shared by all folding sets, which knows how to walk a particular bucket
/// of a folding set hash table. /// of a folding set hash table.
class FoldingSetBucketIteratorImpl { class FoldingSetBucketIteratorImpl {
protected: protected:
void *Ptr; void *Ptr;
explicit FoldingSetBucketIteratorImpl(void **Bucket); explicit FoldingSetBucketIteratorImpl(void **Bucket);
FoldingSetBucketIteratorImpl(void **Bucket, bool) FoldingSetBucketIteratorImpl(void **Bucket, bool)
: Ptr(Bucket) {} : Ptr(Bucket) {}
@@ -363,7 +363,7 @@ protected:
uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1; uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
Ptr = reinterpret_cast<void*>(x); Ptr = reinterpret_cast<void*>(x);
} }
public: public:
bool operator==(const FoldingSetBucketIteratorImpl &RHS) const { bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
return Ptr == RHS.Ptr; return Ptr == RHS.Ptr;
@@ -372,29 +372,29 @@ public:
return Ptr != RHS.Ptr; return Ptr != RHS.Ptr;
} }
}; };
template<class T> template<class T>
class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl { class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
public: public:
explicit FoldingSetBucketIterator(void **Bucket) : explicit FoldingSetBucketIterator(void **Bucket) :
FoldingSetBucketIteratorImpl(Bucket) {} FoldingSetBucketIteratorImpl(Bucket) {}
FoldingSetBucketIterator(void **Bucket, bool) : FoldingSetBucketIterator(void **Bucket, bool) :
FoldingSetBucketIteratorImpl(Bucket, true) {} FoldingSetBucketIteratorImpl(Bucket, true) {}
T& operator*() const { return *static_cast<T*>(Ptr); } T& operator*() const { return *static_cast<T*>(Ptr); }
T* operator->() const { return static_cast<T*>(Ptr); } T* operator->() const { return static_cast<T*>(Ptr); }
inline FoldingSetBucketIterator& operator++() { // Preincrement inline FoldingSetBucketIterator& operator++() { // Preincrement
advance(); advance();
return *this; return *this;
} }
FoldingSetBucketIterator operator++(int) { // Postincrement FoldingSetBucketIterator operator++(int) { // Postincrement
FoldingSetBucketIterator tmp = *this; ++*this; return tmp; FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
} }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary /// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
/// types in an enclosing object so that they can be inserted into FoldingSets. /// types in an enclosing object so that they can be inserted into FoldingSets.
@@ -404,30 +404,30 @@ class FoldingSetNodeWrapper : public FoldingSetNode {
public: public:
explicit FoldingSetNodeWrapper(const T& x) : data(x) {} explicit FoldingSetNodeWrapper(const T& x) : data(x) {}
virtual ~FoldingSetNodeWrapper() {} virtual ~FoldingSetNodeWrapper() {}
template<typename A1> template<typename A1>
explicit FoldingSetNodeWrapper(const A1& a1) explicit FoldingSetNodeWrapper(const A1& a1)
: data(a1) {} : data(a1) {}
template <typename A1, typename A2> template <typename A1, typename A2>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2) explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2)
: data(a1,a2) {} : data(a1,a2) {}
template <typename A1, typename A2, typename A3> template <typename A1, typename A2, typename A3>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3) explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3)
: data(a1,a2,a3) {} : data(a1,a2,a3) {}
template <typename A1, typename A2, typename A3, typename A4> template <typename A1, typename A2, typename A3, typename A4>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) const A4& a4)
: data(a1,a2,a3,a4) {} : data(a1,a2,a3,a4) {}
template <typename A1, typename A2, typename A3, typename A4, typename A5> template <typename A1, typename A2, typename A3, typename A4, typename A5>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
const A4& a4, const A5& a5) const A4& a4, const A5& a5)
: data(a1,a2,a3,a4,a5) {} : data(a1,a2,a3,a4,a5) {}
void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); } void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); }
T& getValue() { return data; } T& getValue() { return data; }
@@ -435,8 +435,8 @@ public:
operator T&() { return data; } operator T&() { return data; }
operator const T&() const { return data; } operator const T&() const { return data; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Partial specializations of FoldingSetTrait. // Partial specializations of FoldingSetTrait.

View File

@@ -84,15 +84,15 @@ template<class T>
struct GraphTraits<Inverse<Inverse<T> > > { struct GraphTraits<Inverse<Inverse<T> > > {
typedef typename GraphTraits<T>::NodeType NodeType; typedef typename GraphTraits<T>::NodeType NodeType;
typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType; typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
static NodeType *getEntryNode(Inverse<Inverse<T> > *G) { static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
return GraphTraits<T>::getEntryNode(G->Graph.Graph); return GraphTraits<T>::getEntryNode(G->Graph.Graph);
} }
static ChildIteratorType child_begin(NodeType* N) { static ChildIteratorType child_begin(NodeType* N) {
return GraphTraits<T>::child_begin(N); return GraphTraits<T>::child_begin(N);
} }
static ChildIteratorType child_end(NodeType* N) { static ChildIteratorType child_end(NodeType* N) {
return GraphTraits<T>::child_end(N); return GraphTraits<T>::child_end(N);
} }

View File

@@ -22,7 +22,7 @@
namespace llvm { namespace llvm {
template <typename T> class ImmutableListFactory; template <typename T> class ImmutableListFactory;
template <typename T> template <typename T>
class ImmutableListImpl : public FoldingSetNode { class ImmutableListImpl : public FoldingSetNode {
T Head; T Head;
@@ -30,28 +30,28 @@ class ImmutableListImpl : public FoldingSetNode {
ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0) ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0)
: Head(head), Tail(tail) {} : Head(head), Tail(tail) {}
friend class ImmutableListFactory<T>; friend class ImmutableListFactory<T>;
// Do not implement. // Do not implement.
void operator=(const ImmutableListImpl&); void operator=(const ImmutableListImpl&);
ImmutableListImpl(const ImmutableListImpl&); ImmutableListImpl(const ImmutableListImpl&);
public: public:
const T& getHead() const { return Head; } const T& getHead() const { return Head; }
const ImmutableListImpl* getTail() const { return Tail; } const ImmutableListImpl* getTail() const { return Tail; }
static inline void Profile(FoldingSetNodeID& ID, const T& H, static inline void Profile(FoldingSetNodeID& ID, const T& H,
const ImmutableListImpl* L){ const ImmutableListImpl* L){
ID.AddPointer(L); ID.AddPointer(L);
ID.Add(H); ID.Add(H);
} }
void Profile(FoldingSetNodeID& ID) { void Profile(FoldingSetNodeID& ID) {
Profile(ID, Head, Tail); Profile(ID, Head, Tail);
} }
}; };
/// ImmutableList - This class represents an immutable (functional) list. /// ImmutableList - This class represents an immutable (functional) list.
/// It is implemented as a smart pointer (wraps ImmutableListImpl), so it /// It is implemented as a smart pointer (wraps ImmutableListImpl), so it
/// it is intended to always be copied by value as if it were a pointer. /// it is intended to always be copied by value as if it were a pointer.
@@ -78,37 +78,37 @@ public:
const ImmutableListImpl<T>* getInternalPointer() const { const ImmutableListImpl<T>* getInternalPointer() const {
return X; return X;
} }
class iterator { class iterator {
const ImmutableListImpl<T>* L; const ImmutableListImpl<T>* L;
public: public:
iterator() : L(0) {} iterator() : L(0) {}
iterator(ImmutableList l) : L(l.getInternalPointer()) {} iterator(ImmutableList l) : L(l.getInternalPointer()) {}
iterator& operator++() { L = L->getTail(); return *this; } iterator& operator++() { L = L->getTail(); return *this; }
bool operator==(const iterator& I) const { return L == I.L; } bool operator==(const iterator& I) const { return L == I.L; }
bool operator!=(const iterator& I) const { return L != I.L; } bool operator!=(const iterator& I) const { return L != I.L; }
const value_type& operator*() const { return L->getHead(); } const value_type& operator*() const { return L->getHead(); }
ImmutableList getList() const { return L; } ImmutableList getList() const { return L; }
}; };
/// begin - Returns an iterator referring to the head of the list, or /// begin - Returns an iterator referring to the head of the list, or
/// an iterator denoting the end of the list if the list is empty. /// an iterator denoting the end of the list if the list is empty.
iterator begin() const { return iterator(X); } iterator begin() const { return iterator(X); }
/// end - Returns an iterator denoting the end of the list. This iterator /// end - Returns an iterator denoting the end of the list. This iterator
/// does not refer to a valid list element. /// does not refer to a valid list element.
iterator end() const { return iterator(); } iterator end() const { return iterator(); }
/// isEmpty - Returns true if the list is empty. /// isEmpty - Returns true if the list is empty.
bool isEmpty() const { return !X; } bool isEmpty() const { return !X; }
/// isEqual - Returns true if two lists are equal. Because all lists created /// isEqual - Returns true if two lists are equal. Because all lists created
/// from the same ImmutableListFactory are uniqued, this has O(1) complexity /// from the same ImmutableListFactory are uniqued, this has O(1) complexity
/// because it the contents of the list do not need to be compared. Note /// because it the contents of the list do not need to be compared. Note
/// that you should only compare two lists created from the same /// that you should only compare two lists created from the same
/// ImmutableListFactory. /// ImmutableListFactory.
bool isEqual(const ImmutableList& L) const { return X == L.X; } bool isEqual(const ImmutableList& L) const { return X == L.X; }
bool operator==(const ImmutableList& L) const { return isEqual(L); } bool operator==(const ImmutableList& L) const { return isEqual(L); }
@@ -117,80 +117,80 @@ public:
assert (!isEmpty() && "Cannot get the head of an empty list."); assert (!isEmpty() && "Cannot get the head of an empty list.");
return X->getHead(); return X->getHead();
} }
/// getTail - Returns the tail of the list, which is another (possibly empty) /// getTail - Returns the tail of the list, which is another (possibly empty)
/// ImmutableList. /// ImmutableList.
ImmutableList getTail() { ImmutableList getTail() {
return X ? X->getTail() : 0; return X ? X->getTail() : 0;
} }
void Profile(FoldingSetNodeID& ID) const { void Profile(FoldingSetNodeID& ID) const {
ID.AddPointer(X); ID.AddPointer(X);
} }
}; };
template <typename T> template <typename T>
class ImmutableListFactory { class ImmutableListFactory {
typedef ImmutableListImpl<T> ListTy; typedef ImmutableListImpl<T> ListTy;
typedef FoldingSet<ListTy> CacheTy; typedef FoldingSet<ListTy> CacheTy;
CacheTy Cache; CacheTy Cache;
uintptr_t Allocator; uintptr_t Allocator;
bool ownsAllocator() const { bool ownsAllocator() const {
return Allocator & 0x1 ? false : true; return Allocator & 0x1 ? false : true;
} }
BumpPtrAllocator& getAllocator() const { BumpPtrAllocator& getAllocator() const {
return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1); return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
} }
public: public:
ImmutableListFactory() ImmutableListFactory()
: Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {} : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
ImmutableListFactory(BumpPtrAllocator& Alloc) ImmutableListFactory(BumpPtrAllocator& Alloc)
: Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {} : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
~ImmutableListFactory() { ~ImmutableListFactory() {
if (ownsAllocator()) delete &getAllocator(); if (ownsAllocator()) delete &getAllocator();
} }
ImmutableList<T> Concat(const T& Head, ImmutableList<T> Tail) { ImmutableList<T> Concat(const T& Head, ImmutableList<T> Tail) {
// Profile the new list to see if it already exists in our cache. // Profile the new list to see if it already exists in our cache.
FoldingSetNodeID ID; FoldingSetNodeID ID;
void* InsertPos; void* InsertPos;
const ListTy* TailImpl = Tail.getInternalPointer(); const ListTy* TailImpl = Tail.getInternalPointer();
ListTy::Profile(ID, Head, TailImpl); ListTy::Profile(ID, Head, TailImpl);
ListTy* L = Cache.FindNodeOrInsertPos(ID, InsertPos); ListTy* L = Cache.FindNodeOrInsertPos(ID, InsertPos);
if (!L) { if (!L) {
// The list does not exist in our cache. Create it. // The list does not exist in our cache. Create it.
BumpPtrAllocator& A = getAllocator(); BumpPtrAllocator& A = getAllocator();
L = (ListTy*) A.Allocate<ListTy>(); L = (ListTy*) A.Allocate<ListTy>();
new (L) ListTy(Head, TailImpl); new (L) ListTy(Head, TailImpl);
// Insert the new list into the cache. // Insert the new list into the cache.
Cache.InsertNode(L, InsertPos); Cache.InsertNode(L, InsertPos);
} }
return L; return L;
} }
ImmutableList<T> Add(const T& D, ImmutableList<T> L) { ImmutableList<T> Add(const T& D, ImmutableList<T> L) {
return Concat(D, L); return Concat(D, L);
} }
ImmutableList<T> GetEmptyList() const { ImmutableList<T> GetEmptyList() const {
return ImmutableList<T>(0); return ImmutableList<T>(0);
} }
ImmutableList<T> Create(const T& X) { ImmutableList<T> Create(const T& X) {
return Concat(X, GetEmptyList()); return Concat(X, GetEmptyList());
} }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Partially-specialized Traits. // Partially-specialized Traits.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -205,7 +205,7 @@ template<typename T> struct DenseMapInfo<ImmutableList<T> > {
} }
static unsigned getHashValue(ImmutableList<T> X) { static unsigned getHashValue(ImmutableList<T> X) {
uintptr_t PtrVal = reinterpret_cast<uintptr_t>(X.getInternalPointer()); uintptr_t PtrVal = reinterpret_cast<uintptr_t>(X.getInternalPointer());
return (unsigned((uintptr_t)PtrVal) >> 4) ^ return (unsigned((uintptr_t)PtrVal) >> 4) ^
(unsigned((uintptr_t)PtrVal) >> 9); (unsigned((uintptr_t)PtrVal) >> 9);
} }
static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) { static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
@@ -213,7 +213,7 @@ template<typename T> struct DenseMapInfo<ImmutableList<T> > {
} }
static bool isPod() { return true; } static bool isPod() { return true; }
}; };
} // end llvm namespace } // end llvm namespace
#endif #endif

View File

@@ -29,34 +29,34 @@ struct ImutKeyValueInfo {
typedef const T& key_type_ref; typedef const T& key_type_ref;
typedef const S data_type; typedef const S data_type;
typedef const S& data_type_ref; typedef const S& data_type_ref;
static inline key_type_ref KeyOfValue(value_type_ref V) { static inline key_type_ref KeyOfValue(value_type_ref V) {
return V.first; return V.first;
} }
static inline data_type_ref DataOfValue(value_type_ref V) { static inline data_type_ref DataOfValue(value_type_ref V) {
return V.second; return V.second;
} }
static inline bool isEqual(key_type_ref L, key_type_ref R) { static inline bool isEqual(key_type_ref L, key_type_ref R) {
return ImutContainerInfo<T>::isEqual(L,R); return ImutContainerInfo<T>::isEqual(L,R);
} }
static inline bool isLess(key_type_ref L, key_type_ref R) { static inline bool isLess(key_type_ref L, key_type_ref R) {
return ImutContainerInfo<T>::isLess(L,R); return ImutContainerInfo<T>::isLess(L,R);
} }
static inline bool isDataEqual(data_type_ref L, data_type_ref R) { static inline bool isDataEqual(data_type_ref L, data_type_ref R) {
return ImutContainerInfo<S>::isEqual(L,R); return ImutContainerInfo<S>::isEqual(L,R);
} }
static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) { static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
ImutContainerInfo<T>::Profile(ID, V.first); ImutContainerInfo<T>::Profile(ID, V.first);
ImutContainerInfo<S>::Profile(ID, V.second); ImutContainerInfo<S>::Profile(ID, V.second);
} }
}; };
template <typename KeyT, typename ValT, template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT> > typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
class ImmutableMap { class ImmutableMap {
public: public:
@@ -67,62 +67,62 @@ public:
typedef typename ValInfo::data_type data_type; typedef typename ValInfo::data_type data_type;
typedef typename ValInfo::data_type_ref data_type_ref; typedef typename ValInfo::data_type_ref data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy; typedef ImutAVLTree<ValInfo> TreeTy;
private: private:
TreeTy* Root; TreeTy* Root;
public: public:
/// Constructs a map from a pointer to a tree root. In general one /// Constructs a map from a pointer to a tree root. In general one
/// should use a Factory object to create maps instead of directly /// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this /// invoking the constructor, but there are cases where make this
/// constructor public is useful. /// constructor public is useful.
explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {} explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {}
class Factory { class Factory {
typename TreeTy::Factory F; typename TreeTy::Factory F;
public: public:
Factory() {} Factory() {}
Factory(BumpPtrAllocator& Alloc) Factory(BumpPtrAllocator& Alloc)
: F(Alloc) {} : F(Alloc) {}
ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); } ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); }
ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) { ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
return ImmutableMap(F.Add(Old.Root, return ImmutableMap(F.Add(Old.Root,
std::make_pair<key_type,data_type>(K,D))); std::make_pair<key_type,data_type>(K,D)));
} }
ImmutableMap Remove(ImmutableMap Old, key_type_ref K) { ImmutableMap Remove(ImmutableMap Old, key_type_ref K) {
return ImmutableMap(F.Remove(Old.Root,K)); return ImmutableMap(F.Remove(Old.Root,K));
} }
private: private:
Factory(const Factory& RHS) {}; Factory(const Factory& RHS) {};
void operator=(const Factory& RHS) {}; void operator=(const Factory& RHS) {};
}; };
friend class Factory; friend class Factory;
bool contains(key_type_ref K) const { bool contains(key_type_ref K) const {
return Root ? Root->contains(K) : false; return Root ? Root->contains(K) : false;
} }
bool operator==(ImmutableMap RHS) const { bool operator==(ImmutableMap RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
} }
bool operator!=(ImmutableMap RHS) const { bool operator!=(ImmutableMap RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
} }
TreeTy* getRoot() const { return Root; } TreeTy* getRoot() const { return Root; }
bool isEmpty() const { return !Root; } bool isEmpty() const { return !Root; }
//===--------------------------------------------------===// //===--------------------------------------------------===//
// Foreach - A limited form of map iteration. // Foreach - A limited form of map iteration.
//===--------------------------------------------------===// //===--------------------------------------------------===//
@@ -130,47 +130,47 @@ private:
template <typename Callback> template <typename Callback>
struct CBWrapper { struct CBWrapper {
Callback C; Callback C;
void operator()(value_type_ref V) { C(V.first,V.second); } void operator()(value_type_ref V) { C(V.first,V.second); }
}; };
template <typename Callback> template <typename Callback>
struct CBWrapperRef { struct CBWrapperRef {
Callback &C; Callback &C;
CBWrapperRef(Callback& c) : C(c) {} CBWrapperRef(Callback& c) : C(c) {}
void operator()(value_type_ref V) { C(V.first,V.second); } void operator()(value_type_ref V) { C(V.first,V.second); }
}; };
public: public:
template <typename Callback> template <typename Callback>
void foreach(Callback& C) { void foreach(Callback& C) {
if (Root) { if (Root) {
CBWrapperRef<Callback> CB(C); CBWrapperRef<Callback> CB(C);
Root->foreach(CB); Root->foreach(CB);
} }
} }
template <typename Callback> template <typename Callback>
void foreach() { void foreach() {
if (Root) { if (Root) {
CBWrapper<Callback> CB; CBWrapper<Callback> CB;
Root->foreach(CB); Root->foreach(CB);
} }
} }
//===--------------------------------------------------===// //===--------------------------------------------------===//
// For testing. // For testing.
//===--------------------------------------------------===// //===--------------------------------------------------===//
void verify() const { if (Root) Root->verify(); } void verify() const { if (Root) Root->verify(); }
//===--------------------------------------------------===// //===--------------------------------------------------===//
// Iterators. // Iterators.
//===--------------------------------------------------===// //===--------------------------------------------------===//
class iterator { class iterator {
typename TreeTy::iterator itr; typename TreeTy::iterator itr;
iterator() {} iterator() {}
iterator(TreeTy* t) : itr(t) {} iterator(TreeTy* t) : itr(t) {}
friend class ImmutableMap; friend class ImmutableMap;
@@ -178,46 +178,46 @@ public:
public: public:
value_type_ref operator*() const { return itr->getValue(); } value_type_ref operator*() const { return itr->getValue(); }
value_type* operator->() const { return &itr->getValue(); } value_type* operator->() const { return &itr->getValue(); }
key_type_ref getKey() const { return itr->getValue().first; } key_type_ref getKey() const { return itr->getValue().first; }
data_type_ref getData() const { return itr->getValue().second; } data_type_ref getData() const { return itr->getValue().second; }
iterator& operator++() { ++itr; return *this; } iterator& operator++() { ++itr; return *this; }
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
iterator& operator--() { --itr; return *this; } iterator& operator--() { --itr; return *this; }
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
bool operator==(const iterator& RHS) const { return RHS.itr == itr; } bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
}; };
iterator begin() const { return iterator(Root); } iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); } iterator end() const { return iterator(); }
data_type* lookup(key_type_ref K) const { data_type* lookup(key_type_ref K) const {
if (Root) { if (Root) {
TreeTy* T = Root->find(K); TreeTy* T = Root->find(K);
if (T) return &T->getValue().second; if (T) return &T->getValue().second;
} }
return 0; return 0;
} }
//===--------------------------------------------------===// //===--------------------------------------------------===//
// Utility methods. // Utility methods.
//===--------------------------------------------------===// //===--------------------------------------------------===//
inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; } inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) { static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
ID.AddPointer(M.Root); ID.AddPointer(M.Root);
} }
inline void Profile(FoldingSetNodeID& ID) const { inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID,*this); return Profile(ID,*this);
} }
}; };
} // end namespace llvm } // end namespace llvm
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ namespace llvm {
/// guarantees deletion of the object pointed to, either on destruction of the /// guarantees deletion of the object pointed to, either on destruction of the
/// OwningPtr or via an explicit reset(). Once created, ownership of the /// OwningPtr or via an explicit reset(). Once created, ownership of the
/// pointee object can be taken away from OwningPtr by using the take method. /// pointee object can be taken away from OwningPtr by using the take method.
template<class T> template<class T>
class OwningPtr { class OwningPtr {
OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT
OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT
@@ -38,7 +38,7 @@ public:
/// reset - Change the current pointee to the specified pointer. Note that /// reset - Change the current pointee to the specified pointer. Note that
/// calling this with any pointer (including a null pointer) deletes the /// calling this with any pointer (including a null pointer) deletes the
/// current pointer. /// current pointer.
void reset(T *P = 0) { void reset(T *P = 0) {
if (P == Ptr) return; if (P == Ptr) return;
T *Tmp = Ptr; T *Tmp = Ptr;
Ptr = P; Ptr = P;
@@ -47,12 +47,12 @@ public:
/// take - Reset the owning pointer to null and return its pointer. This does /// take - Reset the owning pointer to null and return its pointer. This does
/// not delete the pointer before returning it. /// not delete the pointer before returning it.
T *take() { T *take() {
T *Tmp = Ptr; T *Tmp = Ptr;
Ptr = 0; Ptr = 0;
return Tmp; return Tmp;
} }
T &operator*() const { T &operator*() const {
assert(Ptr && "Cannot dereference null pointer"); assert(Ptr && "Cannot dereference null pointer");
return *Ptr; return *Ptr;
@@ -77,7 +77,7 @@ inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same /// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
/// functionality as OwningPtr, except that it works for array types. /// functionality as OwningPtr, except that it works for array types.
template<class T> template<class T>
class OwningArrayPtr { class OwningArrayPtr {
OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT
OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
@@ -92,7 +92,7 @@ public:
/// reset - Change the current pointee to the specified pointer. Note that /// reset - Change the current pointee to the specified pointer. Note that
/// calling this with any pointer (including a null pointer) deletes the /// calling this with any pointer (including a null pointer) deletes the
/// current pointer. /// current pointer.
void reset(T *P = 0) { void reset(T *P = 0) {
if (P == Ptr) return; if (P == Ptr) return;
T *Tmp = Ptr; T *Tmp = Ptr;
Ptr = P; Ptr = P;
@@ -101,17 +101,17 @@ public:
/// take - Reset the owning pointer to null and return its pointer. This does /// take - Reset the owning pointer to null and return its pointer. This does
/// not delete the pointer before returning it. /// not delete the pointer before returning it.
T *take() { T *take() {
T *Tmp = Ptr; T *Tmp = Ptr;
Ptr = 0; Ptr = 0;
return Tmp; return Tmp;
} }
T &operator[](std::ptrdiff_t i) const { T &operator[](std::ptrdiff_t i) const {
assert(Ptr && "Cannot dereference null pointer"); assert(Ptr && "Cannot dereference null pointer");
return Ptr[i]; return Ptr[i];
} }
T *get() const { return Ptr; } T *get() const { return Ptr; }
operator bool() const { return Ptr != 0; } operator bool() const { return Ptr != 0; }
bool operator!() const { return Ptr == 0; } bool operator!() const { return Ptr == 0; }

View File

@@ -17,10 +17,10 @@
#include <cassert> #include <cassert>
namespace llvm { namespace llvm {
template<typename T> template<typename T>
struct DenseMapInfo; struct DenseMapInfo;
/// PointerIntPair - This class implements a pair of a pointer and small /// PointerIntPair - This class implements a pair of a pointer and small
/// integer. It is designed to represent this in the space required by one /// integer. It is designed to represent this in the space required by one
/// pointer by bitmangling the integer into the low part of the pointer. This /// pointer by bitmangling the integer into the low part of the pointer. This
@@ -40,27 +40,27 @@ public:
PointerTy getPointer() const { PointerTy getPointer() const {
return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1)); return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1));
} }
IntType getInt() const { IntType getInt() const {
return (IntType)(Value & ((1 << IntBits)-1)); return (IntType)(Value & ((1 << IntBits)-1));
} }
void setPointer(PointerTy Ptr) { void setPointer(PointerTy Ptr) {
intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr); intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
assert((PtrVal & ((1 << IntBits)-1)) == 0 && assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
"Pointer is not sufficiently aligned"); "Pointer is not sufficiently aligned");
Value = PtrVal | (intptr_t)getInt(); Value = PtrVal | (intptr_t)getInt();
} }
void setInt(IntType Int) { void setInt(IntType Int) {
intptr_t IntVal = Int; intptr_t IntVal = Int;
assert(IntVal < (1 << IntBits) && "Integer too large for field"); assert(IntVal < (1 << IntBits) && "Integer too large for field");
Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal; Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal;
} }
void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); } void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);} void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;} bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;} bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;} bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}

View File

@@ -24,30 +24,30 @@
namespace llvm { namespace llvm {
template<class SetType, bool External> // Non-external set template<class SetType, bool External> // Non-external set
class po_iterator_storage { class po_iterator_storage {
public: public:
SetType Visited; SetType Visited;
}; };
template<class SetType> template<class SetType>
class po_iterator_storage<SetType, true> { class po_iterator_storage<SetType, true> {
public: public:
po_iterator_storage(SetType &VSet) : Visited(VSet) {} po_iterator_storage(SetType &VSet) : Visited(VSet) {}
po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {} po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
SetType &Visited; SetType &Visited;
}; };
template<class GraphT, template<class GraphT,
class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>, class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>,
bool ExtStorage = false, bool ExtStorage = false,
class GT = GraphTraits<GraphT> > class GT = GraphTraits<GraphT> >
class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>, class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
public po_iterator_storage<SetType, ExtStorage> { public po_iterator_storage<SetType, ExtStorage> {
typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super; typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
typedef typename GT::NodeType NodeType; typedef typename GT::NodeType NodeType;
typedef typename GT::ChildIteratorType ChildItTy; typedef typename GT::ChildIteratorType ChildItTy;
// VisitStack - Used to maintain the ordering. Top = current block // VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit // First element is basic block pointer, second is the 'next child' to visit
std::stack<std::pair<NodeType *, ChildItTy> > VisitStack; std::stack<std::pair<NodeType *, ChildItTy> > VisitStack;
@@ -67,33 +67,33 @@ class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
traverseChild(); traverseChild();
} }
inline po_iterator() {} // End is when stack is empty. inline po_iterator() {} // End is when stack is empty.
inline po_iterator(NodeType *BB, SetType &S) : inline po_iterator(NodeType *BB, SetType &S) :
po_iterator_storage<SetType, ExtStorage>(&S) { po_iterator_storage<SetType, ExtStorage>(&S) {
if(!S.count(BB)) { if(!S.count(BB)) {
this->Visited.insert(BB); this->Visited.insert(BB);
VisitStack.push(std::make_pair(BB, GT::child_begin(BB))); VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
traverseChild(); traverseChild();
} }
} }
inline po_iterator(SetType &S) : inline po_iterator(SetType &S) :
po_iterator_storage<SetType, ExtStorage>(&S) { po_iterator_storage<SetType, ExtStorage>(&S) {
} // End is when stack is empty. } // End is when stack is empty.
public: public:
typedef typename super::pointer pointer; typedef typename super::pointer pointer;
typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self; typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
// Provide static "constructors"... // Provide static "constructors"...
static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); } static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
static inline _Self end (GraphT G) { return _Self(); } static inline _Self end (GraphT G) { return _Self(); }
static inline _Self begin(GraphT G, SetType &S) { static inline _Self begin(GraphT G, SetType &S) {
return _Self(GT::getEntryNode(G), S); return _Self(GT::getEntryNode(G), S);
} }
static inline _Self end (GraphT G, SetType &S) { return _Self(S); } static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
inline bool operator==(const _Self& x) const { inline bool operator==(const _Self& x) const {
return VisitStack == x.VisitStack; return VisitStack == x.VisitStack;
} }
@@ -128,30 +128,30 @@ po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
template <class T> template <class T>
po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); } po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
// Provide global definitions of external postorder iterators... // Provide global definitions of external postorder iterators...
template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> > template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
struct po_ext_iterator : public po_iterator<T, SetType, true> { struct po_ext_iterator : public po_iterator<T, SetType, true> {
po_ext_iterator(const po_iterator<T, SetType, true> &V) : po_ext_iterator(const po_iterator<T, SetType, true> &V) :
po_iterator<T, SetType, true>(V) {} po_iterator<T, SetType, true>(V) {}
}; };
template<class T, class SetType>
po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
return po_ext_iterator<T, SetType>::begin(G, S);
}
template<class T, class SetType> template<class T, class SetType>
po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) { po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
return po_ext_iterator<T, SetType>::end(G, S); return po_ext_iterator<T, SetType>::begin(G, S);
} }
template<class T, class SetType>
po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
return po_ext_iterator<T, SetType>::end(G, S);
}
// Provide global definitions of inverse post order iterators... // Provide global definitions of inverse post order iterators...
template <class T, template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*>, class SetType = std::set<typename GraphTraits<T>::NodeType*>,
bool External = false> bool External = false>
struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > { struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) : ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
po_iterator<Inverse<T>, SetType, External> (V) {} po_iterator<Inverse<T>, SetType, External> (V) {}
}; };
template <class T> template <class T>
@@ -164,24 +164,24 @@ ipo_iterator<T> ipo_end(T G){
return ipo_iterator<T>::end(G); return ipo_iterator<T>::end(G);
} }
//Provide global definitions of external inverse postorder iterators... //Provide global definitions of external inverse postorder iterators...
template <class T, class SetType = std::set<typename GraphTraits<T>::NodeType*> > template <class T, class SetType = std::set<typename GraphTraits<T>::NodeType*> >
struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> { struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) : ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
ipo_iterator<T, SetType, true>(&V) {} ipo_iterator<T, SetType, true>(&V) {}
ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) : ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
ipo_iterator<T, SetType, true>(&V) {} ipo_iterator<T, SetType, true>(&V) {}
}; };
template <class T, class SetType> template <class T, class SetType>
ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) { ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
return ipo_ext_iterator<T, SetType>::begin(G, S); return ipo_ext_iterator<T, SetType>::begin(G, S);
} }
template <class T, class SetType> template <class T, class SetType>
ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) { ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
return ipo_ext_iterator<T, SetType>::end(G, S); return ipo_ext_iterator<T, SetType>::end(G, S);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Reverse Post Order CFG iterator code // Reverse Post Order CFG iterator code

View File

@@ -20,7 +20,7 @@ namespace llvm {
/// PriorityQueue - This class behaves like std::priority_queue and /// PriorityQueue - This class behaves like std::priority_queue and
/// provides a few additional convenience functions. /// provides a few additional convenience functions.
/// ///
template<class T, template<class T,
class Sequence = std::vector<T>, class Sequence = std::vector<T>,
class Compare = std::less<typename Sequence::value_type> > class Compare = std::less<typename Sequence::value_type> >

View File

@@ -231,11 +231,11 @@ static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
return 1; return 1;
return 0; return 0;
} }
/// get_array_pad_sort_comparator - This is an internal helper function used to /// get_array_pad_sort_comparator - This is an internal helper function used to
/// get type deduction of T right. /// get type deduction of T right.
template<typename T> template<typename T>
static int (*get_array_pad_sort_comparator(const T &X)) static int (*get_array_pad_sort_comparator(const T &X))
(const void*, const void*) { (const void*, const void*) {
return array_pod_sort_comparator<T>; return array_pod_sort_comparator<T>;
} }
@@ -262,7 +262,7 @@ static inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
qsort(&*Start, End-Start, sizeof(*Start), qsort(&*Start, End-Start, sizeof(*Start),
get_array_pad_sort_comparator(*Start)); get_array_pad_sort_comparator(*Start));
} }
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@@ -46,15 +46,15 @@ class ScopedHashTableVal {
K Key; K Key;
V Val; V Val;
public: public:
ScopedHashTableVal(ScopedHashTableVal *nextInScope, ScopedHashTableVal(ScopedHashTableVal *nextInScope,
ScopedHashTableVal *nextForKey, const K &key, const V &val) ScopedHashTableVal *nextForKey, const K &key, const V &val)
: NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) { : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) {
} }
const K &getKey() const { return Key; } const K &getKey() const { return Key; }
const V &getValue() const { return Val; } const V &getValue() const { return Val; }
V &getValue() { return Val; } V &getValue() { return Val; }
ScopedHashTableVal *getNextForKey() { return NextForKey; } ScopedHashTableVal *getNextForKey() { return NextForKey; }
const ScopedHashTableVal *getNextForKey() const { return NextForKey; } const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
public: public:
@@ -65,7 +65,7 @@ template <typename K, typename V>
class ScopedHashTableScope { class ScopedHashTableScope {
/// HT - The hashtable that we are active for. /// HT - The hashtable that we are active for.
ScopedHashTable<K, V> &HT; ScopedHashTable<K, V> &HT;
/// PrevScope - This is the scope that we are shadowing in HT. /// PrevScope - This is the scope that we are shadowing in HT.
ScopedHashTableScope *PrevScope; ScopedHashTableScope *PrevScope;
@@ -77,7 +77,7 @@ class ScopedHashTableScope {
public: public:
ScopedHashTableScope(ScopedHashTable<K, V> &HT); ScopedHashTableScope(ScopedHashTable<K, V> &HT);
~ScopedHashTableScope(); ~ScopedHashTableScope();
private: private:
friend class ScopedHashTable<K, V>; friend class ScopedHashTable<K, V>;
ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; } ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; }
@@ -90,7 +90,7 @@ class ScopedHashTableIterator {
ScopedHashTableVal<K,V> *Node; ScopedHashTableVal<K,V> *Node;
public: public:
ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){} ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){}
V &operator*() const { V &operator*() const {
assert(Node && "Dereference end()"); assert(Node && "Dereference end()");
return Node->getValue(); return Node->getValue();
@@ -98,14 +98,14 @@ public:
V *operator->() const { V *operator->() const {
return &Node->getValue(); return &Node->getValue();
} }
bool operator==(const ScopedHashTableIterator &RHS) const { bool operator==(const ScopedHashTableIterator &RHS) const {
return Node == RHS.Node; return Node == RHS.Node;
} }
bool operator!=(const ScopedHashTableIterator &RHS) const { bool operator!=(const ScopedHashTableIterator &RHS) const {
return Node != RHS.Node; return Node != RHS.Node;
} }
inline ScopedHashTableIterator& operator++() { // Preincrement inline ScopedHashTableIterator& operator++() { // Preincrement
assert(Node && "incrementing past end()"); assert(Node && "incrementing past end()");
Node = Node->getNextForKey(); Node = Node->getNextForKey();
@@ -129,23 +129,23 @@ public:
~ScopedHashTable() { ~ScopedHashTable() {
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
} }
void insert(const K &Key, const V &Val) { void insert(const K &Key, const V &Val) {
assert(CurScope && "No scope active!"); assert(CurScope && "No scope active!");
ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key]; ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key];
KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(), KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(),
KeyEntry, Key, Val); KeyEntry, Key, Val);
CurScope->setLastValInScope(KeyEntry); CurScope->setLastValInScope(KeyEntry);
} }
typedef ScopedHashTableIterator<K, V> iterator; typedef ScopedHashTableIterator<K, V> iterator;
iterator end() { return iterator(0); } iterator end() { return iterator(0); }
iterator begin(const K &Key) { iterator begin(const K &Key) {
typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I = typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I =
TopLevelMap.find(Key); TopLevelMap.find(Key);
if (I == TopLevelMap.end()) return end(); if (I == TopLevelMap.end()) return end();
return iterator(I->second); return iterator(I->second);
@@ -166,7 +166,7 @@ template <typename K, typename V>
ScopedHashTableScope<K, V>::~ScopedHashTableScope() { ScopedHashTableScope<K, V>::~ScopedHashTableScope() {
assert(HT.CurScope == this && "Scope imbalance!"); assert(HT.CurScope == this && "Scope imbalance!");
HT.CurScope = PrevScope; HT.CurScope = PrevScope;
// Pop and delete all values corresponding to this scope. // Pop and delete all values corresponding to this scope.
while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) { while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
// Pop this value out of the TopLevelMap. // Pop this value out of the TopLevelMap.
@@ -174,15 +174,15 @@ ScopedHashTableScope<K, V>::~ScopedHashTableScope() {
assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry && assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
"Scope imbalance!"); "Scope imbalance!");
HT.TopLevelMap.erase(ThisEntry->getKey()); HT.TopLevelMap.erase(ThisEntry->getKey());
} else { } else {
ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()]; ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
assert(KeyEntry == ThisEntry && "Scope imbalance!"); assert(KeyEntry == ThisEntry && "Scope imbalance!");
KeyEntry = ThisEntry->getNextForKey(); KeyEntry = ThisEntry->getNextForKey();
} }
// Pop this value out of the scope. // Pop this value out of the scope.
LastValInScope = ThisEntry->getNextInScope(); LastValInScope = ThisEntry->getNextInScope();
// Delete this entry. // Delete this entry.
delete ThisEntry; delete ThisEntry;
} }

View File

@@ -154,7 +154,7 @@ template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > { class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
public: public:
SmallSetVector() {} SmallSetVector() {}
/// @brief Initialize a SmallSetVector with a range of elements /// @brief Initialize a SmallSetVector with a range of elements
template<typename It> template<typename It>
SmallSetVector(It Start, It End) { SmallSetVector(It Start, It End) {

View File

@@ -48,7 +48,7 @@ protected:
/// Note that CurArray points to an array that has CurArraySize+1 elements in /// Note that CurArray points to an array that has CurArraySize+1 elements in
/// it, so that the end iterator actually points to valid memory. /// it, so that the end iterator actually points to valid memory.
unsigned CurArraySize; unsigned CurArraySize;
// If small, this is # elts allocated consequtively // If small, this is # elts allocated consequtively
unsigned NumElements; unsigned NumElements;
unsigned NumTombstones; unsigned NumTombstones;
@@ -68,41 +68,41 @@ public:
clear(); clear();
} }
~SmallPtrSetImpl(); ~SmallPtrSetImpl();
bool empty() const { return size() == 0; } bool empty() const { return size() == 0; }
unsigned size() const { return NumElements; } unsigned size() const { return NumElements; }
static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); } static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
static void *getEmptyMarker() { static void *getEmptyMarker() {
// Note that -1 is chosen to make clear() efficiently implementable with // Note that -1 is chosen to make clear() efficiently implementable with
// memset and because it's not a valid pointer value. // memset and because it's not a valid pointer value.
return reinterpret_cast<void*>(-1); return reinterpret_cast<void*>(-1);
} }
void clear() { void clear() {
// If the capacity of the array is huge, and the # elements used is small, // If the capacity of the array is huge, and the # elements used is small,
// shrink the array. // shrink the array.
if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32) if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
return shrink_and_clear(); return shrink_and_clear();
// Fill the array with empty markers. // Fill the array with empty markers.
memset(CurArray, -1, CurArraySize*sizeof(void*)); memset(CurArray, -1, CurArraySize*sizeof(void*));
NumElements = 0; NumElements = 0;
NumTombstones = 0; NumTombstones = 0;
} }
protected: protected:
/// insert_imp - This returns true if the pointer was new to the set, false if /// insert_imp - This returns true if the pointer was new to the set, false if
/// it was already in the set. This is hidden from the client so that the /// it was already in the set. This is hidden from the client so that the
/// derived class can check that the right type of pointer is passed in. /// derived class can check that the right type of pointer is passed in.
bool insert_imp(const void * Ptr); bool insert_imp(const void * Ptr);
/// erase_imp - If the set contains the specified pointer, remove it and /// erase_imp - If the set contains the specified pointer, remove it and
/// return true, otherwise return false. This is hidden from the client so /// return true, otherwise return false. This is hidden from the client so
/// that the derived class can check that the right type of pointer is passed /// that the derived class can check that the right type of pointer is passed
/// in. /// in.
bool erase_imp(const void * Ptr); bool erase_imp(const void * Ptr);
bool count_imp(const void * Ptr) const { bool count_imp(const void * Ptr) const {
if (isSmall()) { if (isSmall()) {
// Linear search for the item. // Linear search for the item.
@@ -112,11 +112,11 @@ protected:
return true; return true;
return false; return false;
} }
// Big set case. // Big set case.
return *FindBucketFor(Ptr) == Ptr; return *FindBucketFor(Ptr) == Ptr;
} }
private: private:
bool isSmall() const { return CurArray == &SmallArray[0]; } bool isSmall() const { return CurArray == &SmallArray[0]; }
@@ -125,10 +125,10 @@ private:
} }
const void * const *FindBucketFor(const void *Ptr) const; const void * const *FindBucketFor(const void *Ptr) const;
void shrink_and_clear(); void shrink_and_clear();
/// Grow - Allocate a larger backing store for the buckets and move it over. /// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(); void Grow();
void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT. void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
protected: protected:
void CopyFrom(const SmallPtrSetImpl &RHS); void CopyFrom(const SmallPtrSetImpl &RHS);
@@ -143,14 +143,14 @@ public:
explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) { explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
AdvanceIfNotValid(); AdvanceIfNotValid();
} }
bool operator==(const SmallPtrSetIteratorImpl &RHS) const { bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
return Bucket == RHS.Bucket; return Bucket == RHS.Bucket;
} }
bool operator!=(const SmallPtrSetIteratorImpl &RHS) const { bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
return Bucket != RHS.Bucket; return Bucket != RHS.Bucket;
} }
protected: protected:
/// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
/// that is. This is guaranteed to stop because the end() bucket is marked /// that is. This is guaranteed to stop because the end() bucket is marked
@@ -170,17 +170,17 @@ public:
: SmallPtrSetIteratorImpl(BP) {} : SmallPtrSetIteratorImpl(BP) {}
// Most methods provided by baseclass. // Most methods provided by baseclass.
const PtrTy operator*() const { const PtrTy operator*() const {
return static_cast<const PtrTy>(const_cast<void*>(*Bucket)); return static_cast<const PtrTy>(const_cast<void*>(*Bucket));
} }
inline SmallPtrSetIterator& operator++() { // Preincrement inline SmallPtrSetIterator& operator++() { // Preincrement
++Bucket; ++Bucket;
AdvanceIfNotValid(); AdvanceIfNotValid();
return *this; return *this;
} }
SmallPtrSetIterator operator++(int) { // Postincrement SmallPtrSetIterator operator++(int) { // Postincrement
SmallPtrSetIterator tmp = *this; ++*this; return tmp; SmallPtrSetIterator tmp = *this; ++*this; return tmp;
} }
@@ -224,30 +224,30 @@ class SmallPtrSet : public SmallPtrSetImpl {
public: public:
SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {} SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {}
SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {} SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {}
template<typename It> template<typename It>
SmallPtrSet(It I, It E) SmallPtrSet(It I, It E)
: SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) { : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {
insert(I, E); insert(I, E);
} }
/// insert - This returns true if the pointer was new to the set, false if it /// insert - This returns true if the pointer was new to the set, false if it
/// was already in the set. /// was already in the set.
bool insert(PtrType Ptr) { return insert_imp(Ptr); } bool insert(PtrType Ptr) { return insert_imp(Ptr); }
/// erase - If the set contains the specified pointer, remove it and return /// erase - If the set contains the specified pointer, remove it and return
/// true, otherwise return false. /// true, otherwise return false.
bool erase(PtrType Ptr) { return erase_imp(Ptr); } bool erase(PtrType Ptr) { return erase_imp(Ptr); }
/// count - Return true if the specified pointer is in the set. /// count - Return true if the specified pointer is in the set.
bool count(PtrType Ptr) const { return count_imp(Ptr); } bool count(PtrType Ptr) const { return count_imp(Ptr); }
template <typename IterT> template <typename IterT>
void insert(IterT I, IterT E) { void insert(IterT I, IterT E) {
for (; I != E; ++I) for (; I != E; ++I)
insert(*I); insert(*I);
} }
typedef SmallPtrSetIterator<PtrType> iterator; typedef SmallPtrSetIterator<PtrType> iterator;
typedef SmallPtrSetIterator<PtrType> const_iterator; typedef SmallPtrSetIterator<PtrType> const_iterator;
inline iterator begin() const { inline iterator begin() const {
@@ -256,7 +256,7 @@ public:
inline iterator end() const { inline iterator end() const {
return iterator(CurArray+CurArraySize); return iterator(CurArray+CurArraySize);
} }
// Allow assignment from any smallptrset with the same element type even if it // Allow assignment from any smallptrset with the same element type even if it
// doesn't have the same smallsize. // doesn't have the same smallsize.
const SmallPtrSet<PtrType, SmallSize>& const SmallPtrSet<PtrType, SmallSize>&

View File

@@ -43,7 +43,7 @@ public:
unsigned size() const { unsigned size() const {
return isSmall() ? Vector.size() : Set.size(); return isSmall() ? Vector.size() : Set.size();
} }
/// count - Return true if the element is in the set. /// count - Return true if the element is in the set.
bool count(const T &V) const { bool count(const T &V) const {
if (isSmall()) { if (isSmall()) {
@@ -53,12 +53,12 @@ public:
return Set.count(V); return Set.count(V);
} }
} }
/// insert - Insert an element into the set if it isn't already there. /// insert - Insert an element into the set if it isn't already there.
bool insert(const T &V) { bool insert(const T &V) {
if (!isSmall()) if (!isSmall())
return Set.insert(V).second; return Set.insert(V).second;
VIterator I = vfind(V); VIterator I = vfind(V);
if (I != Vector.end()) // Don't reinsert if it already exists. if (I != Vector.end()) // Don't reinsert if it already exists.
return false; return false;
@@ -75,7 +75,7 @@ public:
Set.insert(V); Set.insert(V);
return true; return true;
} }
bool erase(const T &V) { bool erase(const T &V) {
if (!isSmall()) if (!isSmall())
return Set.erase(V); return Set.erase(V);
@@ -86,14 +86,14 @@ public:
} }
return false; return false;
} }
void clear() { void clear() {
Vector.clear(); Vector.clear();
Set.clear(); Set.clear();
} }
private: private:
bool isSmall() const { return Set.empty(); } bool isSmall() const { return Set.empty(); }
VIterator vfind(const T &V) const { VIterator vfind(const T &V) const {
for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I) for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
if (*I == V) if (*I == V)

View File

@@ -31,11 +31,11 @@ public:
// Initialize with a range. // Initialize with a range.
template<typename ItTy> template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {} SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
// Copy ctor. // Copy ctor.
SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {} SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
// Extra methods. // Extra methods.
const char *c_str() const { const char *c_str() const {
SmallString *This = const_cast<SmallString*>(this); SmallString *This = const_cast<SmallString*>(this);
@@ -44,13 +44,13 @@ public:
This->End[0] = 0; This->End[0] = 0;
return this->begin(); return this->begin();
} }
// Extra operators. // Extra operators.
const SmallString &operator=(const char *RHS) { const SmallString &operator=(const char *RHS) {
this->clear(); this->clear();
return *this += RHS; return *this += RHS;
} }
SmallString &operator+=(const char *RHS) { SmallString &operator+=(const char *RHS) {
this->append(RHS, RHS+strlen(RHS)); this->append(RHS, RHS+strlen(RHS));
return *this; return *this;
@@ -63,9 +63,9 @@ public:
SmallString &append_uint_32(uint32_t N) { SmallString &append_uint_32(uint32_t N) {
char Buffer[20]; char Buffer[20];
char *BufPtr = Buffer+20; char *BufPtr = Buffer+20;
if (N == 0) *--BufPtr = '0'; // Handle special case. if (N == 0) *--BufPtr = '0'; // Handle special case.
while (N) { while (N) {
*--BufPtr = '0' + char(N % 10); *--BufPtr = '0' + char(N % 10);
N /= 10; N /= 10;
@@ -73,16 +73,16 @@ public:
this->append(BufPtr, Buffer+20); this->append(BufPtr, Buffer+20);
return *this; return *this;
} }
SmallString &append_uint(uint64_t N) { SmallString &append_uint(uint64_t N) {
if (N == uint32_t(N)) if (N == uint32_t(N))
return append_uint_32(uint32_t(N)); return append_uint_32(uint32_t(N));
char Buffer[40]; char Buffer[40];
char *BufPtr = Buffer+40; char *BufPtr = Buffer+40;
if (N == 0) *--BufPtr = '0'; // Handle special case... if (N == 0) *--BufPtr = '0'; // Handle special case...
while (N) { while (N) {
*--BufPtr = '0' + char(N % 10); *--BufPtr = '0' + char(N % 10);
N /= 10; N /= 10;
@@ -91,7 +91,7 @@ public:
this->append(BufPtr, Buffer+40); this->append(BufPtr, Buffer+40);
return *this; return *this;
} }
SmallString &append_sint(int64_t N) { SmallString &append_sint(int64_t N) {
// TODO, wrong for minint64. // TODO, wrong for minint64.
if (N < 0) { if (N < 0) {
@@ -100,10 +100,10 @@ public:
} }
return append_uint(N); return append_uint(N);
} }
}; };
} }
#endif #endif

View File

@@ -54,7 +54,7 @@ template <typename T>
class SmallVectorImpl { class SmallVectorImpl {
protected: protected:
T *Begin, *End, *Capacity; T *Begin, *End, *Capacity;
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
// don't want it to be automatically run, so we need to represent the space as // don't want it to be automatically run, so we need to represent the space as
// something else. An array of char would work great, but might not be // something else. An array of char would work great, but might not be
@@ -76,11 +76,11 @@ protected:
public: public:
// Default ctor - Initialize to empty. // Default ctor - Initialize to empty.
SmallVectorImpl(unsigned N) SmallVectorImpl(unsigned N)
: Begin(reinterpret_cast<T*>(&FirstEl)), : Begin(reinterpret_cast<T*>(&FirstEl)),
End(reinterpret_cast<T*>(&FirstEl)), End(reinterpret_cast<T*>(&FirstEl)),
Capacity(reinterpret_cast<T*>(&FirstEl)+N) { Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
} }
~SmallVectorImpl() { ~SmallVectorImpl() {
// Destroy the constructed elements in the vector. // Destroy the constructed elements in the vector.
destroy_range(Begin, End); destroy_range(Begin, End);
@@ -89,16 +89,16 @@ public:
if (!isSmall()) if (!isSmall())
operator delete(Begin); operator delete(Begin);
} }
typedef size_t size_type; typedef size_t size_type;
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef T value_type; typedef T value_type;
typedef T* iterator; typedef T* iterator;
typedef const T* const_iterator; typedef const T* const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
typedef T* pointer; typedef T* pointer;
@@ -113,14 +113,14 @@ public:
const_iterator begin() const { return Begin; } const_iterator begin() const { return Begin; }
iterator end() { return End; } iterator end() { return End; }
const_iterator end() const { return End; } const_iterator end() const { return End; }
// reverse iterator creation methods. // reverse iterator creation methods.
reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); } reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin());} const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
/* These asserts could be "Begin + idx < End", but there are lots of places /* These asserts could be "Begin + idx < End", but there are lots of places
in llvm where we use &v[v.size()] instead of v.end(). */ in llvm where we use &v[v.size()] instead of v.end(). */
reference operator[](unsigned idx) { reference operator[](unsigned idx) {
@@ -131,21 +131,21 @@ public:
assert (Begin + idx <= End); assert (Begin + idx <= End);
return Begin[idx]; return Begin[idx];
} }
reference front() { reference front() {
return begin()[0]; return begin()[0];
} }
const_reference front() const { const_reference front() const {
return begin()[0]; return begin()[0];
} }
reference back() { reference back() {
return end()[-1]; return end()[-1];
} }
const_reference back() const { const_reference back() const {
return end()[-1]; return end()[-1];
} }
void push_back(const_reference Elt) { void push_back(const_reference Elt) {
if (End < Capacity) { if (End < Capacity) {
Retry: Retry:
@@ -156,23 +156,23 @@ public:
grow(); grow();
goto Retry; goto Retry;
} }
void pop_back() { void pop_back() {
--End; --End;
End->~T(); End->~T();
} }
T pop_back_val() { T pop_back_val() {
T Result = back(); T Result = back();
pop_back(); pop_back();
return Result; return Result;
} }
void clear() { void clear() {
destroy_range(Begin, End); destroy_range(Begin, End);
End = Begin; End = Begin;
} }
void resize(unsigned N) { void resize(unsigned N) {
if (N < size()) { if (N < size()) {
destroy_range(Begin+N, End); destroy_range(Begin+N, End);
@@ -184,7 +184,7 @@ public:
End = Begin+N; End = Begin+N;
} }
} }
void resize(unsigned N, const T &NV) { void resize(unsigned N, const T &NV) {
if (N < size()) { if (N < size()) {
destroy_range(Begin+N, End); destroy_range(Begin+N, End);
@@ -196,14 +196,14 @@ public:
End = Begin+N; End = Begin+N;
} }
} }
void reserve(unsigned N) { void reserve(unsigned N) {
if (unsigned(Capacity-Begin) < N) if (unsigned(Capacity-Begin) < N)
grow(N); grow(N);
} }
void swap(SmallVectorImpl &RHS); void swap(SmallVectorImpl &RHS);
/// append - Add the specified range to the end of the SmallVector. /// append - Add the specified range to the end of the SmallVector.
/// ///
template<typename in_iter> template<typename in_iter>
@@ -217,7 +217,7 @@ public:
std::uninitialized_copy(in_start, in_end, End); std::uninitialized_copy(in_start, in_end, End);
End += NumInputs; End += NumInputs;
} }
/// append - Add the specified range to the end of the SmallVector. /// append - Add the specified range to the end of the SmallVector.
/// ///
void append(size_type NumInputs, const T &Elt) { void append(size_type NumInputs, const T &Elt) {
@@ -229,7 +229,7 @@ public:
std::uninitialized_fill_n(End, NumInputs, Elt); std::uninitialized_fill_n(End, NumInputs, Elt);
End += NumInputs; End += NumInputs;
} }
void assign(unsigned NumElts, const T &Elt) { void assign(unsigned NumElts, const T &Elt) {
clear(); clear();
if (unsigned(Capacity-Begin) < NumElts) if (unsigned(Capacity-Begin) < NumElts)
@@ -237,7 +237,7 @@ public:
End = Begin+NumElts; End = Begin+NumElts;
construct_range(Begin, End, Elt); construct_range(Begin, End, Elt);
} }
iterator erase(iterator I) { iterator erase(iterator I) {
iterator N = I; iterator N = I;
// Shift all elts down one. // Shift all elts down one.
@@ -246,7 +246,7 @@ public:
pop_back(); pop_back();
return(N); return(N);
} }
iterator erase(iterator S, iterator E) { iterator erase(iterator S, iterator E) {
iterator N = S; iterator N = S;
// Shift all elts down. // Shift all elts down.
@@ -256,13 +256,13 @@ public:
End = I; End = I;
return(N); return(N);
} }
iterator insert(iterator I, const T &Elt) { iterator insert(iterator I, const T &Elt) {
if (I == End) { // Important special case for empty vector. if (I == End) { // Important special case for empty vector.
push_back(Elt); push_back(Elt);
return end()-1; return end()-1;
} }
if (End < Capacity) { if (End < Capacity) {
Retry: Retry:
new (End) T(back()); new (End) T(back());
@@ -283,100 +283,100 @@ public:
append(NumToInsert, Elt); append(NumToInsert, Elt);
return end()-1; return end()-1;
} }
// Convert iterator to elt# to avoid invalidating iterator when we reserve() // Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I-begin(); size_t InsertElt = I-begin();
// Ensure there is enough space. // Ensure there is enough space.
reserve(static_cast<unsigned>(size() + NumToInsert)); reserve(static_cast<unsigned>(size() + NumToInsert));
// Uninvalidate the iterator. // Uninvalidate the iterator.
I = begin()+InsertElt; I = begin()+InsertElt;
// If we already have this many elements in the collection, append the // If we already have this many elements in the collection, append the
// dest elements at the end, then copy over the appropriate elements. Since // dest elements at the end, then copy over the appropriate elements. Since
// we already reserved space, we know that this won't reallocate the vector. // we already reserved space, we know that this won't reallocate the vector.
if (size() >= NumToInsert) { if (size() >= NumToInsert) {
T *OldEnd = End; T *OldEnd = End;
append(End-NumToInsert, End); append(End-NumToInsert, End);
// Copy the existing elements that get replaced. // Copy the existing elements that get replaced.
std::copy(I, OldEnd-NumToInsert, I+NumToInsert); std::copy(I, OldEnd-NumToInsert, I+NumToInsert);
std::fill_n(I, NumToInsert, Elt); std::fill_n(I, NumToInsert, Elt);
return I; return I;
} }
// Otherwise, we're inserting more elements than exist already, and we're // Otherwise, we're inserting more elements than exist already, and we're
// not inserting at the end. // not inserting at the end.
// Copy over the elements that we're about to overwrite. // Copy over the elements that we're about to overwrite.
T *OldEnd = End; T *OldEnd = End;
End += NumToInsert; End += NumToInsert;
size_t NumOverwritten = OldEnd-I; size_t NumOverwritten = OldEnd-I;
std::uninitialized_copy(I, OldEnd, End-NumOverwritten); std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
// Replace the overwritten part. // Replace the overwritten part.
std::fill_n(I, NumOverwritten, Elt); std::fill_n(I, NumOverwritten, Elt);
// Insert the non-overwritten middle part. // Insert the non-overwritten middle part.
std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
return I; return I;
} }
template<typename ItTy> template<typename ItTy>
iterator insert(iterator I, ItTy From, ItTy To) { iterator insert(iterator I, ItTy From, ItTy To) {
if (I == End) { // Important special case for empty vector. if (I == End) { // Important special case for empty vector.
append(From, To); append(From, To);
return end()-1; return end()-1;
} }
size_t NumToInsert = std::distance(From, To); size_t NumToInsert = std::distance(From, To);
// Convert iterator to elt# to avoid invalidating iterator when we reserve() // Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I-begin(); size_t InsertElt = I-begin();
// Ensure there is enough space. // Ensure there is enough space.
reserve(static_cast<unsigned>(size() + NumToInsert)); reserve(static_cast<unsigned>(size() + NumToInsert));
// Uninvalidate the iterator. // Uninvalidate the iterator.
I = begin()+InsertElt; I = begin()+InsertElt;
// If we already have this many elements in the collection, append the // If we already have this many elements in the collection, append the
// dest elements at the end, then copy over the appropriate elements. Since // dest elements at the end, then copy over the appropriate elements. Since
// we already reserved space, we know that this won't reallocate the vector. // we already reserved space, we know that this won't reallocate the vector.
if (size() >= NumToInsert) { if (size() >= NumToInsert) {
T *OldEnd = End; T *OldEnd = End;
append(End-NumToInsert, End); append(End-NumToInsert, End);
// Copy the existing elements that get replaced. // Copy the existing elements that get replaced.
std::copy(I, OldEnd-NumToInsert, I+NumToInsert); std::copy(I, OldEnd-NumToInsert, I+NumToInsert);
std::copy(From, To, I); std::copy(From, To, I);
return I; return I;
} }
// Otherwise, we're inserting more elements than exist already, and we're // Otherwise, we're inserting more elements than exist already, and we're
// not inserting at the end. // not inserting at the end.
// Copy over the elements that we're about to overwrite. // Copy over the elements that we're about to overwrite.
T *OldEnd = End; T *OldEnd = End;
End += NumToInsert; End += NumToInsert;
size_t NumOverwritten = OldEnd-I; size_t NumOverwritten = OldEnd-I;
std::uninitialized_copy(I, OldEnd, End-NumOverwritten); std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
// Replace the overwritten part. // Replace the overwritten part.
std::copy(From, From+NumOverwritten, I); std::copy(From, From+NumOverwritten, I);
// Insert the non-overwritten middle part. // Insert the non-overwritten middle part.
std::uninitialized_copy(From+NumOverwritten, To, OldEnd); std::uninitialized_copy(From+NumOverwritten, To, OldEnd);
return I; return I;
} }
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS); const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
bool operator==(const SmallVectorImpl &RHS) const { bool operator==(const SmallVectorImpl &RHS) const {
if (size() != RHS.size()) return false; if (size() != RHS.size()) return false;
for (T *This = Begin, *That = RHS.Begin, *E = Begin+size(); for (T *This = Begin, *That = RHS.Begin, *E = Begin+size();
This != E; ++This, ++That) This != E; ++This, ++That)
if (*This != *That) if (*This != *That)
return false; return false;
@@ -388,12 +388,12 @@ public:
return std::lexicographical_compare(begin(), end(), return std::lexicographical_compare(begin(), end(),
RHS.begin(), RHS.end()); RHS.begin(), RHS.end());
} }
private: private:
/// isSmall - Return true if this is a smallvector which has not had dynamic /// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it. /// memory allocated for it.
bool isSmall() const { bool isSmall() const {
return static_cast<const void*>(Begin) == return static_cast<const void*>(Begin) ==
static_cast<const void*>(&FirstEl); static_cast<const void*>(&FirstEl);
} }
@@ -405,7 +405,7 @@ private:
for (; S != E; ++S) for (; S != E; ++S)
new (S) T(Elt); new (S) T(Elt);
} }
void destroy_range(T *S, T *E) { void destroy_range(T *S, T *E) {
while (S != E) { while (S != E) {
--E; --E;
@@ -423,21 +423,21 @@ void SmallVectorImpl<T>::grow(size_t MinSize) {
if (NewCapacity < MinSize) if (NewCapacity < MinSize)
NewCapacity = MinSize; NewCapacity = MinSize;
T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T))); T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
// Copy the elements over. // Copy the elements over.
if (is_class<T>::value) if (is_class<T>::value)
std::uninitialized_copy(Begin, End, NewElts); std::uninitialized_copy(Begin, End, NewElts);
else else
// Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
memcpy(NewElts, Begin, CurSize * sizeof(T)); memcpy(NewElts, Begin, CurSize * sizeof(T));
// Destroy the original elements. // Destroy the original elements.
destroy_range(Begin, End); destroy_range(Begin, End);
// If this wasn't grown from the inline copy, deallocate the old space. // If this wasn't grown from the inline copy, deallocate the old space.
if (!isSmall()) if (!isSmall())
operator delete(Begin); operator delete(Begin);
Begin = NewElts; Begin = NewElts;
End = NewElts+CurSize; End = NewElts+CurSize;
Capacity = Begin+NewCapacity; Capacity = Begin+NewCapacity;
@@ -446,7 +446,7 @@ void SmallVectorImpl<T>::grow(size_t MinSize) {
template <typename T> template <typename T>
void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) { void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
if (this == &RHS) return; if (this == &RHS) return;
// We can only avoid copying elements if neither vector is small. // We can only avoid copying elements if neither vector is small.
if (!isSmall() && !RHS.isSmall()) { if (!isSmall() && !RHS.isSmall()) {
std::swap(Begin, RHS.Begin); std::swap(Begin, RHS.Begin);
@@ -458,13 +458,13 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
grow(RHS.size()); grow(RHS.size());
if (RHS.begin()+size() > RHS.Capacity) if (RHS.begin()+size() > RHS.Capacity)
RHS.grow(size()); RHS.grow(size());
// Swap the shared elements. // Swap the shared elements.
size_t NumShared = size(); size_t NumShared = size();
if (NumShared > RHS.size()) NumShared = RHS.size(); if (NumShared > RHS.size()) NumShared = RHS.size();
for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i) for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
std::swap(Begin[i], RHS[i]); std::swap(Begin[i], RHS[i]);
// Copy over the extra elts. // Copy over the extra elts.
if (size() > RHS.size()) { if (size() > RHS.size()) {
size_t EltDiff = size() - RHS.size(); size_t EltDiff = size() - RHS.size();
@@ -480,13 +480,13 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
RHS.End = RHS.Begin+NumShared; RHS.End = RHS.Begin+NumShared;
} }
} }
template <typename T> template <typename T>
const SmallVectorImpl<T> & const SmallVectorImpl<T> &
SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) { SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
// Avoid self-assignment. // Avoid self-assignment.
if (this == &RHS) return *this; if (this == &RHS) return *this;
// If we already have sufficient space, assign the common elements, then // If we already have sufficient space, assign the common elements, then
// destroy any excess. // destroy any excess.
unsigned RHSSize = unsigned(RHS.size()); unsigned RHSSize = unsigned(RHS.size());
@@ -498,15 +498,15 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin); NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
else else
NewEnd = Begin; NewEnd = Begin;
// Destroy excess elements. // Destroy excess elements.
destroy_range(NewEnd, End); destroy_range(NewEnd, End);
// Trim. // Trim.
End = NewEnd; End = NewEnd;
return *this; return *this;
} }
// If we have to grow to have enough elements, destroy the current elements. // If we have to grow to have enough elements, destroy the current elements.
// This allows us to avoid copying them during the grow. // This allows us to avoid copying them during the grow.
if (unsigned(Capacity-Begin) < RHSSize) { if (unsigned(Capacity-Begin) < RHSSize) {
@@ -519,15 +519,15 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
// Otherwise, use assignment for the already-constructed elements. // Otherwise, use assignment for the already-constructed elements.
std::copy(RHS.Begin, RHS.Begin+CurSize, Begin); std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
} }
// Copy construct the new elements in place. // Copy construct the new elements in place.
std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize); std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
// Set end. // Set end.
End = Begin+RHSSize; End = Begin+RHSSize;
return *this; return *this;
} }
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements /// for the case when the array is small. It contains some number of elements
/// in-place, which allows it to avoid heap allocation when the actual number of /// in-place, which allows it to avoid heap allocation when the actual number of
@@ -544,36 +544,36 @@ class SmallVector : public SmallVectorImpl<T> {
enum { enum {
// MinUs - The number of U's require to cover N T's. // MinUs - The number of U's require to cover N T's.
MinUs = (static_cast<unsigned int>(sizeof(T))*N + MinUs = (static_cast<unsigned int>(sizeof(T))*N +
static_cast<unsigned int>(sizeof(U)) - 1) / static_cast<unsigned int>(sizeof(U)) - 1) /
static_cast<unsigned int>(sizeof(U)), static_cast<unsigned int>(sizeof(U)),
// NumInlineEltsElts - The number of elements actually in this array. There // NumInlineEltsElts - The number of elements actually in this array. There
// is already one in the parent class, and we have to round up to avoid // is already one in the parent class, and we have to round up to avoid
// having a zero-element array. // having a zero-element array.
NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1, NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
// NumTsAvailable - The number of T's we actually have space for, which may // NumTsAvailable - The number of T's we actually have space for, which may
// be more than N due to rounding. // be more than N due to rounding.
NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/ NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
static_cast<unsigned int>(sizeof(T)) static_cast<unsigned int>(sizeof(T))
}; };
U InlineElts[NumInlineEltsElts]; U InlineElts[NumInlineEltsElts];
public: public:
SmallVector() : SmallVectorImpl<T>(NumTsAvailable) { SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
} }
explicit SmallVector(unsigned Size, const T &Value = T()) explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(NumTsAvailable) { : SmallVectorImpl<T>(NumTsAvailable) {
this->reserve(Size); this->reserve(Size);
while (Size--) while (Size--)
this->push_back(Value); this->push_back(Value);
} }
template<typename ItTy> template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) { SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
this->append(S, E); this->append(S, E);
} }
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) { SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
if (!RHS.empty()) if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS); SmallVectorImpl<T>::operator=(RHS);
@@ -583,7 +583,7 @@ public:
SmallVectorImpl<T>::operator=(RHS); SmallVectorImpl<T>::operator=(RHS);
return *this; return *this;
} }
}; };
} // End llvm namespace } // End llvm namespace
@@ -595,7 +595,7 @@ namespace std {
swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) { swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
LHS.swap(RHS); LHS.swap(RHS);
} }
/// Implement std::swap in terms of SmallVector swap. /// Implement std::swap in terms of SmallVector swap.
template<typename T, unsigned N> template<typename T, unsigned N>
inline void inline void

View File

@@ -459,11 +459,11 @@ public:
CurrElementIter = Elements.begin (); CurrElementIter = Elements.begin ();
} }
// Assignment // Assignment
SparseBitVector& operator=(const SparseBitVector& RHS) { SparseBitVector& operator=(const SparseBitVector& RHS) {
Elements.clear(); Elements.clear();
ElementListConstIter ElementIter = RHS.Elements.begin(); ElementListConstIter ElementIter = RHS.Elements.begin();
while (ElementIter != RHS.Elements.end()) { while (ElementIter != RHS.Elements.end()) {
Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter)); Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
@@ -471,7 +471,7 @@ public:
} }
CurrElementIter = Elements.begin (); CurrElementIter = Elements.begin ();
return *this; return *this;
} }

View File

@@ -56,7 +56,7 @@ public:
const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); } const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); }
const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); } const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); }
const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); } const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); }
protected: protected:
Statistic &init() { Statistic &init() {
if (!Initialized) RegisterStatistic(); if (!Initialized) RegisterStatistic();
@@ -64,7 +64,7 @@ protected:
} }
void RegisterStatistic(); void RegisterStatistic();
}; };
// STATISTIC - A macro to make definition of statistics really simple. This // STATISTIC - A macro to make definition of statistics really simple. This
// automatically passes the DEBUG_TYPE of the file into the statistic. // automatically passes the DEBUG_TYPE of the file into the statistic.
#define STATISTIC(VARNAME, DESC) \ #define STATISTIC(VARNAME, DESC) \

View File

@@ -53,7 +53,7 @@ static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
} }
return BufPtr; return BufPtr;
} }
static inline std::string utohexstr(uint64_t X) { static inline std::string utohexstr(uint64_t X) {
char Buffer[40]; char Buffer[40];
return utohex_buffer(X, Buffer+40); return utohex_buffer(X, Buffer+40);
@@ -79,18 +79,18 @@ static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
static inline std::string utostr(uint64_t X, bool isNeg = false) { static inline std::string utostr(uint64_t X, bool isNeg = false) {
if (X == uint32_t(X)) if (X == uint32_t(X))
return utostr_32(uint32_t(X), isNeg); return utostr_32(uint32_t(X), isNeg);
char Buffer[40]; char Buffer[40];
char *BufPtr = Buffer+39; char *BufPtr = Buffer+39;
*BufPtr = 0; // Null terminate buffer... *BufPtr = 0; // Null terminate buffer...
if (X == 0) *--BufPtr = '0'; // Handle special case... if (X == 0) *--BufPtr = '0'; // Handle special case...
while (X) { while (X) {
*--BufPtr = '0' + char(X % 10); *--BufPtr = '0' + char(X % 10);
X /= 10; X /= 10;
} }
if (isNeg) *--BufPtr = '-'; // Add negative sign... if (isNeg) *--BufPtr = '-'; // Add negative sign...
return std::string(BufPtr); return std::string(BufPtr);
} }
@@ -141,7 +141,7 @@ static inline std::string UppercaseString(const std::string &S) {
/// StringsEqualNoCase - Return true if the two strings are equal, ignoring /// StringsEqualNoCase - Return true if the two strings are equal, ignoring
/// case. /// case.
static inline bool StringsEqualNoCase(const std::string &LHS, static inline bool StringsEqualNoCase(const std::string &LHS,
const std::string &RHS) { const std::string &RHS) {
if (LHS.size() != RHS.size()) return false; if (LHS.size() != RHS.size()) return false;
for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i)
@@ -151,7 +151,7 @@ static inline bool StringsEqualNoCase(const std::string &LHS,
/// StringsEqualNoCase - Return true if the two strings are equal, ignoring /// StringsEqualNoCase - Return true if the two strings are equal, ignoring
/// case. /// case.
static inline bool StringsEqualNoCase(const std::string &LHS, static inline bool StringsEqualNoCase(const std::string &LHS,
const char *RHS) { const char *RHS) {
for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) { for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) {
if (RHS[i] == 0) return false; // RHS too short. if (RHS[i] == 0) return false; // RHS too short.
@@ -159,7 +159,7 @@ static inline bool StringsEqualNoCase(const std::string &LHS,
} }
return RHS[LHS.size()] == 0; // Not too long? return RHS[LHS.size()] == 0; // Not too long?
} }
/// CStrInCStrNoCase - Portable version of strcasestr. Locates the first /// CStrInCStrNoCase - Portable version of strcasestr. Locates the first
/// occurance of c-string 's2' in string 's1', ignoring case. Returns /// occurance of c-string 's2' in string 's1', ignoring case. Returns
/// NULL if 's2' cannot be found. /// NULL if 's2' cannot be found.
@@ -168,12 +168,12 @@ static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) {
// Are either strings NULL or empty? // Are either strings NULL or empty?
if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0') if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0')
return 0; return 0;
if (s1 == s2) if (s1 == s2)
return s1; return s1;
const char *I1=s1, *I2=s2; const char *I1=s1, *I2=s2;
while (*I1 != '\0' && *I2 != '\0' ) while (*I1 != '\0' && *I2 != '\0' )
if (tolower(*I1) != tolower(*I2)) { // No match. Start over. if (tolower(*I1) != tolower(*I2)) { // No match. Start over.
++s1; I1 = s1; I2 = s2; ++s1; I1 = s1; I2 = s2;

View File

@@ -20,7 +20,7 @@ namespace llvm {
/// UniqueVector - This class produces a sequential ID number (base 1) for each /// UniqueVector - This class produces a sequential ID number (base 1) for each
/// unique entry that is added. T is the type of entries in the vector. This /// unique entry that is added. T is the type of entries in the vector. This
/// class should have an implementation of operator== and of operator<. /// class should have an implementation of operator== and of operator<.
/// Entries can be fetched using operator[] with the entry ID. /// Entries can be fetched using operator[] with the entry ID.
template<class T> class UniqueVector { template<class T> class UniqueVector {
private: private:
// Map - Used to handle the correspondence of entry to ID. // Map - Used to handle the correspondence of entry to ID.
@@ -29,34 +29,34 @@ private:
// Vector - ID ordered vector of entries. Entries can be indexed by ID - 1. // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
// //
std::vector<T> Vector; std::vector<T> Vector;
public: public:
/// insert - Append entry to the vector if it doesn't already exist. Returns /// insert - Append entry to the vector if it doesn't already exist. Returns
/// the entry's index + 1 to be used as a unique ID. /// the entry's index + 1 to be used as a unique ID.
unsigned insert(const T &Entry) { unsigned insert(const T &Entry) {
// Check if the entry is already in the map. // Check if the entry is already in the map.
unsigned &Val = Map[Entry]; unsigned &Val = Map[Entry];
// See if entry exists, if so return prior ID. // See if entry exists, if so return prior ID.
if (Val) return Val; if (Val) return Val;
// Compute ID for entry. // Compute ID for entry.
Val = static_cast<unsigned>(Vector.size()) + 1; Val = static_cast<unsigned>(Vector.size()) + 1;
// Insert in vector. // Insert in vector.
Vector.push_back(Entry); Vector.push_back(Entry);
return Val; return Val;
} }
/// idFor - return the ID for an existing entry. Returns 0 if the entry is /// idFor - return the ID for an existing entry. Returns 0 if the entry is
/// not found. /// not found.
unsigned idFor(const T &Entry) const { unsigned idFor(const T &Entry) const {
// Search for entry in the map. // Search for entry in the map.
typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry); typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
// See if entry exists, if so return ID. // See if entry exists, if so return ID.
if (MI != Map.end()) return MI->second; if (MI != Map.end()) return MI->second;
// No luck. // No luck.
return 0; return 0;
} }
@@ -67,15 +67,15 @@ public:
assert(ID-1 < size() && "ID is 0 or out of range!"); assert(ID-1 < size() && "ID is 0 or out of range!");
return Vector[ID - 1]; return Vector[ID - 1];
} }
/// size - Returns the number of entries in the vector. /// size - Returns the number of entries in the vector.
/// ///
size_t size() const { return Vector.size(); } size_t size() const { return Vector.size(); }
/// empty - Returns true if the vector is empty. /// empty - Returns true if the vector is empty.
/// ///
bool empty() const { return Vector.empty(); } bool empty() const { return Vector.empty(); }
/// reset - Clears all the entries. /// reset - Clears all the entries.
/// ///
void reset() { void reset() {

View File

@@ -1,12 +1,12 @@
//==-- llvm/ADT/hash_map.h - "Portable" wrapper around hash_map --*- C++ -*-==// //==-- llvm/ADT/hash_map.h - "Portable" wrapper around hash_map --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file provides a wrapper around the mysterious <hash_map> header file // This file provides a wrapper around the mysterious <hash_map> header file
// that seems to move around between GCC releases into and out of namespaces at // that seems to move around between GCC releases into and out of namespaces at
// will. #including this header will cause hash_map to be available in the // will. #including this header will cause hash_map to be available in the
@@ -92,7 +92,7 @@ template <typename KeyType,
class _HashFcn = hash<KeyType>, class _HashFcn = hash<KeyType>,
class _EqualKey = equal_to<KeyType>, class _EqualKey = equal_to<KeyType>,
class _A = allocator <ValueType> > class _A = allocator <ValueType> >
class hash_map : public rw_hashmap<KeyType, ValueType, class _HashFcn, class hash_map : public rw_hashmap<KeyType, ValueType, class _HashFcn,
class _EqualKey, class _A> { class _EqualKey, class _A> {
}; };
@@ -119,7 +119,7 @@ class hash_multimap : public rw_hashmultimap<KeyType, ValueType, class _HashFcn,
// hash_map to use GCC's hash classes. // hash_map to use GCC's hash classes.
namespace stdext { namespace stdext {
template<class Key> struct hash; template<class Key> struct hash;
// Provide a hash function for unsigned ints... // Provide a hash function for unsigned ints...
template<> struct hash<unsigned int> { template<> struct hash<unsigned int> {
inline size_t operator()(unsigned int Val) const { inline size_t operator()(unsigned int Val) const {

View File

@@ -1,10 +1,10 @@
//==-- llvm/ADT/hash_set.h - "Portable" wrapper around hash_set --*- C++ -*-==// //==-- llvm/ADT/hash_set.h - "Portable" wrapper around hash_set --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// vim:ft=cpp // vim:ft=cpp
// //
@@ -93,7 +93,7 @@ template <typename ValueType,
class _HashFcn = hash<ValueType>, class _HashFcn = hash<ValueType>,
class _EqualKey = equal_to<ValueType>, class _EqualKey = equal_to<ValueType>,
class _A = allocator <ValueType> > class _A = allocator <ValueType> >
class hash_set : class hash_set :
public rw_hashset<ValueType, class _HashFcn, class _EqualKey, class _A> { public rw_hashset<ValueType, class _HashFcn, class _EqualKey, class _A> {
}; };

View File

@@ -1,10 +1,10 @@
//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==// //==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the ilist_node class template, which is a convenient // This file defines the ilist_node class template, which is a convenient

View File

@@ -1,10 +1,10 @@
//==-- llvm/ADT/iterator.h - Portable wrapper around <iterator> --*- C++ -*-==// //==-- llvm/ADT/iterator.h - Portable wrapper around <iterator> --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file provides a wrapper around the mysterious <iterator> header file. // This file provides a wrapper around the mysterious <iterator> header file.