diff options
Diffstat (limited to 'include/llvm')
71 files changed, 1153 insertions, 780 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 894e5571f8ad5..fe75e25bd8d29 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -182,8 +182,9 @@ private: /// provides a more convenient form of divide for internal use since KnuthDiv /// has specific constraints on its inputs. If those constraints are not met /// then it provides a simpler form of divide. - static void divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS, - unsigned rhsWords, APInt *Quotient, APInt *Remainder); + static void divide(const WordType *LHS, unsigned lhsWords, + const WordType *RHS, unsigned rhsWords, WordType *Quotient, + WordType *Remainder); /// out-of-line slow case for inline constructor void initSlowCase(uint64_t val, bool isSigned); @@ -1016,11 +1017,13 @@ public: /// /// \returns a new APInt value containing the division result APInt udiv(const APInt &RHS) const; + APInt udiv(uint64_t RHS) const; /// \brief Signed division function for APInt. /// /// Signed divide this APInt by APInt RHS. APInt sdiv(const APInt &RHS) const; + APInt sdiv(int64_t RHS) const; /// \brief Unsigned remainder operation. /// @@ -1032,11 +1035,13 @@ public: /// /// \returns a new APInt value containing the remainder result APInt urem(const APInt &RHS) const; + uint64_t urem(uint64_t RHS) const; /// \brief Function for signed remainder operation. /// /// Signed remainder operation on APInt. APInt srem(const APInt &RHS) const; + int64_t srem(int64_t RHS) const; /// \brief Dual division/remainder interface. /// @@ -1047,9 +1052,13 @@ public: /// udivrem(X, Y, X, Y), for example. static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder); + static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient, + uint64_t &Remainder); static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder); + static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient, + int64_t &Remainder); // Operations that return overflow indicators. APInt sadd_ov(const APInt &RHS, bool &Overflow) const; @@ -2015,7 +2024,7 @@ inline APInt operator-(APInt a, const APInt &b) { } inline APInt operator-(const APInt &a, APInt &&b) { - b = -std::move(b); + b.negate(); b += a; return std::move(b); } @@ -2026,7 +2035,7 @@ inline APInt operator-(APInt a, uint64_t RHS) { } inline APInt operator-(uint64_t LHS, APInt b) { - b = -std::move(b); + b.negate(); b += LHS; return b; } diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index b49d216e0b6e7..a0b380b237dab 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -365,6 +365,8 @@ protected: public: using iterator = SmallPtrSetIterator<PtrType>; using const_iterator = SmallPtrSetIterator<PtrType>; + using key_type = ConstPtrType; + using value_type = PtrType; SmallPtrSetImpl(const SmallPtrSetImpl &) = delete; diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 53fa2a50fcbaf..d5ebba409c3d3 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -101,6 +101,16 @@ public: return init(); } + void updateMax(unsigned V) { + unsigned PrevMax = Value.load(std::memory_order_relaxed); + // Keep trying to update max until we succeed or another thread produces + // a bigger max than us. + while (V > PrevMax && !Value.compare_exchange_weak( + PrevMax, V, std::memory_order_relaxed)) { + } + init(); + } + #else // Statistics are disabled in release builds. const Statistic &operator=(unsigned Val) { @@ -131,6 +141,8 @@ public: return *this; } + void updateMax(unsigned V) {} + #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) protected: diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index e3a8a31ba9bc3..3a4a37017d61c 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -252,6 +252,10 @@ public: ObjectFormat == Other.ObjectFormat; } + bool operator!=(const Triple &Other) const { + return !(*this == Other); + } + /// @} /// @name Normalization /// @{ @@ -722,6 +726,12 @@ public: /// \returns true if the triple is little endian, false otherwise. bool isLittleEndian() const; + /// Test whether target triples are compatible. + bool isCompatibleWith(const Triple &Other) const; + + /// Merge target triples. + std::string merge(const Triple &Other) const; + /// @} /// @name Static helpers for IDs. /// @{ diff --git a/include/llvm/Analysis/MemorySSA.h b/include/llvm/Analysis/MemorySSA.h index db31ae9f4f109..f0bba8c4c0209 100644 --- a/include/llvm/Analysis/MemorySSA.h +++ b/include/llvm/Analysis/MemorySSA.h @@ -84,6 +84,7 @@ #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/PHITransAddr.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DerivedUser.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Module.h" #include "llvm/IR/OperandTraits.h" @@ -127,7 +128,7 @@ using const_memoryaccess_def_iterator = // \brief The base for all memory accesses. All memory accesses in a block are // linked together using an intrusive list. class MemoryAccess - : public User, + : public DerivedUser, public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>, public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> { public: @@ -145,15 +146,14 @@ public: MemoryAccess(const MemoryAccess &) = delete; MemoryAccess &operator=(const MemoryAccess &) = delete; - ~MemoryAccess() override; void *operator new(size_t, unsigned) = delete; void *operator new(size_t) = delete; BasicBlock *getBlock() const { return Block; } - virtual void print(raw_ostream &OS) const = 0; - virtual void dump() const; + void print(raw_ostream &OS) const; + void dump() const; /// \brief The user iterators for a memory access typedef user_iterator iterator; @@ -207,11 +207,12 @@ protected: /// \brief Used for debugging and tracking things about MemoryAccesses. /// Guaranteed unique among MemoryAccesses, no guarantees otherwise. - virtual unsigned getID() const = 0; + inline unsigned getID() const; - MemoryAccess(LLVMContext &C, unsigned Vty, BasicBlock *BB, - unsigned NumOperands) - : User(Type::getVoidTy(C), Vty, nullptr, NumOperands), Block(BB) {} + MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue, + BasicBlock *BB, unsigned NumOperands) + : DerivedUser(Type::getVoidTy(C), Vty, nullptr, NumOperands, DeleteValue), + Block(BB) {} private: BasicBlock *Block; @@ -248,21 +249,21 @@ public: // Sadly, these have to be public because they are needed in some of the // iterators. - virtual bool isOptimized() const = 0; - virtual MemoryAccess *getOptimized() const = 0; - virtual void setOptimized(MemoryAccess *) = 0; + inline bool isOptimized() const; + inline MemoryAccess *getOptimized() const; + inline void setOptimized(MemoryAccess *); /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to /// be rewalked by the walker if necessary. /// This really should only be called by tests. - virtual void resetOptimized() = 0; + inline void resetOptimized(); protected: friend class MemorySSA; friend class MemorySSAUpdater; MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty, - Instruction *MI, BasicBlock *BB) - : MemoryAccess(C, Vty, BB, 1), MemoryInst(MI) { + DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB) + : MemoryAccess(C, Vty, DeleteValue, BB, 1), MemoryInst(MI) { setDefiningAccess(DMA); } void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) { @@ -292,7 +293,8 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB) - : MemoryUseOrDef(C, DMA, MemoryUseVal, MI, BB), OptimizedID(0) {} + : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB), + OptimizedID(0) {} // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } @@ -302,32 +304,30 @@ public: return MA->getValueID() == MemoryUseVal; } - void print(raw_ostream &OS) const override; + void print(raw_ostream &OS) const; - virtual void setOptimized(MemoryAccess *DMA) override { + void setOptimized(MemoryAccess *DMA) { OptimizedID = DMA->getID(); setOperand(0, DMA); } - virtual bool isOptimized() const override { + bool isOptimized() const { return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID(); } - virtual MemoryAccess *getOptimized() const override { + MemoryAccess *getOptimized() const { return getDefiningAccess(); } - virtual void resetOptimized() override { + void resetOptimized() { OptimizedID = INVALID_MEMORYACCESS_ID; } protected: friend class MemorySSA; - unsigned getID() const override { - llvm_unreachable("MemoryUses do not have IDs"); - } - private: + static void deleteMe(DerivedUser *Self); + unsigned int OptimizedID; }; @@ -350,8 +350,8 @@ public: MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, unsigned Ver) - : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB), ID(Ver), - Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {} + : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB), + ID(Ver), Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {} // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } @@ -361,27 +361,28 @@ public: return MA->getValueID() == MemoryDefVal; } - virtual void setOptimized(MemoryAccess *MA) override { + void setOptimized(MemoryAccess *MA) { Optimized = MA; OptimizedID = getDefiningAccess()->getID(); } - virtual MemoryAccess *getOptimized() const override { return Optimized; } - virtual bool isOptimized() const override { + MemoryAccess *getOptimized() const { return Optimized; } + bool isOptimized() const { return getOptimized() && getDefiningAccess() && OptimizedID == getDefiningAccess()->getID(); } - virtual void resetOptimized() override { + void resetOptimized() { OptimizedID = INVALID_MEMORYACCESS_ID; } - void print(raw_ostream &OS) const override; + void print(raw_ostream &OS) const; -protected: friend class MemorySSA; - unsigned getID() const override { return ID; } + unsigned getID() const { return ID; } private: + static void deleteMe(DerivedUser *Self); + const unsigned ID; MemoryAccess *Optimized; unsigned int OptimizedID; @@ -432,7 +433,8 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds = 0) - : MemoryAccess(C, MemoryPhiVal, BB, 0), ID(Ver), ReservedSpace(NumPreds) { + : MemoryAccess(C, MemoryPhiVal, deleteMe, BB, 0), ID(Ver), + ReservedSpace(NumPreds) { allocHungoffUses(ReservedSpace); } @@ -534,7 +536,9 @@ public: return V->getValueID() == MemoryPhiVal; } - void print(raw_ostream &OS) const override; + void print(raw_ostream &OS) const; + + unsigned getID() const { return ID; } protected: friend class MemorySSA; @@ -546,8 +550,6 @@ protected: User::allocHungoffUses(N, /* IsPhi */ true); } - unsigned getID() const final { return ID; } - private: // For debugging only const unsigned ID; @@ -561,8 +563,45 @@ private: ReservedSpace = std::max(E + E / 2, 2u); growHungoffUses(ReservedSpace, /* IsPhi */ true); } + + static void deleteMe(DerivedUser *Self); }; +inline unsigned MemoryAccess::getID() const { + assert((isa<MemoryDef>(this) || isa<MemoryPhi>(this)) && + "only memory defs and phis have ids"); + if (const auto *MD = dyn_cast<MemoryDef>(this)) + return MD->getID(); + return cast<MemoryPhi>(this)->getID(); +} + +inline bool MemoryUseOrDef::isOptimized() const { + if (const auto *MD = dyn_cast<MemoryDef>(this)) + return MD->isOptimized(); + return cast<MemoryUse>(this)->isOptimized(); +} + +inline MemoryAccess *MemoryUseOrDef::getOptimized() const { + if (const auto *MD = dyn_cast<MemoryDef>(this)) + return MD->getOptimized(); + return cast<MemoryUse>(this)->getOptimized(); +} + +inline void MemoryUseOrDef::setOptimized(MemoryAccess *MA) { + if (auto *MD = dyn_cast<MemoryDef>(this)) + MD->setOptimized(MA); + else + cast<MemoryUse>(this)->setOptimized(MA); +} + +inline void MemoryUseOrDef::resetOptimized() { + if (auto *MD = dyn_cast<MemoryDef>(this)) + MD->resetOptimized(); + else + cast<MemoryUse>(this)->resetOptimized(); +} + + template <> struct OperandTraits<MemoryPhi> : public HungoffOperandTraits<2> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess) diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index ceca6cb389a10..ac54bd4cfffb2 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -656,10 +656,12 @@ private: /// Test whether this BackedgeTakenInfo contains complete information. bool hasFullInfo() const { return isComplete(); } - /// Return an expression indicating the exact backedge-taken count of the - /// loop if it is known or SCEVCouldNotCompute otherwise. This is the - /// number of times the loop header can be guaranteed to execute, minus - /// one. + /// Return an expression indicating the exact *backedge-taken* + /// count of the loop if it is known or SCEVCouldNotCompute + /// otherwise. If execution makes it to the backedge on every + /// iteration (i.e. there are no abnormal exists like exception + /// throws and thread exits) then this is the number of times the + /// loop header will execute minus one. /// /// If the SCEV predicate associated with the answer can be different /// from AlwaysTrue, we must add a (non null) Predicates argument. @@ -1398,11 +1400,11 @@ public: const SCEV *getExitCount(const Loop *L, BasicBlock *ExitingBlock); /// If the specified loop has a predictable backedge-taken count, return it, - /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count - /// is the number of times the loop header will be branched to from within - /// the loop. This is one less than the trip count of the loop, since it - /// doesn't count the first iteration, when the header is branched to from - /// outside the loop. + /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count is + /// the number of times the loop header will be branched to from within the + /// loop, assuming there are no abnormal exists like exception throws. This is + /// one less than the trip count of the loop, since it doesn't count the first + /// iteration, when the header is branched to from outside the loop. /// /// Note that it is not valid to call this method on a loop without a /// loop-invariant backedge-taken count (see @@ -1417,8 +1419,10 @@ public: const SCEV *getPredicatedBackedgeTakenCount(const Loop *L, SCEVUnionPredicate &Predicates); - /// Similar to getBackedgeTakenCount, except return the least SCEV value - /// that is known never to be less than the actual backedge taken count. + /// When successful, this returns a SCEVConstant that is greater than or equal + /// to (i.e. a "conservative over-approximation") of the value returend by + /// getBackedgeTakenCount. If such a value cannot be computed, it returns the + /// SCEVCouldNotCompute object. const SCEV *getMaxBackedgeTakenCount(const Loop *L); /// Return true if the backedge taken count is either the value returned by diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h index 944250cfd6ac1..0e3bdaa11c9aa 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.h +++ b/include/llvm/Analysis/TargetLibraryInfo.h @@ -191,6 +191,14 @@ public: void setShouldSignExtI32Param(bool Val) { ShouldSignExtI32Param = Val; } + + /// Returns the size of the wchar_t type in bytes. + unsigned getWCharSize(const Module &M) const; + + /// Returns size of the default wchar_t type on target \p T. This is mostly + /// intended to verify that the size in the frontend matches LLVM. All other + /// queries should use getWCharSize() instead. + static unsigned getTargetWCharSize(const Triple &T); }; /// Provides information about what library functions are available for @@ -307,6 +315,11 @@ public: return Attribute::None; } + /// \copydoc TargetLibraryInfoImpl::getWCharSize() + unsigned getWCharSize(const Module &M) const { + return Impl->getWCharSize(M); + } + /// Handle invalidation from the pass manager. /// /// If we try to invalidate this info, just return false. It cannot become diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index f5f323c6b7970..cf24062e46f88 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -218,9 +218,38 @@ template <typename T> class ArrayRef; DL); } - /// Returns true if the GEP is based on a pointer to a string (array of i8), - /// and is indexing into this string. - bool isGEPBasedOnPointerToString(const GEPOperator *GEP); + /// Returns true if the GEP is based on a pointer to a string (array of + // \p CharSize integers) and is indexing into this string. + bool isGEPBasedOnPointerToString(const GEPOperator *GEP, + unsigned CharSize = 8); + + /// Represents offset+length into a ConstantDataArray. + struct ConstantDataArraySlice { + /// ConstantDataArray pointer. nullptr indicates a zeroinitializer (a valid + /// initializer, it just doesn't fit the ConstantDataArray interface). + const ConstantDataArray *Array; + /// Slice starts at this Offset. + uint64_t Offset; + /// Length of the slice. + uint64_t Length; + + /// Moves the Offset and adjusts Length accordingly. + void move(uint64_t Delta) { + assert(Delta < Length); + Offset += Delta; + Length -= Delta; + } + /// Convenience accessor for elements in the slice. + uint64_t operator[](unsigned I) const { + return Array==nullptr ? 0 : Array->getElementAsInteger(I + Offset); + } + }; + + /// Returns true if the value \p V is a pointer into a ContantDataArray. + /// If successfull \p Index will point to a ConstantDataArray info object + /// with an apropriate offset. + bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, + unsigned ElementSize, uint64_t Offset = 0); /// This function computes the length of a null-terminated C string pointed to /// by V. If successful, it returns true and returns the string in Str. If @@ -233,7 +262,7 @@ template <typename T> class ArrayRef; /// If we can compute the length of the string pointed to by the specified /// pointer, return 'len+1'. If we can't, return 0. - uint64_t GetStringLength(const Value *V); + uint64_t GetStringLength(const Value *V, unsigned CharSize = 8); /// This method strips off any GEP address adjustments and pointer casts from /// the specified value, returning the original object being addressed. Note diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index f5b1f87720ad3..181cb375de866 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -189,7 +189,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; void pruneValue(LiveRange &LR, SlotIndex Kill, SmallVectorImpl<SlotIndex> *EndPoints); - /// This function should be used. Its intend is to tell you that + /// This function should not be used. Its intend is to tell you that /// you are doing something wrong if you call pruveValue directly on a /// LiveInterval. Indeed, you are supposed to call pruneValue on the main /// LiveRange and all the LiveRange of the subranges if any. diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index a90fe96227b99..e92bb7f749672 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -56,117 +56,119 @@ class MVT { FIRST_FP_VALUETYPE = f16, LAST_FP_VALUETYPE = ppcf128, - v2i1 = 14, // 2 x i1 - v4i1 = 15, // 4 x i1 - v8i1 = 16, // 8 x i1 - v16i1 = 17, // 16 x i1 - v32i1 = 18, // 32 x i1 - v64i1 = 19, // 64 x i1 - v512i1 = 20, // 512 x i1 - v1024i1 = 21, // 1024 x i1 - - v1i8 = 22, // 1 x i8 - v2i8 = 23, // 2 x i8 - v4i8 = 24, // 4 x i8 - v8i8 = 25, // 8 x i8 - v16i8 = 26, // 16 x i8 - v32i8 = 27, // 32 x i8 - v64i8 = 28, // 64 x i8 - v128i8 = 29, //128 x i8 - v256i8 = 30, //256 x i8 - - v1i16 = 31, // 1 x i16 - v2i16 = 32, // 2 x i16 - v4i16 = 33, // 4 x i16 - v8i16 = 34, // 8 x i16 - v16i16 = 35, // 16 x i16 - v32i16 = 36, // 32 x i16 - v64i16 = 37, // 64 x i16 - v128i16 = 38, //128 x i16 - - v1i32 = 39, // 1 x i32 - v2i32 = 40, // 2 x i32 - v4i32 = 41, // 4 x i32 - v8i32 = 42, // 8 x i32 - v16i32 = 43, // 16 x i32 - v32i32 = 44, // 32 x i32 - v64i32 = 45, // 64 x i32 - - v1i64 = 46, // 1 x i64 - v2i64 = 47, // 2 x i64 - v4i64 = 48, // 4 x i64 - v8i64 = 49, // 8 x i64 - v16i64 = 50, // 16 x i64 - v32i64 = 51, // 32 x i64 - - v1i128 = 52, // 1 x i128 + v1i1 = 14, // 1 x i1 + v2i1 = 15, // 2 x i1 + v4i1 = 16, // 4 x i1 + v8i1 = 17, // 8 x i1 + v16i1 = 18, // 16 x i1 + v32i1 = 19, // 32 x i1 + v64i1 = 20, // 64 x i1 + v512i1 = 21, // 512 x i1 + v1024i1 = 22, // 1024 x i1 + + v1i8 = 23, // 1 x i8 + v2i8 = 24, // 2 x i8 + v4i8 = 25, // 4 x i8 + v8i8 = 26, // 8 x i8 + v16i8 = 27, // 16 x i8 + v32i8 = 28, // 32 x i8 + v64i8 = 29, // 64 x i8 + v128i8 = 30, //128 x i8 + v256i8 = 31, //256 x i8 + + v1i16 = 32, // 1 x i16 + v2i16 = 33, // 2 x i16 + v4i16 = 34, // 4 x i16 + v8i16 = 35, // 8 x i16 + v16i16 = 36, // 16 x i16 + v32i16 = 37, // 32 x i16 + v64i16 = 38, // 64 x i16 + v128i16 = 39, //128 x i16 + + v1i32 = 40, // 1 x i32 + v2i32 = 41, // 2 x i32 + v4i32 = 42, // 4 x i32 + v8i32 = 43, // 8 x i32 + v16i32 = 44, // 16 x i32 + v32i32 = 45, // 32 x i32 + v64i32 = 46, // 64 x i32 + + v1i64 = 47, // 1 x i64 + v2i64 = 48, // 2 x i64 + v4i64 = 49, // 4 x i64 + v8i64 = 50, // 8 x i64 + v16i64 = 51, // 16 x i64 + v32i64 = 52, // 32 x i64 + + v1i128 = 53, // 1 x i128 // Scalable integer types - nxv2i1 = 53, // n x 2 x i1 - nxv4i1 = 54, // n x 4 x i1 - nxv8i1 = 55, // n x 8 x i1 - nxv16i1 = 56, // n x 16 x i1 - nxv32i1 = 57, // n x 32 x i1 - - nxv1i8 = 58, // n x 1 x i8 - nxv2i8 = 59, // n x 2 x i8 - nxv4i8 = 60, // n x 4 x i8 - nxv8i8 = 61, // n x 8 x i8 - nxv16i8 = 62, // n x 16 x i8 - nxv32i8 = 63, // n x 32 x i8 - - nxv1i16 = 64, // n x 1 x i16 - nxv2i16 = 65, // n x 2 x i16 - nxv4i16 = 66, // n x 4 x i16 - nxv8i16 = 67, // n x 8 x i16 - nxv16i16 = 68, // n x 16 x i16 - nxv32i16 = 69, // n x 32 x i16 - - nxv1i32 = 70, // n x 1 x i32 - nxv2i32 = 71, // n x 2 x i32 - nxv4i32 = 72, // n x 4 x i32 - nxv8i32 = 73, // n x 8 x i32 - nxv16i32 = 74, // n x 16 x i32 - nxv32i32 = 75, // n x 32 x i32 - - nxv1i64 = 76, // n x 1 x i64 - nxv2i64 = 77, // n x 2 x i64 - nxv4i64 = 78, // n x 4 x i64 - nxv8i64 = 79, // n x 8 x i64 - nxv16i64 = 80, // n x 16 x i64 - nxv32i64 = 81, // n x 32 x i64 - - FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, + nxv1i1 = 54, // n x 1 x i1 + nxv2i1 = 55, // n x 2 x i1 + nxv4i1 = 56, // n x 4 x i1 + nxv8i1 = 57, // n x 8 x i1 + nxv16i1 = 58, // n x 16 x i1 + nxv32i1 = 59, // n x 32 x i1 + + nxv1i8 = 60, // n x 1 x i8 + nxv2i8 = 61, // n x 2 x i8 + nxv4i8 = 62, // n x 4 x i8 + nxv8i8 = 63, // n x 8 x i8 + nxv16i8 = 64, // n x 16 x i8 + nxv32i8 = 65, // n x 32 x i8 + + nxv1i16 = 66, // n x 1 x i16 + nxv2i16 = 67, // n x 2 x i16 + nxv4i16 = 68, // n x 4 x i16 + nxv8i16 = 69, // n x 8 x i16 + nxv16i16 = 70, // n x 16 x i16 + nxv32i16 = 71, // n x 32 x i16 + + nxv1i32 = 72, // n x 1 x i32 + nxv2i32 = 73, // n x 2 x i32 + nxv4i32 = 74, // n x 4 x i32 + nxv8i32 = 75, // n x 8 x i32 + nxv16i32 = 76, // n x 16 x i32 + nxv32i32 = 77, // n x 32 x i32 + + nxv1i64 = 78, // n x 1 x i64 + nxv2i64 = 79, // n x 2 x i64 + nxv4i64 = 80, // n x 4 x i64 + nxv8i64 = 81, // n x 8 x i64 + nxv16i64 = 82, // n x 16 x i64 + nxv32i64 = 83, // n x 32 x i64 + + FIRST_INTEGER_VECTOR_VALUETYPE = v1i1, LAST_INTEGER_VECTOR_VALUETYPE = nxv32i64, - FIRST_INTEGER_SCALABLE_VALUETYPE = nxv2i1, + FIRST_INTEGER_SCALABLE_VALUETYPE = nxv1i1, LAST_INTEGER_SCALABLE_VALUETYPE = nxv32i64, - v2f16 = 82, // 2 x f16 - v4f16 = 83, // 4 x f16 - v8f16 = 84, // 8 x f16 - v1f32 = 85, // 1 x f32 - v2f32 = 86, // 2 x f32 - v4f32 = 87, // 4 x f32 - v8f32 = 88, // 8 x f32 - v16f32 = 89, // 16 x f32 - v1f64 = 90, // 1 x f64 - v2f64 = 91, // 2 x f64 - v4f64 = 92, // 4 x f64 - v8f64 = 93, // 8 x f64 - - nxv2f16 = 94, // n x 2 x f16 - nxv4f16 = 95, // n x 4 x f16 - nxv8f16 = 96, // n x 8 x f16 - nxv1f32 = 97, // n x 1 x f32 - nxv2f32 = 98, // n x 2 x f32 - nxv4f32 = 99, // n x 4 x f32 - nxv8f32 = 100, // n x 8 x f32 - nxv16f32 = 101, // n x 16 x f32 - nxv1f64 = 102, // n x 1 x f64 - nxv2f64 = 103, // n x 2 x f64 - nxv4f64 = 104, // n x 4 x f64 - nxv8f64 = 105, // n x 8 x f64 + v2f16 = 84, // 2 x f16 + v4f16 = 85, // 4 x f16 + v8f16 = 86, // 8 x f16 + v1f32 = 87, // 1 x f32 + v2f32 = 88, // 2 x f32 + v4f32 = 89, // 4 x f32 + v8f32 = 90, // 8 x f32 + v16f32 = 91, // 16 x f32 + v1f64 = 92, // 1 x f64 + v2f64 = 93, // 2 x f64 + v4f64 = 94, // 4 x f64 + v8f64 = 95, // 8 x f64 + + nxv2f16 = 96, // n x 2 x f16 + nxv4f16 = 97, // n x 4 x f16 + nxv8f16 = 98, // n x 8 x f16 + nxv1f32 = 99, // n x 1 x f32 + nxv2f32 = 100, // n x 2 x f32 + nxv4f32 = 101, // n x 4 x f32 + nxv8f32 = 102, // n x 8 x f32 + nxv16f32 = 103, // n x 16 x f32 + nxv1f64 = 104, // n x 1 x f64 + nxv2f64 = 105, // n x 2 x f64 + nxv4f64 = 106, // n x 4 x f64 + nxv8f64 = 107, // n x 8 x f64 FIRST_FP_VECTOR_VALUETYPE = v2f16, LAST_FP_VECTOR_VALUETYPE = nxv8f64, @@ -174,21 +176,21 @@ class MVT { FIRST_FP_SCALABLE_VALUETYPE = nxv2f16, LAST_FP_SCALABLE_VALUETYPE = nxv8f64, - FIRST_VECTOR_VALUETYPE = v2i1, + FIRST_VECTOR_VALUETYPE = v1i1, LAST_VECTOR_VALUETYPE = nxv8f64, - x86mmx = 106, // This is an X86 MMX value + x86mmx = 108, // This is an X86 MMX value - Glue = 107, // This glues nodes together during pre-RA sched + Glue = 109, // This glues nodes together during pre-RA sched - isVoid = 108, // This has no value + isVoid = 110, // This has no value - Untyped = 109, // This value takes a register, but has + Untyped = 111, // This value takes a register, but has // unspecified type. The register class // will be determined by the opcode. FIRST_VALUETYPE = 1, // This is always the beginning of the list. - LAST_VALUETYPE = 110, // This always remains at the end of the list. + LAST_VALUETYPE = 112, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors @@ -411,6 +413,7 @@ class MVT { switch (SimpleTy) { default: llvm_unreachable("Not a vector MVT!"); + case v1i1: case v2i1: case v4i1: case v8i1: @@ -419,6 +422,7 @@ class MVT { case v64i1: case v512i1: case v1024i1: + case nxv1i1: case nxv2i1: case nxv4i1: case nxv8i1: @@ -589,6 +593,7 @@ class MVT { case nxv2f16: case nxv2f32: case nxv2f64: return 2; + case v1i1: case v1i8: case v1i16: case v1i32: @@ -596,6 +601,7 @@ class MVT { case v1i128: case v1f32: case v1f64: + case nxv1i1: case nxv1i8: case nxv1i16: case nxv1i32: @@ -628,7 +634,9 @@ class MVT { "in codegen and has no size"); case Metadata: llvm_unreachable("Value type is metadata."); - case i1 : return 1; + case i1: + case v1i1: + case nxv1i1: return 1; case v2i1: case nxv2i1: return 2; case v4i1: @@ -814,6 +822,7 @@ class MVT { default: break; case MVT::i1: + if (NumElements == 1) return MVT::v1i1; if (NumElements == 2) return MVT::v2i1; if (NumElements == 4) return MVT::v4i1; if (NumElements == 8) return MVT::v8i1; @@ -891,6 +900,7 @@ class MVT { default: break; case MVT::i1: + if (NumElements == 1) return MVT::nxv1i1; if (NumElements == 2) return MVT::nxv2i1; if (NumElements == 4) return MVT::nxv4i1; if (NumElements == 8) return MVT::nxv8i1; diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 8a5a1997386f2..f3e04cffcda69 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -33,7 +33,7 @@ class raw_ostream; /// List of target independent CodeGen pass IDs. namespace llvm { - FunctionPass *createAtomicExpandPass(const TargetMachine *TM); + FunctionPass *createAtomicExpandPass(); /// createUnreachableBlockEliminationPass - The LLVM code generator does not /// work well with unreachable basic blocks (what live ranges make sense for a @@ -66,7 +66,7 @@ namespace llvm { /// createCodeGenPreparePass - Transform the code to expose more pattern /// matching during instruction selection. - FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr); + FunctionPass *createCodeGenPreparePass(); /// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather /// and scatter intrinsics with scalar code when target doesn't support them. @@ -133,10 +133,6 @@ namespace llvm { // instruction and update the MachineFunctionInfo with that information. extern char &ShrinkWrapID; - /// LiveRangeShrink pass. Move instruction close to its definition to shrink - /// the definition's live range. - extern char &LiveRangeShrinkID; - /// Greedy register allocator. extern char &RAGreedyID; @@ -177,7 +173,7 @@ namespace llvm { /// PrologEpilogCodeInserter - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. extern char &PrologEpilogCodeInserterID; - MachineFunctionPass *createPrologEpilogInserterPass(const TargetMachine *TM); + MachineFunctionPass *createPrologEpilogInserterPass(); /// ExpandPostRAPseudos - This pass expands pseudo instructions after /// register allocation. @@ -305,7 +301,7 @@ namespace llvm { /// createStackProtectorPass - This pass adds stack protectors to functions. /// - FunctionPass *createStackProtectorPass(const TargetMachine *TM); + FunctionPass *createStackProtectorPass(); /// createMachineVerifierPass - This pass verifies cenerated machine code /// instructions for correctness. @@ -314,11 +310,11 @@ namespace llvm { /// createDwarfEHPass - This pass mulches exception handling code into a form /// adapted to code generation. Required if using dwarf exception handling. - FunctionPass *createDwarfEHPass(const TargetMachine *TM); + FunctionPass *createDwarfEHPass(); /// createWinEHPass - Prepares personality functions used by MSVC on Windows, /// in addition to the Itanium LSDA based personalities. - FunctionPass *createWinEHPass(const TargetMachine *TM); + FunctionPass *createWinEHPass(); /// createSjLjEHPreparePass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. @@ -362,12 +358,12 @@ namespace llvm { /// InterleavedAccess Pass - This pass identifies and matches interleaved /// memory accesses to target specific intrinsics. /// - FunctionPass *createInterleavedAccessPass(const TargetMachine *TM); + FunctionPass *createInterleavedAccessPass(); /// LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all /// TLS variables for the emulated TLS model. /// - ModulePass *createLowerEmuTLSPass(const TargetMachine *TM); + ModulePass *createLowerEmuTLSPass(); /// This pass lowers the @llvm.load.relative intrinsic to instructions. /// This is unsafe to do earlier because a pass may combine the constant @@ -384,7 +380,7 @@ namespace llvm { /// This pass splits the stack into a safe stack and an unsafe stack to /// protect against stack-based overflow vulnerabilities. - FunctionPass *createSafeStackPass(const TargetMachine *TM = nullptr); + FunctionPass *createSafeStackPass(); /// This pass detects subregister lanes in a virtual register that are used /// independently of other lanes and splits them into separate virtual @@ -419,33 +415,4 @@ namespace llvm { } // End llvm namespace -/// Target machine pass initializer for passes with dependencies. Use with -/// INITIALIZE_TM_PASS_END. -#define INITIALIZE_TM_PASS_BEGIN INITIALIZE_PASS_BEGIN - -/// Target machine pass initializer for passes with dependencies. Use with -/// INITIALIZE_TM_PASS_BEGIN. -#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) \ - PassInfo *PI = new PassInfo( \ - name, arg, &passName::ID, \ - PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis, \ - PassInfo::TargetMachineCtor_t(callTargetMachineCtor<passName>)); \ - Registry.registerPass(*PI, true); \ - return PI; \ - } \ - static llvm::once_flag Initialize##passName##PassFlag; \ - void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ - llvm::call_once(Initialize##passName##PassFlag, \ - initialize##passName##PassOnce, std::ref(Registry)); \ - } - -/// This initializer registers TargetMachine constructor, so the pass being -/// initialized can use target dependent interfaces. Please do not move this -/// macro to be together with INITIALIZE_PASS, which is a complete target -/// independent initializer, and we don't want to make libScalarOpts depend -/// on libCodeGen. -#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \ - INITIALIZE_TM_PASS_BEGIN(passName, arg, name, cfg, analysis) \ - INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) - #endif diff --git a/include/llvm/CodeGen/StackProtector.h b/include/llvm/CodeGen/StackProtector.h index 0655f19a323e4..b970de71f8628 100644 --- a/include/llvm/CodeGen/StackProtector.h +++ b/include/llvm/CodeGen/StackProtector.h @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/ValueMap.h" #include "llvm/Pass.h" @@ -55,7 +56,7 @@ private: /// TLI - Keep a pointer of a TargetLowering to consult for determining /// target type sizes. const TargetLoweringBase *TLI = nullptr; - const Triple Trip; + Triple Trip; Function *F; Module *M; @@ -114,17 +115,12 @@ private: public: static char ID; // Pass identification, replacement for typeid. - StackProtector() : FunctionPass(ID) { - initializeStackProtectorPass(*PassRegistry::getPassRegistry()); - } - - StackProtector(const TargetMachine *TM) - : FunctionPass(ID), TM(TM), Trip(TM->getTargetTriple()), - SSPBufferSize(8) { + StackProtector() : FunctionPass(ID), SSPBufferSize(8) { initializeStackProtectorPass(*PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<TargetPassConfig>(); AU.addPreserved<DominatorTreeWrapperPass>(); } diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index b87a5e56699eb..b1e62daa5aaeb 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -33,115 +33,117 @@ def f80 : ValueType<80 , 11>; // 80-bit floating point value def f128 : ValueType<128, 12>; // 128-bit floating point value def ppcf128: ValueType<128, 13>; // PPC 128-bit floating point value -def v2i1 : ValueType<2 , 14>; // 2 x i1 vector value -def v4i1 : ValueType<4 , 15>; // 4 x i1 vector value -def v8i1 : ValueType<8 , 16>; // 8 x i1 vector value -def v16i1 : ValueType<16, 17>; // 16 x i1 vector value -def v32i1 : ValueType<32 , 18>; // 32 x i1 vector value -def v64i1 : ValueType<64 , 19>; // 64 x i1 vector value -def v512i1 : ValueType<512, 20>; // 512 x i1 vector value -def v1024i1: ValueType<1024,21>; //1024 x i1 vector value - -def v1i8 : ValueType<8, 22>; // 1 x i8 vector value -def v2i8 : ValueType<16 , 23>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 24>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 25>; // 8 x i8 vector value -def v16i8 : ValueType<128, 26>; // 16 x i8 vector value -def v32i8 : ValueType<256, 27>; // 32 x i8 vector value -def v64i8 : ValueType<512, 28>; // 64 x i8 vector value -def v128i8 : ValueType<1024,29>; //128 x i8 vector value -def v256i8 : ValueType<2048,30>; //256 x i8 vector value - -def v1i16 : ValueType<16 , 31>; // 1 x i16 vector value -def v2i16 : ValueType<32 , 32>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 33>; // 4 x i16 vector value -def v8i16 : ValueType<128, 34>; // 8 x i16 vector value -def v16i16 : ValueType<256, 35>; // 16 x i16 vector value -def v32i16 : ValueType<512, 36>; // 32 x i16 vector value -def v64i16 : ValueType<1024,37>; // 64 x i16 vector value -def v128i16: ValueType<2048,38>; //128 x i16 vector value - -def v1i32 : ValueType<32 , 39>; // 1 x i32 vector value -def v2i32 : ValueType<64 , 40>; // 2 x i32 vector value -def v4i32 : ValueType<128, 41>; // 4 x i32 vector value -def v8i32 : ValueType<256, 42>; // 8 x i32 vector value -def v16i32 : ValueType<512, 43>; // 16 x i32 vector value -def v32i32 : ValueType<1024,44>; // 32 x i32 vector value -def v64i32 : ValueType<2048,45>; // 32 x i32 vector value - -def v1i64 : ValueType<64 , 46>; // 1 x i64 vector value -def v2i64 : ValueType<128, 47>; // 2 x i64 vector value -def v4i64 : ValueType<256, 48>; // 4 x i64 vector value -def v8i64 : ValueType<512, 49>; // 8 x i64 vector value -def v16i64 : ValueType<1024,50>; // 16 x i64 vector value -def v32i64 : ValueType<2048,51>; // 32 x i64 vector value - -def v1i128 : ValueType<128, 52>; // 1 x i128 vector value - -def nxv2i1 : ValueType<2, 53>; // n x 2 x i1 vector value -def nxv4i1 : ValueType<4, 54>; // n x 4 x i1 vector value -def nxv8i1 : ValueType<8, 55>; // n x 8 x i1 vector value -def nxv16i1 : ValueType<16, 56>; // n x 16 x i1 vector value -def nxv32i1 : ValueType<32, 57>; // n x 32 x i1 vector value - -def nxv1i8 : ValueType<8, 58>; // n x 1 x i8 vector value -def nxv2i8 : ValueType<16, 59>; // n x 2 x i8 vector value -def nxv4i8 : ValueType<32, 60>; // n x 4 x i8 vector value -def nxv8i8 : ValueType<64, 61>; // n x 8 x i8 vector value -def nxv16i8 : ValueType<128, 62>; // n x 16 x i8 vector value -def nxv32i8 : ValueType<256, 63>; // n x 32 x i8 vector value - -def nxv1i16 : ValueType<16, 64>; // n x 1 x i16 vector value -def nxv2i16 : ValueType<32, 65>; // n x 2 x i16 vector value -def nxv4i16 : ValueType<64, 66>; // n x 4 x i16 vector value -def nxv8i16 : ValueType<128, 67>; // n x 8 x i16 vector value -def nxv16i16: ValueType<256, 68>; // n x 16 x i16 vector value -def nxv32i16: ValueType<512, 69>; // n x 32 x i16 vector value - -def nxv1i32 : ValueType<32, 70>; // n x 1 x i32 vector value -def nxv2i32 : ValueType<64, 71>; // n x 2 x i32 vector value -def nxv4i32 : ValueType<128, 72>; // n x 4 x i32 vector value -def nxv8i32 : ValueType<256, 73>; // n x 8 x i32 vector value -def nxv16i32: ValueType<512, 74>; // n x 16 x i32 vector value -def nxv32i32: ValueType<1024,75>; // n x 32 x i32 vector value - -def nxv1i64 : ValueType<64, 76>; // n x 1 x i64 vector value -def nxv2i64 : ValueType<128, 77>; // n x 2 x i64 vector value -def nxv4i64 : ValueType<256, 78>; // n x 4 x i64 vector value -def nxv8i64 : ValueType<512, 79>; // n x 8 x i64 vector value -def nxv16i64: ValueType<1024,80>; // n x 16 x i64 vector value -def nxv32i64: ValueType<2048,81>; // n x 32 x i64 vector value - -def v2f16 : ValueType<32 , 82>; // 2 x f16 vector value -def v4f16 : ValueType<64 , 83>; // 4 x f16 vector value -def v8f16 : ValueType<128, 84>; // 8 x f16 vector value -def v1f32 : ValueType<32 , 85>; // 1 x f32 vector value -def v2f32 : ValueType<64 , 86>; // 2 x f32 vector value -def v4f32 : ValueType<128, 87>; // 4 x f32 vector value -def v8f32 : ValueType<256, 88>; // 8 x f32 vector value -def v16f32 : ValueType<512, 89>; // 16 x f32 vector value -def v1f64 : ValueType<64, 90>; // 1 x f64 vector value -def v2f64 : ValueType<128, 91>; // 2 x f64 vector value -def v4f64 : ValueType<256, 92>; // 4 x f64 vector value -def v8f64 : ValueType<512, 93>; // 8 x f64 vector value - -def nxv2f16 : ValueType<32 , 94>; // n x 2 x f16 vector value -def nxv4f16 : ValueType<64 , 95>; // n x 4 x f16 vector value -def nxv8f16 : ValueType<128, 96>; // n x 8 x f16 vector value -def nxv1f32 : ValueType<32 , 97>; // n x 1 x f32 vector value -def nxv2f32 : ValueType<64 , 98>; // n x 2 x f32 vector value -def nxv4f32 : ValueType<128, 99>; // n x 4 x f32 vector value -def nxv8f32 : ValueType<256, 100>; // n x 8 x f32 vector value -def nxv16f32 : ValueType<512, 101>; // n x 16 x f32 vector value -def nxv1f64 : ValueType<64, 102>; // n x 1 x f64 vector value -def nxv2f64 : ValueType<128, 103>; // n x 2 x f64 vector value -def nxv4f64 : ValueType<256, 104>; // n x 4 x f64 vector value -def nxv8f64 : ValueType<512, 105>; // n x 8 x f64 vector value - -def x86mmx : ValueType<64 , 106>; // X86 MMX value -def FlagVT : ValueType<0 , 107>; // Pre-RA sched glue -def isVoid : ValueType<0 , 108>; // Produces no value -def untyped: ValueType<8 , 109>; // Produces an untyped value +def v1i1 : ValueType<1 , 14>; // 1 x i1 vector value +def v2i1 : ValueType<2 , 15>; // 2 x i1 vector value +def v4i1 : ValueType<4 , 16>; // 4 x i1 vector value +def v8i1 : ValueType<8 , 17>; // 8 x i1 vector value +def v16i1 : ValueType<16, 18>; // 16 x i1 vector value +def v32i1 : ValueType<32 , 19>; // 32 x i1 vector value +def v64i1 : ValueType<64 , 20>; // 64 x i1 vector value +def v512i1 : ValueType<512, 21>; // 512 x i1 vector value +def v1024i1: ValueType<1024,22>; //1024 x i1 vector value + +def v1i8 : ValueType<8, 23>; // 1 x i8 vector value +def v2i8 : ValueType<16 , 24>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 25>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 26>; // 8 x i8 vector value +def v16i8 : ValueType<128, 27>; // 16 x i8 vector value +def v32i8 : ValueType<256, 28>; // 32 x i8 vector value +def v64i8 : ValueType<512, 29>; // 64 x i8 vector value +def v128i8 : ValueType<1024,30>; //128 x i8 vector value +def v256i8 : ValueType<2048,31>; //256 x i8 vector value + +def v1i16 : ValueType<16 , 32>; // 1 x i16 vector value +def v2i16 : ValueType<32 , 33>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 34>; // 4 x i16 vector value +def v8i16 : ValueType<128, 35>; // 8 x i16 vector value +def v16i16 : ValueType<256, 36>; // 16 x i16 vector value +def v32i16 : ValueType<512, 37>; // 32 x i16 vector value +def v64i16 : ValueType<1024,38>; // 64 x i16 vector value +def v128i16: ValueType<2048,39>; //128 x i16 vector value + +def v1i32 : ValueType<32 , 40>; // 1 x i32 vector value +def v2i32 : ValueType<64 , 41>; // 2 x i32 vector value +def v4i32 : ValueType<128, 42>; // 4 x i32 vector value +def v8i32 : ValueType<256, 43>; // 8 x i32 vector value +def v16i32 : ValueType<512, 44>; // 16 x i32 vector value +def v32i32 : ValueType<1024,45>; // 32 x i32 vector value +def v64i32 : ValueType<2048,46>; // 32 x i32 vector value + +def v1i64 : ValueType<64 , 47>; // 1 x i64 vector value +def v2i64 : ValueType<128, 48>; // 2 x i64 vector value +def v4i64 : ValueType<256, 49>; // 4 x i64 vector value +def v8i64 : ValueType<512, 50>; // 8 x i64 vector value +def v16i64 : ValueType<1024,51>; // 16 x i64 vector value +def v32i64 : ValueType<2048,52>; // 32 x i64 vector value + +def v1i128 : ValueType<128, 53>; // 1 x i128 vector value + +def nxv1i1 : ValueType<1, 54>; // n x 1 x i1 vector value +def nxv2i1 : ValueType<2, 55>; // n x 2 x i1 vector value +def nxv4i1 : ValueType<4, 56>; // n x 4 x i1 vector value +def nxv8i1 : ValueType<8, 57>; // n x 8 x i1 vector value +def nxv16i1 : ValueType<16, 58>; // n x 16 x i1 vector value +def nxv32i1 : ValueType<32, 59>; // n x 32 x i1 vector value + +def nxv1i8 : ValueType<8, 60>; // n x 1 x i8 vector value +def nxv2i8 : ValueType<16, 61>; // n x 2 x i8 vector value +def nxv4i8 : ValueType<32, 62>; // n x 4 x i8 vector value +def nxv8i8 : ValueType<64, 63>; // n x 8 x i8 vector value +def nxv16i8 : ValueType<128, 64>; // n x 16 x i8 vector value +def nxv32i8 : ValueType<256, 65>; // n x 32 x i8 vector value + +def nxv1i16 : ValueType<16, 66>; // n x 1 x i16 vector value +def nxv2i16 : ValueType<32, 67>; // n x 2 x i16 vector value +def nxv4i16 : ValueType<64, 68>; // n x 4 x i16 vector value +def nxv8i16 : ValueType<128, 69>; // n x 8 x i16 vector value +def nxv16i16: ValueType<256, 70>; // n x 16 x i16 vector value +def nxv32i16: ValueType<512, 71>; // n x 32 x i16 vector value + +def nxv1i32 : ValueType<32, 72>; // n x 1 x i32 vector value +def nxv2i32 : ValueType<64, 73>; // n x 2 x i32 vector value +def nxv4i32 : ValueType<128, 74>; // n x 4 x i32 vector value +def nxv8i32 : ValueType<256, 75>; // n x 8 x i32 vector value +def nxv16i32: ValueType<512, 76>; // n x 16 x i32 vector value +def nxv32i32: ValueType<1024,77>; // n x 32 x i32 vector value + +def nxv1i64 : ValueType<64, 78>; // n x 1 x i64 vector value +def nxv2i64 : ValueType<128, 79>; // n x 2 x i64 vector value +def nxv4i64 : ValueType<256, 80>; // n x 4 x i64 vector value +def nxv8i64 : ValueType<512, 81>; // n x 8 x i64 vector value +def nxv16i64: ValueType<1024,82>; // n x 16 x i64 vector value +def nxv32i64: ValueType<2048,83>; // n x 32 x i64 vector value + +def v2f16 : ValueType<32 , 84>; // 2 x f16 vector value +def v4f16 : ValueType<64 , 85>; // 4 x f16 vector value +def v8f16 : ValueType<128, 86>; // 8 x f16 vector value +def v1f32 : ValueType<32 , 87>; // 1 x f32 vector value +def v2f32 : ValueType<64 , 88>; // 2 x f32 vector value +def v4f32 : ValueType<128, 89>; // 4 x f32 vector value +def v8f32 : ValueType<256, 90>; // 8 x f32 vector value +def v16f32 : ValueType<512, 91>; // 16 x f32 vector value +def v1f64 : ValueType<64, 92>; // 1 x f64 vector value +def v2f64 : ValueType<128, 93>; // 2 x f64 vector value +def v4f64 : ValueType<256, 94>; // 4 x f64 vector value +def v8f64 : ValueType<512, 95>; // 8 x f64 vector value + +def nxv2f16 : ValueType<32 , 96>; // n x 2 x f16 vector value +def nxv4f16 : ValueType<64 , 97>; // n x 4 x f16 vector value +def nxv8f16 : ValueType<128, 98>; // n x 8 x f16 vector value +def nxv1f32 : ValueType<32 , 99>; // n x 1 x f32 vector value +def nxv2f32 : ValueType<64 , 100>; // n x 2 x f32 vector value +def nxv4f32 : ValueType<128, 101>; // n x 4 x f32 vector value +def nxv8f32 : ValueType<256, 102>; // n x 8 x f32 vector value +def nxv16f32 : ValueType<512, 103>; // n x 16 x f32 vector value +def nxv1f64 : ValueType<64, 104>; // n x 1 x f64 vector value +def nxv2f64 : ValueType<128, 105>; // n x 2 x f64 vector value +def nxv4f64 : ValueType<256, 106>; // n x 4 x f64 vector value +def nxv8f64 : ValueType<512, 107>; // n x 8 x f64 vector value + +def x86mmx : ValueType<64 , 108>; // X86 MMX value +def FlagVT : ValueType<0 , 109>; // Pre-RA sched glue +def isVoid : ValueType<0 , 110>; // Produces no value +def untyped: ValueType<8 , 111>; // Produces an untyped value def token : ValueType<0 , 248>; // TokenTy def MetadataVT: ValueType<0, 249>; // Metadata diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index ac8aaafeadc1b..71ea82b6a9abe 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -32,6 +32,10 @@ public: uint32_t length() const { return RecordData.size(); } Kind kind() const { return Type; } ArrayRef<uint8_t> data() const { return RecordData; } + StringRef str_data() const { + return StringRef(reinterpret_cast<const char *>(RecordData.data()), + RecordData.size()); + } ArrayRef<uint8_t> content() const { return RecordData.drop_front(sizeof(RecordPrefix)); diff --git a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h deleted file mode 100644 index 02f14ea2107b2..0000000000000 --- a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h +++ /dev/null @@ -1,61 +0,0 @@ -//===-- CVTypeDumper.h - CodeView type info dumper --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H -#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/DebugInfo/CodeView/TypeDatabase.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/Support/ScopedPrinter.h" - -namespace llvm { - -namespace codeview { - -class TypeServerHandler; - -/// Dumper for CodeView type streams found in COFF object files and PDB files. -class CVTypeDumper { -public: - explicit CVTypeDumper(TypeDatabase &TypeDB, - TypeServerHandler *Handler = nullptr) - : TypeDB(TypeDB), Handler(Handler) {} - - /// Dumps one type record. Returns false if there was a type parsing error, - /// and true otherwise. This should be called in order, since the dumper - /// maintains state about previous records which are necessary for cross - /// type references. - Error dump(const CVType &Record, TypeVisitorCallbacks &Dumper); - - /// Dumps the type records in Types. Returns false if there was a type stream - /// parse error, and true otherwise. - Error dump(const CVTypeArray &Types, TypeVisitorCallbacks &Dumper); - - /// Dumps the type records in Data. Returns false if there was a type stream - /// parse error, and true otherwise. Use this method instead of the - /// CVTypeArray overload when type records are laid out contiguously in - /// memory. - Error dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper); - - static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, - TypeIndex TI, TypeDatabase &DB); - -private: - TypeDatabase &TypeDB; - TypeServerHandler *Handler; -}; - -} // end namespace codeview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index 6d9f345755abd..4bc8fbefd5d83 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -10,42 +10,15 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H -#include "llvm/ADT/TinyPtrVector.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/Support/Error.h" namespace llvm { namespace codeview { - -class CVTypeVisitor { -public: - explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks); - - void addTypeServerHandler(TypeServerHandler &Handler); - - Error visitTypeRecord(CVType &Record, TypeIndex Index); - Error visitTypeRecord(CVType &Record); - Error visitMemberRecord(CVMemberRecord Record); - - /// Visits the type records in Data. Sets the error flag on parse failures. - Error visitTypeStream(const CVTypeArray &Types); - Error visitTypeStream(CVTypeRange Types); - - Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList); - Error visitFieldListMemberStream(BinaryStreamReader Reader); - -private: - Expected<bool> handleTypeServer(CVType &Record); - Error finishVisitation(CVType &Record); - - /// The interface to the class that gets notified of each visitation. - TypeVisitorCallbacks &Callbacks; - - TinyPtrVector<TypeServerHandler *> Handlers; -}; +class TypeCollection; +class TypeServerHandler; +class TypeVisitorCallbacks; enum VisitorDataSource { VDS_BytesPresent, // The record bytes are passed into the the visitation @@ -76,6 +49,8 @@ Error visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks, TypeServerHandler *TS = nullptr); Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks, TypeServerHandler *TS = nullptr); +Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks, + TypeServerHandler *TS = nullptr); } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h index 21288df89be21..0d056e42b45f5 100644 --- a/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h @@ -1,4 +1,4 @@ -//===- RandomAccessTypeVisitor.h ------------------------------ *- C++ --*-===// +//===- LazyRandomTypeCollection.h ---------------------------- *- C++ --*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H -#define LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H -#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/DebugInfo/CodeView/TypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" @@ -21,7 +21,6 @@ namespace llvm { namespace codeview { class TypeDatabase; -class TypeServerHandler; class TypeVisitorCallbacks; /// \brief Provides amortized O(1) random access to a CodeView type stream. @@ -40,32 +39,48 @@ class TypeVisitorCallbacks; /// consumer much better access time, because the consumer can find the nearest /// index in this array, and do a linear scan forward only from there. /// -/// RandomAccessTypeVisitor implements this algorithm, but additionally goes one -/// step further by caching offsets of every record that has been visited at +/// LazyRandomTypeCollection implements this algorithm, but additionally goes +/// one step further by caching offsets of every record that has been visited at /// least once. This way, even repeated visits of the same record will never /// require more than one linear scan. For a type stream of N elements divided /// into M chunks of roughly equal size, this yields a worst case lookup time /// of O(N/M) and an amortized time of O(1). -class RandomAccessTypeVisitor { +class LazyRandomTypeCollection : public TypeCollection { typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray; public: - RandomAccessTypeVisitor(const CVTypeArray &Types, uint32_t NumRecords, - PartialOffsetArray PartialOffsets); - - Error visitTypeIndex(TypeIndex Index, TypeVisitorCallbacks &Callbacks); + explicit LazyRandomTypeCollection(uint32_t RecordCountHint); + LazyRandomTypeCollection(StringRef Data, uint32_t RecordCountHint); + LazyRandomTypeCollection(ArrayRef<uint8_t> Data, uint32_t RecordCountHint); + LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint, + PartialOffsetArray PartialOffsets); + LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint); + + void reset(ArrayRef<uint8_t> Data); + void reset(StringRef Data); + + CVType getType(TypeIndex Index) override; + StringRef getTypeName(TypeIndex Index) override; + bool contains(TypeIndex Index) override; + uint32_t size() override; + uint32_t capacity() override; + Optional<TypeIndex> getFirst() override; + Optional<TypeIndex> getNext(TypeIndex Prev) override; +private: const TypeDatabase &database() const { return Database; } + Error ensureTypeExists(TypeIndex Index); -private: Error visitRangeForType(TypeIndex TI); + Error fullScanForType(TypeIndex TI); Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End); + Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record); /// Visited records get automatically added to the type database. TypeDatabase Database; /// The type array to allow random access visitation of. - const CVTypeArray &Types; + CVTypeArray Types; /// The database visitor which adds new records to the database. TypeDatabaseVisitor DatabaseVisitor; @@ -85,4 +100,4 @@ private: } // end namespace codeview } // end namespace llvm -#endif // LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H +#endif // LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h index a5419b37e7761..e91065dcf87e7 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDumper.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h @@ -20,15 +20,15 @@ namespace llvm { class ScopedPrinter; namespace codeview { -class TypeDatabase; +class TypeCollection; /// Dumper for CodeView symbol streams found in COFF object files and PDB files. class CVSymbolDumper { public: - CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB, + CVSymbolDumper(ScopedPrinter &W, TypeCollection &Types, std::unique_ptr<SymbolDumpDelegate> ObjDelegate, bool PrintRecordBytes) - : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)), + : W(W), Types(Types), ObjDelegate(std::move(ObjDelegate)), PrintRecordBytes(PrintRecordBytes) {} /// Dumps one type record. Returns false if there was a type parsing error, @@ -43,7 +43,7 @@ public: private: ScopedPrinter &W; - TypeDatabase &TypeDB; + TypeCollection &Types; std::unique_ptr<SymbolDumpDelegate> ObjDelegate; bool PrintRecordBytes; diff --git a/include/llvm/DebugInfo/CodeView/TypeCollection.h b/include/llvm/DebugInfo/CodeView/TypeCollection.h new file mode 100644 index 0000000000000..0f856f57a7275 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeCollection.h @@ -0,0 +1,38 @@ +//===- TypeCollection.h - A collection of CodeView type records -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H + +#include "llvm/ADT/StringRef.h" + +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" + +namespace llvm { +namespace codeview { +class TypeCollection { +public: + virtual ~TypeCollection() = default; + + bool empty() { return size() == 0; } + + virtual Optional<TypeIndex> getFirst() = 0; + virtual Optional<TypeIndex> getNext(TypeIndex Prev) = 0; + + virtual CVType getType(TypeIndex Index) = 0; + virtual StringRef getTypeName(TypeIndex Index) = 0; + virtual bool contains(TypeIndex Index) = 0; + virtual uint32_t size() = 0; + virtual uint32_t capacity() = 0; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index 92c15ebd8b2b2..a743e7f70855f 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -13,6 +13,7 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/TypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/Allocator.h" @@ -20,7 +21,7 @@ namespace llvm { namespace codeview { -class TypeDatabase { +class TypeDatabase : public TypeCollection { friend class RandomAccessTypeVisitor; public: @@ -41,19 +42,31 @@ public: CVType &getTypeRecord(TypeIndex Index); bool contains(TypeIndex Index) const; - uint32_t size() const; uint32_t capacity() const; bool empty() const; - TypeIndex getAppendIndex() const; + CVType getType(TypeIndex Index) override; + StringRef getTypeName(TypeIndex Index) override; + bool contains(TypeIndex Index) override; + uint32_t size() override; + uint32_t capacity() override; + + Optional<TypeIndex> getFirst() override; + Optional<TypeIndex> getNext(TypeIndex Prev) override; + + Optional<TypeIndex> largestTypeIndexLessThan(TypeIndex TI) const; private: + TypeIndex getAppendIndex() const; + void grow(); + void grow(TypeIndex Index); BumpPtrAllocator Allocator; uint32_t Count = 0; + TypeIndex LargestTypeIndex; /// All user defined type records in .debug$T live in here. Type indices /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h index 6f10afb30d606..65b3a33e6548d 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h @@ -12,7 +12,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSet.h" -#include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" @@ -22,17 +21,20 @@ class ScopedPrinter; namespace codeview { +class TypeCollection; + /// Dumper for CodeView type streams found in COFF object files and PDB files. class TypeDumpVisitor : public TypeVisitorCallbacks { public: - TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes) - : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {} + TypeDumpVisitor(TypeCollection &TpiTypes, ScopedPrinter *W, + bool PrintRecordBytes) + : W(W), PrintRecordBytes(PrintRecordBytes), TpiTypes(TpiTypes) {} /// When dumping types from an IPI stream in a PDB, a type index may refer to /// a type or an item ID. The dumper will lookup the "name" of the index in /// the item database if appropriate. If ItemDB is null, it will use TypeDB, /// which is correct when dumping types from an object file (/Z7). - void setItemDB(TypeDatabase &DB) { ItemDB = &DB; } + void setIpiTypes(TypeCollection &Types) { IpiTypes = &Types; } void printTypeIndex(StringRef FieldName, TypeIndex TI) const; @@ -66,14 +68,16 @@ private: /// Get the database of indices for the stream that we are dumping. If ItemDB /// is set, then we must be dumping an item (IPI) stream. This will also /// always get the appropriate DB for printing item names. - TypeDatabase &getSourceDB() const { return ItemDB ? *ItemDB : TypeDB; } + TypeCollection &getSourceTypes() const { + return IpiTypes ? *IpiTypes : TpiTypes; + } ScopedPrinter *W; bool PrintRecordBytes = false; - TypeDatabase &TypeDB; - TypeDatabase *ItemDB = nullptr; + TypeCollection &TpiTypes; + TypeCollection *IpiTypes = nullptr; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h index b5d695fc49d5b..31eed7d3e877a 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndex.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h @@ -15,8 +15,13 @@ #include <cinttypes> namespace llvm { + +class ScopedPrinter; + namespace codeview { +class TypeCollection; + enum class SimpleTypeKind : uint32_t { None = 0x0000, // uncharacterized type (no type) Void = 0x0003, // void @@ -238,6 +243,11 @@ public: return Result; } + friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) { + assert(A >= B); + return A.toArrayIndex() - B.toArrayIndex(); + } + private: support::ulittle32_t Index; }; @@ -249,6 +259,9 @@ struct TypeIndexOffset { TypeIndex Type; support::ulittle32_t Offset; }; + +void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, + TypeCollection &Types); } } diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index 1f4873c4f9693..6dad98247136f 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -70,6 +70,8 @@ class TypeSerializer : public TypeVisitorCallbacks { MutableArrayRef<uint8_t> getCurrentRecordData(); Error writeRecordPrefix(TypeLeafKind Kind); TypeIndex insertRecordBytesPrivate(MutableArrayRef<uint8_t> Record); + TypeIndex insertRecordBytesWithCopy(CVType &Record, + MutableArrayRef<uint8_t> Data); Expected<MutableArrayRef<uint8_t>> addPadding(MutableArrayRef<uint8_t> Record); diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index 2246f197e7843..65bcf9812e687 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -12,17 +12,20 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/Error.h" namespace llvm { namespace codeview { +class TypeIndex; class TypeServerHandler; +class TypeTableBuilder; /// Merges one type stream into another. Returns true on success. Error mergeTypeStreams(TypeTableBuilder &DestIdStream, TypeTableBuilder &DestTypeStream, + SmallVectorImpl<TypeIndex> &SourceToDest, TypeServerHandler *Handler, const CVTypeArray &Types); } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/include/llvm/DebugInfo/CodeView/TypeTableCollection.h new file mode 100644 index 0000000000000..7de562a19a741 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeTableCollection.h @@ -0,0 +1,42 @@ +//===- TypeTableCollection.h ---------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H + +#include "llvm/DebugInfo/CodeView/TypeCollection.h" +#include "llvm/DebugInfo/CodeView/TypeDatabase.h" + +namespace llvm { +namespace codeview { + +class TypeTableCollection : public TypeCollection { +public: + explicit TypeTableCollection(ArrayRef<MutableArrayRef<uint8_t>> Records); + + Optional<TypeIndex> getFirst() override; + Optional<TypeIndex> getNext(TypeIndex Prev) override; + + CVType getType(TypeIndex Index) override; + StringRef getTypeName(TypeIndex Index) override; + bool contains(TypeIndex Index) override; + uint32_t size() override; + uint32_t capacity() override; + +private: + bool hasCapacityFor(TypeIndex Index) const; + void ensureTypeExists(TypeIndex Index); + + ArrayRef<MutableArrayRef<uint8_t>> Records; + TypeDatabase Database; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h index 2950c7d27cb68..0ea754deb425a 100644 --- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h +++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h @@ -17,8 +17,6 @@ namespace llvm { namespace codeview { class TypeVisitorCallbacks { - friend class CVTypeVisitor; - public: virtual ~TypeVisitorCallbacks() = default; diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index a46d46a5bff31..46c0b7f4ce605 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -19,8 +19,9 @@ class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, - StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, - bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, + StringRef SS, StringRef SOS, const DWARFSection *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 ca82a68ead31a..d3a63edf10ffe 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -235,7 +235,7 @@ public: virtual StringRef getStringDWOSection() = 0; virtual StringRef getStringOffsetDWOSection() = 0; virtual const DWARFSection &getRangeDWOSection() = 0; - virtual StringRef getAddrSection() = 0; + virtual const DWARFSection &getAddrSection() = 0; virtual const DWARFSection& getAppleNamesSection() = 0; virtual const DWARFSection& getAppleTypesSection() = 0; virtual const DWARFSection& getAppleNamespacesSection() = 0; @@ -290,7 +290,7 @@ class DWARFContextInMemory : public DWARFContext { StringRef StringDWOSection; StringRef StringOffsetDWOSection; DWARFSection RangeDWOSection; - StringRef AddrSection; + DWARFSection AddrSection; DWARFSection AppleNamesSection; DWARFSection AppleTypesSection; DWARFSection AppleNamespacesSection; @@ -356,9 +356,7 @@ public: const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; } - StringRef getAddrSection() override { - return AddrSection; - } + const DWARFSection &getAddrSection() override { return AddrSection; } StringRef getCUIndexSection() override { return CUIndexSection; } StringRef getGdbIndexSection() override { return GdbIndexSection; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h index ec0397a0fb099..fabacc0abcea9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -17,7 +17,7 @@ namespace llvm { struct RelocAddrEntry { - int64_t Value; + uint64_t Value; }; /// In place of applying the relocations to the data we've read from disk we use diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index c9da2c9a3e164..c77d946c070a6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -31,8 +31,9 @@ private: public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, - StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, - bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, + StringRef SS, StringRef SOS, const DWARFSection *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 c15e27f36a8b6..ae7fd24ce5bb9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -57,7 +57,7 @@ protected: virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, - StringRef SS, StringRef SOS, StringRef AOS, + StringRef SS, StringRef SOS, const DWARFSection *AOS, StringRef LS, bool isLittleEndian, bool isDWO) = 0; }; @@ -89,8 +89,8 @@ public: private: void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, - StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, - bool LE, bool IsDWO) override { + StringRef SS, StringRef SOS, const DWARFSection *AOS, + StringRef LS, bool LE, bool IsDWO) override { if (Parsed) return; const auto &Index = getDWARFUnitIndex(Context, UnitType::Section); @@ -120,7 +120,7 @@ class DWARFUnit { StringRef LineSection; StringRef StringSection; StringRef StringOffsetSection; - StringRef AddrOffsetSection; + const DWARFSection *AddrOffsetSection; uint32_t AddrOffsetSectionBase; bool isLittleEndian; bool isDWO; @@ -149,7 +149,7 @@ class DWARFUnit { DWARFUnit *DWOU = nullptr; public: - DWOHolder(StringRef DWOPath); + DWOHolder(StringRef DWOPath, uint64_t DWOId); DWARFUnit *getUnit() const { return DWOU; } }; @@ -172,8 +172,8 @@ protected: public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, + StringRef SOS, const DWARFSection *AOS, StringRef LS, bool LE, + bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry = nullptr); virtual ~DWARFUnit(); @@ -184,7 +184,7 @@ public: StringRef getStringSection() const { return StringSection; } StringRef getStringOffsetSection() const { return StringOffsetSection; } - void setAddrOffsetSection(StringRef AOS, uint32_t Base) { + void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) { AddrOffsetSection = AOS; AddrOffsetSectionBase = Base; } diff --git a/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h b/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h index d965e1008e95a..bfd38b6c80ecf 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h @@ -13,7 +13,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeServerHandler.h" #include "llvm/DebugInfo/PDB/Native/NativeSession.h" diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h index 6c609c34665ca..21cfa83e6af4e 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h @@ -72,7 +72,7 @@ private: size_t TypeRecordBytes = 0; - Optional<PdbRaw_TpiVer> VerHeader; + PdbRaw_TpiVer VerHeader = PdbRaw_TpiVer::PdbTpiV80; std::vector<ArrayRef<uint8_t>> TypeRecords; std::vector<uint32_t> TypeHashes; std::vector<codeview::TypeIndexOffset> TypeIndexOffsets; diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 5ed6d030c9843..3efcc637b6eda 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -27,8 +27,7 @@ namespace llvm { /// for a specific function. When used in the body of said function, the /// argument of course represents the value of the actual argument that the /// function was called with. -class Argument : public Value { - virtual void anchor(); +class Argument final : public Value { Function *Parent; unsigned ArgNo; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 97989cf5c6525..c917b1f2cada1 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -51,8 +51,8 @@ class ValueSymbolTable; /// occur because it may be useful in the intermediate stage of constructing or /// modifying a program. However, the verifier will ensure that basic blocks /// are "well formed". -class BasicBlock : public Value, // Basic blocks are data objects also - public ilist_node_with_parent<BasicBlock, Function> { +class BasicBlock final : public Value, // Basic blocks are data objects also + public ilist_node_with_parent<BasicBlock, Function> { public: using InstListType = SymbolTableList<Instruction>; @@ -77,7 +77,7 @@ private: public: BasicBlock(const BasicBlock &) = delete; BasicBlock &operator=(const BasicBlock &) = delete; - ~BasicBlock() override; + ~BasicBlock(); /// \brief Get the context in which this basic block lives. LLVMContext &getContext() const; diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 3b3694e7e60d0..82afd9a2691f5 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -40,8 +40,6 @@ class APInt; /// don't have to worry about the lifetime of the objects. /// @brief LLVM Constant Representation class Constant : public User { - void anchor() override; - protected: Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) : User(ty, vty, Ops, NumOps) {} diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 5db9b3bb50483..40a8d1eb27d06 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -58,8 +58,6 @@ template <class ConstantClass> struct ConstantAggrKeyType; class ConstantData : public Constant { friend class Constant; - void anchor() override; - Value *handleOperandChangeImpl(Value *From, Value *To) { llvm_unreachable("Constant data does not have operands!"); } @@ -93,7 +91,6 @@ class ConstantInt final : public ConstantData { ConstantInt(IntegerType *Ty, const APInt& V); - void anchor() override; void destroyConstantImpl(); public: @@ -274,7 +271,6 @@ class ConstantFP final : public ConstantData { ConstantFP(Type *Ty, const APFloat& V); - void anchor() override; void destroyConstantImpl(); public: @@ -588,7 +584,7 @@ class ConstantDataSequential : public ConstantData { protected: explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data) : ConstantData(ty, VT), DataElements(Data), Next(nullptr) {} - ~ConstantDataSequential() override { delete Next; } + ~ConstantDataSequential() { delete Next; } static Constant *getImpl(StringRef Bytes, Type *Ty); @@ -638,8 +634,8 @@ public: /// The size of the elements is known to be a multiple of one byte. uint64_t getElementByteSize() const; - /// This method returns true if this is an array of i8. - bool isString() const; + /// This method returns true if this is an array of \p CharSize integers. + bool isString(unsigned CharSize = 8) const; /// This method returns true if the array "isString", ends with a null byte, /// and does not contains any other null bytes. @@ -692,8 +688,6 @@ class ConstantDataArray final : public ConstantDataSequential { return User::operator new(s, 0); } - void anchor() override; - public: ConstantDataArray(const ConstantDataArray &) = delete; @@ -755,8 +749,6 @@ class ConstantDataVector final : public ConstantDataSequential { return User::operator new(s, 0); } - void anchor() override; - public: ConstantDataVector(const ConstantDataVector &) = delete; diff --git a/include/llvm/IR/DerivedUser.h b/include/llvm/IR/DerivedUser.h new file mode 100644 index 0000000000000..4d681e0db6111 --- /dev/null +++ b/include/llvm/IR/DerivedUser.h @@ -0,0 +1,41 @@ +//===-- DerivedUser.h - Base for non-IR Users -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_DERIVEDUSER_H +#define LLVM_IR_DERIVEDUSER_H + +#include "llvm/IR/User.h" + +namespace llvm { + +/// Extension point for the Value hierarchy. All classes outside of lib/IR +/// that wish to inherit from User should instead inherit from DerivedUser +/// instead. Inheriting from this class is discouraged. +/// +/// Generally speaking, Value is the base of a closed class hierarchy +/// that can't be extended by code outside of lib/IR. This class creates a +/// loophole that allows classes outside of lib/IR to extend User to leverage +/// its use/def list machinery. +class DerivedUser : public User { +protected: + typedef void (*DeleteValueTy)(DerivedUser *); + +private: + friend Value; + DeleteValueTy DeleteValue; + +public: + DerivedUser(Type *Ty, unsigned VK, Use *U, unsigned NumOps, + DeleteValueTy DeleteValue) + : User(Ty, VK, U, NumOps), DeleteValue(DeleteValue) {} +}; + +} // namespace llvm + +#endif // LLVM_IR_DERIVEDUSER_H diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 8a2a6ed87eb28..f27e5c50a47f2 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -123,7 +123,7 @@ private: public: Function(const Function&) = delete; void operator=(const Function&) = delete; - ~Function() override; + ~Function(); static Function *Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N = "", Module *M = nullptr) { diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 0793a1c0ee2ed..20495725f9d0f 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -161,6 +161,10 @@ protected: Parent = parent; } + ~GlobalValue() { + removeDeadConstantUsers(); // remove any dead constants using this. + } + public: enum ThreadLocalMode { NotThreadLocal = 0, @@ -172,10 +176,6 @@ public: GlobalValue(const GlobalValue &) = delete; - ~GlobalValue() override { - removeDeadConstantUsers(); // remove any dead constants using this. - } - unsigned getAlignment() const; enum class UnnamedAddr { diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index 21d334c8f01db..3f5d00bd3b3ac 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -66,7 +66,7 @@ public: GlobalVariable(const GlobalVariable &) = delete; GlobalVariable &operator=(const GlobalVariable &) = delete; - ~GlobalVariable() override { + ~GlobalVariable() { dropAllReferences(); // FIXME: needed by operator delete diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index a57e7d63012b3..7f03fcd19b650 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -28,7 +28,7 @@ class FunctionType; class PointerType; template <class ConstantClass> class ConstantUniqueMap; -class InlineAsm : public Value { +class InlineAsm final : public Value { public: enum AsmDialect { AD_ATT, @@ -48,7 +48,6 @@ private: InlineAsm(FunctionType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects, bool isAlignStack, AsmDialect asmDialect); - ~InlineAsm() override; /// When the ConstantUniqueMap merges two types and makes two InlineAsms /// identical, it destroys one of them with this method. diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 61ca90de7393c..e850c015d7118 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -62,9 +62,6 @@ protected: Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} - // Out of line virtual method, so the vtable, etc has a home. - ~TerminatorInst() override; - public: /// Return the number of successors that this terminator has. unsigned getNumSuccessors() const; @@ -299,9 +296,6 @@ public: void *operator new(size_t, unsigned) = delete; - // Out of line virtual method, so the vtable, etc has a home. - ~UnaryInstruction() override; - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -568,8 +562,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) /// if (isa<CastInst>(Instr)) { ... } /// @brief Base class of casting instructions. class CastInst : public UnaryInstruction { - void anchor() override; - protected: /// @brief Constructor with insert-before-instruction semantics for subclasses CastInst(Type *Ty, unsigned iType, Value *S, @@ -914,8 +906,6 @@ protected: Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd); - void anchor() override; // Out of line virtual method. - public: CmpInst() = delete; diff --git a/include/llvm/IR/Instruction.def b/include/llvm/IR/Instruction.def index 18711abb8060d..86617299c44ac 100644 --- a/include/llvm/IR/Instruction.def +++ b/include/llvm/IR/Instruction.def @@ -102,6 +102,10 @@ #define LAST_OTHER_INST(num) #endif +#ifndef HANDLE_USER_INST +#define HANDLE_USER_INST(num, opc, Class) HANDLE_OTHER_INST(num, opc, Class) +#endif + // Terminator Instructions - These instructions are used to terminate a basic // block of the program. Every basic block must end with one of these // instructions for it to be a well formed basic block. @@ -185,8 +189,8 @@ HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr. HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(56, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(57, UserOp2, Instruction) // Internal to passes only +HANDLE_USER_INST (56, UserOp1, Instruction) // May be used internally in a pass +HANDLE_USER_INST (57, UserOp2, Instruction) // Internal to passes only HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector @@ -220,6 +224,8 @@ HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction. #undef HANDLE_OTHER_INST #undef LAST_OTHER_INST +#undef HANDLE_USER_INST + #ifdef HANDLE_INST #undef HANDLE_INST #endif diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index fca29900f4c29..6e109735ddd36 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -36,6 +36,10 @@ class FastMathFlags; class MDNode; struct AAMDNodes; +template <> struct ilist_alloc_traits<Instruction> { + static inline void deleteNode(Instruction *V); +}; + class Instruction : public User, public ilist_node_with_parent<Instruction, BasicBlock> { BasicBlock *Parent; @@ -47,13 +51,13 @@ class Instruction : public User, HasMetadataBit = 1 << 15 }; +protected: + ~Instruction(); // Use deleteValue() to delete a generic Instruction. + public: Instruction(const Instruction &) = delete; Instruction &operator=(const Instruction &) = delete; - // Out of line virtual method, so the vtable, etc has a home. - ~Instruction() override; - /// Specialize the methods defined in Value, as we know that an instruction /// can only be used by other instructions. Instruction *user_back() { return cast<Instruction>(*user_begin());} @@ -640,6 +644,10 @@ private: Instruction *cloneImpl() const; }; +inline void ilist_alloc_traits<Instruction>::deleteNode(Instruction *V) { + V->deleteValue(); +} + } // end namespace llvm #endif // LLVM_IR_INSTRUCTION_H diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index c26701af27ce4..6fab59613dd6d 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -89,9 +89,6 @@ public: AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd); - // Out of line virtual method, so the vtable, etc. has a home. - ~AllocaInst() override; - /// Return true if there is an allocation size parameter to the allocation /// instruction that is not 1. bool isArrayAllocation() const; @@ -856,7 +853,6 @@ class GetElementPtrInst : public Instruction { ArrayRef<Value *> IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); - void anchor() override; void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr); protected: @@ -1112,8 +1108,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// must be identical types. /// Represent an integer comparison operator. class ICmpInst: public CmpInst { - void anchor() override; - void AssertOK() { assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE && getPredicate() <= CmpInst::LAST_ICMP_PREDICATE && @@ -1426,8 +1420,6 @@ protected: CallInst *cloneImpl() const; public: - ~CallInst() override; - static CallInst *Create(Value *Func, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", @@ -2592,8 +2584,6 @@ class PHINode : public Instruction { return User::operator new(s); } - void anchor() override; - protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2927,8 +2917,6 @@ protected: ReturnInst *cloneImpl() const; public: - ~ReturnInst() override; - static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr, Instruction *InsertBefore = nullptr) { return new(!!retVal) ReturnInst(C, retVal, InsertBefore); diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 8f24a6a1d69d8..92f701e01ff38 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -174,12 +174,13 @@ class MetadataAsValue : public Value { Metadata *MD; MetadataAsValue(Type *Ty, Metadata *MD); - ~MetadataAsValue() override; /// \brief Drop use of metadata (during teardown). void dropUse() { MD = nullptr; } public: + ~MetadataAsValue(); + static MetadataAsValue *get(LLVMContext &Context, Metadata *MD); static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD); Metadata *getMetadata() const { return MD; } diff --git a/include/llvm/IR/OperandTraits.h b/include/llvm/IR/OperandTraits.h index e97a8009ccc03..7b94283856b6d 100644 --- a/include/llvm/IR/OperandTraits.h +++ b/include/llvm/IR/OperandTraits.h @@ -30,6 +30,9 @@ namespace llvm { template <typename SubClass, unsigned ARITY> struct FixedNumOperandTraits { static Use *op_begin(SubClass* U) { + static_assert( + !std::is_polymorphic<SubClass>::value, + "adding virtual methods to subclasses of User breaks use lists"); return reinterpret_cast<Use*>(U) - ARITY; } static Use *op_end(SubClass* U) { @@ -65,6 +68,9 @@ struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> { template <typename SubClass, unsigned MINARITY = 0> struct VariadicOperandTraits { static Use *op_begin(SubClass* U) { + static_assert( + !std::is_polymorphic<SubClass>::value, + "adding virtual methods to subclasses of User breaks use lists"); return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands(); } static Use *op_end(SubClass* U) { diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 997a85340c259..49fa6a6a877aa 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -29,16 +29,11 @@ namespace llvm { /// This is a utility class that provides an abstraction for the common /// functionality between Instructions and ConstantExprs. class Operator : public User { -protected: - // NOTE: Cannot use = delete because it's not legal to delete - // an overridden method that's not deleted in the base class. Cannot leave - // this unimplemented because that leads to an ODR-violation. - ~Operator() override; - public: // The Operator class is intended to be used as a utility, and is never itself // instantiated. Operator() = delete; + ~Operator() = delete; void *operator new(size_t, unsigned) = delete; void *operator new(size_t s) = delete; diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 6b2b22e82b95c..072c6c5ece831 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -886,17 +886,21 @@ template <typename LHS_t> struct not_match { template <typename OpTy> bool match(OpTy *V) { if (auto *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::Xor) - return matchIfNot(O->getOperand(0), O->getOperand(1)); + if (O->getOpcode() == Instruction::Xor) { + if (isAllOnes(O->getOperand(1))) + return L.match(O->getOperand(0)); + if (isAllOnes(O->getOperand(0))) + return L.match(O->getOperand(1)); + } return false; } private: - bool matchIfNot(Value *LHS, Value *RHS) { - return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) || + bool isAllOnes(Value *V) { + return (isa<ConstantInt>(V) || isa<ConstantDataVector>(V) || // FIXME: Remove CV. - isa<ConstantVector>(RHS)) && - cast<Constant>(RHS)->isAllOnesValue() && L.match(LHS); + isa<ConstantVector>(V)) && + cast<Constant>(V)->isAllOnesValue(); } }; diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 7b9d451aaf537..109a3d5e7be8d 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -46,8 +46,6 @@ class User : public Value { template <unsigned> friend struct HungoffOperandTraits; - virtual void anchor(); - LLVM_ATTRIBUTE_ALWAYS_INLINE inline static void * allocateFixedOperandUser(size_t, unsigned, unsigned); @@ -93,9 +91,11 @@ protected: /// should be called if there are no uses. void growHungoffUses(unsigned N, bool IsPhi = false); +protected: + ~User() = default; // Use deleteValue() to delete a generic Instruction. + public: User(const User &) = delete; - ~User() override = default; /// \brief Free memory allocated for User and Use objects. void operator delete(void *Usr); diff --git a/include/llvm/IR/Value.def b/include/llvm/IR/Value.def index 48842d7f9cd56..cebd7f7297ef3 100644 --- a/include/llvm/IR/Value.def +++ b/include/llvm/IR/Value.def @@ -20,10 +20,14 @@ #if !(defined HANDLE_GLOBAL_VALUE || defined HANDLE_CONSTANT || \ defined HANDLE_INSTRUCTION || defined HANDLE_INLINE_ASM_VALUE || \ defined HANDLE_METADATA_VALUE || defined HANDLE_VALUE || \ - defined HANDLE_CONSTANT_MARKER) + defined HANDLE_CONSTANT_MARKER || defined HANDLE_MEMORY_VALUE) #error "Missing macro definition of HANDLE_VALUE*" #endif +#ifndef HANDLE_MEMORY_VALUE +#define HANDLE_MEMORY_VALUE(ValueName) HANDLE_VALUE(ValueName) +#endif + #ifndef HANDLE_GLOBAL_VALUE #define HANDLE_GLOBAL_VALUE(ValueName) HANDLE_CONSTANT(ValueName) #endif @@ -54,9 +58,13 @@ HANDLE_VALUE(Argument) HANDLE_VALUE(BasicBlock) -HANDLE_VALUE(MemoryUse) -HANDLE_VALUE(MemoryDef) -HANDLE_VALUE(MemoryPhi) + +// FIXME: It's awkward that Value.def knows about classes in Analysis. While +// this doesn't introduce a strict link or include dependency, we should remove +// the circular dependency eventually. +HANDLE_MEMORY_VALUE(MemoryUse) +HANDLE_MEMORY_VALUE(MemoryDef) +HANDLE_MEMORY_VALUE(MemoryPhi) HANDLE_GLOBAL_VALUE(Function) HANDLE_GLOBAL_VALUE(GlobalAlias) @@ -94,6 +102,7 @@ HANDLE_CONSTANT_MARKER(ConstantDataLastVal, ConstantTokenNone) HANDLE_CONSTANT_MARKER(ConstantAggregateFirstVal, ConstantArray) HANDLE_CONSTANT_MARKER(ConstantAggregateLastVal, ConstantVector) +#undef HANDLE_MEMORY_VALUE #undef HANDLE_GLOBAL_VALUE #undef HANDLE_CONSTANT #undef HANDLE_INSTRUCTION diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 96a370dcc35f0..d669b1544070f 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -21,6 +21,7 @@ #include "llvm-c/Types.h" #include <cassert> #include <iterator> +#include <memory> namespace llvm { @@ -69,6 +70,8 @@ using ValueName = StringMapEntry<Value*>; /// objects that watch it and listen to RAUW and Destroy events. See /// llvm/IR/ValueHandle.h for details. class Value { + // The least-significant bit of the first word of Value *must* be zero: + // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm Type *VTy; Use *UseList; @@ -200,10 +203,19 @@ private: protected: Value(Type *Ty, unsigned scid); + /// Value's destructor should be virtual by design, but that would require + /// that Value and all of its subclasses have a vtable that effectively + /// duplicates the information in the value ID. As a size optimization, the + /// destructor has been protected, and the caller should manually call + /// deleteValue. + ~Value(); // Use deleteValue() to delete a generic Value. + public: Value(const Value &) = delete; void operator=(const Value &) = delete; - virtual ~Value(); + + /// Delete a pointer to a generic Value. + void deleteValue(); /// \brief Support for debugging, callable in GDB: V->dump() void dump() const; @@ -643,6 +655,13 @@ protected: void setValueSubclassData(unsigned short D) { SubclassData = D; } }; +struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } }; + +/// Use this instead of std::unique_ptr<Value> or std::unique_ptr<Instruction>. +/// Those don't work because Value and Instruction's destructors are protected, +/// aren't virtual, and won't destroy the complete object. +typedef std::unique_ptr<Value, ValueDeleter> unique_value; + inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) { V.print(OS); return OS; diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index cf314e19d1ca9..3df5244a0bd6f 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -187,7 +187,6 @@ void initializeLintPass(PassRegistry&); void initializeLiveDebugValuesPass(PassRegistry&); void initializeLiveDebugVariablesPass(PassRegistry&); void initializeLiveIntervalsPass(PassRegistry&); -void initializeLiveRangeShrinkPass(PassRegistry&); void initializeLiveRegMatrixPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&); diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index f42048e48ee3a..cf5d93ee9ed7e 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -57,6 +57,8 @@ protected: ID_MachO64L, // MachO 64-bit, little endian ID_MachO64B, // MachO 64-bit, big endian + ID_WinRes, // Windows resource (.res) file. + ID_Wasm, ID_EndObjects @@ -132,6 +134,8 @@ public: TypeID == ID_MachO32B || TypeID == ID_MachO64B); } + bool isWinRes() const { return TypeID == ID_WinRes; } + Triple::ObjectFormatType getTripleObjectFormat() const { if (isCOFF()) return Triple::COFF; diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index 78d9d679acd31..78044a2832faf 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -9,13 +9,15 @@ // // COFF short import file is a special kind of file which contains // only symbol names for DLL-exported symbols. This class implements -// SymbolicFile interface for the file. +// exporting of Symbols to create libraries and a SymbolicFile +// interface for the file type. // //===----------------------------------------------------------------------===// #ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H #define LLVM_OBJECT_COFF_IMPORT_FILE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Object/COFF.h" #include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ObjectFile.h" @@ -68,6 +70,36 @@ private: } }; +struct COFFShortExport { + std::string Name; + std::string ExtName; + + uint16_t Ordinal = 0; + bool Noname = false; + bool Data = false; + bool Private = false; + bool Constant = false; + + bool isWeak() { + return ExtName.size() && ExtName != Name; + } + + friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) { + return L.Name == R.Name && L.ExtName == R.ExtName && + L.Ordinal == R.Ordinal && L.Noname == R.Noname && + L.Data == R.Data && L.Private == R.Private; + } + + friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) { + return !(L == R); + } +}; + +std::error_code writeImportLibrary(StringRef DLLName, + StringRef Path, + ArrayRef<COFFShortExport> Exports, + COFF::MachineTypes Machine); + } // namespace object } // namespace llvm diff --git a/include/llvm/Object/COFFModuleDefinition.h b/include/llvm/Object/COFFModuleDefinition.h new file mode 100644 index 0000000000000..0428283fdc889 --- /dev/null +++ b/include/llvm/Object/COFFModuleDefinition.h @@ -0,0 +1,49 @@ +//===--- COFFModuleDefinition.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Windows-specific. +// A parser for the module-definition file (.def file). +// Parsed results are directly written to Config global variable. +// +// The format of module-definition files are described in this document: +// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H +#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H + +#include "llvm/Object/COFFImportFile.h" +#include "llvm/Object/COFF.h" + +namespace llvm { +namespace object { + +struct COFFModuleDefinition { + std::vector<COFFShortExport> Exports; + std::string OutputFile; + uint64_t ImageBase = 0; + uint64_t StackReserve = 0; + uint64_t StackCommit = 0; + uint64_t HeapReserve = 0; + uint64_t HeapCommit = 0; + uint32_t MajorImageVersion = 0; + uint32_t MinorImageVersion = 0; + uint32_t MajorOSVersion = 0; + uint32_t MinorOSVersion = 0; +}; + +Expected<COFFModuleDefinition> +parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine); + +} // End namespace object. +} // End namespace llvm. + +#endif diff --git a/include/llvm/Object/Decompressor.h b/include/llvm/Object/Decompressor.h index a11857d546aae..0f63f8b821b70 100644 --- a/include/llvm/Object/Decompressor.h +++ b/include/llvm/Object/Decompressor.h @@ -30,7 +30,10 @@ public: /// @brief Resize the buffer and uncompress section data into it. /// @param Out Destination buffer. - Error decompress(SmallString<32> &Out); + template <class T> Error resizeAndDecompress(T &Out) { + Out.resize(DecompressedSize); + return decompress({Out.data(), (size_t)DecompressedSize}); + } /// @brief Uncompress section data to raw buffer provided. /// @param Buffer Destination buffer. diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 42fdfe3e5a744..a4d431b6cbe7e 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -235,10 +235,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols, uint32_t Index = *IndexOrErr; if (Index == 0) return nullptr; - auto SectionsOrErr = sections(); - if (!SectionsOrErr) - return SectionsOrErr.takeError(); - return object::getSection<ELFT>(*SectionsOrErr, Index); + return getSection(Index); } template <class ELFT> diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 73c7ce367cb0c..86579b7c3e3a2 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -32,18 +32,6 @@ namespace llvm { namespace object { -struct RelocToApply { - // The computed value after applying the relevant relocations. - int64_t Value = 0; - - // The width of the value; how many bytes to touch when applying the - // relocation. - char Width = 0; - - RelocToApply() = default; - RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} -}; - /// @brief Base class for object file relocation visitors. class RelocVisitor { public: @@ -52,7 +40,7 @@ public: // TODO: Should handle multiple applied relocations via either passing in the // previously computed value or just count paired relocations as a single // visit. - RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { + uint64_t visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { if (isa<ELFObjectFileBase>(ObjToVisit)) return visitELF(RelocType, R, Value); if (isa<COFFObjectFile>(ObjToVisit)) @@ -61,7 +49,7 @@ public: return visitMachO(RelocType, R, Value); HasError = true; - return RelocToApply(); + return 0; } bool error() { return HasError; } @@ -70,7 +58,7 @@ private: const ObjectFile &ObjToVisit; bool HasError = false; - RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { case Triple::x86_64: @@ -87,7 +75,7 @@ private: return visitELF_X86_64_32S(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::aarch64: case Triple::aarch64_be: @@ -98,7 +86,7 @@ private: return visitELF_AARCH64_ABS64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::bpfel: case Triple::bpfeb: @@ -109,7 +97,7 @@ private: return visitELF_BPF_64_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::mips64el: case Triple::mips64: @@ -120,7 +108,7 @@ private: return visitELF_MIPS64_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::ppc64le: case Triple::ppc64: @@ -131,7 +119,7 @@ private: return visitELF_PPC64_ADDR64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::systemz: switch (RelocType) { @@ -141,7 +129,7 @@ private: return visitELF_390_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::sparcv9: switch (RelocType) { @@ -153,7 +141,7 @@ private: return visitELF_SPARCV9_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::amdgcn: switch (RelocType) { @@ -163,11 +151,11 @@ private: return visitELF_AMDGPU_ABS64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } default: HasError = true; - return RelocToApply(); + return 0; } } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file switch (ObjToVisit.getArch()) { @@ -181,7 +169,7 @@ private: return visitELF_386_PC32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::ppc: switch (RelocType) { @@ -189,14 +177,14 @@ private: return visitELF_PPC_ADDR32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::arm: case Triple::armeb: switch (RelocType) { default: HasError = true; - return RelocToApply(); + return 0; case ELF::R_ARM_ABS32: return visitELF_ARM_ABS32(R, Value); } @@ -206,7 +194,7 @@ private: return visitELF_Lanai_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::mipsel: case Triple::mips: @@ -215,7 +203,7 @@ private: return visitELF_MIPS_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::sparc: switch (RelocType) { @@ -224,7 +212,7 @@ private: return visitELF_SPARC_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::hexagon: switch (RelocType) { @@ -232,18 +220,18 @@ private: return visitELF_HEX_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } default: HasError = true; - return RelocToApply(); + return 0; } } else { report_fatal_error("Invalid word size in object file"); } } - RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) { switch (ObjToVisit.getArch()) { case Triple::x86: switch (RelocType) { @@ -263,10 +251,10 @@ private: break; } HasError = true; - return RelocToApply(); + return 0; } - RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { switch (ObjToVisit.getArch()) { default: break; case Triple::x86_64: @@ -277,7 +265,7 @@ private: } } HasError = true; - return RelocToApply(); + return 0; } int64_t getELFAddend(RelocationRef R) { @@ -287,108 +275,88 @@ private: return *AddendOrErr; } - uint8_t getLengthMachO64(RelocationRef R) { - const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObject()); - return Obj->getRelocationLength(R.getRawDataRefImpl()); - } - /// Operations /// 386-ELF - RelocToApply visitELF_386_NONE(RelocationRef R) { - return RelocToApply(0, 0); + uint64_t visitELF_386_NONE(RelocationRef R) { + return 0; } // Ideally the Addend here will be the addend in the data for // the relocation. It's not actually the case for Rel relocations. - RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, 4); + uint64_t visitELF_386_32(RelocationRef R, uint64_t Value) { + return Value; } - RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) { - uint64_t Address = R.getOffset(); - return RelocToApply(Value - Address, 4); + uint64_t visitELF_386_PC32(RelocationRef R, uint64_t Value) { + return Value - R.getOffset(); } /// X86-64 ELF - RelocToApply visitELF_X86_64_NONE(RelocationRef R) { - return RelocToApply(0, 0); + uint64_t visitELF_X86_64_NONE(RelocationRef R) { + return 0; } - RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + + uint64_t visitELF_X86_64_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint64_t Address = R.getOffset(); - return RelocToApply(Value + Addend - Address, 4); + + uint64_t visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R) - R.getOffset(); } - RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + + uint64_t visitELF_X86_64_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - int32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + + uint64_t visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// BPF ELF - RelocToApply visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { - uint32_t Res = Value & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { + return Value & 0xFFFFFFFF; } - RelocToApply visitELF_BPF_64_64(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, 8); + + uint64_t visitELF_BPF_64_64(RelocationRef R, uint64_t Value) { + return Value; } /// PPC64 ELF - RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + + uint64_t visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } /// PPC32 ELF - RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// Lanai ELF - RelocToApply visitELF_Lanai_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_Lanai_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// MIPS ELF - RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { - uint32_t Res = Value & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_MIPS_32(RelocationRef R, uint64_t Value) { + return Value & 0xFFFFFFFF; } /// MIPS64 ELF - RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint64_t Res = (Value + Addend); - return RelocToApply(Res, 8); + uint64_t visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } // AArch64 ELF - RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); int64_t Res = Value + Addend; @@ -396,16 +364,15 @@ private: if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } // SystemZ ELF - RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_390_32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); int64_t Res = Value + Addend; @@ -413,77 +380,71 @@ private: if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_390_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) { - int32_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + uint64_t visitELF_SPARC_32(RelocationRef R, uint32_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) { - int32_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + uint64_t visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) { int64_t Res = Value; // Overflow check allows for both signed and unsigned interpretation. if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_HEX_32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_HEX_32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + return Value + Addend; } - RelocToApply visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + return Value + Addend; } - RelocToApply visitELF_AMDGPU_ABS64(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AMDGPU_ABS64(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + return Value + Addend; } /// I386 COFF - RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } - RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } /// AMD64 COFF - RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } - RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, /*Width=*/8); + uint64_t visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { + return Value; } // X86_64 MachO - RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { - uint8_t Length = getLengthMachO64(R); - Length = 1<<Length; - return RelocToApply(Value, Length); + uint64_t visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { + return Value; } }; diff --git a/include/llvm/Object/WindowsResource.h b/include/llvm/Object/WindowsResource.h new file mode 100644 index 0000000000000..f94ad09ce0c67 --- /dev/null +++ b/include/llvm/Object/WindowsResource.h @@ -0,0 +1,82 @@ +//===-- WindowsResource.h ---------------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file declares the .res file class. .res files are intermediate +// products of the typical resource-compilation process on Windows. This +// process is as follows: +// +// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file +// +// .rc files are human-readable scripts that list all resources a program uses. +// +// They are compiled into .res files, which are a list of the resources in +// binary form. +// +// Finally the data stored in the .res is compiled into a COFF file, where it +// is organized in a directory tree structure for optimized access by the +// program during runtime. +// +// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H +#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Object/Binary.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace object { + +class WindowsResource; + +class ResourceEntryRef { +public: + Error moveNext(bool &End); + +private: + friend class WindowsResource; + + ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner, + Error &Err); + Error loadNext(); + + BinaryStreamReader Reader; + BinaryStreamRef HeaderBytes; + BinaryStreamRef DataBytes; + const WindowsResource *OwningRes = nullptr; +}; + +class WindowsResource : public Binary { +public: + ~WindowsResource() override; + Expected<ResourceEntryRef> getHeadEntry(); + + static bool classof(const Binary *V) { return V->isWinRes(); } + + static Expected<std::unique_ptr<WindowsResource>> + createWindowsResource(MemoryBufferRef Source); + +private: + friend class ResourceEntryRef; + + WindowsResource(MemoryBufferRef Source); + + BinaryByteStream BBS; +}; + +} // namespace object +} // namespace llvm + +#endif diff --git a/include/llvm/PassInfo.h b/include/llvm/PassInfo.h index 21ade85b682fb..81dface3c9a05 100644 --- a/include/llvm/PassInfo.h +++ b/include/llvm/PassInfo.h @@ -32,7 +32,6 @@ class TargetMachine; class PassInfo { public: typedef Pass* (*NormalCtor_t)(); - typedef Pass *(*TargetMachineCtor_t)(TargetMachine *); private: StringRef PassName; // Nice name for Pass @@ -44,24 +43,20 @@ private: std::vector<const PassInfo *> ItfImpl; // Interfaces implemented by this pass NormalCtor_t NormalCtor; - TargetMachineCtor_t TargetMachineCtor; public: /// PassInfo ctor - Do not call this directly, this should only be invoked /// through RegisterPass. PassInfo(StringRef name, StringRef arg, const void *pi, NormalCtor_t normal, - bool isCFGOnly, bool is_analysis, - TargetMachineCtor_t machine = nullptr) + bool isCFGOnly, bool is_analysis) : PassName(name), PassArgument(arg), PassID(pi), IsCFGOnlyPass(isCFGOnly), - IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal), - TargetMachineCtor(machine) {} + IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) {} /// PassInfo ctor - Do not call this directly, this should only be invoked /// through RegisterPass. This version is for use by analysis groups; it /// does not auto-register the pass. PassInfo(StringRef name, const void *pi) : PassName(name), PassArgument(""), PassID(pi), IsCFGOnlyPass(false), - IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr), - TargetMachineCtor(nullptr) {} + IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr) {} /// getPassName - Return the friendly name for the pass, never returns null /// @@ -101,16 +96,6 @@ public: NormalCtor = Ctor; } - /// getTargetMachineCtor - Return a pointer to a function, that when called - /// with a TargetMachine, creates an instance of the pass and returns it. - /// This pointer may be null if there is no constructor with a TargetMachine - /// for the pass. - /// - TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; } - void setTargetMachineCtor(TargetMachineCtor_t Ctor) { - TargetMachineCtor = Ctor; - } - /// createPass() - Use this method to create an instance of this pass. Pass *createPass() const { assert((!isAnalysisGroup() || NormalCtor) && diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index 50e6b498fb462..602f45ac51787 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -31,8 +31,6 @@ namespace llvm { -class TargetMachine; - #define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \ static void *initialize##passName##PassOnce(PassRegistry &Registry) { \ PassInfo *PI = new PassInfo( \ @@ -78,10 +76,6 @@ class TargetMachine; template <typename PassName> Pass *callDefaultCtor() { return new PassName(); } -template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) { - return new PassName(TM); -} - //===--------------------------------------------------------------------------- /// RegisterPass<t> template - This template class is used to notify the system /// that a Pass is available for use, and registers it into the internal diff --git a/include/llvm/Support/BinaryStreamReader.h b/include/llvm/Support/BinaryStreamReader.h index 77738077f5ffe..56375f41d2c0d 100644 --- a/include/llvm/Support/BinaryStreamReader.h +++ b/include/llvm/Support/BinaryStreamReader.h @@ -16,7 +16,6 @@ #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/type_traits.h" #include <string> @@ -32,7 +31,21 @@ namespace llvm { class BinaryStreamReader { public: BinaryStreamReader() = default; - explicit BinaryStreamReader(BinaryStreamRef Stream); + explicit BinaryStreamReader(BinaryStreamRef Ref); + explicit BinaryStreamReader(BinaryStream &Stream); + explicit BinaryStreamReader(ArrayRef<uint8_t> Data, + llvm::support::endianness Endian); + explicit BinaryStreamReader(StringRef Data, llvm::support::endianness Endian); + + BinaryStreamReader(const BinaryStreamReader &Other) + : Stream(Other.Stream), Offset(Other.Offset) {} + + BinaryStreamReader &operator=(const BinaryStreamReader &Other) { + Stream = Other.Stream; + Offset = Other.Offset; + return *this; + } + virtual ~BinaryStreamReader() {} /// Read as much as possible from the underlying string at the current offset @@ -244,12 +257,14 @@ public: /// \returns the next byte in the stream. uint8_t peek() const; + Error padToAlignment(uint32_t Align); + std::pair<BinaryStreamReader, BinaryStreamReader> split(uint32_t Offset) const; private: BinaryStreamRef Stream; - uint32_t Offset; + uint32_t Offset = 0; }; } // namespace llvm diff --git a/include/llvm/Support/BinaryStreamRef.h b/include/llvm/Support/BinaryStreamRef.h index 465e724a68861..e3bd4bf0860e7 100644 --- a/include/llvm/Support/BinaryStreamRef.h +++ b/include/llvm/Support/BinaryStreamRef.h @@ -16,36 +16,74 @@ #include "llvm/Support/Error.h" #include <algorithm> #include <cstdint> +#include <memory> namespace llvm { /// Common stuff for mutable and immutable StreamRefs. -template <class StreamType, class RefType> class BinaryStreamRefBase { -public: - BinaryStreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {} - BinaryStreamRefBase(StreamType &Stream, uint32_t Offset, uint32_t Length) - : Stream(&Stream), ViewOffset(Offset), Length(Length) {} +template <class RefType, class StreamType> class BinaryStreamRefBase { +protected: + BinaryStreamRefBase() = default; + BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint32_t Offset, + uint32_t Length) + : SharedImpl(SharedImpl), BorrowedImpl(SharedImpl.get()), + ViewOffset(Offset), Length(Length) {} + BinaryStreamRefBase(StreamType &BorrowedImpl, uint32_t Offset, + uint32_t Length) + : BorrowedImpl(&BorrowedImpl), ViewOffset(Offset), Length(Length) {} + BinaryStreamRefBase(const BinaryStreamRefBase &Other) { + SharedImpl = Other.SharedImpl; + BorrowedImpl = Other.BorrowedImpl; + ViewOffset = Other.ViewOffset; + Length = Other.Length; + } - llvm::support::endianness getEndian() const { return Stream->getEndian(); } +public: + llvm::support::endianness getEndian() const { + return BorrowedImpl->getEndian(); + } uint32_t getLength() const { return Length; } - const StreamType *getStream() const { return Stream; } /// Return a new BinaryStreamRef with the first \p N elements removed. RefType drop_front(uint32_t N) const { - if (!Stream) + if (!BorrowedImpl) return RefType(); N = std::min(N, Length); - return RefType(*Stream, ViewOffset + N, Length - N); + RefType Result(static_cast<const RefType &>(*this)); + Result.ViewOffset += N; + Result.Length -= N; + return Result; } - /// Return a new BinaryStreamRef with only the first \p N elements remaining. - RefType keep_front(uint32_t N) const { - if (!Stream) + /// Return a new BinaryStreamRef with the first \p N elements removed. + RefType drop_back(uint32_t N) const { + if (!BorrowedImpl) return RefType(); + N = std::min(N, Length); - return RefType(*Stream, ViewOffset, N); + RefType Result(static_cast<const RefType &>(*this)); + Result.Length -= N; + return Result; + } + + /// Return a new BinaryStreamRef with only the first \p N elements remaining. + RefType keep_front(uint32_t N) const { + assert(N <= getLength()); + return drop_back(getLength() - N); + } + + /// Return a new BinaryStreamRef with only the last \p N elements remaining. + RefType keep_back(uint32_t N) const { + assert(N <= getLength()); + return drop_front(getLength() - N); + } + + /// Return a new BinaryStreamRef with the first and last \p N elements + /// removed. + RefType drop_symmetric(uint32_t N) const { + return drop_front(N).drop_back(N); } /// Return a new BinaryStreamRef with the first \p Offset elements removed, @@ -54,8 +92,10 @@ public: return drop_front(Offset).keep_front(Len); } + bool valid() const { return BorrowedImpl != nullptr; } + bool operator==(const RefType &Other) const { - if (Stream != Other.Stream) + if (BorrowedImpl != Other.BorrowedImpl) return false; if (ViewOffset != Other.ViewOffset) return false; @@ -73,9 +113,10 @@ protected: return Error::success(); } - StreamType *Stream; - uint32_t ViewOffset; - uint32_t Length; + std::shared_ptr<StreamType> SharedImpl; + StreamType *BorrowedImpl = nullptr; + uint32_t ViewOffset = 0; + uint32_t Length = 0; }; /// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It @@ -86,21 +127,27 @@ protected: /// and use inheritance to achieve polymorphism. Instead, you should pass /// around BinaryStreamRefs by value and achieve polymorphism that way. class BinaryStreamRef - : public BinaryStreamRefBase<BinaryStream, BinaryStreamRef> { + : public BinaryStreamRefBase<BinaryStreamRef, BinaryStream> { + friend BinaryStreamRefBase<BinaryStreamRef, BinaryStream>; + friend class WritableBinaryStreamRef; + BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint32_t ViewOffset, + uint32_t Length) + : BinaryStreamRefBase(Impl, ViewOffset, Length) {} + public: BinaryStreamRef() = default; - BinaryStreamRef(BinaryStream &Stream) - : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {} - BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length) - : BinaryStreamRefBase(Stream, Offset, Length) {} + BinaryStreamRef(BinaryStream &Stream); + BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length); + explicit BinaryStreamRef(ArrayRef<uint8_t> Data, + llvm::support::endianness Endian); + explicit BinaryStreamRef(StringRef Data, llvm::support::endianness Endian); + + BinaryStreamRef(const BinaryStreamRef &Other); // Use BinaryStreamRef.slice() instead. BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset, uint32_t Length) = delete; - /// Check if a Stream is valid. - bool valid() const { return Stream != nullptr; } - /// Given an Offset into this StreamRef and a Size, return a reference to a /// buffer owned by the stream. /// @@ -108,12 +155,7 @@ public: /// bounds of this BinaryStreamRef's view and the implementation could read /// the data, and an appropriate error code otherwise. Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const { - if (auto EC = checkOffset(Offset, Size)) - return EC; - - return Stream->readBytes(ViewOffset + Offset, Size, Buffer); - } + ArrayRef<uint8_t> &Buffer) const; /// Given an Offset into this BinaryStreamRef, return a reference to the /// largest buffer the stream could support without necessitating a copy. @@ -121,33 +163,25 @@ public: /// \returns a success error code if implementation could read the data, /// and an appropriate error code otherwise. Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const { - if (auto EC = checkOffset(Offset, 1)) - return EC; - - if (auto EC = - Stream->readLongestContiguousChunk(ViewOffset + Offset, Buffer)) - return EC; - // This StreamRef might refer to a smaller window over a larger stream. In - // that case we will have read out more bytes than we should return, because - // we should not read past the end of the current view. - uint32_t MaxLength = Length - Offset; - if (Buffer.size() > MaxLength) - Buffer = Buffer.slice(0, MaxLength); - return Error::success(); - } + ArrayRef<uint8_t> &Buffer) const; }; class WritableBinaryStreamRef - : public BinaryStreamRefBase<WritableBinaryStream, - WritableBinaryStreamRef> { + : public BinaryStreamRefBase<WritableBinaryStreamRef, + WritableBinaryStream> { + friend BinaryStreamRefBase<WritableBinaryStreamRef, WritableBinaryStream>; + WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl, + uint32_t ViewOffset, uint32_t Length) + : BinaryStreamRefBase(Impl, ViewOffset, Length) {} + public: WritableBinaryStreamRef() = default; - WritableBinaryStreamRef(WritableBinaryStream &Stream) - : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {} + WritableBinaryStreamRef(WritableBinaryStream &Stream); WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset, - uint32_t Length) - : BinaryStreamRefBase(Stream, Offset, Length) {} + uint32_t Length); + explicit WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data, + llvm::support::endianness Endian); + WritableBinaryStreamRef(const WritableBinaryStreamRef &Other); // Use WritableBinaryStreamRef.slice() instead. WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset, @@ -159,17 +193,13 @@ public: /// \returns a success error code if the data could fit within the underlying /// stream at the specified location and the implementation could write the /// data, and an appropriate error code otherwise. - Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const { - if (auto EC = checkOffset(Offset, Data.size())) - return EC; - - return Stream->writeBytes(ViewOffset + Offset, Data); - } + Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const; - operator BinaryStreamRef() { return BinaryStreamRef(*Stream); } + /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef. + operator BinaryStreamRef() const; /// \brief For buffered streams, commits changes to the backing store. - Error commit() { return Stream->commit(); } + Error commit(); }; } // end namespace llvm diff --git a/include/llvm/Support/BinaryStreamWriter.h b/include/llvm/Support/BinaryStreamWriter.h index 1b61c32a25418..a4495a1ce27d4 100644 --- a/include/llvm/Support/BinaryStreamWriter.h +++ b/include/llvm/Support/BinaryStreamWriter.h @@ -32,7 +32,20 @@ namespace llvm { class BinaryStreamWriter { public: BinaryStreamWriter() = default; - explicit BinaryStreamWriter(WritableBinaryStreamRef Stream); + explicit BinaryStreamWriter(WritableBinaryStreamRef Ref); + explicit BinaryStreamWriter(WritableBinaryStream &Stream); + explicit BinaryStreamWriter(MutableArrayRef<uint8_t> Data, + llvm::support::endianness Endian); + + BinaryStreamWriter(const BinaryStreamWriter &Other) + : Stream(Other.Stream), Offset(Other.Offset) {} + + BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) { + Stream = Other.Stream; + Offset = Other.Offset; + return *this; + } + virtual ~BinaryStreamWriter() {} /// Write the bytes specified in \p Buffer to the underlying stream. diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index e3c5de7fbe642..7caefb5359b87 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -261,7 +261,7 @@ struct file_magic { coff_object, ///< COFF object file coff_import_library, ///< COFF import library pecoff_executable, ///< PECOFF executable file - windows_resource, ///< Windows compiled resource file (.rc) + windows_resource, ///< Windows compiled resource file (.res) wasm_object ///< WebAssembly Object file }; diff --git a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 071ec2edb5389..a06c67fe814c8 100644 --- a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -62,7 +62,6 @@ def : GINodeEquiv<G_FMUL, fmul>; def : GINodeEquiv<G_FDIV, fdiv>; def : GINodeEquiv<G_FREM, frem>; def : GINodeEquiv<G_FPOW, fpow>; -def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>; def : GINodeEquiv<G_BR, br>; // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. diff --git a/include/llvm/Transforms/IPO/FunctionImport.h b/include/llvm/Transforms/IPO/FunctionImport.h index ed5742ab8b564..d66b6edc7a4f9 100644 --- a/include/llvm/Transforms/IPO/FunctionImport.h +++ b/include/llvm/Transforms/IPO/FunctionImport.h @@ -53,8 +53,7 @@ public: : Index(Index), ModuleLoader(std::move(ModuleLoader)) {} /// Import functions in Module \p M based on the supplied import list. - Expected<bool> - importFunctions(Module &M, const ImportMapTy &ImportList); + Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList); private: /// The summaries index used to trigger importing. diff --git a/include/llvm/Transforms/Scalar/GVNExpression.h b/include/llvm/Transforms/Scalar/GVNExpression.h index 2670a0c1a5339..a971df975b6fa 100644 --- a/include/llvm/Transforms/Scalar/GVNExpression.h +++ b/include/llvm/Transforms/Scalar/GVNExpression.h @@ -40,6 +40,7 @@ enum ExpressionType { ET_Base, ET_Constant, ET_Variable, + ET_Dead, ET_Unknown, ET_BasicStart, ET_Basic, @@ -380,7 +381,9 @@ public: OS << "ExpressionTypeStore, "; this->BasicExpression::printInternal(OS, false); OS << " represents Store " << *Store; - OS << " with MemoryLeader " << *getMemoryLeader(); + OS << " with StoredValue "; + StoredValue->printAsOperand(OS); + OS << " and MemoryLeader " << *getMemoryLeader(); } }; @@ -513,6 +516,17 @@ public: } }; +class DeadExpression final : public Expression { +public: + DeadExpression() : Expression(ET_Dead) {} + DeadExpression(const DeadExpression &) = delete; + DeadExpression &operator=(const DeadExpression &) = delete; + + static bool classof(const Expression *E) { + return E->getExpressionType() == ET_Dead; + } +}; + class VariableExpression final : public Expression { private: Value *VariableValue; diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 665dd6f4b2579..6aba9b2298b10 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -121,6 +121,7 @@ private: Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B); Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B); Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B); + Value *optimizeWcslen(CallInst *CI, IRBuilder<> &B); // Wrapper for all String/Memory Library Call Optimizations Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B); @@ -165,6 +166,9 @@ private: /// hasFloatVersion - Checks if there is a float version of the specified /// function by checking for an existing function with name FuncName + f bool hasFloatVersion(StringRef FuncName); + + /// Shared code to optimize strlen+wcslen. + Value *optimizeStringLength(CallInst *CI, IRBuilder<> &B, unsigned CharSize); }; } // End llvm namespace |