diff options
Diffstat (limited to 'include/llvm')
58 files changed, 2120 insertions, 1252 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index ab23130b137d8..ceb623d34531c 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -189,17 +189,17 @@ private: void initSlowCase(const APInt &that); /// out-of-line slow case for shl - APInt shlSlowCase(unsigned shiftAmt) const; + void shlSlowCase(unsigned ShiftAmt); + + /// out-of-line slow case for lshr. + void lshrSlowCase(unsigned ShiftAmt); /// out-of-line slow case for operator= - APInt &AssignSlowCase(const APInt &RHS); + void AssignSlowCase(const APInt &RHS); /// out-of-line slow case for operator== bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY; - /// out-of-line slow case for operator== - bool EqualSlowCase(uint64_t Val) const LLVM_READONLY; - /// out-of-line slow case for countLeadingZeros unsigned countLeadingZerosSlowCase() const LLVM_READONLY; @@ -209,6 +209,12 @@ private: /// out-of-line slow case for countPopulation unsigned countPopulationSlowCase() const LLVM_READONLY; + /// out-of-line slow case for intersects. + bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY; + + /// out-of-line slow case for isSubsetOf. + bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY; + /// out-of-line slow case for setBits. void setBitsSlowCase(unsigned loBit, unsigned hiBit); @@ -216,13 +222,13 @@ private: void flipAllBitsSlowCase(); /// out-of-line slow case for operator&=. - APInt& AndAssignSlowCase(const APInt& RHS); + void AndAssignSlowCase(const APInt& RHS); /// out-of-line slow case for operator|=. - APInt& OrAssignSlowCase(const APInt& RHS); + void OrAssignSlowCase(const APInt& RHS); /// out-of-line slow case for operator^=. - APInt& XorAssignSlowCase(const APInt& RHS); + void XorAssignSlowCase(const APInt& RHS); public: /// \name Constructors @@ -330,6 +336,20 @@ public: /// This tests the high bit of the APInt to determine if it is unset. bool isNonNegative() const { return !isNegative(); } + /// \brief Determine if sign bit of this APInt is set. + /// + /// This tests the high bit of this APInt to determine if it is set. + /// + /// \returns true if this APInt has its sign bit set, false otherwise. + bool isSignBitSet() const { return (*this)[BitWidth-1]; } + + /// \brief Determine if sign bit of this APInt is clear. + /// + /// This tests the high bit of this APInt to determine if it is clear. + /// + /// \returns true if this APInt has its sign bit clear, false otherwise. + bool isSignBitClear() const { return !isSignBitSet(); } + /// \brief Determine if this APInt Value is positive. /// /// This tests if the value of this APInt is positive (> 0). Note @@ -396,10 +416,10 @@ public: return countPopulationSlowCase() == 1; } - /// \brief Check if the APInt's value is returned by getSignBit. + /// \brief Check if the APInt's value is returned by getSignMask. /// - /// \returns true if this is the value returned by getSignBit. - bool isSignBit() const { return isMinSignedValue(); } + /// \returns true if this is the value returned by getSignMask. + bool isSignMask() const { return isMinSignedValue(); } /// \brief Convert APInt to a boolean value. /// @@ -409,8 +429,7 @@ public: /// 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 = UINT64_MAX) const { - return (getActiveBits() > 64 || getZExtValue() > Limit) ? Limit - : getZExtValue(); + return ugt(Limit) ? Limit : getZExtValue(); } /// \brief Check if the APInt consists of a repeated bit pattern. @@ -427,8 +446,9 @@ public: assert(numBits <= BitWidth && "numBits out of range"); if (isSingleWord()) return VAL == (UINT64_MAX >> (APINT_BITS_PER_WORD - numBits)); - unsigned Ones = countTrailingOnes(); - return (numBits == Ones) && ((Ones + countLeadingZeros()) == BitWidth); + unsigned Ones = countTrailingOnesSlowCase(); + return (numBits == Ones) && + ((Ones + countLeadingZerosSlowCase()) == BitWidth); } /// \returns true if this APInt is a non-empty sequence of ones starting at @@ -437,8 +457,8 @@ public: bool isMask() const { if (isSingleWord()) return isMask_64(VAL); - unsigned Ones = countTrailingOnes(); - return (Ones > 0) && ((Ones + countLeadingZeros()) == BitWidth); + unsigned Ones = countTrailingOnesSlowCase(); + return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth); } /// \brief Return true if this APInt value contains a sequence of ones with @@ -446,8 +466,9 @@ public: bool isShiftedMask() const { if (isSingleWord()) return isShiftedMask_64(VAL); - unsigned Ones = countPopulation(); - return (Ones + countTrailingZeros() + countLeadingZeros()) == BitWidth; + unsigned Ones = countPopulationSlowCase(); + unsigned LeadZ = countLeadingZerosSlowCase(); + return (Ones + LeadZ + countTrailingZeros()) == BitWidth; } /// @} @@ -476,11 +497,11 @@ public: return API; } - /// \brief Get the SignBit for a specific bit width. + /// \brief Get the SignMask for a specific bit width. /// /// This is just a wrapper function of getSignedMinValue(), and it helps code - /// readability when we want to get a SignBit. - static APInt getSignBit(unsigned BitWidth) { + /// readability when we want to get a SignMask. + static APInt getSignMask(unsigned BitWidth) { return getSignedMinValue(BitWidth); } @@ -674,29 +695,22 @@ public: return clearUnusedBits(); } - return AssignSlowCase(RHS); + AssignSlowCase(RHS); + return *this; } /// @brief Move assignment operator. APInt &operator=(APInt &&that) { - if (!isSingleWord()) { - // The MSVC STL shipped in 2013 requires that self move assignment be a - // no-op. Otherwise algorithms like stable_sort will produce answers - // where half of the output is left in a moved-from state. - if (this == &that) - return *this; + assert(this != &that && "Self-move not supported"); + if (!isSingleWord()) delete[] pVal; - } // Use memcpy so that type based alias analysis sees both VAL and pVal // as modified. memcpy(&VAL, &that.VAL, sizeof(uint64_t)); - // If 'this == &that', avoid zeroing our own bitwidth by storing to 'that' - // first. - unsigned ThatBitWidth = that.BitWidth; + BitWidth = that.BitWidth; that.BitWidth = 0; - BitWidth = ThatBitWidth; return *this; } @@ -727,11 +741,11 @@ public: /// \returns *this after ANDing with RHS. APInt &operator&=(const APInt &RHS) { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) { + if (isSingleWord()) VAL &= RHS.VAL; - return *this; - } - return AndAssignSlowCase(RHS); + else + AndAssignSlowCase(RHS); + return *this; } /// \brief Bitwise AND assignment operator. @@ -757,11 +771,11 @@ public: /// \returns *this after ORing with RHS. APInt &operator|=(const APInt &RHS) { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) { + if (isSingleWord()) VAL |= RHS.VAL; - return *this; - } - return OrAssignSlowCase(RHS); + else + OrAssignSlowCase(RHS); + return *this; } /// \brief Bitwise OR assignment operator. @@ -787,11 +801,11 @@ public: /// \returns *this after XORing with RHS. APInt &operator^=(const APInt &RHS) { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) { + if (isSingleWord()) VAL ^= RHS.VAL; - return *this; - } - return XorAssignSlowCase(RHS); + else + XorAssignSlowCase(RHS); + return *this; } /// \brief Bitwise XOR assignment operator. @@ -836,9 +850,17 @@ public: /// /// Shifts *this left by shiftAmt and assigns the result to *this. /// - /// \returns *this after shifting left by shiftAmt - APInt &operator<<=(unsigned shiftAmt) { - *this = shl(shiftAmt); + /// \returns *this after shifting left by ShiftAmt + APInt &operator<<=(unsigned ShiftAmt) { + assert(ShiftAmt <= BitWidth && "Invalid shift amount"); + if (isSingleWord()) { + if (ShiftAmt == BitWidth) + VAL = 0; + else + VAL <<= ShiftAmt; + return clearUnusedBits(); + } + shlSlowCase(ShiftAmt); return *this; } @@ -875,20 +897,26 @@ public: return R; } - /// Logical right-shift this APInt by shiftAmt in place. - void lshrInPlace(unsigned shiftAmt); + /// Logical right-shift this APInt by ShiftAmt in place. + void lshrInPlace(unsigned ShiftAmt) { + assert(ShiftAmt <= BitWidth && "Invalid shift amount"); + if (isSingleWord()) { + if (ShiftAmt == BitWidth) + VAL = 0; + else + VAL >>= ShiftAmt; + return; + } + lshrSlowCase(ShiftAmt); + } /// \brief Left-shift function. /// /// Left-shift this APInt by shiftAmt. 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); + APInt R(*this); + R <<= shiftAmt; + return R; } /// \brief Rotate left by rotateAmt. @@ -905,7 +933,14 @@ public: /// \brief Logical right-shift function. /// /// Logical right-shift this APInt by shiftAmt. - APInt lshr(const APInt &shiftAmt) const; + APInt lshr(const APInt &ShiftAmt) const { + APInt R(*this); + R.lshrInPlace(ShiftAmt); + return R; + } + + /// Logical right-shift this APInt by ShiftAmt in place. + void lshrInPlace(const APInt &ShiftAmt); /// \brief Left-shift function. /// @@ -1003,9 +1038,7 @@ public: /// /// \returns true if *this == Val bool operator==(uint64_t Val) const { - if (isSingleWord()) - return VAL == Val; - return EqualSlowCase(Val); + return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val; } /// \brief Equality comparison. @@ -1055,7 +1088,8 @@ public: /// /// \returns true if *this < RHS when considered unsigned. bool ult(uint64_t RHS) const { - return getActiveBits() > 64 ? false : getZExtValue() < RHS; + // Only need to check active bits if not a single word. + return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS; } /// \brief Signed less than comparison @@ -1073,7 +1107,8 @@ public: /// /// \returns true if *this < RHS when considered signed. bool slt(int64_t RHS) const { - return getMinSignedBits() > 64 ? isNegative() : getSExtValue() < RHS; + return (!isSingleWord() && getMinSignedBits() > 64) ? isNegative() + : getSExtValue() < RHS; } /// \brief Unsigned less or equal comparison @@ -1123,7 +1158,8 @@ public: /// /// \returns true if *this > RHS when considered unsigned. bool ugt(uint64_t RHS) const { - return getActiveBits() > 64 ? true : getZExtValue() > RHS; + // Only need to check active bits if not a single word. + return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS; } /// \brief Signed greather than comparison @@ -1141,7 +1177,8 @@ public: /// /// \returns true if *this > RHS when considered signed. bool sgt(int64_t RHS) const { - return getMinSignedBits() > 64 ? !isNegative() : getSExtValue() > RHS; + return (!isSingleWord() && getMinSignedBits() > 64) ? !isNegative() + : getSExtValue() > RHS; } /// \brief Unsigned greater or equal comparison @@ -1179,9 +1216,18 @@ public: /// 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 { - APInt temp(*this); - temp &= RHS; - return temp != 0; + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + if (isSingleWord()) + return (VAL & RHS.VAL) != 0; + return intersectsSlowCase(RHS); + } + + /// This operation checks that all bits set in this APInt are also set in RHS. + bool isSubsetOf(const APInt &RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + if (isSingleWord()) + return (VAL & ~RHS.VAL) == 0; + return isSubsetOfSlowCase(RHS); } /// @} @@ -1404,8 +1450,7 @@ public: /// int64_t. Otherwise an assertion will result. int64_t getSExtValue() const { if (isSingleWord()) - return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >> - (APINT_BITS_PER_WORD - BitWidth); + return SignExtend64(VAL, BitWidth); assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); return int64_t(pVal[0]); } @@ -1759,13 +1804,13 @@ public: WordType *remainder, WordType *scratch, unsigned parts); - /// Shift a bignum left COUNT bits. Shifted in bits are zero. There are no - /// restrictions on COUNT. - static void tcShiftLeft(WordType *, unsigned parts, unsigned count); + /// Shift a bignum left Count bits. Shifted in bits are zero. There are no + /// restrictions on Count. + static void tcShiftLeft(WordType *, unsigned Words, unsigned Count); - /// Shift a bignum right COUNT bits. Shifted in bits are zero. There are no - /// restrictions on COUNT. - static void tcShiftRight(WordType *, unsigned parts, unsigned count); + /// Shift a bignum right Count bits. Shifted in bits are zero. There are no + /// restrictions on Count. + static void tcShiftRight(WordType *, unsigned Words, unsigned Count); /// The obvious AND, OR and XOR and complement operations. static void tcAnd(WordType *, const WordType *, unsigned); @@ -1959,7 +2004,7 @@ inline const APInt &umax(const APInt &A, const APInt &B) { /// \brief Compute GCD of two unsigned APInt values. /// /// This function returns the greatest common divisor of the two APInt values -/// using Euclid's algorithm. +/// using Stein's algorithm. /// /// \returns the greatest common divisor of A and B. APInt GreatestCommonDivisor(APInt A, APInt B); diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 8240d01ae977c..e48c023ae7df9 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -14,6 +14,8 @@ #ifndef LLVM_ADT_BITVECTOR_H #define LLVM_ADT_BITVECTOR_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" #include <algorithm> #include <cassert> @@ -455,6 +457,105 @@ public: return *this; } + BitVector &operator>>=(unsigned N) { + assert(N <= Size); + if (LLVM_UNLIKELY(empty() || N == 0)) + return *this; + + unsigned NumWords = NumBitWords(Size); + assert(NumWords >= 1); + + wordShr(N / BITWORD_SIZE); + + unsigned BitDistance = N % BITWORD_SIZE; + if (BitDistance == 0) + return *this; + + // When the shift size is not a multiple of the word size, then we have + // a tricky situation where each word in succession needs to extract some + // of the bits from the next word and or them into this word while + // shifting this word to make room for the new bits. This has to be done + // for every word in the array. + + // Since we're shifting each word right, some bits will fall off the end + // of each word to the right, and empty space will be created on the left. + // The final word in the array will lose bits permanently, so starting at + // the beginning, work forwards shifting each word to the right, and + // OR'ing in the bits from the end of the next word to the beginning of + // the current word. + + // Example: + // Starting with {0xAABBCCDD, 0xEEFF0011, 0x22334455} and shifting right + // by 4 bits. + // Step 1: Word[0] >>= 4 ; 0x0ABBCCDD + // Step 2: Word[0] |= 0x10000000 ; 0x1ABBCCDD + // Step 3: Word[1] >>= 4 ; 0x0EEFF001 + // Step 4: Word[1] |= 0x50000000 ; 0x5EEFF001 + // Step 5: Word[2] >>= 4 ; 0x02334455 + // Result: { 0x1ABBCCDD, 0x5EEFF001, 0x02334455 } + const BitWord Mask = maskTrailingOnes<BitWord>(BitDistance); + const unsigned LSH = BITWORD_SIZE - BitDistance; + + for (unsigned I = 0; I < NumWords - 1; ++I) { + Bits[I] >>= BitDistance; + Bits[I] |= (Bits[I + 1] & Mask) << LSH; + } + + Bits[NumWords - 1] >>= BitDistance; + + return *this; + } + + BitVector &operator<<=(unsigned N) { + assert(N <= Size); + if (LLVM_UNLIKELY(empty() || N == 0)) + return *this; + + unsigned NumWords = NumBitWords(Size); + assert(NumWords >= 1); + + wordShl(N / BITWORD_SIZE); + + unsigned BitDistance = N % BITWORD_SIZE; + if (BitDistance == 0) + return *this; + + // When the shift size is not a multiple of the word size, then we have + // a tricky situation where each word in succession needs to extract some + // of the bits from the previous word and or them into this word while + // shifting this word to make room for the new bits. This has to be done + // for every word in the array. This is similar to the algorithm outlined + // in operator>>=, but backwards. + + // Since we're shifting each word left, some bits will fall off the end + // of each word to the left, and empty space will be created on the right. + // The first word in the array will lose bits permanently, so starting at + // the end, work backwards shifting each word to the left, and OR'ing + // in the bits from the end of the next word to the beginning of the + // current word. + + // Example: + // Starting with {0xAABBCCDD, 0xEEFF0011, 0x22334455} and shifting left + // by 4 bits. + // Step 1: Word[2] <<= 4 ; 0x23344550 + // Step 2: Word[2] |= 0x0000000E ; 0x2334455E + // Step 3: Word[1] <<= 4 ; 0xEFF00110 + // Step 4: Word[1] |= 0x0000000A ; 0xEFF0011A + // Step 5: Word[0] <<= 4 ; 0xABBCCDD0 + // Result: { 0xABBCCDD0, 0xEFF0011A, 0x2334455E } + const BitWord Mask = maskLeadingOnes<BitWord>(BitDistance); + const unsigned RSH = BITWORD_SIZE - BitDistance; + + for (int I = NumWords - 1; I > 0; --I) { + Bits[I] <<= BitDistance; + Bits[I] |= (Bits[I - 1] & Mask) >> RSH; + } + Bits[0] <<= BitDistance; + clear_unused_bits(); + + return *this; + } + // Assignment operator. const BitVector &operator=(const BitVector &RHS) { if (this == &RHS) return *this; @@ -538,6 +639,54 @@ public: } private: + /// \brief Perform a logical left shift of \p Count words by moving everything + /// \p Count words to the right in memory. + /// + /// While confusing, words are stored from least significant at Bits[0] to + /// most significant at Bits[NumWords-1]. A logical shift left, however, + /// moves the current least significant bit to a higher logical index, and + /// fills the previous least significant bits with 0. Thus, we actually + /// need to move the bytes of the memory to the right, not to the left. + /// Example: + /// Words = [0xBBBBAAAA, 0xDDDDFFFF, 0x00000000, 0xDDDD0000] + /// represents a BitVector where 0xBBBBAAAA contain the least significant + /// bits. So if we want to shift the BitVector left by 2 words, we need to + /// turn this into 0x00000000 0x00000000 0xBBBBAAAA 0xDDDDFFFF by using a + /// memmove which moves right, not left. + void wordShl(uint32_t Count) { + if (Count == 0) + return; + + uint32_t NumWords = NumBitWords(Size); + + auto Src = ArrayRef<BitWord>(Bits, NumWords).drop_back(Count); + auto Dest = MutableArrayRef<BitWord>(Bits, NumWords).drop_front(Count); + + // Since we always move Word-sized chunks of data with src and dest both + // aligned to a word-boundary, we don't need to worry about endianness + // here. + std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord)); + std::memset(Bits, 0, Count * sizeof(BitWord)); + clear_unused_bits(); + } + + /// \brief Perform a logical right shift of \p Count words by moving those + /// words to the left in memory. See wordShl for more information. + /// + void wordShr(uint32_t Count) { + if (Count == 0) + return; + + uint32_t NumWords = NumBitWords(Size); + + auto Src = ArrayRef<BitWord>(Bits, NumWords).drop_front(Count); + auto Dest = MutableArrayRef<BitWord>(Bits, NumWords).drop_back(Count); + assert(Dest.size() == Src.size()); + + std::memmove(Dest.begin(), Src.begin(), Dest.size() * sizeof(BitWord)); + std::memset(Dest.end(), 0, Count * sizeof(BitWord)); + } + int next_unset_in_word(int WordIndex, BitWord Word) const { unsigned Result = WordIndex * BITWORD_SIZE + countTrailingOnes(Word); return Result < size() ? Result : -1; diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index edb37da38da1b..607e040a606cb 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -508,6 +508,22 @@ public: return *this; } + SmallBitVector &operator<<=(unsigned N) { + if (isSmall()) + setSmallBits(getSmallBits() << N); + else + getPointer()->operator<<=(N); + return *this; + } + + SmallBitVector &operator>>=(unsigned N) { + if (isSmall()) + setSmallBits(getSmallBits() >> N); + else + getPointer()->operator>>=(N); + return *this; + } + // Assignment operator. const SmallBitVector &operator=(const SmallBitVector &RHS) { if (isSmall()) { diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index e3d81fea49ea1..3e05e09900a5f 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -1164,9 +1164,8 @@ template <class BT> struct BlockEdgesAdder { void operator()(IrreducibleGraph &G, IrreducibleGraph::IrrNode &Irr, const LoopData *OuterLoop) { const BlockT *BB = BFI.RPOT[Irr.Node.Index]; - for (auto I = Successor::child_begin(BB), E = Successor::child_end(BB); - I != E; ++I) - G.addEdge(Irr, BFI.getNode(*I), OuterLoop); + for (const auto Succ : children<const BlockT *>(BB)) + G.addEdge(Irr, BFI.getNode(Succ), OuterLoop); } }; } @@ -1210,10 +1209,9 @@ BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop, return false; } else { const BlockT *BB = getBlock(Node); - for (auto SI = Successor::child_begin(BB), SE = Successor::child_end(BB); - SI != SE; ++SI) - if (!addToDist(Dist, OuterLoop, Node, getNode(*SI), - getWeightFromBranchProb(BPI->getEdgeProbability(BB, SI)))) + for (const auto Succ : children<const BlockT *>(BB)) + if (!addToDist(Dist, OuterLoop, Node, getNode(Succ), + getWeightFromBranchProb(BPI->getEdgeProbability(BB, Succ)))) // Irreducible backedge. return false; } diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h index 629ae38090457..9f8cacc24f2ce 100644 --- a/include/llvm/Analysis/DominanceFrontierImpl.h +++ b/include/llvm/Analysis/DominanceFrontierImpl.h @@ -174,12 +174,10 @@ ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT, // Visit each block only once. if (visited.insert(currentBB).second) { // Loop over CFG successors to calculate DFlocal[currentNode] - for (auto SI = BlockTraits::child_begin(currentBB), - SE = BlockTraits::child_end(currentBB); - SI != SE; ++SI) { + for (const auto Succ : children<BlockT *>(currentBB)) { // Does Node immediately dominate this successor? - if (DT[*SI]->getIDom() != currentNode) - S.insert(*SI); + if (DT[Succ]->getIDom() != currentNode) + S.insert(Succ); } } diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 996794b660a9e..2fad1737d1c03 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -158,11 +158,8 @@ public: /// True if terminator in the block can branch to another block that is /// outside of the current loop. bool isLoopExiting(const BlockT *BB) const { - typedef GraphTraits<const BlockT*> BlockTraits; - for (typename BlockTraits::ChildIteratorType SI = - BlockTraits::child_begin(BB), - SE = BlockTraits::child_end(BB); SI != SE; ++SI) { - if (!contains(*SI)) + for (const auto Succ : children<const BlockT*>(BB)) { + if (!contains(Succ)) return true; } return false; @@ -186,11 +183,8 @@ public: unsigned NumBackEdges = 0; BlockT *H = getHeader(); - typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; - for (typename InvBlockTraits::ChildIteratorType I = - InvBlockTraits::child_begin(H), - E = InvBlockTraits::child_end(H); I != E; ++I) - if (contains(*I)) + for (const auto Pred : children<Inverse<BlockT*> >(H)) + if (contains(Pred)) ++NumBackEdges; return NumBackEdges; @@ -249,12 +243,9 @@ public: /// contains a branch back to the header. void getLoopLatches(SmallVectorImpl<BlockT *> &LoopLatches) const { BlockT *H = getHeader(); - typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; - for (typename InvBlockTraits::ChildIteratorType I = - InvBlockTraits::child_begin(H), - E = InvBlockTraits::child_end(H); I != E; ++I) - if (contains(*I)) - LoopLatches.push_back(*I); + for (const auto Pred : children<Inverse<BlockT*>>(H)) + if (contains(Pred)) + LoopLatches.push_back(Pred); } //===--------------------------------------------------------------------===// diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 761f8721b54fd..6dc0422ce0e94 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -34,14 +34,11 @@ namespace llvm { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const { - typedef GraphTraits<BlockT*> BlockTraits; - for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) - for (typename BlockTraits::ChildIteratorType I = - BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); - I != E; ++I) - if (!contains(*I)) { + for (const auto BB : blocks()) + for (const auto Succ : children<BlockT*>(BB)) + if (!contains(Succ)) { // Not in current loop? It must be an exit block. - ExitingBlocks.push_back(*BI); + ExitingBlocks.push_back(BB); break; } } @@ -63,14 +60,11 @@ BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const { - typedef GraphTraits<BlockT*> BlockTraits; - for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) - for (typename BlockTraits::ChildIteratorType I = - BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); - I != E; ++I) - if (!contains(*I)) + for (const auto BB : blocks()) + for (const auto Succ : children<BlockT*>(BB)) + if (!contains(Succ)) // Not in current loop? It must be an exit block. - ExitBlocks.push_back(*I); + ExitBlocks.push_back(Succ); } /// getExitBlock - If getExitBlocks would return exactly one block, @@ -88,14 +82,11 @@ BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const { template<class BlockT, class LoopT> void LoopBase<BlockT, LoopT>:: getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const { - typedef GraphTraits<BlockT*> BlockTraits; - for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) - for (typename BlockTraits::ChildIteratorType I = - BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI); - I != E; ++I) - if (!contains(*I)) + for (const auto BB : blocks()) + for (const auto Succ : children<BlockT*>(BB)) + if (!contains(Succ)) // Not in current loop? It must be an exit block. - ExitEdges.push_back(Edge(*BI, *I)); + ExitEdges.emplace_back(BB, Succ); } /// getLoopPreheader - If there is a preheader for this loop, return it. A @@ -134,15 +125,11 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const { // Loop over the predecessors of the header node... BlockT *Header = getHeader(); - typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; - for (typename InvBlockTraits::ChildIteratorType PI = - InvBlockTraits::child_begin(Header), - PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) { - typename InvBlockTraits::NodeRef N = *PI; - if (!contains(N)) { // If the block is not in the loop... - if (Out && Out != N) + for (const auto Pred : children<Inverse<BlockT*>>(Header)) { + if (!contains(Pred)) { // If the block is not in the loop... + if (Out && Out != Pred) return nullptr; // Multiple predecessors outside the loop - Out = N; + Out = Pred; } } @@ -156,17 +143,11 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const { template<class BlockT, class LoopT> BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const { BlockT *Header = getHeader(); - typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; - typename InvBlockTraits::ChildIteratorType PI = - InvBlockTraits::child_begin(Header); - typename InvBlockTraits::ChildIteratorType PE = - InvBlockTraits::child_end(Header); BlockT *Latch = nullptr; - for (; PI != PE; ++PI) { - typename InvBlockTraits::NodeRef N = *PI; - if (contains(N)) { + for (const auto Pred : children<Inverse<BlockT*>>(Header)) { + if (contains(Pred)) { if (Latch) return nullptr; - Latch = N; + Latch = Pred; } } @@ -394,11 +375,9 @@ static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges, // within this subloop tree itself. Note that a predecessor may directly // reach another subloop that is not yet discovered to be a subloop of // this loop, which we must traverse. - for (typename InvBlockTraits::ChildIteratorType PI = - InvBlockTraits::child_begin(PredBB), - PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) { - if (LI->getLoopFor(*PI) != Subloop) - ReverseCFGWorklist.push_back(*PI); + for (const auto Pred : children<Inverse<BlockT*>>(PredBB)) { + if (LI->getLoopFor(Pred) != Subloop) + ReverseCFGWorklist.push_back(Pred); } } } @@ -482,13 +461,7 @@ analyze(const DominatorTreeBase<BlockT> &DomTree) { SmallVector<BlockT *, 4> Backedges; // Check each predecessor of the potential loop header. - typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; - for (typename InvBlockTraits::ChildIteratorType PI = - InvBlockTraits::child_begin(Header), - PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) { - - BlockT *Backedge = *PI; - + for (const auto Backedge : children<Inverse<BlockT*>>(Header)) { // If Header dominates predBB, this is a new loop. Collect the backedges. if (DomTree.dominates(Header, Backedge) && DomTree.isReachableFromEntry(Backedge)) { diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index c5514316f75f0..743faf2b67db1 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -54,6 +54,11 @@ bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that +/// allocates memory similar to malloc or calloc. +bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); + +/// \brief Tests if a value is a call or invoke to a library function that /// allocates memory (either malloc, calloc, or strdup like). bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 9a50de540f2b1..91aeae0f728f9 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -1159,8 +1159,20 @@ public: const SCEV *getConstant(const APInt &Val); const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty); + + typedef SmallDenseMap<std::pair<const SCEV *, Type *>, const SCEV *, 8> + ExtendCacheTy; const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty); + const SCEV *getZeroExtendExprCached(const SCEV *Op, Type *Ty, + ExtendCacheTy &Cache); + const SCEV *getZeroExtendExprImpl(const SCEV *Op, Type *Ty, + ExtendCacheTy &Cache); + const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty); + const SCEV *getSignExtendExprCached(const SCEV *Op, Type *Ty, + ExtendCacheTy &Cache); + const SCEV *getSignExtendExprImpl(const SCEV *Op, Type *Ty, + ExtendCacheTy &Cache); const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty); const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, diff --git a/include/llvm/Bitcode/BitcodeReader.h b/include/llvm/Bitcode/BitcodeReader.h index 9e042b17241f7..0701ddbb7f1c0 100644 --- a/include/llvm/Bitcode/BitcodeReader.h +++ b/include/llvm/Bitcode/BitcodeReader.h @@ -46,6 +46,9 @@ namespace llvm { ArrayRef<uint8_t> Buffer; StringRef ModuleIdentifier; + // The string table used to interpret this module. + StringRef Strtab; + // The bitstream location of the IDENTIFICATION_BLOCK. uint64_t IdentificationBit; @@ -70,6 +73,7 @@ namespace llvm { StringRef getBuffer() const { return StringRef((const char *)Buffer.begin(), Buffer.size()); } + StringRef getStrtab() const { return Strtab; } StringRef getModuleIdentifier() const { return ModuleIdentifier; } diff --git a/include/llvm/Bitcode/BitcodeWriter.h b/include/llvm/Bitcode/BitcodeWriter.h index 271cb2d81bbb2..23b5ae87b2787 100644 --- a/include/llvm/Bitcode/BitcodeWriter.h +++ b/include/llvm/Bitcode/BitcodeWriter.h @@ -15,6 +15,7 @@ #define LLVM_BITCODE_BITCODEWRITER_H #include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/MC/StringTableBuilder.h" #include <string> namespace llvm { @@ -26,12 +27,25 @@ namespace llvm { SmallVectorImpl<char> &Buffer; std::unique_ptr<BitstreamWriter> Stream; + StringTableBuilder StrtabBuilder{StringTableBuilder::RAW}; + bool WroteStrtab = false; + + void writeBlob(unsigned Block, unsigned Record, StringRef Blob); + public: /// Create a BitcodeWriter that writes to Buffer. BitcodeWriter(SmallVectorImpl<char> &Buffer); ~BitcodeWriter(); + /// Write the bitcode file's string table. This must be called exactly once + /// after all modules have been written. + void writeStrtab(); + + /// Copy the string table for another module into this bitcode file. This + /// should be called after copying the module itself into the bitcode file. + void copyStrtab(StringRef Strtab); + /// Write the specified module to the buffer specified at construction time. /// /// If \c ShouldPreserveUseListOrder, encode the use-list order for each \a diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index e2d2fbb0f449a..03eac80bc1e89 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -22,7 +22,7 @@ namespace llvm { namespace bitc { -// The only top-level block type defined is for a module. +// The only top-level block types are MODULE, IDENTIFICATION and STRTAB. enum BlockIDs { // Blocks MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, @@ -52,7 +52,9 @@ enum BlockIDs { OPERAND_BUNDLE_TAGS_BLOCK_ID, - METADATA_KIND_BLOCK_ID + METADATA_KIND_BLOCK_ID, + + STRTAB_BLOCK_ID, }; /// Identification block contains a string that describes the producer details, @@ -232,6 +234,10 @@ enum GlobalValueSummarySymtabCodes { // llvm.type.checked.load intrinsic with all constant integer arguments. // [typeid, offset, n x arg] FS_TYPE_CHECKED_LOAD_CONST_VCALL = 15, + // Assigns a GUID to a value ID. This normally appears only in combined + // summaries, but it can also appear in per-module summaries for PGO data. + // [valueid, guid] + FS_VALUE_GUID = 16, }; enum MetadataCodes { @@ -550,6 +556,10 @@ enum ComdatSelectionKindCodes { COMDAT_SELECTION_KIND_SAME_SIZE = 5, }; +enum StrtabCodes { + STRTAB_BLOB = 1, +}; + } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index d8096aeb215ad..911e8756070b2 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -62,9 +62,6 @@ protected: const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const; - Optional<int64_t> getConstantVRegVal(unsigned VReg, - const MachineRegisterInfo &MRI) const; - bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const; diff --git a/include/llvm/CodeGen/GlobalISel/Utils.h b/include/llvm/CodeGen/GlobalISel/Utils.h index 52bf965a3cb3f..92bc9736141a1 100644 --- a/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/include/llvm/CodeGen/GlobalISel/Utils.h @@ -60,5 +60,8 @@ void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, const char *PassName, StringRef Msg, const MachineInstr &MI); +Optional<int64_t> getConstantVRegVal(unsigned VReg, + const MachineRegisterInfo &MRI); + } // End namespace llvm. #endif diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index ef4226d30fe36..412c55d542ea6 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -413,6 +413,11 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB, unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr); +/// Clone a DBG_VALUE whose value has been spilled to FrameIndex. +MachineInstr *buildDbgValueForSpill(MachineBasicBlock &BB, + MachineBasicBlock::iterator I, + const MachineInstr &Orig, int FrameIndex); + inline unsigned getDefRegState(bool B) { return B ? RegState::Define : 0; } diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index e4744fd5e260b..a90fe96227b99 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -28,155 +28,246 @@ namespace llvm { /// type can be represented by an MVT. class MVT { public: - enum SimpleValueType : int8_t { - // Simple value types less than zero are considered extended value types. - INVALID_SIMPLE_VALUE_TYPE = -1, + enum SimpleValueType : uint8_t { + // Simple value types that aren't explicitly part of this enumeration + // are considered extended value types. + INVALID_SIMPLE_VALUE_TYPE = 0, // If you change this numbering, you must change the values in // ValueTypes.td as well! - Other = 0, // This is a non-standard value - i1 = 1, // This is a 1 bit integer value - i8 = 2, // This is an 8 bit integer value - i16 = 3, // This is a 16 bit integer value - i32 = 4, // This is a 32 bit integer value - i64 = 5, // This is a 64 bit integer value - i128 = 6, // This is a 128 bit integer value + Other = 1, // This is a non-standard value + i1 = 2, // This is a 1 bit integer value + i8 = 3, // This is an 8 bit integer value + i16 = 4, // This is a 16 bit integer value + i32 = 5, // This is a 32 bit integer value + i64 = 6, // This is a 64 bit integer value + i128 = 7, // This is a 128 bit integer value FIRST_INTEGER_VALUETYPE = i1, LAST_INTEGER_VALUETYPE = i128, - f16 = 7, // This is a 16 bit floating point value - f32 = 8, // This is a 32 bit floating point value - f64 = 9, // This is a 64 bit floating point value - f80 = 10, // This is a 80 bit floating point value - f128 = 11, // This is a 128 bit floating point value - ppcf128 = 12, // This is a PPC 128-bit floating point value + f16 = 8, // This is a 16 bit floating point value + f32 = 9, // This is a 32 bit floating point value + f64 = 10, // This is a 64 bit floating point value + f80 = 11, // This is a 80 bit floating point value + f128 = 12, // This is a 128 bit floating point value + ppcf128 = 13, // This is a PPC 128-bit floating point value FIRST_FP_VALUETYPE = f16, LAST_FP_VALUETYPE = ppcf128, - v2i1 = 13, // 2 x i1 - v4i1 = 14, // 4 x i1 - v8i1 = 15, // 8 x i1 - v16i1 = 16, // 16 x i1 - v32i1 = 17, // 32 x i1 - v64i1 = 18, // 64 x i1 - v512i1 = 19, // 512 x i1 - v1024i1 = 20, // 1024 x i1 - - v1i8 = 21, // 1 x i8 - v2i8 = 22, // 2 x i8 - v4i8 = 23, // 4 x i8 - v8i8 = 24, // 8 x i8 - v16i8 = 25, // 16 x i8 - v32i8 = 26, // 32 x i8 - v64i8 = 27, // 64 x i8 - v128i8 = 28, //128 x i8 - v256i8 = 29, //256 x i8 - - v1i16 = 30, // 1 x i16 - v2i16 = 31, // 2 x i16 - v4i16 = 32, // 4 x i16 - v8i16 = 33, // 8 x i16 - v16i16 = 34, // 16 x i16 - v32i16 = 35, // 32 x i16 - v64i16 = 36, // 64 x i16 - v128i16 = 37, //128 x i16 - - v1i32 = 38, // 1 x i32 - v2i32 = 39, // 2 x i32 - v4i32 = 40, // 4 x i32 - v8i32 = 41, // 8 x i32 - v16i32 = 42, // 16 x i32 - v32i32 = 43, // 32 x i32 - v64i32 = 44, // 64 x i32 - - v1i64 = 45, // 1 x i64 - v2i64 = 46, // 2 x i64 - v4i64 = 47, // 4 x i64 - v8i64 = 48, // 8 x i64 - v16i64 = 49, // 16 x i64 - v32i64 = 50, // 32 x i64 - - v1i128 = 51, // 1 x i128 + v2i1 = 14, // 2 x i1 + v4i1 = 15, // 4 x i1 + v8i1 = 16, // 8 x i1 + v16i1 = 17, // 16 x i1 + v32i1 = 18, // 32 x i1 + v64i1 = 19, // 64 x i1 + v512i1 = 20, // 512 x i1 + v1024i1 = 21, // 1024 x i1 + + v1i8 = 22, // 1 x i8 + v2i8 = 23, // 2 x i8 + v4i8 = 24, // 4 x i8 + v8i8 = 25, // 8 x i8 + v16i8 = 26, // 16 x i8 + v32i8 = 27, // 32 x i8 + v64i8 = 28, // 64 x i8 + v128i8 = 29, //128 x i8 + v256i8 = 30, //256 x i8 + + v1i16 = 31, // 1 x i16 + v2i16 = 32, // 2 x i16 + v4i16 = 33, // 4 x i16 + v8i16 = 34, // 8 x i16 + v16i16 = 35, // 16 x i16 + v32i16 = 36, // 32 x i16 + v64i16 = 37, // 64 x i16 + v128i16 = 38, //128 x i16 + + v1i32 = 39, // 1 x i32 + v2i32 = 40, // 2 x i32 + v4i32 = 41, // 4 x i32 + v8i32 = 42, // 8 x i32 + v16i32 = 43, // 16 x i32 + v32i32 = 44, // 32 x i32 + v64i32 = 45, // 64 x i32 + + v1i64 = 46, // 1 x i64 + v2i64 = 47, // 2 x i64 + v4i64 = 48, // 4 x i64 + v8i64 = 49, // 8 x i64 + v16i64 = 50, // 16 x i64 + v32i64 = 51, // 32 x i64 + + v1i128 = 52, // 1 x i128 + + // Scalable integer types + nxv2i1 = 53, // n x 2 x i1 + nxv4i1 = 54, // n x 4 x i1 + nxv8i1 = 55, // n x 8 x i1 + nxv16i1 = 56, // n x 16 x i1 + nxv32i1 = 57, // n x 32 x i1 + + nxv1i8 = 58, // n x 1 x i8 + nxv2i8 = 59, // n x 2 x i8 + nxv4i8 = 60, // n x 4 x i8 + nxv8i8 = 61, // n x 8 x i8 + nxv16i8 = 62, // n x 16 x i8 + nxv32i8 = 63, // n x 32 x i8 + + nxv1i16 = 64, // n x 1 x i16 + nxv2i16 = 65, // n x 2 x i16 + nxv4i16 = 66, // n x 4 x i16 + nxv8i16 = 67, // n x 8 x i16 + nxv16i16 = 68, // n x 16 x i16 + nxv32i16 = 69, // n x 32 x i16 + + nxv1i32 = 70, // n x 1 x i32 + nxv2i32 = 71, // n x 2 x i32 + nxv4i32 = 72, // n x 4 x i32 + nxv8i32 = 73, // n x 8 x i32 + nxv16i32 = 74, // n x 16 x i32 + nxv32i32 = 75, // n x 32 x i32 + + nxv1i64 = 76, // n x 1 x i64 + nxv2i64 = 77, // n x 2 x i64 + nxv4i64 = 78, // n x 4 x i64 + nxv8i64 = 79, // n x 8 x i64 + nxv16i64 = 80, // n x 16 x i64 + nxv32i64 = 81, // n x 32 x i64 FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, - LAST_INTEGER_VECTOR_VALUETYPE = v1i128, - - v2f16 = 52, // 2 x f16 - v4f16 = 53, // 4 x f16 - v8f16 = 54, // 8 x f16 - v1f32 = 55, // 1 x f32 - v2f32 = 56, // 2 x f32 - v4f32 = 57, // 4 x f32 - v8f32 = 58, // 8 x f32 - v16f32 = 59, // 16 x f32 - v1f64 = 60, // 1 x f64 - v2f64 = 61, // 2 x f64 - v4f64 = 62, // 4 x f64 - v8f64 = 63, // 8 x f64 + LAST_INTEGER_VECTOR_VALUETYPE = nxv32i64, + + FIRST_INTEGER_SCALABLE_VALUETYPE = nxv2i1, + LAST_INTEGER_SCALABLE_VALUETYPE = nxv32i64, + + v2f16 = 82, // 2 x f16 + v4f16 = 83, // 4 x f16 + v8f16 = 84, // 8 x f16 + v1f32 = 85, // 1 x f32 + v2f32 = 86, // 2 x f32 + v4f32 = 87, // 4 x f32 + v8f32 = 88, // 8 x f32 + v16f32 = 89, // 16 x f32 + v1f64 = 90, // 1 x f64 + v2f64 = 91, // 2 x f64 + v4f64 = 92, // 4 x f64 + v8f64 = 93, // 8 x f64 + + nxv2f16 = 94, // n x 2 x f16 + nxv4f16 = 95, // n x 4 x f16 + nxv8f16 = 96, // n x 8 x f16 + nxv1f32 = 97, // n x 1 x f32 + nxv2f32 = 98, // n x 2 x f32 + nxv4f32 = 99, // n x 4 x f32 + nxv8f32 = 100, // n x 8 x f32 + nxv16f32 = 101, // n x 16 x f32 + nxv1f64 = 102, // n x 1 x f64 + nxv2f64 = 103, // n x 2 x f64 + nxv4f64 = 104, // n x 4 x f64 + nxv8f64 = 105, // n x 8 x f64 FIRST_FP_VECTOR_VALUETYPE = v2f16, - LAST_FP_VECTOR_VALUETYPE = v8f64, + LAST_FP_VECTOR_VALUETYPE = nxv8f64, + + FIRST_FP_SCALABLE_VALUETYPE = nxv2f16, + LAST_FP_SCALABLE_VALUETYPE = nxv8f64, FIRST_VECTOR_VALUETYPE = v2i1, - LAST_VECTOR_VALUETYPE = v8f64, + LAST_VECTOR_VALUETYPE = nxv8f64, - x86mmx = 64, // This is an X86 MMX value + x86mmx = 106, // This is an X86 MMX value - Glue = 65, // This glues nodes together during pre-RA sched + Glue = 107, // This glues nodes together during pre-RA sched - isVoid = 66, // This has no value + isVoid = 108, // This has no value - Untyped = 67, // This value takes a register, but has - // unspecified type. The register class - // will be determined by the opcode. + Untyped = 109, // This value takes a register, but has + // unspecified type. The register class + // will be determined by the opcode. - FIRST_VALUETYPE = 0, // This is always the beginning of the list. - LAST_VALUETYPE = 68, // This always remains at the end of the list. + FIRST_VALUETYPE = 1, // This is always the beginning of the list. + LAST_VALUETYPE = 110, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors // This value must be a multiple of 32. - MAX_ALLOWED_VALUETYPE = 96, + MAX_ALLOWED_VALUETYPE = 128, // A value of type llvm::TokenTy - token = 120, + token = 248, // This is MDNode or MDString. - Metadata = 121, + Metadata = 249, // An int value the size of the pointer of the current // target to any address space. This must only be used internal to // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR. - iPTRAny = 122, + iPTRAny = 250, // A vector with any length and element size. This is used // for intrinsics that have overloadings based on vector types. // This is only for tblgen's consumption! - vAny = 123, + vAny = 251, // Any floating-point or vector floating-point value. This is used // for intrinsics that have overloadings based on floating-point types. // This is only for tblgen's consumption! - fAny = 124, + fAny = 252, // An integer or vector integer value of any bit width. This is // used for intrinsics that have overloadings based on integer bit widths. // This is only for tblgen's consumption! - iAny = 125, + iAny = 253, // An int value the size of the pointer of the current // target. This should only be used internal to tblgen! - iPTR = 126, + iPTR = 254, // Any type. This is used for intrinsics that have overloadings. // This is only for tblgen's consumption! - Any = 127 + Any = 255 }; SimpleValueType SimpleTy; + + // A class to represent the number of elements in a vector + // + // For fixed-length vectors, the total number of elements is equal to 'Min' + // For scalable vectors, the total number of elements is a multiple of 'Min' + class ElementCount { + public: + unsigned Min; + bool Scalable; + + ElementCount(unsigned Min, bool Scalable) + : Min(Min), Scalable(Scalable) {} + + ElementCount operator*(unsigned RHS) { + return { Min * RHS, Scalable }; + } + + ElementCount& operator*=(unsigned RHS) { + Min *= RHS; + return *this; + } + + ElementCount operator/(unsigned RHS) { + return { Min / RHS, Scalable }; + } + + ElementCount& operator/=(unsigned RHS) { + Min /= RHS; + return *this; + } + + bool operator==(const ElementCount& RHS) { + return Min == RHS.Min && Scalable == RHS.Scalable; + } + }; + constexpr MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {} constexpr MVT(SimpleValueType SVT) : SimpleTy(SVT) {} @@ -221,6 +312,15 @@ class MVT { SimpleTy <= MVT::LAST_VECTOR_VALUETYPE); } + /// Return true if this is a vector value type where the + /// runtime length is machine dependent + bool isScalableVector() const { + return ((SimpleTy >= MVT::FIRST_INTEGER_SCALABLE_VALUETYPE && + SimpleTy <= MVT::LAST_INTEGER_SCALABLE_VALUETYPE) || + (SimpleTy >= MVT::FIRST_FP_SCALABLE_VALUETYPE && + SimpleTy <= MVT::LAST_FP_SCALABLE_VALUETYPE)); + } + /// Return true if this is a 16-bit vector type. bool is16BitVector() const { return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 || @@ -318,7 +418,12 @@ class MVT { case v32i1: case v64i1: case v512i1: - case v1024i1: return i1; + case v1024i1: + case nxv2i1: + case nxv4i1: + case nxv8i1: + case nxv16i1: + case nxv32i1: return i1; case v1i8: case v2i8: case v4i8: @@ -327,7 +432,13 @@ class MVT { case v32i8: case v64i8: case v128i8: - case v256i8: return i8; + case v256i8: + case nxv1i8: + case nxv2i8: + case nxv4i8: + case nxv8i8: + case nxv16i8: + case nxv32i8: return i8; case v1i16: case v2i16: case v4i16: @@ -335,33 +446,63 @@ class MVT { case v16i16: case v32i16: case v64i16: - case v128i16: return i16; + case v128i16: + case nxv1i16: + case nxv2i16: + case nxv4i16: + case nxv8i16: + case nxv16i16: + case nxv32i16: return i16; case v1i32: case v2i32: case v4i32: case v8i32: case v16i32: case v32i32: - case v64i32: return i32; + case v64i32: + case nxv1i32: + case nxv2i32: + case nxv4i32: + case nxv8i32: + case nxv16i32: + case nxv32i32: return i32; case v1i64: case v2i64: case v4i64: case v8i64: case v16i64: - case v32i64: return i64; + case v32i64: + case nxv1i64: + case nxv2i64: + case nxv4i64: + case nxv8i64: + case nxv16i64: + case nxv32i64: return i64; case v1i128: return i128; case v2f16: case v4f16: - case v8f16: return f16; + case v8f16: + case nxv2f16: + case nxv4f16: + case nxv8f16: return f16; case v1f32: case v2f32: case v4f32: case v8f32: - case v16f32: return f32; + case v16f32: + case nxv1f32: + case nxv2f32: + case nxv4f32: + case nxv8f32: + case nxv16f32: return f32; case v1f64: case v2f64: case v4f64: - case v8f64: return f64; + case v8f64: + case nxv1f64: + case nxv2f64: + case nxv4f64: + case nxv8f64: return f64; } } @@ -382,13 +523,24 @@ class MVT { case v32i8: case v32i16: case v32i32: - case v32i64: return 32; + case v32i64: + case nxv32i1: + case nxv32i8: + case nxv32i16: + case nxv32i32: + case nxv32i64: return 32; case v16i1: case v16i8: case v16i16: case v16i32: case v16i64: - case v16f32: return 16; + case v16f32: + case nxv16i1: + case nxv16i8: + case nxv16i16: + case nxv16i32: + case nxv16i64: + case nxv16f32: return 16; case v8i1: case v8i8: case v8i16: @@ -396,7 +548,15 @@ class MVT { case v8i64: case v8f16: case v8f32: - case v8f64: return 8; + case v8f64: + case nxv8i1: + case nxv8i8: + case nxv8i16: + case nxv8i32: + case nxv8i64: + case nxv8f16: + case nxv8f32: + case nxv8f64: return 8; case v4i1: case v4i8: case v4i16: @@ -404,7 +564,15 @@ class MVT { case v4i64: case v4f16: case v4f32: - case v4f64: return 4; + case v4f64: + case nxv4i1: + case nxv4i8: + case nxv4i16: + case nxv4i32: + case nxv4i64: + case nxv4f16: + case nxv4f32: + case nxv4f64: return 4; case v2i1: case v2i8: case v2i16: @@ -412,17 +580,35 @@ class MVT { case v2i64: case v2f16: case v2f32: - case v2f64: return 2; + case v2f64: + case nxv2i1: + case nxv2i8: + case nxv2i16: + case nxv2i32: + case nxv2i64: + case nxv2f16: + case nxv2f32: + case nxv2f64: return 2; case v1i8: case v1i16: case v1i32: case v1i64: case v1i128: case v1f32: - case v1f64: return 1; + case v1f64: + case nxv1i8: + case nxv1i16: + case nxv1i32: + case nxv1i64: + case nxv1f32: + case nxv1f64: return 1; } } + MVT::ElementCount getVectorElementCount() const { + return { getVectorNumElements(), isScalableVector() }; + } + unsigned getSizeInBits() const { switch (SimpleTy) { default: @@ -443,16 +629,23 @@ class MVT { case Metadata: llvm_unreachable("Value type is metadata."); case i1 : return 1; - case v2i1: return 2; - case v4i1: return 4; + case v2i1: + case nxv2i1: return 2; + case v4i1: + case nxv4i1: return 4; case i8 : case v1i8: - case v8i1: return 8; + case v8i1: + case nxv1i8: + case nxv8i1: return 8; case i16 : case f16: case v16i1: case v2i8: - case v1i16: return 16; + case v1i16: + case nxv16i1: + case nxv2i8: + case nxv1i16: return 16; case f32 : case i32 : case v32i1: @@ -460,7 +653,13 @@ class MVT { case v2i16: case v2f16: case v1f32: - case v1i32: return 32; + case v1i32: + case nxv32i1: + case nxv4i8: + case nxv2i16: + case nxv1i32: + case nxv2f16: + case nxv1f32: return 32; case x86mmx: case f64 : case i64 : @@ -471,7 +670,14 @@ class MVT { case v1i64: case v4f16: case v2f32: - case v1f64: return 64; + case v1f64: + case nxv8i8: + case nxv4i16: + case nxv2i32: + case nxv1i64: + case nxv4f16: + case nxv2f32: + case nxv1f64: return 64; case f80 : return 80; case f128: case ppcf128: @@ -483,29 +689,50 @@ class MVT { case v1i128: case v8f16: case v4f32: - case v2f64: return 128; + case v2f64: + case nxv16i8: + case nxv8i16: + case nxv4i32: + case nxv2i64: + case nxv8f16: + case nxv4f32: + case nxv2f64: return 128; case v32i8: case v16i16: case v8i32: case v4i64: case v8f32: - case v4f64: return 256; + case v4f64: + case nxv32i8: + case nxv16i16: + case nxv8i32: + case nxv4i64: + case nxv8f32: + case nxv4f64: return 256; case v512i1: case v64i8: case v32i16: case v16i32: case v8i64: case v16f32: - case v8f64: return 512; + case v8f64: + case nxv32i16: + case nxv16i32: + case nxv8i64: + case nxv16f32: + case nxv8f64: return 512; case v1024i1: case v128i8: case v64i16: case v32i32: - case v16i64: return 1024; + case v16i64: + case nxv32i32: + case nxv16i64: return 1024; case v256i8: case v128i16: case v64i32: - case v32i64: return 2048; + case v32i64: + case nxv32i64: return 2048; } } @@ -659,6 +886,83 @@ class MVT { return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); } + static MVT getScalableVectorVT(MVT VT, unsigned NumElements) { + switch(VT.SimpleTy) { + default: + break; + case MVT::i1: + if (NumElements == 2) return MVT::nxv2i1; + if (NumElements == 4) return MVT::nxv4i1; + if (NumElements == 8) return MVT::nxv8i1; + if (NumElements == 16) return MVT::nxv16i1; + if (NumElements == 32) return MVT::nxv32i1; + break; + case MVT::i8: + if (NumElements == 1) return MVT::nxv1i8; + if (NumElements == 2) return MVT::nxv2i8; + if (NumElements == 4) return MVT::nxv4i8; + if (NumElements == 8) return MVT::nxv8i8; + if (NumElements == 16) return MVT::nxv16i8; + if (NumElements == 32) return MVT::nxv32i8; + break; + case MVT::i16: + if (NumElements == 1) return MVT::nxv1i16; + if (NumElements == 2) return MVT::nxv2i16; + if (NumElements == 4) return MVT::nxv4i16; + if (NumElements == 8) return MVT::nxv8i16; + if (NumElements == 16) return MVT::nxv16i16; + if (NumElements == 32) return MVT::nxv32i16; + break; + case MVT::i32: + if (NumElements == 1) return MVT::nxv1i32; + if (NumElements == 2) return MVT::nxv2i32; + if (NumElements == 4) return MVT::nxv4i32; + if (NumElements == 8) return MVT::nxv8i32; + if (NumElements == 16) return MVT::nxv16i32; + if (NumElements == 32) return MVT::nxv32i32; + break; + case MVT::i64: + if (NumElements == 1) return MVT::nxv1i64; + if (NumElements == 2) return MVT::nxv2i64; + if (NumElements == 4) return MVT::nxv4i64; + if (NumElements == 8) return MVT::nxv8i64; + if (NumElements == 16) return MVT::nxv16i64; + if (NumElements == 32) return MVT::nxv32i64; + break; + case MVT::f16: + if (NumElements == 2) return MVT::nxv2f16; + if (NumElements == 4) return MVT::nxv4f16; + if (NumElements == 8) return MVT::nxv8f16; + break; + case MVT::f32: + if (NumElements == 1) return MVT::nxv1f32; + if (NumElements == 2) return MVT::nxv2f32; + if (NumElements == 4) return MVT::nxv4f32; + if (NumElements == 8) return MVT::nxv8f32; + if (NumElements == 16) return MVT::nxv16f32; + break; + case MVT::f64: + if (NumElements == 1) return MVT::nxv1f64; + if (NumElements == 2) return MVT::nxv2f64; + if (NumElements == 4) return MVT::nxv4f64; + if (NumElements == 8) return MVT::nxv8f64; + break; + } + return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); + } + + static MVT getVectorVT(MVT VT, unsigned NumElements, bool IsScalable) { + if (IsScalable) + return getScalableVectorVT(VT, NumElements); + return getVectorVT(VT, NumElements); + } + + static MVT getVectorVT(MVT VT, MVT::ElementCount EC) { + if (EC.Scalable) + return getScalableVectorVT(VT, EC.Min); + return getVectorVT(VT, EC.Min); + } + /// Return the value type corresponding to the specified type. This returns /// all pointers as iPTR. If HandleUnknown is true, unknown types are /// returned as Other, otherwise they are invalid. @@ -709,6 +1013,14 @@ class MVT { MVT::FIRST_FP_VECTOR_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_FP_VECTOR_VALUETYPE + 1)); } + static mvt_range integer_scalable_vector_valuetypes() { + return mvt_range(MVT::FIRST_INTEGER_SCALABLE_VALUETYPE, + (MVT::SimpleValueType)(MVT::LAST_INTEGER_SCALABLE_VALUETYPE + 1)); + } + static mvt_range fp_scalable_vector_valuetypes() { + return mvt_range(MVT::FIRST_FP_SCALABLE_VALUETYPE, + (MVT::SimpleValueType)(MVT::LAST_FP_SCALABLE_VALUETYPE + 1)); + } /// @} }; diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 0a3063663cef8..b404b4ca701f9 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -44,7 +44,7 @@ namespace llvm { bool operator!=(EVT VT) const { if (V.SimpleTy != VT.V.SimpleTy) return true; - if (V.SimpleTy < 0) + if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) return LLVMTy != VT.LLVMTy; return false; } @@ -60,31 +60,48 @@ namespace llvm { /// bits. static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { MVT M = MVT::getIntegerVT(BitWidth); - if (M.SimpleTy >= 0) + if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) return M; return getExtendedIntegerVT(Context, BitWidth); } /// Returns the EVT that represents a vector NumElements in length, where /// each element is of type VT. - static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) { - MVT M = MVT::getVectorVT(VT.V, NumElements); - if (M.SimpleTy >= 0) + static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, + bool IsScalable = false) { + MVT M = MVT::getVectorVT(VT.V, NumElements, IsScalable); + if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) return M; + + assert(!IsScalable && "We don't support extended scalable types yet"); return getExtendedVectorVT(Context, VT, NumElements); } + /// Returns the EVT that represents a vector EC.Min elements in length, + /// where each element is of type VT. + static EVT getVectorVT(LLVMContext &Context, EVT VT, MVT::ElementCount EC) { + MVT M = MVT::getVectorVT(VT.V, EC); + if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) + return M; + assert (!EC.Scalable && "We don't support extended scalable types yet"); + return getExtendedVectorVT(Context, VT, EC.Min); + } + /// Return a vector with the same number of elements as this vector, but /// with the element type converted to an integer type with the same /// bitwidth. EVT changeVectorElementTypeToInteger() const { - if (!isSimple()) + if (!isSimple()) { + assert (!isScalableVector() && + "We don't support extended scalable types yet"); return changeExtendedVectorElementTypeToInteger(); + } MVT EltTy = getSimpleVT().getVectorElementType(); unsigned BitWidth = EltTy.getSizeInBits(); MVT IntTy = MVT::getIntegerVT(BitWidth); - MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); - assert(VecTy.SimpleTy >= 0 && + MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements(), + isScalableVector()); + assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE && "Simple vector VT not representable by simple integer vector VT!"); return VecTy; } @@ -104,7 +121,7 @@ namespace llvm { /// Test if the given EVT is simple (as opposed to being extended). bool isSimple() const { - return V.SimpleTy >= 0; + return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE; } /// Test if the given EVT is extended (as opposed to being simple). @@ -132,6 +149,17 @@ namespace llvm { return isSimple() ? V.isVector() : isExtendedVector(); } + /// Return true if this is a vector type where the runtime + /// length is machine dependent + bool isScalableVector() const { + // FIXME: We don't support extended scalable types yet, because the + // matching IR type doesn't exist. Once it has been added, this can + // be changed to call isExtendedScalableVector. + if (!isSimple()) + return false; + return V.isScalableVector(); + } + /// Return true if this is a 16-bit vector type. bool is16BitVector() const { return isSimple() ? V.is16BitVector() : isExtended16BitVector(); @@ -247,6 +275,17 @@ namespace llvm { return getExtendedVectorNumElements(); } + // Given a (possibly scalable) vector type, return the ElementCount + MVT::ElementCount getVectorElementCount() const { + assert((isVector()) && "Invalid vector type!"); + if (isSimple()) + return V.getVectorElementCount(); + + assert(!isScalableVector() && + "We don't support extended scalable types yet"); + return {getExtendedVectorNumElements(), false}; + } + /// Return the size of the specified value type in bits. unsigned getSizeInBits() const { if (isSimple()) @@ -301,7 +340,17 @@ namespace llvm { EVT widenIntegerVectorElementType(LLVMContext &Context) const { EVT EltVT = getVectorElementType(); EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits()); - return EVT::getVectorVT(Context, EltVT, getVectorNumElements()); + return EVT::getVectorVT(Context, EltVT, getVectorElementCount()); + } + + // Return a VT for a vector type with the same element type but + // half the number of elements. The type returned may be an + // extended type. + EVT getHalfNumVectorElementsVT(LLVMContext &Context) const { + EVT EltVT = getVectorElementType(); + auto EltCnt = getVectorElementCount(); + assert(!(EltCnt.Min & 1) && "Splitting vector, but not in half!"); + return EVT::getVectorVT(Context, EltVT, EltCnt / 2); } /// Returns true if the given vector is a power of 2. @@ -316,7 +365,8 @@ namespace llvm { if (!isPow2VectorType()) { unsigned NElts = getVectorNumElements(); unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts); - return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts); + return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts, + isScalableVector()); } else { return *this; diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index f7b1661d7451b..cd84344754512 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -19,101 +19,147 @@ class ValueType<int size, int value> { int Value = value; } -def OtherVT: ValueType<0 , 0>; // "Other" value -def i1 : ValueType<1 , 1>; // One bit boolean value -def i8 : ValueType<8 , 2>; // 8-bit integer value -def i16 : ValueType<16 , 3>; // 16-bit integer value -def i32 : ValueType<32 , 4>; // 32-bit integer value -def i64 : ValueType<64 , 5>; // 64-bit integer value -def i128 : ValueType<128, 6>; // 128-bit integer value -def f16 : ValueType<16 , 7>; // 16-bit floating point value -def f32 : ValueType<32 , 8>; // 32-bit floating point value -def f64 : ValueType<64 , 9>; // 64-bit floating point value -def f80 : ValueType<80 , 10>; // 80-bit floating point value -def f128 : ValueType<128, 11>; // 128-bit floating point value -def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value - -def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value -def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value -def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value -def v16i1 : ValueType<16, 16>; // 16 x i1 vector value -def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value -def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value -def v512i1 : ValueType<512, 19>; // 512 x i1 vector value -def v1024i1: ValueType<1024,20>; //1024 x i1 vector value - -def v1i8 : ValueType<16, 21>; // 1 x i8 vector value -def v2i8 : ValueType<16 , 22>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 23>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 24>; // 8 x i8 vector value -def v16i8 : ValueType<128, 25>; // 16 x i8 vector value -def v32i8 : ValueType<256, 26>; // 32 x i8 vector value -def v64i8 : ValueType<512, 27>; // 64 x i8 vector value -def v128i8 : ValueType<1024,28>; //128 x i8 vector value -def v256i8 : ValueType<2048,29>; //256 x i8 vector value - -def v1i16 : ValueType<16 , 30>; // 1 x i16 vector value -def v2i16 : ValueType<32 , 31>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 32>; // 4 x i16 vector value -def v8i16 : ValueType<128, 33>; // 8 x i16 vector value -def v16i16 : ValueType<256, 34>; // 16 x i16 vector value -def v32i16 : ValueType<512, 35>; // 32 x i16 vector value -def v64i16 : ValueType<1024,36>; // 64 x i16 vector value -def v128i16: ValueType<2048,37>; //128 x i16 vector value - -def v1i32 : ValueType<32 , 38>; // 1 x i32 vector value -def v2i32 : ValueType<64 , 39>; // 2 x i32 vector value -def v4i32 : ValueType<128, 40>; // 4 x i32 vector value -def v8i32 : ValueType<256, 41>; // 8 x i32 vector value -def v16i32 : ValueType<512, 42>; // 16 x i32 vector value -def v32i32 : ValueType<1024,43>; // 32 x i32 vector value -def v64i32 : ValueType<2048,44>; // 32 x i32 vector value - -def v1i64 : ValueType<64 , 45>; // 1 x i64 vector value -def v2i64 : ValueType<128, 46>; // 2 x i64 vector value -def v4i64 : ValueType<256, 47>; // 4 x i64 vector value -def v8i64 : ValueType<512, 48>; // 8 x i64 vector value -def v16i64 : ValueType<1024,49>; // 16 x i64 vector value -def v32i64 : ValueType<2048,50>; // 32 x i64 vector value - -def v1i128 : ValueType<128, 51>; // 1 x i128 vector value - -def v2f16 : ValueType<32 , 52>; // 2 x f16 vector value -def v4f16 : ValueType<64 , 53>; // 4 x f16 vector value -def v8f16 : ValueType<128, 54>; // 8 x f16 vector value -def v1f32 : ValueType<32 , 55>; // 1 x f32 vector value -def v2f32 : ValueType<64 , 56>; // 2 x f32 vector value -def v4f32 : ValueType<128, 57>; // 4 x f32 vector value -def v8f32 : ValueType<256, 58>; // 8 x f32 vector value -def v16f32 : ValueType<512, 59>; // 16 x f32 vector value -def v1f64 : ValueType<64, 60>; // 1 x f64 vector value -def v2f64 : ValueType<128, 61>; // 2 x f64 vector value -def v4f64 : ValueType<256, 62>; // 4 x f64 vector value -def v8f64 : ValueType<512, 63>; // 8 x f64 vector value - - -def x86mmx : ValueType<64 , 64>; // X86 MMX value -def FlagVT : ValueType<0 , 65>; // Pre-RA sched glue -def isVoid : ValueType<0 , 66>; // Produces no value -def untyped: ValueType<8 , 67>; // Produces an untyped value -def token : ValueType<0 , 120>; // TokenTy -def MetadataVT: ValueType<0, 121>; // Metadata +def OtherVT: ValueType<0 , 1>; // "Other" value +def i1 : ValueType<1 , 2>; // One bit boolean value +def i8 : ValueType<8 , 3>; // 8-bit integer value +def i16 : ValueType<16 , 4>; // 16-bit integer value +def i32 : ValueType<32 , 5>; // 32-bit integer value +def i64 : ValueType<64 , 6>; // 64-bit integer value +def i128 : ValueType<128, 7>; // 128-bit integer value +def f16 : ValueType<16 , 8>; // 16-bit floating point value +def f32 : ValueType<32 , 9>; // 32-bit floating point value +def f64 : ValueType<64 , 10>; // 64-bit floating point value +def f80 : ValueType<80 , 11>; // 80-bit floating point value +def f128 : ValueType<128, 12>; // 128-bit floating point value +def ppcf128: ValueType<128, 13>; // PPC 128-bit floating point value + +def v2i1 : ValueType<2 , 14>; // 2 x i1 vector value +def v4i1 : ValueType<4 , 15>; // 4 x i1 vector value +def v8i1 : ValueType<8 , 16>; // 8 x i1 vector value +def v16i1 : ValueType<16, 17>; // 16 x i1 vector value +def v32i1 : ValueType<32 , 18>; // 32 x i1 vector value +def v64i1 : ValueType<64 , 19>; // 64 x i1 vector value +def v512i1 : ValueType<512, 20>; // 512 x i1 vector value +def v1024i1: ValueType<1024,21>; //1024 x i1 vector value + +def v1i8 : ValueType<16, 22>; // 1 x i8 vector value +def v2i8 : ValueType<16 , 23>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 24>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 25>; // 8 x i8 vector value +def v16i8 : ValueType<128, 26>; // 16 x i8 vector value +def v32i8 : ValueType<256, 27>; // 32 x i8 vector value +def v64i8 : ValueType<512, 28>; // 64 x i8 vector value +def v128i8 : ValueType<1024,29>; //128 x i8 vector value +def v256i8 : ValueType<2048,30>; //256 x i8 vector value + +def v1i16 : ValueType<16 , 31>; // 1 x i16 vector value +def v2i16 : ValueType<32 , 32>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 33>; // 4 x i16 vector value +def v8i16 : ValueType<128, 34>; // 8 x i16 vector value +def v16i16 : ValueType<256, 35>; // 16 x i16 vector value +def v32i16 : ValueType<512, 36>; // 32 x i16 vector value +def v64i16 : ValueType<1024,37>; // 64 x i16 vector value +def v128i16: ValueType<2048,38>; //128 x i16 vector value + +def v1i32 : ValueType<32 , 39>; // 1 x i32 vector value +def v2i32 : ValueType<64 , 40>; // 2 x i32 vector value +def v4i32 : ValueType<128, 41>; // 4 x i32 vector value +def v8i32 : ValueType<256, 42>; // 8 x i32 vector value +def v16i32 : ValueType<512, 43>; // 16 x i32 vector value +def v32i32 : ValueType<1024,44>; // 32 x i32 vector value +def v64i32 : ValueType<2048,45>; // 32 x i32 vector value + +def v1i64 : ValueType<64 , 46>; // 1 x i64 vector value +def v2i64 : ValueType<128, 47>; // 2 x i64 vector value +def v4i64 : ValueType<256, 48>; // 4 x i64 vector value +def v8i64 : ValueType<512, 49>; // 8 x i64 vector value +def v16i64 : ValueType<1024,50>; // 16 x i64 vector value +def v32i64 : ValueType<2048,51>; // 32 x i64 vector value + +def v1i128 : ValueType<128, 52>; // 1 x i128 vector value + +def nxv2i1 : ValueType<2, 53>; // n x 2 x i1 vector value +def nxv4i1 : ValueType<4, 54>; // n x 4 x i1 vector value +def nxv8i1 : ValueType<8, 55>; // n x 8 x i1 vector value +def nxv16i1 : ValueType<16, 56>; // n x 16 x i1 vector value +def nxv32i1 : ValueType<32, 57>; // n x 32 x i1 vector value + +def nxv1i8 : ValueType<8, 58>; // n x 1 x i8 vector value +def nxv2i8 : ValueType<16, 59>; // n x 2 x i8 vector value +def nxv4i8 : ValueType<32, 60>; // n x 4 x i8 vector value +def nxv8i8 : ValueType<64, 61>; // n x 8 x i8 vector value +def nxv16i8 : ValueType<128, 62>; // n x 16 x i8 vector value +def nxv32i8 : ValueType<256, 63>; // n x 32 x i8 vector value + +def nxv1i16 : ValueType<16, 64>; // n x 1 x i16 vector value +def nxv2i16 : ValueType<32, 65>; // n x 2 x i16 vector value +def nxv4i16 : ValueType<64, 66>; // n x 4 x i16 vector value +def nxv8i16 : ValueType<128, 67>; // n x 8 x i16 vector value +def nxv16i16: ValueType<256, 68>; // n x 16 x i16 vector value +def nxv32i16: ValueType<512, 69>; // n x 32 x i16 vector value + +def nxv1i32 : ValueType<32, 70>; // n x 1 x i32 vector value +def nxv2i32 : ValueType<64, 71>; // n x 2 x i32 vector value +def nxv4i32 : ValueType<128, 72>; // n x 4 x i32 vector value +def nxv8i32 : ValueType<256, 73>; // n x 8 x i32 vector value +def nxv16i32: ValueType<512, 74>; // n x 16 x i32 vector value +def nxv32i32: ValueType<1024,75>; // n x 32 x i32 vector value + +def nxv1i64 : ValueType<64, 76>; // n x 1 x i64 vector value +def nxv2i64 : ValueType<128, 77>; // n x 2 x i64 vector value +def nxv4i64 : ValueType<256, 78>; // n x 4 x i64 vector value +def nxv8i64 : ValueType<512, 79>; // n x 8 x i64 vector value +def nxv16i64: ValueType<1024,80>; // n x 16 x i64 vector value +def nxv32i64: ValueType<2048,81>; // n x 32 x i64 vector value + +def v2f16 : ValueType<32 , 82>; // 2 x f16 vector value +def v4f16 : ValueType<64 , 83>; // 4 x f16 vector value +def v8f16 : ValueType<128, 84>; // 8 x f16 vector value +def v1f32 : ValueType<32 , 85>; // 1 x f32 vector value +def v2f32 : ValueType<64 , 86>; // 2 x f32 vector value +def v4f32 : ValueType<128, 87>; // 4 x f32 vector value +def v8f32 : ValueType<256, 88>; // 8 x f32 vector value +def v16f32 : ValueType<512, 89>; // 16 x f32 vector value +def v1f64 : ValueType<64, 90>; // 1 x f64 vector value +def v2f64 : ValueType<128, 91>; // 2 x f64 vector value +def v4f64 : ValueType<256, 92>; // 4 x f64 vector value +def v8f64 : ValueType<512, 93>; // 8 x f64 vector value + +def nxv2f16 : ValueType<32 , 94>; // n x 2 x f16 vector value +def nxv4f16 : ValueType<64 , 95>; // n x 4 x f16 vector value +def nxv8f16 : ValueType<128, 96>; // n x 8 x f16 vector value +def nxv1f32 : ValueType<32 , 97>; // n x 1 x f32 vector value +def nxv2f32 : ValueType<64 , 98>; // n x 2 x f32 vector value +def nxv4f32 : ValueType<128, 99>; // n x 4 x f32 vector value +def nxv8f32 : ValueType<256, 100>; // n x 8 x f32 vector value +def nxv16f32 : ValueType<512, 101>; // n x 16 x f32 vector value +def nxv1f64 : ValueType<64, 102>; // n x 1 x f64 vector value +def nxv2f64 : ValueType<128, 103>; // n x 2 x f64 vector value +def nxv4f64 : ValueType<256, 104>; // n x 4 x f64 vector value +def nxv8f64 : ValueType<512, 105>; // n x 8 x f64 vector value + +def x86mmx : ValueType<64 , 106>; // X86 MMX value +def FlagVT : ValueType<0 , 107>; // Pre-RA sched glue +def isVoid : ValueType<0 , 108>; // Produces no value +def untyped: ValueType<8 , 109>; // Produces an untyped value +def token : ValueType<0 , 248>; // TokenTy +def MetadataVT: ValueType<0, 249>; // Metadata // Pseudo valuetype mapped to the current pointer size to any address space. // Should only be used in TableGen. -def iPTRAny : ValueType<0, 122>; +def iPTRAny : ValueType<0, 250>; // Pseudo valuetype to represent "vector of any size" -def vAny : ValueType<0 , 123>; +def vAny : ValueType<0 , 251>; // Pseudo valuetype to represent "float of any format" -def fAny : ValueType<0 , 124>; +def fAny : ValueType<0 , 252>; // Pseudo valuetype to represent "integer of any bit width" -def iAny : ValueType<0 , 125>; +def iAny : ValueType<0 , 253>; // Pseudo valuetype mapped to the current pointer size. -def iPTR : ValueType<0 , 126>; +def iPTR : ValueType<0 , 254>; // Pseudo valuetype to represent "any type of any size". -def Any : ValueType<0 , 127>; +def Any : ValueType<0 , 255>; diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index a3c919d39804f..a64e208fa7846 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -59,9 +59,6 @@ /* Define to 1 if you have the <errno.h> header file. */ #cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H} -/* Define to 1 if you have the <execinfo.h> header file. */ -#cmakedefine HAVE_EXECINFO_H ${HAVE_EXECINFO_H} - /* Define to 1 if you have the <fcntl.h> header file. */ #cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H} @@ -389,6 +386,9 @@ /* LLVM version information */ #cmakedefine LLVM_VERSION_INFO "${LLVM_VERSION_INFO}" +/* Whether tools show host and target info when invoked with --version */ +#cmakedefine01 LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO + /* Major version of the LLVM API */ #define LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR} diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index 33e24fe3adc90..ee06125ea2786 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -247,16 +247,11 @@ public: /// DW_AT_call_line attribute in this DIE. /// \param CallColumn filled in with non-zero if successful, zero if there is /// no DW_AT_call_column attribute in this DIE. + /// \param CallDiscriminator filled in with non-zero if successful, zero if + /// there is no DW_AT_GNU_discriminator attribute in this DIE. void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, - uint32_t &CallColumn) const; + uint32_t &CallColumn, uint32_t &CallDiscriminator) const; - /// Get inlined chain for a given address, rooted at the current DIE. - /// Returns empty chain if address is not contained in address range - /// of current DIE. - void - getInlinedChainForAddress(const uint64_t Address, - SmallVectorImpl<DWARFDie> &InlinedChain) const; - class attribute_iterator; /// Get an iterator range to all attributes in the current DIE only. diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 40eb4434bd61e..023a0f7b9fb24 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -31,6 +31,7 @@ #include <cstdint> #include <memory> #include <vector> +#include <map> namespace llvm { @@ -134,6 +135,11 @@ class DWARFUnit { uint64_t BaseAddr; // The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; + + // Map from range's start address to end address and corresponding DIE. + // IntervalMap does not support range removal, as a result, we use the + // std::map::upper_bound for address range lookup. + std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap; typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator> die_iterator_range; @@ -183,6 +189,9 @@ public: AddrOffsetSectionBase = Base; } + // Recursively update address to Die map. + void updateAddressDieMap(DWARFDie Die); + void setRangesSection(StringRef RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; @@ -339,10 +348,10 @@ private: /// it was actually constructed. bool parseDWO(); - /// getSubprogramForAddress - Returns subprogram DIE with address range + /// getSubroutineForAddress - Returns subprogram DIE with address range /// encompassing the provided address. The pointer is alive as long as parsed /// compile unit DIEs are not cleared. - DWARFDie getSubprogramForAddress(uint64_t Address); + DWARFDie getSubroutineForAddress(uint64_t Address); }; } // end namespace llvm diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 6fc1dd2f285a1..5c05f19abc1fd 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -108,18 +108,16 @@ public: bool hasSExtAttr() const; /// Add attributes to an argument. - void addAttr(AttributeList AS); + void addAttrs(AttrBuilder &B); - void addAttr(Attribute::AttrKind Kind) { - addAttr(AttributeList::get(getContext(), getArgNo() + 1, Kind)); - } + void addAttr(Attribute::AttrKind Kind); + + void addAttr(Attribute Attr); /// Remove attributes from an argument. void removeAttr(AttributeList AS); - void removeAttr(Attribute::AttrKind Kind) { - removeAttr(AttributeList::get(getContext(), getArgNo() + 1, Kind)); - } + void removeAttr(Attribute::AttrKind Kind); /// Check if an argument has a given attribute. bool hasAttribute(Attribute::AttrKind Kind) const; diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 121f57a433acb..b13f197d25fdc 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -357,9 +357,6 @@ public: AttributeList Attrs) const; AttributeList addAttributes(LLVMContext &C, unsigned Index, - AttributeSet AS) const; - - AttributeList addAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &B) const; /// \brief Remove the specified attribute at the specified index from this diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 6d704666933fc..47004e82cc19a 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -41,17 +41,14 @@ namespace llvm { class MDNode; /// This class represents a range of values. -/// class ConstantRange { APInt Lower, Upper; public: /// Initialize a full (the default) or empty set for the specified bit width. - /// explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true); /// Initialize a range to hold the single specified value. - /// ConstantRange(APInt Value); /// @brief Initialize a range of values explicitly. This will assert out if @@ -119,46 +116,36 @@ public: bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const; /// Return the lower value for this range. - /// const APInt &getLower() const { return Lower; } /// Return the upper value for this range. - /// const APInt &getUpper() const { return Upper; } /// Get the bit width of this ConstantRange. - /// uint32_t getBitWidth() const { return Lower.getBitWidth(); } /// Return true if this set contains all of the elements possible /// for this data-type. - /// bool isFullSet() const; /// Return true if this set contains no members. - /// bool isEmptySet() const; /// Return true if this set wraps around the top of the range. /// For example: [100, 8). - /// bool isWrappedSet() const; /// Return true if this set wraps around the INT_MIN of /// its bitwidth. For example: i8 [120, 140). - /// bool isSignWrappedSet() const; /// Return true if the specified value is in the set. - /// bool contains(const APInt &Val) const; /// Return true if the other range is a subset of this one. - /// bool contains(const ConstantRange &CR) const; /// If this set contains a single element, return it, otherwise return null. - /// const APInt *getSingleElement() const { if (Upper == Lower + 1) return &Lower; @@ -174,35 +161,27 @@ public: } /// Return true if this set contains exactly one member. - /// bool isSingleElement() const { return getSingleElement() != nullptr; } /// Return the number of elements in this set. - /// APInt getSetSize() const; /// Compare set size of this range with the range CR. - /// bool isSizeStrictlySmallerThanOf(const ConstantRange &CR) const; /// Return the largest unsigned value contained in the ConstantRange. - /// APInt getUnsignedMax() const; /// Return the smallest unsigned value contained in the ConstantRange. - /// APInt getUnsignedMin() const; /// Return the largest signed value contained in the ConstantRange. - /// APInt getSignedMax() const; /// Return the smallest signed value contained in the ConstantRange. - /// APInt getSignedMin() const; /// Return true if this range is equal to another range. - /// bool operator==(const ConstantRange &CR) const { return Lower == CR.Lower && Upper == CR.Upper; } @@ -213,8 +192,8 @@ public: /// Subtract the specified constant from the endpoints of this constant range. ConstantRange subtract(const APInt &CI) const; - /// \brief Subtract the specified range from this range (aka relative - /// complement of the sets). + /// Subtract the specified range from this range (aka relative complement of + /// the sets). ConstantRange difference(const ConstantRange &CR) const; /// Return the range that results from the intersection of @@ -223,7 +202,6 @@ public: /// smallest possible set size that does so. Because there may be two /// intersections with the same set size, A.intersectWith(B) might not /// be equal to B.intersectWith(A). - /// ConstantRange intersectWith(const ConstantRange &CR) const; /// Return the range that results from the union of this range @@ -231,7 +209,6 @@ public: /// elements of both sets, but may contain more. For example, [3, 9) union /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included /// in either set before. - /// ConstantRange unionWith(const ConstantRange &CR) const; /// Return a new range representing the possible values resulting @@ -331,15 +308,12 @@ public: ConstantRange lshr(const ConstantRange &Other) const; /// Return a new range that is the logical not of the current set. - /// ConstantRange inverse() const; /// Print out the bounds to a stream. - /// void print(raw_ostream &OS) const; /// Allow printing from a debugger easily. - /// void dump() const; }; diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 69bd5c847a8d0..a4b2a02d50503 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -778,6 +778,9 @@ namespace llvm { } }; + // Create wrappers for C Binding types (see CBindingWrapping.h). + DEFINE_ISA_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef) + } // end namespace llvm #endif // LLVM_IR_DIBUILDER_H diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 8a924b40143aa..8041e35e0e0a6 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -2232,6 +2232,9 @@ public: expr_op_iterator expr_op_end() const { return expr_op_iterator(elements_end()); } + iterator_range<expr_op_iterator> expr_ops() const { + return {expr_op_begin(), expr_op_end()}; + } /// @} bool isValid() const; @@ -2240,7 +2243,7 @@ public: return MD->getMetadataID() == DIExpressionKind; } - /// Is the first element a DW_OP_deref?. + /// Return whether the first element a DW_OP_deref. bool startsWithDeref() const { return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref; } diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 34dafebe0fc5d..d23c1ddf9257b 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -273,10 +273,11 @@ public: Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } + Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return getPointerOperand()->getType()->getPointerAddressSpace(); + return getPointerOperandType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -397,10 +398,11 @@ public: Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } + Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { - return getPointerOperand()->getType()->getPointerAddressSpace(); + return getPointerOperandType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index fd79355bff1ad..8f24a6a1d69d8 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -30,6 +30,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> #include <cstddef> @@ -133,6 +134,14 @@ public: /// @} }; +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) + +// Specialized opaque metadata conversions. +inline Metadata **unwrap(LLVMMetadataRef *MDs) { + return reinterpret_cast<Metadata**>(MDs); +} + #define HANDLE_METADATA(CLASS) class CLASS; #include "llvm/IR/Metadata.def" diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 09f6c18970095..9c0a4159cad2f 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -160,7 +160,6 @@ private: std::vector<ValueInfo> RefEdgeList; protected: - /// GlobalValueSummary constructor. GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs) : Kind(K), Flags(Flags), OriginalName(0), RefEdgeList(std::move(Refs)) {} @@ -221,7 +220,6 @@ class AliasSummary : public GlobalValueSummary { GlobalValueSummary *AliaseeSummary; public: - /// Summary constructors. AliasSummary(GVFlags Flags, std::vector<ValueInfo> Refs) : GlobalValueSummary(AliasKind, Flags, std::move(Refs)) {} @@ -297,7 +295,6 @@ private: std::unique_ptr<TypeIdInfo> TIdInfo; public: - /// Summary constructors. FunctionSummary(GVFlags Flags, unsigned NumInsts, std::vector<ValueInfo> Refs, std::vector<EdgeTy> CGEdges, std::vector<GlobalValue::GUID> TypeTests, @@ -418,7 +415,6 @@ template <> struct DenseMapInfo<FunctionSummary::ConstVCall> { class GlobalVarSummary : public GlobalValueSummary { public: - /// Summary constructors. GlobalVarSummary(GVFlags Flags, std::vector<ValueInfo> Refs) : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {} diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 40f9c21f646bc..31a76b4ed6c32 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -267,15 +267,15 @@ inline cst_pred_ty<is_all_ones> m_AllOnes() { } inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; } -struct is_sign_bit { - bool isValue(const APInt &C) { return C.isSignBit(); } +struct is_sign_mask { + bool isValue(const APInt &C) { return C.isSignMask(); } }; /// \brief Match an integer or vector with only the sign bit(s) set. -inline cst_pred_ty<is_sign_bit> m_SignBit() { - return cst_pred_ty<is_sign_bit>(); +inline cst_pred_ty<is_sign_mask> m_SignMask() { + return cst_pred_ty<is_sign_mask>(); } -inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; } +inline api_pred_ty<is_sign_mask> m_SignMask(const APInt *&V) { return V; } struct is_power2 { bool isValue(const APInt &C) { return C.isPowerOf2(); } diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 05b68ccbb38e8..6b56546f44219 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -61,9 +61,29 @@ public: /// that also works with less standard-compliant compilers void swap(Use &RHS); + /// Pointer traits for the UserRef PointerIntPair. This ensures we always + /// use the LSB regardless of pointer alignment on different targets. + struct UserRefPointerTraits { + static inline void *getAsVoidPointer(User *P) { return P; } + static inline User *getFromVoidPointer(void *P) { + return (User *)P; + } + enum { NumLowBitsAvailable = 1 }; + }; + // A type for the word following an array of hung-off Uses in memory, which is // a pointer back to their User with the bottom bit set. - typedef PointerIntPair<User *, 1, unsigned> UserRef; + typedef PointerIntPair<User *, 1, unsigned, UserRefPointerTraits> UserRef; + + /// Pointer traits for the Prev PointerIntPair. This ensures we always use + /// the two LSBs regardless of pointer alignment on different targets. + struct PrevPointerTraits { + static inline void *getAsVoidPointer(Use **P) { return P; } + static inline Use **getFromVoidPointer(void *P) { + return (Use **)P; + } + enum { NumLowBitsAvailable = 2 }; + }; private: /// Destructor - Only for zap() @@ -115,7 +135,7 @@ private: Value *Val; Use *Next; - PointerIntPair<Use **, 2, PrevPtrTag> Prev; + PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev; void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); } diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index bd2717de9960b..869706c454834 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -65,8 +65,8 @@ protected: // Properties to be set by the target writer, used to configure asm printer. // - /// Pointer size in bytes. Default is 4. - unsigned PointerSize = 4; + /// Code pointer size in bytes. Default is 4. + unsigned CodePointerSize = 4; /// Size of the stack slot reserved for callee-saved registers, in bytes. /// Default is same as pointer size. @@ -384,8 +384,8 @@ public: explicit MCAsmInfo(); virtual ~MCAsmInfo(); - /// Get the pointer size in bytes. - unsigned getPointerSize() const { return PointerSize; } + /// Get the code pointer size in bytes. + unsigned getCodePointerSize() const { return CodePointerSize; } /// Get the callee-saved register stack slot /// size in bytes. diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index e466b368ed34b..eb301031ba3fe 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -128,6 +128,7 @@ public: virtual void emitArch(unsigned Arch); virtual void emitArchExtension(unsigned ArchExt); virtual void emitObjectArch(unsigned Arch); + void emitTargetAttributes(const MCSubtargetInfo &STI); virtual void finishAttributeSection(); virtual void emitInst(uint32_t Inst, char Suffix = '\0'); diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 6229db3bbcb28..bb16463588c3c 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -86,6 +86,10 @@ public: FeatureBits = FeatureBits_; } + bool hasFeature(unsigned Feature) const { + return FeatureBits[Feature]; + } + protected: /// Initialize the scheduling model and feature bits. /// diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index d423957d9b79d..807508107c56d 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -14,15 +14,20 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/Object/Binary.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <vector> namespace llvm { namespace object { @@ -32,25 +37,28 @@ class Archive; class ArchiveMemberHeader { public: friend class Archive; + ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err); // ArchiveMemberHeader() = default; /// Get the name without looking up long names. - Expected<llvm::StringRef> getRawName() const; + Expected<StringRef> getRawName() const; /// Get the name looking up long names. - Expected<llvm::StringRef> getName(uint64_t Size) const; + Expected<StringRef> getName(uint64_t Size) const; /// Members are not larger than 4GB. Expected<uint32_t> getSize() const; Expected<sys::fs::perms> getAccessMode() const; Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const; - llvm::StringRef getRawLastModified() const { + + StringRef getRawLastModified() const { return StringRef(ArMemHdr->LastModified, sizeof(ArMemHdr->LastModified)).rtrim(' '); } + Expected<unsigned> getUID() const; Expected<unsigned> getGID() const; @@ -75,11 +83,13 @@ private: class Archive : public Binary { virtual void anchor(); + public: class Child { friend Archive; - const Archive *Parent; friend ArchiveMemberHeader; + + const Archive *Parent; ArchiveMemberHeader Header; /// \brief Includes header but not padding byte. StringRef Data; @@ -103,17 +113,22 @@ public: Expected<StringRef> getName() const; Expected<std::string> getFullName() const; Expected<StringRef> getRawName() const { return Header.getRawName(); } + Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const { return Header.getLastModified(); } + StringRef getRawLastModified() const { return Header.getRawLastModified(); } + Expected<unsigned> getUID() const { return Header.getUID(); } Expected<unsigned> getGID() const { return Header.getGID(); } + Expected<sys::fs::perms> getAccessMode() const { return Header.getAccessMode(); } + /// \return the size of the archive member without the header or padding. Expected<uint64_t> getSize() const; /// \return the size in the archive header for this member. @@ -130,11 +145,12 @@ public: class child_iterator { Child C; - Error *E; + Error *E = nullptr; public: - child_iterator() : C(Child(nullptr, nullptr, nullptr)), E(nullptr) {} + child_iterator() : C(Child(nullptr, nullptr, nullptr)) {} child_iterator(const Child &C, Error *E) : C(C), E(E) {} + const Child *operator->() const { return &C; } const Child &operator*() const { return C; } @@ -171,14 +187,15 @@ public: uint32_t StringIndex; // Extra index to the string. public: - bool operator ==(const Symbol &other) const { - return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex); - } - Symbol(const Archive *p, uint32_t symi, uint32_t stri) : Parent(p) , SymbolIndex(symi) , StringIndex(stri) {} + + bool operator ==(const Symbol &other) const { + return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex); + } + StringRef getName() const; Expected<Child> getMember() const; Symbol getNext() const; @@ -186,8 +203,10 @@ public: class symbol_iterator { Symbol symbol; + public: symbol_iterator(const Symbol &s) : symbol(s) {} + const Symbol *operator->() const { return &symbol; } const Symbol &operator*() const { return symbol; } @@ -264,7 +283,7 @@ private: mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers; }; -} -} +} // end namespace object +} // end namespace llvm -#endif +#endif // LLVM_OBJECT_ARCHIVE_H diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index bdbe94301dc76..06788326ff578 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -15,10 +15,11 @@ #define LLVM_OBJECT_BINARY_H #include "llvm/ADT/Triple.h" -#include "llvm/Object/Error.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" +#include <algorithm> +#include <memory> +#include <utility> namespace llvm { @@ -29,9 +30,6 @@ namespace object { class Binary { private: - Binary() = delete; - Binary(const Binary &other) = delete; - unsigned int TypeID; protected: @@ -80,6 +78,8 @@ protected: } public: + Binary() = delete; + Binary(const Binary &other) = delete; virtual ~Binary(); StringRef getData() const; @@ -173,7 +173,7 @@ OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf) : Bin(std::move(Bin)), Buf(std::move(Buf)) {} -template <typename T> OwningBinary<T>::OwningBinary() {} +template <typename T> OwningBinary<T>::OwningBinary() = default; template <typename T> OwningBinary<T>::OwningBinary(OwningBinary &&Other) @@ -201,7 +201,9 @@ template <typename T> const T* OwningBinary<T>::getBinary() const { } Expected<OwningBinary<Binary>> createBinary(StringRef Path); -} -} -#endif +} // end namespace object + +} // end namespace llvm + +#endif // LLVM_OBJECT_BINARY_H diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 696042d29dabd..e0bb8f1cf3dd6 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -14,28 +14,39 @@ #ifndef LLVM_OBJECT_COFF_H #define LLVM_OBJECT_COFF_H -#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/Error.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <system_error> namespace llvm { + template <typename T> class ArrayRef; namespace object { -class ImportDirectoryEntryRef; + +class BaseRelocRef; class DelayImportDirectoryEntryRef; class ExportDirectoryEntryRef; +class ImportDirectoryEntryRef; class ImportedSymbolRef; -class BaseRelocRef; -typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator; -typedef content_iterator<DelayImportDirectoryEntryRef> - delay_import_directory_iterator; -typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator; -typedef content_iterator<ImportedSymbolRef> imported_symbol_iterator; -typedef content_iterator<BaseRelocRef> base_reloc_iterator; + +using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>; +using delay_import_directory_iterator = + content_iterator<DelayImportDirectoryEntryRef>; +using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>; +using imported_symbol_iterator = content_iterator<ImportedSymbolRef>; +using base_reloc_iterator = content_iterator<BaseRelocRef>; /// The DOS compatible header at the front of all PE/COFF executables. struct dos_header { @@ -190,10 +201,10 @@ struct import_lookup_table_entry { } }; -typedef import_lookup_table_entry<support::little32_t> - import_lookup_table_entry32; -typedef import_lookup_table_entry<support::little64_t> - import_lookup_table_entry64; +using import_lookup_table_entry32 = + import_lookup_table_entry<support::little32_t>; +using import_lookup_table_entry64 = + import_lookup_table_entry<support::little64_t>; struct delay_import_directory_table_entry { // dumpbin reports this field as "Characteristics" instead of "Attributes". @@ -226,8 +237,8 @@ union export_address_table_entry { support::ulittle32_t ForwarderRVA; }; -typedef support::ulittle32_t export_name_pointer_table_entry; -typedef support::ulittle16_t export_ordinal_table_entry; +using export_name_pointer_table_entry = support::ulittle32_t; +using export_ordinal_table_entry = support::ulittle16_t; struct StringTableOffset { support::ulittle32_t Zeroes; @@ -250,8 +261,8 @@ struct coff_symbol { uint8_t NumberOfAuxSymbols; }; -typedef coff_symbol<support::ulittle16_t> coff_symbol16; -typedef coff_symbol<support::ulittle32_t> coff_symbol32; +using coff_symbol16 = coff_symbol<support::ulittle16_t>; +using coff_symbol32 = coff_symbol<support::ulittle32_t>; // Contains only common parts of coff_symbol16 and coff_symbol32. struct coff_symbol_generic { @@ -264,9 +275,9 @@ struct coff_symbol_generic { class COFFSymbolRef { public: - COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {} - COFFSymbolRef(const coff_symbol32 *CS) : CS16(nullptr), CS32(CS) {} - COFFSymbolRef() : CS16(nullptr), CS32(nullptr) {} + COFFSymbolRef() = default; + COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {} + COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {} const void *getRawPtr() const { return CS16 ? static_cast<const void *>(CS16) : CS32; @@ -396,8 +407,8 @@ public: private: bool isSet() const { return CS16 || CS32; } - const coff_symbol16 *CS16; - const coff_symbol32 *CS32; + const coff_symbol16 *CS16 = nullptr; + const coff_symbol32 *CS32 = nullptr; }; struct coff_section { @@ -418,6 +429,7 @@ struct coff_section { return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) && NumberOfRelocations == UINT16_MAX; } + uint32_t getAlignment() const { // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to // IMAGE_SCN_ALIGN_1BYTES. @@ -508,6 +520,7 @@ struct coff_import_header { support::ulittle32_t SizeOfData; support::ulittle16_t OrdinalHint; support::ulittle16_t TypeInfo; + int getType() const { return TypeInfo & 0x3; } int getNameType() const { return (TypeInfo >> 2) & 0x7; } }; @@ -518,6 +531,7 @@ struct coff_import_directory_table_entry { support::ulittle32_t ForwarderChain; support::ulittle32_t NameRVA; support::ulittle32_t ImportAddressTableRVA; + bool isNull() const { return ImportLookupTableRVA == 0 && TimeDateStamp == 0 && ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0; @@ -532,6 +546,7 @@ struct coff_tls_directory { IntTy AddressOfCallBacks; support::ulittle32_t SizeOfZeroFill; support::ulittle32_t Characteristics; + uint32_t getAlignment() const { // Bit [20:24] contains section alignment. uint32_t Shift = (Characteristics & 0x00F00000) >> 20; @@ -541,8 +556,8 @@ struct coff_tls_directory { } }; -typedef coff_tls_directory<support::little32_t> coff_tls_directory32; -typedef coff_tls_directory<support::little64_t> coff_tls_directory64; +using coff_tls_directory32 = coff_tls_directory<support::little32_t>; +using coff_tls_directory64 = coff_tls_directory<support::little64_t>; struct coff_load_configuration32 { support::ulittle32_t Characteristics; @@ -603,6 +618,7 @@ struct coff_base_reloc_block_header { struct coff_base_reloc_block_entry { support::ulittle16_t Data; + int getType() const { return Data >> 12; } int getOffset() const { return Data & ((1 << 12) - 1); } }; @@ -652,6 +668,7 @@ public: return reinterpret_cast<uintptr_t>(SymbolTable32); return uintptr_t(0); } + uint16_t getMachine() const { if (COFFHeader) return COFFHeader->Machine; @@ -659,6 +676,7 @@ public: return COFFBigObjHeader->Machine; llvm_unreachable("no COFF header!"); } + uint16_t getSizeOfOptionalHeader() const { if (COFFHeader) return COFFHeader->isImportLibrary() ? 0 @@ -668,6 +686,7 @@ public: return 0; llvm_unreachable("no COFF header!"); } + uint16_t getCharacteristics() const { if (COFFHeader) return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics; @@ -677,6 +696,7 @@ public: return 0; llvm_unreachable("no COFF header!"); } + uint32_t getTimeDateStamp() const { if (COFFHeader) return COFFHeader->TimeDateStamp; @@ -684,6 +704,7 @@ public: return COFFBigObjHeader->TimeDateStamp; llvm_unreachable("no COFF header!"); } + uint32_t getNumberOfSections() const { if (COFFHeader) return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections; @@ -691,6 +712,7 @@ public: return COFFBigObjHeader->NumberOfSections; llvm_unreachable("no COFF header!"); } + uint32_t getPointerToSymbolTable() const { if (COFFHeader) return COFFHeader->isImportLibrary() ? 0 @@ -699,6 +721,7 @@ public: return COFFBigObjHeader->PointerToSymbolTable; llvm_unreachable("no COFF header!"); } + uint32_t getRawNumberOfSymbols() const { if (COFFHeader) return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols; @@ -706,11 +729,13 @@ public: return COFFBigObjHeader->NumberOfSymbols; llvm_unreachable("no COFF header!"); } + uint32_t getNumberOfSymbols() const { if (!SymbolTable16 && !SymbolTable32) return 0; return getRawNumberOfSymbols(); } + protected: void moveSymbolNext(DataRefImpl &Symb) const override; Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; @@ -746,6 +771,7 @@ protected: public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); + basic_symbol_iterator symbol_begin() const override; basic_symbol_iterator symbol_end() const override; section_iterator section_begin() const override; @@ -797,6 +823,7 @@ public: std::error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; std::error_code getSection(int32_t index, const coff_section *&Res) const; + template <typename coff_symbol_type> std::error_code getSymbol(uint32_t Index, const coff_symbol_type *&Res) const { @@ -821,6 +848,7 @@ public: } return object_error::parse_failed; } + template <typename T> std::error_code getAuxSymbol(uint32_t index, const T *&Res) const { ErrorOr<COFFSymbolRef> s = getSymbol(index); @@ -829,6 +857,7 @@ public: Res = reinterpret_cast<const T *>(s->getRawPtr()); return std::error_code(); } + std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; std::error_code getSymbolName(const coff_symbol_generic *Symbol, StringRef &Res) const; @@ -885,7 +914,7 @@ public: // The iterator for the import directory table. class ImportDirectoryEntryRef { public: - ImportDirectoryEntryRef() : OwningObject(nullptr) {} + ImportDirectoryEntryRef() = default; ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table, uint32_t I, const COFFObjectFile *Owner) : ImportTable(Table), Index(I), OwningObject(Owner) {} @@ -911,12 +940,12 @@ public: private: const coff_import_directory_table_entry *ImportTable; uint32_t Index; - const COFFObjectFile *OwningObject; + const COFFObjectFile *OwningObject = nullptr; }; class DelayImportDirectoryEntryRef { public: - DelayImportDirectoryEntryRef() : OwningObject(nullptr) {} + DelayImportDirectoryEntryRef() = default; DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T, uint32_t I, const COFFObjectFile *Owner) : Table(T), Index(I), OwningObject(Owner) {} @@ -936,13 +965,13 @@ public: private: const delay_import_directory_table_entry *Table; uint32_t Index; - const COFFObjectFile *OwningObject; + const COFFObjectFile *OwningObject = nullptr; }; // The iterator for the export directory table entry. class ExportDirectoryEntryRef { public: - ExportDirectoryEntryRef() : OwningObject(nullptr) {} + ExportDirectoryEntryRef() = default; ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I, const COFFObjectFile *Owner) : ExportTable(Table), Index(I), OwningObject(Owner) {} @@ -962,12 +991,12 @@ public: private: const export_directory_table_entry *ExportTable; uint32_t Index; - const COFFObjectFile *OwningObject; + const COFFObjectFile *OwningObject = nullptr; }; class ImportedSymbolRef { public: - ImportedSymbolRef() : OwningObject(nullptr) {} + ImportedSymbolRef() = default; ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I, const COFFObjectFile *Owner) : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {} @@ -987,12 +1016,12 @@ private: const import_lookup_table_entry32 *Entry32; const import_lookup_table_entry64 *Entry64; uint32_t Index; - const COFFObjectFile *OwningObject; + const COFFObjectFile *OwningObject = nullptr; }; class BaseRelocRef { public: - BaseRelocRef() : OwningObject(nullptr) {} + BaseRelocRef() = default; BaseRelocRef(const coff_base_reloc_block_header *Header, const COFFObjectFile *Owner) : Header(Header), Index(0), OwningObject(Owner) {} @@ -1006,7 +1035,7 @@ public: private: const coff_base_reloc_block_header *Header; uint32_t Index; - const COFFObjectFile *OwningObject; + const COFFObjectFile *OwningObject = nullptr; }; // Corresponds to `_FPO_DATA` structure in the PE/COFF spec. @@ -1034,6 +1063,7 @@ struct FpoData { }; } // end namespace object + } // end namespace llvm -#endif +#endif // LLVM_OBJECT_COFF_H diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index cde6f3b0f6517..be0f02aa7f171 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -41,9 +41,9 @@ typedef support::ulittle32_t Word; /// A reference to a string in the string table. struct Str { - Word Offset; + Word Offset, Size; StringRef get(StringRef Strtab) const { - return Strtab.data() + Offset; + return {Strtab.data() + Offset, Size}; } }; @@ -59,6 +59,9 @@ template <typename T> struct Range { /// table. struct Module { Word Begin, End; + + /// The index of the first Uncommon for this Module. + Word UncBegin; }; /// This is equivalent to an IR comdat. @@ -82,7 +85,8 @@ struct Symbol { Word Flags; enum FlagBits { FB_visibility, // 2 bits - FB_undefined = FB_visibility + 2, + FB_has_uncommon = FB_visibility + 2, + FB_undefined, FB_weak, FB_common, FB_indirect, @@ -94,10 +98,6 @@ struct Symbol { FB_unnamed_addr, FB_executable, }; - - /// The index into the Uncommon table, or -1 if this symbol does not have an - /// Uncommon. - Word UncommonIndex; }; /// This data structure contains rarely used symbol fields and is optionally @@ -249,15 +249,9 @@ public: /// Reader::module_symbols(). class Reader::SymbolRef : public Symbol { const storage::Symbol *SymI, *SymE; + const storage::Uncommon *UncI; const Reader *R; -public: - SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE, - const Reader *R) - : SymI(SymI), SymE(SymE), R(R) { - read(); - } - void read() { if (SymI == SymE) return; @@ -267,16 +261,24 @@ public: ComdatIndex = SymI->ComdatIndex; Flags = SymI->Flags; - uint32_t UncI = SymI->UncommonIndex; - if (UncI != -1u) { - const storage::Uncommon &Unc = R->Uncommons[UncI]; - CommonSize = Unc.CommonSize; - CommonAlign = Unc.CommonAlign; - COFFWeakExternFallbackName = R->str(Unc.COFFWeakExternFallbackName); + if (Flags & (1 << storage::Symbol::FB_has_uncommon)) { + CommonSize = UncI->CommonSize; + CommonAlign = UncI->CommonAlign; + COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName); } } + +public: + SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE, + const storage::Uncommon *UncI, const Reader *R) + : SymI(SymI), SymE(SymE), UncI(UncI), R(R) { + read(); + } + void moveNext() { ++SymI; + if (Flags & (1 << storage::Symbol::FB_has_uncommon)) + ++UncI; read(); } @@ -284,15 +286,16 @@ public: }; inline Reader::symbol_range Reader::symbols() const { - return {SymbolRef(Symbols.begin(), Symbols.end(), this), - SymbolRef(Symbols.end(), Symbols.end(), this)}; + return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this), + SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)}; } inline Reader::symbol_range Reader::module_symbols(unsigned I) const { const storage::Module &M = Modules[I]; const storage::Symbol *MBegin = Symbols.begin() + M.Begin, *MEnd = Symbols.begin() + M.End; - return {SymbolRef(MBegin, MEnd, this), SymbolRef(MEnd, MEnd, this)}; + return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this), + SymbolRef(MEnd, MEnd, nullptr, this)}; } } diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index b689dc2ac03ac..9a7bc618ffd0a 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -14,39 +14,46 @@ #ifndef LLVM_OBJECT_OBJECTFILE_H #define LLVM_OBJECT_OBJECTFILE_H +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/Error.h" #include "llvm/Object/SymbolicFile.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include <cstring> +#include <cassert> +#include <cstdint> +#include <memory> +#include <system_error> namespace llvm { + class ARMAttributeParser; namespace object { -class ObjectFile; class COFFObjectFile; class MachOObjectFile; -class WasmObjectFile; - +class ObjectFile; +class SectionRef; class SymbolRef; class symbol_iterator; -class SectionRef; -typedef content_iterator<SectionRef> section_iterator; +class WasmObjectFile; + +using section_iterator = content_iterator<SectionRef>; /// This is a value type class that represents a single relocation in the list /// of relocations in the object file. class RelocationRef { DataRefImpl RelocationPimpl; - const ObjectFile *OwningObject; + const ObjectFile *OwningObject = nullptr; public: - RelocationRef() : OwningObject(nullptr) { } - + RelocationRef() = default; RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); bool operator==(const RelocationRef &Other) const; @@ -65,18 +72,19 @@ public: DataRefImpl getRawDataRefImpl() const; const ObjectFile *getObject() const; }; -typedef content_iterator<RelocationRef> relocation_iterator; + +using relocation_iterator = content_iterator<RelocationRef>; /// This is a value type class that represents a single section in the list of /// sections in the object file. class SectionRef { friend class SymbolRef; + DataRefImpl SectionPimpl; - const ObjectFile *OwningObject; + const ObjectFile *OwningObject = nullptr; public: - SectionRef() : OwningObject(nullptr) { } - + SectionRef() = default; SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; @@ -119,8 +127,6 @@ class SymbolRef : public BasicSymbolRef { friend class SectionRef; public: - SymbolRef() : BasicSymbolRef() {} - enum Type { ST_Unknown, // Type not specified ST_Data, @@ -130,6 +136,7 @@ public: ST_Other }; + SymbolRef() = default; SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) { assert(isa<ObjectFile>(BasicSymbolRef::getObject())); @@ -179,8 +186,6 @@ public: /// to create. class ObjectFile : public SymbolicFile { virtual void anchor(); - ObjectFile() = delete; - ObjectFile(const ObjectFile &other) = delete; protected: ObjectFile(unsigned int Type, MemoryBufferRef Source); @@ -198,6 +203,7 @@ protected: // Implementations assume that the DataRefImpl is valid and has not been // modified externally. It's UB otherwise. friend class SymbolRef; + virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0; std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override; @@ -211,6 +217,7 @@ protected: // Same as above for SectionRef. friend class SectionRef; + virtual void moveSectionNext(DataRefImpl &Sec) const = 0; virtual std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0; @@ -242,12 +249,15 @@ protected: uint64_t getSymbolValue(DataRefImpl Symb) const; public: + ObjectFile() = delete; + ObjectFile(const ObjectFile &other) = delete; + uint64_t getCommonSymbolSize(DataRefImpl Symb) const { assert(getSymbolFlags(Symb) & SymbolRef::SF_Common); return getCommonSymbolSizeImpl(Symb); } - typedef iterator_range<symbol_iterator> symbol_iterator_range; + using symbol_iterator_range = iterator_range<symbol_iterator>; symbol_iterator_range symbols() const { return symbol_iterator_range(symbol_begin(), symbol_end()); } @@ -255,7 +265,7 @@ public: virtual section_iterator section_begin() const = 0; virtual section_iterator section_end() const = 0; - typedef iterator_range<section_iterator> section_iterator_range; + using section_iterator_range = iterator_range<section_iterator>; section_iterator_range sections() const { return section_iterator_range(section_begin(), section_end()); } @@ -297,7 +307,6 @@ public: return createObjectFile(Object, sys::fs::file_magic::unknown); } - static inline bool classof(const Binary *v) { return v->isObject(); } @@ -354,7 +363,6 @@ inline const ObjectFile *SymbolRef::getObject() const { return cast<ObjectFile>(O); } - /// SectionRef inline SectionRef::SectionRef(DataRefImpl SectionP, const ObjectFile *Owner) @@ -479,8 +487,8 @@ inline const ObjectFile *RelocationRef::getObject() const { return OwningObject; } - } // end namespace object + } // end namespace llvm -#endif +#endif // LLVM_OBJECT_OBJECTFILE_H diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index ef0f96f7834ab..f4be4bfdb1a38 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -14,10 +14,19 @@ #ifndef LLVM_OBJECT_SYMBOLICFILE_H #define LLVM_OBJECT_SYMBOLICFILE_H +#include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Object/Binary.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" +#include "llvm/Support/MemoryBuffer.h" #include <cinttypes> -#include <utility> +#include <cstdint> +#include <cstring> +#include <iterator> +#include <memory> +#include <system_error> namespace llvm { namespace object { @@ -29,6 +38,7 @@ union DataRefImpl { uint32_t a, b; } d; uintptr_t p; + DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); } }; @@ -87,7 +97,7 @@ class SymbolicFile; /// symbols in the object file. class BasicSymbolRef { DataRefImpl SymbolPimpl; - const SymbolicFile *OwningObject; + const SymbolicFile *OwningObject = nullptr; public: enum Flags : unsigned { @@ -108,7 +118,7 @@ public: // (IR only) }; - BasicSymbolRef() : OwningObject(nullptr) { } + BasicSymbolRef() = default; BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner); bool operator==(const BasicSymbolRef &Other) const; @@ -125,12 +135,12 @@ public: const SymbolicFile *getObject() const; }; -typedef content_iterator<BasicSymbolRef> basic_symbol_iterator; +using basic_symbol_iterator = content_iterator<BasicSymbolRef>; class SymbolicFile : public Binary { public: - ~SymbolicFile() override; SymbolicFile(unsigned int Type, MemoryBufferRef Source); + ~SymbolicFile() override; // virtual interface. virtual void moveSymbolNext(DataRefImpl &Symb) const = 0; @@ -145,7 +155,7 @@ public: virtual basic_symbol_iterator symbol_end() const = 0; // convenience wrappers. - typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range; + using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>; basic_symbol_iterator_range symbols() const { return basic_symbol_iterator_range(symbol_begin(), symbol_end()); } @@ -199,7 +209,7 @@ inline const SymbolicFile *BasicSymbolRef::getObject() const { return OwningObject; } -} -} +} // end namespace object +} // end namespace llvm -#endif +#endif // LLVM_OBJECT_SYMBOLICFILE_H diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h index ec34de1f08814..3f39cfc7bb3d7 100644 --- a/include/llvm/ObjectYAML/DWARFYAML.h +++ b/include/llvm/ObjectYAML/DWARFYAML.h @@ -236,7 +236,7 @@ template <> struct MappingTraits<DWARFYAML::InitialLength> { static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF); }; -#define HANDLE_DW_TAG(unused, name) \ +#define HANDLE_DW_TAG(unused, name, unused2, unused3) \ io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name); template <> struct ScalarEnumerationTraits<dwarf::Tag> { @@ -266,7 +266,7 @@ template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> { } }; -#define HANDLE_DW_AT(unused, name) \ +#define HANDLE_DW_AT(unused, name, unused2, unused3) \ io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name); template <> struct ScalarEnumerationTraits<dwarf::Attribute> { @@ -276,7 +276,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Attribute> { } }; -#define HANDLE_DW_FORM(unused, name) \ +#define HANDLE_DW_FORM(unused, name, unused2, unused3) \ io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name); template <> struct ScalarEnumerationTraits<dwarf::Form> { diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index 852d79fbd4435..50e6b498fb462 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -93,11 +93,7 @@ template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) { /// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name"); /// /// This statement will cause your pass to be created by calling the default -/// constructor exposed by the pass. If you have a different constructor that -/// must be called, create a global constructor function (which takes the -/// arguments you need and returns a Pass*) and register your pass like this: -/// -/// static RegisterPass<PassClassName> tmp("passopt", "My Name"); +/// constructor exposed by the pass. /// template <typename passName> struct RegisterPass : public PassInfo { // Register Pass using default constructor... diff --git a/include/llvm/Support/ARMTargetParser.def b/include/llvm/Support/ARMTargetParser.def index 18bf9af432262..32dc57a0fedf5 100644 --- a/include/llvm/Support/ARMTargetParser.def +++ b/include/llvm/Support/ARMTargetParser.def @@ -78,33 +78,33 @@ ARM_ARCH("armv7-a", AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7, FK_NEON, ARM::AEK_DSP) ARM_ARCH("armv7ve", AK_ARMV7VE, "7VE", "v7ve", ARMBuildAttrs::CPUArch::v7, FK_NEON, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | - ARM::AEK_HWDIVARM | ARM::AEK_HWDIV | ARM::AEK_DSP)) + ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP)) ARM_ARCH("armv7-r", AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7, - FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP)) + FK_NONE, (ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP)) ARM_ARCH("armv7-m", AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7, - FK_NONE, ARM::AEK_HWDIV) + FK_NONE, ARM::AEK_HWDIVTHUMB) ARM_ARCH("armv7e-m", AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M, - FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP)) + FK_NONE, (ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP)) ARM_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC)) + ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC)) ARM_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC)) + ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC)) ARM_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a", ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS)) + ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS)) ARM_ARCH("armv8-r", AK_ARMV8R, "8-R", "v8r", ARMBuildAttrs::CPUArch::v8_R, FK_NEON_FP_ARMV8, - (ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIV | + (ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC)) ARM_ARCH("armv8-m.base", AK_ARMV8MBaseline, "8-M.Baseline", "v8m.base", - ARMBuildAttrs::CPUArch::v8_M_Base, FK_NONE, ARM::AEK_HWDIV) + ARMBuildAttrs::CPUArch::v8_M_Base, FK_NONE, ARM::AEK_HWDIVTHUMB) ARM_ARCH("armv8-m.main", AK_ARMV8MMainline, "8-M.Mainline", "v8m.main", - ARMBuildAttrs::CPUArch::v8_M_Main, FK_FPV5_D16, ARM::AEK_HWDIV) + ARMBuildAttrs::CPUArch::v8_M_Main, FK_FPV5_D16, ARM::AEK_HWDIVTHUMB) // Non-standard Arch names. ARM_ARCH("iwmmxt", AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE, FK_NONE, ARM::AEK_NONE) @@ -128,7 +128,7 @@ ARM_ARCH_EXT_NAME("crc", ARM::AEK_CRC, "+crc", "-crc") ARM_ARCH_EXT_NAME("crypto", ARM::AEK_CRYPTO, "+crypto","-crypto") ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp") ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, nullptr, nullptr) -ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV), nullptr, nullptr) +ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), nullptr, nullptr) ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, nullptr, nullptr) ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, nullptr, nullptr) ARM_ARCH_EXT_NAME("sec", ARM::AEK_SEC, nullptr, nullptr) @@ -147,9 +147,9 @@ ARM_ARCH_EXT_NAME("xscale", ARM::AEK_XSCALE, nullptr, nullptr) #endif ARM_HW_DIV_NAME("invalid", ARM::AEK_INVALID) ARM_HW_DIV_NAME("none", ARM::AEK_NONE) -ARM_HW_DIV_NAME("thumb", ARM::AEK_HWDIV) +ARM_HW_DIV_NAME("thumb", ARM::AEK_HWDIVTHUMB) ARM_HW_DIV_NAME("arm", ARM::AEK_HWDIVARM) -ARM_HW_DIV_NAME("arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV)) +ARM_HW_DIV_NAME("arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB)) #undef ARM_HW_DIV_NAME #ifndef ARM_CPU_NAME @@ -205,20 +205,20 @@ ARM_CPU_NAME("cortex-a5", AK_ARMV7A, FK_NEON_VFPV4, false, (ARM::AEK_SEC | ARM::AEK_MP)) ARM_CPU_NAME("cortex-a7", AK_ARMV7A, FK_NEON_VFPV4, false, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV)) + ARM::AEK_HWDIVTHUMB)) ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, true, ARM::AEK_SEC) ARM_CPU_NAME("cortex-a9", AK_ARMV7A, FK_NEON_FP16, false, (ARM::AEK_SEC | ARM::AEK_MP)) ARM_CPU_NAME("cortex-a12", AK_ARMV7A, FK_NEON_VFPV4, false, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV)) + ARM::AEK_HWDIVTHUMB)) ARM_CPU_NAME("cortex-a15", AK_ARMV7A, FK_NEON_VFPV4, false, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV)) + ARM::AEK_HWDIVTHUMB)) ARM_CPU_NAME("cortex-a17", AK_ARMV7A, FK_NEON_VFPV4, false, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | - ARM::AEK_HWDIV)) + ARM::AEK_HWDIVTHUMB)) ARM_CPU_NAME("krait", AK_ARMV7A, FK_NEON_VFPV4, false, - (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV)) + (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB)) ARM_CPU_NAME("cortex-r4", AK_ARMV7R, FK_NONE, true, ARM::AEK_NONE) ARM_CPU_NAME("cortex-r4f", AK_ARMV7R, FK_VFPV3_D16, false, ARM::AEK_NONE) ARM_CPU_NAME("cortex-r5", AK_ARMV7R, FK_VFPV3_D16, false, @@ -249,7 +249,7 @@ ARM_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC) ARM_CPU_NAME("iwmmxt", AK_IWMMXT, FK_NONE, true, ARM::AEK_NONE) ARM_CPU_NAME("xscale", AK_XSCALE, FK_NONE, true, ARM::AEK_NONE) ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true, - (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV)) + (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB)) // Invalid CPU ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, ARM::AEK_INVALID) #undef ARM_CPU_NAME diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h index 4698f12b3bbc8..68696be6bf3d1 100644 --- a/include/llvm/Support/ArrayRecycler.h +++ b/include/llvm/Support/ArrayRecycler.h @@ -47,7 +47,9 @@ template <class T, size_t Align = alignof(T)> class ArrayRecycler { FreeList *Entry = Bucket[Idx]; if (!Entry) return nullptr; + __asan_unpoison_memory_region(Entry, Capacity::get(Idx).getSize()); Bucket[Idx] = Entry->Next; + __msan_allocated_memory(Entry, Capacity::get(Idx).getSize()); return reinterpret_cast<T*>(Entry); } @@ -59,6 +61,7 @@ template <class T, size_t Align = alignof(T)> class ArrayRecycler { Bucket.resize(size_t(Idx) + 1); Entry->Next = Bucket[Idx]; Bucket[Idx] = Entry; + __asan_poison_memory_region(Ptr, Capacity::get(Idx).getSize()); } public: diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h index 3b1301d3cc0bd..21b2474660f2c 100644 --- a/include/llvm/Support/BinaryStreamArray.h +++ b/include/llvm/Support/BinaryStreamArray.h @@ -162,6 +162,11 @@ public: return ThisValue; } + ValueType &operator*() { + assert(Array && !HasError); + return ThisValue; + } + IterType &operator+=(unsigned N) { for (unsigned I = 0; I < N; ++I) { // We are done with the current record, discard it so that we are diff --git a/include/llvm/Support/Dwarf.def b/include/llvm/Support/Dwarf.def index fdbd8ea701166..3df3300de4668 100644 --- a/include/llvm/Support/Dwarf.def +++ b/include/llvm/Support/Dwarf.def @@ -25,27 +25,27 @@ #endif #ifndef HANDLE_DW_TAG -#define HANDLE_DW_TAG(ID, NAME) +#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_AT -#define HANDLE_DW_AT(ID, NAME) +#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_FORM -#define HANDLE_DW_FORM(ID, NAME) +#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_OP -#define HANDLE_DW_OP(ID, NAME) +#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_LANG -#define HANDLE_DW_LANG(ID, NAME) +#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_ATE -#define HANDLE_DW_ATE(ID, NAME) +#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) #endif #ifndef HANDLE_DW_VIRTUALITY @@ -92,591 +92,591 @@ #define HANDLE_DW_UT(ID, NAME) #endif -HANDLE_DW_TAG(0x0000, null) -HANDLE_DW_TAG(0x0001, array_type) -HANDLE_DW_TAG(0x0002, class_type) -HANDLE_DW_TAG(0x0003, entry_point) -HANDLE_DW_TAG(0x0004, enumeration_type) -HANDLE_DW_TAG(0x0005, formal_parameter) -HANDLE_DW_TAG(0x0008, imported_declaration) -HANDLE_DW_TAG(0x000a, label) -HANDLE_DW_TAG(0x000b, lexical_block) -HANDLE_DW_TAG(0x000d, member) -HANDLE_DW_TAG(0x000f, pointer_type) -HANDLE_DW_TAG(0x0010, reference_type) -HANDLE_DW_TAG(0x0011, compile_unit) -HANDLE_DW_TAG(0x0012, string_type) -HANDLE_DW_TAG(0x0013, structure_type) -HANDLE_DW_TAG(0x0015, subroutine_type) -HANDLE_DW_TAG(0x0016, typedef) -HANDLE_DW_TAG(0x0017, union_type) -HANDLE_DW_TAG(0x0018, unspecified_parameters) -HANDLE_DW_TAG(0x0019, variant) -HANDLE_DW_TAG(0x001a, common_block) -HANDLE_DW_TAG(0x001b, common_inclusion) -HANDLE_DW_TAG(0x001c, inheritance) -HANDLE_DW_TAG(0x001d, inlined_subroutine) -HANDLE_DW_TAG(0x001e, module) -HANDLE_DW_TAG(0x001f, ptr_to_member_type) -HANDLE_DW_TAG(0x0020, set_type) -HANDLE_DW_TAG(0x0021, subrange_type) -HANDLE_DW_TAG(0x0022, with_stmt) -HANDLE_DW_TAG(0x0023, access_declaration) -HANDLE_DW_TAG(0x0024, base_type) -HANDLE_DW_TAG(0x0025, catch_block) -HANDLE_DW_TAG(0x0026, const_type) -HANDLE_DW_TAG(0x0027, constant) -HANDLE_DW_TAG(0x0028, enumerator) -HANDLE_DW_TAG(0x0029, file_type) -HANDLE_DW_TAG(0x002a, friend) -HANDLE_DW_TAG(0x002b, namelist) -HANDLE_DW_TAG(0x002c, namelist_item) -HANDLE_DW_TAG(0x002d, packed_type) -HANDLE_DW_TAG(0x002e, subprogram) -HANDLE_DW_TAG(0x002f, template_type_parameter) -HANDLE_DW_TAG(0x0030, template_value_parameter) -HANDLE_DW_TAG(0x0031, thrown_type) -HANDLE_DW_TAG(0x0032, try_block) -HANDLE_DW_TAG(0x0033, variant_part) -HANDLE_DW_TAG(0x0034, variable) -HANDLE_DW_TAG(0x0035, volatile_type) +HANDLE_DW_TAG(0x0000, null, 2, DWARF) +HANDLE_DW_TAG(0x0001, array_type, 2, DWARF) +HANDLE_DW_TAG(0x0002, class_type, 2, DWARF) +HANDLE_DW_TAG(0x0003, entry_point, 2, DWARF) +HANDLE_DW_TAG(0x0004, enumeration_type, 2, DWARF) +HANDLE_DW_TAG(0x0005, formal_parameter, 2, DWARF) +HANDLE_DW_TAG(0x0008, imported_declaration, 2, DWARF) +HANDLE_DW_TAG(0x000a, label, 2, DWARF) +HANDLE_DW_TAG(0x000b, lexical_block, 2, DWARF) +HANDLE_DW_TAG(0x000d, member, 2, DWARF) +HANDLE_DW_TAG(0x000f, pointer_type, 2, DWARF) +HANDLE_DW_TAG(0x0010, reference_type, 2, DWARF) +HANDLE_DW_TAG(0x0011, compile_unit, 2, DWARF) +HANDLE_DW_TAG(0x0012, string_type, 2, DWARF) +HANDLE_DW_TAG(0x0013, structure_type, 2, DWARF) +HANDLE_DW_TAG(0x0015, subroutine_type, 2, DWARF) +HANDLE_DW_TAG(0x0016, typedef, 2, DWARF) +HANDLE_DW_TAG(0x0017, union_type, 2, DWARF) +HANDLE_DW_TAG(0x0018, unspecified_parameters, 2, DWARF) +HANDLE_DW_TAG(0x0019, variant, 2, DWARF) +HANDLE_DW_TAG(0x001a, common_block, 2, DWARF) +HANDLE_DW_TAG(0x001b, common_inclusion, 2, DWARF) +HANDLE_DW_TAG(0x001c, inheritance, 2, DWARF) +HANDLE_DW_TAG(0x001d, inlined_subroutine, 2, DWARF) +HANDLE_DW_TAG(0x001e, module, 2, DWARF) +HANDLE_DW_TAG(0x001f, ptr_to_member_type, 2, DWARF) +HANDLE_DW_TAG(0x0020, set_type, 2, DWARF) +HANDLE_DW_TAG(0x0021, subrange_type, 2, DWARF) +HANDLE_DW_TAG(0x0022, with_stmt, 2, DWARF) +HANDLE_DW_TAG(0x0023, access_declaration, 2, DWARF) +HANDLE_DW_TAG(0x0024, base_type, 2, DWARF) +HANDLE_DW_TAG(0x0025, catch_block, 2, DWARF) +HANDLE_DW_TAG(0x0026, const_type, 2, DWARF) +HANDLE_DW_TAG(0x0027, constant, 2, DWARF) +HANDLE_DW_TAG(0x0028, enumerator, 2, DWARF) +HANDLE_DW_TAG(0x0029, file_type, 2, DWARF) +HANDLE_DW_TAG(0x002a, friend, 2, DWARF) +HANDLE_DW_TAG(0x002b, namelist, 2, DWARF) +HANDLE_DW_TAG(0x002c, namelist_item, 2, DWARF) +HANDLE_DW_TAG(0x002d, packed_type, 2, DWARF) +HANDLE_DW_TAG(0x002e, subprogram, 2, DWARF) +HANDLE_DW_TAG(0x002f, template_type_parameter, 2, DWARF) +HANDLE_DW_TAG(0x0030, template_value_parameter, 2, DWARF) +HANDLE_DW_TAG(0x0031, thrown_type, 2, DWARF) +HANDLE_DW_TAG(0x0032, try_block, 2, DWARF) +HANDLE_DW_TAG(0x0033, variant_part, 2, DWARF) +HANDLE_DW_TAG(0x0034, variable, 2, DWARF) +HANDLE_DW_TAG(0x0035, volatile_type, 2, DWARF) // New in DWARF v3: -HANDLE_DW_TAG(0x0036, dwarf_procedure) -HANDLE_DW_TAG(0x0037, restrict_type) -HANDLE_DW_TAG(0x0038, interface_type) -HANDLE_DW_TAG(0x0039, namespace) -HANDLE_DW_TAG(0x003a, imported_module) -HANDLE_DW_TAG(0x003b, unspecified_type) -HANDLE_DW_TAG(0x003c, partial_unit) -HANDLE_DW_TAG(0x003d, imported_unit) -HANDLE_DW_TAG(0x003f, condition) -HANDLE_DW_TAG(0x0040, shared_type) +HANDLE_DW_TAG(0x0036, dwarf_procedure, 3, DWARF) +HANDLE_DW_TAG(0x0037, restrict_type, 3, DWARF) +HANDLE_DW_TAG(0x0038, interface_type, 3, DWARF) +HANDLE_DW_TAG(0x0039, namespace, 3, DWARF) +HANDLE_DW_TAG(0x003a, imported_module, 3, DWARF) +HANDLE_DW_TAG(0x003b, unspecified_type, 3, DWARF) +HANDLE_DW_TAG(0x003c, partial_unit, 3, DWARF) +HANDLE_DW_TAG(0x003d, imported_unit, 3, DWARF) +HANDLE_DW_TAG(0x003f, condition, 3, DWARF) +HANDLE_DW_TAG(0x0040, shared_type, 3, DWARF) // New in DWARF v4: -HANDLE_DW_TAG(0x0041, type_unit) -HANDLE_DW_TAG(0x0042, rvalue_reference_type) -HANDLE_DW_TAG(0x0043, template_alias) +HANDLE_DW_TAG(0x0041, type_unit, 4, DWARF) +HANDLE_DW_TAG(0x0042, rvalue_reference_type, 4, DWARF) +HANDLE_DW_TAG(0x0043, template_alias, 4, DWARF) // New in DWARF v5: -HANDLE_DW_TAG(0x0044, coarray_type) -HANDLE_DW_TAG(0x0045, generic_subrange) -HANDLE_DW_TAG(0x0046, dynamic_type) -HANDLE_DW_TAG(0x0047, atomic_type) -HANDLE_DW_TAG(0x0048, call_site) -HANDLE_DW_TAG(0x0049, call_site_parameter) -HANDLE_DW_TAG(0x004a, skeleton_unit) -HANDLE_DW_TAG(0x004b, immutable_type) +HANDLE_DW_TAG(0x0044, coarray_type, 5, DWARF) +HANDLE_DW_TAG(0x0045, generic_subrange, 5, DWARF) +HANDLE_DW_TAG(0x0046, dynamic_type, 5, DWARF) +HANDLE_DW_TAG(0x0047, atomic_type, 5, DWARF) +HANDLE_DW_TAG(0x0048, call_site, 5, DWARF) +HANDLE_DW_TAG(0x0049, call_site_parameter, 5, DWARF) +HANDLE_DW_TAG(0x004a, skeleton_unit, 5, DWARF) +HANDLE_DW_TAG(0x004b, immutable_type, 5, DWARF) // Vendor extensions: -HANDLE_DW_TAG(0x4081, MIPS_loop) -HANDLE_DW_TAG(0x4101, format_label) -HANDLE_DW_TAG(0x4102, function_template) -HANDLE_DW_TAG(0x4103, class_template) -HANDLE_DW_TAG(0x4106, GNU_template_template_param) -HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack) -HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack) -HANDLE_DW_TAG(0x4200, APPLE_property) -HANDLE_DW_TAG(0xb000, BORLAND_property) -HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string) -HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array) -HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set) -HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant) +HANDLE_DW_TAG(0x4081, MIPS_loop, 0, MIPS) +HANDLE_DW_TAG(0x4101, format_label, 0, GNU) +HANDLE_DW_TAG(0x4102, function_template, 0, GNU) +HANDLE_DW_TAG(0x4103, class_template, 0, GNU) +HANDLE_DW_TAG(0x4106, GNU_template_template_param, 0, GNU) +HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack, 0, GNU) +HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack, 0, GNU) +HANDLE_DW_TAG(0x4200, APPLE_property, 0, APPLE) +HANDLE_DW_TAG(0xb000, BORLAND_property, 0, BORLAND) +HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string, 0, BORLAND) +HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array, 0, BORLAND) +HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set, 0, BORLAND) +HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant, 0, BORLAND) // Attributes. -HANDLE_DW_AT(0x01, sibling) -HANDLE_DW_AT(0x02, location) -HANDLE_DW_AT(0x03, name) -HANDLE_DW_AT(0x09, ordering) -HANDLE_DW_AT(0x0b, byte_size) -HANDLE_DW_AT(0x0c, bit_offset) -HANDLE_DW_AT(0x0d, bit_size) -HANDLE_DW_AT(0x10, stmt_list) -HANDLE_DW_AT(0x11, low_pc) -HANDLE_DW_AT(0x12, high_pc) -HANDLE_DW_AT(0x13, language) -HANDLE_DW_AT(0x15, discr) -HANDLE_DW_AT(0x16, discr_value) -HANDLE_DW_AT(0x17, visibility) -HANDLE_DW_AT(0x18, import) -HANDLE_DW_AT(0x19, string_length) -HANDLE_DW_AT(0x1a, common_reference) -HANDLE_DW_AT(0x1b, comp_dir) -HANDLE_DW_AT(0x1c, const_value) -HANDLE_DW_AT(0x1d, containing_type) -HANDLE_DW_AT(0x1e, default_value) -HANDLE_DW_AT(0x20, inline) -HANDLE_DW_AT(0x21, is_optional) -HANDLE_DW_AT(0x22, lower_bound) -HANDLE_DW_AT(0x25, producer) -HANDLE_DW_AT(0x27, prototyped) -HANDLE_DW_AT(0x2a, return_addr) -HANDLE_DW_AT(0x2c, start_scope) -HANDLE_DW_AT(0x2e, bit_stride) -HANDLE_DW_AT(0x2f, upper_bound) -HANDLE_DW_AT(0x31, abstract_origin) -HANDLE_DW_AT(0x32, accessibility) -HANDLE_DW_AT(0x33, address_class) -HANDLE_DW_AT(0x34, artificial) -HANDLE_DW_AT(0x35, base_types) -HANDLE_DW_AT(0x36, calling_convention) -HANDLE_DW_AT(0x37, count) -HANDLE_DW_AT(0x38, data_member_location) -HANDLE_DW_AT(0x39, decl_column) -HANDLE_DW_AT(0x3a, decl_file) -HANDLE_DW_AT(0x3b, decl_line) -HANDLE_DW_AT(0x3c, declaration) -HANDLE_DW_AT(0x3d, discr_list) -HANDLE_DW_AT(0x3e, encoding) -HANDLE_DW_AT(0x3f, external) -HANDLE_DW_AT(0x40, frame_base) -HANDLE_DW_AT(0x41, friend) -HANDLE_DW_AT(0x42, identifier_case) -HANDLE_DW_AT(0x43, macro_info) -HANDLE_DW_AT(0x44, namelist_item) -HANDLE_DW_AT(0x45, priority) -HANDLE_DW_AT(0x46, segment) -HANDLE_DW_AT(0x47, specification) -HANDLE_DW_AT(0x48, static_link) -HANDLE_DW_AT(0x49, type) -HANDLE_DW_AT(0x4a, use_location) -HANDLE_DW_AT(0x4b, variable_parameter) -HANDLE_DW_AT(0x4c, virtuality) -HANDLE_DW_AT(0x4d, vtable_elem_location) +HANDLE_DW_AT(0x01, sibling, 2, DWARF) +HANDLE_DW_AT(0x02, location, 2, DWARF) +HANDLE_DW_AT(0x03, name, 2, DWARF) +HANDLE_DW_AT(0x09, ordering, 2, DWARF) +HANDLE_DW_AT(0x0b, byte_size, 2, DWARF) +HANDLE_DW_AT(0x0c, bit_offset, 2, DWARF) +HANDLE_DW_AT(0x0d, bit_size, 2, DWARF) +HANDLE_DW_AT(0x10, stmt_list, 2, DWARF) +HANDLE_DW_AT(0x11, low_pc, 2, DWARF) +HANDLE_DW_AT(0x12, high_pc, 2, DWARF) +HANDLE_DW_AT(0x13, language, 2, DWARF) +HANDLE_DW_AT(0x15, discr, 2, DWARF) +HANDLE_DW_AT(0x16, discr_value, 2, DWARF) +HANDLE_DW_AT(0x17, visibility, 2, DWARF) +HANDLE_DW_AT(0x18, import, 2, DWARF) +HANDLE_DW_AT(0x19, string_length, 2, DWARF) +HANDLE_DW_AT(0x1a, common_reference, 2, DWARF) +HANDLE_DW_AT(0x1b, comp_dir, 2, DWARF) +HANDLE_DW_AT(0x1c, const_value, 2, DWARF) +HANDLE_DW_AT(0x1d, containing_type, 2, DWARF) +HANDLE_DW_AT(0x1e, default_value, 2, DWARF) +HANDLE_DW_AT(0x20, inline, 2, DWARF) +HANDLE_DW_AT(0x21, is_optional, 2, DWARF) +HANDLE_DW_AT(0x22, lower_bound, 2, DWARF) +HANDLE_DW_AT(0x25, producer, 2, DWARF) +HANDLE_DW_AT(0x27, prototyped, 2, DWARF) +HANDLE_DW_AT(0x2a, return_addr, 2, DWARF) +HANDLE_DW_AT(0x2c, start_scope, 2, DWARF) +HANDLE_DW_AT(0x2e, bit_stride, 2, DWARF) +HANDLE_DW_AT(0x2f, upper_bound, 2, DWARF) +HANDLE_DW_AT(0x31, abstract_origin, 2, DWARF) +HANDLE_DW_AT(0x32, accessibility, 2, DWARF) +HANDLE_DW_AT(0x33, address_class, 2, DWARF) +HANDLE_DW_AT(0x34, artificial, 2, DWARF) +HANDLE_DW_AT(0x35, base_types, 2, DWARF) +HANDLE_DW_AT(0x36, calling_convention, 2, DWARF) +HANDLE_DW_AT(0x37, count, 2, DWARF) +HANDLE_DW_AT(0x38, data_member_location, 2, DWARF) +HANDLE_DW_AT(0x39, decl_column, 2, DWARF) +HANDLE_DW_AT(0x3a, decl_file, 2, DWARF) +HANDLE_DW_AT(0x3b, decl_line, 2, DWARF) +HANDLE_DW_AT(0x3c, declaration, 2, DWARF) +HANDLE_DW_AT(0x3d, discr_list, 2, DWARF) +HANDLE_DW_AT(0x3e, encoding, 2, DWARF) +HANDLE_DW_AT(0x3f, external, 2, DWARF) +HANDLE_DW_AT(0x40, frame_base, 2, DWARF) +HANDLE_DW_AT(0x41, friend, 2, DWARF) +HANDLE_DW_AT(0x42, identifier_case, 2, DWARF) +HANDLE_DW_AT(0x43, macro_info, 2, DWARF) +HANDLE_DW_AT(0x44, namelist_item, 2, DWARF) +HANDLE_DW_AT(0x45, priority, 2, DWARF) +HANDLE_DW_AT(0x46, segment, 2, DWARF) +HANDLE_DW_AT(0x47, specification, 2, DWARF) +HANDLE_DW_AT(0x48, static_link, 2, DWARF) +HANDLE_DW_AT(0x49, type, 2, DWARF) +HANDLE_DW_AT(0x4a, use_location, 2, DWARF) +HANDLE_DW_AT(0x4b, variable_parameter, 2, DWARF) +HANDLE_DW_AT(0x4c, virtuality, 2, DWARF) +HANDLE_DW_AT(0x4d, vtable_elem_location, 2, DWARF) // New in DWARF v3: -HANDLE_DW_AT(0x4e, allocated) -HANDLE_DW_AT(0x4f, associated) -HANDLE_DW_AT(0x50, data_location) -HANDLE_DW_AT(0x51, byte_stride) -HANDLE_DW_AT(0x52, entry_pc) -HANDLE_DW_AT(0x53, use_UTF8) -HANDLE_DW_AT(0x54, extension) -HANDLE_DW_AT(0x55, ranges) -HANDLE_DW_AT(0x56, trampoline) -HANDLE_DW_AT(0x57, call_column) -HANDLE_DW_AT(0x58, call_file) -HANDLE_DW_AT(0x59, call_line) -HANDLE_DW_AT(0x5a, description) -HANDLE_DW_AT(0x5b, binary_scale) -HANDLE_DW_AT(0x5c, decimal_scale) -HANDLE_DW_AT(0x5d, small) -HANDLE_DW_AT(0x5e, decimal_sign) -HANDLE_DW_AT(0x5f, digit_count) -HANDLE_DW_AT(0x60, picture_string) -HANDLE_DW_AT(0x61, mutable) -HANDLE_DW_AT(0x62, threads_scaled) -HANDLE_DW_AT(0x63, explicit) -HANDLE_DW_AT(0x64, object_pointer) -HANDLE_DW_AT(0x65, endianity) -HANDLE_DW_AT(0x66, elemental) -HANDLE_DW_AT(0x67, pure) -HANDLE_DW_AT(0x68, recursive) +HANDLE_DW_AT(0x4e, allocated, 3, DWARF) +HANDLE_DW_AT(0x4f, associated, 3, DWARF) +HANDLE_DW_AT(0x50, data_location, 3, DWARF) +HANDLE_DW_AT(0x51, byte_stride, 3, DWARF) +HANDLE_DW_AT(0x52, entry_pc, 3, DWARF) +HANDLE_DW_AT(0x53, use_UTF8, 3, DWARF) +HANDLE_DW_AT(0x54, extension, 3, DWARF) +HANDLE_DW_AT(0x55, ranges, 3, DWARF) +HANDLE_DW_AT(0x56, trampoline, 3, DWARF) +HANDLE_DW_AT(0x57, call_column, 3, DWARF) +HANDLE_DW_AT(0x58, call_file, 3, DWARF) +HANDLE_DW_AT(0x59, call_line, 3, DWARF) +HANDLE_DW_AT(0x5a, description, 3, DWARF) +HANDLE_DW_AT(0x5b, binary_scale, 3, DWARF) +HANDLE_DW_AT(0x5c, decimal_scale, 3, DWARF) +HANDLE_DW_AT(0x5d, small, 3, DWARF) +HANDLE_DW_AT(0x5e, decimal_sign, 3, DWARF) +HANDLE_DW_AT(0x5f, digit_count, 3, DWARF) +HANDLE_DW_AT(0x60, picture_string, 3, DWARF) +HANDLE_DW_AT(0x61, mutable, 3, DWARF) +HANDLE_DW_AT(0x62, threads_scaled, 3, DWARF) +HANDLE_DW_AT(0x63, explicit, 3, DWARF) +HANDLE_DW_AT(0x64, object_pointer, 3, DWARF) +HANDLE_DW_AT(0x65, endianity, 3, DWARF) +HANDLE_DW_AT(0x66, elemental, 3, DWARF) +HANDLE_DW_AT(0x67, pure, 3, DWARF) +HANDLE_DW_AT(0x68, recursive, 3, DWARF) // New in DWARF v4: -HANDLE_DW_AT(0x69, signature) -HANDLE_DW_AT(0x6a, main_subprogram) -HANDLE_DW_AT(0x6b, data_bit_offset) -HANDLE_DW_AT(0x6c, const_expr) -HANDLE_DW_AT(0x6d, enum_class) -HANDLE_DW_AT(0x6e, linkage_name) +HANDLE_DW_AT(0x69, signature, 4, DWARF) +HANDLE_DW_AT(0x6a, main_subprogram, 4, DWARF) +HANDLE_DW_AT(0x6b, data_bit_offset, 4, DWARF) +HANDLE_DW_AT(0x6c, const_expr, 4, DWARF) +HANDLE_DW_AT(0x6d, enum_class, 4, DWARF) +HANDLE_DW_AT(0x6e, linkage_name, 4, DWARF) // New in DWARF v5: -HANDLE_DW_AT(0x6f, string_length_bit_size) -HANDLE_DW_AT(0x70, string_length_byte_size) -HANDLE_DW_AT(0x71, rank) -HANDLE_DW_AT(0x72, str_offsets_base) -HANDLE_DW_AT(0x73, addr_base) -HANDLE_DW_AT(0x74, rnglists_base) -HANDLE_DW_AT(0x75, dwo_id) ///< Retracted from DWARF 5. -HANDLE_DW_AT(0x76, dwo_name) -HANDLE_DW_AT(0x77, reference) -HANDLE_DW_AT(0x78, rvalue_reference) -HANDLE_DW_AT(0x79, macros) -HANDLE_DW_AT(0x7a, call_all_calls) -HANDLE_DW_AT(0x7b, call_all_source_calls) -HANDLE_DW_AT(0x7c, call_all_tail_calls) -HANDLE_DW_AT(0x7d, call_return_pc) -HANDLE_DW_AT(0x7e, call_value) -HANDLE_DW_AT(0x7f, call_origin) -HANDLE_DW_AT(0x80, call_parameter) -HANDLE_DW_AT(0x81, call_pc) -HANDLE_DW_AT(0x82, call_tail_call) -HANDLE_DW_AT(0x83, call_target) -HANDLE_DW_AT(0x84, call_target_clobbered) -HANDLE_DW_AT(0x85, call_data_location) -HANDLE_DW_AT(0x86, call_data_value) -HANDLE_DW_AT(0x87, noreturn) -HANDLE_DW_AT(0x88, alignment) -HANDLE_DW_AT(0x89, export_symbols) -HANDLE_DW_AT(0x8a, deleted) -HANDLE_DW_AT(0x8b, defaulted) -HANDLE_DW_AT(0x8c, loclists_base) +HANDLE_DW_AT(0x6f, string_length_bit_size, 5, DWARF) +HANDLE_DW_AT(0x70, string_length_byte_size, 5, DWARF) +HANDLE_DW_AT(0x71, rank, 5, DWARF) +HANDLE_DW_AT(0x72, str_offsets_base, 5, DWARF) +HANDLE_DW_AT(0x73, addr_base, 5, DWARF) +HANDLE_DW_AT(0x74, rnglists_base, 5, DWARF) +HANDLE_DW_AT(0x75, dwo_id, 0, DWARF) ///< Retracted from DWARF v5. +HANDLE_DW_AT(0x76, dwo_name, 5, DWARF) +HANDLE_DW_AT(0x77, reference, 5, DWARF) +HANDLE_DW_AT(0x78, rvalue_reference, 5, DWARF) +HANDLE_DW_AT(0x79, macros, 5, DWARF) +HANDLE_DW_AT(0x7a, call_all_calls, 5, DWARF) +HANDLE_DW_AT(0x7b, call_all_source_calls, 5, DWARF) +HANDLE_DW_AT(0x7c, call_all_tail_calls, 5, DWARF) +HANDLE_DW_AT(0x7d, call_return_pc, 5, DWARF) +HANDLE_DW_AT(0x7e, call_value, 5, DWARF) +HANDLE_DW_AT(0x7f, call_origin, 5, DWARF) +HANDLE_DW_AT(0x80, call_parameter, 5, DWARF) +HANDLE_DW_AT(0x81, call_pc, 5, DWARF) +HANDLE_DW_AT(0x82, call_tail_call, 5, DWARF) +HANDLE_DW_AT(0x83, call_target, 5, DWARF) +HANDLE_DW_AT(0x84, call_target_clobbered, 5, DWARF) +HANDLE_DW_AT(0x85, call_data_location, 5, DWARF) +HANDLE_DW_AT(0x86, call_data_value, 5, DWARF) +HANDLE_DW_AT(0x87, noreturn, 5, DWARF) +HANDLE_DW_AT(0x88, alignment, 5, DWARF) +HANDLE_DW_AT(0x89, export_symbols, 5, DWARF) +HANDLE_DW_AT(0x8a, deleted, 5, DWARF) +HANDLE_DW_AT(0x8b, defaulted, 5, DWARF) +HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF) // Vendor extensions: -HANDLE_DW_AT(0x2002, MIPS_loop_begin) -HANDLE_DW_AT(0x2003, MIPS_tail_loop_begin) -HANDLE_DW_AT(0x2004, MIPS_epilog_begin) -HANDLE_DW_AT(0x2005, MIPS_loop_unroll_factor) -HANDLE_DW_AT(0x2006, MIPS_software_pipeline_depth) -HANDLE_DW_AT(0x2007, MIPS_linkage_name) -HANDLE_DW_AT(0x2008, MIPS_stride) -HANDLE_DW_AT(0x2009, MIPS_abstract_name) -HANDLE_DW_AT(0x200a, MIPS_clone_origin) -HANDLE_DW_AT(0x200b, MIPS_has_inlines) -HANDLE_DW_AT(0x200c, MIPS_stride_byte) -HANDLE_DW_AT(0x200d, MIPS_stride_elem) -HANDLE_DW_AT(0x200e, MIPS_ptr_dopetype) -HANDLE_DW_AT(0x200f, MIPS_allocatable_dopetype) -HANDLE_DW_AT(0x2010, MIPS_assumed_shape_dopetype) +HANDLE_DW_AT(0x2002, MIPS_loop_begin, 0, MIPS) +HANDLE_DW_AT(0x2003, MIPS_tail_loop_begin, 0, MIPS) +HANDLE_DW_AT(0x2004, MIPS_epilog_begin, 0, MIPS) +HANDLE_DW_AT(0x2005, MIPS_loop_unroll_factor, 0, MIPS) +HANDLE_DW_AT(0x2006, MIPS_software_pipeline_depth, 0, MIPS) +HANDLE_DW_AT(0x2007, MIPS_linkage_name, 0, MIPS) +HANDLE_DW_AT(0x2008, MIPS_stride, 0, MIPS) +HANDLE_DW_AT(0x2009, MIPS_abstract_name, 0, MIPS) +HANDLE_DW_AT(0x200a, MIPS_clone_origin, 0, MIPS) +HANDLE_DW_AT(0x200b, MIPS_has_inlines, 0, MIPS) +HANDLE_DW_AT(0x200c, MIPS_stride_byte, 0, MIPS) +HANDLE_DW_AT(0x200d, MIPS_stride_elem, 0, MIPS) +HANDLE_DW_AT(0x200e, MIPS_ptr_dopetype, 0, MIPS) +HANDLE_DW_AT(0x200f, MIPS_allocatable_dopetype, 0, MIPS) +HANDLE_DW_AT(0x2010, MIPS_assumed_shape_dopetype, 0, MIPS) // This one appears to have only been implemented by Open64 for // fortran and may conflict with other extensions. -HANDLE_DW_AT(0x2011, MIPS_assumed_size) +HANDLE_DW_AT(0x2011, MIPS_assumed_size, 0, MIPS) // GNU extensions -HANDLE_DW_AT(0x2101, sf_names) -HANDLE_DW_AT(0x2102, src_info) -HANDLE_DW_AT(0x2103, mac_info) -HANDLE_DW_AT(0x2104, src_coords) -HANDLE_DW_AT(0x2105, body_begin) -HANDLE_DW_AT(0x2106, body_end) -HANDLE_DW_AT(0x2107, GNU_vector) -HANDLE_DW_AT(0x2110, GNU_template_name) -HANDLE_DW_AT(0x210f, GNU_odr_signature) -HANDLE_DW_AT(0x2119, GNU_macros) +HANDLE_DW_AT(0x2101, sf_names, 0, GNU) +HANDLE_DW_AT(0x2102, src_info, 0, GNU) +HANDLE_DW_AT(0x2103, mac_info, 0, GNU) +HANDLE_DW_AT(0x2104, src_coords, 0, GNU) +HANDLE_DW_AT(0x2105, body_begin, 0, GNU) +HANDLE_DW_AT(0x2106, body_end, 0, GNU) +HANDLE_DW_AT(0x2107, GNU_vector, 0, GNU) +HANDLE_DW_AT(0x2110, GNU_template_name, 0, GNU) +HANDLE_DW_AT(0x210f, GNU_odr_signature, 0, GNU) +HANDLE_DW_AT(0x2119, GNU_macros, 0, GNU) // Extensions for Fission proposal. -HANDLE_DW_AT(0x2130, GNU_dwo_name) -HANDLE_DW_AT(0x2131, GNU_dwo_id) -HANDLE_DW_AT(0x2132, GNU_ranges_base) -HANDLE_DW_AT(0x2133, GNU_addr_base) -HANDLE_DW_AT(0x2134, GNU_pubnames) -HANDLE_DW_AT(0x2135, GNU_pubtypes) -HANDLE_DW_AT(0x2136, GNU_discriminator) +HANDLE_DW_AT(0x2130, GNU_dwo_name, 0, GNU) +HANDLE_DW_AT(0x2131, GNU_dwo_id, 0, GNU) +HANDLE_DW_AT(0x2132, GNU_ranges_base, 0, GNU) +HANDLE_DW_AT(0x2133, GNU_addr_base, 0, GNU) +HANDLE_DW_AT(0x2134, GNU_pubnames, 0, GNU) +HANDLE_DW_AT(0x2135, GNU_pubtypes, 0, GNU) +HANDLE_DW_AT(0x2136, GNU_discriminator, 0, GNU) // Borland extensions. -HANDLE_DW_AT(0x3b11, BORLAND_property_read) -HANDLE_DW_AT(0x3b12, BORLAND_property_write) -HANDLE_DW_AT(0x3b13, BORLAND_property_implements) -HANDLE_DW_AT(0x3b14, BORLAND_property_index) -HANDLE_DW_AT(0x3b15, BORLAND_property_default) -HANDLE_DW_AT(0x3b20, BORLAND_Delphi_unit) -HANDLE_DW_AT(0x3b21, BORLAND_Delphi_class) -HANDLE_DW_AT(0x3b22, BORLAND_Delphi_record) -HANDLE_DW_AT(0x3b23, BORLAND_Delphi_metaclass) -HANDLE_DW_AT(0x3b24, BORLAND_Delphi_constructor) -HANDLE_DW_AT(0x3b25, BORLAND_Delphi_destructor) -HANDLE_DW_AT(0x3b26, BORLAND_Delphi_anonymous_method) -HANDLE_DW_AT(0x3b27, BORLAND_Delphi_interface) -HANDLE_DW_AT(0x3b28, BORLAND_Delphi_ABI) -HANDLE_DW_AT(0x3b29, BORLAND_Delphi_return) -HANDLE_DW_AT(0x3b30, BORLAND_Delphi_frameptr) -HANDLE_DW_AT(0x3b31, BORLAND_closure) +HANDLE_DW_AT(0x3b11, BORLAND_property_read, 0, BORLAND) +HANDLE_DW_AT(0x3b12, BORLAND_property_write, 0, BORLAND) +HANDLE_DW_AT(0x3b13, BORLAND_property_implements, 0, BORLAND) +HANDLE_DW_AT(0x3b14, BORLAND_property_index, 0, BORLAND) +HANDLE_DW_AT(0x3b15, BORLAND_property_default, 0, BORLAND) +HANDLE_DW_AT(0x3b20, BORLAND_Delphi_unit, 0, BORLAND) +HANDLE_DW_AT(0x3b21, BORLAND_Delphi_class, 0, BORLAND) +HANDLE_DW_AT(0x3b22, BORLAND_Delphi_record, 0, BORLAND) +HANDLE_DW_AT(0x3b23, BORLAND_Delphi_metaclass, 0, BORLAND) +HANDLE_DW_AT(0x3b24, BORLAND_Delphi_constructor, 0, BORLAND) +HANDLE_DW_AT(0x3b25, BORLAND_Delphi_destructor, 0, BORLAND) +HANDLE_DW_AT(0x3b26, BORLAND_Delphi_anonymous_method, 0, BORLAND) +HANDLE_DW_AT(0x3b27, BORLAND_Delphi_interface, 0, BORLAND) +HANDLE_DW_AT(0x3b28, BORLAND_Delphi_ABI, 0, BORLAND) +HANDLE_DW_AT(0x3b29, BORLAND_Delphi_return, 0, BORLAND) +HANDLE_DW_AT(0x3b30, BORLAND_Delphi_frameptr, 0, BORLAND) +HANDLE_DW_AT(0x3b31, BORLAND_closure, 0, BORLAND) // LLVM project extensions. -HANDLE_DW_AT(0x3e00, LLVM_include_path) -HANDLE_DW_AT(0x3e01, LLVM_config_macros) -HANDLE_DW_AT(0x3e02, LLVM_isysroot) +HANDLE_DW_AT(0x3e00, LLVM_include_path, 0, LLVM) +HANDLE_DW_AT(0x3e01, LLVM_config_macros, 0, LLVM) +HANDLE_DW_AT(0x3e02, LLVM_isysroot, 0, LLVM) // Apple extensions. -HANDLE_DW_AT(0x3fe1, APPLE_optimized) -HANDLE_DW_AT(0x3fe2, APPLE_flags) -HANDLE_DW_AT(0x3fe3, APPLE_isa) -HANDLE_DW_AT(0x3fe4, APPLE_block) -HANDLE_DW_AT(0x3fe5, APPLE_major_runtime_vers) -HANDLE_DW_AT(0x3fe6, APPLE_runtime_class) -HANDLE_DW_AT(0x3fe7, APPLE_omit_frame_ptr) -HANDLE_DW_AT(0x3fe8, APPLE_property_name) -HANDLE_DW_AT(0x3fe9, APPLE_property_getter) -HANDLE_DW_AT(0x3fea, APPLE_property_setter) -HANDLE_DW_AT(0x3feb, APPLE_property_attribute) -HANDLE_DW_AT(0x3fec, APPLE_objc_complete_type) -HANDLE_DW_AT(0x3fed, APPLE_property) +HANDLE_DW_AT(0x3fe1, APPLE_optimized, 0, APPLE) +HANDLE_DW_AT(0x3fe2, APPLE_flags, 0, APPLE) +HANDLE_DW_AT(0x3fe3, APPLE_isa, 0, APPLE) +HANDLE_DW_AT(0x3fe4, APPLE_block, 0, APPLE) +HANDLE_DW_AT(0x3fe5, APPLE_major_runtime_vers, 0, APPLE) +HANDLE_DW_AT(0x3fe6, APPLE_runtime_class, 0, APPLE) +HANDLE_DW_AT(0x3fe7, APPLE_omit_frame_ptr, 0, APPLE) +HANDLE_DW_AT(0x3fe8, APPLE_property_name, 0, APPLE) +HANDLE_DW_AT(0x3fe9, APPLE_property_getter, 0, APPLE) +HANDLE_DW_AT(0x3fea, APPLE_property_setter, 0, APPLE) +HANDLE_DW_AT(0x3feb, APPLE_property_attribute, 0, APPLE) +HANDLE_DW_AT(0x3fec, APPLE_objc_complete_type, 0, APPLE) +HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE) // Attribute form encodings. -HANDLE_DW_FORM(0x01, addr) -HANDLE_DW_FORM(0x03, block2) -HANDLE_DW_FORM(0x04, block4) -HANDLE_DW_FORM(0x05, data2) -HANDLE_DW_FORM(0x06, data4) -HANDLE_DW_FORM(0x07, data8) -HANDLE_DW_FORM(0x08, string) -HANDLE_DW_FORM(0x09, block) -HANDLE_DW_FORM(0x0a, block1) -HANDLE_DW_FORM(0x0b, data1) -HANDLE_DW_FORM(0x0c, flag) -HANDLE_DW_FORM(0x0d, sdata) -HANDLE_DW_FORM(0x0e, strp) -HANDLE_DW_FORM(0x0f, udata) -HANDLE_DW_FORM(0x10, ref_addr) -HANDLE_DW_FORM(0x11, ref1) -HANDLE_DW_FORM(0x12, ref2) -HANDLE_DW_FORM(0x13, ref4) -HANDLE_DW_FORM(0x14, ref8) -HANDLE_DW_FORM(0x15, ref_udata) -HANDLE_DW_FORM(0x16, indirect) +HANDLE_DW_FORM(0x01, addr, 2, DWARF) +HANDLE_DW_FORM(0x03, block2, 2, DWARF) +HANDLE_DW_FORM(0x04, block4, 2, DWARF) +HANDLE_DW_FORM(0x05, data2, 2, DWARF) +HANDLE_DW_FORM(0x06, data4, 2, DWARF) +HANDLE_DW_FORM(0x07, data8, 2, DWARF) +HANDLE_DW_FORM(0x08, string, 2, DWARF) +HANDLE_DW_FORM(0x09, block, 2, DWARF) +HANDLE_DW_FORM(0x0a, block1, 2, DWARF) +HANDLE_DW_FORM(0x0b, data1, 2, DWARF) +HANDLE_DW_FORM(0x0c, flag, 2, DWARF) +HANDLE_DW_FORM(0x0d, sdata, 2, DWARF) +HANDLE_DW_FORM(0x0e, strp, 2, DWARF) +HANDLE_DW_FORM(0x0f, udata, 2, DWARF) +HANDLE_DW_FORM(0x10, ref_addr, 2, DWARF) +HANDLE_DW_FORM(0x11, ref1, 2, DWARF) +HANDLE_DW_FORM(0x12, ref2, 2, DWARF) +HANDLE_DW_FORM(0x13, ref4, 2, DWARF) +HANDLE_DW_FORM(0x14, ref8, 2, DWARF) +HANDLE_DW_FORM(0x15, ref_udata, 2, DWARF) +HANDLE_DW_FORM(0x16, indirect, 2, DWARF) // New in DWARF v4: -HANDLE_DW_FORM(0x17, sec_offset) -HANDLE_DW_FORM(0x18, exprloc) -HANDLE_DW_FORM(0x19, flag_present) +HANDLE_DW_FORM(0x17, sec_offset, 4, DWARF) +HANDLE_DW_FORM(0x18, exprloc, 4, DWARF) +HANDLE_DW_FORM(0x19, flag_present, 4, DWARF) // This was defined out of sequence. -HANDLE_DW_FORM(0x20, ref_sig8) +HANDLE_DW_FORM(0x20, ref_sig8, 4, DWARF) // New in DWARF v5: -HANDLE_DW_FORM(0x1a, strx) -HANDLE_DW_FORM(0x1b, addrx) -HANDLE_DW_FORM(0x1c, ref_sup4) -HANDLE_DW_FORM(0x1d, strp_sup) -HANDLE_DW_FORM(0x1e, data16) -HANDLE_DW_FORM(0x1f, line_strp) -HANDLE_DW_FORM(0x21, implicit_const) -HANDLE_DW_FORM(0x22, loclistx) -HANDLE_DW_FORM(0x23, rnglistx) -HANDLE_DW_FORM(0x24, ref_sup8) -HANDLE_DW_FORM(0x25, strx1) -HANDLE_DW_FORM(0x26, strx2) -HANDLE_DW_FORM(0x27, strx3) -HANDLE_DW_FORM(0x28, strx4) -HANDLE_DW_FORM(0x29, addrx1) -HANDLE_DW_FORM(0x2a, addrx2) -HANDLE_DW_FORM(0x2b, addrx3) -HANDLE_DW_FORM(0x2c, addrx4) +HANDLE_DW_FORM(0x1a, strx, 5, DWARF) +HANDLE_DW_FORM(0x1b, addrx, 5, DWARF) +HANDLE_DW_FORM(0x1c, ref_sup4, 5, DWARF) +HANDLE_DW_FORM(0x1d, strp_sup, 5, DWARF) +HANDLE_DW_FORM(0x1e, data16, 5, DWARF) +HANDLE_DW_FORM(0x1f, line_strp, 5, DWARF) +HANDLE_DW_FORM(0x21, implicit_const, 5, DWARF) +HANDLE_DW_FORM(0x22, loclistx, 5, DWARF) +HANDLE_DW_FORM(0x23, rnglistx, 5, DWARF) +HANDLE_DW_FORM(0x24, ref_sup8, 5, DWARF) +HANDLE_DW_FORM(0x25, strx1, 5, DWARF) +HANDLE_DW_FORM(0x26, strx2, 5, DWARF) +HANDLE_DW_FORM(0x27, strx3, 5, DWARF) +HANDLE_DW_FORM(0x28, strx4, 5, DWARF) +HANDLE_DW_FORM(0x29, addrx1, 5, DWARF) +HANDLE_DW_FORM(0x2a, addrx2, 5, DWARF) +HANDLE_DW_FORM(0x2b, addrx3, 5, DWARF) +HANDLE_DW_FORM(0x2c, addrx4, 5, DWARF) // Extensions for Fission proposal -HANDLE_DW_FORM(0x1f01, GNU_addr_index) -HANDLE_DW_FORM(0x1f02, GNU_str_index) +HANDLE_DW_FORM(0x1f01, GNU_addr_index, 0, GNU) +HANDLE_DW_FORM(0x1f02, GNU_str_index, 0, GNU) // Alternate debug sections proposal (output of "dwz" tool). -HANDLE_DW_FORM(0x1f20, GNU_ref_alt) -HANDLE_DW_FORM(0x1f21, GNU_strp_alt) +HANDLE_DW_FORM(0x1f20, GNU_ref_alt, 0, GNU) +HANDLE_DW_FORM(0x1f21, GNU_strp_alt, 0, GNU) // DWARF Expression operators. -HANDLE_DW_OP(0x03, addr) -HANDLE_DW_OP(0x06, deref) -HANDLE_DW_OP(0x08, const1u) -HANDLE_DW_OP(0x09, const1s) -HANDLE_DW_OP(0x0a, const2u) -HANDLE_DW_OP(0x0b, const2s) -HANDLE_DW_OP(0x0c, const4u) -HANDLE_DW_OP(0x0d, const4s) -HANDLE_DW_OP(0x0e, const8u) -HANDLE_DW_OP(0x0f, const8s) -HANDLE_DW_OP(0x10, constu) -HANDLE_DW_OP(0x11, consts) -HANDLE_DW_OP(0x12, dup) -HANDLE_DW_OP(0x13, drop) -HANDLE_DW_OP(0x14, over) -HANDLE_DW_OP(0x15, pick) -HANDLE_DW_OP(0x16, swap) -HANDLE_DW_OP(0x17, rot) -HANDLE_DW_OP(0x18, xderef) -HANDLE_DW_OP(0x19, abs) -HANDLE_DW_OP(0x1a, and) -HANDLE_DW_OP(0x1b, div) -HANDLE_DW_OP(0x1c, minus) -HANDLE_DW_OP(0x1d, mod) -HANDLE_DW_OP(0x1e, mul) -HANDLE_DW_OP(0x1f, neg) -HANDLE_DW_OP(0x20, not) -HANDLE_DW_OP(0x21, or) -HANDLE_DW_OP(0x22, plus) -HANDLE_DW_OP(0x23, plus_uconst) -HANDLE_DW_OP(0x24, shl) -HANDLE_DW_OP(0x25, shr) -HANDLE_DW_OP(0x26, shra) -HANDLE_DW_OP(0x27, xor) -HANDLE_DW_OP(0x28, bra) -HANDLE_DW_OP(0x29, eq) -HANDLE_DW_OP(0x2a, ge) -HANDLE_DW_OP(0x2b, gt) -HANDLE_DW_OP(0x2c, le) -HANDLE_DW_OP(0x2d, lt) -HANDLE_DW_OP(0x2e, ne) -HANDLE_DW_OP(0x2f, skip) -HANDLE_DW_OP(0x30, lit0) -HANDLE_DW_OP(0x31, lit1) -HANDLE_DW_OP(0x32, lit2) -HANDLE_DW_OP(0x33, lit3) -HANDLE_DW_OP(0x34, lit4) -HANDLE_DW_OP(0x35, lit5) -HANDLE_DW_OP(0x36, lit6) -HANDLE_DW_OP(0x37, lit7) -HANDLE_DW_OP(0x38, lit8) -HANDLE_DW_OP(0x39, lit9) -HANDLE_DW_OP(0x3a, lit10) -HANDLE_DW_OP(0x3b, lit11) -HANDLE_DW_OP(0x3c, lit12) -HANDLE_DW_OP(0x3d, lit13) -HANDLE_DW_OP(0x3e, lit14) -HANDLE_DW_OP(0x3f, lit15) -HANDLE_DW_OP(0x40, lit16) -HANDLE_DW_OP(0x41, lit17) -HANDLE_DW_OP(0x42, lit18) -HANDLE_DW_OP(0x43, lit19) -HANDLE_DW_OP(0x44, lit20) -HANDLE_DW_OP(0x45, lit21) -HANDLE_DW_OP(0x46, lit22) -HANDLE_DW_OP(0x47, lit23) -HANDLE_DW_OP(0x48, lit24) -HANDLE_DW_OP(0x49, lit25) -HANDLE_DW_OP(0x4a, lit26) -HANDLE_DW_OP(0x4b, lit27) -HANDLE_DW_OP(0x4c, lit28) -HANDLE_DW_OP(0x4d, lit29) -HANDLE_DW_OP(0x4e, lit30) -HANDLE_DW_OP(0x4f, lit31) -HANDLE_DW_OP(0x50, reg0) -HANDLE_DW_OP(0x51, reg1) -HANDLE_DW_OP(0x52, reg2) -HANDLE_DW_OP(0x53, reg3) -HANDLE_DW_OP(0x54, reg4) -HANDLE_DW_OP(0x55, reg5) -HANDLE_DW_OP(0x56, reg6) -HANDLE_DW_OP(0x57, reg7) -HANDLE_DW_OP(0x58, reg8) -HANDLE_DW_OP(0x59, reg9) -HANDLE_DW_OP(0x5a, reg10) -HANDLE_DW_OP(0x5b, reg11) -HANDLE_DW_OP(0x5c, reg12) -HANDLE_DW_OP(0x5d, reg13) -HANDLE_DW_OP(0x5e, reg14) -HANDLE_DW_OP(0x5f, reg15) -HANDLE_DW_OP(0x60, reg16) -HANDLE_DW_OP(0x61, reg17) -HANDLE_DW_OP(0x62, reg18) -HANDLE_DW_OP(0x63, reg19) -HANDLE_DW_OP(0x64, reg20) -HANDLE_DW_OP(0x65, reg21) -HANDLE_DW_OP(0x66, reg22) -HANDLE_DW_OP(0x67, reg23) -HANDLE_DW_OP(0x68, reg24) -HANDLE_DW_OP(0x69, reg25) -HANDLE_DW_OP(0x6a, reg26) -HANDLE_DW_OP(0x6b, reg27) -HANDLE_DW_OP(0x6c, reg28) -HANDLE_DW_OP(0x6d, reg29) -HANDLE_DW_OP(0x6e, reg30) -HANDLE_DW_OP(0x6f, reg31) -HANDLE_DW_OP(0x70, breg0) -HANDLE_DW_OP(0x71, breg1) -HANDLE_DW_OP(0x72, breg2) -HANDLE_DW_OP(0x73, breg3) -HANDLE_DW_OP(0x74, breg4) -HANDLE_DW_OP(0x75, breg5) -HANDLE_DW_OP(0x76, breg6) -HANDLE_DW_OP(0x77, breg7) -HANDLE_DW_OP(0x78, breg8) -HANDLE_DW_OP(0x79, breg9) -HANDLE_DW_OP(0x7a, breg10) -HANDLE_DW_OP(0x7b, breg11) -HANDLE_DW_OP(0x7c, breg12) -HANDLE_DW_OP(0x7d, breg13) -HANDLE_DW_OP(0x7e, breg14) -HANDLE_DW_OP(0x7f, breg15) -HANDLE_DW_OP(0x80, breg16) -HANDLE_DW_OP(0x81, breg17) -HANDLE_DW_OP(0x82, breg18) -HANDLE_DW_OP(0x83, breg19) -HANDLE_DW_OP(0x84, breg20) -HANDLE_DW_OP(0x85, breg21) -HANDLE_DW_OP(0x86, breg22) -HANDLE_DW_OP(0x87, breg23) -HANDLE_DW_OP(0x88, breg24) -HANDLE_DW_OP(0x89, breg25) -HANDLE_DW_OP(0x8a, breg26) -HANDLE_DW_OP(0x8b, breg27) -HANDLE_DW_OP(0x8c, breg28) -HANDLE_DW_OP(0x8d, breg29) -HANDLE_DW_OP(0x8e, breg30) -HANDLE_DW_OP(0x8f, breg31) -HANDLE_DW_OP(0x90, regx) -HANDLE_DW_OP(0x91, fbreg) -HANDLE_DW_OP(0x92, bregx) -HANDLE_DW_OP(0x93, piece) -HANDLE_DW_OP(0x94, deref_size) -HANDLE_DW_OP(0x95, xderef_size) -HANDLE_DW_OP(0x96, nop) +HANDLE_DW_OP(0x03, addr, 2, DWARF) +HANDLE_DW_OP(0x06, deref, 2, DWARF) +HANDLE_DW_OP(0x08, const1u, 2, DWARF) +HANDLE_DW_OP(0x09, const1s, 2, DWARF) +HANDLE_DW_OP(0x0a, const2u, 2, DWARF) +HANDLE_DW_OP(0x0b, const2s, 2, DWARF) +HANDLE_DW_OP(0x0c, const4u, 2, DWARF) +HANDLE_DW_OP(0x0d, const4s, 2, DWARF) +HANDLE_DW_OP(0x0e, const8u, 2, DWARF) +HANDLE_DW_OP(0x0f, const8s, 2, DWARF) +HANDLE_DW_OP(0x10, constu, 2, DWARF) +HANDLE_DW_OP(0x11, consts, 2, DWARF) +HANDLE_DW_OP(0x12, dup, 2, DWARF) +HANDLE_DW_OP(0x13, drop, 2, DWARF) +HANDLE_DW_OP(0x14, over, 2, DWARF) +HANDLE_DW_OP(0x15, pick, 2, DWARF) +HANDLE_DW_OP(0x16, swap, 2, DWARF) +HANDLE_DW_OP(0x17, rot, 2, DWARF) +HANDLE_DW_OP(0x18, xderef, 2, DWARF) +HANDLE_DW_OP(0x19, abs, 2, DWARF) +HANDLE_DW_OP(0x1a, and, 2, DWARF) +HANDLE_DW_OP(0x1b, div, 2, DWARF) +HANDLE_DW_OP(0x1c, minus, 2, DWARF) +HANDLE_DW_OP(0x1d, mod, 2, DWARF) +HANDLE_DW_OP(0x1e, mul, 2, DWARF) +HANDLE_DW_OP(0x1f, neg, 2, DWARF) +HANDLE_DW_OP(0x20, not, 2, DWARF) +HANDLE_DW_OP(0x21, or, 2, DWARF) +HANDLE_DW_OP(0x22, plus, 2, DWARF) +HANDLE_DW_OP(0x23, plus_uconst, 2, DWARF) +HANDLE_DW_OP(0x24, shl, 2, DWARF) +HANDLE_DW_OP(0x25, shr, 2, DWARF) +HANDLE_DW_OP(0x26, shra, 2, DWARF) +HANDLE_DW_OP(0x27, xor, 2, DWARF) +HANDLE_DW_OP(0x28, bra, 2, DWARF) +HANDLE_DW_OP(0x29, eq, 2, DWARF) +HANDLE_DW_OP(0x2a, ge, 2, DWARF) +HANDLE_DW_OP(0x2b, gt, 2, DWARF) +HANDLE_DW_OP(0x2c, le, 2, DWARF) +HANDLE_DW_OP(0x2d, lt, 2, DWARF) +HANDLE_DW_OP(0x2e, ne, 2, DWARF) +HANDLE_DW_OP(0x2f, skip, 2, DWARF) +HANDLE_DW_OP(0x30, lit0, 2, DWARF) +HANDLE_DW_OP(0x31, lit1, 2, DWARF) +HANDLE_DW_OP(0x32, lit2, 2, DWARF) +HANDLE_DW_OP(0x33, lit3, 2, DWARF) +HANDLE_DW_OP(0x34, lit4, 2, DWARF) +HANDLE_DW_OP(0x35, lit5, 2, DWARF) +HANDLE_DW_OP(0x36, lit6, 2, DWARF) +HANDLE_DW_OP(0x37, lit7, 2, DWARF) +HANDLE_DW_OP(0x38, lit8, 2, DWARF) +HANDLE_DW_OP(0x39, lit9, 2, DWARF) +HANDLE_DW_OP(0x3a, lit10, 2, DWARF) +HANDLE_DW_OP(0x3b, lit11, 2, DWARF) +HANDLE_DW_OP(0x3c, lit12, 2, DWARF) +HANDLE_DW_OP(0x3d, lit13, 2, DWARF) +HANDLE_DW_OP(0x3e, lit14, 2, DWARF) +HANDLE_DW_OP(0x3f, lit15, 2, DWARF) +HANDLE_DW_OP(0x40, lit16, 2, DWARF) +HANDLE_DW_OP(0x41, lit17, 2, DWARF) +HANDLE_DW_OP(0x42, lit18, 2, DWARF) +HANDLE_DW_OP(0x43, lit19, 2, DWARF) +HANDLE_DW_OP(0x44, lit20, 2, DWARF) +HANDLE_DW_OP(0x45, lit21, 2, DWARF) +HANDLE_DW_OP(0x46, lit22, 2, DWARF) +HANDLE_DW_OP(0x47, lit23, 2, DWARF) +HANDLE_DW_OP(0x48, lit24, 2, DWARF) +HANDLE_DW_OP(0x49, lit25, 2, DWARF) +HANDLE_DW_OP(0x4a, lit26, 2, DWARF) +HANDLE_DW_OP(0x4b, lit27, 2, DWARF) +HANDLE_DW_OP(0x4c, lit28, 2, DWARF) +HANDLE_DW_OP(0x4d, lit29, 2, DWARF) +HANDLE_DW_OP(0x4e, lit30, 2, DWARF) +HANDLE_DW_OP(0x4f, lit31, 2, DWARF) +HANDLE_DW_OP(0x50, reg0, 2, DWARF) +HANDLE_DW_OP(0x51, reg1, 2, DWARF) +HANDLE_DW_OP(0x52, reg2, 2, DWARF) +HANDLE_DW_OP(0x53, reg3, 2, DWARF) +HANDLE_DW_OP(0x54, reg4, 2, DWARF) +HANDLE_DW_OP(0x55, reg5, 2, DWARF) +HANDLE_DW_OP(0x56, reg6, 2, DWARF) +HANDLE_DW_OP(0x57, reg7, 2, DWARF) +HANDLE_DW_OP(0x58, reg8, 2, DWARF) +HANDLE_DW_OP(0x59, reg9, 2, DWARF) +HANDLE_DW_OP(0x5a, reg10, 2, DWARF) +HANDLE_DW_OP(0x5b, reg11, 2, DWARF) +HANDLE_DW_OP(0x5c, reg12, 2, DWARF) +HANDLE_DW_OP(0x5d, reg13, 2, DWARF) +HANDLE_DW_OP(0x5e, reg14, 2, DWARF) +HANDLE_DW_OP(0x5f, reg15, 2, DWARF) +HANDLE_DW_OP(0x60, reg16, 2, DWARF) +HANDLE_DW_OP(0x61, reg17, 2, DWARF) +HANDLE_DW_OP(0x62, reg18, 2, DWARF) +HANDLE_DW_OP(0x63, reg19, 2, DWARF) +HANDLE_DW_OP(0x64, reg20, 2, DWARF) +HANDLE_DW_OP(0x65, reg21, 2, DWARF) +HANDLE_DW_OP(0x66, reg22, 2, DWARF) +HANDLE_DW_OP(0x67, reg23, 2, DWARF) +HANDLE_DW_OP(0x68, reg24, 2, DWARF) +HANDLE_DW_OP(0x69, reg25, 2, DWARF) +HANDLE_DW_OP(0x6a, reg26, 2, DWARF) +HANDLE_DW_OP(0x6b, reg27, 2, DWARF) +HANDLE_DW_OP(0x6c, reg28, 2, DWARF) +HANDLE_DW_OP(0x6d, reg29, 2, DWARF) +HANDLE_DW_OP(0x6e, reg30, 2, DWARF) +HANDLE_DW_OP(0x6f, reg31, 2, DWARF) +HANDLE_DW_OP(0x70, breg0, 2, DWARF) +HANDLE_DW_OP(0x71, breg1, 2, DWARF) +HANDLE_DW_OP(0x72, breg2, 2, DWARF) +HANDLE_DW_OP(0x73, breg3, 2, DWARF) +HANDLE_DW_OP(0x74, breg4, 2, DWARF) +HANDLE_DW_OP(0x75, breg5, 2, DWARF) +HANDLE_DW_OP(0x76, breg6, 2, DWARF) +HANDLE_DW_OP(0x77, breg7, 2, DWARF) +HANDLE_DW_OP(0x78, breg8, 2, DWARF) +HANDLE_DW_OP(0x79, breg9, 2, DWARF) +HANDLE_DW_OP(0x7a, breg10, 2, DWARF) +HANDLE_DW_OP(0x7b, breg11, 2, DWARF) +HANDLE_DW_OP(0x7c, breg12, 2, DWARF) +HANDLE_DW_OP(0x7d, breg13, 2, DWARF) +HANDLE_DW_OP(0x7e, breg14, 2, DWARF) +HANDLE_DW_OP(0x7f, breg15, 2, DWARF) +HANDLE_DW_OP(0x80, breg16, 2, DWARF) +HANDLE_DW_OP(0x81, breg17, 2, DWARF) +HANDLE_DW_OP(0x82, breg18, 2, DWARF) +HANDLE_DW_OP(0x83, breg19, 2, DWARF) +HANDLE_DW_OP(0x84, breg20, 2, DWARF) +HANDLE_DW_OP(0x85, breg21, 2, DWARF) +HANDLE_DW_OP(0x86, breg22, 2, DWARF) +HANDLE_DW_OP(0x87, breg23, 2, DWARF) +HANDLE_DW_OP(0x88, breg24, 2, DWARF) +HANDLE_DW_OP(0x89, breg25, 2, DWARF) +HANDLE_DW_OP(0x8a, breg26, 2, DWARF) +HANDLE_DW_OP(0x8b, breg27, 2, DWARF) +HANDLE_DW_OP(0x8c, breg28, 2, DWARF) +HANDLE_DW_OP(0x8d, breg29, 2, DWARF) +HANDLE_DW_OP(0x8e, breg30, 2, DWARF) +HANDLE_DW_OP(0x8f, breg31, 2, DWARF) +HANDLE_DW_OP(0x90, regx, 2, DWARF) +HANDLE_DW_OP(0x91, fbreg, 2, DWARF) +HANDLE_DW_OP(0x92, bregx, 2, DWARF) +HANDLE_DW_OP(0x93, piece, 2, DWARF) +HANDLE_DW_OP(0x94, deref_size, 2, DWARF) +HANDLE_DW_OP(0x95, xderef_size, 2, DWARF) +HANDLE_DW_OP(0x96, nop, 2, DWARF) // New in DWARF v3: -HANDLE_DW_OP(0x97, push_object_address) -HANDLE_DW_OP(0x98, call2) -HANDLE_DW_OP(0x99, call4) -HANDLE_DW_OP(0x9a, call_ref) -HANDLE_DW_OP(0x9b, form_tls_address) -HANDLE_DW_OP(0x9c, call_frame_cfa) -HANDLE_DW_OP(0x9d, bit_piece) +HANDLE_DW_OP(0x97, push_object_address, 3, DWARF) +HANDLE_DW_OP(0x98, call2, 3, DWARF) +HANDLE_DW_OP(0x99, call4, 3, DWARF) +HANDLE_DW_OP(0x9a, call_ref, 3, DWARF) +HANDLE_DW_OP(0x9b, form_tls_address, 3, DWARF) +HANDLE_DW_OP(0x9c, call_frame_cfa, 3, DWARF) +HANDLE_DW_OP(0x9d, bit_piece, 3, DWARF) // New in DWARF v4: -HANDLE_DW_OP(0x9e, implicit_value) -HANDLE_DW_OP(0x9f, stack_value) +HANDLE_DW_OP(0x9e, implicit_value, 4, DWARF) +HANDLE_DW_OP(0x9f, stack_value, 4, DWARF) // New in DWARF v5: -HANDLE_DW_OP(0xa0, implicit_pointer) -HANDLE_DW_OP(0xa1, addrx) -HANDLE_DW_OP(0xa2, constx) -HANDLE_DW_OP(0xa3, entry_value) -HANDLE_DW_OP(0xa4, const_type) -HANDLE_DW_OP(0xa5, regval_type) -HANDLE_DW_OP(0xa6, deref_type) -HANDLE_DW_OP(0xa7, xderef_type) -HANDLE_DW_OP(0xa8, convert) -HANDLE_DW_OP(0xa9, reinterpret) +HANDLE_DW_OP(0xa0, implicit_pointer, 5, DWARF) +HANDLE_DW_OP(0xa1, addrx, 5, DWARF) +HANDLE_DW_OP(0xa2, constx, 5, DWARF) +HANDLE_DW_OP(0xa3, entry_value, 5, DWARF) +HANDLE_DW_OP(0xa4, const_type, 5, DWARF) +HANDLE_DW_OP(0xa5, regval_type, 5, DWARF) +HANDLE_DW_OP(0xa6, deref_type, 5, DWARF) +HANDLE_DW_OP(0xa7, xderef_type, 5, DWARF) +HANDLE_DW_OP(0xa8, convert, 5, DWARF) +HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF) // Vendor extensions: // Extensions for GNU-style thread-local storage. -HANDLE_DW_OP(0xe0, GNU_push_tls_address) +HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU) // Extensions for Fission proposal. -HANDLE_DW_OP(0xfb, GNU_addr_index) -HANDLE_DW_OP(0xfc, GNU_const_index) +HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU) +HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU) // DWARF languages. -HANDLE_DW_LANG(0x0001, C89) -HANDLE_DW_LANG(0x0002, C) -HANDLE_DW_LANG(0x0003, Ada83) -HANDLE_DW_LANG(0x0004, C_plus_plus) -HANDLE_DW_LANG(0x0005, Cobol74) -HANDLE_DW_LANG(0x0006, Cobol85) -HANDLE_DW_LANG(0x0007, Fortran77) -HANDLE_DW_LANG(0x0008, Fortran90) -HANDLE_DW_LANG(0x0009, Pascal83) -HANDLE_DW_LANG(0x000a, Modula2) +HANDLE_DW_LANG(0x0001, C89, 2, DWARF) +HANDLE_DW_LANG(0x0002, C, 2, DWARF) +HANDLE_DW_LANG(0x0003, Ada83, 2, DWARF) +HANDLE_DW_LANG(0x0004, C_plus_plus, 2, DWARF) +HANDLE_DW_LANG(0x0005, Cobol74, 2, DWARF) +HANDLE_DW_LANG(0x0006, Cobol85, 2, DWARF) +HANDLE_DW_LANG(0x0007, Fortran77, 2, DWARF) +HANDLE_DW_LANG(0x0008, Fortran90, 2, DWARF) +HANDLE_DW_LANG(0x0009, Pascal83, 2, DWARF) +HANDLE_DW_LANG(0x000a, Modula2, 2, DWARF) // New in DWARF v3: -HANDLE_DW_LANG(0x000b, Java) -HANDLE_DW_LANG(0x000c, C99) -HANDLE_DW_LANG(0x000d, Ada95) -HANDLE_DW_LANG(0x000e, Fortran95) -HANDLE_DW_LANG(0x000f, PLI) -HANDLE_DW_LANG(0x0010, ObjC) -HANDLE_DW_LANG(0x0011, ObjC_plus_plus) -HANDLE_DW_LANG(0x0012, UPC) -HANDLE_DW_LANG(0x0013, D) +HANDLE_DW_LANG(0x000b, Java, 3, DWARF) +HANDLE_DW_LANG(0x000c, C99, 3, DWARF) +HANDLE_DW_LANG(0x000d, Ada95, 3, DWARF) +HANDLE_DW_LANG(0x000e, Fortran95, 3, DWARF) +HANDLE_DW_LANG(0x000f, PLI, 3, DWARF) +HANDLE_DW_LANG(0x0010, ObjC, 3, DWARF) +HANDLE_DW_LANG(0x0011, ObjC_plus_plus, 3, DWARF) +HANDLE_DW_LANG(0x0012, UPC, 3, DWARF) +HANDLE_DW_LANG(0x0013, D, 3, DWARF) // New in DWARF v4: -HANDLE_DW_LANG(0x0014, Python) +HANDLE_DW_LANG(0x0014, Python, 4, DWARF) // New in DWARF v5: -HANDLE_DW_LANG(0x0015, OpenCL) -HANDLE_DW_LANG(0x0016, Go) -HANDLE_DW_LANG(0x0017, Modula3) -HANDLE_DW_LANG(0x0018, Haskell) -HANDLE_DW_LANG(0x0019, C_plus_plus_03) -HANDLE_DW_LANG(0x001a, C_plus_plus_11) -HANDLE_DW_LANG(0x001b, OCaml) -HANDLE_DW_LANG(0x001c, Rust) -HANDLE_DW_LANG(0x001d, C11) -HANDLE_DW_LANG(0x001e, Swift) -HANDLE_DW_LANG(0x001f, Julia) -HANDLE_DW_LANG(0x0020, Dylan) -HANDLE_DW_LANG(0x0021, C_plus_plus_14) -HANDLE_DW_LANG(0x0022, Fortran03) -HANDLE_DW_LANG(0x0023, Fortran08) -HANDLE_DW_LANG(0x0024, RenderScript) -HANDLE_DW_LANG(0x0025, BLISS) +HANDLE_DW_LANG(0x0015, OpenCL, 5, DWARF) +HANDLE_DW_LANG(0x0016, Go, 5, DWARF) +HANDLE_DW_LANG(0x0017, Modula3, 5, DWARF) +HANDLE_DW_LANG(0x0018, Haskell, 5, DWARF) +HANDLE_DW_LANG(0x0019, C_plus_plus_03, 5, DWARF) +HANDLE_DW_LANG(0x001a, C_plus_plus_11, 5, DWARF) +HANDLE_DW_LANG(0x001b, OCaml, 5, DWARF) +HANDLE_DW_LANG(0x001c, Rust, 5, DWARF) +HANDLE_DW_LANG(0x001d, C11, 5, DWARF) +HANDLE_DW_LANG(0x001e, Swift, 5, DWARF) +HANDLE_DW_LANG(0x001f, Julia, 5, DWARF) +HANDLE_DW_LANG(0x0020, Dylan, 5, DWARF) +HANDLE_DW_LANG(0x0021, C_plus_plus_14, 5, DWARF) +HANDLE_DW_LANG(0x0022, Fortran03, 5, DWARF) +HANDLE_DW_LANG(0x0023, Fortran08, 5, DWARF) +HANDLE_DW_LANG(0x0024, RenderScript, 5, DWARF) +HANDLE_DW_LANG(0x0025, BLISS, 5, DWARF) // Vendor extensions: -HANDLE_DW_LANG(0x8001, Mips_Assembler) -HANDLE_DW_LANG(0x8e57, GOOGLE_RenderScript) -HANDLE_DW_LANG(0xb000, BORLAND_Delphi) +HANDLE_DW_LANG(0x8001, Mips_Assembler, 0, MIPS) +HANDLE_DW_LANG(0x8e57, GOOGLE_RenderScript, 0, GOOGLE) +HANDLE_DW_LANG(0xb000, BORLAND_Delphi, 0, BORLAND) // DWARF attribute type encodings. -HANDLE_DW_ATE(0x01, address) -HANDLE_DW_ATE(0x02, boolean) -HANDLE_DW_ATE(0x03, complex_float) -HANDLE_DW_ATE(0x04, float) -HANDLE_DW_ATE(0x05, signed) -HANDLE_DW_ATE(0x06, signed_char) -HANDLE_DW_ATE(0x07, unsigned) -HANDLE_DW_ATE(0x08, unsigned_char) +HANDLE_DW_ATE(0x01, address, 2, DWARF) +HANDLE_DW_ATE(0x02, boolean, 2, DWARF) +HANDLE_DW_ATE(0x03, complex_float, 2, DWARF) +HANDLE_DW_ATE(0x04, float, 2, DWARF) +HANDLE_DW_ATE(0x05, signed, 2, DWARF) +HANDLE_DW_ATE(0x06, signed_char, 2, DWARF) +HANDLE_DW_ATE(0x07, unsigned, 2, DWARF) +HANDLE_DW_ATE(0x08, unsigned_char, 2, DWARF) // New in DWARF v3: -HANDLE_DW_ATE(0x09, imaginary_float) -HANDLE_DW_ATE(0x0a, packed_decimal) -HANDLE_DW_ATE(0x0b, numeric_string) -HANDLE_DW_ATE(0x0c, edited) -HANDLE_DW_ATE(0x0d, signed_fixed) -HANDLE_DW_ATE(0x0e, unsigned_fixed) -HANDLE_DW_ATE(0x0f, decimal_float) +HANDLE_DW_ATE(0x09, imaginary_float, 3, DWARF) +HANDLE_DW_ATE(0x0a, packed_decimal, 3, DWARF) +HANDLE_DW_ATE(0x0b, numeric_string, 3, DWARF) +HANDLE_DW_ATE(0x0c, edited, 3, DWARF) +HANDLE_DW_ATE(0x0d, signed_fixed, 3, DWARF) +HANDLE_DW_ATE(0x0e, unsigned_fixed, 3, DWARF) +HANDLE_DW_ATE(0x0f, decimal_float, 3, DWARF) // New in DWARF v4: -HANDLE_DW_ATE(0x10, UTF) +HANDLE_DW_ATE(0x10, UTF, 4, DWARF) // New in DWARF v5: -HANDLE_DW_ATE(0x11, UCS) -HANDLE_DW_ATE(0x12, ASCII) +HANDLE_DW_ATE(0x11, UCS, 5, DWARF) +HANDLE_DW_ATE(0x12, ASCII, 5, DWARF) // DWARF virtuality codes. HANDLE_DW_VIRTUALITY(0x00, none) diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 84056682924eb..3061b7b5fa0f0 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -46,7 +46,15 @@ enum LLVMConstants : uint32_t { DWARF_VERSION = 4, // Default dwarf version we output. DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes. DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames. - DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges. + DW_ARANGES_VERSION = 2, // Section version number for .debug_aranges. + // Identifiers we use to distinguish vendor extensions. + DWARF_VENDOR_DWARF = 0, // Defined in v2 or later of the DWARF standard. + DWARF_VENDOR_APPLE = 1, + DWARF_VENDOR_BORLAND = 2, + DWARF_VENDOR_GNU = 3, + DWARF_VENDOR_GOOGLE = 4, + DWARF_VENDOR_LLVM = 5, + DWARF_VENDOR_MIPS = 6 }; // Special ID values that distinguish a CIE from a FDE in DWARF CFI. @@ -55,7 +63,7 @@ const uint32_t DW_CIE_ID = UINT32_MAX; const uint64_t DW64_CIE_ID = UINT64_MAX; enum Tag : uint16_t { -#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME = ID, +#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_TAG_lo_user = 0x4080, DW_TAG_hi_user = 0xffff, @@ -92,20 +100,20 @@ inline bool isType(Tag T) { /// Attributes. enum Attribute : uint16_t { -#define HANDLE_DW_AT(ID, NAME) DW_AT_##NAME = ID, +#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) DW_AT_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, }; enum Form : uint16_t { -#define HANDLE_DW_FORM(ID, NAME) DW_FORM_##NAME = ID, +#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) DW_FORM_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF. }; enum LocationAtom { -#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME = ID, +#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) DW_OP_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff, @@ -113,7 +121,7 @@ enum LocationAtom { }; enum TypeKind { -#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME = ID, +#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_ATE_lo_user = 0x80, DW_ATE_hi_user = 0xff @@ -164,7 +172,7 @@ enum DefaultedMemberAttribute { }; enum SourceLanguage { -#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME = ID, +#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) DW_LANG_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_LANG_lo_user = 0x8000, DW_LANG_hi_user = 0xffff @@ -220,8 +228,8 @@ enum LineNumberExtendedOps { DW_LNE_hi_user = 0xff }; -enum LinerNumberEntryFormat { -#define HANDLE_DW_LNCT(ID, NAME) DW_DEFAULTED_##NAME = ID, +enum LineNumberEntryFormat { +#define HANDLE_DW_LNCT(ID, NAME) DW_LNCT_##NAME = ID, #include "llvm/Support/Dwarf.def" DW_LNCT_lo_user = 0x2000, DW_LNCT_hi_user = 0x3fff, @@ -406,6 +414,40 @@ unsigned getAttributeEncoding(StringRef EncodingString); unsigned getMacinfo(StringRef MacinfoString); /// @} +/// \defgroup DwarfConstantsVersioning Dwarf version for constants +/// +/// For constants defined by DWARF, returns the DWARF version when the constant +/// was first defined. For vendor extensions, if there is a version-related +/// policy for when to emit it, returns a version number for that policy. +/// Otherwise returns 0. +/// +/// @{ +unsigned TagVersion(Tag T); +unsigned AttributeVersion(Attribute A); +unsigned FormVersion(Form F); +unsigned OperationVersion(LocationAtom O); +unsigned AttributeEncodingVersion(TypeKind E); +unsigned LanguageVersion(SourceLanguage L); +/// @} + +/// \defgroup DwarfConstantsVendor Dwarf "vendor" for constants +/// +/// These functions return an identifier describing "who" defined the constant, +/// either the DWARF standard itself or the vendor who defined the extension. +/// +/// @{ +unsigned TagVendor(Tag T); +unsigned AttributeVendor(Attribute A); +unsigned FormVendor(Form F); +unsigned OperationVendor(LocationAtom O); +unsigned AttributeEncodingVendor(TypeKind E); +unsigned LanguageVendor(SourceLanguage L); +/// @} + +/// Tells whether the specified form is defined in the specified version, +/// or is an extension if extensions are allowed. +bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true); + /// \brief Returns the symbolic string representing Val when used as a value /// for attribute Attr. StringRef AttributeValueString(uint16_t Attr, unsigned Val); diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index 20f3ffdf3aab7..eb7c27d2ffa5b 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -276,32 +276,25 @@ protected: // NewBB is split and now it has one successor. Update dominator tree to // reflect this change. - template <class N, class GraphT> - void Split(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef NewBB) { + template <class N> + void Split(typename GraphTraits<N>::NodeRef NewBB) { + using GraphT = GraphTraits<N>; + using NodeRef = typename GraphT::NodeRef; assert(std::distance(GraphT::child_begin(NewBB), GraphT::child_end(NewBB)) == 1 && "NewBB should have a single successor!"); - typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB); + NodeRef NewBBSucc = *GraphT::child_begin(NewBB); - std::vector<typename GraphT::NodeRef> PredBlocks; - typedef GraphTraits<Inverse<N>> InvTraits; - for (typename InvTraits::ChildIteratorType - PI = InvTraits::child_begin(NewBB), - PE = InvTraits::child_end(NewBB); - PI != PE; ++PI) - PredBlocks.push_back(*PI); + std::vector<NodeRef> PredBlocks; + for (const auto Pred : children<Inverse<N>>(NewBB)) + PredBlocks.push_back(Pred); assert(!PredBlocks.empty() && "No predblocks?"); bool NewBBDominatesNewBBSucc = true; - for (typename InvTraits::ChildIteratorType - PI = InvTraits::child_begin(NewBBSucc), - E = InvTraits::child_end(NewBBSucc); - PI != E; ++PI) { - typename InvTraits::NodeRef ND = *PI; - if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && - DT.isReachableFromEntry(ND)) { + for (const auto Pred : children<Inverse<N>>(NewBBSucc)) { + if (Pred != NewBB && !dominates(NewBBSucc, Pred) && + isReachableFromEntry(Pred)) { NewBBDominatesNewBBSucc = false; break; } @@ -312,7 +305,7 @@ protected: NodeT *NewBBIDom = nullptr; unsigned i = 0; for (i = 0; i < PredBlocks.size(); ++i) - if (DT.isReachableFromEntry(PredBlocks[i])) { + if (isReachableFromEntry(PredBlocks[i])) { NewBBIDom = PredBlocks[i]; break; } @@ -324,18 +317,18 @@ protected: return; for (i = i + 1; i < PredBlocks.size(); ++i) { - if (DT.isReachableFromEntry(PredBlocks[i])) - NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]); + if (isReachableFromEntry(PredBlocks[i])) + NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]); } // Create the new dominator tree node... and set the idom of NewBB. - DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); + DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom); // If NewBB strictly dominates other blocks, then it is now the immediate // dominator of NewBBSucc. Update the dominator tree as appropriate. if (NewBBDominatesNewBBSucc) { - DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc); - DT.changeImmediateDominator(NewBBSuccNode, NewBBNode); + DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc); + changeImmediateDominator(NewBBSuccNode, NewBBNode); } } @@ -379,7 +372,7 @@ public: if (DomTreeNodes.size() != OtherDomTreeNodes.size()) return true; - for (const auto &DomTreeNode : this->DomTreeNodes) { + for (const auto &DomTreeNode : DomTreeNodes) { NodeT *BB = DomTreeNode.first; typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB); @@ -663,10 +656,9 @@ public: /// tree to reflect this change. void splitBlock(NodeT *NewBB) { if (this->IsPostDominators) - this->Split<Inverse<NodeT *>, GraphTraits<Inverse<NodeT *>>>(*this, - NewBB); + Split<Inverse<NodeT *>>(NewBB); else - this->Split<NodeT *, GraphTraits<NodeT *>>(*this, NewBB); + Split<NodeT *>(NewBB); } /// print - Convert to human readable form @@ -677,7 +669,7 @@ public: o << "Inorder PostDominator Tree: "; else o << "Inorder Dominator Tree: "; - if (!this->DFSInfoValid) + if (!DFSInfoValid) o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; o << "\n"; @@ -712,12 +704,12 @@ protected: // immediate dominator. NodeT *IDom = getIDom(BB); - assert(IDom || this->DomTreeNodes[nullptr]); + assert(IDom || DomTreeNodes[nullptr]); DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom); // Add a new tree node for this NodeT, and link it as a child of // IDomNode - return (this->DomTreeNodes[BB] = IDomNode->addChild( + return (DomTreeNodes[BB] = IDomNode->addChild( llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get(); } @@ -780,7 +772,7 @@ public: template <class FT> void recalculate(FT &F) { typedef GraphTraits<FT *> TraitsTy; reset(); - this->Vertex.push_back(nullptr); + Vertex.push_back(nullptr); if (!this->IsPostDominators) { // Initialize root diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 7555d5b31a8d6..c318fea536511 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -143,10 +143,9 @@ public: void writeNodes() { // Loop over the graph, printing it out... - for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G); - I != E; ++I) - if (!isNodeHidden(*I)) - writeNode(*I); + for (const auto Node : nodes<GraphType>(G)) + if (!isNodeHidden(Node)) + writeNode(Node); } bool isNodeHidden(NodeRef Node) { diff --git a/include/llvm/Support/LowLevelTypeImpl.h b/include/llvm/Support/LowLevelTypeImpl.h index 02df4d806f13b..e18e58b7b5b23 100644 --- a/include/llvm/Support/LowLevelTypeImpl.h +++ b/include/llvm/Support/LowLevelTypeImpl.h @@ -39,100 +39,123 @@ class raw_ostream; class LLT { public: - enum TypeKind : uint16_t { - Invalid, - Scalar, - Pointer, - Vector, - }; - /// Get a low-level scalar or aggregate "bag of bits". static LLT scalar(unsigned SizeInBits) { assert(SizeInBits > 0 && "invalid scalar size"); - return LLT{Scalar, 1, SizeInBits}; + return LLT{/*isPointer=*/false, /*isVector=*/false, /*NumElements=*/0, + SizeInBits, /*AddressSpace=*/0}; } /// Get a low-level pointer in the given address space (defaulting to 0). static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits) { - return LLT{Pointer, AddressSpace, SizeInBits}; + assert(SizeInBits > 0 && "invalid pointer size"); + return LLT{/*isPointer=*/true, /*isVector=*/false, /*NumElements=*/0, + SizeInBits, AddressSpace}; } /// Get a low-level vector of some number of elements and element width. /// \p NumElements must be at least 2. static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) { assert(NumElements > 1 && "invalid number of vector elements"); - return LLT{Vector, NumElements, ScalarSizeInBits}; + assert(ScalarSizeInBits > 0 && "invalid vector element size"); + return LLT{/*isPointer=*/false, /*isVector=*/true, NumElements, + ScalarSizeInBits, /*AddressSpace=*/0}; } /// Get a low-level vector of some number of elements and element type. static LLT vector(uint16_t NumElements, LLT ScalarTy) { assert(NumElements > 1 && "invalid number of vector elements"); - assert(ScalarTy.isScalar() && "invalid vector element type"); - return LLT{Vector, NumElements, ScalarTy.getSizeInBits()}; + assert(!ScalarTy.isVector() && "invalid vector element type"); + return LLT{ScalarTy.isPointer(), /*isVector=*/true, NumElements, + ScalarTy.getSizeInBits(), + ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0}; } - explicit LLT(TypeKind Kind, uint16_t NumElements, unsigned SizeInBits) - : SizeInBits(SizeInBits), ElementsOrAddrSpace(NumElements), Kind(Kind) { - assert((Kind != Vector || ElementsOrAddrSpace > 1) && - "invalid number of vector elements"); + explicit LLT(bool isPointer, bool isVector, uint16_t NumElements, + unsigned SizeInBits, unsigned AddressSpace) { + init(isPointer, isVector, NumElements, SizeInBits, AddressSpace); } - - explicit LLT() : SizeInBits(0), ElementsOrAddrSpace(0), Kind(Invalid) {} + explicit LLT() : IsPointer(false), IsVector(false), RawData(0) {} explicit LLT(MVT VT); - bool isValid() const { return Kind != Invalid; } + bool isValid() const { return RawData != 0; } - bool isScalar() const { return Kind == Scalar; } + bool isScalar() const { return isValid() && !IsPointer && !IsVector; } - bool isPointer() const { return Kind == Pointer; } + bool isPointer() const { return isValid() && IsPointer && !IsVector; } - bool isVector() const { return Kind == Vector; } + bool isVector() const { return isValid() && IsVector; } /// Returns the number of elements in a vector LLT. Must only be called on /// vector types. uint16_t getNumElements() const { - assert(isVector() && "cannot get number of elements on scalar/aggregate"); - return ElementsOrAddrSpace; + assert(IsVector && "cannot get number of elements on scalar/aggregate"); + if (!IsPointer) + return getFieldValue(VectorElementsFieldInfo); + else + return getFieldValue(PointerVectorElementsFieldInfo); } /// Returns the total size of the type. Must only be called on sized types. unsigned getSizeInBits() const { if (isPointer() || isScalar()) - return SizeInBits; - return SizeInBits * ElementsOrAddrSpace; + return getScalarSizeInBits(); + return getScalarSizeInBits() * getNumElements(); } unsigned getScalarSizeInBits() const { - return SizeInBits; + assert(RawData != 0 && "Invalid Type"); + if (!IsVector) { + if (!IsPointer) + return getFieldValue(ScalarSizeFieldInfo); + else + return getFieldValue(PointerSizeFieldInfo); + } else { + if (!IsPointer) + return getFieldValue(VectorSizeFieldInfo); + else + return getFieldValue(PointerVectorSizeFieldInfo); + } } unsigned getAddressSpace() const { - assert(isPointer() && "cannot get address space of non-pointer type"); - return ElementsOrAddrSpace; + assert(RawData != 0 && "Invalid Type"); + assert(IsPointer && "cannot get address space of non-pointer type"); + if (!IsVector) + return getFieldValue(PointerAddressSpaceFieldInfo); + else + return getFieldValue(PointerVectorAddressSpaceFieldInfo); } /// Returns the vector's element type. Only valid for vector types. LLT getElementType() const { assert(isVector() && "cannot get element type of scalar/aggregate"); - return scalar(SizeInBits); + if (IsPointer) + return pointer(getAddressSpace(), getScalarSizeInBits()); + else + return scalar(getScalarSizeInBits()); } /// Get a low-level type with half the size of the original, by halving the /// size of the scalar type involved. For example `s32` will become `s16`, /// `<2 x s32>` will become `<2 x s16>`. LLT halfScalarSize() const { - assert(!isPointer() && getScalarSizeInBits() > 1 && + assert(!IsPointer && getScalarSizeInBits() > 1 && getScalarSizeInBits() % 2 == 0 && "cannot half size of this type"); - return LLT{Kind, ElementsOrAddrSpace, SizeInBits / 2}; + return LLT{/*isPointer=*/false, IsVector ? true : false, + IsVector ? getNumElements() : (uint16_t)0, + getScalarSizeInBits() / 2, /*AddressSpace=*/0}; } /// Get a low-level type with twice the size of the original, by doubling the /// size of the scalar type involved. For example `s32` will become `s64`, /// `<2 x s32>` will become `<2 x s64>`. LLT doubleScalarSize() const { - assert(!isPointer() && "cannot change size of this type"); - return LLT{Kind, ElementsOrAddrSpace, SizeInBits * 2}; + assert(!IsPointer && "cannot change size of this type"); + return LLT{/*isPointer=*/false, IsVector ? true : false, + IsVector ? getNumElements() : (uint16_t)0, + getScalarSizeInBits() * 2, /*AddressSpace=*/0}; } /// Get a low-level type with half the size of the original, by halving the @@ -140,13 +163,13 @@ public: /// a vector type with an even number of elements. For example `<4 x s32>` /// will become `<2 x s32>`, `<2 x s32>` will become `s32`. LLT halfElements() const { - assert(isVector() && ElementsOrAddrSpace % 2 == 0 && - "cannot half odd vector"); - if (ElementsOrAddrSpace == 2) - return scalar(SizeInBits); + assert(isVector() && getNumElements() % 2 == 0 && "cannot half odd vector"); + if (getNumElements() == 2) + return scalar(getScalarSizeInBits()); - return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace / 2), - SizeInBits}; + return LLT{/*isPointer=*/false, /*isVector=*/true, + (uint16_t)(getNumElements() / 2), getScalarSizeInBits(), + /*AddressSpace=*/0}; } /// Get a low-level type with twice the size of the original, by doubling the @@ -154,25 +177,105 @@ public: /// a vector type. For example `<2 x s32>` will become `<4 x s32>`. Doubling /// the number of elements in sN produces <2 x sN>. LLT doubleElements() const { - assert(!isPointer() && "cannot double elements in pointer"); - return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace * 2), - SizeInBits}; + return LLT{IsPointer ? true : false, /*isVector=*/true, + (uint16_t)(getNumElements() * 2), getScalarSizeInBits(), + IsPointer ? getAddressSpace() : 0}; } void print(raw_ostream &OS) const; bool operator==(const LLT &RHS) const { - return Kind == RHS.Kind && SizeInBits == RHS.SizeInBits && - ElementsOrAddrSpace == RHS.ElementsOrAddrSpace; + return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector && + RHS.RawData == RawData; } bool operator!=(const LLT &RHS) const { return !(*this == RHS); } friend struct DenseMapInfo<LLT>; + private: - unsigned SizeInBits; - uint16_t ElementsOrAddrSpace; - TypeKind Kind; + /// LLT is packed into 64 bits as follows: + /// isPointer : 1 + /// isVector : 1 + /// with 62 bits remaining for Kind-specific data, packed in bitfields + /// as described below. As there isn't a simple portable way to pack bits + /// into bitfields, here the different fields in the packed structure is + /// described in static const *Field variables. Each of these variables + /// is a 2-element array, with the first element describing the bitfield size + /// and the second element describing the bitfield offset. + typedef int BitFieldInfo[2]; + /// + /// This is how the bitfields are packed per Kind: + /// * Invalid: + /// gets encoded as RawData == 0, as that is an invalid encoding, since for + /// valid encodings, SizeInBits/SizeOfElement must be larger than 0. + /// * Non-pointer scalar (isPointer == 0 && isVector == 0): + /// SizeInBits: 32; + static const constexpr BitFieldInfo ScalarSizeFieldInfo{32, 0}; + /// * Pointer (isPointer == 1 && isVector == 0): + /// SizeInBits: 16; + /// AddressSpace: 23; + static const constexpr BitFieldInfo PointerSizeFieldInfo{16, 0}; + static const constexpr BitFieldInfo PointerAddressSpaceFieldInfo{ + 23, PointerSizeFieldInfo[0] + PointerSizeFieldInfo[1]}; + /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1): + /// NumElements: 16; + /// SizeOfElement: 32; + static const constexpr BitFieldInfo VectorElementsFieldInfo{16, 0}; + static const constexpr BitFieldInfo VectorSizeFieldInfo{ + 32, VectorElementsFieldInfo[0] + VectorElementsFieldInfo[1]}; + /// * Vector-of-pointer (isPointer == 1 && isVector == 1): + /// NumElements: 16; + /// SizeOfElement: 16; + /// AddressSpace: 23; + static const constexpr BitFieldInfo PointerVectorElementsFieldInfo{16, 0}; + static const constexpr BitFieldInfo PointerVectorSizeFieldInfo{ + 16, + PointerVectorElementsFieldInfo[1] + PointerVectorElementsFieldInfo[0]}; + static const constexpr BitFieldInfo PointerVectorAddressSpaceFieldInfo{ + 23, PointerVectorSizeFieldInfo[1] + PointerVectorSizeFieldInfo[0]}; + + uint64_t IsPointer : 1; + uint64_t IsVector : 1; + uint64_t RawData : 62; + + static uint64_t getMask(const BitFieldInfo FieldInfo) { + const int FieldSizeInBits = FieldInfo[0]; + return (((uint64_t)1) << FieldSizeInBits) - 1; + } + static uint64_t maskAndShift(uint64_t Val, uint64_t Mask, uint8_t Shift) { + assert(Val <= Mask && "Value too large for field"); + return (Val & Mask) << Shift; + } + static uint64_t maskAndShift(uint64_t Val, const BitFieldInfo FieldInfo) { + return maskAndShift(Val, getMask(FieldInfo), FieldInfo[1]); + } + uint64_t getFieldValue(const BitFieldInfo FieldInfo) const { + return getMask(FieldInfo) & (RawData >> FieldInfo[1]); + } + + void init(bool IsPointer, bool IsVector, uint16_t NumElements, + unsigned SizeInBits, unsigned AddressSpace) { + this->IsPointer = IsPointer; + this->IsVector = IsVector; + if (!IsVector) { + if (!IsPointer) + RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo); + else + RawData = maskAndShift(SizeInBits, PointerSizeFieldInfo) | + maskAndShift(AddressSpace, PointerAddressSpaceFieldInfo); + } else { + assert(NumElements > 1 && "invalid number of vector elements"); + if (!IsPointer) + RawData = maskAndShift(NumElements, VectorElementsFieldInfo) | + maskAndShift(SizeInBits, VectorSizeFieldInfo); + else + RawData = + maskAndShift(NumElements, PointerVectorElementsFieldInfo) | + maskAndShift(SizeInBits, PointerVectorSizeFieldInfo) | + maskAndShift(AddressSpace, PointerVectorAddressSpaceFieldInfo); + } + } }; inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) { @@ -182,14 +285,18 @@ inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) { template<> struct DenseMapInfo<LLT> { static inline LLT getEmptyKey() { - return LLT{LLT::Invalid, 0, -1u}; + LLT Invalid; + Invalid.IsPointer = true; + return Invalid; } static inline LLT getTombstoneKey() { - return LLT{LLT::Invalid, 0, -2u}; + LLT Invalid; + Invalid.IsVector = true; + return Invalid; } static inline unsigned getHashValue(const LLT &Ty) { - uint64_t Val = ((uint64_t)Ty.SizeInBits << 32) | - ((uint64_t)Ty.ElementsOrAddrSpace << 16) | (uint64_t)Ty.Kind; + uint64_t Val = ((uint64_t)Ty.RawData) << 2 | ((uint64_t)Ty.IsPointer) << 1 | + ((uint64_t)Ty.IsVector); return DenseMapInfo<uint64_t>::getHashValue(Val); } static bool isEqual(const LLT &LHS, const LLT &RHS) { diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 19380b23d9d24..994456f9a6819 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -18,6 +18,7 @@ #include "llvm/Support/SwapByteOrder.h" #include <algorithm> #include <cassert> +#include <climits> #include <cstring> #include <type_traits> #include <limits> @@ -198,6 +199,21 @@ template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { return countTrailingZeros(Val, ZB_Undefined); } +/// \brief Create a bitmask with the N right-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template <typename T> T maskTrailingOnes(unsigned N) { + static_assert(std::is_unsigned<T>::value, "Invalid type!"); + const unsigned Bits = CHAR_BIT * sizeof(T); + assert(N <= Bits && "Invalid bit index"); + return N == 0 ? 0 : (T(-1) >> (Bits - N)); +} + +/// \brief Create a bitmask with the N left-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template <typename T> T maskLeadingOnes(unsigned N) { + return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); +} + /// \brief Get the index of the last set bit starting from the least /// significant bit. /// diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h index 1523aad38d46f..53db2e86d12d3 100644 --- a/include/llvm/Support/Recycler.h +++ b/include/llvm/Support/Recycler.h @@ -42,13 +42,16 @@ class Recycler { FreeNode *pop_val() { auto *Val = FreeList; + __asan_unpoison_memory_region(Val, Size); FreeList = FreeList->Next; + __msan_allocated_memory(Val, Size); return Val; } void push(FreeNode *N) { N->Next = FreeList; FreeList = N; + __asan_poison_memory_region(N, Size); } public: diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 83db80359ee21..f498835bcb582 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -57,7 +57,7 @@ namespace llvm { /// isValid - returns the error encountered during regex compilation, or /// matching, if any. - bool isValid(std::string &Error); + bool isValid(std::string &Error) const; /// getNumMatches - In a valid regex, return the number of parenthesized /// matches it contains. The number filled in by match will include this diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h index 68e6b27658102..f29cc40ffdd55 100644 --- a/include/llvm/Support/TargetParser.h +++ b/include/llvm/Support/TargetParser.h @@ -75,7 +75,7 @@ enum ArchExtKind : unsigned { AEK_CRC = 0x2, AEK_CRYPTO = 0x4, AEK_FP = 0x8, - AEK_HWDIV = 0x10, + AEK_HWDIVTHUMB = 0x10, AEK_HWDIVARM = 0x20, AEK_MP = 0x40, AEK_SIMD = 0x80, diff --git a/include/llvm/TableGen/StringToOffsetTable.h b/include/llvm/TableGen/StringToOffsetTable.h index aaf2a356ffab6..4b11e889ea6c7 100644 --- a/include/llvm/TableGen/StringToOffsetTable.h +++ b/include/llvm/TableGen/StringToOffsetTable.h @@ -27,6 +27,8 @@ class StringToOffsetTable { std::string AggregateString; public: + bool Empty() const { return StringOffset.empty(); } + unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) { auto IterBool = StringOffset.insert(std::make_pair(Str, AggregateString.size())); diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 85297ae837c56..24039ea10816e 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -230,6 +230,12 @@ public: return MVT::getIntegerVT(DL.getPointerSizeInBits(AS)); } + /// Return the type for frame index, which is determined by + /// the alloca address space specified through the data layout. + MVT getFrameIndexTy(const DataLayout &DL) const { + return getPointerTy(DL, DL.getAllocaAddrSpace()); + } + /// EVT is not used in-tree, but is used by out-of-tree target. /// A documentation for this function would be nice... virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const; @@ -2807,7 +2813,7 @@ public: /// Return true if the target may be able emit the call instruction as a tail /// call. This is used by optimization passes to determine if it's profitable /// to duplicate return instructions to enable tailcall optimization. - virtual bool mayBeEmittedAsTailCall(CallInst *) const { + virtual bool mayBeEmittedAsTailCall(const CallInst *) const { return false; } diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h index a2978663a4d14..a602498e5f221 100644 --- a/include/llvm/Transforms/Utils/CodeExtractor.h +++ b/include/llvm/Transforms/Utils/CodeExtractor.h @@ -65,14 +65,6 @@ template <typename T> class ArrayRef; /// Blocks containing EHPads, allocas, invokes, or vastarts are not valid. static bool isBlockValidForExtraction(const BasicBlock &BB); - /// \brief Create a code extractor for a single basic block. - /// - /// In this formation, we don't require a dominator tree. The given basic - /// block is set up for extraction. - CodeExtractor(BasicBlock *BB, bool AggregateArgs = false, - BlockFrequencyInfo *BFI = nullptr, - BranchProbabilityInfo *BPI = nullptr); - /// \brief Create a code extractor for a sequence of blocks. /// /// Given a sequence of basic blocks where the first block in the sequence @@ -91,14 +83,6 @@ template <typename T> class ArrayRef; BlockFrequencyInfo *BFI = nullptr, BranchProbabilityInfo *BPI = nullptr); - /// \brief Create a code extractor for a region node. - /// - /// Behaves just like the generic code sequence constructor, but uses the - /// block sequence of the region node passed in. - CodeExtractor(DominatorTree &DT, const RegionNode &RN, - bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr, - BranchProbabilityInfo *BPI = nullptr); - /// \brief Perform the extraction, returning the new function. /// /// Returns zero when called on a CodeExtractor instance where isEligible diff --git a/include/llvm/XRay/InstrumentationMap.h b/include/llvm/XRay/InstrumentationMap.h index f7286c52ff42e..0342da0a2f0fa 100644 --- a/include/llvm/XRay/InstrumentationMap.h +++ b/include/llvm/XRay/InstrumentationMap.h @@ -59,6 +59,7 @@ struct YAMLXRaySledEntry { yaml::Hex64 Function; SledEntry::FunctionKinds Kind; bool AlwaysInstrument; + std::string FunctionName; }; /// The InstrumentationMap represents the computed function id's and indicated @@ -115,6 +116,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> { IO.mapRequired("function", Entry.Function); IO.mapRequired("kind", Entry.Kind); IO.mapRequired("always-instrument", Entry.AlwaysInstrument); + IO.mapOptional("function-name", Entry.FunctionName); } static constexpr bool flow = true; |