From 12f3ca4cdb95b193af905a00e722a4dcb40b3de3 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 26 Apr 2017 19:45:00 +0000 Subject: Vendor import of llvm trunk r301441: https://llvm.org/svn/llvm-project/llvm/trunk@301441 --- include/llvm/ADT/APFloat.h | 14 +- include/llvm/ADT/APInt.h | 80 +++++++--- include/llvm/ADT/APSInt.h | 13 +- include/llvm/ADT/BitVector.h | 149 +++++++++++------- include/llvm/ADT/SmallBitVector.h | 25 +++- include/llvm/ADT/StringExtras.h | 30 ++++ include/llvm/ADT/Triple.h | 3 +- include/llvm/Analysis/DemandedBits.h | 4 +- include/llvm/Analysis/InstructionSimplify.h | 85 ++++++++++- include/llvm/Analysis/LoopInfo.h | 2 +- include/llvm/Analysis/LoopInfoImpl.h | 6 +- include/llvm/Analysis/RegionInfo.h | 22 ++- include/llvm/Analysis/ScalarEvolution.h | 41 +++++ include/llvm/Analysis/ValueTracking.h | 3 +- include/llvm/CodeGen/DIE.h | 13 +- .../llvm/CodeGen/GlobalISel/InstructionSelector.h | 34 +++++ include/llvm/CodeGen/MachineOperand.h | 6 - include/llvm/CodeGen/SelectionDAG.h | 11 +- include/llvm/DebugInfo/CodeView/CodeView.h | 2 +- .../DebugInfo/CodeView/ModuleSubstreamVisitor.h | 2 +- include/llvm/DebugInfo/CodeView/TypeDumperBase.h | 0 include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h | 6 +- include/llvm/DebugInfo/DWARF/DWARFContext.h | 17 ++- include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h | 4 +- include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h | 6 +- include/llvm/DebugInfo/DWARF/DWARFUnit.h | 18 +-- include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h | 3 +- include/llvm/DebugInfo/PDB/IPDBRawSymbol.h | 2 +- include/llvm/DebugInfo/PDB/Native/ModStream.h | 2 + .../llvm/DebugInfo/PDB/Native/NativeRawSymbol.h | 3 +- include/llvm/DebugInfo/PDB/UDTLayout.h | 143 +++++++++--------- .../llvm/ExecutionEngine/Orc/RPCSerialization.h | 65 ++++---- include/llvm/IR/Attributes.h | 2 +- include/llvm/IR/ConstantRange.h | 2 +- include/llvm/IR/Dominators.h | 4 + include/llvm/IR/IntrinsicsAMDGPU.td | 2 + include/llvm/IR/Module.h | 2 +- include/llvm/IR/Value.h | 11 ++ include/llvm/MC/MCTargetOptions.h | 1 + include/llvm/Object/ELF.h | 68 +++++---- include/llvm/Object/ELFObjectFile.h | 32 ++-- include/llvm/Object/ELFTypes.h | 166 +++++++++++---------- include/llvm/Object/IRSymtab.h | 29 +++- include/llvm/Object/MachO.h | 122 ++++++++------- include/llvm/Object/ModuleSummaryIndexObjectFile.h | 25 +++- include/llvm/Object/ModuleSymbolTable.h | 16 +- include/llvm/Object/RelocVisitor.h | 91 +++++------ include/llvm/Object/StackMapParser.h | 43 +++--- include/llvm/Object/Wasm.h | 13 +- include/llvm/ObjectYAML/WasmYAML.h | 2 +- include/llvm/ProfileData/InstrProf.h | 8 - include/llvm/Support/BranchProbability.h | 12 ++ include/llvm/Support/FileSystem.h | 4 +- include/llvm/Support/GenericDomTree.h | 4 +- include/llvm/Support/KnownBits.h | 43 ++++++ include/llvm/Support/YAMLTraits.h | 4 +- include/llvm/Target/GlobalISel/Target.td | 10 +- include/llvm/Target/TargetInstrInfo.h | 2 +- include/llvm/Target/TargetLowering.h | 62 +++++--- include/llvm/Target/TargetRegisterInfo.h | 69 +++++---- include/llvm/Transforms/Instrumentation.h | 3 +- include/llvm/Transforms/Scalar/ConstantHoisting.h | 8 +- 62 files changed, 1093 insertions(+), 581 deletions(-) delete mode 100644 include/llvm/DebugInfo/CodeView/TypeDumperBase.h create mode 100644 include/llvm/Support/KnownBits.h (limited to 'include') diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index e7e5036e6930..bef6efde1f01 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -397,6 +397,12 @@ public: /// consider inserting before falling back to scientific /// notation. 0 means to always use scientific notation. /// + /// \param TruncateZero Indicate whether to remove the trailing zero in + /// fraction part or not. Also setting this parameter to false forcing + /// producing of output more similar to default printf behavior. + /// Specifically the lower e is used as exponent delimiter and exponent + /// always contains no less than two digits. + /// /// Number Precision MaxPadding Result /// ------ --------- ---------- ------ /// 1.01E+4 5 2 10100 @@ -406,7 +412,7 @@ public: /// 1.01E-2 4 2 0.0101 /// 1.01E-2 4 1 1.01E-2 void toString(SmallVectorImpl &Str, unsigned FormatPrecision = 0, - unsigned FormatMaxPadding = 3) const; + unsigned FormatMaxPadding = 3, bool TruncateZero = true) const; /// If this value has an exact multiplicative inverse, store it in inv and /// return true. @@ -649,7 +655,7 @@ public: bool isInteger() const; void toString(SmallVectorImpl &Str, unsigned FormatPrecision, - unsigned FormatMaxPadding) const; + unsigned FormatMaxPadding, bool TruncateZero = true) const; bool getExactInverse(APFloat *inv) const; @@ -1144,9 +1150,9 @@ public: APFloat &operator=(APFloat &&RHS) = default; void toString(SmallVectorImpl &Str, unsigned FormatPrecision = 0, - unsigned FormatMaxPadding = 3) const { + unsigned FormatMaxPadding = 3, bool TruncateZero = true) const { APFLOAT_DISPATCH_ON_SEMANTICS( - toString(Str, FormatPrecision, FormatMaxPadding)); + toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero)); } void print(raw_ostream &) const; diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index ceb623d34531..d0104c3f0fa9 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -78,6 +78,8 @@ public: APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT }; + static const WordType WORD_MAX = ~WordType(0); + private: /// This union is used to store the integer value. When the /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. @@ -90,6 +92,8 @@ private: friend struct DenseMapAPIntKeyInfo; + friend class APSInt; + /// \brief Fast internal constructor /// /// This constructor is used only internally for speed of construction of @@ -134,15 +138,10 @@ private: /// zero'd out. APInt &clearUnusedBits() { // Compute how many bits are used in the final word - unsigned wordBits = BitWidth % APINT_BITS_PER_WORD; - if (wordBits == 0) - // If all bits are used, we want to leave the value alone. This also - // avoids the undefined behavior of >> when the shift is the same size as - // the word size (64). - return *this; + unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1; // Mask out the high bits. - uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - wordBits); + uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - WordBits); if (isSingleWord()) VAL &= mask; else @@ -194,6 +193,9 @@ private: /// out-of-line slow case for lshr. void lshrSlowCase(unsigned ShiftAmt); + /// out-of-line slow case for ashr. + void ashrSlowCase(unsigned ShiftAmt); + /// out-of-line slow case for operator= void AssignSlowCase(const APInt &RHS); @@ -230,6 +232,14 @@ private: /// out-of-line slow case for operator^=. void XorAssignSlowCase(const APInt& RHS); + /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal + /// to, or greater than RHS. + int compare(const APInt &RHS) const LLVM_READONLY; + + /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal + /// to, or greater than RHS. + int compareSigned(const APInt &RHS) const LLVM_READONLY; + public: /// \name Constructors /// @{ @@ -363,7 +373,7 @@ public: /// This checks to see if the value has all bits of the APInt are set or not. bool isAllOnesValue() const { if (isSingleWord()) - return VAL == UINT64_MAX >> (APINT_BITS_PER_WORD - BitWidth); + return VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth); return countPopulationSlowCase() == BitWidth; } @@ -445,7 +455,7 @@ public: assert(numBits != 0 && "numBits must be non-zero"); assert(numBits <= BitWidth && "numBits out of range"); if (isSingleWord()) - return VAL == (UINT64_MAX >> (APINT_BITS_PER_WORD - numBits)); + return VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits)); unsigned Ones = countTrailingOnesSlowCase(); return (numBits == Ones) && ((Ones + countLeadingZerosSlowCase()) == BitWidth); @@ -509,7 +519,7 @@ public: /// /// \returns the all-ones value for an APInt of the specified bit-width. static APInt getAllOnesValue(unsigned numBits) { - return APInt(numBits, UINT64_MAX, true); + return APInt(numBits, WORD_MAX, true); } /// \brief Get the '0' value. @@ -886,7 +896,26 @@ public: /// \brief Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. - APInt ashr(unsigned shiftAmt) const; + APInt ashr(unsigned ShiftAmt) const { + APInt R(*this); + R.ashrInPlace(ShiftAmt); + return R; + } + + /// Arithmetic right-shift this APInt by ShiftAmt in place. + void ashrInPlace(unsigned ShiftAmt) { + assert(ShiftAmt <= BitWidth && "Invalid shift amount"); + if (isSingleWord()) { + int64_t SExtVAL = SignExtend64(VAL, BitWidth); + if (ShiftAmt == BitWidth) + VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit. + else + VAL = SExtVAL >> ShiftAmt; + clearUnusedBits(); + return; + } + ashrSlowCase(ShiftAmt); + } /// \brief Logical right-shift function. /// @@ -928,7 +957,14 @@ public: /// \brief Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. - APInt ashr(const APInt &shiftAmt) const; + APInt ashr(const APInt &ShiftAmt) const { + APInt R(*this); + R.ashrInPlace(ShiftAmt); + return R; + } + + /// Arithmetic right-shift this APInt by shiftAmt in place. + void ashrInPlace(const APInt &shiftAmt); /// \brief Logical right-shift function. /// @@ -1079,7 +1115,7 @@ public: /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when both are considered unsigned. - bool ult(const APInt &RHS) const LLVM_READONLY; + bool ult(const APInt &RHS) const { return compare(RHS) < 0; } /// \brief Unsigned less than comparison /// @@ -1098,7 +1134,7 @@ public: /// validity of the less-than relationship. /// /// \returns true if *this < RHS when both are considered signed. - bool slt(const APInt &RHS) const LLVM_READONLY; + bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; } /// \brief Signed less than comparison /// @@ -1117,7 +1153,7 @@ public: /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when both are considered unsigned. - bool ule(const APInt &RHS) const { return ult(RHS) || eq(RHS); } + bool ule(const APInt &RHS) const { return compare(RHS) <= 0; } /// \brief Unsigned less or equal comparison /// @@ -1133,7 +1169,7 @@ public: /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when both are considered signed. - bool sle(const APInt &RHS) const { return slt(RHS) || eq(RHS); } + bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; } /// \brief Signed less or equal comparison /// @@ -1149,7 +1185,7 @@ public: /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when both are considered unsigned. - bool ugt(const APInt &RHS) const { return !ult(RHS) && !eq(RHS); } + bool ugt(const APInt &RHS) const { return !ule(RHS); } /// \brief Unsigned greater than comparison /// @@ -1168,7 +1204,7 @@ public: /// validity of the greater-than relationship. /// /// \returns true if *this > RHS when both are considered signed. - bool sgt(const APInt &RHS) const { return !slt(RHS) && !eq(RHS); } + bool sgt(const APInt &RHS) const { return !sle(RHS); } /// \brief Signed greater than comparison /// @@ -1286,7 +1322,7 @@ public: /// \brief Set every bit to 1. void setAllBits() { if (isSingleWord()) - VAL = UINT64_MAX; + VAL = WORD_MAX; else // Set all the bits in all the words. memset(pVal, -1, getNumWords() * APINT_WORD_SIZE); @@ -1316,7 +1352,7 @@ public: return; } if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) { - uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit)); + uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit)); mask <<= loBit; if (isSingleWord()) VAL |= mask; @@ -1358,7 +1394,7 @@ public: /// \brief Toggle every bit to its opposite value. void flipAllBits() { if (isSingleWord()) { - VAL ^= UINT64_MAX; + VAL ^= WORD_MAX; clearUnusedBits(); } else { flipAllBitsSlowCase(); @@ -1653,7 +1689,7 @@ public: /// referencing 2 in a space where 2 does no exist. unsigned nearestLogBase2() const { // Special case when we have a bitwidth of 1. If VAL is 1, then we - // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to + // get 0. If VAL is 0, we get WORD_MAX which gets truncated to // UINT32_MAX. if (BitWidth == 1) return VAL - 1; diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 5b6dfa4a4b64..dabbf3314bd0 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -125,7 +125,10 @@ public: return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false); } APSInt& operator>>=(unsigned Amt) { - *this = *this >> Amt; + if (IsUnsigned) + lshrInPlace(Amt); + else + ashrInPlace(Amt); return *this; } @@ -179,7 +182,7 @@ public: return APSInt(static_cast(*this) << Bits, IsUnsigned); } APSInt& operator<<=(unsigned Amt) { - *this = *this << Amt; + static_cast(*this) <<= Amt; return *this; } @@ -285,12 +288,12 @@ public: /// \brief Compare underlying values of two numbers. static int compareValues(const APSInt &I1, const APSInt &I2) { if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned()) - return I1 == I2 ? 0 : I1 > I2 ? 1 : -1; + return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2); // Check for a bit-width mismatch. if (I1.getBitWidth() > I2.getBitWidth()) return compareValues(I1, I2.extend(I1.getBitWidth())); - else if (I2.getBitWidth() > I1.getBitWidth()) + if (I2.getBitWidth() > I1.getBitWidth()) return compareValues(I1.extend(I2.getBitWidth()), I2); // We have a signedness mismatch. Check for negative values and do an @@ -305,7 +308,7 @@ public: return 1; } - return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1; + return I1.compare(I2); } static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); } diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index e48c023ae7df..5aa101591e6e 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -15,7 +15,6 @@ #define LLVM_ADT_BITVECTOR_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" #include #include @@ -35,9 +34,8 @@ class BitVector { static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32, "Unsupported word size"); - BitWord *Bits; // Actual bits. - unsigned Size; // Size of bitvector in bits. - unsigned Capacity; // Number of BitWords allocated in the Bits array. + MutableArrayRef Bits; // Actual bits. + unsigned Size; // Size of bitvector in bits. public: typedef unsigned size_type; @@ -77,16 +75,14 @@ public: /// BitVector default ctor - Creates an empty bitvector. - BitVector() : Size(0), Capacity(0) { - Bits = nullptr; - } + BitVector() : Size(0) {} /// BitVector ctor - Creates a bitvector of specified number of bits. All /// bits are initialized to the specified value. explicit BitVector(unsigned s, bool t = false) : Size(s) { - Capacity = NumBitWords(s); - Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); - init_words(Bits, Capacity, t); + size_t Capacity = NumBitWords(s); + Bits = allocate(Capacity); + init_words(Bits, t); if (t) clear_unused_bits(); } @@ -94,25 +90,21 @@ public: /// BitVector copy ctor. BitVector(const BitVector &RHS) : Size(RHS.size()) { if (Size == 0) { - Bits = nullptr; - Capacity = 0; + Bits = MutableArrayRef(); return; } - Capacity = NumBitWords(RHS.size()); - Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); - std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); + size_t Capacity = NumBitWords(RHS.size()); + Bits = allocate(Capacity); + std::memcpy(Bits.data(), RHS.Bits.data(), Capacity * sizeof(BitWord)); } - BitVector(BitVector &&RHS) - : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { - RHS.Bits = nullptr; - RHS.Size = RHS.Capacity = 0; + BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size) { + RHS.Bits = MutableArrayRef(); + RHS.Size = 0; } - ~BitVector() { - std::free(Bits); - } + ~BitVector() { std::free(Bits.data()); } /// empty - Tests whether there are no bits in this bitvector. bool empty() const { return Size == 0; } @@ -163,6 +155,22 @@ public: return -1; } + /// find_last - Returns the index of the last set bit, -1 if none of the bits + /// are set. + int find_last() const { + if (Size == 0) + return -1; + + unsigned N = NumBitWords(size()); + assert(N > 0); + + unsigned i = N - 1; + while (i > 0 && Bits[i] == BitWord(0)) + --i; + + return int((i + 1) * BITWORD_SIZE - countLeadingZeros(Bits[i])) - 1; + } + /// find_first_unset - Returns the index of the first unset bit, -1 if all /// of the bits are set. int find_first_unset() const { @@ -174,6 +182,30 @@ public: return -1; } + /// find_last_unset - Returns the index of the last unset bit, -1 if all of + /// the bits are set. + int find_last_unset() const { + if (Size == 0) + return -1; + + const unsigned N = NumBitWords(size()); + assert(N > 0); + + unsigned i = N - 1; + BitWord W = Bits[i]; + + // The last word in the BitVector has some unused bits, so we need to set + // them all to 1 first. Set them all to 1 so they don't get treated as + // valid unset bits. + unsigned UnusedCount = BITWORD_SIZE - size() % BITWORD_SIZE; + W |= maskLeadingOnes(UnusedCount); + + while (W == ~BitWord(0) && --i > 0) + W = Bits[i]; + + return int((i + 1) * BITWORD_SIZE - countLeadingOnes(W)) - 1; + } + /// find_next - Returns the index of the next set bit following the /// "Prev" bit. Returns -1 if the next set bit is not found. int find_next(unsigned Prev) const { @@ -228,10 +260,10 @@ public: /// resize - Grow or shrink the bitvector. void resize(unsigned N, bool t = false) { - if (N > Capacity * BITWORD_SIZE) { - unsigned OldCapacity = Capacity; + if (N > getBitCapacity()) { + unsigned OldCapacity = Bits.size(); grow(N); - init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t); + init_words(Bits.drop_front(OldCapacity), t); } // Set any old unused bits that are now included in the BitVector. This @@ -248,19 +280,19 @@ public: } void reserve(unsigned N) { - if (N > Capacity * BITWORD_SIZE) + if (N > getBitCapacity()) grow(N); } // Set, reset, flip BitVector &set() { - init_words(Bits, Capacity, true); + init_words(Bits, true); clear_unused_bits(); return *this; } BitVector &set(unsigned Idx) { - assert(Bits && "Bits never allocated"); + assert(Bits.data() && "Bits never allocated"); Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE); return *this; } @@ -295,7 +327,7 @@ public: } BitVector &reset() { - init_words(Bits, Capacity, false); + init_words(Bits, false); return *this; } @@ -562,21 +594,21 @@ public: Size = RHS.size(); unsigned RHSWords = NumBitWords(Size); - if (Size <= Capacity * BITWORD_SIZE) { + if (Size <= getBitCapacity()) { if (Size) - std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord)); + std::memcpy(Bits.data(), RHS.Bits.data(), RHSWords * sizeof(BitWord)); clear_unused_bits(); return *this; } // Grow the bitvector to have enough elements. - Capacity = RHSWords; - assert(Capacity > 0 && "negative capacity?"); - BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); - std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); + unsigned NewCapacity = RHSWords; + assert(NewCapacity > 0 && "negative capacity?"); + auto NewBits = allocate(NewCapacity); + std::memcpy(NewBits.data(), RHS.Bits.data(), NewCapacity * sizeof(BitWord)); // Destroy the old bits. - std::free(Bits); + std::free(Bits.data()); Bits = NewBits; return *this; @@ -585,13 +617,12 @@ public: const BitVector &operator=(BitVector &&RHS) { if (this == &RHS) return *this; - std::free(Bits); + std::free(Bits.data()); Bits = RHS.Bits; Size = RHS.Size; - Capacity = RHS.Capacity; - RHS.Bits = nullptr; - RHS.Size = RHS.Capacity = 0; + RHS.Bits = MutableArrayRef(); + RHS.Size = 0; return *this; } @@ -599,7 +630,6 @@ public: void swap(BitVector &RHS) { std::swap(Bits, RHS.Bits); std::swap(Size, RHS.Size); - std::swap(Capacity, RHS.Capacity); } //===--------------------------------------------------------------------===// @@ -659,14 +689,14 @@ private: uint32_t NumWords = NumBitWords(Size); - auto Src = ArrayRef(Bits, NumWords).drop_back(Count); - auto Dest = MutableArrayRef(Bits, NumWords).drop_front(Count); + auto Src = Bits.take_front(NumWords).drop_back(Count); + auto Dest = Bits.take_front(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)); + std::memset(Bits.data(), 0, Count * sizeof(BitWord)); clear_unused_bits(); } @@ -679,14 +709,19 @@ private: uint32_t NumWords = NumBitWords(Size); - auto Src = ArrayRef(Bits, NumWords).drop_front(Count); - auto Dest = MutableArrayRef(Bits, NumWords).drop_back(Count); + auto Src = Bits.take_front(NumWords).drop_front(Count); + auto Dest = Bits.take_front(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)); } + MutableArrayRef allocate(size_t NumWords) { + BitWord *RawBits = (BitWord *)std::malloc(NumWords * sizeof(BitWord)); + return MutableArrayRef(RawBits, NumWords); + } + int next_unset_in_word(int WordIndex, BitWord Word) const { unsigned Result = WordIndex * BITWORD_SIZE + countTrailingOnes(Word); return Result < size() ? Result : -1; @@ -700,8 +735,8 @@ private: void set_unused_bits(bool t = true) { // Set high words first. unsigned UsedWords = NumBitWords(Size); - if (Capacity > UsedWords) - init_words(&Bits[UsedWords], (Capacity-UsedWords), t); + if (Bits.size() > UsedWords) + init_words(Bits.drop_front(UsedWords), t); // Then set any stray high bits of the last used word. unsigned ExtraBits = Size % BITWORD_SIZE; @@ -720,16 +755,17 @@ private: } void grow(unsigned NewSize) { - Capacity = std::max(NumBitWords(NewSize), Capacity * 2); - assert(Capacity > 0 && "realloc-ing zero space"); - Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord)); - + size_t NewCapacity = std::max(NumBitWords(NewSize), Bits.size() * 2); + assert(NewCapacity > 0 && "realloc-ing zero space"); + BitWord *NewBits = + (BitWord *)std::realloc(Bits.data(), NewCapacity * sizeof(BitWord)); + Bits = MutableArrayRef(NewBits, NewCapacity); clear_unused_bits(); } - void init_words(BitWord *B, unsigned NumWords, bool t) { - if (NumWords > 0) - memset(B, 0 - (int)t, NumWords*sizeof(BitWord)); + void init_words(MutableArrayRef B, bool t) { + if (B.size() > 0) + memset(B.data(), 0 - (int)t, B.size() * sizeof(BitWord)); } template @@ -761,7 +797,8 @@ private: public: /// Return the size (in bytes) of the bit vector. - size_t getMemorySize() const { return Capacity * sizeof(BitWord); } + size_t getMemorySize() const { return Bits.size() * sizeof(BitWord); } + size_t getBitCapacity() const { return Bits.size() * BITWORD_SIZE; } }; static inline size_t capacity_in_bytes(const BitVector &X) { diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 607e040a606c..bf16af5933f0 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -117,9 +117,7 @@ private: } // Return the size. - size_t getSmallSize() const { - return getSmallRawBits() >> SmallNumDataBits; - } + size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; } void setSmallSize(size_t Size) { setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); @@ -216,6 +214,16 @@ public: return getPointer()->find_first(); } + int find_last() const { + if (isSmall()) { + uintptr_t Bits = getSmallBits(); + if (Bits == 0) + return -1; + return NumBaseBits - countLeadingZeros(Bits); + } + return getPointer()->find_last(); + } + /// Returns the index of the first unset bit, -1 if all of the bits are set. int find_first_unset() const { if (isSmall()) { @@ -228,6 +236,17 @@ public: return getPointer()->find_first_unset(); } + int find_last_unset() const { + if (isSmall()) { + if (count() == getSmallSize()) + return -1; + + uintptr_t Bits = getSmallBits(); + return NumBaseBits - countLeadingOnes(Bits); + } + return getPointer()->find_last_unset(); + } + /// Returns the index of the next set bit following the "Prev" bit. /// Returns -1 if the next set bit is not found. int find_next(unsigned Prev) const { diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 8214782bfe80..26f11924b771 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -76,6 +76,36 @@ static inline std::string toHex(StringRef Input) { return Output; } +static inline uint8_t hexFromNibbles(char MSB, char LSB) { + unsigned U1 = hexDigitValue(MSB); + unsigned U2 = hexDigitValue(LSB); + assert(U1 != -1U && U2 != -1U); + + return static_cast((U1 << 4) | U2); +} + +/// Convert hexadecimal string \p Input to its binary representation. +/// The return string is half the size of \p Input. +static inline std::string fromHex(StringRef Input) { + if (Input.empty()) + return std::string(); + + std::string Output; + Output.reserve((Input.size() + 1) / 2); + if (Input.size() % 2 == 1) { + Output.push_back(hexFromNibbles('0', Input.front())); + Input = Input.drop_front(); + } + + assert(Input.size() % 2 == 0); + while (!Input.empty()) { + uint8_t Hex = hexFromNibbles(Input[0], Input[1]); + Output.push_back(Hex); + Input = Input.drop_front(2); + } + return Output; +} + static inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[21]; char *BufPtr = std::end(Buffer); diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index e271075b7e2a..e3a8a31ba9bc 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -140,7 +140,8 @@ public: Myriad, AMD, Mesa, - LastVendorType = Mesa + SUSE, + LastVendorType = SUSE }; enum OSType { UnknownOS, diff --git a/include/llvm/Analysis/DemandedBits.h b/include/llvm/Analysis/DemandedBits.h index c603274a7161..e5fd8a0007fe 100644 --- a/include/llvm/Analysis/DemandedBits.h +++ b/include/llvm/Analysis/DemandedBits.h @@ -35,6 +35,7 @@ class Function; class Instruction; class DominatorTree; class AssumptionCache; +struct KnownBits; class DemandedBits { public: @@ -58,8 +59,7 @@ private: void determineLiveOperandBits(const Instruction *UserI, const Instruction *I, unsigned OperandNo, const APInt &AOut, APInt &AB, - APInt &KnownZero, APInt &KnownOne, - APInt &KnownZero2, APInt &KnownOne2); + KnownBits &Known, KnownBits &Known2); bool Analyzed; diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index b829e995db05..25240dae75e7 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -47,7 +47,32 @@ namespace llvm { class Type; class Value; + struct SimplifyQuery { + const DataLayout &DL; + const TargetLibraryInfo *TLI = nullptr; + const DominatorTree *DT = nullptr; + AssumptionCache *AC = nullptr; + const Instruction *CxtI = nullptr; + SimplifyQuery(const DataLayout &DL) : DL(DL) {} + + SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI, + const DominatorTree *DT, AssumptionCache *AC = nullptr, + const Instruction *CXTI = nullptr) + : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {} + SimplifyQuery getWithInstruction(Instruction *I) const { + SimplifyQuery Copy(*this); + Copy.CxtI = I; + return Copy; + } + }; + + // NOTE: the explicit multiple argument versions of these functions are + // deprecated. + // Please use the SimplifyQuery versions in new code. + /// Given operands for an Add, fold the result or return null. + Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, + const SimplifyQuery &Q); Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -56,6 +81,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a Sub, fold the result or return null. + Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, + const SimplifyQuery &Q); Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -64,6 +91,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FAdd, fold the result or return null. + Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const SimplifyQuery &Q); Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -72,6 +101,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FSub, fold the result or return null. + Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const SimplifyQuery &Q); Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -80,6 +111,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FMul, fold the result or return null. + Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const SimplifyQuery &Q); Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -88,6 +121,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a Mul, fold the result or return null. + Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -95,6 +129,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an SDiv, fold the result or return null. + Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -102,6 +137,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a UDiv, fold the result or return null. + Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -109,6 +145,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FDiv, fold the result or return null. + Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const SimplifyQuery &Q); Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -117,6 +155,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an SRem, fold the result or return null. + Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -124,6 +163,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a URem, fold the result or return null. + Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -131,6 +171,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FRem, fold the result or return null. + Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const SimplifyQuery &Q); Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -139,6 +181,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a Shl, fold the result or return null. + Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const SimplifyQuery &Q); Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -147,6 +191,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a LShr, fold the result or return null. + Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, + const SimplifyQuery &Q); Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -155,6 +201,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a AShr, fold the result or return nulll. + Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, + const SimplifyQuery &Q); Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -163,6 +211,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an And, fold the result or return null. + Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -170,6 +219,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an Or, fold the result or return null. + Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -177,6 +227,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an Xor, fold the result or return null. + Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -184,6 +235,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an ICmpInst, fold the result or return null. + Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const SimplifyQuery &Q); Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -192,6 +245,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an FCmpInst, fold the result or return null. + Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + FastMathFlags FMF, const SimplifyQuery &Q); Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -200,6 +255,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a SelectInst, fold the result or return null. + Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, + const SimplifyQuery &Q); Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -207,7 +264,9 @@ namespace llvm { AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr); - /// Given operands for a GetElementPtrInst, fold the result or return null. + /// Given operands for a GetElementPtrInst, fold the result or return null. + Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, + const SimplifyQuery &Q); Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -216,6 +275,9 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an InsertValueInst, fold the result or return null. + Value *SimplifyInsertValueInst(Value *Agg, Value *Val, + ArrayRef Idxs, + const SimplifyQuery &Q); Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -224,6 +286,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an ExtractValueInst, fold the result or return null. + Value *SimplifyExtractValueInst(Value *Agg, ArrayRef Idxs, + const SimplifyQuery &Q); Value *SimplifyExtractValueInst(Value *Agg, ArrayRef Idxs, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -232,6 +296,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for an ExtractElementInst, fold the result or return null. + Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, + const SimplifyQuery &Q); Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -240,6 +306,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a CastInst, fold the result or return null. + Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, + const SimplifyQuery &Q); Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -248,6 +316,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a ShuffleVectorInst, fold the result or return null. + Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, + Type *RetTy, const SimplifyQuery &Q); Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, Type *RetTy, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -259,6 +329,8 @@ namespace llvm { /// Given operands for a CmpInst, fold the result or return null. + Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, + const SimplifyQuery &Q); Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -267,6 +339,8 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given operands for a BinaryOperator, fold the result or return null. + Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, + const SimplifyQuery &Q); Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -278,7 +352,9 @@ namespace llvm { /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp. Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const FastMathFlags &FMF, const DataLayout &DL, + FastMathFlags FMF, const SimplifyQuery &Q); + Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, + FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -286,6 +362,8 @@ namespace llvm { /// Given a function and iterators over arguments, fold the result or return /// null. + Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, + User::op_iterator ArgEnd, const SimplifyQuery &Q); Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, User::op_iterator ArgEnd, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, @@ -294,6 +372,7 @@ namespace llvm { const Instruction *CxtI = nullptr); /// Given a function and set of arguments, fold the result or return null. + Value *SimplifyCall(Value *V, ArrayRef Args, const SimplifyQuery &Q); Value *SimplifyCall(Value *V, ArrayRef Args, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, @@ -302,6 +381,8 @@ namespace llvm { /// See if we can compute a simplified version of this instruction. If not, /// return null. + Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, + OptimizationRemarkEmitter *ORE = nullptr); Value *SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 2fad1737d1c0..096df1e421a7 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -158,7 +158,7 @@ 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 { - for (const auto Succ : children(BB)) { + for (const auto &Succ : children(BB)) { if (!contains(Succ)) return true; } diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 6dc0422ce0e9..66c9f68afc60 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -35,7 +35,7 @@ template void LoopBase:: getExitingBlocks(SmallVectorImpl &ExitingBlocks) const { for (const auto BB : blocks()) - for (const auto Succ : children(BB)) + for (const auto &Succ : children(BB)) if (!contains(Succ)) { // Not in current loop? It must be an exit block. ExitingBlocks.push_back(BB); @@ -61,7 +61,7 @@ template void LoopBase:: getExitBlocks(SmallVectorImpl &ExitBlocks) const { for (const auto BB : blocks()) - for (const auto Succ : children(BB)) + for (const auto &Succ : children(BB)) if (!contains(Succ)) // Not in current loop? It must be an exit block. ExitBlocks.push_back(Succ); @@ -83,7 +83,7 @@ template void LoopBase:: getExitEdges(SmallVectorImpl &ExitEdges) const { for (const auto BB : blocks()) - for (const auto Succ : children(BB)) + for (const auto &Succ : children(BB)) if (!contains(Succ)) // Not in current loop? It must be an exit block. ExitEdges.emplace_back(BB, Succ); diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index caeb21db613e..16ee07fa3177 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -708,10 +708,24 @@ class RegionInfoBase { /// The top level region. RegionT *TopLevelRegion; -private: /// Map every BB to the smallest region, that contains BB. BBtoRegionMap BBtoRegion; +protected: + /// \brief Update refences to a RegionInfoT held by the RegionT managed here + /// + /// This is a post-move helper. Regions hold references to the owning + /// RegionInfo object. After a move these need to be fixed. + template + void updateRegionTree(RegionInfoT &RI, TheRegionT *R) { + if (!R) + return; + R->RI = &RI; + for (auto &SubR : *R) + updateRegionTree(RI, SubR.get()); + } + +private: /// \brief Wipe this region tree's state without releasing any resources. /// /// This is essentially a post-move helper only. It leaves the object in an @@ -879,10 +893,12 @@ public: ~RegionInfo() override; - RegionInfo(RegionInfo &&Arg) - : Base(std::move(static_cast(Arg))) {} + RegionInfo(RegionInfo &&Arg) : Base(std::move(static_cast(Arg))) { + updateRegionTree(*this, TopLevelRegion); + } RegionInfo &operator=(RegionInfo &&RHS) { Base::operator=(std::move(static_cast(RHS))); + updateRegionTree(*this, TopLevelRegion); return *this; } diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 91aeae0f728f..54bc4dcfd2cd 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -877,6 +877,47 @@ private: bool ControlsExit, bool AllowPredicates = false); + // Helper functions for computeExitLimitFromCond to avoid exponential time + // complexity. + + class ExitLimitCache { + // It may look like we need key on the whole (L, TBB, FBB, ControlsExit, + // AllowPredicates) tuple, but recursive calls to + // computeExitLimitFromCondCached from computeExitLimitFromCondImpl only + // vary the in \c ExitCond and \c ControlsExit parameters. We remember the + // initial values of the other values to assert our assumption. + SmallDenseMap, ExitLimit> TripCountMap; + + const Loop *L; + BasicBlock *TBB; + BasicBlock *FBB; + bool AllowPredicates; + + public: + ExitLimitCache(const Loop *L, BasicBlock *TBB, BasicBlock *FBB, + bool AllowPredicates) + : L(L), TBB(TBB), FBB(FBB), AllowPredicates(AllowPredicates) {} + + Optional find(const Loop *L, Value *ExitCond, BasicBlock *TBB, + BasicBlock *FBB, bool ControlsExit, + bool AllowPredicates); + + void insert(const Loop *L, Value *ExitCond, BasicBlock *TBB, + BasicBlock *FBB, bool ControlsExit, bool AllowPredicates, + const ExitLimit &EL); + }; + + typedef ExitLimitCache ExitLimitCacheTy; + ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache, + const Loop *L, Value *ExitCond, + BasicBlock *TBB, BasicBlock *FBB, + bool ControlsExit, + bool AllowPredicates); + ExitLimit computeExitLimitFromCondImpl(ExitLimitCacheTy &Cache, const Loop *L, + Value *ExitCond, BasicBlock *TBB, + BasicBlock *FBB, bool ControlsExit, + bool AllowPredicates); + /// Compute the number of times the backedge of the specified loop will /// execute if its exit condition were a conditional branch of the ICmpInst /// ExitCond, TBB, and FBB. If AllowPredicates is set, this call will try diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index e3c2f3bed227..764308dceed9 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -29,6 +29,7 @@ template class ArrayRef; class DominatorTree; class GEPOperator; class Instruction; + struct KnownBits; class Loop; class LoopInfo; class OptimizationRemarkEmitter; @@ -49,7 +50,7 @@ template class ArrayRef; /// where V is a vector, the known zero and known one values are the /// same width as the vector element, and the bit is set only if it is true /// for all of the elements in the vector. - void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne, + void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index 95c4b4248bbd..a40147336fe2 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -793,6 +793,9 @@ class DIEUnit { uint32_t Length; /// The length in bytes of all of the DIEs in this unit. const uint16_t Version; /// The Dwarf version number for this unit. const uint8_t AddrSize; /// The size in bytes of an address for this unit. +protected: + ~DIEUnit() = default; + public: DIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag); DIEUnit(const DIEUnit &RHS) = delete; @@ -808,6 +811,10 @@ public: this->Section = Section; } + virtual const MCSymbol *getCrossSectionRelativeBaseAddress() const { + return nullptr; + } + /// Return the section that this DIEUnit will be emitted into. /// /// \returns Section pointer which can be NULL. @@ -822,7 +829,11 @@ public: const DIE &getUnitDie() const { return Die; } }; - +struct BasicDIEUnit final : DIEUnit { + BasicDIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag) + : DIEUnit(Version, AddrSize, UnitTag) {} +}; + //===--------------------------------------------------------------------===// /// DIELoc - Represents an expression location. // diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index 911e8756070b..899563acc330 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -18,20 +18,52 @@ #include "llvm/ADT/Optional.h" #include +#include +#include namespace llvm { class MachineInstr; +class MachineInstrBuilder; +class MachineFunction; class MachineOperand; class MachineRegisterInfo; class RegisterBankInfo; class TargetInstrInfo; class TargetRegisterInfo; +/// Container class for CodeGen predicate results. +/// This is convenient because std::bitset does not have a constructor +/// with an initializer list of set bits. +/// +/// Each InstructionSelector subclass should define a PredicateBitset class with: +/// const unsigned MAX_SUBTARGET_PREDICATES = 192; +/// using PredicateBitset = PredicateBitsetImpl; +/// and updating the constant to suit the target. Tablegen provides a suitable +/// definition for the predicates in use in GenGlobalISel.inc when +/// GET_GLOBALISEL_PREDICATE_BITSET is defined. +template +class PredicateBitsetImpl : public std::bitset { +public: + // Cannot inherit constructors because it's not supported by VC++.. + PredicateBitsetImpl() = default; + + PredicateBitsetImpl(const std::bitset &B) + : std::bitset(B) {} + + PredicateBitsetImpl(std::initializer_list Init) { + for (auto I : Init) + std::bitset::set(I); + } +}; + /// Provides the logic to select generic machine instructions. class InstructionSelector { public: virtual ~InstructionSelector() {} + /// This is executed before selecting a function. + virtual void beginFunction(const MachineFunction &MF) {} + /// Select the (possibly generic) instruction \p I to only use target-specific /// opcodes. It is OK to insert multiple instructions, but they cannot be /// generic pre-isel instructions. @@ -46,6 +78,8 @@ public: virtual bool select(MachineInstr &I) const = 0; protected: + typedef std::function ComplexRendererFn; + InstructionSelector(); /// Mutate the newly-selected instruction \p I to constrain its (possibly diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 81b43126adeb..e16354088296 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -65,7 +65,6 @@ public: MO_CFIIndex, ///< MCCFIInstruction index. MO_IntrinsicID, ///< Intrinsic ID for ISel MO_Predicate, ///< Generic predicate for ISel - MO_Placeholder, ///< Placeholder for GlobalISel ComplexPattern result. }; private: @@ -768,11 +767,6 @@ public: return Op; } - static MachineOperand CreatePlaceholder() { - MachineOperand Op(MachineOperand::MO_Placeholder); - return Op; - } - friend class MachineInstr; friend class MachineRegisterInfo; private: diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 6f0509543e7d..4bb658898fb5 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -654,6 +654,15 @@ public: return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); } + /// Return an ISD::BUILD_VECTOR node. The number of elements in VT, + /// which must be a vector type, must match the number of operands in Ops. + /// The operands must have the same type as (or, for integers, a type wider + /// than) VT's element type. + SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef Ops) { + // VerifySDNode (via InsertNode) checks BUILD_VECTOR later. + return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); + } + /// Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all /// elements. VT must be a vector type. Op's type must be the same as (or, /// for integers, a type wider than) VT's element type. @@ -968,7 +977,7 @@ public: bool IsExpanding = false); SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Mask, EVT MemVT, - MachineMemOperand *MMO, bool IsTruncating = false, + MachineMemOperand *MMO, bool IsTruncating = false, bool IsCompressing = false); SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef Ops, MachineMemOperand *MMO); diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 2791c9dc3746..e599f8a19e34 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -546,7 +546,7 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland }; // These values correspond to the CV_SourceChksum_t enumeration. enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 }; -enum LineFlags : uint32_t { +enum LineFlags : uint16_t { HaveColumns = 1, // CV_LINES_HAVE_COLUMNS }; } diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h index 1a40654a3f33..31344a9427db 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h +++ b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h @@ -81,7 +81,7 @@ public: BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(BlockHeader)) return EC; - bool HasColumn = Header->Flags & LineFlags::HaveColumns; + bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns); uint32_t LineInfoSize = BlockHeader->NumLines * (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0)); diff --git a/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/include/llvm/DebugInfo/CodeView/TypeDumperBase.h deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index b2a4d247ccc6..a46d46a5bff3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -18,9 +18,9 @@ namespace llvm { class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, - bool IsDWO, const DWARFUnitSectionBase &UnitSection, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index f941cdd1060a..d89e2c684cd3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -50,6 +50,11 @@ class raw_ostream; // entire size of the debug info sections. typedef DenseMap> RelocAddrMap; +/// Reads a value from data extractor and applies a relocation to the result if +/// one exists for the given offset. +uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size, + uint32_t *Off, const RelocAddrMap *Relocs); + /// DWARFContext /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through pure virtual @@ -216,7 +221,7 @@ public: virtual StringRef getEHFrameSection() = 0; virtual const DWARFSection &getLineSection() = 0; virtual StringRef getStringSection() = 0; - virtual StringRef getRangeSection() = 0; + virtual const DWARFSection& getRangeSection() = 0; virtual StringRef getMacinfoSection() = 0; virtual StringRef getPubNamesSection() = 0; virtual StringRef getPubTypesSection() = 0; @@ -231,7 +236,7 @@ public: virtual const DWARFSection &getLocDWOSection() = 0; virtual StringRef getStringDWOSection() = 0; virtual StringRef getStringOffsetDWOSection() = 0; - virtual StringRef getRangeDWOSection() = 0; + virtual const DWARFSection &getRangeDWOSection() = 0; virtual StringRef getAddrSection() = 0; virtual const DWARFSection& getAppleNamesSection() = 0; virtual const DWARFSection& getAppleTypesSection() = 0; @@ -271,7 +276,7 @@ class DWARFContextInMemory : public DWARFContext { StringRef EHFrameSection; DWARFSection LineSection; StringRef StringSection; - StringRef RangeSection; + DWARFSection RangeSection; StringRef MacinfoSection; StringRef PubNamesSection; StringRef PubTypesSection; @@ -286,7 +291,7 @@ class DWARFContextInMemory : public DWARFContext { DWARFSection LocDWOSection; StringRef StringDWOSection; StringRef StringOffsetDWOSection; - StringRef RangeDWOSection; + DWARFSection RangeDWOSection; StringRef AddrSection; DWARFSection AppleNamesSection; DWARFSection AppleTypesSection; @@ -319,7 +324,7 @@ public: StringRef getEHFrameSection() override { return EHFrameSection; } const DWARFSection &getLineSection() override { return LineSection; } StringRef getStringSection() override { return StringSection; } - StringRef getRangeSection() override { return RangeSection; } + const DWARFSection &getRangeSection() override { return RangeSection; } StringRef getMacinfoSection() override { return MacinfoSection; } StringRef getPubNamesSection() override { return PubNamesSection; } StringRef getPubTypesSection() override { return PubTypesSection; } @@ -346,7 +351,7 @@ public: return StringOffsetDWOSection; } - StringRef getRangeDWOSection() override { return RangeDWOSection; } + const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; } StringRef getAddrSection() override { return AddrSection; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index 018a049a3ed8..9172df5bfac6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -11,6 +11,8 @@ #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H #include "llvm/Support/DataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" + #include #include #include @@ -71,7 +73,7 @@ public: void clear(); void dump(raw_ostream &OS) const; - bool extract(DataExtractor data, uint32_t *offset_ptr); + bool extract(DataExtractor data, uint32_t *offset_ptr, const RelocAddrMap& Relocs); const std::vector &getEntries() { return Entries; } /// getAbsoluteRanges - Returns absolute address ranges defined by this range diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index 703316005887..c9da2c9a3e16 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -30,9 +30,9 @@ private: public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 023a0f7b9fb2..e29ba523238c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -56,9 +56,9 @@ protected: ~DWARFUnitSectionBase() = default; virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, - bool isLittleEndian, bool isDWO) = 0; + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, + StringRef LS, bool isLittleEndian, bool isDWO) = 0; }; const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, @@ -88,9 +88,9 @@ public: private: void parseImpl(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, - bool IsDWO) override { + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO) override { if (Parsed) return; const auto &Index = getDWARFUnitIndex(Context, UnitType::Section); @@ -115,7 +115,7 @@ class DWARFUnit { const DWARFSection &InfoSection; const DWARFDebugAbbrev *Abbrev; - StringRef RangeSection; + const DWARFSection *RangeSection; uint32_t RangeSectionBase; StringRef LineSection; StringRef StringSection; @@ -171,7 +171,7 @@ protected: public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry = nullptr); @@ -192,7 +192,7 @@ public: // Recursively update address to Die map. void updateAddressDieMap(DWARFDie Die); - void setRangesSection(StringRef RS, uint32_t Base) { + void setRangesSection(const DWARFSection *RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; } diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h index c0633cbdfa52..3710eb29e7f9 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h @@ -102,7 +102,8 @@ public: uint32_t getVirtualBaseDispIndex() const override; uint32_t getVirtualBaseOffset() const override; uint32_t getVirtualTableShapeId() const override; - std::unique_ptr getVirtualBaseTableType() const override; + std::unique_ptr + getVirtualBaseTableType() const override; PDB_DataKind getDataKind() const override; PDB_SymType getSymTag() const override; PDB_UniqueId getGuid() const override; diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h index 4c28e194bc70..fab086c62c72 100644 --- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h @@ -113,7 +113,7 @@ public: virtual Variant getValue() const = 0; virtual uint32_t getVirtualBaseDispIndex() const = 0; virtual uint32_t getVirtualBaseOffset() const = 0; - virtual std::unique_ptr + virtual std::unique_ptr getVirtualBaseTableType() const = 0; virtual uint32_t getVirtualTableShapeId() const = 0; virtual PDB_DataKind getDataKind() const = 0; diff --git a/include/llvm/DebugInfo/PDB/Native/ModStream.h b/include/llvm/DebugInfo/PDB/Native/ModStream.h index d65e195dbb95..b12d4ff375f3 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModStream.h @@ -40,6 +40,8 @@ public: iterator_range lines(bool *HadError) const; + bool hasLineInfo() const; + Error commit(); private: diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index cffb5d09d225..e1e78035ff38 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -101,7 +101,8 @@ public: uint32_t getVirtualBaseDispIndex() const override; uint32_t getVirtualBaseOffset() const override; uint32_t getVirtualTableShapeId() const override; - std::unique_ptr getVirtualBaseTableType() const override; + std::unique_ptr + getVirtualBaseTableType() const override; PDB_DataKind getDataKind() const override; PDB_SymType getSymTag() const override; PDB_UniqueId getGuid() const override; diff --git a/include/llvm/DebugInfo/PDB/UDTLayout.h b/include/llvm/DebugInfo/PDB/UDTLayout.h index e3dcba50bd1a..6bc3660fbe51 100644 --- a/include/llvm/DebugInfo/PDB/UDTLayout.h +++ b/include/llvm/DebugInfo/PDB/UDTLayout.h @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" #include #include @@ -32,40 +33,63 @@ class PDBSymbolTypeVTable; class ClassLayout; class BaseClassLayout; -class StorageItemBase; +class LayoutItemBase; class UDTLayoutBase; -class StorageItemBase { +class LayoutItemBase { public: - StorageItemBase(const UDTLayoutBase &Parent, const PDBSymbol &Symbol, - const std::string &Name, uint32_t OffsetInParent, - uint32_t Size); - virtual ~StorageItemBase() {} + LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol, + const std::string &Name, uint32_t OffsetInParent, + uint32_t Size, bool IsElided); + virtual ~LayoutItemBase() {} - virtual uint32_t deepPaddingSize() const; + uint32_t deepPaddingSize() const; + virtual uint32_t immediatePadding() const { return 0; } + virtual uint32_t tailPadding() const; - const UDTLayoutBase &getParent() const { return Parent; } + const UDTLayoutBase *getParent() const { return Parent; } StringRef getName() const { return Name; } uint32_t getOffsetInParent() const { return OffsetInParent; } uint32_t getSize() const { return SizeOf; } - const PDBSymbol &getSymbol() const { return Symbol; } + uint32_t getLayoutSize() const { return LayoutSize; } + const PDBSymbol *getSymbol() const { return Symbol; } + const BitVector &usedBytes() const { return UsedBytes; } + bool isElided() const { return IsElided; } + virtual bool isVBPtr() const { return false; } + + uint32_t containsOffset(uint32_t Off) const { + uint32_t Begin = getOffsetInParent(); + uint32_t End = Begin + getSize(); + return (Off >= Begin && Off < End); + } protected: - const UDTLayoutBase &Parent; - const PDBSymbol &Symbol; + const PDBSymbol *Symbol = nullptr; + const UDTLayoutBase *Parent = nullptr; BitVector UsedBytes; std::string Name; uint32_t OffsetInParent = 0; uint32_t SizeOf = 0; + uint32_t LayoutSize = 0; + bool IsElided = false; +}; + +class VBPtrLayoutItem : public LayoutItemBase { +public: + VBPtrLayoutItem(const UDTLayoutBase &Parent, + std::unique_ptr Sym, uint32_t Offset, + uint32_t Size); + virtual bool isVBPtr() const { return true; } + +private: + std::unique_ptr Type; }; -class DataMemberLayoutItem : public StorageItemBase { +class DataMemberLayoutItem : public LayoutItemBase { public: DataMemberLayoutItem(const UDTLayoutBase &Parent, std::unique_ptr DataMember); - virtual uint32_t deepPaddingSize() const; - const PDBSymbolData &getDataMember(); bool hasUDTLayout() const; const ClassLayout &getUDTLayout() const; @@ -75,77 +99,73 @@ private: std::unique_ptr UdtLayout; }; -class VTableLayoutItem : public StorageItemBase { +class VTableLayoutItem : public LayoutItemBase { public: VTableLayoutItem(const UDTLayoutBase &Parent, std::unique_ptr VTable); - ArrayRef funcs() const { return VTableFuncs; } uint32_t getElementSize() const { return ElementSize; } - void setFunction(uint32_t Index, PDBSymbolFunc &Func) { - VTableFuncs[Index] = &Func; - } - private: uint32_t ElementSize = 0; - std::unique_ptr Shape; std::unique_ptr VTable; - std::vector VTableFuncs; }; -class UDTLayoutBase { +class UDTLayoutBase : public LayoutItemBase { template using UniquePtrVector = std::vector>; public: - UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name, - uint32_t Size); - - uint32_t shallowPaddingSize() const; - uint32_t deepPaddingSize() const; - - const BitVector &usedBytes() const { return UsedBytes; } + UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym, + const std::string &Name, uint32_t OffsetInParent, uint32_t Size, + bool IsElided); - uint32_t getClassSize() const { return SizeOf; } + uint32_t tailPadding() const override; - ArrayRef> layout_items() const { - return ChildStorage; - } - - VTableLayoutItem *findVTableAtOffset(uint32_t RelativeOffset); + ArrayRef layout_items() const { return LayoutItems; } - StringRef getUDTName() const { return Name; } + ArrayRef bases() const { return AllBases; } + ArrayRef regular_bases() const { return NonVirtualBases; } + ArrayRef virtual_bases() const { return VirtualBases; } - ArrayRef bases() const { return BaseClasses; } - ArrayRef> vbases() const { - return VirtualBases; - } + uint32_t directVirtualBaseCount() const { return DirectVBaseCount; } ArrayRef> funcs() const { return Funcs; } ArrayRef> other_items() const { return Other; } - const PDBSymbol &getSymbolBase() const { return SymbolBase; } - protected: + bool hasVBPtrAtOffset(uint32_t Off) const; void initializeChildren(const PDBSymbol &Sym); - void addChildToLayout(std::unique_ptr Child); - void addVirtualOverride(PDBSymbolFunc &Func); - void addVirtualIntro(PDBSymbolFunc &Func); + void addChildToLayout(std::unique_ptr Child); - const PDBSymbol &SymbolBase; - std::string Name; - uint32_t SizeOf = 0; + uint32_t DirectVBaseCount = 0; - BitVector UsedBytes; UniquePtrVector Other; UniquePtrVector Funcs; - UniquePtrVector VirtualBases; - UniquePtrVector ChildStorage; - std::vector> ChildrenPerByte; - std::vector BaseClasses; + UniquePtrVector ChildStorage; + std::vector LayoutItems; + + std::vector AllBases; + ArrayRef NonVirtualBases; + ArrayRef VirtualBases; + VTableLayoutItem *VTable = nullptr; + VBPtrLayoutItem *VBPtr = nullptr; +}; + +class BaseClassLayout : public UDTLayoutBase { +public: + BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent, + bool Elide, std::unique_ptr Base); + + const PDBSymbolTypeBaseClass &getBase() const { return *Base; } + bool isVirtualBase() const { return IsVirtualBase; } + bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; } + +private: + std::unique_ptr Base; + bool IsVirtualBase; }; class ClassLayout : public UDTLayoutBase { @@ -156,24 +176,13 @@ public: ClassLayout(ClassLayout &&Other) = default; const PDBSymbolTypeUDT &getClass() const { return UDT; } + uint32_t immediatePadding() const override; private: + BitVector ImmediateUsedBytes; std::unique_ptr OwnedStorage; const PDBSymbolTypeUDT &UDT; }; - -class BaseClassLayout : public UDTLayoutBase, public StorageItemBase { -public: - BaseClassLayout(const UDTLayoutBase &Parent, - std::unique_ptr Base); - - const PDBSymbolTypeBaseClass &getBase() const { return *Base; } - bool isVirtualBase() const { return IsVirtualBase; } - -private: - std::unique_ptr Base; - bool IsVirtualBase; -}; } } // namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h index 84a037b2f998..a3be242b4457 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h +++ b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h @@ -348,7 +348,7 @@ public: // key of the deserializers map to save us from duplicating the string in // the serializer. This should be changed to use a stringpool if we switch // to a map type that may move keys in memory. - std::lock_guard Lock(DeserializersMutex); + std::lock_guard Lock(DeserializersMutex); auto I = Deserializers.insert(Deserializers.begin(), std::make_pair(std::move(Name), @@ -358,7 +358,7 @@ public: { assert(KeyName != nullptr && "No keyname pointer"); - std::lock_guard Lock(SerializersMutex); + std::lock_guard Lock(SerializersMutex); // FIXME: Move capture Serialize once we have C++14. Serializers[ErrorInfoT::classID()] = [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error { @@ -372,7 +372,8 @@ public: } static Error serialize(ChannelT &C, Error &&Err) { - std::lock_guard Lock(SerializersMutex); + std::lock_guard Lock(SerializersMutex); + if (!Err) return serializeSeq(C, std::string()); @@ -386,7 +387,7 @@ public: } static Error deserialize(ChannelT &C, Error &Err) { - std::lock_guard Lock(DeserializersMutex); + std::lock_guard Lock(DeserializersMutex); std::string Key; if (auto Err = deserializeSeq(C, Key)) @@ -406,8 +407,6 @@ public: private: static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) { - assert(EIB.dynamicClassID() != StringError::classID() && - "StringError serialization not registered"); std::string ErrMsg; { raw_string_ostream ErrMsgStream(ErrMsg); @@ -417,17 +416,17 @@ private: inconvertibleErrorCode())); } - static std::mutex SerializersMutex; - static std::mutex DeserializersMutex; + static std::recursive_mutex SerializersMutex; + static std::recursive_mutex DeserializersMutex; static std::map Serializers; static std::map Deserializers; }; template -std::mutex SerializationTraits::SerializersMutex; +std::recursive_mutex SerializationTraits::SerializersMutex; template -std::mutex SerializationTraits::DeserializersMutex; +std::recursive_mutex SerializationTraits::DeserializersMutex; template std::map::WrappedErrorDeserializer> SerializationTraits::Deserializers; +/// Registers a serializer and deserializer for the given error type on the +/// given channel type. +template +void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize, + DeserializeFtor &&Deserialize) { + SerializationTraits::template registerErrorType( + std::move(Name), + std::forward(Serialize), + std::forward(Deserialize)); +} + +/// Registers serialization/deserialization for StringError. template void registerStringError() { static bool AlreadyRegistered = false; if (!AlreadyRegistered) { - SerializationTraits:: - template registerErrorType( - "StringError", - [](ChannelT &C, const StringError &SE) { - return serializeSeq(C, SE.getMessage()); - }, - [](ChannelT &C, Error &Err) { - ErrorAsOutParameter EAO(&Err); - std::string Msg; - if (auto E2 = deserializeSeq(C, Msg)) - return E2; - Err = - make_error(std::move(Msg), - orcError( - OrcErrorCode::UnknownErrorCodeFromRemote)); - return Error::success(); - }); + registerErrorSerialization( + "StringError", + [](ChannelT &C, const StringError &SE) { + return serializeSeq(C, SE.getMessage()); + }, + [](ChannelT &C, Error &Err) -> Error { + ErrorAsOutParameter EAO(&Err); + std::string Msg; + if (auto E2 = deserializeSeq(C, Msg)) + return E2; + Err = + make_error(std::move(Msg), + orcError( + OrcErrorCode::UnknownErrorCodeFromRemote)); + return Error::success(); + }); AlreadyRegistered = true; } } diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index b13f197d25fd..e2cd4c236fcc 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -509,7 +509,7 @@ public: unsigned getSlotIndex(unsigned Slot) const; /// \brief Return the attributes at the given slot. - AttributeList getSlotAttributes(unsigned Slot) const; + AttributeSet getSlotAttributes(unsigned Slot) const; void dump() const; }; diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 47004e82cc19..fd7f96abb19e 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -93,7 +93,7 @@ public: /// /// NB! The returned set does *not* contain **all** possible values of X for /// which "X BinOpC Y" does not wrap -- some viable values of X may be - /// missing, so you cannot use this to contrain X's range. E.g. in the last + /// missing, so you cannot use this to constrain X's range. E.g. in the last /// example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), but (-2) /// is not in the set returned. /// diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index cae03d33a7ee..8f6c85f53efc 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -157,6 +157,10 @@ public: /// This should only be used for debugging as it aborts the program if the /// verification fails. void verifyDomTree() const; + + // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`. + void viewGraph(const Twine &Name, const Twine &Title); + void viewGraph(); }; //===------------------------------------- diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 5415c6b0d151..21d8a15e7e7a 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -629,6 +629,8 @@ def int_amdgcn_readfirstlane : GCCBuiltin<"__builtin_amdgcn_readfirstlane">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrConvergent]>; +// The lane argument must be uniform across the currently active threads of the +// current wave. Otherwise, the result is undefined. def int_amdgcn_readlane : GCCBuiltin<"__builtin_amdgcn_readlane">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>; diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 70c57cf90add..67c35cd22b34 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -319,7 +319,7 @@ public: /// exist, add a prototype for the function and return it. This function /// guarantees to return a constant of pointer to the specified function type /// or a ConstantExpr BitCast of that type if the named function has a - /// different type. This version of the method takes a null terminated list of + /// different type. This version of the method takes a list of /// function arguments, which makes it easier for clients to use. template Constant *getOrInsertFunction(StringRef Name, diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index a4b48d7f3539..00f821399257 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -482,6 +482,17 @@ public: static_cast(this)->stripPointerCasts()); } + /// \brief Strip off pointer casts, all-zero GEPs, aliases and barriers. + /// + /// Returns the original uncasted value. If this is called on a non-pointer + /// value, it returns 'this'. This function should be used only in + /// Alias analysis. + const Value *stripPointerCastsAndBarriers() const; + Value *stripPointerCastsAndBarriers() { + return const_cast( + static_cast(this)->stripPointerCastsAndBarriers()); + } + /// \brief Strip off pointer casts and all-zero GEPs. /// /// Returns the original uncasted value. If this is called on a non-pointer diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h index 06f58d498030..ab027ab27a41 100644 --- a/include/llvm/MC/MCTargetOptions.h +++ b/include/llvm/MC/MCTargetOptions.h @@ -54,6 +54,7 @@ public: int DwarfVersion = 0; std::string ABIName; + std::string SplitDwarfFile; /// Additional paths to search for `.include` directives when using the /// integrated assembler. diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 7a3155b3953e..9c72bd4023d8 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -14,9 +14,19 @@ #ifndef LLVM_OBJECT_ELF_H #define LLVM_OBJECT_ELF_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Object/ELFTypes.h" -#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Object/Error.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include +#include +#include +#include +#include namespace llvm { namespace object { @@ -41,27 +51,27 @@ template class ELFFile { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Ehdr Elf_Ehdr; - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::Dyn Elf_Dyn; - typedef typename ELFT::Phdr Elf_Phdr; - typedef typename ELFT::Rel Elf_Rel; - typedef typename ELFT::Rela Elf_Rela; - typedef typename ELFT::Verdef Elf_Verdef; - typedef typename ELFT::Verdaux Elf_Verdaux; - typedef typename ELFT::Verneed Elf_Verneed; - typedef typename ELFT::Vernaux Elf_Vernaux; - typedef typename ELFT::Versym Elf_Versym; - typedef typename ELFT::Hash Elf_Hash; - typedef typename ELFT::GnuHash Elf_GnuHash; - typedef typename ELFT::DynRange Elf_Dyn_Range; - typedef typename ELFT::ShdrRange Elf_Shdr_Range; - typedef typename ELFT::SymRange Elf_Sym_Range; - typedef typename ELFT::RelRange Elf_Rel_Range; - typedef typename ELFT::RelaRange Elf_Rela_Range; - typedef typename ELFT::PhdrRange Elf_Phdr_Range; + using uintX_t = typename ELFT::uint; + using Elf_Ehdr = typename ELFT::Ehdr; + using Elf_Shdr = typename ELFT::Shdr; + using Elf_Sym = typename ELFT::Sym; + using Elf_Dyn = typename ELFT::Dyn; + using Elf_Phdr = typename ELFT::Phdr; + using Elf_Rel = typename ELFT::Rel; + using Elf_Rela = typename ELFT::Rela; + using Elf_Verdef = typename ELFT::Verdef; + using Elf_Verdaux = typename ELFT::Verdaux; + using Elf_Verneed = typename ELFT::Verneed; + using Elf_Vernaux = typename ELFT::Vernaux; + using Elf_Versym = typename ELFT::Versym; + using Elf_Hash = typename ELFT::Hash; + using Elf_GnuHash = typename ELFT::GnuHash; + using Elf_Dyn_Range = typename ELFT::DynRange; + using Elf_Shdr_Range = typename ELFT::ShdrRange; + using Elf_Sym_Range = typename ELFT::SymRange; + using Elf_Rel_Range = typename ELFT::RelRange; + using Elf_Rela_Range = typename ELFT::RelaRange; + using Elf_Phdr_Range = typename ELFT::PhdrRange; const uint8_t *base() const { return reinterpret_cast(Buf.data()); @@ -70,7 +80,6 @@ public: size_t getBufSize() const { return Buf.size(); } private: - StringRef Buf; public: @@ -161,10 +170,10 @@ public: Expected> getSectionContents(const Elf_Shdr *Sec) const; }; -typedef ELFFile> ELF32LEFile; -typedef ELFFile> ELF64LEFile; -typedef ELFFile> ELF32BEFile; -typedef ELFFile> ELF64BEFile; +using ELF32LEFile = ELFFile>; +using ELF64LEFile = ELFFile>; +using ELF32BEFile = ELFFile>; +using ELF64BEFile = ELFFile>; template inline Expected @@ -194,7 +203,7 @@ ELFFile::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef ShndxTable) const { uint32_t Index = Sym->st_shndx; if (Index == ELF::SHN_XINDEX) { - auto ErrorOrIndex = object::getExtendedSymbolTableIndex( + auto ErrorOrIndex = getExtendedSymbolTableIndex( Sym, Syms.begin(), ShndxTable); if (!ErrorOrIndex) return ErrorOrIndex.takeError(); @@ -519,7 +528,8 @@ inline unsigned hashSysV(StringRef SymbolName) { } return h; } + } // end namespace object } // end namespace llvm -#endif +#endif // LLVM_OBJECT_ELF_H diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 9e95f2958aa4..d8b58b8079fa 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -27,6 +27,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Object/SymbolicFile.h" #include "llvm/Support/ARMAttributeParser.h" +#include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" @@ -42,13 +43,11 @@ namespace llvm { namespace object { class elf_symbol_iterator; -class ELFSymbolRef; -class ELFRelocationRef; class ELFObjectFileBase : public ObjectFile { - friend class ELFSymbolRef; - friend class ELFSectionRef; friend class ELFRelocationRef; + friend class ELFSectionRef; + friend class ELFSymbolRef; protected: ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); @@ -65,7 +64,8 @@ protected: virtual ErrorOr getRelocationAddend(DataRefImpl Rel) const = 0; public: - typedef iterator_range elf_symbol_iterator_range; + using elf_symbol_iterator_range = iterator_range; + virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; elf_symbol_iterator_range symbols() const; @@ -201,14 +201,14 @@ template class ELFObjectFile : public ELFObjectFileBase { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - typedef typename ELFFile::uintX_t uintX_t; + using uintX_t = typename ELFFile::uintX_t; - typedef typename ELFFile::Elf_Sym Elf_Sym; - typedef typename ELFFile::Elf_Shdr Elf_Shdr; - typedef typename ELFFile::Elf_Ehdr Elf_Ehdr; - typedef typename ELFFile::Elf_Rel Elf_Rel; - typedef typename ELFFile::Elf_Rela Elf_Rela; - typedef typename ELFFile::Elf_Dyn Elf_Dyn; + using Elf_Sym = typename ELFFile::Elf_Sym; + using Elf_Shdr = typename ELFFile::Elf_Shdr; + using Elf_Ehdr = typename ELFFile::Elf_Ehdr; + using Elf_Rel = typename ELFFile::Elf_Rel; + using Elf_Rela = typename ELFFile::Elf_Rela; + using Elf_Dyn = typename ELFFile::Elf_Dyn; protected: ELFFile EF; @@ -398,10 +398,10 @@ public: bool isRelocatableObject() const override; }; -typedef ELFObjectFile> ELF32LEObjectFile; -typedef ELFObjectFile> ELF64LEObjectFile; -typedef ELFObjectFile> ELF32BEObjectFile; -typedef ELFObjectFile> ELF64BEObjectFile; +using ELF32LEObjectFile = ELFObjectFile>; +using ELF64LEObjectFile = ELFObjectFile>; +using ELF32BEObjectFile = ELFObjectFile>; +using ELF64BEObjectFile = ELFObjectFile>; template void ELFObjectFile::moveSymbolNext(DataRefImpl &Sym) const { diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 3e03fd8b980e..99346fe1a882 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -11,10 +11,15 @@ #define LLVM_OBJECT_ELFTYPES_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Object/Error.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" -#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/Error.h" +#include +#include +#include +#include namespace llvm { namespace object { @@ -45,58 +50,58 @@ public: static const endianness TargetEndianness = E; static const bool Is64Bits = Is64; - typedef typename std::conditional::type uint; - typedef Elf_Ehdr_Impl> Ehdr; - typedef Elf_Shdr_Impl> Shdr; - typedef Elf_Sym_Impl> Sym; - typedef Elf_Dyn_Impl> Dyn; - typedef Elf_Phdr_Impl> Phdr; - typedef Elf_Rel_Impl, false> Rel; - typedef Elf_Rel_Impl, true> Rela; - typedef Elf_Verdef_Impl> Verdef; - typedef Elf_Verdaux_Impl> Verdaux; - typedef Elf_Verneed_Impl> Verneed; - typedef Elf_Vernaux_Impl> Vernaux; - typedef Elf_Versym_Impl> Versym; - typedef Elf_Hash_Impl> Hash; - typedef Elf_GnuHash_Impl> GnuHash; - typedef Elf_Chdr_Impl> Chdr; - typedef ArrayRef DynRange; - typedef ArrayRef ShdrRange; - typedef ArrayRef SymRange; - typedef ArrayRef RelRange; - typedef ArrayRef RelaRange; - typedef ArrayRef PhdrRange; - - typedef packed Half; - typedef packed Word; - typedef packed Sword; - typedef packed Xword; - typedef packed Sxword; - typedef packed Addr; - typedef packed Off; -}; - -typedef ELFType ELF32LE; -typedef ELFType ELF32BE; -typedef ELFType ELF64LE; -typedef ELFType ELF64BE; + using uint = typename std::conditional::type; + using Ehdr = Elf_Ehdr_Impl>; + using Shdr = Elf_Shdr_Impl>; + using Sym = Elf_Sym_Impl>; + using Dyn = Elf_Dyn_Impl>; + using Phdr = Elf_Phdr_Impl>; + using Rel = Elf_Rel_Impl, false>; + using Rela = Elf_Rel_Impl, true>; + using Verdef = Elf_Verdef_Impl>; + using Verdaux = Elf_Verdaux_Impl>; + using Verneed = Elf_Verneed_Impl>; + using Vernaux = Elf_Vernaux_Impl>; + using Versym = Elf_Versym_Impl>; + using Hash = Elf_Hash_Impl>; + using GnuHash = Elf_GnuHash_Impl>; + using Chdr = Elf_Chdr_Impl>; + using DynRange = ArrayRef; + using ShdrRange = ArrayRef; + using SymRange = ArrayRef; + using RelRange = ArrayRef; + using RelaRange = ArrayRef; + using PhdrRange = ArrayRef; + + using Half = packed; + using Word = packed; + using Sword = packed; + using Xword = packed; + using Sxword = packed; + using Addr = packed; + using Off = packed; +}; + +using ELF32LE = ELFType; +using ELF32BE = ELFType; +using ELF64LE = ELFType; +using ELF64BE = ELFType; // Use an alignment of 2 for the typedefs since that is the worst case for // ELF files in archives. // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. template struct ELFDataTypeTypedefHelperCommon { - typedef support::detail::packed_endian_specific_integral< - uint16_t, target_endianness, 2> Elf_Half; - typedef support::detail::packed_endian_specific_integral< - uint32_t, target_endianness, 2> Elf_Word; - typedef support::detail::packed_endian_specific_integral< - int32_t, target_endianness, 2> Elf_Sword; - typedef support::detail::packed_endian_specific_integral< - uint64_t, target_endianness, 2> Elf_Xword; - typedef support::detail::packed_endian_specific_integral< - int64_t, target_endianness, 2> Elf_Sxword; + using Elf_Half = support::detail::packed_endian_specific_integral< + uint16_t, target_endianness, 2>; + using Elf_Word = support::detail::packed_endian_specific_integral< + uint32_t, target_endianness, 2>; + using Elf_Sword = support::detail::packed_endian_specific_integral< + int32_t, target_endianness, 2>; + using Elf_Xword = support::detail::packed_endian_specific_integral< + uint64_t, target_endianness, 2>; + using Elf_Sxword = support::detail::packed_endian_specific_integral< + int64_t, target_endianness, 2>; }; template struct ELFDataTypeTypedefHelper; @@ -105,34 +110,34 @@ template struct ELFDataTypeTypedefHelper; template struct ELFDataTypeTypedefHelper> : ELFDataTypeTypedefHelperCommon { - typedef uint32_t value_type; - typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, 2> Elf_Addr; - typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, 2> Elf_Off; + using value_type = uint32_t; + using Elf_Addr = support::detail::packed_endian_specific_integral< + value_type, TargetEndianness, 2>; + using Elf_Off = support::detail::packed_endian_specific_integral< + value_type, TargetEndianness, 2>; }; /// ELF 64bit types. template struct ELFDataTypeTypedefHelper> : ELFDataTypeTypedefHelperCommon { - typedef uint64_t value_type; - typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, 2> Elf_Addr; - typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, 2> Elf_Off; + using value_type = uint64_t; + using Elf_Addr = support::detail::packed_endian_specific_integral< + value_type, TargetEndianness, 2>; + using Elf_Off = support::detail::packed_endian_specific_integral< + value_type, TargetEndianness, 2>; }; // I really don't like doing this, but the alternative is copypasta. #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ - typedef typename ELFT::Addr Elf_Addr; \ - typedef typename ELFT::Off Elf_Off; \ - typedef typename ELFT::Half Elf_Half; \ - typedef typename ELFT::Word Elf_Word; \ - typedef typename ELFT::Sword Elf_Sword; \ - typedef typename ELFT::Xword Elf_Xword; \ - typedef typename ELFT::Sxword Elf_Sxword; + using Elf_Addr = typename ELFT::Addr; \ + using Elf_Off = typename ELFT::Off; \ + using Elf_Half = typename ELFT::Half; \ + using Elf_Word = typename ELFT::Word; \ + using Elf_Sword = typename ELFT::Sword; \ + using Elf_Xword = typename ELFT::Xword; \ + using Elf_Sxword = typename ELFT::Sxword; #define LLD_ELF_COMMA , #define LLVM_ELF_IMPORT_TYPES(E, W) \ @@ -222,6 +227,7 @@ struct Elf_Sym_Impl : Elf_Sym_Base { uint64_t getValue() const { return st_value; } void setBinding(unsigned char b) { setBindingAndType(b, getType()); } void setType(unsigned char t) { setBindingAndType(getBinding(), t); } + void setBindingAndType(unsigned char b, unsigned char t) { st_info = (b << 4) + (t & 0x0f); } @@ -238,22 +244,29 @@ struct Elf_Sym_Impl : Elf_Sym_Base { } bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; } + bool isCommon() const { return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON; } + bool isDefined() const { return !isUndefined(); } + bool isProcessorSpecific() const { return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC; } + bool isOSSpecific() const { return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS; } + bool isReserved() const { // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always // true and some compilers warn about it. return st_shndx >= ELF::SHN_LORESERVE; } + bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; } + bool isExternal() const { return getBinding() != ELF::STB_LOCAL; } @@ -277,14 +290,12 @@ struct Elf_Versym_Impl { Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) }; -template struct Elf_Verdaux_Impl; - /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section /// (.gnu.version_d). This structure is identical for ELF32 and ELF64. template struct Elf_Verdef_Impl { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - typedef Elf_Verdaux_Impl Elf_Verdaux; + using Elf_Verdaux = Elf_Verdaux_Impl; Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) Elf_Half vd_ndx; // Version index, used in .gnu.version entries @@ -361,10 +372,10 @@ template struct Elf_Dyn_Impl : Elf_Dyn_Base { using Elf_Dyn_Base::d_tag; using Elf_Dyn_Base::d_un; - typedef typename std::conditional::type intX_t; - typedef typename std::conditional::type uintX_t; + using intX_t = typename std::conditional::type; + using uintX_t = typename std::conditional::type; intX_t getTag() const { return d_tag; } uintX_t getVal() const { return d_un.d_val; } uintX_t getPtr() const { return d_un.d_ptr; } @@ -430,6 +441,7 @@ struct Elf_Rel_Impl, false> { return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); } + void setRInfo(uint64_t R, bool IsMips64EL) { if (IsMips64EL) r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) | @@ -483,15 +495,15 @@ struct Elf_Ehdr_Impl { Elf_Half e_shnum; // Number of entries in the section header table Elf_Half e_shstrndx; // Section header table index of section name // string table + bool checkMagic() const { return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; } + unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } }; -template struct Elf_Phdr_Impl; - template struct Elf_Phdr_Impl> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) @@ -582,7 +594,7 @@ struct Elf_Chdr_Impl> { template struct Elf_Mips_RegInfo; -template +template struct Elf_Mips_RegInfo> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word ri_gprmask; // bit-mask of used general registers @@ -590,7 +602,7 @@ struct Elf_Mips_RegInfo> { Elf_Addr ri_gp_value; // gp register value }; -template +template struct Elf_Mips_RegInfo> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word ri_gprmask; // bit-mask of used general registers @@ -609,7 +621,7 @@ template struct Elf_Mips_Options { Elf_Word info; // Kind-specific information Elf_Mips_RegInfo &getRegInfo() { - assert(kind == llvm::ELF::ODK_REGINFO); + assert(kind == ELF::ODK_REGINFO); return *reinterpret_cast *>( (uint8_t *)this + sizeof(Elf_Mips_Options)); } @@ -637,4 +649,4 @@ template struct Elf_Mips_ABIFlags { } // end namespace object. } // end namespace llvm. -#endif +#endif // LLVM_OBJECT_ELFTYPES_H diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index be0f02aa7f17..b425543bf637 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -25,23 +25,31 @@ #define LLVM_OBJECT_IRSYMTAB_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/GlobalValue.h" #include "llvm/Object/SymbolicFile.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include +#include +#include namespace llvm { namespace irsymtab { + namespace storage { // The data structures in this namespace define the low-level serialization // format. Clients that just want to read a symbol table should use the // irsymtab::Reader class. -typedef support::ulittle32_t Word; +using Word = support::ulittle32_t; /// A reference to a string in the string table. struct Str { Word Offset, Size; + StringRef get(StringRef Strtab) const { return {Strtab.data() + Offset, Size}; } @@ -50,6 +58,7 @@ struct Str { /// A reference to a range of objects in the symbol table. template struct Range { Word Offset, Size; + ArrayRef get(StringRef Symtab) const { return {reinterpret_cast(Symtab.data() + Offset), Size}; } @@ -122,7 +131,7 @@ struct Header { Str COFFLinkerOpts; }; -} +} // end namespace storage /// Fills in Symtab and Strtab with a valid symbol and string table for Mods. Error build(ArrayRef Mods, SmallVector &Symtab, @@ -152,18 +161,22 @@ struct Symbol { int getComdatIndex() const { return ComdatIndex; } using S = storage::Symbol; + GlobalValue::VisibilityTypes getVisibility() const { return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3); } + bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; } bool isWeak() const { return (Flags >> S::FB_weak) & 1; } bool isCommon() const { return (Flags >> S::FB_common) & 1; } bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; } bool isUsed() const { return (Flags >> S::FB_used) & 1; } bool isTLS() const { return (Flags >> S::FB_tls) & 1; } + bool canBeOmittedFromSymbolTable() const { return (Flags >> S::FB_may_omit) & 1; } + bool isGlobal() const { return (Flags >> S::FB_global) & 1; } bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; } bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; } @@ -173,6 +186,7 @@ struct Symbol { assert(isCommon()); return CommonSize; } + uint32_t getCommonAlignment() const { assert(isCommon()); return CommonAlign; @@ -197,9 +211,11 @@ class Reader { ArrayRef Uncommons; StringRef str(storage::Str S) const { return S.get(Strtab); } + template ArrayRef range(storage::Range R) const { return R.get(Symtab); } + const storage::Header &header() const { return *reinterpret_cast(Symtab.data()); } @@ -215,7 +231,7 @@ public: Uncommons = range(header().Uncommons); } - typedef iterator_range> symbol_range; + using symbol_range = iterator_range>; /// Returns the symbol table for the entire bitcode file. /// The symbols enumerated by this method are ephemeral, but they can be @@ -298,8 +314,7 @@ inline Reader::symbol_range Reader::module_symbols(unsigned I) const { SymbolRef(MEnd, MEnd, nullptr, this)}; } -} - -} +} // end namespace irsymtab +} // end namespace llvm -#endif +#endif // LLVM_OBJECT_IRSYMTAB_H diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1ee571cce738..29553558f72f 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -16,10 +16,25 @@ #define LLVM_OBJECT_MACHO_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MachO.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include namespace llvm { namespace object { @@ -28,11 +43,10 @@ namespace object { /// data in code entry in the table in a Mach-O object file. class DiceRef { DataRefImpl DicePimpl; - const ObjectFile *OwningObject; + const ObjectFile *OwningObject = nullptr; public: - DiceRef() : OwningObject(nullptr) { } - + DiceRef() = default; DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); bool operator==(const DiceRef &Other) const; @@ -47,7 +61,7 @@ public: DataRefImpl getRawDataRefImpl() const; const ObjectFile *getObjectFile() const; }; -typedef content_iterator dice_iterator; +using dice_iterator = content_iterator; /// ExportEntry encapsulates the current-state-of-the-walk used when doing a /// non-recursive walk of the trie data structure. This allows you to iterate @@ -71,6 +85,7 @@ public: private: friend class MachOObjectFile; + void moveToFirst(); void moveToEnd(); uint64_t readULEB128(const uint8_t *&p); @@ -80,25 +95,26 @@ private: // Represents a node in the mach-o exports trie. struct NodeState { NodeState(const uint8_t *Ptr); + const uint8_t *Start; const uint8_t *Current; - uint64_t Flags; - uint64_t Address; - uint64_t Other; - const char *ImportName; - unsigned ChildCount; - unsigned NextChildIndex; - unsigned ParentStringLength; - bool IsExportNode; + uint64_t Flags = 0; + uint64_t Address = 0; + uint64_t Other = 0; + const char *ImportName = nullptr; + unsigned ChildCount = 0; + unsigned NextChildIndex = 0; + unsigned ParentStringLength = 0; + bool IsExportNode = false; }; ArrayRef Trie; SmallString<256> CumulativeString; SmallVector Stack; - bool Malformed; - bool Done; + bool Malformed = false; + bool Done = false; }; -typedef content_iterator export_iterator; +using export_iterator = content_iterator; // Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry // can be checked and translated. Only the SegIndex/SegOffset pairs from @@ -106,7 +122,7 @@ typedef content_iterator export_iterator; // address() methods below. class BindRebaseSegInfo { public: - BindRebaseSegInfo(const object::MachOObjectFile *Obj); + BindRebaseSegInfo(const MachOObjectFile *Obj); // Used to check a Mach-O Bind or Rebase entry for errors when iterating. const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset, @@ -130,6 +146,7 @@ private: int32_t SegmentIndex; }; const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset); + SmallVector Sections; int32_t MaxSegIndex; }; @@ -159,6 +176,7 @@ public: private: friend class MachOObjectFile; + void moveToFirst(); void moveToEnd(); uint64_t readULEB128(const char **error); @@ -167,15 +185,15 @@ private: const MachOObjectFile *O; ArrayRef Opcodes; const uint8_t *Ptr; - uint64_t SegmentOffset; - int32_t SegmentIndex; - uint64_t RemainingLoopCount; - uint64_t AdvanceAmount; - uint8_t RebaseType; + uint64_t SegmentOffset = 0; + int32_t SegmentIndex = -1; + uint64_t RemainingLoopCount = 0; + uint64_t AdvanceAmount = 0; + uint8_t RebaseType = 0; uint8_t PointerSize; - bool Done; + bool Done = false; }; -typedef content_iterator rebase_iterator; +using rebase_iterator = content_iterator; /// MachOBindEntry encapsulates the current state in the decompression of /// binding opcodes. This allows you to iterate through the compressed table of @@ -209,6 +227,7 @@ public: private: friend class MachOObjectFile; + void moveToFirst(); void moveToEnd(); uint64_t readULEB128(const char **error); @@ -218,21 +237,21 @@ private: const MachOObjectFile *O; ArrayRef Opcodes; const uint8_t *Ptr; - uint64_t SegmentOffset; - int32_t SegmentIndex; + uint64_t SegmentOffset = 0; + int32_t SegmentIndex = -1; StringRef SymbolName; - bool LibraryOrdinalSet; - int Ordinal; - uint32_t Flags; - int64_t Addend; - uint64_t RemainingLoopCount; - uint64_t AdvanceAmount; - uint8_t BindType; + bool LibraryOrdinalSet = false; + int Ordinal = 0; + uint32_t Flags = 0; + int64_t Addend = 0; + uint64_t RemainingLoopCount = 0; + uint64_t AdvanceAmount = 0; + uint8_t BindType = 0; uint8_t PointerSize; Kind TableKind; - bool Done; + bool Done = false; }; -typedef content_iterator bind_iterator; +using bind_iterator = content_iterator; class MachOObjectFile : public ObjectFile { public: @@ -240,8 +259,8 @@ public: const char *Ptr; // Where in memory the load command is. MachO::load_command C; // The command itself. }; - typedef SmallVector LoadCommandList; - typedef LoadCommandList::const_iterator load_command_iterator; + using LoadCommandList = SmallVector; + using load_command_iterator = LoadCommandList::const_iterator; static Expected> create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, @@ -563,7 +582,7 @@ public: case MachO::PLATFORM_BRIDGEOS: return "bridgeos"; default: std::string ret; - llvm::raw_string_ostream ss(ret); + raw_string_ostream ss(ret); ss << format_hex(platform, 8, true); return ss.str(); } @@ -576,7 +595,7 @@ public: case MachO::TOOL_LD: return "ld"; default: std::string ret; - llvm::raw_string_ostream ss(ret); + raw_string_ostream ss(ret); ss << format_hex(tools, 8, true); return ss.str(); } @@ -595,7 +614,6 @@ public: } private: - MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, Error &Err, uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0); @@ -606,23 +624,23 @@ private: MachO::mach_header_64 Header64; MachO::mach_header Header; }; - typedef SmallVector SectionList; + using SectionList = SmallVector; SectionList Sections; - typedef SmallVector LibraryList; + using LibraryList = SmallVector; LibraryList Libraries; LoadCommandList LoadCommands; - typedef SmallVector LibraryShortName; + using LibraryShortName = SmallVector; using BuildToolList = SmallVector; BuildToolList BuildTools; mutable LibraryShortName LibrariesShortNames; std::unique_ptr BindRebaseSectionTable; - const char *SymtabLoadCmd; - const char *DysymtabLoadCmd; - const char *DataInCodeLoadCmd; - const char *LinkOptHintsLoadCmd; - const char *DyldInfoLoadCmd; - const char *UuidLoadCmd; - bool HasPageZeroSegment; + const char *SymtabLoadCmd = nullptr; + const char *DysymtabLoadCmd = nullptr; + const char *DataInCodeLoadCmd = nullptr; + const char *LinkOptHintsLoadCmd = nullptr; + const char *DyldInfoLoadCmd = nullptr; + const char *UuidLoadCmd = nullptr; + bool HasPageZeroSegment = false; }; /// DiceRef @@ -679,7 +697,7 @@ inline const ObjectFile *DiceRef::getObjectFile() const { return OwningObject; } -} -} +} // end namespace object +} // end namespace llvm -#endif +#endif // LLVM_OBJECT_MACHO_H diff --git a/include/llvm/Object/ModuleSummaryIndexObjectFile.h b/include/llvm/Object/ModuleSummaryIndexObjectFile.h index 713022264ea7..f733f861e2c0 100644 --- a/include/llvm/Object/ModuleSummaryIndexObjectFile.h +++ b/include/llvm/Object/ModuleSummaryIndexObjectFile.h @@ -1,4 +1,4 @@ -//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=// +//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -===// // // The LLVM Compiler Infrastructure // @@ -14,14 +14,22 @@ #ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H #define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H -#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Binary.h" #include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include +#include namespace llvm { + class ModuleSummaryIndex; -class Module; namespace object { + class ObjectFile; /// This class is used to read just the module summary index related @@ -41,15 +49,18 @@ public: void moveSymbolNext(DataRefImpl &Symb) const override { llvm_unreachable("not implemented"); } + std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override { llvm_unreachable("not implemented"); return std::error_code(); } + uint32_t getSymbolFlags(DataRefImpl Symb) const override { llvm_unreachable("not implemented"); return 0; } + basic_symbol_iterator symbol_begin() const override { llvm_unreachable("not implemented"); return basic_symbol_iterator(BasicSymbolRef()); @@ -85,7 +96,8 @@ public: static Expected> create(MemoryBufferRef Object); }; -} + +} // end namespace object /// Parse the module summary index out of an IR file and return the module /// summary index object if found, or nullptr if not. If Identifier is @@ -94,6 +106,7 @@ public: /// containing minimized bitcode just for the thin link. Expected> getModuleSummaryIndexForFile(StringRef Path, StringRef Identifier = ""); -} -#endif +} // end namespace llvm + +#endif // LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H diff --git a/include/llvm/Object/ModuleSymbolTable.h b/include/llvm/Object/ModuleSymbolTable.h index 333301d5b456..9e9322885388 100644 --- a/include/llvm/Object/ModuleSymbolTable.h +++ b/include/llvm/Object/ModuleSymbolTable.h @@ -1,4 +1,4 @@ -//===- ModuleSymbolTable.h - symbol table for in-memory IR ----------------===// +//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,22 +16,24 @@ #ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H #define LLVM_OBJECT_MODULESYMBOLTABLE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/Triple.h" #include "llvm/IR/Mangler.h" #include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/Allocator.h" +#include #include #include +#include namespace llvm { class GlobalValue; -class RecordStreamer; class ModuleSymbolTable { public: - typedef std::pair AsmSymbol; - typedef PointerUnion Symbol; + using AsmSymbol = std::pair; + using Symbol = PointerUnion; private: Module *FirstMod = nullptr; @@ -57,6 +59,6 @@ public: function_ref AsmSymbol); }; -} +} // end namespace llvm -#endif +#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 3a0a62d9283b..73c7ce367cb0 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -1,4 +1,4 @@ -//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===// +//===- RelocVisitor.h - Visitor for object file relocations -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,34 +16,38 @@ #ifndef LLVM_OBJECT_RELOCVISITOR_H #define LLVM_OBJECT_RELOCVISITOR_H +#include "llvm/ADT/Triple.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/MachO.h" -#include "llvm/Support/raw_ostream.h" +#include +#include namespace llvm { namespace object { struct RelocToApply { // The computed value after applying the relevant relocations. - int64_t Value; + int64_t Value = 0; // The width of the value; how many bytes to touch when applying the // relocation. - char Width; + char Width = 0; + + RelocToApply() = default; RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} - RelocToApply() : Value(0), Width(0) {} }; /// @brief Base class for object file relocation visitors. class RelocVisitor { public: - explicit RelocVisitor(const ObjectFile &Obj) - : ObjToVisit(Obj), HasError(false) {} + explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {} // TODO: Should handle multiple applied relocations via either passing in the // previously computed value or just count paired relocations as a single @@ -64,22 +68,22 @@ public: private: const ObjectFile &ObjToVisit; - bool HasError; + bool HasError = false; RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { case Triple::x86_64: switch (RelocType) { - case llvm::ELF::R_X86_64_NONE: + case ELF::R_X86_64_NONE: return visitELF_X86_64_NONE(R); - case llvm::ELF::R_X86_64_64: + case ELF::R_X86_64_64: return visitELF_X86_64_64(R, Value); - case llvm::ELF::R_X86_64_PC32: + case ELF::R_X86_64_PC32: return visitELF_X86_64_PC32(R, Value); - case llvm::ELF::R_X86_64_32: + case ELF::R_X86_64_32: return visitELF_X86_64_32(R, Value); - case llvm::ELF::R_X86_64_32S: + case ELF::R_X86_64_32S: return visitELF_X86_64_32S(R, Value); default: HasError = true; @@ -88,9 +92,9 @@ private: case Triple::aarch64: case Triple::aarch64_be: switch (RelocType) { - case llvm::ELF::R_AARCH64_ABS32: + case ELF::R_AARCH64_ABS32: return visitELF_AARCH64_ABS32(R, Value); - case llvm::ELF::R_AARCH64_ABS64: + case ELF::R_AARCH64_ABS64: return visitELF_AARCH64_ABS64(R, Value); default: HasError = true; @@ -99,9 +103,9 @@ private: case Triple::bpfel: case Triple::bpfeb: switch (RelocType) { - case llvm::ELF::R_BPF_64_64: + case ELF::R_BPF_64_64: return visitELF_BPF_64_64(R, Value); - case llvm::ELF::R_BPF_64_32: + case ELF::R_BPF_64_32: return visitELF_BPF_64_32(R, Value); default: HasError = true; @@ -110,9 +114,9 @@ private: case Triple::mips64el: case Triple::mips64: switch (RelocType) { - case llvm::ELF::R_MIPS_32: + case ELF::R_MIPS_32: return visitELF_MIPS64_32(R, Value); - case llvm::ELF::R_MIPS_64: + case ELF::R_MIPS_64: return visitELF_MIPS64_64(R, Value); default: HasError = true; @@ -121,9 +125,9 @@ private: case Triple::ppc64le: case Triple::ppc64: switch (RelocType) { - case llvm::ELF::R_PPC64_ADDR32: + case ELF::R_PPC64_ADDR32: return visitELF_PPC64_ADDR32(R, Value); - case llvm::ELF::R_PPC64_ADDR64: + case ELF::R_PPC64_ADDR64: return visitELF_PPC64_ADDR64(R, Value); default: HasError = true; @@ -131,9 +135,9 @@ private: } case Triple::systemz: switch (RelocType) { - case llvm::ELF::R_390_32: + case ELF::R_390_32: return visitELF_390_32(R, Value); - case llvm::ELF::R_390_64: + case ELF::R_390_64: return visitELF_390_64(R, Value); default: HasError = true; @@ -141,11 +145,11 @@ private: } case Triple::sparcv9: switch (RelocType) { - case llvm::ELF::R_SPARC_32: - case llvm::ELF::R_SPARC_UA32: + case ELF::R_SPARC_32: + case ELF::R_SPARC_UA32: return visitELF_SPARCV9_32(R, Value); - case llvm::ELF::R_SPARC_64: - case llvm::ELF::R_SPARC_UA64: + case ELF::R_SPARC_64: + case ELF::R_SPARC_UA64: return visitELF_SPARCV9_64(R, Value); default: HasError = true; @@ -153,9 +157,9 @@ private: } case Triple::amdgcn: switch (RelocType) { - case llvm::ELF::R_AMDGPU_ABS32: + case ELF::R_AMDGPU_ABS32: return visitELF_AMDGPU_ABS32(R, Value); - case llvm::ELF::R_AMDGPU_ABS64: + case ELF::R_AMDGPU_ABS64: return visitELF_AMDGPU_ABS64(R, Value); default: HasError = true; @@ -169,11 +173,11 @@ private: switch (ObjToVisit.getArch()) { case Triple::x86: switch (RelocType) { - case llvm::ELF::R_386_NONE: + case ELF::R_386_NONE: return visitELF_386_NONE(R); - case llvm::ELF::R_386_32: + case ELF::R_386_32: return visitELF_386_32(R, Value); - case llvm::ELF::R_386_PC32: + case ELF::R_386_PC32: return visitELF_386_PC32(R, Value); default: HasError = true; @@ -181,7 +185,7 @@ private: } case Triple::ppc: switch (RelocType) { - case llvm::ELF::R_PPC_ADDR32: + case ELF::R_PPC_ADDR32: return visitELF_PPC_ADDR32(R, Value); default: HasError = true; @@ -193,12 +197,12 @@ private: default: HasError = true; return RelocToApply(); - case llvm::ELF::R_ARM_ABS32: + case ELF::R_ARM_ABS32: return visitELF_ARM_ABS32(R, Value); } case Triple::lanai: switch (RelocType) { - case llvm::ELF::R_LANAI_32: + case ELF::R_LANAI_32: return visitELF_Lanai_32(R, Value); default: HasError = true; @@ -207,7 +211,7 @@ private: case Triple::mipsel: case Triple::mips: switch (RelocType) { - case llvm::ELF::R_MIPS_32: + case ELF::R_MIPS_32: return visitELF_MIPS_32(R, Value); default: HasError = true; @@ -215,8 +219,8 @@ private: } case Triple::sparc: switch (RelocType) { - case llvm::ELF::R_SPARC_32: - case llvm::ELF::R_SPARC_UA32: + case ELF::R_SPARC_32: + case ELF::R_SPARC_UA32: return visitELF_SPARC_32(R, Value); default: HasError = true; @@ -224,7 +228,7 @@ private: } case Triple::hexagon: switch (RelocType) { - case llvm::ELF::R_HEX_32: + case ELF::R_HEX_32: return visitELF_HEX_32(R, Value); default: HasError = true; @@ -483,6 +487,7 @@ private: } }; -} -} -#endif +} // end namespace object +} // end namespace llvm + +#endif // LLVM_OBJECT_RELOCVISITOR_H diff --git a/include/llvm/Object/StackMapParser.h b/include/llvm/Object/StackMapParser.h index efea62bb3cb3..0c5e1e38cbaa 100644 --- a/include/llvm/Object/StackMapParser.h +++ b/include/llvm/Object/StackMapParser.h @@ -1,4 +1,4 @@ -//===-------- StackMapParser.h - StackMap Parsing Support -------*- C++ -*-===// +//===- StackMapParser.h - StackMap Parsing Support --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,7 +11,11 @@ #define LLVM_CODEGEN_STACKMAPPARSER_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Endian.h" +#include +#include +#include #include namespace llvm { @@ -19,12 +23,11 @@ namespace llvm { template class StackMapV2Parser { public: - template class AccessorIterator { public: - AccessorIterator(AccessorT A) : A(A) {} + AccessorIterator& operator++() { A = A.next(); return *this; } AccessorIterator operator++(int) { auto tmp = *this; @@ -48,8 +51,8 @@ public: /// Accessor for function records. class FunctionAccessor { friend class StackMapV2Parser; - public: + public: /// Get the function address. uint64_t getFunctionAddress() const { return read(P); @@ -80,13 +83,12 @@ public: /// Accessor for constants. class ConstantAccessor { friend class StackMapV2Parser; - public: + public: /// Return the value of this constant. uint64_t getValue() const { return read(P); } private: - ConstantAccessor(const uint8_t *P) : P(P) {} const static int ConstantAccessorSize = sizeof(uint64_t); @@ -98,20 +100,16 @@ public: const uint8_t *P; }; - // Forward-declare RecordAccessor so we can friend it below. - class RecordAccessor; - enum class LocationKind : uint8_t { Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5 }; - /// Accessor for location records. class LocationAccessor { friend class StackMapV2Parser; friend class RecordAccessor; - public: + public: /// Get the Kind for this location. LocationKind getKind() const { return LocationKind(P[KindOffset]); @@ -144,7 +142,6 @@ public: } private: - LocationAccessor(const uint8_t *P) : P(P) {} LocationAccessor next() const { @@ -163,8 +160,8 @@ public: class LiveOutAccessor { friend class StackMapV2Parser; friend class RecordAccessor; - public: + public: /// Get the Dwarf register number for this live-out. uint16_t getDwarfRegNum() const { return read(P + DwarfRegNumOffset); @@ -176,7 +173,6 @@ public: } private: - LiveOutAccessor(const uint8_t *P) : P(P) {} LiveOutAccessor next() const { @@ -194,10 +190,10 @@ public: /// Accessor for stackmap records. class RecordAccessor { friend class StackMapV2Parser; - public: - typedef AccessorIterator location_iterator; - typedef AccessorIterator liveout_iterator; + public: + using location_iterator = AccessorIterator; + using liveout_iterator = AccessorIterator; /// Get the patchpoint/stackmap ID for this record. uint64_t getID() const { @@ -254,7 +250,6 @@ public: return liveout_iterator(getLiveOut(0)); } - /// End iterator for live-outs. liveout_iterator liveouts_end() const { return liveout_iterator(getLiveOut(getNumLiveOuts())); @@ -266,7 +261,6 @@ public: } private: - RecordAccessor(const uint8_t *P) : P(P) {} unsigned getNumLiveOutsOffset() const { @@ -316,9 +310,9 @@ public: } } - typedef AccessorIterator function_iterator; - typedef AccessorIterator constant_iterator; - typedef AccessorIterator record_iterator; + using function_iterator = AccessorIterator; + using constant_iterator = AccessorIterator; + using record_iterator = AccessorIterator; /// Get the version number of this stackmap. (Always returns 2). unsigned getVersion() const { return 2; } @@ -413,7 +407,6 @@ public: } private: - template static T read(const uint8_t *P) { return support::endian::read(P); @@ -441,6 +434,6 @@ private: std::vector StackMapRecordOffsets; }; -} +} // end namespace llvm -#endif +#endif // LLVM_CODEGEN_STACKMAPPARSER_H diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 43ad62be68b6..6b6bbe252f65 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -17,6 +17,8 @@ #ifndef LLVM_OBJECT_WASM_H #define LLVM_OBJECT_WASM_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" @@ -47,10 +49,10 @@ public: class WasmSection { public: - WasmSection() : Type(0), Offset(0) {} + WasmSection() = default; - uint32_t Type; // Section type (See below) - uint32_t Offset; // Offset with in the file + uint32_t Type = 0; // Section type (See below) + uint32_t Offset = 0; // Offset with in the file StringRef Name; // Section name (User-defined sections only) ArrayRef Content; // Section content std::vector Relocations; // Relocations for this section @@ -74,12 +76,15 @@ public: const std::vector& memories() const { return Memories; } const std::vector& globals() const { return Globals; } const std::vector& exports() const { return Exports; } + const std::vector& elements() const { return ElemSegments; } + const std::vector& dataSegments() const { return DataSegments; } + const std::vector& functions() const { return Functions; } const ArrayRef& code() const { return CodeSection; } uint32_t startFunction() const { return StartFunction; } @@ -178,7 +183,7 @@ private: std::vector Symbols; std::vector Functions; ArrayRef CodeSection; - uint32_t StartFunction; + uint32_t StartFunction = -1; }; } // end namespace object diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index b1af8bbdfa6e..dfeeb8589f82 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -88,7 +88,7 @@ struct Relocation { RelocType Type; uint32_t Index; yaml::Hex32 Offset; - yaml::Hex32 Addend; + int32_t Addend; }; struct DataSegment { diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index c9828858cce3..1b07c33746e7 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -79,14 +79,6 @@ inline StringRef getInstrProfValueRangeProfFuncName() { return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR; } -/// Return the name of the section containing function coverage mapping -/// data. -std::string getInstrProfCoverageSectionName(const Module *M = nullptr); -/// Similar to the above, but used by host tool (e.g, coverage) which has -/// object format information. The section name returned is not prefixed -/// with segment name. -std::string getInstrProfCoverageSectionNameInObject(bool isCoff); - /// Return the name prefix of variables containing instrumented function names. inline StringRef getInstrProfNameVarPrefix() { return "__profn_"; } diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index e8eb50d53eb6..b403d7fbf117 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -112,6 +112,13 @@ public: return *this; } + BranchProbability &operator*=(uint32_t RHS) { + assert(N != UnknownN && + "Unknown probability cannot participate in arithmetics."); + N = (uint64_t(N) * RHS > D) ? D : N * RHS; + return *this; + } + BranchProbability &operator/=(uint32_t RHS) { assert(N != UnknownN && "Unknown probability cannot participate in arithmetics."); @@ -135,6 +142,11 @@ public: return Prob *= RHS; } + BranchProbability operator*(uint32_t RHS) const { + BranchProbability Prob(*this); + return Prob *= RHS; + } + BranchProbability operator/(uint32_t RHS) const { BranchProbability Prob(*this); return Prob /= RHS; diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 29515c231bc4..e3c5de7fbe64 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -116,7 +116,9 @@ inline perms &operator&=(perms &l, perms r) { return l; } inline perms operator~(perms x) { - return static_cast(~static_cast(x)); + // Avoid UB by explicitly truncating the (unsigned) ~ result. + return static_cast( + static_cast(~static_cast(x))); } class UniqueID { diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index eb7c27d2ffa5..851ff7d80403 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -286,13 +286,13 @@ protected: NodeRef NewBBSucc = *GraphT::child_begin(NewBB); std::vector PredBlocks; - for (const auto Pred : children>(NewBB)) + for (const auto &Pred : children>(NewBB)) PredBlocks.push_back(Pred); assert(!PredBlocks.empty() && "No predblocks?"); bool NewBBDominatesNewBBSucc = true; - for (const auto Pred : children>(NewBBSucc)) { + for (const auto &Pred : children>(NewBBSucc)) { if (Pred != NewBB && !dominates(NewBBSucc, Pred) && isReachableFromEntry(Pred)) { NewBBDominatesNewBBSucc = false; diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h new file mode 100644 index 000000000000..08d4dedd0ac8 --- /dev/null +++ b/include/llvm/Support/KnownBits.h @@ -0,0 +1,43 @@ +//===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a class for representing known zeros and ones used by +// computeKnownBits. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_KNOWNBITS_H +#define LLVM_SUPPORT_KNOWNBITS_H + +#include "llvm/ADT/APInt.h" + +namespace llvm { + +// For now this is a simple wrapper around two APInts. +struct KnownBits { + APInt Zero; + APInt One; + + // Default construct Zero and One. + KnownBits() {} + + /// Create a known bits object of BitWidth bits initialized to unknown. + KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {} + + /// Get the bit width of this value. + unsigned getBitWidth() const { + assert(Zero.getBitWidth() == One.getBitWidth() && + "Zero and One should have the same width!"); + return Zero.getBitWidth(); + } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 6d02e4aba48a..ffea679fab82 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -606,7 +606,7 @@ public: template void bitSetCase(T &Val, const char* Str, const T ConstVal) { if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) { - Val = Val | ConstVal; + Val = static_cast(Val | ConstVal); } } @@ -614,7 +614,7 @@ public: template void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) { if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) { - Val = Val | ConstVal; + Val = static_cast(Val | ConstVal); } } diff --git a/include/llvm/Target/GlobalISel/Target.td b/include/llvm/Target/GlobalISel/Target.td index fa1a424b5895..fd2ebca86d60 100644 --- a/include/llvm/Target/GlobalISel/Target.td +++ b/include/llvm/Target/GlobalISel/Target.td @@ -30,21 +30,13 @@ def s64 : LLT; // Definitions that inherit from this may also inherit from // GIComplexPatternEquiv to enable the import of SelectionDAG patterns involving // those ComplexPatterns. -class GIComplexOperandMatcher { +class GIComplexOperandMatcher { // The expected type of the root of the match. // // TODO: We should probably support, any-type, any-scalar, and multiple types // in the future. LLT Type = type; - // The operands that result from a successful match - // Should be of the form '(ops ty1, ty2, ...)' where ty1/ty2 are definitions - // that inherit from Operand. - // - // FIXME: Which definition is used for ty1/ty2 doesn't actually matter at the - // moment. Only the number of operands is used. - dag Operands = operands; - // The function that determines whether the operand matches. It should be of // the form: // bool select(const MatchOperand &Root, MatchOperand &Result1) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 0dc9cf70d335..82a682cf1f7e 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -1108,7 +1108,7 @@ public: /// Return the noop instruction to use for a noop. - virtual void getNoopForMachoTarget(MCInst &NopInst) const; + virtual void getNoop(MCInst &NopInst) const; /// Return true for post-incremented instructions. virtual bool isPostIncrement(const MachineInstr &MI) const { diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 24039ea10816..51f11e1a9a25 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -236,6 +236,12 @@ public: return getPointerTy(DL, DL.getAllocaAddrSpace()); } + /// Return the type for operands of fence. + /// TODO: Let fence operands be of i32 type and remove this. + virtual MVT getFenceOperandTy(const DataLayout &DL) const { + return getPointerTy(DL); + } + /// 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; @@ -2268,7 +2274,8 @@ protected: /// Return true if the value types that can be represented by the specified /// register class are all legal. - bool isLegalRC(const TargetRegisterClass *RC) const; + bool isLegalRC(const TargetRegisterInfo &TRI, + const TargetRegisterClass &RC) const; /// Replace/modify any TargetFrameIndex operands with a targte-dependent /// sequence of memory operands that is recognized by PrologEpilogInserter. @@ -2388,30 +2395,39 @@ public: New = N; return true; } - - /// Check to see if the specified operand of the specified instruction is a - /// constant integer. If so, check to see if there are any bits set in the - /// constant that are not demanded. If so, shrink the constant and return - /// true. - bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded); - - /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This - /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be - /// generalized for targets with other types of implicit widening casts. - bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, - const SDLoc &dl); - - /// Helper for SimplifyDemandedBits that can simplify an operation with - /// multiple uses. This function uses TLI.SimplifyDemandedBits to - /// simplify Operand \p OpIdx of \p User and then updated \p User with - /// the simplified version. No other uses of \p OpIdx are updated. - /// If \p User is the only user of \p OpIdx, this function behaves exactly - /// like TLI.SimplifyDemandedBits except that it also updates the DAG by - /// calling DCI.CommitTargetLoweringOpt. - bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, - const APInt &Demanded, DAGCombinerInfo &DCI); }; + /// Check to see if the specified operand of the specified instruction is a + /// constant integer. If so, check to see if there are any bits set in the + /// constant that are not demanded. If so, shrink the constant and return + /// true. + bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded, + TargetLoweringOpt &TLO) const; + + // Target hook to do target-specific const optimization, which is called by + // ShrinkDemandedConstant. This function should return true if the target + // doesn't want ShrinkDemandedConstant to further optimize the constant. + virtual bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded, + TargetLoweringOpt &TLO) const { + return false; + } + + /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This + /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be + /// generalized for targets with other types of implicit widening casts. + bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, + TargetLoweringOpt &TLO) const; + + /// Helper for SimplifyDemandedBits that can simplify an operation with + /// multiple uses. This function simplifies operand \p OpIdx of \p User and + /// then updates \p User with the simplified version. No other uses of + /// \p OpIdx are updated. If \p User is the only user of \p OpIdx, this + /// function behaves exactly like function SimplifyDemandedBits declared + /// below except that it also updates the DAG by calling + /// DCI.CommitTargetLoweringOpt. + bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, const APInt &Demanded, + DAGCombinerInfo &DCI, TargetLoweringOpt &TLO) const; + /// Look at Op. At this point, we know that only the DemandedMask bits of the /// result of Op are ever used downstream. If we can use this information to /// simplify Op, create a new simplified DAG node and return true, returning diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 3f5daea63ab5..4ce6d2ff5e26 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -40,13 +40,12 @@ class TargetRegisterClass { public: typedef const MCPhysReg* iterator; typedef const MCPhysReg* const_iterator; - typedef const MVT::SimpleValueType* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; // Instance variables filled by tablegen, do not use! const MCRegisterClass *MC; const uint16_t SpillSize, SpillAlignment; - const vt_iterator VTs; + const MVT::SimpleValueType *VTs; const uint32_t *SubClassMask; const uint16_t *SuperRegIndices; const LaneBitmask LaneMask; @@ -93,13 +92,6 @@ public: return MC->contains(Reg1, Reg2); } - /// Return the size of the register in bytes, which is also the size - /// of a stack slot allocated to hold a spilled copy of this register. - unsigned getSize() const { return SpillSize; } - - /// Return the minimum required alignment for a register of this class. - unsigned getAlignment() const { return SpillAlignment; } - /// Return the cost of copying a value between two registers in this class. /// A negative number means the register class is very expensive /// to copy e.g. status flag register classes. @@ -109,26 +101,6 @@ public: /// registers. bool isAllocatable() const { return MC->isAllocatable(); } - /// Return true if this TargetRegisterClass has the ValueType vt. - bool hasType(MVT vt) const { - for(int i = 0; VTs[i] != MVT::Other; ++i) - if (MVT(VTs[i]) == vt) - return true; - return false; - } - - /// vt_begin / vt_end - Loop over all of the value types that can be - /// represented by values in this register class. - vt_iterator vt_begin() const { - return VTs; - } - - vt_iterator vt_end() const { - vt_iterator I = VTs; - while (*I != MVT::Other) ++I; - return I; - } - /// Return true if the specified TargetRegisterClass /// is a proper sub-class of this TargetRegisterClass. bool hasSubClass(const TargetRegisterClass *RC) const { @@ -246,6 +218,7 @@ struct RegClassWeight { class TargetRegisterInfo : public MCRegisterInfo { public: typedef const TargetRegisterClass * const * regclass_iterator; + typedef const MVT::SimpleValueType* vt_iterator; private: const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. @@ -327,6 +300,44 @@ public: return Index | (1u << 31); } + /// Return the size in bits of a register from class RC. + unsigned getRegSizeInBits(const TargetRegisterClass &RC) const { + return RC.SpillSize * 8; + } + + /// Return the size in bytes of the stack slot allocated to hold a spilled + /// copy of a register from class RC. + unsigned getSpillSize(const TargetRegisterClass &RC) const { + return RC.SpillSize; + } + + /// Return the minimum required alignment for a spill slot for a register + /// of this class. + unsigned getSpillAlignment(const TargetRegisterClass &RC) const { + return RC.SpillAlignment; + } + + /// Return true if the given TargetRegisterClass has the ValueType T. + bool isTypeLegalForClass(const TargetRegisterClass &RC, MVT T) const { + for (int i = 0; RC.VTs[i] != MVT::Other; ++i) + if (MVT(RC.VTs[i]) == T) + return true; + return false; + } + + /// Loop over all of the value types that can be represented by values + // in the given register class. + vt_iterator legalclasstypes_begin(const TargetRegisterClass &RC) const { + return RC.VTs; + } + + vt_iterator legalclasstypes_end(const TargetRegisterClass &RC) const { + vt_iterator I = RC.VTs; + while (*I != MVT::Other) + ++I; + return I; + } + /// Returns the Register Class of a physical register of the given type, /// picking the most sub register class of the right type that contains this /// physreg. diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 01a3975a4f2c..db6723da1e61 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -131,7 +131,8 @@ FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false, bool Recover = false, bool UseAfterScope = false); ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false, - bool Recover = false); + bool Recover = false, + bool UseGlobalsGC = true); // Insert MemorySanitizer instrumentation (detection of uninitialized reads) FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0, diff --git a/include/llvm/Transforms/Scalar/ConstantHoisting.h b/include/llvm/Transforms/Scalar/ConstantHoisting.h index 3e2b3327a9fe..edc91add7a73 100644 --- a/include/llvm/Transforms/Scalar/ConstantHoisting.h +++ b/include/llvm/Transforms/Scalar/ConstantHoisting.h @@ -36,6 +36,7 @@ #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H #define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H +#include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/PassManager.h" @@ -98,7 +99,7 @@ public: // Glue for old PM. bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT, - BasicBlock &Entry); + BlockFrequencyInfo *BFI, BasicBlock &Entry); void releaseMemory() { ConstantVec.clear(); @@ -112,6 +113,7 @@ private: const TargetTransformInfo *TTI; DominatorTree *DT; + BlockFrequencyInfo *BFI; BasicBlock *Entry; /// Keeps track of constant candidates found in the function. @@ -124,8 +126,8 @@ private: SmallVector ConstantVec; Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const; - Instruction *findConstantInsertionPoint( - const consthoist::ConstantInfo &ConstInfo) const; + SmallPtrSet + findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo) const; void collectConstantCandidates(ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx, ConstantInt *ConstInt); -- cgit v1.2.3