summaryrefslogtreecommitdiff
path: root/include/llvm/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APFloat.h367
-rw-r--r--include/llvm/ADT/APInt.h1612
-rw-r--r--include/llvm/ADT/APSInt.h264
-rw-r--r--include/llvm/ADT/BitVector.h409
-rw-r--r--include/llvm/ADT/DenseMap.h570
-rw-r--r--include/llvm/ADT/DenseSet.h104
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h232
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h279
-rw-r--r--include/llvm/ADT/FoldingSet.h461
-rw-r--r--include/llvm/ADT/GraphTraits.h103
-rw-r--r--include/llvm/ADT/HashExtras.h40
-rw-r--r--include/llvm/ADT/ImmutableList.h219
-rw-r--r--include/llvm/ADT/ImmutableMap.h230
-rw-r--r--include/llvm/ADT/ImmutableSet.h1070
-rw-r--r--include/llvm/ADT/IndexedMap.h75
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h230
-rw-r--r--include/llvm/ADT/OwningPtr.h134
-rw-r--r--include/llvm/ADT/PointerIntPair.h150
-rw-r--r--include/llvm/ADT/PointerUnion.h259
-rw-r--r--include/llvm/ADT/PostOrderIterator.h231
-rw-r--r--include/llvm/ADT/PriorityQueue.h83
-rw-r--r--include/llvm/ADT/SCCIterator.h199
-rw-r--r--include/llvm/ADT/STLExtras.h268
-rw-r--r--include/llvm/ADT/ScopedHashTable.h193
-rw-r--r--include/llvm/ADT/SetOperations.h71
-rw-r--r--include/llvm/ADT/SetVector.h168
-rw-r--r--include/llvm/ADT/SmallPtrSet.h284
-rw-r--r--include/llvm/ADT/SmallSet.h118
-rw-r--r--include/llvm/ADT/SmallString.h109
-rw-r--r--include/llvm/ADT/SmallVector.h617
-rw-r--r--include/llvm/ADT/SparseBitVector.h901
-rw-r--r--include/llvm/ADT/Statistic.h75
-rw-r--r--include/llvm/ADT/StringExtras.h234
-rw-r--r--include/llvm/ADT/StringMap.h504
-rw-r--r--include/llvm/ADT/StringSet.h39
-rw-r--r--include/llvm/ADT/Tree.h62
-rw-r--r--include/llvm/ADT/Trie.h335
-rw-r--r--include/llvm/ADT/Triple.h204
-rw-r--r--include/llvm/ADT/UniqueVector.h89
-rw-r--r--include/llvm/ADT/VectorExtras.h41
-rw-r--r--include/llvm/ADT/ilist.h709
-rw-r--r--include/llvm/ADT/ilist_node.h47
-rw-r--r--include/llvm/ADT/iterator.cmake79
-rw-r--r--include/llvm/ADT/iterator.h.in76
44 files changed, 12544 insertions, 0 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
new file mode 100644
index 0000000000000..928ecc0c3cf57
--- /dev/null
+++ b/include/llvm/ADT/APFloat.h
@@ -0,0 +1,367 @@
+//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a class to represent arbitrary precision floating
+// point values and provide a variety of arithmetic operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+/* A self-contained host- and target-independent arbitrary-precision
+ floating-point software implementation. It uses bignum integer
+ arithmetic as provided by static functions in the APInt class.
+ The library will work with bignum integers whose parts are any
+ unsigned type at least 16 bits wide, but 64 bits is recommended.
+
+ Written for clarity rather than speed, in particular with a view
+ to use in the front-end of a cross compiler so that target
+ arithmetic can be correctly performed on the host. Performance
+ should nonetheless be reasonable, particularly for its intended
+ use. It may be useful as a base implementation for a run-time
+ library during development of a faster target-specific one.
+
+ All 5 rounding modes in the IEEE-754R draft are handled correctly
+ for all implemented operations. Currently implemented operations
+ are add, subtract, multiply, divide, fused-multiply-add,
+ conversion-to-float, conversion-to-integer and
+ conversion-from-integer. New rounding modes (e.g. away from zero)
+ can be added with three or four lines of code.
+
+ Four formats are built-in: IEEE single precision, double
+ precision, quadruple precision, and x87 80-bit extended double
+ (when operating with full extended precision). Adding a new
+ format that obeys IEEE semantics only requires adding two lines of
+ code: a declaration and definition of the format.
+
+ All operations return the status of that operation as an exception
+ bit-mask, so multiple operations can be done consecutively with
+ their results or-ed together. The returned status can be useful
+ for compiler diagnostics; e.g., inexact, underflow and overflow
+ can be easily diagnosed on constant folding, and compiler
+ optimizers can determine what exceptions would be raised by
+ folding operations and optimize, or perhaps not optimize,
+ accordingly.
+
+ At present, underflow tininess is detected after rounding; it
+ should be straight forward to add support for the before-rounding
+ case too.
+
+ The library reads hexadecimal floating point numbers as per C99,
+ and correctly rounds if necessary according to the specified
+ rounding mode. Syntax is required to have been validated by the
+ caller. It also converts floating point numbers to hexadecimal
+ text as per the C99 %a and %A conversions. The output precision
+ (or alternatively the natural minimal precision) can be specified;
+ if the requested precision is less than the natural precision the
+ output is correctly rounded for the specified rounding mode.
+
+ It also reads decimal floating point numbers and correctly rounds
+ according to the specified rounding mode.
+
+ Conversion to decimal text is not currently implemented.
+
+ Non-zero finite numbers are represented internally as a sign bit,
+ a 16-bit signed exponent, and the significand as an array of
+ integer parts. After normalization of a number of precision P the
+ exponent is within the range of the format, and if the number is
+ not denormal the P-th bit of the significand is set as an explicit
+ integer bit. For denormals the most significant bit is shifted
+ right so that the exponent is maintained at the format's minimum,
+ so that the smallest denormal has just the least significant bit
+ of the significand set. The sign of zeroes and infinities is
+ significant; the exponent and significand of such numbers is not
+ stored, but has a known implicit (deterministic) value: 0 for the
+ significands, 0 for zero exponent, all 1 bits for infinity
+ exponent. For NaNs the sign and significand are deterministic,
+ although not really meaningful, and preserved in non-conversion
+ operations. The exponent is implicitly all 1 bits.
+
+ TODO
+ ====
+
+ Some features that may or may not be worth adding:
+
+ Binary to decimal conversion (hard).
+
+ Optional ability to detect underflow tininess before rounding.
+
+ New formats: x87 in single and double precision mode (IEEE apart
+ from extended exponent range) (hard).
+
+ New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
+ nexttoward.
+*/
+
+#ifndef LLVM_FLOAT_H
+#define LLVM_FLOAT_H
+
+// APInt contains static functions implementing bignum arithmetic.
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+ /* Exponents are stored as signed numbers. */
+ typedef signed short exponent_t;
+
+ struct fltSemantics;
+
+ /* When bits of a floating point number are truncated, this enum is
+ used to indicate what fraction of the LSB those bits represented.
+ It essentially combines the roles of guard and sticky bits. */
+ enum lostFraction { // Example of truncated bits:
+ lfExactlyZero, // 000000
+ lfLessThanHalf, // 0xxxxx x's not all zero
+ lfExactlyHalf, // 100000
+ lfMoreThanHalf // 1xxxxx x's not all zero
+ };
+
+ class APFloat {
+ public:
+
+ /* We support the following floating point semantics. */
+ static const fltSemantics IEEEsingle;
+ static const fltSemantics IEEEdouble;
+ static const fltSemantics IEEEquad;
+ static const fltSemantics PPCDoubleDouble;
+ static const fltSemantics x87DoubleExtended;
+ /* And this pseudo, used to construct APFloats that cannot
+ conflict with anything real. */
+ static const fltSemantics Bogus;
+
+ static unsigned int semanticsPrecision(const fltSemantics &);
+
+ /* Floating point numbers have a four-state comparison relation. */
+ enum cmpResult {
+ cmpLessThan,
+ cmpEqual,
+ cmpGreaterThan,
+ cmpUnordered
+ };
+
+ /* IEEE-754R gives five rounding modes. */
+ enum roundingMode {
+ rmNearestTiesToEven,
+ rmTowardPositive,
+ rmTowardNegative,
+ rmTowardZero,
+ rmNearestTiesToAway
+ };
+
+ // Operation status. opUnderflow or opOverflow are always returned
+ // or-ed with opInexact.
+ enum opStatus {
+ opOK = 0x00,
+ opInvalidOp = 0x01,
+ opDivByZero = 0x02,
+ opOverflow = 0x04,
+ opUnderflow = 0x08,
+ opInexact = 0x10
+ };
+
+ // Category of internally-represented number.
+ enum fltCategory {
+ fcInfinity,
+ fcNaN,
+ fcNormal,
+ fcZero
+ };
+
+ // Constructors.
+ APFloat(const fltSemantics &, const char *);
+ APFloat(const fltSemantics &, integerPart);
+ APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
+ explicit APFloat(double d);
+ explicit APFloat(float f);
+ explicit APFloat(const APInt &, bool isIEEE = false);
+ APFloat(const APFloat &);
+ ~APFloat();
+
+ // Convenience "constructors"
+ static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcZero, Negative);
+ }
+ static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcInfinity, Negative);
+ }
+ /// getNaN - Factory for QNaN values.
+ ///
+ /// \param Negative - True iff the NaN generated should be negative.
+ /// \param type - The unspecified fill bits for creating the NaN, 0 by
+ /// default. The value is truncated as necessary.
+ static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+ unsigned type = 0) {
+ return APFloat(Sem, fcNaN, Negative, type);
+ }
+
+ /// Profile - Used to insert APFloat objects, or objects that contain
+ /// APFloat objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& NID) const;
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ static APFloat ReadVal(Deserializer& D);
+
+ /* Arithmetic. */
+ opStatus add(const APFloat &, roundingMode);
+ opStatus subtract(const APFloat &, roundingMode);
+ opStatus multiply(const APFloat &, roundingMode);
+ opStatus divide(const APFloat &, roundingMode);
+ /* IEEE remainder. */
+ opStatus remainder(const APFloat &);
+ /* C fmod, or llvm frem. */
+ opStatus mod(const APFloat &, roundingMode);
+ opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
+
+ /* Sign operations. */
+ void changeSign();
+ void clearSign();
+ void copySign(const APFloat &);
+
+ /* Conversions. */
+ opStatus convert(const fltSemantics &, roundingMode, bool *);
+ opStatus convertToInteger(integerPart *, unsigned int, bool,
+ roundingMode, bool *) const;
+ opStatus convertFromAPInt(const APInt &,
+ bool, roundingMode);
+ opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromString(const char *, roundingMode);
+ APInt bitcastToAPInt() const;
+ double convertToDouble() const;
+ float convertToFloat() const;
+
+ /* The definition of equality is not straightforward for floating point,
+ so we won't use operator==. Use one of the following, or write
+ whatever it is you really mean. */
+ // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
+
+ /* IEEE comparison with another floating point number (NaNs
+ compare unordered, 0==-0). */
+ cmpResult compare(const APFloat &) const;
+
+ /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
+ bool bitwiseIsEqual(const APFloat &) const;
+
+ /* Write out a hexadecimal representation of the floating point
+ value to DST, which must be of sufficient size, in the C99 form
+ [-]0xh.hhhhp[+-]d. Return the number of characters written,
+ excluding the terminating NUL. */
+ unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase, roundingMode) const;
+
+ /* Simple queries. */
+ fltCategory getCategory() const { return category; }
+ const fltSemantics &getSemantics() const { return *semantics; }
+ bool isZero() const { return category == fcZero; }
+ bool isNonZero() const { return category != fcZero; }
+ bool isNaN() const { return category == fcNaN; }
+ bool isInfinity() const { return category == fcInfinity; }
+ bool isNegative() const { return sign; }
+ bool isPosZero() const { return isZero() && !isNegative(); }
+ bool isNegZero() const { return isZero() && isNegative(); }
+
+ APFloat& operator=(const APFloat &);
+
+ /* Return an arbitrary integer value usable for hashing. */
+ uint32_t getHashValue() const;
+
+ private:
+
+ /* Trivial queries. */
+ integerPart *significandParts();
+ const integerPart *significandParts() const;
+ unsigned int partCount() const;
+
+ /* Significand operations. */
+ integerPart addSignificand(const APFloat &);
+ integerPart subtractSignificand(const APFloat &, integerPart);
+ lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
+ lostFraction multiplySignificand(const APFloat &, const APFloat *);
+ lostFraction divideSignificand(const APFloat &);
+ void incrementSignificand();
+ void initialize(const fltSemantics *);
+ void shiftSignificandLeft(unsigned int);
+ lostFraction shiftSignificandRight(unsigned int);
+ unsigned int significandLSB() const;
+ unsigned int significandMSB() const;
+ void zeroSignificand();
+
+ /* Arithmetic on special values. */
+ opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
+ opStatus divideSpecials(const APFloat &);
+ opStatus multiplySpecials(const APFloat &);
+ opStatus modSpecials(const APFloat &);
+
+ /* Miscellany. */
+ void makeNaN(unsigned = 0);
+ opStatus normalize(roundingMode, lostFraction);
+ opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
+ cmpResult compareAbsoluteValue(const APFloat &) const;
+ opStatus handleOverflow(roundingMode);
+ bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
+ opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+ roundingMode, bool *) const;
+ opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+ roundingMode);
+ opStatus convertFromHexadecimalString(const char *, roundingMode);
+ opStatus convertFromDecimalString (const char *, roundingMode);
+ char *convertNormalToHexString(char *, unsigned int, bool,
+ roundingMode) const;
+ opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
+ int, roundingMode);
+
+ APInt convertFloatAPFloatToAPInt() const;
+ APInt convertDoubleAPFloatToAPInt() const;
+ APInt convertF80LongDoubleAPFloatToAPInt() const;
+ APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+ void initFromAPInt(const APInt& api, bool isIEEE = false);
+ void initFromFloatAPInt(const APInt& api);
+ void initFromDoubleAPInt(const APInt& api);
+ void initFromF80LongDoubleAPInt(const APInt& api);
+ void initFromPPCDoubleDoubleAPInt(const APInt& api);
+
+ void assign(const APFloat &);
+ void copySignificand(const APFloat &);
+ void freeSignificand();
+
+ /* What kind of semantics does this value obey? */
+ const fltSemantics *semantics;
+
+ /* Significand - the fraction with an explicit integer bit. Must be
+ at least one bit wider than the target precision. */
+ union Significand
+ {
+ integerPart part;
+ integerPart *parts;
+ } significand;
+
+ /* The exponent - a signed number. */
+ exponent_t exponent;
+
+ /* What kind of floating point number this is. */
+ /* Only 2 bits are required, but VisualStudio incorrectly sign extends
+ it. Using the extra bit keeps it from failing under VisualStudio */
+ fltCategory category: 3;
+
+ /* The sign bit of this number. */
+ unsigned int sign: 1;
+
+ /* For PPCDoubleDouble, we have a second exponent and sign (the second
+ significand is appended to the first one, although it would be wrong to
+ regard these as a single number for arithmetic purposes). These fields
+ are not meaningful for any other type. */
+ exponent_t exponent2 : 11;
+ unsigned int sign2: 1;
+ };
+} /* namespace llvm */
+
+#endif /* LLVM_FLOAT_H */
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
new file mode 100644
index 0000000000000..63bf4f6d9ba0b
--- /dev/null
+++ b/include/llvm/ADT/APInt.h
@@ -0,0 +1,1612 @@
+//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a class to represent arbitrary precision integral
+// constant values and operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APINT_H
+#define LLVM_APINT_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+ class Serializer;
+ class Deserializer;
+ class FoldingSetNodeID;
+ class raw_ostream;
+
+ template<typename T>
+ class SmallVectorImpl;
+
+ /* An unsigned host type used as a single part of a multi-part
+ bignum. */
+ typedef uint64_t integerPart;
+
+ const unsigned int host_char_bit = 8;
+ const unsigned int integerPartWidth = host_char_bit *
+ static_cast<unsigned int>(sizeof(integerPart));
+
+//===----------------------------------------------------------------------===//
+// APInt Class
+//===----------------------------------------------------------------------===//
+
+/// APInt - This class represents arbitrary precision constant integral values.
+/// It is a functional replacement for common case unsigned integer type like
+/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
+/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
+/// than 64-bits of precision. APInt provides a variety of arithmetic operators
+/// and methods to manipulate integer values of any bit-width. It supports both
+/// the typical integer arithmetic and comparison operations as well as bitwise
+/// manipulation.
+///
+/// The class has several invariants worth noting:
+/// * All bit, byte, and word positions are zero-based.
+/// * Once the bit width is set, it doesn't change except by the Truncate,
+/// SignExtend, or ZeroExtend operations.
+/// * All binary operators must be on APInt instances of the same bit width.
+/// Attempting to use these operators on instances with different bit
+/// widths will yield an assertion.
+/// * The value is stored canonically as an unsigned value. For operations
+/// where it makes a difference, there are both signed and unsigned variants
+/// of the operation. For example, sdiv and udiv. However, because the bit
+/// widths must be the same, operations such as Mul and Add produce the same
+/// results regardless of whether the values are interpreted as signed or
+/// not.
+/// * In general, the class tries to follow the style of computation that LLVM
+/// uses in its IR. This simplifies its use for LLVM.
+///
+/// @brief Class for arbitrary precision integers.
+class APInt {
+ unsigned BitWidth; ///< The number of bits in this APInt.
+
+ /// This union is used to store the integer value. When the
+ /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum {
+ /// Bits in a word
+ APINT_BITS_PER_WORD = static_cast<unsigned int>(sizeof(uint64_t)) *
+ CHAR_BIT,
+ /// Byte size of a word
+ APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
+ };
+
+ /// This constructor is used only internally for speed of construction of
+ /// temporaries. It is unsafe for general use so it is not public.
+ /// @brief Fast internal constructor
+ APInt(uint64_t* val, unsigned bits) : BitWidth(bits), pVal(val) { }
+
+ /// @returns true if the number of bits <= 64, false otherwise.
+ /// @brief Determine if this APInt just has one word to store value.
+ bool isSingleWord() const {
+ return BitWidth <= APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the word position for the specified bit position.
+ /// @brief Determine which word a bit is in.
+ static unsigned whichWord(unsigned bitPosition) {
+ return bitPosition / APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the bit position in a word for the specified bit position
+ /// in the APInt.
+ /// @brief Determine which bit in a word a bit is in.
+ static unsigned whichBit(unsigned bitPosition) {
+ return bitPosition % APINT_BITS_PER_WORD;
+ }
+
+ /// This method generates and returns a uint64_t (word) mask for a single
+ /// bit at a specific bit position. This is used to mask the bit in the
+ /// corresponding word.
+ /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set
+ /// @brief Get a single bit mask.
+ static uint64_t maskBit(unsigned bitPosition) {
+ return 1ULL << whichBit(bitPosition);
+ }
+
+ /// This method is used internally to clear the to "N" bits in the high order
+ /// word that are not used by the APInt. This is needed after the most
+ /// significant word is assigned a value to ensure that those bits are
+ /// zero'd out.
+ /// @brief Clear unused high order bits
+ APInt& clearUnusedBits() {
+ // Compute how many bits are used in the final word
+ unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
+ if (wordBits == 0)
+ // If all bits are used, we want to leave the value alone. This also
+ // avoids the undefined behavior of >> when the shift is the same size as
+ // the word size (64).
+ return *this;
+
+ // Mask out the high bits.
+ uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+ if (isSingleWord())
+ VAL &= mask;
+ else
+ pVal[getNumWords() - 1] &= mask;
+ return *this;
+ }
+
+ /// @returns the corresponding word for the specified bit position.
+ /// @brief Get the word corresponding to a bit position
+ uint64_t getWord(unsigned bitPosition) const {
+ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ }
+
+ /// This is used by the constructors that take string arguments.
+ /// @brief Convert a char array into an APInt
+ void fromString(unsigned numBits, const char *strStart, unsigned slen,
+ uint8_t radix);
+
+ /// This is used by the toString method to divide by the radix. It simply
+ /// provides a more convenient form of divide for internal use since KnuthDiv
+ /// has specific constraints on its inputs. If those constraints are not met
+ /// then it provides a simpler form of divide.
+ /// @brief An internal division function for dividing APInts.
+ static void divide(const APInt LHS, unsigned lhsWords,
+ const APInt &RHS, unsigned rhsWords,
+ APInt *Quotient, APInt *Remainder);
+
+ /// out-of-line slow case for inline constructor
+ void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
+
+ /// out-of-line slow case for inline copy constructor
+ void initSlowCase(const APInt& that);
+
+ /// out-of-line slow case for shl
+ APInt shlSlowCase(unsigned shiftAmt) const;
+
+ /// out-of-line slow case for operator&
+ APInt AndSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator|
+ APInt OrSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator^
+ APInt XorSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator=
+ APInt& AssignSlowCase(const APInt& RHS);
+
+ /// out-of-line slow case for operator==
+ bool EqualSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator==
+ bool EqualSlowCase(uint64_t Val) const;
+
+ /// out-of-line slow case for countLeadingZeros
+ unsigned countLeadingZerosSlowCase() const;
+
+ /// out-of-line slow case for countTrailingOnes
+ unsigned countTrailingOnesSlowCase() const;
+
+ /// out-of-line slow case for countPopulation
+ unsigned countPopulationSlowCase() const;
+
+public:
+ /// @name Constructors
+ /// @{
+ /// If isSigned is true then val is treated as if it were a signed value
+ /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
+ /// will be done. Otherwise, no sign extension occurs (high order bits beyond
+ /// the range of val are zero filled).
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the initial value of the APInt
+ /// @param isSigned how to treat signedness of val
+ /// @brief Create a new APInt of numBits width, initialized as val.
+ APInt(unsigned numBits, uint64_t val, bool isSigned = false)
+ : BitWidth(numBits), VAL(0) {
+ assert(BitWidth && "bitwidth too small");
+ if (isSingleWord())
+ VAL = val;
+ else
+ initSlowCase(numBits, val, isSigned);
+ clearUnusedBits();
+ }
+
+ /// Note that numWords can be smaller or larger than the corresponding bit
+ /// width but any extraneous bits will be dropped.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param numWords the number of words in bigVal
+ /// @param bigVal a sequence of words to form the initial value of the APInt
+ /// @brief Construct an APInt of numBits width, initialized as bigVal[].
+ APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
+
+ /// This constructor interprets the slen characters starting at StrStart as
+ /// a string in the given radix. The interpretation stops when the first
+ /// 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
+ /// the string to require more bits than numBits.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param strStart the start of the string to be interpreted
+ /// @param slen the maximum number of characters to interpret
+ /// @param radix the radix to use for the conversion
+ /// @brief Construct an APInt from a string representation.
+ APInt(unsigned numBits, const char strStart[], unsigned slen, uint8_t radix);
+
+ /// Simply makes *this a copy of that.
+ /// @brief Copy Constructor.
+ APInt(const APInt& that)
+ : BitWidth(that.BitWidth), VAL(0) {
+ assert(BitWidth && "bitwidth too small");
+ if (isSingleWord())
+ VAL = that.VAL;
+ else
+ initSlowCase(that);
+ }
+
+ /// @brief Destructor.
+ ~APInt() {
+ if (!isSingleWord())
+ delete [] pVal;
+ }
+
+ /// Default constructor that creates an uninitialized APInt. This is useful
+ /// for object deserialization (pair this with the static method Read).
+ explicit APInt() : BitWidth(1) {}
+
+ /// Profile - Used to insert APInt objects, or objects that contain APInt
+ /// objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& id) const;
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ void Read(Deserializer& D);
+
+ /// @}
+ /// @name Value Tests
+ /// @{
+ /// This tests the high bit of this APInt to determine if it is set.
+ /// @returns true if this APInt is negative, false otherwise
+ /// @brief Determine sign of this APInt.
+ bool isNegative() const {
+ return (*this)[BitWidth - 1];
+ }
+
+ /// This tests the high bit of the APInt to determine if it is unset.
+ /// @brief Determine if this APInt Value is non-negative (>= 0)
+ bool isNonNegative() const {
+ return !isNegative();
+ }
+
+ /// This tests if the value of this APInt is positive (> 0). Note
+ /// that 0 is not a positive value.
+ /// @returns true if this APInt is positive.
+ /// @brief Determine if this APInt Value is positive.
+ bool isStrictlyPositive() const {
+ return isNonNegative() && (*this) != 0;
+ }
+
+ /// This checks to see if the value has all bits of the APInt are set or not.
+ /// @brief Determine if all bits are set
+ bool isAllOnesValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest unsigned value.
+ bool isMaxValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest signed value.
+ bool isMaxSignedValue() const {
+ return BitWidth == 1 ? VAL == 0 :
+ !isNegative() && countPopulation() == BitWidth - 1;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest unsigned value.
+ bool isMinValue() const {
+ return countPopulation() == 0;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest signed value.
+ bool isMinSignedValue() const {
+ return BitWidth == 1 ? VAL == 1 :
+ isNegative() && countPopulation() == 1;
+ }
+
+ /// @brief Check if this APInt has an N-bits unsigned integer value.
+ bool isIntN(unsigned N) const {
+ assert(N && "N == 0 ???");
+ if (N >= getBitWidth())
+ return true;
+
+ if (isSingleWord())
+ return VAL == (VAL & (~0ULL >> (64 - N)));
+ APInt Tmp(N, getNumWords(), pVal);
+ Tmp.zext(getBitWidth());
+ return Tmp == (*this);
+ }
+
+ /// @brief Check if this APInt has an N-bits signed integer value.
+ bool isSignedIntN(unsigned N) const {
+ assert(N && "N == 0 ???");
+ return getMinSignedBits() <= N;
+ }
+
+ /// @returns true if the argument APInt value is a power of two > 0.
+ bool isPowerOf2() const;
+
+ /// isSignBit - Return true if this is the value returned by getSignBit.
+ bool isSignBit() const { return isMinSignedValue(); }
+
+ /// This converts the APInt to a boolean value as a test against zero.
+ /// @brief Boolean conversion function.
+ bool getBoolValue() const {
+ return *this != 0;
+ }
+
+ /// getLimitedValue - If this value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return (getActiveBits() > 64 || getZExtValue() > Limit) ?
+ Limit : getZExtValue();
+ }
+
+ /// @}
+ /// @name Value Generators
+ /// @{
+ /// @brief Gets maximum unsigned value of APInt for specific bit width.
+ static APInt getMaxValue(unsigned numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @brief Gets maximum signed value of APInt for a specific bit width.
+ static APInt getSignedMaxValue(unsigned numBits) {
+ return APInt(numBits, 0).set().clear(numBits - 1);
+ }
+
+ /// @brief Gets minimum unsigned value of APInt for a specific bit width.
+ static APInt getMinValue(unsigned numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// @brief Gets minimum signed value of APInt for a specific bit width.
+ static APInt getSignedMinValue(unsigned numBits) {
+ return APInt(numBits, 0).set(numBits - 1);
+ }
+
+ /// getSignBit - This is just a wrapper function of getSignedMinValue(), and
+ /// it helps code readability when we want to get a SignBit.
+ /// @brief Get the SignBit for a specific bit width.
+ static APInt getSignBit(unsigned BitWidth) {
+ return getSignedMinValue(BitWidth);
+ }
+
+ /// @returns the all-ones value for an APInt of the specified bit-width.
+ /// @brief Get the all-ones value.
+ static APInt getAllOnesValue(unsigned numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @returns the '0' value for an APInt of the specified bit-width.
+ /// @brief Get the '0' value.
+ static APInt getNullValue(unsigned numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the low bits and right shift to the least significant bit.
+ /// @returns the high "numBits" bits of this APInt.
+ APInt getHiBits(unsigned numBits) const;
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the high bits.
+ /// @returns the low "numBits" bits of this APInt.
+ APInt getLoBits(unsigned numBits) const;
+
+ /// Constructs an APInt value that has a contiguous range of bits set. The
+ /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
+ /// bits will be zero. For example, with parameters(32, 0, 16) you would get
+ /// 0x0000FFFF. If hiBit is less than loBit then the set bits "wrap". For
+ /// example, with parameters (32, 28, 4), you would get 0xF000000F.
+ /// @param numBits the intended bit width of the result
+ /// @param loBit the index of the lowest bit set.
+ /// @param hiBit the index of the highest bit set.
+ /// @returns An APInt value with the requested bits set.
+ /// @brief Get a value with a block of bits set.
+ static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
+ assert(hiBit <= numBits && "hiBit out of range");
+ assert(loBit < numBits && "loBit out of range");
+ if (hiBit < loBit)
+ return getLowBitsSet(numBits, hiBit) |
+ getHighBitsSet(numBits, numBits-loBit);
+ return getLowBitsSet(numBits, hiBit-loBit).shl(loBit);
+ }
+
+ /// Constructs an APInt value that has the top hiBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param hiBitsSet the number of high-order bits set in the result.
+ /// @brief Get a value with high bits set
+ static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
+ assert(hiBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (hiBitsSet == 0)
+ return APInt(numBits, 0);
+ unsigned shiftAmt = numBits - hiBitsSet;
+ // For small values, return quickly
+ if (numBits <= APINT_BITS_PER_WORD)
+ return APInt(numBits, ~0ULL << shiftAmt);
+ return (~APInt(numBits, 0)).shl(shiftAmt);
+ }
+
+ /// Constructs an APInt value that has the bottom loBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param loBitsSet the number of low-order bits set in the result.
+ /// @brief Get a value with low bits set
+ static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
+ assert(loBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (loBitsSet == 0)
+ return APInt(numBits, 0);
+ if (loBitsSet == APINT_BITS_PER_WORD)
+ return APInt(numBits, -1ULL);
+ // For small values, return quickly.
+ if (numBits < APINT_BITS_PER_WORD)
+ return APInt(numBits, (1ULL << loBitsSet) - 1);
+ return (~APInt(numBits, 0)).lshr(numBits - loBitsSet);
+ }
+
+ /// The hash value is computed as the sum of the words and the bit width.
+ /// @returns A hash value computed from the sum of the APInt words.
+ /// @brief Get a hash value based on this APInt
+ uint64_t getHashValue() const;
+
+ /// This function returns a pointer to the internal storage of the APInt.
+ /// This is useful for writing out the APInt in binary form without any
+ /// conversions.
+ const uint64_t* getRawData() const {
+ if (isSingleWord())
+ return &VAL;
+ return &pVal[0];
+ }
+
+ /// @}
+ /// @name Unary Operators
+ /// @{
+ /// @returns a new APInt value representing *this incremented by one
+ /// @brief Postfix increment operator.
+ const APInt operator++(int) {
+ APInt API(*this);
+ ++(*this);
+ return API;
+ }
+
+ /// @returns *this incremented by one
+ /// @brief Prefix increment operator.
+ APInt& operator++();
+
+ /// @returns a new APInt representing *this decremented by one.
+ /// @brief Postfix decrement operator.
+ const APInt operator--(int) {
+ APInt API(*this);
+ --(*this);
+ return API;
+ }
+
+ /// @returns *this decremented by one.
+ /// @brief Prefix decrement operator.
+ APInt& operator--();
+
+ /// Performs a bitwise complement operation on this APInt.
+ /// @returns an APInt that is the bitwise complement of *this
+ /// @brief Unary bitwise complement operator.
+ APInt operator~() const {
+ APInt Result(*this);
+ Result.flip();
+ return Result;
+ }
+
+ /// Negates *this using two's complement logic.
+ /// @returns An APInt value representing the negation of *this.
+ /// @brief Unary negation operator
+ APInt operator-() const {
+ return APInt(BitWidth, 0) - (*this);
+ }
+
+ /// Performs logical negation operation on this APInt.
+ /// @returns true if *this is zero, false otherwise.
+ /// @brief Logical negation operator.
+ bool operator!() const;
+
+ /// @}
+ /// @name Assignment Operators
+ /// @{
+ /// @returns *this after assignment of RHS.
+ /// @brief Copy assignment operator.
+ APInt& operator=(const APInt& RHS) {
+ // If the bitwidths are the same, we can avoid mucking with memory
+ if (isSingleWord() && RHS.isSingleWord()) {
+ VAL = RHS.VAL;
+ BitWidth = RHS.BitWidth;
+ return clearUnusedBits();
+ }
+
+ return AssignSlowCase(RHS);
+ }
+
+ /// The RHS value is assigned to *this. If the significant bits in RHS exceed
+ /// the bit width, the excess bits are truncated. If the bit width is larger
+ /// than 64, the value is zero filled in the unspecified high order bits.
+ /// @returns *this after assignment of RHS value.
+ /// @brief Assignment operator.
+ APInt& operator=(uint64_t RHS);
+
+ /// Performs a bitwise AND operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after ANDing with RHS.
+ /// @brief Bitwise AND assignment operator.
+ APInt& operator&=(const APInt& RHS);
+
+ /// Performs a bitwise OR operation on this APInt and RHS. The result is
+ /// assigned *this;
+ /// @returns *this after ORing with RHS.
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(const APInt& RHS);
+
+ /// Performs a bitwise XOR operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after XORing with RHS.
+ /// @brief Bitwise XOR assignment operator.
+ APInt& operator^=(const APInt& RHS);
+
+ /// Multiplies this APInt by RHS and assigns the result to *this.
+ /// @returns *this
+ /// @brief Multiplication assignment operator.
+ APInt& operator*=(const APInt& RHS);
+
+ /// Adds RHS to *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Addition assignment operator.
+ APInt& operator+=(const APInt& RHS);
+
+ /// Subtracts RHS from *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Subtraction assignment operator.
+ APInt& operator-=(const APInt& RHS);
+
+ /// Shifts *this left by shiftAmt and assigns the result to *this.
+ /// @returns *this after shifting left by shiftAmt
+ /// @brief Left-shift assignment function.
+ APInt& operator<<=(unsigned shiftAmt) {
+ *this = shl(shiftAmt);
+ return *this;
+ }
+
+ /// @}
+ /// @name Binary Operators
+ /// @{
+ /// Performs a bitwise AND operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise AND of *this and RHS.
+ /// @brief Bitwise AND operator.
+ APInt operator&(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(getBitWidth(), VAL & RHS.VAL);
+ return AndSlowCase(RHS);
+ }
+ APInt And(const APInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ /// Performs a bitwise OR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise OR of *this and RHS.
+ /// @brief Bitwise OR operator.
+ APInt operator|(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(getBitWidth(), VAL | RHS.VAL);
+ return OrSlowCase(RHS);
+ }
+ APInt Or(const APInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+ /// Performs a bitwise XOR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise XOR of *this and RHS.
+ /// @brief Bitwise XOR operator.
+ APInt operator^(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(BitWidth, VAL ^ RHS.VAL);
+ return XorSlowCase(RHS);
+ }
+ APInt Xor(const APInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ /// Multiplies this APInt by RHS and returns the result.
+ /// @brief Multiplication operator.
+ APInt operator*(const APInt& RHS) const;
+
+ /// Adds RHS to this APInt and returns the result.
+ /// @brief Addition operator.
+ APInt operator+(const APInt& RHS) const;
+ APInt operator+(uint64_t RHS) const {
+ return (*this) + APInt(BitWidth, RHS);
+ }
+
+ /// Subtracts RHS from this APInt and returns the result.
+ /// @brief Subtraction operator.
+ APInt operator-(const APInt& RHS) const;
+ APInt operator-(uint64_t RHS) const {
+ return (*this) - APInt(BitWidth, RHS);
+ }
+
+ APInt operator<<(unsigned Bits) const {
+ return shl(Bits);
+ }
+
+ APInt operator<<(const APInt &Bits) const {
+ return shl(Bits);
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(unsigned shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(unsigned shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(unsigned shiftAmt) const {
+ assert(shiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ if (shiftAmt == BitWidth)
+ return APInt(BitWidth, 0); // avoid undefined shift results
+ return APInt(BitWidth, VAL << shiftAmt);
+ }
+ return shlSlowCase(shiftAmt);
+ }
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(unsigned rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(unsigned rotateAmt) const;
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(const APInt &shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(const APInt &shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(const APInt &shiftAmt) const;
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(const APInt &rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(const APInt &rotateAmt) const;
+
+ /// Perform an unsigned divide operation on this APInt by RHS. Both this and
+ /// RHS are treated as unsigned quantities for purposes of this division.
+ /// @returns a new APInt value containing the division result
+ /// @brief Unsigned division operation.
+ APInt udiv(const APInt& RHS) const;
+
+ /// Signed divide this APInt by APInt RHS.
+ /// @brief Signed division function for APInt.
+ APInt sdiv(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return (-(*this)).udiv(-RHS);
+ else
+ return -((-(*this)).udiv(RHS));
+ else if (RHS.isNegative())
+ return -(this->udiv(-RHS));
+ return this->udiv(RHS);
+ }
+
+ /// Perform an unsigned remainder operation on this APInt with RHS being the
+ /// divisor. Both this and RHS are treated as unsigned quantities for purposes
+ /// of this operation. Note that this is a true remainder operation and not
+ /// a modulo operation because the sign follows the sign of the dividend
+ /// which is *this.
+ /// @returns a new APInt value containing the remainder result
+ /// @brief Unsigned remainder operation.
+ APInt urem(const APInt& RHS) const;
+
+ /// Signed remainder operation on APInt.
+ /// @brief Function for signed remainder operation.
+ APInt srem(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return -((-(*this)).urem(-RHS));
+ else
+ return -((-(*this)).urem(RHS));
+ else if (RHS.isNegative())
+ return this->urem(-RHS);
+ return this->urem(RHS);
+ }
+
+ /// Sometimes it is convenient to divide two APInt values and obtain both the
+ /// quotient and remainder. This function does both operations in the same
+ /// computation making it a little more efficient. The pair of input arguments
+ /// may overlap with the pair of output arguments. It is safe to call
+ /// udivrem(X, Y, X, Y), for example.
+ /// @brief Dual division/remainder interface.
+ static void udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder);
+
+ static void sdivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder)
+ {
+ if (LHS.isNegative()) {
+ if (RHS.isNegative())
+ APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
+ else
+ APInt::udivrem(-LHS, RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ Remainder = -Remainder;
+ } else if (RHS.isNegative()) {
+ APInt::udivrem(LHS, -RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ } else {
+ APInt::udivrem(LHS, RHS, Quotient, Remainder);
+ }
+ }
+
+ /// @returns the bit value at bitPosition
+ /// @brief Array-indexing support.
+ bool operator[](unsigned bitPosition) const;
+
+ /// @}
+ /// @name Comparison Operators
+ /// @{
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @brief Equality operator.
+ bool operator==(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
+ if (isSingleWord())
+ return VAL == RHS.VAL;
+ return EqualSlowCase(RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality operator.
+ bool operator==(uint64_t Val) const {
+ if (isSingleWord())
+ return VAL == Val;
+ return EqualSlowCase(Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality comparison.
+ bool eq(const APInt &RHS) const {
+ return (*this) == RHS;
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ bool operator!=(const APInt& RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ bool operator!=(uint64_t Val) const {
+ return !((*this) == Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality comparison
+ bool ne(const APInt &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered signed.
+ /// @brief Signed less than comparison
+ bool slt(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(const APInt& RHS) const {
+ return ult(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(const APInt& RHS) const {
+ return slt(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered unsigned.
+ /// @brief Unsigned greather than comparison
+ bool ugt(const APInt& RHS) const {
+ return !ult(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered signed.
+ /// @brief Signed greather than comparison
+ bool sgt(const APInt& RHS) const {
+ return !slt(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(const APInt& RHS) const {
+ return !ult(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered signed.
+ /// @brief Signed greather or equal comparison
+ bool sge(const APInt& RHS) const {
+ return !slt(RHS);
+ }
+
+ /// This operation tests if there are any pairs of corresponding bits
+ /// between this APInt and RHS that are both set.
+ bool intersects(const APInt &RHS) const {
+ return (*this & RHS) != 0;
+ }
+
+ /// @}
+ /// @name Resizing Operators
+ /// @{
+ /// Truncate the APInt to a specified width. It is an error to specify a width
+ /// that is greater than or equal to the current width.
+ /// @brief Truncate to new width.
+ APInt &trunc(unsigned width);
+
+ /// This operation sign extends the APInt to a new width. If the high order
+ /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
+ /// It is an error to specify a width that is less than or equal to the
+ /// current width.
+ /// @brief Sign extend to a new width.
+ APInt &sext(unsigned width);
+
+ /// This operation zero extends the APInt to a new width. The high order bits
+ /// are filled with 0 bits. It is an error to specify a width that is less
+ /// than or equal to the current width.
+ /// @brief Zero extend to a new width.
+ APInt &zext(unsigned width);
+
+ /// Make this APInt have the bit width given by \p width. The value is sign
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Sign extend or truncate to width
+ APInt &sextOrTrunc(unsigned width);
+
+ /// Make this APInt have the bit width given by \p width. The value is zero
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Zero extend or truncate to width
+ APInt &zextOrTrunc(unsigned width);
+
+ /// @}
+ /// @name Bit Manipulation Operators
+ /// @{
+ /// @brief Set every bit to 1.
+ APInt& set() {
+ if (isSingleWord()) {
+ VAL = -1ULL;
+ return clearUnusedBits();
+ }
+
+ // Set all the bits in all the words.
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] = -1ULL;
+ // Clear the unused ones
+ return clearUnusedBits();
+ }
+
+ /// Set the given bit to 1 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 1.
+ APInt& set(unsigned bitPosition);
+
+ /// @brief Set every bit to 0.
+ APInt& clear() {
+ if (isSingleWord())
+ VAL = 0;
+ else
+ memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+ return *this;
+ }
+
+ /// Set the given bit to 0 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 0.
+ APInt& clear(unsigned bitPosition);
+
+ /// @brief Toggle every bit to its opposite value.
+ APInt& flip() {
+ if (isSingleWord()) {
+ VAL ^= -1ULL;
+ return clearUnusedBits();
+ }
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] ^= -1ULL;
+ return clearUnusedBits();
+ }
+
+ /// Toggle a given bit to its opposite value whose position is given
+ /// as "bitPosition".
+ /// @brief Toggles a given bit to its opposite value.
+ APInt& flip(unsigned bitPosition);
+
+ /// @}
+ /// @name Value Characterization Functions
+ /// @{
+
+ /// @returns the total number of bits.
+ unsigned getBitWidth() const {
+ return BitWidth;
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value of this APInt.
+ /// @brief Get the number of words.
+ unsigned getNumWords() const {
+ return getNumWords(BitWidth);
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value with a
+ /// given bit width.
+ /// @brief Get the number of words.
+ static unsigned getNumWords(unsigned BitWidth) {
+ return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ }
+
+ /// This function returns the number of active bits which is defined as the
+ /// bit width minus the number of leading zeros. This is used in several
+ /// computations to see how "wide" the value is.
+ /// @brief Compute the number of active bits in the value
+ unsigned getActiveBits() const {
+ return BitWidth - countLeadingZeros();
+ }
+
+ /// This function returns the number of active words in the value of this
+ /// APInt. This is used in conjunction with getActiveData to extract the raw
+ /// value of the APInt.
+ unsigned getActiveWords() const {
+ return whichWord(getActiveBits()-1) + 1;
+ }
+
+ /// Computes the minimum bit width for this APInt while considering it to be
+ /// a signed (and probably negative) value. If the value is not negative,
+ /// this function returns the same value as getActiveBits()+1. Otherwise, it
+ /// returns the smallest bit width that will retain the negative value. For
+ /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
+ /// for -1, this function will always return 1.
+ /// @brief Get the minimum bit size for this signed APInt
+ unsigned getMinSignedBits() const {
+ if (isNegative())
+ return BitWidth - countLeadingOnes() + 1;
+ return getActiveBits()+1;
+ }
+
+ /// This method attempts to return the value of this APInt as a zero extended
+ /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
+ /// uint64_t. Otherwise an assertion will result.
+ /// @brief Get zero extended value
+ uint64_t getZExtValue() const {
+ if (isSingleWord())
+ return VAL;
+ assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
+ return pVal[0];
+ }
+
+ /// This method attempts to return the value of this APInt as a sign extended
+ /// int64_t. The bit width must be <= 64 or the value must fit within an
+ /// int64_t. Otherwise an assertion will result.
+ /// @brief Get sign extended value
+ int64_t getSExtValue() const {
+ if (isSingleWord())
+ return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
+ (APINT_BITS_PER_WORD - BitWidth);
+ assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
+ return int64_t(pVal[0]);
+ }
+
+ /// This method determines how many bits are required to hold the APInt
+ /// equivalent of the string given by \p str of length \p slen.
+ /// @brief Get bits required for string value.
+ static unsigned getBitsNeeded(const char* str, unsigned slen, uint8_t radix);
+
+ /// countLeadingZeros - This function is an APInt version of the
+ /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
+ /// of zeros from the most significant bit to the first one bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the most significant bit to the first
+ /// one bits.
+ unsigned countLeadingZeros() const {
+ if (isSingleWord()) {
+ unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
+ return CountLeadingZeros_64(VAL) - unusedBits;
+ }
+ return countLeadingZerosSlowCase();
+ }
+
+ /// countLeadingOnes - This function is an APInt version of the
+ /// countLeadingOnes_{32,64} functions in MathExtras.h. It counts the number
+ /// of ones from the most significant bit to the first zero bit.
+ /// @returns 0 if the high order bit is not set
+ /// @returns the number of 1 bits from the most significant to the least
+ /// @brief Count the number of leading one bits.
+ unsigned countLeadingOnes() const;
+
+ /// countTrailingZeros - This function is an APInt version of the
+ /// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
+ /// the number of zeros from the least significant bit to the first set bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the least significant bit to the first
+ /// one bit.
+ /// @brief Count the number of trailing zero bits.
+ unsigned countTrailingZeros() const;
+
+ /// countTrailingOnes - This function is an APInt version of the
+ /// countTrailingOnes_{32,64} functions in MathExtras.h. It counts
+ /// the number of ones from the least significant bit to the first zero bit.
+ /// @returns BitWidth if the value is all ones.
+ /// @returns the number of ones from the least significant bit to the first
+ /// zero bit.
+ /// @brief Count the number of trailing one bits.
+ unsigned countTrailingOnes() const {
+ if (isSingleWord())
+ return CountTrailingOnes_64(VAL);
+ return countTrailingOnesSlowCase();
+ }
+
+ /// countPopulation - This function is an APInt version of the
+ /// countPopulation_{32,64} functions in MathExtras.h. It counts the number
+ /// of 1 bits in the APInt value.
+ /// @returns 0 if the value is zero.
+ /// @returns the number of set bits.
+ /// @brief Count the number of bits set.
+ unsigned countPopulation() const {
+ if (isSingleWord())
+ return CountPopulation_64(VAL);
+ return countPopulationSlowCase();
+ }
+
+ /// @}
+ /// @name Conversion Functions
+ /// @{
+ void print(raw_ostream &OS, bool isSigned) const;
+
+ /// toString - Converts an APInt to a string and append it to Str. Str is
+ /// commonly a SmallString.
+ void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed) const;
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ toString(Str, Radix, false);
+ }
+
+ /// Considers the APInt to be signed and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ toString(Str, Radix, true);
+ }
+
+ /// toString - This returns the APInt as a std::string. Note that this is an
+ /// inefficient method. It is better to pass in a SmallVector/SmallString
+ /// to the methods above to avoid thrashing the heap for the string.
+ std::string toString(unsigned Radix, bool Signed) const;
+
+
+ /// @returns a byte-swapped representation of this APInt Value.
+ APInt byteSwap() const;
+
+ /// @brief Converts this APInt to a double value.
+ double roundToDouble(bool isSigned) const;
+
+ /// @brief Converts this unsigned APInt to a double value.
+ double roundToDouble() const {
+ return roundToDouble(false);
+ }
+
+ /// @brief Converts this signed APInt to a double value.
+ double signedRoundToDouble() const {
+ return roundToDouble(true);
+ }
+
+ /// The conversion does not do a translation from integer to double, it just
+ /// re-interprets the bits as a double. Note that it is valid to do this on
+ /// any bit width. Exactly 64 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ double bitsToDouble() const {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.I = (isSingleWord() ? VAL : pVal[0]);
+ return T.D;
+ }
+
+ /// The conversion does not do a translation from integer to float, it just
+ /// re-interprets the bits as a float. Note that it is valid to do this on
+ /// any bit width. Exactly 32 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ float bitsToFloat() const {
+ union {
+ unsigned I;
+ float F;
+ } T;
+ T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
+ return T.F;
+ }
+
+ /// The conversion does not do a translation from double to integer, it just
+ /// re-interprets the bits of the double. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a double to APInt bits.
+ APInt& doubleToBits(double V) {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.D = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// The conversion does not do a translation from float to integer, it just
+ /// re-interprets the bits of the float. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a float to APInt bits.
+ APInt& floatToBits(float V) {
+ union {
+ unsigned I;
+ float F;
+ } T;
+ T.F = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// @}
+ /// @name Mathematics Operations
+ /// @{
+
+ /// @returns the floor log base 2 of this APInt.
+ unsigned logBase2() const {
+ return BitWidth - 1 - countLeadingZeros();
+ }
+
+ /// @returns the log base 2 of this APInt if its an exact power of two, -1
+ /// otherwise
+ int32_t exactLogBase2() const {
+ if (!isPowerOf2())
+ return -1;
+ return logBase2();
+ }
+
+ /// @brief Compute the square root
+ APInt sqrt() const;
+
+ /// If *this is < 0 then return -(*this), otherwise *this;
+ /// @brief Get the absolute value;
+ APInt abs() const {
+ if (isNegative())
+ return -(*this);
+ return *this;
+ }
+
+ /// @returns the multiplicative inverse for a given modulo.
+ APInt multiplicativeInverse(const APInt& modulo) const;
+
+ /// @}
+ /// @name Support for division by constant
+ /// @{
+
+ /// Calculate the magic number for signed division by a constant.
+ struct ms;
+ ms magic() const;
+
+ /// Calculate the magic number for unsigned division by a constant.
+ struct mu;
+ mu magicu() const;
+
+ /// @}
+ /// @name Building-block Operations for APInt and APFloat
+ /// @{
+
+ // These building block operations operate on a representation of
+ // arbitrary precision, two's-complement, bignum integer values.
+ // They should be sufficient to implement APInt and APFloat bignum
+ // requirements. Inputs are generally a pointer to the base of an
+ // array of integer parts, representing an unsigned bignum, and a
+ // count of how many parts there are.
+
+ /// Sets the least significant part of a bignum to the input value,
+ /// and zeroes out higher parts. */
+ static void tcSet(integerPart *, integerPart, unsigned int);
+
+ /// Assign one bignum to another.
+ static void tcAssign(integerPart *, const integerPart *, unsigned int);
+
+ /// Returns true if a bignum is zero, false otherwise.
+ static bool tcIsZero(const integerPart *, unsigned int);
+
+ /// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
+ static int tcExtractBit(const integerPart *, unsigned int bit);
+
+ /// Copy the bit vector of width srcBITS from SRC, starting at bit
+ /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB
+ /// becomes the least significant bit of DST. All high bits above
+ /// srcBITS in DST are zero-filled.
+ static void tcExtract(integerPart *, unsigned int dstCount,
+ const integerPart *,
+ unsigned int srcBits, unsigned int srcLSB);
+
+ /// Set the given bit of a bignum. Zero-based.
+ static void tcSetBit(integerPart *, unsigned int bit);
+
+ /// Returns the bit number of the least or most significant set bit
+ /// of a number. If the input number has no bits set -1U is
+ /// returned.
+ static unsigned int tcLSB(const integerPart *, unsigned int);
+ static unsigned int tcMSB(const integerPart *parts, unsigned int n);
+
+ /// Negate a bignum in-place.
+ static void tcNegate(integerPart *, unsigned int);
+
+ /// DST += RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcAdd(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST -= RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcSubtract(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST += SRC * MULTIPLIER + PART if add is true
+ /// DST = SRC * MULTIPLIER + PART if add is false
+ ///
+ /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC
+ /// they must start at the same point, i.e. DST == SRC.
+ ///
+ /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is
+ /// returned. Otherwise DST is filled with the least significant
+ /// DSTPARTS parts of the result, and if all of the omitted higher
+ /// parts were zero return zero, otherwise overflow occurred and
+ /// return one.
+ static int tcMultiplyPart(integerPart *dst, const integerPart *src,
+ integerPart multiplier, integerPart carry,
+ unsigned int srcParts, unsigned int dstParts,
+ bool add);
+
+ /// DST = LHS * RHS, where DST has the same width as the operands
+ /// and is filled with the least significant parts of the result.
+ /// Returns one if overflow occurred, otherwise zero. DST must be
+ /// disjoint from both operands.
+ static int tcMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned);
+
+ /// DST = LHS * RHS, where DST has width the sum of the widths of
+ /// the operands. No overflow occurs. DST must be disjoint from
+ /// both operands. Returns the number of parts required to hold the
+ /// result.
+ static unsigned int tcFullMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned, unsigned);
+
+ /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
+ /// Otherwise set LHS to LHS / RHS with the fractional part
+ /// discarded, set REMAINDER to the remainder, return zero. i.e.
+ ///
+ /// OLD_LHS = RHS * LHS + REMAINDER
+ ///
+ /// SCRATCH is a bignum of the same size as the operands and result
+ /// for use by the routine; its contents need not be initialized
+ /// and are destroyed. LHS, REMAINDER and SCRATCH must be
+ /// distinct.
+ static int tcDivide(integerPart *lhs, const integerPart *rhs,
+ integerPart *remainder, integerPart *scratch,
+ unsigned int parts);
+
+ /// Shift a bignum left COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftLeft(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// Shift a bignum right COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftRight(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// The obvious AND, OR and XOR and complement operations.
+ static void tcAnd(integerPart *, const integerPart *, unsigned int);
+ static void tcOr(integerPart *, const integerPart *, unsigned int);
+ static void tcXor(integerPart *, const integerPart *, unsigned int);
+ static void tcComplement(integerPart *, unsigned int);
+
+ /// Comparison (unsigned) of two bignums.
+ static int tcCompare(const integerPart *, const integerPart *,
+ unsigned int);
+
+ /// Increment a bignum in-place. Return the carry flag.
+ static integerPart tcIncrement(integerPart *, unsigned int);
+
+ /// Set the least significant BITS and clear the rest.
+ static void tcSetLeastSignificantBits(integerPart *, unsigned int,
+ unsigned int bits);
+
+ /// @brief debug method
+ void dump() const;
+
+ /// @}
+};
+
+/// Magic data for optimising signed division by a constant.
+struct APInt::ms {
+ APInt m; ///< magic number
+ unsigned s; ///< shift amount
+};
+
+/// Magic data for optimising unsigned division by a constant.
+struct APInt::mu {
+ APInt m; ///< magic number
+ bool a; ///< add indicator
+ unsigned s; ///< shift amount
+};
+
+inline bool operator==(uint64_t V1, const APInt& V2) {
+ return V2 == V1;
+}
+
+inline bool operator!=(uint64_t V1, const APInt& V2) {
+ return V2 != V1;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
+ I.print(OS, true);
+ return OS;
+}
+
+namespace APIntOps {
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt smin(const APInt &A, const APInt &B) {
+ return A.slt(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be signed.
+inline APInt smax(const APInt &A, const APInt &B) {
+ return A.sgt(B) ? A : B;
+}
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt umin(const APInt &A, const APInt &B) {
+ return A.ult(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be unsigned.
+inline APInt umax(const APInt &A, const APInt &B) {
+ return A.ugt(B) ? A : B;
+}
+
+/// @brief Check if the specified APInt has a N-bits unsigned integer value.
+inline bool isIntN(unsigned N, const APInt& APIVal) {
+ return APIVal.isIntN(N);
+}
+
+/// @brief Check if the specified APInt has a N-bits signed integer value.
+inline bool isSignedIntN(unsigned N, const APInt& APIVal) {
+ return APIVal.isSignedIntN(N);
+}
+
+/// @returns true if the argument APInt value is a sequence of ones
+/// starting at the least significant bit with the remainder zero.
+inline bool isMask(unsigned numBits, const APInt& APIVal) {
+ return numBits <= APIVal.getBitWidth() &&
+ APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits);
+}
+
+/// @returns true if the argument APInt value contains a sequence of ones
+/// with the remainder zero.
+inline bool isShiftedMask(unsigned numBits, const APInt& APIVal) {
+ return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal);
+}
+
+/// @returns a byte-swapped representation of the specified APInt Value.
+inline APInt byteSwap(const APInt& APIVal) {
+ return APIVal.byteSwap();
+}
+
+/// @returns the floor log base 2 of the specified APInt value.
+inline unsigned logBase2(const APInt& APIVal) {
+ return APIVal.logBase2();
+}
+
+/// GreatestCommonDivisor - This function returns the greatest common
+/// divisor of the two APInt values using Euclid's algorithm.
+/// @returns the greatest common divisor of Val1 and Val2
+/// @brief Compute GCD of two APInt values.
+APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2);
+
+/// Treats the APInt as an unsigned value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundAPIntToDouble(const APInt& APIVal) {
+ return APIVal.roundToDouble();
+}
+
+/// Treats the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundSignedAPIntToDouble(const APInt& APIVal) {
+ return APIVal.signedRoundToDouble();
+}
+
+/// @brief Converts the given APInt to a float vlalue.
+inline float RoundAPIntToFloat(const APInt& APIVal) {
+ return float(RoundAPIntToDouble(APIVal));
+}
+
+/// Treast the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a float value.
+inline float RoundSignedAPIntToFloat(const APInt& APIVal) {
+ return float(APIVal.signedRoundToDouble());
+}
+
+/// RoundDoubleToAPInt - This function convert a double value to an APInt value.
+/// @brief Converts the given double value into a APInt.
+APInt RoundDoubleToAPInt(double Double, unsigned width);
+
+/// RoundFloatToAPInt - Converts a float value into an APInt value.
+/// @brief Converts a float value into a APInt.
+inline APInt RoundFloatToAPInt(float Float, unsigned width) {
+ return RoundDoubleToAPInt(double(Float), width);
+}
+
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+inline APInt ashr(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.ashr(shiftAmt);
+}
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+inline APInt lshr(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.lshr(shiftAmt);
+}
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+inline APInt shl(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.shl(shiftAmt);
+}
+
+/// Signed divide APInt LHS by APInt RHS.
+/// @brief Signed division function for APInt.
+inline APInt sdiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.sdiv(RHS);
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+inline APInt udiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.udiv(RHS);
+}
+
+/// Signed remainder operation on APInt.
+/// @brief Function for signed remainder operation.
+inline APInt srem(const APInt& LHS, const APInt& RHS) {
+ return LHS.srem(RHS);
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+inline APInt urem(const APInt& LHS, const APInt& RHS) {
+ return LHS.urem(RHS);
+}
+
+/// Performs multiplication on APInt values.
+/// @brief Function for multiplication operation.
+inline APInt mul(const APInt& LHS, const APInt& RHS) {
+ return LHS * RHS;
+}
+
+/// Performs addition on APInt values.
+/// @brief Function for addition operation.
+inline APInt add(const APInt& LHS, const APInt& RHS) {
+ return LHS + RHS;
+}
+
+/// Performs subtraction on APInt values.
+/// @brief Function for subtraction operation.
+inline APInt sub(const APInt& LHS, const APInt& RHS) {
+ return LHS - RHS;
+}
+
+/// Performs bitwise AND operation on APInt LHS and
+/// APInt RHS.
+/// @brief Bitwise AND function for APInt.
+inline APInt And(const APInt& LHS, const APInt& RHS) {
+ return LHS & RHS;
+}
+
+/// Performs bitwise OR operation on APInt LHS and APInt RHS.
+/// @brief Bitwise OR function for APInt.
+inline APInt Or(const APInt& LHS, const APInt& RHS) {
+ return LHS | RHS;
+}
+
+/// Performs bitwise XOR operation on APInt.
+/// @brief Bitwise XOR function for APInt.
+inline APInt Xor(const APInt& LHS, const APInt& RHS) {
+ return LHS ^ RHS;
+}
+
+/// Performs a bitwise complement operation on APInt.
+/// @brief Bitwise complement function.
+inline APInt Not(const APInt& APIVal) {
+ return ~APIVal;
+}
+
+} // End of APIntOps namespace
+
+} // End of llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
new file mode 100644
index 0000000000000..1c9931c30fe51
--- /dev/null
+++ b/include/llvm/ADT/APSInt.h
@@ -0,0 +1,264 @@
+//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the APSInt class, which is a simple class that
+// represents an arbitrary sized integer that knows its signedness.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APSINT_H
+#define LLVM_APSINT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+class APSInt : public APInt {
+ bool IsUnsigned;
+public:
+ /// Default constructor that creates an uninitialized APInt.
+ explicit APSInt() {}
+
+ /// APSInt ctor - Create an APSInt with the specified width, default to
+ /// unsigned.
+ explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
+ : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
+
+ explicit APSInt(const APInt &I, bool isUnsigned = true)
+ : APInt(I), IsUnsigned(isUnsigned) {}
+
+ APSInt &operator=(const APSInt &RHS) {
+ APInt::operator=(RHS);
+ IsUnsigned = RHS.IsUnsigned;
+ return *this;
+ }
+
+ APSInt &operator=(const APInt &RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ APSInt &operator=(uint64_t RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ // Query sign information.
+ bool isSigned() const { return !IsUnsigned; }
+ bool isUnsigned() const { return IsUnsigned; }
+ void setIsUnsigned(bool Val) { IsUnsigned = Val; }
+ void setIsSigned(bool Val) { IsUnsigned = !Val; }
+
+ /// toString - Append this APSInt to the specified SmallString.
+ void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ APInt::toString(Str, Radix, isSigned());
+ }
+ /// toString - Converts an APInt to a std::string. This is an inefficient
+ /// method, your should prefer passing in a SmallString instead.
+ std::string toString(unsigned Radix) const {
+ return APInt::toString(Radix, isSigned());
+ }
+ using APInt::toString;
+
+ APSInt& extend(uint32_t width) {
+ if (IsUnsigned)
+ zext(width);
+ else
+ sext(width);
+ return *this;
+ }
+
+ APSInt& extOrTrunc(uint32_t width) {
+ if (IsUnsigned)
+ zextOrTrunc(width);
+ else
+ sextOrTrunc(width);
+ return *this;
+ }
+
+ const APSInt &operator%=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = urem(RHS);
+ else
+ *this = srem(RHS);
+ return *this;
+ }
+ const APSInt &operator/=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = udiv(RHS);
+ else
+ *this = sdiv(RHS);
+ return *this;
+ }
+ APSInt operator%(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
+ }
+ APSInt operator/(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
+ }
+
+ APSInt operator>>(unsigned Amt) const {
+ return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
+ }
+ APSInt& operator>>=(unsigned Amt) {
+ *this = *this >> Amt;
+ return *this;
+ }
+
+ inline bool operator<(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ult(RHS) : slt(RHS);
+ }
+ inline bool operator>(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ugt(RHS) : sgt(RHS);
+ }
+ inline bool operator<=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ule(RHS) : sle(RHS);
+ }
+ inline bool operator>=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? uge(RHS) : sge(RHS);
+ }
+
+ // The remaining operators just wrap the logic of APInt, but retain the
+ // signedness information.
+
+ APSInt operator<<(unsigned Bits) const {
+ return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
+ }
+ APSInt& operator<<=(unsigned Amt) {
+ *this = *this << Amt;
+ return *this;
+ }
+
+ APSInt& operator++() {
+ static_cast<APInt&>(*this)++;
+ return *this;
+ }
+ APSInt& operator--() {
+ static_cast<APInt&>(*this)--;
+ return *this;
+ }
+ APSInt operator++(int) {
+ return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
+ }
+ APSInt operator--(int) {
+ return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
+ }
+ APSInt operator-() const {
+ return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
+ }
+ APSInt& operator+=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) += RHS;
+ return *this;
+ }
+ APSInt& operator-=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) -= RHS;
+ return *this;
+ }
+ APSInt& operator*=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) *= RHS;
+ return *this;
+ }
+ APSInt& operator&=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) &= RHS;
+ return *this;
+ }
+ APSInt& operator|=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) |= RHS;
+ return *this;
+ }
+ APSInt& operator^=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) ^= RHS;
+ return *this;
+ }
+
+ APSInt operator&(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
+ }
+ APSInt And(const APSInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ APSInt operator|(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
+ }
+ APSInt Or(const APSInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+
+ APSInt operator^(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
+ }
+ APSInt Xor(const APSInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ APSInt operator*(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
+ }
+ APSInt operator+(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
+ }
+ APSInt operator-(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
+ }
+ APSInt operator~() const {
+ return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
+ }
+
+ /// getMaxValue - Return the APSInt representing the maximum integer value
+ /// with the given bit width and signedness.
+ static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMaxValue(numBits)
+ : APInt::getSignedMaxValue(numBits), Unsigned);
+ }
+
+ /// getMinValue - Return the APSInt representing the minimum integer value
+ /// with the given bit width and signedness.
+ static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMinValue(numBits)
+ : APInt::getSignedMinValue(numBits), Unsigned);
+ }
+
+ /// Profile - Used to insert APSInt objects, or objects that contain APSInt
+ /// objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& ID) const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
+ I.print(OS, I.isSigned());
+ return OS;
+}
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
new file mode 100644
index 0000000000000..9c046efaaddd9
--- /dev/null
+++ b/include/llvm/ADT/BitVector.h
@@ -0,0 +1,409 @@
+//===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the BitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITVECTOR_H
+#define LLVM_ADT_BITVECTOR_H
+
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <climits>
+#include <cstring>
+
+namespace llvm {
+
+class BitVector {
+ typedef unsigned long BitWord;
+
+ enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
+
+ BitWord *Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
+ unsigned Capacity; // Size of allocated memory in BitWord.
+
+public:
+ // Encapsulation of a single bit.
+ class reference {
+ friend class BitVector;
+
+ BitWord *WordRef;
+ unsigned BitPos;
+
+ reference(); // Undefined
+
+ public:
+ reference(BitVector &b, unsigned Idx) {
+ WordRef = &b.Bits[Idx / BITWORD_SIZE];
+ BitPos = Idx % BITWORD_SIZE;
+ }
+
+ ~reference() {}
+
+ reference& operator=(bool t) {
+ if (t)
+ *WordRef |= 1L << BitPos;
+ else
+ *WordRef &= ~(1L << BitPos);
+ return *this;
+ }
+
+ operator bool() const {
+ return ((*WordRef) & (1L << BitPos)) ? true : false;
+ }
+ };
+
+
+ /// BitVector default ctor - Creates an empty bitvector.
+ BitVector() : Size(0), Capacity(0) {
+ Bits = 0;
+ }
+
+ /// BitVector ctor - Creates a bitvector of specified number of bits. All
+ /// bits are initialized to the specified value.
+ explicit BitVector(unsigned s, bool t = false) : Size(s) {
+ Capacity = NumBitWords(s);
+ Bits = new BitWord[Capacity];
+ init_words(Bits, Capacity, t);
+ if (t)
+ clear_unused_bits();
+ }
+
+ /// BitVector copy ctor.
+ BitVector(const BitVector &RHS) : Size(RHS.size()) {
+ if (Size == 0) {
+ Bits = 0;
+ Capacity = 0;
+ return;
+ }
+
+ Capacity = NumBitWords(RHS.size());
+ Bits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
+ }
+
+ ~BitVector() {
+ delete[] Bits;
+ }
+
+ /// size - Returns the number of bits in this bitvector.
+ unsigned size() const { return Size; }
+
+ /// count - Returns the number of bits which are set.
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32((uint32_t)Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ return NumBits;
+ }
+
+ /// any - Returns true if any bit is set.
+ bool any() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0)
+ return true;
+ return false;
+ }
+
+ /// none - Returns true if none of the bits are set.
+ bool none() const {
+ return !any();
+ }
+
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const {
+ ++Prev;
+ if (Prev >= Size)
+ return -1;
+
+ unsigned WordPos = Prev / BITWORD_SIZE;
+ unsigned BitPos = Prev % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
+ else if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ else
+ assert(0 && "Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// clear - Clear all bits.
+ void clear() {
+ Size = 0;
+ }
+
+ /// resize - Grow or shrink the bitvector.
+ void resize(unsigned N, bool t = false) {
+ if (N > Capacity * BITWORD_SIZE) {
+ unsigned OldCapacity = Capacity;
+ grow(N);
+ init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ }
+
+ // 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
+ // them back out below.
+ if (N > Size)
+ set_unused_bits(t);
+
+ // Update the size, and clear out any bits that are now unused
+ unsigned OldSize = Size;
+ Size = N;
+ if (t || N < OldSize)
+ clear_unused_bits();
+ }
+
+ void reserve(unsigned N) {
+ if (N > Capacity * BITWORD_SIZE)
+ grow(N);
+ }
+
+ // Set, reset, flip
+ BitVector &set() {
+ init_words(Bits, Capacity, true);
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ BitVector &reset() {
+ init_words(Bits, Capacity, false);
+ return *this;
+ }
+
+ BitVector &reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ return *this;
+ }
+
+ BitVector &flip() {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] = ~Bits[i];
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &flip(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ // No argument flip.
+ BitVector operator~() const {
+ return BitVector(*this).flip();
+ }
+
+ // Indexing.
+ reference operator[](unsigned Idx) {
+ assert (Idx < Size && "Out-of-bounds Bit access.");
+ return reference(*this, Idx);
+ }
+
+ bool operator[](unsigned Idx) const {
+ assert (Idx < Size && "Out-of-bounds Bit access.");
+ BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
+ }
+
+ bool test(unsigned Idx) const {
+ return (*this)[Idx];
+ }
+
+ // Comparison operators.
+ bool operator==(const BitVector &RHS) const {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+
+ // Verify that any extra words are all zeros.
+ if (i != ThisWords) {
+ for (; i != ThisWords; ++i)
+ if (Bits[i])
+ return false;
+ } else if (i != RHSWords) {
+ for (; i != RHSWords; ++i)
+ if (RHS.Bits[i])
+ return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const BitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Intersection, union, disjoint union.
+ BitVector &operator&=(const BitVector &RHS) {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ Bits[i] &= RHS.Bits[i];
+
+ // 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
+ // are already zero in the LHS.
+ for (; i != ThisWords; ++i)
+ Bits[i] = 0;
+
+ return *this;
+ }
+
+ BitVector &operator|=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] |= RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector &operator^=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] ^= RHS.Bits[i];
+ return *this;
+ }
+
+ // Assignment operator.
+ const BitVector &operator=(const BitVector &RHS) {
+ if (this == &RHS) return *this;
+
+ Size = RHS.size();
+ unsigned RHSWords = NumBitWords(Size);
+ if (Size <= Capacity * BITWORD_SIZE) {
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
+ clear_unused_bits();
+ return *this;
+ }
+
+ // Grow the bitvector to have enough elements.
+ Capacity = RHSWords;
+ BitWord *NewBits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+
+ return *this;
+ }
+
+private:
+ unsigned NumBitWords(unsigned S) const {
+ return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
+ }
+
+ // Set the unused bits in the high words.
+ void set_unused_bits(bool t = true) {
+ // Set high words first.
+ unsigned UsedWords = NumBitWords(Size);
+ if (Capacity > UsedWords)
+ init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+
+ // Then set any stray high bits of the last used word.
+ unsigned ExtraBits = Size % BITWORD_SIZE;
+ if (ExtraBits) {
+ Bits[UsedWords-1] &= ~(~0L << ExtraBits);
+ Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
+ }
+ }
+
+ // Clear the unused bits in the high words.
+ void clear_unused_bits() {
+ set_unused_bits(false);
+ }
+
+ void grow(unsigned NewSize) {
+ unsigned OldCapacity = Capacity;
+ Capacity = NumBitWords(NewSize);
+ BitWord *NewBits = new BitWord[Capacity];
+
+ // Copy the old bits over.
+ if (OldCapacity != 0)
+ std::copy(Bits, &Bits[OldCapacity], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+
+ clear_unused_bits();
+ }
+
+ void init_words(BitWord *B, unsigned NumWords, bool t) {
+ memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ }
+};
+
+inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result ^= RHS;
+ return Result;
+}
+
+} // End llvm namespace
+#endif
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
new file mode 100644
index 0000000000000..e18be8963d48b
--- /dev/null
+++ b/include/llvm/ADT/DenseMap.h
@@ -0,0 +1,570 @@
+//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DenseMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAP_H
+#define LLVM_ADT_DENSEMAP_H
+
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <utility>
+#include <new>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo {
+ //static inline T getEmptyKey();
+ //static inline T getTombstoneKey();
+ //static unsigned getHashValue(const T &Val);
+ //static bool isEqual(const T &LHS, const T &RHS);
+ //static bool isPod()
+};
+
+// Provide DenseMapInfo for all pointers.
+template<typename T>
+struct DenseMapInfo<T*> {
+ static inline T* getEmptyKey() {
+ intptr_t Val = -1;
+ Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ return reinterpret_cast<T*>(Val);
+ }
+ static inline T* getTombstoneKey() {
+ intptr_t Val = -2;
+ Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ return reinterpret_cast<T*>(Val);
+ }
+ static unsigned getHashValue(const T *PtrVal) {
+ return (unsigned((uintptr_t)PtrVal) >> 4) ^
+ (unsigned((uintptr_t)PtrVal) >> 9);
+ }
+ static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
+ static bool isPod() { return true; }
+};
+
+// Provide DenseMapInfo for chars.
+template<> struct DenseMapInfo<char> {
+ static inline char getEmptyKey() { return ~0; }
+ static inline char getTombstoneKey() { return ~0 - 1; }
+ static unsigned getHashValue(const char& Val) { return Val * 37; }
+ static bool isPod() { return true; }
+ static bool isEqual(const char &LHS, const char &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for unsigned ints.
+template<> struct DenseMapInfo<unsigned> {
+ static inline unsigned getEmptyKey() { return ~0; }
+ static inline unsigned getTombstoneKey() { return ~0 - 1; }
+ static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
+ static bool isPod() { return true; }
+ static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for unsigned longs.
+template<> struct DenseMapInfo<unsigned long> {
+ static inline unsigned long getEmptyKey() { return ~0L; }
+ static inline unsigned long getTombstoneKey() { return ~0L - 1L; }
+ static unsigned getHashValue(const unsigned long& Val) {
+ return (unsigned)(Val * 37L);
+ }
+ static bool isPod() { return true; }
+ static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for all pairs whose members have info.
+template<typename T, typename U>
+struct DenseMapInfo<std::pair<T, U> > {
+ typedef std::pair<T, U> Pair;
+ typedef DenseMapInfo<T> FirstInfo;
+ typedef DenseMapInfo<U> SecondInfo;
+
+ static inline Pair getEmptyKey() {
+ return std::make_pair(FirstInfo::getEmptyKey(),
+ SecondInfo::getEmptyKey());
+ }
+ static inline Pair getTombstoneKey() {
+ return std::make_pair(FirstInfo::getTombstoneKey(),
+ SecondInfo::getEmptyKey());
+ }
+ static unsigned getHashValue(const Pair& PairVal) {
+ uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
+ | (uint64_t)SecondInfo::getHashValue(PairVal.second);
+ key += ~(key << 32);
+ key ^= (key >> 22);
+ key += ~(key << 13);
+ key ^= (key >> 8);
+ key += (key << 3);
+ key ^= (key >> 15);
+ key += ~(key << 27);
+ key ^= (key >> 31);
+ return (unsigned)key;
+ }
+ static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; }
+ static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); }
+};
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMapIterator;
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMapConstIterator;
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMap {
+ typedef std::pair<KeyT, ValueT> BucketT;
+ unsigned NumBuckets;
+ BucketT *Buckets;
+
+ unsigned NumEntries;
+ unsigned NumTombstones;
+public:
+ typedef KeyT key_type;
+ typedef ValueT mapped_type;
+ typedef BucketT value_type;
+
+ DenseMap(const DenseMap& other) {
+ NumBuckets = 0;
+ CopyFrom(other);
+ }
+
+ explicit DenseMap(unsigned NumInitBuckets = 64) {
+ init(NumInitBuckets);
+ }
+
+ ~DenseMap() {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ operator delete(Buckets);
+ }
+
+ typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
+ typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator;
+ inline iterator begin() {
+ return iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline iterator end() {
+ return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+ inline const_iterator begin() const {
+ return const_iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline const_iterator end() const {
+ return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+
+ bool empty() const { return NumEntries == 0; }
+ unsigned size() const { return NumEntries; }
+
+ /// Grow the densemap so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) { grow(Size); }
+
+ void clear() {
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
+ shrink_and_clear();
+ return;
+ }
+
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
+ if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
+ P->second.~ValueT();
+ --NumEntries;
+ }
+ P->first = EmptyKey;
+ }
+ }
+ assert(NumEntries == 0 && "Node count imbalance!");
+ NumTombstones = 0;
+ }
+
+ /// count - Return true if the specified key is in the map.
+ bool count(const KeyT &Val) const {
+ BucketT *TheBucket;
+ return LookupBucketFor(Val, TheBucket);
+ }
+
+ iterator find(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+ const_iterator find(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return const_iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+
+ /// lookup - Return the entry for the specified key, or a default
+ /// constructed value if no such entry exists.
+ ValueT lookup(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return TheBucket->second;
+ return ValueT();
+ }
+
+ std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(KV.first, TheBucket))
+ return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
+ false); // Already in map.
+
+ // Otherwise, insert the new element.
+ TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
+ return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
+ true);
+ }
+
+ /// insert - Range insertion of pairs.
+ template<typename InputIt>
+ void insert(InputIt I, InputIt E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+
+ bool erase(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (!LookupBucketFor(Val, TheBucket))
+ return false; // not in map.
+
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+ bool erase(iterator I) {
+ BucketT *TheBucket = &*I;
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+
+ value_type& FindAndConstruct(const KeyT &Key) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Key, TheBucket))
+ return *TheBucket;
+
+ return *InsertIntoBucket(Key, ValueT(), TheBucket);
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ return FindAndConstruct(Key).second;
+ }
+
+ DenseMap& operator=(const DenseMap& other) {
+ CopyFrom(other);
+ return *this;
+ }
+
+ /// isPointerIntoBucketsArray - Return true if the specified pointer points
+ /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
+ /// value in the DenseMap).
+ bool isPointerIntoBucketsArray(const void *Ptr) const {
+ return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
+ }
+
+ /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+ /// array. In conjunction with the previous method, this can be used to
+ /// determine whether an insertion caused the DenseMap to reallocate.
+ const void *getPointerIntoBucketsArray() const { return Buckets; }
+
+private:
+ void CopyFrom(const DenseMap& other) {
+ if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ }
+
+ NumEntries = other.NumEntries;
+ NumTombstones = other.NumTombstones;
+
+ if (NumBuckets)
+ operator delete(Buckets);
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
+ other.NumBuckets));
+
+ if (KeyInfoT::isPod() && ValueInfoT::isPod())
+ memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
+ else
+ for (size_t i = 0; i < other.NumBuckets; ++i) {
+ new (&Buckets[i].first) KeyT(other.Buckets[i].first);
+ if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
+ !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
+ new (&Buckets[i].second) ValueT(other.Buckets[i].second);
+ }
+ NumBuckets = other.NumBuckets;
+ }
+
+ BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+ BucketT *TheBucket) {
+ // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ //
+ // The later case is tricky. For example, if we had one empty bucket with
+ // tons of tombstones, failing lookups (e.g. for insertion) would have to
+ // probe almost the entire table until it found the empty bucket. If the
+ // table completely filled with tombstones, no lookup would ever succeed,
+ // causing infinite loops in lookup.
+ ++NumEntries;
+ if (NumEntries*4 >= NumBuckets*3 ||
+ NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+ this->grow(NumBuckets * 2);
+ LookupBucketFor(Key, TheBucket);
+ }
+
+ // If we are writing over a tombstone, remember this.
+ if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
+ --NumTombstones;
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(Value);
+ return TheBucket;
+ }
+
+ static unsigned getHashValue(const KeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ static const KeyT getEmptyKey() {
+ return KeyInfoT::getEmptyKey();
+ }
+ static const KeyT getTombstoneKey() {
+ return KeyInfoT::getTombstoneKey();
+ }
+
+ /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+ /// 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
+ /// returns false.
+ bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
+ unsigned BucketNo = getHashValue(Val);
+ unsigned ProbeAmt = 1;
+ BucketT *BucketsPtr = Buckets;
+
+ // FoundTombstone - Keep track of whether we find a tombstone while probing.
+ BucketT *FoundTombstone = 0;
+ const KeyT EmptyKey = getEmptyKey();
+ const KeyT TombstoneKey = getTombstoneKey();
+ assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
+ !KeyInfoT::isEqual(Val, TombstoneKey) &&
+ "Empty/Tombstone value shouldn't be inserted into map!");
+
+ while (1) {
+ BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+ // Found Val's bucket? If so, return it.
+ if (KeyInfoT::isEqual(ThisBucket->first, Val)) {
+ FoundBucket = ThisBucket;
+ return true;
+ }
+
+ // If we found an empty bucket, the key doesn't exist in the set.
+ // Insert it and return the default value.
+ if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
+ // If we've already seen a tombstone while probing, fill it in instead
+ // of the empty bucket we eventually probed to.
+ if (FoundTombstone) ThisBucket = FoundTombstone;
+ FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+ return false;
+ }
+
+ // 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.
+ if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
+ FoundTombstone = ThisBucket; // Remember the first tombstone found.
+
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
+ // probing.
+ BucketNo += ProbeAmt++;
+ }
+ }
+
+ void init(unsigned InitBuckets) {
+ NumEntries = 0;
+ NumTombstones = 0;
+ NumBuckets = InitBuckets;
+ assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
+ "# initial buckets must be a power of two!");
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0; i != InitBuckets; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+ }
+
+ void grow(unsigned AtLeast) {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Double the number of buckets.
+ while (NumBuckets <= AtLeast)
+ NumBuckets <<= 1;
+ NumTombstones = 0;
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Insert all the old elements.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Insert the key/value into the new table.
+ BucketT *DestBucket;
+ bool FoundVal = LookupBucketFor(B->first, DestBucket);
+ FoundVal = FoundVal; // silence warning.
+ assert(!FoundVal && "Key already in new map?");
+ DestBucket->first = B->first;
+ new (&DestBucket->second) ValueT(B->second);
+
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+ // Free the old table.
+ operator delete(OldBuckets);
+ }
+
+ void shrink_and_clear() {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Reduce the number of buckets.
+ NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
+ : 64;
+ NumTombstones = 0;
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Free the old buckets.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+ // Free the old table.
+ operator delete(OldBuckets);
+
+ NumEntries = 0;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
+class DenseMapIterator {
+ typedef std::pair<KeyT, ValueT> BucketT;
+protected:
+ const BucketT *Ptr, *End;
+public:
+ DenseMapIterator(void) : Ptr(0), End(0) {}
+
+ DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
+ AdvancePastEmptyBuckets();
+ }
+
+ std::pair<KeyT, ValueT> &operator*() const {
+ return *const_cast<BucketT*>(Ptr);
+ }
+ std::pair<KeyT, ValueT> *operator->() const {
+ return const_cast<BucketT*>(Ptr);
+ }
+
+ bool operator==(const DenseMapIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const DenseMapIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline DenseMapIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ DenseMapIterator operator++(int) { // Postincrement
+ DenseMapIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ const KeyT Empty = KeyInfoT::getEmptyKey();
+ const KeyT Tombstone = KeyInfoT::getTombstoneKey();
+
+ while (Ptr != End &&
+ (KeyInfoT::isEqual(Ptr->first, Empty) ||
+ KeyInfoT::isEqual(Ptr->first, Tombstone)))
+ ++Ptr;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
+class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> {
+public:
+ DenseMapConstIterator(void) : DenseMapIterator<KeyT, ValueT, KeyInfoT>() {}
+ DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos,
+ const std::pair<KeyT, ValueT> *E)
+ : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) {
+ }
+ const std::pair<KeyT, ValueT> &operator*() const {
+ return *this->Ptr;
+ }
+ const std::pair<KeyT, ValueT> *operator->() const {
+ return this->Ptr;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
new file mode 100644
index 0000000000000..ce7344bc1f99b
--- /dev/null
+++ b/include/llvm/ADT/DenseSet.h
@@ -0,0 +1,104 @@
+//===- llvm/ADT/DenseSet.h - Dense probed hash table ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DenseSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSESET_H
+#define LLVM_ADT_DENSESET_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+/// DenseSet - This implements a dense probed hash-table based set.
+///
+/// FIXME: This is currently implemented directly in terms of DenseMap, this
+/// should be optimized later if there is a need.
+template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseSet {
+ typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
+ MapTy TheMap;
+public:
+ DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
+ explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
+
+ bool empty() const { return TheMap.empty(); }
+ unsigned size() const { return TheMap.size(); }
+
+ void clear() {
+ TheMap.clear();
+ }
+
+ bool count(const ValueT &V) const {
+ return TheMap.count(V);
+ }
+
+ void erase(const ValueT &V) {
+ TheMap.erase(V);
+ }
+
+ DenseSet &operator=(const DenseSet &RHS) {
+ TheMap = RHS.TheMap;
+ return *this;
+ }
+
+ // Iterators.
+
+ class Iterator {
+ typename MapTy::iterator I;
+ public:
+ Iterator(const typename MapTy::iterator &i) : I(i) {}
+
+ ValueT& operator*() { return I->first; }
+ ValueT* operator->() { return &I->first; }
+
+ 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; }
+ };
+
+ class ConstIterator {
+ typename MapTy::const_iterator I;
+ public:
+ ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
+
+ const ValueT& operator*() { return I->first; }
+ const ValueT* operator->() { return &I->first; }
+
+ 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; }
+ };
+
+ typedef Iterator iterator;
+ typedef ConstIterator const_iterator;
+
+ iterator begin() { return Iterator(TheMap.begin()); }
+ iterator end() { return Iterator(TheMap.end()); }
+
+ const_iterator begin() const { return ConstIterator(TheMap.begin()); }
+ const_iterator end() const { return ConstIterator(TheMap.end()); }
+
+ std::pair<iterator, bool> insert(const ValueT &V) {
+ return TheMap.insert(std::make_pair(V, 0));
+ }
+
+ // Range insertion of values.
+ template<typename InputIt>
+ void insert(InputIt I, InputIt E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
new file mode 100644
index 0000000000000..517768f402df9
--- /dev/null
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -0,0 +1,232 @@
+//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build generic depth
+// first graph iterator. This file exposes the following functions/types:
+//
+// df_begin/df_end/df_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+//
+// idf_begin/idf_end/idf_iterator
+// * Depth-first iteration on the 'inverse' graph.
+//
+// df_ext_begin/df_ext_end/df_ext_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+// idf_ext_begin/idf_ext_end/idf_ext_iterator
+// * Depth-first iteration on the 'inverse' graph.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
+#define LLVM_ADT_DEPTHFIRSTITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// df_iterator_storage - A private class which is used to figure out where to
+// store the visited set.
+template<class SetType, bool External> // Non-external set
+class df_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class df_iterator_storage<SetType, true> {
+public:
+ df_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+
+// Generic Depth First Iterator
+template<class GraphT,
+class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false, class GT = GraphTraits<GraphT> >
+class df_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public df_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is node pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+private:
+ inline df_iterator(NodeType *Node) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ inline df_iterator() { /* End is when stack is empty */ }
+
+ inline df_iterator(NodeType *Node, SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ if (!S.count(Node)) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ }
+ inline df_iterator(SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ // End is when stack is empty
+ }
+
+public:
+ typedef typename super::pointer pointer;
+ typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static begin and end methods as our public "constructors"
+ static inline _Self begin(const GraphT& G) {
+ return _Self(GT::getEntryNode(G));
+ }
+ static inline _Self end(const GraphT& G) { return _Self(); }
+
+ // Static begin and end methods as our public ctors for external iterators
+ static inline _Self begin(const GraphT& G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack.size() == x.VisitStack.size() &&
+ VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.back().first;
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the Node, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ do {
+ std::pair<NodeType *, ChildItTy> &Top = VisitStack.back();
+ NodeType *Node = Top.first;
+ ChildItTy &It = Top.second;
+
+ while (It != GT::child_end(Node)) {
+ NodeType *Next = *It++;
+ if (!this->Visited.count(Next)) { // Has our next sibling been visited?
+ // No, do it now.
+ this->Visited.insert(Next);
+ VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
+ return *this;
+ }
+ }
+
+ // Oops, ran out of successors... go up a level on the stack.
+ VisitStack.pop_back();
+ } while (!VisitStack.empty());
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // nodeVisited - return true if this iterator has already visited the
+ // specified node. This is public, and will probably be used to iterate over
+ // nodes that a depth first iteration did not find: ie unreachable nodes.
+ //
+ inline bool nodeVisited(NodeType *Node) const {
+ return this->Visited.count(Node) != 0;
+ }
+};
+
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+df_iterator<T> df_begin(const T& G) {
+ return df_iterator<T>::begin(G);
+}
+
+template <class T>
+df_iterator<T> df_end(const T& G) {
+ return df_iterator<T>::end(G);
+}
+
+// Provide global definitions of external depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct df_ext_iterator : public df_iterator<T, SetTy, true> {
+ df_ext_iterator(const df_iterator<T, SetTy, true> &V)
+ : df_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_begin(const T& G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::end(G, S);
+}
+
+
+// Provide global definitions of inverse depth first iterators...
+template <class T,
+ class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
+ bool External = false>
+struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
+ idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
+ : df_iterator<Inverse<T>, SetTy, External>(V) {}
+};
+
+template <class T>
+idf_iterator<T> idf_begin(const T& G) {
+ return idf_iterator<T>::begin(Inverse<T>(G));
+}
+
+template <class T>
+idf_iterator<T> idf_end(const T& G){
+ return idf_iterator<T>::end(Inverse<T>(G));
+}
+
+// Provide global definitions of external inverse depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
+ idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+ idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_begin(const T& G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::begin(Inverse<T>(G), S);
+}
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::end(Inverse<T>(G), S);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
new file mode 100644
index 0000000000000..6e00a217bebfe
--- /dev/null
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -0,0 +1,279 @@
+//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic implementation of equivalence classes through the use Tarjan's
+// efficient union-find algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
+#define LLVM_ADT_EQUIVALENCECLASSES_H
+
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/DataTypes.h"
+#include <set>
+
+namespace llvm {
+
+/// EquivalenceClasses - This represents a collection of equivalence classes and
+/// supports three efficient operations: insert an element into a class of its
+/// own, union two classes, and find the class for a given element. In
+/// addition to these modification methods, it is possible to iterate over all
+/// of the equivalence classes and all of the elements in a class.
+///
+/// This implementation is an efficient implementation that only stores one copy
+/// of the element being indexed per entry in the set, and allows any arbitrary
+/// type to be indexed (as long as it can be ordered with operator<).
+///
+/// Here is a simple example using integers:
+///
+/// EquivalenceClasses<int> EC;
+/// EC.unionSets(1, 2); // insert 1, 2 into the same set
+/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
+/// EC.unionSets(5, 1); // merge the set for 1 with 5's set.
+///
+/// for (EquivalenceClasses<int>::iterator I = EC.begin(), E = EC.end();
+/// I != E; ++I) { // Iterate over all of the equivalence sets.
+/// if (!I->isLeader()) continue; // Ignore non-leader sets.
+/// for (EquivalenceClasses<int>::member_iterator MI = EC.member_begin(I);
+/// MI != EC.member_end(); ++MI) // Loop over members in this set.
+/// cerr << *MI << " "; // Print member.
+/// cerr << "\n"; // Finish set.
+/// }
+///
+/// This example prints:
+/// 4
+/// 5 1 2
+///
+template <class ElemTy>
+class EquivalenceClasses {
+ /// ECValue - The EquivalenceClasses data structure is just a set of these.
+ /// Each of these represents a relation for a value. First it stores the
+ /// value itself, which provides the ordering that the set queries. Next, it
+ /// provides a "next pointer", which is used to enumerate all of the elements
+ /// in the unioned set. Finally, it defines either a "end of list pointer" or
+ /// "leader pointer" depending on whether the value itself is a leader. A
+ /// "leader pointer" points to the node that is the leader for this element,
+ /// if the node is not a leader. A "end of list pointer" points to the last
+ /// node in the list of members of this list. Whether or not a node is a
+ /// leader is determined by a bit stolen from one of the pointers.
+ class ECValue {
+ friend class EquivalenceClasses;
+ mutable const ECValue *Leader, *Next;
+ ElemTy Data;
+ // ECValue ctor - Start out with EndOfList pointing to this node, Next is
+ // Null, isLeader = true.
+ ECValue(const ElemTy &Elt)
+ : Leader(this), Next((ECValue*)(intptr_t)1), Data(Elt) {}
+
+ const ECValue *getLeader() const {
+ if (isLeader()) return this;
+ if (Leader->isLeader()) return Leader;
+ // Path compression.
+ return Leader = Leader->getLeader();
+ }
+ const ECValue *getEndOfList() const {
+ assert(isLeader() && "Cannot get the end of a list for a non-leader!");
+ return Leader;
+ }
+
+ void setNext(const ECValue *NewNext) const {
+ assert(getNext() == 0 && "Already has a next pointer!");
+ Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader());
+ }
+ public:
+ ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1),
+ Data(RHS.Data) {
+ // Only support copying of singleton nodes.
+ assert(RHS.isLeader() && RHS.getNext() == 0 && "Not a singleton!");
+ }
+
+ bool operator<(const ECValue &UFN) const { return Data < UFN.Data; }
+
+ bool isLeader() const { return (intptr_t)Next & 1; }
+ const ElemTy &getData() const { return Data; }
+
+ const ECValue *getNext() const {
+ return (ECValue*)((intptr_t)Next & ~(intptr_t)1);
+ }
+
+ template<typename T>
+ bool operator<(const T &Val) const { return Data < Val; }
+ };
+
+ /// TheMapping - This implicitly provides a mapping from ElemTy values to the
+ /// ECValues, it just keeps the key as part of the value.
+ std::set<ECValue> TheMapping;
+
+public:
+ EquivalenceClasses() {}
+ EquivalenceClasses(const EquivalenceClasses &RHS) {
+ operator=(RHS);
+ }
+
+ const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) {
+ TheMapping.clear();
+ for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
+ if (I->isLeader()) {
+ member_iterator MI = RHS.member_begin(I);
+ member_iterator LeaderIt = member_begin(insert(*MI));
+ for (++MI; MI != member_end(); ++MI)
+ unionSets(LeaderIt, member_begin(insert(*MI)));
+ }
+ return *this;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inspection methods
+ //
+
+ /// iterator* - Provides a way to iterate over all values in the set.
+ typedef typename std::set<ECValue>::const_iterator iterator;
+ iterator begin() const { return TheMapping.begin(); }
+ iterator end() const { return TheMapping.end(); }
+
+ bool empty() const { return TheMapping.empty(); }
+
+ /// member_* Iterate over the members of an equivalence class.
+ ///
+ class member_iterator;
+ member_iterator member_begin(iterator I) const {
+ // Only leaders provide anything to iterate over.
+ return member_iterator(I->isLeader() ? &*I : 0);
+ }
+ member_iterator member_end() const {
+ return member_iterator(0);
+ }
+
+ /// findValue - Return an iterator to the specified value. If it does not
+ /// exist, end() is returned.
+ iterator findValue(const ElemTy &V) const {
+ return TheMapping.find(V);
+ }
+
+ /// getLeaderValue - Return the leader for the specified value that is in the
+ /// set. It is an error to call this method for a value that is not yet in
+ /// the set. For that, call getOrInsertLeaderValue(V).
+ const ElemTy &getLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(V);
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getOrInsertLeaderValue - Return the leader for the specified value that is
+ /// in the set. If the member is not in the set, it is inserted, then
+ /// returned.
+ const ElemTy &getOrInsertLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(insert(V));
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getNumClasses - Return the number of equivalence classes in this set.
+ /// Note that this is a linear time operation.
+ unsigned getNumClasses() const {
+ unsigned NC = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (I->isLeader()) ++NC;
+ return NC;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Mutation methods
+
+ /// insert - Insert a new value into the union/find set, ignoring the request
+ /// if the value already exists.
+ iterator insert(const ElemTy &Data) {
+ return TheMapping.insert(Data).first;
+ }
+
+ /// findLeader - Given a value in the set, return a member iterator for the
+ /// equivalence class it is in. This does the path-compression part that
+ /// makes union-find "union findy". This returns an end iterator if the value
+ /// is not in the equivalence class.
+ ///
+ member_iterator findLeader(iterator I) const {
+ if (I == TheMapping.end()) return member_end();
+ return member_iterator(I->getLeader());
+ }
+ member_iterator findLeader(const ElemTy &V) const {
+ return findLeader(TheMapping.find(V));
+ }
+
+
+ /// union - Merge the two equivalence sets for the specified values, inserting
+ /// them if they do not already exist in the equivalence set.
+ member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) {
+ iterator V1I = insert(V1), V2I = insert(V2);
+ return unionSets(findLeader(V1I), findLeader(V2I));
+ }
+ member_iterator unionSets(member_iterator L1, member_iterator L2) {
+ assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!");
+ if (L1 == L2) return L1; // Unifying the same two sets, noop.
+
+ // Otherwise, this is a real union operation. Set the end of the L1 list to
+ // point to the L2 leader node.
+ const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node;
+ L1LV.getEndOfList()->setNext(&L2LV);
+
+ // Update L1LV's end of list pointer.
+ L1LV.Leader = L2LV.getEndOfList();
+
+ // Clear L2's leader flag:
+ L2LV.Next = L2LV.getNext();
+
+ // L2's leader is now L1.
+ L2LV.Leader = &L1LV;
+ return L1;
+ }
+
+ class member_iterator : public forward_iterator<ElemTy, ptrdiff_t> {
+ typedef forward_iterator<const ElemTy, ptrdiff_t> super;
+ const ECValue *Node;
+ friend class EquivalenceClasses;
+ public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ explicit member_iterator() {}
+ explicit member_iterator(const ECValue *N) : Node(N) {}
+ member_iterator(const member_iterator &I) : Node(I.Node) {}
+
+ reference operator*() const {
+ assert(Node != 0 && "Dereferencing end()!");
+ return Node->getData();
+ }
+ reference operator->() const { return operator*(); }
+
+ member_iterator &operator++() {
+ assert(Node != 0 && "++'d off the end of the list!");
+ Node = Node->getNext();
+ return *this;
+ }
+
+ member_iterator operator++(int) { // postincrement operators.
+ member_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const member_iterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const member_iterator &RHS) const {
+ return Node != RHS.Node;
+ }
+ };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 0000000000000..e31e112d0e61e
--- /dev/null
+++ b/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,461 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a hash set that can be used to remove duplication of nodes
+// in a graph. This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FOLDINGSET_H
+#define LLVM_ADT_FOLDINGSET_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+#include <iterator>
+
+namespace llvm {
+ class APFloat;
+ class APInt;
+
+/// This folding set used for two purposes:
+/// 1. Given information about a node we want to create, look up the unique
+/// instance of the node in the set. If the node already exists, return
+/// it, otherwise return the bucket it should be inserted into.
+/// 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
+/// "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.
+///
+/// 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
+/// 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
+/// 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
+/// responsibility of the user to dispose of the nodes.
+///
+/// Eg.
+/// class MyNode : public FoldingSetNode {
+/// private:
+/// std::string Name;
+/// unsigned Value;
+/// public:
+/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+/// ...
+/// void Profile(FoldingSetNodeID &ID) {
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// }
+/// ...
+/// };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+/// FoldingSet<MyNode> MyFoldingSet;
+///
+/// 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
+/// that the node might already exist then call;
+///
+/// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+/// FoldingSetNodeID ID;
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// void *InsertPoint;
+///
+/// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
+/// node with FindNodeOrInsertPos;
+///
+/// InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+/// bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node existed in the folding set.
+
+class FoldingSetNodeID;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality. The main
+/// 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
+/// in the bucket via a singly linked list. The last node in the list points
+/// back to the bucket to facilitate node removal.
+///
+class FoldingSetImpl {
+protected:
+ /// Buckets - Array of bucket chains.
+ ///
+ void **Buckets;
+
+ /// NumBuckets - Length of the Buckets array. Always a power of 2.
+ ///
+ unsigned NumBuckets;
+
+ /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
+ /// is greater than twice the number of buckets.
+ unsigned NumNodes;
+
+public:
+ explicit FoldingSetImpl(unsigned Log2InitSize = 6);
+ virtual ~FoldingSetImpl();
+
+ //===--------------------------------------------------------------------===//
+ /// Node - This class is used to maintain the singly linked bucket list in
+ /// a folding set.
+ ///
+ class Node {
+ private:
+ // NextInFoldingSetBucket - next link in the bucket list.
+ void *NextInFoldingSetBucket;
+
+ public:
+
+ Node() : NextInFoldingSetBucket(0) {}
+
+ // Accessors
+ void *getNextInBucket() const { return NextInFoldingSetBucket; }
+ void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
+ };
+
+ /// clear - Remove all nodes from the folding set.
+ void clear();
+
+ /// 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.
+ bool RemoveNode(Node *N);
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and return
+ /// it instead.
+ Node *GetOrInsertNode(Node *N);
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set. InsertPos must be obtained from
+ /// FindNodeOrInsertPos.
+ void InsertNode(Node *N, void *InsertPos);
+
+ /// size - Returns the number of nodes in the folding set.
+ unsigned size() const { return NumNodes; }
+
+ /// empty - Returns true if there are no nodes in the folding set.
+ bool empty() const { return NumNodes == 0; }
+
+private:
+
+ /// GrowHashTable - Double the size of the hash table and rehash everything.
+ ///
+ void GrowHashTable();
+
+protected:
+
+ /// GetNodeProfile - Instantiations of the FoldingSet template implement
+ /// this function to gather data bits for the given node.
+ virtual void GetNodeProfile(FoldingSetNodeID &ID, Node *N) const = 0;
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetTrait - This trait class is used to define behavior of how
+/// to "profile" (in the FoldingSet parlance) an object of a given type.
+/// The default behavior is to invoke a 'Profile' method on an object, but
+/// through template specialization the behavior can be tailored for specific
+/// types. Combined with the FoldingSetNodeWrapper classs, one can add objects
+/// to FoldingSets that were not originally designed to have that behavior.
+///
+template<typename T> struct FoldingSetTrait {
+ static inline void Profile(const 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
+/// a node. When all the bits are gathered this class is used to produce a
+/// hash value for the node.
+///
+class FoldingSetNodeID {
+ /// Bits - Vector of all the data bits that make the node unique.
+ /// Use a SmallVector to avoid a heap allocation in the common case.
+ SmallVector<unsigned, 32> Bits;
+
+public:
+ FoldingSetNodeID() {}
+
+ /// getRawData - Return the ith entry in the Bits data.
+ ///
+ unsigned getRawData(unsigned i) const {
+ return Bits[i];
+ }
+
+ /// Add* - Add various data types to Bit data.
+ ///
+ void AddPointer(const void *Ptr);
+ void AddInteger(signed I);
+ void AddInteger(unsigned I);
+ void AddInteger(long I);
+ void AddInteger(unsigned long I);
+ void AddInteger(long long I);
+ void AddInteger(unsigned long long I);
+ void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
+ void AddString(const char* String, const char* End);
+ void AddString(const std::string &String);
+ void AddString(const char* String);
+
+ template <typename T>
+ inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); }
+
+ /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
+ /// object to be used to compute a new profile.
+ inline void clear() { Bits.clear(); }
+
+ /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
+ /// to lookup the node in the FoldingSetImpl.
+ unsigned ComputeHash() const;
+
+ /// operator== - Used to compare two nodes to each other.
+ ///
+ bool operator==(const FoldingSetNodeID &RHS) const;
+};
+
+// Convenience type to hide the implementation of the folding set.
+typedef FoldingSetImpl::Node FoldingSetNode;
+template<class T> class FoldingSetIterator;
+template<class T> class FoldingSetBucketIterator;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSet - This template class is used to instantiate a specialized
+/// implementation of the folding set to the node class T. T must be a
+/// subclass of FoldingSetNode and implement a Profile function.
+///
+template<class T> class FoldingSet : public FoldingSetImpl {
+private:
+ /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// way to convert nodes into a unique specifier.
+ virtual void GetNodeProfile(FoldingSetNodeID &ID, Node *N) const {
+ T *TN = static_cast<T *>(N);
+ FoldingSetTrait<T>::Profile(*TN,ID);
+ }
+
+public:
+ explicit FoldingSet(unsigned Log2InitSize = 6)
+ : FoldingSetImpl(Log2InitSize)
+ {}
+
+ typedef FoldingSetIterator<T> iterator;
+ iterator begin() { return iterator(Buckets); }
+ iterator end() { return iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetIterator<const T> const_iterator;
+ const_iterator begin() const { return const_iterator(Buckets); }
+ const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+ bucket_iterator bucket_begin(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+ }
+
+ bucket_iterator bucket_end(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+ }
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and
+ /// return it instead.
+ T *GetOrInsertNode(Node *N) {
+ return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+ }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetIteratorImpl - This is the common iterator support shared by all
+/// folding sets, which knows how to walk the folding set hash table.
+class FoldingSetIteratorImpl {
+protected:
+ FoldingSetNode *NodePtr;
+ FoldingSetIteratorImpl(void **Bucket);
+ void advance();
+
+public:
+ bool operator==(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+};
+
+
+template<class T>
+class FoldingSetIterator : public FoldingSetIteratorImpl {
+public:
+ explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
+
+ T &operator*() const {
+ return *static_cast<T*>(NodePtr);
+ }
+
+ T *operator->() const {
+ return static_cast<T*>(NodePtr);
+ }
+
+ inline FoldingSetIterator& operator++() { // Preincrement
+ advance();
+ return *this;
+ }
+ FoldingSetIterator operator++(int) { // Postincrement
+ FoldingSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
+/// shared by all folding sets, which knows how to walk a particular bucket
+/// of a folding set hash table.
+
+class FoldingSetBucketIteratorImpl {
+protected:
+ void *Ptr;
+
+ explicit FoldingSetBucketIteratorImpl(void **Bucket);
+
+ FoldingSetBucketIteratorImpl(void **Bucket, bool)
+ : Ptr(Bucket) {}
+
+ void advance() {
+ void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
+ uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
+ Ptr = reinterpret_cast<void*>(x);
+ }
+
+public:
+ bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+};
+
+
+template<class T>
+class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
+public:
+ explicit FoldingSetBucketIterator(void **Bucket) :
+ FoldingSetBucketIteratorImpl(Bucket) {}
+
+ FoldingSetBucketIterator(void **Bucket, bool) :
+ FoldingSetBucketIteratorImpl(Bucket, true) {}
+
+ T& operator*() const { return *static_cast<T*>(Ptr); }
+ T* operator->() const { return static_cast<T*>(Ptr); }
+
+ inline FoldingSetBucketIterator& operator++() { // Preincrement
+ advance();
+ return *this;
+ }
+ FoldingSetBucketIterator operator++(int) { // Postincrement
+ FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
+/// types in an enclosing object so that they can be inserted into FoldingSets.
+template <typename T>
+class FoldingSetNodeWrapper : public FoldingSetNode {
+ T data;
+public:
+ explicit FoldingSetNodeWrapper(const T& x) : data(x) {}
+ virtual ~FoldingSetNodeWrapper() {}
+
+ template<typename A1>
+ explicit FoldingSetNodeWrapper(const A1& a1)
+ : data(a1) {}
+
+ template <typename A1, typename A2>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2)
+ : data(a1,a2) {}
+
+ template <typename A1, typename A2, typename A3>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3)
+ : data(a1,a2,a3) {}
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4)
+ : data(a1,a2,a3,a4) {}
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4, const A5& a5)
+ : data(a1,a2,a3,a4,a5) {}
+
+
+ void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); }
+
+ T& getValue() { return data; }
+ const T& getValue() const { return data; }
+
+ operator T&() { return data; }
+ operator const T&() const { return data; }
+};
+
+//===----------------------------------------------------------------------===//
+// Partial specializations of FoldingSetTrait.
+
+template<typename T> struct FoldingSetTrait<T*> {
+ static inline void Profile(const T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+ static inline void Profile(T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+};
+
+template<typename T> struct FoldingSetTrait<const T*> {
+ static inline void Profile(const T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+};
+
+} // End of namespace llvm.
+
+#endif
diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h
new file mode 100644
index 0000000000000..2d103cf83eb83
--- /dev/null
+++ b/include/llvm/ADT/GraphTraits.h
@@ -0,0 +1,103 @@
+//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the little GraphTraits<X> template class that should be
+// specialized by classes that want to be iteratable by generic graph iterators.
+//
+// This file also defines the marker class Inverse that is used to iterate over
+// graphs in a graph defined, inverse ordering...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_GRAPHTRAITS_H
+#define LLVM_ADT_GRAPHTRAITS_H
+
+namespace llvm {
+
+// GraphTraits - This class should be specialized by different graph types...
+// which is why the default version is empty.
+//
+template<class GraphType>
+struct GraphTraits {
+ // Elements to provide:
+
+ // typedef NodeType - Type of Node in the graph
+ // typedef ChildIteratorType - Type used to iterate over children in graph
+
+ // static NodeType *getEntryNode(GraphType *)
+ // Return the entry node of the graph
+
+ // static ChildIteratorType child_begin(NodeType *)
+ // static ChildIteratorType child_end (NodeType *)
+ // Return iterators that point to the beginning and ending of the child
+ // node list for the specified node.
+ //
+
+
+ // typedef ...iterator nodes_iterator;
+ // static nodes_iterator nodes_begin(GraphType *G)
+ // static nodes_iterator nodes_end (GraphType *G)
+ //
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+
+
+ // If anyone tries to use this class without having an appropriate
+ // specialization, make an error. If you get this error, it's because you
+ // need to include the appropriate specialization of GraphTraits<> for your
+ // graph, or you need to define it for a new graph type. Either that or
+ // your argument to XXX_begin(...) is unknown or needs to have the proper .h
+ // file #include'd.
+ //
+ typedef typename GraphType::UnknownGraphTypeError NodeType;
+};
+
+
+// Inverse - This class is used as a little marker class to tell the graph
+// iterator to iterate over the graph in a graph defined "Inverse" ordering.
+// Not all graphs define an inverse ordering, and if they do, it depends on
+// the graph exactly what that is. Here's an example of usage with the
+// df_iterator:
+//
+// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+// Which is equivalent to:
+// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+template <class GraphType>
+struct Inverse {
+ const GraphType &Graph;
+
+ inline Inverse(const GraphType &G) : Graph(G) {}
+};
+
+// Provide a partial specialization of GraphTraits so that the inverse of an
+// inverse falls back to the original graph.
+template<class T>
+struct GraphTraits<Inverse<Inverse<T> > > {
+ typedef typename GraphTraits<T>::NodeType NodeType;
+ typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
+ return GraphTraits<T>::getEntryNode(G->Graph.Graph);
+ }
+
+ static ChildIteratorType child_begin(NodeType* N) {
+ return GraphTraits<T>::child_begin(N);
+ }
+
+ static ChildIteratorType child_end(NodeType* N) {
+ return GraphTraits<T>::child_end(N);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/HashExtras.h b/include/llvm/ADT/HashExtras.h
new file mode 100644
index 0000000000000..20c4fd3058a28
--- /dev/null
+++ b/include/llvm/ADT/HashExtras.h
@@ -0,0 +1,40 @@
+//===-- llvm/ADT/HashExtras.h - Useful functions for STL hash ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL Hashed containers.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASHEXTRAS_H
+#define LLVM_ADT_HASHEXTRAS_H
+
+#include <string>
+
+// Cannot specialize hash template from outside of the std namespace.
+namespace HASH_NAMESPACE {
+
+// Provide a hash function for arbitrary pointers...
+template <class T> struct hash<T *> {
+ inline size_t operator()(const T *Val) const {
+ return reinterpret_cast<size_t>(Val);
+ }
+};
+
+template <> struct hash<std::string> {
+ size_t operator()(std::string const &str) const {
+ return hash<char const *>()(str.c_str());
+ }
+};
+
+} // End namespace std
+
+#endif
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
new file mode 100644
index 0000000000000..a7f5819fa510b
--- /dev/null
+++ b/include/llvm/ADT/ImmutableList.h
@@ -0,0 +1,219 @@
+//==--- ImmutableList.h - Immutable (functional) list interface --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableList class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMLIST_H
+#define LLVM_ADT_IMLIST_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+template <typename T> class ImmutableListFactory;
+
+template <typename T>
+class ImmutableListImpl : public FoldingSetNode {
+ T Head;
+ const ImmutableListImpl* Tail;
+
+ ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0)
+ : Head(head), Tail(tail) {}
+
+ friend class ImmutableListFactory<T>;
+
+ // Do not implement.
+ void operator=(const ImmutableListImpl&);
+ ImmutableListImpl(const ImmutableListImpl&);
+
+public:
+ const T& getHead() const { return Head; }
+ const ImmutableListImpl* getTail() const { return Tail; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const T& H,
+ const ImmutableListImpl* L){
+ ID.AddPointer(L);
+ ID.Add(H);
+ }
+
+ void Profile(FoldingSetNodeID& ID) {
+ Profile(ID, Head, Tail);
+ }
+};
+
+/// ImmutableList - This class represents an immutable (functional) list.
+/// 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.
+/// This interface matches ImmutableSet and ImmutableMap. ImmutableList
+/// objects should almost never be created directly, and instead should
+/// be created by ImmutableListFactory objects that manage the lifetime
+/// of a group of lists. When the factory object is reclaimed, all lists
+/// created by that factory are released as well.
+template <typename T>
+class ImmutableList {
+public:
+ typedef T value_type;
+ typedef ImmutableListFactory<T> Factory;
+
+private:
+ const ImmutableListImpl<T>* X;
+
+public:
+ // This constructor should normally only be called by ImmutableListFactory<T>.
+ // There may be cases, however, when one needs to extract the internal pointer
+ // and reconstruct a list object from that pointer.
+ ImmutableList(const ImmutableListImpl<T>* x = 0) : X(x) {}
+
+ const ImmutableListImpl<T>* getInternalPointer() const {
+ return X;
+ }
+
+ class iterator {
+ const ImmutableListImpl<T>* L;
+ public:
+ iterator() : L(0) {}
+ iterator(ImmutableList l) : L(l.getInternalPointer()) {}
+
+ 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; }
+ const value_type& operator*() const { return L->getHead(); }
+ ImmutableList getList() const { return L; }
+ };
+
+ /// 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.
+ iterator begin() const { return iterator(X); }
+
+ /// end - Returns an iterator denoting the end of the list. This iterator
+ /// does not refer to a valid list element.
+ iterator end() const { return iterator(); }
+
+ /// isEmpty - Returns true if the list is empty.
+ bool isEmpty() const { return !X; }
+
+ /// isEqual - Returns true if two lists are equal. Because all lists created
+ /// 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
+ /// that you should only compare two lists created from the same
+ /// ImmutableListFactory.
+ bool isEqual(const ImmutableList& L) const { return X == L.X; }
+
+ bool operator==(const ImmutableList& L) const { return isEqual(L); }
+
+ /// getHead - Returns the head of the list.
+ const T& getHead() {
+ assert (!isEmpty() && "Cannot get the head of an empty list.");
+ return X->getHead();
+ }
+
+ /// getTail - Returns the tail of the list, which is another (possibly empty)
+ /// ImmutableList.
+ ImmutableList getTail() {
+ return X ? X->getTail() : 0;
+ }
+
+ void Profile(FoldingSetNodeID& ID) const {
+ ID.AddPointer(X);
+ }
+};
+
+template <typename T>
+class ImmutableListFactory {
+ typedef ImmutableListImpl<T> ListTy;
+ typedef FoldingSet<ListTy> CacheTy;
+
+ CacheTy Cache;
+ uintptr_t Allocator;
+
+ bool ownsAllocator() const {
+ return Allocator & 0x1 ? false : true;
+ }
+
+ BumpPtrAllocator& getAllocator() const {
+ return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+ }
+
+public:
+ ImmutableListFactory()
+ : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+ ImmutableListFactory(BumpPtrAllocator& Alloc)
+ : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+ ~ImmutableListFactory() {
+ if (ownsAllocator()) delete &getAllocator();
+ }
+
+ ImmutableList<T> Concat(const T& Head, ImmutableList<T> Tail) {
+ // Profile the new list to see if it already exists in our cache.
+ FoldingSetNodeID ID;
+ void* InsertPos;
+
+ const ListTy* TailImpl = Tail.getInternalPointer();
+ ListTy::Profile(ID, Head, TailImpl);
+ ListTy* L = Cache.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!L) {
+ // The list does not exist in our cache. Create it.
+ BumpPtrAllocator& A = getAllocator();
+ L = (ListTy*) A.Allocate<ListTy>();
+ new (L) ListTy(Head, TailImpl);
+
+ // Insert the new list into the cache.
+ Cache.InsertNode(L, InsertPos);
+ }
+
+ return L;
+ }
+
+ ImmutableList<T> Add(const T& D, ImmutableList<T> L) {
+ return Concat(D, L);
+ }
+
+ ImmutableList<T> GetEmptyList() const {
+ return ImmutableList<T>(0);
+ }
+
+ ImmutableList<T> Create(const T& X) {
+ return Concat(X, GetEmptyList());
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Partially-specialized Traits.
+//===----------------------------------------------------------------------===//
+
+template<typename T> struct DenseMapInfo;
+template<typename T> struct DenseMapInfo<ImmutableList<T> > {
+ static inline ImmutableList<T> getEmptyKey() {
+ return reinterpret_cast<ImmutableListImpl<T>*>(-1);
+ }
+ static inline ImmutableList<T> getTombstoneKey() {
+ return reinterpret_cast<ImmutableListImpl<T>*>(-2);
+ }
+ static unsigned getHashValue(ImmutableList<T> X) {
+ uintptr_t PtrVal = reinterpret_cast<uintptr_t>(X.getInternalPointer());
+ return (unsigned((uintptr_t)PtrVal) >> 4) ^
+ (unsigned((uintptr_t)PtrVal) >> 9);
+ }
+ static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
+ return X1 == X2;
+ }
+ static bool isPod() { return true; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
new file mode 100644
index 0000000000000..52708bc8a1087
--- /dev/null
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -0,0 +1,230 @@
+//===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMAP_H
+#define LLVM_ADT_IMMAP_H
+
+#include "llvm/ADT/ImmutableSet.h"
+
+namespace llvm {
+
+/// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the first
+/// and second elements in a pair are used to generate profile information,
+/// only the first element (the key) is used by isEqual and isLess.
+template <typename T, typename S>
+struct ImutKeyValueInfo {
+ typedef const std::pair<T,S> value_type;
+ typedef const value_type& value_type_ref;
+ typedef const T key_type;
+ typedef const T& key_type_ref;
+ typedef const S data_type;
+ typedef const S& data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref V) {
+ return V.first;
+ }
+
+ static inline data_type_ref DataOfValue(value_type_ref V) {
+ return V.second;
+ }
+
+ static inline bool isEqual(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isEqual(L,R);
+ }
+ static inline bool isLess(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isLess(L,R);
+ }
+
+ static inline bool isDataEqual(data_type_ref L, data_type_ref R) {
+ return ImutContainerInfo<S>::isEqual(L,R);
+ }
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
+ ImutContainerInfo<T>::Profile(ID, V.first);
+ ImutContainerInfo<S>::Profile(ID, V.second);
+ }
+};
+
+
+template <typename KeyT, typename ValT,
+ typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMap {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef typename ValInfo::key_type key_type;
+ typedef typename ValInfo::key_type_ref key_type_ref;
+ typedef typename ValInfo::data_type data_type;
+ typedef typename ValInfo::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+
+private:
+ TreeTy* Root;
+
+public:
+ /// Constructs a map from a pointer to a tree root. In general one
+ /// should use a Factory object to create maps instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {}
+
+ class Factory {
+ typename TreeTy::Factory F;
+
+ public:
+ Factory() {}
+
+ Factory(BumpPtrAllocator& Alloc)
+ : F(Alloc) {}
+
+ ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); }
+
+ ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+ return ImmutableMap(F.Add(Old.Root,
+ std::make_pair<key_type,data_type>(K,D)));
+ }
+
+ ImmutableMap Remove(ImmutableMap Old, key_type_ref K) {
+ return ImmutableMap(F.Remove(Old.Root,K));
+ }
+
+ private:
+ Factory(const Factory& RHS) {};
+ void operator=(const Factory& RHS) {};
+ };
+
+ friend class Factory;
+
+ bool contains(key_type_ref K) const {
+ return Root ? Root->contains(K) : false;
+ }
+
+
+ bool operator==(ImmutableMap RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(ImmutableMap RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ TreeTy* getRoot() const { return Root; }
+
+ bool isEmpty() const { return !Root; }
+
+ //===--------------------------------------------------===//
+ // Foreach - A limited form of map iteration.
+ //===--------------------------------------------------===//
+
+private:
+ template <typename Callback>
+ struct CBWrapper {
+ Callback C;
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+ template <typename Callback>
+ struct CBWrapperRef {
+ Callback &C;
+ CBWrapperRef(Callback& c) : C(c) {}
+
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+public:
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (Root) {
+ CBWrapperRef<Callback> CB(C);
+ Root->foreach(CB);
+ }
+ }
+
+ template <typename Callback>
+ void foreach() {
+ if (Root) {
+ CBWrapper<Callback> CB;
+ Root->foreach(CB);
+ }
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableMap;
+
+ public:
+ value_type_ref operator*() const { return itr->getValue(); }
+ value_type* operator->() const { return &itr->getValue(); }
+
+ key_type_ref getKey() const { return itr->getValue().first; }
+ data_type_ref getData() const { return itr->getValue().second; }
+
+
+ iterator& operator++() { ++itr; return *this; }
+ iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ iterator& operator--() { --itr; return *this; }
+ 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; }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ data_type* lookup(key_type_ref K) const {
+ if (Root) {
+ TreeTy* T = Root->find(K);
+ if (T) return &T->getValue().second;
+ }
+
+ return 0;
+ }
+
+ /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+ /// which key is the highest in the ordering of keys in the map. This
+ /// method returns NULL if the map is empty.
+ value_type* getMaxElement() const {
+ return Root ? &(Root->getMaxElement()->getValue()) : 0;
+ }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
+ ID.AddPointer(M.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID,*this);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
new file mode 100644
index 0000000000000..be274dbe6758c
--- /dev/null
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -0,0 +1,1070 @@
+//===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImutAVLTree and ImmutableSet classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMSET_H
+#define LLVM_ADT_IMSET_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <functional>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Definition.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo> class ImutAVLFactory;
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
+template <typename ImutInfo> class ImutAVLTreeGenericIterator;
+
+template <typename ImutInfo >
+class ImutAVLTree : public FoldingSetNode {
+public:
+ typedef typename ImutInfo::key_type_ref key_type_ref;
+ typedef typename ImutInfo::value_type value_type;
+ typedef typename ImutInfo::value_type_ref value_type_ref;
+
+ typedef ImutAVLFactory<ImutInfo> Factory;
+ friend class ImutAVLFactory<ImutInfo>;
+
+ friend class ImutAVLTreeGenericIterator<ImutInfo>;
+ friend class FoldingSet<ImutAVLTree>;
+
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
+
+ //===----------------------------------------------------===//
+ // Public Interface.
+ //===----------------------------------------------------===//
+
+ /// getLeft - Returns a pointer to the left subtree. This value
+ /// is NULL if there is no left subtree.
+ ImutAVLTree* getLeft() const {
+ assert (!isMutable() && "Node is incorrectly marked mutable.");
+
+ return reinterpret_cast<ImutAVLTree*>(Left);
+ }
+
+ /// getRight - Returns a pointer to the right subtree. This value is
+ /// NULL if there is no right subtree.
+ ImutAVLTree* getRight() const { return Right; }
+
+ /// getHeight - Returns the height of the tree. A tree with no subtrees
+ /// has a height of 1.
+ unsigned getHeight() const { return Height; }
+
+ /// getValue - Returns the data value associated with the tree node.
+ const value_type& getValue() const { return Value; }
+
+ /// find - Finds the subtree associated with the specified key value.
+ /// This method returns NULL if no matching subtree is found.
+ ImutAVLTree* find(key_type_ref K) {
+ ImutAVLTree *T = this;
+
+ while (T) {
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
+
+ if (ImutInfo::isEqual(K,CurrentKey))
+ return T;
+ else if (ImutInfo::isLess(K,CurrentKey))
+ T = T->getLeft();
+ else
+ T = T->getRight();
+ }
+
+ return NULL;
+ }
+
+ /// getMaxElement - Find the subtree associated with the highest ranged
+ /// key value.
+ ImutAVLTree* getMaxElement() {
+ ImutAVLTree *T = this;
+ ImutAVLTree *Right = T->getRight();
+ while (Right) { T = Right; Right = T->getRight(); }
+ return T;
+ }
+
+ /// size - Returns the number of nodes in the tree, which includes
+ /// both leaves and non-leaf nodes.
+ unsigned size() const {
+ unsigned n = 1;
+
+ if (const ImutAVLTree* L = getLeft()) n += L->size();
+ if (const ImutAVLTree* R = getRight()) n += R->size();
+
+ return n;
+ }
+
+ /// begin - Returns an iterator that iterates over the nodes of the tree
+ /// in an inorder traversal. The returned iterator thus refers to the
+ /// the tree node with the minimum data element.
+ iterator begin() const { return iterator(this); }
+
+ /// end - Returns an iterator for the tree that denotes the end of an
+ /// inorder traversal.
+ iterator end() const { return iterator(); }
+
+ bool ElementEqual(value_type_ref V) const {
+ // Compare the keys.
+ if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(V)))
+ return false;
+
+ // Also compare the data values.
+ if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
+ ImutInfo::DataOfValue(V)))
+ return false;
+
+ return true;
+ }
+
+ bool ElementEqual(const ImutAVLTree* RHS) const {
+ return ElementEqual(RHS->getValue());
+ }
+
+ /// isEqual - Compares two trees for structural equality and returns true
+ /// if they are equal. This worst case performance of this operation is
+ // linear in the sizes of the trees.
+ bool isEqual(const ImutAVLTree& RHS) const {
+ if (&RHS == this)
+ return true;
+
+ iterator LItr = begin(), LEnd = end();
+ iterator RItr = RHS.begin(), REnd = RHS.end();
+
+ while (LItr != LEnd && RItr != REnd) {
+ if (*LItr == *RItr) {
+ LItr.SkipSubTree();
+ RItr.SkipSubTree();
+ continue;
+ }
+
+ if (!LItr->ElementEqual(*RItr))
+ return false;
+
+ ++LItr;
+ ++RItr;
+ }
+
+ return LItr == LEnd && RItr == REnd;
+ }
+
+ /// isNotEqual - Compares two trees for structural inequality. Performance
+ /// is the same is isEqual.
+ bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
+
+ /// contains - Returns true if this tree contains a subtree (node) that
+ /// has an data element that matches the specified key. Complexity
+ /// is logarithmic in the size of the tree.
+ bool contains(const key_type_ref K) { return (bool) find(K); }
+
+ /// foreach - A member template the accepts invokes operator() on a functor
+ /// object (specifed by Callback) for every node/subtree in the tree.
+ /// Nodes are visited using an inorder traversal.
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (ImutAVLTree* L = getLeft()) L->foreach(C);
+
+ C(Value);
+
+ if (ImutAVLTree* R = getRight()) R->foreach(C);
+ }
+
+ /// verify - A utility method that checks that the balancing and
+ /// ordering invariants of the tree are satisifed. It is a recursive
+ /// method that returns the height of the tree, which is then consumed
+ /// by the enclosing verify call. External callers should ignore the
+ /// return value. An invalid tree will cause an assertion to fire in
+ /// a debug build.
+ unsigned verify() const {
+ unsigned HL = getLeft() ? getLeft()->verify() : 0;
+ unsigned HR = getRight() ? getRight()->verify() : 0;
+
+ assert (getHeight() == ( HL > HR ? HL : HR ) + 1
+ && "Height calculation wrong.");
+
+ assert ((HL > HR ? HL-HR : HR-HL) <= 2
+ && "Balancing invariant violated.");
+
+
+ assert (!getLeft()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+ ImutInfo::KeyOfValue(getValue()))
+ && "Value in left child is not less that current value.");
+
+
+ assert (!getRight()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(getRight()->getValue()))
+ && "Current value is not less that value of right child.");
+
+ return getHeight();
+ }
+
+ /// Profile - Profiling for ImutAVLTree.
+ void Profile(llvm::FoldingSetNodeID& ID) {
+ ID.AddInteger(ComputeDigest());
+ }
+
+ //===----------------------------------------------------===//
+ // Internal Values.
+ //===----------------------------------------------------===//
+
+private:
+ uintptr_t Left;
+ ImutAVLTree* Right;
+ unsigned Height;
+ value_type Value;
+ unsigned Digest;
+
+ //===----------------------------------------------------===//
+ // Internal methods (node manipulation; used by Factory).
+ //===----------------------------------------------------===//
+
+private:
+
+ enum { Mutable = 0x1 };
+
+ /// ImutAVLTree - Internal constructor that is only called by
+ /// ImutAVLFactory.
+ ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
+ : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
+ Right(r), Height(height), Value(v), Digest(0) {}
+
+
+ /// isMutable - Returns true if the left and right subtree references
+ /// (as well as height) can be changed. If this method returns false,
+ /// the tree is truly immutable. Trees returned from an ImutAVLFactory
+ /// object should always have this method return true. Further, if this
+ /// method returns false for an instance of ImutAVLTree, all subtrees
+ /// will also have this method return false. The converse is not true.
+ bool isMutable() const { return Left & Mutable; }
+
+ /// getSafeLeft - Returns the pointer to the left tree by always masking
+ /// out the mutable bit. This is used internally by ImutAVLFactory,
+ /// as no trees returned to the client should have the mutable flag set.
+ ImutAVLTree* getSafeLeft() const {
+ return reinterpret_cast<ImutAVLTree*>(Left & ~Mutable);
+ }
+
+ //===----------------------------------------------------===//
+ // Mutating operations. A tree root can be manipulated as
+ // long as its reference has not "escaped" from internal
+ // methods of a factory object (see below). When a tree
+ // pointer is externally viewable by client code, the
+ // internal "mutable bit" is cleared to mark the tree
+ // immutable. Note that a tree that still has its mutable
+ // bit set may have children (subtrees) that are themselves
+ // immutable.
+ //===----------------------------------------------------===//
+
+
+ /// MarkImmutable - Clears the mutable flag for a tree. After this happens,
+ /// it is an error to call setLeft(), setRight(), and setHeight(). It
+ /// is also then safe to call getLeft() instead of getSafeLeft().
+ void MarkImmutable() {
+ assert (isMutable() && "Mutable flag already removed.");
+ Left &= ~Mutable;
+ }
+
+ /// setLeft - Changes the reference of the left subtree. Used internally
+ /// by ImutAVLFactory.
+ void setLeft(ImutAVLTree* NewLeft) {
+ assert (isMutable() &&
+ "Only a mutable tree can have its left subtree changed.");
+
+ Left = reinterpret_cast<uintptr_t>(NewLeft) | Mutable;
+ }
+
+ /// setRight - Changes the reference of the right subtree. Used internally
+ /// by ImutAVLFactory.
+ void setRight(ImutAVLTree* NewRight) {
+ assert (isMutable() &&
+ "Only a mutable tree can have its right subtree changed.");
+
+ Right = NewRight;
+ }
+
+ /// setHeight - Changes the height of the tree. Used internally by
+ /// ImutAVLFactory.
+ void setHeight(unsigned h) {
+ assert (isMutable() && "Only a mutable tree can have its height changed.");
+ Height = h;
+ }
+
+
+ static inline
+ unsigned ComputeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+ unsigned digest = 0;
+
+ if (L) digest += L->ComputeDigest();
+
+ { // Compute digest of stored data.
+ FoldingSetNodeID ID;
+ ImutInfo::Profile(ID,V);
+ digest += ID.ComputeHash();
+ }
+
+ if (R) digest += R->ComputeDigest();
+
+ return digest;
+ }
+
+ inline unsigned ComputeDigest() {
+ if (Digest) return Digest;
+
+ unsigned X = ComputeDigest(getSafeLeft(), getRight(), getValue());
+ if (!isMutable()) Digest = X;
+
+ return X;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Factory class.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo >
+class ImutAVLFactory {
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef typename TreeTy::value_type_ref value_type_ref;
+ typedef typename TreeTy::key_type_ref key_type_ref;
+
+ typedef FoldingSet<TreeTy> CacheTy;
+
+ CacheTy Cache;
+ uintptr_t Allocator;
+
+ bool ownsAllocator() const {
+ return Allocator & 0x1 ? false : true;
+ }
+
+ BumpPtrAllocator& getAllocator() const {
+ return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+ }
+
+ //===--------------------------------------------------===//
+ // Public interface.
+ //===--------------------------------------------------===//
+
+public:
+ ImutAVLFactory()
+ : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+ ImutAVLFactory(BumpPtrAllocator& Alloc)
+ : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+ ~ImutAVLFactory() {
+ if (ownsAllocator()) delete &getAllocator();
+ }
+
+ TreeTy* Add(TreeTy* T, value_type_ref V) {
+ T = Add_internal(V,T);
+ MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy* Remove(TreeTy* T, key_type_ref V) {
+ T = Remove_internal(V,T);
+ MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy* GetEmptyTree() const { return NULL; }
+
+ //===--------------------------------------------------===//
+ // A bunch of quick helper functions used for reasoning
+ // about the properties of trees and their children.
+ // These have succinct names so that the balancing code
+ // is as terse (and readable) as possible.
+ //===--------------------------------------------------===//
+private:
+
+ bool isEmpty(TreeTy* T) const { return !T; }
+ unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
+ TreeTy* Left(TreeTy* T) const { return T->getSafeLeft(); }
+ TreeTy* Right(TreeTy* T) const { return T->getRight(); }
+ value_type_ref Value(TreeTy* T) const { return T->Value; }
+
+ unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
+ unsigned hl = Height(L);
+ unsigned hr = Height(R);
+ return ( hl > hr ? hl : hr ) + 1;
+ }
+
+
+ static bool CompareTreeWithSection(TreeTy* T,
+ typename TreeTy::iterator& TI,
+ typename TreeTy::iterator& TE) {
+
+ typename TreeTy::iterator I = T->begin(), E = T->end();
+
+ for ( ; I!=E ; ++I, ++TI)
+ if (TI == TE || !I->ElementEqual(*TI))
+ return false;
+
+ return true;
+ }
+
+ //===--------------------------------------------------===//
+ // "CreateNode" is used to generate new tree roots that link
+ // to other trees. The functon may also simply move links
+ // in an existing root if that root is still marked mutable.
+ // This is necessary because otherwise our balancing code
+ // would leak memory as it would create nodes that are
+ // then discarded later before the finished tree is
+ // returned to the caller.
+ //===--------------------------------------------------===//
+
+ TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+ // Search the FoldingSet bucket for a Tree with the same digest.
+ FoldingSetNodeID ID;
+ unsigned digest = TreeTy::ComputeDigest(L, R, V);
+ ID.AddInteger(digest);
+ unsigned hash = ID.ComputeHash();
+
+ typename CacheTy::bucket_iterator I = Cache.bucket_begin(hash);
+ typename CacheTy::bucket_iterator E = Cache.bucket_end(hash);
+
+ for (; I != E; ++I) {
+ TreeTy* T = &*I;
+
+ if (T->ComputeDigest() != digest)
+ continue;
+
+ // We found a collision. Perform a comparison of Contents('T')
+ // with Contents('L')+'V'+Contents('R').
+
+ typename TreeTy::iterator TI = T->begin(), TE = T->end();
+
+ // First compare Contents('L') with the (initial) contents of T.
+ if (!CompareTreeWithSection(L, TI, TE))
+ continue;
+
+ // Now compare the new data element.
+ if (TI == TE || !TI->ElementEqual(V))
+ continue;
+
+ ++TI;
+
+ // Now compare the remainder of 'T' with 'R'.
+ if (!CompareTreeWithSection(R, TI, TE))
+ continue;
+
+ if (TI != TE) // Contents('R') did not match suffix of 'T'.
+ continue;
+
+ // Trees did match! Return 'T'.
+ return T;
+ }
+
+ // No tree with the contents: Contents('L')+'V'+Contents('R').
+ // Create it.
+
+ // Allocate the new tree node and insert it into the cache.
+ BumpPtrAllocator& A = getAllocator();
+ TreeTy* T = (TreeTy*) A.Allocate<TreeTy>();
+ new (T) TreeTy(L,R,V,IncrementHeight(L,R));
+
+ // We do not insert 'T' into the FoldingSet here. This is because
+ // this tree is still mutable and things may get rebalanced.
+ // Because our digest is associative and based on the contents of
+ // the set, this should hopefully not cause any strange bugs.
+ // 'T' is inserted by 'MarkImmutable'.
+
+ return T;
+ }
+
+ TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {
+ assert (!isEmpty(OldTree));
+
+ if (OldTree->isMutable()) {
+ OldTree->setLeft(L);
+ OldTree->setRight(R);
+ OldTree->setHeight(IncrementHeight(L,R));
+ return OldTree;
+ }
+ else return CreateNode(L, Value(OldTree), R);
+ }
+
+ /// Balance - Used by Add_internal and Remove_internal to
+ /// balance a newly created tree.
+ TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
+
+ unsigned hl = Height(L);
+ unsigned hr = Height(R);
+
+ if (hl > hr + 2) {
+ assert (!isEmpty(L) &&
+ "Left tree cannot be empty to have a height >= 2.");
+
+ TreeTy* LL = Left(L);
+ TreeTy* LR = Right(L);
+
+ if (Height(LL) >= Height(LR))
+ return CreateNode(LL, L, CreateNode(LR,V,R));
+
+ assert (!isEmpty(LR) &&
+ "LR cannot be empty because it has a height >= 1.");
+
+ TreeTy* LRL = Left(LR);
+ TreeTy* LRR = Right(LR);
+
+ return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));
+ }
+ else if (hr > hl + 2) {
+ assert (!isEmpty(R) &&
+ "Right tree cannot be empty to have a height >= 2.");
+
+ TreeTy* RL = Left(R);
+ TreeTy* RR = Right(R);
+
+ if (Height(RR) >= Height(RL))
+ return CreateNode(CreateNode(L,V,RL), R, RR);
+
+ assert (!isEmpty(RL) &&
+ "RL cannot be empty because it has a height >= 1.");
+
+ TreeTy* RLL = Left(RL);
+ TreeTy* RLR = Right(RL);
+
+ return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
+ }
+ else
+ return CreateNode(L,V,R);
+ }
+
+ /// Add_internal - Creates a new tree that includes the specified
+ /// data and the data from the original tree. If the original tree
+ /// already contained the data item, the original tree is returned.
+ TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
+ if (isEmpty(T))
+ return CreateNode(T, V, T);
+
+ assert (!T->isMutable());
+
+ key_type_ref K = ImutInfo::KeyOfValue(V);
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+
+ if (ImutInfo::isEqual(K,KCurrent))
+ return CreateNode(Left(T), V, Right(T));
+ else if (ImutInfo::isLess(K,KCurrent))
+ return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
+ else
+ return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
+ }
+
+ /// Remove_internal - Creates a new tree that includes all the data
+ /// from the original tree except the specified data. If the
+ /// specified data did not exist in the original tree, the original
+ /// tree is returned.
+ TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
+ if (isEmpty(T))
+ return T;
+
+ assert (!T->isMutable());
+
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+
+ if (ImutInfo::isEqual(K,KCurrent))
+ return CombineLeftRightTrees(Left(T),Right(T));
+ else if (ImutInfo::isLess(K,KCurrent))
+ return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
+ else
+ return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
+ }
+
+ TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
+ if (isEmpty(L)) return R;
+ if (isEmpty(R)) return L;
+
+ TreeTy* OldNode;
+ TreeTy* NewRight = RemoveMinBinding(R,OldNode);
+ return Balance(L,Value(OldNode),NewRight);
+ }
+
+ TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
+ assert (!isEmpty(T));
+
+ if (isEmpty(Left(T))) {
+ NodeRemoved = T;
+ return Right(T);
+ }
+
+ return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
+ }
+
+ /// MarkImmutable - Clears the mutable bits of a root and all of its
+ /// descendants.
+ void MarkImmutable(TreeTy* T) {
+ if (!T || !T->isMutable())
+ return;
+
+ T->MarkImmutable();
+ MarkImmutable(Left(T));
+ MarkImmutable(Right(T));
+
+ // Now that the node is immutable it can safely be inserted
+ // into the node cache.
+ llvm::FoldingSetNodeID ID;
+ ID.AddInteger(T->ComputeDigest());
+ Cache.InsertNode(T, (void*) &*Cache.bucket_end(ID.ComputeHash()));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Iterators.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo>
+class ImutAVLTreeGenericIterator {
+ SmallVector<uintptr_t,20> stack;
+public:
+ enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
+ Flags=0x3 };
+
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
+
+ inline ImutAVLTreeGenericIterator() {}
+ inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+ if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
+ }
+
+ TreeTy* operator*() const {
+ assert (!stack.empty());
+ return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ }
+
+ uintptr_t getVisitState() {
+ assert (!stack.empty());
+ return stack.back() & Flags;
+ }
+
+
+ bool AtEnd() const { return stack.empty(); }
+
+ bool AtBeginning() const {
+ return stack.size() == 1 && getVisitState() == VisitedNone;
+ }
+
+ void SkipToParent() {
+ assert (!stack.empty());
+ stack.pop_back();
+
+ if (stack.empty())
+ return;
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.back() |= VisitedLeft;
+ break;
+ case VisitedLeft:
+ stack.back() |= VisitedRight;
+ break;
+ default:
+ assert (false && "Unreachable.");
+ }
+ }
+
+ inline bool operator==(const _Self& x) const {
+ if (stack.size() != x.stack.size())
+ return false;
+
+ for (unsigned i = 0 ; i < stack.size(); i++)
+ if (stack[i] != x.stack[i])
+ return false;
+
+ return true;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ _Self& operator++() {
+ assert (!stack.empty());
+
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert (Current);
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ if (TreeTy* L = Current->getSafeLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L));
+ else
+ stack.back() |= VisitedLeft;
+
+ break;
+
+ case VisitedLeft:
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R));
+ else
+ stack.back() |= VisitedRight;
+
+ break;
+
+ case VisitedRight:
+ SkipToParent();
+ break;
+
+ default:
+ assert (false && "Unreachable.");
+ }
+
+ return *this;
+ }
+
+ _Self& operator--() {
+ assert (!stack.empty());
+
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert (Current);
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.pop_back();
+ break;
+
+ case VisitedLeft:
+ stack.back() &= ~Flags; // Set state to "VisitedNone."
+
+ if (TreeTy* L = Current->getLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
+
+ break;
+
+ case VisitedRight:
+ stack.back() &= ~Flags;
+ stack.back() |= VisitedLeft;
+
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
+
+ break;
+
+ default:
+ assert (false && "Unreachable.");
+ }
+
+ return *this;
+ }
+};
+
+template <typename ImutInfo>
+class ImutAVLTreeInOrderIterator {
+ typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+ InternalIteratorTy InternalItr;
+
+public:
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
+
+ ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
+ if (Root) operator++(); // Advance to first element.
+ }
+
+ ImutAVLTreeInOrderIterator() : InternalItr() {}
+
+ inline bool operator==(const _Self& x) const {
+ return InternalItr == x.InternalItr;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline TreeTy* operator*() const { return *InternalItr; }
+ inline TreeTy* operator->() const { return *InternalItr; }
+
+ inline _Self& operator++() {
+ do ++InternalItr;
+ while (!InternalItr.AtEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline _Self& operator--() {
+ do --InternalItr;
+ while (!InternalItr.AtBeginning() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline void SkipSubTree() {
+ InternalItr.SkipToParent();
+
+ while (!InternalItr.AtEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
+ ++InternalItr;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes for Profile information.
+//===----------------------------------------------------------------------===//
+
+/// Generic profile template. The default behavior is to invoke the
+/// profile method of an object. Specializations for primitive integers
+/// and generic handling of pointers is done below.
+template <typename T>
+struct ImutProfileInfo {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ FoldingSetTrait<T>::Profile(X,ID);
+ }
+};
+
+/// Profile traits for integers.
+template <typename T>
+struct ImutProfileInteger {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ ID.AddInteger(X);
+ }
+};
+
+#define PROFILE_INTEGER_INFO(X)\
+template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
+
+PROFILE_INTEGER_INFO(char)
+PROFILE_INTEGER_INFO(unsigned char)
+PROFILE_INTEGER_INFO(short)
+PROFILE_INTEGER_INFO(unsigned short)
+PROFILE_INTEGER_INFO(unsigned)
+PROFILE_INTEGER_INFO(signed)
+PROFILE_INTEGER_INFO(long)
+PROFILE_INTEGER_INFO(unsigned long)
+PROFILE_INTEGER_INFO(long long)
+PROFILE_INTEGER_INFO(unsigned long long)
+
+#undef PROFILE_INTEGER_INFO
+
+/// Generic profile trait for pointer types. We treat pointers as
+/// references to unique objects.
+template <typename T>
+struct ImutProfileInfo<T*> {
+ typedef const T* value_type;
+ typedef value_type value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
+ ID.AddPointer(X);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes that contain element comparison operators and type
+// definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These
+// inherit from the profile traits (ImutProfileInfo) to include operations
+// for element profiling.
+//===----------------------------------------------------------------------===//
+
+
+/// ImutContainerInfo - Generic definition of comparison operations for
+/// elements of immutable containers that defaults to using
+/// std::equal_to<> and std::less<> to perform comparison of elements.
+template <typename T>
+struct ImutContainerInfo : public ImutProfileInfo<T> {
+ typedef typename ImutProfileInfo<T>::value_type value_type;
+ typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+ typedef bool data_type;
+ typedef bool data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return std::equal_to<key_type>()(LHS,RHS);
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return std::less<key_type>()(LHS,RHS);
+ }
+
+ static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+/// ImutContainerInfo - Specialization for pointer values to treat pointers
+/// as references to unique objects. Pointers are thus compared by
+/// their addresses.
+template <typename T>
+struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
+ typedef typename ImutProfileInfo<T*>::value_type value_type;
+ typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+ typedef bool data_type;
+ typedef bool data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return LHS == RHS;
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return LHS < RHS;
+ }
+
+ static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable Set
+//===----------------------------------------------------------------------===//
+
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSet {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+
+private:
+ TreeTy* Root;
+
+public:
+ /// Constructs a set from a pointer to a tree root. In general one
+ /// should use a Factory object to create sets instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableSet(TreeTy* R) : Root(R) {}
+
+ class Factory {
+ typename TreeTy::Factory F;
+
+ public:
+ Factory() {}
+
+ Factory(BumpPtrAllocator& Alloc)
+ : F(Alloc) {}
+
+ /// GetEmptySet - Returns an immutable set that contains no elements.
+ ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
+
+ /// Add - Creates a new immutable set that contains all of the values
+ /// of the original set with the addition of the specified value. If
+ /// the original set already included the value, then the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
+ return ImmutableSet(F.Add(Old.Root,V));
+ }
+
+ /// Remove - Creates a new immutable set that contains all of the values
+ /// of the original set with the exception of the specified value. If
+ /// the original set did not contain the value, the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
+ return ImmutableSet(F.Remove(Old.Root,V));
+ }
+
+ BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
+
+ private:
+ Factory(const Factory& RHS) {};
+ void operator=(const Factory& RHS) {};
+ };
+
+ friend class Factory;
+
+ /// contains - Returns true if the set contains the specified value.
+ bool contains(const value_type_ref V) const {
+ return Root ? Root->contains(V) : false;
+ }
+
+ bool operator==(ImmutableSet RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(ImmutableSet RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ TreeTy* getRoot() const { return Root; }
+
+ /// isEmpty - Return true if the set contains no elements.
+ bool isEmpty() const { return !Root; }
+
+ /// isSingleton - Return true if the set contains exactly one element.
+ /// This method runs in constant time.
+ bool isSingleton() const { return getHeight() == 1; }
+
+ template <typename Callback>
+ void foreach(Callback& C) { if (Root) Root->foreach(C); }
+
+ template <typename Callback>
+ void foreach() { if (Root) { Callback C; Root->foreach(C); } }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableSet<ValT,ValInfo>;
+ public:
+ inline value_type_ref operator*() const { return itr->getValue(); }
+ inline iterator& operator++() { ++itr; return *this; }
+ inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ inline iterator& operator--() { --itr; return *this; }
+ inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ inline value_type *operator->() const { return &(operator*()); }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) {
+ ID.AddPointer(S.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID,*this);
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
new file mode 100644
index 0000000000000..ff5d3a139c705
--- /dev/null
+++ b/include/llvm/ADT/IndexedMap.h
@@ -0,0 +1,75 @@
+//===- llvm/ADT/IndexedMap.h - An index map implementation ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an indexed map. The index map template takes two
+// types. The first is the mapped type and the second is a functor
+// that maps its argument to a size_t. On instantiation a "null" value
+// can be provided to be used as a "does not exist" indicator in the
+// map. A member function grow() is provided that given the value of
+// the maximally indexed key (the argument of the functor) makes sure
+// the map has enough space for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INDEXEDMAP_H
+#define LLVM_ADT_INDEXEDMAP_H
+
+#include <cassert>
+#include <functional>
+#include <vector>
+
+namespace llvm {
+
+ struct IdentityFunctor : std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Index) const {
+ return Index;
+ }
+ };
+
+ template <typename T, typename ToIndexT = IdentityFunctor>
+ class IndexedMap {
+ typedef typename ToIndexT::argument_type IndexT;
+ typedef std::vector<T> StorageT;
+ StorageT storage_;
+ T nullVal_;
+ ToIndexT toIndex_;
+
+ public:
+ IndexedMap() : nullVal_(T()) { }
+
+ explicit IndexedMap(const T& val) : nullVal_(val) { }
+
+ typename StorageT::reference operator[](IndexT n) {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ typename StorageT::const_reference operator[](IndexT n) const {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ void clear() {
+ storage_.clear();
+ }
+
+ void grow(IndexT n) {
+ unsigned NewSize = toIndex_(n) + 1;
+ if (NewSize > storage_.size())
+ storage_.resize(NewSize, nullVal_);
+ }
+
+ typename StorageT::size_type size() const {
+ return storage_.size();
+ }
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
new file mode 100644
index 0000000000000..37d4ac9d29df5
--- /dev/null
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -0,0 +1,230 @@
+//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines IntrusiveRefCntPtr, a template class that
+// implements a "smart" pointer for objects that maintain their own
+// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two
+// generic base classes for objects that wish to have their lifetimes
+// managed using reference counting.
+//
+// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added
+// LLVM-style casting.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+
+#include <cassert>
+
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+ template <class T>
+ class IntrusiveRefCntPtr;
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBase - A generic base class for objects that wish to
+/// have their lifetimes managed using reference counts. Classes
+/// subclass RefCountedBase to obtain such functionality, and are
+/// typically handled with IntrusivePtr "smart pointers" (see below)
+/// which automatically handle the management of reference counts.
+/// Objects that subclass RefCountedBase should not be allocated on
+/// the stack, as invoking "delete" (which is called when the
+/// reference count hits 0) on such objects is an error.
+//===----------------------------------------------------------------------===//
+ template <class Derived>
+ class RefCountedBase {
+ unsigned ref_cnt;
+
+ protected:
+ RefCountedBase() : ref_cnt(0) {}
+
+ void Retain() { ++ref_cnt; }
+ void Release() {
+ assert (ref_cnt > 0 && "Reference count is already zero.");
+ if (--ref_cnt == 0) delete static_cast<Derived*>(this);
+ }
+
+ friend class IntrusiveRefCntPtr<Derived>;
+ };
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBaseVPTR - A class that has the same function as
+/// RefCountedBase, but with a virtual destructor. Should be used
+/// instead of RefCountedBase for classes that already have virtual
+/// methods to enforce dynamic allocation via 'new'. Classes that
+/// inherit from RefCountedBaseVPTR can't be allocated on stack -
+/// attempting to do this will produce a compile error.
+//===----------------------------------------------------------------------===//
+ template <class Derived>
+ class RefCountedBaseVPTR {
+ unsigned ref_cnt;
+
+ protected:
+ RefCountedBaseVPTR() : ref_cnt(0) {}
+ virtual ~RefCountedBaseVPTR() {}
+
+ void Retain() { ++ref_cnt; }
+ void Release() {
+ assert (ref_cnt > 0 && "Reference count is already zero.");
+ if (--ref_cnt == 0) delete this;
+ }
+
+ friend class IntrusiveRefCntPtr<Derived>;
+ };
+
+//===----------------------------------------------------------------------===//
+/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
+/// that assumes the wrapped object has a reference count associated
+/// with it that can be managed via calls to
+/// IntrusivePtrAddRef/IntrusivePtrRelease. The smart pointers
+/// manage reference counts via the RAII idiom: upon creation of
+/// smart pointer the reference count of the wrapped object is
+/// incremented and upon destruction of the smart pointer the
+/// reference count is decremented. This class also safely handles
+/// wrapping NULL pointers.
+///
+/// Reference counting is implemented via calls to
+/// Obj->Retain()/Obj->Release(). Release() is required to destroy
+/// the object when the reference count reaches zero. Inheriting from
+/// RefCountedBase/RefCountedBaseVPTR takes care of this
+/// automatically.
+//===----------------------------------------------------------------------===//
+ template <typename T>
+ class IntrusiveRefCntPtr {
+ T* Obj;
+ typedef IntrusiveRefCntPtr this_type;
+ public:
+ typedef T element_type;
+
+ explicit IntrusiveRefCntPtr() : Obj(0) {}
+
+ explicit IntrusiveRefCntPtr(T* obj) : Obj(obj) {
+ retain();
+ }
+
+ IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) {
+ retain();
+ }
+
+ template <class X>
+ IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
+ : Obj(S.getPtr()) {
+ retain();
+ }
+
+ IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) {
+ replace(S.getPtr());
+ return *this;
+ }
+
+ template <class X>
+ IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr<X>& S) {
+ replace(S.getPtr());
+ return *this;
+ }
+
+ IntrusiveRefCntPtr& operator=(T * S) {
+ replace(S);
+ return *this;
+ }
+
+ ~IntrusiveRefCntPtr() { release(); }
+
+ T& operator*() const { return *Obj; }
+
+ T* operator->() const { return Obj; }
+
+ T* getPtr() const { return Obj; }
+
+ typedef T* (IntrusiveRefCntPtr::*unspecified_bool_type) () const;
+ operator unspecified_bool_type() const {
+ return Obj == 0 ? 0 : &IntrusiveRefCntPtr::getPtr;
+ }
+
+ void swap(IntrusiveRefCntPtr& other) {
+ T* tmp = other.Obj;
+ other.Obj = Obj;
+ Obj = tmp;
+ }
+
+ private:
+ void retain() { if (Obj) Obj->Retain(); }
+ void release() { if (Obj) Obj->Release(); }
+
+ void replace(T* S) {
+ this_type(S).swap(*this);
+ }
+ };
+
+ template<class T, class U>
+ inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A.getPtr() == B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A.getPtr() != B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+ U* B)
+ {
+ return A.getPtr() == B;
+ }
+
+ template<class T, class U>
+ inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+ U* B)
+ {
+ return A.getPtr() != B;
+ }
+
+ template<class T, class U>
+ inline bool operator==(T* A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A == B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator!=(T* A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A != B.getPtr();
+ }
+
+//===----------------------------------------------------------------------===//
+// LLVM-style downcasting support for IntrusiveRefCntPtr objects
+//===----------------------------------------------------------------------===//
+
+ template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
+ typedef T* SimpleType;
+ static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+ return Val.getPtr();
+ }
+ };
+
+ template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
+ typedef T* SimpleType;
+ static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+ return Val.getPtr();
+ }
+ };
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
new file mode 100644
index 0000000000000..cc53c8c30c121
--- /dev/null
+++ b/include/llvm/ADT/OwningPtr.h
@@ -0,0 +1,134 @@
+//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and implements the OwningPtr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_OWNING_PTR_H
+#define LLVM_ADT_OWNING_PTR_H
+
+#include <cassert>
+#include <cstddef>
+
+namespace llvm {
+
+/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
+/// guarantees deletion of the object pointed to, either on destruction 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.
+template<class T>
+class OwningPtr {
+ OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT
+ OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT
+ T *Ptr;
+public:
+ explicit OwningPtr(T *P = 0) : Ptr(P) {}
+
+ ~OwningPtr() {
+ delete Ptr;
+ }
+
+ /// reset - Change the current pointee to the specified pointer. Note that
+ /// calling this with any pointer (including a null pointer) deletes the
+ /// current pointer.
+ void reset(T *P = 0) {
+ if (P == Ptr) return;
+ T *Tmp = Ptr;
+ Ptr = P;
+ delete Tmp;
+ }
+
+ /// take - Reset the owning pointer to null and return its pointer. This does
+ /// not delete the pointer before returning it.
+ T *take() {
+ T *Tmp = Ptr;
+ Ptr = 0;
+ return Tmp;
+ }
+
+ T &operator*() const {
+ assert(Ptr && "Cannot dereference null pointer");
+ return *Ptr;
+ }
+
+ T *operator->() const { return Ptr; }
+ T *get() const { return Ptr; }
+ operator bool() const { return Ptr != 0; }
+ bool operator!() const { return Ptr == 0; }
+
+ void swap(OwningPtr &RHS) {
+ T *Tmp = RHS.Ptr;
+ RHS.Ptr = Ptr;
+ Ptr = Tmp;
+ }
+};
+
+template<class T>
+inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
+ a.swap(b);
+}
+
+/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
+/// functionality as OwningPtr, except that it works for array types.
+template<class T>
+class OwningArrayPtr {
+ OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT
+ OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
+ T *Ptr;
+public:
+ explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
+
+ ~OwningArrayPtr() {
+ delete [] Ptr;
+ }
+
+ /// reset - Change the current pointee to the specified pointer. Note that
+ /// calling this with any pointer (including a null pointer) deletes the
+ /// current pointer.
+ void reset(T *P = 0) {
+ if (P == Ptr) return;
+ T *Tmp = Ptr;
+ Ptr = P;
+ delete [] Tmp;
+ }
+
+ /// take - Reset the owning pointer to null and return its pointer. This does
+ /// not delete the pointer before returning it.
+ T *take() {
+ T *Tmp = Ptr;
+ Ptr = 0;
+ return Tmp;
+ }
+
+ T &operator[](std::ptrdiff_t i) const {
+ assert(Ptr && "Cannot dereference null pointer");
+ return Ptr[i];
+ }
+
+ T *get() const { return Ptr; }
+ operator bool() const { return Ptr != 0; }
+ bool operator!() const { return Ptr == 0; }
+
+ void swap(OwningArrayPtr &RHS) {
+ T *Tmp = RHS.Ptr;
+ RHS.Ptr = Ptr;
+ Ptr = Tmp;
+ }
+};
+
+template<class T>
+inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
+ a.swap(b);
+}
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
new file mode 100644
index 0000000000000..0aa478b1ff61c
--- /dev/null
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -0,0 +1,150 @@
+//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PointerIntPair class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERINTPAIR_H
+#define LLVM_ADT_POINTERINTPAIR_H
+
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo;
+
+/// PointerIntPair - This class implements a pair of a pointer and small
+/// 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
+/// can only be done for small integers: typically up to 3 bits, but it depends
+/// on the number of bits available according to PointerLikeTypeTraits for the
+/// type.
+///
+/// Note that PointerIntPair always puts the Int part in the highest bits
+/// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
+/// the bool into bit #2, not bit #0, which allows the low two bits to be used
+/// for something else. For example, this allows:
+/// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
+/// ... and the two bools will land in different bits.
+///
+template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
+ typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
+class PointerIntPair {
+ intptr_t Value;
+ enum {
+ /// PointerBitMask - The bits that come from the pointer.
+ PointerBitMask =
+ ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
+
+ /// IntShift - The number of low bits that we reserve for other uses, and
+ /// keep zero.
+ IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
+
+ /// IntMask - This is the unshifted mask for valid bits of the int type.
+ IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
+
+ // ShiftedIntMask - This is the bits for the integer shifted in place.
+ ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
+ };
+public:
+ PointerIntPair() : Value(0) {}
+ PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
+ assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
+ "PointerIntPair formed with integer size too large for pointer");
+ setPointer(Ptr);
+ setInt(Int);
+ }
+
+ PointerTy getPointer() const {
+ return reinterpret_cast<PointerTy>(Value & PointerBitMask);
+ }
+
+ IntType getInt() const {
+ return (IntType)((Value >> IntShift) & IntMask);
+ }
+
+ void setPointer(PointerTy Ptr) {
+ intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
+ assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ // Preserve all low bits, just update the pointer.
+ Value = PtrVal | (Value & ~PointerBitMask);
+ }
+
+ void setInt(IntType Int) {
+ intptr_t IntVal = Int;
+ assert(IntVal < (1 << IntBits) && "Integer too large for field");
+
+ // Preserve all bits other than the ones we are updating.
+ Value &= ~ShiftedIntMask; // Remove integer field.
+ Value |= IntVal << IntShift; // Set new integer.
+ }
+
+ void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
+ void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
+
+ static PointerIntPair getFromOpaqueValue(void *V) {
+ PointerIntPair P; P.setFromOpaqueValue(V); return P;
+ }
+
+ 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;}
+};
+
+// Provide specialization of DenseMapInfo for PointerIntPair.
+template<typename PointerTy, unsigned IntBits, typename IntType>
+struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
+ typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
+ static Ty getEmptyKey() {
+ intptr_t Val = -1;
+ Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+ return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
+ }
+ static Ty getTombstoneKey() {
+ intptr_t Val = -2;
+ Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+ return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
+ }
+ static unsigned getHashValue(Ty V) {
+ uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
+ return unsigned(IV) ^ unsigned(IV >> 9);
+ }
+ static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
+ static bool isPod() { return true; }
+};
+
+// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
+template<typename PointerTy, unsigned IntBits, typename IntType,
+ typename PtrTraits>
+class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
+ PtrTraits> > {
+public:
+ static inline void *
+ getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerIntPair<PointerTy, IntBits, IntType>
+ getFromVoidPointer(void *P) {
+ return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
+ }
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable - IntBits
+ };
+};
+
+} // end namespace llvm
+#endif
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
new file mode 100644
index 0000000000000..b3baec1ff3772
--- /dev/null
+++ b/include/llvm/ADT/PointerUnion.h
@@ -0,0 +1,259 @@
+//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PointerUnion class, which is a discriminated union of
+// pointer types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERUNION_H
+#define LLVM_ADT_POINTERUNION_H
+
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+
+ /// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return
+ /// false or true respectively.
+ template <typename PT1, typename PT2>
+ static inline int getPointerUnionTypeNum(PT1 *P) { return 0; }
+ template <typename PT1, typename PT2>
+ static inline int getPointerUnionTypeNum(PT2 *P) { return 1; }
+ template <typename PT1, typename PT2>
+ static inline int getPointerUnionTypeNum(...) { return -1; }
+
+
+ /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+ /// for the two template arguments.
+ template <typename PT1, typename PT2>
+ class PointerUnionUIntTraits {
+ public:
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ enum {
+ PT1BitsAv = PointerLikeTypeTraits<PT1>::NumLowBitsAvailable,
+ PT2BitsAv = PointerLikeTypeTraits<PT2>::NumLowBitsAvailable,
+ NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
+ };
+ };
+
+ /// PointerUnion - This implements a discriminated union of two pointer types,
+ /// and keeps the discriminator bit-mangled into the low bits of the pointer.
+ /// This allows the implementation to be extremely efficient in space, but
+ /// permits a very natural and type-safe API.
+ ///
+ /// Common use patterns would be something like this:
+ /// PointerUnion<int*, float*> P;
+ /// P = (int*)0;
+ /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
+ /// X = P.get<int*>(); // ok.
+ /// Y = P.get<float*>(); // runtime assertion failure.
+ /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag)
+ /// P = (float*)0;
+ /// Y = P.get<float*>(); // ok.
+ /// X = P.get<int*>(); // runtime assertion failure.
+ template <typename PT1, typename PT2>
+ class PointerUnion {
+ public:
+ typedef PointerIntPair<void*, 1, bool,
+ PointerUnionUIntTraits<PT1,PT2> > ValTy;
+ private:
+ ValTy Val;
+ public:
+ PointerUnion() {}
+
+ PointerUnion(PT1 V) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
+ Val.setInt(0);
+ }
+ PointerUnion(PT2 V) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
+ Val.setInt(1);
+ }
+
+ /// isNull - Return true if the pointer help in the union is null,
+ /// regardless of which type it is.
+ bool isNull() const { return Val.getPointer() == 0; }
+ operator bool() const { return !isNull(); }
+
+ /// is<T>() return true if the Union currently holds the type matching T.
+ template<typename T>
+ int is() const {
+ int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0);
+ assert(TyNo != -1 && "Type query could never succeed on PointerUnion!");
+ return Val.getInt() == TyNo;
+ }
+
+ /// get<T>() - Return the value of the specified pointer type. If the
+ /// specified pointer type is incorrect, assert.
+ template<typename T>
+ T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+ }
+
+ /// dyn_cast<T>() - If the current value is of the specified pointer type,
+ /// return it, otherwise return null.
+ template<typename T>
+ T dyn_cast() const {
+ if (is<T>()) return get<T>();
+ return T();
+ }
+
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion &operator=(const PT1 &RHS) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
+ Val.setInt(0);
+ return *this;
+ }
+ const PointerUnion &operator=(const PT2 &RHS) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
+ Val.setInt(1);
+ return *this;
+ }
+
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static PointerUnion getFromOpaqueValue(void *VP) {
+ PointerUnion V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+ };
+
+ // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
+ // # low bits available = min(PT1bits,PT2bits)-1.
+ template<typename PT1, typename PT2>
+ class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
+ public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion<PT1, PT2>
+ getFromVoidPointer(void *P) {
+ return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
+ ::NumLowBitsAvailable
+ };
+ };
+
+
+ /// PointerUnion3 - This is a pointer union of three pointer types. See
+ /// documentation for PointerUnion for usage.
+ template <typename PT1, typename PT2, typename PT3>
+ class PointerUnion3 {
+ public:
+ typedef PointerUnion<PT1, PT2> InnerUnion;
+ typedef PointerUnion<InnerUnion, PT3> ValTy;
+ private:
+ ValTy Val;
+ public:
+ PointerUnion3() {}
+
+ PointerUnion3(PT1 V) {
+ Val = InnerUnion(V);
+ }
+ PointerUnion3(PT2 V) {
+ Val = InnerUnion(V);
+ }
+ PointerUnion3(PT3 V) {
+ Val = V;
+ }
+
+ /// isNull - Return true if the pointer help in the union is null,
+ /// regardless of which type it is.
+ bool isNull() const { return Val.isNull(); }
+ operator bool() const { return !isNull(); }
+
+ /// is<T>() return true if the Union currently holds the type matching T.
+ template<typename T>
+ int is() const {
+ // Is it PT1/PT2?
+ if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
+ return Val.is<InnerUnion>() && Val.get<InnerUnion>().is<T>();
+ return Val.is<T>();
+ }
+
+ /// get<T>() - Return the value of the specified pointer type. If the
+ /// specified pointer type is incorrect, assert.
+ template<typename T>
+ T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ // Is it PT1/PT2?
+ if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1)
+ return Val.get<InnerUnion>().get<T>();
+
+ return Val.get<T>();
+ }
+
+ /// dyn_cast<T>() - If the current value is of the specified pointer type,
+ /// return it, otherwise return null.
+ template<typename T>
+ T dyn_cast() const {
+ if (is<T>()) return get<T>();
+ return T();
+ }
+
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion3 &operator=(const PT1 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT2 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT3 &RHS) {
+ Val = RHS;
+ return *this;
+ }
+
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static PointerUnion3 getFromOpaqueValue(void *VP) {
+ PointerUnion3 V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+ };
+
+ // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
+ // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+ template<typename PT1, typename PT2, typename PT3>
+ class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
+ public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion3<PT1, PT2, PT3>
+ getFromVoidPointer(void *P) {
+ return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
+ ::NumLowBitsAvailable
+ };
+ };
+}
+
+#endif
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
new file mode 100644
index 0000000000000..bf7ce9d0bb6aa
--- /dev/null
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -0,0 +1,231 @@
+//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic graph
+// post order iterator. This should work over any graph type that has a
+// GraphTraits specialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POSTORDERITERATOR_H
+#define LLVM_ADT_POSTORDERITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
+#include <set>
+#include <stack>
+#include <vector>
+
+namespace llvm {
+
+template<class SetType, bool External> // Non-external set
+class po_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class po_iterator_storage<SetType, true> {
+public:
+ po_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+template<class GraphT,
+ class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>,
+ bool ExtStorage = false,
+ class GT = GraphTraits<GraphT> >
+class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public po_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::stack<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ void traverseChild() {
+ while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) {
+ NodeType *BB = *VisitStack.top().second++;
+ if (!this->Visited.count(BB)) { // If the block is not visited...
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ }
+ }
+ }
+
+ inline po_iterator(NodeType *BB) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ inline po_iterator() {} // End is when stack is empty.
+
+ inline po_iterator(NodeType *BB, SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(&S) {
+ if(!S.count(BB)) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ }
+
+ inline po_iterator(SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(&S) {
+ } // End is when stack is empty.
+public:
+ typedef typename super::pointer pointer;
+ typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT G) { return _Self(); }
+
+ static inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.top().first;
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the BasicBlock, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ VisitStack.pop();
+ if (!VisitStack.empty())
+ traverseChild();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+template <class T>
+po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
+
+// Provide global definitions of external postorder iterators...
+template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
+struct po_ext_iterator : public po_iterator<T, SetType, true> {
+ po_ext_iterator(const 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>
+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...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NodeType*>,
+ bool External = false>
+struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
+ ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
+ po_iterator<Inverse<T>, SetType, External> (V) {}
+};
+
+template <class T>
+ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+ return ipo_iterator<T>::begin(G, Reverse);
+}
+
+template <class T>
+ipo_iterator<T> ipo_end(T G){
+ return ipo_iterator<T>::end(G);
+}
+
+//Provide global definitions of external inverse postorder iterators...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NodeType*> >
+struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
+ ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+ ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+};
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::end(G, S);
+}
+
+//===--------------------------------------------------------------------===//
+// Reverse Post Order CFG iterator code
+//===--------------------------------------------------------------------===//
+//
+// This is used to visit basic blocks in a method in reverse post order. This
+// class is awkward to use because I don't know a good incremental algorithm to
+// computer RPO from a graph. Because of this, the construction of the
+// ReversePostOrderTraversal object is expensive (it must walk the entire graph
+// with a postorder iterator to build the data structures). The moral of this
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
+//
+// This class should be used like this:
+// {
+// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// }
+//
+
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class ReversePostOrderTraversal {
+ typedef typename GT::NodeType NodeType;
+ std::vector<NodeType*> Blocks; // Block list in normal PO order
+ inline void Initialize(NodeType *BB) {
+ copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
+ }
+public:
+ typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+ inline ReversePostOrderTraversal(GraphT G) {
+ Initialize(GT::getEntryNode(G));
+ }
+
+ // Because we want a reverse post order, use reverse iterators from the vector
+ inline rpo_iterator begin() { return Blocks.rbegin(); }
+ inline rpo_iterator end() { return Blocks.rend(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/PriorityQueue.h b/include/llvm/ADT/PriorityQueue.h
new file mode 100644
index 0000000000000..a8809dc0b2676
--- /dev/null
+++ b/include/llvm/ADT/PriorityQueue.h
@@ -0,0 +1,83 @@
+//===- llvm/ADT/PriorityQueue.h - Priority queues ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PriorityQueue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_PRIORITY_QUEUE_H
+#define LLVM_ADT_PRIORITY_QUEUE_H
+
+#include <queue>
+
+namespace llvm {
+
+/// PriorityQueue - This class behaves like std::priority_queue and
+/// provides a few additional convenience functions.
+///
+template<class T,
+ class Sequence = std::vector<T>,
+ class Compare = std::less<typename Sequence::value_type> >
+class PriorityQueue : public std::priority_queue<T, Sequence, Compare> {
+public:
+ explicit PriorityQueue(const Compare &compare = Compare(),
+ const Sequence &sequence = Sequence())
+ : std::priority_queue<T, Sequence, Compare>(compare, sequence)
+ {}
+
+ template<class Iterator>
+ PriorityQueue(Iterator begin, Iterator end,
+ const Compare &compare = Compare(),
+ const Sequence &sequence = Sequence())
+ : std::priority_queue<T, Sequence, Compare>(begin, end, compare, sequence)
+ {}
+
+ /// erase_one - Erase one element from the queue, regardless of its
+ /// position. This operation performs a linear search to find an element
+ /// equal to t, but then uses all logarithmic-time algorithms to do
+ /// the erase operation.
+ ///
+ void erase_one(const T &t) {
+ // Linear-search to find the element.
+ typename Sequence::size_type i =
+ std::find(this->c.begin(), this->c.end(), t) - this->c.begin();
+
+ // Logarithmic-time heap bubble-up.
+ while (i != 0) {
+ typename Sequence::size_type parent = (i - 1) / 2;
+ this->c[i] = this->c[parent];
+ i = parent;
+ }
+
+ // The element we want to remove is now at the root, so we can use
+ // priority_queue's plain pop to remove it.
+ this->pop();
+ }
+
+ /// reheapify - If an element in the queue has changed in a way that
+ /// affects its standing in the comparison function, the queue's
+ /// internal state becomes invalid. Calling reheapify() resets the
+ /// queue's state, making it valid again. This operation has time
+ /// complexity proportional to the number of elements in the queue,
+ /// so don't plan to use it a lot.
+ ///
+ void reheapify() {
+ std::make_heap(this->c.begin(), this->c.end(), this->comp);
+ }
+
+ /// clear - Erase all elements from the queue.
+ ///
+ void clear() {
+ this->c.clear();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
new file mode 100644
index 0000000000000..e28f4caa5d769
--- /dev/null
+++ b/include/llvm/ADT/SCCIterator.h
@@ -0,0 +1,199 @@
+//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
+// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
+//
+// The SCC iterator has the important property that if a node in SCC S1 has an
+// edge to a node in SCC S2, then it visits S1 *after* S2.
+//
+// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
+// (NOTE: This requires some simple wrappers and is not supported yet.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCCITERATOR_H
+#define LLVM_ADT_SCCITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// scc_iterator - Enumerate the SCCs of a directed graph, in
+/// reverse topological order of the SCC DAG.
+///
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class scc_iterator
+ : public forward_iterator<std::vector<typename GT::NodeType>, ptrdiff_t> {
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+ typedef std::vector<NodeType*> SccTy;
+ typedef forward_iterator<SccTy, ptrdiff_t> super;
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ // The visit counters used to detect when a complete SCC is on the stack.
+ // visitNum is the global counter.
+ // nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
+ unsigned visitNum;
+ std::map<NodeType *, unsigned> nodeVisitNumbers;
+
+ // SCCNodeStack - Stack holding nodes of the SCC.
+ std::vector<NodeType *> SCCNodeStack;
+
+ // CurrentSCC - The current SCC, retrieved using operator*().
+ SccTy CurrentSCC;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ // MinVistNumStack - Stack holding the "min" values for each node in the DFS.
+ // This is used to track the minimum uplink values for all children of
+ // the corresponding node on the VisitStack.
+ std::vector<unsigned> MinVisitNumStack;
+
+ // A single "visit" within the non-recursive DFS traversal.
+ void DFSVisitOne(NodeType* N) {
+ ++visitNum; // Global counter for the visit order
+ nodeVisitNumbers[N] = visitNum;
+ SCCNodeStack.push_back(N);
+ MinVisitNumStack.push_back(visitNum);
+ VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
+ //DOUT << "TarjanSCC: Node " << N <<
+ // " : visitNum = " << visitNum << "\n";
+ }
+
+ // The stack-based DFS traversal; defined below.
+ void DFSVisitChildren() {
+ assert(!VisitStack.empty());
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ // TOS has at least one more child so continue DFS
+ NodeType *childN = *VisitStack.back().second++;
+ if (!nodeVisitNumbers.count(childN)) {
+ // this node has never been seen
+ DFSVisitOne(childN);
+ } else {
+ unsigned childNum = nodeVisitNumbers[childN];
+ if (MinVisitNumStack.back() > childNum)
+ MinVisitNumStack.back() = childNum;
+ }
+ }
+ }
+
+ // Compute the next SCC using the DFS traversal.
+ void GetNextSCC() {
+ assert(VisitStack.size() == MinVisitNumStack.size());
+ CurrentSCC.clear(); // Prepare to compute the next SCC
+ while (!VisitStack.empty()) {
+ DFSVisitChildren();
+ assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
+ NodeType* visitingN = VisitStack.back().first;
+ unsigned minVisitNum = MinVisitNumStack.back();
+ VisitStack.pop_back();
+ MinVisitNumStack.pop_back();
+ if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
+ MinVisitNumStack.back() = minVisitNum;
+
+ //DOUT << "TarjanSCC: Popped node " << visitingN <<
+ // " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ // nodeVisitNumbers[visitingN] << "\n";
+
+ if (minVisitNum == nodeVisitNumbers[visitingN]) {
+ // A full SCC is on the SCCNodeStack! It includes all nodes below
+ // visitingN on the stack. Copy those nodes to CurrentSCC,
+ // reset their minVisit values, and return (this suspends
+ // the DFS traversal till the next ++).
+ do {
+ CurrentSCC.push_back(SCCNodeStack.back());
+ SCCNodeStack.pop_back();
+ nodeVisitNumbers[CurrentSCC.back()] = ~0U;
+ } while (CurrentSCC.back() != visitingN);
+ return;
+ }
+ }
+ }
+
+ inline scc_iterator(NodeType *entryN) : visitNum(0) {
+ DFSVisitOne(entryN);
+ GetNextSCC();
+ }
+ inline scc_iterator() { /* End is when DFS stack is empty */ }
+
+public:
+ typedef scc_iterator<GraphT, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT& G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT& G) { return _Self(); }
+
+ // Direct loop termination test (I.fini() is more efficient than I == end())
+ inline bool fini() const {
+ assert(!CurrentSCC.empty() || VisitStack.empty());
+ return CurrentSCC.empty();
+ }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // Iterator traversal: forward iteration only
+ inline _Self& operator++() { // Preincrement
+ GetNextSCC();
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a reference to the current SCC
+ inline const SccTy &operator*() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+ inline SccTy &operator*() {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+
+ // hasLoop() -- Test if the current SCC has a loop. If it has more than one
+ // node, this is trivially true. If not, it may still contain a loop if the
+ // node has an edge back to itself.
+ bool hasLoop() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ if (CurrentSCC.size() > 1) return true;
+ NodeType *N = CurrentSCC.front();
+ for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
+ if (*CI == N)
+ return true;
+ return false;
+ }
+};
+
+
+// Global constructor for the SCC iterator.
+template <class T>
+scc_iterator<T> scc_begin(T G) {
+ return scc_iterator<T>::begin(G);
+}
+
+template <class T>
+scc_iterator<T> scc_end(T G) {
+ return scc_iterator<T>::end(G);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
new file mode 100644
index 0000000000000..964e7e07ef7d5
--- /dev/null
+++ b/include/llvm/ADT/STLExtras.h
@@ -0,0 +1,268 @@
+//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL at all.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
+
+#include <cstddef> // for std::size_t
+#include <functional>
+#include <utility> // for std::pair
+#include "llvm/ADT/iterator.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+template<class Ty>
+struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
+ bool operator()(const Ty* left, const Ty* right) const {
+ return *right < *left;
+ }
+};
+
+// deleter - Very very very simple method that is used to invoke operator
+// delete on something. It is used like this:
+//
+// for_each(V.begin(), B.end(), deleter<Interval>);
+//
+template <class T>
+static inline void deleter(T *Ptr) {
+ delete Ptr;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <iterator>
+//===----------------------------------------------------------------------===//
+
+// mapped_iterator - This is a simple iterator adapter that causes a function to
+// be dereferenced whenever operator* is invoked on the iterator.
+//
+template <class RootIt, class UnaryFunc>
+class mapped_iterator {
+ RootIt current;
+ UnaryFunc Fn;
+public:
+ typedef typename std::iterator_traits<RootIt>::iterator_category
+ iterator_category;
+ typedef typename std::iterator_traits<RootIt>::difference_type
+ difference_type;
+ typedef typename UnaryFunc::result_type value_type;
+
+ typedef void pointer;
+ //typedef typename UnaryFunc::result_type *pointer;
+ typedef void reference; // Can't modify value returned by fn
+
+ typedef RootIt iterator_type;
+ typedef mapped_iterator<RootIt, UnaryFunc> _Self;
+
+ inline const RootIt &getCurrent() const { return current; }
+ inline const UnaryFunc &getFunc() const { return Fn; }
+
+ inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
+ : current(I), Fn(F) {}
+ inline mapped_iterator(const mapped_iterator &It)
+ : current(It.current), Fn(It.Fn) {}
+
+ inline value_type operator*() const { // All this work to do this
+ return Fn(*current); // little change
+ }
+
+ _Self& operator++() { ++current; return *this; }
+ _Self& operator--() { --current; return *this; }
+ _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
+ _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; }
+ _Self operator+ (difference_type n) const {
+ return _Self(current + n, Fn);
+ }
+ _Self& operator+= (difference_type n) { current += n; return *this; }
+ _Self operator- (difference_type n) const {
+ return _Self(current - n, Fn);
+ }
+ _Self& operator-= (difference_type n) { current -= n; return *this; }
+ reference operator[](difference_type n) const { return *(*this + n); }
+
+ inline bool operator!=(const _Self &X) const { return !operator==(X); }
+ inline bool operator==(const _Self &X) const { return current == X.current; }
+ inline bool operator< (const _Self &X) const { return current < X.current; }
+
+ inline difference_type operator-(const _Self &X) const {
+ return current - X.current;
+ }
+};
+
+template <class _Iterator, class Func>
+inline mapped_iterator<_Iterator, Func>
+operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
+ const mapped_iterator<_Iterator, Func>& X) {
+ return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
+}
+
+
+// map_iterator - Provide a convenient way to create mapped_iterators, just like
+// make_pair is useful for creating pairs...
+//
+template <class ItTy, class FuncTy>
+inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
+ return mapped_iterator<ItTy, FuncTy>(I, F);
+}
+
+
+// next/prior - These functions unlike std::advance do not modify the
+// passed iterator but return a copy.
+//
+// next(myIt) returns copy of myIt incremented once
+// next(myIt, n) returns copy of myIt incremented n times
+// prior(myIt) returns copy of myIt decremented once
+// prior(myIt, n) returns copy of myIt decremented n times
+
+template <typename ItTy, typename Dist>
+inline ItTy next(ItTy it, Dist n)
+{
+ std::advance(it, n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy next(ItTy it)
+{
+ return ++it;
+}
+
+template <typename ItTy, typename Dist>
+inline ItTy prior(ItTy it, Dist n)
+{
+ std::advance(it, -n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy prior(ItTy it)
+{
+ return --it;
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <utility>
+//===----------------------------------------------------------------------===//
+
+// tie - this function ties two objects and returns a temporary object
+// that is assignable from a std::pair. This can be used to make code
+// more readable when using values returned from functions bundled in
+// a std::pair. Since an example is worth 1000 words:
+//
+// typedef std::map<int, int> Int2IntMap;
+//
+// Int2IntMap myMap;
+// Int2IntMap::iterator where;
+// bool inserted;
+// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
+//
+// if (inserted)
+// // do stuff
+// else
+// // do other stuff
+
+namespace
+{
+ template <typename T1, typename T2>
+ struct tier {
+ typedef T1 &first_type;
+ typedef T2 &second_type;
+
+ first_type first;
+ second_type second;
+
+ tier(first_type f, second_type s) : first(f), second(s) { }
+ tier& operator=(const std::pair<T1, T2>& p) {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+ };
+}
+
+template <typename T1, typename T2>
+inline tier<T1, T2> tie(T1& f, T2& s) {
+ return tier<T1, T2>(f, s);
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions for arrays
+//===----------------------------------------------------------------------===//
+
+/// Find where an array ends (for ending iterators)
+/// This returns a pointer to the byte immediately
+/// after the end of an array.
+template<class T, std::size_t N>
+inline T *array_endof(T (&x)[N]) {
+ return x+N;
+}
+
+/// Find the length of an array.
+template<class T, std::size_t N>
+inline size_t array_lengthof(T (&x)[N]) {
+ return N;
+}
+
+/// array_pod_sort_comparator - This is helper function for array_pod_sort,
+/// which just uses operator< on T.
+template<typename T>
+static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
+ if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2))
+ return -1;
+ if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1))
+ return 1;
+ return 0;
+}
+
+/// get_array_pad_sort_comparator - This is an internal helper function used to
+/// get type deduction of T right.
+template<typename T>
+static int (*get_array_pad_sort_comparator(const T &X))
+ (const void*, const void*) {
+ return array_pod_sort_comparator<T>;
+}
+
+
+/// array_pod_sort - This sorts an array with the specified start and end
+/// extent. This is just like std::sort, except that it calls qsort instead of
+/// using an inlined template. qsort is slightly slower than std::sort, but
+/// most sorts are not performance critical in LLVM and std::sort has to be
+/// template instantiated for each type, leading to significant measured code
+/// bloat. This function should generally be used instead of std::sort where
+/// possible.
+///
+/// This function assumes that you have simple POD-like types that can be
+/// compared with operator< and can be moved with memcpy. If this isn't true,
+/// you should use std::sort.
+///
+/// NOTE: If qsort_r were portable, we could allow a custom comparator and
+/// default to std::less.
+template<class IteratorTy>
+static inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
+ // Don't dereference start iterator of empty sequence.
+ if (Start == End) return;
+ qsort(&*Start, End-Start, sizeof(*Start),
+ get_array_pad_sort_comparator(*Start));
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
new file mode 100644
index 0000000000000..d5382954c6332
--- /dev/null
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -0,0 +1,193 @@
+//===- ScopedHashTable.h - A simple scoped hash table ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an efficient scoped hash table, which is useful for
+// things like dominator-based optimizations. This allows clients to do things
+// like this:
+//
+// ScopedHashTable<int, int> HT;
+// {
+// ScopedHashTableScope<int, int> Scope1(HT);
+// HT.insert(0, 0);
+// HT.insert(1, 1);
+// {
+// ScopedHashTableScope<int, int> Scope2(HT);
+// HT.insert(0, 42);
+// }
+// }
+//
+// Looking up the value for "0" in the Scope2 block will return 42. Looking
+// up the value for 0 before 42 is inserted or after Scope2 is popped will
+// return 0.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCOPEDHASHTABLE_H
+#define LLVM_ADT_SCOPEDHASHTABLE_H
+
+#include <cassert>
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+template <typename K, typename V>
+class ScopedHashTable;
+
+template <typename K, typename V>
+class ScopedHashTableVal {
+ ScopedHashTableVal *NextInScope;
+ ScopedHashTableVal *NextForKey;
+ K Key;
+ V Val;
+public:
+ ScopedHashTableVal(ScopedHashTableVal *nextInScope,
+ ScopedHashTableVal *nextForKey, const K &key, const V &val)
+ : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) {
+ }
+
+ const K &getKey() const { return Key; }
+ const V &getValue() const { return Val; }
+ V &getValue() { return Val; }
+
+ ScopedHashTableVal *getNextForKey() { return NextForKey; }
+ const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
+public:
+ ScopedHashTableVal *getNextInScope() { return NextInScope; }
+};
+
+template <typename K, typename V>
+class ScopedHashTableScope {
+ /// HT - The hashtable that we are active for.
+ ScopedHashTable<K, V> &HT;
+
+ /// PrevScope - This is the scope that we are shadowing in HT.
+ ScopedHashTableScope *PrevScope;
+
+ /// LastValInScope - This is the last value that was inserted for this scope
+ /// or null if none have been inserted yet.
+ ScopedHashTableVal<K,V> *LastValInScope;
+ void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
+ ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
+public:
+ ScopedHashTableScope(ScopedHashTable<K, V> &HT);
+ ~ScopedHashTableScope();
+
+private:
+ friend class ScopedHashTable<K, V>;
+ ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; }
+ void setLastValInScope(ScopedHashTableVal<K,V> *Val) { LastValInScope = Val; }
+};
+
+
+template <typename K, typename V>
+class ScopedHashTableIterator {
+ ScopedHashTableVal<K,V> *Node;
+public:
+ ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){}
+
+ V &operator*() const {
+ assert(Node && "Dereference end()");
+ return Node->getValue();
+ }
+ V *operator->() const {
+ return &Node->getValue();
+ }
+
+ bool operator==(const ScopedHashTableIterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const ScopedHashTableIterator &RHS) const {
+ return Node != RHS.Node;
+ }
+
+ inline ScopedHashTableIterator& operator++() { // Preincrement
+ assert(Node && "incrementing past end()");
+ Node = Node->getNextForKey();
+ return *this;
+ }
+ ScopedHashTableIterator operator++(int) { // Postincrement
+ ScopedHashTableIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+
+template <typename K, typename V>
+class ScopedHashTable {
+ DenseMap<K, ScopedHashTableVal<K,V>*> TopLevelMap;
+ ScopedHashTableScope<K, V> *CurScope;
+ ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
+ void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
+ friend class ScopedHashTableScope<K, V>;
+public:
+ ScopedHashTable() : CurScope(0) {}
+ ~ScopedHashTable() {
+ assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
+ }
+
+ void insert(const K &Key, const V &Val) {
+ assert(CurScope && "No scope active!");
+
+ ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key];
+
+ KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(),
+ KeyEntry, Key, Val);
+ CurScope->setLastValInScope(KeyEntry);
+ }
+
+ typedef ScopedHashTableIterator<K, V> iterator;
+
+ iterator end() { return iterator(0); }
+
+ iterator begin(const K &Key) {
+ typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I =
+ TopLevelMap.find(Key);
+ if (I == TopLevelMap.end()) return end();
+ return iterator(I->second);
+ }
+};
+
+/// ScopedHashTableScope ctor - Install this as the current scope for the hash
+/// table.
+template <typename K, typename V>
+ScopedHashTableScope<K, V>::ScopedHashTableScope(ScopedHashTable<K, V> &ht)
+ : HT(ht) {
+ PrevScope = HT.CurScope;
+ HT.CurScope = this;
+ LastValInScope = 0;
+}
+
+template <typename K, typename V>
+ScopedHashTableScope<K, V>::~ScopedHashTableScope() {
+ assert(HT.CurScope == this && "Scope imbalance!");
+ HT.CurScope = PrevScope;
+
+ // Pop and delete all values corresponding to this scope.
+ while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
+ // Pop this value out of the TopLevelMap.
+ if (ThisEntry->getNextForKey() == 0) {
+ assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
+ "Scope imbalance!");
+ HT.TopLevelMap.erase(ThisEntry->getKey());
+ } else {
+ ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
+ assert(KeyEntry == ThisEntry && "Scope imbalance!");
+ KeyEntry = ThisEntry->getNextForKey();
+ }
+
+ // Pop this value out of the scope.
+ LastValInScope = ThisEntry->getNextInScope();
+
+ // Delete this entry.
+ delete ThisEntry;
+ }
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h
new file mode 100644
index 0000000000000..71f5db380f6ea
--- /dev/null
+++ b/include/llvm/ADT/SetOperations.h
@@ -0,0 +1,71 @@
+//===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines generic set operations that may be used on set's of
+// different types, and different element types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETOPERATIONS_H
+#define LLVM_ADT_SETOPERATIONS_H
+
+namespace llvm {
+
+/// set_union(A, B) - Compute A := A u B, return whether A changed.
+///
+template <class S1Ty, class S2Ty>
+bool set_union(S1Ty &S1, const S2Ty &S2) {
+ bool Changed = false;
+
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ if (S1.insert(*SI).second)
+ Changed = true;
+
+ return Changed;
+}
+
+/// set_intersect(A, B) - Compute A := A ^ B
+/// Identical to set_intersection, except that it works on set<>'s and
+/// is nicer to use. Functionally, this iterates through S1, removing
+/// elements that are not contained in S2.
+///
+template <class S1Ty, class S2Ty>
+void set_intersect(S1Ty &S1, const S2Ty &S2) {
+ for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
+ const typename S1Ty::key_type &E = *I;
+ ++I;
+ if (!S2.count(E)) S1.erase(E); // Erase element if not in S2
+ }
+}
+
+/// set_difference(A, B) - Return A - B
+///
+template <class S1Ty, class S2Ty>
+S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {
+ S1Ty Result;
+ for (typename S1Ty::const_iterator SI = S1.begin(), SE = S1.end();
+ SI != SE; ++SI)
+ if (!S2.count(*SI)) // if the element is not in set2
+ Result.insert(*SI);
+ return Result;
+}
+
+/// set_subtract(A, B) - Compute A := A - B
+///
+template <class S1Ty, class S2Ty>
+void set_subtract(S1Ty &S1, const S2Ty &S2) {
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ S1.erase(*SI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
new file mode 100644
index 0000000000000..fab133af4c03b
--- /dev/null
+++ b/include/llvm/ADT/SetVector.h
@@ -0,0 +1,168 @@
+//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a set that has insertion order iteration
+// characteristics. This is useful for keeping a set of things that need to be
+// visited later but in a deterministic order (insertion order). The interface
+// is purposefully minimal.
+//
+// This file defines SetVector and SmallSetVector, which performs no allocations
+// if the SetVector has less than a certain number of elements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETVECTOR_H
+#define LLVM_ADT_SETVECTOR_H
+
+#include "llvm/ADT/SmallSet.h"
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+/// This adapter class provides a way to keep a set of things that also has the
+/// property of a deterministic iteration order. The order of iteration is the
+/// order of insertion.
+/// @brief A vector that has set insertion semantics.
+template <typename T, typename Vector = std::vector<T>,
+ typename Set = SmallSet<T, 16> >
+class SetVector {
+public:
+ typedef T value_type;
+ typedef T key_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef Set set_type;
+ typedef Vector vector_type;
+ typedef typename vector_type::const_iterator iterator;
+ typedef typename vector_type::const_iterator const_iterator;
+ typedef typename vector_type::size_type size_type;
+
+ /// @brief Construct an empty SetVector
+ SetVector() {}
+
+ /// @brief Initialize a SetVector with a range of elements
+ template<typename It>
+ SetVector(It Start, It End) {
+ insert(Start, End);
+ }
+
+ /// @brief Determine if the SetVector is empty or not.
+ bool empty() const {
+ return vector_.empty();
+ }
+
+ /// @brief Determine the number of elements in the SetVector.
+ size_type size() const {
+ return vector_.size();
+ }
+
+ /// @brief Get an iterator to the beginning of the SetVector.
+ iterator begin() {
+ return vector_.begin();
+ }
+
+ /// @brief Get a const_iterator to the beginning of the SetVector.
+ const_iterator begin() const {
+ return vector_.begin();
+ }
+
+ /// @brief Get an iterator to the end of the SetVector.
+ iterator end() {
+ return vector_.end();
+ }
+
+ /// @brief Get a const_iterator to the end of the SetVector.
+ const_iterator end() const {
+ return vector_.end();
+ }
+
+ /// @brief Return the last element of the SetVector.
+ const T &back() const {
+ assert(!empty() && "Cannot call back() on empty SetVector!");
+ return vector_.back();
+ }
+
+ /// @brief Index into the SetVector.
+ const_reference operator[](size_type n) const {
+ assert(n < vector_.size() && "SetVector access out of range!");
+ return vector_[n];
+ }
+
+ /// @returns true iff the element was inserted into the SetVector.
+ /// @brief Insert a new element into the SetVector.
+ bool insert(const value_type &X) {
+ bool result = set_.insert(X);
+ if (result)
+ vector_.push_back(X);
+ return result;
+ }
+
+ /// @brief Insert a range of elements into the SetVector.
+ template<typename It>
+ void insert(It Start, It End) {
+ for (; Start != End; ++Start)
+ if (set_.insert(*Start))
+ vector_.push_back(*Start);
+ }
+
+ /// @brief Remove an item from the set vector.
+ void remove(const value_type& X) {
+ if (set_.erase(X)) {
+ typename vector_type::iterator I =
+ std::find(vector_.begin(), vector_.end(), X);
+ assert(I != vector_.end() && "Corrupted SetVector instances!");
+ vector_.erase(I);
+ }
+ }
+
+
+ /// @returns 0 if the element is not in the SetVector, 1 if it is.
+ /// @brief Count the number of elements of a given key in the SetVector.
+ size_type count(const key_type &key) const {
+ return set_.count(key);
+ }
+
+ /// @brief Completely clear the SetVector
+ void clear() {
+ set_.clear();
+ vector_.clear();
+ }
+
+ /// @brief Remove the last element of the SetVector.
+ void pop_back() {
+ assert(!empty() && "Cannot remove an element from an empty SetVector!");
+ set_.erase(back());
+ vector_.pop_back();
+ }
+
+private:
+ set_type set_; ///< The set.
+ vector_type vector_; ///< The vector.
+};
+
+/// SmallSetVector - A SetVector that performs no allocations if smaller than
+/// a certain size.
+template <typename T, unsigned N>
+class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
+public:
+ SmallSetVector() {}
+
+ /// @brief Initialize a SmallSetVector with a range of elements
+ template<typename It>
+ SmallSetVector(It Start, It End) {
+ this->insert(Start, End);
+ }
+};
+
+} // End llvm namespace
+
+// vim: sw=2 ai
+#endif
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
new file mode 100644
index 0000000000000..a189de2c2279d
--- /dev/null
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -0,0 +1,284 @@
+//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallPtrSet class. See the doxygen comment for
+// SmallPtrSetImpl for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLPTRSET_H
+#define LLVM_ADT_SMALLPTRSET_H
+
+#include <cassert>
+#include <cstring>
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+
+namespace llvm {
+
+class SmallPtrSetIteratorImpl;
+
+/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one
+/// for small and one for large sets.
+///
+/// Small sets use an array of pointers allocated in the SmallPtrSet object,
+/// which is treated as a simple array of pointers. When a pointer is added to
+/// the set, the array is scanned to see if the element already exists, if not
+/// the element is 'pushed back' onto the array. If we run out of space in the
+/// array, we grow into the 'large set' case. SmallSet should be used when the
+/// sets are often small. In this case, no memory allocation is used, and only
+/// light-weight and cache-efficient scanning is used.
+///
+/// Large sets use a classic exponentially-probed hash table. Empty buckets are
+/// represented with an illegal pointer value (-1) to allow null pointers to be
+/// inserted. Tombstones are represented with another illegal pointer value
+/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
+/// more. When this happens, the table is doubled in size.
+///
+class SmallPtrSetImpl {
+ friend class SmallPtrSetIteratorImpl;
+protected:
+ /// CurArray - This is the current set of buckets. If it points to
+ /// SmallArray, then the set is in 'small mode'.
+ const void **CurArray;
+ /// CurArraySize - The allocated size of CurArray, always a power of two.
+ /// Note that CurArray points to an array that has CurArraySize+1 elements in
+ /// it, so that the end iterator actually points to valid memory.
+ unsigned CurArraySize;
+
+ // If small, this is # elts allocated consequtively
+ unsigned NumElements;
+ unsigned NumTombstones;
+ const void *SmallArray[1]; // Must be last ivar.
+
+ // Helper to copy construct a SmallPtrSet.
+ SmallPtrSetImpl(const SmallPtrSetImpl& that);
+ explicit SmallPtrSetImpl(unsigned SmallSize) {
+ assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
+ "Initial size must be a power of two!");
+ CurArray = &SmallArray[0];
+ CurArraySize = SmallSize;
+ // The end pointer, always valid, is set to a valid element to help the
+ // iterator.
+ CurArray[SmallSize] = 0;
+ clear();
+ }
+ ~SmallPtrSetImpl();
+
+public:
+ bool empty() const { return size() == 0; }
+ unsigned size() const { return NumElements; }
+
+ void clear() {
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
+ return shrink_and_clear();
+
+ // Fill the array with empty markers.
+ memset(CurArray, -1, CurArraySize*sizeof(void*));
+ NumElements = 0;
+ NumTombstones = 0;
+ }
+
+protected:
+ static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
+ static void *getEmptyMarker() {
+ // Note that -1 is chosen to make clear() efficiently implementable with
+ // memset and because it's not a valid pointer value.
+ return reinterpret_cast<void*>(-1);
+ }
+
+ /// 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
+ /// derived class can check that the right type of pointer is passed in.
+ bool insert_imp(const void * Ptr);
+
+ /// erase_imp - If the set contains the specified pointer, remove it and
+ /// 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
+ /// in.
+ bool erase_imp(const void * Ptr);
+
+ bool count_imp(const void * Ptr) const {
+ if (isSmall()) {
+ // Linear search for the item.
+ for (const void *const *APtr = SmallArray,
+ *const *E = SmallArray+NumElements; APtr != E; ++APtr)
+ if (*APtr == Ptr)
+ return true;
+ return false;
+ }
+
+ // Big set case.
+ return *FindBucketFor(Ptr) == Ptr;
+ }
+
+private:
+ bool isSmall() const { return CurArray == &SmallArray[0]; }
+
+ unsigned Hash(const void *Ptr) const {
+ return static_cast<unsigned>(((uintptr_t)Ptr >> 4) & (CurArraySize-1));
+ }
+ const void * const *FindBucketFor(const void *Ptr) const;
+ void shrink_and_clear();
+
+ /// Grow - Allocate a larger backing store for the buckets and move it over.
+ void Grow();
+
+ void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
+protected:
+ void CopyFrom(const SmallPtrSetImpl &RHS);
+};
+
+/// SmallPtrSetIteratorImpl - This is the common base class shared between all
+/// instances of SmallPtrSetIterator.
+class SmallPtrSetIteratorImpl {
+protected:
+ const void *const *Bucket;
+public:
+ explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
+ AdvanceIfNotValid();
+ }
+
+ bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket == RHS.Bucket;
+ }
+ bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket != RHS.Bucket;
+ }
+
+protected:
+ /// 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
+ /// valid.
+ void AdvanceIfNotValid() {
+ while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImpl::getTombstoneMarker())
+ ++Bucket;
+ }
+};
+
+/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
+template<typename PtrTy>
+class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
+ typedef PointerLikeTypeTraits<PtrTy> PtrTraits;
+public:
+ explicit SmallPtrSetIterator(const void *const *BP)
+ : SmallPtrSetIteratorImpl(BP) {}
+
+ // Most methods provided by baseclass.
+
+ const PtrTy operator*() const {
+ return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
+ }
+
+ inline SmallPtrSetIterator& operator++() { // Preincrement
+ ++Bucket;
+ AdvanceIfNotValid();
+ return *this;
+ }
+
+ SmallPtrSetIterator operator++(int) { // Postincrement
+ SmallPtrSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+/// NextPowerOfTwo - This is a helper template that rounds N up to the next
+/// power of two.
+template<unsigned N>
+struct NextPowerOfTwo;
+
+/// NextPowerOfTwoH - If N is not a power of two, increase it. This is a helper
+/// template used to implement NextPowerOfTwo.
+template<unsigned N, bool isPowerTwo>
+struct NextPowerOfTwoH {
+ enum { Val = N };
+};
+template<unsigned N>
+struct NextPowerOfTwoH<N, false> {
+ enum {
+ // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets
+ // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
+ Val = NextPowerOfTwo<(N|(N-1)) + 1>::Val
+ };
+};
+
+template<unsigned N>
+struct NextPowerOfTwo {
+ enum { Val = NextPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
+};
+
+
+/// SmallPtrSet - This class implements a set which is optimizer for holding
+/// SmallSize or less elements. This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two. See the comments above
+/// SmallPtrSetImpl for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl {
+ // Make sure that SmallSize is a power of two, round up if not.
+ enum { SmallSizePowTwo = NextPowerOfTwo<SmallSize>::Val };
+ void *SmallArray[SmallSizePowTwo];
+ typedef PointerLikeTypeTraits<PtrType> PtrTraits;
+public:
+ SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {}
+ SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E)
+ : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {
+ insert(I, E);
+ }
+
+ /// insert - This returns true if the pointer was new to the set, false if it
+ /// was already in the set.
+ bool insert(PtrType Ptr) {
+ return insert_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ /// erase - If the set contains the specified pointer, remove it and return
+ /// true, otherwise return false.
+ bool erase(PtrType Ptr) {
+ return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ /// count - Return true if the specified pointer is in the set.
+ bool count(PtrType Ptr) const {
+ return count_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+ typedef SmallPtrSetIterator<PtrType> iterator;
+ typedef SmallPtrSetIterator<PtrType> const_iterator;
+ inline iterator begin() const {
+ return iterator(CurArray);
+ }
+ inline iterator end() const {
+ return iterator(CurArray+CurArraySize);
+ }
+
+ // Allow assignment from any smallptrset with the same element type even if it
+ // doesn't have the same smallsize.
+ const SmallPtrSet<PtrType, SmallSize>&
+ operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
+ CopyFrom(RHS);
+ return *this;
+ }
+
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
new file mode 100644
index 0000000000000..caaa96c045f73
--- /dev/null
+++ b/include/llvm/ADT/SmallSet.h
@@ -0,0 +1,118 @@
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSET_H
+#define LLVM_ADT_SMALLSET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+
+namespace llvm {
+
+/// SmallSet - This maintains a set of unique values, optimizing for the case
+/// when the set is small (less than N). In this case, the set can be
+/// maintained with no mallocs. If the set gets large, we expand to using an
+/// std::set to maintain reasonable lookup times.
+///
+/// Note that this set does not provide a way to iterate over members in the
+/// set.
+template <typename T, unsigned N>
+class SmallSet {
+ /// Use a SmallVector to hold the elements here (even though it will never
+ /// reach it's 'large' stage) to avoid calling the default ctors of elements
+ /// we will never use.
+ SmallVector<T, N> Vector;
+ std::set<T> Set;
+ typedef typename SmallVector<T, N>::const_iterator VIterator;
+ typedef typename SmallVector<T, N>::iterator mutable_iterator;
+public:
+ SmallSet() {}
+
+ bool empty() const { return Vector.empty() && Set.empty(); }
+ unsigned size() const {
+ return isSmall() ? Vector.size() : Set.size();
+ }
+
+ /// count - Return true if the element is in the set.
+ bool count(const T &V) const {
+ if (isSmall()) {
+ // Since the collection is small, just do a linear search.
+ return vfind(V) != Vector.end();
+ } else {
+ return Set.count(V);
+ }
+ }
+
+ /// insert - Insert an element into the set if it isn't already there.
+ bool insert(const T &V) {
+ if (!isSmall())
+ return Set.insert(V).second;
+
+ VIterator I = vfind(V);
+ if (I != Vector.end()) // Don't reinsert if it already exists.
+ return false;
+ if (Vector.size() < N) {
+ Vector.push_back(V);
+ return true;
+ }
+
+ // Otherwise, grow from vector to set.
+ while (!Vector.empty()) {
+ Set.insert(Vector.back());
+ Vector.pop_back();
+ }
+ Set.insert(V);
+ return true;
+ }
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+ bool erase(const T &V) {
+ if (!isSmall())
+ return Set.erase(V);
+ for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V) {
+ Vector.erase(I);
+ return true;
+ }
+ return false;
+ }
+
+ void clear() {
+ Vector.clear();
+ Set.clear();
+ }
+private:
+ bool isSmall() const { return Set.empty(); }
+
+ VIterator vfind(const T &V) const {
+ for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V)
+ return I;
+ return Vector.end();
+ }
+};
+
+/// If this set is of pointer values, transparently switch over to using
+/// SmallPtrSet for performance.
+template <typename PointeeType, unsigned N>
+class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
new file mode 100644
index 0000000000000..687fa2d26e246
--- /dev/null
+++ b/include/llvm/ADT/SmallString.h
@@ -0,0 +1,109 @@
+//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallString class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSTRING_H
+#define LLVM_ADT_SMALLSTRING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+
+namespace llvm {
+
+/// SmallString - A SmallString is just a SmallVector with methods and accessors
+/// that make it work better as a string (e.g. operator+ etc).
+template<unsigned InternalLen>
+class SmallString : public SmallVector<char, InternalLen> {
+public:
+ // Default ctor - Initialize to empty.
+ SmallString() {}
+
+ // Initialize with a range.
+ template<typename ItTy>
+ SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
+
+ // Copy ctor.
+ SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
+
+
+ // Extra methods.
+ const char *c_str() const {
+ SmallString *This = const_cast<SmallString*>(this);
+ // Ensure that there is a \0 at the end of the string.
+ This->reserve(this->size()+1);
+ This->End[0] = 0;
+ return this->begin();
+ }
+
+ // Extra operators.
+ const SmallString &operator=(const char *RHS) {
+ this->clear();
+ return *this += RHS;
+ }
+
+ SmallString &operator+=(const char *RHS) {
+ this->append(RHS, RHS+strlen(RHS));
+ return *this;
+ }
+ SmallString &operator+=(char C) {
+ this->push_back(C);
+ return *this;
+ }
+
+ SmallString &append_uint_32(uint32_t N) {
+ char Buffer[20];
+ char *BufPtr = Buffer+20;
+
+ if (N == 0) *--BufPtr = '0'; // Handle special case.
+
+ while (N) {
+ *--BufPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+ this->append(BufPtr, Buffer+20);
+ return *this;
+ }
+
+ SmallString &append_uint(uint64_t N) {
+ if (N == uint32_t(N))
+ return append_uint_32(uint32_t(N));
+
+ char Buffer[40];
+ char *BufPtr = Buffer+40;
+
+ if (N == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (N) {
+ *--BufPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+
+ this->append(BufPtr, Buffer+40);
+ return *this;
+ }
+
+ SmallString &append_sint(int64_t N) {
+ // TODO, wrong for minint64.
+ if (N < 0) {
+ this->push_back('-');
+ N = -N;
+ }
+ return append_uint(N);
+ }
+
+};
+
+
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
new file mode 100644
index 0000000000000..f59a438d3eb4f
--- /dev/null
+++ b/include/llvm/ADT/SmallVector.h
@@ -0,0 +1,617 @@
+//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLVECTOR_H
+#define LLVM_ADT_SMALLVECTOR_H
+
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <memory>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+// is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace llvm {
+
+/// SmallVectorImpl - This class consists of common code factored out of the
+/// SmallVector class to reduce code duplication based on the SmallVector 'N'
+/// template parameter.
+template <typename T>
+class SmallVectorImpl {
+protected:
+ T *Begin, *End, *Capacity;
+
+ // 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
+ // something else. An array of char would work great, but might not be
+ // aligned sufficiently. Instead, we either use GCC extensions, or some
+ // number of union instances for the space, which guarantee maximal alignment.
+protected:
+#ifdef __GNUC__
+ typedef char U;
+ U FirstEl __attribute__((aligned));
+#else
+ union U {
+ double D;
+ long double LD;
+ long long L;
+ void *P;
+ } FirstEl;
+#endif
+ // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
+public:
+ // Default ctor - Initialize to empty.
+ explicit SmallVectorImpl(unsigned N)
+ : Begin(reinterpret_cast<T*>(&FirstEl)),
+ End(reinterpret_cast<T*>(&FirstEl)),
+ Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
+ }
+
+ ~SmallVectorImpl() {
+ // Destroy the constructed elements in the vector.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ operator delete(Begin);
+ }
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+
+ bool empty() const { return Begin == End; }
+ size_type size() const { return End-Begin; }
+ size_type max_size() const { return size_type(-1) / sizeof(T); }
+
+ // forward iterator creation methods.
+ iterator begin() { return Begin; }
+ const_iterator begin() const { return Begin; }
+ iterator end() { return End; }
+ const_iterator end() const { return End; }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+ reference operator[](unsigned idx) {
+ assert (Begin + idx < End);
+ return Begin[idx];
+ }
+ const_reference operator[](unsigned idx) const {
+ assert (Begin + idx < End);
+ return Begin[idx];
+ }
+
+ reference front() {
+ return begin()[0];
+ }
+ const_reference front() const {
+ return begin()[0];
+ }
+
+ reference back() {
+ return end()[-1];
+ }
+ const_reference back() const {
+ return end()[-1];
+ }
+
+ void push_back(const_reference Elt) {
+ if (End < Capacity) {
+ Retry:
+ new (End) T(Elt);
+ ++End;
+ return;
+ }
+ grow();
+ goto Retry;
+ }
+
+ void pop_back() {
+ --End;
+ End->~T();
+ }
+
+ T pop_back_val() {
+ T Result = back();
+ pop_back();
+ return Result;
+ }
+
+ void clear() {
+ destroy_range(Begin, End);
+ End = Begin;
+ }
+
+ void resize(unsigned N) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, T());
+ End = Begin+N;
+ }
+ }
+
+ void resize(unsigned N, const T &NV) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, NV);
+ End = Begin+N;
+ }
+ }
+
+ void reserve(unsigned N) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ }
+
+ void swap(SmallVectorImpl &RHS);
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(in_iter in_start, in_iter in_end) {
+ size_type NumInputs = std::distance(in_start, in_end);
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(Capacity-End))
+ grow(size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_copy(in_start, in_end, End);
+ End += NumInputs;
+ }
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ void append(size_type NumInputs, const T &Elt) {
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(Capacity-End))
+ grow(size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_fill_n(End, NumInputs, Elt);
+ End += NumInputs;
+ }
+
+ void assign(unsigned NumElts, const T &Elt) {
+ clear();
+ if (unsigned(Capacity-Begin) < NumElts)
+ grow(NumElts);
+ End = Begin+NumElts;
+ construct_range(Begin, End, Elt);
+ }
+
+ iterator erase(iterator I) {
+ iterator N = I;
+ // Shift all elts down one.
+ std::copy(I+1, End, I);
+ // Drop the last elt.
+ pop_back();
+ return(N);
+ }
+
+ iterator erase(iterator S, iterator E) {
+ iterator N = S;
+ // Shift all elts down.
+ iterator I = std::copy(E, End, S);
+ // Drop the last elts.
+ destroy_range(I, End);
+ End = I;
+ return(N);
+ }
+
+ iterator insert(iterator I, const T &Elt) {
+ if (I == End) { // Important special case for empty vector.
+ push_back(Elt);
+ return end()-1;
+ }
+
+ if (End < Capacity) {
+ Retry:
+ new (End) T(back());
+ ++End;
+ // Push everything else over.
+ std::copy_backward(I, End-1, End);
+ *I = Elt;
+ return I;
+ }
+ size_t EltNo = I-Begin;
+ grow();
+ I = Begin+EltNo;
+ goto Retry;
+ }
+
+ iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
+ if (I == End) { // Important special case for empty vector.
+ append(NumToInsert, Elt);
+ return end()-1;
+ }
+
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I-begin();
+
+ // Ensure there is enough space.
+ reserve(static_cast<unsigned>(size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(end()-I) >= NumToInsert) {
+ T *OldEnd = End;
+ append(End-NumToInsert, End);
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::fill_n(I, NumToInsert, Elt);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = End;
+ End += NumToInsert;
+ size_t NumOverwritten = OldEnd-I;
+ std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::fill_n(I, NumOverwritten, Elt);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+ return I;
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ if (I == End) { // Important special case for empty vector.
+ append(From, To);
+ return end()-1;
+ }
+
+ size_t NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I-begin();
+
+ // Ensure there is enough space.
+ reserve(static_cast<unsigned>(size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(end()-I) >= NumToInsert) {
+ T *OldEnd = End;
+ append(End-NumToInsert, End);
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::copy(From, To, I);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = End;
+ End += NumToInsert;
+ size_t NumOverwritten = OldEnd-I;
+ std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::copy(From, From+NumOverwritten, I);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_copy(From+NumOverwritten, To, OldEnd);
+ return I;
+ }
+
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ pointer data() {
+ return pointer(Begin);
+ }
+
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ const_pointer data() const {
+ return const_pointer(Begin);
+ }
+
+ const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+
+ bool operator==(const SmallVectorImpl &RHS) const {
+ if (size() != RHS.size()) return false;
+ for (T *This = Begin, *That = RHS.Begin, *E = Begin+size();
+ This != E; ++This, ++That)
+ if (*This != *That)
+ return false;
+ return true;
+ }
+ bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); }
+
+ bool operator<(const SmallVectorImpl &RHS) const {
+ return std::lexicographical_compare(begin(), end(),
+ RHS.begin(), RHS.end());
+ }
+
+private:
+ /// isSmall - Return true if this is a smallvector which has not had dynamic
+ /// memory allocated for it.
+ bool isSmall() const {
+ return static_cast<const void*>(Begin) ==
+ static_cast<const void*>(&FirstEl);
+ }
+
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(size_type MinSize = 0);
+
+ void construct_range(T *S, T *E, const T &Elt) {
+ for (; S != E; ++S)
+ new (S) T(Elt);
+ }
+
+ void destroy_range(T *S, T *E) {
+ while (S != E) {
+ --E;
+ E->~T();
+ }
+ }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void SmallVectorImpl<T>::grow(size_t MinSize) {
+ size_t CurCapacity = Capacity-Begin;
+ size_t CurSize = size();
+ size_t NewCapacity = 2*CurCapacity;
+ if (NewCapacity < MinSize)
+ NewCapacity = MinSize;
+ T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
+
+ // Copy the elements over.
+ if (is_class<T>::value)
+ std::uninitialized_copy(Begin, End, NewElts);
+ else
+ // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+ memcpy(NewElts, Begin, CurSize * sizeof(T));
+
+ // Destroy the original elements.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ operator delete(Begin);
+
+ Begin = NewElts;
+ End = NewElts+CurSize;
+ Capacity = Begin+NewCapacity;
+}
+
+template <typename T>
+void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
+ if (this == &RHS) return;
+
+ // We can only avoid copying elements if neither vector is small.
+ if (!isSmall() && !RHS.isSmall()) {
+ std::swap(Begin, RHS.Begin);
+ std::swap(End, RHS.End);
+ std::swap(Capacity, RHS.Capacity);
+ return;
+ }
+ if (RHS.size() > size_type(Capacity-Begin))
+ grow(RHS.size());
+ if (size() > size_type(RHS.Capacity-RHS.begin()))
+ RHS.grow(size());
+
+ // Swap the shared elements.
+ size_t NumShared = size();
+ if (NumShared > RHS.size()) NumShared = RHS.size();
+ for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
+ std::swap(Begin[i], RHS[i]);
+
+ // Copy over the extra elts.
+ if (size() > RHS.size()) {
+ size_t EltDiff = size() - RHS.size();
+ std::uninitialized_copy(Begin+NumShared, End, RHS.End);
+ RHS.End += EltDiff;
+ destroy_range(Begin+NumShared, End);
+ End = Begin+NumShared;
+ } else if (RHS.size() > size()) {
+ size_t EltDiff = RHS.size() - size();
+ std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
+ End += EltDiff;
+ destroy_range(RHS.Begin+NumShared, RHS.End);
+ RHS.End = RHS.Begin+NumShared;
+ }
+}
+
+template <typename T>
+const SmallVectorImpl<T> &
+SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
+ // Avoid self-assignment.
+ if (this == &RHS) return *this;
+
+ // If we already have sufficient space, assign the common elements, then
+ // destroy any excess.
+ unsigned RHSSize = unsigned(RHS.size());
+ unsigned CurSize = unsigned(size());
+ if (CurSize >= RHSSize) {
+ // Assign common elements.
+ iterator NewEnd;
+ if (RHSSize)
+ NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+ else
+ NewEnd = Begin;
+
+ // Destroy excess elements.
+ destroy_range(NewEnd, End);
+
+ // Trim.
+ End = NewEnd;
+ return *this;
+ }
+
+ // If we have to grow to have enough elements, destroy the current elements.
+ // This allows us to avoid copying them during the grow.
+ if (unsigned(Capacity-Begin) < RHSSize) {
+ // Destroy current elements.
+ destroy_range(Begin, End);
+ End = Begin;
+ CurSize = 0;
+ grow(RHSSize);
+ } else if (CurSize) {
+ // Otherwise, use assignment for the already-constructed elements.
+ std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
+ }
+
+ // Copy construct the new elements in place.
+ std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
+
+ // Set end.
+ End = Begin+RHSSize;
+ return *this;
+}
+
+/// 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
+/// in-place, which allows it to avoid heap allocation when the actual number of
+/// elements is below that threshold. This allows normal "small" cases to be
+/// fast without losing generality for large inputs.
+///
+/// Note that this does not attempt to be exception safe.
+///
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+ /// InlineElts - These are 'N-1' elements that are stored inline in the body
+ /// of the vector. The extra '1' element is stored in SmallVectorImpl.
+ typedef typename SmallVectorImpl<T>::U U;
+ enum {
+ // MinUs - The number of U's require to cover N T's.
+ MinUs = (static_cast<unsigned int>(sizeof(T))*N +
+ static_cast<unsigned int>(sizeof(U)) - 1) /
+ static_cast<unsigned int>(sizeof(U)),
+
+ // 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
+ // having a zero-element array.
+ NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
+
+ // NumTsAvailable - The number of T's we actually have space for, which may
+ // be more than N due to rounding.
+ NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
+ static_cast<unsigned int>(sizeof(T))
+ };
+ U InlineElts[NumInlineEltsElts];
+public:
+ SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
+ }
+
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(NumTsAvailable) {
+ this->reserve(Size);
+ while (Size--)
+ this->push_back(Value);
+ }
+
+ template<typename ItTy>
+ SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
+ this->append(S, E);
+ }
+
+ SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
+ if (!RHS.empty())
+ SmallVectorImpl<T>::operator=(RHS);
+ }
+
+ const SmallVector &operator=(const SmallVector &RHS) {
+ SmallVectorImpl<T>::operator=(RHS);
+ return *this;
+ }
+
+};
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T>
+ inline void
+ swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
+ LHS.swap(RHS);
+ }
+
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T, unsigned N>
+ inline void
+ swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
new file mode 100644
index 0000000000000..6230135131a7c
--- /dev/null
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -0,0 +1,901 @@
+//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- C++ -*- ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SparseBitVector class. See the doxygen comment for
+// SparseBitVector for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEBITVECTOR_H
+#define LLVM_ADT_SPARSEBITVECTOR_H
+
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/ilist.h"
+
+namespace llvm {
+
+/// SparseBitVector is an implementation of a bitvector that is sparse by only
+/// storing the elements that have non-zero bits set. In order to make this
+/// fast for the most common cases, SparseBitVector is implemented as a linked
+/// list of SparseBitVectorElements. We maintain a pointer to the last
+/// SparseBitVectorElement accessed (in the form of a list iterator), in order
+/// to make multiple in-order test/set constant time after the first one is
+/// executed. Note that using vectors to store SparseBitVectorElement's does
+/// not work out very well because it causes insertion in the middle to take
+/// enormous amounts of time with a large amount of bits. Other structures that
+/// have better worst cases for insertion in the middle (various balanced trees,
+/// etc) do not perform as well in practice as a linked list with this iterator
+/// kept up to date. They are also significantly more memory intensive.
+
+
+template <unsigned ElementSize = 128>
+struct SparseBitVectorElement
+ : ilist_node<SparseBitVectorElement<ElementSize> > {
+public:
+ typedef unsigned long BitWord;
+ enum {
+ BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
+ BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
+ BITS_PER_ELEMENT = ElementSize
+ };
+
+private:
+ // Index of Element in terms of where first bit starts.
+ unsigned ElementIndex;
+ BitWord Bits[BITWORDS_PER_ELEMENT];
+ // Needed for sentinels
+ friend struct ilist_sentinel_traits<SparseBitVectorElement>;
+ SparseBitVectorElement() {
+ ElementIndex = ~0U;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+public:
+ explicit SparseBitVectorElement(unsigned Idx) {
+ ElementIndex = Idx;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+ // Comparison.
+ bool operator==(const SparseBitVectorElement &RHS) const {
+ if (ElementIndex != RHS.ElementIndex)
+ return false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+ return true;
+ }
+
+ bool operator!=(const SparseBitVectorElement &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Return the bits that make up word Idx in our element.
+ BitWord word(unsigned Idx) const {
+ assert (Idx < BITWORDS_PER_ELEMENT);
+ return Bits[Idx];
+ }
+
+ unsigned index() const {
+ return ElementIndex;
+ }
+
+ bool empty() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i])
+ return false;
+ return true;
+ }
+
+ void set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ void reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ }
+
+ bool test(unsigned Idx) const {
+ return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
+ }
+
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ return NumBits;
+ }
+
+ /// find_first - Returns the index of the first set bit.
+ int find_first() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ assert(0 && "Illegal empty element");
+ return 0; // Not reached
+ }
+
+ /// find_next - Returns the index of the next set bit starting from the
+ /// "Curr" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Curr) const {
+ if (Curr >= BITS_PER_ELEMENT)
+ return -1;
+
+ unsigned WordPos = Curr / BITWORD_SIZE;
+ unsigned BitPos = Curr % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ assert (WordPos <= BITWORDS_PER_ELEMENT
+ && "Word Position outside of element");
+
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+ else if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ else
+ assert(0 && "Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ // Union this element with RHS and return true if this one changed.
+ bool unionWith(const SparseBitVectorElement &RHS) {
+ bool changed = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] |= RHS.Bits[i];
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ return changed;
+ }
+
+ // Return true if we have any bits in common with RHS
+ bool intersects(const SparseBitVectorElement &RHS) const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ if (RHS.Bits[i] & Bits[i])
+ return true;
+ }
+ return false;
+ }
+
+ // Intersect this Element with RHS and return true if this one changed.
+ // BecameZero is set to true if this element became all-zero bits.
+ bool intersectWith(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Intersect this Element with the complement of RHS and return true if this
+ // one changed. BecameZero is set to true if this element became all-zero
+ // bits.
+ bool intersectWithComplement(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= ~RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Three argument version of intersectWithComplement that intersects
+ // RHS1 & ~RHS2 into this element
+ void intersectWithComplement(const SparseBitVectorElement &RHS1,
+ const SparseBitVectorElement &RHS2,
+ bool &BecameZero) {
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+ }
+ BecameZero = allzero;
+ }
+
+ // Get a hash value for this element;
+ uint64_t getHashValue() const {
+ uint64_t HashVal = 0;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ HashVal ^= Bits[i];
+ }
+ return HashVal;
+ }
+};
+
+template <unsigned ElementSize = 128>
+class SparseBitVector {
+ typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
+ typedef typename ElementList::iterator ElementListIter;
+ typedef typename ElementList::const_iterator ElementListConstIter;
+ enum {
+ BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
+ };
+
+ // Pointer to our current Element.
+ ElementListIter CurrElementIter;
+ ElementList Elements;
+
+ // This is like std::lower_bound, except we do linear searching from the
+ // current position.
+ ElementListIter FindLowerBound(unsigned ElementIndex) {
+
+ if (Elements.empty()) {
+ CurrElementIter = Elements.begin();
+ return Elements.begin();
+ }
+
+ // Make sure our current iterator is valid.
+ if (CurrElementIter == Elements.end())
+ --CurrElementIter;
+
+ // Search from our current iterator, either backwards or forwards,
+ // depending on what element we are looking for.
+ ElementListIter ElementIter = CurrElementIter;
+ if (CurrElementIter->index() == ElementIndex) {
+ return ElementIter;
+ } else if (CurrElementIter->index() > ElementIndex) {
+ while (ElementIter != Elements.begin()
+ && ElementIter->index() > ElementIndex)
+ --ElementIter;
+ } else {
+ while (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ++ElementIter;
+ }
+ CurrElementIter = ElementIter;
+ return ElementIter;
+ }
+
+ // Iterator to walk set bits in the bitmap. This iterator is a lot uglier
+ // than it would be, in order to be efficient.
+ class SparseBitVectorIterator {
+ private:
+ bool AtEnd;
+
+ const SparseBitVector<ElementSize> *BitVector;
+
+ // Current element inside of bitmap.
+ ElementListConstIter Iter;
+
+ // Current bit number inside of our bitmap.
+ unsigned BitNumber;
+
+ // Current word number inside of our element.
+ unsigned WordNumber;
+
+ // Current bits from the element.
+ typename SparseBitVectorElement<ElementSize>::BitWord Bits;
+
+ // Move our iterator to the first non-zero bit in the bitmap.
+ void AdvanceToFirstNonZero() {
+ if (AtEnd)
+ return;
+ if (BitVector->Elements.empty()) {
+ AtEnd = true;
+ return;
+ }
+ Iter = BitVector->Elements.begin();
+ BitNumber = Iter->index() * ElementSize;
+ unsigned BitPos = Iter->find_first();
+ BitNumber += BitPos;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= BitPos % BITWORD_SIZE;
+ }
+
+ // Move our iterator to the next non-zero bit.
+ void AdvanceToNextNonZero() {
+ if (AtEnd)
+ return;
+
+ while (Bits && !(Bits & 1)) {
+ Bits >>= 1;
+ BitNumber += 1;
+ }
+
+ // See if we ran out of Bits in this word.
+ if (!Bits) {
+ int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
+ // If we ran out of set bits in this element, move to next element.
+ if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
+ ++Iter;
+ WordNumber = 0;
+
+ // We may run out of elements in the bitmap.
+ if (Iter == BitVector->Elements.end()) {
+ AtEnd = true;
+ return;
+ }
+ // Set up for next non zero word in bitmap.
+ BitNumber = Iter->index() * ElementSize;
+ NextSetBitNumber = Iter->find_first();
+ BitNumber += NextSetBitNumber;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ } else {
+ WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ BitNumber = Iter->index() * ElementSize;
+ BitNumber += NextSetBitNumber;
+ }
+ }
+ }
+ public:
+ // Preincrement.
+ inline SparseBitVectorIterator& operator++() {
+ ++BitNumber;
+ Bits >>= 1;
+ AdvanceToNextNonZero();
+ return *this;
+ }
+
+ // Postincrement.
+ inline SparseBitVectorIterator operator++(int) {
+ SparseBitVectorIterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Return the current set bit number.
+ unsigned operator*() const {
+ return BitNumber;
+ }
+
+ bool operator==(const SparseBitVectorIterator &RHS) const {
+ // If they are both at the end, ignore the rest of the fields.
+ if (AtEnd && RHS.AtEnd)
+ return true;
+ // Otherwise they are the same if they have the same bit number and
+ // bitmap.
+ return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
+ }
+ bool operator!=(const SparseBitVectorIterator &RHS) const {
+ return !(*this == RHS);
+ }
+ SparseBitVectorIterator(): BitVector(NULL) {
+ }
+
+
+ SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
+ bool end = false):BitVector(RHS) {
+ Iter = BitVector->Elements.begin();
+ BitNumber = 0;
+ Bits = 0;
+ WordNumber = ~0;
+ AtEnd = end;
+ AdvanceToFirstNonZero();
+ }
+ };
+public:
+ typedef SparseBitVectorIterator iterator;
+
+ SparseBitVector () {
+ CurrElementIter = Elements.begin ();
+ }
+
+ ~SparseBitVector() {
+ }
+
+ // SparseBitVector copy ctor.
+ SparseBitVector(const SparseBitVector &RHS) {
+ ElementListConstIter ElementIter = RHS.Elements.begin();
+ while (ElementIter != RHS.Elements.end()) {
+ Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+ ++ElementIter;
+ }
+
+ CurrElementIter = Elements.begin ();
+ }
+
+ // Clear.
+ void clear() {
+ Elements.clear();
+ }
+
+ // Assignment
+ SparseBitVector& operator=(const SparseBitVector& RHS) {
+ Elements.clear();
+
+ ElementListConstIter ElementIter = RHS.Elements.begin();
+ while (ElementIter != RHS.Elements.end()) {
+ Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+ ++ElementIter;
+ }
+
+ CurrElementIter = Elements.begin ();
+
+ return *this;
+ }
+
+ // Test, Reset, and Set a bit in the bitmap.
+ bool test(unsigned Idx) {
+ if (Elements.empty())
+ return false;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return false;
+ return ElementIter->test(Idx % ElementSize);
+ }
+
+ void reset(unsigned Idx) {
+ if (Elements.empty())
+ return;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return;
+ ElementIter->reset(Idx % ElementSize);
+
+ // When the element is zeroed out, delete it.
+ if (ElementIter->empty()) {
+ ++CurrElementIter;
+ Elements.erase(ElementIter);
+ }
+ }
+
+ void set(unsigned Idx) {
+ unsigned ElementIndex = Idx / ElementSize;
+ SparseBitVectorElement<ElementSize> *Element;
+ ElementListIter ElementIter;
+ if (Elements.empty()) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ ElementIter = Elements.insert(Elements.end(), Element);
+
+ } else {
+ ElementIter = FindLowerBound(ElementIndex);
+
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ // We may have hit the beginning of our SparseBitVector, in which case,
+ // we may need to insert right after this element, which requires moving
+ // the current iterator forward one, because insert does insert before.
+ if (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ElementIter = Elements.insert(++ElementIter, Element);
+ else
+ ElementIter = Elements.insert(ElementIter, Element);
+ }
+ }
+ CurrElementIter = ElementIter;
+
+ ElementIter->set(Idx % ElementSize);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ bool operator!=(const SparseBitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool operator==(const SparseBitVector &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
+ ++Iter1, ++Iter2) {
+ if (*Iter1 != *Iter2)
+ return false;
+ }
+ return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
+ }
+
+ // Union our bitmap with the RHS and return true if we changed.
+ bool operator|=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If RHS is empty, we are done
+ if (RHS.Elements.empty())
+ return false;
+
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
+ Elements.insert(Iter1,
+ new SparseBitVectorElement<ElementSize>(*Iter2));
+ ++Iter2;
+ changed = true;
+ } else if (Iter1->index() == Iter2->index()) {
+ changed |= Iter1->unionWith(*Iter2);
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the RHS and return true if ours changed.
+ bool operator&=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWith(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ }
+ }
+ Elements.erase(Iter1, Elements.end());
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the complement of the RHS and return true
+ // if ours changed.
+ bool intersectWithComplement(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If either our bitmap or RHS is empty, we are done
+ if (Elements.empty() || RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
+ return intersectWithComplement(*RHS);
+ }
+
+
+ // Three argument version of intersectWithComplement.
+ // Result of RHS1 & ~RHS2 is stored into this bitmap.
+ void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
+ const SparseBitVector<ElementSize> &RHS2)
+ {
+ Elements.clear();
+ CurrElementIter = Elements.begin();
+ ElementListConstIter Iter1 = RHS1.Elements.begin();
+ ElementListConstIter Iter2 = RHS2.Elements.begin();
+
+ // If RHS1 is empty, we are done
+ // If RHS2 is empty, we still have to copy RHS1
+ if (RHS1.Elements.empty())
+ return;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS2.Elements.end()) {
+ if (Iter1 == RHS1.Elements.end())
+ return;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero = false;
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(Iter1->index());
+ NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
+ if (!BecameZero) {
+ Elements.push_back(NewElement);
+ }
+ else
+ delete NewElement;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+ }
+
+ // copy the remaining elements
+ while (Iter1 != RHS1.Elements.end()) {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+
+ return;
+ }
+
+ void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
+ const SparseBitVector<ElementSize> *RHS2) {
+ intersectWithComplement(*RHS1, *RHS2);
+ }
+
+ bool intersects(const SparseBitVector<ElementSize> *RHS) const {
+ return intersects(*RHS);
+ }
+
+ // Return true if we share any bits in common with RHS
+ bool intersects(const SparseBitVector<ElementSize> &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting stopping when we hit bits in common.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end())
+ return false;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ if (Iter1->intersects(*Iter2))
+ return true;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ return false;
+ }
+
+ // Return true iff all bits set in this SparseBitVector are
+ // also set in RHS.
+ bool contains(const SparseBitVector<ElementSize> &RHS) const {
+ SparseBitVector<ElementSize> Result(*this);
+ Result &= RHS;
+ return (Result == RHS);
+ }
+
+ // Return the first set bit in the bitmap. Return -1 if no bits are set.
+ int find_first() const {
+ if (Elements.empty())
+ return -1;
+ const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
+ return (First.index() * ElementSize) + First.find_first();
+ }
+
+ // Return true if the SparseBitVector is empty
+ bool empty() const {
+ return Elements.empty();
+ }
+
+ unsigned count() const {
+ unsigned BitCount = 0;
+ for (ElementListConstIter Iter = Elements.begin();
+ Iter != Elements.end();
+ ++Iter)
+ BitCount += Iter->count();
+
+ return BitCount;
+ }
+ iterator begin() const {
+ return iterator(this);
+ }
+
+ iterator end() const {
+ return iterator(this, true);
+ }
+
+ // Get a hash value for this bitmap.
+ uint64_t getHashValue() const {
+ uint64_t HashVal = 0;
+ for (ElementListConstIter Iter = Elements.begin();
+ Iter != Elements.end();
+ ++Iter) {
+ HashVal ^= Iter->index();
+ HashVal ^= Iter->getHashValue();
+ }
+ return HashVal;
+ }
+};
+
+// Convenience functions to allow Or and And without dereferencing in the user
+// code.
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS |= *RHS;
+}
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator|=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator&=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS &= *RHS;
+}
+
+// Convenience functions for infix union, intersection, difference operators.
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator|(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator&(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator-(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result;
+ Result.intersectWithComplement(LHS, RHS);
+ return Result;
+}
+
+
+
+
+// Dump a SparseBitVector to a stream
+template <unsigned ElementSize>
+void dump(const SparseBitVector<ElementSize> &LHS, llvm::OStream &out) {
+ out << "[ ";
+
+ typename SparseBitVector<ElementSize>::iterator bi;
+ for (bi = LHS.begin(); bi != LHS.end(); ++bi) {
+ out << *bi << " ";
+ }
+ out << " ]\n";
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
new file mode 100644
index 0000000000000..537f86637953b
--- /dev/null
+++ b/include/llvm/ADT/Statistic.h
@@ -0,0 +1,75 @@
+//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the 'Statistic' class, which is designed to be an easy way
+// to expose various metrics from passes. These statistics are printed at the
+// end of a run (from llvm_shutdown), when the -stats command line option is
+// passed on the command line.
+//
+// This is useful for reporting information like the number of instructions
+// simplified, optimized or removed by various transformations, like this:
+//
+// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstsKilled;
+//
+// NOTE: Statistics *must* be declared as global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STATISTIC_H
+#define LLVM_ADT_STATISTIC_H
+
+namespace llvm {
+
+class Statistic {
+public:
+ const char *Name;
+ const char *Desc;
+ unsigned Value : 31;
+ bool Initialized : 1;
+
+ unsigned getValue() const { return Value; }
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+
+ /// construct - This should only be called for non-global statistics.
+ void construct(const char *name, const char *desc) {
+ Name = name; Desc = desc;
+ Value = 0; Initialized = 0;
+ }
+
+ // Allow use of this class as the value itself.
+ operator unsigned() const { return Value; }
+ const Statistic &operator=(unsigned Val) { Value = Val; return init(); }
+ const Statistic &operator++() { ++Value; return init(); }
+ unsigned operator++(int) { init(); return Value++; }
+ const Statistic &operator--() { --Value; return init(); }
+ unsigned operator--(int) { init(); return Value--; }
+ 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:
+ Statistic &init() {
+ if (!Initialized) RegisterStatistic();
+ return *this;
+ }
+ void RegisterStatistic();
+};
+
+// STATISTIC - A macro to make definition of statistics really simple. This
+// automatically passes the DEBUG_TYPE of the file into the statistic.
+#define STATISTIC(VARNAME, DESC) \
+ static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
new file mode 100644
index 0000000000000..e40e409802d25
--- /dev/null
+++ b/include/llvm/ADT/StringExtras.h
@@ -0,0 +1,234 @@
+//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful when dealing with strings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGEXTRAS_H
+#define LLVM_ADT_STRINGEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APFloat.h"
+#include <cctype>
+#include <cstdio>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+/// hexdigit - Return the (uppercase) hexadecimal character for the
+/// given number \arg X (which should be less than 16).
+static inline char hexdigit(unsigned X) {
+ return X < 10 ? '0' + X : 'A' + X - 10;
+}
+
+/// utohex_buffer - Emit the specified number into the buffer specified by
+/// BufferEnd, returning a pointer to the start of the string. This can be used
+/// like this: (note that the buffer must be large enough to handle any number):
+/// char Buffer[40];
+/// printf("0x%s", utohex_buffer(X, Buffer+40));
+///
+/// This should only be used with unsigned types.
+///
+template<typename IntTy>
+static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
+ char *BufPtr = BufferEnd;
+ *--BufPtr = 0; // Null terminate buffer.
+ if (X == 0) {
+ *--BufPtr = '0'; // Handle special case.
+ return BufPtr;
+ }
+
+ while (X) {
+ unsigned char Mod = static_cast<unsigned char>(X) & 15;
+ *--BufPtr = hexdigit(Mod);
+ X >>= 4;
+ }
+ return BufPtr;
+}
+
+static inline std::string utohexstr(uint64_t X) {
+ char Buffer[40];
+ return utohex_buffer(X, Buffer+40);
+}
+
+static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
+ char Buffer[20];
+ char *BufPtr = Buffer+19;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+
+ return std::string(BufPtr);
+}
+
+static inline std::string utostr(uint64_t X, bool isNeg = false) {
+ if (X == uint32_t(X))
+ return utostr_32(uint32_t(X), isNeg);
+
+ char Buffer[40];
+ char *BufPtr = Buffer+39;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+ return std::string(BufPtr);
+}
+
+
+static inline std::string itostr(int64_t X) {
+ if (X < 0)
+ return utostr(static_cast<uint64_t>(-X), true);
+ else
+ return utostr(static_cast<uint64_t>(X));
+}
+
+static inline std::string itohexstr(int64_t X) {
+ return utohexstr(static_cast<uint64_t>(X));
+}
+
+static inline std::string ftostr(double V) {
+ char Buffer[200];
+ sprintf(Buffer, "%20.6e", V);
+ char *B = Buffer;
+ while (*B == ' ') ++B;
+ return B;
+}
+
+static inline std::string ftostr(const APFloat& V) {
+ if (&V.getSemantics() == &APFloat::IEEEdouble)
+ return ftostr(V.convertToDouble());
+ else if (&V.getSemantics() == &APFloat::IEEEsingle)
+ return ftostr((double)V.convertToFloat());
+ return "<unknown format in ftostr>"; // error
+}
+
+static inline std::string LowercaseString(const std::string &S) {
+ std::string result(S);
+ for (unsigned i = 0; i < S.length(); ++i)
+ if (isupper(result[i]))
+ result[i] = char(tolower(result[i]));
+ return result;
+}
+
+static inline std::string UppercaseString(const std::string &S) {
+ std::string result(S);
+ for (unsigned i = 0; i < S.length(); ++i)
+ if (islower(result[i]))
+ result[i] = char(toupper(result[i]));
+ return result;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const std::string &RHS) {
+ if (LHS.size() != RHS.size()) return false;
+ for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i)
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ return true;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const char *RHS) {
+ for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) {
+ if (RHS[i] == 0) return false; // RHS too short.
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ }
+ return RHS[LHS.size()] == 0; // Not too long?
+}
+
+/// StringsEqualNoCase - Return true if the two null-terminated C strings are
+/// equal, ignoring
+
+static inline bool StringsEqualNoCase(const char *LHS, const char *RHS,
+ unsigned len) {
+
+ for (unsigned i = 0; i < len; ++i) {
+ if (tolower(LHS[i]) != tolower(RHS[i]))
+ return false;
+
+ // If RHS[i] == 0 then LHS[i] == 0 or otherwise we would have returned
+ // at the previous branch as tolower('\0') == '\0'.
+ if (RHS[i] == 0)
+ return true;
+ }
+
+ return true;
+}
+
+/// CStrInCStrNoCase - Portable version of strcasestr. Locates the first
+/// occurance of c-string 's2' in string 's1', ignoring case. Returns
+/// NULL if 's2' cannot be found.
+static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) {
+
+ // Are either strings NULL or empty?
+ if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0')
+ return 0;
+
+ if (s1 == s2)
+ return s1;
+
+ const char *I1=s1, *I2=s2;
+
+ while (*I1 != '\0' && *I2 != '\0' )
+ if (tolower(*I1) != tolower(*I2)) { // No match. Start over.
+ ++s1; I1 = s1; I2 = s2;
+ }
+ else { // Character match. Advance to the next character.
+ ++I1; ++I2;
+ }
+
+ // If we exhausted all of the characters in 's2', then 's2' appears in 's1'.
+ return *I2 == '\0' ? s1 : 0;
+}
+
+/// getToken - This function extracts one token from source, ignoring any
+/// leading characters that appear in the Delimiters string, and ending the
+/// token at any of the characters that appear in the Delimiters string. If
+/// there are no tokens in the source string, an empty string is returned.
+/// The Source source string is updated in place to remove the returned string
+/// and any delimiter prefix from it.
+std::string getToken(std::string &Source,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void SplitString(const std::string &Source,
+ std::vector<std::string> &OutFragments,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// UnescapeString - Modify the argument string, turning two character sequences
+/// like '\\' 'n' into '\n'. This handles: \e \a \b \f \n \r \t \v \' \\ and
+/// \num (where num is a 1-3 byte octal value).
+void UnescapeString(std::string &Str);
+
+/// EscapeString - Modify the argument string, turning '\\' and anything that
+/// doesn't satisfy std::isprint into an escape sequence.
+void EscapeString(std::string &Str);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
new file mode 100644
index 0000000000000..a15d24eeae251
--- /dev/null
+++ b/include/llvm/ADT/StringMap.h
@@ -0,0 +1,504 @@
+//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAP_H
+#define LLVM_ADT_STRINGMAP_H
+
+#include "llvm/Support/Allocator.h"
+#include <cstring>
+#include <string>
+
+namespace llvm {
+ template<typename ValueT>
+ class StringMapConstIterator;
+ template<typename ValueT>
+ class StringMapIterator;
+ template<typename ValueTy>
+ class StringMapEntry;
+
+/// StringMapEntryInitializer - This datatype can be partially specialized for
+/// various datatypes in a stringmap to allow them to be initialized when an
+/// entry is default constructed for the map.
+template<typename ValueTy>
+class StringMapEntryInitializer {
+public:
+ template <typename InitTy>
+ static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
+ T.second = InitVal;
+ }
+};
+
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+ unsigned StrLen;
+public:
+ explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+
+ unsigned getKeyLength() const { return StrLen; }
+};
+
+/// StringMapImpl - This is the base class of StringMap that is shared among
+/// all of its instantiations.
+class StringMapImpl {
+public:
+ /// ItemBucket - The hash table consists of an array of these. If Item is
+ /// non-null, this is an extant entry, otherwise, it is a hole.
+ struct ItemBucket {
+ /// FullHashValue - This remembers the full hash value of the key for
+ /// easy scanning.
+ unsigned FullHashValue;
+
+ /// Item - This is a pointer to the actual item object.
+ StringMapEntryBase *Item;
+ };
+
+protected:
+ ItemBucket *TheTable;
+ unsigned NumBuckets;
+ unsigned NumItems;
+ unsigned NumTombstones;
+ unsigned ItemSize;
+protected:
+ explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
+ // Initialize the map with zero buckets to allocation.
+ TheTable = 0;
+ NumBuckets = 0;
+ NumItems = 0;
+ NumTombstones = 0;
+ }
+ StringMapImpl(unsigned InitSize, unsigned ItemSize);
+ void RehashTable();
+
+ /// ShouldRehash - Return true if the table should be rehashed after a new
+ /// element was recently inserted.
+ bool ShouldRehash() const {
+ // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ return NumItems*4 > NumBuckets*3 ||
+ NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
+ }
+
+ /// LookupBucketFor - Look up the bucket that the specified string should end
+ /// up in. If it already exists as a key in the map, the Item pointer for the
+ /// specified bucket will be non-null. Otherwise, it will be null. In either
+ /// case, the FullHashValue field of the bucket will be set to the hash value
+ /// of the string.
+ unsigned LookupBucketFor(const char *KeyStart, const char *KeyEnd);
+
+ /// FindKey - Look up the bucket that contains the specified key. If it exists
+ /// in the map, return the bucket number of the key. Otherwise return -1.
+ /// This does not modify the map.
+ int FindKey(const char *KeyStart, const char *KeyEnd) const;
+
+ /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+ /// delete it. This aborts if the value isn't in the table.
+ void RemoveKey(StringMapEntryBase *V);
+
+ /// RemoveKey - Remove the StringMapEntry for the specified key from the
+ /// table, returning it. If the key is not in the table, this returns null.
+ StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
+private:
+ void init(unsigned Size);
+public:
+ static StringMapEntryBase *getTombstoneVal() {
+ return (StringMapEntryBase*)-1;
+ }
+
+ unsigned getNumBuckets() const { return NumBuckets; }
+ unsigned getNumItems() const { return NumItems; }
+
+ bool empty() const { return NumItems == 0; }
+ unsigned size() const { return NumItems; }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap. It contains the Value itself and the key: the string length
+/// and data.
+template<typename ValueTy>
+class StringMapEntry : public StringMapEntryBase {
+public:
+ ValueTy second;
+
+ explicit StringMapEntry(unsigned strLen)
+ : StringMapEntryBase(strLen), second() {}
+ StringMapEntry(unsigned strLen, const ValueTy &V)
+ : StringMapEntryBase(strLen), second(V) {}
+
+ const ValueTy &getValue() const { return second; }
+ ValueTy &getValue() { return second; }
+
+ void setValue(const ValueTy &V) { second = V; }
+
+ /// getKeyData - Return the start of the string data that is the key for this
+ /// value. The string data is always stored immediately after the
+ /// StringMapEntry object.
+ const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
+
+ const char *first() const { return getKeyData(); }
+
+ /// Create - Create a StringMapEntry for the specified key and default
+ /// construct the value.
+ template<typename AllocatorTy, typename InitType>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator,
+ InitType InitVal) {
+ unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart);
+
+ // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
+ // in. Allocate a new item with space for the string at the end and a null
+ // terminator.
+
+ unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
+ KeyLength+1;
+ unsigned Alignment = alignof<StringMapEntry>();
+
+ StringMapEntry *NewItem =
+ static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
+
+ // Default construct the value.
+ new (NewItem) StringMapEntry(KeyLength);
+
+ // Copy the string information.
+ char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
+ memcpy(StrBuffer, KeyStart, KeyLength);
+ StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
+
+ // Initialize the value if the client wants to.
+ StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal);
+ return NewItem;
+ }
+
+ template<typename AllocatorTy>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator) {
+ return Create(KeyStart, KeyEnd, Allocator, 0);
+ }
+
+
+ /// Create - Create a StringMapEntry with normal malloc/free.
+ template<typename InitType>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ InitType InitVal) {
+ MallocAllocator A;
+ return Create(KeyStart, KeyEnd, A, InitVal);
+ }
+
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
+ return Create(KeyStart, KeyEnd, ValueTy());
+ }
+
+ /// GetStringMapEntryFromValue - Given a value that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
+ StringMapEntry *EPtr = 0;
+ char *Ptr = reinterpret_cast<char*>(&V) -
+ (reinterpret_cast<char*>(&EPtr->second) -
+ reinterpret_cast<char*>(EPtr));
+ return *reinterpret_cast<StringMapEntry*>(Ptr);
+ }
+ static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
+ return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
+ }
+
+ /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+ /// specified allocator.
+ template<typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~StringMapEntry();
+ Allocator.Deallocate(this);
+ }
+
+ /// Destroy this object, releasing memory back to the malloc allocator.
+ void Destroy() {
+ MallocAllocator A;
+ Destroy(A);
+ }
+};
+
+
+/// StringMap - This is an unconventional map that is specialized for handling
+/// keys that are "strings", which are basically ranges of bytes. This does some
+/// funky memory allocation and hashing things to make it extremely efficient,
+/// storing the string data *after* the value in the map.
+template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+class StringMap : public StringMapImpl {
+ AllocatorTy Allocator;
+ typedef StringMapEntry<ValueTy> MapEntryTy;
+public:
+ StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
+ explicit StringMap(unsigned InitialSize)
+ : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
+ explicit StringMap(const StringMap &RHS)
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
+ assert(RHS.empty() &&
+ "Copy ctor from non-empty stringmap not implemented yet!");
+ }
+ void operator=(const StringMap &RHS) {
+ assert(RHS.empty() &&
+ "assignment from non-empty stringmap not implemented yet!");
+ clear();
+ }
+
+
+ AllocatorTy &getAllocator() { return Allocator; }
+ const AllocatorTy &getAllocator() const { return Allocator; }
+
+ typedef const char* key_type;
+ typedef ValueTy mapped_type;
+ typedef StringMapEntry<ValueTy> value_type;
+ typedef size_t size_type;
+
+ typedef StringMapConstIterator<ValueTy> const_iterator;
+ typedef StringMapIterator<ValueTy> iterator;
+
+ iterator begin() {
+ return iterator(TheTable, NumBuckets == 0);
+ }
+ iterator end() {
+ return iterator(TheTable+NumBuckets, true);
+ }
+ const_iterator begin() const {
+ return const_iterator(TheTable, NumBuckets == 0);
+ }
+ const_iterator end() const {
+ return const_iterator(TheTable+NumBuckets, true);
+ }
+
+ iterator find(const char *KeyStart, const char *KeyEnd) {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return iterator(TheTable+Bucket);
+ }
+ iterator find(const char *Key) {
+ return find(Key, Key + strlen(Key));
+ }
+ iterator find(const std::string &Key) {
+ return find(Key.data(), Key.data() + Key.size());
+ }
+
+ const_iterator find(const char *KeyStart, const char *KeyEnd) const {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return const_iterator(TheTable+Bucket);
+ }
+ const_iterator find(const char *Key) const {
+ return find(Key, Key + strlen(Key));
+ }
+ const_iterator find(const std::string &Key) const {
+ return find(Key.data(), Key.data() + Key.size());
+ }
+
+ /// lookup - Return the entry for the specified key, or a default
+ /// constructed value if no such entry exists.
+ ValueTy lookup(const char *KeyStart, const char *KeyEnd) const {
+ const_iterator it = find(KeyStart, KeyEnd);
+ if (it != end())
+ return it->second;
+ return ValueTy();
+ }
+ ValueTy lookup(const char *Key) const {
+ const_iterator it = find(Key);
+ if (it != end())
+ return it->second;
+ return ValueTy();
+ }
+ ValueTy lookup(const std::string &Key) const {
+ const_iterator it = find(Key);
+ if (it != end())
+ return it->second;
+ return ValueTy();
+ }
+
+ ValueTy& operator[](const char *Key) {
+ return GetOrCreateValue(Key, Key + strlen(Key)).getValue();
+ }
+ ValueTy& operator[](const std::string &Key) {
+ return GetOrCreateValue(Key.data(), Key.data() + Key.size()).getValue();
+ }
+
+ size_type count(const char *KeyStart, const char *KeyEnd) const {
+ return find(KeyStart, KeyEnd) == end() ? 0 : 1;
+ }
+ size_type count(const char *Key) const {
+ return count(Key, Key + strlen(Key));
+ }
+ size_type count(const std::string &Key) const {
+ return count(Key.data(), Key.data() + Key.size());
+ }
+
+ /// insert - Insert the specified key/value pair into the map. If the key
+ /// already exists in the map, return false and ignore the request, otherwise
+ /// insert it and return true.
+ bool insert(MapEntryTy *KeyValue) {
+ unsigned BucketNo =
+ LookupBucketFor(KeyValue->getKeyData(),
+ KeyValue->getKeyData()+KeyValue->getKeyLength());
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return false; // Already exists in map.
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ Bucket.Item = KeyValue;
+ ++NumItems;
+
+ if (ShouldRehash())
+ RehashTable();
+ return true;
+ }
+
+ // clear - Empties out the StringMap
+ void clear() {
+ if (empty()) return;
+
+ // Zap all values, resetting the keys back to non-present (not tombstone),
+ // which is safe because we're removing all elements.
+ for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) {
+ if (I->Item && I->Item != getTombstoneVal()) {
+ static_cast<MapEntryTy*>(I->Item)->Destroy(Allocator);
+ I->Item = 0;
+ }
+ }
+
+ NumItems = 0;
+ }
+
+ /// GetOrCreateValue - Look up the specified key in the table. If a value
+ /// exists, return it. Otherwise, default construct a value, insert it, and
+ /// return.
+ template <typename InitTy>
+ StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
+ const char *KeyEnd,
+ InitTy Val) {
+ unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd);
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return *static_cast<MapEntryTy*>(Bucket.Item);
+
+ MapEntryTy *NewItem = MapEntryTy::Create(KeyStart, KeyEnd, Allocator, Val);
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ ++NumItems;
+
+ // Fill in the bucket for the hash table. The FullHashValue was already
+ // filled in by LookupBucketFor.
+ Bucket.Item = NewItem;
+
+ if (ShouldRehash())
+ RehashTable();
+ return *NewItem;
+ }
+
+ StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
+ const char *KeyEnd) {
+ return GetOrCreateValue(KeyStart, KeyEnd, ValueTy());
+ }
+
+ /// remove - Remove the specified key/value pair from the map, but do not
+ /// erase it. This aborts if the key is not in the map.
+ void remove(MapEntryTy *KeyValue) {
+ RemoveKey(KeyValue);
+ }
+
+ void erase(iterator I) {
+ MapEntryTy &V = *I;
+ remove(&V);
+ V.Destroy(Allocator);
+ }
+
+ bool erase(const char *Key) {
+ iterator I = find(Key);
+ if (I == end()) return false;
+ erase(I);
+ return true;
+ }
+
+ bool erase(const std::string &Key) {
+ iterator I = find(Key);
+ if (I == end()) return false;
+ erase(I);
+ return true;
+ }
+
+ ~StringMap() {
+ clear();
+ free(TheTable);
+ }
+};
+
+
+template<typename ValueTy>
+class StringMapConstIterator {
+protected:
+ StringMapImpl::ItemBucket *Ptr;
+public:
+ typedef StringMapEntry<ValueTy> value_type;
+
+ explicit StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
+ }
+
+ const value_type &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+ const value_type *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+
+ bool operator==(const StringMapConstIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const StringMapConstIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline StringMapConstIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ StringMapConstIterator operator++(int) { // Postincrement
+ StringMapConstIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ while (Ptr->Item == 0 || Ptr->Item == StringMapImpl::getTombstoneVal())
+ ++Ptr;
+ }
+};
+
+template<typename ValueTy>
+class StringMapIterator : public StringMapConstIterator<ValueTy> {
+public:
+ explicit StringMapIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
+ }
+ StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+ StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h
new file mode 100644
index 0000000000000..00048361e86f2
--- /dev/null
+++ b/include/llvm/ADT/StringSet.h
@@ -0,0 +1,39 @@
+//===--- StringSet.h - The LLVM Compiler Driver -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// StringSet - A set-like wrapper for the StringMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGSET_H
+#define LLVM_ADT_STRINGSET_H
+
+#include "llvm/ADT/StringMap.h"
+#include <cassert>
+
+namespace llvm {
+
+ /// StringSet - A wrapper for StringMap that provides set-like
+ /// functionality. Only insert() and count() methods are used by my
+ /// code.
+ template <class AllocatorTy = llvm::MallocAllocator>
+ class StringSet : public llvm::StringMap<char, AllocatorTy> {
+ typedef llvm::StringMap<char, AllocatorTy> base;
+ public:
+ bool insert(const std::string& InLang) {
+ assert(!InLang.empty());
+ const char* KeyStart = &InLang[0];
+ const char* KeyEnd = KeyStart + InLang.size();
+ return base::insert(llvm::StringMapEntry<char>::
+ Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
+ }
+ };
+}
+
+#endif // LLVM_ADT_STRINGSET_H
diff --git a/include/llvm/ADT/Tree.h b/include/llvm/ADT/Tree.h
new file mode 100644
index 0000000000000..78f5b4fab97f7
--- /dev/null
+++ b/include/llvm/ADT/Tree.h
@@ -0,0 +1,62 @@
+//===- llvm/ADT/Tree.h - Generic n-way tree structure -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a generic N-way tree node structure. The tree structure
+// is immutable after creation, but the payload contained within it is not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TREE_H
+#define LLVM_ADT_TREE_H
+
+#include <vector>
+
+namespace llvm {
+
+template<class ConcreteTreeNode, class Payload>
+class Tree {
+ std::vector<ConcreteTreeNode*> Children; // This node's children, if any.
+ ConcreteTreeNode *Parent; // Parent of this node.
+ Payload Data; // Data held in this node.
+
+protected:
+ void setChildren(const std::vector<ConcreteTreeNode*> &children) {
+ Children = children;
+ }
+public:
+ inline Tree(ConcreteTreeNode *parent) : Parent(parent) {}
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par) : Children(children), Parent(par) {}
+
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par, const Payload &data)
+ : Children(children), Parent(par), Data(data) {}
+
+ // Tree dtor - Free all children
+ inline ~Tree() {
+ for (unsigned i = Children.size(); i > 0; --i)
+ delete Children[i-1];
+ }
+
+ // Tree manipulation/walking routines...
+ inline ConcreteTreeNode *getParent() const { return Parent; }
+ inline unsigned getNumChildren() const { return Children.size(); }
+ inline ConcreteTreeNode *getChild(unsigned i) const {
+ assert(i < Children.size() && "Tree::getChild with index out of range!");
+ return Children[i];
+ }
+
+ // Payload access...
+ inline Payload &getTreeData() { return Data; }
+ inline const Payload &getTreeData() const { return Data; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/Trie.h b/include/llvm/ADT/Trie.h
new file mode 100644
index 0000000000000..70f3b4154d399
--- /dev/null
+++ b/include/llvm/ADT/Trie.h
@@ -0,0 +1,335 @@
+//===- llvm/ADT/Trie.h ---- Generic trie structure --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a generic trie structure. The trie structure
+// is immutable after creation, but the payload contained within it is not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TRIE_H
+#define LLVM_ADT_TRIE_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DOTGraphTraits.h"
+
+#include <vector>
+
+namespace llvm {
+
+// FIXME:
+// - Labels are usually small, maybe it's better to use SmallString
+// - Should we use char* during construction?
+// - Should we templatize Empty with traits-like interface?
+
+template<class Payload>
+class Trie {
+ friend class GraphTraits<Trie<Payload> >;
+ friend class DOTGraphTraits<Trie<Payload> >;
+public:
+ class Node {
+ friend class Trie;
+
+ public:
+ typedef std::vector<Node*> NodeVectorType;
+ typedef typename NodeVectorType::iterator iterator;
+ typedef typename NodeVectorType::const_iterator const_iterator;
+
+ private:
+ enum QueryResult {
+ Same = -3,
+ StringIsPrefix = -2,
+ LabelIsPrefix = -1,
+ DontMatch = 0,
+ HaveCommonPart
+ };
+
+ struct NodeCmp {
+ bool operator() (Node* N1, Node* N2) {
+ return (N1->Label[0] < N2->Label[0]);
+ }
+ bool operator() (Node* N, char Id) {
+ return (N->Label[0] < Id);
+ }
+ };
+
+ std::string Label;
+ Payload Data;
+ NodeVectorType Children;
+
+ // Do not implement
+ Node(const Node&);
+ Node& operator=(const Node&);
+
+ inline void addEdge(Node* N) {
+ if (Children.empty())
+ Children.push_back(N);
+ else {
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ N, NodeCmp());
+ // FIXME: no dups are allowed
+ Children.insert(I, N);
+ }
+ }
+
+ inline void setEdge(Node* N) {
+ char Id = N->Label[0];
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ Id, NodeCmp());
+ assert(I != Children.end() && "Node does not exists!");
+ *I = N;
+ }
+
+ QueryResult query(const std::string& s) const {
+ unsigned i, l;
+ unsigned l1 = s.length();
+ unsigned l2 = Label.length();
+
+ // Find the length of common part
+ l = std::min(l1, l2);
+ i = 0;
+ while ((i < l) && (s[i] == Label[i]))
+ ++i;
+
+ if (i == l) { // One is prefix of another, find who is who
+ if (l1 == l2)
+ return Same;
+ else if (i == l1)
+ return StringIsPrefix;
+ else
+ return LabelIsPrefix;
+ } else // s and Label have common (possible empty) part, return its length
+ return (QueryResult)i;
+ }
+
+ public:
+ inline explicit Node(const Payload& data, const std::string& label = ""):
+ Label(label), Data(data) { }
+
+ inline const Payload& data() const { return Data; }
+ inline void setData(const Payload& data) { Data = data; }
+
+ inline const std::string& label() const { return Label; }
+
+#if 0
+ inline void dump() {
+ std::cerr << "Node: " << this << "\n"
+ << "Label: " << Label << "\n"
+ << "Children:\n";
+
+ for (iterator I = Children.begin(), E = Children.end(); I != E; ++I)
+ std::cerr << (*I)->Label << "\n";
+ }
+#endif
+
+ inline Node* getEdge(char Id) {
+ Node* fNode = NULL;
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ Id, NodeCmp());
+ if (I != Children.end() && (*I)->Label[0] == Id)
+ fNode = *I;
+
+ return fNode;
+ }
+
+ inline iterator begin() { return Children.begin(); }
+ inline const_iterator begin() const { return Children.begin(); }
+ inline iterator end () { return Children.end(); }
+ inline const_iterator end () const { return Children.end(); }
+
+ inline size_t size () const { return Children.size(); }
+ inline bool empty() const { return Children.empty(); }
+ inline const Node* &front() const { return Children.front(); }
+ inline Node* &front() { return Children.front(); }
+ inline const Node* &back() const { return Children.back(); }
+ inline Node* &back() { return Children.back(); }
+
+ };
+
+private:
+ std::vector<Node*> Nodes;
+ Payload Empty;
+
+ inline Node* addNode(const Payload& data, const std::string label = "") {
+ Node* N = new Node(data, label);
+ Nodes.push_back(N);
+ return N;
+ }
+
+ inline Node* splitEdge(Node* N, char Id, size_t index) {
+ Node* eNode = N->getEdge(Id);
+ assert(eNode && "Node doesn't exist");
+
+ const std::string &l = eNode->Label;
+ assert(index > 0 && index < l.length() && "Trying to split too far!");
+ std::string l1 = l.substr(0, index);
+ std::string l2 = l.substr(index);
+
+ Node* nNode = addNode(Empty, l1);
+ N->setEdge(nNode);
+
+ eNode->Label = l2;
+ nNode->addEdge(eNode);
+
+ return nNode;
+ }
+
+ // Do not implement
+ Trie(const Trie&);
+ Trie& operator=(const Trie&);
+
+public:
+ inline explicit Trie(const Payload& empty):Empty(empty) {
+ addNode(Empty);
+ }
+ inline ~Trie() {
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
+ delete Nodes[i];
+ }
+
+ inline Node* getRoot() const { return Nodes[0]; }
+
+ bool addString(const std::string& s, const Payload& data);
+ const Payload& lookup(const std::string& s) const;
+
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template<class Payload>
+bool Trie<Payload>::addString(const std::string& s, const Payload& data) {
+ Node* cNode = getRoot();
+ Node* tNode = NULL;
+ std::string s1(s);
+
+ while (tNode == NULL) {
+ char Id = s1[0];
+ if (Node* nNode = cNode->getEdge(Id)) {
+ typename Node::QueryResult r = nNode->query(s1);
+
+ switch (r) {
+ case Node::Same:
+ case Node::StringIsPrefix:
+ // Currently we don't allow to have two strings in the trie one
+ // being a prefix of another. This should be fixed.
+ assert(0 && "FIXME!");
+ return false;
+ case Node::DontMatch:
+ assert(0 && "Impossible!");
+ return false;
+ case Node::LabelIsPrefix:
+ s1 = s1.substr(nNode->label().length());
+ cNode = nNode;
+ break;
+ default:
+ nNode = splitEdge(cNode, Id, r);
+ tNode = addNode(data, s1.substr(r));
+ nNode->addEdge(tNode);
+ }
+ } else {
+ tNode = addNode(data, s1);
+ cNode->addEdge(tNode);
+ }
+ }
+
+ return true;
+}
+
+template<class Payload>
+const Payload& Trie<Payload>::lookup(const std::string& s) const {
+ Node* cNode = getRoot();
+ Node* tNode = NULL;
+ std::string s1(s);
+
+ while (tNode == NULL) {
+ char Id = s1[0];
+ if (Node* nNode = cNode->getEdge(Id)) {
+ typename Node::QueryResult r = nNode->query(s1);
+
+ switch (r) {
+ case Node::Same:
+ tNode = nNode;
+ break;
+ case Node::StringIsPrefix:
+ return Empty;
+ case Node::DontMatch:
+ assert(0 && "Impossible!");
+ return Empty;
+ case Node::LabelIsPrefix:
+ s1 = s1.substr(nNode->label().length());
+ cNode = nNode;
+ break;
+ default:
+ return Empty;
+ }
+ } else
+ return Empty;
+ }
+
+ return tNode->data();
+}
+
+template<class Payload>
+struct GraphTraits<Trie<Payload> > {
+ typedef Trie<Payload> TrieType;
+ typedef typename TrieType::Node NodeType;
+ typedef typename NodeType::iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(const TrieType& T) {
+ return T.getRoot();
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+
+ typedef typename std::vector<NodeType*>::const_iterator nodes_iterator;
+
+ static inline nodes_iterator nodes_begin(const TrieType& G) {
+ return G.Nodes.begin();
+ }
+ static inline nodes_iterator nodes_end(const TrieType& G) {
+ return G.Nodes.end();
+ }
+
+};
+
+template<class Payload>
+struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
+ typedef typename Trie<Payload>::Node NodeType;
+ typedef typename GraphTraits<Trie<Payload> >::ChildIteratorType EdgeIter;
+
+ static std::string getGraphName(const Trie<Payload>& T) {
+ return "Trie";
+ }
+
+ static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
+ if (T.getRoot() == Node)
+ return "<Root>";
+ else
+ return Node->label();
+ }
+
+ static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
+ NodeType* N = *I;
+ return N->label().substr(0, 1);
+ }
+
+ static std::string getNodeAttributes(const NodeType* Node,
+ const Trie<Payload>& T) {
+ if (Node->data() != T.Empty)
+ return "color=blue";
+
+ return "";
+ }
+
+};
+
+} // end of llvm namespace
+
+#endif // LLVM_ADT_TRIE_H
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
new file mode 100644
index 0000000000000..b260f984948ed
--- /dev/null
+++ b/include/llvm/ADT/Triple.h
@@ -0,0 +1,204 @@
+//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TRIPLE_H
+#define LLVM_ADT_TRIPLE_H
+
+#include <string>
+
+namespace llvm {
+
+/// Triple - Helper class for working with target triples.
+///
+/// Target triples are strings in the format of:
+/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM
+/// or
+/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
+///
+/// This class is used for clients which want to support arbitrary
+/// target triples, but also want to implement certain special
+/// behavior for particular targets. This class isolates the mapping
+/// from the components of the target triple to well known IDs.
+///
+/// See autoconf/config.guess for a glimpse into what they look like
+/// in practice.
+class Triple {
+public:
+ enum ArchType {
+ UnknownArch,
+
+ x86, // i?86
+ ppc, // powerpc
+ ppc64, // powerpc64
+ x86_64, // amd64, x86_64
+
+ InvalidArch
+ };
+ enum VendorType {
+ UnknownVendor,
+
+ Apple,
+ PC
+ };
+ enum OSType {
+ UnknownOS,
+
+ Darwin,
+ DragonFly,
+ FreeBSD,
+ Linux
+ };
+
+private:
+ std::string Data;
+
+ /// The parsed arch type (or InvalidArch if uninitialized).
+ mutable ArchType Arch;
+
+ /// The parsed vendor type.
+ mutable VendorType Vendor;
+
+ /// The parsed OS type.
+ mutable OSType OS;
+
+ bool isInitialized() const { return Arch != InvalidArch; }
+ void Parse() const;
+
+public:
+ /// @name Constructors
+ /// @{
+
+ Triple() : Data(""), Arch(InvalidArch) {}
+ explicit Triple(const char *Str) : Data(Str), Arch(InvalidArch) {}
+ explicit Triple(const char *ArchStr, const char *VendorStr, const char *OSStr)
+ : Data(ArchStr), Arch(InvalidArch) {
+ Data += '-';
+ Data += VendorStr;
+ Data += '-';
+ Data += OSStr;
+ }
+
+ /// @}
+ /// @name Typed Component Access
+ /// @{
+
+ /// getArch - Get the parsed architecture type of this triple.
+ ArchType getArch() const {
+ if (!isInitialized()) Parse();
+ return Arch;
+ }
+
+ /// getVendor - Get the parsed vendor type of this triple.
+ VendorType getVendor() const {
+ if (!isInitialized()) Parse();
+ return Vendor;
+ }
+
+ /// getOS - Get the parsed operating system type of this triple.
+ OSType getOS() const {
+ if (!isInitialized()) Parse();
+ return OS;
+ }
+
+ /// hasEnvironment - Does this triple have the optional environment
+ /// (fourth) component?
+ bool hasEnvironment() const {
+ return getEnvironmentName() != "";
+ }
+
+ /// @}
+ /// @name Direct Component Access
+ /// @{
+
+ const std::string &getTriple() const { return Data; }
+
+ // FIXME: Invent a lightweight string representation for these to
+ // use.
+
+ /// getArchName - Get the architecture (first) component of the
+ /// triple.
+ std::string getArchName() const;
+
+ /// getVendorName - Get the vendor (second) component of the triple.
+ std::string getVendorName() const;
+
+ /// getOSName - Get the operating system (third) component of the
+ /// triple.
+ std::string getOSName() const;
+
+ /// getEnvironmentName - Get the optional environment (fourth)
+ /// component of the triple, or "" if empty.
+ std::string getEnvironmentName() const;
+
+ /// getOSAndEnvironmentName - Get the operating system and optional
+ /// environment components as a single string (separated by a '-'
+ /// if the environment component is present).
+ std::string getOSAndEnvironmentName() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+
+ /// setArch - Set the architecture (first) component of the triple
+ /// to a known type.
+ void setArch(ArchType Kind);
+
+ /// setVendor - Set the vendor (second) component of the triple to a
+ /// known type.
+ void setVendor(VendorType Kind);
+
+ /// setOS - Set the operating system (third) component of the triple
+ /// to a known type.
+ void setOS(OSType Kind);
+
+ /// setTriple - Set all components to the new triple \arg Str.
+ void setTriple(const std::string &Str);
+
+ /// setArchName - Set the architecture (first) component of the
+ /// triple by name.
+ void setArchName(const std::string &Str);
+
+ /// setVendorName - Set the vendor (second) component of the triple
+ /// by name.
+ void setVendorName(const std::string &Str);
+
+ /// setOSName - Set the operating system (third) component of the
+ /// triple by name.
+ void setOSName(const std::string &Str);
+
+ /// setEnvironmentName - Set the optional environment (fourth)
+ /// component of the triple by name.
+ void setEnvironmentName(const std::string &Str);
+
+ /// setOSAndEnvironmentName - Set the operating system and optional
+ /// environment components with a single string.
+ void setOSAndEnvironmentName(const std::string &Str);
+
+ /// @}
+ /// @name Static helpers for IDs.
+ /// @{
+
+ /// getArchTypeName - Get the canonical name for the \arg Kind
+ /// architecture.
+ static const char *getArchTypeName(ArchType Kind);
+
+ /// getVendorTypeName - Get the canonical name for the \arg Kind
+ /// vendor.
+ static const char *getVendorTypeName(VendorType Kind);
+
+ /// getOSTypeName - Get the canonical name for the \arg Kind vendor.
+ static const char *getOSTypeName(OSType Kind);
+
+ /// @}
+};
+
+} // End llvm namespace
+
+
+#endif
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
new file mode 100644
index 0000000000000..2d02d1ce166fa
--- /dev/null
+++ b/include/llvm/ADT/UniqueVector.h
@@ -0,0 +1,89 @@
+//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_UNIQUEVECTOR_H
+#define LLVM_ADT_UNIQUEVECTOR_H
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// 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
+/// class should have an implementation of operator== and of operator<.
+/// Entries can be fetched using operator[] with the entry ID.
+template<class T> class UniqueVector {
+private:
+ // Map - Used to handle the correspondence of entry to ID.
+ std::map<T, unsigned> Map;
+
+ // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
+ //
+ std::vector<T> Vector;
+
+public:
+ /// 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.
+ unsigned insert(const T &Entry) {
+ // Check if the entry is already in the map.
+ unsigned &Val = Map[Entry];
+
+ // See if entry exists, if so return prior ID.
+ if (Val) return Val;
+
+ // Compute ID for entry.
+ Val = static_cast<unsigned>(Vector.size()) + 1;
+
+ // Insert in vector.
+ Vector.push_back(Entry);
+ return Val;
+ }
+
+ /// idFor - return the ID for an existing entry. Returns 0 if the entry is
+ /// not found.
+ unsigned idFor(const T &Entry) const {
+ // Search for entry in the map.
+ typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
+
+ // See if entry exists, if so return ID.
+ if (MI != Map.end()) return MI->second;
+
+ // No luck.
+ return 0;
+ }
+
+ /// operator[] - Returns a reference to the entry with the specified ID.
+ ///
+ const T &operator[](unsigned ID) const {
+ assert(ID-1 < size() && "ID is 0 or out of range!");
+ return Vector[ID - 1];
+ }
+
+ /// size - Returns the number of entries in the vector.
+ ///
+ size_t size() const { return Vector.size(); }
+
+ /// empty - Returns true if the vector is empty.
+ ///
+ bool empty() const { return Vector.empty(); }
+
+ /// reset - Clears all the entries.
+ ///
+ void reset() {
+ Map.clear();
+ Vector.resize(0, 0);
+ }
+};
+
+} // End of namespace llvm
+
+#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/include/llvm/ADT/VectorExtras.h b/include/llvm/ADT/VectorExtras.h
new file mode 100644
index 0000000000000..e05f585996f9a
--- /dev/null
+++ b/include/llvm/ADT/VectorExtras.h
@@ -0,0 +1,41 @@
+//===-- llvm/ADT/VectorExtras.h - Helpers for std::vector -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains helper functions which are useful for working with the
+// std::vector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VECTOREXTRAS_H
+#define LLVM_ADT_VECTOREXTRAS_H
+
+#include <cstdarg>
+#include <vector>
+
+namespace llvm {
+
+/// make_vector - Helper function which is useful for building temporary vectors
+/// to pass into type construction of CallInst ctors. This turns a null
+/// terminated list of pointers (or other value types) into a real live vector.
+///
+template<typename T>
+inline std::vector<T> make_vector(T A, ...) {
+ va_list Args;
+ va_start(Args, A);
+ std::vector<T> Result;
+ Result.push_back(A);
+ while (T Val = va_arg(Args, T))
+ Result.push_back(Val);
+ va_end(Args);
+ return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
new file mode 100644
index 0000000000000..9eb70055284af
--- /dev/null
+++ b/include/llvm/ADT/ilist.h
@@ -0,0 +1,709 @@
+//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes to implement an intrusive doubly linked list class
+// (i.e. each node of the list must contain a next and previous field for the
+// list.
+//
+// The ilist_traits trait class is used to gain access to the next and previous
+// fields of the node type that the list is instantiated with. If it is not
+// specialized, the list defaults to using the getPrev(), getNext() method calls
+// to get the next and previous pointers.
+//
+// The ilist class itself, should be a plug in replacement for list, assuming
+// that the nodes contain next/prev pointers. This list replacement does not
+// provide a constant time size() method, so be careful to use empty() when you
+// really want to know if it's empty.
+//
+// The ilist class is implemented by allocating a 'tail' node when the list is
+// created (using ilist_traits<>::createSentinel()). This tail node is
+// absolutely required because the user must be able to compute end()-1. Because
+// of this, users of the direct next/prev links will see an extra link on the
+// end of the list, which should be ignored.
+//
+// Requirements for a user of this list:
+//
+// 1. The user must provide {g|s}et{Next|Prev} methods, or specialize
+// ilist_traits to provide an alternate way of getting and setting next and
+// prev links.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST_H
+#define LLVM_ADT_ILIST_H
+
+#include "llvm/ADT/iterator.h"
+#include <cassert>
+
+namespace llvm {
+
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+/// ilist_nextprev_traits - A fragment for template traits for intrusive list
+/// that provides default next/prev implementations for common operations.
+///
+template<typename NodeTy>
+struct ilist_nextprev_traits {
+ static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+ static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+ static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+ static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+ static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+ static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+};
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_sentinel_traits - A fragment for template traits for intrusive list
+/// that provides default sentinel implementations for common operations.
+///
+/// ilist_sentinel_traits implements a lazy dynamic sentinel allocation
+/// strategy. The sentinel is stored in the prev field of ilist's Head.
+///
+template<typename NodeTy>
+struct ilist_sentinel_traits {
+ /// createSentinel - create the dynamic sentinel
+ static NodeTy *createSentinel() { return new NodeTy(); }
+
+ /// destroySentinel - deallocate the dynamic sentinel
+ static void destroySentinel(NodeTy *N) { delete N; }
+
+ /// provideInitialHead - when constructing an ilist, provide a starting
+ /// value for its Head
+ /// @return null node to indicate that it needs to be allocated later
+ static NodeTy *provideInitialHead() { return 0; }
+
+ /// ensureHead - make sure that Head is either already
+ /// initialized or assigned a fresh sentinel
+ /// @return the sentinel
+ static NodeTy *ensureHead(NodeTy *&Head) {
+ if (!Head) {
+ Head = ilist_traits<NodeTy>::createSentinel();
+ ilist_traits<NodeTy>::noteHead(Head, Head);
+ ilist_traits<NodeTy>::setNext(Head, 0);
+ return Head;
+ }
+ return ilist_traits<NodeTy>::getPrev(Head);
+ }
+
+ /// noteHead - stash the sentinel into its default location
+ static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
+ ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
+ }
+};
+
+/// ilist_node_traits - A fragment for template traits for intrusive list
+/// that provides default node related operations.
+///
+template<typename NodeTy>
+struct ilist_node_traits {
+ static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+ static void deleteNode(NodeTy *V) { delete V; }
+
+ void addNodeToList(NodeTy *) {}
+ void removeNodeFromList(NodeTy *) {}
+ void transferNodesFromList(ilist_node_traits & /*SrcTraits*/,
+ ilist_iterator<NodeTy> /*first*/,
+ ilist_iterator<NodeTy> /*last*/) {}
+};
+
+/// ilist_default_traits - Default template traits for intrusive list.
+/// By inheriting from this, you can easily use default implementations
+/// for all common operations.
+///
+template<typename NodeTy>
+struct ilist_default_traits : ilist_nextprev_traits<NodeTy>,
+ ilist_sentinel_traits<NodeTy>,
+ ilist_node_traits<NodeTy> {
+};
+
+// Template traits for intrusive list. By specializing this template class, you
+// can change what next/prev fields are used to store the links...
+template<typename NodeTy>
+struct ilist_traits : ilist_default_traits<NodeTy> {};
+
+// Const traits are the same as nonconst traits...
+template<typename Ty>
+struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
+
+//===----------------------------------------------------------------------===//
+// ilist_iterator<Node> - Iterator for intrusive list.
+//
+template<typename NodeTy>
+class ilist_iterator
+ : public bidirectional_iterator<NodeTy, ptrdiff_t> {
+
+public:
+ typedef ilist_traits<NodeTy> Traits;
+ typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
+
+ typedef typename super::value_type value_type;
+ typedef typename super::difference_type difference_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+private:
+ pointer NodePtr;
+
+ // ilist_iterator is not a random-access iterator, but it has an
+ // implicit conversion to pointer-type, which is. Declare (but
+ // don't define) these functions as private to help catch
+ // accidental misuse.
+ void operator[](difference_type) const;
+ void operator+(difference_type) const;
+ void operator-(difference_type) const;
+ void operator+=(difference_type) const;
+ void operator-=(difference_type) const;
+ template<class T> void operator<(T) const;
+ template<class T> void operator<=(T) const;
+ template<class T> void operator>(T) const;
+ template<class T> void operator>=(T) const;
+ template<class T> void operator-(T) const;
+public:
+
+ ilist_iterator(pointer NP) : NodePtr(NP) {}
+ ilist_iterator(reference NR) : NodePtr(&NR) {}
+ ilist_iterator() : NodePtr(0) {}
+
+ // This is templated so that we can allow constructing a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ ilist_iterator(const ilist_iterator<node_ty> &RHS)
+ : NodePtr(RHS.getNodePtrUnchecked()) {}
+
+ // This is templated so that we can allow assigning to a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
+ NodePtr = RHS.getNodePtrUnchecked();
+ return *this;
+ }
+
+ // Accessors...
+ operator pointer() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return NodePtr;
+ }
+
+ reference operator*() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return *NodePtr;
+ }
+ pointer operator->() const { return &operator*(); }
+
+ // Comparison operators
+ bool operator==(const ilist_iterator &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const ilist_iterator &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+
+ // Increment and decrement operators...
+ ilist_iterator &operator--() { // predecrement - Back up
+ NodePtr = Traits::getPrev(NodePtr);
+ assert(NodePtr && "--'d off the beginning of an ilist!");
+ return *this;
+ }
+ ilist_iterator &operator++() { // preincrement - Advance
+ NodePtr = Traits::getNext(NodePtr);
+ assert(NodePtr && "++'d off the end of an ilist!");
+ return *this;
+ }
+ ilist_iterator operator--(int) { // postdecrement operators...
+ ilist_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ ilist_iterator operator++(int) { // postincrement operators...
+ ilist_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Internal interface, do not use...
+ pointer getNodePtrUnchecked() const { return NodePtr; }
+};
+
+// do not implement. this is to catch errors when people try to use
+// them as random access iterators
+template<typename T>
+void operator-(int, ilist_iterator<T>);
+template<typename T>
+void operator-(ilist_iterator<T>,int);
+
+template<typename T>
+void operator+(int, ilist_iterator<T>);
+template<typename T>
+void operator+(ilist_iterator<T>,int);
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+
+
+// Allow ilist_iterators to convert into pointers to a node automatically when
+// used by the dyn_cast, cast, isa mechanisms...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+/// iplist - The subset of list functionality that can safely be used on nodes
+/// of polymorphic types, i.e. a heterogenous list with a common base class that
+/// holds the next/prev pointers. The only state of the list itself is a single
+/// pointer to the head of the list.
+///
+/// This list can be in one of three interesting states:
+/// 1. The list may be completely unconstructed. In this case, the head
+/// pointer is null. When in this form, any query for an iterator (e.g.
+/// begin() or end()) causes the list to transparently change to state #2.
+/// 2. The list may be empty, but contain a sentinel for the end iterator. This
+/// sentinel is created by the Traits::createSentinel method and is a link
+/// in the list. When the list is empty, the pointer in the iplist points
+/// to the sentinel. Once the sentinel is constructed, it
+/// is not destroyed until the list is.
+/// 3. The list may contain actual objects in it, which are stored as a doubly
+/// linked list of nodes. One invariant of the list is that the predecessor
+/// of the first node in the list always points to the last node in the list,
+/// and the successor pointer for the sentinel (which always stays at the
+/// end of the list) is always null.
+///
+template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
+class iplist : public Traits {
+ mutable NodeTy *Head;
+
+ // Use the prev node pointer of 'head' as the tail pointer. This is really a
+ // circularly linked list where we snip the 'next' link from the sentinel node
+ // back to the first node in the list (to preserve assertions about going off
+ // the end of the list).
+ NodeTy *getTail() { return this->ensureHead(Head); }
+ const NodeTy *getTail() const { return this->ensureHead(Head); }
+ void setTail(NodeTy *N) const { this->noteHead(Head, N); }
+
+ /// CreateLazySentinel - This method verifies whether the sentinel for the
+ /// list has been created and lazily makes it if not.
+ void CreateLazySentinel() const {
+ this->Traits::ensureHead(Head);
+ }
+
+ static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
+ static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
+
+ // No fundamental reason why iplist can't by copyable, but the default
+ // copy/copy-assign won't do.
+ iplist(const iplist &); // do not implement
+ void operator=(const iplist &); // do not implement
+
+public:
+ typedef NodeTy *pointer;
+ typedef const NodeTy *const_pointer;
+ typedef NodeTy &reference;
+ typedef const NodeTy &const_reference;
+ typedef NodeTy value_type;
+ typedef ilist_iterator<NodeTy> iterator;
+ typedef ilist_iterator<const NodeTy> const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iplist() : Head(this->Traits::provideInitialHead()) {}
+ ~iplist() {
+ if (!Head) return;
+ clear();
+ Traits::destroySentinel(getTail());
+ }
+
+ // Iterator creation methods.
+ iterator begin() {
+ CreateLazySentinel();
+ return iterator(Head);
+ }
+ const_iterator begin() const {
+ CreateLazySentinel();
+ return const_iterator(Head);
+ }
+ iterator end() {
+ CreateLazySentinel();
+ return iterator(getTail());
+ }
+ const_iterator end() const {
+ CreateLazySentinel();
+ return const_iterator(getTail());
+ }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+ // Miscellaneous inspection routines.
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return Head == 0 || Head == getTail(); }
+
+ // Front and back accessor functions...
+ reference front() {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ const_reference front() const {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ reference back() {
+ assert(!empty() && "Called back() on empty list!");
+ return *this->getPrev(getTail());
+ }
+ const_reference back() const {
+ assert(!empty() && "Called back() on empty list!");
+ return *this->getPrev(getTail());
+ }
+
+ void swap(iplist &RHS) {
+ assert(0 && "Swap does not use list traits callback correctly yet!");
+ std::swap(Head, RHS.Head);
+ }
+
+ iterator insert(iterator where, NodeTy *New) {
+ NodeTy *CurNode = where.getNodePtrUnchecked();
+ NodeTy *PrevNode = this->getPrev(CurNode);
+ this->setNext(New, CurNode);
+ this->setPrev(New, PrevNode);
+
+ if (CurNode != Head) // Is PrevNode off the beginning of the list?
+ this->setNext(PrevNode, New);
+ else
+ Head = New;
+ this->setPrev(CurNode, New);
+
+ this->addNodeToList(New); // Notify traits that we added a node...
+ return New;
+ }
+
+ iterator insertAfter(iterator where, NodeTy *New) {
+ if (empty())
+ return insert(begin(), New);
+ else
+ return insert(++where, New);
+ }
+
+ NodeTy *remove(iterator &IT) {
+ assert(IT != end() && "Cannot remove end of list!");
+ NodeTy *Node = &*IT;
+ NodeTy *NextNode = this->getNext(Node);
+ NodeTy *PrevNode = this->getPrev(Node);
+
+ if (Node != Head) // Is PrevNode off the beginning of the list?
+ this->setNext(PrevNode, NextNode);
+ else
+ Head = NextNode;
+ this->setPrev(NextNode, PrevNode);
+ IT = NextNode;
+ this->removeNodeFromList(Node); // Notify traits that we removed a node...
+
+ // Set the next/prev pointers of the current node to null. This isn't
+ // strictly required, but this catches errors where a node is removed from
+ // an ilist (and potentially deleted) with iterators still pointing at it.
+ // When those iterators are incremented or decremented, they will assert on
+ // the null next/prev pointer instead of "usually working".
+ this->setNext(Node, 0);
+ this->setPrev(Node, 0);
+ return Node;
+ }
+
+ NodeTy *remove(const iterator &IT) {
+ iterator MutIt = IT;
+ return remove(MutIt);
+ }
+
+ // erase - remove a node from the controlled sequence... and delete it.
+ iterator erase(iterator where) {
+ this->deleteNode(remove(where));
+ return where;
+ }
+
+
+private:
+ // transfer - The heart of the splice function. Move linked list nodes from
+ // [first, last) into position.
+ //
+ void transfer(iterator position, iplist &L2, iterator first, iterator last) {
+ assert(first != last && "Should be checked by callers");
+
+ if (position != last) {
+ // Note: we have to be careful about the case when we move the first node
+ // in the list. This node is the list sentinel node and we can't move it.
+ NodeTy *ThisSentinel = getTail();
+ setTail(0);
+ NodeTy *L2Sentinel = L2.getTail();
+ L2.setTail(0);
+
+ // Remove [first, last) from its old position.
+ NodeTy *First = &*first, *Prev = getPrev(First);
+ NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
+ if (Prev)
+ this->setNext(Prev, Next);
+ else
+ L2.Head = Next;
+ this->setPrev(Next, Prev);
+
+ // Splice [first, last) into its new position.
+ NodeTy *PosNext = position.getNodePtrUnchecked();
+ NodeTy *PosPrev = getPrev(PosNext);
+
+ // Fix head of list...
+ if (PosPrev)
+ this->setNext(PosPrev, First);
+ else
+ Head = First;
+ this->setPrev(First, PosPrev);
+
+ // Fix end of list...
+ this->setNext(Last, PosNext);
+ this->setPrev(PosNext, Last);
+
+ transferNodesFromList(L2, First, PosNext);
+
+ // Now that everything is set, restore the pointers to the list sentinels.
+ L2.setTail(L2Sentinel);
+ setTail(ThisSentinel);
+ }
+ }
+
+public:
+
+ //===----------------------------------------------------------------------===
+ // Functionality derived from other functions defined above...
+ //
+
+ size_type size() const {
+ if (Head == 0) return 0; // Don't require construction of sentinel if empty.
+ return std::distance(begin(), end());
+ }
+
+ iterator erase(iterator first, iterator last) {
+ while (first != last)
+ first = erase(first);
+ return last;
+ }
+
+ void clear() { if (Head) erase(begin(), end()); }
+
+ // Front and back inserters...
+ void push_front(NodeTy *val) { insert(begin(), val); }
+ void push_back(NodeTy *val) { insert(end(), val); }
+ void pop_front() {
+ assert(!empty() && "pop_front() on empty list!");
+ erase(begin());
+ }
+ void pop_back() {
+ assert(!empty() && "pop_back() on empty list!");
+ iterator t = end(); erase(--t);
+ }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+
+ // Splice members - defined in terms of transfer...
+ void splice(iterator where, iplist &L2) {
+ if (!L2.empty())
+ transfer(where, L2, L2.begin(), L2.end());
+ }
+ void splice(iterator where, iplist &L2, iterator first) {
+ iterator last = first; ++last;
+ if (where == first || where == last) return; // No change
+ transfer(where, L2, first, last);
+ }
+ void splice(iterator where, iplist &L2, iterator first, iterator last) {
+ if (first != last) transfer(where, L2, first, last);
+ }
+
+
+
+ //===----------------------------------------------------------------------===
+ // High-Level Functionality that shouldn't really be here, but is part of list
+ //
+
+ // These two functions are actually called remove/remove_if in list<>, but
+ // they actually do the job of erase, rename them accordingly.
+ //
+ void erase(const NodeTy &val) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (*I == val) erase(I);
+ I = next;
+ }
+ }
+ template<class Pr1> void erase_if(Pr1 pred) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (pred(*I)) erase(I);
+ I = next;
+ }
+ }
+
+ template<class Pr2> void unique(Pr2 pred) {
+ if (empty()) return;
+ for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
+ if (pred(*I))
+ erase(Next);
+ else
+ I = Next;
+ Next = I;
+ }
+ }
+ void unique() { unique(op_equal); }
+
+ template<class Pr3> void merge(iplist &right, Pr3 pred) {
+ iterator first1 = begin(), last1 = end();
+ iterator first2 = right.begin(), last2 = right.end();
+ while (first1 != last1 && first2 != last2)
+ if (pred(*first2, *first1)) {
+ iterator next = first2;
+ transfer(first1, right, first2, ++next);
+ first2 = next;
+ } else {
+ ++first1;
+ }
+ if (first2 != last2) transfer(last1, right, first2, last2);
+ }
+ void merge(iplist &right) { return merge(right, op_less); }
+
+ template<class Pr3> void sort(Pr3 pred);
+ void sort() { sort(op_less); }
+ void reverse();
+};
+
+
+template<typename NodeTy>
+struct ilist : public iplist<NodeTy> {
+ typedef typename iplist<NodeTy>::size_type size_type;
+ typedef typename iplist<NodeTy>::iterator iterator;
+
+ ilist() {}
+ ilist(const ilist &right) {
+ insert(this->begin(), right.begin(), right.end());
+ }
+ explicit ilist(size_type count) {
+ insert(this->begin(), count, NodeTy());
+ }
+ ilist(size_type count, const NodeTy &val) {
+ insert(this->begin(), count, val);
+ }
+ template<class InIt> ilist(InIt first, InIt last) {
+ insert(this->begin(), first, last);
+ }
+
+ // bring hidden functions into scope
+ using iplist<NodeTy>::insert;
+ using iplist<NodeTy>::push_front;
+ using iplist<NodeTy>::push_back;
+
+ // Main implementation here - Insert for a node passed by value...
+ iterator insert(iterator where, const NodeTy &val) {
+ return insert(where, createNode(val));
+ }
+
+
+ // Front and back inserters...
+ void push_front(const NodeTy &val) { insert(this->begin(), val); }
+ void push_back(const NodeTy &val) { insert(this->end(), val); }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+ void insert(iterator where, size_type count, const NodeTy &val) {
+ for (; count != 0; --count) insert(where, val);
+ }
+
+ // Assign special forms...
+ void assign(size_type count, const NodeTy &val) {
+ iterator I = this->begin();
+ for (; I != this->end() && count != 0; ++I, --count)
+ *I = val;
+ if (count != 0)
+ insert(this->end(), val, val);
+ else
+ erase(I, this->end());
+ }
+ template<class InIt> void assign(InIt first1, InIt last1) {
+ iterator first2 = this->begin(), last2 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ erase(first1, last1);
+ else
+ insert(last1, first2, last2);
+ }
+
+
+ // Resize members...
+ void resize(size_type newsize, NodeTy val) {
+ iterator i = this->begin();
+ size_type len = 0;
+ for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
+
+ if (len == newsize)
+ erase(i, this->end());
+ else // i == end()
+ insert(this->end(), newsize - len, val);
+ }
+ void resize(size_type newsize) { resize(newsize, NodeTy()); }
+};
+
+} // End llvm namespace
+
+namespace std {
+ // Ensure that swap uses the fast list swap...
+ template<class Ty>
+ void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
+ Left.swap(Right);
+ }
+} // End 'std' extensions...
+
+#endif // LLVM_ADT_ILIST_H
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
new file mode 100644
index 0000000000000..dae7475ffa012
--- /dev/null
+++ b/include/llvm/ADT/ilist_node.h
@@ -0,0 +1,47 @@
+//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ilist_node class template, which is a convenient
+// base class for creating classes that can be used with ilists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST_NODE_H
+#define LLVM_ADT_ILIST_NODE_H
+
+namespace llvm {
+
+template<typename NodeTy>
+struct ilist_nextprev_traits;
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_node - Base class that provides next/prev services for nodes
+/// that use ilist_nextprev_traits or ilist_default_traits.
+///
+template<typename NodeTy>
+class ilist_node {
+private:
+ friend struct ilist_nextprev_traits<NodeTy>;
+ friend struct ilist_traits<NodeTy>;
+ NodeTy *Prev, *Next;
+ NodeTy *getPrev() { return Prev; }
+ NodeTy *getNext() { return Next; }
+ const NodeTy *getPrev() const { return Prev; }
+ const NodeTy *getNext() const { return Next; }
+ void setPrev(NodeTy *N) { Prev = N; }
+ void setNext(NodeTy *N) { Next = N; }
+protected:
+ ilist_node() : Prev(0), Next(0) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/iterator.cmake b/include/llvm/ADT/iterator.cmake
new file mode 100644
index 0000000000000..55df8ce2643e5
--- /dev/null
+++ b/include/llvm/ADT/iterator.cmake
@@ -0,0 +1,79 @@
+//===-- llvm/ADT/iterator - Portable wrapper around <iterator> --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <iterator> header file.
+// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
+// friends), instead of the standard iterator class. In GCC 3.1, the
+// bidirectional_iterator class got moved out and the new, standards compliant,
+// iterator<> class was added. Because there is nothing that we can do to get
+// correct behavior on both compilers, we have this header with #ifdef's. Gross
+// huh?
+//
+// By #includ'ing this file, you get the contents of <iterator> plus the
+// following classes in the global namespace:
+//
+// 1. bidirectional_iterator
+// 2. forward_iterator
+//
+// The #if directives' expressions are filled in by Autoconf.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR
+#define LLVM_ADT_ITERATOR
+
+#include <iterator>
+
+#undef HAVE_BI_ITERATOR
+#undef HAVE_STD_ITERATOR
+#undef HAVE_FWD_ITERATOR
+
+// defined by Kevin
+#define HAVE_STD_ITERATOR 1
+
+#ifdef _MSC_VER
+# define HAVE_BI_ITERATOR 0
+# define HAVE_STD_ITERATOR 1
+# define HAVE_FWD_ITERATOR 0
+#endif
+
+#if !HAVE_BI_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the bidirectional iterator is not defined, we attempt to define it in
+/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
+/// statement.
+///
+template<class Ty, class PtrDiffTy>
+struct bidirectional_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define bidirectional iterator!"
+# endif
+#else
+using std::bidirectional_iterator;
+#endif
+
+#if !HAVE_FWD_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the forward iterator is not defined, attempt to define it in terms of
+/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
+///
+template<class Ty, class PtrDiffTy>
+struct forward_iterator
+ : public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define forward iterator!"
+# endif
+#else
+using std::forward_iterator;
+#endif
+
+#endif
diff --git a/include/llvm/ADT/iterator.h.in b/include/llvm/ADT/iterator.h.in
new file mode 100644
index 0000000000000..dce74625118b3
--- /dev/null
+++ b/include/llvm/ADT/iterator.h.in
@@ -0,0 +1,76 @@
+//==-- llvm/ADT/iterator.h - Portable wrapper around <iterator> --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <iterator> header file.
+// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
+// friends), instead of the standard iterator class. In GCC 3.1, the
+// bidirectional_iterator class got moved out and the new, standards compliant,
+// iterator<> class was added. Because there is nothing that we can do to get
+// correct behavior on both compilers, we have this header with #ifdef's. Gross
+// huh?
+//
+// By #includ'ing this file, you get the contents of <iterator> plus the
+// following classes in the global namespace:
+//
+// 1. bidirectional_iterator
+// 2. forward_iterator
+//
+// The #if directives' expressions are filled in by Autoconf.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_H
+#define LLVM_ADT_ITERATOR_H
+
+#include <iterator>
+
+#undef HAVE_BI_ITERATOR
+#undef HAVE_STD_ITERATOR
+#undef HAVE_FWD_ITERATOR
+
+#ifdef _MSC_VER
+# define HAVE_BI_ITERATOR 0
+# define HAVE_STD_ITERATOR 1
+# define HAVE_FWD_ITERATOR 0
+#endif
+
+#if !HAVE_BI_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the bidirectional iterator is not defined, we attempt to define it in
+/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
+/// statement.
+///
+template<class Ty, class PtrDiffTy>
+struct bidirectional_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define bidirectional iterator!"
+# endif
+#else
+using std::bidirectional_iterator;
+#endif
+
+#if !HAVE_FWD_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the forward iterator is not defined, attempt to define it in terms of
+/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
+///
+template<class Ty, class PtrDiffTy>
+struct forward_iterator
+ : public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define forward iterator!"
+# endif
+#else
+using std::forward_iterator;
+#endif
+
+#endif // LLVM_ADT_ITERATOR_H