summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-03 20:26:11 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-03 20:26:11 +0000
commit148779df305667b6942fee7e758fdf81a6498f38 (patch)
tree976d85fb9cb4bc8ed54348b045f742be90e10c57 /include
parenta303c417bbdb53703c2c17398b08486bde78f1f6 (diff)
downloadsrc-test2-148779df305667b6942fee7e758fdf81a6498f38.tar.gz
src-test2-148779df305667b6942fee7e758fdf81a6498f38.zip
Notes
Diffstat (limited to 'include')
-rw-r--r--include/llvm/ADT/APInt.h135
-rw-r--r--include/llvm/CodeGen/CommandFlags.h30
-rw-r--r--include/llvm/DebugInfo/CodeView/CVRecord.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h16
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h8
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h17
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h14
-rw-r--r--include/llvm/DebugInfo/CodeView/StringTable.h75
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h3
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugLine.h10
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFVerifier.h98
-rw-r--r--include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h2
-rw-r--r--include/llvm/DebugInfo/PDB/Native/DbiStream.h4
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBFile.h8
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h10
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBStringTable.h (renamed from include/llvm/DebugInfo/PDB/Native/StringTable.h)40
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h60
-rw-r--r--include/llvm/DebugInfo/PDB/Native/RawTypes.h10
-rw-r--r--include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h45
-rw-r--r--include/llvm/IR/Attributes.h23
-rw-r--r--include/llvm/IR/CallSite.h16
-rw-r--r--include/llvm/IR/Function.h47
-rw-r--r--include/llvm/IR/Instructions.h28
-rw-r--r--include/llvm/IR/Intrinsics.h26
-rw-r--r--include/llvm/IR/Intrinsics.td41
-rw-r--r--include/llvm/IR/IntrinsicsX86.td23
-rw-r--r--include/llvm/Support/BinaryStreamArray.h234
-rw-r--r--include/llvm/Support/BinaryStreamReader.h28
-rw-r--r--include/llvm/Support/BinaryStreamRef.h3
-rw-r--r--include/llvm/Support/BinaryStreamWriter.h6
-rw-r--r--include/llvm/Support/DataExtractor.h22
-rw-r--r--include/llvm/Support/ELFRelocs/Hexagon.def5
-rw-r--r--include/llvm/Target/TargetLowering.h8
35 files changed, 742 insertions, 365 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 6d74f344aad5..63c92c1a7fce 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -86,7 +86,7 @@ private:
union {
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
+ } U;
unsigned BitWidth; ///< The number of bits in this APInt.
@@ -98,7 +98,9 @@ private:
///
/// This constructor is used only internally for speed of construction of
/// temporaries. It is unsafe for general use so it is not public.
- APInt(uint64_t *val, unsigned bits) : pVal(val), BitWidth(bits) {}
+ APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {
+ U.pVal = val;
+ }
/// \brief Determine if this APInt just has one word to store value.
///
@@ -143,16 +145,16 @@ private:
// Mask out the high bits.
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - WordBits);
if (isSingleWord())
- VAL &= mask;
+ U.VAL &= mask;
else
- pVal[getNumWords() - 1] &= mask;
+ U.pVal[getNumWords() - 1] &= mask;
return *this;
}
/// \brief Get the word corresponding to a bit position
/// \returns the corresponding word for the specified bit position.
uint64_t getWord(unsigned bitPosition) const {
- return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
}
/// \brief Convert a char array into an APInt
@@ -258,7 +260,7 @@ public:
: BitWidth(numBits) {
assert(BitWidth && "bitwidth too small");
if (isSingleWord()) {
- VAL = val;
+ U.VAL = val;
clearUnusedBits();
} else {
initSlowCase(val, isSigned);
@@ -300,20 +302,21 @@ public:
/// @brief Copy Constructor.
APInt(const APInt &that) : BitWidth(that.BitWidth) {
if (isSingleWord())
- VAL = that.VAL;
+ U.VAL = that.U.VAL;
else
initSlowCase(that);
}
/// \brief Move Constructor.
- APInt(APInt &&that) : VAL(that.VAL), BitWidth(that.BitWidth) {
+ APInt(APInt &&that) : BitWidth(that.BitWidth) {
+ memcpy(&U, &that.U, sizeof(U));
that.BitWidth = 0;
}
/// \brief Destructor.
~APInt() {
if (needsCleanup())
- delete[] pVal;
+ delete[] U.pVal;
}
/// \brief Default constructor that creates an uninteresting APInt
@@ -321,7 +324,7 @@ public:
///
/// This is useful for object deserialization (pair this with the static
/// method Read).
- explicit APInt() : VAL(0), BitWidth(1) {}
+ explicit APInt() : BitWidth(1) { U.VAL = 0; }
/// \brief Returns whether this instance allocated memory.
bool needsCleanup() const { return !isSingleWord(); }
@@ -373,7 +376,7 @@ public:
/// This checks to see if the value has all bits of the APInt are set or not.
bool isAllOnesValue() const {
if (isSingleWord())
- return VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
+ return U.VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
return countPopulationSlowCase() == BitWidth;
}
@@ -428,7 +431,7 @@ public:
/// \returns true if the argument APInt value is a power of two > 0.
bool isPowerOf2() const {
if (isSingleWord())
- return isPowerOf2_64(VAL);
+ return isPowerOf2_64(U.VAL);
return countPopulationSlowCase() == 1;
}
@@ -461,7 +464,7 @@ public:
assert(numBits != 0 && "numBits must be non-zero");
assert(numBits <= BitWidth && "numBits out of range");
if (isSingleWord())
- return VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
+ return U.VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
unsigned Ones = countTrailingOnesSlowCase();
return (numBits == Ones) &&
((Ones + countLeadingZerosSlowCase()) == BitWidth);
@@ -472,7 +475,7 @@ public:
/// Ex. isMask(0x0000FFFFU) == true.
bool isMask() const {
if (isSingleWord())
- return isMask_64(VAL);
+ return isMask_64(U.VAL);
unsigned Ones = countTrailingOnesSlowCase();
return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
}
@@ -481,7 +484,7 @@ public:
/// the remainder zero.
bool isShiftedMask() const {
if (isSingleWord())
- return isShiftedMask_64(VAL);
+ return isShiftedMask_64(U.VAL);
unsigned Ones = countPopulationSlowCase();
unsigned LeadZ = countLeadingZerosSlowCase();
return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
@@ -639,8 +642,8 @@ public:
/// conversions.
const uint64_t *getRawData() const {
if (isSingleWord())
- return &VAL;
- return &pVal[0];
+ return &U.VAL;
+ return &U.pVal[0];
}
/// @}
@@ -686,7 +689,7 @@ public:
/// \returns true if *this is zero, false otherwise.
bool operator!() const {
if (isSingleWord())
- return VAL == 0;
+ return U.VAL == 0;
return countLeadingZerosSlowCase() == BitWidth;
}
@@ -700,7 +703,7 @@ public:
APInt &operator=(const APInt &RHS) {
// If the bitwidths are the same, we can avoid mucking with memory
if (isSingleWord() && RHS.isSingleWord()) {
- VAL = RHS.VAL;
+ U.VAL = RHS.U.VAL;
BitWidth = RHS.BitWidth;
return clearUnusedBits();
}
@@ -713,11 +716,11 @@ public:
APInt &operator=(APInt &&that) {
assert(this != &that && "Self-move not supported");
if (!isSingleWord())
- delete[] pVal;
+ delete[] U.pVal;
// Use memcpy so that type based alias analysis sees both VAL and pVal
// as modified.
- memcpy(&VAL, &that.VAL, sizeof(uint64_t));
+ memcpy(&U, &that.U, sizeof(U));
BitWidth = that.BitWidth;
that.BitWidth = 0;
@@ -734,11 +737,11 @@ public:
/// \returns *this after assignment of RHS value.
APInt &operator=(uint64_t RHS) {
if (isSingleWord()) {
- VAL = RHS;
+ U.VAL = RHS;
clearUnusedBits();
} else {
- pVal[0] = RHS;
- memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ U.pVal[0] = RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
}
return *this;
}
@@ -752,7 +755,7 @@ public:
APInt &operator&=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL &= RHS.VAL;
+ U.VAL &= RHS.U.VAL;
else
AndAssignSlowCase(RHS);
return *this;
@@ -765,11 +768,11 @@ public:
/// the LHS.
APInt &operator&=(uint64_t RHS) {
if (isSingleWord()) {
- VAL &= RHS;
+ U.VAL &= RHS;
return *this;
}
- pVal[0] &= RHS;
- memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ U.pVal[0] &= RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
return *this;
}
@@ -782,7 +785,7 @@ public:
APInt &operator|=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL |= RHS.VAL;
+ U.VAL |= RHS.U.VAL;
else
OrAssignSlowCase(RHS);
return *this;
@@ -795,10 +798,10 @@ public:
/// the LHS.
APInt &operator|=(uint64_t RHS) {
if (isSingleWord()) {
- VAL |= RHS;
+ U.VAL |= RHS;
clearUnusedBits();
} else {
- pVal[0] |= RHS;
+ U.pVal[0] |= RHS;
}
return *this;
}
@@ -812,7 +815,7 @@ public:
APInt &operator^=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL ^= RHS.VAL;
+ U.VAL ^= RHS.U.VAL;
else
XorAssignSlowCase(RHS);
return *this;
@@ -825,10 +828,10 @@ public:
/// the LHS.
APInt &operator^=(uint64_t RHS) {
if (isSingleWord()) {
- VAL ^= RHS;
+ U.VAL ^= RHS;
clearUnusedBits();
} else {
- pVal[0] ^= RHS;
+ U.pVal[0] ^= RHS;
}
return *this;
}
@@ -865,9 +868,9 @@ public:
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (ShiftAmt == BitWidth)
- VAL = 0;
+ U.VAL = 0;
else
- VAL <<= ShiftAmt;
+ U.VAL <<= ShiftAmt;
return clearUnusedBits();
}
shlSlowCase(ShiftAmt);
@@ -913,11 +916,11 @@ public:
void ashrInPlace(unsigned ShiftAmt) {
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
- int64_t SExtVAL = SignExtend64(VAL, BitWidth);
+ int64_t SExtVAL = SignExtend64(U.VAL, BitWidth);
if (ShiftAmt == BitWidth)
- VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
+ U.VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
else
- VAL = SExtVAL >> ShiftAmt;
+ U.VAL = SExtVAL >> ShiftAmt;
clearUnusedBits();
return;
}
@@ -938,9 +941,9 @@ public:
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (ShiftAmt == BitWidth)
- VAL = 0;
+ U.VAL = 0;
else
- VAL >>= ShiftAmt;
+ U.VAL >>= ShiftAmt;
return;
}
lshrSlowCase(ShiftAmt);
@@ -1059,7 +1062,7 @@ public:
bool operator[](unsigned bitPosition) const {
assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
return (maskBit(bitPosition) &
- (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) !=
+ (isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)])) !=
0;
}
@@ -1074,7 +1077,7 @@ public:
bool operator==(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
if (isSingleWord())
- return VAL == RHS.VAL;
+ return U.VAL == RHS.U.VAL;
return EqualSlowCase(RHS);
}
@@ -1265,7 +1268,7 @@ public:
bool intersects(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- return (VAL & RHS.VAL) != 0;
+ return (U.VAL & RHS.U.VAL) != 0;
return intersectsSlowCase(RHS);
}
@@ -1273,7 +1276,7 @@ public:
bool isSubsetOf(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- return (VAL & ~RHS.VAL) == 0;
+ return (U.VAL & ~RHS.U.VAL) == 0;
return isSubsetOfSlowCase(RHS);
}
@@ -1333,10 +1336,10 @@ public:
/// \brief Set every bit to 1.
void setAllBits() {
if (isSingleWord())
- VAL = WORD_MAX;
+ U.VAL = WORD_MAX;
else
// Set all the bits in all the words.
- memset(pVal, -1, getNumWords() * APINT_WORD_SIZE);
+ memset(U.pVal, -1, getNumWords() * APINT_WORD_SIZE);
// Clear the unused ones
clearUnusedBits();
}
@@ -1348,9 +1351,9 @@ public:
assert(BitPosition <= BitWidth && "BitPosition out of range");
WordType Mask = maskBit(BitPosition);
if (isSingleWord())
- VAL |= Mask;
+ U.VAL |= Mask;
else
- pVal[whichWord(BitPosition)] |= Mask;
+ U.pVal[whichWord(BitPosition)] |= Mask;
}
/// Set the sign bit to 1.
@@ -1369,9 +1372,9 @@ public:
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
mask <<= loBit;
if (isSingleWord())
- VAL |= mask;
+ U.VAL |= mask;
else
- pVal[0] |= mask;
+ U.pVal[0] |= mask;
} else {
setBitsSlowCase(loBit, hiBit);
}
@@ -1395,9 +1398,9 @@ public:
/// \brief Set every bit to 0.
void clearAllBits() {
if (isSingleWord())
- VAL = 0;
+ U.VAL = 0;
else
- memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+ memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
}
/// \brief Set a given bit to 0.
@@ -1407,9 +1410,9 @@ public:
assert(BitPosition <= BitWidth && "BitPosition out of range");
WordType Mask = ~maskBit(BitPosition);
if (isSingleWord())
- VAL &= Mask;
+ U.VAL &= Mask;
else
- pVal[whichWord(BitPosition)] &= Mask;
+ U.pVal[whichWord(BitPosition)] &= Mask;
}
/// Set the sign bit to 0.
@@ -1420,7 +1423,7 @@ public:
/// \brief Toggle every bit to its opposite value.
void flipAllBits() {
if (isSingleWord()) {
- VAL ^= WORD_MAX;
+ U.VAL ^= WORD_MAX;
clearUnusedBits();
} else {
flipAllBitsSlowCase();
@@ -1500,9 +1503,9 @@ public:
/// uint64_t. Otherwise an assertion will result.
uint64_t getZExtValue() const {
if (isSingleWord())
- return VAL;
+ return U.VAL;
assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
- return pVal[0];
+ return U.pVal[0];
}
/// \brief Get sign extended value
@@ -1512,9 +1515,9 @@ public:
/// int64_t. Otherwise an assertion will result.
int64_t getSExtValue() const {
if (isSingleWord())
- return SignExtend64(VAL, BitWidth);
+ return SignExtend64(U.VAL, BitWidth);
assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
- return int64_t(pVal[0]);
+ return int64_t(U.pVal[0]);
}
/// \brief Get bits required for string value.
@@ -1534,7 +1537,7 @@ public:
unsigned countLeadingZeros() const {
if (isSingleWord()) {
unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
- return llvm::countLeadingZeros(VAL) - unusedBits;
+ return llvm::countLeadingZeros(U.VAL) - unusedBits;
}
return countLeadingZerosSlowCase();
}
@@ -1575,7 +1578,7 @@ public:
/// of ones from the least significant bit to the first zero bit.
unsigned countTrailingOnes() const {
if (isSingleWord())
- return llvm::countTrailingOnes(VAL);
+ return llvm::countTrailingOnes(U.VAL);
return countTrailingOnesSlowCase();
}
@@ -1587,7 +1590,7 @@ public:
/// \returns 0 if the value is zero, otherwise returns the number of set bits.
unsigned countPopulation() const {
if (isSingleWord())
- return llvm::countPopulation(VAL);
+ return llvm::countPopulation(U.VAL);
return countPopulationSlowCase();
}
@@ -1646,7 +1649,7 @@ public:
uint64_t I;
double D;
} T;
- T.I = (isSingleWord() ? VAL : pVal[0]);
+ T.I = (isSingleWord() ? U.VAL : U.pVal[0]);
return T.D;
}
@@ -1660,7 +1663,7 @@ public:
unsigned I;
float F;
} T;
- T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
+ T.I = unsigned((isSingleWord() ? U.VAL : U.pVal[0]));
return T.F;
}
@@ -1718,7 +1721,7 @@ public:
// get 0. If VAL is 0, we get WORD_MAX which gets truncated to
// UINT32_MAX.
if (BitWidth == 1)
- return VAL - 1;
+ return U.VAL - 1;
// Handle the zero case.
if (isNullValue())
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index 317a5d3f54c8..0d898827efc6 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -346,29 +346,21 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features,
Module &M) {
for (auto &F : M) {
auto &Ctx = F.getContext();
- AttributeList Attrs = F.getAttributes(), NewAttrs;
+ AttributeList Attrs = F.getAttributes();
+ AttrBuilder NewAttrs;
if (!CPU.empty())
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeList::FunctionIndex,
- "target-cpu", CPU);
-
+ NewAttrs.addAttribute("target-cpu", CPU);
if (!Features.empty())
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeList::FunctionIndex,
- "target-features", Features);
-
+ NewAttrs.addAttribute("target-features", Features);
if (DisableFPElim.getNumOccurrences() > 0)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeList::FunctionIndex,
- "no-frame-pointer-elim",
- DisableFPElim ? "true" : "false");
-
+ NewAttrs.addAttribute("no-frame-pointer-elim",
+ DisableFPElim ? "true" : "false");
if (DisableTailCalls.getNumOccurrences() > 0)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeList::FunctionIndex,
- "disable-tail-calls",
- toStringRef(DisableTailCalls));
-
+ NewAttrs.addAttribute("disable-tail-calls",
+ toStringRef(DisableTailCalls));
if (StackRealign)
- NewAttrs = NewAttrs.addAttribute(Ctx, AttributeList::FunctionIndex,
- "stackrealign");
+ NewAttrs.addAttribute("stackrealign");
if (TrapFuncName.getNumOccurrences() > 0)
for (auto &B : F)
@@ -382,8 +374,8 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features,
Attribute::get(Ctx, "trap-func-name", TrapFuncName));
// Let NewAttrs override Attrs.
- NewAttrs = Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs);
- F.setAttributes(NewAttrs);
+ F.setAttributes(
+ Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
}
}
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h
index 086d6dff11c5..ac8aaafeadc1 100644
--- a/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -53,7 +53,7 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
typedef void ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::CVRecord<Kind> &Item, void *Ctx) {
+ codeview::CVRecord<Kind> &Item) {
using namespace codeview;
const RecordPrefix *Prefix = nullptr;
BinaryStreamReader Reader(Stream);
diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
index a5a3b851b841..6c08c9aa2137 100644
--- a/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
+++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
@@ -21,6 +21,8 @@
namespace llvm {
namespace codeview {
+class StringTable;
+
struct FileChecksumEntry {
uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
FileChecksumKind Kind; // The type of checksum.
@@ -35,7 +37,7 @@ public:
typedef void ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::FileChecksumEntry &Item, void *Ctx);
+ codeview::FileChecksumEntry &Item);
};
}
@@ -55,8 +57,8 @@ public:
Error initialize(BinaryStreamReader Reader);
- Iterator begin() const { return Checksums.begin(); }
- Iterator end() const { return Checksums.end(); }
+ Iterator begin() { return Checksums.begin(); }
+ Iterator end() { return Checksums.end(); }
const FileChecksumArray &getArray() const { return Checksums; }
@@ -66,20 +68,22 @@ private:
class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment {
public:
- ModuleDebugFileChecksumFragment();
+ explicit ModuleDebugFileChecksumFragment(StringTable &Strings);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::FileChecksums;
}
- void addChecksum(uint32_t StringTableOffset, FileChecksumKind Kind,
+ void addChecksum(StringRef FileName, FileChecksumKind Kind,
ArrayRef<uint8_t> Bytes);
uint32_t calculateSerializedLength() override;
Error commit(BinaryStreamWriter &Writer) override;
- uint32_t mapChecksumOffset(uint32_t StringTableOffset) const;
+ uint32_t mapChecksumOffset(StringRef FileName) const;
private:
+ StringTable &Strings;
+
DenseMap<uint32_t, uint32_t> OffsetMap;
uint32_t SerializedSize = 0;
llvm::BumpPtrAllocator Storage;
diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
index b98c8605592c..f68f21b224f1 100644
--- a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
+++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
@@ -57,8 +57,6 @@ private:
ModuleDebugFragment &Frag;
};
-typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
-
} // namespace codeview
template <>
@@ -66,13 +64,17 @@ struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
typedef void ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Length,
- codeview::ModuleDebugFragmentRecord &Info, void *Ctx) {
+ codeview::ModuleDebugFragmentRecord &Info) {
if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
return Error::success();
}
};
+
+namespace codeview {
+typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
+}
} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h
index 177367c111c3..348497cbf7f2 100644
--- a/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h
+++ b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h
@@ -20,6 +20,8 @@ namespace llvm {
namespace codeview {
class ModuleDebugInlineeLineFragmentRef;
+class ModuleDebugFileChecksumFragment;
+class StringTable;
enum class InlineeLinesSignature : uint32_t {
Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
@@ -42,11 +44,10 @@ struct InlineeSourceLine {
}
template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
- typedef codeview::ModuleDebugInlineeLineFragmentRef ContextType;
+ typedef bool ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- codeview::InlineeSourceLine &Item,
- ContextType *Fragment);
+ codeview::InlineeSourceLine &Item, bool HasExtraFiles);
};
namespace codeview {
@@ -74,7 +75,8 @@ private:
class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment {
public:
- explicit ModuleDebugInlineeLineFragment(bool HasExtraFiles);
+ ModuleDebugInlineeLineFragment(ModuleDebugFileChecksumFragment &Checksums,
+ bool HasExtraFiles);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::InlineeLines;
@@ -83,11 +85,12 @@ public:
Error commit(BinaryStreamWriter &Writer) override;
uint32_t calculateSerializedLength() override;
- void addInlineSite(TypeIndex FuncId, uint32_t FileOffset,
- uint32_t SourceLine);
- void addExtraFile(uint32_t FileOffset);
+ void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine);
+ void addExtraFile(StringRef FileName);
private:
+ ModuleDebugFileChecksumFragment &Checksums;
+
bool HasExtraFiles = false;
uint32_t ExtraFileCount = 0;
diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
index dcfe86dd8503..3124236b8fb1 100644
--- a/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
+++ b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
@@ -19,6 +19,9 @@
namespace llvm {
namespace codeview {
+class ModuleDebugFileChecksumFragment;
+class StringTable;
+
// Corresponds to the `CV_DebugSLinesHeader_t` structure.
struct LineFragmentHeader {
support::ulittle32_t RelocOffset; // Code offset of line contribution.
@@ -61,10 +64,10 @@ struct LineColumnEntry {
class LineColumnExtractor {
public:
- typedef const LineFragmentHeader ContextType;
+ typedef const LineFragmentHeader *ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
- LineColumnEntry &Item, const LineFragmentHeader *Header);
+ LineColumnEntry &Item, const LineFragmentHeader *Ctx);
};
class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef {
@@ -104,13 +107,14 @@ class ModuleDebugLineFragment final : public ModuleDebugFragment {
};
public:
- ModuleDebugLineFragment();
+ ModuleDebugLineFragment(ModuleDebugFileChecksumFragment &Checksums,
+ StringTable &Strings);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::Lines;
}
- void createBlock(uint32_t ChecksumBufferOffset);
+ void createBlock(StringRef FileName);
void addLineInfo(uint32_t Offset, const LineInfo &Line);
void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
uint32_t ColStart, uint32_t ColEnd);
@@ -125,6 +129,8 @@ public:
bool hasColumnInfo() const;
private:
+ ModuleDebugFileChecksumFragment &Checksums;
+
uint16_t RelocOffset = 0;
uint16_t RelocSegment = 0;
uint32_t CodeSize = 0;
diff --git a/include/llvm/DebugInfo/CodeView/StringTable.h b/include/llvm/DebugInfo/CodeView/StringTable.h
new file mode 100644
index 000000000000..05dc02ee849f
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StringTable.h
@@ -0,0 +1,75 @@
+//===- StringTable.h - CodeView String Table Reader/Writer ------*- 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_STRINGTABLE_H
+#define LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+
+#include <stdint.h>
+
+namespace llvm {
+
+class BinaryStreamReader;
+class BinaryStreamRef;
+class BinaryStreamWriter;
+
+namespace codeview {
+
+/// Represents a read-only view of a CodeView string table. This is a very
+/// simple flat buffer consisting of null-terminated strings, where strings
+/// are retrieved by their offset in the buffer. StringTableRef does not own
+/// the underlying storage for the buffer.
+class StringTableRef {
+public:
+ StringTableRef();
+
+ Error initialize(BinaryStreamRef Contents);
+
+ Expected<StringRef> getString(uint32_t Offset) const;
+
+ bool valid() const { return Stream.valid(); }
+
+private:
+ BinaryStreamRef Stream;
+};
+
+/// Represents a read-write view of a CodeView string table. StringTable owns
+/// the underlying storage for the table, and is capable of serializing the
+/// string table into a format understood by StringTableRef.
+class StringTable {
+public:
+ // If string S does not exist in the string table, insert it.
+ // Returns the ID for S.
+ uint32_t insert(StringRef S);
+
+ // Return the ID for string S. Assumes S exists in the table.
+ uint32_t getStringId(StringRef S) const;
+
+ uint32_t calculateSerializedSize() const;
+ Error commit(BinaryStreamWriter &Writer) const;
+
+ uint32_t size() const;
+
+ StringMap<uint32_t>::const_iterator begin() const { return Strings.begin(); }
+
+ StringMap<uint32_t>::const_iterator end() const { return Strings.end(); }
+
+private:
+ StringMap<uint32_t> Strings;
+ uint32_t StringSize = 1;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
index 2bef3f61adfc..96c8a47a3669 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -19,13 +19,15 @@ class BinaryStreamReader;
namespace codeview {
+class StringTableRef;
+
class SymbolVisitorDelegate {
public:
virtual ~SymbolVisitorDelegate() = default;
virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
- virtual StringRef getStringTable() = 0;
+ virtual StringTableRef getStringTable() = 0;
};
} // end namespace codeview
diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 3c04c6716ea3..b9f3425d5deb 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -172,6 +172,9 @@ public:
return DWOCUs[index].get();
}
+ /// Get a DIE given an exact offset.
+ DWARFDie getDIEForOffset(uint32_t Offset);
+
const DWARFUnitIndex &getCUIndex();
DWARFGdbIndex &getGdbIndex();
const DWARFUnitIndex &getTUIndex();
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index dd0e2648bf30..e21245b97b73 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -30,7 +30,7 @@ public:
struct FileNameEntry {
FileNameEntry() = default;
- const char *Name = nullptr;
+ StringRef Name = StringRef();
uint64_t DirIdx = 0;
uint64_t ModTime = 0;
uint64_t Length = 0;
@@ -44,6 +44,10 @@ public:
uint64_t TotalLength;
/// Version identifier for the statement information format.
uint16_t Version;
+ /// In v5, size in bytes of an address (or segment offset).
+ uint8_t AddressSize;
+ /// In v5, size in bytes of a segment selector.
+ uint8_t SegSelectorSize;
/// The number of bytes following the prologue_length field to the beginning
/// of the first byte of the statement program itself.
uint64_t PrologueLength;
@@ -63,7 +67,7 @@ public:
/// The number assigned to the first special opcode.
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
- std::vector<const char *> IncludeDirectories;
+ std::vector<StringRef> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
bool IsDWARF64;
@@ -100,7 +104,7 @@ public:
void postAppend();
void reset(bool DefaultIsStmt);
void dump(raw_ostream &OS) const;
-
+ static void dumpTableHeader(raw_ostream &OS);
static bool orderByAddress(const Row &LHS, const Row &RHS) {
return LHS.Address < RHS.Address;
}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index e29ba523238c..68e541bac73c 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -312,9 +312,9 @@ public:
[](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
return LHS.getOffset() < Offset;
});
- if (it == DieArray.end())
- return DWARFDie();
- return DWARFDie(this, &*it);
+ if (it != DieArray.end() && it->getOffset() == Offset)
+ return DWARFDie(this, &*it);
+ return DWARFDie();
}
uint32_t getLineTableOffset() const {
diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
new file mode 100644
index 000000000000..8e12bcd2c8e2
--- /dev/null
+++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -0,0 +1,98 @@
+//===- DWARFVerifier.h ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+
+#include <cstdint>
+#include <map>
+#include <set>
+
+namespace llvm {
+class raw_ostream;
+struct DWARFAttribute;
+class DWARFContext;
+class DWARFDie;
+class DWARFUnit;
+
+/// A class that verifies DWARF debug information given a DWARF Context.
+class DWARFVerifier {
+ raw_ostream &OS;
+ DWARFContext &DCtx;
+ /// A map that tracks all references (converted absolute references) so we
+ /// can verify each reference points to a valid DIE and not an offset that
+ /// lies between to valid DIEs.
+ std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
+ uint32_t NumDebugInfoErrors;
+ uint32_t NumDebugLineErrors;
+
+ /// Verifies the attribute's DWARF attribute and its value.
+ ///
+ /// This function currently checks for:
+ /// - DW_AT_ranges values is a valid .debug_ranges offset
+ /// - DW_AT_stmt_list is a valid .debug_line offset
+ ///
+ /// @param Die The DWARF DIE that owns the attribute value
+ /// @param AttrValue The DWARF attribute value to check
+ void verifyDebugInfoAttribute(DWARFDie &Die, DWARFAttribute &AttrValue);
+
+ /// Verifies the attribute's DWARF form.
+ ///
+ /// This function currently checks for:
+ /// - All DW_FORM_ref values that are CU relative have valid CU offsets
+ /// - All DW_FORM_ref_addr values have valid .debug_info offsets
+ /// - All DW_FORM_strp values have valid .debug_str offsets
+ ///
+ /// @param Die The DWARF DIE that owns the attribute value
+ /// @param AttrValue The DWARF attribute value to check
+ void verifyDebugInfoForm(DWARFDie &Die, DWARFAttribute &AttrValue);
+
+ /// Verifies the all valid references that were found when iterating through
+ /// all of the DIE attributes.
+ ///
+ /// This function will verify that all references point to DIEs whose DIE
+ /// offset matches. This helps to ensure if a DWARF link phase moved things
+ /// around, that it doesn't create invalid references by failing to relocate
+ /// CU relative and absolute references.
+ void veifyDebugInfoReferences();
+
+ /// Verify the the DW_AT_stmt_list encoding and value and ensure that no
+ /// compile units that have the same DW_AT_stmt_list value.
+ void verifyDebugLineStmtOffsets();
+
+ /// Verify that all of the rows in the line table are valid.
+ ///
+ /// This function currently checks for:
+ /// - addresses within a sequence that decrease in value
+ /// - invalid file indexes
+ void verifyDebugLineRows();
+
+public:
+ DWARFVerifier(raw_ostream &S, DWARFContext &D)
+ : OS(S), DCtx(D), NumDebugInfoErrors(0), NumDebugLineErrors(0) {}
+ /// Verify the information in the .debug_info section.
+ ///
+ /// Any errors are reported to the stream that was this object was
+ /// constructed with.
+ ///
+ /// @return True if the .debug_info verifies successfully, false otherwise.
+ bool handleDebugInfo();
+
+ /// Verify the information in the .debug_line section.
+ ///
+ /// Any errors are reported to the stream that was this object was
+ /// constructed with.
+ ///
+ /// @return True if the .debug_line verifies successfully, false otherwise.
+ bool handleDebugLine();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
index 879cb4285cd7..d1f791b9daed 100644
--- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
+++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h
@@ -66,7 +66,7 @@ struct ModuleInfoEx {
template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> {
typedef void ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Length,
- pdb::DbiModuleDescriptor &Info, void *Ctx) {
+ pdb::DbiModuleDescriptor &Info) {
if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h
index 84ae57f2e23a..08262e47f77f 100644
--- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h
+++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h
@@ -13,9 +13,9 @@
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/DebugInfo/PDB/Native/StringTable.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamArray.h"
@@ -91,7 +91,7 @@ private:
std::unique_ptr<msf::MappedBlockStream> Stream;
std::vector<ModuleInfoEx> ModuleInfos;
- StringTable ECNames;
+ PDBStringTable ECNames;
BinaryStreamRef ModInfoSubstream;
BinaryStreamRef SecContrSubstream;
diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/include/llvm/DebugInfo/PDB/Native/PDBFile.h
index fbca62d6e9d9..3bed67141c56 100644
--- a/include/llvm/DebugInfo/PDB/Native/PDBFile.h
+++ b/include/llvm/DebugInfo/PDB/Native/PDBFile.h
@@ -33,7 +33,7 @@ namespace pdb {
class DbiStream;
class GlobalsStream;
class InfoStream;
-class StringTable;
+class PDBStringTable;
class PDBFileBuilder;
class PublicsStream;
class SymbolStream;
@@ -95,7 +95,7 @@ public:
Expected<TpiStream &> getPDBIpiStream();
Expected<PublicsStream &> getPDBPublicsStream();
Expected<SymbolStream &> getPDBSymbolStream();
- Expected<StringTable &> getStringTable();
+ Expected<PDBStringTable &> getStringTable();
BumpPtrAllocator &getAllocator() { return Allocator; }
@@ -106,7 +106,7 @@ public:
bool hasPDBPublicsStream();
bool hasPDBSymbolStream();
bool hasPDBTpiStream() const;
- bool hasStringTable();
+ bool hasPDBStringTable();
private:
Expected<std::unique_ptr<msf::MappedBlockStream>>
@@ -131,7 +131,7 @@ private:
std::unique_ptr<SymbolStream> Symbols;
std::unique_ptr<msf::MappedBlockStream> DirectoryStream;
std::unique_ptr<msf::MappedBlockStream> StringTableStream;
- std::unique_ptr<StringTable> Strings;
+ std::unique_ptr<PDBStringTable> Strings;
};
}
}
diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index 3898af5afc9e..cd7d3b063793 100644
--- a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
+++ b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -15,8 +15,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -46,12 +46,14 @@ public:
DbiStreamBuilder &getDbiBuilder();
TpiStreamBuilder &getTpiBuilder();
TpiStreamBuilder &getIpiBuilder();
- StringTableBuilder &getStringTableBuilder();
+ PDBStringTableBuilder &getStringTableBuilder();
Error commit(StringRef Filename);
-private:
+ Expected<uint32_t> getNamedStreamIndex(StringRef Name) const;
Error addNamedStream(StringRef Name, uint32_t Size);
+
+private:
Expected<msf::MSFLayout> finalizeMsfLayout();
BumpPtrAllocator &Allocator;
@@ -62,7 +64,7 @@ private:
std::unique_ptr<TpiStreamBuilder> Tpi;
std::unique_ptr<TpiStreamBuilder> Ipi;
- StringTableBuilder Strings;
+ PDBStringTableBuilder Strings;
NamedStreamMap NamedStreams;
};
}
diff --git a/include/llvm/DebugInfo/PDB/Native/StringTable.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
index dd5e30e61827..7c7f16bd1c73 100644
--- a/include/llvm/DebugInfo/PDB/Native/StringTable.h
+++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
@@ -1,4 +1,4 @@
-//===- StringTable.h - PDB String Table -------------------------*- C++ -*-===//
+//===- PDBStringTable.h - PDB String Table -----------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
-#define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
@@ -22,31 +23,38 @@
namespace llvm {
class BinaryStreamReader;
+namespace msf {
+class MappedBlockStream;
+}
+
namespace pdb {
-class StringTable {
-public:
- StringTable();
+struct PDBStringTableHeader;
- Error load(BinaryStreamReader &Stream);
+class PDBStringTable {
+public:
+ Error reload(BinaryStreamReader &Reader);
uint32_t getByteSize() const;
+ uint32_t getNameCount() const;
+ uint32_t getHashVersion() const;
+ uint32_t getSignature() const;
- uint32_t getNameCount() const { return NameCount; }
- uint32_t getHashVersion() const { return HashVersion; }
- uint32_t getSignature() const { return Signature; }
-
- StringRef getStringForID(uint32_t ID) const;
- uint32_t getIDForString(StringRef Str) const;
+ Expected<StringRef> getStringForID(uint32_t ID) const;
+ Expected<uint32_t> getIDForString(StringRef Str) const;
FixedStreamArray<support::ulittle32_t> name_ids() const;
private:
- BinaryStreamRef NamesBuffer;
+ Error readHeader(BinaryStreamReader &Reader);
+ Error readStrings(BinaryStreamReader &Reader);
+ Error readHashTable(BinaryStreamReader &Reader);
+ Error readEpilogue(BinaryStreamReader &Reader);
+
+ const PDBStringTableHeader *Header = nullptr;
+ codeview::StringTableRef Strings;
FixedStreamArray<support::ulittle32_t> IDs;
uint32_t ByteSize = 0;
- uint32_t Signature = 0;
- uint32_t HashVersion = 0;
uint32_t NameCount = 0;
};
diff --git a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
new file mode 100644
index 000000000000..6f85e7a4a074
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
@@ -0,0 +1,60 @@
+//===- PDBStringTableBuilder.h - PDB String Table Builder -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file creates the "/names" stream.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StringTable.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+class BinaryStreamWriter;
+class WritableBinaryStreamRef;
+
+namespace msf {
+struct MSFLayout;
+}
+
+namespace pdb {
+
+class PDBFileBuilder;
+
+class PDBStringTableBuilder {
+public:
+ // If string S does not exist in the string table, insert it.
+ // Returns the ID for S.
+ uint32_t insert(StringRef S);
+
+ uint32_t calculateSerializedSize() const;
+ Error commit(BinaryStreamWriter &Writer) const;
+
+ codeview::StringTable &getStrings() { return Strings; }
+ const codeview::StringTable &getStrings() const { return Strings; }
+
+private:
+ uint32_t calculateHashTableSize() const;
+ Error writeHeader(BinaryStreamWriter &Writer) const;
+ Error writeStrings(BinaryStreamWriter &Writer) const;
+ Error writeHashTable(BinaryStreamWriter &Writer) const;
+ Error writeEpilogue(BinaryStreamWriter &Writer) const;
+
+ codeview::StringTable Strings;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h
index e1c6cf0021d5..93622d0a4394 100644
--- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h
+++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h
@@ -307,13 +307,13 @@ struct InfoStreamHeader {
};
/// The header preceeding the /names stream.
-struct StringTableHeader {
- support::ulittle32_t Signature;
- support::ulittle32_t HashVersion;
- support::ulittle32_t ByteSize;
+struct PDBStringTableHeader {
+ support::ulittle32_t Signature; // PDBStringTableSignature
+ support::ulittle32_t HashVersion; // 1 or 2
+ support::ulittle32_t ByteSize; // Number of bytes of names buffer.
};
-const uint32_t StringTableSignature = 0xEFFEEFFE;
+const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
} // namespace pdb
} // namespace llvm
diff --git a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h
deleted file mode 100644
index 9c4b12e33ba0..000000000000
--- a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===- StringTableBuilder.h - PDB String Table Builder ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file creates the "/names" stream.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
-#define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include <vector>
-
-namespace llvm {
-class BinaryStreamWriter;
-
-namespace pdb {
-
-class StringTableBuilder {
-public:
- // If string S does not exist in the string table, insert it.
- // Returns the ID for S.
- uint32_t insert(StringRef S);
- uint32_t getStringIndex(StringRef S);
-
- uint32_t finalize();
- Error commit(BinaryStreamWriter &Writer) const;
-
-private:
- DenseMap<StringRef, uint32_t> Strings;
- uint32_t StringSize = 1;
-};
-
-} // end namespace pdb
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index af46034d5a9e..adcb7266073b 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -285,7 +285,8 @@ class AttributeList {
public:
enum AttrIndex : unsigned {
ReturnIndex = 0U,
- FunctionIndex = ~0U
+ FunctionIndex = ~0U,
+ FirstArgIndex = 1,
};
private:
@@ -336,6 +337,13 @@ public:
static AttributeList get(LLVMContext &C, unsigned Index,
const AttrBuilder &B);
+ /// Add an argument attribute to the list. Returns a new list because
+ /// attribute lists are immutable.
+ AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
+ Attribute::AttrKind Kind) const {
+ return addAttribute(C, ArgNo + FirstArgIndex, Kind);
+ }
+
/// \brief Add an attribute to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
AttributeList addAttribute(LLVMContext &C, unsigned Index,
@@ -354,9 +362,6 @@ public:
/// \brief Add attributes to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
AttributeList addAttributes(LLVMContext &C, unsigned Index,
- AttributeList Attrs) const;
-
- AttributeList addAttributes(LLVMContext &C, unsigned Index,
const AttrBuilder &B) const;
/// \brief Remove the specified attribute at the specified index from this
@@ -375,13 +380,7 @@ public:
/// attribute list. Because attribute lists are immutable, this returns the
/// new list.
AttributeList removeAttributes(LLVMContext &C, unsigned Index,
- AttributeList Attrs) const;
-
- /// \brief Remove the specified attributes at the specified index from this
- /// attribute list. Because attribute lists are immutable, this returns the
- /// new list.
- AttributeList removeAttributes(LLVMContext &C, unsigned Index,
- const AttrBuilder &Attrs) const;
+ const AttrBuilder &AttrsToRemove) const;
/// \brief Remove all attributes at the specified index from this
/// attribute list. Because attribute lists are immutable, this returns the
@@ -442,7 +441,7 @@ public:
/// may be faster.
bool hasFnAttribute(StringRef Kind) const;
- /// \brief Equivalent to hasAttribute(ArgNo + 1, Kind).
+ /// \brief Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind).
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const;
/// \brief Return true if the specified attribute is set for at least one
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index bad1d4e383d5..d61431a51a97 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -339,6 +339,10 @@ public:
CALLSITE_DELEGATE_SETTER(addAttribute(i, Attr));
}
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ CALLSITE_DELEGATE_SETTER(addParamAttr(ArgNo, Kind));
+ }
+
void removeAttribute(unsigned i, Attribute::AttrKind Kind) {
CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
}
@@ -347,6 +351,10 @@ public:
CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
}
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ CALLSITE_DELEGATE_SETTER(removeParamAttr(ArgNo, Kind));
+ }
+
/// Return true if this function has the given attribute.
bool hasFnAttr(Attribute::AttrKind Kind) const {
CALLSITE_DELEGATE_GETTER(hasFnAttr(Kind));
@@ -408,11 +416,9 @@ public:
CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
}
- /// Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- CALLSITE_DELEGATE_GETTER(doesNotAlias(n));
+ /// Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ CALLSITE_DELEGATE_GETTER(returnDoesNotAlias());
}
/// Return true if the call should not be treated as a call to a builtin.
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 9e723f977755..f9582f51ca8d 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -204,6 +204,10 @@ public:
addAttribute(AttributeList::FunctionIndex, Attr);
}
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ }
+
/// @brief Remove function attributes from this function.
void removeFnAttr(Attribute::AttrKind Kind) {
removeAttribute(AttributeList::FunctionIndex, Kind);
@@ -211,10 +215,14 @@ public:
/// @brief Remove function attribute from this function.
void removeFnAttr(StringRef Kind) {
- setAttributes(AttributeSets.removeAttribute(
+ setAttributes(getAttributes().removeAttribute(
getContext(), AttributeList::FunctionIndex, Kind));
}
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+ removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
+ }
+
/// \brief Set the entry count for this function.
///
/// Entry count is the number of times this function was executed based on
@@ -279,7 +287,7 @@ public:
void addAttribute(unsigned i, Attribute Attr);
/// @brief adds the attributes to the list of attributes.
- void addAttributes(unsigned i, AttributeList Attrs);
+ void addAttributes(unsigned i, const AttrBuilder &Attrs);
/// @brief removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
@@ -288,7 +296,7 @@ public:
void removeAttribute(unsigned i, StringRef Kind);
/// @brief removes the attributes from the list of attributes.
- void removeAttributes(unsigned i, AttributeList Attrs);
+ void removeAttributes(unsigned i, const AttrBuilder &Attrs);
/// @brief check if an attributes is in the list of attributes.
bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const {
@@ -459,35 +467,12 @@ public:
/// @brief Determine if the parameter or return value is marked with NoAlias
/// attribute.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::NoAlias);
- }
- void setDoesNotAlias(unsigned n) {
- addAttribute(n, Attribute::NoAlias);
- }
-
- /// @brief Determine if the parameter can be captured.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotCapture(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::NoCapture);
- }
- void setDoesNotCapture(unsigned n) {
- addAttribute(n, Attribute::NoCapture);
- }
-
- bool doesNotAccessMemory(unsigned n) const {
- return AttributeSets.hasAttribute(n, Attribute::ReadNone);
- }
- void setDoesNotAccessMemory(unsigned n) {
- addAttribute(n, Attribute::ReadNone);
- }
-
- bool onlyReadsMemory(unsigned n) const {
- return doesNotAccessMemory(n) ||
- AttributeSets.hasAttribute(n, Attribute::ReadOnly);
+ bool returnDoesNotAlias() const {
+ return AttributeSets.hasAttribute(AttributeList::ReturnIndex,
+ Attribute::NoAlias);
}
- void setOnlyReadsMemory(unsigned n) {
- addAttribute(n, Attribute::ReadOnly);
+ void setReturnDoesNotAlias() {
+ addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Optimize this function for minimum size (-Oz).
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 4d3f1dc267f2..844a7273eca9 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -1658,12 +1658,18 @@ public:
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute Attr);
+ /// Adds the attribute to the indicated argument
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, StringRef Kind);
+ /// Removes the attribute from the given argument
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@@ -1734,11 +1740,9 @@ public:
return Attrs.getDereferenceableOrNullBytes(i);
}
- /// @brief Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return Attrs.hasAttribute(n, Attribute::NoAlias);
+ /// @brief Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ return Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Return true if the call should not be treated as a call to a
@@ -3750,12 +3754,18 @@ public:
/// adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute Attr);
+ /// Adds the attribute to the indicated argument
+ void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);
/// removes the attribute from the list of attributes.
void removeAttribute(unsigned i, StringRef Kind);
+ /// Removes the attribute from the given argument
+ void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
+
/// adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
@@ -3827,11 +3837,9 @@ public:
return Attrs.getDereferenceableOrNullBytes(i);
}
- /// @brief Determine if the parameter or return value is marked with NoAlias
- /// attribute.
- /// @param n The parameter to check. 1 is the first parameter, 0 is the return
- bool doesNotAlias(unsigned n) const {
- return Attrs.hasAttribute(n, Attribute::NoAlias);
+ /// @brief Determine if the return value is marked with NoAlias attribute.
+ bool returnDoesNotAlias() const {
+ return Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
}
/// Return true if the call should not be treated as a call to a
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index 2f6bdf8ecf19..fc79da7ae0e6 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -100,7 +100,7 @@ namespace Intrinsic {
Void, VarArg, MMX, Token, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
- SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfPtrsToElt
+ SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt
} Kind;
union {
@@ -119,25 +119,43 @@ namespace Intrinsic {
AK_AnyVector,
AK_AnyPointer
};
+
unsigned getArgumentNumber() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == PtrToElt || Kind == VecOfPtrsToElt);
+ Kind == PtrToElt);
return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
- Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == VecOfPtrsToElt);
+ Kind == SameVecWidthArgument || Kind == PtrToArgument);
return (ArgKind)(Argument_Info & 7);
}
+ // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
+ // and a reference argument (for matching vector width and element types)
+ unsigned getOverloadArgNumber() const {
+ assert(Kind == VecOfAnyPtrsToElt);
+ return Argument_Info >> 16;
+ }
+ unsigned getRefArgNumber() const {
+ assert(Kind == VecOfAnyPtrsToElt);
+ return Argument_Info & 0xFFFF;
+ }
+
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
}
+
+ static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
+ unsigned short Lo) {
+ unsigned Field = Hi << 16 | Lo;
+ IITDescriptor Result = {K, {Field}};
+ return Result;
+ }
};
/// Return the IIT table descriptor for the specified intrinsic into an array
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 39b992cd06a8..cf7e5d8758a9 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -155,7 +155,7 @@ class LLVMVectorSameWidth<int num, LLVMType elty>
}
class LLVMPointerTo<int num> : LLVMMatchType<num>;
class LLVMPointerToElt<int num> : LLVMMatchType<num>;
-class LLVMVectorOfPointersToElt<int num> : LLVMMatchType<num>;
+class LLVMVectorOfAnyPointersToElt<int num> : LLVMMatchType<num>;
// Match the type of another intrinsic parameter that is expected to be a
// vector type, but change the element count to be half as many
@@ -404,7 +404,7 @@ def int_memset : Intrinsic<[],
// FIXME: Add version of these floating point intrinsics which allow non-default
// rounding modes and FP exception handling.
-let IntrProperties = [IntrNoMem] in {
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_fma : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>,
LLVMMatchType<0>]>;
@@ -440,10 +440,12 @@ let IntrProperties = [IntrNoMem] in {
}
def int_minnum : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, Commutative]
>;
def int_maxnum : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable, Commutative]
>;
// NOTE: these are internal interfaces.
@@ -455,7 +457,7 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
// Internal interface for object size checking
def int_objectsize : Intrinsic<[llvm_anyint_ty],
[llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty],
- [IntrNoMem]>,
+ [IntrNoMem, IntrSpeculatable]>,
GCCBuiltin<"__builtin_object_size">;
//===--------------- Constrained Floating Point Intrinsics ----------------===//
@@ -500,7 +502,7 @@ def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
//
// None of these intrinsics accesses memory at all.
-let IntrProperties = [IntrNoMem] in {
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
@@ -511,10 +513,11 @@ let IntrProperties = [IntrNoMem] in {
//===------------------------ Debugger Intrinsics -------------------------===//
//
-// None of these intrinsics accesses memory at all...but that doesn't mean the
-// optimizers can change them aggressively. Special handling needed in a few
-// places.
-let IntrProperties = [IntrNoMem] in {
+// None of these intrinsics accesses memory at all...but that doesn't
+// mean the optimizers can change them aggressively. Special handling
+// needed in a few places. These synthetic intrinsics have no
+// side-effects and just mark information about their operands.
+let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_dbg_declare : Intrinsic<[],
[llvm_metadata_ty,
llvm_metadata_ty,
@@ -592,24 +595,24 @@ def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
// Expose the carry flag from add operations on two integrals.
def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem]>;
+ [IntrNoMem, IntrSpeculatable]>;
//===------------------------- Memory Use Markers -------------------------===//
//
@@ -633,7 +636,7 @@ def int_invariant_end : Intrinsic<[],
// it can be CSE only if memory didn't change between 2 barriers call,
// which is valid.
// The argument also can't be marked with 'returned' attribute, because
-// it would remove barrier.
+// it would remove barrier.
def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
@@ -758,14 +761,14 @@ def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
- [LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
[IntrReadMem]>;
def int_masked_scatter: Intrinsic<[],
[llvm_anyvector_ty,
- LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>]>;
def int_masked_expandload: Intrinsic<[llvm_anyvector_ty],
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 97c756cf4b60..1c466e73eb1b 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -3221,6 +3221,29 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
+// LWP
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_llwpcb :
+ GCCBuiltin<"__builtin_ia32_llwpcb">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_slwpcb :
+ GCCBuiltin<"__builtin_ia32_slwpcb">,
+ Intrinsic<[llvm_ptr_ty], [], []>;
+ def int_x86_lwpins32 :
+ GCCBuiltin<"__builtin_ia32_lwpins32">,
+ Intrinsic<[llvm_i8_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpins64 :
+ GCCBuiltin<"__builtin_ia32_lwpins64">,
+ Intrinsic<[llvm_i8_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpval32 :
+ GCCBuiltin<"__builtin_ia32_lwpval32">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_lwpval64 :
+ GCCBuiltin<"__builtin_ia32_lwpval64">,
+ Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
// MMX
// Empty MMX state op.
diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h
index 748a62be231e..f141c30f16c7 100644
--- a/include/llvm/Support/BinaryStreamArray.h
+++ b/include/llvm/Support/BinaryStreamArray.h
@@ -42,99 +42,34 @@ namespace llvm {
/// having to specify a second template argument to VarStreamArray (documented
/// below).
template <typename T> struct VarStreamArrayExtractor {
- typedef void Context;
+ struct ContextType {};
// Method intentionally deleted. You must provide an explicit specialization
- // with the following method implemented.
- static Error extract(BinaryStreamRef Stream, uint32_t &Len, T &Item,
- Context *Ctx) = delete;
-};
-
-/// VarStreamArray represents an array of variable length records backed by a
-/// stream. This could be a contiguous sequence of bytes in memory, it could
-/// be a file on disk, or it could be a PDB stream where bytes are stored as
-/// discontiguous blocks in a file. Usually it is desirable to treat arrays
-/// as contiguous blocks of memory, but doing so with large PDB files, for
-/// example, could mean allocating huge amounts of memory just to allow
-/// re-ordering of stream data to be contiguous before iterating over it. By
-/// abstracting this out, we need not duplicate this memory, and we can
-/// iterate over arrays in arbitrarily formatted streams. Elements are parsed
-/// lazily on iteration, so there is no upfront cost associated with building
-/// or copying a VarStreamArray, no matter how large it may be.
-///
-/// You create a VarStreamArray by specifying a ValueType and an Extractor type.
-/// If you do not specify an Extractor type, you are expected to specialize
-/// VarStreamArrayExtractor<T> for your ValueType.
-///
-/// The default extractor type is stateless, but by specializing
-/// VarStreamArrayExtractor or defining your own custom extractor type and
-/// adding the appropriate ContextType typedef to the class, you can pass a
-/// context field during construction of the VarStreamArray that will be
-/// passed to each call to extract.
-///
-template <typename ValueType, typename ExtractorType>
-class VarStreamArrayIterator;
-
-template <typename ValueType,
- typename ExtractorType = VarStreamArrayExtractor<ValueType>>
-class VarStreamArray {
-public:
- typedef typename ExtractorType::ContextType ContextType;
- typedef VarStreamArrayIterator<ValueType, ExtractorType> Iterator;
- friend Iterator;
-
- VarStreamArray() = default;
-
- explicit VarStreamArray(BinaryStreamRef Stream,
- ContextType *Context = nullptr)
- : Stream(Stream), Context(Context) {}
-
- VarStreamArray(const VarStreamArray<ValueType, ExtractorType> &Other)
- : Stream(Other.Stream), Context(Other.Context) {}
-
- Iterator begin(bool *HadError = nullptr) const {
- if (empty())
- return end();
-
- return Iterator(*this, Context, HadError);
- }
-
- Iterator end() const { return Iterator(); }
-
- bool empty() const { return Stream.getLength() == 0; }
-
- /// \brief given an offset into the array's underlying stream, return an
- /// iterator to the record at that offset. This is considered unsafe
- /// since the behavior is undefined if \p Offset does not refer to the
- /// beginning of a valid record.
- Iterator at(uint32_t Offset) const {
- return Iterator(*this, Context, Stream.drop_front(Offset), nullptr);
- }
-
- BinaryStreamRef getUnderlyingStream() const { return Stream; }
+ // with one of the following two methods implemented.
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len, T &Item) = delete;
-private:
- BinaryStreamRef Stream;
- ContextType *Context = nullptr;
+ static Error extract(BinaryStreamRef Stream, uint32_t &Len, T &Item,
+ const ContextType &Ctx) = delete;
};
-template <typename ValueType, typename ExtractorType>
+template <typename ArrayType, typename Value, typename Extractor,
+ typename WrappedCtx>
class VarStreamArrayIterator
: public iterator_facade_base<
- VarStreamArrayIterator<ValueType, ExtractorType>,
- std::forward_iterator_tag, ValueType> {
- typedef typename ExtractorType::ContextType ContextType;
- typedef VarStreamArrayIterator<ValueType, ExtractorType> IterType;
- typedef VarStreamArray<ValueType, ExtractorType> ArrayType;
+ VarStreamArrayIterator<ArrayType, Value, Extractor, WrappedCtx>,
+ std::forward_iterator_tag, Value> {
+ typedef VarStreamArrayIterator<ArrayType, Value, Extractor, WrappedCtx>
+ IterType;
public:
- VarStreamArrayIterator(const ArrayType &Array, ContextType *Context,
+ VarStreamArrayIterator() = default;
+ VarStreamArrayIterator(const ArrayType &Array, const WrappedCtx &Ctx,
BinaryStreamRef Stream, bool *HadError = nullptr)
- : IterRef(Stream), Context(Context), Array(&Array), HadError(HadError) {
+ : IterRef(Stream), Ctx(&Ctx), Array(&Array), HadError(HadError) {
if (IterRef.getLength() == 0)
moveToEnd();
else {
- auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context);
+ auto EC = Ctx.template invoke<Extractor>(IterRef, ThisLen, ThisValue);
if (EC) {
consumeError(std::move(EC));
markError();
@@ -142,11 +77,13 @@ public:
}
}
- VarStreamArrayIterator(const ArrayType &Array, ContextType *Context,
+ VarStreamArrayIterator(const ArrayType &Array, const WrappedCtx &Ctx,
bool *HadError = nullptr)
- : VarStreamArrayIterator(Array, Context, Array.Stream, HadError) {}
+ : VarStreamArrayIterator(Array, Ctx, Array.Stream, HadError) {}
+
+ VarStreamArrayIterator(const WrappedCtx &Ctx) : Ctx(&Ctx) {}
+ VarStreamArrayIterator(const VarStreamArrayIterator &Other) = default;
- VarStreamArrayIterator() = default;
~VarStreamArrayIterator() = default;
bool operator==(const IterType &R) const {
@@ -164,12 +101,12 @@ public:
return false;
}
- const ValueType &operator*() const {
+ const Value &operator*() const {
assert(Array && !HasError);
return ThisValue;
}
- ValueType &operator*() {
+ Value &operator*() {
assert(Array && !HasError);
return ThisValue;
}
@@ -185,7 +122,7 @@ public:
moveToEnd();
} else {
// There is some data after the current record.
- auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context);
+ auto EC = Ctx->template invoke<Extractor>(IterRef, ThisLen, ThisValue);
if (EC) {
consumeError(std::move(EC));
markError();
@@ -210,15 +147,136 @@ private:
*HadError = true;
}
- ValueType ThisValue;
+ Value ThisValue;
BinaryStreamRef IterRef;
- ContextType *Context{nullptr};
+ const WrappedCtx *Ctx{nullptr};
const ArrayType *Array{nullptr};
uint32_t ThisLen{0};
bool HasError{false};
bool *HadError{nullptr};
};
+template <typename T, typename Context> struct ContextWrapper {
+ ContextWrapper() = default;
+
+ explicit ContextWrapper(Context &&Ctx) : Ctx(Ctx) {}
+
+ template <typename Extractor>
+ Error invoke(BinaryStreamRef Stream, uint32_t &Len, T &Item) const {
+ return Extractor::extract(Stream, Len, Item, Ctx);
+ }
+
+ Context Ctx;
+};
+
+template <typename T> struct ContextWrapper<T, void> {
+ ContextWrapper() = default;
+
+ template <typename Extractor>
+ Error invoke(BinaryStreamRef Stream, uint32_t &Len, T &Item) const {
+ return Extractor::extract(Stream, Len, Item);
+ }
+};
+
+/// VarStreamArray represents an array of variable length records backed by a
+/// stream. This could be a contiguous sequence of bytes in memory, it could
+/// be a file on disk, or it could be a PDB stream where bytes are stored as
+/// discontiguous blocks in a file. Usually it is desirable to treat arrays
+/// as contiguous blocks of memory, but doing so with large PDB files, for
+/// example, could mean allocating huge amounts of memory just to allow
+/// re-ordering of stream data to be contiguous before iterating over it. By
+/// abstracting this out, we need not duplicate this memory, and we can
+/// iterate over arrays in arbitrarily formatted streams. Elements are parsed
+/// lazily on iteration, so there is no upfront cost associated with building
+/// or copying a VarStreamArray, no matter how large it may be.
+///
+/// You create a VarStreamArray by specifying a ValueType and an Extractor type.
+/// If you do not specify an Extractor type, you are expected to specialize
+/// VarStreamArrayExtractor<T> for your ValueType.
+///
+/// The default extractor type is stateless, but by specializing
+/// VarStreamArrayExtractor or defining your own custom extractor type and
+/// adding the appropriate ContextType typedef to the class, you can pass a
+/// context field during construction of the VarStreamArray that will be
+/// passed to each call to extract.
+///
+template <typename Value, typename Extractor, typename WrappedCtx>
+class VarStreamArrayBase {
+ typedef VarStreamArrayBase<Value, Extractor, WrappedCtx> MyType;
+
+public:
+ typedef VarStreamArrayIterator<MyType, Value, Extractor, WrappedCtx> Iterator;
+ friend Iterator;
+
+ VarStreamArrayBase() = default;
+
+ VarStreamArrayBase(BinaryStreamRef Stream, const WrappedCtx &Ctx)
+ : Stream(Stream), Ctx(Ctx) {}
+
+ VarStreamArrayBase(const MyType &Other)
+ : Stream(Other.Stream), Ctx(Other.Ctx) {}
+
+ Iterator begin(bool *HadError = nullptr) const {
+ if (empty())
+ return end();
+
+ return Iterator(*this, Ctx, Stream, HadError);
+ }
+
+ bool valid() const { return Stream.valid(); }
+
+ Iterator end() const { return Iterator(Ctx); }
+
+ bool empty() const { return Stream.getLength() == 0; }
+
+ /// \brief given an offset into the array's underlying stream, return an
+ /// iterator to the record at that offset. This is considered unsafe
+ /// since the behavior is undefined if \p Offset does not refer to the
+ /// beginning of a valid record.
+ Iterator at(uint32_t Offset) const {
+ return Iterator(*this, Ctx, Stream.drop_front(Offset), nullptr);
+ }
+
+ BinaryStreamRef getUnderlyingStream() const { return Stream; }
+
+private:
+ BinaryStreamRef Stream;
+ WrappedCtx Ctx;
+};
+
+template <typename Value, typename Extractor, typename Context>
+class VarStreamArrayImpl
+ : public VarStreamArrayBase<Value, Extractor,
+ ContextWrapper<Value, Context>> {
+ typedef ContextWrapper<Value, Context> WrappedContext;
+ typedef VarStreamArrayImpl<Value, Extractor, Context> MyType;
+ typedef VarStreamArrayBase<Value, Extractor, WrappedContext> BaseType;
+
+public:
+ typedef Context ContextType;
+
+ VarStreamArrayImpl() = default;
+ VarStreamArrayImpl(BinaryStreamRef Stream, Context &&Ctx)
+ : BaseType(Stream, WrappedContext(std::forward<Context>(Ctx))) {}
+};
+
+template <typename Value, typename Extractor>
+class VarStreamArrayImpl<Value, Extractor, void>
+ : public VarStreamArrayBase<Value, Extractor, ContextWrapper<Value, void>> {
+ typedef ContextWrapper<Value, void> WrappedContext;
+ typedef VarStreamArrayImpl<Value, Extractor, void> MyType;
+ typedef VarStreamArrayBase<Value, Extractor, WrappedContext> BaseType;
+
+public:
+ VarStreamArrayImpl() = default;
+ VarStreamArrayImpl(BinaryStreamRef Stream)
+ : BaseType(Stream, WrappedContext()) {}
+};
+
+template <typename Value, typename Extractor = VarStreamArrayExtractor<Value>>
+using VarStreamArray =
+ VarStreamArrayImpl<Value, Extractor, typename Extractor::ContextType>;
+
template <typename T> class FixedStreamArrayIterator;
/// FixedStreamArray is similar to VarStreamArray, except with each record
diff --git a/include/llvm/Support/BinaryStreamReader.h b/include/llvm/Support/BinaryStreamReader.h
index f30d82d81b25..77738077f5ff 100644
--- a/include/llvm/Support/BinaryStreamReader.h
+++ b/include/llvm/Support/BinaryStreamReader.h
@@ -31,6 +31,7 @@ namespace llvm {
/// are overridable.
class BinaryStreamReader {
public:
+ BinaryStreamReader() = default;
explicit BinaryStreamReader(BinaryStreamRef Stream);
virtual ~BinaryStreamReader() {}
@@ -172,13 +173,29 @@ public:
/// \returns a success error code if the data was successfully read, otherwise
/// returns an appropriate error code.
template <typename T, typename U>
- Error
- readArray(VarStreamArray<T, U> &Array, uint32_t Size,
- typename VarStreamArray<T, U>::ContextType *Context = nullptr) {
+ Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
BinaryStreamRef S;
if (auto EC = readStreamRef(S, Size))
return EC;
- Array = VarStreamArray<T, U>(S, Context);
+ Array = VarStreamArray<T, U>(S);
+ return Error::success();
+ }
+
+ /// Read a VarStreamArray of size \p Size bytes and store the result into
+ /// \p Array. Updates the stream's offset to point after the newly read
+ /// array. Never causes a copy (although iterating the elements of the
+ /// VarStreamArray may, depending upon the implementation of the underlying
+ /// stream).
+ ///
+ /// \returns a success error code if the data was successfully read, otherwise
+ /// returns an appropriate error code.
+ template <typename T, typename U, typename ContextType>
+ Error readArray(VarStreamArray<T, U> &Array, uint32_t Size,
+ ContextType &&Context) {
+ BinaryStreamRef S;
+ if (auto EC = readStreamRef(S, Size))
+ return EC;
+ Array = VarStreamArray<T, U>(S, std::move(Context));
return Error::success();
}
@@ -227,6 +244,9 @@ public:
/// \returns the next byte in the stream.
uint8_t peek() const;
+ std::pair<BinaryStreamReader, BinaryStreamReader>
+ split(uint32_t Offset) const;
+
private:
BinaryStreamRef Stream;
uint32_t Offset;
diff --git a/include/llvm/Support/BinaryStreamRef.h b/include/llvm/Support/BinaryStreamRef.h
index 23ce02fd7ca4..465e724a6886 100644
--- a/include/llvm/Support/BinaryStreamRef.h
+++ b/include/llvm/Support/BinaryStreamRef.h
@@ -98,6 +98,9 @@ public:
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.
///
diff --git a/include/llvm/Support/BinaryStreamWriter.h b/include/llvm/Support/BinaryStreamWriter.h
index 6734a797ccc4..1b61c32a2541 100644
--- a/include/llvm/Support/BinaryStreamWriter.h
+++ b/include/llvm/Support/BinaryStreamWriter.h
@@ -20,6 +20,7 @@
#include "llvm/Support/Error.h"
#include <cstdint>
#include <type_traits>
+#include <utility>
namespace llvm {
@@ -30,8 +31,6 @@ namespace llvm {
/// although no methods are overridable.
class BinaryStreamWriter {
public:
- // FIXME: We should be able to slice and drop_front etc on Writers / Readers.
-
BinaryStreamWriter() = default;
explicit BinaryStreamWriter(WritableBinaryStreamRef Stream);
virtual ~BinaryStreamWriter() {}
@@ -152,6 +151,9 @@ public:
return writeStreamRef(Array.getUnderlyingStream());
}
+ /// Splits the Writer into two Writers at a given offset.
+ std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const;
+
void setOffset(uint32_t Off) { Offset = Off; }
uint32_t getOffset() const { return Offset; }
uint32_t getLength() const { return Stream.getLength(); }
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index 2d1180c228e3..380b628fd95f 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -58,6 +58,28 @@ public:
/// NULL will be returned.
const char *getCStr(uint32_t *offset_ptr) const;
+ /// Extract a C string from \a *OffsetPtr.
+ ///
+ /// Returns a StringRef for the C String from the data at the offset
+ /// pointed to by \a OffsetPtr. A variable length NULL terminated C
+ /// string will be extracted and the \a OffsetPtr will be
+ /// updated with the offset of the byte that follows the NULL
+ /// terminator byte.
+ ///
+ /// \param[in,out] OffsetPtr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// \return
+ /// A StringRef for the C string value in the data. If the offset
+ /// pointed to by \a OffsetPtr is out of bounds, or if the
+ /// offset plus the length of the C string is out of bounds,
+ /// a default-initialized StringRef will be returned.
+ StringRef getCStrRef(uint32_t *OffsetPtr) const;
+
/// Extract an unsigned integer of size \a byte_size from \a
/// *offset_ptr.
///
diff --git a/include/llvm/Support/ELFRelocs/Hexagon.def b/include/llvm/Support/ELFRelocs/Hexagon.def
index 74e1d405cebd..5021e2b26ce5 100644
--- a/include/llvm/Support/ELFRelocs/Hexagon.def
+++ b/include/llvm/Support/ELFRelocs/Hexagon.def
@@ -99,3 +99,8 @@ ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
ELF_RELOC(R_HEX_23_REG, 94)
+ELF_RELOC(R_HEX_GD_PLT_B22_PCREL_X, 95)
+ELF_RELOC(R_HEX_GD_PLT_B32_PCREL_X, 96)
+ELF_RELOC(R_HEX_LD_PLT_B22_PCREL_X, 97)
+ELF_RELOC(R_HEX_LD_PLT_B32_PCREL_X, 98)
+ELF_RELOC(R_HEX_27_REG, 99)
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index aa9230044b1f..ced183852146 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -2061,6 +2061,14 @@ public:
return false;
}
+ // Return true if the instruction that performs a << b actually performs
+ // a << (b % (sizeof(a) * 8)).
+ virtual bool supportsModuloShift(ISD::NodeType Inst, EVT ReturnType) const {
+ assert((Inst == ISD::SHL || Inst == ISD::SRA || Inst == ISD::SRL) &&
+ "Expect a shift instruction");
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// Runtime Library hooks
//