summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APInt.h17
-rw-r--r--include/llvm/ADT/SmallPtrSet.h2
-rw-r--r--include/llvm/ADT/Statistic.h12
-rw-r--r--include/llvm/ADT/Triple.h10
-rw-r--r--include/llvm/Analysis/MemorySSA.h113
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h26
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.h13
-rw-r--r--include/llvm/Analysis/ValueTracking.h37
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h2
-rw-r--r--include/llvm/CodeGen/MachineValueType.h234
-rw-r--r--include/llvm/CodeGen/Passes.h51
-rw-r--r--include/llvm/CodeGen/StackProtector.h12
-rw-r--r--include/llvm/CodeGen/ValueTypes.td220
-rw-r--r--include/llvm/DebugInfo/CodeView/CVRecord.h4
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeDumper.h61
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeVisitor.h35
-rw-r--r--include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h (renamed from include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h)45
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumper.h8
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeCollection.h38
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDatabase.h19
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h18
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeIndex.h13
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeSerializer.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeStreamMerger.h5
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeTableCollection.h42
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h5
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h8
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFRelocMap.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h5
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h16
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h1
-rw-r--r--include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h2
-rw-r--r--include/llvm/IR/Argument.h3
-rw-r--r--include/llvm/IR/BasicBlock.h6
-rw-r--r--include/llvm/IR/Constant.h2
-rw-r--r--include/llvm/IR/Constants.h14
-rw-r--r--include/llvm/IR/DerivedUser.h41
-rw-r--r--include/llvm/IR/Function.h2
-rw-r--r--include/llvm/IR/GlobalValue.h8
-rw-r--r--include/llvm/IR/GlobalVariable.h2
-rw-r--r--include/llvm/IR/InlineAsm.h3
-rw-r--r--include/llvm/IR/InstrTypes.h10
-rw-r--r--include/llvm/IR/Instruction.def10
-rw-r--r--include/llvm/IR/Instruction.h14
-rw-r--r--include/llvm/IR/Instructions.h12
-rw-r--r--include/llvm/IR/Metadata.h3
-rw-r--r--include/llvm/IR/OperandTraits.h6
-rw-r--r--include/llvm/IR/Operator.h7
-rw-r--r--include/llvm/IR/PatternMatch.h16
-rw-r--r--include/llvm/IR/User.h6
-rw-r--r--include/llvm/IR/Value.def17
-rw-r--r--include/llvm/IR/Value.h21
-rw-r--r--include/llvm/InitializePasses.h1
-rw-r--r--include/llvm/Object/Binary.h4
-rw-r--r--include/llvm/Object/COFFImportFile.h34
-rw-r--r--include/llvm/Object/COFFModuleDefinition.h49
-rw-r--r--include/llvm/Object/Decompressor.h5
-rw-r--r--include/llvm/Object/ELF.h5
-rw-r--r--include/llvm/Object/RelocVisitor.h231
-rw-r--r--include/llvm/Object/WindowsResource.h82
-rw-r--r--include/llvm/PassInfo.h21
-rw-r--r--include/llvm/PassSupport.h6
-rw-r--r--include/llvm/Support/BinaryStreamReader.h21
-rw-r--r--include/llvm/Support/BinaryStreamRef.h150
-rw-r--r--include/llvm/Support/BinaryStreamWriter.h15
-rw-r--r--include/llvm/Support/FileSystem.h2
-rw-r--r--include/llvm/Target/GlobalISel/SelectionDAGCompat.td1
-rw-r--r--include/llvm/Transforms/IPO/FunctionImport.h3
-rw-r--r--include/llvm/Transforms/Scalar/GVNExpression.h16
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h4
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