summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APInt.h201
-rw-r--r--include/llvm/ADT/BitVector.h149
-rw-r--r--include/llvm/ADT/SmallBitVector.h16
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h12
-rw-r--r--include/llvm/Analysis/DominanceFrontierImpl.h8
-rw-r--r--include/llvm/Analysis/LoopInfo.h23
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h73
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h5
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h12
-rw-r--r--include/llvm/Bitcode/BitcodeReader.h4
-rw-r--r--include/llvm/Bitcode/BitcodeWriter.h14
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h14
-rw-r--r--include/llvm/CodeGen/GlobalISel/InstructionSelector.h3
-rw-r--r--include/llvm/CodeGen/GlobalISel/Utils.h3
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h5
-rw-r--r--include/llvm/CodeGen/MachineValueType.h548
-rw-r--r--include/llvm/CodeGen/ValueTypes.h72
-rw-r--r--include/llvm/CodeGen/ValueTypes.td216
-rw-r--r--include/llvm/Config/config.h.cmake6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDie.h11
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h13
-rw-r--r--include/llvm/IR/Argument.h12
-rw-r--r--include/llvm/IR/Attributes.h3
-rw-r--r--include/llvm/IR/ConstantRange.h30
-rw-r--r--include/llvm/IR/DIBuilder.h3
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h5
-rw-r--r--include/llvm/IR/Instructions.h6
-rw-r--r--include/llvm/IR/Metadata.h9
-rw-r--r--include/llvm/IR/ModuleSummaryIndex.h4
-rw-r--r--include/llvm/IR/PatternMatch.h10
-rw-r--r--include/llvm/IR/Use.h24
-rw-r--r--include/llvm/MC/MCAsmInfo.h8
-rw-r--r--include/llvm/MC/MCStreamer.h1
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h4
-rw-r--r--include/llvm/Object/Archive.h49
-rw-r--r--include/llvm/Object/Binary.h22
-rw-r--r--include/llvm/Object/COFF.h100
-rw-r--r--include/llvm/Object/IRSymtab.h49
-rw-r--r--include/llvm/Object/ObjectFile.h58
-rw-r--r--include/llvm/Object/SymbolicFile.h28
-rw-r--r--include/llvm/ObjectYAML/DWARFYAML.h6
-rw-r--r--include/llvm/PassSupport.h6
-rw-r--r--include/llvm/Support/ARMTargetParser.def38
-rw-r--r--include/llvm/Support/ArrayRecycler.h3
-rw-r--r--include/llvm/Support/BinaryStreamArray.h5
-rw-r--r--include/llvm/Support/Dwarf.def1096
-rw-r--r--include/llvm/Support/Dwarf.h60
-rw-r--r--include/llvm/Support/GenericDomTree.h56
-rw-r--r--include/llvm/Support/GraphWriter.h7
-rw-r--r--include/llvm/Support/LowLevelTypeImpl.h211
-rw-r--r--include/llvm/Support/MathExtras.h16
-rw-r--r--include/llvm/Support/Recycler.h3
-rw-r--r--include/llvm/Support/Regex.h2
-rw-r--r--include/llvm/Support/TargetParser.h2
-rw-r--r--include/llvm/TableGen/StringToOffsetTable.h2
-rw-r--r--include/llvm/Target/TargetLowering.h8
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h16
-rw-r--r--include/llvm/XRay/InstrumentationMap.h2
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;